diff options
author | Michal Wilczynski <m.wilczynski@samsung.com> | 2024-05-27 15:04:59 +0200 |
---|---|---|
committer | Michal Wilczynski <m.wilczynski@samsung.com> | 2024-05-27 15:06:34 +0200 |
commit | 6034b259abd6fe6472ffb0e0890a3a0b8f266d68 (patch) | |
tree | 33a24c19d0705fe5cdedad137ac6fbb8600dadf9 | |
parent | 80bd8940f3c9698b648a82706ba7043c9a044d79 (diff) | |
download | linux-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.c | 44 | ||||
-rw-r--r-- | include/drm/bridge/dw_hdmi.h | 5 |
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, |