linux-renesas-soc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] drm/rcar-du: dsi: Implement DSI command support
@ 2025-06-08 14:24 Marek Vasut
  2025-06-08 14:24 ` [PATCH 1/4] drm/rcar-du: dsi: Convert register bits to BIT() macro Marek Vasut
                   ` (3 more replies)
  0 siblings, 4 replies; 24+ messages in thread
From: Marek Vasut @ 2025-06-08 14:24 UTC (permalink / raw)
  To: dri-devel
  Cc: Marek Vasut, David Airlie, Geert Uytterhoeven, Kieran Bingham,
	Laurent Pinchart, Maarten Lankhorst, Magnus Damm, Maxime Ripard,
	Simona Vetter, Thomas Zimmermann, Tomi Valkeinen,
	linux-renesas-soc

Use BIT() macro. Clean up lane count handling for non-4-lane panels.

Implement support for DSI command transfer mode using register based
access, with maximum payload length of 16 Bytes in Long Packet.

Marek Vasut (4):
  drm/rcar-du: dsi: Convert register bits to BIT() macro
  drm/rcar-du: dsi: Remove fixed PPI lane count setup
  drm/rcar-du: dsi: Configure TXSETR register to match PPI lane count
  drm/rcar-du: dsi: Implement DSI command support

 .../gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c   | 220 ++++++++++++++++-
 .../drm/renesas/rcar-du/rcar_mipi_dsi_regs.h  | 226 ++++++++++++++----
 2 files changed, 395 insertions(+), 51 deletions(-)
---
Cc: David Airlie <airlied@gmail.com>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
Cc: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Magnus Damm <magnus.damm@gmail.com>
Cc: Maxime Ripard <mripard@kernel.org>
Cc: Simona Vetter <simona@ffwll.ch>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: Tomi Valkeinen <tomi.valkeinen+renesas@ideasonboard.com>
Cc: dri-devel@lists.freedesktop.org
Cc: linux-renesas-soc@vger.kernel.org

-- 
2.47.2


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 1/4] drm/rcar-du: dsi: Convert register bits to BIT() macro
  2025-06-08 14:24 [PATCH 0/4] drm/rcar-du: dsi: Implement DSI command support Marek Vasut
@ 2025-06-08 14:24 ` Marek Vasut
  2025-08-12 13:26   ` Tomi Valkeinen
  2025-06-08 14:24 ` [PATCH 2/4] drm/rcar-du: dsi: Remove fixed PPI lane count setup Marek Vasut
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 24+ messages in thread
From: Marek Vasut @ 2025-06-08 14:24 UTC (permalink / raw)
  To: dri-devel
  Cc: Marek Vasut, David Airlie, Geert Uytterhoeven, Kieran Bingham,
	Laurent Pinchart, Maarten Lankhorst, Magnus Damm, Maxime Ripard,
	Simona Vetter, Thomas Zimmermann, Tomi Valkeinen,
	linux-renesas-soc

Convert register bits to BIT() macro where applicable. This is done
automatically using regex 's@(1 << \([0-9]\+\))@BIT(\1)', except for
two BPP_18 macros which are not bits, but bitfields, and which are
not modified.

Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
---
Cc: David Airlie <airlied@gmail.com>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
Cc: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Magnus Damm <magnus.damm@gmail.com>
Cc: Maxime Ripard <mripard@kernel.org>
Cc: Simona Vetter <simona@ffwll.ch>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: Tomi Valkeinen <tomi.valkeinen+renesas@ideasonboard.com>
Cc: dri-devel@lists.freedesktop.org
Cc: linux-renesas-soc@vger.kernel.org
---
 .../drm/renesas/rcar-du/rcar_mipi_dsi_regs.h  | 92 +++++++++----------
 1 file changed, 46 insertions(+), 46 deletions(-)

diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
index a6b276f1d6ee..b3e57217ae63 100644
--- a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
+++ b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
@@ -9,38 +9,38 @@
 #define __RCAR_MIPI_DSI_REGS_H__
 
 #define LINKSR				0x010
-#define LINKSR_LPBUSY			(1 << 1)
-#define LINKSR_HSBUSY			(1 << 0)
+#define LINKSR_LPBUSY			BIT(1)
+#define LINKSR_HSBUSY			BIT(0)
 
 /*
  * Video Mode Register
  */
 #define TXVMSETR			0x180
 #define TXVMSETR_SYNSEQ_PULSES		(0 << 16)
-#define TXVMSETR_SYNSEQ_EVENTS		(1 << 16)
-#define TXVMSETR_VSTPM			(1 << 15)
-#define TXVMSETR_PIXWDTH		(1 << 8)
-#define TXVMSETR_VSEN_EN		(1 << 4)
+#define TXVMSETR_SYNSEQ_EVENTS		BIT(16)
+#define TXVMSETR_VSTPM			BIT(15)
+#define TXVMSETR_PIXWDTH		BIT(8)
+#define TXVMSETR_VSEN_EN		BIT(4)
 #define TXVMSETR_VSEN_DIS		(0 << 4)
-#define TXVMSETR_HFPBPEN_EN		(1 << 2)
+#define TXVMSETR_HFPBPEN_EN		BIT(2)
 #define TXVMSETR_HFPBPEN_DIS		(0 << 2)
-#define TXVMSETR_HBPBPEN_EN		(1 << 1)
+#define TXVMSETR_HBPBPEN_EN		BIT(1)
 #define TXVMSETR_HBPBPEN_DIS		(0 << 1)
-#define TXVMSETR_HSABPEN_EN		(1 << 0)
+#define TXVMSETR_HSABPEN_EN		BIT(0)
 #define TXVMSETR_HSABPEN_DIS		(0 << 0)
 
 #define TXVMCR				0x190
-#define TXVMCR_VFCLR			(1 << 12)
-#define TXVMCR_EN_VIDEO			(1 << 0)
+#define TXVMCR_VFCLR			BIT(12)
+#define TXVMCR_EN_VIDEO			BIT(0)
 
 #define TXVMSR				0x1a0
-#define TXVMSR_STR			(1 << 16)
-#define TXVMSR_VFRDY			(1 << 12)
-#define TXVMSR_ACT			(1 << 8)
-#define TXVMSR_RDY			(1 << 0)
+#define TXVMSR_STR			BIT(16)
+#define TXVMSR_VFRDY			BIT(12)
+#define TXVMSR_ACT			BIT(8)
+#define TXVMSR_RDY			BIT(0)
 
 #define TXVMSCR				0x1a4
-#define TXVMSCR_STR			(1 << 16)
+#define TXVMSCR_STR			BIT(16)
 
 #define TXVMPSPHSETR			0x1c0
 #define TXVMPSPHSETR_DT_RGB16		(0x0e << 16)
@@ -51,11 +51,11 @@
 
 #define TXVMVPRMSET0R			0x1d0
 #define TXVMVPRMSET0R_HSPOL_HIG		(0 << 17)
-#define TXVMVPRMSET0R_HSPOL_LOW		(1 << 17)
+#define TXVMVPRMSET0R_HSPOL_LOW		BIT(17)
 #define TXVMVPRMSET0R_VSPOL_HIG		(0 << 16)
-#define TXVMVPRMSET0R_VSPOL_LOW		(1 << 16)
+#define TXVMVPRMSET0R_VSPOL_LOW		BIT(16)
 #define TXVMVPRMSET0R_CSPC_RGB		(0 << 4)
-#define TXVMVPRMSET0R_CSPC_YCbCr	(1 << 4)
+#define TXVMVPRMSET0R_CSPC_YCbCr	BIT(4)
 #define TXVMVPRMSET0R_BPP_16		(0 << 0)
 #define TXVMVPRMSET0R_BPP_18		(1 << 0)
 #define TXVMVPRMSET0R_BPP_24		(2 << 0)
@@ -84,21 +84,21 @@
 #define PPISETR_DLEN_1			(0x3 << 0)
 #define PPISETR_DLEN_2			(0x7 << 0)
 #define PPISETR_DLEN_3			(0xf << 0)
-#define PPISETR_CLEN			(1 << 8)
+#define PPISETR_CLEN			BIT(8)
 
 #define PPICLCR				0x710
-#define PPICLCR_TXREQHS			(1 << 8)
-#define PPICLCR_TXULPSEXT		(1 << 1)
-#define PPICLCR_TXULPSCLK		(1 << 0)
+#define PPICLCR_TXREQHS			BIT(8)
+#define PPICLCR_TXULPSEXT		BIT(1)
+#define PPICLCR_TXULPSCLK		BIT(0)
 
 #define PPICLSR				0x720
-#define PPICLSR_HSTOLP			(1 << 27)
-#define PPICLSR_TOHS			(1 << 26)
-#define PPICLSR_STPST			(1 << 0)
+#define PPICLSR_HSTOLP			BIT(27)
+#define PPICLSR_TOHS			BIT(26)
+#define PPICLSR_STPST			BIT(0)
 
 #define PPICLSCR			0x724
-#define PPICLSCR_HSTOLP			(1 << 27)
-#define PPICLSCR_TOHS			(1 << 26)
+#define PPICLSCR_HSTOLP			BIT(27)
+#define PPICLSCR_TOHS			BIT(26)
 
 #define PPIDLSR				0x760
 #define PPIDLSR_STPST			(0xf << 0)
@@ -107,21 +107,21 @@
  * Clocks registers
  */
 #define LPCLKSET			0x1000
-#define LPCLKSET_CKEN			(1 << 8)
+#define LPCLKSET_CKEN			BIT(8)
 #define LPCLKSET_LPCLKDIV(x)		(((x) & 0x3f) << 0)
 
 #define CFGCLKSET			0x1004
-#define CFGCLKSET_CKEN			(1 << 8)
+#define CFGCLKSET_CKEN			BIT(8)
 #define CFGCLKSET_CFGCLKDIV(x)		(((x) & 0x3f) << 0)
 
 #define DOTCLKDIV			0x1008
-#define DOTCLKDIV_CKEN			(1 << 8)
+#define DOTCLKDIV_CKEN			BIT(8)
 #define DOTCLKDIV_DOTCLKDIV(x)		(((x) & 0x3f) << 0)
 
 #define VCLKSET				0x100c
-#define VCLKSET_CKEN			(1 << 16)
+#define VCLKSET_CKEN			BIT(16)
 #define VCLKSET_COLOR_RGB		(0 << 8)
-#define VCLKSET_COLOR_YCC		(1 << 8)
+#define VCLKSET_COLOR_YCC		BIT(8)
 #define VCLKSET_DIV_V3U(x)		(((x) & 0x3) << 4)
 #define VCLKSET_DIV_V4H(x)		(((x) & 0x7) << 4)
 #define VCLKSET_BPP_16			(0 << 2)
@@ -131,23 +131,23 @@
 #define VCLKSET_LANE(x)			(((x) & 0x3) << 0)
 
 #define VCLKEN				0x1010
-#define VCLKEN_CKEN			(1 << 0)
+#define VCLKEN_CKEN			BIT(0)
 
 #define PHYSETUP			0x1014
 #define PHYSETUP_HSFREQRANGE(x)		(((x) & 0x7f) << 16)
 #define PHYSETUP_HSFREQRANGE_MASK	(0x7f << 16)
 #define PHYSETUP_CFGCLKFREQRANGE(x)	(((x) & 0x3f) << 8)
-#define PHYSETUP_SHUTDOWNZ		(1 << 1)
-#define PHYSETUP_RSTZ			(1 << 0)
+#define PHYSETUP_SHUTDOWNZ		BIT(1)
+#define PHYSETUP_RSTZ			BIT(0)
 
 #define CLOCKSET1			0x101c
-#define CLOCKSET1_LOCK_PHY		(1 << 17)
-#define CLOCKSET1_CLKSEL		(1 << 8)
+#define CLOCKSET1_LOCK_PHY		BIT(17)
+#define CLOCKSET1_CLKSEL		BIT(8)
 #define CLOCKSET1_CLKINSEL_EXTAL	(0 << 2)
-#define CLOCKSET1_CLKINSEL_DIG		(1 << 2)
-#define CLOCKSET1_CLKINSEL_DU		(1 << 3)
-#define CLOCKSET1_SHADOW_CLEAR		(1 << 1)
-#define CLOCKSET1_UPDATEPLL		(1 << 0)
+#define CLOCKSET1_CLKINSEL_DIG		BIT(2)
+#define CLOCKSET1_CLKINSEL_DU		BIT(3)
+#define CLOCKSET1_SHADOW_CLEAR		BIT(1)
+#define CLOCKSET1_UPDATEPLL		BIT(0)
 
 #define CLOCKSET2			0x1020
 #define CLOCKSET2_M(x)			(((x) & 0xfff) << 16)
@@ -161,15 +161,15 @@
 #define CLOCKSET3_GMP_CNTRL(x)		(((x) & 0x3) << 0)
 
 #define PHTW				0x1034
-#define PHTW_DWEN			(1 << 24)
+#define PHTW_DWEN			BIT(24)
 #define PHTW_TESTDIN_DATA(x)		(((x) & 0xff) << 16)
-#define PHTW_CWEN			(1 << 8)
+#define PHTW_CWEN			BIT(8)
 #define PHTW_TESTDIN_CODE(x)		(((x) & 0xff) << 0)
 
 #define PHTR				0x1038
-#define PHTR_TEST			(1 << 16)
+#define PHTR_TEST			BIT(16)
 
 #define PHTC				0x103c
-#define PHTC_TESTCLR			(1 << 0)
+#define PHTC_TESTCLR			BIT(0)
 
 #endif /* __RCAR_MIPI_DSI_REGS_H__ */
-- 
2.47.2


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 2/4] drm/rcar-du: dsi: Remove fixed PPI lane count setup
  2025-06-08 14:24 [PATCH 0/4] drm/rcar-du: dsi: Implement DSI command support Marek Vasut
  2025-06-08 14:24 ` [PATCH 1/4] drm/rcar-du: dsi: Convert register bits to BIT() macro Marek Vasut
@ 2025-06-08 14:24 ` Marek Vasut
  2025-08-12 13:18   ` Tomi Valkeinen
  2025-06-08 14:24 ` [PATCH 3/4] drm/rcar-du: dsi: Configure TXSETR register to match PPI lane count Marek Vasut
  2025-06-08 14:24 ` [PATCH 4/4] drm/rcar-du: dsi: Implement DSI command support Marek Vasut
  3 siblings, 1 reply; 24+ messages in thread
From: Marek Vasut @ 2025-06-08 14:24 UTC (permalink / raw)
  To: dri-devel
  Cc: Marek Vasut, David Airlie, Geert Uytterhoeven, Kieran Bingham,
	Laurent Pinchart, Maarten Lankhorst, Magnus Damm, Maxime Ripard,
	Simona Vetter, Thomas Zimmermann, Tomi Valkeinen,
	linux-renesas-soc

The R-Car DSI host is capable of operating in 1..4 DSI lane mode.
Remove hard-coded 4-lane configuration from PPI register settings
and instead configure the PPI lane count according to lane count
information already obtained by this driver instance.

Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
---
Cc: David Airlie <airlied@gmail.com>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
Cc: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Magnus Damm <magnus.damm@gmail.com>
Cc: Maxime Ripard <mripard@kernel.org>
Cc: Simona Vetter <simona@ffwll.ch>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: Tomi Valkeinen <tomi.valkeinen+renesas@ideasonboard.com>
Cc: dri-devel@lists.freedesktop.org
Cc: linux-renesas-soc@vger.kernel.org
---
 drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c      | 2 +-
 drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h | 5 +----
 2 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c
