Re: drm: Bogus WARN() in drm_atomic_helper_update_legacy_modeset_state() ?

From: Liviu Dudau
Date: Thu Nov 12 2015 - 08:57:19 EST


On Thu, Nov 12, 2015 at 01:16:55PM +0100, Thierry Reding wrote:
> On Wed, Nov 11, 2015 at 04:09:42PM +0000, Liviu Dudau wrote:
> > On Tue, Nov 10, 2015 at 05:56:15PM +0100, Thierry Reding wrote:
> > > On Tue, Nov 10, 2015 at 03:01:03PM +0000, Liviu Dudau wrote:
> > > > Hello,
> > > >
> > > > When booting my Juno board with the HDLCD driver that I have converted to
> > > > atomic operations I'm getting the following warning:
> > >
> > > Perhaps you can provide pointers to the source code, that might make it
> > > easier for people to spot what's going wrong.
> > >
> > > Thierry
> >
> > Hi Thierry,
> >
> > I have just pushed to the mailing lists my patch series. [1] [2]
> >
> > If you want to checkout the code I also have a branch here:
> >
> > git://git://linux-arm.org/linux-ld testing/hdlcd
>
> Okay, so if I understand correctly you're using the tda998x as encoder/
> connector attached to your new HDLCD driver. I think the problem isn't
> so much that nothing has set up the CRTC for the encoder, but rather
> that the tda998x encoder tries to statically associate the encoder with
> the connector. While that might be correct in that it represents the
> hardware state (i.e. there is no way to physically route it anywhere
> else), the DRM logical state is that it's not connected until a complete
> pipeline has been set up, in which case a CRTC would have been assigned
> to the encoder.
>
> If your setup were working correctly you'd never reach the WARN_ON
> because the
>
> if (connector->encoder) {
>
> conditional (on line 673 in drivers/gpu/drm/drm_atomic_helper.c) would
> have evaluated to false already, since logically there'd be no encoder
> associated with the connector yet.

Your analysis is spot on and matches my conditions. However ...

>
> Does the patch below help? Let me know and I can produce a proper patch.
>
> Thierry
>
> --- >8 ---
> diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
> index 896b6aaf8c4d..8b0a402190eb 100644
> --- a/drivers/gpu/drm/i2c/tda998x_drv.c
> +++ b/drivers/gpu/drm/i2c/tda998x_drv.c
> @@ -1453,7 +1453,6 @@ static int tda998x_bind(struct device *dev, struct device *master, void *data)
> if (ret)
> goto err_sysfs;
>
> - priv->connector.encoder = &priv->encoder;

while this patch helps (no WARN() printed) I'm not sure this is the right fix.
TDA998x is also used by armada DRM driver which has not been converted (yet) to
atomic modesetting. And judging by the code and comment of drm_connector_get_encoder()
in drm_crtc.c, having access to the encoder through the connector is the non-atomic
way of doing things:

static struct drm_encoder *drm_connector_get_encoder(struct drm_connector *connector)
{
/* For atomic drivers only state objects are synchronously updated and
* protected by modeset locks, so check those first. */
if (connector->state)
return connector->state->best_encoder;
return connector->encoder;
}

To me, it looks like the WARN() is bogus when the atomic modesetting is used in
drm_atomic_helper_update_legacy_modeset_state(). Either we acknowledge that the "legacy"
code sets the connector in the encoder structure before complete pipeline is setup
and we remove the WARN(), or we find a better way of detecting that some sort of mixed
support is in place (i.e. atomic and non-atomic aware code running) and we clean up
in a way that is compatible with both worlds.

Best regards,
Liviu

> drm_mode_connector_attach_encoder(&priv->connector, &priv->encoder);
>
> return 0;



--
====================
| I would like to |
| fix the world, |
| but they're not |
| giving me the |
\ source code! /
---------------
Â\_(ã)_/Â
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/