summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorRomain Perier <romain.perier@collabora.com>2017-04-14 10:31:12 +0200
committerZheng Yang <zhengyang@rock-chips.com>2019-02-25 17:21:12 +0800
commit74e95498c458cf048ef6ab4cff79eb3c1d12a138 (patch)
tree451322f96f3b3e7c9c0f34fd8e0af226eef78704 /drivers/gpu
parent22e601b986de96b6c1ac481e852f5b1b030a7b0f (diff)
UPSTREAM: drm: dw-hdmi: add specific I2S and AHB functions for stream handling
Currently, CTS+N is forced to zero as a workaround of the IP block for i.MX platforms. This is requested in the datasheet of the corresponding IP for AHB mode only. However, we have seen that it introduces glitches or delays when playing a sound on HDMI for I2S mode. This proves that we cannot keep the current functions for handling audio stream as-is if these contain workaround that are specific to a mode. This commit introduces two callbacks, one for each variant. dw_hdmi_setup defines the right function depending on the detected variant. Then, the exported functions dw_hdmi_audio_enable and dw_hdmi_audio_disable calls the corresponding callbacks Reviewed-by: Neil Armstrong <narmstrong@baylibre.com> Signed-off-by: Romain Perier <romain.perier@collabora.com> Signed-off-by: Archit Taneja <architt@codeaurora.org> Link: http://patchwork.freedesktop.org/patch/msgid/20170414083113.4255-2-romain.perier@collabora.com (cherry picked from commit a7d555d2f2bd675d641e742a202a5e4b37d4d019) Change-Id: Ie988cdd7ab54466fa01135ae940ce0d2c27431d2 Signed-off-by: Zheng Yang <zhengyang@rock-chips.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-hdmi.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 68d998526071..e59947a3a0fe 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -261,6 +261,8 @@ struct dw_hdmi {
void (*write)(struct dw_hdmi *hdmi, u8 val, int offset);
u8 (*read)(struct dw_hdmi *hdmi, int offset);
+ void (*enable_audio)(struct dw_hdmi *hdmi);
+ void (*disable_audio)(struct dw_hdmi *hdmi);
bool initialized; /* hdmi is enabled before bind */
};
@@ -821,13 +823,29 @@ void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate)
}
EXPORT_SYMBOL_GPL(dw_hdmi_set_sample_rate);
+static void dw_hdmi_ahb_audio_enable(struct dw_hdmi *hdmi)
+{
+ hdmi_set_cts_n(hdmi, hdmi->audio_cts, hdmi->audio_n);
+}
+
+static void dw_hdmi_ahb_audio_disable(struct dw_hdmi *hdmi)
+{
+ hdmi_set_cts_n(hdmi, hdmi->audio_cts, 0);
+}
+
+static void dw_hdmi_i2s_audio_enable(struct dw_hdmi *hdmi)
+{
+ hdmi_set_cts_n(hdmi, hdmi->audio_cts, hdmi->audio_n);
+}
+
void dw_hdmi_audio_enable(struct dw_hdmi *hdmi)
{
unsigned long flags;
spin_lock_irqsave(&hdmi->audio_lock, flags);
hdmi->audio_enable = true;
- hdmi_set_cts_n(hdmi, hdmi->audio_cts, hdmi->audio_n);
+ if (hdmi->enable_audio)
+ hdmi->enable_audio(hdmi);
spin_unlock_irqrestore(&hdmi->audio_lock, flags);
}
EXPORT_SYMBOL_GPL(dw_hdmi_audio_enable);
@@ -838,7 +856,8 @@ void dw_hdmi_audio_disable(struct dw_hdmi *hdmi)
spin_lock_irqsave(&hdmi->audio_lock, flags);
hdmi->audio_enable = false;
- hdmi_set_cts_n(hdmi, hdmi->audio_cts, 0);
+ if (hdmi->disable_audio)
+ hdmi->disable_audio(hdmi);
spin_unlock_irqrestore(&hdmi->audio_lock, flags);
}
EXPORT_SYMBOL_GPL(dw_hdmi_audio_disable);
@@ -3716,6 +3735,8 @@ int dw_hdmi_bind(struct device *dev, struct device *master,
audio.irq = irq;
audio.hdmi = hdmi;
audio.eld = hdmi->connector.eld;
+ hdmi->enable_audio = dw_hdmi_ahb_audio_enable;
+ hdmi->disable_audio = dw_hdmi_ahb_audio_disable;
pdevinfo.name = "dw-hdmi-ahb-audio";
pdevinfo.data = &audio;
@@ -3729,6 +3750,7 @@ int dw_hdmi_bind(struct device *dev, struct device *master,
audio.write = hdmi_writeb;
audio.read = hdmi_readb;
audio.mod = hdmi_modb;
+ hdmi->enable_audio = dw_hdmi_i2s_audio_enable;
pdevinfo.name = "dw-hdmi-i2s-audio";
pdevinfo.data = &audio;