[PATCH 06/18] drm/vc4: Rework the encoder retrieval code
Thomas Zimmermann
tzimmermann at suse.de
Fri Apr 9 08:54:39 UTC 2021
Hi
Am 17.03.21 um 16:43 schrieb Maxime Ripard:
> Due to a FIFO that cannot be flushed between the pixelvalve and the HDMI
> controllers on BCM2711, we need to carefully disable both at boot time
> if they were left enabled by the firmware.
>
> However, at the time we're running that code, the struct drm_connector
> encoder pointer isn't set yet, and thus we cannot retrieve the encoder
> associated to our CRTC.
>
> We can however make use of the fact that we have a less flexible setup
> than what DRM allows where we have a 1:1 relationship between our CRTCs
> and encoders (and connectors), and thus store the crtc associated to our
> encoder at boot time.
>
> We cannot do that at the time the encoders are probed though, since the
> CRTCs won't be probed yet and thus we don't know at that time which CRTC
> index we're going to get, so let's do this in two passes: we can first
> bind all the components and then once they all are bound, we can iterate
> over all the encoders to find their associated CRTC and set the pointer.
>
> This is similar to what we're doing to set the possible_crtcs field.
>
> Fixes: 875a4d536842 ("drm/vc4: drv: Disable the CRTC at boot time")
Cc: <stable at vger.kernel.org> # v5.10+
> Signed-off-by: Maxime Ripard <maxime at cerno.tech>
> ---
> drivers/gpu/drm/vc4/vc4_crtc.c | 25 +++++++++++++++++++++--
> drivers/gpu/drm/vc4/vc4_drv.c | 36 ++++++++++++++++++++++++++++++++++
> drivers/gpu/drm/vc4/vc4_drv.h | 1 +
> 3 files changed, 60 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
> index f1f2e8cbce79..e2607e1f2520 100644
> --- a/drivers/gpu/drm/vc4/vc4_crtc.c
> +++ b/drivers/gpu/drm/vc4/vc4_crtc.c
> @@ -255,6 +255,19 @@ static u32 vc4_crtc_get_fifo_full_level_bits(struct vc4_crtc *vc4_crtc,
> PV_CONTROL_FIFO_LEVEL);
> }
>
> +struct drm_encoder *vc4_get_connector_encoder(struct drm_connector *connector)
> +{
> + struct drm_encoder *encoder;
> +
> + if (WARN_ON(hweight32(connector->possible_encoders) != 1))
drm_WARN_ON
> + return NULL;
> +
> + drm_connector_for_each_possible_encoder(connector, encoder)
> + return encoder;
> +
> + return NULL;
> +}
> +
> /*
> * Returns the encoder attached to the CRTC.
> *
> @@ -269,9 +282,17 @@ static struct drm_encoder *vc4_get_crtc_encoder(struct drm_crtc *crtc)
>
> drm_connector_list_iter_begin(crtc->dev, &conn_iter);
> drm_for_each_connector_iter(connector, &conn_iter) {
> - if (connector->state->crtc == crtc) {
> + struct drm_encoder *encoder;
> + struct vc4_encoder *vc4_encoder;
> +
> + encoder = vc4_get_connector_encoder(connector);
> + if (!encoder)
> + continue;
> +
> + vc4_encoder = to_vc4_encoder(encoder);
> + if (vc4_encoder->crtc == crtc) {
> drm_connector_list_iter_end(&conn_iter);
> - return connector->encoder;
> + return encoder;
> }
> }
> drm_connector_list_iter_end(&conn_iter);
> diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
> index 556ad0f02a0d..cd1fb75c66a7 100644
> --- a/drivers/gpu/drm/vc4/vc4_drv.c
> +++ b/drivers/gpu/drm/vc4/vc4_drv.c
> @@ -199,6 +199,41 @@ static int compare_dev(struct device *dev, void *data)
> return dev == data;
> }
>
> +static struct drm_crtc *vc4_drv_find_crtc(struct drm_device *drm,
> + struct drm_encoder *encoder)
> +{
> + struct drm_crtc *crtc;
> +
> + if (WARN_ON(hweight32(encoder->possible_crtcs) != 1))
> + return NULL;
> +
> + drm_for_each_crtc(crtc, drm) {
> + if (!drm_encoder_crtc_ok(encoder, crtc))
> + continue;
> +
> + return crtc;
> + }
> +
> + return NULL;
> +}
> +
> +static void vc4_drv_set_encoder_data(struct drm_device *drm)
> +{
> + struct drm_encoder *encoder;
> +
> + drm_for_each_encoder(encoder, drm) {
> + struct vc4_encoder *vc4_encoder;
> + struct drm_crtc *crtc;
> +
> + crtc = vc4_drv_find_crtc(drm, encoder);
> + if (WARN_ON(!crtc))
> + return;
> +
> + vc4_encoder = to_vc4_encoder(encoder);
> + vc4_encoder->crtc = crtc;
> + }
> +}
> +
> static void vc4_match_add_drivers(struct device *dev,
> struct component_match **match,
> struct platform_driver *const *drivers,
> @@ -261,6 +296,7 @@ static int vc4_drm_bind(struct device *dev)
> ret = component_bind_all(dev, drm);
> if (ret)
> return ret;
> + vc4_drv_set_encoder_data(drm);
>
> ret = vc4_plane_create_additional_planes(drm);
> if (ret)
> diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
> index a7500716cf3f..1b569dcc2154 100644
> --- a/drivers/gpu/drm/vc4/vc4_drv.h
> +++ b/drivers/gpu/drm/vc4/vc4_drv.h
> @@ -438,6 +438,7 @@ enum vc4_encoder_type {
>
> struct vc4_encoder {
> struct drm_encoder base;
> + struct drm_crtc *crtc;
I'd probably deserves a comment why this is explicitly stored here.
> enum vc4_encoder_type type;
> u32 clock_select;
>
>
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Felix Imendörffer
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature
Type: application/pgp-signature
Size: 840 bytes
Desc: OpenPGP digital signature
URL: <https://lists.freedesktop.org/archives/dri-devel/attachments/20210409/f4a0a72f/attachment.sig>
More information about the dri-devel
mailing list