All of lore.kernel.org
 help / color / mirror / Atom feed
From: Maxime Ripard <maxime@cerno.tech>
To: dri-devel@lists.freedesktop.org,
	Maarten Lankhorst <maarten.lankhorst@linux.intel.com>,
	Thomas Zimmermann <tzimmermann@suse.de>,
	Maxime Ripard <maxime@cerno.tech>
Cc: Tim Gover <tim.gover@raspberrypi.com>,
	Dave Stevenson <dave.stevenson@raspberrypi.com>,
	David Airlie <airlied@linux.ie>,
	bcm-kernel-feedback-list@broadcom.com,
	linux-rpi-kernel@lists.infradead.org,
	Daniel Vetter <daniel.vetter@intel.com>,
	Phil Elwell <phil@raspberrypi.com>,
	Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
Subject: [PATCH v3 3/9] drm/vc4: Rework the encoder retrieval code
Date: Tue, 13 Apr 2021 16:54:35 +0200	[thread overview]
Message-ID: <20210413145441.483977-4-maxime@cerno.tech> (raw)
In-Reply-To: <20210413145441.483977-1-maxime@cerno.tech>

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")
Signed-off-by: Maxime Ripard <maxime@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  | 10 ++++++++++
 3 files changed, 69 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index f1f2e8cbce79..2bcd7c4e0fc7 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);
 }
 
+static struct drm_encoder *vc4_get_connector_encoder(struct drm_connector *connector)
+{
+	struct drm_encoder *encoder;
+
+	if (drm_WARN_ON(connector->dev, hweight32(connector->possible_encoders) != 1))
+		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..a22e49665d9c 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -438,6 +438,16 @@ enum vc4_encoder_type {
 
 struct vc4_encoder {
 	struct drm_encoder base;
+
+	/*
+	 * At boot time, we need to be able to retrieve the CRTC for a given
+	 * connector in order to run the disable hooks below to avoid the stuck
+	 * pixel issue. Unfortunately the drm_connector->encoder pointer is
+	 * NULL at that time so we can't move up the chain, so we'll store it
+	 * ourselves here.
+	 */
+	struct drm_crtc *crtc;
+
 	enum vc4_encoder_type type;
 	u32 clock_select;
 
-- 
2.30.2

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

  parent reply	other threads:[~2021-04-13 14:54 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-13 14:54 [PATCH v3 0/9] drm/vc4: hdmi: Support the 4k @ 60Hz modes Maxime Ripard
2021-04-13 14:54 ` [PATCH v3 1/9] drm/vc4: txp: Properly set the possible_crtcs mask Maxime Ripard
2021-04-13 14:54   ` Maxime Ripard
2021-04-13 14:54 ` [PATCH v3 2/9] drm/vc4: crtc: Skip the TXP Maxime Ripard
2021-04-13 14:54   ` Maxime Ripard
2021-04-13 14:54 ` Maxime Ripard [this message]
2021-04-13 14:54 ` [PATCH v3 4/9] drm/vc4: hdmi: Prevent clock unbalance Maxime Ripard
2021-04-13 14:54   ` Maxime Ripard
2021-04-13 14:54 ` [PATCH v3 5/9] drm/vc4: hvs: Make the HVS bind first Maxime Ripard
2021-04-13 14:54 ` [PATCH v3 6/9] drm/vc4: hdmi: Properly compute the BVB clock rate Maxime Ripard
2021-04-13 14:54 ` [PATCH v3 7/9] drm/vc4: hdmi: Check and warn if we can't reach 4kp60 frequencies Maxime Ripard
2021-04-13 14:54 ` [PATCH v3 8/9] drm/vc4: hdmi: Enable the scrambler Maxime Ripard
2021-04-13 14:54 ` [PATCH v3 9/9] drm/vc4: hdmi: Raise the maximum clock rate Maxime Ripard

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210413145441.483977-4-maxime@cerno.tech \
    --to=maxime@cerno.tech \
    --cc=airlied@linux.ie \
    --cc=bcm-kernel-feedback-list@broadcom.com \
    --cc=daniel.vetter@intel.com \
    --cc=dave.stevenson@raspberrypi.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=linux-rpi-kernel@lists.infradead.org \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=nsaenzjulienne@suse.de \
    --cc=phil@raspberrypi.com \
    --cc=tim.gover@raspberrypi.com \
    --cc=tzimmermann@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.