All of lore.kernel.org
 help / color / mirror / Atom feed
* [PROTO][PATCH 00/10] R-Car D3 LVDS/HDMI support (with PLL)
@ 2018-08-14 13:49 ` Ulrich Hecht
  0 siblings, 0 replies; 50+ messages in thread
From: Ulrich Hecht @ 2018-08-14 13:49 UTC (permalink / raw)
  To: laurent.pinchart
  Cc: linux-renesas-soc, dri-devel, jacopo+renesas,
	kieran.bingham+renesas, Ulrich Hecht

Hi!

This is a prototype extension of the series "R-Car D3 LVDS/HDMI support"
that includes an up-port of the LVDS PLL support in the BSP.

While this is prototype-quality code, there are in my judgment no serious
hacks in it.  The most significant deviation in behavior between this and
the BSP code is that the LVDS PLL setup is not done in two steps, but in one
go as the LVDS device is enabled.  This was easier to implement, and works
just as fine.

Instructions for testing this are found at
https://elinux.org/User:Uli/D3_HDMI_Test, including links to git trees based
on renesas-drivers and drm-next, as well as config files for each.

CU
Uli


Jacopo Mondi (1):
  drm: rcar-du: lvds: Handle LVDS interface reset

Kieran Bingham (1):
  arm64: dts: renesas: r8a77995: Add LVDS support

Koji Matsuoka (5):
  drm: rcar-du: Add clk_set_rate for external clock device
  drm: rcar-du: Fix digital RGB routing for R8A77995
  drm/bridge: adv7511: Add max-clock, min-vrefresh options
  drm: rcar-du: Fix procedure for extal and dotclkin selection
  arm64: dts: r8a77995-draak: set external clock for DU

Ulrich Hecht (3):
  drm: rcar-du: Add r8a77995 device support
  drm: rcar-du: lvds: LVDS PLL support
  arm64: dts: renesas: r8a77995-draak: add HDMI output

 arch/arm64/boot/dts/renesas/r8a77995-draak.dts |  92 +++++++++-
 arch/arm64/boot/dts/renesas/r8a77995.dtsi      |  56 ++++++
 drivers/gpu/drm/bridge/adv7511/adv7511.h       |   7 +
 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c   |  22 +++
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c         |  33 ++--
 drivers/gpu/drm/rcar-du/rcar_du_crtc.h         |   4 +
 drivers/gpu/drm/rcar-du/rcar_du_drv.c          |  28 +++
 drivers/gpu/drm/rcar-du/rcar_du_drv.h          |   4 +
 drivers/gpu/drm/rcar-du/rcar_du_group.c        |  18 +-
 drivers/gpu/drm/rcar-du/rcar_lvds.c            | 227 +++++++++++++++++++++++++
 drivers/gpu/drm/rcar-du/rcar_lvds_regs.h       |  44 ++++-
 11 files changed, 517 insertions(+), 18 deletions(-)

-- 
2.7.4

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

* [PROTO][PATCH 00/10] R-Car D3 LVDS/HDMI support (with PLL)
@ 2018-08-14 13:49 ` Ulrich Hecht
  0 siblings, 0 replies; 50+ messages in thread
From: Ulrich Hecht @ 2018-08-14 13:49 UTC (permalink / raw)
  To: laurent.pinchart
  Cc: linux-renesas-soc, kieran.bingham+renesas, jacopo+renesas,
	Ulrich Hecht, dri-devel

Hi!

This is a prototype extension of the series "R-Car D3 LVDS/HDMI support"
that includes an up-port of the LVDS PLL support in the BSP.

While this is prototype-quality code, there are in my judgment no serious
hacks in it.  The most significant deviation in behavior between this and
the BSP code is that the LVDS PLL setup is not done in two steps, but in one
go as the LVDS device is enabled.  This was easier to implement, and works
just as fine.

Instructions for testing this are found at
https://elinux.org/User:Uli/D3_HDMI_Test, including links to git trees based
on renesas-drivers and drm-next, as well as config files for each.

CU
Uli


Jacopo Mondi (1):
  drm: rcar-du: lvds: Handle LVDS interface reset

Kieran Bingham (1):
  arm64: dts: renesas: r8a77995: Add LVDS support

Koji Matsuoka (5):
  drm: rcar-du: Add clk_set_rate for external clock device
  drm: rcar-du: Fix digital RGB routing for R8A77995
  drm/bridge: adv7511: Add max-clock, min-vrefresh options
  drm: rcar-du: Fix procedure for extal and dotclkin selection
  arm64: dts: r8a77995-draak: set external clock for DU

Ulrich Hecht (3):
  drm: rcar-du: Add r8a77995 device support
  drm: rcar-du: lvds: LVDS PLL support
  arm64: dts: renesas: r8a77995-draak: add HDMI output

 arch/arm64/boot/dts/renesas/r8a77995-draak.dts |  92 +++++++++-
 arch/arm64/boot/dts/renesas/r8a77995.dtsi      |  56 ++++++
 drivers/gpu/drm/bridge/adv7511/adv7511.h       |   7 +
 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c   |  22 +++
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c         |  33 ++--
 drivers/gpu/drm/rcar-du/rcar_du_crtc.h         |   4 +
 drivers/gpu/drm/rcar-du/rcar_du_drv.c          |  28 +++
 drivers/gpu/drm/rcar-du/rcar_du_drv.h          |   4 +
 drivers/gpu/drm/rcar-du/rcar_du_group.c        |  18 +-
 drivers/gpu/drm/rcar-du/rcar_lvds.c            | 227 +++++++++++++++++++++++++
 drivers/gpu/drm/rcar-du/rcar_lvds_regs.h       |  44 ++++-
 11 files changed, 517 insertions(+), 18 deletions(-)

-- 
2.7.4

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

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

* [PROTO][PATCH 01/10] drm: rcar-du: Add clk_set_rate for external clock device
  2018-08-14 13:49 ` Ulrich Hecht
@ 2018-08-14 13:49   ` Ulrich Hecht
  -1 siblings, 0 replies; 50+ messages in thread
From: Ulrich Hecht @ 2018-08-14 13:49 UTC (permalink / raw)
  To: laurent.pinchart
  Cc: linux-renesas-soc, dri-devel, jacopo+renesas,
	kieran.bingham+renesas, Koji Matsuoka

From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>

Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
---
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index b52b3e8..cd6803a 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -229,6 +229,7 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
 		unsigned long rate;
 		u32 extdiv;
 
+		clk_set_rate(rcrtc->extclock, mode_clock);
 		extclk = clk_get_rate(rcrtc->extclock);
 		if (rcdu->info->dpll_ch & (1 << rcrtc->index)) {
 			unsigned long target = mode_clock;
-- 
2.7.4

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

* [PROTO][PATCH 01/10] drm: rcar-du: Add clk_set_rate for external clock device
@ 2018-08-14 13:49   ` Ulrich Hecht
  0 siblings, 0 replies; 50+ messages in thread
From: Ulrich Hecht @ 2018-08-14 13:49 UTC (permalink / raw)
  To: laurent.pinchart
  Cc: linux-renesas-soc, kieran.bingham+renesas, jacopo+renesas,
	Koji Matsuoka, dri-devel

From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>

Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
---
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index b52b3e8..cd6803a 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -229,6 +229,7 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
 		unsigned long rate;
 		u32 extdiv;
 
+		clk_set_rate(rcrtc->extclock, mode_clock);
 		extclk = clk_get_rate(rcrtc->extclock);
 		if (rcdu->info->dpll_ch & (1 << rcrtc->index)) {
 			unsigned long target = mode_clock;
-- 
2.7.4

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

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

* [PROTO][PATCH 02/10] drm: rcar-du: Add r8a77995 device support
  2018-08-14 13:49 ` Ulrich Hecht
@ 2018-08-14 13:49   ` Ulrich Hecht
  -1 siblings, 0 replies; 50+ messages in thread
From: Ulrich Hecht @ 2018-08-14 13:49 UTC (permalink / raw)
  To: laurent.pinchart
  Cc: linux-renesas-soc, dri-devel, jacopo+renesas,
	kieran.bingham+renesas, Ulrich Hecht

Add support for the R-Car D3 (R8A77995) SoC to the R-Car DU driver.

Based on patch by Koji Matsuoka <koji.matsuoka.xm@renesas.com>.

Signed-off-by: Ulrich Hecht <uli+renesas@fpond.eu>
---
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c  | 17 ++++++-----------
 drivers/gpu/drm/rcar-du/rcar_du_drv.c   | 26 ++++++++++++++++++++++++++
 drivers/gpu/drm/rcar-du/rcar_du_drv.h   |  1 +
 drivers/gpu/drm/rcar-du/rcar_du_group.c |  3 ++-
 4 files changed, 35 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index cd6803a..9153e7a 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -53,14 +53,6 @@ static void rcar_du_crtc_clr(struct rcar_du_crtc *rcrtc, u32 reg, u32 clr)
 		      rcar_du_read(rcdu, rcrtc->mmio_offset + reg) & ~clr);
 }
 
-static void rcar_du_crtc_set(struct rcar_du_crtc *rcrtc, u32 reg, u32 set)
-{
-	struct rcar_du_device *rcdu = rcrtc->group->dev;
-
-	rcar_du_write(rcdu, rcrtc->mmio_offset + reg,
-		      rcar_du_read(rcdu, rcrtc->mmio_offset + reg) | set);
-}
-
 static void rcar_du_crtc_clr_set(struct rcar_du_crtc *rcrtc, u32 reg,
 				 u32 clr, u32 set)
 {
@@ -527,7 +519,8 @@ static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc)
 	 * actively driven).
 	 */
 	interlaced = rcrtc->crtc.mode.flags & DRM_MODE_FLAG_INTERLACE;
-	rcar_du_crtc_clr_set(rcrtc, DSYSR, DSYSR_TVM_MASK | DSYSR_SCM_MASK,
+	rcar_du_crtc_clr_set(rcrtc, DSYSR,
+			     DSYSR_TVM_MASK | DSYSR_SCM_MASK | DSYSR_ILTS,
 			     (interlaced ? DSYSR_SCM_INT_VIDEO : 0) |
 			     DSYSR_TVM_MASTER);
 
@@ -596,7 +589,9 @@ static void rcar_du_crtc_stop(struct rcar_du_crtc *rcrtc)
 	 * Select switch sync mode. This stops display operation and configures
 	 * the HSYNC and VSYNC signals as inputs.
 	 */
-	rcar_du_crtc_clr_set(rcrtc, DSYSR, DSYSR_TVM_MASK, DSYSR_TVM_SWITCH);
+	rcar_du_crtc_clr_set(rcrtc, DSYSR, DSYSR_TVM_MASK | DSYSR_ILTS,
+		rcar_du_needs(rcrtc->group->dev, RCAR_DU_QUIRK_TVM_MASTER_ONLY) ?
+		DSYSR_TVM_MASTER : DSYSR_TVM_SWITCH);
 
 	rcar_du_group_start_stop(rcrtc->group, false);
 }
@@ -744,7 +739,7 @@ static int rcar_du_crtc_enable_vblank(struct drm_crtc *crtc)
 	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
 
 	rcar_du_crtc_write(rcrtc, DSRCR, DSRCR_VBCL);
-	rcar_du_crtc_set(rcrtc, DIER, DIER_VBE);
+	rcar_du_crtc_clr_set(rcrtc, DIER, DIER_TVE | DIER_FRE, DIER_VBE);
 	rcrtc->vblank_enable = true;
 
 	return 0;
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
index 56f9472..5c2f764 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
@@ -294,6 +294,31 @@ static const struct rcar_du_device_info rcar_du_r8a77970_info = {
 	.num_lvds = 1,
 };
 
+static const struct rcar_du_device_info rcar_du_r8a77995_info = {
+	.gen = 3,
+	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
+		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
+		  | RCAR_DU_FEATURE_VSP1_SOURCE,
+	.quirks = RCAR_DU_QUIRK_TVM_MASTER_ONLY,
+	.channels_mask = BIT(1) | BIT(0),
+	.routes = {
+		/* R8A77995 has two LVDS output and one RGB output. */
+		[RCAR_DU_OUTPUT_DPAD0] = {
+			.possible_crtcs = BIT(0) | BIT(1),
+			.port = 0,
+		},
+		[RCAR_DU_OUTPUT_LVDS0] = {
+			.possible_crtcs = BIT(0),
+			.port = 1,
+		},
+		[RCAR_DU_OUTPUT_LVDS1] = {
+			.possible_crtcs = BIT(1),
+			.port = 2,
+		},
+	},
+	.num_lvds = 2,
+};
+
 static const struct of_device_id rcar_du_of_table[] = {
 	{ .compatible = "renesas,du-r8a7743", .data = &rzg1_du_r8a7743_info },
 	{ .compatible = "renesas,du-r8a7745", .data = &rzg1_du_r8a7745_info },
@@ -307,6 +332,7 @@ static const struct of_device_id rcar_du_of_table[] = {
 	{ .compatible = "renesas,du-r8a7796", .data = &rcar_du_r8a7796_info },
 	{ .compatible = "renesas,du-r8a77965", .data = &rcar_du_r8a77965_info },
 	{ .compatible = "renesas,du-r8a77970", .data = &rcar_du_r8a77970_info },
+	{ .compatible = "renesas,du-r8a77995", .data = &rcar_du_r8a77995_info },
 	{ }
 };
 
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
index b3a25e8..6257405 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
@@ -32,6 +32,7 @@ struct rcar_du_device;
 #define RCAR_DU_FEATURE_VSP1_SOURCE	(1 << 2)	/* Has inputs from VSP1 */
 
 #define RCAR_DU_QUIRK_ALIGN_128B	(1 << 0)	/* Align pitches to 128 bytes */
+#define RCAR_DU_QUIRK_TVM_MASTER_ONLY	(1 << 1)	/* Does not have TV switch/sync modes */
 
 /*
  * struct rcar_du_output_routing - Output routing specification
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c
index d539cb2..9a0a694 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
@@ -178,7 +178,8 @@ void rcar_du_group_put(struct rcar_du_group *rgrp)
 static void __rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool start)
 {
 	rcar_du_group_write(rgrp, DSYSR,
-		(rcar_du_group_read(rgrp, DSYSR) & ~(DSYSR_DRES | DSYSR_DEN)) |
+		(rcar_du_group_read(rgrp, DSYSR) &
+		 ~(DSYSR_DRES | DSYSR_DEN | DSYSR_ILTS)) |
 		(start ? DSYSR_DEN : DSYSR_DRES));
 }
 
-- 
2.7.4

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

* [PROTO][PATCH 02/10] drm: rcar-du: Add r8a77995 device support
@ 2018-08-14 13:49   ` Ulrich Hecht
  0 siblings, 0 replies; 50+ messages in thread
From: Ulrich Hecht @ 2018-08-14 13:49 UTC (permalink / raw)
  To: laurent.pinchart
  Cc: linux-renesas-soc, kieran.bingham+renesas, jacopo+renesas,
	Ulrich Hecht, dri-devel

Add support for the R-Car D3 (R8A77995) SoC to the R-Car DU driver.

Based on patch by Koji Matsuoka <koji.matsuoka.xm@renesas.com>.

Signed-off-by: Ulrich Hecht <uli+renesas@fpond.eu>
---
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c  | 17 ++++++-----------
 drivers/gpu/drm/rcar-du/rcar_du_drv.c   | 26 ++++++++++++++++++++++++++
 drivers/gpu/drm/rcar-du/rcar_du_drv.h   |  1 +
 drivers/gpu/drm/rcar-du/rcar_du_group.c |  3 ++-
 4 files changed, 35 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index cd6803a..9153e7a 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -53,14 +53,6 @@ static void rcar_du_crtc_clr(struct rcar_du_crtc *rcrtc, u32 reg, u32 clr)
 		      rcar_du_read(rcdu, rcrtc->mmio_offset + reg) & ~clr);
 }
 
-static void rcar_du_crtc_set(struct rcar_du_crtc *rcrtc, u32 reg, u32 set)
-{
-	struct rcar_du_device *rcdu = rcrtc->group->dev;
-
-	rcar_du_write(rcdu, rcrtc->mmio_offset + reg,
-		      rcar_du_read(rcdu, rcrtc->mmio_offset + reg) | set);
-}
-
 static void rcar_du_crtc_clr_set(struct rcar_du_crtc *rcrtc, u32 reg,
 				 u32 clr, u32 set)
 {
@@ -527,7 +519,8 @@ static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc)
 	 * actively driven).
 	 */
 	interlaced = rcrtc->crtc.mode.flags & DRM_MODE_FLAG_INTERLACE;
-	rcar_du_crtc_clr_set(rcrtc, DSYSR, DSYSR_TVM_MASK | DSYSR_SCM_MASK,
+	rcar_du_crtc_clr_set(rcrtc, DSYSR,
+			     DSYSR_TVM_MASK | DSYSR_SCM_MASK | DSYSR_ILTS,
 			     (interlaced ? DSYSR_SCM_INT_VIDEO : 0) |
 			     DSYSR_TVM_MASTER);
 
@@ -596,7 +589,9 @@ static void rcar_du_crtc_stop(struct rcar_du_crtc *rcrtc)
 	 * Select switch sync mode. This stops display operation and configures
 	 * the HSYNC and VSYNC signals as inputs.
 	 */
-	rcar_du_crtc_clr_set(rcrtc, DSYSR, DSYSR_TVM_MASK, DSYSR_TVM_SWITCH);
+	rcar_du_crtc_clr_set(rcrtc, DSYSR, DSYSR_TVM_MASK | DSYSR_ILTS,
+		rcar_du_needs(rcrtc->group->dev, RCAR_DU_QUIRK_TVM_MASTER_ONLY) ?
+		DSYSR_TVM_MASTER : DSYSR_TVM_SWITCH);
 
 	rcar_du_group_start_stop(rcrtc->group, false);
 }
@@ -744,7 +739,7 @@ static int rcar_du_crtc_enable_vblank(struct drm_crtc *crtc)
 	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
 
 	rcar_du_crtc_write(rcrtc, DSRCR, DSRCR_VBCL);
-	rcar_du_crtc_set(rcrtc, DIER, DIER_VBE);
+	rcar_du_crtc_clr_set(rcrtc, DIER, DIER_TVE | DIER_FRE, DIER_VBE);
 	rcrtc->vblank_enable = true;
 
 	return 0;
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
index 56f9472..5c2f764 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
@@ -294,6 +294,31 @@ static const struct rcar_du_device_info rcar_du_r8a77970_info = {
 	.num_lvds = 1,
 };
 
+static const struct rcar_du_device_info rcar_du_r8a77995_info = {
+	.gen = 3,
+	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
+		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
+		  | RCAR_DU_FEATURE_VSP1_SOURCE,
+	.quirks = RCAR_DU_QUIRK_TVM_MASTER_ONLY,
+	.channels_mask = BIT(1) | BIT(0),
+	.routes = {
+		/* R8A77995 has two LVDS output and one RGB output. */
+		[RCAR_DU_OUTPUT_DPAD0] = {
+			.possible_crtcs = BIT(0) | BIT(1),
+			.port = 0,
+		},
+		[RCAR_DU_OUTPUT_LVDS0] = {
+			.possible_crtcs = BIT(0),
+			.port = 1,
+		},
+		[RCAR_DU_OUTPUT_LVDS1] = {
+			.possible_crtcs = BIT(1),
+			.port = 2,
+		},
+	},
+	.num_lvds = 2,
+};
+
 static const struct of_device_id rcar_du_of_table[] = {
 	{ .compatible = "renesas,du-r8a7743", .data = &rzg1_du_r8a7743_info },
 	{ .compatible = "renesas,du-r8a7745", .data = &rzg1_du_r8a7745_info },
@@ -307,6 +332,7 @@ static const struct of_device_id rcar_du_of_table[] = {
 	{ .compatible = "renesas,du-r8a7796", .data = &rcar_du_r8a7796_info },
 	{ .compatible = "renesas,du-r8a77965", .data = &rcar_du_r8a77965_info },
 	{ .compatible = "renesas,du-r8a77970", .data = &rcar_du_r8a77970_info },
+	{ .compatible = "renesas,du-r8a77995", .data = &rcar_du_r8a77995_info },
 	{ }
 };
 
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
index b3a25e8..6257405 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
@@ -32,6 +32,7 @@ struct rcar_du_device;
 #define RCAR_DU_FEATURE_VSP1_SOURCE	(1 << 2)	/* Has inputs from VSP1 */
 
 #define RCAR_DU_QUIRK_ALIGN_128B	(1 << 0)	/* Align pitches to 128 bytes */
+#define RCAR_DU_QUIRK_TVM_MASTER_ONLY	(1 << 1)	/* Does not have TV switch/sync modes */
 
 /*
  * struct rcar_du_output_routing - Output routing specification
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c
index d539cb2..9a0a694 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
@@ -178,7 +178,8 @@ void rcar_du_group_put(struct rcar_du_group *rgrp)
 static void __rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool start)
 {
 	rcar_du_group_write(rgrp, DSYSR,
-		(rcar_du_group_read(rgrp, DSYSR) & ~(DSYSR_DRES | DSYSR_DEN)) |
+		(rcar_du_group_read(rgrp, DSYSR) &
+		 ~(DSYSR_DRES | DSYSR_DEN | DSYSR_ILTS)) |
 		(start ? DSYSR_DEN : DSYSR_DRES));
 }
 
-- 
2.7.4

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

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

* [PROTO][PATCH 03/10] drm: rcar-du: Fix digital RGB routing for R8A77995
  2018-08-14 13:49 ` Ulrich Hecht
@ 2018-08-14 13:49   ` Ulrich Hecht
  -1 siblings, 0 replies; 50+ messages in thread
From: Ulrich Hecht @ 2018-08-14 13:49 UTC (permalink / raw)
  To: laurent.pinchart
  Cc: linux-renesas-soc, dri-devel, jacopo+renesas,
	kieran.bingham+renesas, Koji Matsuoka

From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>

This patch adds D3 definition for DU and fixes digital RGB routing.

Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
---
 drivers/gpu/drm/rcar-du/rcar_du_drv.c   | 3 ++-
 drivers/gpu/drm/rcar-du/rcar_du_drv.h   | 2 ++
 drivers/gpu/drm/rcar-du/rcar_du_group.c | 4 ++++
 3 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
index 5c2f764..d930996 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
@@ -298,7 +298,8 @@ static const struct rcar_du_device_info rcar_du_r8a77995_info = {
 	.gen = 3,
 	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
 		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
-		  | RCAR_DU_FEATURE_VSP1_SOURCE,
+		  | RCAR_DU_FEATURE_VSP1_SOURCE
+		  | RCAR_DU_FEATURE_R8A77995_REGS,
 	.quirks = RCAR_DU_QUIRK_TVM_MASTER_ONLY,
 	.channels_mask = BIT(1) | BIT(0),
 	.routes = {
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
index 6257405..9355b58 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
@@ -30,6 +30,8 @@ struct rcar_du_device;
 #define RCAR_DU_FEATURE_CRTC_IRQ_CLOCK	(1 << 0)	/* Per-CRTC IRQ and clock */
 #define RCAR_DU_FEATURE_EXT_CTRL_REGS	(1 << 1)	/* Has extended control registers */
 #define RCAR_DU_FEATURE_VSP1_SOURCE	(1 << 2)	/* Has inputs from VSP1 */
+#define RCAR_DU_FEATURE_R8A77965_REGS	(1 << 3)	/* Use R8A77965 registers */
+#define RCAR_DU_FEATURE_R8A77995_REGS	(1 << 4)	/* Use R8A77995 registers */
 
 #define RCAR_DU_QUIRK_ALIGN_128B	(1 << 0)	/* Align pitches to 128 bytes */
 #define RCAR_DU_QUIRK_TVM_MASTER_ONLY	(1 << 1)	/* Does not have TV switch/sync modes */
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c
index 9a0a694..371d780 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
@@ -88,6 +88,10 @@ static void rcar_du_group_setup_defr8(struct rcar_du_group *rgrp)
 
 		if (crtc->index / 2 == rgrp->index)
 			defr8 |= DEFR8_DRGBS_DU(crtc->index);
+
+		if (rcar_du_has(rcdu, RCAR_DU_FEATURE_R8A77995_REGS))
+			defr8 |= (DEFR8_DRGBS_DU(rcdu->dpad0_source) |
+				 DEFR8_DRGBS_DU(crtc->index));
 	}
 
 	rcar_du_group_write(rgrp, DEFR8, defr8);
-- 
2.7.4

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

* [PROTO][PATCH 03/10] drm: rcar-du: Fix digital RGB routing for R8A77995
@ 2018-08-14 13:49   ` Ulrich Hecht
  0 siblings, 0 replies; 50+ messages in thread
From: Ulrich Hecht @ 2018-08-14 13:49 UTC (permalink / raw)
  To: laurent.pinchart
  Cc: linux-renesas-soc, kieran.bingham+renesas, jacopo+renesas,
	Koji Matsuoka, dri-devel

From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>

This patch adds D3 definition for DU and fixes digital RGB routing.

Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
---
 drivers/gpu/drm/rcar-du/rcar_du_drv.c   | 3 ++-
 drivers/gpu/drm/rcar-du/rcar_du_drv.h   | 2 ++
 drivers/gpu/drm/rcar-du/rcar_du_group.c | 4 ++++
 3 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
index 5c2f764..d930996 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
@@ -298,7 +298,8 @@ static const struct rcar_du_device_info rcar_du_r8a77995_info = {
 	.gen = 3,
 	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
 		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
-		  | RCAR_DU_FEATURE_VSP1_SOURCE,
+		  | RCAR_DU_FEATURE_VSP1_SOURCE
+		  | RCAR_DU_FEATURE_R8A77995_REGS,
 	.quirks = RCAR_DU_QUIRK_TVM_MASTER_ONLY,
 	.channels_mask = BIT(1) | BIT(0),
 	.routes = {
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
index 6257405..9355b58 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
@@ -30,6 +30,8 @@ struct rcar_du_device;
 #define RCAR_DU_FEATURE_CRTC_IRQ_CLOCK	(1 << 0)	/* Per-CRTC IRQ and clock */
 #define RCAR_DU_FEATURE_EXT_CTRL_REGS	(1 << 1)	/* Has extended control registers */
 #define RCAR_DU_FEATURE_VSP1_SOURCE	(1 << 2)	/* Has inputs from VSP1 */
+#define RCAR_DU_FEATURE_R8A77965_REGS	(1 << 3)	/* Use R8A77965 registers */
+#define RCAR_DU_FEATURE_R8A77995_REGS	(1 << 4)	/* Use R8A77995 registers */
 
 #define RCAR_DU_QUIRK_ALIGN_128B	(1 << 0)	/* Align pitches to 128 bytes */
 #define RCAR_DU_QUIRK_TVM_MASTER_ONLY	(1 << 1)	/* Does not have TV switch/sync modes */
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c
index 9a0a694..371d780 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
@@ -88,6 +88,10 @@ static void rcar_du_group_setup_defr8(struct rcar_du_group *rgrp)
 
 		if (crtc->index / 2 == rgrp->index)
 			defr8 |= DEFR8_DRGBS_DU(crtc->index);
+
+		if (rcar_du_has(rcdu, RCAR_DU_FEATURE_R8A77995_REGS))
+			defr8 |= (DEFR8_DRGBS_DU(rcdu->dpad0_source) |
+				 DEFR8_DRGBS_DU(crtc->index));
 	}
 
 	rcar_du_group_write(rgrp, DEFR8, defr8);
-- 
2.7.4

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

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

* [PROTO][PATCH 04/10] drm: rcar-du: lvds: LVDS PLL support
  2018-08-14 13:49 ` Ulrich Hecht
