summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Wilczynski <m.wilczynski@samsung.com>2024-05-27 15:04:59 +0200
committerMichal Wilczynski <m.wilczynski@samsung.com>2024-05-27 15:06:34 +0200
commit6034b259abd6fe6472ffb0e0890a3a0b8f266d68 (patch)
tree33a24c19d0705fe5cdedad137ac6fbb8600dadf9
parent80bd8940f3c9698b648a82706ba7043c9a044d79 (diff)
downloadlinux-thead-6034b259abd6fe6472ffb0e0890a3a0b8f266d68.tar.gz
linux-thead-6034b259abd6fe6472ffb0e0890a3a0b8f266d68.tar.bz2
linux-thead-6034b259abd6fe6472ffb0e0890a3a0b8f266d68.zip
drm: bridge: synopsys: dw-hdmi: Enable LicheePi 4A dw-hdmi modifications
Unfortunately, besides adding it's own hdmi driver LicheePi4 also need some modifications to generic dw-hdmi driver. Enable them. Change-Id: I5c49d46fed5a8c1b57863404438ef0f1ff25d883 Signed-off-by: Michal Wilczynski <m.wilczynski@samsung.com>
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-hdmi.c44
-rw-r--r--include/drm/bridge/dw_hdmi.h5
2 files changed, 48 insertions, 1 deletions
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 6c1d79474505..4bd164202966 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -16,6 +16,7 @@
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/pinctrl/consumer.h>
+#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/dma-mapping.h>
#include <linux/spinlock.h>
@@ -140,6 +141,8 @@ struct dw_hdmi {
struct clk *isfr_clk;
struct clk *iahb_clk;
struct clk *cec_clk;
+ struct clk *pix_clk;
+ struct clk *i2s_clk;
struct dw_hdmi_i2c *i2c;
struct hdmi_data_info hdmi_data;
@@ -676,10 +679,12 @@ static void hdmi_set_clk_regenerator(struct dw_hdmi *hdmi,
cts = 0;
}
+ hdmi->audio_enable = true;
spin_lock_irq(&hdmi->audio_lock);
hdmi->audio_n = n;
hdmi->audio_cts = cts;
hdmi_set_cts_n(hdmi, cts, hdmi->audio_enable ? n : 0);
+ hdmi_writeb(hdmi, 0x4, HDMI_AUD_INPUTCLKFS);
spin_unlock_irq(&hdmi->audio_lock);
}
@@ -2096,6 +2101,7 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
* Source Devices compliant shall set the
* Source Version = 1.
*/
+ mdelay(60);
drm_scdc_readb(hdmi->ddc, SCDC_SINK_VERSION,
&bytes);
drm_scdc_writeb(hdmi->ddc, SCDC_SOURCE_VERSION,
@@ -2166,6 +2172,7 @@ static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
hdmi_writeb(hdmi, 0x21, HDMI_FC_CH2PREAM);
/* Enable pixel clock and tmds data path */
+#if 0
hdmi->mc_clkdis |= HDMI_MC_CLKDIS_HDCPCLK_DISABLE |
HDMI_MC_CLKDIS_CSCCLK_DISABLE |
HDMI_MC_CLKDIS_AUDCLK_DISABLE |
@@ -2191,6 +2198,7 @@ static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
hdmi_writeb(hdmi, HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS,
HDMI_MC_FLOWCTRL);
}
+#endif
}
/* Workaround to clear the overflow condition */
@@ -2952,6 +2960,7 @@ static void dw_hdmi_bridge_atomic_disable(struct drm_bridge *bridge,
dw_hdmi_update_phy_mask(hdmi);
handle_plugged_change(hdmi, false);
mutex_unlock(&hdmi->mutex);
+ pm_runtime_put(hdmi->dev);
}
static void dw_hdmi_bridge_atomic_enable(struct drm_bridge *bridge,
@@ -2964,6 +2973,7 @@ static void dw_hdmi_bridge_atomic_enable(struct drm_bridge *bridge,
connector = drm_atomic_get_new_connector_for_encoder(state,
bridge->encoder);
+ pm_runtime_get_sync(hdmi->dev);
mutex_lock(&hdmi->mutex);
hdmi->disabled = false;
hdmi->curr_conn = connector;
@@ -3362,7 +3372,7 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
hdmi->disabled = true;
hdmi->rxsense = true;
hdmi->phy_mask = (u8)~(HDMI_PHY_HPD | HDMI_PHY_RX_SENSE);
- hdmi->mc_clkdis = 0x7f;
+ hdmi->mc_clkdis = 0x0;
hdmi->last_connector_result = connector_status_disconnected;
mutex_init(&hdmi->mutex);
@@ -3467,6 +3477,20 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
}
}
+ hdmi->pix_clk = devm_clk_get(hdmi->dev, "pixclk");
+ if (IS_ERR(hdmi->pix_clk)) {
+ ret = PTR_ERR(hdmi->pix_clk);
+ dev_err(hdmi->dev, "Unable to get HDMI pix clk: %d\n", ret);
+ goto err_iahb;
+ }
+
+ hdmi->i2s_clk = devm_clk_get_optional(hdmi->dev, "i2s");
+ if (IS_ERR(hdmi->i2s_clk)) {
+ ret = PTR_ERR(hdmi->i2s_clk);
+ dev_err(hdmi->dev, "Unable to get HDMI i2s clk: %d\n", ret);
+ goto err_iahb;
+ }
+
/* Product and revision IDs */
hdmi->version = (hdmi_readb(hdmi, HDMI_DESIGN_ID) << 8)
| (hdmi_readb(hdmi, HDMI_REVISION_ID) << 0);
@@ -3691,6 +3715,24 @@ void dw_hdmi_resume(struct dw_hdmi *hdmi)
}
EXPORT_SYMBOL_GPL(dw_hdmi_resume);
+#ifdef CONFIG_PM
+int dw_hdmi_runtime_suspend(struct dw_hdmi *hdmi)
+{
+ clk_disable_unprepare(hdmi->pix_clk);
+ clk_disable_unprepare(hdmi->cec_clk);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(dw_hdmi_runtime_suspend);
+
+int dw_hdmi_runtime_resume(struct dw_hdmi *hdmi)
+{
+ clk_prepare_enable(hdmi->cec_clk);
+ clk_prepare_enable(hdmi->pix_clk);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(dw_hdmi_runtime_resume);
+#endif
+
MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
MODULE_AUTHOR("Andy Yan <andy.yan@rock-chips.com>");
MODULE_AUTHOR("Yakir Yang <ykk@rock-chips.com>");
diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
index 6a46baa0737c..30de0e07c2eb 100644
--- a/include/drm/bridge/dw_hdmi.h
+++ b/include/drm/bridge/dw_hdmi.h
@@ -174,6 +174,11 @@ struct dw_hdmi *dw_hdmi_bind(struct platform_device *pdev,
void dw_hdmi_resume(struct dw_hdmi *hdmi);
+#ifdef CONFIG_PM
+int dw_hdmi_runtime_suspend(struct dw_hdmi *hdmi);
+int dw_hdmi_runtime_resume(struct dw_hdmi *hdmi);
+#endif
+
void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense);
int dw_hdmi_set_plugged_cb(struct dw_hdmi *hdmi, hdmi_codec_plugged_cb fn,