index 7ab8be46c7f6..373bd0040a46 100644
--- a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c
+++ b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c
@@ -576,7 +576,7 @@ static int rcar_mipi_dsi_startup(struct rcar_mipi_dsi *dsi,
 	udelay(10);
 	rcar_mipi_dsi_clr(dsi, CLOCKSET1, CLOCKSET1_UPDATEPLL);
 
-	ppisetr = PPISETR_DLEN_3 | PPISETR_CLEN;
+	ppisetr = ((BIT(dsi->lanes) - 1) & PPISETR_DLEN_MASK) | PPISETR_CLEN;
 	rcar_mipi_dsi_write(dsi, PPISETR, ppisetr);
 
 	rcar_mipi_dsi_set(dsi, PHYSETUP, PHYSETUP_SHUTDOWNZ);
diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
index b3e57217ae63..cefa7e92b5b8 100644
--- a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
+++ b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
@@ -80,10 +80,7 @@
  * PHY-Protocol Interface (PPI) Registers
  */
 #define PPISETR				0x700
-#define PPISETR_DLEN_0			(0x1 << 0)
-#define PPISETR_DLEN_1			(0x3 << 0)
-#define PPISETR_DLEN_2			(0x7 << 0)
-#define PPISETR_DLEN_3			(0xf << 0)
+#define PPISETR_DLEN_MASK		(0xf << 0)
 #define PPISETR_CLEN			BIT(8)
 
 #define PPICLCR				0x710
-- 
2.47.2


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 3/4] drm/rcar-du: dsi: Configure TXSETR register to match PPI lane count
  2025-06-08 14:24 [PATCH 0/4] drm/rcar-du: dsi: Implement DSI command support Marek Vasut
  2025-06-08 14:24 ` [PATCH 1/4] drm/rcar-du: dsi: Convert register bits to BIT() macro Marek Vasut
  2025-06-08 14:24 ` [PATCH 2/4] drm/rcar-du: dsi: Remove fixed PPI lane count setup Marek Vasut
@ 2025-06-08 14:24 ` Marek Vasut
  2025-06-08 14:24 ` [PATCH 4/4] drm/rcar-du: dsi: Implement DSI command support Marek Vasut
  3 siblings, 0 replies; 24+ messages in thread
From: Marek Vasut @ 2025-06-08 14:24 UTC (permalink / raw)
  To: dri-devel
  Cc: Marek Vasut, David Airlie, Geert Uytterhoeven, Kieran Bingham,
	Laurent Pinchart, Maarten Lankhorst, Magnus Damm, Maxime Ripard,
	Simona Vetter, Thomas Zimmermann, Tomi Valkeinen,
	linux-renesas-soc

The R-Car V4H Reference Manual R19UH0186EJ0121 Rev.1.21 section
67.2.2.3 Tx Set Register (TXSETR), field LANECNT description
indicates that the TXSETR register LANECNT bitfield lane count
must be configured such, that it matches lane count configuration
in PPISETR register DLEN bitfield. Make sure the LANECNT and DLEN
bitfields are configured to match.

Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
---
Cc: David Airlie <airlied@gmail.com>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
Cc: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Magnus Damm <magnus.damm@gmail.com>
Cc: Maxime Ripard <mripard@kernel.org>
Cc: Simona Vetter <simona@ffwll.ch>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: Tomi Valkeinen <tomi.valkeinen+renesas@ideasonboard.com>
Cc: dri-devel@lists.freedesktop.org
Cc: linux-renesas-soc@vger.kernel.org
---
 drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c      | 3 +++
 drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h | 4 ++++
 2 files changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c
index 373bd0040a46..c31e0d8f3ff9 100644
--- a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c
+++ b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c
@@ -576,6 +576,9 @@ static int rcar_mipi_dsi_startup(struct rcar_mipi_dsi *dsi,
 	udelay(10);
 	rcar_mipi_dsi_clr(dsi, CLOCKSET1, CLOCKSET1_UPDATEPLL);
 
+	rcar_mipi_dsi_clr(dsi, TXSETR, TXSETR_LANECNT_MASK);
+	rcar_mipi_dsi_set(dsi, TXSETR, dsi->lanes - 1);
+
 	ppisetr = ((BIT(dsi->lanes) - 1) & PPISETR_DLEN_MASK) | PPISETR_CLEN;
 	rcar_mipi_dsi_write(dsi, PPISETR, ppisetr);
 
diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
index cefa7e92b5b8..b018037e116d 100644
--- a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
+++ b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
@@ -12,6 +12,10 @@
 #define LINKSR_LPBUSY			BIT(1)
 #define LINKSR_HSBUSY			BIT(0)
 
+#define TXSETR				0x100
+#define TXSETR_EOTPEN			BIT(12)
+#define TXSETR_LANECNT_MASK		(0x3 << 0)
+
 /*
  * Video Mode Register
  */
-- 
2.47.2


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 4/4] drm/rcar-du: dsi: Implement DSI command support
  2025-06-08 14:24 [PATCH 0/4] drm/rcar-du: dsi: Implement DSI command support Marek Vasut
                   ` (2 preceding siblings ...)
  2025-06-08 14:24 ` [PATCH 3/4] drm/rcar-du: dsi: Configure TXSETR register to match PPI lane count Marek Vasut
@ 2025-06-08 14:24 ` Marek Vasut
  2025-06-09  0:51   ` kernel test robot
  2025-08-12 14:36   ` Tomi Valkeinen
  3 siblings, 2 replies; 24+ messages in thread
From: Marek Vasut @ 2025-06-08 14:24 UTC (permalink / raw)
  To: dri-devel
  Cc: Marek Vasut, David Airlie, Geert Uytterhoeven, Kieran Bingham,
	Laurent Pinchart, Maarten Lankhorst, Magnus Damm, Maxime Ripard,
	Simona Vetter, Thomas Zimmermann, Tomi Valkeinen,
	linux-renesas-soc

Implement support for DSI command transfer mode. Transmission of both Short
Packet and Long Packet is implemented, so is command transmission to request
response from peripheral device and transmission of non-read command with BTA.

The AXI memory access mode is currently not implemented, each transfer is
performed purely using controller register interface. Short Packet transfer
can transfer up to 2 Bytes of data, Long Packet transfer can transfer up to
16 Bytes of data.

Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
---
Cc: David Airlie <airlied@gmail.com>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
Cc: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Magnus Damm <magnus.damm@gmail.com>
Cc: Maxime Ripard <mripard@kernel.org>
Cc: Simona Vetter <simona@ffwll.ch>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: Tomi Valkeinen <tomi.valkeinen+renesas@ideasonboard.com>
Cc: dri-devel@lists.freedesktop.org
Cc: linux-renesas-soc@vger.kernel.org
---
 .../gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c   | 215 ++++++++++++++++++
 .../drm/renesas/rcar-du/rcar_mipi_dsi_regs.h  | 125 ++++++++++
 2 files changed, 340 insertions(+)

diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c
index c31e0d8f3ff9..bc1151c3ce90 100644
--- a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c
+++ b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c
@@ -938,9 +938,224 @@ static int rcar_mipi_dsi_host_detach(struct mipi_dsi_host *host,
 	return 0;
 }
 
+static ssize_t rcar_mipi_dsi_host_tx_transfer(struct mipi_dsi_host *host,
+					      const struct mipi_dsi_msg *msg,
+					      bool is_rx_xfer)
+{
+	const bool is_tx_long = mipi_dsi_packet_format_is_long(msg->type);
+	struct rcar_mipi_dsi *dsi = host_to_rcar_mipi_dsi(host);
+	struct mipi_dsi_packet packet;
+	u8 payload[16] = { 0 };
+	u32 status;
+	int ret;
+
+	ret = mipi_dsi_create_packet(&packet, msg);
+	if (ret)
+		return ret;
+
+	/* Configure LP or HS command transfer. */
+	rcar_mipi_dsi_write(dsi, TXCMSETR, (msg->flags & MIPI_DSI_MSG_USE_LPM) ?
+					   TXCMSETR_SPDTYP : 0);
+
+	/* Register access mode for RX transfer. */
+	if (is_rx_xfer)
+		rcar_mipi_dsi_write(dsi, RXPSETR, 0);
+
+	/* Do not use IRQ, poll for completion, the completion is quick. */
+	rcar_mipi_dsi_write(dsi, TXCMIER, 0);
+
+	/*
+	 * Send the header:
+	 * header[0] = Virtual Channel + Data Type
+	 * header[1] = Word Count LSB (LP) or first param (SP)
+	 * header[2] = Word Count MSB (LP) or second param (SP)
+	 */
+	rcar_mipi_dsi_write(dsi, TXCMPHDR,
+			    (is_tx_long ? TXCMPHDR_FMT : 0) |
+			    TXCMPHDR_VC(msg->channel) |
+			    TXCMPHDR_DT(msg->type) |
+			    TXCMPHDR_DATA1(packet.header[2]) |
+			    TXCMPHDR_DATA0(packet.header[1]));
+
+	if (is_tx_long) {
+		memcpy(payload, packet.payload,
+		       min(msg->tx_len, sizeof(payload)));
+
+		rcar_mipi_dsi_write(dsi, TXCMPPD0R,
+				    (payload[3] << 24) | (payload[2] << 16) |
+				    (payload[1] << 8) | payload[0]);
+		rcar_mipi_dsi_write(dsi, TXCMPPD1R,
+				    (payload[7] << 24) | (payload[6] << 16) |
+				    (payload[5] << 8) | payload[4]);
+		rcar_mipi_dsi_write(dsi, TXCMPPD2R,
+				    (payload[11] << 24) | (payload[10] << 16) |
+				    (payload[9] << 8) | payload[8]);
+		rcar_mipi_dsi_write(dsi, TXCMPPD3R,
+				    (payload[15] << 24) | (payload[14] << 16) |
+				    (payload[13] << 8) | payload[12]);
+	}
+
+	/* Start the transfer, RX with BTA, TX without BTA */
+	if (is_rx_xfer) {
+		rcar_mipi_dsi_write(dsi, TXCMCR, TXCMCR_BTAREQ);
+
+		ret = read_poll_timeout(rcar_mipi_dsi_read, status,
+					(status & RXPSR_BTAREQEND),
+					2000, 10000, false, dsi, RXPSR);
+	} else {
+		rcar_mipi_dsi_write(dsi, TXCMCR, TXCMCR_TXREQ);
+
+		ret = read_poll_timeout(rcar_mipi_dsi_read, status,
+					(status & TXCMSR_TXREQEND),
+					2000, 10000, false, dsi, TXCMSR);
+	}
+
+	if (ret < 0) {
+		dev_err(dsi->dev, "Command transfer timeout (0x%08x)\n",
+			status);
+		return ret;
+	}
+
+	return packet.size;
+}
+
+static ssize_t rcar_mipi_dsi_host_rx_transfer(struct mipi_dsi_host *host,
+					      const struct mipi_dsi_msg *msg)
+{
+	struct rcar_mipi_dsi *dsi = host_to_rcar_mipi_dsi(host);
+	u8 *rx_buf = (u8 *)(msg->rx_buf);
+	u32 reg, data, status, wc;
+	int i, ret;
+
+	/* RX transfer received data validation and parsing starts here. */
+	reg = rcar_mipi_dsi_read(dsi, TOSR);
+	if (reg & TOSR_TATO) {	/* Turn-Around TimeOut. */
+		/* Clear TATO Turn-Around TimeOut bit. */
+		rcar_mipi_dsi_write(dsi, TOSR, TOSR_TATO);
+		return -ETIMEDOUT;
+	}
+
+	reg = rcar_mipi_dsi_read(dsi, RXPSR);
+
+	if (msg->flags & MIPI_DSI_MSG_REQ_ACK) {
+		/* Transfer with zero-length RX */
+		if (!(reg & RXPSR_RCVACK)) {
+			/* No ACK on RX response received */
+			return -EINVAL;
+		}
+	} else {
+		/* Transfer with non-zero-length RX */
+		if (!(reg & RXPSR_RCVRESP)) {
+			/* No packet header of RX response received */
+			return -EINVAL;
+		}
+
+		if (reg & (RXPSR_CRCERR | RXPSR_WCERR | RXPSR_AXIERR | RXPSR_OVRERR)) {
+			/* Incorrect response payload */
+			return -ENODATA;
+		}
+
+		data = rcar_mipi_dsi_read(dsi, RXPHDR);
+		if (data & RXPHDR_FMT) {	/* Long Packet Response */
+			/* Read Long Packet Response length from packet header. */
+			wc = data & 0xffff;
+			if (wc > msg->rx_len) {
+				dev_warn(dsi->dev,
+					 "Long Packet Response longer than RX buffer (%d), limited to %ld Bytes\n",
+					 wc, msg->rx_len);
+				wc = msg->rx_len;
+			}
+
+			if (wc > 16) {
+				dev_warn(dsi->dev,
+					 "Long Packet Response too long (%d), limited to 16 Bytes\n",
+					 wc);
+				wc = 16;
+			}
+
+			for (i = 0; i < msg->rx_len; i++) {
+				if (!(i % 4))
+					data = rcar_mipi_dsi_read(dsi, RXPPD0R + i);
+
+				rx_buf[i] = data & 0xff;
+				data >>= 8;
+			}
+		} else {	/* Short Packet Response */
+			if (msg->rx_len >= 1)
+				rx_buf[0] = data & 0xff;
+			if (msg->rx_len >= 2)
+				rx_buf[1] = (data >> 8) & 0xff;
+			if (msg->rx_len >= 3) {
+				dev_warn(dsi->dev,
+					 "Expected Short Packet Response too long (%ld), limited to 2 Bytes\n",
+					 msg->rx_len);
+			}
+		}
+	}
+
+	if (reg & RXPSR_RCVAKE) {
+		/* Acknowledge and Error report received */
+		return -EFAULT;
+	}
+
+	ret = read_poll_timeout(rcar_mipi_dsi_read, status,
+				!(status & PPIDL0SR_DIR),
+				2000, 10000, false, dsi, PPIDL0SR);
+	if (ret < 0) {
+		dev_err(dsi->dev, "Command RX DIR timeout (0x%08x)\n", status);
+		return ret;
+	}
+
+	ret = read_poll_timeout(rcar_mipi_dsi_read, status,
+				status & PPIDL0SR_STPST,
+				2000, 10000, false, dsi, PPIDL0SR);
+	if (ret < 0) {
+		dev_err(dsi->dev, "Command RX STPST timeout (0x%08x)\n", status);
+		return ret;
+	}
+
+	return 0;
+}
+
+static ssize_t rcar_mipi_dsi_host_transfer(struct mipi_dsi_host *host,
+					   const struct mipi_dsi_msg *msg)
+{
+	const bool is_rx_xfer = (msg->flags & MIPI_DSI_MSG_REQ_ACK) || msg->rx_len;
+	struct rcar_mipi_dsi *dsi = host_to_rcar_mipi_dsi(host);
+	int ret;
+
+	if (msg->tx_len > 16 || msg->rx_len > 16) {
+		/* ToDo: Implement Memory on AXI bus command mode. */
+		dev_warn(dsi->dev,
+			 "Register-based command mode supports only up to 16 Bytes long payload\n");
+		return -EOPNOTSUPP;
+	}
+
+	ret = rcar_mipi_dsi_host_tx_transfer(host, msg, is_rx_xfer);
+
+	/* If TX transfer succeeded and this transfer has RX part. */
+	if (ret >= 0 && is_rx_xfer) {
+		ret = rcar_mipi_dsi_host_rx_transfer(host, msg);
+		if (ret)
+			return ret;
+
+		ret = msg->rx_len;
+	}
+
+	/* Wait a bit between commands */
+	usleep_range(1000, 2000);
+
+	/* Clear the completion interrupt */
+	if (!msg->rx_len)
+		rcar_mipi_dsi_write(dsi, TXCMSR, TXCMSR_TXREQEND);
+
+	return ret;
+}
+
 static const struct mipi_dsi_host_ops rcar_mipi_dsi_host_ops = {
 	.attach = rcar_mipi_dsi_host_attach,
 	.detach = rcar_mipi_dsi_host_detach,
+	.transfer = rcar_mipi_dsi_host_transfer
 };
 
 /* -----------------------------------------------------------------------------
diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
index b018037e116d..8c5c4fc8a55c 100644
--- a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
+++ b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
@@ -16,6 +16,127 @@
 #define TXSETR_EOTPEN			BIT(12)
 #define TXSETR_LANECNT_MASK		(0x3 << 0)
 
+/*
+ * DSI Command Transfer Registers
+ */
+#define TXCMSETR			0x110
+#define TXCMSETR_SPDTYP			BIT(8)	/* 0:HS 1:LP */
+#define TXCMSETR_LPPDACC		BIT(0)
+#define TXCMCR				0x120
+#define TXCMCR_BTATYP			BIT(2)
+#define TXCMCR_BTAREQ			BIT(1)
+#define TXCMCR_TXREQ			BIT(0)
+#define TXCMSR				0x130
+#define TXCMSR_CLSNERR			BIT(18)
+#define TXCMSR_AXIERR			BIT(16)
+#define TXCMSR_TXREQEND			BIT(0)
+#define TXCMSCR				0x134
+#define TXCMSCR_CLSNERR			BIT(18)
+#define TXCMSCR_AXIERR			BIT(16)
+#define TXCMSCR_TXREQEND		BIT(0)
+#define TXCMIER				0x138
+#define TXCMIER_CLSNERR			BIT(18)
+#define TXCMIER_AXIERR			BIT(16)
+#define TXCMIER_TXREQEND		BIT(0)
+#define TXCMADDRSET0R			0x140
+#define TXCMPHDR			0x150
+#define TXCMPHDR_FMT			BIT(24)	/* 0:SP 1:LP */
+#define TXCMPHDR_VC(n)			(((n) & 0x3) << 22)
+#define TXCMPHDR_DT(n)			(((n) & 0x3f) << 16)
+#define TXCMPHDR_DATA1(n)		(((n) & 0xff) << 8)
+#define TXCMPHDR_DATA0(n)		(((n) & 0xff) << 0)
+#define TXCMPPD0R			0x160
+#define TXCMPPD1R			0x164
+#define TXCMPPD2R			0x168
+#define TXCMPPD3R			0x16c
+
+#define RXSETR				0x200
+#define RXSETR_CRCEN			(((n) & 0xf) << 24)
+#define RXSETR_ECCEN			(((n) & 0xf) << 16)
+#define RXPSETR				0x210
+#define RXPSETR_LPPDACC			BIT(0)
+#define RXPSR				0x220
+#define RXPSR_ECCERR1B			BIT(28)
+#define RXPSR_UEXTRGERR			BIT(25)
+#define RXPSR_RESPTOERR			BIT(24)
+#define RXPSR_OVRERR			BIT(23)
+#define RXPSR_AXIERR			BIT(22)
+#define RXPSR_CRCERR			BIT(21)
+#define RXPSR_WCERR			BIT(20)
+#define RXPSR_UEXDTERR			BIT(19)
+#define RXPSR_UEXPKTERR			BIT(18)
+#define RXPSR_ECCERR			BIT(17)
+#define RXPSR_MLFERR			BIT(16)
+#define RXPSR_RCVACK			BIT(14)
+#define RXPSR_RCVEOT			BIT(10)
+#define RXPSR_RCVAKE			BIT(9)
+#define RXPSR_RCVRESP			BIT(8)
+#define RXPSR_BTAREQEND			BIT(0)
+#define RXPSCR				0x224
+#define RXPSCR_ECCERR1B			BIT(28)
+#define RXPSCR_UEXTRGERR		BIT(25)
+#define RXPSCR_RESPTOERR		BIT(24)
+#define RXPSCR_OVRERR			BIT(23)
+#define RXPSCR_AXIERR			BIT(22)
+#define RXPSCR_CRCERR			BIT(21)
+#define RXPSCR_WCERR			BIT(20)
+#define RXPSCR_UEXDTERR			BIT(19)
+#define RXPSCR_UEXPKTERR		BIT(18)
+#define RXPSCR_ECCERR			BIT(17)
+#define RXPSCR_MLFERR			BIT(16)
+#define RXPSCR_RCVACK			BIT(14)
+#define RXPSCR_RCVEOT			BIT(10)
+#define RXPSCR_RCVAKE			BIT(9)
+#define RXPSCR_RCVRESP			BIT(8)
+#define RXPSCR_BTAREQEND		BIT(0)
+#define RXPIER				0x228
+#define RXPIER_ECCERR1B			BIT(28)
+#define RXPIER_UEXTRGERR		BIT(25)
+#define RXPIER_RESPTOERR		BIT(24)
+#define RXPIER_OVRERR			BIT(23)
+#define RXPIER_AXIERR			BIT(22)
+#define RXPIER_CRCERR			BIT(21)
+#define RXPIER_WCERR			BIT(20)
+#define RXPIER_UEXDTERR			BIT(19)
+#define RXPIER_UEXPKTERR		BIT(18)
+#define RXPIER_ECCERR			BIT(17)
+#define RXPIER_MLFERR			BIT(16)
+#define RXPIER_RCVACK			BIT(14)
+#define RXPIER_RCVEOT			BIT(10)
+#define RXPIER_RCVAKE			BIT(9)
+#define RXPIER_RCVRESP			BIT(8)
+#define RXPIER_BTAREQEND		BIT(0)
+#define RXPADDRSET0R			0x230
+#define RXPSIZESETR			0x238
+#define RXPSIZESETR_SIZE(n)		(((n) & 0xf) << 3)
+#define RXPHDR				0x240
+#define RXPHDR_FMT			BIT(24)	/* 0:SP 1:LP */
+#define RXPHDR_VC(n)			(((n) & 0x3) << 22)
+#define RXPHDR_DT(n)			(((n) & 0x3f) << 16)
+#define RXPHDR_DATA1(n)			(((n) & 0xff) << 8)
+#define RXPHDR_DATA0(n)			(((n) & 0xff) << 0)
+#define RXPPD0R				0x250
+#define RXPPD1R				0x254
+#define RXPPD2R				0x258
+#define RXPPD3R				0x25c
+#define AKEPR				0x300
+#define AKEPR_VC(n)			(((n) & 0x3) << 22)
+#define AKEPR_DT(n)			(((n) & 0x3f) << 16)
+#define AKEPR_ERRRPT(n)			(((n) & 0xffff) << 0)
+#define RXRESPTOSETR			0x400
+#define TACR				0x500
+#define TASR				0x510
+#define TASCR				0x514
+#define TAIER				0x518
+#define TOSR				0x610
+#define TOSR_TATO			BIT(2)
+#define TOSR_LRXHTO			BIT(1)
+#define TOSR_HRXTO			BIT(0)
+#define TOSCR				0x614
+#define TOSCR_TATO			BIT(2)
+#define TOSCR_LRXHTO			BIT(1)
+#define TOSCR_HRXTO			BIT(0)
+
 /*
  * Video Mode Register
  */
@@ -101,6 +222,10 @@
 #define PPICLSCR_HSTOLP			BIT(27)
 #define PPICLSCR_TOHS			BIT(26)
 
+#define PPIDL0SR			0x740
+#define PPIDL0SR_DIR			BIT(10)
+#define PPIDL0SR_STPST			BIT(6)
+
 #define PPIDLSR				0x760
 #define PPIDLSR_STPST			(0xf << 0)
 
-- 
2.47.2


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: [PATCH 4/4] drm/rcar-du: dsi: Implement DSI command support
  2025-06-08 14:24 ` [PATCH 4/4] drm/rcar-du: dsi: Implement DSI command support Marek Vasut
