drm/tegra: sor: Move register programming out of ->init()
authorThierry Reding <treding@nvidia.com>
Wed, 20 Feb 2019 09:03:46 +0000 (10:03 +0100)
committerThierry Reding <treding@nvidia.com>
Thu, 24 Oct 2019 16:41:53 +0000 (18:41 +0200)
The hardware is not guaranteed to be enabled during execution of the
tegra_sor_init() function, which can lead to a crash on some Tegra SoCs.
Fix this by moving all register programming into code that is guaranteed
to only be executed when the hardware is enabled.

Signed-off-by: Thierry Reding <treding@nvidia.com>
drivers/gpu/drm/tegra/sor.c

index fbbb974c1e1a844f49a1c2999d04b54a47a12196..91d5c5041d2c10cd831bbd818f8a1a864b61b0f9 100644 (file)
@@ -2161,6 +2161,15 @@ static void tegra_sor_audio_prepare(struct tegra_sor *sor)
 {
        u32 value;
 
+       /*
+        * Enable and unmask the HDA codec SCRATCH0 register interrupt. This
+        * is used for interoperability between the HDA codec driver and the
+        * HDMI/DP driver.
+        */
+       value = SOR_INT_CODEC_SCRATCH1 | SOR_INT_CODEC_SCRATCH0;
+       tegra_sor_writel(sor, value, SOR_INT_ENABLE);
+       tegra_sor_writel(sor, value, SOR_INT_MASK);
+
        tegra_sor_write_eld(sor);
 
        value = SOR_AUDIO_HDA_PRESENSE_ELDV | SOR_AUDIO_HDA_PRESENSE_PD;
@@ -2170,6 +2179,8 @@ static void tegra_sor_audio_prepare(struct tegra_sor *sor)
 static void tegra_sor_audio_unprepare(struct tegra_sor *sor)
 {
        tegra_sor_writel(sor, 0, SOR_AUDIO_HDA_PRESENSE);
+       tegra_sor_writel(sor, 0, SOR_INT_MASK);
+       tegra_sor_writel(sor, 0, SOR_INT_ENABLE);
 }
 
 static int tegra_sor_hdmi_enable_audio_infoframe(struct tegra_sor *sor)
@@ -2811,7 +2822,6 @@ static int tegra_sor_init(struct host1x_client *client)
        struct tegra_sor *sor = host1x_client_to_sor(client);
        int connector = DRM_MODE_CONNECTOR_Unknown;
        int encoder = DRM_MODE_ENCODER_NONE;
-       u32 value;
        int err;
 
        if (!sor->aux) {
@@ -2914,15 +2924,6 @@ static int tegra_sor_init(struct host1x_client *client)
        if (err < 0)
                return err;
 
-       /*
-        * Enable and unmask the HDA codec SCRATCH0 register interrupt. This
-        * is used for interoperability between the HDA codec driver and the
-        * HDMI/DP driver.
-        */
-       value = SOR_INT_CODEC_SCRATCH1 | SOR_INT_CODEC_SCRATCH0;
-       tegra_sor_writel(sor, value, SOR_INT_ENABLE);
-       tegra_sor_writel(sor, value, SOR_INT_MASK);
-
        return 0;
 }
 
@@ -2931,9 +2932,6 @@ static int tegra_sor_exit(struct host1x_client *client)
        struct tegra_sor *sor = host1x_client_to_sor(client);
        int err;
 
-       tegra_sor_writel(sor, 0, SOR_INT_MASK);
-       tegra_sor_writel(sor, 0, SOR_INT_ENABLE);
-
        tegra_output_exit(&sor->output);
 
        if (sor->aux) {