All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eric Anholt <eric@anholt.net>
To: Florian Fainelli <f.fainelli@gmail.com>,
	Michael Turquette <mturquette@baylibre.com>,
	Stephen Boyd <sboyd@codeaurora.org>,
	Rob Herring <robh+dt@kernel.org>,
	Mark Rutland <mark.rutland@arm.com>,
	dri-devel@lists.freedesktop.org,
	Thierry Reding <thierry.reding@gmail.com>
Cc: linux-rpi-kernel@lists.infradead.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org,
	Stephen Warren <swarren@wwwdotorg.org>,
	Lee Jones <lee@kernel.org>,
	bcm-kernel-feedback-list@broadcom.com, linux-clk@vger.kernel.org,
	Eric Anholt <eric@anholt.net>
Subject: [PATCH 05/11] drm/vc4: Add support for feeding DSI encoders from the pixel valve.
Date: Wed, 14 Dec 2016 11:46:15 -0800	[thread overview]
Message-ID: <20161214194621.16499-6-eric@anholt.net> (raw)
In-Reply-To: <20161214194621.16499-1-eric@anholt.net>

We have to set a different pixel format, which tells the hardware to
use the pix_width field that's fed in sideband from the DSI encoder to
divide the "pixel" clock.

Signed-off-by: Eric Anholt <eric@anholt.net>
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 33 +++++++++++++++++++--------------
 drivers/gpu/drm/vc4/vc4_regs.h |  2 ++
 2 files changed, 21 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index a0fd3e66bc4b..cd070e0c79a6 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -349,38 +349,40 @@ static u32 vc4_get_fifo_full_level(u32 format)
 }
 
 /*
- * Returns the clock select bit for the connector attached to the
- * CRTC.
+ * Returns the encoder attached to the CRTC.
+ *
+ * VC4 can only scan out to one encoder at a time, while the DRM core
+ * allows drivers to push pixels to more than one encoder from the
+ * same CRTC.
  */