@ 2025-06-09  0:51   ` kernel test robot
  2025-08-12 14:36   ` Tomi Valkeinen
  1 sibling, 0 replies; 24+ messages in thread
From: kernel test robot @ 2025-06-09  0:51 UTC (permalink / raw)
  To: Marek Vasut, dri-devel
  Cc: llvm, oe-kbuild-all, Marek Vasut, David Airlie,
	Geert Uytterhoeven, Kieran Bingham, Laurent Pinchart,
	Maarten Lankhorst, Magnus Damm, Maxime Ripard, Simona Vetter,
	Thomas Zimmermann, Tomi Valkeinen, linux-renesas-soc

Hi Marek,

kernel test robot noticed the following build warnings:

[auto build test WARNING on geert-renesas-devel/next]
[also build test WARNING on drm-exynos/exynos-drm-next linus/master v6.16-rc1 next-20250606]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Marek-Vasut/drm-rcar-du-dsi-Convert-register-bits-to-BIT-macro/20250609-054641
base:   https://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel.git next
patch link:    https://lore.kernel.org/r/20250608142636.54033-5-marek.vasut%2Brenesas%40mailbox.org
patch subject: [PATCH 4/4] drm/rcar-du: dsi: Implement DSI command support
config: i386-buildonly-randconfig-005-20250609 (https://download.01.org/0day-ci/archive/20250609/202506090832.Vo4IJeD2-lkp@intel.com/config)
compiler: clang version 20.1.2 (https://github.com/llvm/llvm-project 58df0ef89dd64126512e4ee27b4ac3fd8ddf6247)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250609/202506090832.Vo4IJeD2-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202506090832.Vo4IJeD2-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c:1064:11: warning: format specifies type 'long' but the argument has type 'size_t' (aka 'unsigned int') [-Wformat]
    1063 |                                          "Long Packet Response longer than RX buffer (%d), limited to %ld Bytes\n",
         |                                                                                                       ~~~
         |                                                                                                       %zu
    1064 |                                          wc, msg->rx_len);
         |                                              ^~~~~~~~~~~
   include/linux/dev_printk.h:156:70: note: expanded from macro 'dev_warn'
     156 |         dev_printk_index_wrap(_dev_warn, KERN_WARNING, dev, dev_fmt(fmt), ##__VA_ARGS__)
         |                                                                     ~~~     ^~~~~~~~~~~
   include/linux/dev_printk.h:110:23: note: expanded from macro 'dev_printk_index_wrap'
     110 |                 _p_func(dev, fmt, ##__VA_ARGS__);                       \
         |                              ~~~    ^~~~~~~~~~~
   drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c:1090:7: warning: format specifies type 'long' but the argument has type 'size_t' (aka 'unsigned int') [-Wformat]
    1089 |                                          "Expected Short Packet Response too long (%ld), limited to 2 Bytes\n",
         |                                                                                    ~~~
         |                                                                                    %zu
    1090 |                                          msg->rx_len);
         |                                          ^~~~~~~~~~~
   include/linux/dev_printk.h:156:70: note: expanded from macro 'dev_warn'
     156 |         dev_printk_index_wrap(_dev_warn, KERN_WARNING, dev, dev_fmt(fmt), ##__VA_ARGS__)
         |                                                                     ~~~     ^~~~~~~~~~~
   include/linux/dev_printk.h:110:23: note: expanded from macro 'dev_printk_index_wrap'
     110 |                 _p_func(dev, fmt, ##__VA_ARGS__);                       \
         |                              ~~~    ^~~~~~~~~~~
   2 warnings generated.


vim +1064 drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c

  1020	
  1021	static ssize_t rcar_mipi_dsi_host_rx_transfer(struct mipi_dsi_host *host,
  1022						      const struct mipi_dsi_msg *msg)
  1023	{
  1024		struct rcar_mipi_dsi *dsi = host_to_rcar_mipi_dsi(host);
  1025		u8 *rx_buf = (u8 *)(msg->rx_buf);
  1026		u32 reg, data, status, wc;
  1027		int i, ret;
  1028	
  1029		/* RX transfer received data validation and parsing starts here. */
  1030		reg = rcar_mipi_dsi_read(dsi, TOSR);
  1031		if (reg & TOSR_TATO) {	/* Turn-Around TimeOut. */
  1032			/* Clear TATO Turn-Around TimeOut bit. */
  1033			rcar_mipi_dsi_write(dsi, TOSR, TOSR_TATO);
  1034			return -ETIMEDOUT;
  1035		}
  1036	
  1037		reg = rcar_mipi_dsi_read(dsi, RXPSR);
  1038	
  1039		if (msg->flags & MIPI_DSI_MSG_REQ_ACK) {
  1040			/* Transfer with zero-length RX */
  1041			if (!(reg & RXPSR_RCVACK)) {
  1042				/* No ACK on RX response received */
  1043				return -EINVAL;
  1044			}
  1045		} else {
  1046			/* Transfer with non-zero-length RX */
  1047			if (!(reg & RXPSR_RCVRESP)) {
  1048				/* No packet header of RX response received */
  1049				return -EINVAL;
  1050			}
  1051	
  1052			if (reg & (RXPSR_CRCERR | RXPSR_WCERR | RXPSR_AXIERR | RXPSR_OVRERR)) {
  1053				/* Incorrect response payload */
  1054				return -ENODATA;
  1055			}
  1056	
  1057			data = rcar_mipi_dsi_read(dsi, RXPHDR);
  1058			if (data & RXPHDR_FMT) {	/* Long Packet Response */
  1059				/* Read Long Packet Response length from packet header. */
  1060				wc = data & 0xffff;
  1061				if (wc > msg->rx_len) {
  1062					dev_warn(dsi->dev,
  1063						 "Long Packet Response longer than RX buffer (%d), limited to %ld Bytes\n",
> 1064						 wc, msg->rx_len);
  1065					wc = msg->rx_len;
  1066				}
  1067	
  1068				if (wc > 16) {
  1069					dev_warn(dsi->dev,
  1070						 "Long Packet Response too long (%d), limited to 16 Bytes\n",
  1071						 wc);
  1072					wc = 16;
  1073				}
  1074	
  1075				for (i = 0; i < msg->rx_len; i++) {
  1076					if (!(i % 4))
  1077						data = rcar_mipi_dsi_read(dsi, RXPPD0R + i);
  1078	
  1079					rx_buf[i] = data & 0xff;
  1080					data >>= 8;
  1081				}
  1082			} else {	/* Short Packet Response */
  1083				if (msg->rx_len >= 1)
  1084					rx_buf[0] = data & 0xff;
  1085				if (msg->rx_len >= 2)
  1086					rx_buf[1] = (data >> 8) & 0xff;
  1087				if (msg->rx_len >= 3) {
  1088					dev_warn(dsi->dev,
  1089						 "Expected Short Packet Response too long (%ld), limited to 2 Bytes\n",
  1090						 msg->rx_len);
  1091				}
  1092			}
  1093		}
  1094	
  1095		if (reg & RXPSR_RCVAKE) {
  1096			/* Acknowledge and Error report received */
  1097			return -EFAULT;
  1098		}
  1099	
  1100		ret = read_poll_timeout(rcar_mipi_dsi_read, status,
  1101					!(status & PPIDL0SR_DIR),
  1102					2000, 10000, false, dsi, PPIDL0SR);
  1103		if (ret < 0) {
  1104			dev_err(dsi->dev, "Command RX DIR timeout (0x%08x)\n", status);
  1105			return ret;
  1106		}
  1107	
  1108		ret = read_poll_timeout(rcar_mipi_dsi_read, status,
  1109					status & PPIDL0SR_STPST,
  1110					2000, 10000, false, dsi, PPIDL0SR);
  1111		if (ret < 0) {
  1112			dev_err(dsi->dev, "Command RX STPST timeout (0x%08x)\n", status);
  1113			return ret;
  1114		}
  1115	
  1116		return 0;
  1117	}
  1118	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 2/4] drm/rcar-du: dsi: Remove fixed PPI lane count setup
  2025-06-08 14:24 ` [PATCH 2/4] drm/rcar-du: dsi: Remove fixed PPI lane count setup Marek Vasut
@ 2025-08-12 13:18   ` Tomi Valkeinen
  2025-08-12 13:30     ` Tomi Valkeinen
  0 siblings, 1 reply; 24+ messages in thread
From: Tomi Valkeinen @ 2025-08-12 13:18 UTC (permalink / raw)
  To: Marek Vasut, dri-devel
  Cc: David Airlie, Geert Uytterhoeven, Kieran Bingham,
	Laurent Pinchart, Maarten Lankhorst, Magnus Damm, Maxime Ripard,
	Simona Vetter, Thomas Zimmermann, linux-renesas-soc

Hi,

On 08/06/2025 17:24, Marek Vasut wrote:
> The R-Car DSI host is capable of operating in 1..4 DSI lane mode.
> Remove hard-coded 4-lane configuration from PPI register settings
> and instead configure the PPI lane count according to lane count
> information already obtained by this driver instance.
> 
> Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
> ---
> Cc: David Airlie <airlied@gmail.com>
> Cc: Geert Uytterhoeven <geert+renesas@glider.be>
> Cc: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
> Cc: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Cc: Magnus Damm <magnus.damm@gmail.com>
> Cc: Maxime Ripard <mripard@kernel.org>
> Cc: Simona Vetter <simona@ffwll.ch>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: Tomi Valkeinen <tomi.valkeinen+renesas@ideasonboard.com>
> Cc: dri-devel@lists.freedesktop.org
> Cc: linux-renesas-soc@vger.kernel.org
> ---
>  drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c      | 2 +-
>  drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h | 5 +----
>  2 files changed, 2 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c
> index 7ab8be46c7f6..373bd0040a46 100644
> --- a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c
> +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c
> @@ -576,7 +576,7 @@ static int rcar_mipi_dsi_startup(struct rcar_mipi_dsi *dsi,
>  	udelay(10);
>  	rcar_mipi_dsi_clr(dsi, CLOCKSET1, CLOCKSET1_UPDATEPLL);
>  
> -	ppisetr = PPISETR_DLEN_3 | PPISETR_CLEN;
> +	ppisetr = ((BIT(dsi->lanes) - 1) & PPISETR_DLEN_MASK) | PPISETR_CLEN;
>  	rcar_mipi_dsi_write(dsi, PPISETR, ppisetr);
>  
>  	rcar_mipi_dsi_set(dsi, PHYSETUP, PHYSETUP_SHUTDOWNZ);
> diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
> index b3e57217ae63..cefa7e92b5b8 100644
> --- a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
> +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
> @@ -80,10 +80,7 @@
>   * PHY-Protocol Interface (PPI) Registers
>   */
>  #define PPISETR				0x700
> -#define PPISETR_DLEN_0			(0x1 << 0)
> -#define PPISETR_DLEN_1			(0x3 << 0)
> -#define PPISETR_DLEN_2			(0x7 << 0)
> -#define PPISETR_DLEN_3			(0xf << 0)
> +#define PPISETR_DLEN_MASK		(0xf << 0)
>  #define PPISETR_CLEN			BIT(8)

Looks fine, but do you know what the TXSETR register does? It also has
LANECNT, but I don't see the driver touching that register at all.
TXSETR:LANECNT default value is 3 (4 lanes), which matches with the old
hardcoded behavior for PPISETR... So I wonder if that register should
also be set?

 Tomi


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 1/4] drm/rcar-du: dsi: Convert register bits to BIT() macro
  2025-06-08 14:24 ` [PATCH 1/4] drm/rcar-du: dsi: Convert register bits to BIT() macro Marek Vasut
@ 2025-08-12 13:26   ` Tomi Valkeinen
  2025-08-12 19:32     ` Marek Vasut
  0 siblings, 1 reply; 24+ messages in thread
From: Tomi Valkeinen @ 2025-08-12 13:26 UTC (permalink / raw)
  To: Marek Vasut, dri-devel
  Cc: David Airlie, Geert Uytterhoeven, Kieran Bingham,
	Laurent Pinchart, Maarten Lankhorst, Magnus Damm, Maxime Ripard,
	Simona Vetter, Thomas Zimmermann, linux-renesas-soc

Hi,

On 08/06/2025 17:24, Marek Vasut wrote:
> Convert register bits to BIT() macro where applicable. This is done
> automatically using regex 's@(1 << \([0-9]\+\))@BIT(\1)', except for
> two BPP_18 macros which are not bits, but bitfields, and which are
> not modified.
> 
> Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
> ---
> Cc: David Airlie <airlied@gmail.com>
> Cc: Geert Uytterhoeven <geert+renesas@glider.be>
> Cc: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
> Cc: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Cc: Magnus Damm <magnus.damm@gmail.com>
> Cc: Maxime Ripard <mripard@kernel.org>
> Cc: Simona Vetter <simona@ffwll.ch>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: Tomi Valkeinen <tomi.valkeinen+renesas@ideasonboard.com>
> Cc: dri-devel@lists.freedesktop.org
> Cc: linux-renesas-soc@vger.kernel.org
> ---
>  .../drm/renesas/rcar-du/rcar_mipi_dsi_regs.h  | 92 +++++++++----------
>  1 file changed, 46 insertions(+), 46 deletions(-)
> 
> diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
> index a6b276f1d6ee..b3e57217ae63 100644
> --- a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
> +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
> @@ -9,38 +9,38 @@
>  #define __RCAR_MIPI_DSI_REGS_H__
>  
>  #define LINKSR				0x010
> -#define LINKSR_LPBUSY			(1 << 1)
> -#define LINKSR_HSBUSY			(1 << 0)
> +#define LINKSR_LPBUSY			BIT(1)
> +#define LINKSR_HSBUSY			BIT(0)
>  
>  /*
>   * Video Mode Register
>   */
>  #define TXVMSETR			0x180
>  #define TXVMSETR_SYNSEQ_PULSES		(0 << 16)
> -#define TXVMSETR_SYNSEQ_EVENTS		(1 << 16)
> -#define TXVMSETR_VSTPM			(1 << 15)
> -#define TXVMSETR_PIXWDTH		(1 << 8)
> -#define TXVMSETR_VSEN_EN		(1 << 4)
> +#define TXVMSETR_SYNSEQ_EVENTS		BIT(16)
> +#define TXVMSETR_VSTPM			BIT(15)
> +#define TXVMSETR_PIXWDTH		BIT(8)
> +#define TXVMSETR_VSEN_EN		BIT(4)
>  #define TXVMSETR_VSEN_DIS		(0 << 4)
> -#define TXVMSETR_HFPBPEN_EN		(1 << 2)
> +#define TXVMSETR_HFPBPEN_EN		BIT(2)
>  #define TXVMSETR_HFPBPEN_DIS		(0 << 2)
> -#define TXVMSETR_HBPBPEN_EN		(1 << 1)
> +#define TXVMSETR_HBPBPEN_EN		BIT(1)
>  #define TXVMSETR_HBPBPEN_DIS		(0 << 1)
> -#define TXVMSETR_HSABPEN_EN		(1 << 0)
> +#define TXVMSETR_HSABPEN_EN		BIT(0)
>  #define TXVMSETR_HSABPEN_DIS		(0 << 0)
>  
>  #define TXVMCR				0x190
> -#define TXVMCR_VFCLR			(1 << 12)
> -#define TXVMCR_EN_VIDEO			(1 << 0)
> +#define TXVMCR_VFCLR			BIT(12)
> +#define TXVMCR_EN_VIDEO			BIT(0)
>  
>  #define TXVMSR				0x1a0
> -#define TXVMSR_STR			(1 << 16)
> -#define TXVMSR_VFRDY			(1 << 12)
> -#define TXVMSR_ACT			(1 << 8)
> -#define TXVMSR_RDY			(1 << 0)
> +#define TXVMSR_STR			BIT(16)
> +#define TXVMSR_VFRDY			BIT(12)
> +#define TXVMSR_ACT			BIT(8)
> +#define TXVMSR_RDY			BIT(0)
>  
>  #define TXVMSCR				0x1a4
> -#define TXVMSCR_STR			(1 << 16)
> +#define TXVMSCR_STR			BIT(16)
>  
>  #define TXVMPSPHSETR			0x1c0
>  #define TXVMPSPHSETR_DT_RGB16		(0x0e << 16)
> @@ -51,11 +51,11 @@
>  
>  #define TXVMVPRMSET0R			0x1d0
>  #define TXVMVPRMSET0R_HSPOL_HIG		(0 << 17)
> -#define TXVMVPRMSET0R_HSPOL_LOW		(1 << 17)
> +#define TXVMVPRMSET0R_HSPOL_LOW		BIT(17)

I'm not sure about this (and below). We have two defines for the HSPOL,
high and low. If one of them is (x << y), shouldn't the other one be of
that style too?

>  #define TXVMVPRMSET0R_VSPOL_HIG		(0 << 16)
> -#define TXVMVPRMSET0R_VSPOL_LOW		(1 << 16)
> +#define TXVMVPRMSET0R_VSPOL_LOW		BIT(16)
>  #define TXVMVPRMSET0R_CSPC_RGB		(0 << 4)
> -#define TXVMVPRMSET0R_CSPC_YCbCr	(1 << 4)
> +#define TXVMVPRMSET0R_CSPC_YCbCr	BIT(4)

This looks like a value, not a bit.

>  #define TXVMVPRMSET0R_BPP_16		(0 << 0)
>  #define TXVMVPRMSET0R_BPP_18		(1 << 0)
>  #define TXVMVPRMSET0R_BPP_24		(2 << 0)
> @@ -84,21 +84,21 @@
>  #define PPISETR_DLEN_1			(0x3 << 0)
>  #define PPISETR_DLEN_2			(0x7 << 0)
>  #define PPISETR_DLEN_3			(0xf << 0)
> -#define PPISETR_CLEN			(1 << 8)
> +#define PPISETR_CLEN			BIT(8)
>  
>  #define PPICLCR				0x710
> -#define PPICLCR_TXREQHS			(1 << 8)
> -#define PPICLCR_TXULPSEXT		(1 << 1)
> -#define PPICLCR_TXULPSCLK		(1 << 0)
> +#define PPICLCR_TXREQHS			BIT(8)
> +#define PPICLCR_TXULPSEXT		BIT(1)
> +#define PPICLCR_TXULPSCLK		BIT(0)
>  
>  #define PPICLSR				0x720
> -#define PPICLSR_HSTOLP			(1 << 27)
> -#define PPICLSR_TOHS			(1 << 26)
> -#define PPICLSR_STPST			(1 << 0)
> +#define PPICLSR_HSTOLP			BIT(27)
> +#define PPICLSR_TOHS			BIT(26)
> +#define PPICLSR_STPST			BIT(0)
>  
>  #define PPICLSCR			0x724
> -#define PPICLSCR_HSTOLP			(1 << 27)
> -#define PPICLSCR_TOHS			(1 << 26)
> +#define PPICLSCR_HSTOLP			BIT(27)
> +#define PPICLSCR_TOHS			BIT(26)
>  
>  #define PPIDLSR				0x760
>  #define PPIDLSR_STPST			(0xf << 0)
> @@ -107,21 +107,21 @@
>   * Clocks registers
>   */
>  #define LPCLKSET			0x1000
> -#define LPCLKSET_CKEN			(1 << 8)
> +#define LPCLKSET_CKEN			BIT(8)
>  #define LPCLKSET_LPCLKDIV(x)		(((x) & 0x3f) << 0)
>  
>  #define CFGCLKSET			0x1004
> -#define CFGCLKSET_CKEN			(1 << 8)
> +#define CFGCLKSET_CKEN			BIT(8)
>  #define CFGCLKSET_CFGCLKDIV(x)		(((x) & 0x3f) << 0)
>  
>  #define DOTCLKDIV			0x1008
> -#define DOTCLKDIV_CKEN			(1 << 8)
> +#define DOTCLKDIV_CKEN			BIT(8)
>  #define DOTCLKDIV_DOTCLKDIV(x)		(((x) & 0x3f) << 0)
>  
>  #define VCLKSET				0x100c
> -#define VCLKSET_CKEN			(1 << 16)
> +#define VCLKSET_CKEN			BIT(16)
>  #define VCLKSET_COLOR_RGB		(0 << 8)
> -#define VCLKSET_COLOR_YCC		(1 << 8)
> +#define VCLKSET_COLOR_YCC		BIT(8)

And this.

>  #define VCLKSET_DIV_V3U(x)		(((x) & 0x3) << 4)
>  #define VCLKSET_DIV_V4H(x)		(((x) & 0x7) << 4)
>  #define VCLKSET_BPP_16			(0 << 2)
> @@ -131,23 +131,23 @@
>  #define VCLKSET_LANE(x)			(((x) & 0x3) << 0)
>  
>  #define VCLKEN				0x1010
> -#define VCLKEN_CKEN			(1 << 0)
> +#define VCLKEN_CKEN			BIT(0)
>  
>  #define PHYSETUP			0x1014
>  #define PHYSETUP_HSFREQRANGE(x)		(((x) & 0x7f) << 16)
>  #define PHYSETUP_HSFREQRANGE_MASK	(0x7f << 16)
>  #define PHYSETUP_CFGCLKFREQRANGE(x)	(((x) & 0x3f) << 8)
> -#define PHYSETUP_SHUTDOWNZ		(1 << 1)
> -#define PHYSETUP_RSTZ			(1 << 0)
> +#define PHYSETUP_SHUTDOWNZ		BIT(1)
> +#define PHYSETUP_RSTZ			BIT(0)
>  
>  #define CLOCKSET1			0x101c
> -#define CLOCKSET1_LOCK_PHY		(1 << 17)
> -#define CLOCKSET1_CLKSEL		(1 << 8)
> +#define CLOCKSET1_LOCK_PHY		BIT(17)
> +#define CLOCKSET1_CLKSEL		BIT(8)
>  #define CLOCKSET1_CLKINSEL_EXTAL	(0 << 2)
> -#define CLOCKSET1_CLKINSEL_DIG		(1 << 2)
> -#define CLOCKSET1_CLKINSEL_DU		(1 << 3)

And this (although the shift by 3 is confusing with CLOCKSET1_CLKINSEL_DU).

> -#define CLOCKSET1_SHADOW_CLEAR		(1 << 1)
> -#define CLOCKSET1_UPDATEPLL		(1 << 0)
> +#define CLOCKSET1_CLKINSEL_DIG		BIT(2)
> +#define CLOCKSET1_CLKINSEL_DU		BIT(3)
> +#define CLOCKSET1_SHADOW_CLEAR		BIT(1)
> +#define CLOCKSET1_UPDATEPLL		BIT(0)
>  
>  #define CLOCKSET2			0x1020
>  #define CLOCKSET2_M(x)			(((x) & 0xfff) << 16)
> @@ -161,15 +161,15 @@
>  #define CLOCKSET3_GMP_CNTRL(x)		(((x) & 0x3) << 0)
>  
>  #define PHTW				0x1034
> -#define PHTW_DWEN			(1 << 24)
> +#define PHTW_DWEN			BIT(24)
>  #define PHTW_TESTDIN_DATA(x)		(((x) & 0xff) << 16)
> -#define PHTW_CWEN			(1 << 8)
> +#define PHTW_CWEN			BIT(8)
>  #define PHTW_TESTDIN_CODE(x)		(((x) & 0xff) << 0)
>  
>  #define PHTR				0x1038
> -#define PHTR_TEST			(1 << 16)
> +#define PHTR_TEST			BIT(16)
>  
>  #define PHTC				0x103c
> -#define PHTC_TESTCLR			(1 << 0)
> +#define PHTC_TESTCLR			BIT(0)
>  
>  #endif /* __RCAR_MIPI_DSI_REGS_H__ */


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 2/4] drm/rcar-du: dsi: Remove fixed PPI lane count setup
  2025-08-12 13:18   ` Tomi Valkeinen
@ 2025-08-12 13:30     ` Tomi Valkeinen
  2025-08-12 19:35       ` Marek Vasut
  0 siblings, 1 reply; 24+ messages in thread
From: Tomi Valkeinen @ 2025-08-12 13:30 UTC (permalink / raw)
  To: Marek Vasut, dri-devel
  Cc: David Airlie, Geert Uytterhoeven, Kieran Bingham,
	Laurent Pinchart, Maarten Lankhorst, Magnus Damm, Maxime Ripard,
	Simona Vetter, Thomas Zimmermann, linux-renesas-soc

Hi,

On 12/08/2025 16:18, Tomi Valkeinen wrote:
> Hi,
> 
> On 08/06/2025 17:24, Marek Vasut wrote:
>> The R-Car DSI host is capable of operating in 1..4 DSI lane mode.
>> Remove hard-coded 4-lane configuration from PPI register settings
>> and instead configure the PPI lane count according to lane count
>> information already obtained by this driver instance.
>>
>> Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
>> ---
>> Cc: David Airlie <airlied@gmail.com>
>> Cc: Geert Uytterhoeven <geert+renesas@glider.be>
>> Cc: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
>> Cc: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
>> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> Cc: Magnus Damm <magnus.damm@gmail.com>
>> Cc: Maxime Ripard <mripard@kernel.org>
>> Cc: Simona Vetter <simona@ffwll.ch>
>> Cc: Thomas Zimmermann <tzimmermann@suse.de>
>> Cc: Tomi Valkeinen <tomi.valkeinen+renesas@ideasonboard.com>
>> Cc: dri-devel@lists.freedesktop.org
>> Cc: linux-renesas-soc@vger.kernel.org
>> ---
>>  drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c      | 2 +-
>>  drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h | 5 +----
>>  2 files changed, 2 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c
>> index 7ab8be46c7f6..373bd0040a46 100644
>> --- a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c
>> +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c
>> @@ -576,7 +576,7 @@ static int rcar_mipi_dsi_startup(struct rcar_mipi_dsi *dsi,
>>  	udelay(10);
>>  	rcar_mipi_dsi_clr(dsi, CLOCKSET1, CLOCKSET1_UPDATEPLL);
>>  
>> -	ppisetr = PPISETR_DLEN_3 | PPISETR_CLEN;
>> +	ppisetr = ((BIT(dsi->lanes) - 1) & PPISETR_DLEN_MASK) | PPISETR_CLEN;
>>  	rcar_mipi_dsi_write(dsi, PPISETR, ppisetr);
>>  
>>  	rcar_mipi_dsi_set(dsi, PHYSETUP, PHYSETUP_SHUTDOWNZ);
>> diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
>> index b3e57217ae63..cefa7e92b5b8 100644
>> --- a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
>> +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
>> @@ -80,10 +80,7 @@
>>   * PHY-Protocol Interface (PPI) Registers
>>   */
>>  #define PPISETR				0x700
>> -#define PPISETR_DLEN_0			(0x1 << 0)
>> -#define PPISETR_DLEN_1			(0x3 << 0)
>> -#define PPISETR_DLEN_2			(0x7 << 0)
>> -#define PPISETR_DLEN_3			(0xf << 0)
>> +#define PPISETR_DLEN_MASK		(0xf << 0)
>>  #define PPISETR_CLEN			BIT(8)
> 
> Looks fine, but do you know what the TXSETR register does? It also has
> LANECNT, but I don't see the driver touching that register at all.
> TXSETR:LANECNT default value is 3 (4 lanes), which matches with the old
> hardcoded behavior for PPISETR... So I wonder if that register should
> also be set?

Ah, never mind, I now saw the patch 3 =). But should it be before patch
2? Hmm, I guess that ordering is no better. Should they be combined into
"support 1,2,3 datalanes" patch?

 Tomi


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 4/4] drm/rcar-du: dsi: Implement DSI command support
  2025-06-08 14:24 ` [PATCH 4/4] drm/rcar-du: dsi: Implement DSI command support Marek Vasut
  2025-06-09  0:51   ` kernel test robot
@ 2025-08-12 14:36   ` Tomi Valkeinen
  2025-08-17 23:40     ` Marek Vasut
  1 sibling, 1 reply; 24+ messages in thread
From: Tomi Valkeinen @ 2025-08-12 14:36 UTC (permalink / raw)
  To: Marek Vasut, dri-devel
  Cc: David Airlie, Geert Uytterhoeven, Kieran Bingham,
	Laurent Pinchart, Maarten Lankhorst, Magnus Damm, Maxime Ripard,
	Simona Vetter, Thomas Zimmermann, linux-renesas-soc

Hi,

On 08/06/2025 17:24, Marek Vasut wrote:
> Implement support for DSI command transfer mode. Transmission of both Short

I constantly kept reading "DSI command mode support". So I was quite
confused for a bit =). Maybe avoid the use of "mode" with "DSI command".

> Packet and Long Packet is implemented, so is command transmission to request
> response from peripheral device and transmission of non-read command with BTA.
> 
> The AXI memory access mode is currently not implemented, each transfer is
> performed purely using controller register interface. Short Packet transfer
> can transfer up to 2 Bytes of data, Long Packet transfer can transfer up to
> 16 Bytes of data.
> 
> Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
> ---
> Cc: David Airlie <airlied@gmail.com>
> Cc: Geert Uytterhoeven <geert+renesas@glider.be>
> Cc: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
> Cc: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Cc: Magnus Damm <magnus.damm@gmail.com>
> Cc: Maxime Ripard <mripard@kernel.org>
> Cc: Simona Vetter <simona@ffwll.ch>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: Tomi Valkeinen <tomi.valkeinen+renesas@ideasonboard.com>
> Cc: dri-devel@lists.freedesktop.org
> Cc: linux-renesas-soc@vger.kernel.org
> ---
>  .../gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c   | 215 ++++++++++++++++++
>  .../drm/renesas/rcar-du/rcar_mipi_dsi_regs.h  | 125 ++++++++++
>  2 files changed, 340 insertions(+)
> 
> diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c
> index c31e0d8f3ff9..bc1151c3ce90 100644
> --- a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c
> +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c
> @@ -938,9 +938,224 @@ static int rcar_mipi_dsi_host_detach(struct mipi_dsi_host *host,
>  	return 0;
>  }
>  
> +static ssize_t rcar_mipi_dsi_host_tx_transfer(struct mipi_dsi_host *host,
> +					      const struct mipi_dsi_msg *msg,
> +					      bool is_rx_xfer)
> +{
> +	const bool is_tx_long = mipi_dsi_packet_format_is_long(msg->type);
> +	struct rcar_mipi_dsi *dsi = host_to_rcar_mipi_dsi(host);
> +	struct mipi_dsi_packet packet;
> +	u8 payload[16] = { 0 };
> +	u32 status;
> +	int ret;
> +
> +	ret = mipi_dsi_create_packet(&packet, msg);
> +	if (ret)
> +		return ret;
> +
> +	/* Configure LP or HS command transfer. */
> +	rcar_mipi_dsi_write(dsi, TXCMSETR, (msg->flags & MIPI_DSI_MSG_USE_LPM) ?
> +					   TXCMSETR_SPDTYP : 0);

There's no runtime PM in the driver, and the clocks are enabled
externally... So I think we just assume that the IP is running here?
It's not a few times (on other platforms) I've hit an issue with
dsi_host tx being called when the video output is not yet enabled, and
thus the whole IP is off. So, maybe this works, but just a note.

> +	/* Register access mode for RX transfer. */
> +	if (is_rx_xfer)
> +		rcar_mipi_dsi_write(dsi, RXPSETR, 0);
> +
> +	/* Do not use IRQ, poll for completion, the completion is quick. */
> +	rcar_mipi_dsi_write(dsi, TXCMIER, 0);
> +
> +	/*
> +	 * Send the header:
> +	 * header[0] = Virtual Channel + Data Type
> +	 * header[1] = Word Count LSB (LP) or first param (SP)
> +	 * header[2] = Word Count MSB (LP) or second param (SP)
> +	 */
> +	rcar_mipi_dsi_write(dsi, TXCMPHDR,
> +			    (is_tx_long ? TXCMPHDR_FMT : 0) |
> +			    TXCMPHDR_VC(msg->channel) |
> +			    TXCMPHDR_DT(msg->type) |
> +			    TXCMPHDR_DATA1(packet.header[2]) |
> +			    TXCMPHDR_DATA0(packet.header[1]));
> +
> +	if (is_tx_long) {
> +		memcpy(payload, packet.payload,
> +		       min(msg->tx_len, sizeof(payload)));
> +
> +		rcar_mipi_dsi_write(dsi, TXCMPPD0R,
> +				    (payload[3] << 24) | (payload[2] << 16) |
> +				    (payload[1] << 8) | payload[0]);
> +		rcar_mipi_dsi_write(dsi, TXCMPPD1R,
> +				    (payload[7] << 24) | (payload[6] << 16) |
> +				    (payload[5] << 8) | payload[4]);
> +		rcar_mipi_dsi_write(dsi, TXCMPPD2R,
> +				    (payload[11] << 24) | (payload[10] << 16) |
> +				    (payload[9] << 8) | payload[8]);
> +		rcar_mipi_dsi_write(dsi, TXCMPPD3R,
> +				    (payload[15] << 24) | (payload[14] << 16) |
> +				    (payload[13] << 8) | payload[12]);
> +	}
> +
> +	/* Start the transfer, RX with BTA, TX without BTA */
> +	if (is_rx_xfer) {
> +		rcar_mipi_dsi_write(dsi, TXCMCR, TXCMCR_BTAREQ);
> +
> +		ret = read_poll_timeout(rcar_mipi_dsi_read, status,
> +					(status & RXPSR_BTAREQEND),
> +					2000, 10000, false, dsi, RXPSR);
> +	} else {
> +		rcar_mipi_dsi_write(dsi, TXCMCR, TXCMCR_TXREQ);
> +
> +		ret = read_poll_timeout(rcar_mipi_dsi_read, status,
> +					(status & TXCMSR_TXREQEND),
> +					2000, 10000, false, dsi, TXCMSR);
> +	}

Did you check the timeout is big enough? With LP and BTA... Well, it's
only 16 bytes at max. Maybe it's fine. Again, just a note. =)

Does this work when the video stream is on? If yes, then it might take
much longer until the command can be transferred. If not maybe the
function should return an error if the video stream is enabled.

What do these read_poll_timeouts wait, exactly? The first one waits
until the data is sent, and BTA has been done? And the latter waits only
for the data to be sent? Hmm, no... The first must wait until the
peripheral has replied, as there's no wait in the
rcar_mipi_dsi_host_rx_transfer()...

It would be nice to have a short comment what the wait is for.

> +
> +	if (ret < 0) {
> +		dev_err(dsi->dev, "Command transfer timeout (0x%08x)\n",
> +			status);
> +		return ret;
> +	}
> +
> +	return packet.size;
> +}
> +
> +static ssize_t rcar_mipi_dsi_host_rx_transfer(struct mipi_dsi_host *host,
> +					      const struct mipi_dsi_msg *msg)
> +{
> +	struct rcar_mipi_dsi *dsi = host_to_rcar_mipi_dsi(host);
> +	u8 *rx_buf = (u8 *)(msg->rx_buf);
> +	u32 reg, data, status, wc;
> +	int i, ret;
> +
> +	/* RX transfer received data validation and parsing starts here. */
> +	reg = rcar_mipi_dsi_read(dsi, TOSR);
> +	if (reg & TOSR_TATO) {	/* Turn-Around TimeOut. */
> +		/* Clear TATO Turn-Around TimeOut bit. */
> +		rcar_mipi_dsi_write(dsi, TOSR, TOSR_TATO);
> +		return -ETIMEDOUT;
> +	}
> +
> +	reg = rcar_mipi_dsi_read(dsi, RXPSR);
> +
> +	if (msg->flags & MIPI_DSI_MSG_REQ_ACK) {
> +		/* Transfer with zero-length RX */
> +		if (!(reg & RXPSR_RCVACK)) {
> +			/* No ACK on RX response received */
> +			return -EINVAL;
> +		}
> +	} else {
> +		/* Transfer with non-zero-length RX */
> +		if (!(reg & RXPSR_RCVRESP)) {
> +			/* No packet header of RX response received */
> +			return -EINVAL;
> +		}
> +
> +		if (reg & (RXPSR_CRCERR | RXPSR_WCERR | RXPSR_AXIERR | RXPSR_OVRERR)) {
> +			/* Incorrect response payload */
> +			return -ENODATA;
> +		}
> +
> +		data = rcar_mipi_dsi_read(dsi, RXPHDR);
> +		if (data & RXPHDR_FMT) {	/* Long Packet Response */
> +			/* Read Long Packet Response length from packet header. */
> +			wc = data & 0xffff;
> +			if (wc > msg->rx_len) {
> +				dev_warn(dsi->dev,
> +					 "Long Packet Response longer than RX buffer (%d), limited to %ld Bytes\n",
> +					 wc, msg->rx_len);
> +				wc = msg->rx_len;
> +			}
> +
> +			if (wc > 16) {
> +				dev_warn(dsi->dev,
> +					 "Long Packet Response too long (%d), limited to 16 Bytes\n",
> +					 wc);
> +				wc = 16;
> +			}
> +
> +			for (i = 0; i < msg->rx_len; i++) {
> +				if (!(i % 4))
> +					data = rcar_mipi_dsi_read(dsi, RXPPD0R + i);
> +
> +				rx_buf[i] = data & 0xff;
> +				data >>= 8;
> +			}
> +		} else {	/* Short Packet Response */
> +			if (msg->rx_len >= 1)
> +				rx_buf[0] = data & 0xff;
> +			if (msg->rx_len >= 2)
> +				rx_buf[1] = (data >> 8) & 0xff;
> +			if (msg->rx_len >= 3) {
> +				dev_warn(dsi->dev,
> +					 "Expected Short Packet Response too long (%ld), limited to 2 Bytes\n",
> +					 msg->rx_len);
> +			}
> +		}
> +	}
> +
> +	if (reg & RXPSR_RCVAKE) {
> +		/* Acknowledge and Error report received */
> +		return -EFAULT;
> +	}
> +
> +	ret = read_poll_timeout(rcar_mipi_dsi_read, status,
> +				!(status & PPIDL0SR_DIR),
> +				2000, 10000, false, dsi, PPIDL0SR);
> +	if (ret < 0) {
> +		dev_err(dsi->dev, "Command RX DIR timeout (0x%08x)\n", status);
> +		return ret;
> +	}
> +
> +	ret = read_poll_timeout(rcar_mipi_dsi_read, status,
> +				status & PPIDL0SR_STPST,
> +				2000, 10000, false, dsi, PPIDL0SR);
> +	if (ret < 0) {
> +		dev_err(dsi->dev, "Command RX STPST timeout (0x%08x)\n", status);
> +		return ret;
> +	}

Same here, it's not very clear what the waits are for. Aren't we done
already after the tx function finished?

> +
> +	return 0;
> +}
> +
> +static ssize_t rcar_mipi_dsi_host_transfer(struct mipi_dsi_host *host,
> +					   const struct mipi_dsi_msg *msg)
> +{
> +	const bool is_rx_xfer = (msg->flags & MIPI_DSI_MSG_REQ_ACK) || msg->rx_len;
> +	struct rcar_mipi_dsi *dsi = host_to_rcar_mipi_dsi(host);
> +	int ret;
> +
> +	if (msg->tx_len > 16 || msg->rx_len > 16) {
> +		/* ToDo: Implement Memory on AXI bus command mode. */
> +		dev_warn(dsi->dev,
> +			 "Register-based command mode supports only up to 16 Bytes long payload\n");
> +		return -EOPNOTSUPP;
> +	}
> +
> +	ret = rcar_mipi_dsi_host_tx_transfer(host, msg, is_rx_xfer);
> +
> +	/* If TX transfer succeeded and this transfer has RX part. */
> +	if (ret >= 0 && is_rx_xfer) {
> +		ret = rcar_mipi_dsi_host_rx_transfer(host, msg);
> +		if (ret)
> +			return ret;
> +
> +		ret = msg->rx_len;
> +	}
> +
> +	/* Wait a bit between commands */
> +	usleep_range(1000, 2000);

Why wait and wait a bit between what?

 Tomi


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 1/4] drm/rcar-du: dsi: Convert register bits to BIT() macro
  2025-08-12 13:26   ` Tomi Valkeinen
@ 2025-08-12 19:32     ` Marek Vasut
  2025-08-12 20:05       ` Laurent Pinchart
  2025-08-13  7:42       ` Tomi Valkeinen
  0 siblings, 2 replies; 24+ messages in thread
From: Marek Vasut @ 2025-08-12 19:32 UTC (permalink / raw)
  To: Tomi Valkeinen, Marek Vasut, dri-devel
  Cc: David Airlie, Geert Uytterhoeven, Kieran Bingham,
	Laurent Pinchart, Maarten Lankhorst, Magnus Damm, Maxime Ripard,
	Simona Vetter, Thomas Zimmermann, linux-renesas-soc

On 8/12/25 3:26 PM, Tomi Valkeinen wrote:

Hi,

>> diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
>> index a6b276f1d6ee..b3e57217ae63 100644
>> --- a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
>> +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h

[...]

>> @@ -51,11 +51,11 @@
>>   
>>   #define TXVMVPRMSET0R			0x1d0
>>   #define TXVMVPRMSET0R_HSPOL_HIG		(0 << 17)
>> -#define TXVMVPRMSET0R_HSPOL_LOW		(1 << 17)
>> +#define TXVMVPRMSET0R_HSPOL_LOW		BIT(17)
> 
> I'm not sure about this (and below). We have two defines for the HSPOL,
> high and low. If one of them is (x << y), shouldn't the other one be of
> that style too?
It is inconsistent, but one macro describes bit set to 0 and the other 
bit set to 1 (i.e. the actual bit) which is converted to BIT(n) macro. I 
would be tempted to remove the bits set to 0, that's probably the real 
discussion that should happen here. But that would also be a much bigger 
patch. What do you think ?

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 2/4] drm/rcar-du: dsi: Remove fixed PPI lane count setup
  2025-08-12 13:30     ` Tomi Valkeinen
@ 2025-08-12 19:35       ` Marek Vasut
  2025-08-13  7:34         ` Tomi Valkeinen
  0 siblings, 1 reply; 24+ messages in thread
From: Marek Vasut @ 2025-08-12 19:35 UTC (permalink / raw)
  To: Tomi Valkeinen, Marek Vasut, dri-devel
  Cc: David Airlie, Geert Uytterhoeven, Kieran Bingham,
	Laurent Pinchart, Maarten Lankhorst, Magnus Damm, Maxime Ripard,
	Simona Vetter, Thomas Zimmermann, linux-renesas-soc

On 8/12/25 3:30 PM, Tomi Valkeinen wrote:

Hi,

>>> diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
>>> index b3e57217ae63..cefa7e92b5b8 100644
>>> --- a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
>>> +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
>>> @@ -80,10 +80,7 @@
>>>    * PHY-Protocol Interface (PPI) Registers
>>>    */
>>>   #define PPISETR				0x700
>>> -#define PPISETR_DLEN_0			(0x1 << 0)
>>> -#define PPISETR_DLEN_1			(0x3 << 0)
>>> -#define PPISETR_DLEN_2			(0x7 << 0)
>>> -#define PPISETR_DLEN_3			(0xf << 0)
>>> +#define PPISETR_DLEN_MASK		(0xf << 0)
>>>   #define PPISETR_CLEN			BIT(8)
>>
>> Looks fine, but do you know what the TXSETR register does? It also has
>> LANECNT, but I don't see the driver touching that register at all.
>> TXSETR:LANECNT default value is 3 (4 lanes), which matches with the old
>> hardcoded behavior for PPISETR... So I wonder if that register should
>> also be set?
> 
> Ah, never mind, I now saw the patch 3 =). But should it be before patch
> 2? Hmm, I guess that ordering is no better. Should they be combined into
> "support 1,2,3 datalanes" patch?
I think each patch fixes slighly different issue, even if the issues are 
related. I tried to keep the issue description in each patch commit 
message for posterity. I can squash them if you think that's better, I 
don't mind either way.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 1/4] drm/rcar-du: dsi: Convert register bits to BIT() macro
  2025-08-12 19:32     ` Marek Vasut
@ 2025-08-12 20:05       ` Laurent Pinchart
  2025-08-13  6:59         ` Geert Uytterhoeven
  2025-08-13  7:42       ` Tomi Valkeinen
  1 sibling, 1 reply; 24+ messages in thread
From: Laurent Pinchart @ 2025-08-12 20:05 UTC (permalink / raw)
  To: Marek Vasut
  Cc: Tomi Valkeinen, Marek Vasut, dri-devel, David Airlie,
	Geert Uytterhoeven, Kieran Bingham, Maarten Lankhorst,
	Magnus Damm, Maxime Ripard, Simona Vetter, Thomas Zimmermann,
	linux-renesas-soc

On Tue, Aug 12, 2025 at 09:32:36PM +0200, Marek Vasut wrote:
> On 8/12/25 3:26 PM, Tomi Valkeinen wrote:
> 
> Hi,
> 
> >> diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
> >> index a6b276f1d6ee..b3e57217ae63 100644
> >> --- a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
> >> +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
> 
> [...]
> 
> >> @@ -51,11 +51,11 @@
> >>   
> >>   #define TXVMVPRMSET0R			0x1d0
> >>   #define TXVMVPRMSET0R_HSPOL_HIG		(0 << 17)
> >> -#define TXVMVPRMSET0R_HSPOL_LOW		(1 << 17)
> >> +#define TXVMVPRMSET0R_HSPOL_LOW		BIT(17)
> > 
> > I'm not sure about this (and below). We have two defines for the HSPOL,
> > high and low. If one of them is (x << y), shouldn't the other one be of
> > that style too?
> 
> It is inconsistent, but one macro describes bit set to 0 and the other 
> bit set to 1 (i.e. the actual bit) which is converted to BIT(n) macro. I 
> would be tempted to remove the bits set to 0, that's probably the real 
> discussion that should happen here. But that would also be a much bigger 
> patch. What do you think ?

For what it's worth, for single-bit register fields, I usually define a
single macro. I understand it's usually a coding style preference.

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 1/4] drm/rcar-du: dsi: Convert register bits to BIT() macro
  2025-08-12 20:05       ` Laurent Pinchart
@ 2025-08-13  6:59         ` Geert Uytterhoeven
  2025-08-13 20:47           ` Marek Vasut
  0 siblings, 1 reply; 24+ messages in thread
From: Geert Uytterhoeven @ 2025-08-13  6:59 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Marek Vasut, Tomi Valkeinen, Marek Vasut, dri-devel, David Airlie,
	Geert Uytterhoeven, Kieran Bingham, Maarten Lankhorst,
	Magnus Damm, Maxime Ripard, Simona Vetter, Thomas Zimmermann,
	linux-renesas-soc

On Tue, 12 Aug 2025 at 22:05, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
> On Tue, Aug 12, 2025 at 09:32:36PM +0200, Marek Vasut wrote:
> > On 8/12/25 3:26 PM, Tomi Valkeinen wrote:
> > >> diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
> > >> index a6b276f1d6ee..b3e57217ae63 100644
> > >> --- a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
> > >> +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
> >
> > [...]
> >
> > >> @@ -51,11 +51,11 @@
> > >>
> > >>   #define TXVMVPRMSET0R                    0x1d0
> > >>   #define TXVMVPRMSET0R_HSPOL_HIG          (0 << 17)
> > >> -#define TXVMVPRMSET0R_HSPOL_LOW           (1 << 17)
> > >> +#define TXVMVPRMSET0R_HSPOL_LOW           BIT(17)
> > >
> > > I'm not sure about this (and below). We have two defines for the HSPOL,
> > > high and low. If one of them is (x << y), shouldn't the other one be of
> > > that style too?
> >
> > It is inconsistent, but one macro describes bit set to 0 and the other
> > bit set to 1 (i.e. the actual bit) which is converted to BIT(n) macro. I
> > would be tempted to remove the bits set to 0, that's probably the real
> > discussion that should happen here. But that would also be a much bigger
> > patch. What do you think ?
>
> For what it's worth, for single-bit register fields, I usually define a
> single macro. I understand it's usually a coding style preference.

An alternative would be to define 3 macros:

    #define TXVMVPRMSET0R_HSPOL        BIT(17)
    #define TXVMVPRMSET0R_HSPOL_HIG    0
    #define TXVMVPRMSET0R_HSPOL_LOW    1

and use FIELD_PREP(TXVMVPRMSET0R_HSPOL, TXVMVPRMSET0R_HSPOL_{HIG,LOW}).
But I agree a single definition is fine for a single-bit register field.

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 2/4] drm/rcar-du: dsi: Remove fixed PPI lane count setup
  2025-08-12 19:35       ` Marek Vasut
