All of lore.kernel.org
 help / color / mirror / Atom feed
From: Biju Das <biju.das.jz@bp.renesas.com>
To: cip-dev@lists.cip-project.org,
	Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>,
	Pavel Machek <pavel@denx.de>
Cc: Chris Paterson <chris.paterson2@renesas.com>,
	Biju Das <biju.das.jz@bp.renesas.com>,
	Prabhakar Mahadev Lad <prabhakar.mahadev-lad.rj@bp.renesas.com>
Subject: [cip-dev] [PATCH 4.19.y-cip 13/17] drm: rcar-du: lvds: Allow for even and odd pixels swap
Date: Wed, 22 Jul 2020 17:34:45 +0100	[thread overview]
Message-ID: <20200722163449.3513-14-biju.das.jz@bp.renesas.com> (raw)
In-Reply-To: <20200722163449.3513-1-biju.das.jz@bp.renesas.com>

[-- Attachment #1: Type: text/plain, Size: 6568 bytes --]

From: Fabrizio Castro <fabrizio.castro@bp.renesas.com>

commit 59c1f061c97e70d81b046e90b259589b645bb87f upstream.

DT properties dual-lvds-even-pixels and dual-lvds-odd-pixels
can be used to work out if the driver needs to swap even
and odd pixels around.

This patch makes use of the return value from function
drm_of_lvds_get_dual_link_pixel_order to determine if we
need to swap odd and even pixels around for things to work
properly.

The dual_link boolean field from struct rcar_lvds is not
sufficient to describe the type of LVDS link anymore, since
we now have information related to pixel order, therefore
rename it to link_type and repurpose its usage to fit the
new requirements.

Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
 drivers/gpu/drm/rcar-du/rcar_lvds.c | 77 ++++++++++++++++++++++-------
 1 file changed, 58 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c b/drivers/gpu/drm/rcar-du/rcar_lvds.c
index 12d2bbbb02f0..e4d0bd043613 100644
--- a/drivers/gpu/drm/rcar-du/rcar_lvds.c
+++ b/drivers/gpu/drm/rcar-du/rcar_lvds.c
@@ -35,6 +35,12 @@ enum rcar_lvds_mode {
 	RCAR_LVDS_MODE_VESA = 4,
 };
 
+enum rcar_lvds_link_type {
+	RCAR_LVDS_SINGLE_LINK = 0,
+	RCAR_LVDS_DUAL_LINK_EVEN_ODD_PIXELS = 1,
+	RCAR_LVDS_DUAL_LINK_ODD_EVEN_PIXELS = 2,
+};
+
 #define RCAR_LVDS_QUIRK_LANES		BIT(0)	/* LVDS lanes 1 and 3 inverted */
 #define RCAR_LVDS_QUIRK_GEN3_LVEN	BIT(1)	/* LVEN bit needs to be set on R8A77970/R8A7799x */
 #define RCAR_LVDS_QUIRK_PWD		BIT(2)	/* PWD bit available (all of Gen3 but E3) */
@@ -65,7 +71,7 @@ struct rcar_lvds {
 	} clocks;
 
 	struct drm_bridge *companion;
-	bool dual_link;
+	enum rcar_lvds_link_type link_type;
 };
 
 #define bridge_to_rcar_lvds(b) \
