drm: tda998x: Fix a couple of problems
Subsystems (2)
cover drm: tda998x: Fix a couple of problems
1)
The HDMI registers of the tda998x chips are accessed by pages. As these HDMI registers may be accessed from different tasks (video, irq/workqueue, and soon audio), the page register setting must be protected.
2)
On HDMI reconnect (cable plug-in), the EDID is read too early and this raises a EDID read timeout. Delaying a bit the connect event fixes the problem.
Jean-Francois Moine (2):
drm: tda998x: Protect the page register
drm: tda998x: Fix EDID read timeout on HDMI connect
drivers/gpu/drm/i2c/tda998x_drv.c | 47 +++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 9 deletions(-)
Signature · 6 lines
2.1.3 _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH 1/2 drm: tda998x: Protect the page register
As the HDMI registers of the TDA998x chips are accessed by pages, the page register must be protected.
--- drivers/gpu/drm/i2c/tda998x_drv.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-)
drivers/gpu/drm/i2c/tda998x_drv.c +20 -5
@@ -32,6 +32,7 @@struct tda998x_priv {struct i2c_client *cec;struct i2c_client *hdmi; +struct mutex mutex;uint16_t rev;uint8_t current_page;int dpms;
@@ -402,9 +403,10 @@ reg_read_range(struct tda998x_priv *priv, uint16_t reg, char *buf, int cnt)uint8_t addr =REG2ADDR (reg);int ret; +mutex_lock (&priv->mutex); ret =set_page (priv, reg);if (ret <0 ) -return ret; + goto out; ret =i2c_master_send (client, &addr,sizeof (addr));if (ret <0 )
@@ -414,10 +416,12 @@ reg_read_range(struct tda998x_priv *priv, uint16_t reg, char *buf, int cnt)if (ret <0 ) goto fail; -return ret; + goto out; fail:dev_err (&client->dev,"Error %d reading from 0x%x\n" , ret, reg); +out: +mutex_unlock (&priv->mutex);return ret; }
@@ -431,13 +435,16 @@ reg_write_range(struct tda998x_priv *priv, uint16_t reg, uint8_t *p, int cnt) buf[0 ] =REG2ADDR (reg);memcpy (&buf[1 ], p, cnt); +mutex_lock (&priv->mutex); ret =set_page (priv, reg);if (ret <0 ) -return ; + goto out; ret =i2c_master_send (client, buf, cnt +1 );if (ret <0 )dev_err (&client->dev,"Error %d writing to 0x%x\n" , ret, reg); +out: +mutex_unlock (&priv->mutex); } static int
@@ -459,13 +466,16 @@ reg_write(struct tda998x_priv *priv, uint16_t reg, uint8_t val)uint8_t buf[] = {REG2ADDR (reg), val};int ret; +mutex_lock (&priv->mutex); ret =set_page (priv, reg);if (ret <0 ) -return ; + goto out; ret =i2c_master_send (client, buf,sizeof (buf));if (ret <0 )dev_err (&client->dev,"Error %d writing to 0x%x\n" , ret, reg); +out: +mutex_unlock (&priv->mutex); } static void
@@ -475,13 +485,16 @@ reg_write16(struct tda998x_priv *priv, uint16_t reg, uint16_t val)uint8_t buf[] = {REG2ADDR (reg), val >>8 , val};int ret; +mutex_lock (&priv->mutex); ret =set_page (priv, reg);if (ret <0 ) -return ; + goto out; ret =i2c_master_send (client, buf,sizeof (buf));if (ret <0 )dev_err (&client->dev,"Error %d writing to 0x%x\n" , ret, reg); +out: +mutex_unlock (&priv->mutex); } static void
@@ -1268,6 +1281,8 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) priv->dpms =DRM_MODE_DPMS_OFF ; +mutex_init (&priv->mutex);/* protect the page access */ +/* wake up the device: */ cec_write (priv,REG_CEC_ENAMODS ,CEC_ENAMODS_EN_RXSENS |CEC_ENAMODS_EN_HDMI );
Signature · 6 lines
2.1.3 _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH 2/2 drm: tda998x: Fix EDID read timeout on HDMI connect
In reply to Jean-Francois MoineWhen the HDMI cable is disconnected and reconnected, EDID reading is called too early raising a EDID read timeout.
This patch uses the system work queue to delay the notification of the HDMI connect/disconnect event.
--- drivers/gpu/drm/i2c/tda998x_drv.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-)
drivers/gpu/drm/i2c/tda998x_drv.c +18 -4
@@ -33,6 +33,7 @@ struct tda998x_priv {struct i2c_client *cec;struct i2c_client *hdmi;struct mutex mutex; +struct delayed_work dwork;uint16_t rev;uint8_t current_page;int dpms;
@@ -549,6 +550,17 @@ tda998x_reset(struct tda998x_priv *priv)reg_write (priv,REG_MUX_VP_VIP_OUT ,0x24 ); } +/* handle HDMI connect/disconnect */ +static void tda998x_hpd (struct work_struct *work) +{ +struct delayed_work *dwork =to_delayed_work (work); +struct tda998x_priv *priv = + container_of(dwork, struct tda998x_priv, dwork); + +if (priv->encoder && priv->encoder->dev) +drm_kms_helper_hotplug_event (priv->encoder->dev); +} +/* * only 2 interrupts may occur: screen plug/unplug and EDID read */
@@ -572,8 +584,7 @@ static irqreturn_t tda998x_irq_thread(int irq, void *data) priv->wq_edid_wait =0 ;wake_up (&priv->wq_edid); }else if (cec !=0 ) {/* HPD change */ -if (priv->encoder && priv->encoder->dev) -drm_helper_hpd_irq_event (priv->encoder->dev); +schedule_delayed_work (&priv->dwork,HZ /10 ); }return IRQ_HANDLED ; }
@@ -1183,8 +1194,10 @@ static void tda998x_destroy(struct tda998x_priv *priv)/* disable all IRQs and free the IRQ handler */ cec_write (priv,REG_CEC_RXSHPDINTENA ,0 );reg_clear (priv,REG_INT_FLAGS_2 ,INT_FLAGS_2_EDID_BLK_RD ); -if (priv->hdmi->irq) +if (priv->hdmi->irq) {free_irq (priv->hdmi->irq, priv); +cancel_delayed_work_sync (&priv->dwork); + }i2c_unregister_device (priv->cec); }
@@ -1338,8 +1351,9 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv)if (client->irq) {int irqf_trigger; -/* init read EDID waitqueue */ +/* init read EDID waitqueue and HDP work */ init_waitqueue_head (&priv->wq_edid); +INIT_DELAYED_WORK (&priv->dwork, tda998x_hpd);/* clear pending interrupts */ reg_read (priv,REG_INT_FLAGS_0 );
Signature · 6 lines
2.1.3 _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-devel
Quoted 10 lines · Jean-Francois Moine
1)
The HDMI registers of the tda998x chips are accessed by pages. As these HDMI registers may be accessed from different tasks (video, irq/workqueue, and soon audio), the page register setting must be protected.2)
On HDMI reconnect (cable plug-in), the EDID is read too early and this raises a EDID read timeout. Delaying a bit the connect event fixes the problem.
Both patches applied, thanks.
Signature · 6 lines
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up according to speedtest.net. _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-devel