@ 2025-08-13  7:34         ` Tomi Valkeinen
  2025-08-13 21:06           ` Marek Vasut
  0 siblings, 1 reply; 24+ messages in thread
From: Tomi Valkeinen @ 2025-08-13  7:34 UTC (permalink / raw)
  To: Marek Vasut, Marek Vasut, dri-devel
  Cc: David Airlie, Geert Uytterhoeven, Kieran Bingham,
	Laurent Pinchart, Maarten Lankhorst, Magnus Damm, Maxime Ripard,
	Simona Vetter, Thomas Zimmermann, linux-renesas-soc

Hi,

On 12/08/2025 22:35, Marek Vasut wrote:
> On 8/12/25 3:30 PM, Tomi Valkeinen wrote:
> 
> Hi,
> 
>>>> diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h b/
>>>> drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
>>>> index b3e57217ae63..cefa7e92b5b8 100644
>>>> --- a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
>>>> +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
>>>> @@ -80,10 +80,7 @@
>>>>    * PHY-Protocol Interface (PPI) Registers
>>>>    */
>>>>   #define PPISETR                0x700
>>>> -#define PPISETR_DLEN_0            (0x1 << 0)
>>>> -#define PPISETR_DLEN_1            (0x3 << 0)
>>>> -#define PPISETR_DLEN_2            (0x7 << 0)
>>>> -#define PPISETR_DLEN_3            (0xf << 0)
>>>> +#define PPISETR_DLEN_MASK        (0xf << 0)
>>>>   #define PPISETR_CLEN            BIT(8)
>>>
>>> Looks fine, but do you know what the TXSETR register does? It also has
>>> LANECNT, but I don't see the driver touching that register at all.
>>> TXSETR:LANECNT default value is 3 (4 lanes), which matches with the old
>>> hardcoded behavior for PPISETR... So I wonder if that register should
>>> also be set?
>>
>> Ah, never mind, I now saw the patch 3 =). But should it be before patch
>> 2? Hmm, I guess that ordering is no better. Should they be combined into
>> "support 1,2,3 datalanes" patch?
> I think each patch fixes slighly different issue, even if the issues are
> related. I tried to keep the issue description in each patch commit
> message for posterity. I can squash them if you think that's better, I
> don't mind either way.

