diff options
| author | Robert Winkler <robert.winkler@boundarydevices.com> | 2013-07-19 19:00:41 -0700 | 
|---|---|---|
| committer | Robert Winkler <robert.winkler@boundarydevices.com> | 2013-07-19 19:05:16 -0700 | 
| commit | 7d8752905c118af9063738a533227de0b2f6ecd4 (patch) | |
| tree | 3f6cf636efc2477f87fb45d7648b6a430a72058d | |
| parent | 9a25a3684e15951a570896f14936bd65e5b05d2f (diff) | |
Add support for DVI monitors3.0-boundary-imx6-3.0.35-4.0.0-ts1
Signed-off-by: Robert Winkler <robert.winkler@boundarydevices.com>
| -rw-r--r-- | arch/arm/plat-mxc/include/mach/mxc_hdmi.h | 7 | ||||
| -rw-r--r-- | drivers/video/mxc_hdmi.c | 100 | 
2 files changed, 50 insertions, 57 deletions
| diff --git a/arch/arm/plat-mxc/include/mach/mxc_hdmi.h b/arch/arm/plat-mxc/include/mach/mxc_hdmi.h index 60946cadc441..8a7b991a669d 100644 --- a/arch/arm/plat-mxc/include/mach/mxc_hdmi.h +++ b/arch/arm/plat-mxc/include/mach/mxc_hdmi.h @@ -605,6 +605,10 @@ enum {  	HDMI_IH_MUTE_PHY_STAT0_TX_PHY_LOCK = 0x2,  	HDMI_IH_MUTE_PHY_STAT0_HPD = 0x1, +/* IH and IH_MUTE convenience macro RX_SENSE | HPD*/ +	HDMI_DVI_IH_STAT = 0x3D, + +  /* IH_AHBDMAAUD_STAT0 field values */  	HDMI_IH_AHBDMAAUD_STAT0_ERROR = 0x20,  	HDMI_IH_AHBDMAAUD_STAT0_LOST = 0x10, @@ -903,6 +907,9 @@ enum {  	HDMI_PHY_HPD = 0x02,  	HDMI_PHY_TX_PHY_LOCK = 0x01, +/* HDMI STAT convenience RX_SENSE | HPD */ +	HDMI_DVI_STAT = 0xF2, +  /* PHY_I2CM_SLAVE_ADDR field values */  	HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2 = 0x69,  	HDMI_PHY_I2CM_SLAVE_ADDR_HEAC_PHY = 0x49, diff --git a/drivers/video/mxc_hdmi.c b/drivers/video/mxc_hdmi.c index d38ac10b76ae..68f845093e2a 100644 --- a/drivers/video/mxc_hdmi.c +++ b/drivers/video/mxc_hdmi.c @@ -178,7 +178,6 @@ struct mxc_hdmi {  	bool dft_mode_set;  	char *dft_mode_str;  	int default_bpp; -	u8 latest_intr_stat;  	bool irq_enabled;  	spinlock_t irq_lock;  	bool phy_enabled; @@ -1784,58 +1783,48 @@ static void hotplug_worker(struct work_struct *work)  	struct delayed_work *delay_work = to_delayed_work(work);  	struct mxc_hdmi *hdmi =  		container_of(delay_work, struct mxc_hdmi, hotplug_work); -	u32 phy_int_stat, phy_int_pol, phy_int_mask; -	u8 val; +	u32 hdmi_phy_stat0, hdmi_phy_pol0, hdmi_phy_mask0;  	unsigned long flags;  	char event_string[16];  	char *envp[] = { event_string, NULL }; -	phy_int_stat = hdmi->latest_intr_stat; -	phy_int_pol = hdmi_readb(HDMI_PHY_POL0); -	dev_dbg(&hdmi->pdev->dev, "phy_int_stat=0x%x, phy_int_pol=0x%x\n", -			phy_int_stat, phy_int_pol); +	hdmi_phy_stat0 = hdmi_readb(HDMI_PHY_STAT0); +	hdmi_phy_pol0 = hdmi_readb(HDMI_PHY_POL0); + +	dev_dbg(&hdmi->pdev->dev, "hdmi_phy_stat0=0x%x, hdmi_phy_pol0=0x%x\n", +			hdmi_phy_stat0, hdmi_phy_pol0); + +	/* Make HPD intr active low to capture unplug event or +	 * active high to capture plugin event */ +	hdmi_writeb((HDMI_DVI_STAT & ~hdmi_phy_stat0), HDMI_PHY_POL0);  	/* check cable status */ -	if (phy_int_stat & HDMI_IH_PHY_STAT0_HPD) { -		/* cable connection changes */ -		if (phy_int_pol & HDMI_PHY_HPD) { -			/* Plugin event */ -			dev_dbg(&hdmi->pdev->dev, "EVENT=plugin\n"); -			mxc_hdmi_cable_connected(hdmi); - -			/* Make HPD intr active low to capture unplug event */ -			val = hdmi_readb(HDMI_PHY_POL0); -			val &= ~HDMI_PHY_HPD; -			hdmi_writeb(val, HDMI_PHY_POL0); - -			sprintf(event_string, "EVENT=plugin"); -			kobject_uevent_env(&hdmi->pdev->dev.kobj, KOBJ_CHANGE, envp); +	if (hdmi_phy_stat0 & HDMI_DVI_STAT) { +		/* Plugin event */ +		dev_dbg(&hdmi->pdev->dev, "EVENT=plugin\n"); +		mxc_hdmi_cable_connected(hdmi); + +		sprintf(event_string, "EVENT=plugin"); +		kobject_uevent_env(&hdmi->pdev->dev.kobj, KOBJ_CHANGE, envp);  #ifdef CONFIG_MXC_HDMI_CEC -			mxc_hdmi_cec_handle(0x80); +		mxc_hdmi_cec_handle(0x80);  #endif -			hdmi_set_cable_state(1); - -		} else if (!(phy_int_pol & HDMI_PHY_HPD)) { -			/* Plugout event */ -			dev_dbg(&hdmi->pdev->dev, "EVENT=plugout\n"); -			hdmi_set_cable_state(0); -			mxc_hdmi_abort_stream(); -			mxc_hdmi_cable_disconnected(hdmi); +		hdmi_set_cable_state(1); -			/* Make HPD intr active high to capture plugin event */ -			val = hdmi_readb(HDMI_PHY_POL0); -			val |= HDMI_PHY_HPD; -			hdmi_writeb(val, HDMI_PHY_POL0); - -			sprintf(event_string, "EVENT=plugout"); -			kobject_uevent_env(&hdmi->pdev->dev.kobj, KOBJ_CHANGE, envp); +	} else { +		/* Plugout event */ +		dev_dbg(&hdmi->pdev->dev, "EVENT=plugout\n"); +		hdmi_set_cable_state(0); +		mxc_hdmi_abort_stream(); +		mxc_hdmi_cable_disconnected(hdmi); + +		sprintf(event_string, "EVENT=plugout"); +		kobject_uevent_env(&hdmi->pdev->dev.kobj, KOBJ_CHANGE, envp);  #ifdef CONFIG_MXC_HDMI_CEC -			mxc_hdmi_cec_handle(0x100); +		mxc_hdmi_cec_handle(0x100);  #endif -		} else -			dev_dbg(&hdmi->pdev->dev, "EVENT=none?\n");  	}  	/* Lock here to ensure full powerdown sequence @@ -1843,12 +1832,12 @@ static void hotplug_worker(struct work_struct *work)  	spin_lock_irqsave(&hdmi->irq_lock, flags);  	/* Re-enable HPD interrupts */ -	phy_int_mask = hdmi_readb(HDMI_PHY_MASK0); -	phy_int_mask &= ~HDMI_PHY_HPD; -	hdmi_writeb(phy_int_mask, HDMI_PHY_MASK0); +	hdmi_phy_mask0 = hdmi_readb(HDMI_PHY_MASK0); +	hdmi_phy_mask0 &= ~HDMI_DVI_STAT; +	hdmi_writeb(hdmi_phy_mask0, HDMI_PHY_MASK0);  	/* Unmute interrupts */ -	hdmi_writeb(~HDMI_IH_MUTE_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0); +	hdmi_writeb(~HDMI_DVI_IH_STAT, HDMI_IH_MUTE_PHY_STAT0);  	if (hdmi_readb(HDMI_IH_FC_STAT2) & HDMI_IH_FC_STAT2_OVERFLOW_MASK)  		mxc_hdmi_clear_overflow(); @@ -1859,7 +1848,7 @@ static void hotplug_worker(struct work_struct *work)  static irqreturn_t mxc_hdmi_hotplug(int irq, void *data)  {  	struct mxc_hdmi *hdmi = data; -	u8 val, intr_stat; +	u8 val;  	unsigned long flags;  	spin_lock_irqsave(&hdmi->irq_lock, flags); @@ -1881,25 +1870,22 @@ static irqreturn_t mxc_hdmi_hotplug(int irq, void *data)  	 * HDMI registers.  	 */  	/* Capture status - used in hotplug_worker ISR */ -	intr_stat = hdmi_readb(HDMI_IH_PHY_STAT0); - -	if (intr_stat & HDMI_IH_PHY_STAT0_HPD) { +	if (hdmi_readb(HDMI_IH_PHY_STAT0) & HDMI_DVI_IH_STAT) {  		dev_dbg(&hdmi->pdev->dev, "Hotplug interrupt received\n"); -		hdmi->latest_intr_stat = intr_stat;  		/* Mute interrupts until handled */  		val = hdmi_readb(HDMI_IH_MUTE_PHY_STAT0); -		val |= HDMI_IH_MUTE_PHY_STAT0_HPD; +		val |= HDMI_DVI_IH_STAT;  		hdmi_writeb(val, HDMI_IH_MUTE_PHY_STAT0);  		val = hdmi_readb(HDMI_PHY_MASK0); -		val |= HDMI_PHY_HPD; +		val |= HDMI_DVI_STAT;  		hdmi_writeb(val, HDMI_PHY_MASK0);  		/* Clear Hotplug interrupts */ -		hdmi_writeb(HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0); +		hdmi_writeb(HDMI_DVI_IH_STAT, HDMI_IH_PHY_STAT0);  		schedule_delayed_work(&(hdmi->hotplug_work), msecs_to_jiffies(20));  	} @@ -2059,13 +2045,13 @@ static void mxc_hdmi_fb_registered(struct mxc_hdmi *hdmi)  		    HDMI_PHY_I2CM_CTLINT_ADDR);  	/* enable cable hot plug irq */ -	hdmi_writeb((u8)~HDMI_PHY_HPD, HDMI_PHY_MASK0); +	hdmi_writeb((u8)~HDMI_DVI_STAT, HDMI_PHY_MASK0);  	/* Clear Hotplug interrupts */ -	hdmi_writeb(HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0); +	hdmi_writeb(HDMI_DVI_IH_STAT, HDMI_IH_PHY_STAT0);  	/* Unmute interrupts */ -	hdmi_writeb(~HDMI_IH_MUTE_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0); +	hdmi_writeb(~HDMI_DVI_IH_STAT, HDMI_IH_MUTE_PHY_STAT0);  	hdmi->fb_reg = true; @@ -2298,10 +2284,10 @@ static int mxc_hdmi_disp_init(struct mxc_dispdrv_handle *disp,  	/* Configure registers related to HDMI interrupt  	 * generation before registering IRQ. */ -	hdmi_writeb(HDMI_PHY_HPD, HDMI_PHY_POL0); +	hdmi_writeb(HDMI_DVI_STAT, HDMI_PHY_POL0);  	/* Clear Hotplug interrupts */ -	hdmi_writeb(HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0); +	hdmi_writeb(HDMI_DVI_IH_STAT, HDMI_IH_PHY_STAT0);  	hdmi->nb.notifier_call = mxc_hdmi_fb_event;  	ret = fb_register_client(&hdmi->nb); | 