-static int vc4_get_clock_select(struct drm_crtc *crtc)
+static struct drm_encoder *vc4_get_crtc_encoder(struct drm_crtc *crtc)
 {
 	struct drm_connector *connector;
 
 	drm_for_each_connector(connector, crtc->dev) {
 		if (connector->state->crtc == crtc) {
-			struct drm_encoder *encoder = connector->encoder;
-			struct vc4_encoder *vc4_encoder =
-				to_vc4_encoder(encoder);
-
-			return vc4_encoder->clock_select;
+			return connector->encoder;
 		}
 	}
 
-	return -1;
+	return NULL;
 }
 
 static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
 {
 	struct drm_device *dev = crtc->dev;
 	struct vc4_dev *vc4 = to_vc4_dev(dev);
+	struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc);
+	struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
 	struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
 	struct drm_crtc_state *state = crtc->state;
 	struct drm_display_mode *mode = &state->adjusted_mode;
 	bool interlace = mode->flags & DRM_MODE_FLAG_INTERLACE;
 	u32 pixel_rep = (mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1;
-	u32 format = PV_CONTROL_FORMAT_24;
+	bool is_dsi = (vc4_encoder->type == VC4_ENCODER_TYPE_DSI0 ||
+		       vc4_encoder->type == VC4_ENCODER_TYPE_DSI1);
+	u32 format = is_dsi ? PV_CONTROL_FORMAT_DSIV_24 : PV_CONTROL_FORMAT_24;
 	bool debug_dump_regs = false;
-	int clock_select = vc4_get_clock_select(crtc);
 
 	if (debug_dump_regs) {
 		DRM_INFO("CRTC %d regs before:\n", drm_crtc_index(crtc));
@@ -436,17 +438,19 @@ static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
 		 */
 		CRTC_WRITE(PV_V_CONTROL,
 			   PV_VCONTROL_CONTINUOUS |
+			   (is_dsi ? PV_VCONTROL_DSI : 0) |
 			   PV_VCONTROL_INTERLACE |
 			   VC4_SET_FIELD(mode->htotal * pixel_rep / 2,
 					 PV_VCONTROL_ODD_DELAY));
 		CRTC_WRITE(PV_VSYNCD_EVEN, 0);
 	} else {
-		CRTC_WRITE(PV_V_CONTROL, PV_VCONTROL_CONTINUOUS);
+		CRTC_WRITE(PV_V_CONTROL,
+			   PV_VCONTROL_CONTINUOUS |
+			   (is_dsi ? PV_VCONTROL_DSI : 0));
 	}
 
 	CRTC_WRITE(PV_HACT_ACT, mode->hdisplay * pixel_rep);
 
-
 	CRTC_WRITE(PV_CONTROL,
 		   VC4_SET_FIELD(format, PV_CONTROL_FORMAT) |
 		   VC4_SET_FIELD(vc4_get_fifo_full_level(format),
@@ -455,7 +459,8 @@ static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
 		   PV_CONTROL_CLR_AT_START |
 		   PV_CONTROL_TRIGGER_UNDERFLOW |
 		   PV_CONTROL_WAIT_HSTART |
-		   VC4_SET_FIELD(clock_select, PV_CONTROL_CLK_SELECT) |
+		   VC4_SET_FIELD(vc4_encoder->clock_select,
+				 PV_CONTROL_CLK_SELECT) |
 		   PV_CONTROL_FIFO_CLR |
 		   PV_CONTROL_EN);
 
diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h
index b3b297fba709..385405a2df05 100644
--- a/drivers/gpu/drm/vc4/vc4_regs.h
+++ b/drivers/gpu/drm/vc4/vc4_regs.h
@@ -190,6 +190,8 @@
 # define PV_VCONTROL_ODD_DELAY_SHIFT		6
 # define PV_VCONTROL_ODD_FIRST			BIT(5)
 # define PV_VCONTROL_INTERLACE			BIT(4)
+# define PV_VCONTROL_DSI			BIT(3)
+# define PV_VCONTROL_COMMAND			BIT(2)
 # define PV_VCONTROL_CONTINUOUS			BIT(1)
 # define PV_VCONTROL_VIDEN			BIT(0)
 
-- 
2.11.0

WARNING: multiple messages have this Message-ID (diff)
From: eric@anholt.net (Eric Anholt)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 05/11] drm/vc4: Add support for feeding DSI encoders from the pixel valve.
Date: Wed, 14 Dec 2016 11:46:15 -0800	[thread overview]
Message-ID: <20161214194621.16499-6-eric@anholt.net> (raw)
In-Reply-To: <20161214194621.16499-1-eric@anholt.net>

We have to set a different pixel format, which tells the hardware to
use the pix_width field that's fed in sideband from the DSI encoder to
divide the "pixel" clock.

Signed-off-by: Eric Anholt <eric@anholt.net>
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 33 +++++++++++++++++++--------------
 drivers/gpu/drm/vc4/vc4_regs.h |  2 ++
 2 files changed, 21 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index a0fd3e66bc4b..cd070e0c79a6 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -349,38 +349,40 @@ static u32 vc4_get_fifo_full_level(u32 format)
 }
 
 /*
- * Returns the clock select bit for the connector attached to the
- * CRTC.
+ * Returns the encoder attached to the CRTC.
+ *
+ * VC4 can only scan out to one encoder at a time, while the DRM core
+ * allows drivers to push pixels to more than one encoder from the
+ * same CRTC.
  */