I was thinking about this the user's or backporting point of view.
Neither of the commits (clearly) say that they add support for 1/2/3
lane modes. You say they "fix", but they're not quite fixes either. The
patch 3 could be considered a fix, but at the moment it just writes the
default value to the register, so no point in marking it as a fix to be
backported.

So... I don't have a strong opinion, but I think a single patch that
adds support to 1, 2,3 lanes makes most sense.

 Tomi


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 1/4] drm/rcar-du: dsi: Convert register bits to BIT() macro
  2025-08-12 19:32     ` Marek Vasut
  2025-08-12 20:05       ` Laurent Pinchart
@ 2025-08-13  7:42       ` Tomi Valkeinen
  2025-08-13 20:51         ` Marek Vasut
  1 sibling, 1 reply; 24+ messages in thread
From: Tomi Valkeinen @ 2025-08-13  7:42 UTC (permalink / raw)
  To: Marek Vasut, Marek Vasut, dri-devel
  Cc: David Airlie, Geert Uytterhoeven, Kieran Bingham,
	Laurent Pinchart, Maarten Lankhorst, Magnus Damm, Maxime Ripard,
	Simona Vetter, Thomas Zimmermann, linux-renesas-soc

Hi,

On 12/08/2025 22:32, Marek Vasut wrote:
> On 8/12/25 3:26 PM, Tomi Valkeinen wrote:
> 
> Hi,
> 
>>> diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h b/
>>> drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
>>> index a6b276f1d6ee..b3e57217ae63 100644
>>> --- a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
>>> +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
> 
> [...]
> 
>>> @@ -51,11 +51,11 @@
>>>     #define TXVMVPRMSET0R            0x1d0
>>>   #define TXVMVPRMSET0R_HSPOL_HIG        (0 << 17)
>>> -#define TXVMVPRMSET0R_HSPOL_LOW        (1 << 17)
>>> +#define TXVMVPRMSET0R_HSPOL_LOW        BIT(17)
>>
>> I'm not sure about this (and below). We have two defines for the HSPOL,
>> high and low. If one of them is (x << y), shouldn't the other one be of
>> that style too?
> It is inconsistent, but one macro describes bit set to 0 and the other
> bit set to 1 (i.e. the actual bit) which is converted to BIT(n) macro. I
> would be tempted to remove the bits set to 0, that's probably the real
> discussion that should happen here. But that would also be a much bigger
> patch. What do you think ?

