Skip to contentSkip to conversation

drm: sun4i: add Display Engine 3.3 (DE33) support

PATCH In review Chris Morgan 7 participants 37 messages May 7, 2025 – May 10, 2025

Subsystems (8)
lore
Share & tools
lore
#0 lore raw

v9 cover drm: sun4i: add Display Engine 3.3 (DE33) support

From: Chris Morgan <[email protected]>

I've spoken with Ryan and he agreed to let me take over this series to get the display engine working on the Allwinner H616. I've taken his previous patch series for Display Engine 3.3 and combined it with the LCD controller patch series. I've also fixed a few additional bugs and made some changes to the device tree bindings.

Changes since V8:
- Combined the DE33 [1] series and the LCD [2] series to better track all patches necessary to output to an LCD display for the Allwinner H700.
- Added a required LVDS reset as requested here [3].
- Added compatible strings with a fallback for allwinner,sun50i-h616-display-engine, allwinner,sun50i-h616-tcon-top, and allwinner,sun50i-h616-sram-c.
- Added binding documentation for the LCD controller.
- Renamed the de3_sram device tree node to de33_sram.
- Corrected the LVDS reset for the LCD controller binding.
- Removed the PWM pins from the pincontroller bindings, as PWM is not yet supported.
- Reordered the patches so that a binding or a device tree node is not referenced before it is defined.

[1] https://lore.kernel.org/linux-sunxi/[email protected]/
[2] https://lore.kernel.org/linux-sunxi/[email protected]/
[3] https://lore.kernel.org/linux-sunxi/38669808.XM6RcZxFsP@jernej-laptop/

Chris Morgan (24):
dt-bindings: clock: sun50i-h616-ccu: Add LVDS reset
clk: sunxi-ng: h616: Add LVDS reset for LCD TCON
drm: sun4i: de2/de3: add mixer version enum
drm: sun4i: de2/de3: refactor mixer initialisation
drm: sun4i: de2/de3: add generic blender register reference function
drm: sun4i: de2/de3: use generic register reference function for layer
configuration
dt-bindings: allwinner: add H616 DE33 bus binding
dt-bindings: allwinner: add H616 DE33 clock binding
dt-bindings: allwinner: add H616 DE33 mixer binding
clk: sunxi-ng: ccu: add Display Engine 3.3 (DE33) support
drm: sun4i: de33: vi_scaler: add Display Engine 3.3 (DE33) support
drm: sun4i: de33: mixer: add Display Engine 3.3 (DE33) support
drm: sun4i: de33: mixer: add mixer configuration for the H616
dt-bindings: allwinner: Add TCON_TOP and TCON_LCD clock/reset defines
dt-bindings: display: sun4i: Add compatible strings for H616 DE
dt-bindings: display: sun4i: Add compatible strings for H616 TCON TOP
dt-bindings: sram: sunxi-sram: Add H616 SRAM C compatible
dt-bindings: display: Add R40 and H616 display engine compatibles drm/sun4i: tcon: Add support for R40 LCD
arm64: dts: allwinner: h616: add display engine, bus and mixer nodes
arm64: dts: allwinner: h616: Add TCON nodes to H616 DTSI
arm64: dts: allwinner: h616: add LCD and LVDS pins
arm64: dts: allwinner: rg35xx: Add GPIO backlight control
arm64: dts: allwinner: rg35xx: Enable LCD output

 .../bus/allwinner,sun50i-a64-de2.yaml         |   7 +-
 .../clock/allwinner,sun8i-a83t-de2-clk.yaml   |   1 +
 .../allwinner,sun4i-a10-display-engine.yaml   |  39 +--
 .../display/allwinner,sun4i-a10-tcon.yaml     |  10 +
 .../allwinner,sun8i-a83t-de2-mixer.yaml       |  34 ++-
 .../display/allwinner,sun8i-r40-tcon-top.yaml |  13 +-
 .../allwinner,sun4i-a10-system-control.yaml   |   4 +-
 .../arm64/boot/dts/allwinner/sun50i-h616.dtsi | 224 ++++++++++++++++++
 .../sun50i-h700-anbernic-rg35xx-2024.dts      |  64 +++++
 drivers/clk/sunxi-ng/ccu-sun50i-h616.c        |   1 +
 drivers/clk/sunxi-ng/ccu-sun8i-de2.c          |  25 ++
 drivers/gpu/drm/sun4i/sun4i_tcon.c            |   9 +
 drivers/gpu/drm/sun4i/sun8i_csc.c             |   4 +-
 drivers/gpu/drm/sun4i/sun8i_mixer.c           | 168 ++++++++++---
 drivers/gpu/drm/sun4i/sun8i_mixer.h           |  30 ++-
 drivers/gpu/drm/sun4i/sun8i_ui_layer.c        |  27 ++-
 drivers/gpu/drm/sun4i/sun8i_ui_scaler.c       |   2 +-
 drivers/gpu/drm/sun4i/sun8i_vi_layer.c        |  14 +-
 drivers/gpu/drm/sun4i/sun8i_vi_scaler.c       |   6 +-
 include/dt-bindings/clock/sun8i-tcon-top.h    |   2 +
 include/dt-bindings/reset/sun50i-h616-ccu.h   |   1 +
 21 files changed, 597 insertions(+), 88 deletions(-)
Signature · 1 line
2.43.0
#1 lore raw

PATCH v9 1/24 dt-bindings: clock: sun50i-h616-ccu: Add LVDS reset

From: Chris Morgan <[email protected]>

Add the required LVDS reset binding for the LCD TCON.

---
 include/dt-bindings/reset/sun50i-h616-ccu.h | 1 +
 1 file changed, 1 insertion(+)
include/dt-bindings/reset/sun50i-h616-ccu.h +1 -0
index 81b1eba2a7f7..ba626f7015b5 100644
@@ -69,5 +69,6 @@
 #define RST_BUS_GPADC		60
 #define RST_BUS_TCON_LCD0	61
 #define RST_BUS_TCON_LCD1	62
+#define RST_BUS_LVDS		63
 
 #endif /* _DT_BINDINGS_RESET_SUN50I_H616_H_ */
Signature · 1 line
2.43.0
Reviewed-by on v9 1/24
#2 lore raw

Re: [PATCH V9 01/24] dt-bindings: clock: sun50i-h616-ccu: Add LVDS reset

Quoted 6 lines · On Wed, 7 May 2025 15:19:20 -0500 Chris Morgan <[email protected]> wrote:

From: Chris Morgan <[email protected]>

Add the required LVDS reset binding for the LCD TCON.

Cheers,
Andre

Quoted 15 lines
---
 include/dt-bindings/reset/sun50i-h616-ccu.h | 1 +
 1 file changed, 1 insertion(+)
include/dt-bindings/reset/sun50i-h616-ccu.h +1 -0
index 81b1eba2a7f7..ba626f7015b5 100644
@@ -69,5 +69,6 @@
 #define RST_BUS_GPADC		60
 #define RST_BUS_TCON_LCD0	61
 #define RST_BUS_TCON_LCD1	62
+#define RST_BUS_LVDS		63
 
 #endif /* _DT_BINDINGS_RESET_SUN50I_H616_H_ */
#3 lore raw

PATCH v9 2/24 clk: sunxi-ng: h616: Add LVDS reset for LCD TCON

In reply to Chris Morgan

From: Chris Morgan <[email protected]>

Add the required LVDS reset for the LCD TCON. Note that while this reset is exposed for the T507, H616, and H700 only the H700 has an LCD controller.

---
 drivers/clk/sunxi-ng/ccu-sun50i-h616.c | 1 +
 1 file changed, 1 insertion(+)
