@@ -139,6 +139,7 @@ struct imx_hdmi {
struct regmap *regmap;
struct i2c_adapter *ddc;
+ bool hpd_unreliable;
void __iomem *regs;
unsigned int sample_rate;
@@ -1309,6 +1310,14 @@ static int imx_hdmi_setup(struct imx_hdmi *hdmi, struct drm_display_mode *mode)
/* Wait until we are registered to enable interrupts */
static int imx_hdmi_fb_registered(struct imx_hdmi *hdmi)
{
+ int stat_bit = HDMI_IH_PHY_STAT0_HPD;
+ int mask_bits = ~HDMI_PHY_HPD;
+
+ if (hdmi->hpd_unreliable) {
+ stat_bit = HDMI_IH_PHY_STAT0_RX_SENSE0;
+ mask_bits = ~HDMI_PHY_RX_SENSE0;
+ }
+
hdmi_writeb(hdmi, HDMI_PHY_I2CM_INT_ADDR_DONE_POL,
HDMI_PHY_I2CM_INT_ADDR);
@@ -1317,10 +1326,10 @@ static int imx_hdmi_fb_registered(struct imx_hdmi *hdmi)
HDMI_PHY_I2CM_CTLINT_ADDR);
/* enable cable hot plug irq */
- hdmi_writeb(hdmi, (u8)~HDMI_PHY_RX_SENSE0, HDMI_PHY_MASK0);
+ hdmi_writeb(hdmi, (u8)mask_bits, HDMI_PHY_MASK0);
/* Clear Hotplug interrupts */
- hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_RX_SENSE0, HDMI_IH_PHY_STAT0);
+ hdmi_writeb(hdmi, stat_bit, HDMI_IH_PHY_STAT0);
return 0;
}
@@ -1524,25 +1533,32 @@ static irqreturn_t imx_hdmi_hardirq(int irq, void *dev_id)
static irqreturn_t imx_hdmi_irq(int irq, void *dev_id)
{
struct imx_hdmi *hdmi = dev_id;
+ int stat_bit = HDMI_IH_PHY_STAT0_HPD;
+ int pol_bit = HDMI_PHY_HPD;
u8 intr_stat;
u8 phy_int_pol;
+ if (hdmi->hpd_unreliable) {
+ stat_bit = HDMI_IH_PHY_STAT0_RX_SENSE0;
+ pol_bit = HDMI_PHY_RX_SENSE0;
+ }
+
intr_stat = hdmi_readb(hdmi, HDMI_IH_PHY_STAT0);
phy_int_pol = hdmi_readb(hdmi, HDMI_PHY_POL0);
- if (intr_stat & HDMI_IH_PHY_STAT0_RX_SENSE0) {
- if (phy_int_pol & HDMI_PHY_RX_SENSE0) {
+ if (intr_stat & stat_bit) {
+ if (phy_int_pol & pol_bit) {
dev_dbg(hdmi->dev, "EVENT=plugin\n");
- hdmi_modb(hdmi, 0, HDMI_PHY_RX_SENSE0, HDMI_PHY_POL0);
+ hdmi_modb(hdmi, 0, pol_bit, HDMI_PHY_POL0);
hdmi->connector_status = connector_status_connected;
imx_hdmi_poweron(hdmi);
} else {
dev_dbg(hdmi->dev, "EVENT=plugout\n");
- hdmi_modb(hdmi, HDMI_PHY_RX_SENSE0, HDMI_PHY_RX_SENSE0, HDMI_PHY_POL0);
+ hdmi_modb(hdmi, pol_bit, pol_bit, HDMI_PHY_POL0);
hdmi->connector_status = connector_status_disconnected;
imx_hdmi_poweroff(hdmi);
@@ -1551,7 +1567,7 @@ static irqreturn_t imx_hdmi_irq(int irq, void *dev_id)
}
hdmi_writeb(hdmi, intr_stat, HDMI_IH_PHY_STAT0);
- hdmi_writeb(hdmi, ~HDMI_IH_PHY_STAT0_RX_SENSE0, HDMI_IH_MUTE_PHY_STAT0);
+ hdmi_writeb(hdmi, ~stat_bit, HDMI_IH_MUTE_PHY_STAT0);
return IRQ_HANDLED;
}
@@ -1611,6 +1627,7 @@ static int imx_hdmi_bind(struct device *dev, struct device *master, void *data)
struct device_node *ddc_node;
struct imx_hdmi *hdmi;
struct resource *iores;
+ int pol_bit, stat_bit;
int ret, irq;
hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
@@ -1703,14 +1720,22 @@ static int imx_hdmi_bind(struct device *dev, struct device *master, void *data)
*/
hdmi_init_clk_regenerator(hdmi);
+ pol_bit = HDMI_PHY_HPD;
+ stat_bit = HDMI_IH_PHY_STAT0_HPD;
+ hdmi->hpd_unreliable = of_property_read_bool(np, "hpd-unreliable");
+ if (hdmi->hpd_unreliable) {
+ pol_bit = HDMI_PHY_RX_SENSE0;
+ stat_bit = HDMI_IH_PHY_STAT0_RX_SENSE0;
+ }
+
/*
* Configure registers related to HDMI interrupt
* generation before registering IRQ.
*/
- hdmi_writeb(hdmi, HDMI_PHY_RX_SENSE0, HDMI_PHY_POL0);
+ hdmi_writeb(hdmi, pol_bit, HDMI_PHY_POL0);
/* Clear Hotplug interrupts */
- hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_RX_SENSE0, HDMI_IH_PHY_STAT0);
+ hdmi_writeb(hdmi, stat_bit, HDMI_IH_PHY_STAT0);
ret = imx_hdmi_fb_registered(hdmi);
if (ret)
@@ -1721,7 +1746,7 @@ static int imx_hdmi_bind(struct device *dev, struct device *master, void *data)
goto err_iahb;
/* Unmute interrupts */
- hdmi_writeb(hdmi, ~HDMI_IH_PHY_STAT0_RX_SENSE0, HDMI_IH_MUTE_PHY_STAT0);
+ hdmi_writeb(hdmi, ~stat_bit, HDMI_IH_MUTE_PHY_STAT0);
ret = snd_dw_hdmi_probe(&hdmi->audio, dev, hdmi->regs, irq, hdmi);
if (ret)