In my mind if you have defines for both HIGH and LOW, you have a
bitfield with a value, the values being 0 and 1, and for values you use
(0 << 17) and (1 << 17). It just happens here that the bitfield value is
only one bit long.

But I'm also fine with having only "TXVMVPRMSET0R_HSPOL_LOW
BIT(17)", and then the interpretation is that we have a enable/disable
style bit.

In the end, I'm fine with any of these, or the current one in the patch.
Although the current one does rub me the wrong way just enough for me to
comment about it =).

 Tomi


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 1/4] drm/rcar-du: dsi: Convert register bits to BIT() macro
  2025-08-13  6:59         ` Geert Uytterhoeven
@ 2025-08-13 20:47           ` Marek Vasut
  0 siblings, 0 replies; 24+ messages in thread
From: Marek Vasut @ 2025-08-13 20:47 UTC (permalink / raw)
  To: Geert Uytterhoeven, Laurent Pinchart
  Cc: Tomi Valkeinen, Marek Vasut, dri-devel, David Airlie,
	Geert Uytterhoeven, Kieran Bingham, Maarten Lankhorst,
	Magnus Damm, Maxime Ripard, Simona Vetter, Thomas Zimmermann,
	linux-renesas-soc

On 8/13/25 8:59 AM, Geert Uytterhoeven wrote:
> On Tue, 12 Aug 2025 at 22:05, Laurent Pinchart
> <laurent.pinchart@ideasonboard.com> wrote:
>> On Tue, Aug 12, 2025 at 09:32:36PM +0200, Marek Vasut wrote:
>>> On 8/12/25 3:26 PM, Tomi Valkeinen wrote:
>>>>> diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
>>>>> index a6b276f1d6ee..b3e57217ae63 100644
>>>>> --- a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
>>>>> +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
>>>
>>> [...]
>>>
>>>>> @@ -51,11 +51,11 @@
>>>>>
>>>>>    #define TXVMVPRMSET0R                    0x1d0
>>>>>    #define TXVMVPRMSET0R_HSPOL_HIG          (0 << 17)
>>>>> -#define TXVMVPRMSET0R_HSPOL_LOW           (1 << 17)
>>>>> +#define TXVMVPRMSET0R_HSPOL_LOW           BIT(17)
>>>>
>>>> I'm not sure about this (and below). We have two defines for the HSPOL,
>>>> high and low. If one of them is (x << y), shouldn't the other one be of
>>>> that style too?
>>>
>>> It is inconsistent, but one macro describes bit set to 0 and the other
>>> bit set to 1 (i.e. the actual bit) which is converted to BIT(n) macro. I
>>> would be tempted to remove the bits set to 0, that's probably the real
>>> discussion that should happen here. But that would also be a much bigger
>>> patch. What do you think ?
>>
>> For what it's worth, for single-bit register fields, I usually define a
>> single macro. I understand it's usually a coding style preference.
> 
> An alternative would be to define 3 macros:
> 
>      #define TXVMVPRMSET0R_HSPOL        BIT(17)
>      #define TXVMVPRMSET0R_HSPOL_HIG    0
>      #define TXVMVPRMSET0R_HSPOL_LOW    1
> 
> and use FIELD_PREP(TXVMVPRMSET0R_HSPOL, TXVMVPRMSET0R_HSPOL_{HIG,LOW}).
> But I agree a single definition is fine for a single-bit register field.