@ 2018-08-14 13:49   ` Ulrich Hecht
  -1 siblings, 0 replies; 50+ messages in thread
From: Ulrich Hecht @ 2018-08-14 13:49 UTC (permalink / raw)
  To: laurent.pinchart
  Cc: linux-renesas-soc, dri-devel, jacopo+renesas,
	kieran.bingham+renesas, Ulrich Hecht

In R-Car D3 and E3, the DU dot clock can be sourced from the LVDS PLL.
This patch enables that PLL if present.

Based on patch by Koji Matsuoka <koji.matsuoka.xm@renesas.com>.

Signed-off-by: Ulrich Hecht <uli+renesas@fpond.eu>
---
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c   |   3 +
 drivers/gpu/drm/rcar-du/rcar_du_crtc.h   |   2 +
 drivers/gpu/drm/rcar-du/rcar_du_drv.c    |   3 +-
 drivers/gpu/drm/rcar-du/rcar_du_drv.h    |   1 +
 drivers/gpu/drm/rcar-du/rcar_du_group.c  |  11 +-
 drivers/gpu/drm/rcar-du/rcar_lvds.c      | 212 +++++++++++++++++++++++++++++++
 drivers/gpu/drm/rcar-du/rcar_lvds_regs.h |  46 ++++++-
 7 files changed, 274 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index 9153e7a..a903456 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -275,6 +275,9 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
 			mode_clock, extrate, rate, escr);
 	}
 
+	if (rcar_du_has(rcdu, RCAR_DU_FEATURE_LVDS_PLL))
+		escr = 0;
+
 	rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? ESCR2 : ESCR,
 			    escr);
 	rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? OTAR2 : OTAR, 0);
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
index 7680cb2..65de551 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
@@ -44,6 +44,7 @@ struct rcar_du_vsp;
  * @group: CRTC group this CRTC belongs to
  * @vsp: VSP feeding video to this CRTC
  * @vsp_pipe: index of the VSP pipeline feeding video to this CRTC
+ * @lvds_ch: index of LVDS
  */
 struct rcar_du_crtc {
 	struct drm_crtc crtc;
@@ -67,6 +68,7 @@ struct rcar_du_crtc {
 	struct rcar_du_group *group;
 	struct rcar_du_vsp *vsp;
 	unsigned int vsp_pipe;
+	int lvds_ch;
 };
 
 #define to_rcar_crtc(c)	container_of(c, struct rcar_du_crtc, crtc)
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
index d930996..3338ef5 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
@@ -299,7 +299,8 @@ static const struct rcar_du_device_info rcar_du_r8a77995_info = {
 	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
 		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
 		  | RCAR_DU_FEATURE_VSP1_SOURCE
-		  | RCAR_DU_FEATURE_R8A77995_REGS,
+		  | RCAR_DU_FEATURE_R8A77995_REGS
+		  | RCAR_DU_FEATURE_LVDS_PLL,
 	.quirks = RCAR_DU_QUIRK_TVM_MASTER_ONLY,
 	.channels_mask = BIT(1) | BIT(0),
 	.routes = {
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
index 9355b58..6009b7d 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
@@ -32,6 +32,7 @@ struct rcar_du_device;
 #define RCAR_DU_FEATURE_VSP1_SOURCE	(1 << 2)	/* Has inputs from VSP1 */
 #define RCAR_DU_FEATURE_R8A77965_REGS	(1 << 3)	/* Use R8A77965 registers */
 #define RCAR_DU_FEATURE_R8A77995_REGS	(1 << 4)	/* Use R8A77995 registers */
+#define RCAR_DU_FEATURE_LVDS_PLL	(1 << 5)	/* Use PLL in LVDS */
 
 #define RCAR_DU_QUIRK_ALIGN_128B	(1 << 0)	/* Align pitches to 128 bytes */
 #define RCAR_DU_QUIRK_TVM_MASTER_ONLY	(1 << 1)	/* Does not have TV switch/sync modes */
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c
index 371d780..44681e3 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
@@ -126,8 +126,15 @@ static void rcar_du_group_setup(struct rcar_du_group *rgrp)
 		 * are setup through per-group registers, only available when
 		 * the group has two channels.
 		 */
-		if ((rcdu->info->gen < 3 && rgrp->index == 0) ||
-		    (rcdu->info->gen == 3 &&  rgrp->num_crtcs > 1))
+		if (rcar_du_has(rcdu, RCAR_DU_FEATURE_LVDS_PLL))
+			rcar_du_group_write(rgrp,
+					    DIDSR, DIDSR_CODE |
+					    DIDSR_LCDS_LVDS0(1) |
+					    DIDSR_LCDS_LVDS0(0) |
+					    DIDSR_PDCS_CLK(1, 0) |
+					    DIDSR_PDCS_CLK(0, 0));
+		else if ((rcdu->info->gen < 3 && rgrp->index == 0) ||
+			 (rcdu->info->gen == 3 &&  rgrp->num_crtcs > 1))
 			rcar_du_group_write(rgrp, DIDSR, DIDSR_CODE);
 	}
 
diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c b/drivers/gpu/drm/rcar-du/rcar_lvds.c
index 4c39de3..cd55576 100644
--- a/drivers/gpu/drm/rcar-du/rcar_lvds.c
+++ b/drivers/gpu/drm/rcar-du/rcar_lvds.c
@@ -23,6 +23,8 @@
 #include <drm/drm_panel.h>
 
 #include "rcar_lvds_regs.h"
+#include "rcar_du_crtc.h"
+#include "rcar_du_drv.h"
 
 /* Keep in sync with the LVDCR0.LVMD hardware register values. */
 enum rcar_lvds_mode {
@@ -65,6 +67,15 @@ struct rcar_lvds {
 #define connector_to_rcar_lvds(connector) \
 	container_of(connector, struct rcar_lvds, connector)
 
+struct pll_info {
+	unsigned int pllclk;
+	unsigned int diff;
+	unsigned int clk_n;
+	unsigned int clk_m;
+	unsigned int clk_e;
+	unsigned int div;
+};
+
 static void rcar_lvds_write(struct rcar_lvds *lvds, u32 reg, u32 data)
 {
 	iowrite32(data, lvds->mmio + reg);
@@ -155,6 +166,198 @@ static u32 rcar_lvds_lvdpllcr_gen3(unsigned int freq)
 		return LVDPLLCR_PLLDIVCNT_148M;
 }
 
+static void rcar_lvds_pll_calc(struct rcar_du_crtc *rcrtc,
+				     struct pll_info *pll, unsigned int in_fre,
+				     unsigned int mode_freq, bool edivider)
+{
+	unsigned long diff = (unsigned long)-1;
+	unsigned long fout, fpfd, fvco, n, m, e, div;
+	bool clk_diff_set = true;
+
+	if (in_fre < 12000000 || in_fre > 192000000)
+		return;
+
+	for (n = 0; n < 127; n++) {
+		if (n + 1 < 60 || n + 1 > 120)
+			continue;
+
+		for (m = 0; m < 7; m++) {
+			for (e = 0; e < 1; e++) {
+				if (edivider)
+					fout = (((in_fre / 1000) * (n + 1)) /
+						((m + 1) * (e + 1) * 2)) *
+						1000;
+				else
+					fout = (((in_fre / 1000) * (n + 1)) /
+						(m + 1)) * 1000;
+
+				if (fout > 1039500000)
+					continue;
+
+				fpfd  = (in_fre / (m + 1));
+				if (fpfd < 12000000 || fpfd > 24000000)
+					continue;
+
+				fvco  = (((in_fre / 1000) * (n + 1)) / (m + 1))
+					 * 1000;
+				if (fvco < 900000000 || fvco > 1800000000)
+					continue;
+
+				fout = fout / 7; /* 7 divider */
+
+				for (div = 0; div < 64; div++) {
+					diff = abs((long)(fout / (div + 1)) -
+					       (long)mode_freq);
+
+					if (clk_diff_set ||
+					    (diff == 0 ||
+					    pll->diff > diff)) {
+						pll->diff = diff;
+						pll->clk_n = n;
+						pll->clk_m = m;
+						pll->clk_e = e;
+						pll->pllclk = fout;
+						pll->div = div;
+
+						clk_diff_set = false;
+
+						if (diff == 0)
+							return;
+					}
+				}
+			}
+		}
+	}
+}
+
+static void rcar_lvds_pll_pre_start(struct rcar_lvds *lvds,
+				    struct rcar_du_crtc *rcrtc)
+{
+	const struct drm_display_mode *mode =
+				&rcrtc->crtc.state->adjusted_mode;
+	unsigned int mode_freq = mode->clock * 1000;
+	unsigned int ext_clk = 0;
+	struct pll_info *lvds_pll[2];
+	u32 clksel, cksel;
+	int i, ret;
+
+	if (rcrtc->extclock)
+		ext_clk = clk_get_rate(rcrtc->extclock);
+	else
+		dev_warn(lvds->dev, "external clock is not set\n");
+
+	dev_dbg(lvds->dev, "external clock %d Hz\n", ext_clk);
+
+	if (lvds->enabled)
+		return;
+
+	for (i = 0; i < 2; i++) {
+		lvds_pll[i] = kzalloc(sizeof(*lvds_pll), GFP_KERNEL);
+		if (!lvds_pll[i])
+			return;
+	}
+
+	/* software reset release */
+	reset_control_deassert(lvds->rst);
+
+	ret = clk_prepare_enable(lvds->clock);
+	if (ret < 0)
+		goto end;
+
+	for (i = 0; i < 2; i++) {
+		bool edivider;
+
+		if (i == 0)
+			edivider = true;
+		else
+			edivider = false;
+
+		rcar_lvds_pll_calc(rcrtc, lvds_pll[i], ext_clk,
+					 mode_freq, edivider);
+	}
+
+	dev_dbg(lvds->dev, "mode_frequency %d Hz\n", mode_freq);
+
+	if (lvds_pll[1]->diff >= lvds_pll[0]->diff) {
+		/* use E-edivider */
+		i = 0;
+		clksel = LVDPLLCR_OUTCLKSEL_AFTER |
+			 LVDPLLCR_STP_CLKOUTE1_EN;
+	} else {
+		/* do not use E-divider */
+		i = 1;
+		clksel = LVDPLLCR_OUTCLKSEL_BEFORE |
+			 LVDPLLCR_STP_CLKOUTE1_DIS;
+	}
+	dev_dbg(lvds->dev,
+		"E-divider %s\n", (i == 0 ? "is used" : "is not used"));
+
+	dev_dbg(lvds->dev,
+		"pllclk:%u, n:%u, m:%u, e:%u, diff:%u, div:%u\n",
+		 lvds_pll[i]->pllclk, lvds_pll[i]->clk_n, lvds_pll[i]->clk_m,
+		 lvds_pll[i]->clk_e, lvds_pll[i]->diff, lvds_pll[i]->div);
+
+	if (rcrtc->extal_use)
+		cksel = LVDPLLCR_CKSEL_EXTAL;
+	else
+		cksel = LVDPLLCR_CKSEL_DU_DOTCLKIN(rcrtc->index);
+
+	rcar_lvds_write(lvds, LVDPLLCR, LVDPLLCR_PLLON |
+			LVDPLLCR_OCKSEL_7 | clksel | LVDPLLCR_CLKOUT_ENABLE |
+			cksel | (lvds_pll[i]->clk_e << 10) |
+			(lvds_pll[i]->clk_n << 3) | lvds_pll[i]->clk_m);
+
+	if (lvds_pll[i]->div > 0)
+		rcar_lvds_write(lvds, LVDDIV, LVDDIV_DIVSEL |
+				LVDDIV_DIVRESET | lvds_pll[i]->div);
+	else
+		rcar_lvds_write(lvds, LVDDIV, 0);
+
+	dev_dbg(lvds->dev, "LVDPLLCR: 0x%x\n",
+		ioread32(lvds->mmio + LVDPLLCR));
+	dev_dbg(lvds->dev, "LVDDIV: 0x%x\n",
+		ioread32(lvds->mmio + LVDDIV));
+
+end:
+	for (i = 0; i < 2; i++)
+		kfree(lvds_pll[i]);
+}
+
+static void rcar_lvds_pll_start(struct rcar_lvds *lvds,
+			       struct rcar_du_crtc *rcrtc)
+{
+	u32 lvdhcr, lvdcr0;
+
+	rcar_lvds_write(lvds, LVDCTRCR, LVDCTRCR_CTR3SEL_ZERO |
+			LVDCTRCR_CTR2SEL_DISP | LVDCTRCR_CTR1SEL_VSYNC |
+			LVDCTRCR_CTR0SEL_HSYNC);
+
+	lvdhcr = LVDCHCR_CHSEL_CH(0, 0) | LVDCHCR_CHSEL_CH(1, 1) |
+		 LVDCHCR_CHSEL_CH(2, 2) | LVDCHCR_CHSEL_CH(3, 3);
+	rcar_lvds_write(lvds, LVDCHCR, lvdhcr);
+
+	rcar_lvds_write(lvds, LVDSTRIPE, 0);
+	/* Turn all the channels on. */
+	rcar_lvds_write(lvds, LVDCR1,
+			LVDCR1_CHSTBY(3) | LVDCR1_CHSTBY(2) |
+			LVDCR1_CHSTBY(1) | LVDCR1_CHSTBY(0) |
+			LVDCR1_CLKSTBY);
+	/*
+	 * Turn the PLL on, set it to LVDS normal mode, wait for the startup
+	 * delay and turn the output on.
+	 */
+	lvdcr0 = (lvds->mode << LVDCR0_LVMD_SHIFT) | LVDCR0_PWD;
+	rcar_lvds_write(lvds, LVDCR0, lvdcr0);
+
+	lvdcr0 |= LVDCR0_LVEN;
+	rcar_lvds_write(lvds, LVDCR0, lvdcr0);
+
+	lvdcr0 |= LVDCR0_LVRES;
+	rcar_lvds_write(lvds, LVDCR0, lvdcr0);
+
+	lvds->enabled = true;
+}
+
 static void rcar_lvds_enable(struct drm_bridge *bridge)
 {
 	struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
@@ -164,6 +367,7 @@ static void rcar_lvds_enable(struct drm_bridge *bridge)
 	 * do we get a state pointer?
 	 */
 	struct drm_crtc *crtc = lvds->bridge.encoder->crtc;
+	struct rcar_du_device *rcdu = to_rcar_crtc(crtc)->group->dev;
 	u32 lvdpllcr;
 	u32 lvdhcr;
 	u32 lvdcr0;
@@ -171,6 +375,12 @@ static void rcar_lvds_enable(struct drm_bridge *bridge)
 
 	WARN_ON(lvds->enabled);
 
+	if (rcar_du_has(rcdu, RCAR_DU_FEATURE_LVDS_PLL)) {
+		rcar_lvds_pll_pre_start(lvds, to_rcar_crtc(crtc));
+		rcar_lvds_pll_start(lvds, to_rcar_crtc(crtc));
+		return;
+	}
+
 	ret = clk_prepare_enable(lvds->clock);
 	if (ret < 0)
 		return;
@@ -264,6 +474,7 @@ static void rcar_lvds_disable(struct drm_bridge *bridge)
 
 	rcar_lvds_write(lvds, LVDCR0, 0);
 	rcar_lvds_write(lvds, LVDCR1, 0);
+	rcar_lvds_write(lvds, LVDPLLCR, 0);
 
 	clk_disable_unprepare(lvds->clock);
 
@@ -522,6 +733,7 @@ static const struct of_device_id rcar_lvds_of_table[] = {
 	{ .compatible = "renesas,r8a7795-lvds", .data = &rcar_lvds_gen3_info },
 	{ .compatible = "renesas,r8a7796-lvds", .data = &rcar_lvds_gen3_info },
 	{ .compatible = "renesas,r8a77970-lvds", .data = &rcar_lvds_r8a77970_info },
+	{ .compatible = "renesas,r8a77995-lvds", .data = &rcar_lvds_gen3_info },
 	{ }
 };
 
diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h b/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
index 2896835..e37db95 100644
--- a/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
+++ b/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
@@ -21,7 +21,7 @@
 #define LVDCR0_PLLON			(1 << 4)
 #define LVDCR0_PWD			(1 << 2)		/* Gen3 only */
 #define LVDCR0_BEN			(1 << 2)		/* Gen2 only */
-#define LVDCR0_LVEN			(1 << 1)		/* Gen2 only */
+#define LVDCR0_LVEN			(1 << 1)
 #define LVDCR0_LVRES			(1 << 0)
 
 #define LVDCR1				0x0004
@@ -46,6 +46,24 @@
 #define LVDPLLCR_PLLDIVCNT_148M		(0x046c1 << 0)
 #define LVDPLLCR_PLLDIVCNT_MASK		(0x7ffff << 0)
 
+/* R-Car D3 */
+#define LVDPLLCR_PLLON			(1 << 22)
+#define LVDPLLCR_PLLSEL_PLL0		(0 << 20)
+#define LVDPLLCR_PLLSEL_LVX		(1 << 20)
+#define LVDPLLCR_PLLSEL_PLL1		(2 << 20)
+#define LVDPLLCR_CKSEL_LVX		(1 << 17)
+#define LVDPLLCR_CKSEL_EXTAL		(3 << 17)
+#define LVDPLLCR_CKSEL_DU_DOTCLKIN0	(5 << 17)
+#define LVDPLLCR_CKSEL_DU_DOTCLKIN1	(7 << 17)
+#define LVDPLLCR_OCKSEL_7		(0 << 16)
+#define LVDPLLCR_OCKSEL_NOT_DIVIDED	(1 << 16)
+#define LVDPLLCR_STP_CLKOUTE1_DIS	(0 << 14)
+#define LVDPLLCR_STP_CLKOUTE1_EN	(1 << 14)
+#define LVDPLLCR_OUTCLKSEL_BEFORE	(0 << 12)
+#define LVDPLLCR_OUTCLKSEL_AFTER	(1 << 12)
+#define LVDPLLCR_CLKOUT_DISABLE		(0 << 11)
+#define LVDPLLCR_CLKOUT_ENABLE		(1 << 11)
+
 #define LVDCTRCR			0x000c
 #define LVDCTRCR_CTR3SEL_ZERO		(0 << 12)
 #define LVDCTRCR_CTR3SEL_ODD		(1 << 12)
@@ -74,4 +92,30 @@
 #define LVDCHCR_CHSEL_CH(n, c)		((((c) - (n)) & 3) << ((n) * 4))
 #define LVDCHCR_CHSEL_MASK(n)		(3 << ((n) * 4))
 
+#define LVDSTRIPE			0x0014
+#define LVDSTRIPE_ST_TRGSEL_DISP	(0 << 2)
+#define LVDSTRIPE_ST_TRGSEL_HSYNC_R	(1 << 2)
+#define LVDSTRIPE_ST_TRGSEL_HSYNC_F	(2 << 2)
+
+#define LVDSTRIPE_ST_SWAP_NORMAL	(0 << 1)
+#define LVDSTRIPE_ST_SWAP_SWAP		(1 << 1)
+#define LVDSTRIPE_ST_ON			(1 << 0)
+
+#define LVDSCR				0x0018
+#define LVDSCR_DEPTH_DP1		(0 << 29)
+#define LVDSCR_DEPTH_DP2		(1 << 29)
+#define LVDSCR_DEPTH_DP3		(2 << 29)
+#define LVDSCR_BANDSET_10KHZ_LESS_THAN	(1 << 28)
+#define LVDSCR_SDIV_SR1			(0 << 22)
+#define LVDSCR_SDIV_SR2			(1 << 22)
+#define LVDSCR_SDIV_SR4			(2 << 22)
+#define LVDSCR_SDIV_SR8			(3 << 22)
+#define LVDSCR_MODE_DOWN		(1 << 21)
+#define LVDSCR_RSTN_ENABLE		(1 << 20)
+
+#define LVDDIV				0x001c
+#define LVDDIV_DIVSEL			(1 << 8)
+#define LVDDIV_DIVRESET			(1 << 7)
+#define LVDDIV_DIVSTP			(1 << 6)
+
 #endif /* __RCAR_LVDS_REGS_H__ */
-- 
2.7.4

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

* [PROTO][PATCH 04/10] drm: rcar-du: lvds: LVDS PLL support
@ 2018-08-14 13:49   ` Ulrich Hecht
  0 siblings, 0 replies; 50+ messages in thread
From: Ulrich Hecht @ 2018-08-14 13:49 UTC (permalink / raw)
  To: laurent.pinchart
  Cc: linux-renesas-soc, kieran.bingham+renesas, jacopo+renesas,
	Ulrich Hecht, dri-devel

In R-Car D3 and E3, the DU dot clock can be sourced from the LVDS PLL.
This patch enables that PLL if present.

Based on patch by Koji Matsuoka <koji.matsuoka.xm@renesas.com>.

Signed-off-by: Ulrich Hecht <uli+renesas@fpond.eu>
---
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c   |   3 +
 drivers/gpu/drm/rcar-du/rcar_du_crtc.h   |   2 +
 drivers/gpu/drm/rcar-du/rcar_du_drv.c    |   3 +-
 drivers/gpu/drm/rcar-du/rcar_du_drv.h    |   1 +
 drivers/gpu/drm/rcar-du/rcar_du_group.c  |  11 +-
 drivers/gpu/drm/rcar-du/rcar_lvds.c      | 212 +++++++++++++++++++++++++++++++
 drivers/gpu/drm/rcar-du/rcar_lvds_regs.h |  46 ++++++-
 7 files changed, 274 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index 9153e7a..a903456 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -275,6 +275,9 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
 			mode_clock, extrate, rate, escr);
 	}
 
+	if (rcar_du_has(rcdu, RCAR_DU_FEATURE_LVDS_PLL))
+		escr = 0;
+
 	rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? ESCR2 : ESCR,
 			    escr);
 	rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? OTAR2 : OTAR, 0);
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
index 7680cb2..65de551 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
@@ -44,6 +44,7 @@ struct rcar_du_vsp;
  * @group: CRTC group this CRTC belongs to
  * @vsp: VSP feeding video to this CRTC
  * @vsp_pipe: index of the VSP pipeline feeding video to this CRTC
