* [PATCH v2 0/7] tda998x: allow use with bridge based devices @ 2018-07-30 16:41 ` Russell King - ARM Linux 0 siblings, 0 replies; 80+ messages in thread From: Russell King - ARM Linux @ 2018-07-30 16:41 UTC (permalink / raw) To: linux-arm-kernel Hi, This is a re-posting of the series I responded to Peter Rosin's May posting, with a few bugs fixed, and the bridge registered outside of the component helper. This should allow Peter to use the driver while maintaining armada drm and tilcdc support. No comments (other than 0-day test results) were received on the previous posting. This is independent of the component helper vs bridge safety issues. drivers/gpu/drm/i2c/tda998x_drv.c | 288 ++++++++++++++++++++------------------ 1 file changed, 151 insertions(+), 137 deletions(-) -- RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line in suburbia: sync at 13.8Mbps down 630kbps up According to speedtest.net: 13Mbps down 490kbps up ^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH v2 0/7] tda998x: allow use with bridge based devices @ 2018-07-30 16:41 ` Russell King - ARM Linux 0 siblings, 0 replies; 80+ messages in thread From: Russell King - ARM Linux @ 2018-07-30 16:41 UTC (permalink / raw) To: dri-devel, linux-arm-kernel Cc: David Airlie, Tomi Valkeinen, Liviu Dudau, Peter Rosin, Jyri Sarha Hi, This is a re-posting of the series I responded to Peter Rosin's May posting, with a few bugs fixed, and the bridge registered outside of the component helper. This should allow Peter to use the driver while maintaining armada drm and tilcdc support. No comments (other than 0-day test results) were received on the previous posting. This is independent of the component helper vs bridge safety issues. drivers/gpu/drm/i2c/tda998x_drv.c | 288 ++++++++++++++++++++------------------ 1 file changed, 151 insertions(+), 137 deletions(-) -- RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line in suburbia: sync at 13.8Mbps down 630kbps up According to speedtest.net: 13Mbps down 490kbps up ^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH v2 1/7] drm/i2c: tda998x: find the drm_device via the drm_connector 2018-07-30 16:41 ` Russell King - ARM Linux @ 2018-07-30 16:42 ` Russell King -1 siblings, 0 replies; 80+ messages in thread From: Russell King @ 2018-07-30 16:42 UTC (permalink / raw) To: linux-arm-kernel From: Peter Rosin <peda@axentia.se> This prepares for being a drm_bridge which will not register the encoder. That makes the connector the better choice. Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Peter Rosin <peda@axentia.se> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> --- drivers/gpu/drm/i2c/tda998x_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index c3ebb9c4fc26..b05f54c8585b 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -753,7 +753,7 @@ static void tda998x_detect_work(struct work_struct *work) { struct tda998x_priv *priv = container_of(work, struct tda998x_priv, detect_work); - struct drm_device *dev = priv->encoder.dev; + struct drm_device *dev = priv->connector.dev; if (dev) drm_kms_helper_hotplug_event(dev); -- 2.7.4 ^ permalink raw reply related [flat|nested] 80+ messages in thread
* [PATCH v2 1/7] drm/i2c: tda998x: find the drm_device via the drm_connector @ 2018-07-30 16:42 ` Russell King 0 siblings, 0 replies; 80+ messages in thread From: Russell King @ 2018-07-30 16:42 UTC (permalink / raw) To: dri-devel, linux-arm-kernel Cc: David Airlie, Tomi Valkeinen, Liviu Dudau, Peter Rosin, Jyri Sarha From: Peter Rosin <peda@axentia.se> This prepares for being a drm_bridge which will not register the encoder. That makes the connector the better choice. Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Peter Rosin <peda@axentia.se> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> --- drivers/gpu/drm/i2c/tda998x_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index c3ebb9c4fc26..b05f54c8585b 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -753,7 +753,7 @@ static void tda998x_detect_work(struct work_struct *work) { struct tda998x_priv *priv = container_of(work, struct tda998x_priv, detect_work); - struct drm_device *dev = priv->encoder.dev; + struct drm_device *dev = priv->connector.dev; if (dev) drm_kms_helper_hotplug_event(dev); -- 2.7.4 ^ permalink raw reply related [flat|nested] 80+ messages in thread
* [PATCH v2 2/7] drm/i2c: tda998x: split tda998x_encoder_dpms into enable/disable 2018-07-30 16:41 ` Russell King - ARM Linux @ 2018-07-30 16:42 ` Russell King -1 siblings, 0 replies; 80+ messages in thread From: Russell King @ 2018-07-30 16:42 UTC (permalink / raw) To: linux-arm-kernel From: Peter Rosin <peda@axentia.se> This fits better with the drm_bridge callbacks for when this driver becomes a drm_bridge. Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Peter Rosin <peda@axentia.se> [edited by rmk to just split the tda998x_encoder_dpms() function and restore the double-disable protection we originally had, preserving original behaviour.] Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> --- drivers/gpu/drm/i2c/tda998x_drv.c | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index b05f54c8585b..1c2f5dac1886 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -1299,18 +1299,9 @@ static int tda998x_connector_init(struct tda998x_priv *priv, /* DRM encoder functions */ -static void tda998x_encoder_dpms(struct drm_encoder *encoder, int mode) +static void tda998x_enable(struct tda998x_priv *priv) { - struct tda998x_priv *priv = enc_to_tda998x_priv(encoder); - bool on; - - /* we only care about on or off: */ - on = mode == DRM_MODE_DPMS_ON; - - if (on == priv->is_on) - return; - - if (on) { + if (!priv->is_on) { /* enable video ports, audio will be enabled later */ reg_write(priv, REG_ENA_VP_0, 0xff); reg_write(priv, REG_ENA_VP_1, 0xff); @@ -1321,7 +1312,12 @@ static void tda998x_encoder_dpms(struct drm_encoder *encoder, int mode) reg_write(priv, REG_VIP_CNTRL_2, priv->vip_cntrl_2); priv->is_on = true; - } else { + } +} + +static void tda998x_disable(struct tda998x_priv *priv) +{ + if (!priv->is_on) { /* disable video ports */ reg_write(priv, REG_ENA_VP_0, 0x00); reg_write(priv, REG_ENA_VP_1, 0x00); @@ -1331,6 +1327,23 @@ static void tda998x_encoder_dpms(struct drm_encoder *encoder, int mode) } } +static void tda998x_encoder_dpms(struct drm_encoder *encoder, int mode) +{ + struct tda998x_priv *priv = enc_to_tda998x_priv(encoder); + bool on; + + /* we only care about on or off: */ + on = mode == DRM_MODE_DPMS_ON; + + if (on == priv->is_on) + return; + + if (on) + tda998x_enable(priv); + else + tda998x_disable(priv); +} + static void tda998x_encoder_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, -- 2.7.4 ^ permalink raw reply related [flat|nested] 80+ messages in thread
* [PATCH v2 2/7] drm/i2c: tda998x: split tda998x_encoder_dpms into enable/disable @ 2018-07-30 16:42 ` Russell King 0 siblings, 0 replies; 80+ messages in thread From: Russell King @ 2018-07-30 16:42 UTC (permalink / raw) To: dri-devel, linux-arm-kernel Cc: David Airlie, Tomi Valkeinen, Liviu Dudau, Peter Rosin, Jyri Sarha From: Peter Rosin <peda@axentia.se> This fits better with the drm_bridge callbacks for when this driver becomes a drm_bridge. Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Peter Rosin <peda@axentia.se> [edited by rmk to just split the tda998x_encoder_dpms() function and restore the double-disable protection we originally had, preserving original behaviour.] Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> --- drivers/gpu/drm/i2c/tda998x_drv.c | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index b05f54c8585b..1c2f5dac1886 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -1299,18 +1299,9 @@ static int tda998x_connector_init(struct tda998x_priv *priv, /* DRM encoder functions */ -static void tda998x_encoder_dpms(struct drm_encoder *encoder, int mode) +static void tda998x_enable(struct tda998x_priv *priv) { - struct tda998x_priv *priv = enc_to_tda998x_priv(encoder); - bool on; - - /* we only care about on or off: */ - on = mode == DRM_MODE_DPMS_ON; - - if (on == priv->is_on) - return; - - if (on) { + if (!priv->is_on) { /* enable video ports, audio will be enabled later */ reg_write(priv, REG_ENA_VP_0, 0xff); reg_write(priv, REG_ENA_VP_1, 0xff); @@ -1321,7 +1312,12 @@ static void tda998x_encoder_dpms(struct drm_encoder *encoder, int mode) reg_write(priv, REG_VIP_CNTRL_2, priv->vip_cntrl_2); priv->is_on = true; - } else { + } +} + +static void tda998x_disable(struct tda998x_priv *priv) +{ + if (!priv->is_on) { /* disable video ports */ reg_write(priv, REG_ENA_VP_0, 0x00); reg_write(priv, REG_ENA_VP_1, 0x00); @@ -1331,6 +1327,23 @@ static void tda998x_encoder_dpms(struct drm_encoder *encoder, int mode) } } +static void tda998x_encoder_dpms(struct drm_encoder *encoder, int mode) +{ + struct tda998x_priv *priv = enc_to_tda998x_priv(encoder); + bool on; + + /* we only care about on or off: */ + on = mode == DRM_MODE_DPMS_ON; + + if (on == priv->is_on) + return; + + if (on) + tda998x_enable(priv); + else + tda998x_disable(priv); +} + static void tda998x_encoder_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, -- 2.7.4 ^ permalink raw reply related [flat|nested] 80+ messages in thread
* [PATCH v2 2/7] drm/i2c: tda998x: split tda998x_encoder_dpms into enable/disable 2018-07-30 16:42 ` Russell King @ 2018-07-31 5:46 ` Peter Rosin -1 siblings, 0 replies; 80+ messages in thread From: Peter Rosin @ 2018-07-31 5:46 UTC (permalink / raw) To: linux-arm-kernel On 2018-07-30 18:42, Russell King wrote: > From: Peter Rosin <peda@axentia.se> > > This fits better with the drm_bridge callbacks for when this > driver becomes a drm_bridge. > > Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> > Signed-off-by: Peter Rosin <peda@axentia.se> > [edited by rmk to just split the tda998x_encoder_dpms() function > and restore the double-disable protection we originally had, > preserving original behaviour.] > Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> > --- > drivers/gpu/drm/i2c/tda998x_drv.c | 37 +++++++++++++++++++++++++------------ > 1 file changed, 25 insertions(+), 12 deletions(-) > > diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c > index b05f54c8585b..1c2f5dac1886 100644 > --- a/drivers/gpu/drm/i2c/tda998x_drv.c > +++ b/drivers/gpu/drm/i2c/tda998x_drv.c > @@ -1299,18 +1299,9 @@ static int tda998x_connector_init(struct tda998x_priv *priv, > > /* DRM encoder functions */ > > -static void tda998x_encoder_dpms(struct drm_encoder *encoder, int mode) > +static void tda998x_enable(struct tda998x_priv *priv) > { > - struct tda998x_priv *priv = enc_to_tda998x_priv(encoder); > - bool on; > - > - /* we only care about on or off: */ > - on = mode == DRM_MODE_DPMS_ON; > - > - if (on == priv->is_on) > - return; > - > - if (on) { > + if (!priv->is_on) { > /* enable video ports, audio will be enabled later */ > reg_write(priv, REG_ENA_VP_0, 0xff); > reg_write(priv, REG_ENA_VP_1, 0xff); > @@ -1321,7 +1312,12 @@ static void tda998x_encoder_dpms(struct drm_encoder *encoder, int mode) > reg_write(priv, REG_VIP_CNTRL_2, priv->vip_cntrl_2); > > priv->is_on = true; > - } else { > + } > +} > + > +static void tda998x_disable(struct tda998x_priv *priv) > +{ > + if (!priv->is_on) { if (priv->is_on) { I'm pretty sure that one's on you... :-) Cheers, Peter > /* disable video ports */ > reg_write(priv, REG_ENA_VP_0, 0x00); > reg_write(priv, REG_ENA_VP_1, 0x00); > @@ -1331,6 +1327,23 @@ static void tda998x_encoder_dpms(struct drm_encoder *encoder, int mode) > } > } > > +static void tda998x_encoder_dpms(struct drm_encoder *encoder, int mode) > +{ > + struct tda998x_priv *priv = enc_to_tda998x_priv(encoder); > + bool on; > + > + /* we only care about on or off: */ > + on = mode == DRM_MODE_DPMS_ON; > + > + if (on == priv->is_on) > + return; > + > + if (on) > + tda998x_enable(priv); > + else > + tda998x_disable(priv); > +} > + > static void > tda998x_encoder_mode_set(struct drm_encoder *encoder, > struct drm_display_mode *mode, > ^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PATCH v2 2/7] drm/i2c: tda998x: split tda998x_encoder_dpms into enable/disable @ 2018-07-31 5:46 ` Peter Rosin 0 siblings, 0 replies; 80+ messages in thread From: Peter Rosin @ 2018-07-31 5:46 UTC (permalink / raw) To: Russell King, dri-devel, linux-arm-kernel Cc: David Airlie, Tomi Valkeinen, Liviu Dudau, Jyri Sarha On 2018-07-30 18:42, Russell King wrote: > From: Peter Rosin <peda@axentia.se> > > This fits better with the drm_bridge callbacks for when this > driver becomes a drm_bridge. > > Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> > Signed-off-by: Peter Rosin <peda@axentia.se> > [edited by rmk to just split the tda998x_encoder_dpms() function > and restore the double-disable protection we originally had, > preserving original behaviour.] > Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> > --- > drivers/gpu/drm/i2c/tda998x_drv.c | 37 +++++++++++++++++++++++++------------ > 1 file changed, 25 insertions(+), 12 deletions(-) > > diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c > index b05f54c8585b..1c2f5dac1886 100644 > --- a/drivers/gpu/drm/i2c/tda998x_drv.c > +++ b/drivers/gpu/drm/i2c/tda998x_drv.c > @@ -1299,18 +1299,9 @@ static int tda998x_connector_init(struct tda998x_priv *priv, > > /* DRM encoder functions */ > > -static void tda998x_encoder_dpms(struct drm_encoder *encoder, int mode) > +static void tda998x_enable(struct tda998x_priv *priv) > { > - struct tda998x_priv *priv = enc_to_tda998x_priv(encoder); > - bool on; > - > - /* we only care about on or off: */ > - on = mode == DRM_MODE_DPMS_ON; > - > - if (on == priv->is_on) > - return; > - > - if (on) { > + if (!priv->is_on) { > /* enable video ports, audio will be enabled later */ > reg_write(priv, REG_ENA_VP_0, 0xff); > reg_write(priv, REG_ENA_VP_1, 0xff); > @@ -1321,7 +1312,12 @@ static void tda998x_encoder_dpms(struct drm_encoder *encoder, int mode) > reg_write(priv, REG_VIP_CNTRL_2, priv->vip_cntrl_2); > > priv->is_on = true; > - } else { > + } > +} > + > +static void tda998x_disable(struct tda998x_priv *priv) > +{ > + if (!priv->is_on) { if (priv->is_on) { I'm pretty sure that one's on you... :-) Cheers, Peter > /* disable video ports */ > reg_write(priv, REG_ENA_VP_0, 0x00); > reg_write(priv, REG_ENA_VP_1, 0x00); > @@ -1331,6 +1327,23 @@ static void tda998x_encoder_dpms(struct drm_encoder *encoder, int mode) > } > } > > +static void tda998x_encoder_dpms(struct drm_encoder *encoder, int mode) > +{ > + struct tda998x_priv *priv = enc_to_tda998x_priv(encoder); > + bool on; > + > + /* we only care about on or off: */ > + on = mode == DRM_MODE_DPMS_ON; > + > + if (on == priv->is_on) > + return; > + > + if (on) > + tda998x_enable(priv); > + else > + tda998x_disable(priv); > +} > + > static void > tda998x_encoder_mode_set(struct drm_encoder *encoder, > struct drm_display_mode *mode, > ^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH v2 3/7] drm/i2c: tda998x: move tda998x_set_config() into tda998x_create() 2018-07-30 16:41 ` Russell King - ARM Linux @ 2018-07-30 16:42 ` Russell King -1 siblings, 0 replies; 80+ messages in thread From: Russell King @ 2018-07-30 16:42 UTC (permalink / raw) To: linux-arm-kernel Move the non-DT configuration of the TDA998x into tda998x_create() so that we do all setup in one place. Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> --- drivers/gpu/drm/i2c/tda998x_drv.c | 73 +++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 38 deletions(-) diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index 1c2f5dac1886..843078e9fbf3 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -1621,6 +1621,25 @@ static int tda998x_get_audio_ports(struct tda998x_priv *priv, return 0; } +static void tda998x_set_config(struct tda998x_priv *priv, + const struct tda998x_encoder_params *p) +{ + priv->vip_cntrl_0 = VIP_CNTRL_0_SWAP_A(p->swap_a) | + (p->mirr_a ? VIP_CNTRL_0_MIRR_A : 0) | + VIP_CNTRL_0_SWAP_B(p->swap_b) | + (p->mirr_b ? VIP_CNTRL_0_MIRR_B : 0); + priv->vip_cntrl_1 = VIP_CNTRL_1_SWAP_C(p->swap_c) | + (p->mirr_c ? VIP_CNTRL_1_MIRR_C : 0) | + VIP_CNTRL_1_SWAP_D(p->swap_d) | + (p->mirr_d ? VIP_CNTRL_1_MIRR_D : 0); + priv->vip_cntrl_2 = VIP_CNTRL_2_SWAP_E(p->swap_e) | + (p->mirr_e ? VIP_CNTRL_2_MIRR_E : 0) | + VIP_CNTRL_2_SWAP_F(p->swap_f) | + (p->mirr_f ? VIP_CNTRL_2_MIRR_F : 0); + + priv->audio_params = p->audio_params; +} + static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) { struct device_node *np = client->dev.of_node; @@ -1772,23 +1791,24 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) /* enable EDID read irq: */ reg_set(priv, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD); - if (!np) - return 0; /* non-DT */ + if (np) { + /* get the device tree parameters */ + ret = of_property_read_u32(np, "video-ports", &video); + if (ret == 0) { + priv->vip_cntrl_0 = video >> 16; + priv->vip_cntrl_1 = video >> 8; + priv->vip_cntrl_2 = video; + } - /* get the device tree parameters */ - ret = of_property_read_u32(np, "video-ports", &video); - if (ret == 0) { - priv->vip_cntrl_0 = video >> 16; - priv->vip_cntrl_1 = video >> 8; - priv->vip_cntrl_2 = video; - } + ret = tda998x_get_audio_ports(priv, np); + if (ret) + goto fail; - ret = tda998x_get_audio_ports(priv, np); - if (ret) - goto fail; - - if (priv->audio_port[0].format != AFMT_UNUSED) - tda998x_audio_codec_init(priv, &client->dev); + if (priv->audio_port[0].format != AFMT_UNUSED) + tda998x_audio_codec_init(priv, &client->dev); + } else if (client->dev.platform_data) { + tda998x_set_config(priv, client->dev.platform_data); + } return 0; @@ -1834,28 +1854,8 @@ static const struct drm_encoder_funcs tda998x_encoder_funcs = { .destroy = tda998x_encoder_destroy, }; -static void tda998x_set_config(struct tda998x_priv *priv, - const struct tda998x_encoder_params *p) -{ - priv->vip_cntrl_0 = VIP_CNTRL_0_SWAP_A(p->swap_a) | - (p->mirr_a ? VIP_CNTRL_0_MIRR_A : 0) | - VIP_CNTRL_0_SWAP_B(p->swap_b) | - (p->mirr_b ? VIP_CNTRL_0_MIRR_B : 0); - priv->vip_cntrl_1 = VIP_CNTRL_1_SWAP_C(p->swap_c) | - (p->mirr_c ? VIP_CNTRL_1_MIRR_C : 0) | - VIP_CNTRL_1_SWAP_D(p->swap_d) | - (p->mirr_d ? VIP_CNTRL_1_MIRR_D : 0); - priv->vip_cntrl_2 = VIP_CNTRL_2_SWAP_E(p->swap_e) | - (p->mirr_e ? VIP_CNTRL_2_MIRR_E : 0) | - VIP_CNTRL_2_SWAP_F(p->swap_f) | - (p->mirr_f ? VIP_CNTRL_2_MIRR_F : 0); - - priv->audio_params = p->audio_params; -} - static int tda998x_bind(struct device *dev, struct device *master, void *data) { - struct tda998x_encoder_params *params = dev->platform_data; struct i2c_client *client = to_i2c_client(dev); struct drm_device *drm = data; struct tda998x_priv *priv; @@ -1883,9 +1883,6 @@ static int tda998x_bind(struct device *dev, struct device *master, void *data) if (ret) return ret; - if (!dev->of_node && params) - tda998x_set_config(priv, params); - drm_encoder_helper_add(&priv->encoder, &tda998x_encoder_helper_funcs); ret = drm_encoder_init(drm, &priv->encoder, &tda998x_encoder_funcs, DRM_MODE_ENCODER_TMDS, NULL); -- 2.7.4 ^ permalink raw reply related [flat|nested] 80+ messages in thread
* [PATCH v2 3/7] drm/i2c: tda998x: move tda998x_set_config() into tda998x_create() @ 2018-07-30 16:42 ` Russell King 0 siblings, 0 replies; 80+ messages in thread From: Russell King @ 2018-07-30 16:42 UTC (permalink / raw) To: dri-devel, linux-arm-kernel Cc: David Airlie, Tomi Valkeinen, Liviu Dudau, Peter Rosin, Jyri Sarha Move the non-DT configuration of the TDA998x into tda998x_create() so that we do all setup in one place. Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> --- drivers/gpu/drm/i2c/tda998x_drv.c | 73 +++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 38 deletions(-) diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index 1c2f5dac1886..843078e9fbf3 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -1621,6 +1621,25 @@ static int tda998x_get_audio_ports(struct tda998x_priv *priv, return 0; } +static void tda998x_set_config(struct tda998x_priv *priv, + const struct tda998x_encoder_params *p) +{ + priv->vip_cntrl_0 = VIP_CNTRL_0_SWAP_A(p->swap_a) | + (p->mirr_a ? VIP_CNTRL_0_MIRR_A : 0) | + VIP_CNTRL_0_SWAP_B(p->swap_b) | + (p->mirr_b ? VIP_CNTRL_0_MIRR_B : 0); + priv->vip_cntrl_1 = VIP_CNTRL_1_SWAP_C(p->swap_c) | + (p->mirr_c ? VIP_CNTRL_1_MIRR_C : 0) | + VIP_CNTRL_1_SWAP_D(p->swap_d) | + (p->mirr_d ? VIP_CNTRL_1_MIRR_D : 0); + priv->vip_cntrl_2 = VIP_CNTRL_2_SWAP_E(p->swap_e) | + (p->mirr_e ? VIP_CNTRL_2_MIRR_E : 0) | + VIP_CNTRL_2_SWAP_F(p->swap_f) | + (p->mirr_f ? VIP_CNTRL_2_MIRR_F : 0); + + priv->audio_params = p->audio_params; +} + static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) { struct device_node *np = client->dev.of_node; @@ -1772,23 +1791,24 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) /* enable EDID read irq: */ reg_set(priv, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD); - if (!np) - return 0; /* non-DT */ + if (np) { + /* get the device tree parameters */ + ret = of_property_read_u32(np, "video-ports", &video); + if (ret == 0) { + priv->vip_cntrl_0 = video >> 16; + priv->vip_cntrl_1 = video >> 8; + priv->vip_cntrl_2 = video; + } - /* get the device tree parameters */ - ret = of_property_read_u32(np, "video-ports", &video); - if (ret == 0) { - priv->vip_cntrl_0 = video >> 16; - priv->vip_cntrl_1 = video >> 8; - priv->vip_cntrl_2 = video; - } + ret = tda998x_get_audio_ports(priv, np); + if (ret) + goto fail; - ret = tda998x_get_audio_ports(priv, np); - if (ret) - goto fail; - - if (priv->audio_port[0].format != AFMT_UNUSED) - tda998x_audio_codec_init(priv, &client->dev); + if (priv->audio_port[0].format != AFMT_UNUSED) + tda998x_audio_codec_init(priv, &client->dev); + } else if (client->dev.platform_data) { + tda998x_set_config(priv, client->dev.platform_data); + } return 0; @@ -1834,28 +1854,8 @@ static const struct drm_encoder_funcs tda998x_encoder_funcs = { .destroy = tda998x_encoder_destroy, }; -static void tda998x_set_config(struct tda998x_priv *priv, - const struct tda998x_encoder_params *p) -{ - priv->vip_cntrl_0 = VIP_CNTRL_0_SWAP_A(p->swap_a) | - (p->mirr_a ? VIP_CNTRL_0_MIRR_A : 0) | - VIP_CNTRL_0_SWAP_B(p->swap_b) | - (p->mirr_b ? VIP_CNTRL_0_MIRR_B : 0); - priv->vip_cntrl_1 = VIP_CNTRL_1_SWAP_C(p->swap_c) | - (p->mirr_c ? VIP_CNTRL_1_MIRR_C : 0) | - VIP_CNTRL_1_SWAP_D(p->swap_d) | - (p->mirr_d ? VIP_CNTRL_1_MIRR_D : 0); - priv->vip_cntrl_2 = VIP_CNTRL_2_SWAP_E(p->swap_e) | - (p->mirr_e ? VIP_CNTRL_2_MIRR_E : 0) | - VIP_CNTRL_2_SWAP_F(p->swap_f) | - (p->mirr_f ? VIP_CNTRL_2_MIRR_F : 0); - - priv->audio_params = p->audio_params; -} - static int tda998x_bind(struct device *dev, struct device *master, void *data) { - struct tda998x_encoder_params *params = dev->platform_data; struct i2c_client *client = to_i2c_client(dev); struct drm_device *drm = data; struct tda998x_priv *priv; @@ -1883,9 +1883,6 @@ static int tda998x_bind(struct device *dev, struct device *master, void *data) if (ret) return ret; - if (!dev->of_node && params) - tda998x_set_config(priv, params); - drm_encoder_helper_add(&priv->encoder, &tda998x_encoder_helper_funcs); ret = drm_encoder_init(drm, &priv->encoder, &tda998x_encoder_funcs, DRM_MODE_ENCODER_TMDS, NULL); -- 2.7.4 ^ permalink raw reply related [flat|nested] 80+ messages in thread
* [PATCH v2 4/7] drm/i2c: tda998x: convert to bridge driver 2018-07-30 16:41 ` Russell King - ARM Linux @ 2018-07-30 16:42 ` Russell King -1 siblings, 0 replies; 80+ messages in thread From: Russell King @ 2018-07-30 16:42 UTC (permalink / raw) To: linux-arm-kernel Convert tda998x to a bridge driver with built-in encoder support for compatibility with existing component drivers. Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> --- drivers/gpu/drm/i2c/tda998x_drv.c | 154 +++++++++++++++++++------------------- 1 file changed, 79 insertions(+), 75 deletions(-) diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index 843078e9fbf3..1ea62052f3e0 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -69,6 +69,7 @@ struct tda998x_priv { bool edid_delay_active; struct drm_encoder encoder; + struct drm_bridge bridge; struct drm_connector connector; struct tda998x_audio_port audio_port[2]; @@ -79,9 +80,10 @@ struct tda998x_priv { #define conn_to_tda998x_priv(x) \ container_of(x, struct tda998x_priv, connector) - #define enc_to_tda998x_priv(x) \ container_of(x, struct tda998x_priv, encoder) +#define bridge_to_tda998x_priv(x) \ + container_of(x, struct tda998x_priv, bridge) /* The TDA9988 series of devices use a paged register scheme.. to simplify * things we encode the page # in upper bits of the register #. To read/ @@ -1262,7 +1264,7 @@ tda998x_connector_best_encoder(struct drm_connector *connector) { struct tda998x_priv *priv = conn_to_tda998x_priv(connector); - return &priv->encoder; + return priv->bridge.encoder; } static @@ -1292,15 +1294,32 @@ static int tda998x_connector_init(struct tda998x_priv *priv, if (ret) return ret; - drm_mode_connector_attach_encoder(&priv->connector, &priv->encoder); + drm_mode_connector_attach_encoder(&priv->connector, + priv->bridge.encoder); return 0; } -/* DRM encoder functions */ +/* DRM bridge functions */ + +static int tda998x_bridge_attach(struct drm_bridge *bridge) +{ + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); + + return tda998x_connector_init(priv, bridge->dev); +} + +static void tda998x_bridge_detach(struct drm_bridge *bridge) +{ + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); + + drm_connector_cleanup(&priv->connector); +} -static void tda998x_enable(struct tda998x_priv *priv) +static void tda998x_bridge_enable(struct drm_bridge *bridge) { + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); + if (!priv->is_on) { /* enable video ports, audio will be enabled later */ reg_write(priv, REG_ENA_VP_0, 0xff); @@ -1315,8 +1334,10 @@ static void tda998x_enable(struct tda998x_priv *priv) } } -static void tda998x_disable(struct tda998x_priv *priv) +static void tda998x_bridge_disable(struct drm_bridge *bridge) { + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); + if (!priv->is_on) { /* disable video ports */ reg_write(priv, REG_ENA_VP_0, 0x00); @@ -1327,29 +1348,11 @@ static void tda998x_disable(struct tda998x_priv *priv) } } -static void tda998x_encoder_dpms(struct drm_encoder *encoder, int mode) +static void tda998x_bridge_mode_set(struct drm_bridge *bridge, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) { - struct tda998x_priv *priv = enc_to_tda998x_priv(encoder); - bool on; - - /* we only care about on or off: */ - on = mode == DRM_MODE_DPMS_ON; - - if (on == priv->is_on) - return; - - if (on) - tda998x_enable(priv); - else - tda998x_disable(priv); -} - -static void -tda998x_encoder_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct tda998x_priv *priv = enc_to_tda998x_priv(encoder); + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); u16 ref_pix, ref_line, n_pix, n_line; u16 hs_pix_s, hs_pix_e; u16 vs1_pix_s, vs1_pix_e, vs1_line_s, vs1_line_e; @@ -1556,8 +1559,18 @@ tda998x_encoder_mode_set(struct drm_encoder *encoder, mutex_unlock(&priv->audio_mutex); } +static const struct drm_bridge_funcs tda998x_bridge_funcs = { + .attach = tda998x_bridge_attach, + .detach = tda998x_bridge_detach, + .disable = tda998x_bridge_disable, + .mode_set = tda998x_bridge_mode_set, + .enable = tda998x_bridge_enable, +}; + static void tda998x_destroy(struct tda998x_priv *priv) { + drm_bridge_remove(&priv->bridge); + /* 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); @@ -1650,6 +1663,7 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) mutex_init(&priv->mutex); /* protect the page access */ mutex_init(&priv->audio_mutex); /* protect access from audio thread */ mutex_init(&priv->edid_mutex); + INIT_LIST_HEAD(&priv->bridge.list); init_waitqueue_head(&priv->edid_delay_waitq); timer_setup(&priv->edid_delay_timer, tda998x_edid_delay_done, 0); INIT_WORK(&priv->detect_work, tda998x_detect_work); @@ -1810,43 +1824,23 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) tda998x_set_config(priv, client->dev.platform_data); } + priv->bridge.funcs = &tda998x_bridge_funcs; + priv->bridge.of_node = dev->of_node; + + drm_bridge_add(&priv->bridge); + return 0; fail: - /* if encoder_init fails, the encoder slave is never registered, - * so cleanup here: - */ - i2c_unregister_device(priv->cec); - if (priv->cec_notify) - cec_notifier_put(priv->cec_notify); - if (client->irq) - free_irq(client->irq, priv); + tda998x_destroy(priv); err_irq: return ret; } -static void tda998x_encoder_prepare(struct drm_encoder *encoder) -{ - tda998x_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); -} - -static void tda998x_encoder_commit(struct drm_encoder *encoder) -{ - tda998x_encoder_dpms(encoder, DRM_MODE_DPMS_ON); -} - -static const struct drm_encoder_helper_funcs tda998x_encoder_helper_funcs = { - .dpms = tda998x_encoder_dpms, - .prepare = tda998x_encoder_prepare, - .commit = tda998x_encoder_commit, - .mode_set = tda998x_encoder_mode_set, -}; +/* DRM encoder functions */ static void tda998x_encoder_destroy(struct drm_encoder *encoder) { - struct tda998x_priv *priv = enc_to_tda998x_priv(encoder); - - tda998x_destroy(priv); drm_encoder_cleanup(encoder); } @@ -1854,20 +1848,12 @@ static const struct drm_encoder_funcs tda998x_encoder_funcs = { .destroy = tda998x_encoder_destroy, }; -static int tda998x_bind(struct device *dev, struct device *master, void *data) +static int tda998x_encoder_init(struct device *dev, struct drm_device *drm) { - struct i2c_client *client = to_i2c_client(dev); - struct drm_device *drm = data; - struct tda998x_priv *priv; + struct tda998x_priv *priv = dev_get_drvdata(dev); u32 crtcs = 0; int ret; - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - dev_set_drvdata(dev, priv); - if (dev->of_node) crtcs = drm_of_find_possible_crtcs(drm, dev->of_node); @@ -1879,35 +1865,53 @@ static int tda998x_bind(struct device *dev, struct device *master, void *data) priv->encoder.possible_crtcs = crtcs; - ret = tda998x_create(client, priv); - if (ret) - return ret; - - drm_encoder_helper_add(&priv->encoder, &tda998x_encoder_helper_funcs); ret = drm_encoder_init(drm, &priv->encoder, &tda998x_encoder_funcs, DRM_MODE_ENCODER_TMDS, NULL); if (ret) goto err_encoder; - ret = tda998x_connector_init(priv, drm); + ret = drm_bridge_attach(&priv->encoder, &priv->bridge, NULL); if (ret) - goto err_connector; + goto err_bridge; return 0; -err_connector: +err_bridge: drm_encoder_cleanup(&priv->encoder); err_encoder: - tda998x_destroy(priv); return ret; } +static int tda998x_bind(struct device *dev, struct device *master, void *data) +{ + struct i2c_client *client = to_i2c_client(dev); + struct drm_device *drm = data; + struct tda998x_priv *priv; + int ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + dev_set_drvdata(dev, priv); + + ret = tda998x_create(client, priv); + if (ret) + return ret; + + ret = tda998x_encoder_init(dev, drm); + if (ret) { + tda998x_destroy(priv); + return ret; + } + return 0; +} + static void tda998x_unbind(struct device *dev, struct device *master, void *data) { struct tda998x_priv *priv = dev_get_drvdata(dev); - drm_connector_cleanup(&priv->connector); drm_encoder_cleanup(&priv->encoder); tda998x_destroy(priv); } -- 2.7.4 ^ permalink raw reply related [flat|nested] 80+ messages in thread
* [PATCH v2 4/7] drm/i2c: tda998x: convert to bridge driver @ 2018-07-30 16:42 ` Russell King 0 siblings, 0 replies; 80+ messages in thread From: Russell King @ 2018-07-30 16:42 UTC (permalink / raw) To: dri-devel, linux-arm-kernel Cc: David Airlie, Tomi Valkeinen, Liviu Dudau, Peter Rosin, Jyri Sarha Convert tda998x to a bridge driver with built-in encoder support for compatibility with existing component drivers. Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> --- drivers/gpu/drm/i2c/tda998x_drv.c | 154 +++++++++++++++++++------------------- 1 file changed, 79 insertions(+), 75 deletions(-) diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index 843078e9fbf3..1ea62052f3e0 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -69,6 +69,7 @@ struct tda998x_priv { bool edid_delay_active; struct drm_encoder encoder; + struct drm_bridge bridge; struct drm_connector connector; struct tda998x_audio_port audio_port[2]; @@ -79,9 +80,10 @@ struct tda998x_priv { #define conn_to_tda998x_priv(x) \ container_of(x, struct tda998x_priv, connector) - #define enc_to_tda998x_priv(x) \ container_of(x, struct tda998x_priv, encoder) +#define bridge_to_tda998x_priv(x) \ + container_of(x, struct tda998x_priv, bridge) /* The TDA9988 series of devices use a paged register scheme.. to simplify * things we encode the page # in upper bits of the register #. To read/ @@ -1262,7 +1264,7 @@ tda998x_connector_best_encoder(struct drm_connector *connector) { struct tda998x_priv *priv = conn_to_tda998x_priv(connector); - return &priv->encoder; + return priv->bridge.encoder; } static @@ -1292,15 +1294,32 @@ static int tda998x_connector_init(struct tda998x_priv *priv, if (ret) return ret; - drm_mode_connector_attach_encoder(&priv->connector, &priv->encoder); + drm_mode_connector_attach_encoder(&priv->connector, + priv->bridge.encoder); return 0; } -/* DRM encoder functions */ +/* DRM bridge functions */ + +static int tda998x_bridge_attach(struct drm_bridge *bridge) +{ + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); + + return tda998x_connector_init(priv, bridge->dev); +} + +static void tda998x_bridge_detach(struct drm_bridge *bridge) +{ + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); + + drm_connector_cleanup(&priv->connector); +} -static void tda998x_enable(struct tda998x_priv *priv) +static void tda998x_bridge_enable(struct drm_bridge *bridge) { + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); + if (!priv->is_on) { /* enable video ports, audio will be enabled later */ reg_write(priv, REG_ENA_VP_0, 0xff); @@ -1315,8 +1334,10 @@ static void tda998x_enable(struct tda998x_priv *priv) } } -static void tda998x_disable(struct tda998x_priv *priv) +static void tda998x_bridge_disable(struct drm_bridge *bridge) { + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); + if (!priv->is_on) { /* disable video ports */ reg_write(priv, REG_ENA_VP_0, 0x00); @@ -1327,29 +1348,11 @@ static void tda998x_disable(struct tda998x_priv *priv) } } -static void tda998x_encoder_dpms(struct drm_encoder *encoder, int mode) +static void tda998x_bridge_mode_set(struct drm_bridge *bridge, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) { - struct tda998x_priv *priv = enc_to_tda998x_priv(encoder); - bool on; - - /* we only care about on or off: */ - on = mode == DRM_MODE_DPMS_ON; - - if (on == priv->is_on) - return; - - if (on) - tda998x_enable(priv); - else - tda998x_disable(priv); -} - -static void -tda998x_encoder_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct tda998x_priv *priv = enc_to_tda998x_priv(encoder); + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); u16 ref_pix, ref_line, n_pix, n_line; u16 hs_pix_s, hs_pix_e; u16 vs1_pix_s, vs1_pix_e, vs1_line_s, vs1_line_e; @@ -1556,8 +1559,18 @@ tda998x_encoder_mode_set(struct drm_encoder *encoder, mutex_unlock(&priv->audio_mutex); } +static const struct drm_bridge_funcs tda998x_bridge_funcs = { + .attach = tda998x_bridge_attach, + .detach = tda998x_bridge_detach, + .disable = tda998x_bridge_disable, + .mode_set = tda998x_bridge_mode_set, + .enable = tda998x_bridge_enable, +}; + static void tda998x_destroy(struct tda998x_priv *priv) { + drm_bridge_remove(&priv->bridge); + /* 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); @@ -1650,6 +1663,7 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) mutex_init(&priv->mutex); /* protect the page access */ mutex_init(&priv->audio_mutex); /* protect access from audio thread */ mutex_init(&priv->edid_mutex); + INIT_LIST_HEAD(&priv->bridge.list); init_waitqueue_head(&priv->edid_delay_waitq); timer_setup(&priv->edid_delay_timer, tda998x_edid_delay_done, 0); INIT_WORK(&priv->detect_work, tda998x_detect_work); @@ -1810,43 +1824,23 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) tda998x_set_config(priv, client->dev.platform_data); } + priv->bridge.funcs = &tda998x_bridge_funcs; + priv->bridge.of_node = dev->of_node; + + drm_bridge_add(&priv->bridge); + return 0; fail: - /* if encoder_init fails, the encoder slave is never registered, - * so cleanup here: - */ - i2c_unregister_device(priv->cec); - if (priv->cec_notify) - cec_notifier_put(priv->cec_notify); - if (client->irq) - free_irq(client->irq, priv); + tda998x_destroy(priv); err_irq: return ret; } -static void tda998x_encoder_prepare(struct drm_encoder *encoder) -{ - tda998x_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); -} - -static void tda998x_encoder_commit(struct drm_encoder *encoder) -{ - tda998x_encoder_dpms(encoder, DRM_MODE_DPMS_ON); -} - -static const struct drm_encoder_helper_funcs tda998x_encoder_helper_funcs = { - .dpms = tda998x_encoder_dpms, - .prepare = tda998x_encoder_prepare, - .commit = tda998x_encoder_commit, - .mode_set = tda998x_encoder_mode_set, -}; +/* DRM encoder functions */ static void tda998x_encoder_destroy(struct drm_encoder *encoder) { - struct tda998x_priv *priv = enc_to_tda998x_priv(encoder); - - tda998x_destroy(priv); drm_encoder_cleanup(encoder); } @@ -1854,20 +1848,12 @@ static const struct drm_encoder_funcs tda998x_encoder_funcs = { .destroy = tda998x_encoder_destroy, }; -static int tda998x_bind(struct device *dev, struct device *master, void *data) +static int tda998x_encoder_init(struct device *dev, struct drm_device *drm) { - struct i2c_client *client = to_i2c_client(dev); - struct drm_device *drm = data; - struct tda998x_priv *priv; + struct tda998x_priv *priv = dev_get_drvdata(dev); u32 crtcs = 0; int ret; - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - dev_set_drvdata(dev, priv); - if (dev->of_node) crtcs = drm_of_find_possible_crtcs(drm, dev->of_node); @@ -1879,35 +1865,53 @@ static int tda998x_bind(struct device *dev, struct device *master, void *data) priv->encoder.possible_crtcs = crtcs; - ret = tda998x_create(client, priv); - if (ret) - return ret; - - drm_encoder_helper_add(&priv->encoder, &tda998x_encoder_helper_funcs); ret = drm_encoder_init(drm, &priv->encoder, &tda998x_encoder_funcs, DRM_MODE_ENCODER_TMDS, NULL); if (ret) goto err_encoder; - ret = tda998x_connector_init(priv, drm); + ret = drm_bridge_attach(&priv->encoder, &priv->bridge, NULL); if (ret) - goto err_connector; + goto err_bridge; return 0; -err_connector: +err_bridge: drm_encoder_cleanup(&priv->encoder); err_encoder: - tda998x_destroy(priv); return ret; } +static int tda998x_bind(struct device *dev, struct device *master, void *data) +{ + struct i2c_client *client = to_i2c_client(dev); + struct drm_device *drm = data; + struct tda998x_priv *priv; + int ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + dev_set_drvdata(dev, priv); + + ret = tda998x_create(client, priv); + if (ret) + return ret; + + ret = tda998x_encoder_init(dev, drm); + if (ret) { + tda998x_destroy(priv); + return ret; + } + return 0; +} + static void tda998x_unbind(struct device *dev, struct device *master, void *data) { struct tda998x_priv *priv = dev_get_drvdata(dev); - drm_connector_cleanup(&priv->connector); drm_encoder_cleanup(&priv->encoder); tda998x_destroy(priv); } -- 2.7.4 ^ permalink raw reply related [flat|nested] 80+ messages in thread
* [PATCH v2 4/7] drm/i2c: tda998x: convert to bridge driver 2018-07-30 16:42 ` Russell King @ 2018-07-31 7:37 ` Peter Rosin -1 siblings, 0 replies; 80+ messages in thread From: Peter Rosin @ 2018-07-31 7:37 UTC (permalink / raw) To: linux-arm-kernel Hi! This patch needs a refresh since commit cde4c44d8769 ("drm: drop _mode_ from drm_mode_connector_attach_encoder") interferes with hunk#4 On 2018-07-30 18:42, Russell King wrote: > Convert tda998x to a bridge driver with built-in encoder support for > compatibility with existing component drivers. > > Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> > --- > drivers/gpu/drm/i2c/tda998x_drv.c | 154 +++++++++++++++++++------------------- > 1 file changed, 79 insertions(+), 75 deletions(-) > > diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c > index 843078e9fbf3..1ea62052f3e0 100644 > --- a/drivers/gpu/drm/i2c/tda998x_drv.c > +++ b/drivers/gpu/drm/i2c/tda998x_drv.c > @@ -69,6 +69,7 @@ struct tda998x_priv { > bool edid_delay_active; > > struct drm_encoder encoder; > + struct drm_bridge bridge; > struct drm_connector connector; > > struct tda998x_audio_port audio_port[2]; > @@ -79,9 +80,10 @@ struct tda998x_priv { > > #define conn_to_tda998x_priv(x) \ > container_of(x, struct tda998x_priv, connector) > - > #define enc_to_tda998x_priv(x) \ > container_of(x, struct tda998x_priv, encoder) > +#define bridge_to_tda998x_priv(x) \ > + container_of(x, struct tda998x_priv, bridge) > > /* The TDA9988 series of devices use a paged register scheme.. to simplify > * things we encode the page # in upper bits of the register #. To read/ > @@ -1262,7 +1264,7 @@ tda998x_connector_best_encoder(struct drm_connector *connector) > { > struct tda998x_priv *priv = conn_to_tda998x_priv(connector); > > - return &priv->encoder; > + return priv->bridge.encoder; > } > > static > @@ -1292,15 +1294,32 @@ static int tda998x_connector_init(struct tda998x_priv *priv, > if (ret) > return ret; > > - drm_mode_connector_attach_encoder(&priv->connector, &priv->encoder); > + drm_mode_connector_attach_encoder(&priv->connector, > + priv->bridge.encoder); cde4c44d8769 ("drm: drop _mode_ from drm_mode_connector_attach_encoder") conflicts with this hunk. Cheers, Peter > > return 0; > } > > -/* DRM encoder functions */ > +/* DRM bridge functions */ > + > +static int tda998x_bridge_attach(struct drm_bridge *bridge) > +{ > + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); > + > + return tda998x_connector_init(priv, bridge->dev); > +} > + > +static void tda998x_bridge_detach(struct drm_bridge *bridge) > +{ > + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); > + > + drm_connector_cleanup(&priv->connector); > +} > > -static void tda998x_enable(struct tda998x_priv *priv) > +static void tda998x_bridge_enable(struct drm_bridge *bridge) > { > + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); > + > if (!priv->is_on) { > /* enable video ports, audio will be enabled later */ > reg_write(priv, REG_ENA_VP_0, 0xff); > @@ -1315,8 +1334,10 @@ static void tda998x_enable(struct tda998x_priv *priv) > } > } > > -static void tda998x_disable(struct tda998x_priv *priv) > +static void tda998x_bridge_disable(struct drm_bridge *bridge) > { > + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); > + > if (!priv->is_on) { > /* disable video ports */ > reg_write(priv, REG_ENA_VP_0, 0x00); > @@ -1327,29 +1348,11 @@ static void tda998x_disable(struct tda998x_priv *priv) > } > } > > -static void tda998x_encoder_dpms(struct drm_encoder *encoder, int mode) > +static void tda998x_bridge_mode_set(struct drm_bridge *bridge, > + struct drm_display_mode *mode, > + struct drm_display_mode *adjusted_mode) > { > - struct tda998x_priv *priv = enc_to_tda998x_priv(encoder); > - bool on; > - > - /* we only care about on or off: */ > - on = mode == DRM_MODE_DPMS_ON; > - > - if (on == priv->is_on) > - return; > - > - if (on) > - tda998x_enable(priv); > - else > - tda998x_disable(priv); > -} > - > -static void > -tda998x_encoder_mode_set(struct drm_encoder *encoder, > - struct drm_display_mode *mode, > - struct drm_display_mode *adjusted_mode) > -{ > - struct tda998x_priv *priv = enc_to_tda998x_priv(encoder); > + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); > u16 ref_pix, ref_line, n_pix, n_line; > u16 hs_pix_s, hs_pix_e; > u16 vs1_pix_s, vs1_pix_e, vs1_line_s, vs1_line_e; > @@ -1556,8 +1559,18 @@ tda998x_encoder_mode_set(struct drm_encoder *encoder, > mutex_unlock(&priv->audio_mutex); > } > > +static const struct drm_bridge_funcs tda998x_bridge_funcs = { > + .attach = tda998x_bridge_attach, > + .detach = tda998x_bridge_detach, > + .disable = tda998x_bridge_disable, > + .mode_set = tda998x_bridge_mode_set, > + .enable = tda998x_bridge_enable, > +}; > + > static void tda998x_destroy(struct tda998x_priv *priv) > { > + drm_bridge_remove(&priv->bridge); > + > /* 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); > @@ -1650,6 +1663,7 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) > mutex_init(&priv->mutex); /* protect the page access */ > mutex_init(&priv->audio_mutex); /* protect access from audio thread */ > mutex_init(&priv->edid_mutex); > + INIT_LIST_HEAD(&priv->bridge.list); > init_waitqueue_head(&priv->edid_delay_waitq); > timer_setup(&priv->edid_delay_timer, tda998x_edid_delay_done, 0); > INIT_WORK(&priv->detect_work, tda998x_detect_work); > @@ -1810,43 +1824,23 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) > tda998x_set_config(priv, client->dev.platform_data); > } > > + priv->bridge.funcs = &tda998x_bridge_funcs; > + priv->bridge.of_node = dev->of_node; > + > + drm_bridge_add(&priv->bridge); > + > return 0; > > fail: > - /* if encoder_init fails, the encoder slave is never registered, > - * so cleanup here: > - */ > - i2c_unregister_device(priv->cec); > - if (priv->cec_notify) > - cec_notifier_put(priv->cec_notify); > - if (client->irq) > - free_irq(client->irq, priv); > + tda998x_destroy(priv); > err_irq: > return ret; > } > > -static void tda998x_encoder_prepare(struct drm_encoder *encoder) > -{ > - tda998x_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); > -} > - > -static void tda998x_encoder_commit(struct drm_encoder *encoder) > -{ > - tda998x_encoder_dpms(encoder, DRM_MODE_DPMS_ON); > -} > - > -static const struct drm_encoder_helper_funcs tda998x_encoder_helper_funcs = { > - .dpms = tda998x_encoder_dpms, > - .prepare = tda998x_encoder_prepare, > - .commit = tda998x_encoder_commit, > - .mode_set = tda998x_encoder_mode_set, > -}; > +/* DRM encoder functions */ > > static void tda998x_encoder_destroy(struct drm_encoder *encoder) > { > - struct tda998x_priv *priv = enc_to_tda998x_priv(encoder); > - > - tda998x_destroy(priv); > drm_encoder_cleanup(encoder); > } > > @@ -1854,20 +1848,12 @@ static const struct drm_encoder_funcs tda998x_encoder_funcs = { > .destroy = tda998x_encoder_destroy, > }; > > -static int tda998x_bind(struct device *dev, struct device *master, void *data) > +static int tda998x_encoder_init(struct device *dev, struct drm_device *drm) > { > - struct i2c_client *client = to_i2c_client(dev); > - struct drm_device *drm = data; > - struct tda998x_priv *priv; > + struct tda998x_priv *priv = dev_get_drvdata(dev); > u32 crtcs = 0; > int ret; > > - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); > - if (!priv) > - return -ENOMEM; > - > - dev_set_drvdata(dev, priv); > - > if (dev->of_node) > crtcs = drm_of_find_possible_crtcs(drm, dev->of_node); > > @@ -1879,35 +1865,53 @@ static int tda998x_bind(struct device *dev, struct device *master, void *data) > > priv->encoder.possible_crtcs = crtcs; > > - ret = tda998x_create(client, priv); > - if (ret) > - return ret; > - > - drm_encoder_helper_add(&priv->encoder, &tda998x_encoder_helper_funcs); > ret = drm_encoder_init(drm, &priv->encoder, &tda998x_encoder_funcs, > DRM_MODE_ENCODER_TMDS, NULL); > if (ret) > goto err_encoder; > > - ret = tda998x_connector_init(priv, drm); > + ret = drm_bridge_attach(&priv->encoder, &priv->bridge, NULL); > if (ret) > - goto err_connector; > + goto err_bridge; > > return 0; > > -err_connector: > +err_bridge: > drm_encoder_cleanup(&priv->encoder); > err_encoder: > - tda998x_destroy(priv); > return ret; > } > > +static int tda998x_bind(struct device *dev, struct device *master, void *data) > +{ > + struct i2c_client *client = to_i2c_client(dev); > + struct drm_device *drm = data; > + struct tda998x_priv *priv; > + int ret; > + > + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); > + if (!priv) > + return -ENOMEM; > + > + dev_set_drvdata(dev, priv); > + > + ret = tda998x_create(client, priv); > + if (ret) > + return ret; > + > + ret = tda998x_encoder_init(dev, drm); > + if (ret) { > + tda998x_destroy(priv); > + return ret; > + } > + return 0; > +} > + > static void tda998x_unbind(struct device *dev, struct device *master, > void *data) > { > struct tda998x_priv *priv = dev_get_drvdata(dev); > > - drm_connector_cleanup(&priv->connector); > drm_encoder_cleanup(&priv->encoder); > tda998x_destroy(priv); > } > ^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PATCH v2 4/7] drm/i2c: tda998x: convert to bridge driver @ 2018-07-31 7:37 ` Peter Rosin 0 siblings, 0 replies; 80+ messages in thread From: Peter Rosin @ 2018-07-31 7:37 UTC (permalink / raw) To: Russell King, dri-devel, linux-arm-kernel Cc: David Airlie, Tomi Valkeinen, Liviu Dudau, Jyri Sarha Hi! This patch needs a refresh since commit cde4c44d8769 ("drm: drop _mode_ from drm_mode_connector_attach_encoder") interferes with hunk#4 On 2018-07-30 18:42, Russell King wrote: > Convert tda998x to a bridge driver with built-in encoder support for > compatibility with existing component drivers. > > Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> > --- > drivers/gpu/drm/i2c/tda998x_drv.c | 154 +++++++++++++++++++------------------- > 1 file changed, 79 insertions(+), 75 deletions(-) > > diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c > index 843078e9fbf3..1ea62052f3e0 100644 > --- a/drivers/gpu/drm/i2c/tda998x_drv.c > +++ b/drivers/gpu/drm/i2c/tda998x_drv.c > @@ -69,6 +69,7 @@ struct tda998x_priv { > bool edid_delay_active; > > struct drm_encoder encoder; > + struct drm_bridge bridge; > struct drm_connector connector; > > struct tda998x_audio_port audio_port[2]; > @@ -79,9 +80,10 @@ struct tda998x_priv { > > #define conn_to_tda998x_priv(x) \ > container_of(x, struct tda998x_priv, connector) > - > #define enc_to_tda998x_priv(x) \ > container_of(x, struct tda998x_priv, encoder) > +#define bridge_to_tda998x_priv(x) \ > + container_of(x, struct tda998x_priv, bridge) > > /* The TDA9988 series of devices use a paged register scheme.. to simplify > * things we encode the page # in upper bits of the register #. To read/ > @@ -1262,7 +1264,7 @@ tda998x_connector_best_encoder(struct drm_connector *connector) > { > struct tda998x_priv *priv = conn_to_tda998x_priv(connector); > > - return &priv->encoder; > + return priv->bridge.encoder; > } > > static > @@ -1292,15 +1294,32 @@ static int tda998x_connector_init(struct tda998x_priv *priv, > if (ret) > return ret; > > - drm_mode_connector_attach_encoder(&priv->connector, &priv->encoder); > + drm_mode_connector_attach_encoder(&priv->connector, > + priv->bridge.encoder); cde4c44d8769 ("drm: drop _mode_ from drm_mode_connector_attach_encoder") conflicts with this hunk. Cheers, Peter > > return 0; > } > > -/* DRM encoder functions */ > +/* DRM bridge functions */ > + > +static int tda998x_bridge_attach(struct drm_bridge *bridge) > +{ > + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); > + > + return tda998x_connector_init(priv, bridge->dev); > +} > + > +static void tda998x_bridge_detach(struct drm_bridge *bridge) > +{ > + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); > + > + drm_connector_cleanup(&priv->connector); > +} > > -static void tda998x_enable(struct tda998x_priv *priv) > +static void tda998x_bridge_enable(struct drm_bridge *bridge) > { > + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); > + > if (!priv->is_on) { > /* enable video ports, audio will be enabled later */ > reg_write(priv, REG_ENA_VP_0, 0xff); > @@ -1315,8 +1334,10 @@ static void tda998x_enable(struct tda998x_priv *priv) > } > } > > -static void tda998x_disable(struct tda998x_priv *priv) > +static void tda998x_bridge_disable(struct drm_bridge *bridge) > { > + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); > + > if (!priv->is_on) { > /* disable video ports */ > reg_write(priv, REG_ENA_VP_0, 0x00); > @@ -1327,29 +1348,11 @@ static void tda998x_disable(struct tda998x_priv *priv) > } > } > > -static void tda998x_encoder_dpms(struct drm_encoder *encoder, int mode) > +static void tda998x_bridge_mode_set(struct drm_bridge *bridge, > + struct drm_display_mode *mode, > + struct drm_display_mode *adjusted_mode) > { > - struct tda998x_priv *priv = enc_to_tda998x_priv(encoder); > - bool on; > - > - /* we only care about on or off: */ > - on = mode == DRM_MODE_DPMS_ON; > - > - if (on == priv->is_on) > - return; > - > - if (on) > - tda998x_enable(priv); > - else > - tda998x_disable(priv); > -} > - > -static void > -tda998x_encoder_mode_set(struct drm_encoder *encoder, > - struct drm_display_mode *mode, > - struct drm_display_mode *adjusted_mode) > -{ > - struct tda998x_priv *priv = enc_to_tda998x_priv(encoder); > + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); > u16 ref_pix, ref_line, n_pix, n_line; > u16 hs_pix_s, hs_pix_e; > u16 vs1_pix_s, vs1_pix_e, vs1_line_s, vs1_line_e; > @@ -1556,8 +1559,18 @@ tda998x_encoder_mode_set(struct drm_encoder *encoder, > mutex_unlock(&priv->audio_mutex); > } > > +static const struct drm_bridge_funcs tda998x_bridge_funcs = { > + .attach = tda998x_bridge_attach, > + .detach = tda998x_bridge_detach, > + .disable = tda998x_bridge_disable, > + .mode_set = tda998x_bridge_mode_set, > + .enable = tda998x_bridge_enable, > +}; > + > static void tda998x_destroy(struct tda998x_priv *priv) > { > + drm_bridge_remove(&priv->bridge); > + > /* 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); > @@ -1650,6 +1663,7 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) > mutex_init(&priv->mutex); /* protect the page access */ > mutex_init(&priv->audio_mutex); /* protect access from audio thread */ > mutex_init(&priv->edid_mutex); > + INIT_LIST_HEAD(&priv->bridge.list); > init_waitqueue_head(&priv->edid_delay_waitq); > timer_setup(&priv->edid_delay_timer, tda998x_edid_delay_done, 0); > INIT_WORK(&priv->detect_work, tda998x_detect_work); > @@ -1810,43 +1824,23 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) > tda998x_set_config(priv, client->dev.platform_data); > } > > + priv->bridge.funcs = &tda998x_bridge_funcs; > + priv->bridge.of_node = dev->of_node; > + > + drm_bridge_add(&priv->bridge); > + > return 0; > > fail: > - /* if encoder_init fails, the encoder slave is never registered, > - * so cleanup here: > - */ > - i2c_unregister_device(priv->cec); > - if (priv->cec_notify) > - cec_notifier_put(priv->cec_notify); > - if (client->irq) > - free_irq(client->irq, priv); > + tda998x_destroy(priv); > err_irq: > return ret; > } > > -static void tda998x_encoder_prepare(struct drm_encoder *encoder) > -{ > - tda998x_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); > -} > - > -static void tda998x_encoder_commit(struct drm_encoder *encoder) > -{ > - tda998x_encoder_dpms(encoder, DRM_MODE_DPMS_ON); > -} > - > -static const struct drm_encoder_helper_funcs tda998x_encoder_helper_funcs = { > - .dpms = tda998x_encoder_dpms, > - .prepare = tda998x_encoder_prepare, > - .commit = tda998x_encoder_commit, > - .mode_set = tda998x_encoder_mode_set, > -}; > +/* DRM encoder functions */ > > static void tda998x_encoder_destroy(struct drm_encoder *encoder) > { > - struct tda998x_priv *priv = enc_to_tda998x_priv(encoder); > - > - tda998x_destroy(priv); > drm_encoder_cleanup(encoder); > } > > @@ -1854,20 +1848,12 @@ static const struct drm_encoder_funcs tda998x_encoder_funcs = { > .destroy = tda998x_encoder_destroy, > }; > > -static int tda998x_bind(struct device *dev, struct device *master, void *data) > +static int tda998x_encoder_init(struct device *dev, struct drm_device *drm) > { > - struct i2c_client *client = to_i2c_client(dev); > - struct drm_device *drm = data; > - struct tda998x_priv *priv; > + struct tda998x_priv *priv = dev_get_drvdata(dev); > u32 crtcs = 0; > int ret; > > - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); > - if (!priv) > - return -ENOMEM; > - > - dev_set_drvdata(dev, priv); > - > if (dev->of_node) > crtcs = drm_of_find_possible_crtcs(drm, dev->of_node); > > @@ -1879,35 +1865,53 @@ static int tda998x_bind(struct device *dev, struct device *master, void *data) > > priv->encoder.possible_crtcs = crtcs; > > - ret = tda998x_create(client, priv); > - if (ret) > - return ret; > - > - drm_encoder_helper_add(&priv->encoder, &tda998x_encoder_helper_funcs); > ret = drm_encoder_init(drm, &priv->encoder, &tda998x_encoder_funcs, > DRM_MODE_ENCODER_TMDS, NULL); > if (ret) > goto err_encoder; > > - ret = tda998x_connector_init(priv, drm); > + ret = drm_bridge_attach(&priv->encoder, &priv->bridge, NULL); > if (ret) > - goto err_connector; > + goto err_bridge; > > return 0; > > -err_connector: > +err_bridge: > drm_encoder_cleanup(&priv->encoder); > err_encoder: > - tda998x_destroy(priv); > return ret; > } > > +static int tda998x_bind(struct device *dev, struct device *master, void *data) > +{ > + struct i2c_client *client = to_i2c_client(dev); > + struct drm_device *drm = data; > + struct tda998x_priv *priv; > + int ret; > + > + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); > + if (!priv) > + return -ENOMEM; > + > + dev_set_drvdata(dev, priv); > + > + ret = tda998x_create(client, priv); > + if (ret) > + return ret; > + > + ret = tda998x_encoder_init(dev, drm); > + if (ret) { > + tda998x_destroy(priv); > + return ret; > + } > + return 0; > +} > + > static void tda998x_unbind(struct device *dev, struct device *master, > void *data) > { > struct tda998x_priv *priv = dev_get_drvdata(dev); > > - drm_connector_cleanup(&priv->connector); > drm_encoder_cleanup(&priv->encoder); > tda998x_destroy(priv); > } > ^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH v2 4/7] drm/i2c: tda998x: convert to bridge driver 2018-07-30 16:42 ` Russell King @ 2018-08-08 19:09 ` Sean Paul -1 siblings, 0 replies; 80+ messages in thread From: Sean Paul @ 2018-08-08 19:09 UTC (permalink / raw) To: linux-arm-kernel On Mon, Jul 30, 2018 at 05:42:21PM +0100, Russell King wrote: > Convert tda998x to a bridge driver with built-in encoder support for > compatibility with existing component drivers. > > Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> Hi Russell, Thanks for doing the bridge conversion, it certainly seems a better fit. I've cc'd the bridge maintainers/reviewer on this patch so that hopefully they will see it. We should probably also move this driver into bridge/ once it's been reviewed. > --- > drivers/gpu/drm/i2c/tda998x_drv.c | 154 +++++++++++++++++++------------------- > 1 file changed, 79 insertions(+), 75 deletions(-) > > diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c > index 843078e9fbf3..1ea62052f3e0 100644 > --- a/drivers/gpu/drm/i2c/tda998x_drv.c > +++ b/drivers/gpu/drm/i2c/tda998x_drv.c > @@ -69,6 +69,7 @@ struct tda998x_priv { > bool edid_delay_active; > > struct drm_encoder encoder; > + struct drm_bridge bridge; > struct drm_connector connector; > > struct tda998x_audio_port audio_port[2]; > @@ -79,9 +80,10 @@ struct tda998x_priv { > > #define conn_to_tda998x_priv(x) \ > container_of(x, struct tda998x_priv, connector) > - > #define enc_to_tda998x_priv(x) \ > container_of(x, struct tda998x_priv, encoder) > +#define bridge_to_tda998x_priv(x) \ > + container_of(x, struct tda998x_priv, bridge) > > /* The TDA9988 series of devices use a paged register scheme.. to simplify > * things we encode the page # in upper bits of the register #. To read/ > @@ -1262,7 +1264,7 @@ tda998x_connector_best_encoder(struct drm_connector *connector) > { > struct tda998x_priv *priv = conn_to_tda998x_priv(connector); > > - return &priv->encoder; > + return priv->bridge.encoder; > } > > static > @@ -1292,15 +1294,32 @@ static int tda998x_connector_init(struct tda998x_priv *priv, > if (ret) > return ret; > > - drm_mode_connector_attach_encoder(&priv->connector, &priv->encoder); > + drm_mode_connector_attach_encoder(&priv->connector, > + priv->bridge.encoder); > > return 0; > } > > -/* DRM encoder functions */ > +/* DRM bridge functions */ > + > +static int tda998x_bridge_attach(struct drm_bridge *bridge) > +{ > + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); > + > + return tda998x_connector_init(priv, bridge->dev); There doesn't seem to be any benefit to having tda998x_connector_init() as a separate function. I'd suggest just rolling that code in here. > +} > + > +static void tda998x_bridge_detach(struct drm_bridge *bridge) > +{ > + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); > + > + drm_connector_cleanup(&priv->connector); > +} > > -static void tda998x_enable(struct tda998x_priv *priv) > +static void tda998x_bridge_enable(struct drm_bridge *bridge) > { > + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); > + > if (!priv->is_on) { > /* enable video ports, audio will be enabled later */ > reg_write(priv, REG_ENA_VP_0, 0xff); > @@ -1315,8 +1334,10 @@ static void tda998x_enable(struct tda998x_priv *priv) > } > } > > -static void tda998x_disable(struct tda998x_priv *priv) > +static void tda998x_bridge_disable(struct drm_bridge *bridge) > { > + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); > + > if (!priv->is_on) { > /* disable video ports */ > reg_write(priv, REG_ENA_VP_0, 0x00); > @@ -1327,29 +1348,11 @@ static void tda998x_disable(struct tda998x_priv *priv) > } > } > > -static void tda998x_encoder_dpms(struct drm_encoder *encoder, int mode) > +static void tda998x_bridge_mode_set(struct drm_bridge *bridge, > + struct drm_display_mode *mode, > + struct drm_display_mode *adjusted_mode) > { > - struct tda998x_priv *priv = enc_to_tda998x_priv(encoder); > - bool on; > - > - /* we only care about on or off: */ > - on = mode == DRM_MODE_DPMS_ON; > - > - if (on == priv->is_on) > - return; > - > - if (on) > - tda998x_enable(priv); > - else > - tda998x_disable(priv); > -} > - > -static void > -tda998x_encoder_mode_set(struct drm_encoder *encoder, > - struct drm_display_mode *mode, > - struct drm_display_mode *adjusted_mode) > -{ > - struct tda998x_priv *priv = enc_to_tda998x_priv(encoder); > + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); > u16 ref_pix, ref_line, n_pix, n_line; > u16 hs_pix_s, hs_pix_e; > u16 vs1_pix_s, vs1_pix_e, vs1_line_s, vs1_line_e; > @@ -1556,8 +1559,18 @@ tda998x_encoder_mode_set(struct drm_encoder *encoder, > mutex_unlock(&priv->audio_mutex); > } > > +static const struct drm_bridge_funcs tda998x_bridge_funcs = { > + .attach = tda998x_bridge_attach, > + .detach = tda998x_bridge_detach, > + .disable = tda998x_bridge_disable, > + .mode_set = tda998x_bridge_mode_set, > + .enable = tda998x_bridge_enable, > +}; > + > static void tda998x_destroy(struct tda998x_priv *priv) > { > + drm_bridge_remove(&priv->bridge); > + > /* 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); > @@ -1650,6 +1663,7 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) > mutex_init(&priv->mutex); /* protect the page access */ > mutex_init(&priv->audio_mutex); /* protect access from audio thread */ > mutex_init(&priv->edid_mutex); > + INIT_LIST_HEAD(&priv->bridge.list); > init_waitqueue_head(&priv->edid_delay_waitq); > timer_setup(&priv->edid_delay_timer, tda998x_edid_delay_done, 0); > INIT_WORK(&priv->detect_work, tda998x_detect_work); > @@ -1810,43 +1824,23 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) > tda998x_set_config(priv, client->dev.platform_data); > } > > + priv->bridge.funcs = &tda998x_bridge_funcs; > + priv->bridge.of_node = dev->of_node; > + > + drm_bridge_add(&priv->bridge); > + > return 0; > > fail: > - /* if encoder_init fails, the encoder slave is never registered, > - * so cleanup here: > - */ > - i2c_unregister_device(priv->cec); > - if (priv->cec_notify) > - cec_notifier_put(priv->cec_notify); > - if (client->irq) > - free_irq(client->irq, priv); > + tda998x_destroy(priv); > err_irq: > return ret; > } > > -static void tda998x_encoder_prepare(struct drm_encoder *encoder) > -{ > - tda998x_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); > -} > - > -static void tda998x_encoder_commit(struct drm_encoder *encoder) > -{ > - tda998x_encoder_dpms(encoder, DRM_MODE_DPMS_ON); > -} > - > -static const struct drm_encoder_helper_funcs tda998x_encoder_helper_funcs = { > - .dpms = tda998x_encoder_dpms, > - .prepare = tda998x_encoder_prepare, > - .commit = tda998x_encoder_commit, > - .mode_set = tda998x_encoder_mode_set, > -}; Now that encoder is a stub, it should really be removed from here. The encoder should be instantiated elsewhere and attach the bridge to itself. There are a bunch of examples of this in bridge/ > +/* DRM encoder functions */ > > static void tda998x_encoder_destroy(struct drm_encoder *encoder) > { > - struct tda998x_priv *priv = enc_to_tda998x_priv(encoder); > - > - tda998x_destroy(priv); > drm_encoder_cleanup(encoder); > } > > @@ -1854,20 +1848,12 @@ static const struct drm_encoder_funcs tda998x_encoder_funcs = { > .destroy = tda998x_encoder_destroy, Just use drm_encoder_cleanup directly. > }; > > -static int tda998x_bind(struct device *dev, struct device *master, void *data) > +static int tda998x_encoder_init(struct device *dev, struct drm_device *drm) > { > - struct i2c_client *client = to_i2c_client(dev); > - struct drm_device *drm = data; > - struct tda998x_priv *priv; > + struct tda998x_priv *priv = dev_get_drvdata(dev); > u32 crtcs = 0; > int ret; > > - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); > - if (!priv) > - return -ENOMEM; > - > - dev_set_drvdata(dev, priv); > - > if (dev->of_node) > crtcs = drm_of_find_possible_crtcs(drm, dev->of_node); > > @@ -1879,35 +1865,53 @@ static int tda998x_bind(struct device *dev, struct device *master, void *data) > > priv->encoder.possible_crtcs = crtcs; > > - ret = tda998x_create(client, priv); > - if (ret) > - return ret; > - > - drm_encoder_helper_add(&priv->encoder, &tda998x_encoder_helper_funcs); > ret = drm_encoder_init(drm, &priv->encoder, &tda998x_encoder_funcs, > DRM_MODE_ENCODER_TMDS, NULL); > if (ret) > goto err_encoder; > > - ret = tda998x_connector_init(priv, drm); > + ret = drm_bridge_attach(&priv->encoder, &priv->bridge, NULL); > if (ret) > - goto err_connector; > + goto err_bridge; > > return 0; > > -err_connector: > +err_bridge: > drm_encoder_cleanup(&priv->encoder); > err_encoder: > - tda998x_destroy(priv); > return ret; > } > > +static int tda998x_bind(struct device *dev, struct device *master, void *data) > +{ > + struct i2c_client *client = to_i2c_client(dev); > + struct drm_device *drm = data; > + struct tda998x_priv *priv; > + int ret; > + > + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); > + if (!priv) > + return -ENOMEM; > + > + dev_set_drvdata(dev, priv); > + > + ret = tda998x_create(client, priv); > + if (ret) > + return ret; > + > + ret = tda998x_encoder_init(dev, drm); > + if (ret) { > + tda998x_destroy(priv); > + return ret; > + } > + return 0; > +} > + > static void tda998x_unbind(struct device *dev, struct device *master, > void *data) > { > struct tda998x_priv *priv = dev_get_drvdata(dev); > > - drm_connector_cleanup(&priv->connector); > drm_encoder_cleanup(&priv->encoder); > tda998x_destroy(priv); > } > -- > 2.7.4 > > > _______________________________________________ > linux-arm-kernel mailing list > linux-arm-kernel at lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel -- Sean Paul, Software Engineer, Google / Chromium OS ^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PATCH v2 4/7] drm/i2c: tda998x: convert to bridge driver @ 2018-08-08 19:09 ` Sean Paul 0 siblings, 0 replies; 80+ messages in thread From: Sean Paul @ 2018-08-08 19:09 UTC (permalink / raw) To: Russell King Cc: David Airlie, Liviu Dudau, dri-devel, Tomi Valkeinen, Jyri Sarha, Peter Rosin, linux-arm-kernel, Laurent Pinchart On Mon, Jul 30, 2018 at 05:42:21PM +0100, Russell King wrote: > Convert tda998x to a bridge driver with built-in encoder support for > compatibility with existing component drivers. > > Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> Hi Russell, Thanks for doing the bridge conversion, it certainly seems a better fit. I've cc'd the bridge maintainers/reviewer on this patch so that hopefully they will see it. We should probably also move this driver into bridge/ once it's been reviewed. > --- > drivers/gpu/drm/i2c/tda998x_drv.c | 154 +++++++++++++++++++------------------- > 1 file changed, 79 insertions(+), 75 deletions(-) > > diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c > index 843078e9fbf3..1ea62052f3e0 100644 > --- a/drivers/gpu/drm/i2c/tda998x_drv.c > +++ b/drivers/gpu/drm/i2c/tda998x_drv.c > @@ -69,6 +69,7 @@ struct tda998x_priv { > bool edid_delay_active; > > struct drm_encoder encoder; > + struct drm_bridge bridge; > struct drm_connector connector; > > struct tda998x_audio_port audio_port[2]; > @@ -79,9 +80,10 @@ struct tda998x_priv { > > #define conn_to_tda998x_priv(x) \ > container_of(x, struct tda998x_priv, connector) > - > #define enc_to_tda998x_priv(x) \ > container_of(x, struct tda998x_priv, encoder) > +#define bridge_to_tda998x_priv(x) \ > + container_of(x, struct tda998x_priv, bridge) > > /* The TDA9988 series of devices use a paged register scheme.. to simplify > * things we encode the page # in upper bits of the register #. To read/ > @@ -1262,7 +1264,7 @@ tda998x_connector_best_encoder(struct drm_connector *connector) > { > struct tda998x_priv *priv = conn_to_tda998x_priv(connector); > > - return &priv->encoder; > + return priv->bridge.encoder; > } > > static > @@ -1292,15 +1294,32 @@ static int tda998x_connector_init(struct tda998x_priv *priv, > if (ret) > return ret; > > - drm_mode_connector_attach_encoder(&priv->connector, &priv->encoder); > + drm_mode_connector_attach_encoder(&priv->connector, > + priv->bridge.encoder); > > return 0; > } > > -/* DRM encoder functions */ > +/* DRM bridge functions */ > + > +static int tda998x_bridge_attach(struct drm_bridge *bridge) > +{ > + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); > + > + return tda998x_connector_init(priv, bridge->dev); There doesn't seem to be any benefit to having tda998x_connector_init() as a separate function. I'd suggest just rolling that code in here. > +} > + > +static void tda998x_bridge_detach(struct drm_bridge *bridge) > +{ > + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); > + > + drm_connector_cleanup(&priv->connector); > +} > > -static void tda998x_enable(struct tda998x_priv *priv) > +static void tda998x_bridge_enable(struct drm_bridge *bridge) > { > + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); > + > if (!priv->is_on) { > /* enable video ports, audio will be enabled later */ > reg_write(priv, REG_ENA_VP_0, 0xff); > @@ -1315,8 +1334,10 @@ static void tda998x_enable(struct tda998x_priv *priv) > } > } > > -static void tda998x_disable(struct tda998x_priv *priv) > +static void tda998x_bridge_disable(struct drm_bridge *bridge) > { > + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); > + > if (!priv->is_on) { > /* disable video ports */ > reg_write(priv, REG_ENA_VP_0, 0x00); > @@ -1327,29 +1348,11 @@ static void tda998x_disable(struct tda998x_priv *priv) > } > } > > -static void tda998x_encoder_dpms(struct drm_encoder *encoder, int mode) > +static void tda998x_bridge_mode_set(struct drm_bridge *bridge, > + struct drm_display_mode *mode, > + struct drm_display_mode *adjusted_mode) > { > - struct tda998x_priv *priv = enc_to_tda998x_priv(encoder); > - bool on; > - > - /* we only care about on or off: */ > - on = mode == DRM_MODE_DPMS_ON; > - > - if (on == priv->is_on) > - return; > - > - if (on) > - tda998x_enable(priv); > - else > - tda998x_disable(priv); > -} > - > -static void > -tda998x_encoder_mode_set(struct drm_encoder *encoder, > - struct drm_display_mode *mode, > - struct drm_display_mode *adjusted_mode) > -{ > - struct tda998x_priv *priv = enc_to_tda998x_priv(encoder); > + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); > u16 ref_pix, ref_line, n_pix, n_line; > u16 hs_pix_s, hs_pix_e; > u16 vs1_pix_s, vs1_pix_e, vs1_line_s, vs1_line_e; > @@ -1556,8 +1559,18 @@ tda998x_encoder_mode_set(struct drm_encoder *encoder, > mutex_unlock(&priv->audio_mutex); > } > > +static const struct drm_bridge_funcs tda998x_bridge_funcs = { > + .attach = tda998x_bridge_attach, > + .detach = tda998x_bridge_detach, > + .disable = tda998x_bridge_disable, > + .mode_set = tda998x_bridge_mode_set, > + .enable = tda998x_bridge_enable, > +}; > + > static void tda998x_destroy(struct tda998x_priv *priv) > { > + drm_bridge_remove(&priv->bridge); > + > /* 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); > @@ -1650,6 +1663,7 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) > mutex_init(&priv->mutex); /* protect the page access */ > mutex_init(&priv->audio_mutex); /* protect access from audio thread */ > mutex_init(&priv->edid_mutex); > + INIT_LIST_HEAD(&priv->bridge.list); > init_waitqueue_head(&priv->edid_delay_waitq); > timer_setup(&priv->edid_delay_timer, tda998x_edid_delay_done, 0); > INIT_WORK(&priv->detect_work, tda998x_detect_work); > @@ -1810,43 +1824,23 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) > tda998x_set_config(priv, client->dev.platform_data); > } > > + priv->bridge.funcs = &tda998x_bridge_funcs; > + priv->bridge.of_node = dev->of_node; > + > + drm_bridge_add(&priv->bridge); > + > return 0; > > fail: > - /* if encoder_init fails, the encoder slave is never registered, > - * so cleanup here: > - */ > - i2c_unregister_device(priv->cec); > - if (priv->cec_notify) > - cec_notifier_put(priv->cec_notify); > - if (client->irq) > - free_irq(client->irq, priv); > + tda998x_destroy(priv); > err_irq: > return ret; > } > > -static void tda998x_encoder_prepare(struct drm_encoder *encoder) > -{ > - tda998x_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); > -} > - > -static void tda998x_encoder_commit(struct drm_encoder *encoder) > -{ > - tda998x_encoder_dpms(encoder, DRM_MODE_DPMS_ON); > -} > - > -static const struct drm_encoder_helper_funcs tda998x_encoder_helper_funcs = { > - .dpms = tda998x_encoder_dpms, > - .prepare = tda998x_encoder_prepare, > - .commit = tda998x_encoder_commit, > - .mode_set = tda998x_encoder_mode_set, > -}; Now that encoder is a stub, it should really be removed from here. The encoder should be instantiated elsewhere and attach the bridge to itself. There are a bunch of examples of this in bridge/ > +/* DRM encoder functions */ > > static void tda998x_encoder_destroy(struct drm_encoder *encoder) > { > - struct tda998x_priv *priv = enc_to_tda998x_priv(encoder); > - > - tda998x_destroy(priv); > drm_encoder_cleanup(encoder); > } > > @@ -1854,20 +1848,12 @@ static const struct drm_encoder_funcs tda998x_encoder_funcs = { > .destroy = tda998x_encoder_destroy, Just use drm_encoder_cleanup directly. > }; > > -static int tda998x_bind(struct device *dev, struct device *master, void *data) > +static int tda998x_encoder_init(struct device *dev, struct drm_device *drm) > { > - struct i2c_client *client = to_i2c_client(dev); > - struct drm_device *drm = data; > - struct tda998x_priv *priv; > + struct tda998x_priv *priv = dev_get_drvdata(dev); > u32 crtcs = 0; > int ret; > > - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); > - if (!priv) > - return -ENOMEM; > - > - dev_set_drvdata(dev, priv); > - > if (dev->of_node) > crtcs = drm_of_find_possible_crtcs(drm, dev->of_node); > > @@ -1879,35 +1865,53 @@ static int tda998x_bind(struct device *dev, struct device *master, void *data) > > priv->encoder.possible_crtcs = crtcs; > > - ret = tda998x_create(client, priv); > - if (ret) > - return ret; > - > - drm_encoder_helper_add(&priv->encoder, &tda998x_encoder_helper_funcs); > ret = drm_encoder_init(drm, &priv->encoder, &tda998x_encoder_funcs, > DRM_MODE_ENCODER_TMDS, NULL); > if (ret) > goto err_encoder; > > - ret = tda998x_connector_init(priv, drm); > + ret = drm_bridge_attach(&priv->encoder, &priv->bridge, NULL); > if (ret) > - goto err_connector; > + goto err_bridge; > > return 0; > > -err_connector: > +err_bridge: > drm_encoder_cleanup(&priv->encoder); > err_encoder: > - tda998x_destroy(priv); > return ret; > } > > +static int tda998x_bind(struct device *dev, struct device *master, void *data) > +{ > + struct i2c_client *client = to_i2c_client(dev); > + struct drm_device *drm = data; > + struct tda998x_priv *priv; > + int ret; > + > + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); > + if (!priv) > + return -ENOMEM; > + > + dev_set_drvdata(dev, priv); > + > + ret = tda998x_create(client, priv); > + if (ret) > + return ret; > + > + ret = tda998x_encoder_init(dev, drm); > + if (ret) { > + tda998x_destroy(priv); > + return ret; > + } > + return 0; > +} > + > static void tda998x_unbind(struct device *dev, struct device *master, > void *data) > { > struct tda998x_priv *priv = dev_get_drvdata(dev); > > - drm_connector_cleanup(&priv->connector); > drm_encoder_cleanup(&priv->encoder); > tda998x_destroy(priv); > } > -- > 2.7.4 > > > _______________________________________________ > linux-arm-kernel mailing list > linux-arm-kernel@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel -- Sean Paul, Software Engineer, Google / Chromium OS _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH v2 4/7] drm/i2c: tda998x: convert to bridge driver 2018-08-08 19:09 ` Sean Paul @ 2018-08-08 22:15 ` Russell King - ARM Linux -1 siblings, 0 replies; 80+ messages in thread From: Russell King - ARM Linux @ 2018-08-08 22:15 UTC (permalink / raw) To: linux-arm-kernel On Wed, Aug 08, 2018 at 03:09:30PM -0400, Sean Paul wrote: > > -static const struct drm_encoder_helper_funcs tda998x_encoder_helper_funcs = { > > - .dpms = tda998x_encoder_dpms, > > - .prepare = tda998x_encoder_prepare, > > - .commit = tda998x_encoder_commit, > > - .mode_set = tda998x_encoder_mode_set, > > -}; > > Now that encoder is a stub, it should really be removed from here. The encoder > should be instantiated elsewhere and attach the bridge to itself. There are a > bunch of examples of this in bridge/ That's not possible at present - this driver has to remain compatible with Armada and TI LCDC, both of which expect this driver to create the encoder. In any case, bridges are buggy with unbinding/rebinding as I've pointed out several times in the past, but TDA998x used with Armada and TI LCDC as it currently stands are not. So, to do this as a full conversion to bridge and pushing the encoders into the DRM drivers results in a regression for these two DRM drivers. I'm not willing to accept such a regression, sorry. Thanks for the other cleanup suggestions, they can be done with a later patch (these changes have already been been merged.) -- RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line in suburbia: sync at 13.8Mbps down 630kbps up According to speedtest.net: 13Mbps down 490kbps up ^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PATCH v2 4/7] drm/i2c: tda998x: convert to bridge driver @ 2018-08-08 22:15 ` Russell King - ARM Linux 0 siblings, 0 replies; 80+ messages in thread From: Russell King - ARM Linux @ 2018-08-08 22:15 UTC (permalink / raw) To: Sean Paul Cc: Archit Taneja, David Airlie, Liviu Dudau, dri-devel, Andrzej Hajda, Tomi Valkeinen, Jyri Sarha, Peter Rosin, linux-arm-kernel, Laurent Pinchart On Wed, Aug 08, 2018 at 03:09:30PM -0400, Sean Paul wrote: > > -static const struct drm_encoder_helper_funcs tda998x_encoder_helper_funcs = { > > - .dpms = tda998x_encoder_dpms, > > - .prepare = tda998x_encoder_prepare, > > - .commit = tda998x_encoder_commit, > > - .mode_set = tda998x_encoder_mode_set, > > -}; > > Now that encoder is a stub, it should really be removed from here. The encoder > should be instantiated elsewhere and attach the bridge to itself. There are a > bunch of examples of this in bridge/ That's not possible at present - this driver has to remain compatible with Armada and TI LCDC, both of which expect this driver to create the encoder. In any case, bridges are buggy with unbinding/rebinding as I've pointed out several times in the past, but TDA998x used with Armada and TI LCDC as it currently stands are not. So, to do this as a full conversion to bridge and pushing the encoders into the DRM drivers results in a regression for these two DRM drivers. I'm not willing to accept such a regression, sorry. Thanks for the other cleanup suggestions, they can be done with a later patch (these changes have already been been merged.) -- RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line in suburbia: sync at 13.8Mbps down 630kbps up According to speedtest.net: 13Mbps down 490kbps up ^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH v2 4/7] drm/i2c: tda998x: convert to bridge driver 2018-08-08 22:15 ` Russell King - ARM Linux @ 2018-08-10 16:11 ` Sean Paul -1 siblings, 0 replies; 80+ messages in thread From: Sean Paul @ 2018-08-10 16:11 UTC (permalink / raw) To: linux-arm-kernel On Wed, Aug 08, 2018 at 11:15:47PM +0100, Russell King - ARM Linux wrote: > On Wed, Aug 08, 2018 at 03:09:30PM -0400, Sean Paul wrote: > > > -static const struct drm_encoder_helper_funcs tda998x_encoder_helper_funcs = { > > > - .dpms = tda998x_encoder_dpms, > > > - .prepare = tda998x_encoder_prepare, > > > - .commit = tda998x_encoder_commit, > > > - .mode_set = tda998x_encoder_mode_set, > > > -}; > > > > Now that encoder is a stub, it should really be removed from here. The encoder > > should be instantiated elsewhere and attach the bridge to itself. There are a > > bunch of examples of this in bridge/ > > That's not possible at present - this driver has to remain compatible > with Armada and TI LCDC, both of which expect this driver to create > the encoder. Hmm, yeah, I just read that thread. I suppose once bridges play nice with components the encoder can migrate into the drivers? > > In any case, bridges are buggy with unbinding/rebinding as I've pointed > out several times in the past, but TDA998x used with Armada and TI LCDC > as it currently stands are not. So, to do this as a full conversion to > bridge and pushing the encoders into the DRM drivers results in a > regression for these two DRM drivers. I'm not willing to accept such > a regression, sorry. > > Thanks for the other cleanup suggestions, they can be done with a > later patch (these changes have already been been merged.) I still think you should get review from a bridge maintainer before it goes to drm-next. Sean > > -- > RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ > FTTC broadband for 0.8mile line in suburbia: sync at 13.8Mbps down 630kbps up > According to speedtest.net: 13Mbps down 490kbps up -- Sean Paul, Software Engineer, Google / Chromium OS ^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PATCH v2 4/7] drm/i2c: tda998x: convert to bridge driver @ 2018-08-10 16:11 ` Sean Paul 0 siblings, 0 replies; 80+ messages in thread From: Sean Paul @ 2018-08-10 16:11 UTC (permalink / raw) To: Russell King - ARM Linux Cc: David Airlie, Liviu Dudau, dri-devel, Tomi Valkeinen, Jyri Sarha, Peter Rosin, linux-arm-kernel, Laurent Pinchart On Wed, Aug 08, 2018 at 11:15:47PM +0100, Russell King - ARM Linux wrote: > On Wed, Aug 08, 2018 at 03:09:30PM -0400, Sean Paul wrote: > > > -static const struct drm_encoder_helper_funcs tda998x_encoder_helper_funcs = { > > > - .dpms = tda998x_encoder_dpms, > > > - .prepare = tda998x_encoder_prepare, > > > - .commit = tda998x_encoder_commit, > > > - .mode_set = tda998x_encoder_mode_set, > > > -}; > > > > Now that encoder is a stub, it should really be removed from here. The encoder > > should be instantiated elsewhere and attach the bridge to itself. There are a > > bunch of examples of this in bridge/ > > That's not possible at present - this driver has to remain compatible > with Armada and TI LCDC, both of which expect this driver to create > the encoder. Hmm, yeah, I just read that thread. I suppose once bridges play nice with components the encoder can migrate into the drivers? > > In any case, bridges are buggy with unbinding/rebinding as I've pointed > out several times in the past, but TDA998x used with Armada and TI LCDC > as it currently stands are not. So, to do this as a full conversion to > bridge and pushing the encoders into the DRM drivers results in a > regression for these two DRM drivers. I'm not willing to accept such > a regression, sorry. > > Thanks for the other cleanup suggestions, they can be done with a > later patch (these changes have already been been merged.) I still think you should get review from a bridge maintainer before it goes to drm-next. Sean > > -- > RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ > FTTC broadband for 0.8mile line in suburbia: sync at 13.8Mbps down 630kbps up > According to speedtest.net: 13Mbps down 490kbps up -- Sean Paul, Software Engineer, Google / Chromium OS _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH v2 4/7] drm/i2c: tda998x: convert to bridge driver 2018-08-10 16:11 ` Sean Paul @ 2018-08-10 16:50 ` Russell King - ARM Linux -1 siblings, 0 replies; 80+ messages in thread From: Russell King - ARM Linux @ 2018-08-10 16:50 UTC (permalink / raw) To: linux-arm-kernel On Fri, Aug 10, 2018 at 12:11:05PM -0400, Sean Paul wrote: > On Wed, Aug 08, 2018 at 11:15:47PM +0100, Russell King - ARM Linux wrote: > > In any case, bridges are buggy with unbinding/rebinding as I've pointed > > out several times in the past, but TDA998x used with Armada and TI LCDC > > as it currently stands are not. So, to do this as a full conversion to > > bridge and pushing the encoders into the DRM drivers results in a > > regression for these two DRM drivers. I'm not willing to accept such > > a regression, sorry. > > > > Thanks for the other cleanup suggestions, they can be done with a > > later patch (these changes have already been been merged.) > > I still think you should get review from a bridge maintainer before it goes to > drm-next. They are free to review them any time they wish, all the patches are on dri-devel. However "before it goes to drm-next" has been impossible for a while now because David has already pulled it in. Almost none of my DRM specific patches on dri-devel this time around received any feedback what so ever, even after myself and David chasing them up. Over the Armada changes, David Airlie eventually said to me "if it works for you, send it to me I suppose". David also tried poking the tda998x/component discussion thread as well from the beginning of July (or so David told me), with seemingly the same result. So, in summary, it's been almost impossible to get any feedback on any of the patches and discussions I've sent - I think extracting blood from a rock might be easier! ;) I sent a patch about the "broadcast rgb" property - there are no replies to that email, and it was only in a completely different thread that I happened to notice a comment about that patch - it is not a sign of a healthy community to be providing feedback on patches by sending replies to other threads! Yet that seems to be happening on dri-devel! I guess everyone could've gone to the beach (lucky them) because of the hot weather for the last couple of months, and now that it's cooled down in some parts, people are starting to re-engage... If the bridge maintainers eventually get around to reviewing the changes, then, as I've said, any necessary changes can be made later, but what you ask is now impossible - they've been in drm-next since Tuesday evening, and by implication they've been in linux-next too - including last night's linux-next which is the final one before the merge window opens assuming it opens on Sunday. -- RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line in suburbia: sync at 13.8Mbps down 630kbps up According to speedtest.net: 13Mbps down 490kbps up ^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PATCH v2 4/7] drm/i2c: tda998x: convert to bridge driver @ 2018-08-10 16:50 ` Russell King - ARM Linux 0 siblings, 0 replies; 80+ messages in thread From: Russell King - ARM Linux @ 2018-08-10 16:50 UTC (permalink / raw) To: Sean Paul Cc: Archit Taneja, David Airlie, Liviu Dudau, dri-devel, Andrzej Hajda, Tomi Valkeinen, Jyri Sarha, Peter Rosin, linux-arm-kernel, Laurent Pinchart On Fri, Aug 10, 2018 at 12:11:05PM -0400, Sean Paul wrote: > On Wed, Aug 08, 2018 at 11:15:47PM +0100, Russell King - ARM Linux wrote: > > In any case, bridges are buggy with unbinding/rebinding as I've pointed > > out several times in the past, but TDA998x used with Armada and TI LCDC > > as it currently stands are not. So, to do this as a full conversion to > > bridge and pushing the encoders into the DRM drivers results in a > > regression for these two DRM drivers. I'm not willing to accept such > > a regression, sorry. > > > > Thanks for the other cleanup suggestions, they can be done with a > > later patch (these changes have already been been merged.) > > I still think you should get review from a bridge maintainer before it goes to > drm-next. They are free to review them any time they wish, all the patches are on dri-devel. However "before it goes to drm-next" has been impossible for a while now because David has already pulled it in. Almost none of my DRM specific patches on dri-devel this time around received any feedback what so ever, even after myself and David chasing them up. Over the Armada changes, David Airlie eventually said to me "if it works for you, send it to me I suppose". David also tried poking the tda998x/component discussion thread as well from the beginning of July (or so David told me), with seemingly the same result. So, in summary, it's been almost impossible to get any feedback on any of the patches and discussions I've sent - I think extracting blood from a rock might be easier! ;) I sent a patch about the "broadcast rgb" property - there are no replies to that email, and it was only in a completely different thread that I happened to notice a comment about that patch - it is not a sign of a healthy community to be providing feedback on patches by sending replies to other threads! Yet that seems to be happening on dri-devel! I guess everyone could've gone to the beach (lucky them) because of the hot weather for the last couple of months, and now that it's cooled down in some parts, people are starting to re-engage... If the bridge maintainers eventually get around to reviewing the changes, then, as I've said, any necessary changes can be made later, but what you ask is now impossible - they've been in drm-next since Tuesday evening, and by implication they've been in linux-next too - including last night's linux-next which is the final one before the merge window opens assuming it opens on Sunday. -- RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line in suburbia: sync at 13.8Mbps down 630kbps up According to speedtest.net: 13Mbps down 490kbps up ^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH v2 4/7] drm/i2c: tda998x: convert to bridge driver 2018-08-10 16:50 ` Russell King - ARM Linux @ 2018-08-10 17:02 ` Sean Paul -1 siblings, 0 replies; 80+ messages in thread From: Sean Paul @ 2018-08-10 17:02 UTC (permalink / raw) To: linux-arm-kernel On Fri, Aug 10, 2018 at 05:50:37PM +0100, Russell King - ARM Linux wrote: > On Fri, Aug 10, 2018 at 12:11:05PM -0400, Sean Paul wrote: > > On Wed, Aug 08, 2018 at 11:15:47PM +0100, Russell King - ARM Linux wrote: > > > In any case, bridges are buggy with unbinding/rebinding as I've pointed > > > out several times in the past, but TDA998x used with Armada and TI LCDC > > > as it currently stands are not. So, to do this as a full conversion to > > > bridge and pushing the encoders into the DRM drivers results in a > > > regression for these two DRM drivers. I'm not willing to accept such > > > a regression, sorry. > > > > > > Thanks for the other cleanup suggestions, they can be done with a > > > later patch (these changes have already been been merged.) > > > > I still think you should get review from a bridge maintainer before it goes to > > drm-next. > > They are free to review them any time they wish, all the patches are > on dri-devel. However "before it goes to drm-next" has been impossible > for a while now because David has already pulled it in. > Oh, I didn't realize it was already pulled into -next. > Almost none of my DRM specific patches on dri-devel this time around > received any feedback what so ever, even after myself and David chasing > them up. Over the Armada changes, David Airlie eventually said to me > "if it works for you, send it to me I suppose". > > David also tried poking the tda998x/component discussion thread as well > from the beginning of July (or so David told me), with seemingly the > same result. > > So, in summary, it's been almost impossible to get any feedback on any > of the patches and discussions I've sent - I think extracting blood > from a rock might be easier! ;) Yeah, I suspect a lot of people have blinders wrt tda given that it's off in i2c/. Feel free to ping me on irc in future if you're looking for a review. Once tda moves to bridge/ and drm-misc, it'll likely be much easier to get people engaged. > > I sent a patch about the "broadcast rgb" property - there are no replies > to that email, and it was only in a completely different thread that I > happened to notice a comment about that patch - it is not a sign of a > healthy community to be providing feedback on patches by sending replies > to other threads! Yet that seems to be happening on dri-devel! > > I guess everyone could've gone to the beach (lucky them) because of the > hot weather for the last couple of months, and now that it's cooled down > in some parts, people are starting to re-engage... > > If the bridge maintainers eventually get around to reviewing the changes, > then, as I've said, any necessary changes can be made later, but what you > ask is now impossible - they've been in drm-next since Tuesday evening, > and by implication they've been in linux-next too - including last night's > linux-next which is the final one before the merge window opens assuming > it opens on Sunday. FYI, drm-misc (and by extension, bridge drivers) are under feature freeze after rc6 is cut. That soak time in linux-next has proven quite helpful for the stability of drm. Having the bridge conversion spend only a week in linux-next before merge window is not ideal. Again, nothing that can be done about that now, but keep that in mind for future. Sean > > -- > RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ > FTTC broadband for 0.8mile line in suburbia: sync at 13.8Mbps down 630kbps up > According to speedtest.net: 13Mbps down 490kbps up -- Sean Paul, Software Engineer, Google / Chromium OS ^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PATCH v2 4/7] drm/i2c: tda998x: convert to bridge driver @ 2018-08-10 17:02 ` Sean Paul 0 siblings, 0 replies; 80+ messages in thread From: Sean Paul @ 2018-08-10 17:02 UTC (permalink / raw) To: Russell King - ARM Linux Cc: David Airlie, Liviu Dudau, dri-devel, Tomi Valkeinen, Jyri Sarha, Peter Rosin, linux-arm-kernel, Laurent Pinchart On Fri, Aug 10, 2018 at 05:50:37PM +0100, Russell King - ARM Linux wrote: > On Fri, Aug 10, 2018 at 12:11:05PM -0400, Sean Paul wrote: > > On Wed, Aug 08, 2018 at 11:15:47PM +0100, Russell King - ARM Linux wrote: > > > In any case, bridges are buggy with unbinding/rebinding as I've pointed > > > out several times in the past, but TDA998x used with Armada and TI LCDC > > > as it currently stands are not. So, to do this as a full conversion to > > > bridge and pushing the encoders into the DRM drivers results in a > > > regression for these two DRM drivers. I'm not willing to accept such > > > a regression, sorry. > > > > > > Thanks for the other cleanup suggestions, they can be done with a > > > later patch (these changes have already been been merged.) > > > > I still think you should get review from a bridge maintainer before it goes to > > drm-next. > > They are free to review them any time they wish, all the patches are > on dri-devel. However "before it goes to drm-next" has been impossible > for a while now because David has already pulled it in. > Oh, I didn't realize it was already pulled into -next. > Almost none of my DRM specific patches on dri-devel this time around > received any feedback what so ever, even after myself and David chasing > them up. Over the Armada changes, David Airlie eventually said to me > "if it works for you, send it to me I suppose". > > David also tried poking the tda998x/component discussion thread as well > from the beginning of July (or so David told me), with seemingly the > same result. > > So, in summary, it's been almost impossible to get any feedback on any > of the patches and discussions I've sent - I think extracting blood > from a rock might be easier! ;) Yeah, I suspect a lot of people have blinders wrt tda given that it's off in i2c/. Feel free to ping me on irc in future if you're looking for a review. Once tda moves to bridge/ and drm-misc, it'll likely be much easier to get people engaged. > > I sent a patch about the "broadcast rgb" property - there are no replies > to that email, and it was only in a completely different thread that I > happened to notice a comment about that patch - it is not a sign of a > healthy community to be providing feedback on patches by sending replies > to other threads! Yet that seems to be happening on dri-devel! > > I guess everyone could've gone to the beach (lucky them) because of the > hot weather for the last couple of months, and now that it's cooled down > in some parts, people are starting to re-engage... > > If the bridge maintainers eventually get around to reviewing the changes, > then, as I've said, any necessary changes can be made later, but what you > ask is now impossible - they've been in drm-next since Tuesday evening, > and by implication they've been in linux-next too - including last night's > linux-next which is the final one before the merge window opens assuming > it opens on Sunday. FYI, drm-misc (and by extension, bridge drivers) are under feature freeze after rc6 is cut. That soak time in linux-next has proven quite helpful for the stability of drm. Having the bridge conversion spend only a week in linux-next before merge window is not ideal. Again, nothing that can be done about that now, but keep that in mind for future. Sean > > -- > RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ > FTTC broadband for 0.8mile line in suburbia: sync at 13.8Mbps down 630kbps up > According to speedtest.net: 13Mbps down 490kbps up -- Sean Paul, Software Engineer, Google / Chromium OS _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH v2 4/7] drm/i2c: tda998x: convert to bridge driver 2018-08-10 17:02 ` Sean Paul @ 2018-08-10 17:16 ` Russell King - ARM Linux -1 siblings, 0 replies; 80+ messages in thread From: Russell King - ARM Linux @ 2018-08-10 17:16 UTC (permalink / raw) To: linux-arm-kernel On Fri, Aug 10, 2018 at 01:02:29PM -0400, Sean Paul wrote: > On Fri, Aug 10, 2018 at 05:50:37PM +0100, Russell King - ARM Linux wrote: > > Almost none of my DRM specific patches on dri-devel this time around > > received any feedback what so ever, even after myself and David chasing > > them up. Over the Armada changes, David Airlie eventually said to me > > "if it works for you, send it to me I suppose". > > > > David also tried poking the tda998x/component discussion thread as well > > from the beginning of July (or so David told me), with seemingly the > > same result. > > > > So, in summary, it's been almost impossible to get any feedback on any > > of the patches and discussions I've sent - I think extracting blood > > from a rock might be easier! ;) > > Yeah, I suspect a lot of people have blinders wrt tda given that it's off in > i2c/. Feel free to ping me on irc in future if you're looking for a review. Once > tda moves to bridge/ and drm-misc, it'll likely be much easier to get people > engaged. I suspect that those who actually use it don't have such blinders, yet they also have ignored the patches despite being copied with them. I can't see that the location of the driver would make any difference for them. -- RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line in suburbia: sync at 13.8Mbps down 630kbps up According to speedtest.net: 13Mbps down 490kbps up ^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PATCH v2 4/7] drm/i2c: tda998x: convert to bridge driver @ 2018-08-10 17:16 ` Russell King - ARM Linux 0 siblings, 0 replies; 80+ messages in thread From: Russell King - ARM Linux @ 2018-08-10 17:16 UTC (permalink / raw) To: Sean Paul Cc: Archit Taneja, David Airlie, Liviu Dudau, dri-devel, Andrzej Hajda, Tomi Valkeinen, Jyri Sarha, Peter Rosin, linux-arm-kernel, Laurent Pinchart On Fri, Aug 10, 2018 at 01:02:29PM -0400, Sean Paul wrote: > On Fri, Aug 10, 2018 at 05:50:37PM +0100, Russell King - ARM Linux wrote: > > Almost none of my DRM specific patches on dri-devel this time around > > received any feedback what so ever, even after myself and David chasing > > them up. Over the Armada changes, David Airlie eventually said to me > > "if it works for you, send it to me I suppose". > > > > David also tried poking the tda998x/component discussion thread as well > > from the beginning of July (or so David told me), with seemingly the > > same result. > > > > So, in summary, it's been almost impossible to get any feedback on any > > of the patches and discussions I've sent - I think extracting blood > > from a rock might be easier! ;) > > Yeah, I suspect a lot of people have blinders wrt tda given that it's off in > i2c/. Feel free to ping me on irc in future if you're looking for a review. Once > tda moves to bridge/ and drm-misc, it'll likely be much easier to get people > engaged. I suspect that those who actually use it don't have such blinders, yet they also have ignored the patches despite being copied with them. I can't see that the location of the driver would make any difference for them. -- RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line in suburbia: sync at 13.8Mbps down 630kbps up According to speedtest.net: 13Mbps down 490kbps up ^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH v2 4/7] drm/i2c: tda998x: convert to bridge driver 2018-08-10 17:16 ` Russell King - ARM Linux @ 2018-08-14 10:42 ` Daniel Vetter -1 siblings, 0 replies; 80+ messages in thread From: Daniel Vetter @ 2018-08-14 10:42 UTC (permalink / raw) To: linux-arm-kernel On Fri, Aug 10, 2018 at 06:16:30PM +0100, Russell King - ARM Linux wrote: > On Fri, Aug 10, 2018 at 01:02:29PM -0400, Sean Paul wrote: > > On Fri, Aug 10, 2018 at 05:50:37PM +0100, Russell King - ARM Linux wrote: > > > Almost none of my DRM specific patches on dri-devel this time around > > > received any feedback what so ever, even after myself and David chasing > > > them up. Over the Armada changes, David Airlie eventually said to me > > > "if it works for you, send it to me I suppose". > > > > > > David also tried poking the tda998x/component discussion thread as well > > > from the beginning of July (or so David told me), with seemingly the > > > same result. > > > > > > So, in summary, it's been almost impossible to get any feedback on any > > > of the patches and discussions I've sent - I think extracting blood > > > from a rock might be easier! ;) > > > > Yeah, I suspect a lot of people have blinders wrt tda given that it's off in > > i2c/. Feel free to ping me on irc in future if you're looking for a review. Once > > tda moves to bridge/ and drm-misc, it'll likely be much easier to get people > > engaged. > > I suspect that those who actually use it don't have such blinders, yet > they also have ignored the patches despite being copied with them. I > can't see that the location of the driver would make any difference > for them. Expecting review to magically happen doesn't work. You need to actively solicit that, and often that involves a bit of reviewing trading. Especially anywhere where a part of the kernel is officially group-maintained like drm_bridge. Given your past track record of handling other contributors I think it's entirely understandably that people do not choose to collaborate with you voluntarily. Fixing that is entirely up to you though. I good first step here would imo be to move the tda driver under bridge, formally put it under the drm-misc group maintainership, actively solict and ack for that from other bridge maintainers and then also suggest other authors and contributors to the tda driver to join as committers and co-maintainers. Thanks, Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch ^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PATCH v2 4/7] drm/i2c: tda998x: convert to bridge driver @ 2018-08-14 10:42 ` Daniel Vetter 0 siblings, 0 replies; 80+ messages in thread From: Daniel Vetter @ 2018-08-14 10:42 UTC (permalink / raw) To: Russell King - ARM Linux Cc: David Airlie, Liviu Dudau, Jyri Sarha, Tomi Valkeinen, dri-devel, Peter Rosin, linux-arm-kernel, Laurent Pinchart On Fri, Aug 10, 2018 at 06:16:30PM +0100, Russell King - ARM Linux wrote: > On Fri, Aug 10, 2018 at 01:02:29PM -0400, Sean Paul wrote: > > On Fri, Aug 10, 2018 at 05:50:37PM +0100, Russell King - ARM Linux wrote: > > > Almost none of my DRM specific patches on dri-devel this time around > > > received any feedback what so ever, even after myself and David chasing > > > them up. Over the Armada changes, David Airlie eventually said to me > > > "if it works for you, send it to me I suppose". > > > > > > David also tried poking the tda998x/component discussion thread as well > > > from the beginning of July (or so David told me), with seemingly the > > > same result. > > > > > > So, in summary, it's been almost impossible to get any feedback on any > > > of the patches and discussions I've sent - I think extracting blood > > > from a rock might be easier! ;) > > > > Yeah, I suspect a lot of people have blinders wrt tda given that it's off in > > i2c/. Feel free to ping me on irc in future if you're looking for a review. Once > > tda moves to bridge/ and drm-misc, it'll likely be much easier to get people > > engaged. > > I suspect that those who actually use it don't have such blinders, yet > they also have ignored the patches despite being copied with them. I > can't see that the location of the driver would make any difference > for them. Expecting review to magically happen doesn't work. You need to actively solicit that, and often that involves a bit of reviewing trading. Especially anywhere where a part of the kernel is officially group-maintained like drm_bridge. Given your past track record of handling other contributors I think it's entirely understandably that people do not choose to collaborate with you voluntarily. Fixing that is entirely up to you though. I good first step here would imo be to move the tda driver under bridge, formally put it under the drm-misc group maintainership, actively solict and ack for that from other bridge maintainers and then also suggest other authors and contributors to the tda driver to join as committers and co-maintainers. Thanks, Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH v2 4/7] drm/i2c: tda998x: convert to bridge driver 2018-08-14 10:42 ` Daniel Vetter @ 2018-08-14 10:48 ` Russell King - ARM Linux -1 siblings, 0 replies; 80+ messages in thread From: Russell King - ARM Linux @ 2018-08-14 10:48 UTC (permalink / raw) To: linux-arm-kernel On Tue, Aug 14, 2018 at 12:42:42PM +0200, Daniel Vetter wrote: > Given your past track record of handling other contributors I think it's > entirely understandably that people do not choose to collaborate with you > voluntarily. Fixing that is entirely up to you though. I do not work piecemeal. I work in blocks, so at some point, I'll switch to working on X, and then I'll work on X until that's complete before moving on to Y. It's more efficient use of my time, otherwise I have to constantly context switch - and that leads to mistakes. I'm sorry that you don't think that's a good way of working, and you find that unacceptable, and you blame this on lack of collaboration. -- RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line in suburbia: sync at 13.8Mbps down 630kbps up According to speedtest.net: 13Mbps down 490kbps up ^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PATCH v2 4/7] drm/i2c: tda998x: convert to bridge driver @ 2018-08-14 10:48 ` Russell King - ARM Linux 0 siblings, 0 replies; 80+ messages in thread From: Russell King - ARM Linux @ 2018-08-14 10:48 UTC (permalink / raw) To: Daniel Vetter Cc: David Airlie, Liviu Dudau, Jyri Sarha, Tomi Valkeinen, Sean Paul, dri-devel, Peter Rosin, linux-arm-kernel, Laurent Pinchart On Tue, Aug 14, 2018 at 12:42:42PM +0200, Daniel Vetter wrote: > Given your past track record of handling other contributors I think it's > entirely understandably that people do not choose to collaborate with you > voluntarily. Fixing that is entirely up to you though. I do not work piecemeal. I work in blocks, so at some point, I'll switch to working on X, and then I'll work on X until that's complete before moving on to Y. It's more efficient use of my time, otherwise I have to constantly context switch - and that leads to mistakes. I'm sorry that you don't think that's a good way of working, and you find that unacceptable, and you blame this on lack of collaboration. -- RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line in suburbia: sync at 13.8Mbps down 630kbps up According to speedtest.net: 13Mbps down 490kbps up ^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH v2 4/7] drm/i2c: tda998x: convert to bridge driver 2018-08-14 10:48 ` Russell King - ARM Linux @ 2018-08-14 11:11 ` Daniel Vetter -1 siblings, 0 replies; 80+ messages in thread From: Daniel Vetter @ 2018-08-14 11:11 UTC (permalink / raw) To: linux-arm-kernel On Tue, Aug 14, 2018 at 12:48 PM, Russell King - ARM Linux <linux@armlinux.org.uk> wrote: > On Tue, Aug 14, 2018 at 12:42:42PM +0200, Daniel Vetter wrote: >> Given your past track record of handling other contributors I think it's >> entirely understandably that people do not choose to collaborate with you >> voluntarily. Fixing that is entirely up to you though. > > I do not work piecemeal. I work in blocks, so at some point, I'll > switch to working on X, and then I'll work on X until that's complete > before moving on to Y. It's more efficient use of my time, otherwise > I have to constantly context switch - and that leads to mistakes. > > I'm sorry that you don't think that's a good way of working, and you > find that unacceptable, and you blame this on lack of collaboration. Maybe it's not clear, but I'm not referring to how you schedule your own time here. I've referred to your downright abuse behaviour in past years here on dri-devel, which only stopped once we've put a full formal Code of Conduct into place, including enforcement. Up to and including simply throwing existing maintainers out. You blaming others for not reviewing your patches in this context is simply victim blaming. You do not get to blame others for the consequence of your past actions. It took you years of abuse emails to get there, it will take you years of hard constructive work and showing your best behaviour only, with no blaming others, to restore your reputation. Thanks, Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PATCH v2 4/7] drm/i2c: tda998x: convert to bridge driver @ 2018-08-14 11:11 ` Daniel Vetter 0 siblings, 0 replies; 80+ messages in thread From: Daniel Vetter @ 2018-08-14 11:11 UTC (permalink / raw) To: Russell King - ARM Linux Cc: David Airlie, Liviu Dudau, Jyri Sarha, Tomi Valkeinen, dri-devel, Peter Rosin, Linux ARM, Laurent Pinchart On Tue, Aug 14, 2018 at 12:48 PM, Russell King - ARM Linux <linux@armlinux.org.uk> wrote: > On Tue, Aug 14, 2018 at 12:42:42PM +0200, Daniel Vetter wrote: >> Given your past track record of handling other contributors I think it's >> entirely understandably that people do not choose to collaborate with you >> voluntarily. Fixing that is entirely up to you though. > > I do not work piecemeal. I work in blocks, so at some point, I'll > switch to working on X, and then I'll work on X until that's complete > before moving on to Y. It's more efficient use of my time, otherwise > I have to constantly context switch - and that leads to mistakes. > > I'm sorry that you don't think that's a good way of working, and you > find that unacceptable, and you blame this on lack of collaboration. Maybe it's not clear, but I'm not referring to how you schedule your own time here. I've referred to your downright abuse behaviour in past years here on dri-devel, which only stopped once we've put a full formal Code of Conduct into place, including enforcement. Up to and including simply throwing existing maintainers out. You blaming others for not reviewing your patches in this context is simply victim blaming. You do not get to blame others for the consequence of your past actions. It took you years of abuse emails to get there, it will take you years of hard constructive work and showing your best behaviour only, with no blaming others, to restore your reputation. Thanks, Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH v2 4/7] drm/i2c: tda998x: convert to bridge driver 2018-07-30 16:42 ` Russell King @ 2018-08-27 16:15 ` Andrzej Hajda -1 siblings, 0 replies; 80+ messages in thread From: Andrzej Hajda @ 2018-08-27 16:15 UTC (permalink / raw) To: linux-arm-kernel On 30.07.2018 18:42, Russell King wrote: > Convert tda998x to a bridge driver with built-in encoder support for > compatibility with existing component drivers. > > Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> > --- > drivers/gpu/drm/i2c/tda998x_drv.c | 154 +++++++++++++++++++------------------- > 1 file changed, 79 insertions(+), 75 deletions(-) > > diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c > index 843078e9fbf3..1ea62052f3e0 100644 > --- a/drivers/gpu/drm/i2c/tda998x_drv.c > +++ b/drivers/gpu/drm/i2c/tda998x_drv.c > @@ -69,6 +69,7 @@ struct tda998x_priv { > bool edid_delay_active; > > struct drm_encoder encoder; > + struct drm_bridge bridge; > struct drm_connector connector; > > struct tda998x_audio_port audio_port[2]; > @@ -79,9 +80,10 @@ struct tda998x_priv { > > #define conn_to_tda998x_priv(x) \ > container_of(x, struct tda998x_priv, connector) > - > #define enc_to_tda998x_priv(x) \ > container_of(x, struct tda998x_priv, encoder) > +#define bridge_to_tda998x_priv(x) \ > + container_of(x, struct tda998x_priv, bridge) > > /* The TDA9988 series of devices use a paged register scheme.. to simplify > * things we encode the page # in upper bits of the register #. To read/ > @@ -1262,7 +1264,7 @@ tda998x_connector_best_encoder(struct drm_connector *connector) > { > struct tda998x_priv *priv = conn_to_tda998x_priv(connector); > > - return &priv->encoder; > + return priv->bridge.encoder; > } > > static > @@ -1292,15 +1294,32 @@ static int tda998x_connector_init(struct tda998x_priv *priv, > if (ret) > return ret; > > - drm_mode_connector_attach_encoder(&priv->connector, &priv->encoder); > + drm_mode_connector_attach_encoder(&priv->connector, > + priv->bridge.encoder); > > return 0; > } > > -/* DRM encoder functions */ > +/* DRM bridge functions */ > + > +static int tda998x_bridge_attach(struct drm_bridge *bridge) > +{ > + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); > + > + return tda998x_connector_init(priv, bridge->dev); > +} > + > +static void tda998x_bridge_detach(struct drm_bridge *bridge) > +{ > + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); > + > + drm_connector_cleanup(&priv->connector); > +} > > -static void tda998x_enable(struct tda998x_priv *priv) > +static void tda998x_bridge_enable(struct drm_bridge *bridge) > { > + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); > + > if (!priv->is_on) { > /* enable video ports, audio will be enabled later */ > reg_write(priv, REG_ENA_VP_0, 0xff); > @@ -1315,8 +1334,10 @@ static void tda998x_enable(struct tda998x_priv *priv) > } > } > > -static void tda998x_disable(struct tda998x_priv *priv) > +static void tda998x_bridge_disable(struct drm_bridge *bridge) > { > + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); > + > if (!priv->is_on) { > /* disable video ports */ > reg_write(priv, REG_ENA_VP_0, 0x00); > @@ -1327,29 +1348,11 @@ static void tda998x_disable(struct tda998x_priv *priv) > } > } > > -static void tda998x_encoder_dpms(struct drm_encoder *encoder, int mode) > +static void tda998x_bridge_mode_set(struct drm_bridge *bridge, > + struct drm_display_mode *mode, > + struct drm_display_mode *adjusted_mode) > { > - struct tda998x_priv *priv = enc_to_tda998x_priv(encoder); > - bool on; > - > - /* we only care about on or off: */ > - on = mode == DRM_MODE_DPMS_ON; > - > - if (on == priv->is_on) > - return; > - > - if (on) > - tda998x_enable(priv); > - else > - tda998x_disable(priv); > -} > - > -static void > -tda998x_encoder_mode_set(struct drm_encoder *encoder, > - struct drm_display_mode *mode, > - struct drm_display_mode *adjusted_mode) > -{ > - struct tda998x_priv *priv = enc_to_tda998x_priv(encoder); > + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); > u16 ref_pix, ref_line, n_pix, n_line; > u16 hs_pix_s, hs_pix_e; > u16 vs1_pix_s, vs1_pix_e, vs1_line_s, vs1_line_e; > @@ -1556,8 +1559,18 @@ tda998x_encoder_mode_set(struct drm_encoder *encoder, > mutex_unlock(&priv->audio_mutex); > } > > +static const struct drm_bridge_funcs tda998x_bridge_funcs = { > + .attach = tda998x_bridge_attach, > + .detach = tda998x_bridge_detach, > + .disable = tda998x_bridge_disable, > + .mode_set = tda998x_bridge_mode_set, > + .enable = tda998x_bridge_enable, > +}; > + > static void tda998x_destroy(struct tda998x_priv *priv) > { > + drm_bridge_remove(&priv->bridge); > + > /* 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); > @@ -1650,6 +1663,7 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) > mutex_init(&priv->mutex); /* protect the page access */ > mutex_init(&priv->audio_mutex); /* protect access from audio thread */ > mutex_init(&priv->edid_mutex); > + INIT_LIST_HEAD(&priv->bridge.list); This line can be probably removed, unless there is a reason I am not aware of. > init_waitqueue_head(&priv->edid_delay_waitq); > timer_setup(&priv->edid_delay_timer, tda998x_edid_delay_done, 0); > INIT_WORK(&priv->detect_work, tda998x_detect_work); > @@ -1810,43 +1824,23 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) > tda998x_set_config(priv, client->dev.platform_data); > } > > + priv->bridge.funcs = &tda998x_bridge_funcs; > + priv->bridge.of_node = dev->of_node; > + > + drm_bridge_add(&priv->bridge); > + > return 0; > > fail: > - /* if encoder_init fails, the encoder slave is never registered, > - * so cleanup here: > - */ > - i2c_unregister_device(priv->cec); > - if (priv->cec_notify) > - cec_notifier_put(priv->cec_notify); > - if (client->irq) > - free_irq(client->irq, priv); > + tda998x_destroy(priv); > err_irq: > return ret; > } > > -static void tda998x_encoder_prepare(struct drm_encoder *encoder) > -{ > - tda998x_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); > -} > - > -static void tda998x_encoder_commit(struct drm_encoder *encoder) > -{ > - tda998x_encoder_dpms(encoder, DRM_MODE_DPMS_ON); > -} > - > -static const struct drm_encoder_helper_funcs tda998x_encoder_helper_funcs = { > - .dpms = tda998x_encoder_dpms, > - .prepare = tda998x_encoder_prepare, > - .commit = tda998x_encoder_commit, > - .mode_set = tda998x_encoder_mode_set, > -}; > +/* DRM encoder functions */ > > static void tda998x_encoder_destroy(struct drm_encoder *encoder) > { > - struct tda998x_priv *priv = enc_to_tda998x_priv(encoder); > - > - tda998x_destroy(priv); > drm_encoder_cleanup(encoder); > } > > @@ -1854,20 +1848,12 @@ static const struct drm_encoder_funcs tda998x_encoder_funcs = { > .destroy = tda998x_encoder_destroy, > }; > > -static int tda998x_bind(struct device *dev, struct device *master, void *data) > +static int tda998x_encoder_init(struct device *dev, struct drm_device *drm) > { > - struct i2c_client *client = to_i2c_client(dev); > - struct drm_device *drm = data; > - struct tda998x_priv *priv; > + struct tda998x_priv *priv = dev_get_drvdata(dev); > u32 crtcs = 0; > int ret; > > - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); > - if (!priv) > - return -ENOMEM; > - > - dev_set_drvdata(dev, priv); > - > if (dev->of_node) > crtcs = drm_of_find_possible_crtcs(drm, dev->of_node); > > @@ -1879,35 +1865,53 @@ static int tda998x_bind(struct device *dev, struct device *master, void *data) > > priv->encoder.possible_crtcs = crtcs; > > - ret = tda998x_create(client, priv); > - if (ret) > - return ret; > - > - drm_encoder_helper_add(&priv->encoder, &tda998x_encoder_helper_funcs); > ret = drm_encoder_init(drm, &priv->encoder, &tda998x_encoder_funcs, > DRM_MODE_ENCODER_TMDS, NULL); > if (ret) > goto err_encoder; > > - ret = tda998x_connector_init(priv, drm); > + ret = drm_bridge_attach(&priv->encoder, &priv->bridge, NULL); > if (ret) > - goto err_connector; > + goto err_bridge; > > return 0; > > -err_connector: > +err_bridge: > drm_encoder_cleanup(&priv->encoder); > err_encoder: > - tda998x_destroy(priv); > return ret; > } > > +static int tda998x_bind(struct device *dev, struct device *master, void *data) > +{ > + struct i2c_client *client = to_i2c_client(dev); > + struct drm_device *drm = data; > + struct tda998x_priv *priv; > + int ret; > + > + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); > + if (!priv) > + return -ENOMEM; > + > + dev_set_drvdata(dev, priv); > + > + ret = tda998x_create(client, priv); > + if (ret) > + return ret; > + > + ret = tda998x_encoder_init(dev, drm); > + if (ret) { > + tda998x_destroy(priv); > + return ret; > + } > + return 0; It could be replaced by: ??? ret = tda998x_encoder_init(dev, drm); ??? if (ret) ??? ??? tda998x_destroy(priv); ??? return ret; but this is probably matter of taste. Moreover I guess priv->is_on could be removed if enable/disable callbacks are called only by drm_core, but this is for another patch. With removed initialization of bridge.list: Reviewed-by: Andrzej Hajda <a.hajda@samsung.com> ?-- Regards Andrzej > +} > + > static void tda998x_unbind(struct device *dev, struct device *master, > void *data) > { > struct tda998x_priv *priv = dev_get_drvdata(dev); > > - drm_connector_cleanup(&priv->connector); > drm_encoder_cleanup(&priv->encoder); > tda998x_destroy(priv); > } ^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PATCH v2 4/7] drm/i2c: tda998x: convert to bridge driver @ 2018-08-27 16:15 ` Andrzej Hajda 0 siblings, 0 replies; 80+ messages in thread From: Andrzej Hajda @ 2018-08-27 16:15 UTC (permalink / raw) To: Russell King, dri-devel, linux-arm-kernel Cc: David Airlie, Tomi Valkeinen, Liviu Dudau, Peter Rosin, Jyri Sarha On 30.07.2018 18:42, Russell King wrote: > Convert tda998x to a bridge driver with built-in encoder support for > compatibility with existing component drivers. > > Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> > --- > drivers/gpu/drm/i2c/tda998x_drv.c | 154 +++++++++++++++++++------------------- > 1 file changed, 79 insertions(+), 75 deletions(-) > > diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c > index 843078e9fbf3..1ea62052f3e0 100644 > --- a/drivers/gpu/drm/i2c/tda998x_drv.c > +++ b/drivers/gpu/drm/i2c/tda998x_drv.c > @@ -69,6 +69,7 @@ struct tda998x_priv { > bool edid_delay_active; > > struct drm_encoder encoder; > + struct drm_bridge bridge; > struct drm_connector connector; > > struct tda998x_audio_port audio_port[2]; > @@ -79,9 +80,10 @@ struct tda998x_priv { > > #define conn_to_tda998x_priv(x) \ > container_of(x, struct tda998x_priv, connector) > - > #define enc_to_tda998x_priv(x) \ > container_of(x, struct tda998x_priv, encoder) > +#define bridge_to_tda998x_priv(x) \ > + container_of(x, struct tda998x_priv, bridge) > > /* The TDA9988 series of devices use a paged register scheme.. to simplify > * things we encode the page # in upper bits of the register #. To read/ > @@ -1262,7 +1264,7 @@ tda998x_connector_best_encoder(struct drm_connector *connector) > { > struct tda998x_priv *priv = conn_to_tda998x_priv(connector); > > - return &priv->encoder; > + return priv->bridge.encoder; > } > > static > @@ -1292,15 +1294,32 @@ static int tda998x_connector_init(struct tda998x_priv *priv, > if (ret) > return ret; > > - drm_mode_connector_attach_encoder(&priv->connector, &priv->encoder); > + drm_mode_connector_attach_encoder(&priv->connector, > + priv->bridge.encoder); > > return 0; > } > > -/* DRM encoder functions */ > +/* DRM bridge functions */ > + > +static int tda998x_bridge_attach(struct drm_bridge *bridge) > +{ > + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); > + > + return tda998x_connector_init(priv, bridge->dev); > +} > + > +static void tda998x_bridge_detach(struct drm_bridge *bridge) > +{ > + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); > + > + drm_connector_cleanup(&priv->connector); > +} > > -static void tda998x_enable(struct tda998x_priv *priv) > +static void tda998x_bridge_enable(struct drm_bridge *bridge) > { > + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); > + > if (!priv->is_on) { > /* enable video ports, audio will be enabled later */ > reg_write(priv, REG_ENA_VP_0, 0xff); > @@ -1315,8 +1334,10 @@ static void tda998x_enable(struct tda998x_priv *priv) > } > } > > -static void tda998x_disable(struct tda998x_priv *priv) > +static void tda998x_bridge_disable(struct drm_bridge *bridge) > { > + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); > + > if (!priv->is_on) { > /* disable video ports */ > reg_write(priv, REG_ENA_VP_0, 0x00); > @@ -1327,29 +1348,11 @@ static void tda998x_disable(struct tda998x_priv *priv) > } > } > > -static void tda998x_encoder_dpms(struct drm_encoder *encoder, int mode) > +static void tda998x_bridge_mode_set(struct drm_bridge *bridge, > + struct drm_display_mode *mode, > + struct drm_display_mode *adjusted_mode) > { > - struct tda998x_priv *priv = enc_to_tda998x_priv(encoder); > - bool on; > - > - /* we only care about on or off: */ > - on = mode == DRM_MODE_DPMS_ON; > - > - if (on == priv->is_on) > - return; > - > - if (on) > - tda998x_enable(priv); > - else > - tda998x_disable(priv); > -} > - > -static void > -tda998x_encoder_mode_set(struct drm_encoder *encoder, > - struct drm_display_mode *mode, > - struct drm_display_mode *adjusted_mode) > -{ > - struct tda998x_priv *priv = enc_to_tda998x_priv(encoder); > + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); > u16 ref_pix, ref_line, n_pix, n_line; > u16 hs_pix_s, hs_pix_e; > u16 vs1_pix_s, vs1_pix_e, vs1_line_s, vs1_line_e; > @@ -1556,8 +1559,18 @@ tda998x_encoder_mode_set(struct drm_encoder *encoder, > mutex_unlock(&priv->audio_mutex); > } > > +static const struct drm_bridge_funcs tda998x_bridge_funcs = { > + .attach = tda998x_bridge_attach, > + .detach = tda998x_bridge_detach, > + .disable = tda998x_bridge_disable, > + .mode_set = tda998x_bridge_mode_set, > + .enable = tda998x_bridge_enable, > +}; > + > static void tda998x_destroy(struct tda998x_priv *priv) > { > + drm_bridge_remove(&priv->bridge); > + > /* 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); > @@ -1650,6 +1663,7 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) > mutex_init(&priv->mutex); /* protect the page access */ > mutex_init(&priv->audio_mutex); /* protect access from audio thread */ > mutex_init(&priv->edid_mutex); > + INIT_LIST_HEAD(&priv->bridge.list); This line can be probably removed, unless there is a reason I am not aware of. > init_waitqueue_head(&priv->edid_delay_waitq); > timer_setup(&priv->edid_delay_timer, tda998x_edid_delay_done, 0); > INIT_WORK(&priv->detect_work, tda998x_detect_work); > @@ -1810,43 +1824,23 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) > tda998x_set_config(priv, client->dev.platform_data); > } > > + priv->bridge.funcs = &tda998x_bridge_funcs; > + priv->bridge.of_node = dev->of_node; > + > + drm_bridge_add(&priv->bridge); > + > return 0; > > fail: > - /* if encoder_init fails, the encoder slave is never registered, > - * so cleanup here: > - */ > - i2c_unregister_device(priv->cec); > - if (priv->cec_notify) > - cec_notifier_put(priv->cec_notify); > - if (client->irq) > - free_irq(client->irq, priv); > + tda998x_destroy(priv); > err_irq: > return ret; > } > > -static void tda998x_encoder_prepare(struct drm_encoder *encoder) > -{ > - tda998x_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); > -} > - > -static void tda998x_encoder_commit(struct drm_encoder *encoder) > -{ > - tda998x_encoder_dpms(encoder, DRM_MODE_DPMS_ON); > -} > - > -static const struct drm_encoder_helper_funcs tda998x_encoder_helper_funcs = { > - .dpms = tda998x_encoder_dpms, > - .prepare = tda998x_encoder_prepare, > - .commit = tda998x_encoder_commit, > - .mode_set = tda998x_encoder_mode_set, > -}; > +/* DRM encoder functions */ > > static void tda998x_encoder_destroy(struct drm_encoder *encoder) > { > - struct tda998x_priv *priv = enc_to_tda998x_priv(encoder); > - > - tda998x_destroy(priv); > drm_encoder_cleanup(encoder); > } > > @@ -1854,20 +1848,12 @@ static const struct drm_encoder_funcs tda998x_encoder_funcs = { > .destroy = tda998x_encoder_destroy, > }; > > -static int tda998x_bind(struct device *dev, struct device *master, void *data) > +static int tda998x_encoder_init(struct device *dev, struct drm_device *drm) > { > - struct i2c_client *client = to_i2c_client(dev); > - struct drm_device *drm = data; > - struct tda998x_priv *priv; > + struct tda998x_priv *priv = dev_get_drvdata(dev); > u32 crtcs = 0; > int ret; > > - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); > - if (!priv) > - return -ENOMEM; > - > - dev_set_drvdata(dev, priv); > - > if (dev->of_node) > crtcs = drm_of_find_possible_crtcs(drm, dev->of_node); > > @@ -1879,35 +1865,53 @@ static int tda998x_bind(struct device *dev, struct device *master, void *data) > > priv->encoder.possible_crtcs = crtcs; > > - ret = tda998x_create(client, priv); > - if (ret) > - return ret; > - > - drm_encoder_helper_add(&priv->encoder, &tda998x_encoder_helper_funcs); > ret = drm_encoder_init(drm, &priv->encoder, &tda998x_encoder_funcs, > DRM_MODE_ENCODER_TMDS, NULL); > if (ret) > goto err_encoder; > > - ret = tda998x_connector_init(priv, drm); > + ret = drm_bridge_attach(&priv->encoder, &priv->bridge, NULL); > if (ret) > - goto err_connector; > + goto err_bridge; > > return 0; > > -err_connector: > +err_bridge: > drm_encoder_cleanup(&priv->encoder); > err_encoder: > - tda998x_destroy(priv); > return ret; > } > > +static int tda998x_bind(struct device *dev, struct device *master, void *data) > +{ > + struct i2c_client *client = to_i2c_client(dev); > + struct drm_device *drm = data; > + struct tda998x_priv *priv; > + int ret; > + > + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); > + if (!priv) > + return -ENOMEM; > + > + dev_set_drvdata(dev, priv); > + > + ret = tda998x_create(client, priv); > + if (ret) > + return ret; > + > + ret = tda998x_encoder_init(dev, drm); > + if (ret) { > + tda998x_destroy(priv); > + return ret; > + } > + return 0; It could be replaced by: ret = tda998x_encoder_init(dev, drm); if (ret) tda998x_destroy(priv); return ret; but this is probably matter of taste. Moreover I guess priv->is_on could be removed if enable/disable callbacks are called only by drm_core, but this is for another patch. With removed initialization of bridge.list: Reviewed-by: Andrzej Hajda <a.hajda@samsung.com> -- Regards Andrzej > +} > + > static void tda998x_unbind(struct device *dev, struct device *master, > void *data) > { > struct tda998x_priv *priv = dev_get_drvdata(dev); > > - drm_connector_cleanup(&priv->connector); > drm_encoder_cleanup(&priv->encoder); > tda998x_destroy(priv); > } _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH v2 4/7] drm/i2c: tda998x: convert to bridge driver 2018-08-27 16:15 ` Andrzej Hajda @ 2018-08-27 17:59 ` Russell King - ARM Linux -1 siblings, 0 replies; 80+ messages in thread From: Russell King - ARM Linux @ 2018-08-27 17:59 UTC (permalink / raw) To: linux-arm-kernel Hi Andrzej, On Mon, Aug 27, 2018 at 06:15:59PM +0200, Andrzej Hajda wrote: > On 30.07.2018 18:42, Russell King wrote: > > static void tda998x_destroy(struct tda998x_priv *priv) > > { > > + drm_bridge_remove(&priv->bridge); > > + > > /* 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); > > @@ -1650,6 +1663,7 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) > > mutex_init(&priv->mutex); /* protect the page access */ > > mutex_init(&priv->audio_mutex); /* protect access from audio thread */ > > mutex_init(&priv->edid_mutex); > > + INIT_LIST_HEAD(&priv->bridge.list); > > This line can be probably removed, unless there is a reason I am not > aware of. The addition above of drm_bridge_remove() to tda998x_destroy() means that we end up calling this function in the error cleanup path. This avoids unnecessary complexity with lots of different gotos - tda998x has had a long history of not cleaning up stuff properly. devm interfaces for bridge do not help avoid that - devm stuff only works if everything that is registered previously is cleaned up via devm mechanisms to ensure that a device's interface becomes unavailable before stuff (eg, edid timers, detect work) is started to be cleaned up. Otherwise, there's a chance of this stuff being triggered during tear-down. > > +static int tda998x_bind(struct device *dev, struct device *master, void *data) > > +{ > > + struct i2c_client *client = to_i2c_client(dev); > > + struct drm_device *drm = data; > > + struct tda998x_priv *priv; > > + int ret; > > + > > + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); > > + if (!priv) > > + return -ENOMEM; > > + > > + dev_set_drvdata(dev, priv); > > + > > + ret = tda998x_create(client, priv); > > + if (ret) > > + return ret; > > + > > + ret = tda998x_encoder_init(dev, drm); > > + if (ret) { > > + tda998x_destroy(priv); > > + return ret; > > + } > > + return 0; > > It could be replaced by: > ??? ret = tda998x_encoder_init(dev, drm); > ??? if (ret) > ??? ??? tda998x_destroy(priv); > ??? return ret; > > but this is probably matter of taste. It's not clear to me what "It" is - I think you're suggesting combining tda998x_create() and tda998x_encoder_init() ? The code is structured this way to make the following patches easier - there is no point of combining things only to have to then break them apart again in a later patch. Please see patch 7, where tda998x_create() moves out of this function, where exactly this happens. > Moreover I guess priv->is_on could be removed if enable/disable > callbacks are called only by drm_core, but this is for another patch. Is it guaranteed that a bridge ->enable or ->disable callback won't be called twice, even for legacy drivers? I think atomic guarantees this but I don't think it's guaranteed for legacy drivers. I'm guessing Rob had a reason why he added the check when he originally created the driver (encoder ->dpms can be called for the same dpms state multiple times?) -- RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line in suburbia: sync at 13.8Mbps down 630kbps up According to speedtest.net: 13Mbps down 490kbps up ^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PATCH v2 4/7] drm/i2c: tda998x: convert to bridge driver @ 2018-08-27 17:59 ` Russell King - ARM Linux 0 siblings, 0 replies; 80+ messages in thread From: Russell King - ARM Linux @ 2018-08-27 17:59 UTC (permalink / raw) To: Andrzej Hajda Cc: David Airlie, Liviu Dudau, dri-devel, Tomi Valkeinen, Jyri Sarha, Peter Rosin, linux-arm-kernel Hi Andrzej, On Mon, Aug 27, 2018 at 06:15:59PM +0200, Andrzej Hajda wrote: > On 30.07.2018 18:42, Russell King wrote: > > static void tda998x_destroy(struct tda998x_priv *priv) > > { > > + drm_bridge_remove(&priv->bridge); > > + > > /* 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); > > @@ -1650,6 +1663,7 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) > > mutex_init(&priv->mutex); /* protect the page access */ > > mutex_init(&priv->audio_mutex); /* protect access from audio thread */ > > mutex_init(&priv->edid_mutex); > > + INIT_LIST_HEAD(&priv->bridge.list); > > This line can be probably removed, unless there is a reason I am not > aware of. The addition above of drm_bridge_remove() to tda998x_destroy() means that we end up calling this function in the error cleanup path. This avoids unnecessary complexity with lots of different gotos - tda998x has had a long history of not cleaning up stuff properly. devm interfaces for bridge do not help avoid that - devm stuff only works if everything that is registered previously is cleaned up via devm mechanisms to ensure that a device's interface becomes unavailable before stuff (eg, edid timers, detect work) is started to be cleaned up. Otherwise, there's a chance of this stuff being triggered during tear-down. > > +static int tda998x_bind(struct device *dev, struct device *master, void *data) > > +{ > > + struct i2c_client *client = to_i2c_client(dev); > > + struct drm_device *drm = data; > > + struct tda998x_priv *priv; > > + int ret; > > + > > + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); > > + if (!priv) > > + return -ENOMEM; > > + > > + dev_set_drvdata(dev, priv); > > + > > + ret = tda998x_create(client, priv); > > + if (ret) > > + return ret; > > + > > + ret = tda998x_encoder_init(dev, drm); > > + if (ret) { > > + tda998x_destroy(priv); > > + return ret; > > + } > > + return 0; > > It could be replaced by: > ret = tda998x_encoder_init(dev, drm); > if (ret) > tda998x_destroy(priv); > return ret; > > but this is probably matter of taste. It's not clear to me what "It" is - I think you're suggesting combining tda998x_create() and tda998x_encoder_init() ? The code is structured this way to make the following patches easier - there is no point of combining things only to have to then break them apart again in a later patch. Please see patch 7, where tda998x_create() moves out of this function, where exactly this happens. > Moreover I guess priv->is_on could be removed if enable/disable > callbacks are called only by drm_core, but this is for another patch. Is it guaranteed that a bridge ->enable or ->disable callback won't be called twice, even for legacy drivers? I think atomic guarantees this but I don't think it's guaranteed for legacy drivers. I'm guessing Rob had a reason why he added the check when he originally created the driver (encoder ->dpms can be called for the same dpms state multiple times?) -- RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line in suburbia: sync at 13.8Mbps down 630kbps up According to speedtest.net: 13Mbps down 490kbps up _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH v2 4/7] drm/i2c: tda998x: convert to bridge driver 2018-08-27 17:59 ` Russell King - ARM Linux @ 2018-08-28 7:31 ` Andrzej Hajda -1 siblings, 0 replies; 80+ messages in thread From: Andrzej Hajda @ 2018-08-28 7:31 UTC (permalink / raw) To: linux-arm-kernel On 27.08.2018 19:59, Russell King - ARM Linux wrote: > Hi Andrzej, > > On Mon, Aug 27, 2018 at 06:15:59PM +0200, Andrzej Hajda wrote: >> On 30.07.2018 18:42, Russell King wrote: >>> static void tda998x_destroy(struct tda998x_priv *priv) >>> { >>> + drm_bridge_remove(&priv->bridge); >>> + >>> /* 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); >>> @@ -1650,6 +1663,7 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) >>> mutex_init(&priv->mutex); /* protect the page access */ >>> mutex_init(&priv->audio_mutex); /* protect access from audio thread */ >>> mutex_init(&priv->edid_mutex); >>> + INIT_LIST_HEAD(&priv->bridge.list); >> This line can be probably removed, unless there is a reason I am not >> aware of. > The addition above of drm_bridge_remove() to tda998x_destroy() means > that we end up calling this function in the error cleanup path. This > avoids unnecessary complexity with lots of different gotos - tda998x > has had a long history of not cleaning up stuff properly. 1. bridge.list is/should be a private field of drm_bridge framework, so it's direct usage in driver looks like layer violation. 2. Calling drm_bridge_remove() without drm_bridge_add() is not strictly forbidden, but at least looks very suspicious. Even if current implementation tolerates it, it can change in the future. Neither argument is a blocker IMO so if you prefer to stay with current solution please add a comment in the code explaining why do you initializes list field, the code at first sight looks suspicious. > devm interfaces for bridge do not help avoid that - devm stuff only > works if everything that is registered previously is cleaned up via > devm mechanisms to ensure that a device's interface becomes unavailable > before stuff (eg, edid timers, detect work) is started to be cleaned up. > Otherwise, there's a chance of this stuff being triggered during > tear-down. > >>> +static int tda998x_bind(struct device *dev, struct device *master, void *data) >>> +{ >>> + struct i2c_client *client = to_i2c_client(dev); >>> + struct drm_device *drm = data; >>> + struct tda998x_priv *priv; >>> + int ret; >>> + >>> + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); >>> + if (!priv) >>> + return -ENOMEM; >>> + >>> + dev_set_drvdata(dev, priv); >>> + >>> + ret = tda998x_create(client, priv); >>> + if (ret) >>> + return ret; >>> + >>> + ret = tda998x_encoder_init(dev, drm); >>> + if (ret) { >>> + tda998x_destroy(priv); >>> + return ret; >>> + } >>> + return 0; >> It could be replaced by: >> ??? ret = tda998x_encoder_init(dev, drm); >> ??? if (ret) >> ??? ??? tda998x_destroy(priv); >> ??? return ret; >> >> but this is probably matter of taste. > It's not clear to me what "It" is - I think you're suggesting combining > tda998x_create() and tda998x_encoder_init() ? No, just simplifying error path. > > The code is structured this way to make the following patches easier - > there is no point of combining things only to have to then break them > apart again in a later patch. Please see patch 7, where tda998x_create() > moves out of this function, where exactly this happens. OK. As I said: up to you. > >> Moreover I guess priv->is_on could be removed if enable/disable >> callbacks are called only by drm_core, but this is for another patch. > Is it guaranteed that a bridge ->enable or ->disable callback won't be > called twice, even for legacy drivers? I think atomic guarantees this > but I don't think it's guaranteed for legacy drivers. > > I'm guessing Rob had a reason why he added the check when he originally > created the driver (encoder ->dpms can be called for the same dpms > state multiple times?) > OK, my guess was incorrect. Regards Andrzej ^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PATCH v2 4/7] drm/i2c: tda998x: convert to bridge driver @ 2018-08-28 7:31 ` Andrzej Hajda 0 siblings, 0 replies; 80+ messages in thread From: Andrzej Hajda @ 2018-08-28 7:31 UTC (permalink / raw) To: Russell King - ARM Linux Cc: David Airlie, Liviu Dudau, dri-devel, Tomi Valkeinen, Jyri Sarha, Peter Rosin, linux-arm-kernel On 27.08.2018 19:59, Russell King - ARM Linux wrote: > Hi Andrzej, > > On Mon, Aug 27, 2018 at 06:15:59PM +0200, Andrzej Hajda wrote: >> On 30.07.2018 18:42, Russell King wrote: >>> static void tda998x_destroy(struct tda998x_priv *priv) >>> { >>> + drm_bridge_remove(&priv->bridge); >>> + >>> /* 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); >>> @@ -1650,6 +1663,7 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) >>> mutex_init(&priv->mutex); /* protect the page access */ >>> mutex_init(&priv->audio_mutex); /* protect access from audio thread */ >>> mutex_init(&priv->edid_mutex); >>> + INIT_LIST_HEAD(&priv->bridge.list); >> This line can be probably removed, unless there is a reason I am not >> aware of. > The addition above of drm_bridge_remove() to tda998x_destroy() means > that we end up calling this function in the error cleanup path. This > avoids unnecessary complexity with lots of different gotos - tda998x > has had a long history of not cleaning up stuff properly. 1. bridge.list is/should be a private field of drm_bridge framework, so it's direct usage in driver looks like layer violation. 2. Calling drm_bridge_remove() without drm_bridge_add() is not strictly forbidden, but at least looks very suspicious. Even if current implementation tolerates it, it can change in the future. Neither argument is a blocker IMO so if you prefer to stay with current solution please add a comment in the code explaining why do you initializes list field, the code at first sight looks suspicious. > devm interfaces for bridge do not help avoid that - devm stuff only > works if everything that is registered previously is cleaned up via > devm mechanisms to ensure that a device's interface becomes unavailable > before stuff (eg, edid timers, detect work) is started to be cleaned up. > Otherwise, there's a chance of this stuff being triggered during > tear-down. > >>> +static int tda998x_bind(struct device *dev, struct device *master, void *data) >>> +{ >>> + struct i2c_client *client = to_i2c_client(dev); >>> + struct drm_device *drm = data; >>> + struct tda998x_priv *priv; >>> + int ret; >>> + >>> + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); >>> + if (!priv) >>> + return -ENOMEM; >>> + >>> + dev_set_drvdata(dev, priv); >>> + >>> + ret = tda998x_create(client, priv); >>> + if (ret) >>> + return ret; >>> + >>> + ret = tda998x_encoder_init(dev, drm); >>> + if (ret) { >>> + tda998x_destroy(priv); >>> + return ret; >>> + } >>> + return 0; >> It could be replaced by: >> ret = tda998x_encoder_init(dev, drm); >> if (ret) >> tda998x_destroy(priv); >> return ret; >> >> but this is probably matter of taste. > It's not clear to me what "It" is - I think you're suggesting combining > tda998x_create() and tda998x_encoder_init() ? No, just simplifying error path. > > The code is structured this way to make the following patches easier - > there is no point of combining things only to have to then break them > apart again in a later patch. Please see patch 7, where tda998x_create() > moves out of this function, where exactly this happens. OK. As I said: up to you. > >> Moreover I guess priv->is_on could be removed if enable/disable >> callbacks are called only by drm_core, but this is for another patch. > Is it guaranteed that a bridge ->enable or ->disable callback won't be > called twice, even for legacy drivers? I think atomic guarantees this > but I don't think it's guaranteed for legacy drivers. > > I'm guessing Rob had a reason why he added the check when he originally > created the driver (encoder ->dpms can be called for the same dpms > state multiple times?) > OK, my guess was incorrect. Regards Andrzej _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH v2 5/7] drm/i2c: tda998x: allocate tda998x_priv inside tda998x_create() 2018-07-30 16:41 ` Russell King - ARM Linux @ 2018-07-30 16:42 ` Russell King -1 siblings, 0 replies; 80+ messages in thread From: Russell King @ 2018-07-30 16:42 UTC (permalink / raw) To: linux-arm-kernel Move the tda998x_priv allocation inside tda998x_create() and simplify the tda998x_create()'s arguments. Pass the same to tda998x_destroy(). Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> --- drivers/gpu/drm/i2c/tda998x_drv.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index 1ea62052f3e0..476161967742 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -1567,8 +1567,10 @@ static const struct drm_bridge_funcs tda998x_bridge_funcs = { .enable = tda998x_bridge_enable, }; -static void tda998x_destroy(struct tda998x_priv *priv) +static void tda998x_destroy(struct device *dev) { + struct tda998x_priv *priv = dev_get_drvdata(dev); + drm_bridge_remove(&priv->bridge); /* disable all IRQs and free the IRQ handler */ @@ -1653,13 +1655,21 @@ static void tda998x_set_config(struct tda998x_priv *priv, priv->audio_params = p->audio_params; } -static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) +static int tda998x_create(struct device *dev) { + struct i2c_client *client = to_i2c_client(dev); struct device_node *np = client->dev.of_node; struct i2c_board_info cec_info; + struct tda998x_priv *priv; u32 video; int rev_lo, rev_hi, ret; + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + dev_set_drvdata(dev, priv); + mutex_init(&priv->mutex); /* protect the page access */ mutex_init(&priv->audio_mutex); /* protect access from audio thread */ mutex_init(&priv->edid_mutex); @@ -1832,7 +1842,7 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) return 0; fail: - tda998x_destroy(priv); + tda998x_destroy(dev); err_irq: return ret; } @@ -1884,24 +1894,16 @@ static int tda998x_encoder_init(struct device *dev, struct drm_device *drm) static int tda998x_bind(struct device *dev, struct device *master, void *data) { - struct i2c_client *client = to_i2c_client(dev); struct drm_device *drm = data; - struct tda998x_priv *priv; int ret; - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - dev_set_drvdata(dev, priv); - - ret = tda998x_create(client, priv); + ret = tda998x_create(dev); if (ret) return ret; ret = tda998x_encoder_init(dev, drm); if (ret) { - tda998x_destroy(priv); + tda998x_destroy(dev); return ret; } return 0; @@ -1913,7 +1915,7 @@ static void tda998x_unbind(struct device *dev, struct device *master, struct tda998x_priv *priv = dev_get_drvdata(dev); drm_encoder_cleanup(&priv->encoder); - tda998x_destroy(priv); + tda998x_destroy(dev); } static const struct component_ops tda998x_ops = { -- 2.7.4 ^ permalink raw reply related [flat|nested] 80+ messages in thread
* [PATCH v2 5/7] drm/i2c: tda998x: allocate tda998x_priv inside tda998x_create() @ 2018-07-30 16:42 ` Russell King 0 siblings, 0 replies; 80+ messages in thread From: Russell King @ 2018-07-30 16:42 UTC (permalink / raw) To: dri-devel, linux-arm-kernel Cc: David Airlie, Tomi Valkeinen, Liviu Dudau, Peter Rosin, Jyri Sarha Move the tda998x_priv allocation inside tda998x_create() and simplify the tda998x_create()'s arguments. Pass the same to tda998x_destroy(). Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> --- drivers/gpu/drm/i2c/tda998x_drv.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index 1ea62052f3e0..476161967742 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -1567,8 +1567,10 @@ static const struct drm_bridge_funcs tda998x_bridge_funcs = { .enable = tda998x_bridge_enable, }; -static void tda998x_destroy(struct tda998x_priv *priv) +static void tda998x_destroy(struct device *dev) { + struct tda998x_priv *priv = dev_get_drvdata(dev); + drm_bridge_remove(&priv->bridge); /* disable all IRQs and free the IRQ handler */ @@ -1653,13 +1655,21 @@ static void tda998x_set_config(struct tda998x_priv *priv, priv->audio_params = p->audio_params; } -static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) +static int tda998x_create(struct device *dev) { + struct i2c_client *client = to_i2c_client(dev); struct device_node *np = client->dev.of_node; struct i2c_board_info cec_info; + struct tda998x_priv *priv; u32 video; int rev_lo, rev_hi, ret; + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + dev_set_drvdata(dev, priv); + mutex_init(&priv->mutex); /* protect the page access */ mutex_init(&priv->audio_mutex); /* protect access from audio thread */ mutex_init(&priv->edid_mutex); @@ -1832,7 +1842,7 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) return 0; fail: - tda998x_destroy(priv); + tda998x_destroy(dev); err_irq: return ret; } @@ -1884,24 +1894,16 @@ static int tda998x_encoder_init(struct device *dev, struct drm_device *drm) static int tda998x_bind(struct device *dev, struct device *master, void *data) { - struct i2c_client *client = to_i2c_client(dev); struct drm_device *drm = data; - struct tda998x_priv *priv; int ret; - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - dev_set_drvdata(dev, priv); - - ret = tda998x_create(client, priv); + ret = tda998x_create(dev); if (ret) return ret; ret = tda998x_encoder_init(dev, drm); if (ret) { - tda998x_destroy(priv); + tda998x_destroy(dev); return ret; } return 0; @@ -1913,7 +1915,7 @@ static void tda998x_unbind(struct device *dev, struct device *master, struct tda998x_priv *priv = dev_get_drvdata(dev); drm_encoder_cleanup(&priv->encoder); - tda998x_destroy(priv); + tda998x_destroy(dev); } static const struct component_ops tda998x_ops = { -- 2.7.4 ^ permalink raw reply related [flat|nested] 80+ messages in thread
* [PATCH v2 6/7] drm/i2c: tda998x: cleanup from previous changes 2018-07-30 16:41 ` Russell King - ARM Linux @ 2018-07-30 16:42 ` Russell King -1 siblings, 0 replies; 80+ messages in thread From: Russell King @ 2018-07-30 16:42 UTC (permalink / raw) To: linux-arm-kernel Cleanup the code a little from the effects of the previous changes: - Move tda998x_destroy() to be above tda998x_create() - Use 'dev' directly in tda998x_create() where appropriate. Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> --- drivers/gpu/drm/i2c/tda998x_drv.c | 76 +++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 39 deletions(-) diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index 476161967742..ea71602d1139 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -1567,31 +1567,6 @@ static const struct drm_bridge_funcs tda998x_bridge_funcs = { .enable = tda998x_bridge_enable, }; -static void tda998x_destroy(struct device *dev) -{ - struct tda998x_priv *priv = dev_get_drvdata(dev); - - drm_bridge_remove(&priv->bridge); - - /* 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->audio_pdev) - platform_device_unregister(priv->audio_pdev); - - if (priv->hdmi->irq) - free_irq(priv->hdmi->irq, priv); - - del_timer_sync(&priv->edid_delay_timer); - cancel_work_sync(&priv->detect_work); - - i2c_unregister_device(priv->cec); - - if (priv->cec_notify) - cec_notifier_put(priv->cec_notify); -} - /* I2C driver functions */ static int tda998x_get_audio_ports(struct tda998x_priv *priv, @@ -1655,6 +1630,31 @@ static void tda998x_set_config(struct tda998x_priv *priv, priv->audio_params = p->audio_params; } +static void tda998x_destroy(struct device *dev) +{ + struct tda998x_priv *priv = dev_get_drvdata(dev); + + drm_bridge_remove(&priv->bridge); + + /* 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->audio_pdev) + platform_device_unregister(priv->audio_pdev); + + if (priv->hdmi->irq) + free_irq(priv->hdmi->irq, priv); + + del_timer_sync(&priv->edid_delay_timer); + cancel_work_sync(&priv->detect_work); + + i2c_unregister_device(priv->cec); + + if (priv->cec_notify) + cec_notifier_put(priv->cec_notify); +} + static int tda998x_create(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -1696,13 +1696,13 @@ static int tda998x_create(struct device *dev) /* read version: */ rev_lo = reg_read(priv, REG_VERSION_LSB); if (rev_lo < 0) { - dev_err(&client->dev, "failed to read version: %d\n", rev_lo); + dev_err(dev, "failed to read version: %d\n", rev_lo); return rev_lo; } rev_hi = reg_read(priv, REG_VERSION_MSB); if (rev_hi < 0) { - dev_err(&client->dev, "failed to read version: %d\n", rev_hi); + dev_err(dev, "failed to read version: %d\n", rev_hi); return rev_hi; } @@ -1713,20 +1713,19 @@ static int tda998x_create(struct device *dev) switch (priv->rev) { case TDA9989N2: - dev_info(&client->dev, "found TDA9989 n2"); + dev_info(dev, "found TDA9989 n2"); break; case TDA19989: - dev_info(&client->dev, "found TDA19989"); + dev_info(dev, "found TDA19989"); break; case TDA19989N2: - dev_info(&client->dev, "found TDA19989 n2"); + dev_info(dev, "found TDA19989 n2"); break; case TDA19988: - dev_info(&client->dev, "found TDA19988"); + dev_info(dev, "found TDA19988"); break; default: - dev_err(&client->dev, "found unsupported device: %04x\n", - priv->rev); + dev_err(dev, "found unsupported device: %04x\n", priv->rev); return -ENXIO; } @@ -1769,8 +1768,7 @@ static int tda998x_create(struct device *dev) tda998x_irq_thread, irq_flags, "tda998x", priv); if (ret) { - dev_err(&client->dev, - "failed to request IRQ#%u: %d\n", + dev_err(dev, "failed to request IRQ#%u: %d\n", client->irq, ret); goto err_irq; } @@ -1779,13 +1777,13 @@ static int tda998x_create(struct device *dev) cec_write(priv, REG_CEC_RXSHPDINTENA, CEC_RXSHPDLEV_HPD); } - priv->cec_notify = cec_notifier_get(&client->dev); + priv->cec_notify = cec_notifier_get(dev); if (!priv->cec_notify) { ret = -ENOMEM; goto fail; } - priv->cec_glue.parent = &client->dev; + priv->cec_glue.parent = dev; priv->cec_glue.data = priv; priv->cec_glue.init = tda998x_cec_hook_init; priv->cec_glue.exit = tda998x_cec_hook_exit; @@ -1830,8 +1828,8 @@ static int tda998x_create(struct device *dev) if (priv->audio_port[0].format != AFMT_UNUSED) tda998x_audio_codec_init(priv, &client->dev); - } else if (client->dev.platform_data) { - tda998x_set_config(priv, client->dev.platform_data); + } else if (dev->platform_data) { + tda998x_set_config(priv, dev->platform_data); } priv->bridge.funcs = &tda998x_bridge_funcs; -- 2.7.4 ^ permalink raw reply related [flat|nested] 80+ messages in thread
* [PATCH v2 6/7] drm/i2c: tda998x: cleanup from previous changes @ 2018-07-30 16:42 ` Russell King 0 siblings, 0 replies; 80+ messages in thread From: Russell King @ 2018-07-30 16:42 UTC (permalink / raw) To: dri-devel, linux-arm-kernel Cc: David Airlie, Tomi Valkeinen, Liviu Dudau, Peter Rosin, Jyri Sarha Cleanup the code a little from the effects of the previous changes: - Move tda998x_destroy() to be above tda998x_create() - Use 'dev' directly in tda998x_create() where appropriate. Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> --- drivers/gpu/drm/i2c/tda998x_drv.c | 76 +++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 39 deletions(-) diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index 476161967742..ea71602d1139 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -1567,31 +1567,6 @@ static const struct drm_bridge_funcs tda998x_bridge_funcs = { .enable = tda998x_bridge_enable, }; -static void tda998x_destroy(struct device *dev) -{ - struct tda998x_priv *priv = dev_get_drvdata(dev); - - drm_bridge_remove(&priv->bridge); - - /* 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->audio_pdev) - platform_device_unregister(priv->audio_pdev); - - if (priv->hdmi->irq) - free_irq(priv->hdmi->irq, priv); - - del_timer_sync(&priv->edid_delay_timer); - cancel_work_sync(&priv->detect_work); - - i2c_unregister_device(priv->cec); - - if (priv->cec_notify) - cec_notifier_put(priv->cec_notify); -} - /* I2C driver functions */ static int tda998x_get_audio_ports(struct tda998x_priv *priv, @@ -1655,6 +1630,31 @@ static void tda998x_set_config(struct tda998x_priv *priv, priv->audio_params = p->audio_params; } +static void tda998x_destroy(struct device *dev) +{ + struct tda998x_priv *priv = dev_get_drvdata(dev); + + drm_bridge_remove(&priv->bridge); + + /* 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->audio_pdev) + platform_device_unregister(priv->audio_pdev); + + if (priv->hdmi->irq) + free_irq(priv->hdmi->irq, priv); + + del_timer_sync(&priv->edid_delay_timer); + cancel_work_sync(&priv->detect_work); + + i2c_unregister_device(priv->cec); + + if (priv->cec_notify) + cec_notifier_put(priv->cec_notify); +} + static int tda998x_create(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -1696,13 +1696,13 @@ static int tda998x_create(struct device *dev) /* read version: */ rev_lo = reg_read(priv, REG_VERSION_LSB); if (rev_lo < 0) { - dev_err(&client->dev, "failed to read version: %d\n", rev_lo); + dev_err(dev, "failed to read version: %d\n", rev_lo); return rev_lo; } rev_hi = reg_read(priv, REG_VERSION_MSB); if (rev_hi < 0) { - dev_err(&client->dev, "failed to read version: %d\n", rev_hi); + dev_err(dev, "failed to read version: %d\n", rev_hi); return rev_hi; } @@ -1713,20 +1713,19 @@ static int tda998x_create(struct device *dev) switch (priv->rev) { case TDA9989N2: - dev_info(&client->dev, "found TDA9989 n2"); + dev_info(dev, "found TDA9989 n2"); break; case TDA19989: - dev_info(&client->dev, "found TDA19989"); + dev_info(dev, "found TDA19989"); break; case TDA19989N2: - dev_info(&client->dev, "found TDA19989 n2"); + dev_info(dev, "found TDA19989 n2"); break; case TDA19988: - dev_info(&client->dev, "found TDA19988"); + dev_info(dev, "found TDA19988"); break; default: - dev_err(&client->dev, "found unsupported device: %04x\n", - priv->rev); + dev_err(dev, "found unsupported device: %04x\n", priv->rev); return -ENXIO; } @@ -1769,8 +1768,7 @@ static int tda998x_create(struct device *dev) tda998x_irq_thread, irq_flags, "tda998x", priv); if (ret) { - dev_err(&client->dev, - "failed to request IRQ#%u: %d\n", + dev_err(dev, "failed to request IRQ#%u: %d\n", client->irq, ret); goto err_irq; } @@ -1779,13 +1777,13 @@ static int tda998x_create(struct device *dev) cec_write(priv, REG_CEC_RXSHPDINTENA, CEC_RXSHPDLEV_HPD); } - priv->cec_notify = cec_notifier_get(&client->dev); + priv->cec_notify = cec_notifier_get(dev); if (!priv->cec_notify) { ret = -ENOMEM; goto fail; } - priv->cec_glue.parent = &client->dev; + priv->cec_glue.parent = dev; priv->cec_glue.data = priv; priv->cec_glue.init = tda998x_cec_hook_init; priv->cec_glue.exit = tda998x_cec_hook_exit; @@ -1830,8 +1828,8 @@ static int tda998x_create(struct device *dev) if (priv->audio_port[0].format != AFMT_UNUSED) tda998x_audio_codec_init(priv, &client->dev); - } else if (client->dev.platform_data) { - tda998x_set_config(priv, client->dev.platform_data); + } else if (dev->platform_data) { + tda998x_set_config(priv, dev->platform_data); } priv->bridge.funcs = &tda998x_bridge_funcs; -- 2.7.4 ^ permalink raw reply related [flat|nested] 80+ messages in thread
* [PATCH v2 7/7] drm/i2c: tda998x: register bridge outside of component helper 2018-07-30 16:41 ` Russell King - ARM Linux @ 2018-07-30 16:42 ` Russell King -1 siblings, 0 replies; 80+ messages in thread From: Russell King @ 2018-07-30 16:42 UTC (permalink / raw) To: linux-arm-kernel Register the bridge outside of the component helper as we have drivers that wish to use the tda998x without its encoder. Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> --- drivers/gpu/drm/i2c/tda998x_drv.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index ea71602d1139..57a42269a7fb 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -1893,18 +1893,8 @@ static int tda998x_encoder_init(struct device *dev, struct drm_device *drm) static int tda998x_bind(struct device *dev, struct device *master, void *data) { struct drm_device *drm = data; - int ret; - - ret = tda998x_create(dev); - if (ret) - return ret; - ret = tda998x_encoder_init(dev, drm); - if (ret) { - tda998x_destroy(dev); - return ret; - } - return 0; + return tda998x_encoder_init(dev, drm); } static void tda998x_unbind(struct device *dev, struct device *master, @@ -1913,7 +1903,6 @@ static void tda998x_unbind(struct device *dev, struct device *master, struct tda998x_priv *priv = dev_get_drvdata(dev); drm_encoder_cleanup(&priv->encoder); - tda998x_destroy(dev); } static const struct component_ops tda998x_ops = { @@ -1924,16 +1913,27 @@ static const struct component_ops tda998x_ops = { static int tda998x_probe(struct i2c_client *client, const struct i2c_device_id *id) { + int ret; + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { dev_warn(&client->dev, "adapter does not support I2C\n"); return -EIO; } - return component_add(&client->dev, &tda998x_ops); + + ret = tda998x_create(&client->dev); + if (ret) + return ret; + + ret = component_add(&client->dev, &tda998x_ops); + if (ret) + tda998x_destroy(&client->dev); + return ret; } static int tda998x_remove(struct i2c_client *client) { component_del(&client->dev, &tda998x_ops); + tda998x_destroy(&client->dev); return 0; } -- 2.7.4 ^ permalink raw reply related [flat|nested] 80+ messages in thread
* [PATCH v2 7/7] drm/i2c: tda998x: register bridge outside of component helper @ 2018-07-30 16:42 ` Russell King 0 siblings, 0 replies; 80+ messages in thread From: Russell King @ 2018-07-30 16:42 UTC (permalink / raw) To: dri-devel, linux-arm-kernel Cc: David Airlie, Tomi Valkeinen, Liviu Dudau, Peter Rosin, Jyri Sarha Register the bridge outside of the component helper as we have drivers that wish to use the tda998x without its encoder. Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> --- drivers/gpu/drm/i2c/tda998x_drv.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index ea71602d1139..57a42269a7fb 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -1893,18 +1893,8 @@ static int tda998x_encoder_init(struct device *dev, struct drm_device *drm) static int tda998x_bind(struct device *dev, struct device *master, void *data) { struct drm_device *drm = data; - int ret; - - ret = tda998x_create(dev); - if (ret) - return ret; - ret = tda998x_encoder_init(dev, drm); - if (ret) { - tda998x_destroy(dev); - return ret; - } - return 0; + return tda998x_encoder_init(dev, drm); } static void tda998x_unbind(struct device *dev, struct device *master, @@ -1913,7 +1903,6 @@ static void tda998x_unbind(struct device *dev, struct device *master, struct tda998x_priv *priv = dev_get_drvdata(dev); drm_encoder_cleanup(&priv->encoder); - tda998x_destroy(dev); } static const struct component_ops tda998x_ops = { @@ -1924,16 +1913,27 @@ static const struct component_ops tda998x_ops = { static int tda998x_probe(struct i2c_client *client, const struct i2c_device_id *id) { + int ret; + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { dev_warn(&client->dev, "adapter does not support I2C\n"); return -EIO; } - return component_add(&client->dev, &tda998x_ops); + + ret = tda998x_create(&client->dev); + if (ret) + return ret; + + ret = component_add(&client->dev, &tda998x_ops); + if (ret) + tda998x_destroy(&client->dev); + return ret; } static int tda998x_remove(struct i2c_client *client) { component_del(&client->dev, &tda998x_ops); + tda998x_destroy(&client->dev); return 0; } -- 2.7.4 ^ permalink raw reply related [flat|nested] 80+ messages in thread
* [PATCH v2 7/7] drm/i2c: tda998x: register bridge outside of component helper 2018-07-30 16:42 ` Russell King @ 2018-08-27 16:19 ` Andrzej Hajda -1 siblings, 0 replies; 80+ messages in thread From: Andrzej Hajda @ 2018-08-27 16:19 UTC (permalink / raw) To: linux-arm-kernel On 30.07.2018 18:42, Russell King wrote: > Register the bridge outside of the component helper as we have > drivers that wish to use the tda998x without its encoder. > > Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> Reviewed-by: Andrzej Hajda <a.hajda@samsung.com> ?-- Regards Andrzej ^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PATCH v2 7/7] drm/i2c: tda998x: register bridge outside of component helper @ 2018-08-27 16:19 ` Andrzej Hajda 0 siblings, 0 replies; 80+ messages in thread From: Andrzej Hajda @ 2018-08-27 16:19 UTC (permalink / raw) To: Russell King, dri-devel, linux-arm-kernel Cc: David Airlie, Tomi Valkeinen, Liviu Dudau, Peter Rosin, Jyri Sarha On 30.07.2018 18:42, Russell King wrote: > Register the bridge outside of the component helper as we have > drivers that wish to use the tda998x without its encoder. > > Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> Reviewed-by: Andrzej Hajda <a.hajda@samsung.com> -- Regards Andrzej _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH v2 0/7] tda998x: allow use with bridge based devices 2018-07-30 16:41 ` Russell King - ARM Linux @ 2018-07-31 5:44 ` Peter Rosin -1 siblings, 0 replies; 80+ messages in thread From: Peter Rosin @ 2018-07-31 5:44 UTC (permalink / raw) To: linux-arm-kernel On 2018-07-30 18:41, Russell King - ARM Linux wrote: > Hi, > > This is a re-posting of the series I responded to Peter Rosin's May > posting, with a few bugs fixed, and the bridge registered outside of > the component helper. This should allow Peter to use the driver > while maintaining armada drm and tilcdc support. > > No comments (other than 0-day test results) were received on the > previous posting. I of course meant to comment on this! I didn't because there was a rush before vacation, then vacation, then a heap of important stuff that had piled up. This one simply had too low priority to make a significant bleep on the radar. Sorry for the silence... However, now that I do try to test, I get conflicts as I try to apply the patches. I'm wondering what this was based on? I've tried next-20180730 drm-misc/drm-misc-next from some minutes ago. Cheers, Peter > > This is independent of the component helper vs bridge safety issues. > > drivers/gpu/drm/i2c/tda998x_drv.c | 288 ++++++++++++++++++++------------------ > 1 file changed, 151 insertions(+), 137 deletions(-) > ^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PATCH v2 0/7] tda998x: allow use with bridge based devices @ 2018-07-31 5:44 ` Peter Rosin 0 siblings, 0 replies; 80+ messages in thread From: Peter Rosin @ 2018-07-31 5:44 UTC (permalink / raw) To: Russell King - ARM Linux, dri-devel, linux-arm-kernel Cc: David Airlie, Tomi Valkeinen, Liviu Dudau, Jyri Sarha On 2018-07-30 18:41, Russell King - ARM Linux wrote: > Hi, > > This is a re-posting of the series I responded to Peter Rosin's May > posting, with a few bugs fixed, and the bridge registered outside of > the component helper. This should allow Peter to use the driver > while maintaining armada drm and tilcdc support. > > No comments (other than 0-day test results) were received on the > previous posting. I of course meant to comment on this! I didn't because there was a rush before vacation, then vacation, then a heap of important stuff that had piled up. This one simply had too low priority to make a significant bleep on the radar. Sorry for the silence... However, now that I do try to test, I get conflicts as I try to apply the patches. I'm wondering what this was based on? I've tried next-20180730 drm-misc/drm-misc-next from some minutes ago. Cheers, Peter > > This is independent of the component helper vs bridge safety issues. > > drivers/gpu/drm/i2c/tda998x_drv.c | 288 ++++++++++++++++++++------------------ > 1 file changed, 151 insertions(+), 137 deletions(-) > ^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH v2 0/7] tda998x: allow use with bridge based devices 2018-07-31 5:44 ` Peter Rosin @ 2018-07-31 7:41 ` Russell King - ARM Linux -1 siblings, 0 replies; 80+ messages in thread From: Russell King - ARM Linux @ 2018-07-31 7:41 UTC (permalink / raw) To: linux-arm-kernel On Tue, Jul 31, 2018 at 07:44:24AM +0200, Peter Rosin wrote: > On 2018-07-30 18:41, Russell King - ARM Linux wrote: > > Hi, > > > > This is a re-posting of the series I responded to Peter Rosin's May > > posting, with a few bugs fixed, and the bridge registered outside of > > the component helper. This should allow Peter to use the driver > > while maintaining armada drm and tilcdc support. > > > > No comments (other than 0-day test results) were received on the > > previous posting. > > I of course meant to comment on this! I didn't because there was a rush > before vacation, then vacation, then a heap of important stuff that had > piled up. This one simply had too low priority to make a significant bleep > on the radar. Sorry for the silence... > > However, now that I do try to test, I get conflicts as I try to apply the > patches. I'm wondering what this was based on? I've tried next-20180730 > drm-misc/drm-misc-next from some minutes ago. They're based on 4.17. -- RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line in suburbia: sync at 13.8Mbps down 630kbps up According to speedtest.net: 13Mbps down 490kbps up ^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PATCH v2 0/7] tda998x: allow use with bridge based devices @ 2018-07-31 7:41 ` Russell King - ARM Linux 0 siblings, 0 replies; 80+ messages in thread From: Russell King - ARM Linux @ 2018-07-31 7:41 UTC (permalink / raw) To: Peter Rosin Cc: David Airlie, Liviu Dudau, Jyri Sarha, Tomi Valkeinen, dri-devel, linux-arm-kernel On Tue, Jul 31, 2018 at 07:44:24AM +0200, Peter Rosin wrote: > On 2018-07-30 18:41, Russell King - ARM Linux wrote: > > Hi, > > > > This is a re-posting of the series I responded to Peter Rosin's May > > posting, with a few bugs fixed, and the bridge registered outside of > > the component helper. This should allow Peter to use the driver > > while maintaining armada drm and tilcdc support. > > > > No comments (other than 0-day test results) were received on the > > previous posting. > > I of course meant to comment on this! I didn't because there was a rush > before vacation, then vacation, then a heap of important stuff that had > piled up. This one simply had too low priority to make a significant bleep > on the radar. Sorry for the silence... > > However, now that I do try to test, I get conflicts as I try to apply the > patches. I'm wondering what this was based on? I've tried next-20180730 > drm-misc/drm-misc-next from some minutes ago. They're based on 4.17. -- RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line in suburbia: sync at 13.8Mbps down 630kbps up According to speedtest.net: 13Mbps down 490kbps up ^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH v2 0/7] tda998x: allow use with bridge based devices 2018-07-31 7:41 ` Russell King - ARM Linux @ 2018-07-31 7:53 ` Peter Rosin -1 siblings, 0 replies; 80+ messages in thread From: Peter Rosin @ 2018-07-31 7:53 UTC (permalink / raw) To: linux-arm-kernel On 2018-07-31 09:41, Russell King - ARM Linux wrote: > On Tue, Jul 31, 2018 at 07:44:24AM +0200, Peter Rosin wrote: >> On 2018-07-30 18:41, Russell King - ARM Linux wrote: >>> Hi, >>> >>> This is a re-posting of the series I responded to Peter Rosin's May >>> posting, with a few bugs fixed, and the bridge registered outside of >>> the component helper. This should allow Peter to use the driver >>> while maintaining armada drm and tilcdc support. >>> >>> No comments (other than 0-day test results) were received on the >>> previous posting. >> >> I of course meant to comment on this! I didn't because there was a rush >> before vacation, then vacation, then a heap of important stuff that had >> piled up. This one simply had too low priority to make a significant bleep >> on the radar. Sorry for the silence... >> >> However, now that I do try to test, I get conflicts as I try to apply the >> patches. I'm wondering what this was based on? I've tried next-20180730 >> drm-misc/drm-misc-next from some minutes ago. > > They're based on 4.17. Right, meanwhile I massaged the patches into a combo of some local patches, next-20180730 and drm-misc-next, and tested that. The conflict was trivial once I had a closer look... And it seems to work (with atmel-hlcdc), so you can add Tested-by: Peter Rosin <peda@axentia.se> Thank you for very much for picking this up! Cheers, Peter ^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PATCH v2 0/7] tda998x: allow use with bridge based devices @ 2018-07-31 7:53 ` Peter Rosin 0 siblings, 0 replies; 80+ messages in thread From: Peter Rosin @ 2018-07-31 7:53 UTC (permalink / raw) To: Russell King - ARM Linux Cc: David Airlie, Liviu Dudau, Jyri Sarha, Tomi Valkeinen, dri-devel, linux-arm-kernel On 2018-07-31 09:41, Russell King - ARM Linux wrote: > On Tue, Jul 31, 2018 at 07:44:24AM +0200, Peter Rosin wrote: >> On 2018-07-30 18:41, Russell King - ARM Linux wrote: >>> Hi, >>> >>> This is a re-posting of the series I responded to Peter Rosin's May >>> posting, with a few bugs fixed, and the bridge registered outside of >>> the component helper. This should allow Peter to use the driver >>> while maintaining armada drm and tilcdc support. >>> >>> No comments (other than 0-day test results) were received on the >>> previous posting. >> >> I of course meant to comment on this! I didn't because there was a rush >> before vacation, then vacation, then a heap of important stuff that had >> piled up. This one simply had too low priority to make a significant bleep >> on the radar. Sorry for the silence... >> >> However, now that I do try to test, I get conflicts as I try to apply the >> patches. I'm wondering what this was based on? I've tried next-20180730 >> drm-misc/drm-misc-next from some minutes ago. > > They're based on 4.17. Right, meanwhile I massaged the patches into a combo of some local patches, next-20180730 and drm-misc-next, and tested that. The conflict was trivial once I had a closer look... And it seems to work (with atmel-hlcdc), so you can add Tested-by: Peter Rosin <peda@axentia.se> Thank you for very much for picking this up! Cheers, Peter ^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH v2 0/7] tda998x: allow use with bridge based devices 2018-07-31 7:53 ` Peter Rosin @ 2018-07-31 9:23 ` Russell King - ARM Linux -1 siblings, 0 replies; 80+ messages in thread From: Russell King - ARM Linux @ 2018-07-31 9:23 UTC (permalink / raw) To: linux-arm-kernel On Tue, Jul 31, 2018 at 09:53:57AM +0200, Peter Rosin wrote: > On 2018-07-31 09:41, Russell King - ARM Linux wrote: > > On Tue, Jul 31, 2018 at 07:44:24AM +0200, Peter Rosin wrote: > >> On 2018-07-30 18:41, Russell King - ARM Linux wrote: > >>> Hi, > >>> > >>> This is a re-posting of the series I responded to Peter Rosin's May > >>> posting, with a few bugs fixed, and the bridge registered outside of > >>> the component helper. This should allow Peter to use the driver > >>> while maintaining armada drm and tilcdc support. > >>> > >>> No comments (other than 0-day test results) were received on the > >>> previous posting. > >> > >> I of course meant to comment on this! I didn't because there was a rush > >> before vacation, then vacation, then a heap of important stuff that had > >> piled up. This one simply had too low priority to make a significant bleep > >> on the radar. Sorry for the silence... > >> > >> However, now that I do try to test, I get conflicts as I try to apply the > >> patches. I'm wondering what this was based on? I've tried next-20180730 > >> drm-misc/drm-misc-next from some minutes ago. > > > > They're based on 4.17. > > Right, meanwhile I massaged the patches into a combo of some local patches, > next-20180730 and drm-misc-next, and tested that. The conflict was trivial > once I had a closer look... > > And it seems to work (with atmel-hlcdc), so you can add > > Tested-by: Peter Rosin <peda@axentia.se> Thanks, I've added your attributation, and fixed patch 2 as you pointed out. I have a four more tda998x patches if you're willing to test. These follow on from this set - I've tweaked patch 2 in this follow on set to cater for the removal of "_mode_" in drm_mode_connector_update_edid_property. drivers/gpu/drm/i2c/tda998x_drv.c | 106 ++++++++++++++++++-------------------- 1 file changed, 51 insertions(+), 55 deletions(-) -- RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line in suburbia: sync at 13.8Mbps down 630kbps up According to speedtest.net: 13Mbps down 490kbps up ^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PATCH v2 0/7] tda998x: allow use with bridge based devices @ 2018-07-31 9:23 ` Russell King - ARM Linux 0 siblings, 0 replies; 80+ messages in thread From: Russell King - ARM Linux @ 2018-07-31 9:23 UTC (permalink / raw) To: Peter Rosin Cc: David Airlie, Liviu Dudau, Jyri Sarha, Tomi Valkeinen, dri-devel, linux-arm-kernel On Tue, Jul 31, 2018 at 09:53:57AM +0200, Peter Rosin wrote: > On 2018-07-31 09:41, Russell King - ARM Linux wrote: > > On Tue, Jul 31, 2018 at 07:44:24AM +0200, Peter Rosin wrote: > >> On 2018-07-30 18:41, Russell King - ARM Linux wrote: > >>> Hi, > >>> > >>> This is a re-posting of the series I responded to Peter Rosin's May > >>> posting, with a few bugs fixed, and the bridge registered outside of > >>> the component helper. This should allow Peter to use the driver > >>> while maintaining armada drm and tilcdc support. > >>> > >>> No comments (other than 0-day test results) were received on the > >>> previous posting. > >> > >> I of course meant to comment on this! I didn't because there was a rush > >> before vacation, then vacation, then a heap of important stuff that had > >> piled up. This one simply had too low priority to make a significant bleep > >> on the radar. Sorry for the silence... > >> > >> However, now that I do try to test, I get conflicts as I try to apply the > >> patches. I'm wondering what this was based on? I've tried next-20180730 > >> drm-misc/drm-misc-next from some minutes ago. > > > > They're based on 4.17. > > Right, meanwhile I massaged the patches into a combo of some local patches, > next-20180730 and drm-misc-next, and tested that. The conflict was trivial > once I had a closer look... > > And it seems to work (with atmel-hlcdc), so you can add > > Tested-by: Peter Rosin <peda@axentia.se> Thanks, I've added your attributation, and fixed patch 2 as you pointed out. I have a four more tda998x patches if you're willing to test. These follow on from this set - I've tweaked patch 2 in this follow on set to cater for the removal of "_mode_" in drm_mode_connector_update_edid_property. drivers/gpu/drm/i2c/tda998x_drv.c | 106 ++++++++++++++++++-------------------- 1 file changed, 51 insertions(+), 55 deletions(-) -- RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line in suburbia: sync at 13.8Mbps down 630kbps up According to speedtest.net: 13Mbps down 490kbps up ^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH 1/4] drm/i2c: tda998x: move mode_valid() to bridge 2018-07-31 9:23 ` Russell King - ARM Linux @ 2018-07-31 9:26 ` Russell King -1 siblings, 0 replies; 80+ messages in thread From: Russell King @ 2018-07-31 9:26 UTC (permalink / raw) To: linux-arm-kernel Move the mode_valid() implementation to the bridge instead of the connector, as we're checking the bridge's capabilities. Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> --- drivers/gpu/drm/i2c/tda998x_drv.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index 8ca5c9786bdf..58831b6a4722 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -1244,21 +1244,6 @@ static int tda998x_connector_get_modes(struct drm_connector *connector) return n; } -static int tda998x_connector_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - /* TDA19988 dotclock can go up to 165MHz */ - struct tda998x_priv *priv = conn_to_tda998x_priv(connector); - - if (mode->clock > ((priv->rev == TDA19988) ? 165000 : 150000)) - return MODE_CLOCK_HIGH; - if (mode->htotal >= BIT(13)) - return MODE_BAD_HVALUE; - if (mode->vtotal >= BIT(11)) - return MODE_BAD_VVALUE; - return MODE_OK; -} - static struct drm_encoder * tda998x_connector_best_encoder(struct drm_connector *connector) { @@ -1270,7 +1255,6 @@ tda998x_connector_best_encoder(struct drm_connector *connector) static const struct drm_connector_helper_funcs tda998x_connector_helper_funcs = { .get_modes = tda998x_connector_get_modes, - .mode_valid = tda998x_connector_mode_valid, .best_encoder = tda998x_connector_best_encoder, }; @@ -1316,6 +1300,21 @@ static void tda998x_bridge_detach(struct drm_bridge *bridge) drm_connector_cleanup(&priv->connector); } +static int tda998x_bridge_mode_valid(struct drm_bridge *bridge, + const struct drm_display_mode *mode) +{ + /* TDA19988 dotclock can go up to 165MHz */ + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); + + if (mode->clock > ((priv->rev == TDA19988) ? 165000 : 150000)) + return MODE_CLOCK_HIGH; + if (mode->htotal >= BIT(13)) + return MODE_BAD_HVALUE; + if (mode->vtotal >= BIT(11)) + return MODE_BAD_VVALUE; + return MODE_OK; +} + static void tda998x_bridge_enable(struct drm_bridge *bridge) { struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); @@ -1562,6 +1561,7 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge, static const struct drm_bridge_funcs tda998x_bridge_funcs = { .attach = tda998x_bridge_attach, .detach = tda998x_bridge_detach, + .mode_valid = tda998x_bridge_mode_valid, .disable = tda998x_bridge_disable, .mode_set = tda998x_bridge_mode_set, .enable = tda998x_bridge_enable, -- 2.7.4 ^ permalink raw reply related [flat|nested] 80+ messages in thread
* [PATCH 1/4] drm/i2c: tda998x: move mode_valid() to bridge @ 2018-07-31 9:26 ` Russell King 0 siblings, 0 replies; 80+ messages in thread From: Russell King @ 2018-07-31 9:26 UTC (permalink / raw) To: Peter Rosin Cc: David Airlie, Liviu Dudau, Jyri Sarha, Tomi Valkeinen, dri-devel, linux-arm-kernel Move the mode_valid() implementation to the bridge instead of the connector, as we're checking the bridge's capabilities. Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> --- drivers/gpu/drm/i2c/tda998x_drv.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index 8ca5c9786bdf..58831b6a4722 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -1244,21 +1244,6 @@ static int tda998x_connector_get_modes(struct drm_connector *connector) return n; } -static int tda998x_connector_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - /* TDA19988 dotclock can go up to 165MHz */ - struct tda998x_priv *priv = conn_to_tda998x_priv(connector); - - if (mode->clock > ((priv->rev == TDA19988) ? 165000 : 150000)) - return MODE_CLOCK_HIGH; - if (mode->htotal >= BIT(13)) - return MODE_BAD_HVALUE; - if (mode->vtotal >= BIT(11)) - return MODE_BAD_VVALUE; - return MODE_OK; -} - static struct drm_encoder * tda998x_connector_best_encoder(struct drm_connector *connector) { @@ -1270,7 +1255,6 @@ tda998x_connector_best_encoder(struct drm_connector *connector) static const struct drm_connector_helper_funcs tda998x_connector_helper_funcs = { .get_modes = tda998x_connector_get_modes, - .mode_valid = tda998x_connector_mode_valid, .best_encoder = tda998x_connector_best_encoder, }; @@ -1316,6 +1300,21 @@ static void tda998x_bridge_detach(struct drm_bridge *bridge) drm_connector_cleanup(&priv->connector); } +static int tda998x_bridge_mode_valid(struct drm_bridge *bridge, + const struct drm_display_mode *mode) +{ + /* TDA19988 dotclock can go up to 165MHz */ + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); + + if (mode->clock > ((priv->rev == TDA19988) ? 165000 : 150000)) + return MODE_CLOCK_HIGH; + if (mode->htotal >= BIT(13)) + return MODE_BAD_HVALUE; + if (mode->vtotal >= BIT(11)) + return MODE_BAD_VVALUE; + return MODE_OK; +} + static void tda998x_bridge_enable(struct drm_bridge *bridge) { struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); @@ -1562,6 +1561,7 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge, static const struct drm_bridge_funcs tda998x_bridge_funcs = { .attach = tda998x_bridge_attach, .detach = tda998x_bridge_detach, + .mode_valid = tda998x_bridge_mode_valid, .disable = tda998x_bridge_disable, .mode_set = tda998x_bridge_mode_set, .enable = tda998x_bridge_enable, -- 2.7.4 ^ permalink raw reply related [flat|nested] 80+ messages in thread
* [PATCH 1/4] drm/i2c: tda998x: move mode_valid() to bridge 2018-07-31 9:26 ` Russell King @ 2018-08-27 16:24 ` Andrzej Hajda -1 siblings, 0 replies; 80+ messages in thread From: Andrzej Hajda @ 2018-08-27 16:24 UTC (permalink / raw) To: linux-arm-kernel On 31.07.2018 11:26, Russell King wrote: > Move the mode_valid() implementation to the bridge instead of the > connector, as we're checking the bridge's capabilities. > > Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> Reviewed-by: Andrzej Hajda <a.hajda@samsung.com> ?-- Regards Andrzej > --- > drivers/gpu/drm/i2c/tda998x_drv.c | 32 ++++++++++++++++---------------- > 1 file changed, 16 insertions(+), 16 deletions(-) > > diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c > index 8ca5c9786bdf..58831b6a4722 100644 > --- a/drivers/gpu/drm/i2c/tda998x_drv.c > +++ b/drivers/gpu/drm/i2c/tda998x_drv.c > @@ -1244,21 +1244,6 @@ static int tda998x_connector_get_modes(struct drm_connector *connector) > return n; > } > > -static int tda998x_connector_mode_valid(struct drm_connector *connector, > - struct drm_display_mode *mode) > -{ > - /* TDA19988 dotclock can go up to 165MHz */ > - struct tda998x_priv *priv = conn_to_tda998x_priv(connector); > - > - if (mode->clock > ((priv->rev == TDA19988) ? 165000 : 150000)) > - return MODE_CLOCK_HIGH; > - if (mode->htotal >= BIT(13)) > - return MODE_BAD_HVALUE; > - if (mode->vtotal >= BIT(11)) > - return MODE_BAD_VVALUE; > - return MODE_OK; > -} > - > static struct drm_encoder * > tda998x_connector_best_encoder(struct drm_connector *connector) > { > @@ -1270,7 +1255,6 @@ tda998x_connector_best_encoder(struct drm_connector *connector) > static > const struct drm_connector_helper_funcs tda998x_connector_helper_funcs = { > .get_modes = tda998x_connector_get_modes, > - .mode_valid = tda998x_connector_mode_valid, > .best_encoder = tda998x_connector_best_encoder, > }; > > @@ -1316,6 +1300,21 @@ static void tda998x_bridge_detach(struct drm_bridge *bridge) > drm_connector_cleanup(&priv->connector); > } > > +static int tda998x_bridge_mode_valid(struct drm_bridge *bridge, > + const struct drm_display_mode *mode) > +{ > + /* TDA19988 dotclock can go up to 165MHz */ > + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); > + > + if (mode->clock > ((priv->rev == TDA19988) ? 165000 : 150000)) > + return MODE_CLOCK_HIGH; > + if (mode->htotal >= BIT(13)) > + return MODE_BAD_HVALUE; > + if (mode->vtotal >= BIT(11)) > + return MODE_BAD_VVALUE; > + return MODE_OK; > +} > + > static void tda998x_bridge_enable(struct drm_bridge *bridge) > { > struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); > @@ -1562,6 +1561,7 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge, > static const struct drm_bridge_funcs tda998x_bridge_funcs = { > .attach = tda998x_bridge_attach, > .detach = tda998x_bridge_detach, > + .mode_valid = tda998x_bridge_mode_valid, > .disable = tda998x_bridge_disable, > .mode_set = tda998x_bridge_mode_set, > .enable = tda998x_bridge_enable, ^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PATCH 1/4] drm/i2c: tda998x: move mode_valid() to bridge @ 2018-08-27 16:24 ` Andrzej Hajda 0 siblings, 0 replies; 80+ messages in thread From: Andrzej Hajda @ 2018-08-27 16:24 UTC (permalink / raw) To: Russell King, Peter Rosin Cc: David Airlie, Liviu Dudau, dri-devel, Tomi Valkeinen, Jyri Sarha, linux-arm-kernel On 31.07.2018 11:26, Russell King wrote: > Move the mode_valid() implementation to the bridge instead of the > connector, as we're checking the bridge's capabilities. > > Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> Reviewed-by: Andrzej Hajda <a.hajda@samsung.com> -- Regards Andrzej > --- > drivers/gpu/drm/i2c/tda998x_drv.c | 32 ++++++++++++++++---------------- > 1 file changed, 16 insertions(+), 16 deletions(-) > > diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c > index 8ca5c9786bdf..58831b6a4722 100644 > --- a/drivers/gpu/drm/i2c/tda998x_drv.c > +++ b/drivers/gpu/drm/i2c/tda998x_drv.c > @@ -1244,21 +1244,6 @@ static int tda998x_connector_get_modes(struct drm_connector *connector) > return n; > } > > -static int tda998x_connector_mode_valid(struct drm_connector *connector, > - struct drm_display_mode *mode) > -{ > - /* TDA19988 dotclock can go up to 165MHz */ > - struct tda998x_priv *priv = conn_to_tda998x_priv(connector); > - > - if (mode->clock > ((priv->rev == TDA19988) ? 165000 : 150000)) > - return MODE_CLOCK_HIGH; > - if (mode->htotal >= BIT(13)) > - return MODE_BAD_HVALUE; > - if (mode->vtotal >= BIT(11)) > - return MODE_BAD_VVALUE; > - return MODE_OK; > -} > - > static struct drm_encoder * > tda998x_connector_best_encoder(struct drm_connector *connector) > { > @@ -1270,7 +1255,6 @@ tda998x_connector_best_encoder(struct drm_connector *connector) > static > const struct drm_connector_helper_funcs tda998x_connector_helper_funcs = { > .get_modes = tda998x_connector_get_modes, > - .mode_valid = tda998x_connector_mode_valid, > .best_encoder = tda998x_connector_best_encoder, > }; > > @@ -1316,6 +1300,21 @@ static void tda998x_bridge_detach(struct drm_bridge *bridge) > drm_connector_cleanup(&priv->connector); > } > > +static int tda998x_bridge_mode_valid(struct drm_bridge *bridge, > + const struct drm_display_mode *mode) > +{ > + /* TDA19988 dotclock can go up to 165MHz */ > + struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); > + > + if (mode->clock > ((priv->rev == TDA19988) ? 165000 : 150000)) > + return MODE_CLOCK_HIGH; > + if (mode->htotal >= BIT(13)) > + return MODE_BAD_HVALUE; > + if (mode->vtotal >= BIT(11)) > + return MODE_BAD_VVALUE; > + return MODE_OK; > +} > + > static void tda998x_bridge_enable(struct drm_bridge *bridge) > { > struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); > @@ -1562,6 +1561,7 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge, > static const struct drm_bridge_funcs tda998x_bridge_funcs = { > .attach = tda998x_bridge_attach, > .detach = tda998x_bridge_detach, > + .mode_valid = tda998x_bridge_mode_valid, > .disable = tda998x_bridge_disable, > .mode_set = tda998x_bridge_mode_set, > .enable = tda998x_bridge_enable, _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH 2/4] drm/i2c: tda998x: get rid of private fill_modes function 2018-07-31 9:23 ` Russell King - ARM Linux @ 2018-07-31 9:26 ` Russell King -1 siblings, 0 replies; 80+ messages in thread From: Russell King @ 2018-07-31 9:26 UTC (permalink / raw) To: linux-arm-kernel We can achieve the same effect via the get_modes() method, rather than wrapping the fill_modes helper. Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> --- drivers/gpu/drm/i2c/tda998x_drv.c | 30 ++++++------------------------ 1 file changed, 6 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index 58831b6a4722..98ec91a55a6a 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -1097,29 +1097,6 @@ static int tda998x_audio_codec_init(struct tda998x_priv *priv, /* DRM connector functions */ -static int tda998x_connector_fill_modes(struct drm_connector *connector, - uint32_t maxX, uint32_t maxY) -{ - struct tda998x_priv *priv = conn_to_tda998x_priv(connector); - int ret; - - mutex_lock(&priv->audio_mutex); - ret = drm_helper_probe_single_connector_modes(connector, maxX, maxY); - - if (connector->edid_blob_ptr) { - struct edid *edid = (void *)connector->edid_blob_ptr->data; - - cec_notifier_set_phys_addr_from_edid(priv->cec_notify, edid); - - priv->sink_has_audio = drm_detect_monitor_audio(edid); - } else { - priv->sink_has_audio = false; - } - mutex_unlock(&priv->audio_mutex); - - return ret; -} - static enum drm_connector_status tda998x_connector_detect(struct drm_connector *connector, bool force) { @@ -1138,7 +1115,7 @@ static void tda998x_connector_destroy(struct drm_connector *connector) static const struct drm_connector_funcs tda998x_connector_funcs = { .dpms = drm_helper_connector_dpms, .reset = drm_atomic_helper_connector_reset, - .fill_modes = tda998x_connector_fill_modes, + .fill_modes = drm_helper_probe_single_connector_modes, .detect = tda998x_connector_detect, .destroy = tda998x_connector_destroy, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, @@ -1237,7 +1214,12 @@ static int tda998x_connector_get_modes(struct drm_connector *connector) } drm_connector_update_edid_property(connector, edid); + cec_notifier_set_phys_addr_from_edid(priv->cec_notify, edid); + + mutex_lock(&priv->audio_mutex); n = drm_add_edid_modes(connector, edid); + priv->sink_has_audio = drm_detect_monitor_audio(edid); + mutex_unlock(&priv->audio_mutex); kfree(edid); -- 2.7.4 ^ permalink raw reply related [flat|nested] 80+ messages in thread
* [PATCH 2/4] drm/i2c: tda998x: get rid of private fill_modes function @ 2018-07-31 9:26 ` Russell King 0 siblings, 0 replies; 80+ messages in thread From: Russell King @ 2018-07-31 9:26 UTC (permalink / raw) To: Peter Rosin Cc: David Airlie, Liviu Dudau, Jyri Sarha, Tomi Valkeinen, dri-devel, linux-arm-kernel We can achieve the same effect via the get_modes() method, rather than wrapping the fill_modes helper. Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> --- drivers/gpu/drm/i2c/tda998x_drv.c | 30 ++++++------------------------ 1 file changed, 6 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index 58831b6a4722..98ec91a55a6a 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -1097,29 +1097,6 @@ static int tda998x_audio_codec_init(struct tda998x_priv *priv, /* DRM connector functions */ -static int tda998x_connector_fill_modes(struct drm_connector *connector, - uint32_t maxX, uint32_t maxY) -{ - struct tda998x_priv *priv = conn_to_tda998x_priv(connector); - int ret; - - mutex_lock(&priv->audio_mutex); - ret = drm_helper_probe_single_connector_modes(connector, maxX, maxY); - - if (connector->edid_blob_ptr) { - struct edid *edid = (void *)connector->edid_blob_ptr->data; - - cec_notifier_set_phys_addr_from_edid(priv->cec_notify, edid); - - priv->sink_has_audio = drm_detect_monitor_audio(edid); - } else { - priv->sink_has_audio = false; - } - mutex_unlock(&priv->audio_mutex); - - return ret; -} - static enum drm_connector_status tda998x_connector_detect(struct drm_connector *connector, bool force) { @@ -1138,7 +1115,7 @@ static void tda998x_connector_destroy(struct drm_connector *connector) static const struct drm_connector_funcs tda998x_connector_funcs = { .dpms = drm_helper_connector_dpms, .reset = drm_atomic_helper_connector_reset, - .fill_modes = tda998x_connector_fill_modes, + .fill_modes = drm_helper_probe_single_connector_modes, .detect = tda998x_connector_detect, .destroy = tda998x_connector_destroy, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, @@ -1237,7 +1214,12 @@ static int tda998x_connector_get_modes(struct drm_connector *connector) } drm_connector_update_edid_property(connector, edid); + cec_notifier_set_phys_addr_from_edid(priv->cec_notify, edid); + + mutex_lock(&priv->audio_mutex); n = drm_add_edid_modes(connector, edid); + priv->sink_has_audio = drm_detect_monitor_audio(edid); + mutex_unlock(&priv->audio_mutex); kfree(edid); -- 2.7.4 ^ permalink raw reply related [flat|nested] 80+ messages in thread
* [PATCH 3/4] drm/i2c: tda998x: correct PLL divider calculation 2018-07-31 9:23 ` Russell King - ARM Linux @ 2018-07-31 9:26 ` Russell King -1 siblings, 0 replies; 80+ messages in thread From: Russell King @ 2018-07-31 9:26 UTC (permalink / raw) To: linux-arm-kernel The serializer PLL divider is a power-of-two divider, so our calculation which assumes that it's a numerical divider is incorrect. Replace it with one that results in a power-of-two divider value instead. Tested with all supported modes with a Samsung S24C750. Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> --- drivers/gpu/drm/i2c/tda998x_drv.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index 98ec91a55a6a..a31809ce30e2 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -1334,6 +1334,7 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge, struct drm_display_mode *adjusted_mode) { struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); + unsigned long tmds_clock; u16 ref_pix, ref_line, n_pix, n_line; u16 hs_pix_s, hs_pix_e; u16 vs1_pix_s, vs1_pix_e, vs1_line_s, vs1_line_e; @@ -1404,12 +1405,19 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge, (mode->vsync_end - mode->vsync_start)/2; } - div = 148500 / mode->clock; - if (div != 0) { - div--; - if (div > 3) - div = 3; - } + tmds_clock = mode->clock; + + /* + * The divisor is power-of-2. The TDA9983B datasheet gives + * this as ranges of Msample/s, which is 10x the TMDS clock: + * 0 - 800 to 1500 Msample/s + * 1 - 400 to 800 Msample/s + * 2 - 200 to 400 Msample/s + * 3 - as 2 above + */ + for (div = 0; div < 3; div++) + if (80000 >> div <= tmds_clock) + break; mutex_lock(&priv->audio_mutex); -- 2.7.4 ^ permalink raw reply related [flat|nested] 80+ messages in thread
* [PATCH 3/4] drm/i2c: tda998x: correct PLL divider calculation @ 2018-07-31 9:26 ` Russell King 0 siblings, 0 replies; 80+ messages in thread From: Russell King @ 2018-07-31 9:26 UTC (permalink / raw) To: Peter Rosin Cc: David Airlie, Liviu Dudau, Jyri Sarha, Tomi Valkeinen, dri-devel, linux-arm-kernel The serializer PLL divider is a power-of-two divider, so our calculation which assumes that it's a numerical divider is incorrect. Replace it with one that results in a power-of-two divider value instead. Tested with all supported modes with a Samsung S24C750. Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> --- drivers/gpu/drm/i2c/tda998x_drv.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index 98ec91a55a6a..a31809ce30e2 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -1334,6 +1334,7 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge, struct drm_display_mode *adjusted_mode) { struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); + unsigned long tmds_clock; u16 ref_pix, ref_line, n_pix, n_line; u16 hs_pix_s, hs_pix_e; u16 vs1_pix_s, vs1_pix_e, vs1_line_s, vs1_line_e; @@ -1404,12 +1405,19 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge, (mode->vsync_end - mode->vsync_start)/2; } - div = 148500 / mode->clock; - if (div != 0) { - div--; - if (div > 3) - div = 3; - } + tmds_clock = mode->clock; + + /* + * The divisor is power-of-2. The TDA9983B datasheet gives + * this as ranges of Msample/s, which is 10x the TMDS clock: + * 0 - 800 to 1500 Msample/s + * 1 - 400 to 800 Msample/s + * 2 - 200 to 400 Msample/s + * 3 - as 2 above + */ + for (div = 0; div < 3; div++) + if (80000 >> div <= tmds_clock) + break; mutex_lock(&priv->audio_mutex); -- 2.7.4 ^ permalink raw reply related [flat|nested] 80+ messages in thread
* [PATCH 4/4] drm/i2c: tda998x: add support for pixel repeated modes 2018-07-31 9:23 ` Russell King - ARM Linux @ 2018-07-31 9:26 ` Russell King -1 siblings, 0 replies; 80+ messages in thread From: Russell King @ 2018-07-31 9:26 UTC (permalink / raw) To: linux-arm-kernel TDA998x has no support for pixel repeated modes, and the code notes this as a "TODO" item. The implementation appears to be relatively simple, so lets add it. We need to calculate the serializer clock divisor based on the TMDS clock rate, set the repeat control, and set the serializer pixel repeat count. Since the audio code needs the actual TMDS clock, record that. Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> --- drivers/gpu/drm/i2c/tda998x_drv.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index a31809ce30e2..08ce28cbdec4 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -241,6 +241,7 @@ struct tda998x_priv { # define HVF_CNTRL_1_PAD(x) (((x) & 3) << 4) # define HVF_CNTRL_1_SEMI_PLANAR (1 << 6) #define REG_RPT_CNTRL REG(0x00, 0xf0) /* write */ +# define RPT_CNTRL_REPEAT(x) ((x) & 15) #define REG_I2S_FORMAT REG(0x00, 0xfc) /* read/write */ # define I2S_FORMAT(x) (((x) & 3) << 0) #define REG_AIP_CLKSEL REG(0x00, 0xfd) /* write */ @@ -1342,7 +1343,7 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge, u16 vwin1_line_s, vwin1_line_e; u16 vwin2_line_s, vwin2_line_e; u16 de_pix_s, de_pix_e; - u8 reg, div, rep; + u8 reg, div, rep, sel_clk; /* * Internally TDA998x is using ITU-R BT.656 style sync but @@ -1405,7 +1406,16 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge, (mode->vsync_end - mode->vsync_start)/2; } - tmds_clock = mode->clock; + /* + * Select pixel repeat depending on the double-clock flag + * (which means we have to repeat each pixel once.) + */ + rep = mode->flags & DRM_MODE_FLAG_DBLCLK ? 1 : 0; + sel_clk = SEL_CLK_ENA_SC_CLK | SEL_CLK_SEL_CLK1 | + SEL_CLK_SEL_VRF_CLK(rep ? 2 : 0); + + /* the TMDS clock is scaled up by the pixel repeat */ + tmds_clock = mode->clock * (1 + rep); /* * The divisor is power-of-2. The TDA9983B datasheet gives @@ -1421,6 +1431,8 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge, mutex_lock(&priv->audio_mutex); + priv->tmds_clock = tmds_clock; + /* mute the audio FIFO: */ reg_set(priv, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO); @@ -1443,12 +1455,8 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge, reg_write(priv, REG_SERIALIZER, 0); reg_write(priv, REG_HVF_CNTRL_1, HVF_CNTRL_1_VQR(0)); - /* TODO enable pixel repeat for pixel rates less than 25Msamp/s */ - rep = 0; - reg_write(priv, REG_RPT_CNTRL, 0); - reg_write(priv, REG_SEL_CLK, SEL_CLK_SEL_VRF_CLK(0) | - SEL_CLK_SEL_CLK1 | SEL_CLK_ENA_SC_CLK); - + reg_write(priv, REG_RPT_CNTRL, RPT_CNTRL_REPEAT(rep)); + reg_write(priv, REG_SEL_CLK, sel_clk); reg_write(priv, REG_PLL_SERIAL_2, PLL_SERIAL_2_SRL_NOSC(div) | PLL_SERIAL_2_SRL_PR(rep)); @@ -1516,8 +1524,6 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge, /* must be last register set: */ reg_write(priv, REG_TBG_CNTRL_0, 0); - priv->tmds_clock = adjusted_mode->clock; - /* CEA-861B section 6 says that: * CEA version 1 (CEA-861) has no support for infoframes. * CEA version 2 (CEA-861A) supports version 1 AVI infoframes, -- 2.7.4 ^ permalink raw reply related [flat|nested] 80+ messages in thread
* [PATCH 4/4] drm/i2c: tda998x: add support for pixel repeated modes @ 2018-07-31 9:26 ` Russell King 0 siblings, 0 replies; 80+ messages in thread From: Russell King @ 2018-07-31 9:26 UTC (permalink / raw) To: Peter Rosin Cc: David Airlie, Liviu Dudau, Jyri Sarha, Tomi Valkeinen, dri-devel, linux-arm-kernel TDA998x has no support for pixel repeated modes, and the code notes this as a "TODO" item. The implementation appears to be relatively simple, so lets add it. We need to calculate the serializer clock divisor based on the TMDS clock rate, set the repeat control, and set the serializer pixel repeat count. Since the audio code needs the actual TMDS clock, record that. Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> --- drivers/gpu/drm/i2c/tda998x_drv.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index a31809ce30e2..08ce28cbdec4 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -241,6 +241,7 @@ struct tda998x_priv { # define HVF_CNTRL_1_PAD(x) (((x) & 3) << 4) # define HVF_CNTRL_1_SEMI_PLANAR (1 << 6) #define REG_RPT_CNTRL REG(0x00, 0xf0) /* write */ +# define RPT_CNTRL_REPEAT(x) ((x) & 15) #define REG_I2S_FORMAT REG(0x00, 0xfc) /* read/write */ # define I2S_FORMAT(x) (((x) & 3) << 0) #define REG_AIP_CLKSEL REG(0x00, 0xfd) /* write */ @@ -1342,7 +1343,7 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge, u16 vwin1_line_s, vwin1_line_e; u16 vwin2_line_s, vwin2_line_e; u16 de_pix_s, de_pix_e; - u8 reg, div, rep; + u8 reg, div, rep, sel_clk; /* * Internally TDA998x is using ITU-R BT.656 style sync but @@ -1405,7 +1406,16 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge, (mode->vsync_end - mode->vsync_start)/2; } - tmds_clock = mode->clock; + /* + * Select pixel repeat depending on the double-clock flag + * (which means we have to repeat each pixel once.) + */ + rep = mode->flags & DRM_MODE_FLAG_DBLCLK ? 1 : 0; + sel_clk = SEL_CLK_ENA_SC_CLK | SEL_CLK_SEL_CLK1 | + SEL_CLK_SEL_VRF_CLK(rep ? 2 : 0); + + /* the TMDS clock is scaled up by the pixel repeat */ + tmds_clock = mode->clock * (1 + rep); /* * The divisor is power-of-2. The TDA9983B datasheet gives @@ -1421,6 +1431,8 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge, mutex_lock(&priv->audio_mutex); + priv->tmds_clock = tmds_clock; + /* mute the audio FIFO: */ reg_set(priv, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO); @@ -1443,12 +1455,8 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge, reg_write(priv, REG_SERIALIZER, 0); reg_write(priv, REG_HVF_CNTRL_1, HVF_CNTRL_1_VQR(0)); - /* TODO enable pixel repeat for pixel rates less than 25Msamp/s */ - rep = 0; - reg_write(priv, REG_RPT_CNTRL, 0); - reg_write(priv, REG_SEL_CLK, SEL_CLK_SEL_VRF_CLK(0) | - SEL_CLK_SEL_CLK1 | SEL_CLK_ENA_SC_CLK); - + reg_write(priv, REG_RPT_CNTRL, RPT_CNTRL_REPEAT(rep)); + reg_write(priv, REG_SEL_CLK, sel_clk); reg_write(priv, REG_PLL_SERIAL_2, PLL_SERIAL_2_SRL_NOSC(div) | PLL_SERIAL_2_SRL_PR(rep)); @@ -1516,8 +1524,6 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge, /* must be last register set: */ reg_write(priv, REG_TBG_CNTRL_0, 0); - priv->tmds_clock = adjusted_mode->clock; - /* CEA-861B section 6 says that: * CEA version 1 (CEA-861) has no support for infoframes. * CEA version 2 (CEA-861A) supports version 1 AVI infoframes, -- 2.7.4 ^ permalink raw reply related [flat|nested] 80+ messages in thread
* [PATCH 4/4] drm/i2c: tda998x: add support for pixel repeated modes 2018-07-31 9:26 ` Russell King @ 2018-07-31 9:42 ` Russell King - ARM Linux -1 siblings, 0 replies; 80+ messages in thread From: Russell King - ARM Linux @ 2018-07-31 9:42 UTC (permalink / raw) To: linux-arm-kernel On Tue, Jul 31, 2018 at 10:26:55AM +0100, Russell King wrote: > TDA998x has no support for pixel repeated modes, and the code notes this > as a "TODO" item. The implementation appears to be relatively simple, > so lets add it. > > We need to calculate the serializer clock divisor based on the TMDS > clock rate, set the repeat control, and set the serializer pixel > repeat count. Since the audio code needs the actual TMDS clock, > record that. Note that this is an experimental patch - I haven't yet been able to test it beyond "does it still work with non-doubled modes". They tend to be low resolution modes, because the doubling is needed to maintain a minimum clock rate over HDMI. The doubled modes are (eg): VIC Name 6 720(1440)x480i at 60Hz 7 720(1440)x480i at 60Hz 8 720(1440)x240 at 60Hz 21 720(1440)x576i at 50Hz 22 720(1440)x576i at 50Hz 23 720(1440)x288 at 50Hz 24 720(1440)x288 at 50Hz They are probably only found with TVs rather than monitors. > > Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> > --- > drivers/gpu/drm/i2c/tda998x_drv.c | 26 ++++++++++++++++---------- > 1 file changed, 16 insertions(+), 10 deletions(-) > > diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c > index a31809ce30e2..08ce28cbdec4 100644 > --- a/drivers/gpu/drm/i2c/tda998x_drv.c > +++ b/drivers/gpu/drm/i2c/tda998x_drv.c > @@ -241,6 +241,7 @@ struct tda998x_priv { > # define HVF_CNTRL_1_PAD(x) (((x) & 3) << 4) > # define HVF_CNTRL_1_SEMI_PLANAR (1 << 6) > #define REG_RPT_CNTRL REG(0x00, 0xf0) /* write */ > +# define RPT_CNTRL_REPEAT(x) ((x) & 15) > #define REG_I2S_FORMAT REG(0x00, 0xfc) /* read/write */ > # define I2S_FORMAT(x) (((x) & 3) << 0) > #define REG_AIP_CLKSEL REG(0x00, 0xfd) /* write */ > @@ -1342,7 +1343,7 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge, > u16 vwin1_line_s, vwin1_line_e; > u16 vwin2_line_s, vwin2_line_e; > u16 de_pix_s, de_pix_e; > - u8 reg, div, rep; > + u8 reg, div, rep, sel_clk; > > /* > * Internally TDA998x is using ITU-R BT.656 style sync but > @@ -1405,7 +1406,16 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge, > (mode->vsync_end - mode->vsync_start)/2; > } > > - tmds_clock = mode->clock; > + /* > + * Select pixel repeat depending on the double-clock flag > + * (which means we have to repeat each pixel once.) > + */ > + rep = mode->flags & DRM_MODE_FLAG_DBLCLK ? 1 : 0; > + sel_clk = SEL_CLK_ENA_SC_CLK | SEL_CLK_SEL_CLK1 | > + SEL_CLK_SEL_VRF_CLK(rep ? 2 : 0); > + > + /* the TMDS clock is scaled up by the pixel repeat */ > + tmds_clock = mode->clock * (1 + rep); > > /* > * The divisor is power-of-2. The TDA9983B datasheet gives > @@ -1421,6 +1431,8 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge, > > mutex_lock(&priv->audio_mutex); > > + priv->tmds_clock = tmds_clock; > + > /* mute the audio FIFO: */ > reg_set(priv, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO); > > @@ -1443,12 +1455,8 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge, > reg_write(priv, REG_SERIALIZER, 0); > reg_write(priv, REG_HVF_CNTRL_1, HVF_CNTRL_1_VQR(0)); > > - /* TODO enable pixel repeat for pixel rates less than 25Msamp/s */ > - rep = 0; > - reg_write(priv, REG_RPT_CNTRL, 0); > - reg_write(priv, REG_SEL_CLK, SEL_CLK_SEL_VRF_CLK(0) | > - SEL_CLK_SEL_CLK1 | SEL_CLK_ENA_SC_CLK); > - > + reg_write(priv, REG_RPT_CNTRL, RPT_CNTRL_REPEAT(rep)); > + reg_write(priv, REG_SEL_CLK, sel_clk); > reg_write(priv, REG_PLL_SERIAL_2, PLL_SERIAL_2_SRL_NOSC(div) | > PLL_SERIAL_2_SRL_PR(rep)); > > @@ -1516,8 +1524,6 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge, > /* must be last register set: */ > reg_write(priv, REG_TBG_CNTRL_0, 0); > > - priv->tmds_clock = adjusted_mode->clock; > - > /* CEA-861B section 6 says that: > * CEA version 1 (CEA-861) has no support for infoframes. > * CEA version 2 (CEA-861A) supports version 1 AVI infoframes, > -- > 2.7.4 > -- RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line in suburbia: sync at 13.8Mbps down 630kbps up According to speedtest.net: 13Mbps down 490kbps up ^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PATCH 4/4] drm/i2c: tda998x: add support for pixel repeated modes @ 2018-07-31 9:42 ` Russell King - ARM Linux 0 siblings, 0 replies; 80+ messages in thread From: Russell King - ARM Linux @ 2018-07-31 9:42 UTC (permalink / raw) To: Peter Rosin Cc: David Airlie, Liviu Dudau, Jyri Sarha, Tomi Valkeinen, dri-devel, linux-arm-kernel On Tue, Jul 31, 2018 at 10:26:55AM +0100, Russell King wrote: > TDA998x has no support for pixel repeated modes, and the code notes this > as a "TODO" item. The implementation appears to be relatively simple, > so lets add it. > > We need to calculate the serializer clock divisor based on the TMDS > clock rate, set the repeat control, and set the serializer pixel > repeat count. Since the audio code needs the actual TMDS clock, > record that. Note that this is an experimental patch - I haven't yet been able to test it beyond "does it still work with non-doubled modes". They tend to be low resolution modes, because the doubling is needed to maintain a minimum clock rate over HDMI. The doubled modes are (eg): VIC Name 6 720(1440)x480i@60Hz 7 720(1440)x480i@60Hz 8 720(1440)x240@60Hz 21 720(1440)x576i@50Hz 22 720(1440)x576i@50Hz 23 720(1440)x288@50Hz 24 720(1440)x288@50Hz They are probably only found with TVs rather than monitors. > > Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> > --- > drivers/gpu/drm/i2c/tda998x_drv.c | 26 ++++++++++++++++---------- > 1 file changed, 16 insertions(+), 10 deletions(-) > > diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c > index a31809ce30e2..08ce28cbdec4 100644 > --- a/drivers/gpu/drm/i2c/tda998x_drv.c > +++ b/drivers/gpu/drm/i2c/tda998x_drv.c > @@ -241,6 +241,7 @@ struct tda998x_priv { > # define HVF_CNTRL_1_PAD(x) (((x) & 3) << 4) > # define HVF_CNTRL_1_SEMI_PLANAR (1 << 6) > #define REG_RPT_CNTRL REG(0x00, 0xf0) /* write */ > +# define RPT_CNTRL_REPEAT(x) ((x) & 15) > #define REG_I2S_FORMAT REG(0x00, 0xfc) /* read/write */ > # define I2S_FORMAT(x) (((x) & 3) << 0) > #define REG_AIP_CLKSEL REG(0x00, 0xfd) /* write */ > @@ -1342,7 +1343,7 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge, > u16 vwin1_line_s, vwin1_line_e; > u16 vwin2_line_s, vwin2_line_e; > u16 de_pix_s, de_pix_e; > - u8 reg, div, rep; > + u8 reg, div, rep, sel_clk; > > /* > * Internally TDA998x is using ITU-R BT.656 style sync but > @@ -1405,7 +1406,16 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge, > (mode->vsync_end - mode->vsync_start)/2; > } > > - tmds_clock = mode->clock; > + /* > + * Select pixel repeat depending on the double-clock flag > + * (which means we have to repeat each pixel once.) > + */ > + rep = mode->flags & DRM_MODE_FLAG_DBLCLK ? 1 : 0; > + sel_clk = SEL_CLK_ENA_SC_CLK | SEL_CLK_SEL_CLK1 | > + SEL_CLK_SEL_VRF_CLK(rep ? 2 : 0); > + > + /* the TMDS clock is scaled up by the pixel repeat */ > + tmds_clock = mode->clock * (1 + rep); > > /* > * The divisor is power-of-2. The TDA9983B datasheet gives > @@ -1421,6 +1431,8 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge, > > mutex_lock(&priv->audio_mutex); > > + priv->tmds_clock = tmds_clock; > + > /* mute the audio FIFO: */ > reg_set(priv, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO); > > @@ -1443,12 +1455,8 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge, > reg_write(priv, REG_SERIALIZER, 0); > reg_write(priv, REG_HVF_CNTRL_1, HVF_CNTRL_1_VQR(0)); > > - /* TODO enable pixel repeat for pixel rates less than 25Msamp/s */ > - rep = 0; > - reg_write(priv, REG_RPT_CNTRL, 0); > - reg_write(priv, REG_SEL_CLK, SEL_CLK_SEL_VRF_CLK(0) | > - SEL_CLK_SEL_CLK1 | SEL_CLK_ENA_SC_CLK); > - > + reg_write(priv, REG_RPT_CNTRL, RPT_CNTRL_REPEAT(rep)); > + reg_write(priv, REG_SEL_CLK, sel_clk); > reg_write(priv, REG_PLL_SERIAL_2, PLL_SERIAL_2_SRL_NOSC(div) | > PLL_SERIAL_2_SRL_PR(rep)); > > @@ -1516,8 +1524,6 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge, > /* must be last register set: */ > reg_write(priv, REG_TBG_CNTRL_0, 0); > > - priv->tmds_clock = adjusted_mode->clock; > - > /* CEA-861B section 6 says that: > * CEA version 1 (CEA-861) has no support for infoframes. > * CEA version 2 (CEA-861A) supports version 1 AVI infoframes, > -- > 2.7.4 > -- RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line in suburbia: sync at 13.8Mbps down 630kbps up According to speedtest.net: 13Mbps down 490kbps up ^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH v2 0/7] tda998x: allow use with bridge based devices 2018-07-31 9:23 ` Russell King - ARM Linux @ 2018-07-31 10:43 ` Peter Rosin -1 siblings, 0 replies; 80+ messages in thread From: Peter Rosin @ 2018-07-31 10:43 UTC (permalink / raw) To: linux-arm-kernel On 2018-07-31 11:23, Russell King - ARM Linux wrote: > On Tue, Jul 31, 2018 at 09:53:57AM +0200, Peter Rosin wrote: >> On 2018-07-31 09:41, Russell King - ARM Linux wrote: >>> On Tue, Jul 31, 2018 at 07:44:24AM +0200, Peter Rosin wrote: >>>> On 2018-07-30 18:41, Russell King - ARM Linux wrote: >>>>> Hi, >>>>> >>>>> This is a re-posting of the series I responded to Peter Rosin's May >>>>> posting, with a few bugs fixed, and the bridge registered outside of >>>>> the component helper. This should allow Peter to use the driver >>>>> while maintaining armada drm and tilcdc support. >>>>> >>>>> No comments (other than 0-day test results) were received on the >>>>> previous posting. >>>> >>>> I of course meant to comment on this! I didn't because there was a rush >>>> before vacation, then vacation, then a heap of important stuff that had >>>> piled up. This one simply had too low priority to make a significant bleep >>>> on the radar. Sorry for the silence... >>>> >>>> However, now that I do try to test, I get conflicts as I try to apply the >>>> patches. I'm wondering what this was based on? I've tried next-20180730 >>>> drm-misc/drm-misc-next from some minutes ago. >>> >>> They're based on 4.17. >> >> Right, meanwhile I massaged the patches into a combo of some local patches, >> next-20180730 and drm-misc-next, and tested that. The conflict was trivial >> once I had a closer look... >> >> And it seems to work (with atmel-hlcdc), so you can add >> >> Tested-by: Peter Rosin <peda@axentia.se> > > Thanks, I've added your attributation, and fixed patch 2 as you pointed > out. > > I have a four more tda998x patches if you're willing to test. These > follow on from this set - I've tweaked patch 2 in this follow on set to > cater for the removal of "_mode_" in > drm_mode_connector_update_edid_property. Sure thing. Those patches work for me too. So, feel free to add Tested-by: Peter Rosin <peda@axentia.se> However, a couple of notes: 1) I never succeeded in reading the edid, so I'm using a built-in edid. I noticed the patch adding the nxp,calib gpio and got my hopes up, but if I just add that to the DT I get tda998x 2-0070: found TDA19988 gpio-21 (nxp,calib): gpiod_direction_output: tried to set a GPIO tied to an IRQ as output tda9950 2-0034: TDA9950 CEC interface, hardware version 3.3 Grepping the source, that comes from gpiod_direction_output, which fails with -EIO after that message, so that can't be working... (Side note on that gpio; the way I read the patch I should specify the gpio as GPIO_ACTIVE_HIGH, but that seems backwards? Isn't the INT pin on the tda19988 active low?) ...and if I try to evade that by commenting out the interrupt stuff from the DT, I instead get tda998x 2-0070: found TDA19988 tda9950 2-0034: driver requires an interrupt Are we supposed to wire the INT pin to two different pins on the CPU, or what? Is edid reading know to work on 19988? The code suggests so, but maybe it hasn't been tested? Or maybe it regressed? 2) The lowest resolution on my monitor is 800x600, so I suppose I can't really test 4/4? Cheers, Peter > drivers/gpu/drm/i2c/tda998x_drv.c | 106 ++++++++++++++++++-------------------- > 1 file changed, 51 insertions(+), 55 deletions(-) > ^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PATCH v2 0/7] tda998x: allow use with bridge based devices @ 2018-07-31 10:43 ` Peter Rosin 0 siblings, 0 replies; 80+ messages in thread From: Peter Rosin @ 2018-07-31 10:43 UTC (permalink / raw) To: Russell King - ARM Linux Cc: David Airlie, Liviu Dudau, Jyri Sarha, Tomi Valkeinen, dri-devel, linux-arm-kernel On 2018-07-31 11:23, Russell King - ARM Linux wrote: > On Tue, Jul 31, 2018 at 09:53:57AM +0200, Peter Rosin wrote: >> On 2018-07-31 09:41, Russell King - ARM Linux wrote: >>> On Tue, Jul 31, 2018 at 07:44:24AM +0200, Peter Rosin wrote: >>>> On 2018-07-30 18:41, Russell King - ARM Linux wrote: >>>>> Hi, >>>>> >>>>> This is a re-posting of the series I responded to Peter Rosin's May >>>>> posting, with a few bugs fixed, and the bridge registered outside of >>>>> the component helper. This should allow Peter to use the driver >>>>> while maintaining armada drm and tilcdc support. >>>>> >>>>> No comments (other than 0-day test results) were received on the >>>>> previous posting. >>>> >>>> I of course meant to comment on this! I didn't because there was a rush >>>> before vacation, then vacation, then a heap of important stuff that had >>>> piled up. This one simply had too low priority to make a significant bleep >>>> on the radar. Sorry for the silence... >>>> >>>> However, now that I do try to test, I get conflicts as I try to apply the >>>> patches. I'm wondering what this was based on? I've tried next-20180730 >>>> drm-misc/drm-misc-next from some minutes ago. >>> >>> They're based on 4.17. >> >> Right, meanwhile I massaged the patches into a combo of some local patches, >> next-20180730 and drm-misc-next, and tested that. The conflict was trivial >> once I had a closer look... >> >> And it seems to work (with atmel-hlcdc), so you can add >> >> Tested-by: Peter Rosin <peda@axentia.se> > > Thanks, I've added your attributation, and fixed patch 2 as you pointed > out. > > I have a four more tda998x patches if you're willing to test. These > follow on from this set - I've tweaked patch 2 in this follow on set to > cater for the removal of "_mode_" in > drm_mode_connector_update_edid_property. Sure thing. Those patches work for me too. So, feel free to add Tested-by: Peter Rosin <peda@axentia.se> However, a couple of notes: 1) I never succeeded in reading the edid, so I'm using a built-in edid. I noticed the patch adding the nxp,calib gpio and got my hopes up, but if I just add that to the DT I get tda998x 2-0070: found TDA19988 gpio-21 (nxp,calib): gpiod_direction_output: tried to set a GPIO tied to an IRQ as output tda9950 2-0034: TDA9950 CEC interface, hardware version 3.3 Grepping the source, that comes from gpiod_direction_output, which fails with -EIO after that message, so that can't be working... (Side note on that gpio; the way I read the patch I should specify the gpio as GPIO_ACTIVE_HIGH, but that seems backwards? Isn't the INT pin on the tda19988 active low?) ...and if I try to evade that by commenting out the interrupt stuff from the DT, I instead get tda998x 2-0070: found TDA19988 tda9950 2-0034: driver requires an interrupt Are we supposed to wire the INT pin to two different pins on the CPU, or what? Is edid reading know to work on 19988? The code suggests so, but maybe it hasn't been tested? Or maybe it regressed? 2) The lowest resolution on my monitor is 800x600, so I suppose I can't really test 4/4? Cheers, Peter > drivers/gpu/drm/i2c/tda998x_drv.c | 106 ++++++++++++++++++-------------------- > 1 file changed, 51 insertions(+), 55 deletions(-) > ^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH v2 0/7] tda998x: allow use with bridge based devices 2018-07-31 10:43 ` Peter Rosin @ 2018-07-31 11:15 ` Russell King - ARM Linux -1 siblings, 0 replies; 80+ messages in thread From: Russell King - ARM Linux @ 2018-07-31 11:15 UTC (permalink / raw) To: linux-arm-kernel On Tue, Jul 31, 2018 at 12:43:34PM +0200, Peter Rosin wrote: > On 2018-07-31 11:23, Russell King - ARM Linux wrote: > > On Tue, Jul 31, 2018 at 09:53:57AM +0200, Peter Rosin wrote: > >> On 2018-07-31 09:41, Russell King - ARM Linux wrote: > >>> On Tue, Jul 31, 2018 at 07:44:24AM +0200, Peter Rosin wrote: > >>>> On 2018-07-30 18:41, Russell King - ARM Linux wrote: > >>>>> Hi, > >>>>> > >>>>> This is a re-posting of the series I responded to Peter Rosin's May > >>>>> posting, with a few bugs fixed, and the bridge registered outside of > >>>>> the component helper. This should allow Peter to use the driver > >>>>> while maintaining armada drm and tilcdc support. > >>>>> > >>>>> No comments (other than 0-day test results) were received on the > >>>>> previous posting. > >>>> > >>>> I of course meant to comment on this! I didn't because there was a rush > >>>> before vacation, then vacation, then a heap of important stuff that had > >>>> piled up. This one simply had too low priority to make a significant bleep > >>>> on the radar. Sorry for the silence... > >>>> > >>>> However, now that I do try to test, I get conflicts as I try to apply the > >>>> patches. I'm wondering what this was based on? I've tried next-20180730 > >>>> drm-misc/drm-misc-next from some minutes ago. > >>> > >>> They're based on 4.17. > >> > >> Right, meanwhile I massaged the patches into a combo of some local patches, > >> next-20180730 and drm-misc-next, and tested that. The conflict was trivial > >> once I had a closer look... > >> > >> And it seems to work (with atmel-hlcdc), so you can add > >> > >> Tested-by: Peter Rosin <peda@axentia.se> > > > > Thanks, I've added your attributation, and fixed patch 2 as you pointed > > out. > > > > I have a four more tda998x patches if you're willing to test. These > > follow on from this set - I've tweaked patch 2 in this follow on set to > > cater for the removal of "_mode_" in > > drm_mode_connector_update_edid_property. > > Sure thing. Those patches work for me too. So, feel free to add > > Tested-by: Peter Rosin <peda@axentia.se> > > However, a couple of notes: > > 1) I never succeeded in reading the edid, so I'm using a built-in edid. > > I noticed the patch adding the nxp,calib gpio and got my hopes up, but > if I just add that to the DT I get > > tda998x 2-0070: found TDA19988 > gpio-21 (nxp,calib): gpiod_direction_output: tried to set a GPIO tied to an IRQ as output > tda9950 2-0034: TDA9950 CEC interface, hardware version 3.3 > > Grepping the source, that comes from gpiod_direction_output, which > fails with -EIO after that message, so that can't be working... > > (Side note on that gpio; the way I read the patch I should specify > the gpio as GPIO_ACTIVE_HIGH, but that seems backwards? Isn't the > INT pin on the tda19988 active low?) See below... > ...and if I try to evade that by commenting out the interrupt stuff > from the DT, I instead get > > tda998x 2-0070: found TDA19988 > tda9950 2-0034: driver requires an interrupt > > Are we supposed to wire the INT pin to two different pins on the CPU, or > what? It's a problem with how some GPIO/IRQ drivers in Linux model GPIOs used as interrupts. There is a school of thought that if an IRQ is requested, then the GPIO associated with it should be requested and forced as an input. Not every GPIO/IRQ driver implements this, and the Dove driver does not. So, TDA998x with CEC works there. That's fine and dandy when you have "sensible" hardware, but the TDA998x uses the INT pin for more than just signalling an interrupt. It is also used as a calibration mechanism for the CEC controller's free-running clock. The CEC block requires various registers set, and then the INT pin being pulled low for exactly 10ms and then raised by the CPU. It uses this pulse to count the number of cycles of the internal FRO to calculate the divider necessary to get the CEC bus clock. The GPIO is "active high" because we drive it in "true" sense: local_irq_disable(); gpiod_set_value(calib, 0); mdelay(10); gpiod_set_value(calib, 1); local_irq_enable(); Note that the GPIO sense is independent of the IRQ trigger sense. Some TDA998x seem to function without calibration, but it depends on the temperature and supply voltage to the device, and the margins on other devices on the CEC bus. The TDA998x and CEC implement what's required for CEC to work, which requires a GPIO/IRQ driver that does not subscribe to the above mentioned school of thought. However, this should only cause the CEC part to fail, and should not be an issue for reading the EDID. EDID reading works in two stages with the TDA998x - there is no direct access to the EEPROM in the HDMI sink. Instead, the TDA998x is requested to read a block from the HDMI sink, and the received data then appears in the TDA998x registers. The interrupt _is_ optional for the TDA998x non-CEC part, and when present will be used to deal with hotplug and EDID reading. It is required for the CEC functionality though, so if there's no interrupt present in DT, the TDA9950 CEC controller driver will fail, but the TDA998x should continue to work. If you have tried without an interrupt, and EDID reading still doesn't work, it suggests there's an electrical problem with the DDC bus between the TDA998x and the HDMI sink. > Is edid reading know to work on 19988? The code suggests so, but maybe > it hasn't been tested? Or maybe it regressed? I've been using the TDA998x pretty much constantly and EDID reading does work. I've not had any reports that it fails on Juno nor with the TI hardware either, and I'm sure that I would've had some reports if it didnt' work there. There is an issue I'm aware of with the Synopsis DesignWare I2C controller - attempts to read more than 16 bytes result in the I2C master hardware crapping out, but in that case you'll get: "transfer terminated early - interrupt latency too high" in the kernel log - the problem there is that the hardware _automatically_ performs an I2C bus stop if the TX FIFO empties during a read, which means a high interrupt latency causes only the first TX FIFO-depth of data to be received. The driver _used_ to report success with garbage in the receive buffer after the first 16 bytes, now it gracefully fails and reports the condition to the kernel log. So, failure to read the EDID can have multiple reasons - it'll need some investigation - is it the TDA998x failing to read the EDID from the sink, or is it a failure to correctly read the EDID out of the TDA998x due to some bug in the I2C driver interacting with a large I2C receive request? > 2) The lowest resolution on my monitor is 800x600, so I suppose I > can't really test 4/4? No matter, it can stay as "experimental" for the time being. However, I should probably arrange for the mode validation to reject pixel doubled modes while we don't support them. -- RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line in suburbia: sync at 13.8Mbps down 630kbps up According to speedtest.net: 13Mbps down 490kbps up ^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PATCH v2 0/7] tda998x: allow use with bridge based devices @ 2018-07-31 11:15 ` Russell King - ARM Linux 0 siblings, 0 replies; 80+ messages in thread From: Russell King - ARM Linux @ 2018-07-31 11:15 UTC (permalink / raw) To: Peter Rosin Cc: David Airlie, Liviu Dudau, Jyri Sarha, Tomi Valkeinen, dri-devel, linux-arm-kernel On Tue, Jul 31, 2018 at 12:43:34PM +0200, Peter Rosin wrote: > On 2018-07-31 11:23, Russell King - ARM Linux wrote: > > On Tue, Jul 31, 2018 at 09:53:57AM +0200, Peter Rosin wrote: > >> On 2018-07-31 09:41, Russell King - ARM Linux wrote: > >>> On Tue, Jul 31, 2018 at 07:44:24AM +0200, Peter Rosin wrote: > >>>> On 2018-07-30 18:41, Russell King - ARM Linux wrote: > >>>>> Hi, > >>>>> > >>>>> This is a re-posting of the series I responded to Peter Rosin's May > >>>>> posting, with a few bugs fixed, and the bridge registered outside of > >>>>> the component helper. This should allow Peter to use the driver > >>>>> while maintaining armada drm and tilcdc support. > >>>>> > >>>>> No comments (other than 0-day test results) were received on the > >>>>> previous posting. > >>>> > >>>> I of course meant to comment on this! I didn't because there was a rush > >>>> before vacation, then vacation, then a heap of important stuff that had > >>>> piled up. This one simply had too low priority to make a significant bleep > >>>> on the radar. Sorry for the silence... > >>>> > >>>> However, now that I do try to test, I get conflicts as I try to apply the > >>>> patches. I'm wondering what this was based on? I've tried next-20180730 > >>>> drm-misc/drm-misc-next from some minutes ago. > >>> > >>> They're based on 4.17. > >> > >> Right, meanwhile I massaged the patches into a combo of some local patches, > >> next-20180730 and drm-misc-next, and tested that. The conflict was trivial > >> once I had a closer look... > >> > >> And it seems to work (with atmel-hlcdc), so you can add > >> > >> Tested-by: Peter Rosin <peda@axentia.se> > > > > Thanks, I've added your attributation, and fixed patch 2 as you pointed > > out. > > > > I have a four more tda998x patches if you're willing to test. These > > follow on from this set - I've tweaked patch 2 in this follow on set to > > cater for the removal of "_mode_" in > > drm_mode_connector_update_edid_property. > > Sure thing. Those patches work for me too. So, feel free to add > > Tested-by: Peter Rosin <peda@axentia.se> > > However, a couple of notes: > > 1) I never succeeded in reading the edid, so I'm using a built-in edid. > > I noticed the patch adding the nxp,calib gpio and got my hopes up, but > if I just add that to the DT I get > > tda998x 2-0070: found TDA19988 > gpio-21 (nxp,calib): gpiod_direction_output: tried to set a GPIO tied to an IRQ as output > tda9950 2-0034: TDA9950 CEC interface, hardware version 3.3 > > Grepping the source, that comes from gpiod_direction_output, which > fails with -EIO after that message, so that can't be working... > > (Side note on that gpio; the way I read the patch I should specify > the gpio as GPIO_ACTIVE_HIGH, but that seems backwards? Isn't the > INT pin on the tda19988 active low?) See below... > ...and if I try to evade that by commenting out the interrupt stuff > from the DT, I instead get > > tda998x 2-0070: found TDA19988 > tda9950 2-0034: driver requires an interrupt > > Are we supposed to wire the INT pin to two different pins on the CPU, or > what? It's a problem with how some GPIO/IRQ drivers in Linux model GPIOs used as interrupts. There is a school of thought that if an IRQ is requested, then the GPIO associated with it should be requested and forced as an input. Not every GPIO/IRQ driver implements this, and the Dove driver does not. So, TDA998x with CEC works there. That's fine and dandy when you have "sensible" hardware, but the TDA998x uses the INT pin for more than just signalling an interrupt. It is also used as a calibration mechanism for the CEC controller's free-running clock. The CEC block requires various registers set, and then the INT pin being pulled low for exactly 10ms and then raised by the CPU. It uses this pulse to count the number of cycles of the internal FRO to calculate the divider necessary to get the CEC bus clock. The GPIO is "active high" because we drive it in "true" sense: local_irq_disable(); gpiod_set_value(calib, 0); mdelay(10); gpiod_set_value(calib, 1); local_irq_enable(); Note that the GPIO sense is independent of the IRQ trigger sense. Some TDA998x seem to function without calibration, but it depends on the temperature and supply voltage to the device, and the margins on other devices on the CEC bus. The TDA998x and CEC implement what's required for CEC to work, which requires a GPIO/IRQ driver that does not subscribe to the above mentioned school of thought. However, this should only cause the CEC part to fail, and should not be an issue for reading the EDID. EDID reading works in two stages with the TDA998x - there is no direct access to the EEPROM in the HDMI sink. Instead, the TDA998x is requested to read a block from the HDMI sink, and the received data then appears in the TDA998x registers. The interrupt _is_ optional for the TDA998x non-CEC part, and when present will be used to deal with hotplug and EDID reading. It is required for the CEC functionality though, so if there's no interrupt present in DT, the TDA9950 CEC controller driver will fail, but the TDA998x should continue to work. If you have tried without an interrupt, and EDID reading still doesn't work, it suggests there's an electrical problem with the DDC bus between the TDA998x and the HDMI sink. > Is edid reading know to work on 19988? The code suggests so, but maybe > it hasn't been tested? Or maybe it regressed? I've been using the TDA998x pretty much constantly and EDID reading does work. I've not had any reports that it fails on Juno nor with the TI hardware either, and I'm sure that I would've had some reports if it didnt' work there. There is an issue I'm aware of with the Synopsis DesignWare I2C controller - attempts to read more than 16 bytes result in the I2C master hardware crapping out, but in that case you'll get: "transfer terminated early - interrupt latency too high" in the kernel log - the problem there is that the hardware _automatically_ performs an I2C bus stop if the TX FIFO empties during a read, which means a high interrupt latency causes only the first TX FIFO-depth of data to be received. The driver _used_ to report success with garbage in the receive buffer after the first 16 bytes, now it gracefully fails and reports the condition to the kernel log. So, failure to read the EDID can have multiple reasons - it'll need some investigation - is it the TDA998x failing to read the EDID from the sink, or is it a failure to correctly read the EDID out of the TDA998x due to some bug in the I2C driver interacting with a large I2C receive request? > 2) The lowest resolution on my monitor is 800x600, so I suppose I > can't really test 4/4? No matter, it can stay as "experimental" for the time being. However, I should probably arrange for the mode validation to reject pixel doubled modes while we don't support them. -- RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line in suburbia: sync at 13.8Mbps down 630kbps up According to speedtest.net: 13Mbps down 490kbps up ^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH v2 0/7] tda998x: allow use with bridge based devices 2018-07-31 11:15 ` Russell King - ARM Linux @ 2018-08-01 9:01 ` Peter Rosin -1 siblings, 0 replies; 80+ messages in thread From: Peter Rosin @ 2018-08-01 9:01 UTC (permalink / raw) To: linux-arm-kernel On 2018-07-31 13:15, Russell King - ARM Linux wrote: > On Tue, Jul 31, 2018 at 12:43:34PM +0200, Peter Rosin wrote: >> On 2018-07-31 11:23, Russell King - ARM Linux wrote: >>> On Tue, Jul 31, 2018 at 09:53:57AM +0200, Peter Rosin wrote: >>>> On 2018-07-31 09:41, Russell King - ARM Linux wrote: >>>>> On Tue, Jul 31, 2018 at 07:44:24AM +0200, Peter Rosin wrote: >>>>>> On 2018-07-30 18:41, Russell King - ARM Linux wrote: >>>>>>> Hi, >>>>>>> >>>>>>> This is a re-posting of the series I responded to Peter Rosin's May >>>>>>> posting, with a few bugs fixed, and the bridge registered outside of >>>>>>> the component helper. This should allow Peter to use the driver >>>>>>> while maintaining armada drm and tilcdc support. >>>>>>> >>>>>>> No comments (other than 0-day test results) were received on the >>>>>>> previous posting. >>>>>> >>>>>> I of course meant to comment on this! I didn't because there was a rush >>>>>> before vacation, then vacation, then a heap of important stuff that had >>>>>> piled up. This one simply had too low priority to make a significant bleep >>>>>> on the radar. Sorry for the silence... >>>>>> >>>>>> However, now that I do try to test, I get conflicts as I try to apply the >>>>>> patches. I'm wondering what this was based on? I've tried next-20180730 >>>>>> drm-misc/drm-misc-next from some minutes ago. >>>>> >>>>> They're based on 4.17. >>>> >>>> Right, meanwhile I massaged the patches into a combo of some local patches, >>>> next-20180730 and drm-misc-next, and tested that. The conflict was trivial >>>> once I had a closer look... >>>> >>>> And it seems to work (with atmel-hlcdc), so you can add >>>> >>>> Tested-by: Peter Rosin <peda@axentia.se> >>> >>> Thanks, I've added your attributation, and fixed patch 2 as you pointed >>> out. >>> >>> I have a four more tda998x patches if you're willing to test. These >>> follow on from this set - I've tweaked patch 2 in this follow on set to >>> cater for the removal of "_mode_" in >>> drm_mode_connector_update_edid_property. >> >> Sure thing. Those patches work for me too. So, feel free to add >> >> Tested-by: Peter Rosin <peda@axentia.se> >> >> However, a couple of notes: >> >> 1) I never succeeded in reading the edid, so I'm using a built-in edid. >> >> I noticed the patch adding the nxp,calib gpio and got my hopes up, but >> if I just add that to the DT I get >> >> tda998x 2-0070: found TDA19988 >> gpio-21 (nxp,calib): gpiod_direction_output: tried to set a GPIO tied to an IRQ as output >> tda9950 2-0034: TDA9950 CEC interface, hardware version 3.3 >> >> Grepping the source, that comes from gpiod_direction_output, which >> fails with -EIO after that message, so that can't be working... >> >> (Side note on that gpio; the way I read the patch I should specify >> the gpio as GPIO_ACTIVE_HIGH, but that seems backwards? Isn't the >> INT pin on the tda19988 active low?) > > See below... > >> ...and if I try to evade that by commenting out the interrupt stuff >> from the DT, I instead get >> >> tda998x 2-0070: found TDA19988 >> tda9950 2-0034: driver requires an interrupt >> >> Are we supposed to wire the INT pin to two different pins on the CPU, or >> what? > > It's a problem with how some GPIO/IRQ drivers in Linux model GPIOs > used as interrupts. There is a school of thought that if an IRQ is > requested, then the GPIO associated with it should be requested and > forced as an input. Not every GPIO/IRQ driver implements this, and > the Dove driver does not. So, TDA998x with CEC works there. I guess I might have to live without CEC, which BTW is not the end of the world... > That's fine and dandy when you have "sensible" hardware, but the TDA998x > uses the INT pin for more than just signalling an interrupt. It is also > used as a calibration mechanism for the CEC controller's free-running > clock. The CEC block requires various registers set, and then the INT > pin being pulled low for exactly 10ms and then raised by the CPU. It > uses this pulse to count the number of cycles of the internal FRO to > calculate the divider necessary to get the CEC bus clock. > > The GPIO is "active high" because we drive it in "true" sense: > > local_irq_disable(); > gpiod_set_value(calib, 0); > mdelay(10); > gpiod_set_value(calib, 1); > local_irq_enable(); > > Note that the GPIO sense is independent of the IRQ trigger sense. Yes, I noticed this, but just mentioned that I thought it backwards. You activate the special state by setting the pin low, which to me make it a prime candidate for using active-low (especially when the INT function of the pin is active-low, but that isn't really related). But of course, active-low or active-high ultimately depends on *what* it is that is active, so it will always be a matter of definition. Anyway, the ship has sailed... > Some TDA998x seem to function without calibration, but it depends on the > temperature and supply voltage to the device, and the margins on other > devices on the CEC bus. > > The TDA998x and CEC implement what's required for CEC to work, which > requires a GPIO/IRQ driver that does not subscribe to the above > mentioned school of thought. > > However, this should only cause the CEC part to fail, and should not be > an issue for reading the EDID. > > EDID reading works in two stages with the TDA998x - there is no direct > access to the EEPROM in the HDMI sink. Instead, the TDA998x is > requested to read a block from the HDMI sink, and the received data > then appears in the TDA998x registers. The interrupt _is_ optional > for the TDA998x non-CEC part, and when present will be used to deal with > hotplug and EDID reading. It is required for the CEC functionality > though, so if there's no interrupt present in DT, the TDA9950 CEC > controller driver will fail, but the TDA998x should continue to work. > > If you have tried without an interrupt, and EDID reading still doesn't > work, it suggests there's an electrical problem with the DDC bus between > the TDA998x and the HDMI sink. Interrupt or not does not seem to matter. And yes, my plan is to try to hook up a oscilloscope to the DDC bus, but it's a bit difficult since the HW designer didn't add any test points and covered the interesting part of the board with the CPU module. Sigh. And a microscope would be helpful, something which I don't have at this location. So, it might be a while before I can actually do it... >> Is edid reading know to work on 19988? The code suggests so, but maybe >> it hasn't been tested? Or maybe it regressed? > > I've been using the TDA998x pretty much constantly and EDID reading > does work. I've not had any reports that it fails on Juno nor with > the TI hardware either, and I'm sure that I would've had some reports > if it didnt' work there. > > There is an issue I'm aware of with the Synopsis DesignWare I2C > controller - attempts to read more than 16 bytes result in the I2C > master hardware crapping out, but in that case you'll get: > > "transfer terminated early - interrupt latency too high" > > in the kernel log - the problem there is that the hardware > _automatically_ performs an I2C bus stop if the TX FIFO empties > during a read, which means a high interrupt latency causes only the > first TX FIFO-depth of data to be received. The driver _used_ to > report success with garbage in the receive buffer after the first > 16 bytes, now it gracefully fails and reports the condition to the > kernel log. > > So, failure to read the EDID can have multiple reasons - it'll need > some investigation - is it the TDA998x failing to read the EDID from > the sink, or is it a failure to correctly read the EDID out of the > TDA998x due to some bug in the I2C driver interacting with a large > I2C receive request? I don't think it's a problem with the atmel I2C driver. IIRC, the tda998x driver issues the command a initiate the EDID read, but that times out. So it appears to be the TDA19988 that fails to read the EDID over the DDC bus? Which brings me to the double problem with the scopes mentioned above... Cheers, Peter >> 2) The lowest resolution on my monitor is 800x600, so I suppose I >> can't really test 4/4? > > No matter, it can stay as "experimental" for the time being. However, > I should probably arrange for the mode validation to reject pixel > doubled modes while we don't support them. > ^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PATCH v2 0/7] tda998x: allow use with bridge based devices @ 2018-08-01 9:01 ` Peter Rosin 0 siblings, 0 replies; 80+ messages in thread From: Peter Rosin @ 2018-08-01 9:01 UTC (permalink / raw) To: Russell King - ARM Linux Cc: David Airlie, Liviu Dudau, Jyri Sarha, Tomi Valkeinen, dri-devel, linux-arm-kernel On 2018-07-31 13:15, Russell King - ARM Linux wrote: > On Tue, Jul 31, 2018 at 12:43:34PM +0200, Peter Rosin wrote: >> On 2018-07-31 11:23, Russell King - ARM Linux wrote: >>> On Tue, Jul 31, 2018 at 09:53:57AM +0200, Peter Rosin wrote: >>>> On 2018-07-31 09:41, Russell King - ARM Linux wrote: >>>>> On Tue, Jul 31, 2018 at 07:44:24AM +0200, Peter Rosin wrote: >>>>>> On 2018-07-30 18:41, Russell King - ARM Linux wrote: >>>>>>> Hi, >>>>>>> >>>>>>> This is a re-posting of the series I responded to Peter Rosin's May >>>>>>> posting, with a few bugs fixed, and the bridge registered outside of >>>>>>> the component helper. This should allow Peter to use the driver >>>>>>> while maintaining armada drm and tilcdc support. >>>>>>> >>>>>>> No comments (other than 0-day test results) were received on the >>>>>>> previous posting. >>>>>> >>>>>> I of course meant to comment on this! I didn't because there was a rush >>>>>> before vacation, then vacation, then a heap of important stuff that had >>>>>> piled up. This one simply had too low priority to make a significant bleep >>>>>> on the radar. Sorry for the silence... >>>>>> >>>>>> However, now that I do try to test, I get conflicts as I try to apply the >>>>>> patches. I'm wondering what this was based on? I've tried next-20180730 >>>>>> drm-misc/drm-misc-next from some minutes ago. >>>>> >>>>> They're based on 4.17. >>>> >>>> Right, meanwhile I massaged the patches into a combo of some local patches, >>>> next-20180730 and drm-misc-next, and tested that. The conflict was trivial >>>> once I had a closer look... >>>> >>>> And it seems to work (with atmel-hlcdc), so you can add >>>> >>>> Tested-by: Peter Rosin <peda@axentia.se> >>> >>> Thanks, I've added your attributation, and fixed patch 2 as you pointed >>> out. >>> >>> I have a four more tda998x patches if you're willing to test. These >>> follow on from this set - I've tweaked patch 2 in this follow on set to >>> cater for the removal of "_mode_" in >>> drm_mode_connector_update_edid_property. >> >> Sure thing. Those patches work for me too. So, feel free to add >> >> Tested-by: Peter Rosin <peda@axentia.se> >> >> However, a couple of notes: >> >> 1) I never succeeded in reading the edid, so I'm using a built-in edid. >> >> I noticed the patch adding the nxp,calib gpio and got my hopes up, but >> if I just add that to the DT I get >> >> tda998x 2-0070: found TDA19988 >> gpio-21 (nxp,calib): gpiod_direction_output: tried to set a GPIO tied to an IRQ as output >> tda9950 2-0034: TDA9950 CEC interface, hardware version 3.3 >> >> Grepping the source, that comes from gpiod_direction_output, which >> fails with -EIO after that message, so that can't be working... >> >> (Side note on that gpio; the way I read the patch I should specify >> the gpio as GPIO_ACTIVE_HIGH, but that seems backwards? Isn't the >> INT pin on the tda19988 active low?) > > See below... > >> ...and if I try to evade that by commenting out the interrupt stuff >> from the DT, I instead get >> >> tda998x 2-0070: found TDA19988 >> tda9950 2-0034: driver requires an interrupt >> >> Are we supposed to wire the INT pin to two different pins on the CPU, or >> what? > > It's a problem with how some GPIO/IRQ drivers in Linux model GPIOs > used as interrupts. There is a school of thought that if an IRQ is > requested, then the GPIO associated with it should be requested and > forced as an input. Not every GPIO/IRQ driver implements this, and > the Dove driver does not. So, TDA998x with CEC works there. I guess I might have to live without CEC, which BTW is not the end of the world... > That's fine and dandy when you have "sensible" hardware, but the TDA998x > uses the INT pin for more than just signalling an interrupt. It is also > used as a calibration mechanism for the CEC controller's free-running > clock. The CEC block requires various registers set, and then the INT > pin being pulled low for exactly 10ms and then raised by the CPU. It > uses this pulse to count the number of cycles of the internal FRO to > calculate the divider necessary to get the CEC bus clock. > > The GPIO is "active high" because we drive it in "true" sense: > > local_irq_disable(); > gpiod_set_value(calib, 0); > mdelay(10); > gpiod_set_value(calib, 1); > local_irq_enable(); > > Note that the GPIO sense is independent of the IRQ trigger sense. Yes, I noticed this, but just mentioned that I thought it backwards. You activate the special state by setting the pin low, which to me make it a prime candidate for using active-low (especially when the INT function of the pin is active-low, but that isn't really related). But of course, active-low or active-high ultimately depends on *what* it is that is active, so it will always be a matter of definition. Anyway, the ship has sailed... > Some TDA998x seem to function without calibration, but it depends on the > temperature and supply voltage to the device, and the margins on other > devices on the CEC bus. > > The TDA998x and CEC implement what's required for CEC to work, which > requires a GPIO/IRQ driver that does not subscribe to the above > mentioned school of thought. > > However, this should only cause the CEC part to fail, and should not be > an issue for reading the EDID. > > EDID reading works in two stages with the TDA998x - there is no direct > access to the EEPROM in the HDMI sink. Instead, the TDA998x is > requested to read a block from the HDMI sink, and the received data > then appears in the TDA998x registers. The interrupt _is_ optional > for the TDA998x non-CEC part, and when present will be used to deal with > hotplug and EDID reading. It is required for the CEC functionality > though, so if there's no interrupt present in DT, the TDA9950 CEC > controller driver will fail, but the TDA998x should continue to work. > > If you have tried without an interrupt, and EDID reading still doesn't > work, it suggests there's an electrical problem with the DDC bus between > the TDA998x and the HDMI sink. Interrupt or not does not seem to matter. And yes, my plan is to try to hook up a oscilloscope to the DDC bus, but it's a bit difficult since the HW designer didn't add any test points and covered the interesting part of the board with the CPU module. Sigh. And a microscope would be helpful, something which I don't have at this location. So, it might be a while before I can actually do it... >> Is edid reading know to work on 19988? The code suggests so, but maybe >> it hasn't been tested? Or maybe it regressed? > > I've been using the TDA998x pretty much constantly and EDID reading > does work. I've not had any reports that it fails on Juno nor with > the TI hardware either, and I'm sure that I would've had some reports > if it didnt' work there. > > There is an issue I'm aware of with the Synopsis DesignWare I2C > controller - attempts to read more than 16 bytes result in the I2C > master hardware crapping out, but in that case you'll get: > > "transfer terminated early - interrupt latency too high" > > in the kernel log - the problem there is that the hardware > _automatically_ performs an I2C bus stop if the TX FIFO empties > during a read, which means a high interrupt latency causes only the > first TX FIFO-depth of data to be received. The driver _used_ to > report success with garbage in the receive buffer after the first > 16 bytes, now it gracefully fails and reports the condition to the > kernel log. > > So, failure to read the EDID can have multiple reasons - it'll need > some investigation - is it the TDA998x failing to read the EDID from > the sink, or is it a failure to correctly read the EDID out of the > TDA998x due to some bug in the I2C driver interacting with a large > I2C receive request? I don't think it's a problem with the atmel I2C driver. IIRC, the tda998x driver issues the command a initiate the EDID read, but that times out. So it appears to be the TDA19988 that fails to read the EDID over the DDC bus? Which brings me to the double problem with the scopes mentioned above... Cheers, Peter >> 2) The lowest resolution on my monitor is 800x600, so I suppose I >> can't really test 4/4? > > No matter, it can stay as "experimental" for the time being. However, > I should probably arrange for the mode validation to reject pixel > doubled modes while we don't support them. > ^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH v2 0/7] tda998x: allow use with bridge based devices 2018-08-01 9:01 ` Peter Rosin @ 2018-08-01 9:35 ` Russell King - ARM Linux -1 siblings, 0 replies; 80+ messages in thread From: Russell King - ARM Linux @ 2018-08-01 9:35 UTC (permalink / raw) To: linux-arm-kernel On Wed, Aug 01, 2018 at 11:01:12AM +0200, Peter Rosin wrote: > I don't think it's a problem with the atmel I2C driver. IIRC, the > tda998x driver issues the command a initiate the EDID read, but that > times out. So it appears to be the TDA19988 that fails to read the > EDID over the DDC bus? Which brings me to the double problem with the > scopes mentioned above... It sounds like it. It may be helpful to know that there are HDMI pass-through boards available that give access to all the HDMI signals: https://elabbay.myshopify.com/collections/camera https://elabbay.myshopify.com/collections/camera/products/hdmi-af-af-v1a-hdmi-type-a-female-to-hdmi-type-a-male-pass-through-adapter-breakout-board I've never bought from them, so please don't take this as a recommendation - the fact that there seems to be no company details on their site doesn't seem good, and as the whois for elabbay.com is obscured also doesn't give me any confidence to buy from them. -- RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line in suburbia: sync at 13.8Mbps down 630kbps up According to speedtest.net: 13Mbps down 490kbps up ^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PATCH v2 0/7] tda998x: allow use with bridge based devices @ 2018-08-01 9:35 ` Russell King - ARM Linux 0 siblings, 0 replies; 80+ messages in thread From: Russell King - ARM Linux @ 2018-08-01 9:35 UTC (permalink / raw) To: Peter Rosin Cc: David Airlie, Liviu Dudau, Jyri Sarha, Tomi Valkeinen, dri-devel, linux-arm-kernel On Wed, Aug 01, 2018 at 11:01:12AM +0200, Peter Rosin wrote: > I don't think it's a problem with the atmel I2C driver. IIRC, the > tda998x driver issues the command a initiate the EDID read, but that > times out. So it appears to be the TDA19988 that fails to read the > EDID over the DDC bus? Which brings me to the double problem with the > scopes mentioned above... It sounds like it. It may be helpful to know that there are HDMI pass-through boards available that give access to all the HDMI signals: https://elabbay.myshopify.com/collections/camera https://elabbay.myshopify.com/collections/camera/products/hdmi-af-af-v1a-hdmi-type-a-female-to-hdmi-type-a-male-pass-through-adapter-breakout-board I've never bought from them, so please don't take this as a recommendation - the fact that there seems to be no company details on their site doesn't seem good, and as the whois for elabbay.com is obscured also doesn't give me any confidence to buy from them. -- RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line in suburbia: sync at 13.8Mbps down 630kbps up According to speedtest.net: 13Mbps down 490kbps up ^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH v2 0/7] tda998x: allow use with bridge based devices 2018-08-01 9:35 ` Russell King - ARM Linux @ 2018-08-02 6:06 ` Peter Rosin -1 siblings, 0 replies; 80+ messages in thread From: Peter Rosin @ 2018-08-02 6:06 UTC (permalink / raw) To: linux-arm-kernel On 2018-08-01 11:35, Russell King - ARM Linux wrote: > On Wed, Aug 01, 2018 at 11:01:12AM +0200, Peter Rosin wrote: >> I don't think it's a problem with the atmel I2C driver. IIRC, the >> tda998x driver issues the command a initiate the EDID read, but that >> times out. So it appears to be the TDA19988 that fails to read the >> EDID over the DDC bus? Which brings me to the double problem with the >> scopes mentioned above... > > It sounds like it. > > It may be helpful to know that there are HDMI pass-through boards > available that give access to all the HDMI signals: > > https://elabbay.myshopify.com/collections/camera > https://elabbay.myshopify.com/collections/camera/products/hdmi-af-af-v1a-hdmi-type-a-female-to-hdmi-type-a-male-pass-through-adapter-breakout-board > > I've never bought from them, so please don't take this as a > recommendation - the fact that there seems to be no company details > on their site doesn't seem good, and as the whois for elabbay.com is > obscured also doesn't give me any confidence to buy from them. I still will not be able to inspect the DDC bus between the TDA19988 and the buffer circuit (IP4786), but the gadget seems useful enough and it's not a shitload of money. We'll see how long it takes for it to get here... Thanks for the pointer! Maybe :-) Cheers, Peter ^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PATCH v2 0/7] tda998x: allow use with bridge based devices @ 2018-08-02 6:06 ` Peter Rosin 0 siblings, 0 replies; 80+ messages in thread From: Peter Rosin @ 2018-08-02 6:06 UTC (permalink / raw) To: Russell King - ARM Linux Cc: David Airlie, Liviu Dudau, Jyri Sarha, Tomi Valkeinen, dri-devel, linux-arm-kernel On 2018-08-01 11:35, Russell King - ARM Linux wrote: > On Wed, Aug 01, 2018 at 11:01:12AM +0200, Peter Rosin wrote: >> I don't think it's a problem with the atmel I2C driver. IIRC, the >> tda998x driver issues the command a initiate the EDID read, but that >> times out. So it appears to be the TDA19988 that fails to read the >> EDID over the DDC bus? Which brings me to the double problem with the >> scopes mentioned above... > > It sounds like it. > > It may be helpful to know that there are HDMI pass-through boards > available that give access to all the HDMI signals: > > https://elabbay.myshopify.com/collections/camera > https://elabbay.myshopify.com/collections/camera/products/hdmi-af-af-v1a-hdmi-type-a-female-to-hdmi-type-a-male-pass-through-adapter-breakout-board > > I've never bought from them, so please don't take this as a > recommendation - the fact that there seems to be no company details > on their site doesn't seem good, and as the whois for elabbay.com is > obscured also doesn't give me any confidence to buy from them. I still will not be able to inspect the DDC bus between the TDA19988 and the buffer circuit (IP4786), but the gadget seems useful enough and it's not a shitload of money. We'll see how long it takes for it to get here... Thanks for the pointer! Maybe :-) Cheers, Peter ^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH v2 0/7] tda998x: allow use with bridge based devices 2018-08-02 6:06 ` Peter Rosin @ 2018-11-12 16:50 ` Peter Rosin -1 siblings, 0 replies; 80+ messages in thread From: Peter Rosin @ 2018-11-12 16:50 UTC (permalink / raw) To: linux-arm-kernel On 2018-08-02 08:06, Peter Rosin wrote: > On 2018-08-01 11:35, Russell King - ARM Linux wrote: >> On Wed, Aug 01, 2018 at 11:01:12AM +0200, Peter Rosin wrote: >>> I don't think it's a problem with the atmel I2C driver. IIRC, the >>> tda998x driver issues the command a initiate the EDID read, but that >>> times out. So it appears to be the TDA19988 that fails to read the >>> EDID over the DDC bus? Which brings me to the double problem with the >>> scopes mentioned above... >> >> It sounds like it. >> >> It may be helpful to know that there are HDMI pass-through boards >> available that give access to all the HDMI signals: >> >> https://elabbay.myshopify.com/collections/camera >> https://elabbay.myshopify.com/collections/camera/products/hdmi-af-af-v1a-hdmi-type-a-female-to-hdmi-type-a-male-pass-through-adapter-breakout-board >> >> I've never bought from them, so please don't take this as a >> recommendation - the fact that there seems to be no company details >> on their site doesn't seem good, and as the whois for elabbay.com is >> obscured also doesn't give me any confidence to buy from them. > > I still will not be able to inspect the DDC bus between the TDA19988 > and the buffer circuit (IP4786), but the gadget seems useful enough and > it's not a shitload of money. We'll see how long it takes for it to get > here... > > Thanks for the pointer! Maybe :-) I got the pass-through board a while back, and that board works as expected and there was no problem with ordering etc. What I could see with that was that the TDA19988 was able to initiate a start condition (SDA -> low) but then nothing more happened. Then last week, someone noticed that even though the TDA19988 is driven by 1.8V, it still needs the high signals of the DDC bus to be above 3V, which was unexpected and not catered for by the design. Changing VCC(SYS) of the buffer circuit in place (IP4786, pin 27) to 3.3V fixed the issue and EDID reading works, and this was confirmed earlier today. So, the problem was that the TDA19988 only ever saw "low" DDC signals, and probably aborted when the bus appeared busy. Or something. If anyone cares... Cheers, Peter ^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PATCH v2 0/7] tda998x: allow use with bridge based devices @ 2018-11-12 16:50 ` Peter Rosin 0 siblings, 0 replies; 80+ messages in thread From: Peter Rosin @ 2018-11-12 16:50 UTC (permalink / raw) To: Russell King - ARM Linux Cc: David Airlie, Liviu Dudau, Jyri Sarha, Tomi Valkeinen, dri-devel, linux-arm-kernel On 2018-08-02 08:06, Peter Rosin wrote: > On 2018-08-01 11:35, Russell King - ARM Linux wrote: >> On Wed, Aug 01, 2018 at 11:01:12AM +0200, Peter Rosin wrote: >>> I don't think it's a problem with the atmel I2C driver. IIRC, the >>> tda998x driver issues the command a initiate the EDID read, but that >>> times out. So it appears to be the TDA19988 that fails to read the >>> EDID over the DDC bus? Which brings me to the double problem with the >>> scopes mentioned above... >> >> It sounds like it. >> >> It may be helpful to know that there are HDMI pass-through boards >> available that give access to all the HDMI signals: >> >> https://elabbay.myshopify.com/collections/camera >> https://elabbay.myshopify.com/collections/camera/products/hdmi-af-af-v1a-hdmi-type-a-female-to-hdmi-type-a-male-pass-through-adapter-breakout-board >> >> I've never bought from them, so please don't take this as a >> recommendation - the fact that there seems to be no company details >> on their site doesn't seem good, and as the whois for elabbay.com is >> obscured also doesn't give me any confidence to buy from them. > > I still will not be able to inspect the DDC bus between the TDA19988 > and the buffer circuit (IP4786), but the gadget seems useful enough and > it's not a shitload of money. We'll see how long it takes for it to get > here... > > Thanks for the pointer! Maybe :-) I got the pass-through board a while back, and that board works as expected and there was no problem with ordering etc. What I could see with that was that the TDA19988 was able to initiate a start condition (SDA -> low) but then nothing more happened. Then last week, someone noticed that even though the TDA19988 is driven by 1.8V, it still needs the high signals of the DDC bus to be above 3V, which was unexpected and not catered for by the design. Changing VCC(SYS) of the buffer circuit in place (IP4786, pin 27) to 3.3V fixed the issue and EDID reading works, and this was confirmed earlier today. So, the problem was that the TDA19988 only ever saw "low" DDC signals, and probably aborted when the bus appeared busy. Or something. If anyone cares... Cheers, Peter ^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH v2 0/7] tda998x: allow use with bridge based devices 2018-11-12 16:50 ` Peter Rosin @ 2018-11-12 17:00 ` Russell King - ARM Linux -1 siblings, 0 replies; 80+ messages in thread From: Russell King - ARM Linux @ 2018-11-12 17:00 UTC (permalink / raw) To: linux-arm-kernel On Mon, Nov 12, 2018 at 04:50:37PM +0000, Peter Rosin wrote: > On 2018-08-02 08:06, Peter Rosin wrote: > > On 2018-08-01 11:35, Russell King - ARM Linux wrote: > >> On Wed, Aug 01, 2018 at 11:01:12AM +0200, Peter Rosin wrote: > >>> I don't think it's a problem with the atmel I2C driver. IIRC, the > >>> tda998x driver issues the command a initiate the EDID read, but that > >>> times out. So it appears to be the TDA19988 that fails to read the > >>> EDID over the DDC bus? Which brings me to the double problem with the > >>> scopes mentioned above... > >> > >> It sounds like it. > >> > >> It may be helpful to know that there are HDMI pass-through boards > >> available that give access to all the HDMI signals: > >> > >> https://elabbay.myshopify.com/collections/camera > >> https://elabbay.myshopify.com/collections/camera/products/hdmi-af-af-v1a-hdmi-type-a-female-to-hdmi-type-a-male-pass-through-adapter-breakout-board > >> > >> I've never bought from them, so please don't take this as a > >> recommendation - the fact that there seems to be no company details > >> on their site doesn't seem good, and as the whois for elabbay.com is > >> obscured also doesn't give me any confidence to buy from them. > > > > I still will not be able to inspect the DDC bus between the TDA19988 > > and the buffer circuit (IP4786), but the gadget seems useful enough and > > it's not a shitload of money. We'll see how long it takes for it to get > > here... > > > > Thanks for the pointer! Maybe :-) > > I got the pass-through board a while back, and that board works as expected > and there was no problem with ordering etc. What I could see with that was > that the TDA19988 was able to initiate a start condition (SDA -> low) but > then nothing more happened. > > Then last week, someone noticed that even though the TDA19988 is driven by > 1.8V, it still needs the high signals of the DDC bus to be above 3V, which > was unexpected and not catered for by the design. Changing VCC(SYS) of the > buffer circuit in place (IP4786, pin 27) to 3.3V fixed the issue and EDID > reading works, and this was confirmed earlier today. > > So, the problem was that the TDA19988 only ever saw "low" DDC signals, and > probably aborted when the bus appeared busy. Or something. Thanks for following up on this issue. Normally, if a master device sees that the I2C clock is being held low, it assumes that a slave is "clock stretching" and it will wait until it is raised. I wonder if that's what is causing this issue here. -- RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up According to speedtest.net: 11.9Mbps down 500kbps up ^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PATCH v2 0/7] tda998x: allow use with bridge based devices @ 2018-11-12 17:00 ` Russell King - ARM Linux 0 siblings, 0 replies; 80+ messages in thread From: Russell King - ARM Linux @ 2018-11-12 17:00 UTC (permalink / raw) To: Peter Rosin Cc: David Airlie, Liviu Dudau, Jyri Sarha, Tomi Valkeinen, dri-devel, linux-arm-kernel On Mon, Nov 12, 2018 at 04:50:37PM +0000, Peter Rosin wrote: > On 2018-08-02 08:06, Peter Rosin wrote: > > On 2018-08-01 11:35, Russell King - ARM Linux wrote: > >> On Wed, Aug 01, 2018 at 11:01:12AM +0200, Peter Rosin wrote: > >>> I don't think it's a problem with the atmel I2C driver. IIRC, the > >>> tda998x driver issues the command a initiate the EDID read, but that > >>> times out. So it appears to be the TDA19988 that fails to read the > >>> EDID over the DDC bus? Which brings me to the double problem with the > >>> scopes mentioned above... > >> > >> It sounds like it. > >> > >> It may be helpful to know that there are HDMI pass-through boards > >> available that give access to all the HDMI signals: > >> > >> https://elabbay.myshopify.com/collections/camera > >> https://elabbay.myshopify.com/collections/camera/products/hdmi-af-af-v1a-hdmi-type-a-female-to-hdmi-type-a-male-pass-through-adapter-breakout-board > >> > >> I've never bought from them, so please don't take this as a > >> recommendation - the fact that there seems to be no company details > >> on their site doesn't seem good, and as the whois for elabbay.com is > >> obscured also doesn't give me any confidence to buy from them. > > > > I still will not be able to inspect the DDC bus between the TDA19988 > > and the buffer circuit (IP4786), but the gadget seems useful enough and > > it's not a shitload of money. We'll see how long it takes for it to get > > here... > > > > Thanks for the pointer! Maybe :-) > > I got the pass-through board a while back, and that board works as expected > and there was no problem with ordering etc. What I could see with that was > that the TDA19988 was able to initiate a start condition (SDA -> low) but > then nothing more happened. > > Then last week, someone noticed that even though the TDA19988 is driven by > 1.8V, it still needs the high signals of the DDC bus to be above 3V, which > was unexpected and not catered for by the design. Changing VCC(SYS) of the > buffer circuit in place (IP4786, pin 27) to 3.3V fixed the issue and EDID > reading works, and this was confirmed earlier today. > > So, the problem was that the TDA19988 only ever saw "low" DDC signals, and > probably aborted when the bus appeared busy. Or something. Thanks for following up on this issue. Normally, if a master device sees that the I2C clock is being held low, it assumes that a slave is "clock stretching" and it will wait until it is raised. I wonder if that's what is causing this issue here. -- RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up According to speedtest.net: 11.9Mbps down 500kbps up _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply [flat|nested] 80+ messages in thread
end of thread, other threads:[~2018-11-12 17:00 UTC | newest] Thread overview: 80+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2018-07-30 16:41 [PATCH v2 0/7] tda998x: allow use with bridge based devices Russell King - ARM Linux 2018-07-30 16:41 ` Russell King - ARM Linux 2018-07-30 16:42 ` [PATCH v2 1/7] drm/i2c: tda998x: find the drm_device via the drm_connector Russell King 2018-07-30 16:42 ` Russell King 2018-07-30 16:42 ` [PATCH v2 2/7] drm/i2c: tda998x: split tda998x_encoder_dpms into enable/disable Russell King 2018-07-30 16:42 ` Russell King 2018-07-31 5:46 ` Peter Rosin 2018-07-31 5:46 ` Peter Rosin 2018-07-30 16:42 ` [PATCH v2 3/7] drm/i2c: tda998x: move tda998x_set_config() into tda998x_create() Russell King 2018-07-30 16:42 ` Russell King 2018-07-30 16:42 ` [PATCH v2 4/7] drm/i2c: tda998x: convert to bridge driver Russell King 2018-07-30 16:42 ` Russell King 2018-07-31 7:37 ` Peter Rosin 2018-07-31 7:37 ` Peter Rosin 2018-08-08 19:09 ` Sean Paul 2018-08-08 19:09 ` Sean Paul 2018-08-08 22:15 ` Russell King - ARM Linux 2018-08-08 22:15 ` Russell King - ARM Linux 2018-08-10 16:11 ` Sean Paul 2018-08-10 16:11 ` Sean Paul 2018-08-10 16:50 ` Russell King - ARM Linux 2018-08-10 16:50 ` Russell King - ARM Linux 2018-08-10 17:02 ` Sean Paul 2018-08-10 17:02 ` Sean Paul 2018-08-10 17:16 ` Russell King - ARM Linux 2018-08-10 17:16 ` Russell King - ARM Linux 2018-08-14 10:42 ` Daniel Vetter 2018-08-14 10:42 ` Daniel Vetter 2018-08-14 10:48 ` Russell King - ARM Linux 2018-08-14 10:48 ` Russell King - ARM Linux 2018-08-14 11:11 ` Daniel Vetter 2018-08-14 11:11 ` Daniel Vetter 2018-08-27 16:15 ` Andrzej Hajda 2018-08-27 16:15 ` Andrzej Hajda 2018-08-27 17:59 ` Russell King - ARM Linux 2018-08-27 17:59 ` Russell King - ARM Linux 2018-08-28 7:31 ` Andrzej Hajda 2018-08-28 7:31 ` Andrzej Hajda 2018-07-30 16:42 ` [PATCH v2 5/7] drm/i2c: tda998x: allocate tda998x_priv inside tda998x_create() Russell King 2018-07-30 16:42 ` Russell King 2018-07-30 16:42 ` [PATCH v2 6/7] drm/i2c: tda998x: cleanup from previous changes Russell King 2018-07-30 16:42 ` Russell King 2018-07-30 16:42 ` [PATCH v2 7/7] drm/i2c: tda998x: register bridge outside of component helper Russell King 2018-07-30 16:42 ` Russell King 2018-08-27 16:19 ` Andrzej Hajda 2018-08-27 16:19 ` Andrzej Hajda 2018-07-31 5:44 ` [PATCH v2 0/7] tda998x: allow use with bridge based devices Peter Rosin 2018-07-31 5:44 ` Peter Rosin 2018-07-31 7:41 ` Russell King - ARM Linux 2018-07-31 7:41 ` Russell King - ARM Linux 2018-07-31 7:53 ` Peter Rosin 2018-07-31 7:53 ` Peter Rosin 2018-07-31 9:23 ` Russell King - ARM Linux 2018-07-31 9:23 ` Russell King - ARM Linux 2018-07-31 9:26 ` [PATCH 1/4] drm/i2c: tda998x: move mode_valid() to bridge Russell King 2018-07-31 9:26 ` Russell King 2018-08-27 16:24 ` Andrzej Hajda 2018-08-27 16:24 ` Andrzej Hajda 2018-07-31 9:26 ` [PATCH 2/4] drm/i2c: tda998x: get rid of private fill_modes function Russell King 2018-07-31 9:26 ` Russell King 2018-07-31 9:26 ` [PATCH 3/4] drm/i2c: tda998x: correct PLL divider calculation Russell King 2018-07-31 9:26 ` Russell King 2018-07-31 9:26 ` [PATCH 4/4] drm/i2c: tda998x: add support for pixel repeated modes Russell King 2018-07-31 9:26 ` Russell King 2018-07-31 9:42 ` Russell King - ARM Linux 2018-07-31 9:42 ` Russell King - ARM Linux 2018-07-31 10:43 ` [PATCH v2 0/7] tda998x: allow use with bridge based devices Peter Rosin 2018-07-31 10:43 ` Peter Rosin 2018-07-31 11:15 ` Russell King - ARM Linux 2018-07-31 11:15 ` Russell King - ARM Linux 2018-08-01 9:01 ` Peter Rosin 2018-08-01 9:01 ` Peter Rosin 2018-08-01 9:35 ` Russell King - ARM Linux 2018-08-01 9:35 ` Russell King - ARM Linux 2018-08-02 6:06 ` Peter Rosin 2018-08-02 6:06 ` Peter Rosin 2018-11-12 16:50 ` Peter Rosin 2018-11-12 16:50 ` Peter Rosin 2018-11-12 17:00 ` Russell King - ARM Linux 2018-11-12 17:00 ` Russell King - ARM Linux
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.