I think single bit macro for single register bit is just about the right 
amount of complexity .

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 1/4] drm/rcar-du: dsi: Convert register bits to BIT() macro
  2025-08-13  7:42       ` Tomi Valkeinen
@ 2025-08-13 20:51         ` Marek Vasut
  0 siblings, 0 replies; 24+ messages in thread
From: Marek Vasut @ 2025-08-13 20:51 UTC (permalink / raw)
  To: Tomi Valkeinen, Marek Vasut, dri-devel
  Cc: David Airlie, Geert Uytterhoeven, Kieran Bingham,
	Laurent Pinchart, Maarten Lankhorst, Magnus Damm, Maxime Ripard,
	Simona Vetter, Thomas Zimmermann, linux-renesas-soc

On 8/13/25 9:42 AM, Tomi Valkeinen wrote:

Hi,

>>>> diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h b/
>>>> drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
>>>> index a6b276f1d6ee..b3e57217ae63 100644
>>>> --- a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
>>>> +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
>>
>> [...]
>>
>>>> @@ -51,11 +51,11 @@
>>>>      #define TXVMVPRMSET0R            0x1d0
>>>>    #define TXVMVPRMSET0R_HSPOL_HIG        (0 << 17)
>>>> -#define TXVMVPRMSET0R_HSPOL_LOW        (1 << 17)
>>>> +#define TXVMVPRMSET0R_HSPOL_LOW        BIT(17)
>>>
>>> I'm not sure about this (and below). We have two defines for the HSPOL,
>>> high and low. If one of them is (x << y), shouldn't the other one be of
>>> that style too?
>> It is inconsistent, but one macro describes bit set to 0 and the other
>> bit set to 1 (i.e. the actual bit) which is converted to BIT(n) macro. I
>> would be tempted to remove the bits set to 0, that's probably the real
>> discussion that should happen here. But that would also be a much bigger
>> patch. What do you think ?
> 
> In my mind if you have defines for both HIGH and LOW, you have a
> bitfield with a value, the values being 0 and 1, and for values you use
> (0 << 17) and (1 << 17). It just happens here that the bitfield value is
> only one bit long.

I am not a big fan of that, it seems overcomplicated, hence this clean up.

> But I'm also fine with having only "TXVMVPRMSET0R_HSPOL_LOW
> BIT(17)", and then the interpretation is that we have a enable/disable
> style bit.

I think this would work, yes.

> In the end, I'm fine with any of these, or the current one in the patch.
> Although the current one does rub me the wrong way just enough for me to
> comment about it =).
I can also drop this patch from the series and do full conversion of the 
driver to TXVMVPRMSET0R_HSPOL_LOW BIT(17) style afterward. This patch is 
not strictly necessary for the follow up patches.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 2/4] drm/rcar-du: dsi: Remove fixed PPI lane count setup
  2025-08-13  7:34         ` Tomi Valkeinen
@ 2025-08-13 21:06           ` Marek Vasut
  2025-08-14  5:39             ` Tomi Valkeinen
  0 siblings, 1 reply; 24+ messages in thread
From: Marek Vasut @ 2025-08-13 21:06 UTC (permalink / raw)
  To: Tomi Valkeinen, Marek Vasut, dri-devel
  Cc: David Airlie, Geert Uytterhoeven, Kieran Bingham,
	Laurent Pinchart, Maarten Lankhorst, Magnus Damm, Maxime Ripard,
	Simona Vetter, Thomas Zimmermann, linux-renesas-soc

On 8/13/25 9:34 AM, Tomi Valkeinen wrote:

Hi,

>>>>> diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h b/
>>>>> drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
>>>>> index b3e57217ae63..cefa7e92b5b8 100644
>>>>> --- a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
>>>>> +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
>>>>> @@ -80,10 +80,7 @@
>>>>>     * PHY-Protocol Interface (PPI) Registers
>>>>>     */
>>>>>    #define PPISETR                0x700
>>>>> -#define PPISETR_DLEN_0            (0x1 << 0)
>>>>> -#define PPISETR_DLEN_1            (0x3 << 0)
>>>>> -#define PPISETR_DLEN_2            (0x7 << 0)
>>>>> -#define PPISETR_DLEN_3            (0xf << 0)
>>>>> +#define PPISETR_DLEN_MASK        (0xf << 0)
>>>>>    #define PPISETR_CLEN            BIT(8)
>>>>
>>>> Looks fine, but do you know what the TXSETR register does? It also has
>>>> LANECNT, but I don't see the driver touching that register at all.
>>>> TXSETR:LANECNT default value is 3 (4 lanes), which matches with the old
>>>> hardcoded behavior for PPISETR... So I wonder if that register should
>>>> also be set?
>>>
>>> Ah, never mind, I now saw the patch 3 =). But should it be before patch
>>> 2? Hmm, I guess that ordering is no better. Should they be combined into
>>> "support 1,2,3 datalanes" patch?
>> I think each patch fixes slighly different issue, even if the issues are
>> related. I tried to keep the issue description in each patch commit
>> message for posterity. I can squash them if you think that's better, I
>> don't mind either way.
> 
> I was thinking about this the user's or backporting point of view.
> Neither of the commits (clearly) say that they add support for 1/2/3
> lane modes.

The 1/2/3 lane mode was already implemented in the driver, except it was 
broken.

> You say they "fix", but they're not quite fixes either. The
> patch 3 could be considered a fix, but at the moment it just writes the
> default value to the register, so no point in marking it as a fix to be
> backported.

3/4 does write the DSI lane count into TXSETR , not the default value.

> So... I don't have a strong opinion, but I think a single patch that
> adds support to 1, 2,3 lanes makes most sense.

Lemme send a single patch with Fixes tag then. The combined patch does 
not look too great though.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 2/4] drm/rcar-du: dsi: Remove fixed PPI lane count setup
  2025-08-13 21:06           ` Marek Vasut
@ 2025-08-14  5:39             ` Tomi Valkeinen
  2025-08-17 22:46               ` Marek Vasut
  0 siblings, 1 reply; 24+ messages in thread
From: Tomi Valkeinen @ 2025-08-14  5:39 UTC (permalink / raw)
  To: Marek Vasut, Marek Vasut, dri-devel
  Cc: David Airlie, Geert Uytterhoeven, Kieran Bingham,
	Laurent Pinchart, Maarten Lankhorst, Magnus Damm, Maxime Ripard,
	Simona Vetter, Thomas Zimmermann, linux-renesas-soc

Hi,

On 14/08/2025 00:06, Marek Vasut wrote:
> On 8/13/25 9:34 AM, Tomi Valkeinen wrote:
> 
> Hi,
> 
>>>>>> diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h b/
>>>>>> drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
>>>>>> index b3e57217ae63..cefa7e92b5b8 100644
>>>>>> --- a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
>>>>>> +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
>>>>>> @@ -80,10 +80,7 @@
>>>>>>     * PHY-Protocol Interface (PPI) Registers
>>>>>>     */
>>>>>>    #define PPISETR                0x700
>>>>>> -#define PPISETR_DLEN_0            (0x1 << 0)
>>>>>> -#define PPISETR_DLEN_1            (0x3 << 0)
>>>>>> -#define PPISETR_DLEN_2            (0x7 << 0)
>>>>>> -#define PPISETR_DLEN_3            (0xf << 0)
>>>>>> +#define PPISETR_DLEN_MASK        (0xf << 0)
>>>>>>    #define PPISETR_CLEN            BIT(8)
>>>>>
>>>>> Looks fine, but do you know what the TXSETR register does? It also has
>>>>> LANECNT, but I don't see the driver touching that register at all.
>>>>> TXSETR:LANECNT default value is 3 (4 lanes), which matches with the
>>>>> old
>>>>> hardcoded behavior for PPISETR... So I wonder if that register should
>>>>> also be set?
>>>>
>>>> Ah, never mind, I now saw the patch 3 =). But should it be before patch
>>>> 2? Hmm, I guess that ordering is no better. Should they be combined
>>>> into
>>>> "support 1,2,3 datalanes" patch?
>>> I think each patch fixes slighly different issue, even if the issues are
>>> related. I tried to keep the issue description in each patch commit
>>> message for posterity. I can squash them if you think that's better, I
>>> don't mind either way.
>>
>> I was thinking about this the user's or backporting point of view.
>> Neither of the commits (clearly) say that they add support for 1/2/3
>> lane modes.
> 
> The 1/2/3 lane mode was already implemented in the driver, except it was
> broken.

If it never worked, was it broken or not implemented? How much code the
original driver must have for the feature to have the feature
"implemented, just broken"? If it reads the num lanes from the DT, and
allows the driver to probe with 1-4 lanes, is it then "implemented, but
broken"? Or does the driver have to have a clear intent on having the
feature (even if it doesn't work) for it to be implemented?

I'm not trying to be annoying here, and I'm fine with the new patch you
sent. I bring this topic up as I just had a similar discussion in a
thread for another patch series, and the answer is not clear to me.

stable-kernel-rules.rst doesn't really cover this case, so, afaics,
someone could argue that this (well, the new one you sent) is not valid
stable patch: it doesn't fix a crash/hang/etc, it adds support for more
lane setups.

In this particular case I'm fine calling this a fix, and backporting to
stable, as the patch is such a small one and "obviously correct" (as
stable-kernel-rules.rst says) because with the only working lane setup,
4-lanes, we can easily see that the values written to registers are
identical to default/old values.

Still, if someone has feedback on how to approach this question, I
wouldn't mind hearing the thoughts =).

>> You say they "fix", but they're not quite fixes either. The
>> patch 3 could be considered a fix, but at the moment it just writes the
>> default value to the register, so no point in marking it as a fix to be
>> backported.
> 
> 3/4 does write the DSI lane count into TXSETR , not the default value.

I meant that as only the 4-lane mode works, I must assume all the users
use 4-lane mode. Thus with patch 3, a value identical to the default
value gets written, as everyone uses 4 lanes. So, if it's backported to
kernels where everyone uses 4 lanes, it won't change anything.

 Tomi


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 2/4] drm/rcar-du: dsi: Remove fixed PPI lane count setup
  2025-08-14  5:39             ` Tomi Valkeinen
@ 2025-08-17 22:46               ` Marek Vasut
  0 siblings, 0 replies; 24+ messages in thread
From: Marek Vasut @ 2025-08-17 22:46 UTC (permalink / raw)
  To: Tomi Valkeinen, Marek Vasut, dri-devel
  Cc: David Airlie, Geert Uytterhoeven, Kieran Bingham,
	Laurent Pinchart, Maarten Lankhorst, Magnus Damm, Maxime Ripard,
	Simona Vetter, Thomas Zimmermann, linux-renesas-soc

On 8/14/25 7:39 AM, Tomi Valkeinen wrote:

Hello Tomi,

>> The 1/2/3 lane mode was already implemented in the driver, except it was
>> broken.
> 
> If it never worked, was it broken or not implemented? How much code the
> original driver must have for the feature to have the feature
> "implemented, just broken"?

I believe the code was all there, and the lane count could be 
configured, it simply never worked. That's why I think the lane count 
was implemented, but broken.