-static int vc4_get_clock_select(struct drm_crtc *crtc)
+static struct drm_encoder *vc4_get_crtc_encoder(struct drm_crtc *crtc)
 {
 	struct drm_connector *connector;
 
 	drm_for_each_connector(connector, crtc->dev) {
 		if (connector->state->crtc == crtc) {
-			struct drm_encoder *encoder = connector->encoder;
-			struct vc4_encoder *vc4_encoder =
-				to_vc4_encoder(encoder);
-
-			return vc4_encoder->clock_select;
+			return connector->encoder;
 		}
 	}
 
-	return -1;
+	return NULL;
 }
 
 static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
 {
 	struct drm_device *dev = crtc->dev;
 	struct vc4_dev *vc4 = to_vc4_dev(dev);
+	struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc);
+	struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
 	struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
 	struct drm_crtc_state *state = crtc->state;
 	struct drm_display_mode *mode = &state->adjusted_mode;
 	bool interlace = mode->flags & DRM_MODE_FLAG_INTERLACE;
 	u32 pixel_rep = (mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1;
-	u32 format = PV_CONTROL_FORMAT_24;
+	bool is_dsi = (vc4_encoder->type == VC4_ENCODER_TYPE_DSI0 ||
+		       vc4_encoder->type == VC4_ENCODER_TYPE_DSI1);
+	u32 format = is_dsi ? PV_CONTROL_FORMAT_DSIV_24 : PV_CONTROL_FORMAT_24;
 	bool debug_dump_regs = false;
-	int clock_select = vc4_get_clock_select(crtc);
 
 	if (debug_dump_regs) {
 		DRM_INFO("CRTC %d regs before:\n", drm_crtc_index(crtc));
@@ -436,17 +438,19 @@ static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
 		 */
 		CRTC_WRITE(PV_V_CONTROL,
 			   PV_VCONTROL_CONTINUOUS |
+			   (is_dsi ? PV_VCONTROL_DSI : 0) |
 			   PV_VCONTROL_INTERLACE |
 			   VC4_SET_FIELD(mode->htotal * pixel_rep / 2,
 					 PV_VCONTROL_ODD_DELAY));
 		CRTC_WRITE(PV_VSYNCD_EVEN, 0);
 	} else {
-		CRTC_WRITE(PV_V_CONTROL, PV_VCONTROL_CONTINUOUS);
+		CRTC_WRITE(PV_V_CONTROL,
+			   PV_VCONTROL_CONTINUOUS |
+			   (is_dsi ? PV_VCONTROL_DSI : 0));
 	}
 
 	CRTC_WRITE(PV_HACT_ACT, mode->hdisplay * pixel_rep);
 
-
 	CRTC_WRITE(PV_CONTROL,
 		   VC4_SET_FIELD(format, PV_CONTROL_FORMAT) |
 		   VC4_SET_FIELD(vc4_get_fifo_full_level(format),
@@ -455,7 +459,8 @@ static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
 		   PV_CONTROL_CLR_AT_START |
 		   PV_CONTROL_TRIGGER_UNDERFLOW |
 		   PV_CONTROL_WAIT_HSTART |
-		   VC4_SET_FIELD(clock_select, PV_CONTROL_CLK_SELECT) |
+		   VC4_SET_FIELD(vc4_encoder->clock_select,
+				 PV_CONTROL_CLK_SELECT) |
 		   PV_CONTROL_FIFO_CLR |
 		   PV_CONTROL_EN);
 
diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h
index b3b297fba709..385405a2df05 100644
--- a/drivers/gpu/drm/vc4/vc4_regs.h
+++ b/drivers/gpu/drm/vc4/vc4_regs.h
@@ -190,6 +190,8 @@
 # define PV_VCONTROL_ODD_DELAY_SHIFT		6
 # define PV_VCONTROL_ODD_FIRST			BIT(5)
 # define PV_VCONTROL_INTERLACE			BIT(4)
+# define PV_VCONTROL_DSI			BIT(3)
+# define PV_VCONTROL_COMMAND			BIT(2)
 # define PV_VCONTROL_CONTINUOUS			BIT(1)
 # define PV_VCONTROL_VIDEN			BIT(0)
 
-- 
2.11.0

  parent reply	other threads:[~2016-12-14 19:47 UTC|newest]

Thread overview: 64+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-12-14 19:46 [PATCH 00/11] drm/vc4: DSI panel support + Raspberry Pi touchscreen Eric Anholt
2016-12-14 19:46 ` Eric Anholt
2016-12-14 19:46 ` [PATCH 01/11] clk: bcm2835: Don't rate change PLLs on behalf of DSI PLL dividers Eric Anholt
2016-12-14 19:46   ` Eric Anholt
2016-12-14 19:46   ` Eric Anholt
2016-12-14 19:46 ` [PATCH 02/11] clk: bcm2835: Register the DSI0/DSI1 pixel clocks Eric Anholt
2016-12-14 19:46   ` Eric Anholt
2016-12-14 19:46   ` Eric Anholt
2016-12-21 23:14   ` Stephen Boyd
2016-12-21 23:14     ` Stephen Boyd
2016-12-21 23:14     ` Stephen Boyd
2016-12-22  1:23     ` Eric Anholt
2016-12-22  1:23       ` Eric Anholt
2016-12-22  1:23       ` Eric Anholt
2016-12-14 19:46 ` [PATCH 03/11] clk: bcm2835: Add leaf clock measurement support, disabled by default Eric Anholt
2016-12-14 19:46   ` Eric Anholt
2016-12-14 19:46   ` Eric Anholt
2016-12-14 19:46 ` [PATCH 04/11] drm/vc4: Set up SCALER_DISPCTRL at boot Eric Anholt
2016-12-14 19:46   ` Eric Anholt
2017-01-31 19:35   ` Daniel Vetter
2017-01-31 19:35     ` Daniel Vetter
2017-01-31 19:35     ` Daniel Vetter
2016-12-14 19:46 ` Eric Anholt [this message]
2016-12-14 19:46   ` [PATCH 05/11] drm/vc4: Add support for feeding DSI encoders from the pixel valve Eric Anholt
2017-01-31 19:39   ` Daniel Vetter
2017-01-31 19:39     ` Daniel Vetter
2017-01-31 19:39     ` Daniel Vetter
2017-01-31 19:54     ` Eric Anholt
2017-01-31 19:54       ` Eric Anholt
2017-01-31 19:54       ` Eric Anholt
2016-12-14 19:46 ` [PATCH 06/11] dt-bindings: Document the VC4 DSI module nodes Eric Anholt
2016-12-14 19:46   ` Eric Anholt
2016-12-14 19:46   ` Eric Anholt
2016-12-14 19:46 ` [PATCH 07/11] drm/vc4: Add DSI driver Eric Anholt
2016-12-14 19:46   ` Eric Anholt
2016-12-14 19:46   ` Eric Anholt
2017-01-31 19:51   ` Daniel Vetter
2017-01-31 19:51     ` Daniel Vetter
2017-01-31 19:51     ` Daniel Vetter
2016-12-14 19:46 ` [PATCH 08/11] dt-bindings: Document the Raspberry Pi Touchscreen nodes Eric Anholt
2016-12-14 19:46   ` Eric Anholt
2016-12-14 19:46   ` Eric Anholt
2016-12-14 19:46 ` [PATCH 09/11] drm/panel: Add support for the Raspberry Pi 7" Touchscreen Eric Anholt
2016-12-14 19:46   ` Eric Anholt
2016-12-14 19:46   ` Eric Anholt
2017-01-31 21:07   ` Thierry Reding
2017-01-31 21:07     ` Thierry Reding
2017-01-31 21:07     ` Thierry Reding
2017-01-31 21:17     ` Daniel Vetter
2017-01-31 21:17       ` Daniel Vetter
2017-01-31 21:17       ` Daniel Vetter
2017-01-31 21:42       ` Thierry Reding
2017-01-31 21:42         ` Thierry Reding
2017-01-31 21:42         ` Thierry Reding
2017-01-31 21:19     ` Daniel Vetter
2017-01-31 21:19       ` Daniel Vetter
2017-01-31 21:19       ` Daniel Vetter
2017-01-31 21:38       ` Thierry Reding
2017-01-31 21:38         ` Thierry Reding
2016-12-14 19:46 ` [PATCH 10/11] ARM: bcm2835: dt: Add the DSI module nodes and clocks Eric Anholt
2016-12-14 19:46   ` Eric Anholt
2016-12-14 19:46 ` [PATCH 11/11] ARM: bcm2835: Enable the Raspberry Pi touchscreen panel Eric Anholt
2016-12-14 19:46   ` Eric Anholt
2016-12-14 19:46   ` Eric Anholt

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=20161214194621.16499-6-eric@anholt.net \
    --to=eric@anholt.net \
    --cc=bcm-kernel-feedback-list@broadcom.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=f.fainelli@gmail.com \
    --cc=lee@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-clk@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rpi-kernel@lists.infradead.org \
    --cc=mark.rutland@arm.com \
    --cc=mturquette@baylibre.com \
    --cc=robh+dt@kernel.org \
    --cc=sboyd@codeaurora.org \
    --cc=swarren@wwwdotorg.org \
    --cc=thierry.reding@gmail.com \
    /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.