+ * @lvds_ch: index of LVDS
  */
 struct rcar_du_crtc {
 	struct drm_crtc crtc;
@@ -67,6 +68,7 @@ struct rcar_du_crtc {
 	struct rcar_du_group *group;
 	struct rcar_du_vsp *vsp;
 	unsigned int vsp_pipe;
+	int lvds_ch;
 };
 
 #define to_rcar_crtc(c)	container_of(c, struct rcar_du_crtc, crtc)
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
index d930996..3338ef5 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
@@ -299,7 +299,8 @@ static const struct rcar_du_device_info rcar_du_r8a77995_info = {
 	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
 		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
 		  | RCAR_DU_FEATURE_VSP1_SOURCE
-		  | RCAR_DU_FEATURE_R8A77995_REGS,
+		  | RCAR_DU_FEATURE_R8A77995_REGS
+		  | RCAR_DU_FEATURE_LVDS_PLL,
 	.quirks = RCAR_DU_QUIRK_TVM_MASTER_ONLY,
 	.channels_mask = BIT(1) | BIT(0),
 	.routes = {
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
index 9355b58..6009b7d 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
@@ -32,6 +32,7 @@ struct rcar_du_device;
 #define RCAR_DU_FEATURE_VSP1_SOURCE	(1 << 2)	/* Has inputs from VSP1 */
 #define RCAR_DU_FEATURE_R8A77965_REGS	(1 << 3)	/* Use R8A77965 registers */
 #define RCAR_DU_FEATURE_R8A77995_REGS	(1 << 4)	/* Use R8A77995 registers */
+#define RCAR_DU_FEATURE_LVDS_PLL	(1 << 5)	/* Use PLL in LVDS */
 
 #define RCAR_DU_QUIRK_ALIGN_128B	(1 << 0)	/* Align pitches to 128 bytes */
 #define RCAR_DU_QUIRK_TVM_MASTER_ONLY	(1 << 1)	/* Does not have TV switch/sync modes */
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c
index 371d780..44681e3 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
@@ -126,8 +126,15 @@ static void rcar_du_group_setup(struct rcar_du_group *rgrp)
 		 * are setup through per-group registers, only available when
 		 * the group has two channels.
 		 */
-		if ((rcdu->info->gen < 3 && rgrp->index == 0) ||
-		    (rcdu->info->gen == 3 &&  rgrp->num_crtcs > 1))
+		if (rcar_du_has(rcdu, RCAR_DU_FEATURE_LVDS_PLL))
+			rcar_du_group_write(rgrp,
+					    DIDSR, DIDSR_CODE |
+					    DIDSR_LCDS_LVDS0(1) |
+					    DIDSR_LCDS_LVDS0(0) |
+					    DIDSR_PDCS_CLK(1, 0) |
+					    DIDSR_PDCS_CLK(0, 0));
+		else if ((rcdu->info->gen < 3 && rgrp->index == 0) ||
+			 (rcdu->info->gen == 3 &&  rgrp->num_crtcs > 1))
 			rcar_du_group_write(rgrp, DIDSR, DIDSR_CODE);
 	}
 
diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c b/drivers/gpu/drm/rcar-du/rcar_lvds.c
index 4c39de3..cd55576 100644
--- a/drivers/gpu/drm/rcar-du/rcar_lvds.c
+++ b/drivers/gpu/drm/rcar-du/rcar_lvds.c
@@ -23,6 +23,8 @@
 #include <drm/drm_panel.h>
 
 #include "rcar_lvds_regs.h"
+#include "rcar_du_crtc.h"
+#include "rcar_du_drv.h"
 
 /* Keep in sync with the LVDCR0.LVMD hardware register values. */
 enum rcar_lvds_mode {
@@ -65,6 +67,15 @@ struct rcar_lvds {
 #define connector_to_rcar_lvds(connector) \
 	container_of(connector, struct rcar_lvds, connector)
 
+struct pll_info {
+	unsigned int pllclk;
+	unsigned int diff;
+	unsigned int clk_n;
+	unsigned int clk_m;
+	unsigned int clk_e;
+	unsigned int div;
+};
+
 static void rcar_lvds_write(struct rcar_lvds *lvds, u32 reg, u32 data)
 {
 	iowrite32(data, lvds->mmio + reg);
@@ -155,6 +166,198 @@ static u32 rcar_lvds_lvdpllcr_gen3(unsigned int freq)
 		return LVDPLLCR_PLLDIVCNT_148M;
 }
 
+static void rcar_lvds_pll_calc(struct rcar_du_crtc *rcrtc,
+				     struct pll_info *pll, unsigned int in_fre,
+				     unsigned int mode_freq, bool edivider)
+{
+	unsigned long diff = (unsigned long)-1;
+	unsigned long fout, fpfd, fvco, n, m, e, div;
+	bool clk_diff_set = true;
+
+	if (in_fre < 12000000 || in_fre > 192000000)
+		return;
+
+	for (n = 0; n < 127; n++) {
+		if (n + 1 < 60 || n + 1 > 120)
+			continue;
+
+		for (m = 0; m < 7; m++) {
+			for (e = 0; e < 1; e++) {
+				if (edivider)
+					fout = (((in_fre / 1000) * (n + 1)) /
+						((m + 1) * (e + 1) * 2)) *
+						1000;
+				else
+					fout = (((in_fre / 1000) * (n + 1)) /
+						(m + 1)) * 1000;
+
+				if (fout > 1039500000)
+					continue;
+
+				fpfd  = (in_fre / (m + 1));
+				if (fpfd < 12000000 || fpfd > 24000000)
+					continue;
+
+				fvco  = (((in_fre / 1000) * (n + 1)) / (m + 1))
+					 * 1000;
+				if (fvco < 900000000 || fvco > 1800000000)
+					continue;
+
+				fout = fout / 7; /* 7 divider */
+
+				for (div = 0; div < 64; div++) {
+					diff = abs((long)(fout / (div + 1)) -
+					       (long)mode_freq);
+
+					if (clk_diff_set ||
+					    (diff == 0 ||
+					    pll->diff > diff)) {
+						pll->diff = diff;
+						pll->clk_n = n;
+						pll->clk_m = m;
+						pll->clk_e = e;
+						pll->pllclk = fout;
+						pll->div = div;
+
+						clk_diff_set = false;
+
+						if (diff == 0)
+							return;
+					}
+				}
+			}
+		}
+	}
+}
+
+static void rcar_lvds_pll_pre_start(struct rcar_lvds *lvds,
+				    struct rcar_du_crtc *rcrtc)
+{
+	const struct drm_display_mode *mode =
+				&rcrtc->crtc.state->adjusted_mode;
+	unsigned int mode_freq = mode->clock * 1000;
+	unsigned int ext_clk = 0;
+	struct pll_info *lvds_pll[2];
+	u32 clksel, cksel;
+	int i, ret;
+
+	if (rcrtc->extclock)
+		ext_clk = clk_get_rate(rcrtc->extclock);
+	else
+		dev_warn(lvds->dev, "external clock is not set\n");
+
+	dev_dbg(lvds->dev, "external clock %d Hz\n", ext_clk);
+
+	if (lvds->enabled)
+		return;
+
+	for (i = 0; i < 2; i++) {
+		lvds_pll[i] = kzalloc(sizeof(*lvds_pll), GFP_KERNEL);
+		if (!lvds_pll[i])
+			return;
+	}
+
+	/* software reset release */
+	reset_control_deassert(lvds->rst);
+
+	ret = clk_prepare_enable(lvds->clock);
+	if (ret < 0)
+		goto end;
+
+	for (i = 0; i < 2; i++) {
+		bool edivider;
+
+		if (i == 0)
+			edivider = true;
+		else
+			edivider = false;
+
+		rcar_lvds_pll_calc(rcrtc, lvds_pll[i], ext_clk,
+					 mode_freq, edivider);
+	}
+
+	dev_dbg(lvds->dev, "mode_frequency %d Hz\n", mode_freq);
+
+	if (lvds_pll[1]->diff >= lvds_pll[0]->diff) {
+		/* use E-edivider */
+		i = 0;
+		clksel = LVDPLLCR_OUTCLKSEL_AFTER |
+			 LVDPLLCR_STP_CLKOUTE1_EN;
+	} else {
+		/* do not use E-divider */
+		i = 1;
+		clksel = LVDPLLCR_OUTCLKSEL_BEFORE |
+			 LVDPLLCR_STP_CLKOUTE1_DIS;
+	}
+	dev_dbg(lvds->dev,
+		"E-divider %s\n", (i == 0 ? "is used" : "is not used"));
+
+	dev_dbg(lvds->dev,
+		"pllclk:%u, n:%u, m:%u, e:%u, diff:%u, div:%u\n",
+		 lvds_pll[i]->pllclk, lvds_pll[i]->clk_n, lvds_pll[i]->clk_m,
+		 lvds_pll[i]->clk_e, lvds_pll[i]->diff, lvds_pll[i]->div);
+
+	if (rcrtc->extal_use)
+		cksel = LVDPLLCR_CKSEL_EXTAL;
+	else
+		cksel = LVDPLLCR_CKSEL_DU_DOTCLKIN(rcrtc->index);
+
+	rcar_lvds_write(lvds, LVDPLLCR, LVDPLLCR_PLLON |
+			LVDPLLCR_OCKSEL_7 | clksel | LVDPLLCR_CLKOUT_ENABLE |
+			cksel | (lvds_pll[i]->clk_e << 10) |
+			(lvds_pll[i]->clk_n << 3) | lvds_pll[i]->clk_m);
+
+	if (lvds_pll[i]->div > 0)
+		rcar_lvds_write(lvds, LVDDIV, LVDDIV_DIVSEL |
+				LVDDIV_DIVRESET | lvds_pll[i]->div);
+	else
+		rcar_lvds_write(lvds, LVDDIV, 0);
+
+	dev_dbg(lvds->dev, "LVDPLLCR: 0x%x\n",
+		ioread32(lvds->mmio + LVDPLLCR));
+	dev_dbg(lvds->dev, "LVDDIV: 0x%x\n",
+		ioread32(lvds->mmio + LVDDIV));
+
+end:
+	for (i = 0; i < 2; i++)
+		kfree(lvds_pll[i]);
+}
+
+static void rcar_lvds_pll_start(struct rcar_lvds *lvds,
+			       struct rcar_du_crtc *rcrtc)
+{
+	u32 lvdhcr, lvdcr0;
+
+	rcar_lvds_write(lvds, LVDCTRCR, LVDCTRCR_CTR3SEL_ZERO |
+			LVDCTRCR_CTR2SEL_DISP | LVDCTRCR_CTR1SEL_VSYNC |
+			LVDCTRCR_CTR0SEL_HSYNC);
+
+	lvdhcr = LVDCHCR_CHSEL_CH(0, 0) | LVDCHCR_CHSEL_CH(1, 1) |
+		 LVDCHCR_CHSEL_CH(2, 2) | LVDCHCR_CHSEL_CH(3, 3);
+	rcar_lvds_write(lvds, LVDCHCR, lvdhcr);
+
+	rcar_lvds_write(lvds, LVDSTRIPE, 0);
+	/* Turn all the channels on. */
+	rcar_lvds_write(lvds, LVDCR1,
+			LVDCR1_CHSTBY(3) | LVDCR1_CHSTBY(2) |
+			LVDCR1_CHSTBY(1) | LVDCR1_CHSTBY(0) |
+			LVDCR1_CLKSTBY);
+	/*
+	 * Turn the PLL on, set it to LVDS normal mode, wait for the startup
+	 * delay and turn the output on.
+	 */
+	lvdcr0 = (lvds->mode << LVDCR0_LVMD_SHIFT) | LVDCR0_PWD;
+	rcar_lvds_write(lvds, LVDCR0, lvdcr0);
+
+	lvdcr0 |= LVDCR0_LVEN;
+	rcar_lvds_write(lvds, LVDCR0, lvdcr0);
+
+	lvdcr0 |= LVDCR0_LVRES;
+	rcar_lvds_write(lvds, LVDCR0, lvdcr0);
+
+	lvds->enabled = true;
+}
+
 static void rcar_lvds_enable(struct drm_bridge *bridge)
 {
 	struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
@@ -164,6 +367,7 @@ static void rcar_lvds_enable(struct drm_bridge *bridge)
 	 * do we get a state pointer?
 	 */
 	struct drm_crtc *crtc = lvds->bridge.encoder->crtc;
+	struct rcar_du_device *rcdu = to_rcar_crtc(crtc)->group->dev;
 	u32 lvdpllcr;
 	u32 lvdhcr;
 	u32 lvdcr0;
@@ -171,6 +375,12 @@ static void rcar_lvds_enable(struct drm_bridge *bridge)
 
 	WARN_ON(lvds->enabled);
 
+	if (rcar_du_has(rcdu, RCAR_DU_FEATURE_LVDS_PLL)) {
+		rcar_lvds_pll_pre_start(lvds, to_rcar_crtc(crtc));
+		rcar_lvds_pll_start(lvds, to_rcar_crtc(crtc));
+		return;
+	}
+
 	ret = clk_prepare_enable(lvds->clock);
 	if (ret < 0)
 		return;
@@ -264,6 +474,7 @@ static void rcar_lvds_disable(struct drm_bridge *bridge)
 
 	rcar_lvds_write(lvds, LVDCR0, 0);
 	rcar_lvds_write(lvds, LVDCR1, 0);
+	rcar_lvds_write(lvds, LVDPLLCR, 0);
 
 	clk_disable_unprepare(lvds->clock);
 
@@ -522,6 +733,7 @@ static const struct of_device_id rcar_lvds_of_table[] = {
 	{ .compatible = "renesas,r8a7795-lvds", .data = &rcar_lvds_gen3_info },
 	{ .compatible = "renesas,r8a7796-lvds", .data = &rcar_lvds_gen3_info },
 	{ .compatible = "renesas,r8a77970-lvds", .data = &rcar_lvds_r8a77970_info },
+	{ .compatible = "renesas,r8a77995-lvds", .data = &rcar_lvds_gen3_info },
 	{ }
 };
 
diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h b/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
index 2896835..e37db95 100644
--- a/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
+++ b/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
@@ -21,7 +21,7 @@
 #define LVDCR0_PLLON			(1 << 4)
 #define LVDCR0_PWD			(1 << 2)		/* Gen3 only */
 #define LVDCR0_BEN			(1 << 2)		/* Gen2 only */
-#define LVDCR0_LVEN			(1 << 1)		/* Gen2 only */
+#define LVDCR0_LVEN			(1 << 1)
 #define LVDCR0_LVRES			(1 << 0)
 
 #define LVDCR1				0x0004
@@ -46,6 +46,24 @@
 #define LVDPLLCR_PLLDIVCNT_148M		(0x046c1 << 0)
 #define LVDPLLCR_PLLDIVCNT_MASK		(0x7ffff << 0)
 
+/* R-Car D3 */
+#define LVDPLLCR_PLLON			(1 << 22)
+#define LVDPLLCR_PLLSEL_PLL0		(0 << 20)
+#define LVDPLLCR_PLLSEL_LVX		(1 << 20)
+#define LVDPLLCR_PLLSEL_PLL1		(2 << 20)
+#define LVDPLLCR_CKSEL_LVX		(1 << 17)
+#define LVDPLLCR_CKSEL_EXTAL		(3 << 17)
+#define LVDPLLCR_CKSEL_DU_DOTCLKIN0	(5 << 17)
+#define LVDPLLCR_CKSEL_DU_DOTCLKIN1	(7 << 17)
+#define LVDPLLCR_OCKSEL_7		(0 << 16)
+#define LVDPLLCR_OCKSEL_NOT_DIVIDED	(1 << 16)
+#define LVDPLLCR_STP_CLKOUTE1_DIS	(0 << 14)
+#define LVDPLLCR_STP_CLKOUTE1_EN	(1 << 14)
+#define LVDPLLCR_OUTCLKSEL_BEFORE	(0 << 12)
+#define LVDPLLCR_OUTCLKSEL_AFTER	(1 << 12)
+#define LVDPLLCR_CLKOUT_DISABLE		(0 << 11)
+#define LVDPLLCR_CLKOUT_ENABLE		(1 << 11)
+
 #define LVDCTRCR			0x000c
 #define LVDCTRCR_CTR3SEL_ZERO		(0 << 12)
 #define LVDCTRCR_CTR3SEL_ODD		(1 << 12)
@@ -74,4 +92,30 @@
 #define LVDCHCR_CHSEL_CH(n, c)		((((c) - (n)) & 3) << ((n) * 4))
 #define LVDCHCR_CHSEL_MASK(n)		(3 << ((n) * 4))
 
+#define LVDSTRIPE			0x0014
+#define LVDSTRIPE_ST_TRGSEL_DISP	(0 << 2)
+#define LVDSTRIPE_ST_TRGSEL_HSYNC_R	(1 << 2)
+#define LVDSTRIPE_ST_TRGSEL_HSYNC_F	(2 << 2)
+
+#define LVDSTRIPE_ST_SWAP_NORMAL	(0 << 1)
+#define LVDSTRIPE_ST_SWAP_SWAP		(1 << 1)
+#define LVDSTRIPE_ST_ON			(1 << 0)
+
+#define LVDSCR				0x0018
+#define LVDSCR_DEPTH_DP1		(0 << 29)
+#define LVDSCR_DEPTH_DP2		(1 << 29)
+#define LVDSCR_DEPTH_DP3		(2 << 29)
+#define LVDSCR_BANDSET_10KHZ_LESS_THAN	(1 << 28)
+#define LVDSCR_SDIV_SR1			(0 << 22)
+#define LVDSCR_SDIV_SR2			(1 << 22)
+#define LVDSCR_SDIV_SR4			(2 << 22)
+#define LVDSCR_SDIV_SR8			(3 << 22)
+#define LVDSCR_MODE_DOWN		(1 << 21)
+#define LVDSCR_RSTN_ENABLE		(1 << 20)
+
+#define LVDDIV				0x001c
+#define LVDDIV_DIVSEL			(1 << 8)
+#define LVDDIV_DIVRESET			(1 << 7)
+#define LVDDIV_DIVSTP			(1 << 6)
+
 #endif /* __RCAR_LVDS_REGS_H__ */
-- 
2.7.4

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

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

* [PROTO][PATCH 05/10] drm/bridge: adv7511: Add max-clock, min-vrefresh options
  2018-08-14 13:49 ` Ulrich Hecht
@ 2018-08-14 13:49   ` Ulrich Hecht
  -1 siblings, 0 replies; 50+ messages in thread
From: Ulrich Hecht @ 2018-08-14 13:49 UTC (permalink / raw)
  To: laurent.pinchart
  Cc: linux-renesas-soc, dri-devel, jacopo+renesas,
	kieran.bingham+renesas, Koji Matsuoka, Ulrich Hecht

From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>

This patch adds the option to specify a maximal clock and a minimal vertical
refresh rate.

Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
[uli: renamed properties, fixed transposed parsing]
Signed-off-by: Ulrich Hecht <uli+renesas@fpond.eu>
---
 drivers/gpu/drm/bridge/adv7511/adv7511.h     |  7 +++++++
 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 22 ++++++++++++++++++++++
 2 files changed, 29 insertions(+)

diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h
index 73d8ccb..7f29d4f 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
@@ -271,6 +271,8 @@ enum adv7511_sync_polarity {
  * @sync_pulse:			Select the sync pulse
  * @vsync_polarity:		vsync input signal configuration
  * @hsync_polarity:		hsync input signal configuration
+ * @min_vrefresh_option:	min vrefresh option
+ * @max_freq_option:		max frequency option
  */
 struct adv7511_link_config {
 	unsigned int input_color_depth;
@@ -285,6 +287,9 @@ struct adv7511_link_config {
 	enum adv7511_input_sync_pulse sync_pulse;
 	enum adv7511_sync_polarity vsync_polarity;
 	enum adv7511_sync_polarity hsync_polarity;
+
+	unsigned int min_vrefresh_option;
+	unsigned int max_freq_option;
 };
 
 /**
@@ -354,6 +359,8 @@ struct adv7511 {
 	enum adv7511_sync_polarity vsync_polarity;
 	enum adv7511_sync_polarity hsync_polarity;
 	bool rgb;
+	unsigned int min_vref;
+	unsigned int max_freq;
 
 	struct gpio_desc *gpio_pd;
 
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index 6437b87..2938b02 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -323,6 +323,8 @@ static void adv7511_set_link_config(struct adv7511 *adv7511,
 	adv7511->hsync_polarity = config->hsync_polarity;
 	adv7511->vsync_polarity = config->vsync_polarity;
 	adv7511->rgb = config->input_colorspace == HDMI_COLORSPACE_RGB;
+	adv7511->min_vref = config->min_vrefresh_option;
+	adv7511->max_freq = config->max_freq_option;
 }
 
 static void __adv7511_power_on(struct adv7511 *adv7511)
@@ -660,6 +662,16 @@ static enum drm_mode_status adv7511_mode_valid(struct adv7511 *adv7511,
 	if (mode->clock > 165000)
 		return MODE_CLOCK_HIGH;
 
+	if (adv7511->max_freq) {
+		if (mode->clock > (adv7511->max_freq / 1000))
+			return MODE_CLOCK_HIGH;
+	}
+
+	if (adv7511->min_vref) {
+		if (drm_mode_vrefresh(mode) < adv7511->min_vref)
+			return MODE_BAD;
+	}
+
 	return MODE_OK;
 }
 
@@ -1074,6 +1086,16 @@ static int adv7511_parse_dt(struct device_node *np,
 	config->vsync_polarity = ADV7511_SYNC_POLARITY_PASSTHROUGH;
 	config->hsync_polarity = ADV7511_SYNC_POLARITY_PASSTHROUGH;
 
+	ret = of_property_read_u32(np, "max-clock",
+				   &config->max_freq_option);
+	if (ret < 0)
+		config->max_freq_option = 0;
+
+	ret = of_property_read_u32(np, "min-vrefresh",
+				   &config->min_vrefresh_option);
+	if (ret < 0)
+		config->min_vrefresh_option = 0;
+
 	return 0;
 }
 
-- 
2.7.4

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

* [PROTO][PATCH 05/10] drm/bridge: adv7511: Add max-clock, min-vrefresh options
@ 2018-08-14 13:49   ` Ulrich Hecht
  0 siblings, 0 replies; 50+ messages in thread
From: Ulrich Hecht @ 2018-08-14 13:49 UTC (permalink / raw)
  To: laurent.pinchart
  Cc: Koji Matsuoka, dri-devel, linux-renesas-soc,
	kieran.bingham+renesas, jacopo+renesas, Ulrich Hecht

From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>

This patch adds the option to specify a maximal clock and a minimal vertical
refresh rate.

Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
[uli: renamed properties, fixed transposed parsing]
Signed-off-by: Ulrich Hecht <uli+renesas@fpond.eu>
---
 drivers/gpu/drm/bridge/adv7511/adv7511.h     |  7 +++++++
 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 22 ++++++++++++++++++++++
 2 files changed, 29 insertions(+)

diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h
index 73d8ccb..7f29d4f 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
@@ -271,6 +271,8 @@ enum adv7511_sync_polarity {
  * @sync_pulse:			Select the sync pulse
  * @vsync_polarity:		vsync input signal configuration
  * @hsync_polarity:		hsync input signal configuration
+ * @min_vrefresh_option:	min vrefresh option
+ * @max_freq_option:		max frequency option
  */
 struct adv7511_link_config {
 	unsigned int input_color_depth;
@@ -285,6 +287,9 @@ struct adv7511_link_config {
 	enum adv7511_input_sync_pulse sync_pulse;
 	enum adv7511_sync_polarity vsync_polarity;
 	enum adv7511_sync_polarity hsync_polarity;
+
+	unsigned int min_vrefresh_option;
+	unsigned int max_freq_option;
 };
 
 /**
@@ -354,6 +359,8 @@ struct adv7511 {
 	enum adv7511_sync_polarity vsync_polarity;
 	enum adv7511_sync_polarity hsync_polarity;
 	bool rgb;
+	unsigned int min_vref;
+	unsigned int max_freq;
 
 	struct gpio_desc *gpio_pd;
 
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index 6437b87..2938b02 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -323,6 +323,8 @@ static void adv7511_set_link_config(struct adv7511 *adv7511,
 	adv7511->hsync_polarity = config->hsync_polarity;
 	adv7511->vsync_polarity = config->vsync_polarity;
 	adv7511->rgb = config->input_colorspace == HDMI_COLORSPACE_RGB;
+	adv7511->min_vref = config->min_vrefresh_option;
+	adv7511->max_freq = config->max_freq_option;
 }
 
 static void __adv7511_power_on(struct adv7511 *adv7511)
@@ -660,6 +662,16 @@ static enum drm_mode_status adv7511_mode_valid(struct adv7511 *adv7511,
 	if (mode->clock > 165000)
 		return MODE_CLOCK_HIGH;
 
+	if (adv7511->max_freq) {
+		if (mode->clock > (adv7511->max_freq / 1000))
+			return MODE_CLOCK_HIGH;
+	}
+
+	if (adv7511->min_vref) {
+		if (drm_mode_vrefresh(mode) < adv7511->min_vref)
+			return MODE_BAD;
+	}
+
 	return MODE_OK;
 }
 
@@ -1074,6 +1086,16 @@ static int adv7511_parse_dt(struct device_node *np,
 	config->vsync_polarity = ADV7511_SYNC_POLARITY_PASSTHROUGH;
 	config->hsync_polarity = ADV7511_SYNC_POLARITY_PASSTHROUGH;
 
+	ret = of_property_read_u32(np, "max-clock",
+				   &config->max_freq_option);
+	if (ret < 0)
+		config->max_freq_option = 0;
+
+	ret = of_property_read_u32(np, "min-vrefresh",
+				   &config->min_vrefresh_option);
+	if (ret < 0)
+		config->min_vrefresh_option = 0;
+
 	return 0;
 }
 
-- 
2.7.4

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

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

* [PROTO][PATCH 06/10] drm: rcar-du: Fix procedure for extal and dotclkin selection
  2018-08-14 13:49 ` Ulrich Hecht
@ 2018-08-14 13:50   ` Ulrich Hecht
  -1 siblings, 0 replies; 50+ messages in thread
From: Ulrich Hecht @ 2018-08-14 13:50 UTC (permalink / raw)
  To: laurent.pinchart
  Cc: linux-renesas-soc, dri-devel, jacopo+renesas,
	kieran.bingham+renesas, Koji Matsuoka

From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>

This patch corrects that the extal clock used with the fixed value
is acquired from the device tree.
Also, it is possible to select extal or dotclkin for R8A77995 and
R8A77990. This patch adds its selection procedure.

Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
---
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c   | 12 ++++++++++++
 drivers/gpu/drm/rcar-du/rcar_du_crtc.h   |  2 ++
 drivers/gpu/drm/rcar-du/rcar_lvds_regs.h |  4 +---
 3 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index a903456..4e22d40 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -942,10 +942,22 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int swindex,
 		return PTR_ERR(rcrtc->clock);
 	}
 
+	sprintf(clk_name, "extal");
+	clk = devm_clk_get(rcdu->dev, clk_name);
+	if (!IS_ERR(clk)) {
+		rcrtc->extclock = clk;
+		rcrtc->extal_use = true;
+	} else if (PTR_ERR(rcrtc->clock) == -EPROBE_DEFER) {
+		dev_info(rcdu->dev, "can't get extal clock %u\n",
+			 hwindex);
+		return -EPROBE_DEFER;
+	}
+
 	sprintf(clk_name, "dclkin.%u", hwindex);
 	clk = devm_clk_get(rcdu->dev, clk_name);
 	if (!IS_ERR(clk)) {
 		rcrtc->extclock = clk;
+		rcrtc->extal_use = false;
 	} else if (PTR_ERR(rcrtc->clock) == -EPROBE_DEFER) {
 		dev_info(rcdu->dev, "can't get external clock %u\n", hwindex);
 		return -EPROBE_DEFER;
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
index 65de551..fa27104 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
@@ -45,6 +45,7 @@ struct rcar_du_vsp;
  * @vsp: VSP feeding video to this CRTC
  * @vsp_pipe: index of the VSP pipeline feeding video to this CRTC
  * @lvds_ch: index of LVDS
+ * @extal_use: extal clock use
  */
 struct rcar_du_crtc {
 	struct drm_crtc crtc;
@@ -69,6 +70,7 @@ struct rcar_du_crtc {
 	struct rcar_du_vsp *vsp;
 	unsigned int vsp_pipe;
 	int lvds_ch;
+	bool extal_use;
 };
 
 #define to_rcar_crtc(c)	container_of(c, struct rcar_du_crtc, crtc)
diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h b/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
index e37db95..4899062 100644
--- a/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
+++ b/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
@@ -46,15 +46,13 @@
 #define LVDPLLCR_PLLDIVCNT_148M		(0x046c1 << 0)
 #define LVDPLLCR_PLLDIVCNT_MASK		(0x7ffff << 0)
 
-/* R-Car D3 */
 #define LVDPLLCR_PLLON			(1 << 22)
 #define LVDPLLCR_PLLSEL_PLL0		(0 << 20)
 #define LVDPLLCR_PLLSEL_LVX		(1 << 20)
 #define LVDPLLCR_PLLSEL_PLL1		(2 << 20)
 #define LVDPLLCR_CKSEL_LVX		(1 << 17)
 #define LVDPLLCR_CKSEL_EXTAL		(3 << 17)
-#define LVDPLLCR_CKSEL_DU_DOTCLKIN0	(5 << 17)
-#define LVDPLLCR_CKSEL_DU_DOTCLKIN1	(7 << 17)
+#define LVDPLLCR_CKSEL_DU_DOTCLKIN(n)	((5 + (n) * 2) << 17)
 #define LVDPLLCR_OCKSEL_7		(0 << 16)
 #define LVDPLLCR_OCKSEL_NOT_DIVIDED	(1 << 16)
 #define LVDPLLCR_STP_CLKOUTE1_DIS	(0 << 14)
-- 
2.7.4

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

* [PROTO][PATCH 06/10] drm: rcar-du: Fix procedure for extal and dotclkin selection
@ 2018-08-14 13:50   ` Ulrich Hecht
  0 siblings, 0 replies; 50+ messages in thread
From: Ulrich Hecht @ 2018-08-14 13:50 UTC (permalink / raw)
  To: laurent.pinchart
  Cc: linux-renesas-soc, kieran.bingham+renesas, jacopo+renesas,
	Koji Matsuoka, dri-devel

From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>

This patch corrects that the extal clock used with the fixed value
is acquired from the device tree.
Also, it is possible to select extal or dotclkin for R8A77995 and
R8A77990. This patch adds its selection procedure.

Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
---
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c   | 12 ++++++++++++
 drivers/gpu/drm/rcar-du/rcar_du_crtc.h   |  2 ++
 drivers/gpu/drm/rcar-du/rcar_lvds_regs.h |  4 +---
 3 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index a903456..4e22d40 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -942,10 +942,22 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int swindex,
 		return PTR_ERR(rcrtc->clock);
 	}
 
+	sprintf(clk_name, "extal");
+	clk = devm_clk_get(rcdu->dev, clk_name);
+	if (!IS_ERR(clk)) {
+		rcrtc->extclock = clk;
+		rcrtc->extal_use = true;
+	} else if (PTR_ERR(rcrtc->clock) == -EPROBE_DEFER) {
+		dev_info(rcdu->dev, "can't get extal clock %u\n",
+			 hwindex);
+		return -EPROBE_DEFER;
+	}
+
 	sprintf(clk_name, "dclkin.%u", hwindex);
 	clk = devm_clk_get(rcdu->dev, clk_name);
 	if (!IS_ERR(clk)) {
 		rcrtc->extclock = clk;
+		rcrtc->extal_use = false;
 	} else if (PTR_ERR(rcrtc->clock) == -EPROBE_DEFER) {
 		dev_info(rcdu->dev, "can't get external clock %u\n", hwindex);
 		return -EPROBE_DEFER;
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
index 65de551..fa27104 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
@@ -45,6 +45,7 @@ struct rcar_du_vsp;
  * @vsp: VSP feeding video to this CRTC
  * @vsp_pipe: index of the VSP pipeline feeding video to this CRTC
  * @lvds_ch: index of LVDS
+ * @extal_use: extal clock use
  */
 struct rcar_du_crtc {
 	struct drm_crtc crtc;
@@ -69,6 +70,7 @@ struct rcar_du_crtc {
 	struct rcar_du_vsp *vsp;
 	unsigned int vsp_pipe;
 	int lvds_ch;
+	bool extal_use;
 };
 
 #define to_rcar_crtc(c)	container_of(c, struct rcar_du_crtc, crtc)
diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h b/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
index e37db95..4899062 100644
--- a/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
+++ b/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
@@ -46,15 +46,13 @@
 #define LVDPLLCR_PLLDIVCNT_148M		(0x046c1 << 0)
 #define LVDPLLCR_PLLDIVCNT_MASK		(0x7ffff << 0)
 
-/* R-Car D3 */
 #define LVDPLLCR_PLLON			(1 << 22)
 #define LVDPLLCR_PLLSEL_PLL0		(0 << 20)
 #define LVDPLLCR_PLLSEL_LVX		(1 << 20)
 #define LVDPLLCR_PLLSEL_PLL1		(2 << 20)
 #define LVDPLLCR_CKSEL_LVX		(1 << 17)
 #define LVDPLLCR_CKSEL_EXTAL		(3 << 17)
-#define LVDPLLCR_CKSEL_DU_DOTCLKIN0	(5 << 17)
-#define LVDPLLCR_CKSEL_DU_DOTCLKIN1	(7 << 17)
+#define LVDPLLCR_CKSEL_DU_DOTCLKIN(n)	((5 + (n) * 2) << 17)
 #define LVDPLLCR_OCKSEL_7		(0 << 16)
 #define LVDPLLCR_OCKSEL_NOT_DIVIDED	(1 << 16)
 #define LVDPLLCR_STP_CLKOUTE1_DIS	(0 << 14)
-- 
2.7.4

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

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

* [PROTO][PATCH 07/10] arm64: dts: r8a77995-draak: set external clock for DU
  2018-08-14 13:49 ` Ulrich Hecht
@ 2018-08-14 13:50   ` Ulrich Hecht
  -1 siblings, 0 replies; 50+ messages in thread
From: Ulrich Hecht @ 2018-08-14 13:50 UTC (permalink / raw)
  To: laurent.pinchart
  Cc: linux-renesas-soc, dri-devel, jacopo+renesas,
	kieran.bingham+renesas, Koji Matsuoka, Takeshi Kihara,
	Ulrich Hecht

From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>

Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
Signed-off-by: Takeshi Kihara <takeshi.kihara.df@renesas.com>
Signed-off-by: Ulrich Hecht <uli+renesas@fpond.eu>
---
 arch/arm64/boot/dts/renesas/r8a77995-draak.dts | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/renesas/r8a77995-draak.dts b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts
index a8e8f26..bd5c6fa 100644
--- a/arch/arm64/boot/dts/renesas/r8a77995-draak.dts
+++ b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts
@@ -2,7 +2,7 @@
 /*
  * Device Tree Source for the Draak board
  *
- * Copyright (C) 2016 Renesas Electronics Corp.
+ * Copyright (C) 2016-2018 Renesas Electronics Corp.
  * Copyright (C) 2017 Glider bvba
  */
 
@@ -269,8 +269,10 @@
 
 	clocks = <&cpg CPG_MOD 724>,
 		 <&cpg CPG_MOD 723>,
-		 <&x12_clk>;
-	clock-names = "du.0", "du.1", "dclkin.0";
+		 <&x12_clk>,
+		 <&extal_clk>;
+	clock-names = "du.0", "du.1",
+		      "dclkin.0", "extal";
 
 	ports {
 		port@0 {
-- 
2.7.4

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

* [PROTO][PATCH 07/10] arm64: dts: r8a77995-draak: set external clock for DU
@ 2018-08-14 13:50   ` Ulrich Hecht
  0 siblings, 0 replies; 50+ messages in thread
From: Ulrich Hecht @ 2018-08-14 13:50 UTC (permalink / raw)
  To: laurent.pinchart
  Cc: Takeshi Kihara, Koji Matsuoka, dri-devel, linux-renesas-soc,
	kieran.bingham+renesas, jacopo+renesas, Ulrich Hecht

From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>

Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
Signed-off-by: Takeshi Kihara <takeshi.kihara.df@renesas.com>
Signed-off-by: Ulrich Hecht <uli+renesas@fpond.eu>
---
 arch/arm64/boot/dts/renesas/r8a77995-draak.dts | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/renesas/r8a77995-draak.dts b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts
index a8e8f26..bd5c6fa 100644
--- a/arch/arm64/boot/dts/renesas/r8a77995-draak.dts
+++ b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts
@@ -2,7 +2,7 @@
 /*
  * Device Tree Source for the Draak board
  *
- * Copyright (C) 2016 Renesas Electronics Corp.
+ * Copyright (C) 2016-2018 Renesas Electronics Corp.
  * Copyright (C) 2017 Glider bvba
  */
 
@@ -269,8 +269,10 @@
 
 	clocks = <&cpg CPG_MOD 724>,
 		 <&cpg CPG_MOD 723>,
-		 <&x12_clk>;
-	clock-names = "du.0", "du.1", "dclkin.0";
+		 <&x12_clk>,
+		 <&extal_clk>;
+	clock-names = "du.0", "du.1",
+		      "dclkin.0", "extal";
 
 	ports {
 		port@0 {
-- 
2.7.4

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

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

* [PROTO][PATCH 08/10] drm: rcar-du: lvds: Handle LVDS interface reset
  2018-08-14 13:49 ` Ulrich Hecht
@ 2018-08-14 13:50   ` Ulrich Hecht
  -1 siblings, 0 replies; 50+ messages in thread
From: Ulrich Hecht @ 2018-08-14 13:50 UTC (permalink / raw)
  To: laurent.pinchart
  Cc: linux-renesas-soc, dri-devel, jacopo+renesas,
	kieran.bingham+renesas, Ulrich Hecht

From: Jacopo Mondi <jacopo+renesas@jmondi.org>

The processor manual prescribes to clear reset of LVDS interface in CPG/MSSR
module before display on, and to assert the same reset line at display off
time, to have the module resuming in a known state.

The module is said to be in "standby state" at initialization time, and this
requires, according to section 37.3.7 of the manual, to de-assert the reset to
have it functional.

Based on the original patch from
Koji Matsuoka <koji.matsuoka.xm@renesas.com>

Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
Signed-off-by: Ulrich Hecht <uli+renesas@fpond.eu>
---
 drivers/gpu/drm/rcar-du/rcar_lvds.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c b/drivers/gpu/drm/rcar-du/rcar_lvds.c
index cd55576..f6a4f9c 100644
--- a/drivers/gpu/drm/rcar-du/rcar_lvds.c
+++ b/drivers/gpu/drm/rcar-du/rcar_lvds.c
@@ -14,6 +14,7 @@
 #include <linux/of_device.h>
 #include <linux/of_graph.h>
 #include <linux/platform_device.h>
+#include <linux/reset.h>
 #include <linux/slab.h>
 
 #include <drm/drm_atomic.h>
@@ -55,6 +56,7 @@ struct rcar_lvds {
 
 	void __iomem *mmio;
 	struct clk *clock;
+	struct reset_control *rst;
 	bool enabled;
 
 	struct drm_display_mode display_mode;
@@ -385,6 +387,12 @@ static void rcar_lvds_enable(struct drm_bridge *bridge)
 	if (ret < 0)
 		return;
 
+	ret = reset_control_deassert(lvds->rst);
+	if (ret < 0) {
+		clk_disable_unprepare(lvds->clock);
+		return;
+	}
+
 	/*
 	 * Hardcode the channels and control signals routing for now.
 	 *
@@ -476,6 +484,7 @@ static void rcar_lvds_disable(struct drm_bridge *bridge)
 	rcar_lvds_write(lvds, LVDCR1, 0);
 	rcar_lvds_write(lvds, LVDPLLCR, 0);
 
+	reset_control_assert(lvds->rst);
 	clk_disable_unprepare(lvds->clock);
 
 	lvds->enabled = false;
@@ -692,6 +701,12 @@ static int rcar_lvds_probe(struct platform_device *pdev)
 		return PTR_ERR(lvds->clock);
 	}
 
+	lvds->rst = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL);
+	if (IS_ERR(lvds->rst)) {
+		dev_err(&pdev->dev, "failed to get reset\n");
+		return PTR_ERR(lvds->rst);
+	}
+
 	drm_bridge_add(&lvds->bridge);
 
 	return 0;
-- 
2.7.4

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

* [PROTO][PATCH 08/10] drm: rcar-du: lvds: Handle LVDS interface reset
@ 2018-08-14 13:50   ` Ulrich Hecht
  0 siblings, 0 replies; 50+ messages in thread
From: Ulrich Hecht @ 2018-08-14 13:50 UTC (permalink / raw)
  To: laurent.pinchart
  Cc: linux-renesas-soc, kieran.bingham+renesas, jacopo+renesas,
	Ulrich Hecht, dri-devel

From: Jacopo Mondi <jacopo+renesas@jmondi.org>

The processor manual prescribes to clear reset of LVDS interface in CPG/MSSR
module before display on, and to assert the same reset line at display off
time, to have the module resuming in a known state.

The module is said to be in "standby state" at initialization time, and this
requires, according to section 37.3.7 of the manual, to de-assert the reset to
have it functional.

Based on the original patch from
Koji Matsuoka <koji.matsuoka.xm@renesas.com>

Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
Signed-off-by: Ulrich Hecht <uli+renesas@fpond.eu>
---
 drivers/gpu/drm/rcar-du/rcar_lvds.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c b/drivers/gpu/drm/rcar-du/rcar_lvds.c
index cd55576..f6a4f9c 100644
--- a/drivers/gpu/drm/rcar-du/rcar_lvds.c
+++ b/drivers/gpu/drm/rcar-du/rcar_lvds.c
@@ -14,6 +14,7 @@
 #include <linux/of_device.h>
 #include <linux/of_graph.h>
 #include <linux/platform_device.h>
+#include <linux/reset.h>
 #include <linux/slab.h>
 
 #include <drm/drm_atomic.h>
@@ -55,6 +56,7 @@ struct rcar_lvds {
 
 	void __iomem *mmio;
 	struct clk *clock;
+	struct reset_control *rst;
 	bool enabled;
 
 	struct drm_display_mode display_mode;
@@ -385,6 +387,12 @@ static void rcar_lvds_enable(struct drm_bridge *bridge)
 	if (ret < 0)
 		return;
 
+	ret = reset_control_deassert(lvds->rst);
+	if (ret < 0) {
+		clk_disable_unprepare(lvds->clock);
+		return;
+	}
+
 	/*
 	 * Hardcode the channels and control signals routing for now.
 	 *
@@ -476,6 +484,7 @@ static void rcar_lvds_disable(struct drm_bridge *bridge)
 	rcar_lvds_write(lvds, LVDCR1, 0);
 	rcar_lvds_write(lvds, LVDPLLCR, 0);
 
+	reset_control_assert(lvds->rst);
 	clk_disable_unprepare(lvds->clock);
 
 	lvds->enabled = false;
@@ -692,6 +701,12 @@ static int rcar_lvds_probe(struct platform_device *pdev)
 		return PTR_ERR(lvds->clock);
 	}
 
+	lvds->rst = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL);
+	if (IS_ERR(lvds->rst)) {
+		dev_err(&pdev->dev, "failed to get reset\n");
+		return PTR_ERR(lvds->rst);
+	}
+
 	drm_bridge_add(&lvds->bridge);
 
 	return 0;
-- 
2.7.4

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

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

* [PROTO][PATCH 09/10] arm64: dts: renesas: r8a77995: Add LVDS support
  2018-08-14 13:49 ` Ulrich Hecht
@ 2018-08-14 13:50   ` Ulrich Hecht
  -1 siblings, 0 replies; 50+ messages in thread
From: Ulrich Hecht @ 2018-08-14 13:50 UTC (permalink / raw)
  To: laurent.pinchart
  Cc: linux-renesas-soc, dri-devel, jacopo+renesas,
	kieran.bingham+renesas, Ulrich Hecht

From: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>

The r8a77995 D3 platform has 2 LVDS channels connected to the DU.

Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
[uli: moved lvds* into the soc node, added PM domains, resets]
Signed-off-by: Ulrich Hecht <uli+renesas@fpond.eu>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 arch/arm64/boot/dts/renesas/r8a77995.dtsi | 56 +++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a77995.dtsi b/arch/arm64/boot/dts/renesas/r8a77995.dtsi
index 625ba2b..b0652a0 100644
--- a/arch/arm64/boot/dts/renesas/r8a77995.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77995.dtsi
@@ -972,12 +972,68 @@
 				port@1 {
 					reg = <1>;
 					du_out_lvds0: endpoint {
+						remote-endpoint = <&lvds0_in>;
 					};
 				};
 
 				port@2 {
 					reg = <2>;
 					du_out_lvds1: endpoint {
+						remote-endpoint = <&lvds1_in>;
+					};
+				};
+			};
+		};
+
+		lvds0: lvds-encoder@feb90000 {
+			compatible = "renesas,r8a77995-lvds";
+			reg = <0 0xfeb90000 0 0x20>;
+			clocks = <&cpg CPG_MOD 727>;
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 727>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					lvds0_in: endpoint {
+						remote-endpoint = <&du_out_lvds0>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					lvds0_out: endpoint {
+					};
+				};
+			};
+		};
+
+		lvds1: lvds-encoder@feb90100 {
+			compatible = "renesas,r8a77995-lvds";
+			reg = <0 0xfeb90100 0 0x20>;
+			clocks = <&cpg CPG_MOD 727>;
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 726>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					lvds1_in: endpoint {
+						remote-endpoint = <&du_out_lvds1>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					lvds1_out: endpoint {
 					};
 				};
 			};
-- 
2.7.4

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

* [PROTO][PATCH 09/10] arm64: dts: renesas: r8a77995: Add LVDS support
@ 2018-08-14 13:50   ` Ulrich Hecht
  0 siblings, 0 replies; 50+ messages in thread
From: Ulrich Hecht @ 2018-08-14 13:50 UTC (permalink / raw)
  To: laurent.pinchart
  Cc: linux-renesas-soc, kieran.bingham+renesas, jacopo+renesas,
	Ulrich Hecht, dri-devel

From: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>

The r8a77995 D3 platform has 2 LVDS channels connected to the DU.

Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
[uli: moved lvds* into the soc node, added PM domains, resets]
Signed-off-by: Ulrich Hecht <uli+renesas@fpond.eu>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 arch/arm64/boot/dts/renesas/r8a77995.dtsi | 56 +++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a77995.dtsi b/arch/arm64/boot/dts/renesas/r8a77995.dtsi
index 625ba2b..b0652a0 100644
--- a/arch/arm64/boot/dts/renesas/r8a77995.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77995.dtsi
@@ -972,12 +972,68 @@
 				port@1 {
 					reg = <1>;
 					du_out_lvds0: endpoint {
+						remote-endpoint = <&lvds0_in>;
 					};
 				};
 
 				port@2 {
 					reg = <2>;
 					du_out_lvds1: endpoint {
+						remote-endpoint = <&lvds1_in>;
+					};
+				};
+			};
+		};
+
+		lvds0: lvds-encoder@feb90000 {
+			compatible = "renesas,r8a77995-lvds";
+			reg = <0 0xfeb90000 0 0x20>;
+			clocks = <&cpg CPG_MOD 727>;
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 727>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					lvds0_in: endpoint {
+						remote-endpoint = <&du_out_lvds0>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					lvds0_out: endpoint {
+					};
+				};
+			};
+		};
+
+		lvds1: lvds-encoder@feb90100 {
+			compatible = "renesas,r8a77995-lvds";
+			reg = <0 0xfeb90100 0 0x20>;
+			clocks = <&cpg CPG_MOD 727>;
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 726>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					lvds1_in: endpoint {
+						remote-endpoint = <&du_out_lvds1>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					lvds1_out: endpoint {
 					};
 				};
 			};
-- 
2.7.4

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

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

* [PROTO][PATCH 10/10] arm64: dts: renesas: r8a77995-draak: add HDMI output
  2018-08-14 13:49 ` Ulrich Hecht
@ 2018-08-14 13:50   ` Ulrich Hecht
  -1 siblings, 0 replies; 50+ messages in thread
From: Ulrich Hecht @ 2018-08-14 13:50 UTC (permalink / raw)
  To: laurent.pinchart
  Cc: linux-renesas-soc, dri-devel, jacopo+renesas,
	kieran.bingham+renesas, Ulrich Hecht

Adds LVDS decoder, HDMI encoder and connector for Draak boards.

Signed-off-by: Ulrich Hecht <uli+renesas@fpond.eu>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 arch/arm64/boot/dts/renesas/r8a77995-draak.dts | 84 ++++++++++++++++++++++++++
 1 file changed, 84 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a77995-draak.dts b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts
index bd5c6fa..157adf9 100644
--- a/arch/arm64/boot/dts/renesas/r8a77995-draak.dts
+++ b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts
@@ -24,6 +24,41 @@
 		stdout-path = "serial0:115200n8";
 	};
 
+	lvds-decoder {
+		compatible = "thine,thc63lvd1024";
+		vcc-supply = <&reg_3p3v>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				thc63lvd1024_in: endpoint {
+					remote-endpoint = <&lvds0_out>;
+				};
+			};
+
+			port@2 {
+				reg = <2>;
+				thc63lvd1024_out: endpoint {
+					remote-endpoint = <&adv7511_in>;
+				};
+			};
+		};
+	};
+
+	hdmi-out {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_out: endpoint {
+				remote-endpoint = <&adv7511_out>;
+			};
+		};
+	};
+
 	vga {
 		compatible = "vga-connector";
 
@@ -218,6 +253,43 @@
 
 	};
 
+	hdmi@39 {
+		compatible = "adi,adv7511w";
+		reg = <0x39>, <0x3f>, <0x38>, <0x3c>;
+		reg-names = "main", "edid", "packet", "cec";
+		interrupt-parent = <&gpio1>;
+		interrupts = <28 IRQ_TYPE_LEVEL_LOW>;
+
+		/* Depends on LVDS */
+		max-clock = <135000000>;
+		min-vrefresh = <50>;
+
+		adi,input-depth = <8>;
+		adi,input-colorspace = "rgb";
+		adi,input-clock = "1x";
+		adi,input-style = <1>;
+		adi,input-justification = "evenly";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				adv7511_in: endpoint {
+					remote-endpoint = <&thc63lvd1024_out>;
+				};
+			};
+
+			port@1 {
+				reg = <1>;
+				adv7511_out: endpoint {
+					remote-endpoint = <&hdmi_con_out>;
+				};
+			};
+		};
+	};
+
 	hdmi-decoder@4c {
 		compatible = "adi,adv7612";
 		reg = <0x4c>;
@@ -283,6 +355,18 @@
 	};
 };
 
+&lvds0 {
+	status = "okay";
+
+	ports {
+		port@1 {
+			lvds0_out: endpoint {
+				remote-endpoint = <&thc63lvd1024_in>;
+			};
+		};
+	};
+};
+
 &ehci0 {
 	status = "okay";
 };
-- 
2.7.4

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

* [PROTO][PATCH 10/10] arm64: dts: renesas: r8a77995-draak: add HDMI output
@ 2018-08-14 13:50   ` Ulrich Hecht
  0 siblings, 0 replies; 50+ messages in thread
From: Ulrich Hecht @ 2018-08-14 13:50 UTC (permalink / raw)
  To: laurent.pinchart
  Cc: linux-renesas-soc, kieran.bingham+renesas, jacopo+renesas,
	Ulrich Hecht, dri-devel

Adds LVDS decoder, HDMI encoder and connector for Draak boards.

Signed-off-by: Ulrich Hecht <uli+renesas@fpond.eu>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 arch/arm64/boot/dts/renesas/r8a77995-draak.dts | 84 ++++++++++++++++++++++++++
 1 file changed, 84 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a77995-draak.dts b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts
index bd5c6fa..157adf9 100644
--- a/arch/arm64/boot/dts/renesas/r8a77995-draak.dts
+++ b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts
@@ -24,6 +24,41 @@
 		stdout-path = "serial0:115200n8";
 	};
 
+	lvds-decoder {
+		compatible = "thine,thc63lvd1024";
+		vcc-supply = <&reg_3p3v>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				thc63lvd1024_in: endpoint {
+					remote-endpoint = <&lvds0_out>;
+				};
+			};
+
+			port@2 {
+				reg = <2>;
+				thc63lvd1024_out: endpoint {
+					remote-endpoint = <&adv7511_in>;
+				};
+			};
+		};
+	};
+
+	hdmi-out {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_out: endpoint {
+				remote-endpoint = <&adv7511_out>;
+			};
+		};
+	};
+
 	vga {
 		compatible = "vga-connector";
 
@@ -218,6 +253,43 @@
 
 	};
 
+	hdmi@39 {
+		compatible = "adi,adv7511w";
+		reg = <0x39>, <0x3f>, <0x38>, <0x3c>;
+		reg-names = "main", "edid", "packet", "cec";
+		interrupt-parent = <&gpio1>;
+		interrupts = <28 IRQ_TYPE_LEVEL_LOW>;
+
+		/* Depends on LVDS */
+		max-clock = <135000000>;
+		min-vrefresh = <50>;
+
+		adi,input-depth = <8>;
+		adi,input-colorspace = "rgb";
+		adi,input-clock = "1x";
+		adi,input-style = <1>;
+		adi,input-justification = "evenly";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				adv7511_in: endpoint {
+					remote-endpoint = <&thc63lvd1024_out>;
+				};
+			};
+
+			port@1 {
+				reg = <1>;
+				adv7511_out: endpoint {
+					remote-endpoint = <&hdmi_con_out>;
+				};
+			};
+		};
+	};
+
 	hdmi-decoder@4c {
 		compatible = "adi,adv7612";
 		reg = <0x4c>;
@@ -283,6 +355,18 @@
 	};
 };
 
+&lvds0 {
+	status = "okay";
+
+	ports {
+		port@1 {
+			lvds0_out: endpoint {
+				remote-endpoint = <&thc63lvd1024_in>;
+			};
+		};
+	};
+};
+
 &ehci0 {
 	status = "okay";
 };
-- 
2.7.4

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

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

* Re: [PROTO][PATCH 02/10] drm: rcar-du: Add r8a77995 device support
  2018-08-14 13:49   ` Ulrich Hecht
@ 2018-08-20  8:39     ` Laurent Pinchart
  -1 siblings, 0 replies; 50+ messages in thread
From: Laurent Pinchart @ 2018-08-20  8:39 UTC (permalink / raw)
  To: Ulrich Hecht
  Cc: linux-renesas-soc, dri-devel, jacopo+renesas, kieran.bingham+renesas

Hi Ulrich,

Thank you for the patch.

On Tuesday, 14 August 2018 16:49:56 EEST Ulrich Hecht wrote:
> Add support for the R-Car D3 (R8A77995) SoC to the R-Car DU driver.
> 
> Based on patch by Koji Matsuoka <koji.matsuoka.xm@renesas.com>.
> 
> Signed-off-by: Ulrich Hecht <uli+renesas@fpond.eu>
> ---
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.c  | 17 ++++++-----------
>  drivers/gpu/drm/rcar-du/rcar_du_drv.c   | 26 ++++++++++++++++++++++++++
>  drivers/gpu/drm/rcar-du/rcar_du_drv.h   |  1 +
>  drivers/gpu/drm/rcar-du/rcar_du_group.c |  3 ++-
>  4 files changed, 35 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c index cd6803a..9153e7a 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> @@ -53,14 +53,6 @@ static void rcar_du_crtc_clr(struct rcar_du_crtc *rcrtc,
> u32 reg, u32 clr) rcar_du_read(rcdu, rcrtc->mmio_offset + reg) & ~clr);
>  }
> 
> -static void rcar_du_crtc_set(struct rcar_du_crtc *rcrtc, u32 reg, u32 set)
> -{
> -	struct rcar_du_device *rcdu = rcrtc->group->dev;
> -
> -	rcar_du_write(rcdu, rcrtc->mmio_offset + reg,
> -		      rcar_du_read(rcdu, rcrtc->mmio_offset + reg) | set);
> -}
> -
>  static void rcar_du_crtc_clr_set(struct rcar_du_crtc *rcrtc, u32 reg,
>  				 u32 clr, u32 set)
>  {
> @@ -527,7 +519,8 @@ static void rcar_du_crtc_start(struct rcar_du_crtc
> *rcrtc) * actively driven).
>  	 */
>  	interlaced = rcrtc->crtc.mode.flags & DRM_MODE_FLAG_INTERLACE;
> -	rcar_du_crtc_clr_set(rcrtc, DSYSR, DSYSR_TVM_MASK | DSYSR_SCM_MASK,
> +	rcar_du_crtc_clr_set(rcrtc, DSYSR,
> +			     DSYSR_TVM_MASK | DSYSR_SCM_MASK | DSYSR_ILTS,

The ILTS bit defaults to 0 so this shouldn't be needed. However, we never 
initialize the DSYSR register completely but only modify bits. It would be 
safer to write all bits at init time. I'll write a separate patch.

>  			     (interlaced ? DSYSR_SCM_INT_VIDEO : 0) |
>  			     DSYSR_TVM_MASTER);
> 
> @@ -596,7 +589,9 @@ static void rcar_du_crtc_stop(struct rcar_du_crtc
> *rcrtc) * Select switch sync mode. This stops display operation and
> configures * the HSYNC and VSYNC signals as inputs.
>  	 */
> -	rcar_du_crtc_clr_set(rcrtc, DSYSR, DSYSR_TVM_MASK, DSYSR_TVM_SWITCH);
> +	rcar_du_crtc_clr_set(rcrtc, DSYSR, DSYSR_TVM_MASK | DSYSR_ILTS,
> +		rcar_du_needs(rcrtc->group->dev, RCAR_DU_QUIRK_TVM_MASTER_ONLY) ?
> +		DSYSR_TVM_MASTER : DSYSR_TVM_SWITCH);

Now this is a problem. The driver uses switch mode as a way to disable the 
display output, as the display enable bits in the DSYSR register cover a group 
of two DU channels. TVM switch mode was the only workaround I found to be able 
to disable the display output. If the D3 and E3 SoCs don't implement TVM 
switch mode we need a different mechanism.

>  	rcar_du_group_start_stop(rcrtc->group, false);
>  }
> @@ -744,7 +739,7 @@ static int rcar_du_crtc_enable_vblank(struct drm_crtc
> *crtc) struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
> 
>  	rcar_du_crtc_write(rcrtc, DSRCR, DSRCR_VBCL);
> -	rcar_du_crtc_set(rcrtc, DIER, DIER_VBE);
> +	rcar_du_crtc_clr_set(rcrtc, DIER, DIER_TVE | DIER_FRE, DIER_VBE);
>  	rcrtc->vblank_enable = true;
> 
>  	return 0;
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> b/drivers/gpu/drm/rcar-du/rcar_du_drv.c index 56f9472..5c2f764 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> @@ -294,6 +294,31 @@ static const struct rcar_du_device_info
> rcar_du_r8a77970_info = { .num_lvds = 1,
>  };
> 
> +static const struct rcar_du_device_info rcar_du_r8a77995_info = {
> +	.gen = 3,
> +	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
> +		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
> +		  | RCAR_DU_FEATURE_VSP1_SOURCE,
> +	.quirks = RCAR_DU_QUIRK_TVM_MASTER_ONLY,
> +	.channels_mask = BIT(1) | BIT(0),
> +	.routes = {
> +		/* R8A77995 has two LVDS output and one RGB output. */
> +		[RCAR_DU_OUTPUT_DPAD0] = {
> +			.possible_crtcs = BIT(0) | BIT(1),
> +			.port = 0,
> +		},
> +		[RCAR_DU_OUTPUT_LVDS0] = {
> +			.possible_crtcs = BIT(0),
> +			.port = 1,
> +		},
> +		[RCAR_DU_OUTPUT_LVDS1] = {
> +			.possible_crtcs = BIT(1),
> +			.port = 2,
> +		},
> +	},
> +	.num_lvds = 2,
> +};
> +
>  static const struct of_device_id rcar_du_of_table[] = {
>  	{ .compatible = "renesas,du-r8a7743", .data = &rzg1_du_r8a7743_info },
>  	{ .compatible = "renesas,du-r8a7745", .data = &rzg1_du_r8a7745_info },
> @@ -307,6 +332,7 @@ static const struct of_device_id rcar_du_of_table[] = {
>  	{ .compatible = "renesas,du-r8a7796", .data = &rcar_du_r8a7796_info },
>  	{ .compatible = "renesas,du-r8a77965", .data = &rcar_du_r8a77965_info },
>  	{ .compatible = "renesas,du-r8a77970", .data = &rcar_du_r8a77970_info },
> +	{ .compatible = "renesas,du-r8a77995", .data = &rcar_du_r8a77995_info },
>  	{ }
>  };
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> b/drivers/gpu/drm/rcar-du/rcar_du_drv.h index b3a25e8..6257405 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> @@ -32,6 +32,7 @@ struct rcar_du_device;
>  #define RCAR_DU_FEATURE_VSP1_SOURCE	(1 << 2)	/* Has inputs from VSP1 */
> 
>  #define RCAR_DU_QUIRK_ALIGN_128B	(1 << 0)	/* Align pitches to 128 bytes 
*/
> +#define RCAR_DU_QUIRK_TVM_MASTER_ONLY	(1 << 1)	/* Does not have TV
> switch/sync modes */
> 
>  /*
>   * struct rcar_du_output_routing - Output routing specification
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c
> b/drivers/gpu/drm/rcar-du/rcar_du_group.c index d539cb2..9a0a694 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
> @@ -178,7 +178,8 @@ void rcar_du_group_put(struct rcar_du_group *rgrp)
>  static void __rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool
> start) {
>  	rcar_du_group_write(rgrp, DSYSR,
> -		(rcar_du_group_read(rgrp, DSYSR) & ~(DSYSR_DRES | DSYSR_DEN)) |
> +		(rcar_du_group_read(rgrp, DSYSR) &
> +		 ~(DSYSR_DRES | DSYSR_DEN | DSYSR_ILTS)) |
>  		(start ? DSYSR_DEN : DSYSR_DRES));
>  }

-- 
Regards,

Laurent Pinchart

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

* Re: [PROTO][PATCH 02/10] drm: rcar-du: Add r8a77995 device support
@ 2018-08-20  8:39     ` Laurent Pinchart
  0 siblings, 0 replies; 50+ messages in thread
From: Laurent Pinchart @ 2018-08-20  8:39 UTC (permalink / raw)
  To: Ulrich Hecht
  Cc: linux-renesas-soc, kieran.bingham+renesas, jacopo+renesas, dri-devel

Hi Ulrich,

Thank you for the patch.

On Tuesday, 14 August 2018 16:49:56 EEST Ulrich Hecht wrote:
> Add support for the R-Car D3 (R8A77995) SoC to the R-Car DU driver.
> 
> Based on patch by Koji Matsuoka <koji.matsuoka.xm@renesas.com>.
> 
> Signed-off-by: Ulrich Hecht <uli+renesas@fpond.eu>
> ---
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.c  | 17 ++++++-----------
>  drivers/gpu/drm/rcar-du/rcar_du_drv.c   | 26 ++++++++++++++++++++++++++
>  drivers/gpu/drm/rcar-du/rcar_du_drv.h   |  1 +
>  drivers/gpu/drm/rcar-du/rcar_du_group.c |  3 ++-
>  4 files changed, 35 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c index cd6803a..9153e7a 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> @@ -53,14 +53,6 @@ static void rcar_du_crtc_clr(struct rcar_du_crtc *rcrtc,
> u32 reg, u32 clr) rcar_du_read(rcdu, rcrtc->mmio_offset + reg) & ~clr);
>  }
> 
> -static void rcar_du_crtc_set(struct rcar_du_crtc *rcrtc, u32 reg, u32 set)
> -{
> -	struct rcar_du_device *rcdu = rcrtc->group->dev;
> -
> -	rcar_du_write(rcdu, rcrtc->mmio_offset + reg,
> -		      rcar_du_read(rcdu, rcrtc->mmio_offset + reg) | set);
> -}
> -
>  static void rcar_du_crtc_clr_set(struct rcar_du_crtc *rcrtc, u32 reg,
>  				 u32 clr, u32 set)
>  {
> @@ -527,7 +519,8 @@ static void rcar_du_crtc_start(struct rcar_du_crtc
> *rcrtc) * actively driven).
>  	 */
>  	interlaced = rcrtc->crtc.mode.flags & DRM_MODE_FLAG_INTERLACE;
> -	rcar_du_crtc_clr_set(rcrtc, DSYSR, DSYSR_TVM_MASK | DSYSR_SCM_MASK,
> +	rcar_du_crtc_clr_set(rcrtc, DSYSR,
> +			     DSYSR_TVM_MASK | DSYSR_SCM_MASK | DSYSR_ILTS,

The ILTS bit defaults to 0 so this shouldn't be needed. However, we never 
initialize the DSYSR register completely but only modify bits. It would be 
safer to write all bits at init time. I'll write a separate patch.

>  			     (interlaced ? DSYSR_SCM_INT_VIDEO : 0) |
>  			     DSYSR_TVM_MASTER);
> 
> @@ -596,7 +589,9 @@ static void rcar_du_crtc_stop(struct rcar_du_crtc
> *rcrtc) * Select switch sync mode. This stops display operation and
> configures * the HSYNC and VSYNC signals as inputs.
>  	 */
> -	rcar_du_crtc_clr_set(rcrtc, DSYSR, DSYSR_TVM_MASK, DSYSR_TVM_SWITCH);
> +	rcar_du_crtc_clr_set(rcrtc, DSYSR, DSYSR_TVM_MASK | DSYSR_ILTS,
> +		rcar_du_needs(rcrtc->group->dev, RCAR_DU_QUIRK_TVM_MASTER_ONLY) ?
> +		DSYSR_TVM_MASTER : DSYSR_TVM_SWITCH);

Now this is a problem. The driver uses switch mode as a way to disable the 
display output, as the display enable bits in the DSYSR register cover a group 
of two DU channels. TVM switch mode was the only workaround I found to be able 
to disable the display output. If the D3 and E3 SoCs don't implement TVM 
switch mode we need a different mechanism.

>  	rcar_du_group_start_stop(rcrtc->group, false);
>  }
> @@ -744,7 +739,7 @@ static int rcar_du_crtc_enable_vblank(struct drm_crtc
> *crtc) struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
> 
>  	rcar_du_crtc_write(rcrtc, DSRCR, DSRCR_VBCL);
> -	rcar_du_crtc_set(rcrtc, DIER, DIER_VBE);
> +	rcar_du_crtc_clr_set(rcrtc, DIER, DIER_TVE | DIER_FRE, DIER_VBE);
>  	rcrtc->vblank_enable = true;
> 
>  	return 0;
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> b/drivers/gpu/drm/rcar-du/rcar_du_drv.c index 56f9472..5c2f764 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> @@ -294,6 +294,31 @@ static const struct rcar_du_device_info
> rcar_du_r8a77970_info = { .num_lvds = 1,
>  };
> 
> +static const struct rcar_du_device_info rcar_du_r8a77995_info = {
> +	.gen = 3,
> +	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
> +		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
> +		  | RCAR_DU_FEATURE_VSP1_SOURCE,
> +	.quirks = RCAR_DU_QUIRK_TVM_MASTER_ONLY,
> +	.channels_mask = BIT(1) | BIT(0),
> +	.routes = {
> +		/* R8A77995 has two LVDS output and one RGB output. */
> +		[RCAR_DU_OUTPUT_DPAD0] = {
> +			.possible_crtcs = BIT(0) | BIT(1),
> +			.port = 0,
> +		},
> +		[RCAR_DU_OUTPUT_LVDS0] = {
> +			.possible_crtcs = BIT(0),
> +			.port = 1,
> +		},
> +		[RCAR_DU_OUTPUT_LVDS1] = {
> +			.possible_crtcs = BIT(1),
> +			.port = 2,
> +		},
> +	},
> +	.num_lvds = 2,
> +};
> +
>  static const struct of_device_id rcar_du_of_table[] = {
>  	{ .compatible = "renesas,du-r8a7743", .data = &rzg1_du_r8a7743_info },
>  	{ .compatible = "renesas,du-r8a7745", .data = &rzg1_du_r8a7745_info },
> @@ -307,6 +332,7 @@ static const struct of_device_id rcar_du_of_table[] = {
>  	{ .compatible = "renesas,du-r8a7796", .data = &rcar_du_r8a7796_info },
>  	{ .compatible = "renesas,du-r8a77965", .data = &rcar_du_r8a77965_info },
>  	{ .compatible = "renesas,du-r8a77970", .data = &rcar_du_r8a77970_info },
> +	{ .compatible = "renesas,du-r8a77995", .data = &rcar_du_r8a77995_info },
>  	{ }
>  };
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> b/drivers/gpu/drm/rcar-du/rcar_du_drv.h index b3a25e8..6257405 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> @@ -32,6 +32,7 @@ struct rcar_du_device;
>  #define RCAR_DU_FEATURE_VSP1_SOURCE	(1 << 2)	/* Has inputs from VSP1 */
> 
>  #define RCAR_DU_QUIRK_ALIGN_128B	(1 << 0)	/* Align pitches to 128 bytes 
*/
> +#define RCAR_DU_QUIRK_TVM_MASTER_ONLY	(1 << 1)	/* Does not have TV
> switch/sync modes */
> 
>  /*
>   * struct rcar_du_output_routing - Output routing specification
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c
> b/drivers/gpu/drm/rcar-du/rcar_du_group.c index d539cb2..9a0a694 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
> @@ -178,7 +178,8 @@ void rcar_du_group_put(struct rcar_du_group *rgrp)
>  static void __rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool
> start) {
>  	rcar_du_group_write(rgrp, DSYSR,
> -		(rcar_du_group_read(rgrp, DSYSR) & ~(DSYSR_DRES | DSYSR_DEN)) |
> +		(rcar_du_group_read(rgrp, DSYSR) &
> +		 ~(DSYSR_DRES | DSYSR_DEN | DSYSR_ILTS)) |
>  		(start ? DSYSR_DEN : DSYSR_DRES));
>  }

-- 
Regards,

Laurent Pinchart



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

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

* Re: [PROTO][PATCH 03/10] drm: rcar-du: Fix digital RGB routing for R8A77995
  2018-08-14 13:49   ` Ulrich Hecht
@ 2018-08-20  9:25     ` Laurent Pinchart
  -1 siblings, 0 replies; 50+ messages in thread
From: Laurent Pinchart @ 2018-08-20  9:25 UTC (permalink / raw)
  To: Ulrich Hecht
  Cc: linux-renesas-soc, dri-devel, jacopo+renesas,
	kieran.bingham+renesas, Koji Matsuoka

Hi Ulrich,

Thank you for the patch.

On Tuesday, 14 August 2018 16:49:57 EEST Ulrich Hecht wrote:
> From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
> 
> This patch adds D3 definition for DU and fixes digital RGB routing.
> 
> Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
> ---
>  drivers/gpu/drm/rcar-du/rcar_du_drv.c   | 3 ++-
>  drivers/gpu/drm/rcar-du/rcar_du_drv.h   | 2 ++
>  drivers/gpu/drm/rcar-du/rcar_du_group.c | 4 ++++
>  3 files changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> b/drivers/gpu/drm/rcar-du/rcar_du_drv.c index 5c2f764..d930996 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> @@ -298,7 +298,8 @@ static const struct rcar_du_device_info
> rcar_du_r8a77995_info = { .gen = 3,
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
> 
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
> 
> -		  | RCAR_DU_FEATURE_VSP1_SOURCE,
> +		  | RCAR_DU_FEATURE_VSP1_SOURCE
> +		  | RCAR_DU_FEATURE_R8A77995_REGS,
>  	.quirks = RCAR_DU_QUIRK_TVM_MASTER_ONLY,
>  	.channels_mask = BIT(1) | BIT(0),
>  	.routes = {
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> b/drivers/gpu/drm/rcar-du/rcar_du_drv.h index 6257405..9355b58 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> @@ -30,6 +30,8 @@ struct rcar_du_device;
>  #define RCAR_DU_FEATURE_CRTC_IRQ_CLOCK	(1 << 0)	/* Per-CRTC IRQ and clock
> */ #define RCAR_DU_FEATURE_EXT_CTRL_REGS	(1 << 1)	/* Has extended control
> registers */ #define RCAR_DU_FEATURE_VSP1_SOURCE	(1 << 2)	/* Has inputs
> from VSP1 */ +#define RCAR_DU_FEATURE_R8A77965_REGS	(1 << 3)	/* Use
> R8A77965 registers */ +#define RCAR_DU_FEATURE_R8A77995_REGS	(1 << 4)	/*
> Use R8A77995 registers */
> 
>  #define RCAR_DU_QUIRK_ALIGN_128B	(1 << 0)	/* Align pitches to 128 bytes 
*/
>  #define RCAR_DU_QUIRK_TVM_MASTER_ONLY	(1 << 1)	/* Does not have TV
> switch/sync modes */ diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c
> b/drivers/gpu/drm/rcar-du/rcar_du_group.c index 9a0a694..371d780 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
> @@ -88,6 +88,10 @@ static void rcar_du_group_setup_defr8(struct
> rcar_du_group *rgrp)
> 
>  		if (crtc->index / 2 == rgrp->index)
>  			defr8 |= DEFR8_DRGBS_DU(crtc->index);
> +
> +		if (rcar_du_has(rcdu, RCAR_DU_FEATURE_R8A77995_REGS))
> +			defr8 |= (DEFR8_DRGBS_DU(rcdu->dpad0_source) |
> +				 DEFR8_DRGBS_DU(crtc->index));

Does this need a special case ? Can't we replace the existing logic with code 
based on dpad0_source, and make sure that dpad0_source always contains the 
correct value on SoCs that have a hardcoded connection between DU and DPAD ?

>  	}
> 
>  	rcar_du_group_write(rgrp, DEFR8, defr8);

-- 
Regards,

Laurent Pinchart

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

* Re: [PROTO][PATCH 03/10] drm: rcar-du: Fix digital RGB routing for R8A77995
@ 2018-08-20  9:25     ` Laurent Pinchart
  0 siblings, 0 replies; 50+ messages in thread
From: Laurent Pinchart @ 2018-08-20  9:25 UTC (permalink / raw)
  To: Ulrich Hecht
  Cc: linux-renesas-soc, kieran.bingham+renesas, jacopo+renesas,
	Koji Matsuoka, dri-devel

Hi Ulrich,

Thank you for the patch.

On Tuesday, 14 August 2018 16:49:57 EEST Ulrich Hecht wrote:
> From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
> 
> This patch adds D3 definition for DU and fixes digital RGB routing.
> 
> Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
> ---
>  drivers/gpu/drm/rcar-du/rcar_du_drv.c   | 3 ++-
>  drivers/gpu/drm/rcar-du/rcar_du_drv.h   | 2 ++
>  drivers/gpu/drm/rcar-du/rcar_du_group.c | 4 ++++
>  3 files changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> b/drivers/gpu/drm/rcar-du/rcar_du_drv.c index 5c2f764..d930996 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> @@ -298,7 +298,8 @@ static const struct rcar_du_device_info
> rcar_du_r8a77995_info = { .gen = 3,
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
> 
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
> 
> -		  | RCAR_DU_FEATURE_VSP1_SOURCE,
> +		  | RCAR_DU_FEATURE_VSP1_SOURCE
> +		  | RCAR_DU_FEATURE_R8A77995_REGS,
>  	.quirks = RCAR_DU_QUIRK_TVM_MASTER_ONLY,
>  	.channels_mask = BIT(1) | BIT(0),
>  	.routes = {
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> b/drivers/gpu/drm/rcar-du/rcar_du_drv.h index 6257405..9355b58 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> @@ -30,6 +30,8 @@ struct rcar_du_device;
>  #define RCAR_DU_FEATURE_CRTC_IRQ_CLOCK	(1 << 0)	/* Per-CRTC IRQ and clock
> */ #define RCAR_DU_FEATURE_EXT_CTRL_REGS	(1 << 1)	/* Has extended control
> registers */ #define RCAR_DU_FEATURE_VSP1_SOURCE	(1 << 2)	/* Has inputs
> from VSP1 */ +#define RCAR_DU_FEATURE_R8A77965_REGS	(1 << 3)	/* Use
> R8A77965 registers */ +#define RCAR_DU_FEATURE_R8A77995_REGS	(1 << 4)	/*
> Use R8A77995 registers */
> 
>  #define RCAR_DU_QUIRK_ALIGN_128B	(1 << 0)	/* Align pitches to 128 bytes 
*/
>  #define RCAR_DU_QUIRK_TVM_MASTER_ONLY	(1 << 1)	/* Does not have TV
> switch/sync modes */ diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c
> b/drivers/gpu/drm/rcar-du/rcar_du_group.c index 9a0a694..371d780 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
> @@ -88,6 +88,10 @@ static void rcar_du_group_setup_defr8(struct
> rcar_du_group *rgrp)
> 
>  		if (crtc->index / 2 == rgrp->index)
>  			defr8 |= DEFR8_DRGBS_DU(crtc->index);
> +
> +		if (rcar_du_has(rcdu, RCAR_DU_FEATURE_R8A77995_REGS))
> +			defr8 |= (DEFR8_DRGBS_DU(rcdu->dpad0_source) |
> +				 DEFR8_DRGBS_DU(crtc->index));

Does this need a special case ? Can't we replace the existing logic with code 
based on dpad0_source, and make sure that dpad0_source always contains the 
correct value on SoCs that have a hardcoded connection between DU and DPAD ?

>  	}
> 
>  	rcar_du_group_write(rgrp, DEFR8, defr8);

-- 
Regards,

Laurent Pinchart



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

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

* Re: [PROTO][PATCH 05/10] drm/bridge: adv7511: Add max-clock, min-vrefresh options
  2018-08-14 13:49   ` Ulrich Hecht
@ 2018-08-20  9:28     ` Laurent Pinchart
  -1 siblings, 0 replies; 50+ messages in thread
From: Laurent Pinchart @ 2018-08-20  9:28 UTC (permalink / raw)
  To: Ulrich Hecht
  Cc: linux-renesas-soc, dri-devel, jacopo+renesas,
	kieran.bingham+renesas, Koji Matsuoka

Hi Ulrich,

Thank you for the patch.

On Tuesday, 14 August 2018 16:49:59 EEST Ulrich Hecht wrote:
> From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
> 
> This patch adds the option to specify a maximal clock and a minimal vertical
> refresh rate.

What is this needed for ?

> Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
> [uli: renamed properties, fixed transposed parsing]
> Signed-off-by: Ulrich Hecht <uli+renesas@fpond.eu>
> ---
>  drivers/gpu/drm/bridge/adv7511/adv7511.h     |  7 +++++++
>  drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 22 ++++++++++++++++++++++

You're missing updates to the DT bindings.

>  2 files changed, 29 insertions(+)
> 
> diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h
> b/drivers/gpu/drm/bridge/adv7511/adv7511.h index 73d8ccb..7f29d4f 100644
> --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
> +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
> @@ -271,6 +271,8 @@ enum adv7511_sync_polarity {
>   * @sync_pulse:			Select the sync pulse
>   * @vsync_polarity:		vsync input signal configuration
>   * @hsync_polarity:		hsync input signal configuration
> + * @min_vrefresh_option:	min vrefresh option
> + * @max_freq_option:		max frequency option
>   */
>  struct adv7511_link_config {
>  	unsigned int input_color_depth;
> @@ -285,6 +287,9 @@ struct adv7511_link_config {
>  	enum adv7511_input_sync_pulse sync_pulse;
>  	enum adv7511_sync_polarity vsync_polarity;
>  	enum adv7511_sync_polarity hsync_polarity;
> +
> +	unsigned int min_vrefresh_option;
> +	unsigned int max_freq_option;
>  };
> 
>  /**
> @@ -354,6 +359,8 @@ struct adv7511 {
>  	enum adv7511_sync_polarity vsync_polarity;
>  	enum adv7511_sync_polarity hsync_polarity;
>  	bool rgb;
> +	unsigned int min_vref;
> +	unsigned int max_freq;
> 
>  	struct gpio_desc *gpio_pd;
> 
> diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index 6437b87..2938b02
> 100644
> --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> @@ -323,6 +323,8 @@ static void adv7511_set_link_config(struct adv7511
> *adv7511, adv7511->hsync_polarity = config->hsync_polarity;
>  	adv7511->vsync_polarity = config->vsync_polarity;
>  	adv7511->rgb = config->input_colorspace == HDMI_COLORSPACE_RGB;
> +	adv7511->min_vref = config->min_vrefresh_option;
> +	adv7511->max_freq = config->max_freq_option;
>  }
> 
>  static void __adv7511_power_on(struct adv7511 *adv7511)
> @@ -660,6 +662,16 @@ static enum drm_mode_status adv7511_mode_valid(struct
> adv7511 *adv7511, if (mode->clock > 165000)
>  		return MODE_CLOCK_HIGH;
> 
> +	if (adv7511->max_freq) {
> +		if (mode->clock > (adv7511->max_freq / 1000))
> +			return MODE_CLOCK_HIGH;
> +	}
> +
> +	if (adv7511->min_vref) {
> +		if (drm_mode_vrefresh(mode) < adv7511->min_vref)
> +			return MODE_BAD;
> +	}
> +
>  	return MODE_OK;
>  }
> 
> @@ -1074,6 +1086,16 @@ static int adv7511_parse_dt(struct device_node *np,
>  	config->vsync_polarity = ADV7511_SYNC_POLARITY_PASSTHROUGH;
>  	config->hsync_polarity = ADV7511_SYNC_POLARITY_PASSTHROUGH;
> 
> +	ret = of_property_read_u32(np, "max-clock",
> +				   &config->max_freq_option);
> +	if (ret < 0)
> +		config->max_freq_option = 0;
> +
> +	ret = of_property_read_u32(np, "min-vrefresh",
> +				   &config->min_vrefresh_option);
> +	if (ret < 0)
> +		config->min_vrefresh_option = 0;
> +
>  	return 0;
>  }


-- 
Regards,

Laurent Pinchart

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

* Re: [PROTO][PATCH 05/10] drm/bridge: adv7511: Add max-clock, min-vrefresh options
@ 2018-08-20  9:28     ` Laurent Pinchart
  0 siblings, 0 replies; 50+ messages in thread
From: Laurent Pinchart @ 2018-08-20  9:28 UTC (permalink / raw)
  To: Ulrich Hecht
  Cc: linux-renesas-soc, kieran.bingham+renesas, jacopo+renesas,
	Koji Matsuoka, dri-devel

Hi Ulrich,

Thank you for the patch.

On Tuesday, 14 August 2018 16:49:59 EEST Ulrich Hecht wrote:
> From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
> 
> This patch adds the option to specify a maximal clock and a minimal vertical
> refresh rate.

What is this needed for ?

> Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
> [uli: renamed properties, fixed transposed parsing]
> Signed-off-by: Ulrich Hecht <uli+renesas@fpond.eu>
> ---
>  drivers/gpu/drm/bridge/adv7511/adv7511.h     |  7 +++++++
>  drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 22 ++++++++++++++++++++++

You're missing updates to the DT bindings.

>  2 files changed, 29 insertions(+)
> 
> diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h
> b/drivers/gpu/drm/bridge/adv7511/adv7511.h index 73d8ccb..7f29d4f 100644
> --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
> +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
> @@ -271,6 +271,8 @@ enum adv7511_sync_polarity {
>   * @sync_pulse:			Select the sync pulse
>   * @vsync_polarity:		vsync input signal configuration
>   * @hsync_polarity:		hsync input signal configuration
> + * @min_vrefresh_option:	min vrefresh option
> + * @max_freq_option:		max frequency option
>   */
>  struct adv7511_link_config {
>  	unsigned int input_color_depth;
> @@ -285,6 +287,9 @@ struct adv7511_link_config {
>  	enum adv7511_input_sync_pulse sync_pulse;
>  	enum adv7511_sync_polarity vsync_polarity;
>  	enum adv7511_sync_polarity hsync_polarity;
> +
> +	unsigned int min_vrefresh_option;
> +	unsigned int max_freq_option;
>  };
> 
>  /**
> @@ -354,6 +359,8 @@ struct adv7511 {
>  	enum adv7511_sync_polarity vsync_polarity;
>  	enum adv7511_sync_polarity hsync_polarity;
>  	bool rgb;
> +	unsigned int min_vref;
> +	unsigned int max_freq;
> 
>  	struct gpio_desc *gpio_pd;
> 
> diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index 6437b87..2938b02
> 100644
> --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> @@ -323,6 +323,8 @@ static void adv7511_set_link_config(struct adv7511
> *adv7511, adv7511->hsync_polarity = config->hsync_polarity;
>  	adv7511->vsync_polarity = config->vsync_polarity;
>  	adv7511->rgb = config->input_colorspace == HDMI_COLORSPACE_RGB;
> +	adv7511->min_vref = config->min_vrefresh_option;
> +	adv7511->max_freq = config->max_freq_option;
>  }
> 
>  static void __adv7511_power_on(struct adv7511 *adv7511)
> @@ -660,6 +662,16 @@ static enum drm_mode_status adv7511_mode_valid(struct
> adv7511 *adv7511, if (mode->clock > 165000)
>  		return MODE_CLOCK_HIGH;
> 
> +	if (adv7511->max_freq) {
> +		if (mode->clock > (adv7511->max_freq / 1000))
> +			return MODE_CLOCK_HIGH;
> +	}
> +
> +	if (adv7511->min_vref) {
> +		if (drm_mode_vrefresh(mode) < adv7511->min_vref)
> +			return MODE_BAD;
> +	}
> +
>  	return MODE_OK;
>  }
> 
> @@ -1074,6 +1086,16 @@ static int adv7511_parse_dt(struct device_node *np,
>  	config->vsync_polarity = ADV7511_SYNC_POLARITY_PASSTHROUGH;
>  	config->hsync_polarity = ADV7511_SYNC_POLARITY_PASSTHROUGH;
> 
> +	ret = of_property_read_u32(np, "max-clock",
> +				   &config->max_freq_option);
> +	if (ret < 0)
> +		config->max_freq_option = 0;
> +
> +	ret = of_property_read_u32(np, "min-vrefresh",
> +				   &config->min_vrefresh_option);
> +	if (ret < 0)
> +		config->min_vrefresh_option = 0;
> +
>  	return 0;
>  }


-- 
Regards,

Laurent Pinchart



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

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

* Re: [PROTO][PATCH 06/10] drm: rcar-du: Fix procedure for extal and dotclkin selection
  2018-08-14 13:50   ` Ulrich Hecht
@ 2018-08-20  9:40     ` Laurent Pinchart
  -1 siblings, 0 replies; 50+ messages in thread
From: Laurent Pinchart @ 2018-08-20  9:40 UTC (permalink / raw)
  To: Ulrich Hecht
  Cc: linux-renesas-soc, dri-devel, jacopo+renesas,
	kieran.bingham+renesas, Koji Matsuoka

Hi Ulrich,

Thank you for the patch.

On Tuesday, 14 August 2018 16:50:00 EEST Ulrich Hecht wrote:
> From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
> 
> This patch corrects that the extal clock used with the fixed value
> is acquired from the device tree.
> Also, it is possible to select extal or dotclkin for R8A77995 and
> R8A77990. This patch adds its selection procedure.
> 
> Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
> ---
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.c   | 12 ++++++++++++
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.h   |  2 ++
>  drivers/gpu/drm/rcar-du/rcar_lvds_regs.h |  4 +---

DT bindings are missing for this clock.

>  3 files changed, 15 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c index a903456..4e22d40 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> @@ -942,10 +942,22 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp,
> unsigned int swindex, return PTR_ERR(rcrtc->clock);
>  	}
> 
> +	sprintf(clk_name, "extal");
> +	clk = devm_clk_get(rcdu->dev, clk_name);

Unless I'm mistaken, this clock is specific to the LVDS encoder, it's not used 
by the DU. Why is it handled in the DU driver ?

> +	if (!IS_ERR(clk)) {
> +		rcrtc->extclock = clk;
> +		rcrtc->extal_use = true;
> +	} else if (PTR_ERR(rcrtc->clock) == -EPROBE_DEFER) {
> +		dev_info(rcdu->dev, "can't get extal clock %u\n",
> +			 hwindex);
> +		return -EPROBE_DEFER;
> +	}
> +
>  	sprintf(clk_name, "dclkin.%u", hwindex);
>  	clk = devm_clk_get(rcdu->dev, clk_name);
>  	if (!IS_ERR(clk)) {
>  		rcrtc->extclock = clk;
> +		rcrtc->extal_use = false;
>  	} else if (PTR_ERR(rcrtc->clock) == -EPROBE_DEFER) {
>  		dev_info(rcdu->dev, "can't get external clock %u\n", hwindex);
>  		return -EPROBE_DEFER;
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h index 65de551..fa27104 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> @@ -45,6 +45,7 @@ struct rcar_du_vsp;
>   * @vsp: VSP feeding video to this CRTC
>   * @vsp_pipe: index of the VSP pipeline feeding video to this CRTC
>   * @lvds_ch: index of LVDS
> + * @extal_use: extal clock use
>   */
>  struct rcar_du_crtc {
>  	struct drm_crtc crtc;
> @@ -69,6 +70,7 @@ struct rcar_du_crtc {
>  	struct rcar_du_vsp *vsp;
>  	unsigned int vsp_pipe;
>  	int lvds_ch;
> +	bool extal_use;

This field is used in patch 04/10... It would be nice to make sure that each 
commit compiles when submitting a patch series.

>  };
> 
>  #define to_rcar_crtc(c)	container_of(c, struct rcar_du_crtc, crtc)
> diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
> b/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h index e37db95..4899062 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
> @@ -46,15 +46,13 @@
>  #define LVDPLLCR_PLLDIVCNT_148M		(0x046c1 << 0)
>  #define LVDPLLCR_PLLDIVCNT_MASK		(0x7ffff << 0)
> 
> -/* R-Car D3 */
>  #define LVDPLLCR_PLLON			(1 << 22)
>  #define LVDPLLCR_PLLSEL_PLL0		(0 << 20)
>  #define LVDPLLCR_PLLSEL_LVX		(1 << 20)
>  #define LVDPLLCR_PLLSEL_PLL1		(2 << 20)
>  #define LVDPLLCR_CKSEL_LVX		(1 << 17)
>  #define LVDPLLCR_CKSEL_EXTAL		(3 << 17)
> -#define LVDPLLCR_CKSEL_DU_DOTCLKIN0	(5 << 17)
> -#define LVDPLLCR_CKSEL_DU_DOTCLKIN1	(7 << 17)
> +#define LVDPLLCR_CKSEL_DU_DOTCLKIN(n)	((5 + (n) * 2) << 17)

This seems to belong to patch 04/10.

>  #define LVDPLLCR_OCKSEL_7		(0 << 16)
>  #define LVDPLLCR_OCKSEL_NOT_DIVIDED	(1 << 16)
>  #define LVDPLLCR_STP_CLKOUTE1_DIS	(0 << 14)

-- 
Regards,

Laurent Pinchart

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

* Re: [PROTO][PATCH 06/10] drm: rcar-du: Fix procedure for extal and dotclkin selection
@ 2018-08-20  9:40     ` Laurent Pinchart
  0 siblings, 0 replies; 50+ messages in thread
From: Laurent Pinchart @ 2018-08-20  9:40 UTC (permalink / raw)
  To: Ulrich Hecht
  Cc: linux-renesas-soc, kieran.bingham+renesas, jacopo+renesas,
	Koji Matsuoka, dri-devel

Hi Ulrich,

Thank you for the patch.

On Tuesday, 14 August 2018 16:50:00 EEST Ulrich Hecht wrote:
> From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
> 
> This patch corrects that the extal clock used with the fixed value
> is acquired from the device tree.
> Also, it is possible to select extal or dotclkin for R8A77995 and
> R8A77990. This patch adds its selection procedure.
> 
> Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
> ---
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.c   | 12 ++++++++++++
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.h   |  2 ++
>  drivers/gpu/drm/rcar-du/rcar_lvds_regs.h |  4 +---

DT bindings are missing for this clock.

>  3 files changed, 15 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c index a903456..4e22d40 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> @@ -942,10 +942,22 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp,
> unsigned int swindex, return PTR_ERR(rcrtc->clock);
>  	}
> 
> +	sprintf(clk_name, "extal");
> +	clk = devm_clk_get(rcdu->dev, clk_name);

Unless I'm mistaken, this clock is specific to the LVDS encoder, it's not used 
by the DU. Why is it handled in the DU driver ?

> +	if (!IS_ERR(clk)) {
> +		rcrtc->extclock = clk;
> +		rcrtc->extal_use = true;
> +	} else if (PTR_ERR(rcrtc->clock) == -EPROBE_DEFER) {
> +		dev_info(rcdu->dev, "can't get extal clock %u\n",
> +			 hwindex);
> +		return -EPROBE_DEFER;
> +	}
> +
>  	sprintf(clk_name, "dclkin.%u", hwindex);
>  	clk = devm_clk_get(rcdu->dev, clk_name);
>  	if (!IS_ERR(clk)) {
>  		rcrtc->extclock = clk;
> +		rcrtc->extal_use = false;
>  	} else if (PTR_ERR(rcrtc->clock) == -EPROBE_DEFER) {
>  		dev_info(rcdu->dev, "can't get external clock %u\n", hwindex);
>  		return -EPROBE_DEFER;
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h index 65de551..fa27104 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> @@ -45,6 +45,7 @@ struct rcar_du_vsp;
>   * @vsp: VSP feeding video to this CRTC
>   * @vsp_pipe: index of the VSP pipeline feeding video to this CRTC
>   * @lvds_ch: index of LVDS
> + * @extal_use: extal clock use
>   */
>  struct rcar_du_crtc {
>  	struct drm_crtc crtc;
> @@ -69,6 +70,7 @@ struct rcar_du_crtc {
>  	struct rcar_du_vsp *vsp;
>  	unsigned int vsp_pipe;
>  	int lvds_ch;
> +	bool extal_use;

This field is used in patch 04/10... It would be nice to make sure that each 
commit compiles when submitting a patch series.

>  };
> 
>  #define to_rcar_crtc(c)	container_of(c, struct rcar_du_crtc, crtc)
> diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
> b/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h index e37db95..4899062 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
> @@ -46,15 +46,13 @@
>  #define LVDPLLCR_PLLDIVCNT_148M		(0x046c1 << 0)
>  #define LVDPLLCR_PLLDIVCNT_MASK		(0x7ffff << 0)
> 
> -/* R-Car D3 */
>  #define LVDPLLCR_PLLON			(1 << 22)
>  #define LVDPLLCR_PLLSEL_PLL0		(0 << 20)
>  #define LVDPLLCR_PLLSEL_LVX		(1 << 20)
>  #define LVDPLLCR_PLLSEL_PLL1		(2 << 20)
>  #define LVDPLLCR_CKSEL_LVX		(1 << 17)
>  #define LVDPLLCR_CKSEL_EXTAL		(3 << 17)
> -#define LVDPLLCR_CKSEL_DU_DOTCLKIN0	(5 << 17)
> -#define LVDPLLCR_CKSEL_DU_DOTCLKIN1	(7 << 17)
> +#define LVDPLLCR_CKSEL_DU_DOTCLKIN(n)	((5 + (n) * 2) << 17)

This seems to belong to patch 04/10.

>  #define LVDPLLCR_OCKSEL_7		(0 << 16)
>  #define LVDPLLCR_OCKSEL_NOT_DIVIDED	(1 << 16)
>  #define LVDPLLCR_STP_CLKOUTE1_DIS	(0 << 14)

-- 
Regards,

Laurent Pinchart



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

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

* Re: [PROTO][PATCH 00/10] R-Car D3 LVDS/HDMI support (with PLL)
  2018-08-14 13:49 ` Ulrich Hecht
@ 2018-08-20  9:50   ` Laurent Pinchart
  -1 siblings, 0 replies; 50+ messages in thread
From: Laurent Pinchart @ 2018-08-20  9:50 UTC (permalink / raw)
  To: Ulrich Hecht
  Cc: linux-renesas-soc, dri-devel, jacopo+renesas, kieran.bingham+renesas

Hi Ulrich,

Thank you for the patches.

On Tuesday, 14 August 2018 16:49:54 EEST Ulrich Hecht wrote:
> Hi!
> 
> This is a prototype extension of the series "R-Car D3 LVDS/HDMI support"
> that includes an up-port of the LVDS PLL support in the BSP.
> 
> While this is prototype-quality code, there are in my judgment no serious
> hacks in it.  The most significant deviation in behavior between this and
> the BSP code is that the LVDS PLL setup is not done in two steps, but in one
> go as the LVDS device is enabled.  This was easier to implement, and works
> just as fine.
> 
> Instructions for testing this are found at
> https://elinux.org/User:Uli/D3_HDMI_Test, including links to git trees based
> on renesas-drivers and drm-next, as well as config files for each.

The instructions there end with

"4. Boot kernel and observe activity on HDMI display."

Does "activity" mean that I can expect a working HDMI output with a proper 
image on the display ? :-)

-- 
Regards,

Laurent Pinchart

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

* Re: [PROTO][PATCH 00/10] R-Car D3 LVDS/HDMI support (with PLL)
@ 2018-08-20  9:50   ` Laurent Pinchart
  0 siblings, 0 replies; 50+ messages in thread
From: Laurent Pinchart @ 2018-08-20  9:50 UTC (permalink / raw)
  To: Ulrich Hecht
  Cc: linux-renesas-soc, kieran.bingham+renesas, jacopo+renesas, dri-devel

Hi Ulrich,

Thank you for the patches.

On Tuesday, 14 August 2018 16:49:54 EEST Ulrich Hecht wrote:
> Hi!
> 
> This is a prototype extension of the series "R-Car D3 LVDS/HDMI support"
> that includes an up-port of the LVDS PLL support in the BSP.
> 
> While this is prototype-quality code, there are in my judgment no serious
> hacks in it.  The most significant deviation in behavior between this and
> the BSP code is that the LVDS PLL setup is not done in two steps, but in one
> go as the LVDS device is enabled.  This was easier to implement, and works
> just as fine.
> 
> Instructions for testing this are found at
> https://elinux.org/User:Uli/D3_HDMI_Test, including links to git trees based
> on renesas-drivers and drm-next, as well as config files for each.

The instructions there end with

"4. Boot kernel and observe activity on HDMI display."

Does "activity" mean that I can expect a working HDMI output with a proper 
image on the display ? :-)

-- 
Regards,

Laurent Pinchart



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

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

* Re: [PROTO][PATCH 01/10] drm: rcar-du: Add clk_set_rate for external clock device
  2018-08-14 13:49   ` Ulrich Hecht
@ 2018-08-20 10:10     ` Laurent Pinchart
  -1 siblings, 0 replies; 50+ messages in thread
From: Laurent Pinchart @ 2018-08-20 10:10 UTC (permalink / raw)
  To: Ulrich Hecht
  Cc: linux-renesas-soc, dri-devel, jacopo+renesas,
	kieran.bingham+renesas, Koji Matsuoka

Hi Ulrich,

Thank you for the patch.

On Tuesday, 14 August 2018 16:49:55 EEST Ulrich Hecht wrote:
> From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
> 
> Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
> ---
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c index b52b3e8..cd6803a 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> @@ -229,6 +229,7 @@ static void rcar_du_crtc_set_display_timing(struct
> rcar_du_crtc *rcrtc) unsigned long rate;
>  		u32 extdiv;
> 
> +		clk_set_rate(rcrtc->extclock, mode_clock);

This is a hack, Jacopo has posted "[PATCH 3/3] drm: rcar-du: Improve non-DPLL 
clock selection" which I think is a better solution (or will be in v2 :-)).

>  		extclk = clk_get_rate(rcrtc->extclock);
>  		if (rcdu->info->dpll_ch & (1 << rcrtc->index)) {
>  			unsigned long target = mode_clock;

-- 
Regards,

Laurent Pinchart

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

* Re: [PROTO][PATCH 01/10] drm: rcar-du: Add clk_set_rate for external clock device
@ 2018-08-20 10:10     ` Laurent Pinchart
  0 siblings, 0 replies; 50+ messages in thread
From: Laurent Pinchart @ 2018-08-20 10:10 UTC (permalink / raw)
  To: Ulrich Hecht
  Cc: linux-renesas-soc, kieran.bingham+renesas, jacopo+renesas,
	Koji Matsuoka, dri-devel

Hi Ulrich,

Thank you for the patch.

On Tuesday, 14 August 2018 16:49:55 EEST Ulrich Hecht wrote:
> From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
> 
> Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
> ---
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c index b52b3e8..cd6803a 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> @@ -229,6 +229,7 @@ static void rcar_du_crtc_set_display_timing(struct
> rcar_du_crtc *rcrtc) unsigned long rate;
>  		u32 extdiv;
> 
> +		clk_set_rate(rcrtc->extclock, mode_clock);

This is a hack, Jacopo has posted "[PATCH 3/3] drm: rcar-du: Improve non-DPLL 
clock selection" which I think is a better solution (or will be in v2 :-)).

>  		extclk = clk_get_rate(rcrtc->extclock);
>  		if (rcdu->info->dpll_ch & (1 << rcrtc->index)) {
>  			unsigned long target = mode_clock;

-- 
Regards,

Laurent Pinchart



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

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

* Re: [PROTO][PATCH 04/10] drm: rcar-du: lvds: LVDS PLL support
  2018-08-14 13:49   ` Ulrich Hecht
@ 2018-08-20 10:48     ` Laurent Pinchart
  -1 siblings, 0 replies; 50+ messages in thread
From: Laurent Pinchart @ 2018-08-20 10:48 UTC (permalink / raw)
  To: Ulrich Hecht
  Cc: linux-renesas-soc, dri-devel, jacopo+renesas, kieran.bingham+renesas

Hi Ulrich,

Thank you for the patch.

On Tuesday, 14 August 2018 16:49:58 EEST Ulrich Hecht wrote:
> In R-Car D3 and E3, the DU dot clock can be sourced from the LVDS PLL.
> This patch enables that PLL if present.
> 
> Based on patch by Koji Matsuoka <koji.matsuoka.xm@renesas.com>.
> 
> Signed-off-by: Ulrich Hecht <uli+renesas@fpond.eu>
> ---
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.c   |   3 +
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.h   |   2 +
>  drivers/gpu/drm/rcar-du/rcar_du_drv.c    |   3 +-
>  drivers/gpu/drm/rcar-du/rcar_du_drv.h    |   1 +
>  drivers/gpu/drm/rcar-du/rcar_du_group.c  |  11 +-
>  drivers/gpu/drm/rcar-du/rcar_lvds.c      | 212 ++++++++++++++++++++++++++++
>  drivers/gpu/drm/rcar-du/rcar_lvds_regs.h |  46 ++++++-

The DU and LVDS encoder changes should be split in two patches.

>  7 files changed, 274 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c index 9153e7a..a903456 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> @@ -275,6 +275,9 @@ static void rcar_du_crtc_set_display_timing(struct
> rcar_du_crtc *rcrtc) mode_clock, extrate, rate, escr);
>  	}
> 
> +	if (rcar_du_has(rcdu, RCAR_DU_FEATURE_LVDS_PLL))
> +		escr = 0;
> +
>  	rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? ESCR2 : ESCR,
>  			    escr);
>  	rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? OTAR2 : OTAR, 0);
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h index 7680cb2..65de551 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> @@ -44,6 +44,7 @@ struct rcar_du_vsp;
>   * @group: CRTC group this CRTC belongs to
>   * @vsp: VSP feeding video to this CRTC
>   * @vsp_pipe: index of the VSP pipeline feeding video to this CRTC
> + * @lvds_ch: index of LVDS
>   */
>  struct rcar_du_crtc {
>  	struct drm_crtc crtc;
> @@ -67,6 +68,7 @@ struct rcar_du_crtc {
>  	struct rcar_du_group *group;
>  	struct rcar_du_vsp *vsp;
>  	unsigned int vsp_pipe;
> +	int lvds_ch;

This field is never set or used.

>  };
> 
>  #define to_rcar_crtc(c)	container_of(c, struct rcar_du_crtc, crtc)
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> b/drivers/gpu/drm/rcar-du/rcar_du_drv.c index d930996..3338ef5 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> @@ -299,7 +299,8 @@ static const struct rcar_du_device_info
> rcar_du_r8a77995_info = {
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
>  		  | RCAR_DU_FEATURE_VSP1_SOURCE
> -		  | RCAR_DU_FEATURE_R8A77995_REGS,
> +		  | RCAR_DU_FEATURE_R8A77995_REGS
> +		  | RCAR_DU_FEATURE_LVDS_PLL,
>  	.quirks = RCAR_DU_QUIRK_TVM_MASTER_ONLY,
>  	.channels_mask = BIT(1) | BIT(0),
>  	.routes = {
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> b/drivers/gpu/drm/rcar-du/rcar_du_drv.h index 9355b58..6009b7d 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> @@ -32,6 +32,7 @@ struct rcar_du_device;
>  #define RCAR_DU_FEATURE_VSP1_SOURCE	(1 << 2)	/* Has inputs from VSP1 */
>  #define RCAR_DU_FEATURE_R8A77965_REGS	(1 << 3)	/* Use R8A77965 registers 
*/
> #define RCAR_DU_FEATURE_R8A77995_REGS	(1 << 4)	/* Use R8A77995 registers 
*/
> +#define RCAR_DU_FEATURE_LVDS_PLL	(1 << 5)	/* Use PLL in LVDS */

The feature bit should tell if the LVDS encore has a PLL. Whether to use it or 
not should be a runtime decision.

>  #define RCAR_DU_QUIRK_ALIGN_128B	(1 << 0)	/* Align pitches to 128 bytes 
*/
>  #define RCAR_DU_QUIRK_TVM_MASTER_ONLY	(1 << 1)	/* Does not have TV
> switch/sync modes */ diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c
> b/drivers/gpu/drm/rcar-du/rcar_du_group.c index 371d780..44681e3 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
> @@ -126,8 +126,15 @@ static void rcar_du_group_setup(struct rcar_du_group
> *rgrp) * are setup through per-group registers, only available when
>  		 * the group has two channels.
>  		 */
> -		if ((rcdu->info->gen < 3 && rgrp->index == 0) ||
> -		    (rcdu->info->gen == 3 &&  rgrp->num_crtcs > 1))
> +		if (rcar_du_has(rcdu, RCAR_DU_FEATURE_LVDS_PLL))
> +			rcar_du_group_write(rgrp,
> +					    DIDSR, DIDSR_CODE |
> +					    DIDSR_LCDS_LVDS0(1) |
> +					    DIDSR_LCDS_LVDS0(0) |
> +					    DIDSR_PDCS_CLK(1, 0) |
> +					    DIDSR_PDCS_CLK(0, 0));
> +		else if ((rcdu->info->gen < 3 && rgrp->index == 0) ||
> +			 (rcdu->info->gen == 3 &&  rgrp->num_crtcs > 1))
>  			rcar_du_group_write(rgrp, DIDSR, DIDSR_CODE);
>  	}
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c
> b/drivers/gpu/drm/rcar-du/rcar_lvds.c index 4c39de3..cd55576 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_lvds.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_lvds.c
> @@ -23,6 +23,8 @@
>  #include <drm/drm_panel.h>
> 
>  #include "rcar_lvds_regs.h"
> +#include "rcar_du_crtc.h"
> +#include "rcar_du_drv.h"

That's a layering violation that I'd like to avoid.

>  /* Keep in sync with the LVDCR0.LVMD hardware register values. */
>  enum rcar_lvds_mode {
> @@ -65,6 +67,15 @@ struct rcar_lvds {
>  #define connector_to_rcar_lvds(connector) \
>  	container_of(connector, struct rcar_lvds, connector)
> 
> +struct pll_info {
> +	unsigned int pllclk;
> +	unsigned int diff;
> +	unsigned int clk_n;
> +	unsigned int clk_m;
> +	unsigned int clk_e;
> +	unsigned int div;
> +};
> +
>  static void rcar_lvds_write(struct rcar_lvds *lvds, u32 reg, u32 data)
>  {
>  	iowrite32(data, lvds->mmio + reg);
> @@ -155,6 +166,198 @@ static u32 rcar_lvds_lvdpllcr_gen3(unsigned int freq)
>  		return LVDPLLCR_PLLDIVCNT_148M;
>  }
> 
> +static void rcar_lvds_pll_calc(struct rcar_du_crtc *rcrtc,
> +				     struct pll_info *pll, unsigned int in_fre,
> +				     unsigned int mode_freq, bool edivider)
> +{
> +	unsigned long diff = (unsigned long)-1;
> +	unsigned long fout, fpfd, fvco, n, m, e, div;
> +	bool clk_diff_set = true;
> +
> +	if (in_fre < 12000000 || in_fre > 192000000)
> +		return;
> +
> +	for (n = 0; n < 127; n++) {
> +		if (n + 1 < 60 || n + 1 > 120)
> +			continue;

Seriously ? :-)

> +		for (m = 0; m < 7; m++) {
> +			for (e = 0; e < 1; e++) {
> +				if (edivider)
> +					fout = (((in_fre / 1000) * (n + 1)) /
> +						((m + 1) * (e + 1) * 2)) *
> +						1000;
> +				else
> +					fout = (((in_fre / 1000) * (n + 1)) /
> +						(m + 1)) * 1000;
> +
> +				if (fout > 1039500000)
> +					continue;
> +
> +				fpfd  = (in_fre / (m + 1));
> +				if (fpfd < 12000000 || fpfd > 24000000)
> +					continue;
> +
> +				fvco  = (((in_fre / 1000) * (n + 1)) / (m + 1))
> +					 * 1000;
> +				if (fvco < 900000000 || fvco > 1800000000)
> +					continue;
> +
> +				fout = fout / 7; /* 7 divider */
> +
> +				for (div = 0; div < 64; div++) {

That's a lot of iterations for the four nested loops, surely it can be 
simplified.

> +					diff = abs((long)(fout / (div + 1)) -
> +					       (long)mode_freq);
> +
> +					if (clk_diff_set ||
> +					    (diff == 0 ||
> +					    pll->diff > diff)) {
> +						pll->diff = diff;
> +						pll->clk_n = n;
> +						pll->clk_m = m;
> +						pll->clk_e = e;
> +						pll->pllclk = fout;
> +						pll->div = div;
> +
> +						clk_diff_set = false;
> +
> +						if (diff == 0)
> +							return;
> +					}
> +				}
> +			}
> +		}
> +	}
> +}
> +
> +static void rcar_lvds_pll_pre_start(struct rcar_lvds *lvds,
> +				    struct rcar_du_crtc *rcrtc)
> +{
> +	const struct drm_display_mode *mode =
> +				&rcrtc->crtc.state->adjusted_mode;
> +	unsigned int mode_freq = mode->clock * 1000;
> +	unsigned int ext_clk = 0;
> +	struct pll_info *lvds_pll[2];
> +	u32 clksel, cksel;
> +	int i, ret;
> +
> +	if (rcrtc->extclock)
> +		ext_clk = clk_get_rate(rcrtc->extclock);
> +	else
> +		dev_warn(lvds->dev, "external clock is not set\n");
> +
> +	dev_dbg(lvds->dev, "external clock %d Hz\n", ext_clk);
> +
> +	if (lvds->enabled)
> +		return;
> +
> +	for (i = 0; i < 2; i++) {
> +		lvds_pll[i] = kzalloc(sizeof(*lvds_pll), GFP_KERNEL);
> +		if (!lvds_pll[i])
> +			return;

Memory leak if kzalloc() fails in any but the first iteration.

Why do you need dynamic allocation at all ?

> +	}
> +
> +	/* software reset release */
> +	reset_control_deassert(lvds->rst);
> +
> +	ret = clk_prepare_enable(lvds->clock);
> +	if (ret < 0)
> +		goto end;
> +
> +	for (i = 0; i < 2; i++) {
> +		bool edivider;
> +
> +		if (i == 0)
> +			edivider = true;
> +		else
> +			edivider = false;
> +
> +		rcar_lvds_pll_calc(rcrtc, lvds_pll[i], ext_clk,
> +					 mode_freq, edivider);
> +	}
> +
> +	dev_dbg(lvds->dev, "mode_frequency %d Hz\n", mode_freq);
> +
> +	if (lvds_pll[1]->diff >= lvds_pll[0]->diff) {
> +		/* use E-edivider */
> +		i = 0;
> +		clksel = LVDPLLCR_OUTCLKSEL_AFTER |
> +			 LVDPLLCR_STP_CLKOUTE1_EN;
> +	} else {
> +		/* do not use E-divider */
> +		i = 1;
> +		clksel = LVDPLLCR_OUTCLKSEL_BEFORE |
> +			 LVDPLLCR_STP_CLKOUTE1_DIS;
> +	}
> +	dev_dbg(lvds->dev,
> +		"E-divider %s\n", (i == 0 ? "is used" : "is not used"));
> +
> +	dev_dbg(lvds->dev,
> +		"pllclk:%u, n:%u, m:%u, e:%u, diff:%u, div:%u\n",
> +		 lvds_pll[i]->pllclk, lvds_pll[i]->clk_n, lvds_pll[i]->clk_m,
> +		 lvds_pll[i]->clk_e, lvds_pll[i]->diff, lvds_pll[i]->div);
> +
> +	if (rcrtc->extal_use)
> +		cksel = LVDPLLCR_CKSEL_EXTAL;
> +	else
> +		cksel = LVDPLLCR_CKSEL_DU_DOTCLKIN(rcrtc->index);
> +
> +	rcar_lvds_write(lvds, LVDPLLCR, LVDPLLCR_PLLON |
> +			LVDPLLCR_OCKSEL_7 | clksel | LVDPLLCR_CLKOUT_ENABLE |
> +			cksel | (lvds_pll[i]->clk_e << 10) |
> +			(lvds_pll[i]->clk_n << 3) | lvds_pll[i]->clk_m);
> +
> +	if (lvds_pll[i]->div > 0)
> +		rcar_lvds_write(lvds, LVDDIV, LVDDIV_DIVSEL |
> +				LVDDIV_DIVRESET | lvds_pll[i]->div);
> +	else
> +		rcar_lvds_write(lvds, LVDDIV, 0);
> +
> +	dev_dbg(lvds->dev, "LVDPLLCR: 0x%x\n",
> +		ioread32(lvds->mmio + LVDPLLCR));
> +	dev_dbg(lvds->dev, "LVDDIV: 0x%x\n",
> +		ioread32(lvds->mmio + LVDDIV));
> +
> +end:
> +	for (i = 0; i < 2; i++)
> +		kfree(lvds_pll[i]);
> +}
> +
> +static void rcar_lvds_pll_start(struct rcar_lvds *lvds,
> +			       struct rcar_du_crtc *rcrtc)
> +{
> +	u32 lvdhcr, lvdcr0;
> +
> +	rcar_lvds_write(lvds, LVDCTRCR, LVDCTRCR_CTR3SEL_ZERO |
> +			LVDCTRCR_CTR2SEL_DISP | LVDCTRCR_CTR1SEL_VSYNC |
> +			LVDCTRCR_CTR0SEL_HSYNC);
> +
> +	lvdhcr = LVDCHCR_CHSEL_CH(0, 0) | LVDCHCR_CHSEL_CH(1, 1) |
> +		 LVDCHCR_CHSEL_CH(2, 2) | LVDCHCR_CHSEL_CH(3, 3);
> +	rcar_lvds_write(lvds, LVDCHCR, lvdhcr);
> +
> +	rcar_lvds_write(lvds, LVDSTRIPE, 0);
> +	/* Turn all the channels on. */
> +	rcar_lvds_write(lvds, LVDCR1,
> +			LVDCR1_CHSTBY(3) | LVDCR1_CHSTBY(2) |
> +			LVDCR1_CHSTBY(1) | LVDCR1_CHSTBY(0) |
> +			LVDCR1_CLKSTBY);
> +	/*
> +	 * Turn the PLL on, set it to LVDS normal mode, wait for the startup
> +	 * delay and turn the output on.
> +	 */
> +	lvdcr0 = (lvds->mode << LVDCR0_LVMD_SHIFT) | LVDCR0_PWD;
> +	rcar_lvds_write(lvds, LVDCR0, lvdcr0);
> +
> +	lvdcr0 |= LVDCR0_LVEN;
> +	rcar_lvds_write(lvds, LVDCR0, lvdcr0);
> +
> +	lvdcr0 |= LVDCR0_LVRES;
> +	rcar_lvds_write(lvds, LVDCR0, lvdcr0);
> +
> +	lvds->enabled = true;
> +}
> +
>  static void rcar_lvds_enable(struct drm_bridge *bridge)
>  {
>  	struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
> @@ -164,6 +367,7 @@ static void rcar_lvds_enable(struct drm_bridge *bridge)
>  	 * do we get a state pointer?
>  	 */
>  	struct drm_crtc *crtc = lvds->bridge.encoder->crtc;
> +	struct rcar_du_device *rcdu = to_rcar_crtc(crtc)->group->dev;
>  	u32 lvdpllcr;
>  	u32 lvdhcr;
>  	u32 lvdcr0;
> @@ -171,6 +375,12 @@ static void rcar_lvds_enable(struct drm_bridge *bridge)
> 
>  	WARN_ON(lvds->enabled);
> 
> +	if (rcar_du_has(rcdu, RCAR_DU_FEATURE_LVDS_PLL)) {

This should be turned into an LVDS encoder feature bit.

> +		rcar_lvds_pll_pre_start(lvds, to_rcar_crtc(crtc));
> +		rcar_lvds_pll_start(lvds, to_rcar_crtc(crtc));
> +		return;
> +	}
> +
>  	ret = clk_prepare_enable(lvds->clock);
>  	if (ret < 0)
>  		return;
> @@ -264,6 +474,7 @@ static void rcar_lvds_disable(struct drm_bridge *bridge)
> 
>  	rcar_lvds_write(lvds, LVDCR0, 0);
>  	rcar_lvds_write(lvds, LVDCR1, 0);
> +	rcar_lvds_write(lvds, LVDPLLCR, 0);
> 
>  	clk_disable_unprepare(lvds->clock);
> 
> @@ -522,6 +733,7 @@ static const struct of_device_id rcar_lvds_of_table[] =
> { { .compatible = "renesas,r8a7795-lvds", .data = &rcar_lvds_gen3_info }, {
> .compatible = "renesas,r8a7796-lvds", .data = &rcar_lvds_gen3_info }, {
> .compatible = "renesas,r8a77970-lvds", .data = &rcar_lvds_r8a77970_info },
> +	{ .compatible = "renesas,r8a77995-lvds", .data = &rcar_lvds_gen3_info },
> { }
>  };
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
> b/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h index 2896835..e37db95 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
> @@ -21,7 +21,7 @@
>  #define LVDCR0_PLLON			(1 << 4)
>  #define LVDCR0_PWD			(1 << 2)		/* Gen3 only */
>  #define LVDCR0_BEN			(1 << 2)		/* Gen2 only */
> -#define LVDCR0_LVEN			(1 << 1)		/* Gen2 only */
> +#define LVDCR0_LVEN			(1 << 1)
>  #define LVDCR0_LVRES			(1 << 0)
> 
>  #define LVDCR1				0x0004
> @@ -46,6 +46,24 @@
>  #define LVDPLLCR_PLLDIVCNT_148M		(0x046c1 << 0)
>  #define LVDPLLCR_PLLDIVCNT_MASK		(0x7ffff << 0)
> 
> +/* R-Car D3 */
> +#define LVDPLLCR_PLLON			(1 << 22)
> +#define LVDPLLCR_PLLSEL_PLL0		(0 << 20)
> +#define LVDPLLCR_PLLSEL_LVX		(1 << 20)
> +#define LVDPLLCR_PLLSEL_PLL1		(2 << 20)
> +#define LVDPLLCR_CKSEL_LVX		(1 << 17)
> +#define LVDPLLCR_CKSEL_EXTAL		(3 << 17)
> +#define LVDPLLCR_CKSEL_DU_DOTCLKIN0	(5 << 17)
> +#define LVDPLLCR_CKSEL_DU_DOTCLKIN1	(7 << 17)
> +#define LVDPLLCR_OCKSEL_7		(0 << 16)
> +#define LVDPLLCR_OCKSEL_NOT_DIVIDED	(1 << 16)
> +#define LVDPLLCR_STP_CLKOUTE1_DIS	(0 << 14)
> +#define LVDPLLCR_STP_CLKOUTE1_EN	(1 << 14)
> +#define LVDPLLCR_OUTCLKSEL_BEFORE	(0 << 12)
> +#define LVDPLLCR_OUTCLKSEL_AFTER	(1 << 12)
> +#define LVDPLLCR_CLKOUT_DISABLE		(0 << 11)
> +#define LVDPLLCR_CLKOUT_ENABLE		(1 << 11)
> +
>  #define LVDCTRCR			0x000c
>  #define LVDCTRCR_CTR3SEL_ZERO		(0 << 12)
>  #define LVDCTRCR_CTR3SEL_ODD		(1 << 12)
> @@ -74,4 +92,30 @@
>  #define LVDCHCR_CHSEL_CH(n, c)		((((c) - (n)) & 3) << ((n) * 4))
>  #define LVDCHCR_CHSEL_MASK(n)		(3 << ((n) * 4))
> 
> +#define LVDSTRIPE			0x0014
> +#define LVDSTRIPE_ST_TRGSEL_DISP	(0 << 2)
> +#define LVDSTRIPE_ST_TRGSEL_HSYNC_R	(1 << 2)
> +#define LVDSTRIPE_ST_TRGSEL_HSYNC_F	(2 << 2)
> +
> +#define LVDSTRIPE_ST_SWAP_NORMAL	(0 << 1)
> +#define LVDSTRIPE_ST_SWAP_SWAP		(1 << 1)
> +#define LVDSTRIPE_ST_ON			(1 << 0)
> +
> +#define LVDSCR				0x0018
> +#define LVDSCR_DEPTH_DP1		(0 << 29)
> +#define LVDSCR_DEPTH_DP2		(1 << 29)
> +#define LVDSCR_DEPTH_DP3		(2 << 29)
> +#define LVDSCR_BANDSET_10KHZ_LESS_THAN	(1 << 28)
> +#define LVDSCR_SDIV_SR1			(0 << 22)
> +#define LVDSCR_SDIV_SR2			(1 << 22)
> +#define LVDSCR_SDIV_SR4			(2 << 22)
> +#define LVDSCR_SDIV_SR8			(3 << 22)
> +#define LVDSCR_MODE_DOWN		(1 << 21)
> +#define LVDSCR_RSTN_ENABLE		(1 << 20)
> +
> +#define LVDDIV				0x001c
> +#define LVDDIV_DIVSEL			(1 << 8)
> +#define LVDDIV_DIVRESET			(1 << 7)
> +#define LVDDIV_DIVSTP			(1 << 6)
> +
>  #endif /* __RCAR_LVDS_REGS_H__ */

-- 
Regards,

Laurent Pinchart

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

* Re: [PROTO][PATCH 04/10] drm: rcar-du: lvds: LVDS PLL support
@ 2018-08-20 10:48     ` Laurent Pinchart
  0 siblings, 0 replies; 50+ messages in thread
From: Laurent Pinchart @ 2018-08-20 10:48 UTC (permalink / raw)
  To: Ulrich Hecht
  Cc: linux-renesas-soc, kieran.bingham+renesas, jacopo+renesas, dri-devel

Hi Ulrich,

Thank you for the patch.

On Tuesday, 14 August 2018 16:49:58 EEST Ulrich Hecht wrote:
> In R-Car D3 and E3, the DU dot clock can be sourced from the LVDS PLL.
> This patch enables that PLL if present.
> 
> Based on patch by Koji Matsuoka <koji.matsuoka.xm@renesas.com>.
> 
> Signed-off-by: Ulrich Hecht <uli+renesas@fpond.eu>
> ---
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.c   |   3 +
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.h   |   2 +
>  drivers/gpu/drm/rcar-du/rcar_du_drv.c    |   3 +-
>  drivers/gpu/drm/rcar-du/rcar_du_drv.h    |   1 +
>  drivers/gpu/drm/rcar-du/rcar_du_group.c  |  11 +-
>  drivers/gpu/drm/rcar-du/rcar_lvds.c      | 212 ++++++++++++++++++++++++++++
>  drivers/gpu/drm/rcar-du/rcar_lvds_regs.h |  46 ++++++-

The DU and LVDS encoder changes should be split in two patches.

>  7 files changed, 274 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c index 9153e7a..a903456 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> @@ -275,6 +275,9 @@ static void rcar_du_crtc_set_display_timing(struct
> rcar_du_crtc *rcrtc) mode_clock, extrate, rate, escr);
>  	}
> 
> +	if (rcar_du_has(rcdu, RCAR_DU_FEATURE_LVDS_PLL))
> +		escr = 0;
> +
>  	rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? ESCR2 : ESCR,
>  			    escr);
>  	rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? OTAR2 : OTAR, 0);
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h index 7680cb2..65de551 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> @@ -44,6 +44,7 @@ struct rcar_du_vsp;
>   * @group: CRTC group this CRTC belongs to
>   * @vsp: VSP feeding video to this CRTC
>   * @vsp_pipe: index of the VSP pipeline feeding video to this CRTC
> + * @lvds_ch: index of LVDS
>   */
>  struct rcar_du_crtc {
>  	struct drm_crtc crtc;
> @@ -67,6 +68,7 @@ struct rcar_du_crtc {
>  	struct rcar_du_group *group;
>  	struct rcar_du_vsp *vsp;
>  	unsigned int vsp_pipe;
> +	int lvds_ch;

This field is never set or used.

>  };
> 
>  #define to_rcar_crtc(c)	container_of(c, struct rcar_du_crtc, crtc)
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> b/drivers/gpu/drm/rcar-du/rcar_du_drv.c index d930996..3338ef5 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> @@ -299,7 +299,8 @@ static const struct rcar_du_device_info
> rcar_du_r8a77995_info = {
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
>  		  | RCAR_DU_FEATURE_VSP1_SOURCE
> -		  | RCAR_DU_FEATURE_R8A77995_REGS,
> +		  | RCAR_DU_FEATURE_R8A77995_REGS
> +		  | RCAR_DU_FEATURE_LVDS_PLL,
>  	.quirks = RCAR_DU_QUIRK_TVM_MASTER_ONLY,
>  	.channels_mask = BIT(1) | BIT(0),
>  	.routes = {
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> b/drivers/gpu/drm/rcar-du/rcar_du_drv.h index 9355b58..6009b7d 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> @@ -32,6 +32,7 @@ struct rcar_du_device;
>  #define RCAR_DU_FEATURE_VSP1_SOURCE	(1 << 2)	/* Has inputs from VSP1 */
>  #define RCAR_DU_FEATURE_R8A77965_REGS	(1 << 3)	/* Use R8A77965 registers 
*/
> #define RCAR_DU_FEATURE_R8A77995_REGS	(1 << 4)	/* Use R8A77995 registers 
*/
> +#define RCAR_DU_FEATURE_LVDS_PLL	(1 << 5)	/* Use PLL in LVDS */

The feature bit should tell if the LVDS encore has a PLL. Whether to use it or 
not should be a runtime decision.

>  #define RCAR_DU_QUIRK_ALIGN_128B	(1 << 0)	/* Align pitches to 128 bytes 
*/
>  #define RCAR_DU_QUIRK_TVM_MASTER_ONLY	(1 << 1)	/* Does not have TV
> switch/sync modes */ diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c
> b/drivers/gpu/drm/rcar-du/rcar_du_group.c index 371d780..44681e3 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
> @@ -126,8 +126,15 @@ static void rcar_du_group_setup(struct rcar_du_group
> *rgrp) * are setup through per-group registers, only available when
>  		 * the group has two channels.
>  		 */
> -		if ((rcdu->info->gen < 3 && rgrp->index == 0) ||
> -		    (rcdu->info->gen == 3 &&  rgrp->num_crtcs > 1))
> +		if (rcar_du_has(rcdu, RCAR_DU_FEATURE_LVDS_PLL))
> +			rcar_du_group_write(rgrp,
> +					    DIDSR, DIDSR_CODE |
> +					    DIDSR_LCDS_LVDS0(1) |
> +					    DIDSR_LCDS_LVDS0(0) |
> +					    DIDSR_PDCS_CLK(1, 0) |
> +					    DIDSR_PDCS_CLK(0, 0));
> +		else if ((rcdu->info->gen < 3 && rgrp->index == 0) ||
> +			 (rcdu->info->gen == 3 &&  rgrp->num_crtcs > 1))
>  			rcar_du_group_write(rgrp, DIDSR, DIDSR_CODE);
>  	}
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c
> b/drivers/gpu/drm/rcar-du/rcar_lvds.c index 4c39de3..cd55576 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_lvds.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_lvds.c
> @@ -23,6 +23,8 @@
>  #include <drm/drm_panel.h>
> 
>  #include "rcar_lvds_regs.h"
> +#include "rcar_du_crtc.h"
> +#include "rcar_du_drv.h"

That's a layering violation that I'd like to avoid.

>  /* Keep in sync with the LVDCR0.LVMD hardware register values. */
>  enum rcar_lvds_mode {
> @@ -65,6 +67,15 @@ struct rcar_lvds {
>  #define connector_to_rcar_lvds(connector) \
>  	container_of(connector, struct rcar_lvds, connector)
> 
> +struct pll_info {
> +	unsigned int pllclk;
> +	unsigned int diff;
> +	unsigned int clk_n;
> +	unsigned int clk_m;
> +	unsigned int clk_e;
> +	unsigned int div;
> +};
> +
>  static void rcar_lvds_write(struct rcar_lvds *lvds, u32 reg, u32 data)
>  {
>  	iowrite32(data, lvds->mmio + reg);
> @@ -155,6 +166,198 @@ static u32 rcar_lvds_lvdpllcr_gen3(unsigned int freq)
>  		return LVDPLLCR_PLLDIVCNT_148M;
>  }
> 
> +static void rcar_lvds_pll_calc(struct rcar_du_crtc *rcrtc,
> +				     struct pll_info *pll, unsigned int in_fre,
> +				     unsigned int mode_freq, bool edivider)
> +{
> +	unsigned long diff = (unsigned long)-1;
> +	unsigned long fout, fpfd, fvco, n, m, e, div;
> +	bool clk_diff_set = true;
> +
> +	if (in_fre < 12000000 || in_fre > 192000000)
> +		return;
> +
> +	for (n = 0; n < 127; n++) {
> +		if (n + 1 < 60 || n + 1 > 120)
> +			continue;

Seriously ? :-)

> +		for (m = 0; m < 7; m++) {
> +			for (e = 0; e < 1; e++) {
> +				if (edivider)
> +					fout = (((in_fre / 1000) * (n + 1)) /
> +						((m + 1) * (e + 1) * 2)) *
> +						1000;
> +				else
> +					fout = (((in_fre / 1000) * (n + 1)) /
> +						(m + 1)) * 1000;
> +
> +				if (fout > 1039500000)
> +					continue;
> +
> +				fpfd  = (in_fre / (m + 1));
> +				if (fpfd < 12000000 || fpfd > 24000000)
> +					continue;
> +
> +				fvco  = (((in_fre / 1000) * (n + 1)) / (m + 1))
> +					 * 1000;
> +				if (fvco < 900000000 || fvco > 1800000000)
> +					continue;
> +
> +				fout = fout / 7; /* 7 divider */
> +
> +				for (div = 0; div < 64; div++) {

That's a lot of iterations for the four nested loops, surely it can be 
simplified.

> +					diff = abs((long)(fout / (div + 1)) -
> +					       (long)mode_freq);
> +
> +					if (clk_diff_set ||
> +					    (diff == 0 ||
> +					    pll->diff > diff)) {
> +						pll->diff = diff;
> +						pll->clk_n = n;
> +						pll->clk_m = m;
> +						pll->clk_e = e;
> +						pll->pllclk = fout;
> +						pll->div = div;
> +
> +						clk_diff_set = false;
> +
> +						if (diff == 0)
> +							return;
> +					}
> +				}
> +			}
> +		}
> +	}
> +}
> +
> +static void rcar_lvds_pll_pre_start(struct rcar_lvds *lvds,
> +				    struct rcar_du_crtc *rcrtc)
> +{
> +	const struct drm_display_mode *mode =
> +				&rcrtc->crtc.state->adjusted_mode;
> +	unsigned int mode_freq = mode->clock * 1000;
> +	unsigned int ext_clk = 0;
> +	struct pll_info *lvds_pll[2];
> +	u32 clksel, cksel;
> +	int i, ret;
> +
> +	if (rcrtc->extclock)
> +		ext_clk = clk_get_rate(rcrtc->extclock);
> +	else
> +		dev_warn(lvds->dev, "external clock is not set\n");
> +
> +	dev_dbg(lvds->dev, "external clock %d Hz\n", ext_clk);
> +
> +	if (lvds->enabled)
> +		return;
> +
> +	for (i = 0; i < 2; i++) {
> +		lvds_pll[i] = kzalloc(sizeof(*lvds_pll), GFP_KERNEL);
> +		if (!lvds_pll[i])
> +			return;

Memory leak if kzalloc() fails in any but the first iteration.

Why do you need dynamic allocation at all ?

> +	}
> +
> +	/* software reset release */
> +	reset_control_deassert(lvds->rst);
> +
> +	ret = clk_prepare_enable(lvds->clock);
> +	if (ret < 0)
> +		goto end;
> +
> +	for (i = 0; i < 2; i++) {
> +		bool edivider;
> +
> +		if (i == 0)
> +			edivider = true;
> +		else
> +			edivider = false;
> +
> +		rcar_lvds_pll_calc(rcrtc, lvds_pll[i], ext_clk,
> +					 mode_freq, edivider);
> +	}
> +
> +	dev_dbg(lvds->dev, "mode_frequency %d Hz\n", mode_freq);
> +
> +	if (lvds_pll[1]->diff >= lvds_pll[0]->diff) {
> +		/* use E-edivider */
> +		i = 0;
> +		clksel = LVDPLLCR_OUTCLKSEL_AFTER |
> +			 LVDPLLCR_STP_CLKOUTE1_EN;
> +	} else {
> +		/* do not use E-divider */
> +		i = 1;
> +		clksel = LVDPLLCR_OUTCLKSEL_BEFORE |
> +			 LVDPLLCR_STP_CLKOUTE1_DIS;
> +	}
> +	dev_dbg(lvds->dev,
> +		"E-divider %s\n", (i == 0 ? "is used" : "is not used"));
> +
> +	dev_dbg(lvds->dev,
> +		"pllclk:%u, n:%u, m:%u, e:%u, diff:%u, div:%u\n",
> +		 lvds_pll[i]->pllclk, lvds_pll[i]->clk_n, lvds_pll[i]->clk_m,
> +		 lvds_pll[i]->clk_e, lvds_pll[i]->diff, lvds_pll[i]->div);
> +
> +	if (rcrtc->extal_use)
> +		cksel = LVDPLLCR_CKSEL_EXTAL;
> +	else
> +		cksel = LVDPLLCR_CKSEL_DU_DOTCLKIN(rcrtc->index);
> +
> +	rcar_lvds_write(lvds, LVDPLLCR, LVDPLLCR_PLLON |
> +			LVDPLLCR_OCKSEL_7 | clksel | LVDPLLCR_CLKOUT_ENABLE |
> +			cksel | (lvds_pll[i]->clk_e << 10) |
> +			(lvds_pll[i]->clk_n << 3) | lvds_pll[i]->clk_m);
> +
> +	if (lvds_pll[i]->div > 0)
> +		rcar_lvds_write(lvds, LVDDIV, LVDDIV_DIVSEL |
> +				LVDDIV_DIVRESET | lvds_pll[i]->div);
> +	else
> +		rcar_lvds_write(lvds, LVDDIV, 0);
> +
> +	dev_dbg(lvds->dev, "LVDPLLCR: 0x%x\n",
> +		ioread32(lvds->mmio + LVDPLLCR));
> +	dev_dbg(lvds->dev, "LVDDIV: 0x%x\n",
> +		ioread32(lvds->mmio + LVDDIV));
> +
> +end:
> +	for (i = 0; i < 2; i++)
> +		kfree(lvds_pll[i]);
> +}
> +
> +static void rcar_lvds_pll_start(struct rcar_lvds *lvds,
> +			       struct rcar_du_crtc *rcrtc)
> +{
> +	u32 lvdhcr, lvdcr0;
> +
> +	rcar_lvds_write(lvds, LVDCTRCR, LVDCTRCR_CTR3SEL_ZERO |
> +			LVDCTRCR_CTR2SEL_DISP | LVDCTRCR_CTR1SEL_VSYNC |
> +			LVDCTRCR_CTR0SEL_HSYNC);
> +
> +	lvdhcr = LVDCHCR_CHSEL_CH(0, 0) | LVDCHCR_CHSEL_CH(1, 1) |
> +		 LVDCHCR_CHSEL_CH(2, 2) | LVDCHCR_CHSEL_CH(3, 3);
> +	rcar_lvds_write(lvds, LVDCHCR, lvdhcr);
> +
> +	rcar_lvds_write(lvds, LVDSTRIPE, 0);
> +	/* Turn all the channels on. */
> +	rcar_lvds_write(lvds, LVDCR1,
> +			LVDCR1_CHSTBY(3) | LVDCR1_CHSTBY(2) |
> +			LVDCR1_CHSTBY(1) | LVDCR1_CHSTBY(0) |
> +			LVDCR1_CLKSTBY);
> +	/*
> +	 * Turn the PLL on, set it to LVDS normal mode, wait for the startup
> +	 * delay and turn the output on.
> +	 */
> +	lvdcr0 = (lvds->mode << LVDCR0_LVMD_SHIFT) | LVDCR0_PWD;
> +	rcar_lvds_write(lvds, LVDCR0, lvdcr0);
> +
> +	lvdcr0 |= LVDCR0_LVEN;
> +	rcar_lvds_write(lvds, LVDCR0, lvdcr0);
> +
> +	lvdcr0 |= LVDCR0_LVRES;
> +	rcar_lvds_write(lvds, LVDCR0, lvdcr0);
> +
> +	lvds->enabled = true;
> +}
> +
>  static void rcar_lvds_enable(struct drm_bridge *bridge)
>  {
>  	struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
> @@ -164,6 +367,7 @@ static void rcar_lvds_enable(struct drm_bridge *bridge)
>  	 * do we get a state pointer?
>  	 */
>  	struct drm_crtc *crtc = lvds->bridge.encoder->crtc;
> +	struct rcar_du_device *rcdu = to_rcar_crtc(crtc)->group->dev;
>  	u32 lvdpllcr;
>  	u32 lvdhcr;
>  	u32 lvdcr0;
> @@ -171,6 +375,12 @@ static void rcar_lvds_enable(struct drm_bridge *bridge)
> 
>  	WARN_ON(lvds->enabled);
> 
> +	if (rcar_du_has(rcdu, RCAR_DU_FEATURE_LVDS_PLL)) {

This should be turned into an LVDS encoder feature bit.

> +		rcar_lvds_pll_pre_start(lvds, to_rcar_crtc(crtc));
> +		rcar_lvds_pll_start(lvds, to_rcar_crtc(crtc));
> +		return;
> +	}
> +
>  	ret = clk_prepare_enable(lvds->clock);
>  	if (ret < 0)
>  		return;
> @@ -264,6 +474,7 @@ static void rcar_lvds_disable(struct drm_bridge *bridge)
> 
>  	rcar_lvds_write(lvds, LVDCR0, 0);
>  	rcar_lvds_write(lvds, LVDCR1, 0);
> +	rcar_lvds_write(lvds, LVDPLLCR, 0);
> 
>  	clk_disable_unprepare(lvds->clock);
> 
> @@ -522,6 +733,7 @@ static const struct of_device_id rcar_lvds_of_table[] =
> { { .compatible = "renesas,r8a7795-lvds", .data = &rcar_lvds_gen3_info }, {
> .compatible = "renesas,r8a7796-lvds", .data = &rcar_lvds_gen3_info }, {
> .compatible = "renesas,r8a77970-lvds", .data = &rcar_lvds_r8a77970_info },
> +	{ .compatible = "renesas,r8a77995-lvds", .data = &rcar_lvds_gen3_info },
> { }
>  };
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
> b/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h index 2896835..e37db95 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
> @@ -21,7 +21,7 @@
>  #define LVDCR0_PLLON			(1 << 4)
>  #define LVDCR0_PWD			(1 << 2)		/* Gen3 only */
>  #define LVDCR0_BEN			(1 << 2)		/* Gen2 only */
> -#define LVDCR0_LVEN			(1 << 1)		/* Gen2 only */
> +#define LVDCR0_LVEN			(1 << 1)
>  #define LVDCR0_LVRES			(1 << 0)
> 
>  #define LVDCR1				0x0004
> @@ -46,6 +46,24 @@
>  #define LVDPLLCR_PLLDIVCNT_148M		(0x046c1 << 0)
>  #define LVDPLLCR_PLLDIVCNT_MASK		(0x7ffff << 0)
> 
> +/* R-Car D3 */
> +#define LVDPLLCR_PLLON			(1 << 22)
> +#define LVDPLLCR_PLLSEL_PLL0		(0 << 20)
> +#define LVDPLLCR_PLLSEL_LVX		(1 << 20)
> +#define LVDPLLCR_PLLSEL_PLL1		(2 << 20)
> +#define LVDPLLCR_CKSEL_LVX		(1 << 17)
> +#define LVDPLLCR_CKSEL_EXTAL		(3 << 17)
> +#define LVDPLLCR_CKSEL_DU_DOTCLKIN0	(5 << 17)
> +#define LVDPLLCR_CKSEL_DU_DOTCLKIN1	(7 << 17)
> +#define LVDPLLCR_OCKSEL_7		(0 << 16)
> +#define LVDPLLCR_OCKSEL_NOT_DIVIDED	(1 << 16)
> +#define LVDPLLCR_STP_CLKOUTE1_DIS	(0 << 14)
> +#define LVDPLLCR_STP_CLKOUTE1_EN	(1 << 14)
> +#define LVDPLLCR_OUTCLKSEL_BEFORE	(0 << 12)
> +#define LVDPLLCR_OUTCLKSEL_AFTER	(1 << 12)
> +#define LVDPLLCR_CLKOUT_DISABLE		(0 << 11)
> +#define LVDPLLCR_CLKOUT_ENABLE		(1 << 11)
> +
>  #define LVDCTRCR			0x000c
>  #define LVDCTRCR_CTR3SEL_ZERO		(0 << 12)
>  #define LVDCTRCR_CTR3SEL_ODD		(1 << 12)
> @@ -74,4 +92,30 @@
>  #define LVDCHCR_CHSEL_CH(n, c)		((((c) - (n)) & 3) << ((n) * 4))
>  #define LVDCHCR_CHSEL_MASK(n)		(3 << ((n) * 4))
> 
> +#define LVDSTRIPE			0x0014
> +#define LVDSTRIPE_ST_TRGSEL_DISP	(0 << 2)
> +#define LVDSTRIPE_ST_TRGSEL_HSYNC_R	(1 << 2)
> +#define LVDSTRIPE_ST_TRGSEL_HSYNC_F	(2 << 2)
> +
> +#define LVDSTRIPE_ST_SWAP_NORMAL	(0 << 1)
> +#define LVDSTRIPE_ST_SWAP_SWAP		(1 << 1)
> +#define LVDSTRIPE_ST_ON			(1 << 0)
> +
> +#define LVDSCR				0x0018
> +#define LVDSCR_DEPTH_DP1		(0 << 29)
> +#define LVDSCR_DEPTH_DP2		(1 << 29)
> +#define LVDSCR_DEPTH_DP3		(2 << 29)
> +#define LVDSCR_BANDSET_10KHZ_LESS_THAN	(1 << 28)
> +#define LVDSCR_SDIV_SR1			(0 << 22)
> +#define LVDSCR_SDIV_SR2			(1 << 22)
> +#define LVDSCR_SDIV_SR4			(2 << 22)
> +#define LVDSCR_SDIV_SR8			(3 << 22)
> +#define LVDSCR_MODE_DOWN		(1 << 21)
> +#define LVDSCR_RSTN_ENABLE		(1 << 20)
> +
> +#define LVDDIV				0x001c
> +#define LVDDIV_DIVSEL			(1 << 8)
> +#define LVDDIV_DIVRESET			(1 << 7)
> +#define LVDDIV_DIVSTP			(1 << 6)
> +
>  #endif /* __RCAR_LVDS_REGS_H__ */

-- 
Regards,

Laurent Pinchart



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

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

* Re: [PROTO][PATCH 07/10] arm64: dts: r8a77995-draak: set external clock for DU
  2018-08-14 13:50   ` Ulrich Hecht
@ 2018-08-20 10:51     ` Laurent Pinchart
  -1 siblings, 0 replies; 50+ messages in thread
From: Laurent Pinchart @ 2018-08-20 10:51 UTC (permalink / raw)
  To: Ulrich Hecht
  Cc: linux-renesas-soc, dri-devel, jacopo+renesas,
	kieran.bingham+renesas, Koji Matsuoka, Takeshi Kihara

Hi Ulrich,

Thank you for the patch.

On Tuesday, 14 August 2018 16:50:01 EEST Ulrich Hecht wrote:
> From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
> 
> Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
> Signed-off-by: Takeshi Kihara <takeshi.kihara.df@renesas.com>
> Signed-off-by: Ulrich Hecht <uli+renesas@fpond.eu>
> ---
>  arch/arm64/boot/dts/renesas/r8a77995-draak.dts | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/renesas/r8a77995-draak.dts
> b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts index a8e8f26..bd5c6fa
> 100644
> --- a/arch/arm64/boot/dts/renesas/r8a77995-draak.dts
> +++ b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts
> @@ -2,7 +2,7 @@
>  /*
>   * Device Tree Source for the Draak board
>   *
> - * Copyright (C) 2016 Renesas Electronics Corp.
> + * Copyright (C) 2016-2018 Renesas Electronics Corp.
>   * Copyright (C) 2017 Glider bvba
>   */
> 
> @@ -269,8 +269,10 @@
> 
>  	clocks = <&cpg CPG_MOD 724>,
>  		 <&cpg CPG_MOD 723>,
> -		 <&x12_clk>;
> -	clock-names = "du.0", "du.1", "dclkin.0";
> +		 <&x12_clk>,
> +		 <&extal_clk>;
> +	clock-names = "du.0", "du.1",
> +		      "dclkin.0", "extal";

This should be moved to the LVDS encoder DT node.

>  	ports {
>  		port@0 {

-- 
Regards,

Laurent Pinchart

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

* Re: [PROTO][PATCH 07/10] arm64: dts: r8a77995-draak: set external clock for DU
@ 2018-08-20 10:51     ` Laurent Pinchart
  0 siblings, 0 replies; 50+ messages in thread
From: Laurent Pinchart @ 2018-08-20 10:51 UTC (permalink / raw)
  To: Ulrich Hecht
  Cc: Takeshi Kihara, Koji Matsuoka, dri-devel, linux-renesas-soc,
	kieran.bingham+renesas, jacopo+renesas

Hi Ulrich,

Thank you for the patch.

On Tuesday, 14 August 2018 16:50:01 EEST Ulrich Hecht wrote:
> From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
> 
> Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
> Signed-off-by: Takeshi Kihara <takeshi.kihara.df@renesas.com>
> Signed-off-by: Ulrich Hecht <uli+renesas@fpond.eu>
> ---
>  arch/arm64/boot/dts/renesas/r8a77995-draak.dts | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/renesas/r8a77995-draak.dts
> b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts index a8e8f26..bd5c6fa
> 100644
> --- a/arch/arm64/boot/dts/renesas/r8a77995-draak.dts
> +++ b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts
> @@ -2,7 +2,7 @@
>  /*
>   * Device Tree Source for the Draak board
>   *
> - * Copyright (C) 2016 Renesas Electronics Corp.
> + * Copyright (C) 2016-2018 Renesas Electronics Corp.
>   * Copyright (C) 2017 Glider bvba
>   */
> 
> @@ -269,8 +269,10 @@
> 
>  	clocks = <&cpg CPG_MOD 724>,
>  		 <&cpg CPG_MOD 723>,
> -		 <&x12_clk>;
> -	clock-names = "du.0", "du.1", "dclkin.0";
> +		 <&x12_clk>,
> +		 <&extal_clk>;
> +	clock-names = "du.0", "du.1",
> +		      "dclkin.0", "extal";

This should be moved to the LVDS encoder DT node.

>  	ports {
>  		port@0 {

-- 
Regards,

Laurent Pinchart



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

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

* Re: [PROTO][PATCH 10/10] arm64: dts: renesas: r8a77995-draak: add HDMI output
  2018-08-14 13:50   ` Ulrich Hecht
@ 2018-08-20 11:01     ` Laurent Pinchart
  -1 siblings, 0 replies; 50+ messages in thread
From: Laurent Pinchart @ 2018-08-20 11:01 UTC (permalink / raw)
  To: Ulrich Hecht
  Cc: linux-renesas-soc, dri-devel, jacopo+renesas, kieran.bingham+renesas

Hi Ulrich,

Thank you for the patch.

On Tuesday, 14 August 2018 16:50:04 EEST Ulrich Hecht wrote:
> Adds LVDS decoder, HDMI encoder and connector for Draak boards.
> 
> Signed-off-by: Ulrich Hecht <uli+renesas@fpond.eu>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

I'm afraid I'll have to revoke that, as it applied to the patch before the 
addition of the max-clock and min-vrefresh properties. Let's discuss them in 
replies to patch 05/10 in this series.

> ---
>  arch/arm64/boot/dts/renesas/r8a77995-draak.dts | 84 +++++++++++++++++++++++
>  1 file changed, 84 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/renesas/r8a77995-draak.dts
> b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts index bd5c6fa..157adf9
> 100644
> --- a/arch/arm64/boot/dts/renesas/r8a77995-draak.dts
> +++ b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts
> @@ -24,6 +24,41 @@
>  		stdout-path = "serial0:115200n8";
>  	};
> 
> +	lvds-decoder {
> +		compatible = "thine,thc63lvd1024";
> +		vcc-supply = <&reg_3p3v>;
> +
> +		ports {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			port@0 {
> +				reg = <0>;
> +				thc63lvd1024_in: endpoint {
> +					remote-endpoint = <&lvds0_out>;
> +				};
> +			};
> +
> +			port@2 {
> +				reg = <2>;
> +				thc63lvd1024_out: endpoint {
> +					remote-endpoint = <&adv7511_in>;
> +				};
> +			};
> +		};
> +	};
> +
> +	hdmi-out {
> +		compatible = "hdmi-connector";
> +		type = "a";
> +
> +		port {
> +			hdmi_con_out: endpoint {
> +				remote-endpoint = <&adv7511_out>;
> +			};
> +		};
> +	};
> +
>  	vga {
>  		compatible = "vga-connector";
> 
> @@ -218,6 +253,43 @@
> 
>  	};
> 
> +	hdmi@39 {
> +		compatible = "adi,adv7511w";
> +		reg = <0x39>, <0x3f>, <0x38>, <0x3c>;
> +		reg-names = "main", "edid", "packet", "cec";
> +		interrupt-parent = <&gpio1>;
> +		interrupts = <28 IRQ_TYPE_LEVEL_LOW>;
> +
> +		/* Depends on LVDS */
> +		max-clock = <135000000>;
> +		min-vrefresh = <50>;
> +
> +		adi,input-depth = <8>;
> +		adi,input-colorspace = "rgb";
> +		adi,input-clock = "1x";
> +		adi,input-style = <1>;
> +		adi,input-justification = "evenly";
> +
> +		ports {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			port@0 {
> +				reg = <0>;
> +				adv7511_in: endpoint {
> +					remote-endpoint = <&thc63lvd1024_out>;
> +				};
> +			};
> +
> +			port@1 {
> +				reg = <1>;
> +				adv7511_out: endpoint {
> +					remote-endpoint = <&hdmi_con_out>;
> +				};
> +			};
> +		};
> +	};
> +
>  	hdmi-decoder@4c {
>  		compatible = "adi,adv7612";
>  		reg = <0x4c>;
> @@ -283,6 +355,18 @@
>  	};
>  };
> 
> +&lvds0 {
> +	status = "okay";
> +
> +	ports {
> +		port@1 {
> +			lvds0_out: endpoint {
> +				remote-endpoint = <&thc63lvd1024_in>;
> +			};
> +		};
> +	};
> +};
> +
>  &ehci0 {
>  	status = "okay";
>  };


-- 
Regards,

Laurent Pinchart

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

* Re: [PROTO][PATCH 10/10] arm64: dts: renesas: r8a77995-draak: add HDMI output
@ 2018-08-20 11:01     ` Laurent Pinchart
  0 siblings, 0 replies; 50+ messages in thread
From: Laurent Pinchart @ 2018-08-20 11:01 UTC (permalink / raw)
  To: Ulrich Hecht
  Cc: linux-renesas-soc, kieran.bingham+renesas, jacopo+renesas, dri-devel

Hi Ulrich,

Thank you for the patch.

On Tuesday, 14 August 2018 16:50:04 EEST Ulrich Hecht wrote:
> Adds LVDS decoder, HDMI encoder and connector for Draak boards.
> 
> Signed-off-by: Ulrich Hecht <uli+renesas@fpond.eu>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

I'm afraid I'll have to revoke that, as it applied to the patch before the 
addition of the max-clock and min-vrefresh properties. Let's discuss them in 
replies to patch 05/10 in this series.

> ---
>  arch/arm64/boot/dts/renesas/r8a77995-draak.dts | 84 +++++++++++++++++++++++
>  1 file changed, 84 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/renesas/r8a77995-draak.dts
> b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts index bd5c6fa..157adf9
> 100644
> --- a/arch/arm64/boot/dts/renesas/r8a77995-draak.dts
> +++ b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts
> @@ -24,6 +24,41 @@
>  		stdout-path = "serial0:115200n8";
>  	};
> 
> +	lvds-decoder {
> +		compatible = "thine,thc63lvd1024";
> +		vcc-supply = <&reg_3p3v>;
> +
> +		ports {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			port@0 {
> +				reg = <0>;
> +				thc63lvd1024_in: endpoint {
> +					remote-endpoint = <&lvds0_out>;
> +				};
> +			};
> +
> +			port@2 {
> +				reg = <2>;
> +				thc63lvd1024_out: endpoint {
> +					remote-endpoint = <&adv7511_in>;
> +				};
> +			};
> +		};
> +	};
> +
> +	hdmi-out {
> +		compatible = "hdmi-connector";
> +		type = "a";
> +
> +		port {
> +			hdmi_con_out: endpoint {
> +				remote-endpoint = <&adv7511_out>;
> +			};
> +		};
> +	};
> +
>  	vga {
>  		compatible = "vga-connector";
> 
> @@ -218,6 +253,43 @@
> 
>  	};
> 
> +	hdmi@39 {
> +		compatible = "adi,adv7511w";
> +		reg = <0x39>, <0x3f>, <0x38>, <0x3c>;
> +		reg-names = "main", "edid", "packet", "cec";
> +		interrupt-parent = <&gpio1>;
> +		interrupts = <28 IRQ_TYPE_LEVEL_LOW>;
> +
> +		/* Depends on LVDS */
> +		max-clock = <135000000>;
> +		min-vrefresh = <50>;
> +
> +		adi,input-depth = <8>;
> +		adi,input-colorspace = "rgb";
> +		adi,input-clock = "1x";
> +		adi,input-style = <1>;
> +		adi,input-justification = "evenly";
> +
> +		ports {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			port@0 {
> +				reg = <0>;
> +				adv7511_in: endpoint {
> +					remote-endpoint = <&thc63lvd1024_out>;
> +				};
> +			};
> +
> +			port@1 {
> +				reg = <1>;
> +				adv7511_out: endpoint {
> +					remote-endpoint = <&hdmi_con_out>;
> +				};
> +			};
> +		};
> +	};
> +
>  	hdmi-decoder@4c {
>  		compatible = "adi,adv7612";
>  		reg = <0x4c>;
> @@ -283,6 +355,18 @@
>  	};
>  };
> 
> +&lvds0 {
> +	status = "okay";
> +
> +	ports {
> +		port@1 {
> +			lvds0_out: endpoint {
> +				remote-endpoint = <&thc63lvd1024_in>;
> +			};
> +		};
> +	};
> +};
> +
>  &ehci0 {
>  	status = "okay";
>  };


-- 
Regards,

Laurent Pinchart



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

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

* Re: [PROTO][PATCH 00/10] R-Car D3 LVDS/HDMI support (with PLL)
  2018-08-20  9:50   ` Laurent Pinchart
@ 2018-08-21  8:02     ` Ulrich Hecht
  -1 siblings, 0 replies; 50+ messages in thread
From: Ulrich Hecht @ 2018-08-21  8:02 UTC (permalink / raw)
  To: Laurent Pinchart, Ulrich Hecht
  Cc: linux-renesas-soc, dri-devel, jacopo+renesas, kieran.bingham+renesas


> On August 20, 2018 at 11:50 AM Laurent Pinchart <laurent.pinchart@ideasonboard.com> wrote:
> On Tuesday, 14 August 2018 16:49:54 EEST Ulrich Hecht wrote:
> > Instructions for testing this are found at
> > https://elinux.org/User:Uli/D3_HDMI_Test, including links to git trees based
> > on renesas-drivers and drm-next, as well as config files for each.
> 
> The instructions there end with
> 
> "4. Boot kernel and observe activity on HDMI display."
> 
> Does "activity" mean that I can expect a working HDMI output with a proper 
> image on the display ? :-)

Yes, you can. :)

CU
Uli

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

* Re: [PROTO][PATCH 00/10] R-Car D3 LVDS/HDMI support (with PLL)
@ 2018-08-21  8:02     ` Ulrich Hecht
  0 siblings, 0 replies; 50+ messages in thread
From: Ulrich Hecht @ 2018-08-21  8:02 UTC (permalink / raw)
  To: Laurent Pinchart, Ulrich Hecht
  Cc: linux-renesas-soc, kieran.bingham+renesas, jacopo+renesas, dri-devel


> On August 20, 2018 at 11:50 AM Laurent Pinchart <laurent.pinchart@ideasonboard.com> wrote:
> On Tuesday, 14 August 2018 16:49:54 EEST Ulrich Hecht wrote:
> > Instructions for testing this are found at
> > https://elinux.org/User:Uli/D3_HDMI_Test, including links to git trees based
> > on renesas-drivers and drm-next, as well as config files for each.
> 
> The instructions there end with
> 
> "4. Boot kernel and observe activity on HDMI display."
> 
> Does "activity" mean that I can expect a working HDMI output with a proper 
> image on the display ? :-)

Yes, you can. :)

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

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

* Re: [PROTO][PATCH 05/10] drm/bridge: adv7511: Add max-clock, min-vrefresh options
  2018-08-20  9:28     ` Laurent Pinchart
@ 2018-08-21  8:03       ` Ulrich Hecht
  -1 siblings, 0 replies; 50+ messages in thread
From: Ulrich Hecht @ 2018-08-21  8:03 UTC (permalink / raw)
  To: Laurent Pinchart, Ulrich Hecht
  Cc: linux-renesas-soc, dri-devel, jacopo+renesas,
	kieran.bingham+renesas, Koji Matsuoka


> On August 20, 2018 at 11:28 AM Laurent Pinchart <laurent.pinchart@ideasonboard.com> wrote:
> 
> 
> Hi Ulrich,
> 
> Thank you for the patch.
> 
> On Tuesday, 14 August 2018 16:49:59 EEST Ulrich Hecht wrote:
> > From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
> > 
> > This patch adds the option to specify a maximal clock and a minimal vertical
> > refresh rate.
> 
> What is this needed for ?

Somewhere in the chain there is a component that will not tolerate clocks in excess of 135 MHz; if you don't limit it, the default for a 1920x1200 display is somewhere along 148 MHz, and the HDMI signal output is invalid.

CU
Uli

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

* Re: [PROTO][PATCH 05/10] drm/bridge: adv7511: Add max-clock, min-vrefresh options
@ 2018-08-21  8:03       ` Ulrich Hecht
  0 siblings, 0 replies; 50+ messages in thread
From: Ulrich Hecht @ 2018-08-21  8:03 UTC (permalink / raw)
  To: Laurent Pinchart, Ulrich Hecht
  Cc: linux-renesas-soc, kieran.bingham+renesas, jacopo+renesas,
	Koji Matsuoka, dri-devel


> On August 20, 2018 at 11:28 AM Laurent Pinchart <laurent.pinchart@ideasonboard.com> wrote:
> 
> 
> Hi Ulrich,
> 
> Thank you for the patch.
> 
> On Tuesday, 14 August 2018 16:49:59 EEST Ulrich Hecht wrote:
> > From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
> > 
> > This patch adds the option to specify a maximal clock and a minimal vertical
> > refresh rate.
> 
> What is this needed for ?

Somewhere in the chain there is a component that will not tolerate clocks in excess of 135 MHz; if you don't limit it, the default for a 1920x1200 display is somewhere along 148 MHz, and the HDMI signal output is invalid.

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

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

* Re: [PROTO][PATCH 05/10] drm/bridge: adv7511: Add max-clock, min-vrefresh options
  2018-08-21  8:03       ` Ulrich Hecht
@ 2018-08-21  8:09         ` Laurent Pinchart
  -1 siblings, 0 replies; 50+ messages in thread
From: Laurent Pinchart @ 2018-08-21  8:09 UTC (permalink / raw)
  To: Ulrich Hecht
  Cc: Ulrich Hecht, linux-renesas-soc, dri-devel, jacopo+renesas,
	kieran.bingham+renesas, Koji Matsuoka

Hi Ulrich,

On Tuesday, 21 August 2018 11:03:45 EEST Ulrich Hecht wrote:
> On August 20, 2018 at 11:28 AM Laurent Pinchart wrote:
> > On Tuesday, 14 August 2018 16:49:59 EEST Ulrich Hecht wrote:
> >> From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
> >> 
> >> This patch adds the option to specify a maximal clock and a minimal
> >> vertical refresh rate.
> > 
> > What is this needed for ?
> 
> Somewhere in the chain there is a component that will not tolerate clocks in
> excess of 135 MHz; if you don't limit it, the default for a 1920x1200
> display is somewhere along 148 MHz, and the HDMI signal output is invalid.

Do you know which component that is ?

-- 
Regards,

Laurent Pinchart

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

* Re: [PROTO][PATCH 05/10] drm/bridge: adv7511: Add max-clock, min-vrefresh options
@ 2018-08-21  8:09         ` Laurent Pinchart
  0 siblings, 0 replies; 50+ messages in thread
From: Laurent Pinchart @ 2018-08-21  8:09 UTC (permalink / raw)
  To: Ulrich Hecht
  Cc: Koji Matsuoka, dri-devel, linux-renesas-soc,
	kieran.bingham+renesas, jacopo+renesas, Ulrich Hecht

Hi Ulrich,

On Tuesday, 21 August 2018 11:03:45 EEST Ulrich Hecht wrote:
> On August 20, 2018 at 11:28 AM Laurent Pinchart wrote:
> > On Tuesday, 14 August 2018 16:49:59 EEST Ulrich Hecht wrote:
> >> From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
> >> 
> >> This patch adds the option to specify a maximal clock and a minimal
> >> vertical refresh rate.
> > 
> > What is this needed for ?
> 
> Somewhere in the chain there is a component that will not tolerate clocks in
> excess of 135 MHz; if you don't limit it, the default for a 1920x1200
> display is somewhere along 148 MHz, and the HDMI signal output is invalid.

Do you know which component that is ?

-- 
Regards,

Laurent Pinchart



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

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

* Re: [PROTO][PATCH 05/10] drm/bridge: adv7511: Add max-clock, min-vrefresh options
  2018-08-21  8:09         ` Laurent Pinchart
@ 2018-08-22  9:13           ` Ulrich Hecht
  -1 siblings, 0 replies; 50+ messages in thread
From: Ulrich Hecht @ 2018-08-22  9:13 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Ulrich Hecht, linux-renesas-soc, dri-devel, jacopo+renesas,
	kieran.bingham+renesas, Koji Matsuoka


> On August 21, 2018 at 10:09 AM Laurent Pinchart <laurent.pinchart@ideasonboard.com> wrote:
> 
> 
> Hi Ulrich,
> 
> On Tuesday, 21 August 2018 11:03:45 EEST Ulrich Hecht wrote:
> > On August 20, 2018 at 11:28 AM Laurent Pinchart wrote:
> > > On Tuesday, 14 August 2018 16:49:59 EEST Ulrich Hecht wrote:
> > >> From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
> > >> 
> > >> This patch adds the option to specify a maximal clock and a minimal
> > >> vertical refresh rate.
> > > 
> > > What is this needed for ?
> > 
> > Somewhere in the chain there is a component that will not tolerate clocks in
> > excess of 135 MHz; if you don't limit it, the default for a 1920x1200
> > display is somewhere along 148 MHz, and the HDMI signal output is invalid.
> 
> Do you know which component that is ?

Unfortunately not. It's not the ADV7511, though, that goes up to 225 MHz...

CU
Uli

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

* Re: [PROTO][PATCH 05/10] drm/bridge: adv7511: Add max-clock, min-vrefresh options
@ 2018-08-22  9:13           ` Ulrich Hecht
  0 siblings, 0 replies; 50+ messages in thread
From: Ulrich Hecht @ 2018-08-22  9:13 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Koji Matsuoka, dri-devel, linux-renesas-soc,
	kieran.bingham+renesas, jacopo+renesas, Ulrich Hecht


> On August 21, 2018 at 10:09 AM Laurent Pinchart <laurent.pinchart@ideasonboard.com> wrote:
> 
> 
> Hi Ulrich,
> 
> On Tuesday, 21 August 2018 11:03:45 EEST Ulrich Hecht wrote:
> > On August 20, 2018 at 11:28 AM Laurent Pinchart wrote:
> > > On Tuesday, 14 August 2018 16:49:59 EEST Ulrich Hecht wrote:
> > >> From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
> > >> 
> > >> This patch adds the option to specify a maximal clock and a minimal
> > >> vertical refresh rate.
> > > 
> > > What is this needed for ?
> > 
> > Somewhere in the chain there is a component that will not tolerate clocks in
> > excess of 135 MHz; if you don't limit it, the default for a 1920x1200
> > display is somewhere along 148 MHz, and the HDMI signal output is invalid.
> 
> Do you know which component that is ?

Unfortunately not. It's not the ADV7511, though, that goes up to 225 MHz...

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

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

* Re: [PROTO][PATCH 05/10] drm/bridge: adv7511: Add max-clock, min-vrefresh options
  2018-08-22  9:13           ` Ulrich Hecht
@ 2018-08-22 14:00             ` Laurent Pinchart
  -1 siblings, 0 replies; 50+ messages in thread
From: Laurent Pinchart @ 2018-08-22 14:00 UTC (permalink / raw)
  To: Ulrich Hecht
  Cc: Ulrich Hecht, linux-renesas-soc, dri-devel, jacopo+renesas,
	kieran.bingham+renesas, Koji Matsuoka

Hi Ulrich,

On Wednesday, 22 August 2018 12:13:59 EEST Ulrich Hecht wrote:
> On August 21, 2018 at 10:09 AM Laurent Pinchart wrote:
> > On Tuesday, 21 August 2018 11:03:45 EEST Ulrich Hecht wrote:
> >> On August 20, 2018 at 11:28 AM Laurent Pinchart wrote:
> >>> On Tuesday, 14 August 2018 16:49:59 EEST Ulrich Hecht wrote:
> >>>> From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
> >>>> 
> >>>> This patch adds the option to specify a maximal clock and a minimal
> >>>> vertical refresh rate.
> >>> 
> >>> What is this needed for ?
> >> 
> >> Somewhere in the chain there is a component that will not tolerate
> >> clocks in excess of 135 MHz; if you don't limit it, the default for a
> >> 1920x1200 display is somewhere along 148 MHz, and the HDMI signal
> >> output is invalid.
> > 
> > Do you know which component that is ?
> 
> Unfortunately not. It's not the ADV7511, though, that goes up to 225 MHz...

After investigation, it turns out that the THC63LVD1024 is the culprit, its 
datasheet reports a maximum operating frequency of 135 MHz.

Do you have any idea what the minimal refresh rate is for ?

-- 
Regards,

Laurent Pinchart

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

* Re: [PROTO][PATCH 05/10] drm/bridge: adv7511: Add max-clock, min-vrefresh options
@ 2018-08-22 14:00             ` Laurent Pinchart
  0 siblings, 0 replies; 50+ messages in thread
From: Laurent Pinchart @ 2018-08-22 14:00 UTC (permalink / raw)
  To: Ulrich Hecht
  Cc: Koji Matsuoka, dri-devel, linux-renesas-soc,
	kieran.bingham+renesas, jacopo+renesas, Ulrich Hecht

Hi Ulrich,

On Wednesday, 22 August 2018 12:13:59 EEST Ulrich Hecht wrote:
> On August 21, 2018 at 10:09 AM Laurent Pinchart wrote:
> > On Tuesday, 21 August 2018 11:03:45 EEST Ulrich Hecht wrote:
> >> On August 20, 2018 at 11:28 AM Laurent Pinchart wrote:
> >>> On Tuesday, 14 August 2018 16:49:59 EEST Ulrich Hecht wrote:
> >>>> From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
> >>>> 
> >>>> This patch adds the option to specify a maximal clock and a minimal
> >>>> vertical refresh rate.
> >>> 
> >>> What is this needed for ?
> >> 
> >> Somewhere in the chain there is a component that will not tolerate
> >> clocks in excess of 135 MHz; if you don't limit it, the default for a
> >> 1920x1200 display is somewhere along 148 MHz, and the HDMI signal
> >> output is invalid.
> > 
> > Do you know which component that is ?
> 
> Unfortunately not. It's not the ADV7511, though, that goes up to 225 MHz...

After investigation, it turns out that the THC63LVD1024 is the culprit, its 
datasheet reports a maximum operating frequency of 135 MHz.

Do you have any idea what the minimal refresh rate is for ?

-- 
Regards,

Laurent Pinchart



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

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

end of thread, other threads:[~2018-08-22 17:24 UTC | newest]

Thread overview: 50+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-08-14 13:49 [PROTO][PATCH 00/10] R-Car D3 LVDS/HDMI support (with PLL) Ulrich Hecht
2018-08-14 13:49 ` Ulrich Hecht
2018-08-14 13:49 ` [PROTO][PATCH 01/10] drm: rcar-du: Add clk_set_rate for external clock device Ulrich Hecht
2018-08-14 13:49   ` Ulrich Hecht
2018-08-20 10:10   ` Laurent Pinchart
2018-08-20 10:10     ` Laurent Pinchart
2018-08-14 13:49 ` [PROTO][PATCH 02/10] drm: rcar-du: Add r8a77995 device support Ulrich Hecht
2018-08-14 13:49   ` Ulrich Hecht
2018-08-20  8:39   ` Laurent Pinchart
2018-08-20  8:39     ` Laurent Pinchart
2018-08-14 13:49 ` [PROTO][PATCH 03/10] drm: rcar-du: Fix digital RGB routing for R8A77995 Ulrich Hecht
2018-08-14 13:49   ` Ulrich Hecht
2018-08-20  9:25   ` Laurent Pinchart
2018-08-20  9:25     ` Laurent Pinchart
2018-08-14 13:49 ` [PROTO][PATCH 04/10] drm: rcar-du: lvds: LVDS PLL support Ulrich Hecht
2018-08-14 13:49   ` Ulrich Hecht
2018-08-20 10:48   ` Laurent Pinchart
2018-08-20 10:48     ` Laurent Pinchart
2018-08-14 13:49 ` [PROTO][PATCH 05/10] drm/bridge: adv7511: Add max-clock, min-vrefresh options Ulrich Hecht
2018-08-14 13:49   ` Ulrich Hecht
2018-08-20  9:28   ` Laurent Pinchart
2018-08-20  9:28     ` Laurent Pinchart
2018-08-21  8:03     ` Ulrich Hecht
2018-08-21  8:03       ` Ulrich Hecht
2018-08-21  8:09       ` Laurent Pinchart
2018-08-21  8:09         ` Laurent Pinchart
2018-08-22  9:13         ` Ulrich Hecht
2018-08-22  9:13           ` Ulrich Hecht
2018-08-22 14:00           ` Laurent Pinchart
2018-08-22 14:00             ` Laurent Pinchart
2018-08-14 13:50 ` [PROTO][PATCH 06/10] drm: rcar-du: Fix procedure for extal and dotclkin selection Ulrich Hecht
2018-08-14 13:50   ` Ulrich Hecht
2018-08-20  9:40   ` Laurent Pinchart
2018-08-20  9:40     ` Laurent Pinchart
2018-08-14 13:50 ` [PROTO][PATCH 07/10] arm64: dts: r8a77995-draak: set external clock for DU Ulrich Hecht
2018-08-14 13:50   ` Ulrich Hecht
2018-08-20 10:51   ` Laurent Pinchart
2018-08-20 10:51     ` Laurent Pinchart
2018-08-14 13:50 ` [PROTO][PATCH 08/10] drm: rcar-du: lvds: Handle LVDS interface reset Ulrich Hecht
2018-08-14 13:50   ` Ulrich Hecht
2018-08-14 13:50 ` [PROTO][PATCH 09/10] arm64: dts: renesas: r8a77995: Add LVDS support Ulrich Hecht
2018-08-14 13:50   ` Ulrich Hecht
2018-08-14 13:50 ` [PROTO][PATCH 10/10] arm64: dts: renesas: r8a77995-draak: add HDMI output Ulrich Hecht
2018-08-14 13:50   ` Ulrich Hecht
2018-08-20 11:01   ` Laurent Pinchart
2018-08-20 11:01     ` Laurent Pinchart
2018-08-20  9:50 ` [PROTO][PATCH 00/10] R-Car D3 LVDS/HDMI support (with PLL) Laurent Pinchart
2018-08-20  9:50   ` Laurent Pinchart
2018-08-21  8:02   ` Ulrich Hecht
2018-08-21  8:02     ` Ulrich Hecht

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.