> If it reads the num lanes from the DT, and
> allows the driver to probe with 1-4 lanes, is it then "implemented, but
> broken"? Or does the driver have to have a clear intent on having the
> feature (even if it doesn't work) for it to be implemented?

If it was not implemented, then the lane count from DT should have been 
checked and if it was != 4, such configuration should have been rejected.

> I'm not trying to be annoying here, and I'm fine with the new patch you
> sent. I bring this topic up as I just had a similar discussion in a
> thread for another patch series, and the answer is not clear to me.
> 
> stable-kernel-rules.rst doesn't really cover this case, so, afaics,
> someone could argue that this (well, the new one you sent) is not valid
> stable patch: it doesn't fix a crash/hang/etc, it adds support for more
> lane setups.
> 
> In this particular case I'm fine calling this a fix, and backporting to
> stable, as the patch is such a small one and "obviously correct" (as
> stable-kernel-rules.rst says) because with the only working lane setup,
> 4-lanes, we can easily see that the values written to registers are
> identical to default/old values.
> 
> Still, if someone has feedback on how to approach this question, I
> wouldn't mind hearing the thoughts =).

See above why I think this is a fix, maybe it helps.

>>> You say they "fix", but they're not quite fixes either. The
>>> patch 3 could be considered a fix, but at the moment it just writes the
>>> default value to the register, so no point in marking it as a fix to be
>>> backported.
>>
>> 3/4 does write the DSI lane count into TXSETR , not the default value.
> 
> I meant that as only the 4-lane mode works, I must assume all the users
> use 4-lane mode.

Yes, that is currently the case.

> Thus with patch 3, a value identical to the default
> value gets written, as everyone uses 4 lanes. So, if it's backported to
> kernels where everyone uses 4 lanes, it won't change anything.
Correct.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 4/4] drm/rcar-du: dsi: Implement DSI command support
  2025-08-12 14:36   ` Tomi Valkeinen
@ 2025-08-17 23:40     ` Marek Vasut
  2025-08-18  7:20       ` Tomi Valkeinen
  0 siblings, 1 reply; 24+ messages in thread
From: Marek Vasut @ 2025-08-17 23:40 UTC (permalink / raw)
  To: Tomi Valkeinen, dri-devel
  Cc: David Airlie, Geert Uytterhoeven, Kieran Bingham,
	Laurent Pinchart, Maarten Lankhorst, Magnus Damm, Maxime Ripard,
	Simona Vetter, Thomas Zimmermann, linux-renesas-soc

On 8/12/25 4:36 PM, Tomi Valkeinen wrote:

Hello Tomi,

> On 08/06/2025 17:24, Marek Vasut wrote:
>> Implement support for DSI command transfer mode. Transmission of both Short
> 
> I constantly kept reading "DSI command mode support". So I was quite
> confused for a bit =). Maybe avoid the use of "mode" with "DSI command".

I dropped the "mode" in V3.

[...]

>> +static ssize_t rcar_mipi_dsi_host_tx_transfer(struct mipi_dsi_host *host,
>> +					      const struct mipi_dsi_msg *msg,
>> +					      bool is_rx_xfer)
>> +{
>> +	const bool is_tx_long = mipi_dsi_packet_format_is_long(msg->type);
>> +	struct rcar_mipi_dsi *dsi = host_to_rcar_mipi_dsi(host);
>> +	struct mipi_dsi_packet packet;
>> +	u8 payload[16] = { 0 };
>> +	u32 status;
>> +	int ret;
>> +
>> +	ret = mipi_dsi_create_packet(&packet, msg);
>> +	if (ret)
>> +		return ret;
>> +
>> +	/* Configure LP or HS command transfer. */
>> +	rcar_mipi_dsi_write(dsi, TXCMSETR, (msg->flags & MIPI_DSI_MSG_USE_LPM) ?
>> +					   TXCMSETR_SPDTYP : 0);
> 
> There's no runtime PM in the driver, and the clocks are enabled
> externally... So I think we just assume that the IP is running here?

Correct.

[...]

>> +	/* Start the transfer, RX with BTA, TX without BTA */
>> +	if (is_rx_xfer) {
>> +		rcar_mipi_dsi_write(dsi, TXCMCR, TXCMCR_BTAREQ);
>> +
>> +		ret = read_poll_timeout(rcar_mipi_dsi_read, status,
>> +					(status & RXPSR_BTAREQEND),
>> +					2000, 10000, false, dsi, RXPSR);
>> +	} else {
>> +		rcar_mipi_dsi_write(dsi, TXCMCR, TXCMCR_TXREQ);
>> +
>> +		ret = read_poll_timeout(rcar_mipi_dsi_read, status,
>> +					(status & TXCMSR_TXREQEND),
>> +					2000, 10000, false, dsi, TXCMSR);
>> +	}
> 
> Did you check the timeout is big enough? With LP and BTA... Well, it's
> only 16 bytes at max. Maybe it's fine. Again, just a note. =)

I did check it with the only hardware I had available which needs this 
command mode so far, the RPi Display 2 using ILI9881 DSI-to-TCON .

> Does this work when the video stream is on?

That is untested, the ILI9881 only uses command mode during 
initialization, before it switches video mode on.

> If yes, then it might take
> much longer until the command can be transferred.

Do you know the upper limit , is that one or two frame times ?

> If not maybe the
> function should return an error if the video stream is enabled.

I haven't seen any drivers special casing that, I'd prefer to increase 
the timeouts. For V3, I'll update the timeout to 50ms , which is about 3 
frame times.

> What do these read_poll_timeouts wait, exactly? The first one waits
> until the data is sent, and BTA has been done? And the latter waits only
> for the data to be sent? Hmm, no... The first must wait until the
> peripheral has replied, as there's no wait in the
> rcar_mipi_dsi_host_rx_transfer()...

First one is transmit+BTA+receive , second one is only transmit .

> It would be nice to have a short comment what the wait is for.

Will do in V3.

[...]

>> +	ret = read_poll_timeout(rcar_mipi_dsi_read, status,
>> +				status & PPIDL0SR_STPST,
>> +				2000, 10000, false, dsi, PPIDL0SR);
>> +	if (ret < 0) {
>> +		dev_err(dsi->dev, "Command RX STPST timeout (0x%08x)\n", status);
>> +		return ret;
>> +	}
> 
> Same here, it's not very clear what the waits are for. Aren't we done
> already after the tx function finished?

First one waits for bus handover to host processor to complete, the 
second one (STPST) waits for data lane to enter LP11 stop state .

>> +
>> +	return 0;
>> +}
>> +
>> +static ssize_t rcar_mipi_dsi_host_transfer(struct mipi_dsi_host *host,
>> +					   const struct mipi_dsi_msg *msg)
>> +{
>> +	const bool is_rx_xfer = (msg->flags & MIPI_DSI_MSG_REQ_ACK) || msg->rx_len;
>> +	struct rcar_mipi_dsi *dsi = host_to_rcar_mipi_dsi(host);
>> +	int ret;
>> +
>> +	if (msg->tx_len > 16 || msg->rx_len > 16) {
>> +		/* ToDo: Implement Memory on AXI bus command mode. */
>> +		dev_warn(dsi->dev,
>> +			 "Register-based command mode supports only up to 16 Bytes long payload\n");
>> +		return -EOPNOTSUPP;
>> +	}
>> +
>> +	ret = rcar_mipi_dsi_host_tx_transfer(host, msg, is_rx_xfer);
>> +
>> +	/* If TX transfer succeeded and this transfer has RX part. */
>> +	if (ret >= 0 && is_rx_xfer) {
>> +		ret = rcar_mipi_dsi_host_rx_transfer(host, msg);
>> +		if (ret)
>> +			return ret;
>> +
>> +		ret = msg->rx_len;
>> +	}
>> +
>> +	/* Wait a bit between commands */
>> +	usleep_range(1000, 2000);
> 
> Why wait and wait a bit between what?
The consecutive command transmission was unreliable unless there was a 
slight delay between the consecutive commands. Hence this delay.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 4/4] drm/rcar-du: dsi: Implement DSI command support
  2025-08-17 23:40     ` Marek Vasut
@ 2025-08-18  7:20       ` Tomi Valkeinen
  2025-08-31 18:57         ` Marek Vasut
  0 siblings, 1 reply; 24+ messages in thread
From: Tomi Valkeinen @ 2025-08-18  7:20 UTC (permalink / raw)
  To: Marek Vasut, dri-devel
  Cc: David Airlie, Geert Uytterhoeven, Kieran Bingham,
	Laurent Pinchart, Maarten Lankhorst, Magnus Damm, Maxime Ripard,
	Simona Vetter, Thomas Zimmermann, linux-renesas-soc

Hi,

On 18/08/2025 02:40, Marek Vasut wrote:
> On 8/12/25 4:36 PM, Tomi Valkeinen wrote:
> 
> Hello Tomi,
> 
>> On 08/06/2025 17:24, Marek Vasut wrote:
>>> Implement support for DSI command transfer mode. Transmission of both
>>> Short
>>
>> I constantly kept reading "DSI command mode support". So I was quite
>> confused for a bit =). Maybe avoid the use of "mode" with "DSI command".
> 
> I dropped the "mode" in V3.
> 
> [...]
> 
>>> +static ssize_t rcar_mipi_dsi_host_tx_transfer(struct mipi_dsi_host
>>> *host,
>>> +                          const struct mipi_dsi_msg *msg,
>>> +                          bool is_rx_xfer)
>>> +{
>>> +    const bool is_tx_long = mipi_dsi_packet_format_is_long(msg->type);
>>> +    struct rcar_mipi_dsi *dsi = host_to_rcar_mipi_dsi(host);
>>> +    struct mipi_dsi_packet packet;
>>> +    u8 payload[16] = { 0 };
>>> +    u32 status;
>>> +    int ret;
>>> +
>>> +    ret = mipi_dsi_create_packet(&packet, msg);
>>> +    if (ret)
>>> +        return ret;
>>> +
>>> +    /* Configure LP or HS command transfer. */
>>> +    rcar_mipi_dsi_write(dsi, TXCMSETR, (msg->flags &
>>> MIPI_DSI_MSG_USE_LPM) ?
>>> +                       TXCMSETR_SPDTYP : 0);
>>
>> There's no runtime PM in the driver, and the clocks are enabled
>> externally... So I think we just assume that the IP is running here?
> 
> Correct.
> 
> [...]
> 
>>> +    /* Start the transfer, RX with BTA, TX without BTA */
>>> +    if (is_rx_xfer) {
>>> +        rcar_mipi_dsi_write(dsi, TXCMCR, TXCMCR_BTAREQ);
>>> +
>>> +        ret = read_poll_timeout(rcar_mipi_dsi_read, status,
>>> +                    (status & RXPSR_BTAREQEND),
>>> +                    2000, 10000, false, dsi, RXPSR);
>>> +    } else {
>>> +        rcar_mipi_dsi_write(dsi, TXCMCR, TXCMCR_TXREQ);
>>> +
>>> +        ret = read_poll_timeout(rcar_mipi_dsi_read, status,
>>> +                    (status & TXCMSR_TXREQEND),
>>> +                    2000, 10000, false, dsi, TXCMSR);
>>> +    }
>>
>> Did you check the timeout is big enough? With LP and BTA... Well, it's
>> only 16 bytes at max. Maybe it's fine. Again, just a note. =)
> 
> I did check it with the only hardware I had available which needs this
> command mode so far, the RPi Display 2 using ILI9881 DSI-to-TCON .

Don't call it "command mode" ;).

>> Does this work when the video stream is on?
> 
> That is untested, the ILI9881 only uses command mode during
> initialization, before it switches video mode on.
> 
>> If yes, then it might take
>> much longer until the command can be transferred.
> 
> Do you know the upper limit , is that one or two frame times ?

If using DSI video mode and the stream is on, the DSI TX has to
interleave the commands either to the line blanking or frame blanking.
Usually this is configurable in the DSI TX (if the chip can do
interleaving).

A read command will be the most difficult to interleave, as it takes
more time with the BTA and reply.

I think the worst case is one frame delay (next vblank).

>> If not maybe the
>> function should return an error if the video stream is enabled.
> 
> I haven't seen any drivers special casing that, I'd prefer to increase
> the timeouts. For V3, I'll update the timeout to 50ms , which is about 3
> frame times.

If the docs have no word about interleaving the commands and there are
no related registers, I would guess that it's not supported. If this
can't be tested, I suggest just returning an error if a command is sent
while the video is on.

You should be able to test this, though. E.g. just add a debugfs/sysfs
file to the panel or dsi tx driver, which does a DSI command, possibly a
read. See what happens when the video is enabled.

>> What do these read_poll_timeouts wait, exactly? The first one waits
>> until the data is sent, and BTA has been done? And the latter waits only
>> for the data to be sent? Hmm, no... The first must wait until the
>> peripheral has replied, as there's no wait in the
>> rcar_mipi_dsi_host_rx_transfer()...
> 
> First one is transmit+BTA+receive , second one is only transmit .
> 
>> It would be nice to have a short comment what the wait is for.
> 
> Will do in V3.
> 
> [...]
> 
>>> +    ret = read_poll_timeout(rcar_mipi_dsi_read, status,
>>> +                status & PPIDL0SR_STPST,
>>> +                2000, 10000, false, dsi, PPIDL0SR);
>>> +    if (ret < 0) {
>>> +        dev_err(dsi->dev, "Command RX STPST timeout (0x%08x)\n",
>>> status);
>>> +        return ret;
>>> +    }
>>
>> Same here, it's not very clear what the waits are for. Aren't we done
>> already after the tx function finished?
> 
> First one waits for bus handover to host processor to complete, the
> second one (STPST) waits for data lane to enter LP11 stop state .
> 
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +static ssize_t rcar_mipi_dsi_host_transfer(struct mipi_dsi_host *host,
>>> +                       const struct mipi_dsi_msg *msg)
>>> +{
>>> +    const bool is_rx_xfer = (msg->flags & MIPI_DSI_MSG_REQ_ACK) ||
>>> msg->rx_len;
>>> +    struct rcar_mipi_dsi *dsi = host_to_rcar_mipi_dsi(host);
>>> +    int ret;
>>> +
>>> +    if (msg->tx_len > 16 || msg->rx_len > 16) {
>>> +        /* ToDo: Implement Memory on AXI bus command mode. */
>>> +        dev_warn(dsi->dev,
>>> +             "Register-based command mode supports only up to 16
>>> Bytes long payload\n");
>>> +        return -EOPNOTSUPP;
>>> +    }
>>> +
>>> +    ret = rcar_mipi_dsi_host_tx_transfer(host, msg, is_rx_xfer);
>>> +
>>> +    /* If TX transfer succeeded and this transfer has RX part. */
>>> +    if (ret >= 0 && is_rx_xfer) {
>>> +        ret = rcar_mipi_dsi_host_rx_transfer(host, msg);
>>> +        if (ret)
>>> +            return ret;
>>> +
>>> +        ret = msg->rx_len;
>>> +    }
>>> +
>>> +    /* Wait a bit between commands */
>>> +    usleep_range(1000, 2000);
>>
>> Why wait and wait a bit between what?
> The consecutive command transmission was unreliable unless there was a
> slight delay between the consecutive commands. Hence this delay.

This sounds like there's a bug in the driver, or the TX or RX hardware.
Please document the sleep clearly in the comment.

 Tomi


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 4/4] drm/rcar-du: dsi: Implement DSI command support
  2025-08-18  7:20       ` Tomi Valkeinen
@ 2025-08-31 18:57         ` Marek Vasut
  0 siblings, 0 replies; 24+ messages in thread
From: Marek Vasut @ 2025-08-31 18:57 UTC (permalink / raw)
  To: Tomi Valkeinen, dri-devel
  Cc: David Airlie, Geert Uytterhoeven, Kieran Bingham,
	Laurent Pinchart, Maarten Lankhorst, Magnus Damm, Maxime Ripard,
	Simona Vetter, Thomas Zimmermann, linux-renesas-soc

On 8/18/25 9:20 AM, Tomi Valkeinen wrote:

Hello Tomi,

>>> If yes, then it might take
>>> much longer until the command can be transferred.
>>
>> Do you know the upper limit , is that one or two frame times ?
> 
> If using DSI video mode and the stream is on, the DSI TX has to
> interleave the commands either to the line blanking or frame blanking.
> Usually this is configurable in the DSI TX (if the chip can do
> interleaving).
> 
> A read command will be the most difficult to interleave, as it takes
> more time with the BTA and reply.
> 
> I think the worst case is one frame delay (next vblank).

I set the timeouts to 50ms, which at 60 Hz refresh should be a bit over 
three frame delays, which should be safe.

>>> If not maybe the
>>> function should return an error if the video stream is enabled.
>>
>> I haven't seen any drivers special casing that, I'd prefer to increase
>> the timeouts. For V3, I'll update the timeout to 50ms , which is about 3
>> frame times.
> 
> If the docs have no word about interleaving the commands and there are
> no related registers, I would guess that it's not supported. If this
> can't be tested, I suggest just returning an error if a command is sent
> while the video is on.
> 
> You should be able to test this, though. E.g. just add a debugfs/sysfs
> file to the panel or dsi tx driver, which does a DSI command, possibly a
> read. See what happens when the video is enabled.

I patched the ili9881c panel and triggered DCS read of its ID via sysfs 
attribute , I could always get valid ID, so I think we are safe here.

[...]

>>>> +    /* Wait a bit between commands */
>>>> +    usleep_range(1000, 2000);
>>>
>>> Why wait and wait a bit between what?
>> The consecutive command transmission was unreliable unless there was a
>> slight delay between the consecutive commands. Hence this delay.
> 
> This sounds like there's a bug in the driver, or the TX or RX hardware.
> Please document the sleep clearly in the comment.
Done.

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2025-08-31 18:57 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-08 14:24 [PATCH 0/4] drm/rcar-du: dsi: Implement DSI command support Marek Vasut
2025-06-08 14:24 ` [PATCH 1/4] drm/rcar-du: dsi: Convert register bits to BIT() macro Marek Vasut
2025-08-12 13:26   ` Tomi Valkeinen
2025-08-12 19:32     ` Marek Vasut
2025-08-12 20:05       ` Laurent Pinchart
2025-08-13  6:59         ` Geert Uytterhoeven
2025-08-13 20:47           ` Marek Vasut
2025-08-13  7:42       ` Tomi Valkeinen
2025-08-13 20:51         ` Marek Vasut
2025-06-08 14:24 ` [PATCH 2/4] drm/rcar-du: dsi: Remove fixed PPI lane count setup Marek Vasut
2025-08-12 13:18   ` Tomi Valkeinen
2025-08-12 13:30     ` Tomi Valkeinen
2025-08-12 19:35       ` Marek Vasut
2025-08-13  7:34         ` Tomi Valkeinen
2025-08-13 21:06           ` Marek Vasut
2025-08-14  5:39             ` Tomi Valkeinen
2025-08-17 22:46               ` Marek Vasut
2025-06-08 14:24 ` [PATCH 3/4] drm/rcar-du: dsi: Configure TXSETR register to match PPI lane count Marek Vasut
2025-06-08 14:24 ` [PATCH 4/4] drm/rcar-du: dsi: Implement DSI command support Marek Vasut
2025-06-09  0:51   ` kernel test robot
2025-08-12 14:36   ` Tomi Valkeinen
2025-08-17 23:40     ` Marek Vasut
2025-08-18  7:20       ` Tomi Valkeinen
2025-08-31 18:57         ` Marek Vasut

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).