drm: dw-hdmi: gate audio clock from the I2S enablement callbacks
authorRomain Perier <romain.perier@collabora.com>
Thu, 20 Apr 2017 09:04:34 +0000 (14:34 +0530)
committerArchit Taneja <architt@codeaurora.org>
Thu, 20 Apr 2017 09:24:13 +0000 (14:54 +0530)
Currently, the audio sampler clock is enabled from dw_hdmi_setup() at
step E. and is kept enabled for later use. This clock should be enabled
and disabled along with the actual audio stream and not always on (that
is bad for PM). Furthermore, as described by the datasheet, the I2S
variant needs to gate/ungate the clock when the stream is
enabled/disabled.

This commit adds a parameter to hdmi_audio_enable_clk() that controls
when the audio sample clock must be enabled or disabled. Then, it adds
the call to this function from dw_hdmi_i2s_audio_enable() and
dw_hdmi_i2s_audio_disable().

Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
Signed-off-by: Romain Perier <romain.perier@collabora.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20170414083113.4255-3-romain.perier@collabora.com
Signed-off-by: Archit Taneja <architt@codeaurora.org>
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c

index 94efe0e9e37b2de45c13937133faae44eb64e975..80a6d09cf73dbfe7a596a9e5708cd1e2043ae4f7 100644 (file)
@@ -544,6 +544,12 @@ void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate)
 }
 EXPORT_SYMBOL_GPL(dw_hdmi_set_sample_rate);
 
+static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi, bool enable)
+{
+       hdmi_modb(hdmi, enable ? 0 : HDMI_MC_CLKDIS_AUDCLK_DISABLE,
+                 HDMI_MC_CLKDIS_AUDCLK_DISABLE, HDMI_MC_CLKDIS);
+}
+
 static void dw_hdmi_ahb_audio_enable(struct dw_hdmi *hdmi)
 {
        hdmi_set_cts_n(hdmi, hdmi->audio_cts, hdmi->audio_n);
@@ -557,6 +563,12 @@ static void dw_hdmi_ahb_audio_disable(struct dw_hdmi *hdmi)
 static void dw_hdmi_i2s_audio_enable(struct dw_hdmi *hdmi)
 {
        hdmi_set_cts_n(hdmi, hdmi->audio_cts, hdmi->audio_n);
+       hdmi_enable_audio_clk(hdmi, true);
+}
+
+static void dw_hdmi_i2s_audio_disable(struct dw_hdmi *hdmi)
+{
+       hdmi_enable_audio_clk(hdmi, false);
 }
 
 void dw_hdmi_audio_enable(struct dw_hdmi *hdmi)
@@ -1592,11 +1604,6 @@ static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
                            HDMI_MC_FLOWCTRL);
 }
 
-static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi)
-{
-       hdmi_modb(hdmi, 0, HDMI_MC_CLKDIS_AUDCLK_DISABLE, HDMI_MC_CLKDIS);
-}
-
 /* Workaround to clear the overflow condition */
 static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi)
 {
@@ -1710,7 +1717,7 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
 
                /* HDMI Initialization Step E - Configure audio */
                hdmi_clk_regenerator_update_pixel_clock(hdmi);
-               hdmi_enable_audio_clk(hdmi);
+               hdmi_enable_audio_clk(hdmi, true);
        }
 
        /* not for DVI mode */
@@ -2422,6 +2429,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
                audio.write     = hdmi_writeb;
                audio.read      = hdmi_readb;
                hdmi->enable_audio = dw_hdmi_i2s_audio_enable;
+               hdmi->disable_audio = dw_hdmi_i2s_audio_disable;
 
                pdevinfo.name = "dw-hdmi-i2s-audio";
                pdevinfo.data = &audio;