@@ -452,7 +458,7 @@ static void __rcar_lvds_atomic_enable(struct drm_bridge *bridge,
 		return;
 
 	/* Enable the companion LVDS encoder in dual-link mode. */
-	if (lvds->dual_link && lvds->companion)
+	if (lvds->link_type != RCAR_LVDS_SINGLE_LINK && lvds->companion)
 		__rcar_lvds_atomic_enable(lvds->companion, state, crtc,
 					  connector);
 
@@ -478,19 +484,38 @@ static void __rcar_lvds_atomic_enable(struct drm_bridge *bridge,
 	rcar_lvds_write(lvds, LVDCHCR, lvdhcr);
 
 	if (lvds->info->quirks & RCAR_LVDS_QUIRK_DUAL_LINK) {
-		/*
-		 * Configure vertical stripe based on the mode of operation of
-		 * the connected device.
-		 */
-		rcar_lvds_write(lvds, LVDSTRIPE,
-				lvds->dual_link ? LVDSTRIPE_ST_ON : 0);
+		u32 lvdstripe = 0;
+
+		if (lvds->link_type != RCAR_LVDS_SINGLE_LINK) {
+			/*
+			 * By default we generate even pixels from the primary
+			 * encoder and odd pixels from the companion encoder.
+			 * Swap pixels around if the sink requires odd pixels
+			 * from the primary encoder and even pixels from the
+			 * companion encoder.
+			 */
+			bool swap_pixels = lvds->link_type ==
+				RCAR_LVDS_DUAL_LINK_ODD_EVEN_PIXELS;
+
+			/*
+			 * Configure vertical stripe since we are dealing with
+			 * an LVDS dual-link connection.
+			 *
+			 * ST_SWAP is reserved for the companion encoder, only
+			 * set it in the primary encoder.
+			 */
+			lvdstripe = LVDSTRIPE_ST_ON
+				  | (lvds->companion && swap_pixels ?
+				     LVDSTRIPE_ST_SWAP : 0);
+		}
+		rcar_lvds_write(lvds, LVDSTRIPE, lvdstripe);
 	}
 
 	/*
 	 * PLL clock configuration on all instances but the companion in
 	 * dual-link mode.
 	 */
-	if (!lvds->dual_link || lvds->companion) {
+	if (lvds->link_type == RCAR_LVDS_SINGLE_LINK || lvds->companion) {
 		const struct drm_crtc_state *crtc_state =
 			drm_atomic_get_new_crtc_state(state, crtc);
 		const struct drm_display_mode *mode =
@@ -584,7 +609,7 @@ static void rcar_lvds_atomic_disable(struct drm_bridge *bridge,
 	rcar_lvds_write(lvds, LVDPLLCR, 0);
 
 	/* Disable the companion LVDS encoder in dual-link mode. */
-	if (lvds->dual_link && lvds->companion)
+	if (lvds->link_type != RCAR_LVDS_SINGLE_LINK && lvds->companion)
 		lvds->companion->funcs->atomic_disable(lvds->companion, state);
 
 	clk_disable_unprepare(lvds->clocks.mod);
@@ -658,7 +683,7 @@ bool rcar_lvds_dual_link(struct drm_bridge *bridge)
 {
 	struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
 
-	return lvds->dual_link;
+	return lvds->link_type != RCAR_LVDS_SINGLE_LINK;
 }
 EXPORT_SYMBOL_GPL(rcar_lvds_dual_link);
 
@@ -704,17 +729,28 @@ static int rcar_lvds_parse_dt_companion(struct rcar_lvds *lvds)
 	of_node_put(port0);
 	of_node_put(port1);
 
-	if (dual_link >= DRM_LVDS_DUAL_LINK_EVEN_ODD_PIXELS)
-		lvds->dual_link = true;
-	else if (lvds->next_bridge && lvds->next_bridge->timings)
+	switch (dual_link) {
+	case DRM_LVDS_DUAL_LINK_ODD_EVEN_PIXELS:
+		lvds->link_type = RCAR_LVDS_DUAL_LINK_ODD_EVEN_PIXELS;
+		break;
+	case DRM_LVDS_DUAL_LINK_EVEN_ODD_PIXELS:
+		lvds->link_type = RCAR_LVDS_DUAL_LINK_EVEN_ODD_PIXELS;
+		break;
+	default:
 		/*
 		 * Early dual-link bridge specific implementations populate the
-		 * timings field of drm_bridge, read the dual_link flag off the
-		 * bridge directly for backward compatibility.
+		 * timings field of drm_bridge. If the flag is set, we assume
+		 * that we are expected to generate even pixels from the primary
+		 * encoder, and odd pixels from the companion encoder.
 		 */
-		lvds->dual_link = lvds->next_bridge->timings->dual_link;
+		if (lvds->next_bridge && lvds->next_bridge->timings &&
+		    lvds->next_bridge->timings->dual_link)
+			lvds->link_type = RCAR_LVDS_DUAL_LINK_EVEN_ODD_PIXELS;
+		else
+			lvds->link_type = RCAR_LVDS_SINGLE_LINK;
+	}
 
-	if (!lvds->dual_link) {
+	if (lvds->link_type == RCAR_LVDS_SINGLE_LINK) {
 		dev_dbg(dev, "Single-link configuration detected\n");
 		goto done;
 	}
@@ -729,6 +765,9 @@ static int rcar_lvds_parse_dt_companion(struct rcar_lvds *lvds)
 		"Dual-link configuration detected (companion encoder %pOF)\n",
 		companion);
 
+	if (lvds->link_type == RCAR_LVDS_DUAL_LINK_ODD_EVEN_PIXELS)
+		dev_dbg(dev, "Data swapping required\n");
+
 	/*
 	 * FIXME: We should not be messing with the companion encoder private
 	 * data from the primary encoder, we should rather let the companion
@@ -739,7 +778,7 @@ static int rcar_lvds_parse_dt_companion(struct rcar_lvds *lvds)
 	 * for the time being.
 	 */
 	companion_lvds = bridge_to_rcar_lvds(lvds->companion);
-	companion_lvds->dual_link = true;
+	companion_lvds->link_type = lvds->link_type;
 
 done:
 	of_node_put(companion);
-- 
2.17.1


[-- Attachment #2: Type: text/plain, Size: 419 bytes --]

-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.

View/Reply Online (#4968): https://lists.cip-project.org/g/cip-dev/message/4968
Mute This Topic: https://lists.cip-project.org/mt/75730030/4520388
Group Owner: cip-dev+owner@lists.cip-project.org
Unsubscribe: https://lists.cip-project.org/g/cip-dev/leave/8129055/727948398/xyzzy  [cip-dev@archiver.kernel.org]
-=-=-=-=-=-=-=-=-=-=-=-

  parent reply	other threads:[~2020-07-22 17:47 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-22 16:34 [cip-dev] [PATCH 4.19.y-cip 00/17] Add RZ/G2E Dual LVDS display Biju Das
2020-07-22 16:34 ` [cip-dev] [PATCH 4.19.y-cip 01/17] drm: rcar-du: lvds: Remove LVDS double-enable checks Biju Das
2020-07-22 16:34 ` [cip-dev] [PATCH 4.19.y-cip 02/17] drm: bridge: Add dual_link field to the drm_bridge_timings structure Biju Das
2020-07-22 16:34 ` [cip-dev] [PATCH 4.19.y-cip 03/17] dt-bindings: display: renesas: lvds: Add renesas,companion property Biju Das
2020-07-22 16:34 ` [cip-dev] [PATCH 4.19.y-cip 04/17] drm: rcar-du: lvds: Add support for dual-link mode Biju Das
2020-07-22 16:34 ` [cip-dev] [PATCH 4.19.y-cip 05/17] drm: rcar-du: Skip LVDS1 output on Gen3 when using dual-link LVDS mode Biju Das
2020-07-22 16:34 ` [cip-dev] [PATCH 4.19.y-cip 06/17] drm: rcar_lvds: Fix dual link mode operations Biju Das
2020-07-22 16:34 ` [cip-dev] [PATCH 4.19.y-cip 07/17] drm: Add drm_atomic_get_(old|new)_connector_for_encoder() helpers Biju Das
2020-07-22 16:34 ` [cip-dev] [PATCH 4.19.y-cip 08/17] drm: Add atomic variants for bridge enable/disable Biju Das
2020-07-22 16:34 ` [cip-dev] [PATCH 4.19.y-cip 09/17] drm: rcar-du: lvds: Get mode from state Biju Das
2020-07-22 16:34 ` [cip-dev] [PATCH 4.19.y-cip 10/17] drm: rcar-du: lvds: Improve identification of panels Biju Das
2020-07-22 16:34 ` [cip-dev] [PATCH 4.19.y-cip 11/17] drm: of: Add drm_of_lvds_get_dual_link_pixel_order Biju Das
2020-07-22 21:38   ` Pavel Machek
2020-07-23  6:56     ` Biju Das
2020-07-22 16:34 ` [cip-dev] [PATCH 4.19.y-cip 12/17] drm: rcar-du: lvds: Get dual link configuration from DT Biju Das
2020-07-22 16:34 ` Biju Das [this message]
2020-07-22 16:34 ` [cip-dev] [PATCH 4.19.y-cip 14/17] arm64: dts: renesas: r8a774c0: Point LVDS0 to its companion LVDS1 Biju Das
2020-07-22 16:34 ` [cip-dev] [PATCH 4.19.y-cip 15/17] arm64: dts: renesas: rzg2: Add reset control properties for display Biju Das
2020-07-22 16:34 ` [cip-dev] [PATCH 4.19.y-cip 16/17] dt-bindings: display: Add idk-2121wr binding Biju Das
2020-07-22 16:34 ` [cip-dev] [PATCH 4.19.y-cip 17/17] arm64: dts: renesas: Add EK874 board with idk-2121wr display support Biju Das
2020-07-22 21:49 ` [cip-dev] [PATCH 4.19.y-cip 00/17] Add RZ/G2E Dual LVDS display Pavel Machek
2020-07-24  7:30   ` Pavel Machek

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=20200722163449.3513-14-biju.das.jz@bp.renesas.com \
    --to=biju.das.jz@bp.renesas.com \
    --cc=chris.paterson2@renesas.com \
    --cc=cip-dev@lists.cip-project.org \
    --cc=nobuhiro1.iwamatsu@toshiba.co.jp \
    --cc=pavel@denx.de \
    --cc=prabhakar.mahadev-lad.rj@bp.renesas.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.