#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>
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;
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);
}
* 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,
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 |
hdmi_writeb(hdmi, HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS,
HDMI_MC_FLOWCTRL);
}
+#endif
}
/* Workaround to clear the overflow condition */
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,
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;
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);
}
}
+ 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);
}
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>");