drivers/clk/sunxi-ng/ccu-sun50i-h616.c +1 -0
index daa462c7d477..955c614830fa 100644
@@ -1094,6 +1094,7 @@ static const struct ccu_reset_map sun50i_h616_ccu_resets[] = {
 	[RST_BUS_TCON_LCD1]	= { 0xb7c, BIT(17) },
 	[RST_BUS_TCON_TV0]	= { 0xb9c, BIT(16) },
 	[RST_BUS_TCON_TV1]	= { 0xb9c, BIT(17) },
+	[RST_BUS_LVDS]		= { 0xbac, BIT(16) },
 	[RST_BUS_TVE_TOP]	= { 0xbbc, BIT(16) },
 	[RST_BUS_TVE0]		= { 0xbbc, BIT(17) },
 	[RST_BUS_HDCP]		= { 0xc4c, BIT(16) },
Signature · 1 line
2.43.0
Reviewed-by on v9 2/24
#4 lore raw

Re: [PATCH V9 02/24] clk: sunxi-ng: h616: Add LVDS reset for LCD TCON

On Wed, 7 May 2025 15:19:21 -0500
Chris Morgan <[email protected]> wrote:

Hi,

despite the slightly ill fate of this series, I was wondering if we could get the non-controversial clock parts for instance already merged, to reduce the number of patches and mitigate the churn with dependencies?

Quoted 8 lines

From: Chris Morgan <[email protected]>

Add the required LVDS reset for the LCD TCON. Note that while this reset is exposed for the T507, H616, and H700 only the H700 has an LCD controller.

Matches the T507 manual:

Cheers,
Andre

Quoted 16 lines
---
 drivers/clk/sunxi-ng/ccu-sun50i-h616.c | 1 +
 1 file changed, 1 insertion(+)
drivers/clk/sunxi-ng/ccu-sun50i-h616.c +1 -0
index daa462c7d477..955c614830fa 100644
@@ -1094,6 +1094,7 @@ static const struct ccu_reset_map sun50i_h616_ccu_resets[] = {
 	[RST_BUS_TCON_LCD1]	= { 0xb7c, BIT(17) },
 	[RST_BUS_TCON_TV0]	= { 0xb9c, BIT(16) },
 	[RST_BUS_TCON_TV1]	= { 0xb9c, BIT(17) },
+	[RST_BUS_LVDS]		= { 0xbac, BIT(16) },
 	[RST_BUS_TVE_TOP]	= { 0xbbc, BIT(16) },
 	[RST_BUS_TVE0]		= { 0xbbc, BIT(17) },
 	[RST_BUS_HDCP]		= { 0xc4c, BIT(16) },
#5 lore raw

Re: [PATCH V9 02/24] clk: sunxi-ng: h616: Add LVDS reset for LCD TCON

Quoted 9 lines · Andre Przywara

On Wed, 7 May 2025 15:19:21 -0500
Chris Morgan <[email protected]> wrote:

Hi,

despite the slightly ill fate of this series, I was wondering if we could get the non-controversial clock parts for instance already merged, to reduce the number of patches and mitigate the churn with dependencies?

Sure. Are we expecting any of the DT bits to go in this cycle? If not I won't have to split the DT header patch on a separate branch.

ChenYu

Quoted 34 lines
Quoted 8 lines

From: Chris Morgan <[email protected]>

Add the required LVDS reset for the LCD TCON. Note that while this reset is exposed for the T507, H616, and H700 only the H700 has an LCD controller.

Matches the T507 manual:

Cheers,
Andre

Quoted 16 lines
---
 drivers/clk/sunxi-ng/ccu-sun50i-h616.c | 1 +
 1 file changed, 1 insertion(+)
drivers/clk/sunxi-ng/ccu-sun50i-h616.c +1 -0
index daa462c7d477..955c614830fa 100644
@@ -1094,6 +1094,7 @@ static const struct ccu_reset_map sun50i_h616_ccu_resets[] = {
      [RST_BUS_TCON_LCD1]     = { 0xb7c, BIT(17) },
      [RST_BUS_TCON_TV0]      = { 0xb9c, BIT(16) },
      [RST_BUS_TCON_TV1]      = { 0xb9c, BIT(17) },
+     [RST_BUS_LVDS]          = { 0xbac, BIT(16) },
      [RST_BUS_TVE_TOP]       = { 0xbbc, BIT(16) },
      [RST_BUS_TVE0]          = { 0xbbc, BIT(17) },
      [RST_BUS_HDCP]          = { 0xc4c, BIT(16) },
#6 lore raw

Re: [PATCH V9 02/24] clk: sunxi-ng: h616: Add LVDS reset for LCD TCON

Quoted 7 lines · On Fri, 9 May 2025 23:29:50 +0900 Chen-Yu Tsai <[email protected]> wrote:
Quoted 6 lines · Andre Przywara

On Wed, 7 May 2025 15:19:21 -0500
Chris Morgan <[email protected]> wrote:

Hi,

Quoted 7 lines
Quoted 3 lines

despite the slightly ill fate of this series, I was wondering if we could get the non-controversial clock parts for instance already merged, to reduce the number of patches and mitigate the churn with dependencies?

Sure. Are we expecting any of the DT bits to go in this cycle? If not I won't have to split the DT header patch on a separate branch.

I don't think so, the DT wouldn't make much sense on its own anyway. But I guess it would help if the bindings / binding headers would go in already?

Cheers,
Andre

Quoted 36 lines
Quoted 35 lines
Quoted 9 lines

From: Chris Morgan <[email protected]>

Add the required LVDS reset for the LCD TCON. Note that while this reset is exposed for the T507, H616, and H700 only the H700 has an LCD controller.

Matches the T507 manual:

Cheers,
Andre

Quoted 16 lines
---
 drivers/clk/sunxi-ng/ccu-sun50i-h616.c | 1 +
 1 file changed, 1 insertion(+)
drivers/clk/sunxi-ng/ccu-sun50i-h616.c +1 -0
index daa462c7d477..955c614830fa 100644
@@ -1094,6 +1094,7 @@ static const struct ccu_reset_map sun50i_h616_ccu_resets[] = {
      [RST_BUS_TCON_LCD1]     = { 0xb7c, BIT(17) },
      [RST_BUS_TCON_TV0]      = { 0xb9c, BIT(16) },
      [RST_BUS_TCON_TV1]      = { 0xb9c, BIT(17) },
+     [RST_BUS_LVDS]          = { 0xbac, BIT(16) },
      [RST_BUS_TVE_TOP]       = { 0xbbc, BIT(16) },
      [RST_BUS_TVE0]          = { 0xbbc, BIT(17) },
      [RST_BUS_HDCP]          = { 0xc4c, BIT(16) },  
#7 lore raw

Re: [PATCH V9 02/24] clk: sunxi-ng: h616: Add LVDS reset for LCD TCON

Quoted 18 lines · Andre Przywara
Quoted 7 lines · On Fri, 9 May 2025 23:29:50 +0900 Chen-Yu Tsai <[email protected]> wrote:
Quoted 6 lines · Andre Przywara

On Wed, 7 May 2025 15:19:21 -0500
Chris Morgan <[email protected]> wrote:

Hi,

Quoted 7 lines
Quoted 3 lines

despite the slightly ill fate of this series, I was wondering if we could get the non-controversial clock parts for instance already merged, to reduce the number of patches and mitigate the churn with dependencies?

Sure. Are we expecting any of the DT bits to go in this cycle? If not I won't have to split the DT header patch on a separate branch.

Quoted 6 lines

I don't think so, the DT wouldn't make much sense on its own anyway. But I guess it would help if the bindings / binding headers would go in already?

Cheers,
Andre

I erred in combining everything into a large patch series, so I'm going to resubmit with things broken out by subsystem/in-order. Do you just want me to resubmit these two patches by themselves or can you take them now since they're the first 2? I won't need them until I add the LCD bindings into the sun50i-h616.dtsi file which will be towards the end of the commit chain.

Thank you,
Chris.

Quoted 38 lines
Quoted 37 lines
Quoted 36 lines
Quoted 10 lines

From: Chris Morgan <[email protected]>

Add the required LVDS reset for the LCD TCON. Note that while this reset is exposed for the T507, H616, and H700 only the H700 has an LCD controller.

Matches the T507 manual:

Cheers,
Andre

Quoted 16 lines
---
 drivers/clk/sunxi-ng/ccu-sun50i-h616.c | 1 +
 1 file changed, 1 insertion(+)
drivers/clk/sunxi-ng/ccu-sun50i-h616.c +1 -0
index daa462c7d477..955c614830fa 100644
@@ -1094,6 +1094,7 @@ static const struct ccu_reset_map sun50i_h616_ccu_resets[] = {
      [RST_BUS_TCON_LCD1]     = { 0xb7c, BIT(17) },
      [RST_BUS_TCON_TV0]      = { 0xb9c, BIT(16) },
      [RST_BUS_TCON_TV1]      = { 0xb9c, BIT(17) },
+     [RST_BUS_LVDS]          = { 0xbac, BIT(16) },
      [RST_BUS_TVE_TOP]       = { 0xbbc, BIT(16) },
      [RST_BUS_TVE0]          = { 0xbbc, BIT(17) },
      [RST_BUS_HDCP]          = { 0xc4c, BIT(16) },  
#8 lore raw

PATCH v9 3/24 drm: sun4i: de2/de3: add mixer version enum

In reply to Chris Morgan

From: Chris Morgan <[email protected]>

The Allwinner DE2 and DE3 display engine mixers are currently identified by a simple boolean flag. This will not scale to support additional DE variants.

Convert the boolean flag to an enum.

---
Changelog v5..v6:
- Update struct comment regarding change from is_de3 flag to de_type

---
 drivers/gpu/drm/sun4i/sun8i_csc.c       |  4 ++--
 drivers/gpu/drm/sun4i/sun8i_mixer.c     | 14 ++++++++++++--
 drivers/gpu/drm/sun4i/sun8i_mixer.h     |  4 ++--
 drivers/gpu/drm/sun4i/sun8i_ui_scaler.c |  2 +-
 drivers/gpu/drm/sun4i/sun8i_vi_layer.c  |  8 ++++----
 drivers/gpu/drm/sun4i/sun8i_vi_scaler.c |  4 ++--
 6 files changed, 23 insertions(+), 13 deletions(-)
drivers/gpu/drm/sun4i/sun8i_csc.c +2 -2
index 58480d8e4f70..6f4a2e9c6fca 100644
@@ -212,7 +212,7 @@ void sun8i_csc_set_ccsc_coefficients(struct sun8i_mixer *mixer, int layer,
 {
 	u32 base;
 
-	if (mixer->cfg->is_de3) {
+	if (mixer->cfg->de_type == sun8i_mixer_de3) {
 		sun8i_de3_ccsc_set_coefficients(mixer->engine.regs, layer,
 						mode, encoding, range);
 		return;
@@ -228,7 +228,7 @@ void sun8i_csc_enable_ccsc(struct sun8i_mixer *mixer, int layer, bool enable)
 {
 	u32 base;
 
-	if (mixer->cfg->is_de3) {
+	if (mixer->cfg->de_type == sun8i_mixer_de3) {
 		sun8i_de3_ccsc_enable(mixer->engine.regs, layer, enable);
 		return;
 	}
drivers/gpu/drm/sun4i/sun8i_mixer.c +12 -2
index 8b41d33baa30..2252bef19597 100644
@@ -537,7 +537,7 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master,
 	base = sun8i_blender_base(mixer);
 
 	/* Reset registers and disable unused sub-engines */
-	if (mixer->cfg->is_de3) {
+	if (mixer->cfg->de_type == sun8i_mixer_de3) {
 		for (i = 0; i < DE3_MIXER_UNIT_SIZE; i += 4)
 			regmap_write(mixer->engine.regs, i, 0);
 
@@ -628,6 +628,7 @@ static void sun8i_mixer_remove(struct platform_device *pdev)
 
 static const struct sun8i_mixer_cfg sun8i_a83t_mixer0_cfg = {
 	.ccsc		= CCSC_MIXER0_LAYOUT,
+	.de_type	= sun8i_mixer_de2,
 	.scaler_mask	= 0xf,
 	.scanline_yuv	= 2048,
 	.ui_num		= 3,
@@ -636,6 +637,7 @@ static const struct sun8i_mixer_cfg sun8i_a83t_mixer0_cfg = {
 
 static const struct sun8i_mixer_cfg sun8i_a83t_mixer1_cfg = {
 	.ccsc		= CCSC_MIXER1_LAYOUT,
+	.de_type	= sun8i_mixer_de2,
 	.scaler_mask	= 0x3,
 	.scanline_yuv	= 2048,
 	.ui_num		= 1,
@@ -644,6 +646,7 @@ static const struct sun8i_mixer_cfg sun8i_a83t_mixer1_cfg = {
 
 static const struct sun8i_mixer_cfg sun8i_h3_mixer0_cfg = {
 	.ccsc		= CCSC_MIXER0_LAYOUT,
+	.de_type	= sun8i_mixer_de2,
 	.mod_rate	= 432000000,
 	.scaler_mask	= 0xf,
 	.scanline_yuv	= 2048,
@@ -653,6 +656,7 @@ static const struct sun8i_mixer_cfg sun8i_h3_mixer0_cfg = {
 
 static const struct sun8i_mixer_cfg sun8i_r40_mixer0_cfg = {
 	.ccsc		= CCSC_MIXER0_LAYOUT,
+	.de_type	= sun8i_mixer_de2,
 	.mod_rate	= 297000000,
 	.scaler_mask	= 0xf,
 	.scanline_yuv	= 2048,
@@ -662,6 +666,7 @@ static const struct sun8i_mixer_cfg sun8i_r40_mixer0_cfg = {
 
 static const struct sun8i_mixer_cfg sun8i_r40_mixer1_cfg = {
 	.ccsc		= CCSC_MIXER1_LAYOUT,
+	.de_type	= sun8i_mixer_de2,
 	.mod_rate	= 297000000,
 	.scaler_mask	= 0x3,
 	.scanline_yuv	= 2048,
@@ -670,6 +675,7 @@ static const struct sun8i_mixer_cfg sun8i_r40_mixer1_cfg = {
 };
 
 static const struct sun8i_mixer_cfg sun8i_v3s_mixer_cfg = {
+	.de_type = sun8i_mixer_de2,
 	.vi_num = 2,
 	.ui_num = 1,
 	.scaler_mask = 0x3,
@@ -680,6 +686,7 @@ static const struct sun8i_mixer_cfg sun8i_v3s_mixer_cfg = {
 
 static const struct sun8i_mixer_cfg sun20i_d1_mixer0_cfg = {
 	.ccsc		= CCSC_D1_MIXER0_LAYOUT,
+	.de_type	= sun8i_mixer_de2,
 	.mod_rate	= 297000000,
 	.scaler_mask	= 0x3,
 	.scanline_yuv	= 2048,
@@ -689,6 +696,7 @@ static const struct sun8i_mixer_cfg sun20i_d1_mixer0_cfg = {
 
 static const struct sun8i_mixer_cfg sun20i_d1_mixer1_cfg = {
 	.ccsc		= CCSC_MIXER1_LAYOUT,
+	.de_type	= sun8i_mixer_de2,
 	.mod_rate	= 297000000,
 	.scaler_mask	= 0x1,
 	.scanline_yuv	= 1024,
@@ -698,6 +706,7 @@ static const struct sun8i_mixer_cfg sun20i_d1_mixer1_cfg = {
 
 static const struct sun8i_mixer_cfg sun50i_a64_mixer0_cfg = {
 	.ccsc		= CCSC_MIXER0_LAYOUT,
+	.de_type	= sun8i_mixer_de2,
 	.mod_rate	= 297000000,
 	.scaler_mask	= 0xf,
 	.scanline_yuv	= 4096,
@@ -707,6 +716,7 @@ static const struct sun8i_mixer_cfg sun50i_a64_mixer0_cfg = {
 
 static const struct sun8i_mixer_cfg sun50i_a64_mixer1_cfg = {
 	.ccsc		= CCSC_MIXER1_LAYOUT,
+	.de_type	= sun8i_mixer_de2,
 	.mod_rate	= 297000000,
 	.scaler_mask	= 0x3,
 	.scanline_yuv	= 2048,
@@ -716,7 +726,7 @@ static const struct sun8i_mixer_cfg sun50i_a64_mixer1_cfg = {
 
 static const struct sun8i_mixer_cfg sun50i_h6_mixer0_cfg = {
 	.ccsc		= CCSC_MIXER0_LAYOUT,
-	.is_de3		= true,
+	.de_type	= sun8i_mixer_de3,
 	.mod_rate	= 600000000,
 	.scaler_mask	= 0xf,
 	.scanline_yuv	= 4096,
drivers/gpu/drm/sun4i/sun8i_mixer.h +2 -2
index d7898c9c9cc0..7fe5ce20082a 100644
@@ -162,7 +162,7 @@ enum {
  * @ccsc: select set of CCSC base addresses from the enumeration above.
  * @mod_rate: module clock rate that needs to be set in order to have
  *	a functional block.
- * @is_de3: true, if this is next gen display engine 3.0, false otherwise.
+ * @de_type: sun8i_mixer_type enum representing the display engine generation.
  * @scaline_yuv: size of a scanline for VI scaler for YUV formats.
  */
 struct sun8i_mixer_cfg {
@@ -214,7 +214,7 @@ engine_to_sun8i_mixer(struct sunxi_engine *engine)
 static inline u32
 sun8i_blender_base(struct sun8i_mixer *mixer)
 {
-	return mixer->cfg->is_de3 ? DE3_BLD_BASE : DE2_BLD_BASE;
+	return mixer->cfg->de_type == sun8i_mixer_de3 ? DE3_BLD_BASE : DE2_BLD_BASE;
 }
 
 static inline u32
drivers/gpu/drm/sun4i/sun8i_ui_scaler.c +1 -1
index ae0806bccac7..504ffa0971a4 100644
@@ -93,7 +93,7 @@ static u32 sun8i_ui_scaler_base(struct sun8i_mixer *mixer, int channel)
 {
 	int vi_num = mixer->cfg->vi_num;
 
-	if (mixer->cfg->is_de3)
+	if (mixer->cfg->de_type == sun8i_mixer_de3)
 		return DE3_VI_SCALER_UNIT_BASE +
 		       DE3_VI_SCALER_UNIT_SIZE * vi_num +
 		       DE3_UI_SCALER_UNIT_SIZE * (channel - vi_num);
drivers/gpu/drm/sun4i/sun8i_vi_layer.c +4 -4
index 9c09d9c08496..a7a3a75ffd63 100644
@@ -25,7 +25,7 @@ static void sun8i_vi_layer_update_alpha(struct sun8i_mixer *mixer, int channel,
 
 	ch_base = sun8i_channel_base(mixer, channel);
 
-	if (mixer->cfg->is_de3) {
+	if (mixer->cfg->de_type >= sun8i_mixer_de3) {
 		mask = SUN50I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA_MASK |
 		       SUN50I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA_MODE_MASK;
 		val = SUN50I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA
@@ -483,7 +483,7 @@ struct sun8i_layer *sun8i_vi_layer_init_one(struct drm_device *drm,
 	if (!layer)
 		return ERR_PTR(-ENOMEM);
 
-	if (mixer->cfg->is_de3) {
+	if (mixer->cfg->de_type >= sun8i_mixer_de3) {
 		formats = sun8i_vi_layer_de3_formats;
 		format_count = ARRAY_SIZE(sun8i_vi_layer_de3_formats);
 	} else {
@@ -507,7 +507,7 @@ struct sun8i_layer *sun8i_vi_layer_init_one(struct drm_device *drm,
 
 	plane_cnt = mixer->cfg->ui_num + mixer->cfg->vi_num;
 
-	if (mixer->cfg->vi_num == 1 || mixer->cfg->is_de3) {
+	if (mixer->cfg->vi_num == 1 || mixer->cfg->de_type >= sun8i_mixer_de3) {
 		ret = drm_plane_create_alpha_property(&layer->plane);
 		if (ret) {
 			dev_err(drm->dev, "Couldn't add alpha property\n");
@@ -524,7 +524,7 @@ struct sun8i_layer *sun8i_vi_layer_init_one(struct drm_device *drm,
 
 	supported_encodings = BIT(DRM_COLOR_YCBCR_BT601) |
 			      BIT(DRM_COLOR_YCBCR_BT709);
-	if (mixer->cfg->is_de3)
+	if (mixer->cfg->de_type >= sun8i_mixer_de3)
 		supported_encodings |= BIT(DRM_COLOR_YCBCR_BT2020);
 
 	supported_ranges = BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
drivers/gpu/drm/sun4i/sun8i_vi_scaler.c +2 -2
index 7ba75011adf9..ad87ab395803 100644
@@ -835,7 +835,7 @@ static const u32 bicubic4coefftab32[480] = {
 
 static u32 sun8i_vi_scaler_base(struct sun8i_mixer *mixer, int channel)
 {
-	if (mixer->cfg->is_de3)
+	if (mixer->cfg->de_type == sun8i_mixer_de3)
 		return DE3_VI_SCALER_UNIT_BASE +
 		       DE3_VI_SCALER_UNIT_SIZE * channel;
 	else
@@ -956,7 +956,7 @@ void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer, int layer,
 		cvphase = vphase;
 	}
 
-	if (mixer->cfg->is_de3) {
+	if (mixer->cfg->de_type >= sun8i_mixer_de3) {
 		u32 val;
 
 		if (format->hsub == 1 && format->vsub == 1)
Signature · 1 line
2.43.0
#9 lore raw

PATCH v9 4/24 drm: sun4i: de2/de3: refactor mixer initialisation

In reply to Chris Morgan

From: Chris Morgan <[email protected]>

Now that the DE variant can be selected by enum, take the oppportunity to factor out some common initialisation code to a separate function.

---
Changelog v1..v2:
- Combine base register allocation and initialisation in sun8i_mixer_init
- Whitespace fix

Changelog v4..v5:
- Remove trailing whitespace

Changelog v7..v8:
- Remove CSC configuration changes (logically better placed with future YUV support) making this the first patch in the series.

---
 drivers/gpu/drm/sun4i/sun8i_mixer.c | 64 +++++++++++++++--------------
 1 file changed, 34 insertions(+), 30 deletions(-)
drivers/gpu/drm/sun4i/sun8i_mixer.c +34 -30
index 2252bef19597..41815b42d6d2 100644
@@ -425,6 +425,38 @@ static int sun8i_mixer_of_get_id(struct device_node *node)
 	return of_ep.id;
 }
 
+static void sun8i_mixer_init(struct sun8i_mixer *mixer)
+{
+	unsigned int base = sun8i_blender_base(mixer);
+	int plane_cnt, i;
+
+	/* Enable the mixer */
+	regmap_write(mixer->engine.regs, SUN8I_MIXER_GLOBAL_CTL,
+		     SUN8I_MIXER_GLOBAL_CTL_RT_EN);
+
+	/* Set background color to black */
+	regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_BKCOLOR(base),
+		     SUN8I_MIXER_BLEND_COLOR_BLACK);
+
+	/*
+	 * Set fill color of bottom plane to black. Generally not needed
+	 * except when VI plane is at bottom (zpos = 0) and enabled.
+	 */
+	regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(base),
+		     SUN8I_MIXER_BLEND_PIPE_CTL_FC_EN(0));
+	regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ATTR_FCOLOR(base, 0),
+		     SUN8I_MIXER_BLEND_COLOR_BLACK);
+
+	plane_cnt = mixer->cfg->vi_num + mixer->cfg->ui_num;
+	for (i = 0; i < plane_cnt; i++)
+		regmap_write(mixer->engine.regs,
+			     SUN8I_MIXER_BLEND_MODE(base, i),
+			     SUN8I_MIXER_BLEND_MODE_DEF);
+
+	regmap_update_bits(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(base),
+			   SUN8I_MIXER_BLEND_PIPE_CTL_EN_MSK, 0);
+}
+
 static int sun8i_mixer_bind(struct device *dev, struct device *master,
 			      void *data)
 {
@@ -433,8 +465,6 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master,
 	struct sun4i_drv *drv = drm->dev_private;
 	struct sun8i_mixer *mixer;
 	void __iomem *regs;
-	unsigned int base;
-	int plane_cnt;
 	int i, ret;
 
 	/*
@@ -534,8 +564,6 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master,
 
 	list_add_tail(&mixer->engine.list, &drv->engine_list);
 
-	base = sun8i_blender_base(mixer);
-
 	/* Reset registers and disable unused sub-engines */
 	if (mixer->cfg->de_type == sun8i_mixer_de3) {
 		for (i = 0; i < DE3_MIXER_UNIT_SIZE; i += 4)
@@ -551,7 +579,7 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master,
 		regmap_write(mixer->engine.regs, SUN50I_MIXER_FMT_EN, 0);
 		regmap_write(mixer->engine.regs, SUN50I_MIXER_CDC0_EN, 0);
 		regmap_write(mixer->engine.regs, SUN50I_MIXER_CDC1_EN, 0);
-	} else {
+	} else if (mixer->cfg->de_type == sun8i_mixer_de2) {
 		for (i = 0; i < DE2_MIXER_UNIT_SIZE; i += 4)
 			regmap_write(mixer->engine.regs, i, 0);
 
@@ -564,31 +592,7 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master,
 		regmap_write(mixer->engine.regs, SUN8I_MIXER_DCSC_EN, 0);
 	}
 
-	/* Enable the mixer */
-	regmap_write(mixer->engine.regs, SUN8I_MIXER_GLOBAL_CTL,
-		     SUN8I_MIXER_GLOBAL_CTL_RT_EN);
-
-	/* Set background color to black */
-	regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_BKCOLOR(base),
-		     SUN8I_MIXER_BLEND_COLOR_BLACK);
-
-	/*
-	 * Set fill color of bottom plane to black. Generally not needed
-	 * except when VI plane is at bottom (zpos = 0) and enabled.
-	 */
-	regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(base),
-		     SUN8I_MIXER_BLEND_PIPE_CTL_FC_EN(0));
-	regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ATTR_FCOLOR(base, 0),
-		     SUN8I_MIXER_BLEND_COLOR_BLACK);
-
-	plane_cnt = mixer->cfg->vi_num + mixer->cfg->ui_num;
-	for (i = 0; i < plane_cnt; i++)
-		regmap_write(mixer->engine.regs,
-			     SUN8I_MIXER_BLEND_MODE(base, i),
-			     SUN8I_MIXER_BLEND_MODE_DEF);
-
-	regmap_update_bits(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(base),
-			   SUN8I_MIXER_BLEND_PIPE_CTL_EN_MSK, 0);
+	sun8i_mixer_init(mixer);
 
 	return 0;
 
Signature · 1 line
2.43.0
#10 lore raw

PATCH v9 5/24 drm: sun4i: de2/de3: add generic blender register reference function

In reply to Chris Morgan

From: Chris Morgan <[email protected]>

The DE2 and DE3 engines have a blender register range within the mixer engine register map, whereas the DE33 separates this out into a separate display group.

Prepare for this by adding a function to look the blender reference up, with a subsequent patch to add a conditional based on the DE type.

---
 drivers/gpu/drm/sun4i/sun8i_mixer.h | 6 ++++++
 1 file changed, 6 insertions(+)
drivers/gpu/drm/sun4i/sun8i_mixer.h +6 -0
index 7fe5ce20082a..43c413052a22 100644
@@ -217,6 +217,12 @@ sun8i_blender_base(struct sun8i_mixer *mixer)
 	return mixer->cfg->de_type == sun8i_mixer_de3 ? DE3_BLD_BASE : DE2_BLD_BASE;
 }
 
+static inline struct regmap *
+sun8i_blender_regmap(struct sun8i_mixer *mixer)
+{
+	return mixer->engine.regs;
+}
+
 static inline u32
 sun8i_channel_base(struct sun8i_mixer *mixer, int channel)
 {
Signature · 1 line
2.43.0
#11 lore raw

PATCH v9 6/24 drm: sun4i: de2/de3: use generic register reference function for layer configuration

In reply to Chris Morgan

From: Chris Morgan <[email protected]>

Use the new blender register lookup function where required in the layer commit and update code.

---
Changelog v2..v3:
- Refactor for 6.11 layer init/modesetting changes

---
 drivers/gpu/drm/sun4i/sun8i_mixer.c    | 5 +++--
 drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 7 +++++--
 drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 6 ++++--
 3 files changed, 12 insertions(+), 6 deletions(-)
drivers/gpu/drm/sun4i/sun8i_mixer.c +3 -2
index 41815b42d6d2..cc4da11e2c10 100644
@@ -274,6 +274,7 @@ static void sun8i_mixer_commit(struct sunxi_engine *engine,
 {
 	struct sun8i_mixer *mixer = engine_to_sun8i_mixer(engine);
 	u32 bld_base = sun8i_blender_base(mixer);
+	struct regmap *bld_regs = sun8i_blender_regmap(mixer);
 	struct drm_plane_state *plane_state;
 	struct drm_plane *plane;
 	u32 route = 0, pipe_en = 0;
@@ -313,8 +314,8 @@ static void sun8i_mixer_commit(struct sunxi_engine *engine,
 		pipe_en |= SUN8I_MIXER_BLEND_PIPE_CTL_EN(zpos);
 	}
 
-	regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ROUTE(bld_base), route);
-	regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
+	regmap_write(bld_regs, SUN8I_MIXER_BLEND_ROUTE(bld_base), route);
+	regmap_write(bld_regs, SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
 		     pipe_en | SUN8I_MIXER_BLEND_PIPE_CTL_FC_EN(0));
 
 	regmap_write(engine->regs, SUN8I_MIXER_GLOBAL_DBUFF,
drivers/gpu/drm/sun4i/sun8i_ui_layer.c +5 -2
index b90e5edef4e8..7a21d32ff1e4 100644
@@ -23,6 +23,7 @@
 #include "sun8i_mixer.h"
 #include "sun8i_ui_layer.h"
 #include "sun8i_ui_scaler.h"
+#include "sun8i_vi_scaler.h"
 
 static void sun8i_ui_layer_update_alpha(struct sun8i_mixer *mixer, int channel,
 					int overlay, struct drm_plane *plane)
@@ -51,6 +52,7 @@ static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel,
 {
 	struct drm_plane_state *state = plane->state;
 	u32 src_w, src_h, dst_w, dst_h;
+	struct regmap *bld_regs;
 	u32 bld_base, ch_base;
 	u32 outsize, insize;
 	u32 hphase, vphase;
@@ -59,6 +61,7 @@ static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel,
 			 channel, overlay);
 
 	bld_base = sun8i_blender_base(mixer);
+	bld_regs = sun8i_blender_regmap(mixer);
 	ch_base = sun8i_channel_base(mixer, channel);
 
 	src_w = drm_rect_width(&state->src) >> 16;
@@ -103,10 +106,10 @@ static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel,
 	DRM_DEBUG_DRIVER("Layer destination coordinates X: %d Y: %d\n",
 			 state->dst.x1, state->dst.y1);
 	DRM_DEBUG_DRIVER("Layer destination size W: %d H: %d\n", dst_w, dst_h);
-	regmap_write(mixer->engine.regs,
+	regmap_write(bld_regs,
 		     SUN8I_MIXER_BLEND_ATTR_COORD(bld_base, zpos),
 		     SUN8I_MIXER_COORD(state->dst.x1, state->dst.y1));
-	regmap_write(mixer->engine.regs,
+	regmap_write(bld_regs,
 		     SUN8I_MIXER_BLEND_ATTR_INSIZE(bld_base, zpos),
 		     outsize);
 
drivers/gpu/drm/sun4i/sun8i_vi_layer.c +4 -2
index a7a3a75ffd63..3d81d23d0195 100644
@@ -55,6 +55,7 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel,
 	struct drm_plane_state *state = plane->state;
 	const struct drm_format_info *format = state->fb->format;
 	u32 src_w, src_h, dst_w, dst_h;
+	struct regmap *bld_regs;
 	u32 bld_base, ch_base;
 	u32 outsize, insize;
 	u32 hphase, vphase;
@@ -66,6 +67,7 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel,
 			 channel, overlay);
 
 	bld_base = sun8i_blender_base(mixer);
+	bld_regs = sun8i_blender_regmap(mixer);
 	ch_base = sun8i_channel_base(mixer, channel);
 
 	src_w = drm_rect_width(&state->src) >> 16;
@@ -183,10 +185,10 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel,
 	DRM_DEBUG_DRIVER("Layer destination coordinates X: %d Y: %d\n",
 			 state->dst.x1, state->dst.y1);
 	DRM_DEBUG_DRIVER("Layer destination size W: %d H: %d\n", dst_w, dst_h);
-	regmap_write(mixer->engine.regs,
+	regmap_write(bld_regs,
 		     SUN8I_MIXER_BLEND_ATTR_COORD(bld_base, zpos),
 		     SUN8I_MIXER_COORD(state->dst.x1, state->dst.y1));
-	regmap_write(mixer->engine.regs,
+	regmap_write(bld_regs,
 		     SUN8I_MIXER_BLEND_ATTR_INSIZE(bld_base, zpos),
 		     outsize);
 
Signature · 1 line
2.43.0
#12 lore raw

PATCH v9 7/24 dt-bindings: allwinner: add H616 DE33 bus binding

In reply to Chris Morgan

From: Chris Morgan <[email protected]>

The Allwinner H616 and variants have a new display engine revision (DE33).

Add a display engine bus binding for the DE33. Note that the DE33 requires 3 register blocks instead of 1. To keep things simple remove the maxItems value for registers for the child nodes and instead rely on the bindings for the child nodes such as allwinner,sun8i-a83t-de2-mixer.yaml to enforce the max values.

---
Changelog v1..v2:
- Correct DE2 bus enum to reflect fallback devices accurately.

Changelog v2..v3:
- Separate content into three patches for three separate subsystems

Changelog v5..v6:
- Increase reg maxItems to 3.

Changelog v8..v9:
- Remove maxItems from child nodes completely and rely on bindings for child nodes to enforce maxItems.
- Remove reviewed and acked tags due to changes made.

---
 .../devicetree/bindings/bus/allwinner,sun50i-a64-de2.yaml  | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)
Documentation/devicetree/bindings/bus/allwinner,sun50i-a64-de2.yaml +3 -4
index 9845a187bdf6..9d9418c40b95 100644
@@ -24,7 +24,9 @@ properties:
     oneOf:
       - const: allwinner,sun50i-a64-de2
       - items:
-          - const: allwinner,sun50i-h6-de3
+          - enum:
+              - allwinner,sun50i-h6-de3
+              - allwinner,sun50i-h616-de33
           - const: allwinner,sun50i-a64-de2
 
   reg:
@@ -47,9 +49,6 @@ patternProperties:
   "^[a-zA-Z][a-zA-Z0-9,+\\-._]{0,63}@[0-9a-fA-F]+$":
     type: object
     additionalProperties: true
-    properties:
-      reg:
-        maxItems: 1
 
     required:
       - reg
Signature · 1 line
2.43.0
#13 lore raw

PATCH v9 8/24 dt-bindings: allwinner: add H616 DE33 clock binding

In reply to Chris Morgan

From: Chris Morgan <[email protected]>

The Allwinner H616 and variants have a new display engine revision (DE33).

Add a clock binding for the DE33.

---
Changelog v2..v3:
- Separate content into three patches for three separate subsystems

---
 .../devicetree/bindings/clock/allwinner,sun8i-a83t-de2-clk.yaml  | 1 +
 1 file changed, 1 insertion(+)
Documentation/devicetree/bindings/clock/allwinner,sun8i-a83t-de2-clk.yaml +1 -0
index 70369bd633e4..7fcd55d468d4 100644
@@ -25,6 +25,7 @@ properties:
       - const: allwinner,sun50i-a64-de2-clk
       - const: allwinner,sun50i-h5-de2-clk
       - const: allwinner,sun50i-h6-de3-clk
+      - const: allwinner,sun50i-h616-de33-clk
       - items:
           - const: allwinner,sun8i-r40-de2-clk
           - const: allwinner,sun8i-h3-de2-clk
Signature · 1 line
2.43.0
#14 lore raw

PATCH v9 9/24 dt-bindings: allwinner: add H616 DE33 mixer binding

In reply to Chris Morgan

From: Chris Morgan <[email protected]>

The Allwinner H616 and variants have a new display engine revision (DE33).

The mixer configuration registers are significantly different to the DE3 and DE2 revisions, being split into separate top and display blocks, therefore a fallback for the mixer compatible is not provided.

Add a display engine mixer binding for the DE33.

---
Changelog v2..v3:
- Separate content into three patches for three separate subsystems

Changelog v5..v6:
- Increase reg maxItems to 3 and add conditional for h616-de33

Changelog v8..v9:
- Correct conditional logic for reg items as it was not working for me when using dtbs_check
- Add reg-names property and description for the registers used by the DE33 mixer
- Removed Acked and Reviewed tags so that change can be re-reviewed.

---
 .../allwinner,sun8i-a83t-de2-mixer.yaml       | 34 +++++++++++++++++--
 1 file changed, 32 insertions(+), 2 deletions(-)
Documentation/devicetree/bindings/display/allwinner,sun8i-a83t-de2-mixer.yaml +32 -2
index b75c1ec686ad..cbd18fd83e52 100644
@@ -24,9 +24,11 @@ properties:
       - allwinner,sun50i-a64-de2-mixer-0
       - allwinner,sun50i-a64-de2-mixer-1
       - allwinner,sun50i-h6-de3-mixer-0
+      - allwinner,sun50i-h616-de33-mixer-0
 
-  reg:
-    maxItems: 1
+  reg: true
+
+  reg-names: true
 
   clocks:
     items:
@@ -61,6 +63,34 @@ properties:
     required:
       - port@1
 
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - allwinner,sun50i-h616-de33-mixer-0
+    then:
+      properties:
+        reg:
+          description: |
+            Registers for controlling individual layers of the display
+            engine (layers), global control (top), and display blending
+            control (display). Names are from Allwinner BSP kernel.
+          maxItems: 3
+        reg-names:
+          items:
+            - const: layers
+            - const: top
+            - const: display
+      required:
+        - reg-names
+
+    else:
+      properties:
+        reg:
+          maxItems: 1
+
 required:
   - compatible
   - reg
Signature · 1 line
2.43.0
#15 lore raw

PATCH v9 10/24 clk: sunxi-ng: ccu: add Display Engine 3.3 (DE33) support

In reply to Chris Morgan

From: Chris Morgan <[email protected]>

The DE33 is a newer version of the Allwinner Display Engine IP block, found in the H616, H618, H700 and T507 SoCs. DE2 and DE3 are already supported by the mainline driver.

The DE33 in the H616 has mixer0 and writeback units. The clocks and resets required are identical to the H3 and H5 respectively, so use those existing structs for the H616 description.

There are two additional 32-bit registers (at offsets 0x24 and 0x28) which require clearing and setting respectively to bring up the hardware. The function of these registers is currently unknown, and the values are taken from the out-of-tree driver.

Add the required clock description struct and compatible string to the DE2 driver.

---
Changelog v2..v3:
- Lowercase hex value

Changelog v2..v3:
- Correct #include for writel()

Changelog v4..v5:
- Whitespace fix

---
 drivers/clk/sunxi-ng/ccu-sun8i-de2.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)
drivers/clk/sunxi-ng/ccu-sun8i-de2.c +25 -0
index f2aa71206bc2..a6cd0f988859 100644
@@ -5,6 +5,7 @@
 
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
+#include <linux/io.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
@@ -239,6 +240,16 @@ static const struct sunxi_ccu_desc sun50i_h5_de2_clk_desc = {
 	.num_resets	= ARRAY_SIZE(sun50i_h5_de2_resets),
 };
 
+static const struct sunxi_ccu_desc sun50i_h616_de33_clk_desc = {
+	.ccu_clks	= sun8i_de2_ccu_clks,
+	.num_ccu_clks	= ARRAY_SIZE(sun8i_de2_ccu_clks),
+
+	.hw_clks	= &sun8i_h3_de2_hw_clks,
+
+	.resets		= sun50i_h5_de2_resets,
+	.num_resets	= ARRAY_SIZE(sun50i_h5_de2_resets),
+};
+
 static int sunxi_de2_clk_probe(struct platform_device *pdev)
 {
 	struct clk *bus_clk, *mod_clk;
@@ -291,6 +302,16 @@ static int sunxi_de2_clk_probe(struct platform_device *pdev)
 		goto err_disable_mod_clk;
 	}
 
+	/*
+	 * The DE33 requires these additional (unknown) registers set
+	 * during initialisation.
+	 */
+	if (of_device_is_compatible(pdev->dev.of_node,
+				    "allwinner,sun50i-h616-de33-clk")) {
+		writel(0, reg + 0x24);
+		writel(0x0000a980, reg + 0x28);
+	}
+
 	ret = devm_sunxi_ccu_probe(&pdev->dev, reg, ccu_desc);
 	if (ret)
 		goto err_assert_reset;
@@ -335,6 +356,10 @@ static const struct of_device_id sunxi_de2_clk_ids[] = {
 		.compatible = "allwinner,sun50i-h6-de3-clk",
 		.data = &sun50i_h5_de2_clk_desc,
 	},
+	{
+		.compatible = "allwinner,sun50i-h616-de33-clk",
+		.data = &sun50i_h616_de33_clk_desc,
+	},
 	{ }
 };
 MODULE_DEVICE_TABLE(of, sunxi_de2_clk_ids);
Signature · 1 line
2.43.0
#16 lore raw

PATCH v9 11/24 drm: sun4i: de33: vi_scaler: add Display Engine 3.3 (DE33) support

In reply to Chris Morgan

From: Chris Morgan <[email protected]>

The vi_scaler appears to be used in preference to the ui_scaler module for hardware video scaling in the DE33.

Enable support for this scaler.

---
 drivers/gpu/drm/sun4i/sun8i_ui_layer.c  | 20 ++++++++++++++++----
 drivers/gpu/drm/sun4i/sun8i_vi_scaler.c |  4 +++-
 2 files changed, 19 insertions(+), 5 deletions(-)
drivers/gpu/drm/sun4i/sun8i_ui_layer.c +16 -4
index 7a21d32ff1e4..3eefdb710dee 100644
@@ -94,12 +94,24 @@ static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel,
 		hscale = state->src_w / state->crtc_w;
 		vscale = state->src_h / state->crtc_h;
 
-		sun8i_ui_scaler_setup(mixer, channel, src_w, src_h, dst_w,
-				      dst_h, hscale, vscale, hphase, vphase);
-		sun8i_ui_scaler_enable(mixer, channel, true);
+		if (mixer->cfg->de_type == sun8i_mixer_de33) {
+			sun8i_vi_scaler_setup(mixer, channel, src_w, src_h,
+					      dst_w, dst_h, hscale, vscale,
+					      hphase, vphase,
+					      state->fb->format);
+			sun8i_vi_scaler_enable(mixer, channel, true);
+		} else {
+			sun8i_ui_scaler_setup(mixer, channel, src_w, src_h,
+					      dst_w, dst_h, hscale, vscale,
+					      hphase, vphase);
+			sun8i_ui_scaler_enable(mixer, channel, true);
+		}
 	} else {
 		DRM_DEBUG_DRIVER("HW scaling is not needed\n");
-		sun8i_ui_scaler_enable(mixer, channel, false);
+		if (mixer->cfg->de_type == sun8i_mixer_de33)
+			sun8i_vi_scaler_enable(mixer, channel, false);
+		else
+			sun8i_ui_scaler_enable(mixer, channel, false);
 	}
 
 	/* Set base coordinates */
drivers/gpu/drm/sun4i/sun8i_vi_scaler.c +3 -1
index ad87ab395803..6839fd5ab602 100644
@@ -835,7 +835,9 @@ static const u32 bicubic4coefftab32[480] = {
 
 static u32 sun8i_vi_scaler_base(struct sun8i_mixer *mixer, int channel)
 {
-	if (mixer->cfg->de_type == sun8i_mixer_de3)
+	if (mixer->cfg->de_type == sun8i_mixer_de33)
+		return sun8i_channel_base(mixer, channel) + 0x3000;
+	else if (mixer->cfg->de_type == sun8i_mixer_de3)
 		return DE3_VI_SCALER_UNIT_BASE +
 		       DE3_VI_SCALER_UNIT_SIZE * channel;
 	else
Signature · 1 line
2.43.0
#17 lore raw

PATCH v9 12/24 drm: sun4i: de33: mixer: add Display Engine 3.3 (DE33) support

In reply to Chris Morgan

From: Chris Morgan <[email protected]>

The DE33 is a newer version of the Allwinner Display Engine IP block, found in the H616, H618, H700 and T507 SoCs. DE2 and DE3 are already supported by the mainline driver.

Notable features (from the H616 datasheet and implemented):
- 4096 x 2048 (4K) output support

Other features (implemented but not in this patchset):
- AFBC ARM Frame Buffer Compression support
- YUV pipeline support

The DE2 and DE3 engines have a blender register range within the mixer engine register map, whereas the DE33 separates this out into a separate display group, and adds a top register map.

The DE33 also appears to remove the global double buffer control register, present in the DE2 and DE3.

Extend the mixer to support the DE33.

---
Changelog v4..v5:
- Whitespace fixes
- Correct strict mode warnings from checkpatch.pl

Changelog v7..v8:
- Add top/disp regmaps to mixer for DE33
- Remove YUV-specific code
- Remove use of global double buffer
- Remove unneeded if/then parentheses and fix an alignment issue as suggested by checkpatch.pl

Changelog v8..v9:
- Change devm_platform_ioremap_resource() for the 2nd and 3rd register set to devm_platform_ioremap_resource_byname() since we now are enforcing reg-names in the device tree.

---
 drivers/gpu/drm/sun4i/sun8i_mixer.c | 82 +++++++++++++++++++++++++----
 drivers/gpu/drm/sun4i/sun8i_mixer.h | 22 ++++++--
 2 files changed, 90 insertions(+), 14 deletions(-)
drivers/gpu/drm/sun4i/sun8i_mixer.c +71 -11
index cc4da11e2c10..0d4695132dae 100644
@@ -318,8 +318,9 @@ static void sun8i_mixer_commit(struct sunxi_engine *engine,
 	regmap_write(bld_regs, SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
 		     pipe_en | SUN8I_MIXER_BLEND_PIPE_CTL_FC_EN(0));
 
-	regmap_write(engine->regs, SUN8I_MIXER_GLOBAL_DBUFF,
-		     SUN8I_MIXER_GLOBAL_DBUFF_ENABLE);
+	if (mixer->cfg->de_type != sun8i_mixer_de33)
+		regmap_write(engine->regs, SUN8I_MIXER_GLOBAL_DBUFF,
+			     SUN8I_MIXER_GLOBAL_DBUFF_ENABLE);
 }
 
 static struct drm_plane **sun8i_layers_init(struct drm_device *drm,
@@ -368,25 +369,31 @@ static void sun8i_mixer_mode_set(struct sunxi_engine *engine,
 				 const struct drm_display_mode *mode)
 {
 	struct sun8i_mixer *mixer = engine_to_sun8i_mixer(engine);
+	struct regmap *bld_regs;
 	u32 bld_base, size, val;
 	bool interlaced;
 
 	bld_base = sun8i_blender_base(mixer);
+	bld_regs = sun8i_blender_regmap(mixer);
 	interlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
 	size = SUN8I_MIXER_SIZE(mode->hdisplay, mode->vdisplay);
 
 	DRM_DEBUG_DRIVER("Updating global size W: %u H: %u\n",
 			 mode->hdisplay, mode->vdisplay);
 
-	regmap_write(engine->regs, SUN8I_MIXER_GLOBAL_SIZE, size);
-	regmap_write(engine->regs, SUN8I_MIXER_BLEND_OUTSIZE(bld_base), size);
+	if (mixer->cfg->de_type == sun8i_mixer_de33)
+		regmap_write(mixer->top_regs, SUN50I_MIXER_GLOBAL_SIZE, size);
+	else
+		regmap_write(mixer->engine.regs, SUN8I_MIXER_GLOBAL_SIZE, size);
+
+	regmap_write(bld_regs, SUN8I_MIXER_BLEND_OUTSIZE(bld_base), size);
 
 	if (interlaced)
 		val = SUN8I_MIXER_BLEND_OUTCTL_INTERLACED;
 	else
 		val = 0;
 
-	regmap_update_bits(engine->regs, SUN8I_MIXER_BLEND_OUTCTL(bld_base),
+	regmap_update_bits(bld_regs, SUN8I_MIXER_BLEND_OUTCTL(bld_base),
 			   SUN8I_MIXER_BLEND_OUTCTL_INTERLACED, val);
 
 	DRM_DEBUG_DRIVER("Switching display mixer interlaced mode %s\n",
@@ -400,12 +407,29 @@ static const struct sunxi_engine_ops sun8i_engine_ops = {
 };
 
 static const struct regmap_config sun8i_mixer_regmap_config = {
+	.name		= "layers",
 	.reg_bits	= 32,
 	.val_bits	= 32,
 	.reg_stride	= 4,
 	.max_register	= 0xffffc, /* guessed */
 };
 
+static const struct regmap_config sun8i_top_regmap_config = {
+	.name		= "top",
+	.reg_bits	= 32,
+	.val_bits	= 32,
+	.reg_stride	= 4,
+	.max_register	= 0x3c,
+};
+
+static const struct regmap_config sun8i_disp_regmap_config = {
+	.name		= "display",
+	.reg_bits	= 32,
+	.val_bits	= 32,
+	.reg_stride	= 4,
+	.max_register	= 0x20000,
+};
+
 static int sun8i_mixer_of_get_id(struct device_node *node)
 {
 	struct device_node *ep, *remote;
@@ -428,33 +452,45 @@ static int sun8i_mixer_of_get_id(struct device_node *node)
 
 static void sun8i_mixer_init(struct sun8i_mixer *mixer)
 {
+	struct regmap *top_regs, *disp_regs;
 	unsigned int base = sun8i_blender_base(mixer);
 	int plane_cnt, i;
 
+	if (mixer->cfg->de_type == sun8i_mixer_de33) {
+		top_regs = mixer->top_regs;
+		disp_regs = mixer->disp_regs;
+	} else {
+		top_regs = mixer->engine.regs;
+		disp_regs = mixer->engine.regs;
+	}
+
 	/* Enable the mixer */
-	regmap_write(mixer->engine.regs, SUN8I_MIXER_GLOBAL_CTL,
+	regmap_write(top_regs, SUN8I_MIXER_GLOBAL_CTL,
 		     SUN8I_MIXER_GLOBAL_CTL_RT_EN);
 
+	if (mixer->cfg->de_type == sun8i_mixer_de33)
+		regmap_write(top_regs, SUN50I_MIXER_GLOBAL_CLK, 1);
+
 	/* Set background color to black */
-	regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_BKCOLOR(base),
+	regmap_write(disp_regs, SUN8I_MIXER_BLEND_BKCOLOR(base),
 		     SUN8I_MIXER_BLEND_COLOR_BLACK);
 
 	/*
 	 * Set fill color of bottom plane to black. Generally not needed
 	 * except when VI plane is at bottom (zpos = 0) and enabled.
 	 */
-	regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(base),
+	regmap_write(disp_regs, SUN8I_MIXER_BLEND_PIPE_CTL(base),
 		     SUN8I_MIXER_BLEND_PIPE_CTL_FC_EN(0));
-	regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ATTR_FCOLOR(base, 0),
+	regmap_write(disp_regs, SUN8I_MIXER_BLEND_ATTR_FCOLOR(base, 0),
 		     SUN8I_MIXER_BLEND_COLOR_BLACK);
 
 	plane_cnt = mixer->cfg->vi_num + mixer->cfg->ui_num;
 	for (i = 0; i < plane_cnt; i++)
-		regmap_write(mixer->engine.regs,
+		regmap_write(disp_regs,
 			     SUN8I_MIXER_BLEND_MODE(base, i),
 			     SUN8I_MIXER_BLEND_MODE_DEF);
 
-	regmap_update_bits(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(base),
+	regmap_update_bits(disp_regs, SUN8I_MIXER_BLEND_PIPE_CTL(base),
 			   SUN8I_MIXER_BLEND_PIPE_CTL_EN_MSK, 0);
 }
 
@@ -526,6 +562,30 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master,
 		return PTR_ERR(mixer->engine.regs);
 	}
 
+	if (mixer->cfg->de_type == sun8i_mixer_de33) {
+		regs = devm_platform_ioremap_resource_byname(pdev, "top");
+		if (IS_ERR(regs))
+			return PTR_ERR(regs);
+
+		mixer->top_regs = devm_regmap_init_mmio(dev, regs,
+							&sun8i_top_regmap_config);
+		if (IS_ERR(mixer->top_regs)) {
+			dev_err(dev, "Couldn't create the top regmap\n");
+			return PTR_ERR(mixer->top_regs);
+		}
+
+		regs = devm_platform_ioremap_resource_byname(pdev, "display");
+		if (IS_ERR(regs))
+			return PTR_ERR(regs);
+
+		mixer->disp_regs = devm_regmap_init_mmio(dev, regs,
+							 &sun8i_disp_regmap_config);
+		if (IS_ERR(mixer->disp_regs)) {
+			dev_err(dev, "Couldn't create the disp regmap\n");
+			return PTR_ERR(mixer->disp_regs);
+		}
+	}
+
 	mixer->reset = devm_reset_control_get(dev, NULL);
 	if (IS_ERR(mixer->reset)) {
 		dev_err(dev, "Couldn't get our reset line\n");
drivers/gpu/drm/sun4i/sun8i_mixer.h +19 -3
index 43c413052a22..d87d197610e1 100644
@@ -21,6 +21,9 @@
 #define SUN8I_MIXER_GLOBAL_DBUFF		0x8
 #define SUN8I_MIXER_GLOBAL_SIZE			0xc
 
+#define SUN50I_MIXER_GLOBAL_SIZE		0x8
+#define SUN50I_MIXER_GLOBAL_CLK			0xc
+
 #define SUN8I_MIXER_GLOBAL_CTL_RT_EN		BIT(0)
 
 #define SUN8I_MIXER_GLOBAL_DBUFF_ENABLE		BIT(0)
@@ -151,6 +154,12 @@ enum {
 	CCSC_D1_MIXER0_LAYOUT,
 };
 
+enum sun8i_mixer_type {
+	sun8i_mixer_de2,
+	sun8i_mixer_de3,
+	sun8i_mixer_de33,
+};
+
 /**
  * struct sun8i_mixer_cfg - mixer HW configuration
  * @vi_num: number of VI channels
@@ -171,8 +180,9 @@ struct sun8i_mixer_cfg {
 	int		scaler_mask;
 	int		ccsc;
 	unsigned long	mod_rate;
-	unsigned int	is_de3 : 1;
+	unsigned int	de_type;
 	unsigned int	scanline_yuv;
+	unsigned int	map[6];
 };
 
 struct sun8i_mixer {
@@ -184,6 +194,9 @@ struct sun8i_mixer {
 
 	struct clk			*bus_clk;
 	struct clk			*mod_clk;
+
+	struct regmap			*top_regs;
+	struct regmap			*disp_regs;
 };
 
 enum {
@@ -220,13 +233,16 @@ sun8i_blender_base(struct sun8i_mixer *mixer)
 static inline struct regmap *
 sun8i_blender_regmap(struct sun8i_mixer *mixer)
 {
-	return mixer->engine.regs;
+	return mixer->cfg->de_type == sun8i_mixer_de33 ?
+		mixer->disp_regs : mixer->engine.regs;
 }
 
 static inline u32
 sun8i_channel_base(struct sun8i_mixer *mixer, int channel)
 {
-	if (mixer->cfg->is_de3)
+	if (mixer->cfg->de_type == sun8i_mixer_de33)
+		return mixer->cfg->map[channel] * 0x20000 + DE2_CH_SIZE;
+	else if (mixer->cfg->de_type == sun8i_mixer_de3)
 		return DE3_CH_BASE + channel * DE3_CH_SIZE;
 	else
 		return DE2_CH_BASE + channel * DE2_CH_SIZE;
Signature · 1 line
2.43.0
#18 lore raw

PATCH v9 13/24 drm: sun4i: de33: mixer: add mixer configuration for the H616

In reply to Chris Morgan

From: Chris Morgan <[email protected]>

The H616 (and related SoC packages sharing the same die) carry the new DE33 display engine.

Add the mixer configuration and a compatible string for the H616 to the mixer.

---
Changelog v7..v8:
- Separate DE33 support and H616 enablement in the mixer.

---
 drivers/gpu/drm/sun4i/sun8i_mixer.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
drivers/gpu/drm/sun4i/sun8i_mixer.c +15 -0
index 0d4695132dae..f774b693634d 100644
@@ -799,6 +799,17 @@ static const struct sun8i_mixer_cfg sun50i_h6_mixer0_cfg = {
 	.vi_num		= 1,
 };
 
+static const struct sun8i_mixer_cfg sun50i_h616_mixer0_cfg = {
+	.ccsc		= CCSC_MIXER0_LAYOUT,
+	.de_type	= sun8i_mixer_de33,
+	.mod_rate	= 600000000,
+	.scaler_mask	= 0xf,
+	.scanline_yuv	= 4096,
+	.ui_num		= 3,
+	.vi_num		= 1,
+	.map		= {0, 6, 7, 8},
+};
+
 static const struct of_device_id sun8i_mixer_of_table[] = {
 	{
 		.compatible = "allwinner,sun8i-a83t-de2-mixer-0",
@@ -844,6 +855,10 @@ static const struct of_device_id sun8i_mixer_of_table[] = {
 		.compatible = "allwinner,sun50i-h6-de3-mixer-0",
 		.data = &sun50i_h6_mixer0_cfg,
 	},
+	{
+		.compatible = "allwinner,sun50i-h616-de33-mixer-0",
+		.data = &sun50i_h616_mixer0_cfg,
+	},
 	{ }
 };
 MODULE_DEVICE_TABLE(of, sun8i_mixer_of_table);
Signature · 1 line
2.43.0
#19 lore raw

PATCH v9 14/24 dt-bindings: allwinner: Add TCON_TOP and TCON_LCD clock/reset defines

In reply to Chris Morgan

From: Chris Morgan <[email protected]>

The Allwinner H700 exposes RGB and LVDS pins as well as a HDMI connector. This requires additional clocks for the TCON_TOP and clock and resets for the TCON_LCD LCD controllers to be defined as per the T507 datasheet (which shares the same die).

---
 include/dt-bindings/clock/sun8i-tcon-top.h | 2 ++
 1 file changed, 2 insertions(+)
include/dt-bindings/clock/sun8i-tcon-top.h +2 -0
index 25164d767835..2a12d047d2e1 100644
@@ -7,5 +7,7 @@
 #define CLK_TCON_TOP_TV0	0
 #define CLK_TCON_TOP_TV1	1
 #define CLK_TCON_TOP_DSI	2
+#define CLK_TCON_TOP_LCD0	3
+#define CLK_TCON_TOP_LCD1	4
 
 #endif /* _DT_BINDINGS_CLOCK_SUN8I_TCON_TOP_H_ */
Signature · 1 line
2.43.0
#20 lore raw

PATCH v9 15/24 dt-bindings: display: sun4i: Add compatible strings for H616 DE

In reply to Chris Morgan

From: Chris Morgan <[email protected]>

Add compatible strings for allwinner,sun50i-h616-display-engine. The device is functionally identical to the allwinner,sun50i-h6-display-engine.

---
 .../allwinner,sun4i-a10-display-engine.yaml   | 39 +++++++++++--------
 1 file changed, 22 insertions(+), 17 deletions(-)
Documentation/devicetree/bindings/display/allwinner,sun4i-a10-display-engine.yaml +22 -17
index e6088f379f70..81a173b41534 100644
@@ -48,23 +48,28 @@ description: |
 
 properties:
   compatible:
-    enum:
-      - allwinner,sun4i-a10-display-engine
-      - allwinner,sun5i-a10s-display-engine
-      - allwinner,sun5i-a13-display-engine
-      - allwinner,sun6i-a31-display-engine
-      - allwinner,sun6i-a31s-display-engine
-      - allwinner,sun7i-a20-display-engine
-      - allwinner,sun8i-a23-display-engine
-      - allwinner,sun8i-a33-display-engine
-      - allwinner,sun8i-a83t-display-engine
-      - allwinner,sun8i-h3-display-engine
-      - allwinner,sun8i-r40-display-engine
-      - allwinner,sun8i-v3s-display-engine
-      - allwinner,sun9i-a80-display-engine
-      - allwinner,sun20i-d1-display-engine
-      - allwinner,sun50i-a64-display-engine
-      - allwinner,sun50i-h6-display-engine
+    oneOf:
+      - enum:
+          - allwinner,sun4i-a10-display-engine
+          - allwinner,sun5i-a10s-display-engine
+          - allwinner,sun5i-a13-display-engine
+          - allwinner,sun6i-a31-display-engine
+          - allwinner,sun6i-a31s-display-engine
+          - allwinner,sun7i-a20-display-engine
+          - allwinner,sun8i-a23-display-engine
+          - allwinner,sun8i-a33-display-engine
+          - allwinner,sun8i-a83t-display-engine
+          - allwinner,sun8i-h3-display-engine
+          - allwinner,sun8i-r40-display-engine
+          - allwinner,sun8i-v3s-display-engine
+          - allwinner,sun9i-a80-display-engine
+          - allwinner,sun20i-d1-display-engine
+          - allwinner,sun50i-a64-display-engine
+          - allwinner,sun50i-h6-display-engine
+      - items:
+          - enum:
+              - allwinner,sun50i-h616-display-engine
+          - const: allwinner,sun50i-h6-display-engine
 
   allwinner,pipelines:
     $ref: /schemas/types.yaml#/definitions/phandle-array
Signature · 1 line
2.43.0
#21 lore raw

PATCH v9 16/24 dt-bindings: display: sun4i: Add compatible strings for H616 TCON TOP

In reply to Chris Morgan

From: Chris Morgan <[email protected]>

Add compatible string for allwinner,sun50i-h616-tcon-top with a fallback string of allwinner,sun50i-h6-tcon-top.

---
 .../display/allwinner,sun8i-r40-tcon-top.yaml       | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)
Documentation/devicetree/bindings/display/allwinner,sun8i-r40-tcon-top.yaml +9 -4
index 7d849c4095a3..80f1e49f5b7a 100644
@@ -39,10 +39,15 @@ properties:
     const: 1
 
   compatible:
-    enum:
-      - allwinner,sun8i-r40-tcon-top
-      - allwinner,sun20i-d1-tcon-top
-      - allwinner,sun50i-h6-tcon-top
+    oneOf:
+      - enum:
+          - allwinner,sun8i-r40-tcon-top
+          - allwinner,sun20i-d1-tcon-top
+          - allwinner,sun50i-h6-tcon-top
+      - items:
+          - enum:
+              - allwinner,sun50i-h616-tcon-top
+          - const: allwinner,sun50i-h6-tcon-top
 
   reg:
     maxItems: 1
Signature · 1 line
2.43.0
#22 lore raw

PATCH v9 17/24 dt-bindings: sram: sunxi-sram: Add H616 SRAM C compatible

In reply to Chris Morgan

From: Chris Morgan <[email protected]>

Add a compatible string for the H616 SRAM C region which is functionally similar to the A64 SRAM C region.

---
 .../bindings/sram/allwinner,sun4i-a10-system-control.yaml     | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
Documentation/devicetree/bindings/sram/allwinner,sun4i-a10-system-control.yaml +3 -1
index a7236f7db4ec..976d3320c803 100644
@@ -102,7 +102,9 @@ patternProperties:
                       - allwinner,sun7i-a20-sram-d
                   - const: allwinner,sun4i-a10-sram-d
               - items:
-                  - const: allwinner,sun50i-h6-sram-c
+                  - enum:
+                      - allwinner,sun50i-h6-sram-c
+                      - allwinner,sun50i-h616-sram-c
                   - const: allwinner,sun50i-a64-sram-c
 
 required:
Signature · 1 line
2.43.0
#23 lore raw

PATCH v9 18/24 dt-bindings: display: Add R40 and H616 display engine compatibles

In reply to Chris Morgan

From: Chris Morgan <[email protected]>

Add display engine compatible for the R40 LCD controller, and for the H616 TV and LCD controller which is functionally identical to the R40.

---
 .../bindings/display/allwinner,sun4i-a10-tcon.yaml     | 10 ++++++++++
 1 file changed, 10 insertions(+)
Documentation/devicetree/bindings/display/allwinner,sun4i-a10-tcon.yaml +10 -0
index 724d93b9193b..caed517c68de 100644
@@ -29,6 +29,7 @@ properties:
       - const: allwinner,sun8i-a33-tcon
       - const: allwinner,sun8i-a83t-tcon-lcd
       - const: allwinner,sun8i-a83t-tcon-tv
+      - const: allwinner,sun8i-r40-tcon-lcd
       - const: allwinner,sun8i-r40-tcon-tv
       - const: allwinner,sun8i-v3s-tcon
       - const: allwinner,sun9i-a80-tcon-lcd
@@ -53,9 +54,15 @@ properties:
               - allwinner,sun50i-a64-tcon-tv
           - const: allwinner,sun8i-a83t-tcon-tv
 
+      - items:
+          - enum:
+              - allwinner,sun50i-h616-tcon-lcd
+          - const: allwinner,sun8i-r40-tcon-lcd
+
       - items:
           - enum:
               - allwinner,sun50i-h6-tcon-tv
+              - allwinner,sun50i-h616-tcon-tv
           - const: allwinner,sun8i-r40-tcon-tv
 
   reg:
@@ -231,6 +238,7 @@ allOf:
           contains:
             enum:
               - allwinner,sun8i-a83t-tcon-lcd
+              - allwinner,sun8i-r40-tcon-lcd
               - allwinner,sun8i-v3s-tcon
               - allwinner,sun9i-a80-tcon-lcd
               - allwinner,sun20i-d1-tcon-lcd
@@ -280,6 +288,7 @@ allOf:
               - allwinner,sun9i-a80-tcon-lcd
               - allwinner,sun4i-a10-tcon
               - allwinner,sun8i-a83t-tcon-lcd
+              - allwinner,sun8i-r40-tcon-lcd
               - allwinner,sun20i-d1-tcon-lcd
 
     then:
@@ -297,6 +306,7 @@ allOf:
               - allwinner,sun8i-a23-tcon
               - allwinner,sun8i-a33-tcon
               - allwinner,sun8i-a83t-tcon-lcd
+              - allwinner,sun8i-r40-tcon-lcd
               - allwinner,sun20i-d1-tcon-lcd
 
     then:
Signature · 1 line
2.43.0
#24 lore raw

PATCH v9 19/24 drm/sun4i: tcon: Add support for R40 LCD

In reply to Chris Morgan

From: Chris Morgan <[email protected]>

The Allwinner H616 and related SOCs have an LCD timing controller (TCON) which is compatible with the R40 SOC's controller and existing sun4i driver. The H616 does not expose this controller but the H700 and T507 (based on the same die) do. The controller supports LVDS and RGB output.

Add quirks and compatible string to cover these SOCs.

---
 drivers/gpu/drm/sun4i/sun4i_tcon.c | 9 +++++++++
 1 file changed, 9 insertions(+)
drivers/gpu/drm/sun4i/sun4i_tcon.c +9 -0
index 960e83c8291d..8cc8488483ec 100644
@@ -1514,6 +1514,14 @@ static const struct sun4i_tcon_quirks sun8i_a83t_tv_quirks = {
 	.has_channel_1		= true,
 };
 
+static const struct sun4i_tcon_quirks sun8i_r40_lcd_quirks = {
+	.supports_lvds		= true,
+	.has_channel_0		= true,
+	.set_mux		= sun8i_r40_tcon_tv_set_mux,
+	.dclk_min_div		= 1,
+	.setup_lvds_phy		= sun6i_tcon_setup_lvds_phy,
+};
+
 static const struct sun4i_tcon_quirks sun8i_r40_tv_quirks = {
 	.has_channel_1		= true,
 	.polarity_in_ch0	= true,
@@ -1555,6 +1563,7 @@ const struct of_device_id sun4i_tcon_of_table[] = {
 	{ .compatible = "allwinner,sun8i-a33-tcon", .data = &sun8i_a33_quirks },
 	{ .compatible = "allwinner,sun8i-a83t-tcon-lcd", .data = &sun8i_a83t_lcd_quirks },
 	{ .compatible = "allwinner,sun8i-a83t-tcon-tv", .data = &sun8i_a83t_tv_quirks },
+	{ .compatible = "allwinner,sun8i-r40-tcon-lcd", .data = &sun8i_r40_lcd_quirks },
 	{ .compatible = "allwinner,sun8i-r40-tcon-tv", .data = &sun8i_r40_tv_quirks },
 	{ .compatible = "allwinner,sun8i-v3s-tcon", .data = &sun8i_v3s_quirks },
 	{ .compatible = "allwinner,sun9i-a80-tcon-lcd", .data = &sun9i_a80_tcon_lcd_quirks },
Signature · 1 line
2.43.0
#25 lore raw

PATCH v9 20/24 arm64: dts: allwinner: h616: add display engine, bus and mixer nodes

In reply to Chris Morgan

From: Chris Morgan <[email protected]>

The Allwinner H616 and variants (H618, H700 and T507) have a new display engine variant (DE33). Support has been added to the existing DE2/DE3 sun4i driver in a previous patch series (x). The variant is selected via the appropriate mixer device tree compatible string.

Add the respective device-tree nodes for the DE, bus, clock and mixer to the H616 DTSI, and the matching SRAM section for the DE.

---
 .../arm64/boot/dts/allwinner/sun50i-h616.dtsi | 59 +++++++++++++++++++
 1 file changed, 59 insertions(+)
arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi +59 -0
index cdce3dcb8ec0..542d129da9c3 100644
@@ -94,6 +94,13 @@ l2_cache: l2-cache {
 		};
 	};
 
+	de: display-engine {
+		compatible = "allwinner,sun50i-h616-display-engine",
+			     "allwinner,sun50i-h6-display-engine";
+		allwinner,pipelines = <&mixer0>;
+		status = "disabled";
+	};
+
 	reserved-memory {
 		#address-cells = <2>;
 		#size-cells = <2>;
@@ -150,6 +157,52 @@ soc {
 		#size-cells = <1>;
 		ranges = <0x0 0x0 0x0 0x40000000>;
 
+		bus: bus@1000000 {
+			compatible = "allwinner,sun50i-h616-de33",
+				     "allwinner,sun50i-a64-de2";
+			reg = <0x1000000 0x400000>;
+			allwinner,sram = <&de33_sram 1>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 0x1000000 0x400000>;
+
+			display_clocks: clock@8000 {
+				compatible = "allwinner,sun50i-h616-de33-clk";
+				reg = <0x8000 0x100>;
+				clocks = <&ccu CLK_BUS_DE>, <&ccu CLK_DE>;
+				clock-names = "bus", "mod";
+				resets = <&ccu RST_BUS_DE>;
+				#clock-cells = <1>;
+				#reset-cells = <1>;
+			};
+
+			mixer0: mixer@100000 {
+				compatible = "allwinner,sun50i-h616-de33-mixer-0";
+				reg = <0x100000 0x100000>,
+				      <0x8100 0x40>,
+				      <0x280000 0x20000>;
+				reg-names = "layers", "top", "display";
+				clocks = <&display_clocks CLK_BUS_MIXER0>,
+					 <&display_clocks CLK_MIXER0>;
+				clock-names = "bus", "mod";
+				resets = <&display_clocks RST_MIXER0>;
+				iommus = <&iommu 0>;
+
+				ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					mixer0_out: port@1 {
+						reg = <1>;
+
+						mixer0_out_tcon_top_mixer0: endpoint {
+							remote-endpoint = <&tcon_top_mixer0_in_mixer0>;
+						};
+					};
+				};
+			};
+		};
+
 		crypto: crypto@1904000 {
 			compatible = "allwinner,sun50i-h616-crypto";
 			reg = <0x01904000 0x800>;
@@ -173,6 +226,12 @@ sram_c: sram@28000 {
 				#address-cells = <1>;
 				#size-cells = <1>;
 				ranges = <0 0x00028000 0x30000>;
+
+				de33_sram: sram-section@0 {
+					compatible = "allwinner,sun50i-h616-sram-c",
+						     "allwinner,sun50i-a64-sram-c";
+					reg = <0x0000 0x1e000>;
+				};
 			};
 		};
 
Signature · 1 line
2.43.0
#26 lore raw

PATCH v9 21/24 arm64: dts: allwinner: h616: Add TCON nodes to H616 DTSI

In reply to Chris Morgan

From: Chris Morgan <[email protected]>

The Allwinner H616 has a display pipeline similar to other Allwinner devices, specifically the A10, but using a newer display engine revision (DE33).

Not all output pins are exposed on all package variants, for example only the H700 and T507 have LCD pins exposed, but all variants support HDMI output. However on the die these are connected to a display engine via a TCON TOP and one or more timing controllers (TCONs).

HDMI output support is not provided in this series (but will be in a subsequent patch) so for now note this within the relevant node to prevent a DT compiler error.

Add TCON nodes for the TOP, and the LCD and TV timing controllers. The timing controllers are compatible with the existing R40 driver.

---
 .../arm64/boot/dts/allwinner/sun50i-h616.dtsi | 139 ++++++++++++++++++
 1 file changed, 139 insertions(+)
arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi +139 -0
index 542d129da9c3..129ce78ae5f3 100644
@@ -7,9 +7,12 @@
 #include <dt-bindings/clock/sun50i-h616-ccu.h>
 #include <dt-bindings/clock/sun50i-h6-r-ccu.h>
 #include <dt-bindings/clock/sun6i-rtc.h>
+#include <dt-bindings/clock/sun8i-de2.h>
+#include <dt-bindings/clock/sun8i-tcon-top.h>
 #include <dt-bindings/reset/sun50i-h616-ccu.h>
 #include <dt-bindings/reset/sun50i-h6-r-ccu.h>
 #include <dt-bindings/thermal/thermal.h>
+#include <dt-bindings/reset/sun8i-de2.h>
 
 / {
 	interrupt-parent = <&gic>;
@@ -912,6 +915,142 @@ ohci3: usb@5311400 {
 			status = "disabled";
 		};
 
+		tcon_top: tcon-top@6510000 {
+			compatible = "allwinner,sun50i-h616-tcon-top",
+				     "allwinner,sun50i-h6-tcon-top";
+			reg = <0x06510000 0x1000>;
+			clocks = <&ccu CLK_BUS_TCON_TOP>,
+				 <&ccu CLK_TCON_TV0>;
+			clock-names = "bus", "tcon-tv0";
+			clock-output-names = "tcon-top-tv0";
+			#clock-cells = <1>;
+			resets = <&ccu RST_BUS_TCON_TOP>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				tcon_top_mixer0_in: port@0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+
+					tcon_top_mixer0_in_mixer0: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&mixer0_out_tcon_top_mixer0>;
+					};
+				};
+
+				tcon_top_mixer0_out: port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+
+					tcon_top_mixer0_out_tcon_lcd0: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&tcon_lcd0_in_tcon_top_mixer0>;
+					};
+
+					tcon_top_mixer0_out_tcon_tv0: endpoint@2 {
+						reg = <2>;
+						remote-endpoint = <&tcon_tv0_in_tcon_top_mixer0>;
+					};
+				};
+
+				tcon_top_hdmi_in: port@4 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <4>;
+
+					tcon_top_hdmi_in_tcon_tv0: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&tcon_tv0_out_tcon_top>;
+					};
+				};
+
+				tcon_top_hdmi_out: port@5 {
+					reg = <5>;
+
+					tcon_top_hdmi_out_hdmi: endpoint {
+						/* placeholder for HDMI  - remote-endpoint = <&hdmi_in_tcon_top>;*/
+					};
+				};
+			};
+		};
+
+		tcon_lcd0: lcd-controller@6511000 {
+			compatible = "allwinner,sun50i-h616-tcon-lcd",
+				     "allwinner,sun8i-r40-tcon-lcd";
+			reg = <0x06511000 0x1000>;
+			interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_TCON_LCD0>, <&ccu CLK_TCON_LCD0>;
+			clock-names = "ahb", "tcon-ch0";
+			clock-output-names = "tcon-data-clock";
+			#clock-cells = <0>;
+			resets = <&ccu RST_BUS_TCON_LCD0>, <&ccu RST_BUS_LVDS>;
+			reset-names = "lcd", "lvds";
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				tcon_lcd0_in: port@0 {
+					reg = <0>;
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					tcon_lcd0_in_tcon_top_mixer0: endpoint {
+						remote-endpoint = <&tcon_top_mixer0_out_tcon_lcd0>;
+					};
+				};
+
+				tcon_lcd0_out: port@1 {
+					reg = <1>;
+					#address-cells = <1>;
+					#size-cells = <0>;
+				};
+			};
+		};
+
+		tcon_tv0: lcd-controller@6515000 {
+			compatible = "allwinner,sun50i-h616-tcon-tv",
+				     "allwinner,sun8i-r40-tcon-tv";
+			reg = <0x06515000 0x1000>;
+			interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_TCON_TV0>,
+				 <&tcon_top CLK_TCON_TOP_TV0>;
+			clock-names = "ahb", "tcon-ch1";
+			#clock-cells = <0>;
+			resets = <&ccu RST_BUS_TCON_TV0>;
+			reset-names = "lcd";
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				tcon_tv0_in: port@0 {
+					reg = <0>;
+
+					tcon_tv0_in_tcon_top_mixer0: endpoint {
+						remote-endpoint = <&tcon_top_mixer0_out_tcon_tv0>;
+					};
+				};
+
+				tcon_tv0_out: port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+
+					tcon_tv0_out_tcon_top: endpoint@1 {
+						reg = <1>;
+						remote-endpoint = <&tcon_top_hdmi_in_tcon_tv0>;
+					};
+				};
+			};
+		};
+
 		rtc: rtc@7000000 {
 			compatible = "allwinner,sun50i-h616-rtc";
 			reg = <0x07000000 0x400>;
Signature · 1 line
2.43.0
#27 lore raw

PATCH v9 22/24 arm64: dts: allwinner: h616: add LCD and LVDS pins

In reply to Chris Morgan

From: Chris Morgan <[email protected]>

The Allwinner H616 (and its H618, H700 and T507 package variants with the same die) have 28 video output pins for RGB/SPI and LVDS display. These are in GPIO Bank D and are multiplexed.

In RGB mode, pins PD0-PD23 are for 24-bit RGB pixel output, pins PD24-PD27 are for clock, DE, HSYNC and VSYNC.

In LVDS mode, pins PD0-PD9 are for LVDS0 and LVDS1, and can be configured by the H616 display engine for either one high-resolution (dual link) or two low resolution displays.

Add device tree nodes for the LCD, LVDS0, and LVDS1 pins.

---
 .../arm64/boot/dts/allwinner/sun50i-h616.dtsi | 26 +++++++++++++++++++
 1 file changed, 26 insertions(+)
arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi +26 -0
index 129ce78ae5f3..3d8b412afb88 100644
@@ -325,6 +325,32 @@ ir_rx_pin: ir-rx-pin {
 				function = "ir_rx";
 			};
 
+			/omit-if-no-ref/
+			lcd0_rgb888_pins: lcd0-rgb888-pins {
+				pins = "PD0", "PD1", "PD2", "PD3",
+				       "PD4", "PD5", "PD6", "PD7",
+				       "PD8", "PD9", "PD10", "PD11",
+				       "PD12", "PD13", "PD14", "PD15",
+				       "PD16", "PD17", "PD18", "PD19",
+				       "PD20", "PD21", "PD22", "PD23",
+				       "PD24", "PD25", "PD26", "PD27";
+				function = "lcd0";
+			};
+
+			/omit-if-no-ref/
+			lvds0_pins: lvds0-pins {
+				pins = "PD0", "PD1", "PD2", "PD3", "PD4",
+				       "PD5", "PD6", "PD7", "PD8", "PD9";
+				function = "lvds0";
+			};
+
+			/omit-if-no-ref/
+			lvds1_pins: lvds1-pins {
+				pins = "PD10", "PD11", "PD12", "PD13", "PD14",
+				       "PD15", "PD16", "PD17", "PD18", "PD19";
+				function = "lvds1";
+			};
+
 			mmc0_pins: mmc0-pins {
 				pins = "PF0", "PF1", "PF2", "PF3",
 				       "PF4", "PF5";
Signature · 1 line
2.43.0
#28 lore raw

PATCH v9 23/24 arm64: dts: allwinner: rg35xx: Add GPIO backlight control

In reply to Chris Morgan

From: Chris Morgan <[email protected]>

The LCD backlight for this device can be exposed as a simple GPIO- controlled device. It would be more accurately modelled using PWM to enable brightness control, however the PWM driver design for the H616 is not yet upstreamed.

Add a GPIO backlight node to the DTS.

---
 .../boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts | 6 ++++++
 1 file changed, 6 insertions(+)
arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts +6 -0
index 7e17ca07892d..95f2ae04bd95 100644
@@ -21,6 +21,12 @@ aliases {
 		serial0 = &uart0;
 	};
 
+	backlight: backlight {
+		compatible = "gpio-backlight";
+		gpios = <&pio 3 28 GPIO_ACTIVE_HIGH>; // PD28
+		default-on;
+	};
+
 	battery: battery {
 		compatible = "simple-battery";
 		constant-charge-current-max-microamp = <1024000>;
Signature · 1 line
2.43.0
#29 lore raw

Re: [PATCH V9 23/24] arm64: dts: allwinner: rg35xx: Add GPIO backlight control

On Wed, 7 May 2025 15:19:42 -0500
Chris Morgan <[email protected]> wrote:

Hi Chris,

Quoted 6 lines

From: Chris Morgan <[email protected]>

The LCD backlight for this device can be exposed as a simple GPIO- controlled device. It would be more accurately modelled using PWM to enable brightness control, however the PWM driver design for the H616 is not yet upstreamed.

I don't think this is right then: First there should be no notion of a "driver being upstreamed" in a *DT* patch, as "the driver" is a Linux speciality, which the DT itself doesn't care about.
And secondly we should not chicken out and go with an interim solution.

So I guess we need to wait for the PWM binding to appear.

Cheers,
Andre

Quoted 25 lines

Add a GPIO backlight node to the DTS.

---
 .../boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts | 6 ++++++
 1 file changed, 6 insertions(+)
arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts +6 -0
index 7e17ca07892d..95f2ae04bd95 100644
@@ -21,6 +21,12 @@ aliases {
 		serial0 = &uart0;
 	};
 
+	backlight: backlight {
+		compatible = "gpio-backlight";
+		gpios = <&pio 3 28 GPIO_ACTIVE_HIGH>; // PD28
+		default-on;
+	};
+
 	battery: battery {
 		compatible = "simple-battery";
 		constant-charge-current-max-microamp = <1024000>;
#30 lore raw

Re: [PATCH V9 23/24] arm64: dts: allwinner: rg35xx: Add GPIO backlight control

Quoted 17 lines · Andre Przywara

On Wed, 7 May 2025 15:19:42 -0500
Chris Morgan <[email protected]> wrote:

Hi Chris,

Quoted 6 lines

From: Chris Morgan <[email protected]>

The LCD backlight for this device can be exposed as a simple GPIO- controlled device. It would be more accurately modelled using PWM to enable brightness control, however the PWM driver design for the H616 is not yet upstreamed.

I don't think this is right then: First there should be no notion of a "driver being upstreamed" in a *DT* patch, as "the driver" is a Linux speciality, which the DT itself doesn't care about.
And secondly we should not chicken out and go with an interim solution.

Quoted 4 lines

So I guess we need to wait for the PWM binding to appear.

Cheers,
Andre

Okay, so then I can drop the backlight (and might as well drop the LCD bindings as well) until the PWM is upstreamed. I just figured "something" for now is okay, but we can wait.

This is the specific series I'm tracking [1]... adding support for the H616 would just require a little bit of boilerplate code and a new compatible string once that gets upstreamed.

[1] https://lore.kernel.org/linux-sunxi/[email protected]/

Thank you,
Chris

Quoted 27 lines
Quoted 26 lines

Add a GPIO backlight node to the DTS.

---
 .../boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts | 6 ++++++
 1 file changed, 6 insertions(+)
arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts +6 -0
index 7e17ca07892d..95f2ae04bd95 100644
@@ -21,6 +21,12 @@ aliases {
 		serial0 = &uart0;
 	};
 
+	backlight: backlight {
+		compatible = "gpio-backlight";
+		gpios = <&pio 3 28 GPIO_ACTIVE_HIGH>; // PD28
+		default-on;
+	};
+
 	battery: battery {
 		compatible = "simple-battery";
 		constant-charge-current-max-microamp = <1024000>;
#31 lore raw

PATCH v9 24/24 arm64: dts: allwinner: rg35xx: Enable LCD output

In reply to Chris Morgan

From: Chris Morgan <[email protected]>

The RG35XX has a 640x480 RGB/SPI LCD panel, supported by the SoC display pipeline and an NV3052C controller. The H616 SOC's GPIO bank D contains the muxed display pins for RGB and LVDS output support.

Enable the display engine and LCD timing controller, configure the panel, and add a fixed 3.3v GPIO-controlled regulator for the panel, and a VCC supply for the display pins as per the other GPIO banks.

---
 .../sun50i-h700-anbernic-rg35xx-2024.dts      | 59 +++++++++++++++++++
 1 file changed, 59 insertions(+)
arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts +59 -0
index 95f2ae04bd95..260c2d55a86e 100644
@@ -187,6 +187,49 @@ reg_vcc5v: regulator-vcc5v { /* USB-C power input */
 		regulator-min-microvolt = <5000000>;
 		regulator-max-microvolt = <5000000>;
 	};
+
+	reg_lcd: regulator-gpio-lcd-vdd {
+		compatible = "regulator-fixed";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-name = "vdd-lcd";
+		gpio = <&pio 8 15 GPIO_ACTIVE_HIGH>; // PI15
+		enable-active-high;
+	};
+
+	spi_lcd: spi {
+		compatible = "spi-gpio";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		sck-gpios = <&pio 8 9 GPIO_ACTIVE_HIGH>; // PI9
+		mosi-gpios = <&pio 8 10 GPIO_ACTIVE_HIGH>; // PI10
+		cs-gpios = <&pio 8 8 GPIO_ACTIVE_HIGH>; // PI8
+		num-chipselects = <1>;
+
+		panel: panel@0 {
+			compatible = "anbernic,rg35xx-plus-panel";
+
+			reg = <0>;
+
+			spi-max-frequency = <3125000>;
+			spi-3wire;
+
+			reset-gpios = <&pio 8 14 GPIO_ACTIVE_LOW>; // PI14
+
+			backlight = <&backlight>;
+			power-supply = <&reg_lcd>;
+
+			pinctrl-0 = <&lcd0_rgb888_pins>;
+			pinctrl-names = "default";
+
+			port {
+				panel_in_rgb: endpoint {
+					remote-endpoint = <&tcon_lcd0_out_lcd>;
+				};
+			};
+		};
+	};
 };
 
 &codec {
@@ -199,6 +242,10 @@ &cpu0 {
 	cpu-supply = <&reg_dcdc1>;
 };
 
+&de {
+	status = "okay";
+};
+
 &ehci0 {
 	status = "okay";
 };
@@ -218,6 +265,7 @@ &ohci0 {
 &pio {
 	vcc-pa-supply = <&reg_cldo3>;
 	vcc-pc-supply = <&reg_cldo3>;
+	vcc-pd-supply = <&reg_cldo3>;
 	vcc-pe-supply = <&reg_cldo3>;
 	vcc-pf-supply = <&reg_cldo3>;
 	vcc-pg-supply = <&reg_aldo4>;
@@ -377,3 +425,14 @@ &usbotg {
 &usbphy {
 	status = "okay";
 };
+
+&tcon_lcd0 {
+	status = "okay";
+};
+
+&tcon_lcd0_out {
+	tcon_lcd0_out_lcd: endpoint@1 {
+		reg = <1>;
+		remote-endpoint = <&panel_in_rgb>;
+	};
+};
Signature · 1 line
2.43.0
maintainer
#32 lore raw
In reply to Chris Morgan
Quoted 47 lines · Chris Morgan

From: Chris Morgan <[email protected]>

I've spoken with Ryan and he agreed to let me take over this series to get the display engine working on the Allwinner H616. I've taken his previous patch series for Display Engine 3.3 and combined it with the LCD controller patch series. I've also fixed a few additional bugs and made some changes to the device tree bindings.

Changes since V8:
- Combined the DE33 [1] series and the LCD [2] series to better track all patches necessary to output to an LCD display for the Allwinner H700.
- Added a required LVDS reset as requested here [3].
- Added compatible strings with a fallback for allwinner,sun50i-h616-display-engine, allwinner,sun50i-h616-tcon-top, and allwinner,sun50i-h616-sram-c.
- Added binding documentation for the LCD controller.
- Renamed the de3_sram device tree node to de33_sram.
- Corrected the LVDS reset for the LCD controller binding.
- Removed the PWM pins from the pincontroller bindings, as PWM is not yet supported.
- Reordered the patches so that a binding or a device tree node is not referenced before it is defined.

[1] https://lore.kernel.org/linux-sunxi/[email protected]/
[2] https://lore.kernel.org/linux-sunxi/[email protected]/
[3] https://lore.kernel.org/linux-sunxi/38669808.XM6RcZxFsP@jernej-laptop/

Chris Morgan (24):
dt-bindings: clock: sun50i-h616-ccu: Add LVDS reset
clk: sunxi-ng: h616: Add LVDS reset for LCD TCON
drm: sun4i: de2/de3: add mixer version enum
drm: sun4i: de2/de3: refactor mixer initialisation
drm: sun4i: de2/de3: add generic blender register reference function
drm: sun4i: de2/de3: use generic register reference function for layer
configuration
dt-bindings: allwinner: add H616 DE33 bus binding
dt-bindings: allwinner: add H616 DE33 clock binding
dt-bindings: allwinner: add H616 DE33 mixer binding
clk: sunxi-ng: ccu: add Display Engine 3.3 (DE33) support
drm: sun4i: de33: vi_scaler: add Display Engine 3.3 (DE33) support
drm: sun4i: de33: mixer: add Display Engine 3.3 (DE33) support
drm: sun4i: de33: mixer: add mixer configuration for the H616
dt-bindings: allwinner: Add TCON_TOP and TCON_LCD clock/reset defines
dt-bindings: display: sun4i: Add compatible strings for H616 DE
dt-bindings: display: sun4i: Add compatible strings for H616 TCON TOP

Quoted 8 lines

dt-bindings: sram: sunxi-sram: Add H616 SRAM C compatible
dt-bindings: display: Add R40 and H616 display engine compatibles drm/sun4i: tcon: Add support for R40 LCD
arm64: dts: allwinner: h616: add display engine, bus and mixer nodes
arm64: dts: allwinner: h616: Add TCON nodes to H616 DTSI
arm64: dts: allwinner: h616: add LCD and LVDS pins
arm64: dts: allwinner: rg35xx: Add GPIO backlight control
arm64: dts: allwinner: rg35xx: Enable LCD output

What's the base for this series? It didn't apply for me (using b4).

Rob

#33 lore raw
Quoted 57 lines · Rob Herring
Quoted 47 lines · Chris Morgan

From: Chris Morgan <[email protected]>

I've spoken with Ryan and he agreed to let me take over this series to get the display engine working on the Allwinner H616. I've taken his previous patch series for Display Engine 3.3 and combined it with the LCD controller patch series. I've also fixed a few additional bugs and made some changes to the device tree bindings.

Changes since V8:
- Combined the DE33 [1] series and the LCD [2] series to better track all patches necessary to output to an LCD display for the Allwinner H700.
- Added a required LVDS reset as requested here [3].
- Added compatible strings with a fallback for allwinner,sun50i-h616-display-engine, allwinner,sun50i-h616-tcon-top, and allwinner,sun50i-h616-sram-c.
- Added binding documentation for the LCD controller.
- Renamed the de3_sram device tree node to de33_sram.
- Corrected the LVDS reset for the LCD controller binding.
- Removed the PWM pins from the pincontroller bindings, as PWM is not yet supported.
- Reordered the patches so that a binding or a device tree node is not referenced before it is defined.

[1] https://lore.kernel.org/linux-sunxi/[email protected]/
[2] https://lore.kernel.org/linux-sunxi/[email protected]/
[3] https://lore.kernel.org/linux-sunxi/38669808.XM6RcZxFsP@jernej-laptop/

Chris Morgan (24):
dt-bindings: clock: sun50i-h616-ccu: Add LVDS reset
clk: sunxi-ng: h616: Add LVDS reset for LCD TCON
drm: sun4i: de2/de3: add mixer version enum
drm: sun4i: de2/de3: refactor mixer initialisation
drm: sun4i: de2/de3: add generic blender register reference function
drm: sun4i: de2/de3: use generic register reference function for layer
configuration
dt-bindings: allwinner: add H616 DE33 bus binding
dt-bindings: allwinner: add H616 DE33 clock binding
dt-bindings: allwinner: add H616 DE33 mixer binding
clk: sunxi-ng: ccu: add Display Engine 3.3 (DE33) support
drm: sun4i: de33: vi_scaler: add Display Engine 3.3 (DE33) support
drm: sun4i: de33: mixer: add Display Engine 3.3 (DE33) support
drm: sun4i: de33: mixer: add mixer configuration for the H616
dt-bindings: allwinner: Add TCON_TOP and TCON_LCD clock/reset defines
dt-bindings: display: sun4i: Add compatible strings for H616 DE
dt-bindings: display: sun4i: Add compatible strings for H616 TCON TOP

Quoted 8 lines

dt-bindings: sram: sunxi-sram: Add H616 SRAM C compatible
dt-bindings: display: Add R40 and H616 display engine compatibles drm/sun4i: tcon: Add support for R40 LCD
arm64: dts: allwinner: h616: add display engine, bus and mixer nodes
arm64: dts: allwinner: h616: Add TCON nodes to H616 DTSI
arm64: dts: allwinner: h616: add LCD and LVDS pins
arm64: dts: allwinner: rg35xx: Add GPIO backlight control
arm64: dts: allwinner: rg35xx: Enable LCD output

Quoted 4 lines

What's the base for this series? It didn't apply for me (using b4).

Rob

I tested it on top of linux-next next-20250508 and revert "arm64: dts: allwinner: h616: Add Mali GPU node"

#34 lore raw
In reply to Chris Morgan
Quoted 8 lines · Chris Morgan

From: Chris Morgan <[email protected]>

I've spoken with Ryan and he agreed to let me take over this series to get the display engine working on the Allwinner H616. I've taken his previous patch series for Display Engine 3.3 and combined it with the LCD controller patch series. I've also fixed a few additional bugs and made some changes to the device tree bindings.

Quoted 4 lines

Changes since V8:
- Combined the DE33 [1] series and the LCD [2] series to better track all patches necessary to output to an LCD display for the Allwinner H700.

You have here three or four different subsystems. This does not make it easier, but it makes it a huge patchbomb with unspecific or complex base.

Such combination makes no sense, because anyway it will have to be split per subsystem. You just know made it difficult for maintainers to review and apply, because they cannot apply entire set.

Best regards,
Krzysztof

#35 lore raw
Quoted 18 lines · Krzysztof Kozlowski
Quoted 8 lines · Chris Morgan

From: Chris Morgan <[email protected]>

I've spoken with Ryan and he agreed to let me take over this series to get the display engine working on the Allwinner H616. I've taken his previous patch series for Display Engine 3.3 and combined it with the LCD controller patch series. I've also fixed a few additional bugs and made some changes to the device tree bindings.

Quoted 4 lines

Changes since V8:
- Combined the DE33 [1] series and the LCD [2] series to better track all patches necessary to output to an LCD display for the Allwinner H700.

You have here three or four different subsystems. This does not make it easier, but it makes it a huge patchbomb with unspecific or complex base.

Quoted 7 lines

Such combination makes no sense, because anyway it will have to be split per subsystem. You just know made it difficult for maintainers to review and apply, because they cannot apply entire set.

Best regards,
Krzysztof

I apologize, please ignore this series then. I'll break it up more among subsystem lines and note that they are all related in the notes.

Thank you.

#36 lore raw

Re: (subset) [PATCH V9 00/24] drm: sun4i: add Display Engine 3.3 (DE33) support

In reply to Chris Morgan
Quoted 9 lines · Chris Morgan

From: Chris Morgan <[email protected]>

I've spoken with Ryan and he agreed to let me take over this series to get the display engine working on the Allwinner H616. I've taken his previous patch series for Display Engine 3.3 and combined it with the LCD controller patch series. I've also fixed a few additional bugs and made some changes to the device tree bindings.

[...]

Applied to sunxi/clk-for-6.16 in local tree, thanks!

[01/24] dt-bindings: clock: sun50i-h616-ccu: Add LVDS reset

        commit: 20fb4ac9cda06527cf60c5ec7dda7c463c9c81be
[02/24] clk: sunxi-ng: h616: Add LVDS reset for LCD TCON
        commit: 390e4cfe87cb99c80614235cbc4651c3b315a9c9

Best regards,

Signature · 1 line
Chen-Yu Tsai <[email protected]>