aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-hdmi.c48
-rw-r--r--include/drm/bridge/dw_hdmi.h2
2 files changed, 31 insertions, 19 deletions
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 3a6320108575..f6c89007d3bb 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -233,6 +233,13 @@ static void hdmi_mask_writeb(struct dw_hdmi *hdmi, u8 data, unsigned int reg,
static void dw_hdmi_i2c_init(struct dw_hdmi *hdmi)
{
+ hdmi_writeb(hdmi, HDMI_PHY_I2CM_INT_ADDR_DONE_POL,
+ HDMI_PHY_I2CM_INT_ADDR);
+
+ hdmi_writeb(hdmi, HDMI_PHY_I2CM_CTLINT_ADDR_NAC_POL |
+ HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_POL,
+ HDMI_PHY_I2CM_CTLINT_ADDR);
+
/* Software reset */
hdmi_writeb(hdmi, 0x00, HDMI_I2CM_SOFTRSTZ);
@@ -1994,16 +2001,6 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
return 0;
}
-static void dw_hdmi_setup_i2c(struct dw_hdmi *hdmi)
-{
- hdmi_writeb(hdmi, HDMI_PHY_I2CM_INT_ADDR_DONE_POL,
- HDMI_PHY_I2CM_INT_ADDR);
-
- hdmi_writeb(hdmi, HDMI_PHY_I2CM_CTLINT_ADDR_NAC_POL |
- HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_POL,
- HDMI_PHY_I2CM_CTLINT_ADDR);
-}
-
static void initialize_hdmi_ih_mutes(struct dw_hdmi *hdmi)
{
u8 ih_mute;
@@ -2504,6 +2501,21 @@ static const struct regmap_config hdmi_regmap_32bit_config = {
.max_register = HDMI_I2CM_FS_SCL_LCNT_0_ADDR << 2,
};
+static void dw_hdmi_init_hw(struct dw_hdmi *hdmi)
+{
+ initialize_hdmi_ih_mutes(hdmi);
+
+ /*
+ * Reset HDMI DDC I2C master controller and mute I2CM interrupts.
+ * Even if we are using a separate i2c adapter doing this doesn't
+ * hurt.
+ */
+ dw_hdmi_i2c_init(hdmi);
+
+ if (hdmi->phy.ops->setup_hpd)
+ hdmi->phy.ops->setup_hpd(hdmi, hdmi->phy.data);
+}
+
static struct dw_hdmi *
__dw_hdmi_probe(struct platform_device *pdev,
const struct dw_hdmi_plat_data *plat_data)
@@ -2655,7 +2667,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
prod_id1 & HDMI_PRODUCT_ID1_HDCP ? "with" : "without",
hdmi->phy.name);
- initialize_hdmi_ih_mutes(hdmi);
+ dw_hdmi_init_hw(hdmi);
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
@@ -2712,10 +2724,6 @@ __dw_hdmi_probe(struct platform_device *pdev,
hdmi->bridge.of_node = pdev->dev.of_node;
#endif
- dw_hdmi_setup_i2c(hdmi);
- if (hdmi->phy.ops->setup_hpd)
- hdmi->phy.ops->setup_hpd(hdmi, hdmi->phy.data);
-
memset(&pdevinfo, 0, sizeof(pdevinfo));
pdevinfo.parent = dev;
pdevinfo.id = PLATFORM_DEVID_AUTO;
@@ -2768,10 +2776,6 @@ __dw_hdmi_probe(struct platform_device *pdev,
hdmi->cec = platform_device_register_full(&pdevinfo);
}
- /* Reset HDMI DDC I2C master controller and mute I2CM interrupts */
- if (hdmi->i2c)
- dw_hdmi_i2c_init(hdmi);
-
return hdmi;
err_iahb:
@@ -2875,6 +2879,12 @@ void dw_hdmi_unbind(struct dw_hdmi *hdmi)
}
EXPORT_SYMBOL_GPL(dw_hdmi_unbind);
+void dw_hdmi_resume(struct dw_hdmi *hdmi)
+{
+ dw_hdmi_init_hw(hdmi);
+}
+EXPORT_SYMBOL_GPL(dw_hdmi_resume);
+
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 66e70770cce5..601243b56b69 100644
--- a/include/drm/bridge/dw_hdmi.h
+++ b/include/drm/bridge/dw_hdmi.h
@@ -154,6 +154,8 @@ struct dw_hdmi *dw_hdmi_bind(struct platform_device *pdev,
struct drm_encoder *encoder,
const struct dw_hdmi_plat_data *plat_data);
+void dw_hdmi_resume(struct dw_hdmi *hdmi);
+
void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense);
void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate);