All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/16] R-Car D3/E3 display support (with LVDS PLL)
@ 2018-09-14  9:10 ` Laurent Pinchart
  0 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-14  9:10 UTC (permalink / raw)
  To: dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham

Hello everybody,

This patch series adds display support for the D3 and E3 SoCs, and in
particular the Draak and Ebisu boards.

The code is based on Ulrich's "[PROTO][PATCH 00/10] R-Car D3 LVDS/HDMI support
(with PLL)" series previously posted to the dri-devel and linux-renesas-soc
mailing lists. It has been extensively reworked and partly rewritten, and
support for E3 and Ebisu has been added.

The DU in the D3 and E3 SoCs has no internal PLL. In order to achieve precise
pixel clock rates (required, among other use cases, for HDMI operation), the
PLL from the internal LVDS encoder must be programmed and its output clock
routed back to the DU.

The series starts with update to the DU and LVDS encoder DT bindings to add E3
(R8A77990) support (patches 01/16 and 02/16) and new clock sources for the
LVDS encoder (patch 03/16).

The next patch (04/16) adds a .mode_valid() operation to the thc63lvd1024
driver, to reject modes outside of the LVDS decoder's pixel clock operating
range (8 MHz to 135 MHz). The patch can be merged on its own separately from
this series.

Patch (05/16) adds support for D3 and E3 to the LVDS encoder driver. Compared
to the already supported SoCs, D3 and E3 use a different initialization
sequence and have a different PLL architecture, with more options for the
input clock.

The next five patches (06/16 to 10/16) perform small reworks or add support
for miscellaneous missing features and limitations of the DU, to be followed
by patch 11/16 that adds support for the D3 and E3 to the DU driver.

Finally patches 12/16 to 16/16 enable display for the D3 and E3 boards in DT.
Patch 12/16 adds support for the I2C controllers in the E3 DT, and will likely
be merged separately from this series. Patch 13/16 adds all the display IP
cores (FCP, VSP, DU and LVDS encoders) to the E3 DT, while patch 14/16 adds
(and wires up) the missing LVDS encoders to the D3 DT. Patches 15/16 and 16/16
then enable display output for the Ebisu and Draak boards respectively.

I believe the patch series to be ready for upstreaming (after fixing the
issues found during review of course). There is no big hack in the code, and I
haven't noticed any regression. A few issues are still unsolved, such as how
to disable display outputs independently on D3 and E3, and usage of the LVDS
PLL for the RGB output, but those are not regressions and shouldn't in my
opinion be considered as show stoppers.

The patches are available from

        git://linuxtv.org/pinchartl/media.git drm/du/lvds-pll

with an additional patch for E3 pinctrl that is required for testing and has
been queued by Geert for v4.20 already.

Please see individual patches for changelogs since v1.

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

Laurent Pinchart (12):
  dt-bindings: display: renesas: du: Document r8a77990 bindings
  dt-bindings: display: renesas: lvds: Document r8a77990 bindings
  dt-bindings: display: renesas: lvds: Add EXTAL and DU_DOTCLKIN clocks
  drm: bridge: thc63: Restrict modes based on hardware operating
    frequency
  drm: rcar-du: lvds: D3/E3 support
  drm: rcar-du: Perform the initial CRTC setup from rcar_du_crtc_get()
  drm: rcar-du: Use LVDS PLL clock as dot clock when possible
  drm: rcar-du: Enable configurable DPAD0 routing on Gen3
  drm: rcar-du: Cache DSYSR value to ensure known initial value
  drm: rcar-du: Don't use TV sync mode when not supported by the
    hardware
  arm64: dts: renesas: r8a77990: Add display output support
  arm64: dts: renesas: r8a77990: ebisu: Enable VGA and HDMI outputs

Takeshi Kihara (1):
  arm64: dts: renesas: r8a77990: Add I2C device nodes

Ulrich Hecht (2):
  drm: rcar-du: Add r8a77990 and r8a77995 device support
  arm64: dts: renesas: r8a77995: draak: Enable HDMI display output

 .../bindings/display/bridge/renesas,lvds.txt       |  13 +-
 .../devicetree/bindings/display/renesas,du.txt     |   2 +
 arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts     | 166 ++++++++++
 arch/arm64/boot/dts/renesas/r8a77990.dtsi          | 290 +++++++++++++++++
 arch/arm64/boot/dts/renesas/r8a77995-draak.dts     |  98 +++++-
 arch/arm64/boot/dts/renesas/r8a77995.dtsi          |  56 ++++
 drivers/gpu/drm/bridge/thc63lvd1024.c              |  18 ++
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c             | 136 ++++----
 drivers/gpu/drm/rcar-du/rcar_du_crtc.h             |   5 +
 drivers/gpu/drm/rcar-du/rcar_du_drv.c              |  63 +++-
 drivers/gpu/drm/rcar-du/rcar_du_drv.h              |   3 +
 drivers/gpu/drm/rcar-du/rcar_du_group.c            |  88 +++--
 drivers/gpu/drm/rcar-du/rcar_du_kms.c              |  12 +
 drivers/gpu/drm/rcar-du/rcar_lvds.c                | 355 ++++++++++++++++++---
 drivers/gpu/drm/rcar-du/rcar_lvds_regs.h           |  43 ++-
 15 files changed, 1200 insertions(+), 148 deletions(-)

-- 
Regards,

Laurent Pinchart

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

* [PATCH v2 00/16] R-Car D3/E3 display support (with LVDS PLL)
@ 2018-09-14  9:10 ` Laurent Pinchart
  0 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-14  9:10 UTC (permalink / raw)
  To: dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham

Hello everybody,

This patch series adds display support for the D3 and E3 SoCs, and in
particular the Draak and Ebisu boards.

The code is based on Ulrich's "[PROTO][PATCH 00/10] R-Car D3 LVDS/HDMI support
(with PLL)" series previously posted to the dri-devel and linux-renesas-soc
mailing lists. It has been extensively reworked and partly rewritten, and
support for E3 and Ebisu has been added.

The DU in the D3 and E3 SoCs has no internal PLL. In order to achieve precise
pixel clock rates (required, among other use cases, for HDMI operation), the
PLL from the internal LVDS encoder must be programmed and its output clock
routed back to the DU.

The series starts with update to the DU and LVDS encoder DT bindings to add E3
(R8A77990) support (patches 01/16 and 02/16) and new clock sources for the
LVDS encoder (patch 03/16).

The next patch (04/16) adds a .mode_valid() operation to the thc63lvd1024
driver, to reject modes outside of the LVDS decoder's pixel clock operating
range (8 MHz to 135 MHz). The patch can be merged on its own separately from
this series.

Patch (05/16) adds support for D3 and E3 to the LVDS encoder driver. Compared
to the already supported SoCs, D3 and E3 use a different initialization
sequence and have a different PLL architecture, with more options for the
input clock.

The next five patches (06/16 to 10/16) perform small reworks or add support
for miscellaneous missing features and limitations of the DU, to be followed
by patch 11/16 that adds support for the D3 and E3 to the DU driver.

Finally patches 12/16 to 16/16 enable display for the D3 and E3 boards in DT.
Patch 12/16 adds support for the I2C controllers in the E3 DT, and will likely
be merged separately from this series. Patch 13/16 adds all the display IP
cores (FCP, VSP, DU and LVDS encoders) to the E3 DT, while patch 14/16 adds
(and wires up) the missing LVDS encoders to the D3 DT. Patches 15/16 and 16/16
then enable display output for the Ebisu and Draak boards respectively.

I believe the patch series to be ready for upstreaming (after fixing the
issues found during review of course). There is no big hack in the code, and I
haven't noticed any regression. A few issues are still unsolved, such as how
to disable display outputs independently on D3 and E3, and usage of the LVDS
PLL for the RGB output, but those are not regressions and shouldn't in my
opinion be considered as show stoppers.

The patches are available from

        git://linuxtv.org/pinchartl/media.git drm/du/lvds-pll

with an additional patch for E3 pinctrl that is required for testing and has
been queued by Geert for v4.20 already.

Please see individual patches for changelogs since v1.

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

Laurent Pinchart (12):
  dt-bindings: display: renesas: du: Document r8a77990 bindings
  dt-bindings: display: renesas: lvds: Document r8a77990 bindings
  dt-bindings: display: renesas: lvds: Add EXTAL and DU_DOTCLKIN clocks
  drm: bridge: thc63: Restrict modes based on hardware operating
    frequency
  drm: rcar-du: lvds: D3/E3 support
  drm: rcar-du: Perform the initial CRTC setup from rcar_du_crtc_get()
  drm: rcar-du: Use LVDS PLL clock as dot clock when possible
  drm: rcar-du: Enable configurable DPAD0 routing on Gen3
  drm: rcar-du: Cache DSYSR value to ensure known initial value
  drm: rcar-du: Don't use TV sync mode when not supported by the
    hardware
  arm64: dts: renesas: r8a77990: Add display output support
  arm64: dts: renesas: r8a77990: ebisu: Enable VGA and HDMI outputs

Takeshi Kihara (1):
  arm64: dts: renesas: r8a77990: Add I2C device nodes

Ulrich Hecht (2):
  drm: rcar-du: Add r8a77990 and r8a77995 device support
  arm64: dts: renesas: r8a77995: draak: Enable HDMI display output

 .../bindings/display/bridge/renesas,lvds.txt       |  13 +-
 .../devicetree/bindings/display/renesas,du.txt     |   2 +
 arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts     | 166 ++++++++++
 arch/arm64/boot/dts/renesas/r8a77990.dtsi          | 290 +++++++++++++++++
 arch/arm64/boot/dts/renesas/r8a77995-draak.dts     |  98 +++++-
 arch/arm64/boot/dts/renesas/r8a77995.dtsi          |  56 ++++
 drivers/gpu/drm/bridge/thc63lvd1024.c              |  18 ++
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c             | 136 ++++----
 drivers/gpu/drm/rcar-du/rcar_du_crtc.h             |   5 +
 drivers/gpu/drm/rcar-du/rcar_du_drv.c              |  63 +++-
 drivers/gpu/drm/rcar-du/rcar_du_drv.h              |   3 +
 drivers/gpu/drm/rcar-du/rcar_du_group.c            |  88 +++--
 drivers/gpu/drm/rcar-du/rcar_du_kms.c              |  12 +
 drivers/gpu/drm/rcar-du/rcar_lvds.c                | 355 ++++++++++++++++++---
 drivers/gpu/drm/rcar-du/rcar_lvds_regs.h           |  43 ++-
 15 files changed, 1200 insertions(+), 148 deletions(-)

-- 
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] 118+ messages in thread

* [PATCH v2 01/16] dt-bindings: display: renesas: du: Document r8a77990 bindings
  2018-09-14  9:10 ` Laurent Pinchart
@ 2018-09-14  9:10   ` Laurent Pinchart
  -1 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-14  9:10 UTC (permalink / raw)
  To: dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham

Document the E3 (r8a77990) SoC in the R-Car DU bindings.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
---
 Documentation/devicetree/bindings/display/renesas,du.txt | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/renesas,du.txt b/Documentation/devicetree/bindings/display/renesas,du.txt
index caae2348a292..9de67be632d1 100644
--- a/Documentation/devicetree/bindings/display/renesas,du.txt
+++ b/Documentation/devicetree/bindings/display/renesas,du.txt
@@ -16,6 +16,7 @@ Required Properties:
     - "renesas,du-r8a77965" for R8A77965 (R-Car M3-N) compatible DU
     - "renesas,du-r8a77970" for R8A77970 (R-Car V3M) compatible DU
     - "renesas,du-r8a77980" for R8A77980 (R-Car V3H) compatible DU
+    - "renesas,du-r8a77990" for R8A77990 (R-Car E3) compatible DU
     - "renesas,du-r8a77995" for R8A77995 (R-Car D3) compatible DU
 
   - reg: the memory-mapped I/O registers base address and length
@@ -63,6 +64,7 @@ corresponding to each DU output.
  R8A77965 (R-Car M3-N)  DPAD 0         HDMI 0         LVDS 0         -
  R8A77970 (R-Car V3M)   DPAD 0         LVDS 0         -              -
  R8A77980 (R-Car V3H)   DPAD 0         LVDS 0         -              -
+ R8A77990 (R-Car E3)    DPAD 0         LVDS 0         LVDS 1         -
  R8A77995 (R-Car D3)    DPAD 0         LVDS 0         LVDS 1         -
 
 
-- 
Regards,

Laurent Pinchart

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

* [PATCH v2 01/16] dt-bindings: display: renesas: du: Document r8a77990 bindings
@ 2018-09-14  9:10   ` Laurent Pinchart
  0 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-14  9:10 UTC (permalink / raw)
  To: dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham

Document the E3 (r8a77990) SoC in the R-Car DU bindings.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
---
 Documentation/devicetree/bindings/display/renesas,du.txt | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/renesas,du.txt b/Documentation/devicetree/bindings/display/renesas,du.txt
index caae2348a292..9de67be632d1 100644
--- a/Documentation/devicetree/bindings/display/renesas,du.txt
+++ b/Documentation/devicetree/bindings/display/renesas,du.txt
@@ -16,6 +16,7 @@ Required Properties:
     - "renesas,du-r8a77965" for R8A77965 (R-Car M3-N) compatible DU
     - "renesas,du-r8a77970" for R8A77970 (R-Car V3M) compatible DU
     - "renesas,du-r8a77980" for R8A77980 (R-Car V3H) compatible DU
+    - "renesas,du-r8a77990" for R8A77990 (R-Car E3) compatible DU
     - "renesas,du-r8a77995" for R8A77995 (R-Car D3) compatible DU
 
   - reg: the memory-mapped I/O registers base address and length
@@ -63,6 +64,7 @@ corresponding to each DU output.
  R8A77965 (R-Car M3-N)  DPAD 0         HDMI 0         LVDS 0         -
  R8A77970 (R-Car V3M)   DPAD 0         LVDS 0         -              -
  R8A77980 (R-Car V3H)   DPAD 0         LVDS 0         -              -
+ R8A77990 (R-Car E3)    DPAD 0         LVDS 0         LVDS 1         -
  R8A77995 (R-Car D3)    DPAD 0         LVDS 0         LVDS 1         -
 
 
-- 
Regards,

Laurent Pinchart

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

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

* [PATCH v2 02/16] dt-bindings: display: renesas: lvds: Document r8a77990 bindings
  2018-09-14  9:10 ` Laurent Pinchart
@ 2018-09-14  9:10   ` Laurent Pinchart
  -1 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-14  9:10 UTC (permalink / raw)
  To: dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham

The E3 (r8a77990) supports two LVDS channels. Extend the binding to
support them.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
---
 Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
index 5a4e379bb414..13af7e2ac7e8 100644
--- a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
+++ b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
@@ -15,6 +15,7 @@ Required properties:
   - "renesas,r8a7796-lvds" for R8A7796 (R-Car M3-W) compatible LVDS encoders
   - "renesas,r8a77970-lvds" for R8A77970 (R-Car V3M) compatible LVDS encoders
   - "renesas,r8a77980-lvds" for R8A77980 (R-Car V3H) compatible LVDS encoders
+  - "renesas,r8a77990-lvds" for R8A77990 (R-Car E3) compatible LVDS encoders
   - "renesas,r8a77995-lvds" for R8A77995 (R-Car D3) compatible LVDS encoders
 
 - reg: Base address and length for the memory-mapped registers
-- 
Regards,

Laurent Pinchart

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

* [PATCH v2 02/16] dt-bindings: display: renesas: lvds: Document r8a77990 bindings
@ 2018-09-14  9:10   ` Laurent Pinchart
  0 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-14  9:10 UTC (permalink / raw)
  To: dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham

The E3 (r8a77990) supports two LVDS channels. Extend the binding to
support them.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
---
 Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
index 5a4e379bb414..13af7e2ac7e8 100644
--- a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
+++ b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
@@ -15,6 +15,7 @@ Required properties:
   - "renesas,r8a7796-lvds" for R8A7796 (R-Car M3-W) compatible LVDS encoders
   - "renesas,r8a77970-lvds" for R8A77970 (R-Car V3M) compatible LVDS encoders
   - "renesas,r8a77980-lvds" for R8A77980 (R-Car V3H) compatible LVDS encoders
+  - "renesas,r8a77990-lvds" for R8A77990 (R-Car E3) compatible LVDS encoders
   - "renesas,r8a77995-lvds" for R8A77995 (R-Car D3) compatible LVDS encoders
 
 - reg: Base address and length for the memory-mapped registers
-- 
Regards,

Laurent Pinchart

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

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

* [PATCH v2 03/16] dt-bindings: display: renesas: lvds: Add EXTAL and DU_DOTCLKIN clocks
  2018-09-14  9:10 ` Laurent Pinchart
@ 2018-09-14  9:10   ` Laurent Pinchart
  -1 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-14  9:10 UTC (permalink / raw)
  To: dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham

On the D3 and E3 SoCs, the LVDS encoder can derive its internal pixel
clock from an externally supplied clock, either through the EXTAL pin or
through one of the DU_DOTCLKINx pins. Add corresponding clocks to the DT
bindings.

To retain backward compatibility with DT that don't specify the
clock-names property, the functional clock must always be specified
first, and the clock-names property is optional when only the functional
clock is specified.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
---
Changes since v1:

- Clarified wording
---
 .../devicetree/bindings/display/bridge/renesas,lvds.txt      | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
index 13af7e2ac7e8..3aeb0ec06fd0 100644
--- a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
+++ b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
@@ -19,7 +19,17 @@ Required properties:
   - "renesas,r8a77995-lvds" for R8A77995 (R-Car D3) compatible LVDS encoders
 
 - reg: Base address and length for the memory-mapped registers
-- clocks: A phandle + clock-specifier pair for the functional clock
+- clocks: A list of phandles + clock-specifier pairs, one for each entry in
+  the clock-names property.
+- clock-names: Name of the clocks. This property is model-dependent.
+  - The functional clock, which mandatory for all models, shall be listed
+    first, and shall be named "fck".
+  - On R8A77990 and R8A77995, the LVDS encoder can use the EXTAL or
+    DU_DOTCLKINx clocks. Those clocks are optional. When supplied they must be
+    named "extal" and "dclkin.x" respectively, with "x" being the DU_DOTCLKIN
+    numerical index.
+  - When the clocks property only contains the functional clock, the
+    clock-names property may be omitted.
 - resets: A phandle + reset specifier for the module reset
 
 Required nodes:
-- 
Regards,

Laurent Pinchart

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

* [PATCH v2 03/16] dt-bindings: display: renesas: lvds: Add EXTAL and DU_DOTCLKIN clocks
@ 2018-09-14  9:10   ` Laurent Pinchart
  0 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-14  9:10 UTC (permalink / raw)
  To: dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham

On the D3 and E3 SoCs, the LVDS encoder can derive its internal pixel
clock from an externally supplied clock, either through the EXTAL pin or
through one of the DU_DOTCLKINx pins. Add corresponding clocks to the DT
bindings.

To retain backward compatibility with DT that don't specify the
clock-names property, the functional clock must always be specified
first, and the clock-names property is optional when only the functional
clock is specified.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
---
Changes since v1:

- Clarified wording
---
 .../devicetree/bindings/display/bridge/renesas,lvds.txt      | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
index 13af7e2ac7e8..3aeb0ec06fd0 100644
--- a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
+++ b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
@@ -19,7 +19,17 @@ Required properties:
   - "renesas,r8a77995-lvds" for R8A77995 (R-Car D3) compatible LVDS encoders
 
 - reg: Base address and length for the memory-mapped registers
-- clocks: A phandle + clock-specifier pair for the functional clock
+- clocks: A list of phandles + clock-specifier pairs, one for each entry in
+  the clock-names property.
+- clock-names: Name of the clocks. This property is model-dependent.
+  - The functional clock, which mandatory for all models, shall be listed
+    first, and shall be named "fck".
+  - On R8A77990 and R8A77995, the LVDS encoder can use the EXTAL or
+    DU_DOTCLKINx clocks. Those clocks are optional. When supplied they must be
+    named "extal" and "dclkin.x" respectively, with "x" being the DU_DOTCLKIN
+    numerical index.
+  - When the clocks property only contains the functional clock, the
+    clock-names property may be omitted.
 - resets: A phandle + reset specifier for the module reset
 
 Required nodes:
-- 
Regards,

Laurent Pinchart

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

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

* [PATCH v2 04/16] drm: bridge: thc63: Restrict modes based on hardware operating frequency
  2018-09-14  9:10 ` Laurent Pinchart
@ 2018-09-14  9:10   ` Laurent Pinchart
  -1 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-14  9:10 UTC (permalink / raw)
  To: dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham

The THC63LVD1024 is restricted to a pixel clock frequency in the range
of 8 to 135 MHz. Implement the bridge .mode_valid() operation
accordingly.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
---
 drivers/gpu/drm/bridge/thc63lvd1024.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/bridge/thc63lvd1024.c b/drivers/gpu/drm/bridge/thc63lvd1024.c
index c8b9edd5a7f4..63609ba16b6d 100644
--- a/drivers/gpu/drm/bridge/thc63lvd1024.c
+++ b/drivers/gpu/drm/bridge/thc63lvd1024.c
@@ -45,6 +45,23 @@ static int thc63_attach(struct drm_bridge *bridge)
 	return drm_bridge_attach(bridge->encoder, thc63->next, bridge);
 }
 
+static enum drm_mode_status thc63_mode_valid(struct drm_bridge *bridge,
+					const struct drm_display_mode *mode)
+{
+	/*
+	 * The THC63LVD0124 clock frequency range is 8 to 135 MHz in single-in,
+	 * single-out mode. Note that the limits depends on the mode and will
+	 * need to be adjusted accordingly.
+	 */
+	if (mode->clock < 8000)
+		return MODE_CLOCK_LOW;
+
+	if (mode->clock > 135000)
+		return MODE_CLOCK_HIGH;
+
+	return MODE_OK;
+}
+
 static void thc63_enable(struct drm_bridge *bridge)
 {
 	struct thc63_dev *thc63 = to_thc63(bridge);
@@ -77,6 +94,7 @@ static void thc63_disable(struct drm_bridge *bridge)
 
 static const struct drm_bridge_funcs thc63_bridge_func = {
 	.attach	= thc63_attach,
+	.mode_valid = thc63_mode_valid,
 	.enable = thc63_enable,
 	.disable = thc63_disable,
 };
-- 
Regards,

Laurent Pinchart

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

* [PATCH v2 04/16] drm: bridge: thc63: Restrict modes based on hardware operating frequency
@ 2018-09-14  9:10   ` Laurent Pinchart
  0 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-14  9:10 UTC (permalink / raw)
  To: dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham

The THC63LVD1024 is restricted to a pixel clock frequency in the range
of 8 to 135 MHz. Implement the bridge .mode_valid() operation
accordingly.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
---
 drivers/gpu/drm/bridge/thc63lvd1024.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/bridge/thc63lvd1024.c b/drivers/gpu/drm/bridge/thc63lvd1024.c
index c8b9edd5a7f4..63609ba16b6d 100644
--- a/drivers/gpu/drm/bridge/thc63lvd1024.c
+++ b/drivers/gpu/drm/bridge/thc63lvd1024.c
@@ -45,6 +45,23 @@ static int thc63_attach(struct drm_bridge *bridge)
 	return drm_bridge_attach(bridge->encoder, thc63->next, bridge);
 }
 
+static enum drm_mode_status thc63_mode_valid(struct drm_bridge *bridge,
+					const struct drm_display_mode *mode)
+{
+	/*
+	 * The THC63LVD0124 clock frequency range is 8 to 135 MHz in single-in,
+	 * single-out mode. Note that the limits depends on the mode and will
+	 * need to be adjusted accordingly.
+	 */
+	if (mode->clock < 8000)
+		return MODE_CLOCK_LOW;
+
+	if (mode->clock > 135000)
+		return MODE_CLOCK_HIGH;
+
+	return MODE_OK;
+}
+
 static void thc63_enable(struct drm_bridge *bridge)
 {
 	struct thc63_dev *thc63 = to_thc63(bridge);
@@ -77,6 +94,7 @@ static void thc63_disable(struct drm_bridge *bridge)
 
 static const struct drm_bridge_funcs thc63_bridge_func = {
 	.attach	= thc63_attach,
+	.mode_valid = thc63_mode_valid,
 	.enable = thc63_enable,
 	.disable = thc63_disable,
 };
-- 
Regards,

Laurent Pinchart

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

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

* [PATCH v2 05/16] drm: rcar-du: lvds: D3/E3 support
  2018-09-14  9:10 ` Laurent Pinchart
@ 2018-09-14  9:10   ` Laurent Pinchart
  -1 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-14  9:10 UTC (permalink / raw)
  To: dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham

The LVDS encoders in the D3 and E3 SoCs differ significantly from those
in the other R-Car Gen3 family members:

- The LVDS PLL architecture is more complex and requires computing PLL
  parameters manually.
- The PLL uses external clocks as inputs, which need to be retrieved
  from DT.
- In addition to the different PLL setup, the startup sequence has
  changed *again* (seems someone had trouble making his/her mind).

Supporting all this requires DT bindings extensions for external clocks,
brand new PLL setup code, and a few quirks to handle the differences in
the startup sequence.

The implementation doesn't support all hardware features yet, namely

- Using the LV[01] clocks generated by the CPG as PLL input.
- Providing the LVDS PLL clock to the DU for use with the RGB output.

Those features can be added later when the need will arise.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
---
Changes since v1:

- Don't compile-out debug code based on DEBUG and CONFIG_DYNAMIC_DEBUG
- Test all three input clocks (DOTCLKIN[01] and EXTAL) and pick the best
  one
---
 drivers/gpu/drm/rcar-du/rcar_lvds.c      | 355 +++++++++++++++++++++++++++----
 drivers/gpu/drm/rcar-du/rcar_lvds_regs.h |  43 +++-
 2 files changed, 351 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c b/drivers/gpu/drm/rcar-du/rcar_lvds.c
index ce0eb68c3416..23e7743144c8 100644
--- a/drivers/gpu/drm/rcar-du/rcar_lvds.c
+++ b/drivers/gpu/drm/rcar-du/rcar_lvds.c
@@ -24,6 +24,8 @@
 
 #include "rcar_lvds_regs.h"
 
+struct rcar_lvds;
+
 /* Keep in sync with the LVDCR0.LVMD hardware register values. */
 enum rcar_lvds_mode {
 	RCAR_LVDS_MODE_JEIDA = 0,
@@ -31,14 +33,16 @@ enum rcar_lvds_mode {
 	RCAR_LVDS_MODE_VESA = 4,
 };
 
-#define RCAR_LVDS_QUIRK_LANES	(1 << 0)	/* LVDS lanes 1 and 3 inverted */
-#define RCAR_LVDS_QUIRK_GEN2_PLLCR (1 << 1)	/* LVDPLLCR has gen2 layout */
-#define RCAR_LVDS_QUIRK_GEN3_LVEN (1 << 2)	/* LVEN bit needs to be set */
-						/* on R8A77970/R8A7799x */
+#define RCAR_LVDS_QUIRK_LANES		BIT(0)	/* LVDS lanes 1 and 3 inverted */
+#define RCAR_LVDS_QUIRK_GEN3_LVEN	BIT(1)	/* LVEN bit needs to be set on R8A77970/R8A7799x */
+#define RCAR_LVDS_QUIRK_PWD		BIT(2)	/* PWD bit available (all of Gen3 but E3) */
+#define RCAR_LVDS_QUIRK_EXT_PLL		BIT(3)	/* Has extended PLL */
+#define RCAR_LVDS_QUIRK_DUAL_LINK	BIT(4)	/* Supports dual-link operation */
 
 struct rcar_lvds_device_info {
 	unsigned int gen;
 	unsigned int quirks;
+	void (*pll_setup)(struct rcar_lvds *lvds, unsigned int freq);
 };
 
 struct rcar_lvds {
@@ -52,7 +56,11 @@ struct rcar_lvds {
 	struct drm_panel *panel;
 
 	void __iomem *mmio;
-	struct clk *clock;
+	struct {
+		struct clk *mod;		/* CPG module clock */
+		struct clk *extal;		/* External clock */
+		struct clk *dotclkin[2];	/* External DU clocks */
+	} clocks;
 	bool enabled;
 
 	struct drm_display_mode display_mode;
@@ -128,33 +136,212 @@ static const struct drm_connector_funcs rcar_lvds_conn_funcs = {
 };
 
 /* -----------------------------------------------------------------------------
- * Bridge
+ * PLL Setup
  */
 
-static u32 rcar_lvds_lvdpllcr_gen2(unsigned int freq)
+static void rcar_lvds_pll_setup_gen2(struct rcar_lvds *lvds, unsigned int freq)
 {
-	if (freq < 39000)
-		return LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_38M;
-	else if (freq < 61000)
-		return LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_60M;
-	else if (freq < 121000)
-		return LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_121M;
+	u32 val;
+
+	if (freq < 39000000)
+		val = LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_38M;
+	else if (freq < 61000000)
+		val = LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_60M;
+	else if (freq < 121000000)
+		val = LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_121M;
 	else
-		return LVDPLLCR_PLLDLYCNT_150M;
+		val = LVDPLLCR_PLLDLYCNT_150M;
+
+	rcar_lvds_write(lvds, LVDPLLCR, val);
 }
 
-static u32 rcar_lvds_lvdpllcr_gen3(unsigned int freq)
+static void rcar_lvds_pll_setup_gen3(struct rcar_lvds *lvds, unsigned int freq)
 {
-	if (freq < 42000)
-		return LVDPLLCR_PLLDIVCNT_42M;
-	else if (freq < 85000)
-		return LVDPLLCR_PLLDIVCNT_85M;
-	else if (freq < 128000)
-		return LVDPLLCR_PLLDIVCNT_128M;
+	u32 val;
+
+	if (freq < 42000000)
+		val = LVDPLLCR_PLLDIVCNT_42M;
+	else if (freq < 85000000)
+		val = LVDPLLCR_PLLDIVCNT_85M;
+	else if (freq < 128000000)
+		val = LVDPLLCR_PLLDIVCNT_128M;
 	else
-		return LVDPLLCR_PLLDIVCNT_148M;
+		val = LVDPLLCR_PLLDIVCNT_148M;
+
+	rcar_lvds_write(lvds, LVDPLLCR, val);
 }
 
+struct pll_info {
+	unsigned long diff;
+	unsigned int pll_m;
+	unsigned int pll_n;
+	unsigned int pll_e;
+	unsigned int div;
+	u32 clksel;
+};
+
+static void rcar_lvds_d3_e3_pll_calc(struct rcar_lvds *lvds, struct clk *clk,
+				     unsigned long target, struct pll_info *pll,
+				     u32 clksel)
+{
+	unsigned long output;
+	unsigned long fin;
+	unsigned int m_min;
+	unsigned int m_max;
+	unsigned int m;
+	int error;
+
+	if (!clk)
+		return;
+
+	/*
+	 * The LVDS PLL is made of a pre-divider and a multiplier (strangerly
+	 * enough called M and N respectively), followed by a post-divider E.
+	 *
+	 *         ,-----.         ,-----.     ,-----.         ,-----.
+	 * Fin --> | 1/M | -Fpdf-> | PFD | --> | VCO | -Fvco-> | 1/E | --> Fout
+	 *         `-----'     ,-> |     |     `-----'   |     `-----'
+	 *                     |   `-----'               |
+	 *                     |         ,-----.         |
+	 *                     `-------- | 1/N | <-------'
+	 *                               `-----'
+	 *
+	 * The clock output by the PLL is then further divided by a programmable
+	 * divider DIV to achieve the desired target frequency. Finally, an
+	 * optional fixed /7 divider is used to convert the bit clock to a pixel
+	 * clock (as LVDS transmits 7 bits per lane per clock sample).
+	 *
+	 *          ,-------.     ,-----.     |\
+	 * Fout --> | 1/DIV | --> | 1/7 | --> | |
+	 *          `-------'  |  `-----'     | | --> dot clock
+	 *                     `------------> | |
+	 *                                    |/
+	 *
+	 * The /7 divider is optional when the LVDS PLL is used to generate a
+	 * dot clock for the DU RGB output, without using the LVDS encoder. We
+	 * don't support this configuration yet.
+	 *
+	 * The PLL allowed input frequency range is 12 MHz to 192 MHz.
+	 */
+
+	fin = clk_get_rate(clk);
+	if (fin < 12000000 || fin > 192000000)
+		return;
+
+	/*
+	 * The comparison frequency range is 12 MHz to 24 MHz, which limits the
+	 * allowed values for the pre-divider M (normal range 1-8).
+	 *
+	 * Fpfd = Fin / M
+	 */
+	m_min = max_t(unsigned int, 1, DIV_ROUND_UP(fin, 24000000));
+	m_max = min_t(unsigned int, 8, fin / 12000000);
+
+	for (m = m_min; m <= m_max; ++m) {
+		unsigned long fpfd;
+		unsigned int n_min;
+		unsigned int n_max;
+		unsigned int n;
+
+		/*
+		 * The VCO operating range is 900 Mhz to 1800 MHz, which limits
+		 * the allowed values for the multiplier N (normal range
+		 * 60-120).
+		 *
+		 * Fvco = Fin * N / M
+		 */
+		fpfd = fin / m;
+		n_min = max_t(unsigned int, 60, DIV_ROUND_UP(900000000, fpfd));
+		n_max = min_t(unsigned int, 120, 1800000000 / fpfd);
+
+		for (n = n_min; n < n_max; ++n) {
+			unsigned long fvco;
+			unsigned int e_min;
+			unsigned int e;
+
+			/*
+			 * The output frequency is limited to 1039.5 MHz,
+			 * limiting again the allowed values for the
+			 * post-divider E (normal value 1, 2 or 4).
+			 *
+			 * Fout = Fvco / E
+			 */
+			fvco = fpfd * n;
+			e_min = fvco > 1039500000 ? 1 : 0;
+
+			for (e = e_min; e < 3; ++e) {
+				unsigned long fout;
+				unsigned long diff;
+				unsigned int div;
+
+				/*
+				 * Finally we have a programable divider after
+				 * the PLL, followed by a an optional fixed /7
+				 * divider.
+				 */
+				fout = fvco / (1 << e) / 7;
+				div = DIV_ROUND_CLOSEST(fout, target);
+				diff = abs(fout / div - target);
+
+				if (diff < pll->diff) {
+					pll->diff = diff;
+					pll->pll_m = m;
+					pll->pll_n = n;
+					pll->pll_e = e;
+					pll->div = div;
+					pll->clksel = clksel;
+
+					if (diff == 0)
+						goto done;
+				}
+			}
+		}
+	}
+
+done:
+	output = fin * pll->pll_n / pll->pll_m / (1 << pll->pll_e)
+	       / 7 / pll->div;
+	error = (long)(output - target) * 10000 / (long)target;
+
+	dev_dbg(lvds->dev,
+		"%pC %lu Hz -> Fout %lu Hz (target %lu Hz, error %d.%02u%%), PLL M/N/E/DIV %u/%u/%u/%u\n",
+		clk, fin, output, target, error / 100,
+		error < 0 ? -error % 100 : error % 100,
+		pll->pll_m, pll->pll_n, pll->pll_e, pll->div);
+}
+
+static void rcar_lvds_pll_setup_d3_e3(struct rcar_lvds *lvds, unsigned int freq)
+{
+	struct pll_info pll = { .diff = (unsigned long)-1 };
+	u32 lvdpllcr;
+
+	rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.dotclkin[0], freq, &pll,
+				 LVDPLLCR_CKSEL_DU_DOTCLKIN(0));
+	rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.dotclkin[1], freq, &pll,
+				 LVDPLLCR_CKSEL_DU_DOTCLKIN(1));
+	rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.extal, freq, &pll,
+				 LVDPLLCR_CKSEL_EXTAL);
+
+	lvdpllcr = LVDPLLCR_PLLON | pll.clksel | LVDPLLCR_CLKOUT
+		 | LVDPLLCR_PLLN(pll.pll_n - 1) | LVDPLLCR_PLLM(pll.pll_m - 1);
+
+	if (pll.pll_e > 0)
+		lvdpllcr |= LVDPLLCR_STP_CLKOUTE | LVDPLLCR_OUTCLKSEL
+			 |  LVDPLLCR_PLLE(pll.pll_e - 1);
+
+	rcar_lvds_write(lvds, LVDPLLCR, lvdpllcr);
+
+	if (pll.div > 1)
+		rcar_lvds_write(lvds, LVDDIV, LVDDIV_DIVSEL |
+				LVDDIV_DIVRESET | LVDDIV_DIV(pll.div - 1));
+	else
+		rcar_lvds_write(lvds, LVDDIV, 0);
+}
+
+/* -----------------------------------------------------------------------------
+ * Bridge
+ */
+
 static void rcar_lvds_enable(struct drm_bridge *bridge)
 {
 	struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
@@ -164,14 +351,13 @@ static void rcar_lvds_enable(struct drm_bridge *bridge)
 	 * do we get a state pointer?
 	 */
 	struct drm_crtc *crtc = lvds->bridge.encoder->crtc;
-	u32 lvdpllcr;
 	u32 lvdhcr;
 	u32 lvdcr0;
 	int ret;
 
 	WARN_ON(lvds->enabled);
 
-	ret = clk_prepare_enable(lvds->clock);
+	ret = clk_prepare_enable(lvds->clocks.mod);
 	if (ret < 0)
 		return;
 
@@ -196,12 +382,13 @@ static void rcar_lvds_enable(struct drm_bridge *bridge)
 
 	rcar_lvds_write(lvds, LVDCHCR, lvdhcr);
 
+	if (lvds->info->quirks & RCAR_LVDS_QUIRK_DUAL_LINK) {
+		/* Disable dual-link mode. */
+		rcar_lvds_write(lvds, LVDSTRIPE, 0);
+	}
+
 	/* PLL clock configuration. */
-	if (lvds->info->quirks & RCAR_LVDS_QUIRK_GEN2_PLLCR)
-		lvdpllcr = rcar_lvds_lvdpllcr_gen2(mode->clock);
-	else
-		lvdpllcr = rcar_lvds_lvdpllcr_gen3(mode->clock);
-	rcar_lvds_write(lvds, LVDPLLCR, lvdpllcr);
+	lvds->info->pll_setup(lvds, mode->clock * 1000);
 
 	/* Set the LVDS mode and select the input. */
 	lvdcr0 = lvds->mode << LVDCR0_LVMD_SHIFT;
@@ -220,11 +407,16 @@ static void rcar_lvds_enable(struct drm_bridge *bridge)
 		rcar_lvds_write(lvds, LVDCR0, lvdcr0);
 	}
 
-	/* Turn the PLL on. */
-	lvdcr0 |= LVDCR0_PLLON;
-	rcar_lvds_write(lvds, LVDCR0, lvdcr0);
+	if (!(lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL)) {
+		/*
+		 * Turn the PLL on (simple PLL only, extended PLL is fully
+		 * controlled through LVDPLLCR).
+		 */
+		lvdcr0 |= LVDCR0_PLLON;
+		rcar_lvds_write(lvds, LVDCR0, lvdcr0);
+	}
 
-	if (lvds->info->gen > 2) {
+	if (lvds->info->quirks & RCAR_LVDS_QUIRK_PWD) {
 		/* Set LVDS normal mode. */
 		lvdcr0 |= LVDCR0_PWD;
 		rcar_lvds_write(lvds, LVDCR0, lvdcr0);
@@ -236,8 +428,10 @@ static void rcar_lvds_enable(struct drm_bridge *bridge)
 		rcar_lvds_write(lvds, LVDCR0, lvdcr0);
 	}
 
-	/* Wait for the startup delay. */
-	usleep_range(100, 150);
+	if (!(lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL)) {
+		/* Wait for the PLL startup delay (simple PLL only). */
+		usleep_range(100, 150);
+	}
 
 	/* Turn the output on. */
 	lvdcr0 |= LVDCR0_LVRES;
@@ -264,8 +458,9 @@ 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);
+	clk_disable_unprepare(lvds->clocks.mod);
 
 	lvds->enabled = false;
 }
@@ -446,6 +641,60 @@ static int rcar_lvds_parse_dt(struct rcar_lvds *lvds)
 	return ret;
 }
 
+static struct clk *rcar_lvds_get_clock(struct rcar_lvds *lvds, const char *name,
+				       bool optional)
+{
+	struct clk *clk;
+
+	clk = devm_clk_get(lvds->dev, name);
+	if (!IS_ERR(clk))
+		return clk;
+
+	if (PTR_ERR(clk) == -ENOENT && optional)
+		return NULL;
+
+	if (PTR_ERR(clk) != -EPROBE_DEFER)
+		dev_err(lvds->dev, "failed to get %s clock\n",
+			name ? name : "module");
+
+	return clk;
+}
+
+static int rcar_lvds_get_clocks(struct rcar_lvds *lvds)
+{
+	lvds->clocks.mod = rcar_lvds_get_clock(lvds, NULL, false);
+	if (IS_ERR(lvds->clocks.mod))
+		return PTR_ERR(lvds->clocks.mod);
+
+	/*
+	 * LVDS encoders without an extended PLL have no external clock inputs.
+	 */
+	if (!(lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL))
+		return 0;
+
+	lvds->clocks.extal = rcar_lvds_get_clock(lvds, "extal", true);
+	if (IS_ERR(lvds->clocks.extal))
+		return PTR_ERR(lvds->clocks.extal);
+
+	lvds->clocks.dotclkin[0] = rcar_lvds_get_clock(lvds, "dclkin.0", true);
+	if (IS_ERR(lvds->clocks.dotclkin[0]))
+		return PTR_ERR(lvds->clocks.dotclkin[0]);
+
+	lvds->clocks.dotclkin[1] = rcar_lvds_get_clock(lvds, "dclkin.1", true);
+	if (IS_ERR(lvds->clocks.dotclkin[1]))
+		return PTR_ERR(lvds->clocks.dotclkin[1]);
+
+	/* At least one input to the PLL must be available. */
+	if (!lvds->clocks.extal && !lvds->clocks.dotclkin[0] &&
+	    !lvds->clocks.dotclkin[1]) {
+		dev_err(lvds->dev,
+			"no input clock (extal, dclkin.0 or dclkin.1)\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static int rcar_lvds_probe(struct platform_device *pdev)
 {
 	struct rcar_lvds *lvds;
@@ -475,11 +724,9 @@ static int rcar_lvds_probe(struct platform_device *pdev)
 	if (IS_ERR(lvds->mmio))
 		return PTR_ERR(lvds->mmio);
 
-	lvds->clock = devm_clk_get(&pdev->dev, NULL);
-	if (IS_ERR(lvds->clock)) {
-		dev_err(&pdev->dev, "failed to get clock\n");
-		return PTR_ERR(lvds->clock);
-	}
+	ret = rcar_lvds_get_clocks(lvds);
+	if (ret < 0)
+		return ret;
 
 	drm_bridge_add(&lvds->bridge);
 
@@ -497,21 +744,39 @@ static int rcar_lvds_remove(struct platform_device *pdev)
 
 static const struct rcar_lvds_device_info rcar_lvds_gen2_info = {
 	.gen = 2,
-	.quirks = RCAR_LVDS_QUIRK_GEN2_PLLCR,
+	.pll_setup = rcar_lvds_pll_setup_gen2,
 };
 
 static const struct rcar_lvds_device_info rcar_lvds_r8a7790_info = {
 	.gen = 2,
-	.quirks = RCAR_LVDS_QUIRK_GEN2_PLLCR | RCAR_LVDS_QUIRK_LANES,
+	.quirks = RCAR_LVDS_QUIRK_LANES,
+	.pll_setup = rcar_lvds_pll_setup_gen2,
 };
 
 static const struct rcar_lvds_device_info rcar_lvds_gen3_info = {
 	.gen = 3,
+	.quirks = RCAR_LVDS_QUIRK_PWD,
+	.pll_setup = rcar_lvds_pll_setup_gen3,
 };
 
 static const struct rcar_lvds_device_info rcar_lvds_r8a77970_info = {
 	.gen = 3,
-	.quirks = RCAR_LVDS_QUIRK_GEN2_PLLCR | RCAR_LVDS_QUIRK_GEN3_LVEN,
+	.quirks = RCAR_LVDS_QUIRK_PWD | RCAR_LVDS_QUIRK_GEN3_LVEN,
+	.pll_setup = rcar_lvds_pll_setup_gen2,
+};
+
+static const struct rcar_lvds_device_info rcar_lvds_r8a77990_info = {
+	.gen = 3,
+	.quirks = RCAR_LVDS_QUIRK_GEN3_LVEN | RCAR_LVDS_QUIRK_EXT_PLL
+		| RCAR_LVDS_QUIRK_DUAL_LINK,
+	.pll_setup = rcar_lvds_pll_setup_d3_e3,
+};
+
+static const struct rcar_lvds_device_info rcar_lvds_r8a77995_info = {
+	.gen = 3,
+	.quirks = RCAR_LVDS_QUIRK_GEN3_LVEN | RCAR_LVDS_QUIRK_PWD
+		| RCAR_LVDS_QUIRK_EXT_PLL | RCAR_LVDS_QUIRK_DUAL_LINK,
+	.pll_setup = rcar_lvds_pll_setup_d3_e3,
 };
 
 static const struct of_device_id rcar_lvds_of_table[] = {
@@ -523,6 +788,8 @@ static const struct of_device_id rcar_lvds_of_table[] = {
 	{ .compatible = "renesas,r8a7796-lvds", .data = &rcar_lvds_gen3_info },
 	{ .compatible = "renesas,r8a77970-lvds", .data = &rcar_lvds_r8a77970_info },
 	{ .compatible = "renesas,r8a77980-lvds", .data = &rcar_lvds_gen3_info },
+	{ .compatible = "renesas,r8a77990-lvds", .data = &rcar_lvds_r8a77990_info },
+	{ .compatible = "renesas,r8a77995-lvds", .data = &rcar_lvds_r8a77995_info },
 	{ }
 };
 
diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h b/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
index 4870f50d9bec..87149f2f8056 100644
--- a/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
+++ b/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
@@ -18,7 +18,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
@@ -27,21 +27,36 @@
 #define LVDCR1_CLKSTBY			(3 << 0)
 
 #define LVDPLLCR			0x0008
+/* Gen2 & V3M */
 #define LVDPLLCR_CEEN			(1 << 14)
 #define LVDPLLCR_FBEN			(1 << 13)
 #define LVDPLLCR_COSEL			(1 << 12)
-/* Gen2 */
 #define LVDPLLCR_PLLDLYCNT_150M		(0x1bf << 0)
 #define LVDPLLCR_PLLDLYCNT_121M		(0x22c << 0)
 #define LVDPLLCR_PLLDLYCNT_60M		(0x77b << 0)
 #define LVDPLLCR_PLLDLYCNT_38M		(0x69a << 0)
 #define LVDPLLCR_PLLDLYCNT_MASK		(0x7ff << 0)
-/* Gen3 */
+/* Gen3 but V3M,D3 and E3 */
 #define LVDPLLCR_PLLDIVCNT_42M		(0x014cb << 0)
 #define LVDPLLCR_PLLDIVCNT_85M		(0x00a45 << 0)
 #define LVDPLLCR_PLLDIVCNT_128M		(0x006c3 << 0)
 #define LVDPLLCR_PLLDIVCNT_148M		(0x046c1 << 0)
 #define LVDPLLCR_PLLDIVCNT_MASK		(0x7ffff << 0)
+/* D3 and E3 */
+#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_DOTCLKIN(n)	((5 + (n) * 2) << 17)
+#define LVDPLLCR_OCKSEL			(1 << 16)
+#define LVDPLLCR_STP_CLKOUTE		(1 << 14)
+#define LVDPLLCR_OUTCLKSEL		(1 << 12)
+#define LVDPLLCR_CLKOUT			(1 << 11)
+#define LVDPLLCR_PLLE(n)		((n) << 10)
+#define LVDPLLCR_PLLN(n)		((n) << 3)
+#define LVDPLLCR_PLLM(n)		((n) << 0)
 
 #define LVDCTRCR			0x000c
 #define LVDCTRCR_CTR3SEL_ZERO		(0 << 12)
@@ -71,4 +86,26 @@
 #define LVDCHCR_CHSEL_CH(n, c)		((((c) - (n)) & 3) << ((n) * 4))
 #define LVDCHCR_CHSEL_MASK(n)		(3 << ((n) * 4))
 
+/* All registers below are specific to D3 and E3 */
+#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		(1 << 1)
+#define LVDSTRIPE_ST_ON			(1 << 0)
+
+#define LVDSCR				0x0018
+#define LVDSCR_DEPTH(n)			(((n) - 1) << 29)
+#define LVDSCR_BANDSET			(1 << 28)
+#define LVDSCR_TWGCNT(n)		((((n) - 256) / 16) << 24)
+#define LVDSCR_SDIV(n)			((n) << 22)
+#define LVDSCR_MODE			(1 << 21)
+#define LVDSCR_RSTN			(1 << 20)
+
+#define LVDDIV				0x001c
+#define LVDDIV_DIVSEL			(1 << 8)
+#define LVDDIV_DIVRESET			(1 << 7)
+#define LVDDIV_DIVSTP			(1 << 6)
+#define LVDDIV_DIV(n)			((n) << 0)
+
 #endif /* __RCAR_LVDS_REGS_H__ */
-- 
Regards,

Laurent Pinchart

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

* [PATCH v2 05/16] drm: rcar-du: lvds: D3/E3 support
@ 2018-09-14  9:10   ` Laurent Pinchart
  0 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-14  9:10 UTC (permalink / raw)
  To: dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham

The LVDS encoders in the D3 and E3 SoCs differ significantly from those
in the other R-Car Gen3 family members:

- The LVDS PLL architecture is more complex and requires computing PLL
  parameters manually.
- The PLL uses external clocks as inputs, which need to be retrieved
  from DT.
- In addition to the different PLL setup, the startup sequence has
  changed *again* (seems someone had trouble making his/her mind).

Supporting all this requires DT bindings extensions for external clocks,
brand new PLL setup code, and a few quirks to handle the differences in
the startup sequence.

The implementation doesn't support all hardware features yet, namely

- Using the LV[01] clocks generated by the CPG as PLL input.
- Providing the LVDS PLL clock to the DU for use with the RGB output.

Those features can be added later when the need will arise.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
---
Changes since v1:

- Don't compile-out debug code based on DEBUG and CONFIG_DYNAMIC_DEBUG
- Test all three input clocks (DOTCLKIN[01] and EXTAL) and pick the best
  one
---
 drivers/gpu/drm/rcar-du/rcar_lvds.c      | 355 +++++++++++++++++++++++++++----
 drivers/gpu/drm/rcar-du/rcar_lvds_regs.h |  43 +++-
 2 files changed, 351 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c b/drivers/gpu/drm/rcar-du/rcar_lvds.c
index ce0eb68c3416..23e7743144c8 100644
--- a/drivers/gpu/drm/rcar-du/rcar_lvds.c
+++ b/drivers/gpu/drm/rcar-du/rcar_lvds.c
@@ -24,6 +24,8 @@
 
 #include "rcar_lvds_regs.h"
 
+struct rcar_lvds;
+
 /* Keep in sync with the LVDCR0.LVMD hardware register values. */
 enum rcar_lvds_mode {
 	RCAR_LVDS_MODE_JEIDA = 0,
@@ -31,14 +33,16 @@ enum rcar_lvds_mode {
 	RCAR_LVDS_MODE_VESA = 4,
 };
 
-#define RCAR_LVDS_QUIRK_LANES	(1 << 0)	/* LVDS lanes 1 and 3 inverted */
-#define RCAR_LVDS_QUIRK_GEN2_PLLCR (1 << 1)	/* LVDPLLCR has gen2 layout */
-#define RCAR_LVDS_QUIRK_GEN3_LVEN (1 << 2)	/* LVEN bit needs to be set */
-						/* on R8A77970/R8A7799x */
+#define RCAR_LVDS_QUIRK_LANES		BIT(0)	/* LVDS lanes 1 and 3 inverted */
+#define RCAR_LVDS_QUIRK_GEN3_LVEN	BIT(1)	/* LVEN bit needs to be set on R8A77970/R8A7799x */
+#define RCAR_LVDS_QUIRK_PWD		BIT(2)	/* PWD bit available (all of Gen3 but E3) */
+#define RCAR_LVDS_QUIRK_EXT_PLL		BIT(3)	/* Has extended PLL */
+#define RCAR_LVDS_QUIRK_DUAL_LINK	BIT(4)	/* Supports dual-link operation */
 
 struct rcar_lvds_device_info {
 	unsigned int gen;
 	unsigned int quirks;
+	void (*pll_setup)(struct rcar_lvds *lvds, unsigned int freq);
 };
 
 struct rcar_lvds {
@@ -52,7 +56,11 @@ struct rcar_lvds {
 	struct drm_panel *panel;
 
 	void __iomem *mmio;
-	struct clk *clock;
+	struct {
+		struct clk *mod;		/* CPG module clock */
+		struct clk *extal;		/* External clock */
+		struct clk *dotclkin[2];	/* External DU clocks */
+	} clocks;
 	bool enabled;
 
 	struct drm_display_mode display_mode;
@@ -128,33 +136,212 @@ static const struct drm_connector_funcs rcar_lvds_conn_funcs = {
 };
 
 /* -----------------------------------------------------------------------------
- * Bridge
+ * PLL Setup
  */
 
-static u32 rcar_lvds_lvdpllcr_gen2(unsigned int freq)
+static void rcar_lvds_pll_setup_gen2(struct rcar_lvds *lvds, unsigned int freq)
 {
-	if (freq < 39000)
-		return LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_38M;
-	else if (freq < 61000)
-		return LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_60M;
-	else if (freq < 121000)
-		return LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_121M;
+	u32 val;
+
+	if (freq < 39000000)
+		val = LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_38M;
+	else if (freq < 61000000)
+		val = LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_60M;
+	else if (freq < 121000000)
+		val = LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_121M;
 	else
-		return LVDPLLCR_PLLDLYCNT_150M;
+		val = LVDPLLCR_PLLDLYCNT_150M;
+
+	rcar_lvds_write(lvds, LVDPLLCR, val);
 }
 
-static u32 rcar_lvds_lvdpllcr_gen3(unsigned int freq)
+static void rcar_lvds_pll_setup_gen3(struct rcar_lvds *lvds, unsigned int freq)
 {
-	if (freq < 42000)
-		return LVDPLLCR_PLLDIVCNT_42M;
-	else if (freq < 85000)
-		return LVDPLLCR_PLLDIVCNT_85M;
-	else if (freq < 128000)
-		return LVDPLLCR_PLLDIVCNT_128M;
+	u32 val;
+
+	if (freq < 42000000)
+		val = LVDPLLCR_PLLDIVCNT_42M;
+	else if (freq < 85000000)
+		val = LVDPLLCR_PLLDIVCNT_85M;
+	else if (freq < 128000000)
+		val = LVDPLLCR_PLLDIVCNT_128M;
 	else
-		return LVDPLLCR_PLLDIVCNT_148M;
+		val = LVDPLLCR_PLLDIVCNT_148M;
+
+	rcar_lvds_write(lvds, LVDPLLCR, val);
 }
 
+struct pll_info {
+	unsigned long diff;
+	unsigned int pll_m;
+	unsigned int pll_n;
+	unsigned int pll_e;
+	unsigned int div;
+	u32 clksel;
+};
+
+static void rcar_lvds_d3_e3_pll_calc(struct rcar_lvds *lvds, struct clk *clk,
+				     unsigned long target, struct pll_info *pll,
+				     u32 clksel)
+{
+	unsigned long output;
+	unsigned long fin;
+	unsigned int m_min;
+	unsigned int m_max;
+	unsigned int m;
+	int error;
+
+	if (!clk)
+		return;
+
+	/*
+	 * The LVDS PLL is made of a pre-divider and a multiplier (strangerly
+	 * enough called M and N respectively), followed by a post-divider E.
+	 *
+	 *         ,-----.         ,-----.     ,-----.         ,-----.
+	 * Fin --> | 1/M | -Fpdf-> | PFD | --> | VCO | -Fvco-> | 1/E | --> Fout
+	 *         `-----'     ,-> |     |     `-----'   |     `-----'
+	 *                     |   `-----'               |
+	 *                     |         ,-----.         |
+	 *                     `-------- | 1/N | <-------'
+	 *                               `-----'
+	 *
+	 * The clock output by the PLL is then further divided by a programmable
+	 * divider DIV to achieve the desired target frequency. Finally, an
+	 * optional fixed /7 divider is used to convert the bit clock to a pixel
+	 * clock (as LVDS transmits 7 bits per lane per clock sample).
+	 *
+	 *          ,-------.     ,-----.     |\
+	 * Fout --> | 1/DIV | --> | 1/7 | --> | |
+	 *          `-------'  |  `-----'     | | --> dot clock
+	 *                     `------------> | |
+	 *                                    |/
+	 *
+	 * The /7 divider is optional when the LVDS PLL is used to generate a
+	 * dot clock for the DU RGB output, without using the LVDS encoder. We
+	 * don't support this configuration yet.
+	 *
+	 * The PLL allowed input frequency range is 12 MHz to 192 MHz.
+	 */
+
+	fin = clk_get_rate(clk);
+	if (fin < 12000000 || fin > 192000000)
+		return;
+
+	/*
+	 * The comparison frequency range is 12 MHz to 24 MHz, which limits the
+	 * allowed values for the pre-divider M (normal range 1-8).
+	 *
+	 * Fpfd = Fin / M
+	 */
+	m_min = max_t(unsigned int, 1, DIV_ROUND_UP(fin, 24000000));
+	m_max = min_t(unsigned int, 8, fin / 12000000);
+
+	for (m = m_min; m <= m_max; ++m) {
+		unsigned long fpfd;
+		unsigned int n_min;
+		unsigned int n_max;
+		unsigned int n;
+
+		/*
+		 * The VCO operating range is 900 Mhz to 1800 MHz, which limits
+		 * the allowed values for the multiplier N (normal range
+		 * 60-120).
+		 *
+		 * Fvco = Fin * N / M
+		 */
+		fpfd = fin / m;
+		n_min = max_t(unsigned int, 60, DIV_ROUND_UP(900000000, fpfd));
+		n_max = min_t(unsigned int, 120, 1800000000 / fpfd);
+
+		for (n = n_min; n < n_max; ++n) {
+			unsigned long fvco;
+			unsigned int e_min;
+			unsigned int e;
+
+			/*
+			 * The output frequency is limited to 1039.5 MHz,
+			 * limiting again the allowed values for the
+			 * post-divider E (normal value 1, 2 or 4).
+			 *
+			 * Fout = Fvco / E
+			 */
+			fvco = fpfd * n;
+			e_min = fvco > 1039500000 ? 1 : 0;
+
+			for (e = e_min; e < 3; ++e) {
+				unsigned long fout;
+				unsigned long diff;
+				unsigned int div;
+
+				/*
+				 * Finally we have a programable divider after
+				 * the PLL, followed by a an optional fixed /7
+				 * divider.
+				 */
+				fout = fvco / (1 << e) / 7;
+				div = DIV_ROUND_CLOSEST(fout, target);
+				diff = abs(fout / div - target);
+
+				if (diff < pll->diff) {
+					pll->diff = diff;
+					pll->pll_m = m;
+					pll->pll_n = n;
+					pll->pll_e = e;
+					pll->div = div;
+					pll->clksel = clksel;
+
+					if (diff == 0)
+						goto done;
+				}
+			}
+		}
+	}
+
+done:
+	output = fin * pll->pll_n / pll->pll_m / (1 << pll->pll_e)
+	       / 7 / pll->div;
+	error = (long)(output - target) * 10000 / (long)target;
+
+	dev_dbg(lvds->dev,
+		"%pC %lu Hz -> Fout %lu Hz (target %lu Hz, error %d.%02u%%), PLL M/N/E/DIV %u/%u/%u/%u\n",
+		clk, fin, output, target, error / 100,
+		error < 0 ? -error % 100 : error % 100,
+		pll->pll_m, pll->pll_n, pll->pll_e, pll->div);
+}
+
+static void rcar_lvds_pll_setup_d3_e3(struct rcar_lvds *lvds, unsigned int freq)
+{
+	struct pll_info pll = { .diff = (unsigned long)-1 };
+	u32 lvdpllcr;
+
+	rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.dotclkin[0], freq, &pll,
+				 LVDPLLCR_CKSEL_DU_DOTCLKIN(0));
+	rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.dotclkin[1], freq, &pll,
+				 LVDPLLCR_CKSEL_DU_DOTCLKIN(1));
+	rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.extal, freq, &pll,
+				 LVDPLLCR_CKSEL_EXTAL);
+
+	lvdpllcr = LVDPLLCR_PLLON | pll.clksel | LVDPLLCR_CLKOUT
+		 | LVDPLLCR_PLLN(pll.pll_n - 1) | LVDPLLCR_PLLM(pll.pll_m - 1);
+
+	if (pll.pll_e > 0)
+		lvdpllcr |= LVDPLLCR_STP_CLKOUTE | LVDPLLCR_OUTCLKSEL
+			 |  LVDPLLCR_PLLE(pll.pll_e - 1);
+
+	rcar_lvds_write(lvds, LVDPLLCR, lvdpllcr);
+
+	if (pll.div > 1)
+		rcar_lvds_write(lvds, LVDDIV, LVDDIV_DIVSEL |
+				LVDDIV_DIVRESET | LVDDIV_DIV(pll.div - 1));
+	else
+		rcar_lvds_write(lvds, LVDDIV, 0);
+}
+
+/* -----------------------------------------------------------------------------
+ * Bridge
+ */
+
 static void rcar_lvds_enable(struct drm_bridge *bridge)
 {
 	struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
@@ -164,14 +351,13 @@ static void rcar_lvds_enable(struct drm_bridge *bridge)
 	 * do we get a state pointer?
 	 */
 	struct drm_crtc *crtc = lvds->bridge.encoder->crtc;
-	u32 lvdpllcr;
 	u32 lvdhcr;
 	u32 lvdcr0;
 	int ret;
 
 	WARN_ON(lvds->enabled);
 
-	ret = clk_prepare_enable(lvds->clock);
+	ret = clk_prepare_enable(lvds->clocks.mod);
 	if (ret < 0)
 		return;
 
@@ -196,12 +382,13 @@ static void rcar_lvds_enable(struct drm_bridge *bridge)
 
 	rcar_lvds_write(lvds, LVDCHCR, lvdhcr);
 
+	if (lvds->info->quirks & RCAR_LVDS_QUIRK_DUAL_LINK) {
+		/* Disable dual-link mode. */
+		rcar_lvds_write(lvds, LVDSTRIPE, 0);
+	}
+
 	/* PLL clock configuration. */
-	if (lvds->info->quirks & RCAR_LVDS_QUIRK_GEN2_PLLCR)
-		lvdpllcr = rcar_lvds_lvdpllcr_gen2(mode->clock);
-	else
-		lvdpllcr = rcar_lvds_lvdpllcr_gen3(mode->clock);
-	rcar_lvds_write(lvds, LVDPLLCR, lvdpllcr);
+	lvds->info->pll_setup(lvds, mode->clock * 1000);
 
 	/* Set the LVDS mode and select the input. */
 	lvdcr0 = lvds->mode << LVDCR0_LVMD_SHIFT;
@@ -220,11 +407,16 @@ static void rcar_lvds_enable(struct drm_bridge *bridge)
 		rcar_lvds_write(lvds, LVDCR0, lvdcr0);
 	}
 
-	/* Turn the PLL on. */
-	lvdcr0 |= LVDCR0_PLLON;
-	rcar_lvds_write(lvds, LVDCR0, lvdcr0);
+	if (!(lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL)) {
+		/*
+		 * Turn the PLL on (simple PLL only, extended PLL is fully
+		 * controlled through LVDPLLCR).
+		 */
+		lvdcr0 |= LVDCR0_PLLON;
+		rcar_lvds_write(lvds, LVDCR0, lvdcr0);
+	}
 
-	if (lvds->info->gen > 2) {
+	if (lvds->info->quirks & RCAR_LVDS_QUIRK_PWD) {
 		/* Set LVDS normal mode. */
 		lvdcr0 |= LVDCR0_PWD;
 		rcar_lvds_write(lvds, LVDCR0, lvdcr0);
@@ -236,8 +428,10 @@ static void rcar_lvds_enable(struct drm_bridge *bridge)
 		rcar_lvds_write(lvds, LVDCR0, lvdcr0);
 	}
 
-	/* Wait for the startup delay. */
-	usleep_range(100, 150);
+	if (!(lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL)) {
+		/* Wait for the PLL startup delay (simple PLL only). */
+		usleep_range(100, 150);
+	}
 
 	/* Turn the output on. */
 	lvdcr0 |= LVDCR0_LVRES;
@@ -264,8 +458,9 @@ 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);
+	clk_disable_unprepare(lvds->clocks.mod);
 
 	lvds->enabled = false;
 }
@@ -446,6 +641,60 @@ static int rcar_lvds_parse_dt(struct rcar_lvds *lvds)
 	return ret;
 }
 
+static struct clk *rcar_lvds_get_clock(struct rcar_lvds *lvds, const char *name,
+				       bool optional)
+{
+	struct clk *clk;
+
+	clk = devm_clk_get(lvds->dev, name);
+	if (!IS_ERR(clk))
+		return clk;
+
+	if (PTR_ERR(clk) == -ENOENT && optional)
+		return NULL;
+
+	if (PTR_ERR(clk) != -EPROBE_DEFER)
+		dev_err(lvds->dev, "failed to get %s clock\n",
+			name ? name : "module");
+
+	return clk;
+}
+
+static int rcar_lvds_get_clocks(struct rcar_lvds *lvds)
+{
+	lvds->clocks.mod = rcar_lvds_get_clock(lvds, NULL, false);
+	if (IS_ERR(lvds->clocks.mod))
+		return PTR_ERR(lvds->clocks.mod);
+
+	/*
+	 * LVDS encoders without an extended PLL have no external clock inputs.
+	 */
+	if (!(lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL))
+		return 0;
+
+	lvds->clocks.extal = rcar_lvds_get_clock(lvds, "extal", true);
+	if (IS_ERR(lvds->clocks.extal))
+		return PTR_ERR(lvds->clocks.extal);
+
+	lvds->clocks.dotclkin[0] = rcar_lvds_get_clock(lvds, "dclkin.0", true);
+	if (IS_ERR(lvds->clocks.dotclkin[0]))
+		return PTR_ERR(lvds->clocks.dotclkin[0]);
+
+	lvds->clocks.dotclkin[1] = rcar_lvds_get_clock(lvds, "dclkin.1", true);
+	if (IS_ERR(lvds->clocks.dotclkin[1]))
+		return PTR_ERR(lvds->clocks.dotclkin[1]);
+
+	/* At least one input to the PLL must be available. */
+	if (!lvds->clocks.extal && !lvds->clocks.dotclkin[0] &&
+	    !lvds->clocks.dotclkin[1]) {
+		dev_err(lvds->dev,
+			"no input clock (extal, dclkin.0 or dclkin.1)\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static int rcar_lvds_probe(struct platform_device *pdev)
 {
 	struct rcar_lvds *lvds;
@@ -475,11 +724,9 @@ static int rcar_lvds_probe(struct platform_device *pdev)
 	if (IS_ERR(lvds->mmio))
 		return PTR_ERR(lvds->mmio);
 
-	lvds->clock = devm_clk_get(&pdev->dev, NULL);
-	if (IS_ERR(lvds->clock)) {
-		dev_err(&pdev->dev, "failed to get clock\n");
-		return PTR_ERR(lvds->clock);
-	}
+	ret = rcar_lvds_get_clocks(lvds);
+	if (ret < 0)
+		return ret;
 
 	drm_bridge_add(&lvds->bridge);
 
@@ -497,21 +744,39 @@ static int rcar_lvds_remove(struct platform_device *pdev)
 
 static const struct rcar_lvds_device_info rcar_lvds_gen2_info = {
 	.gen = 2,
-	.quirks = RCAR_LVDS_QUIRK_GEN2_PLLCR,
+	.pll_setup = rcar_lvds_pll_setup_gen2,
 };
 
 static const struct rcar_lvds_device_info rcar_lvds_r8a7790_info = {
 	.gen = 2,
-	.quirks = RCAR_LVDS_QUIRK_GEN2_PLLCR | RCAR_LVDS_QUIRK_LANES,
+	.quirks = RCAR_LVDS_QUIRK_LANES,
+	.pll_setup = rcar_lvds_pll_setup_gen2,
 };
 
 static const struct rcar_lvds_device_info rcar_lvds_gen3_info = {
 	.gen = 3,
+	.quirks = RCAR_LVDS_QUIRK_PWD,
+	.pll_setup = rcar_lvds_pll_setup_gen3,
 };
 
 static const struct rcar_lvds_device_info rcar_lvds_r8a77970_info = {
 	.gen = 3,
-	.quirks = RCAR_LVDS_QUIRK_GEN2_PLLCR | RCAR_LVDS_QUIRK_GEN3_LVEN,
+	.quirks = RCAR_LVDS_QUIRK_PWD | RCAR_LVDS_QUIRK_GEN3_LVEN,
+	.pll_setup = rcar_lvds_pll_setup_gen2,
+};
+
+static const struct rcar_lvds_device_info rcar_lvds_r8a77990_info = {
+	.gen = 3,
+	.quirks = RCAR_LVDS_QUIRK_GEN3_LVEN | RCAR_LVDS_QUIRK_EXT_PLL
+		| RCAR_LVDS_QUIRK_DUAL_LINK,
+	.pll_setup = rcar_lvds_pll_setup_d3_e3,
+};
+
+static const struct rcar_lvds_device_info rcar_lvds_r8a77995_info = {
+	.gen = 3,
+	.quirks = RCAR_LVDS_QUIRK_GEN3_LVEN | RCAR_LVDS_QUIRK_PWD
+		| RCAR_LVDS_QUIRK_EXT_PLL | RCAR_LVDS_QUIRK_DUAL_LINK,
+	.pll_setup = rcar_lvds_pll_setup_d3_e3,
 };
 
 static const struct of_device_id rcar_lvds_of_table[] = {
@@ -523,6 +788,8 @@ static const struct of_device_id rcar_lvds_of_table[] = {
 	{ .compatible = "renesas,r8a7796-lvds", .data = &rcar_lvds_gen3_info },
 	{ .compatible = "renesas,r8a77970-lvds", .data = &rcar_lvds_r8a77970_info },
 	{ .compatible = "renesas,r8a77980-lvds", .data = &rcar_lvds_gen3_info },
+	{ .compatible = "renesas,r8a77990-lvds", .data = &rcar_lvds_r8a77990_info },
+	{ .compatible = "renesas,r8a77995-lvds", .data = &rcar_lvds_r8a77995_info },
 	{ }
 };
 
diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h b/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
index 4870f50d9bec..87149f2f8056 100644
--- a/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
+++ b/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
@@ -18,7 +18,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
@@ -27,21 +27,36 @@
 #define LVDCR1_CLKSTBY			(3 << 0)
 
 #define LVDPLLCR			0x0008
+/* Gen2 & V3M */
 #define LVDPLLCR_CEEN			(1 << 14)
 #define LVDPLLCR_FBEN			(1 << 13)
 #define LVDPLLCR_COSEL			(1 << 12)
-/* Gen2 */
 #define LVDPLLCR_PLLDLYCNT_150M		(0x1bf << 0)
 #define LVDPLLCR_PLLDLYCNT_121M		(0x22c << 0)
 #define LVDPLLCR_PLLDLYCNT_60M		(0x77b << 0)
 #define LVDPLLCR_PLLDLYCNT_38M		(0x69a << 0)
 #define LVDPLLCR_PLLDLYCNT_MASK		(0x7ff << 0)
-/* Gen3 */
+/* Gen3 but V3M,D3 and E3 */
 #define LVDPLLCR_PLLDIVCNT_42M		(0x014cb << 0)
 #define LVDPLLCR_PLLDIVCNT_85M		(0x00a45 << 0)
 #define LVDPLLCR_PLLDIVCNT_128M		(0x006c3 << 0)
 #define LVDPLLCR_PLLDIVCNT_148M		(0x046c1 << 0)
 #define LVDPLLCR_PLLDIVCNT_MASK		(0x7ffff << 0)
+/* D3 and E3 */
+#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_DOTCLKIN(n)	((5 + (n) * 2) << 17)
+#define LVDPLLCR_OCKSEL			(1 << 16)
+#define LVDPLLCR_STP_CLKOUTE		(1 << 14)
+#define LVDPLLCR_OUTCLKSEL		(1 << 12)
+#define LVDPLLCR_CLKOUT			(1 << 11)
+#define LVDPLLCR_PLLE(n)		((n) << 10)
+#define LVDPLLCR_PLLN(n)		((n) << 3)
+#define LVDPLLCR_PLLM(n)		((n) << 0)
 
 #define LVDCTRCR			0x000c
 #define LVDCTRCR_CTR3SEL_ZERO		(0 << 12)
@@ -71,4 +86,26 @@
 #define LVDCHCR_CHSEL_CH(n, c)		((((c) - (n)) & 3) << ((n) * 4))
 #define LVDCHCR_CHSEL_MASK(n)		(3 << ((n) * 4))
 
+/* All registers below are specific to D3 and E3 */
+#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		(1 << 1)
+#define LVDSTRIPE_ST_ON			(1 << 0)
+
+#define LVDSCR				0x0018
+#define LVDSCR_DEPTH(n)			(((n) - 1) << 29)
+#define LVDSCR_BANDSET			(1 << 28)
+#define LVDSCR_TWGCNT(n)		((((n) - 256) / 16) << 24)
+#define LVDSCR_SDIV(n)			((n) << 22)
+#define LVDSCR_MODE			(1 << 21)
+#define LVDSCR_RSTN			(1 << 20)
+
+#define LVDDIV				0x001c
+#define LVDDIV_DIVSEL			(1 << 8)
+#define LVDDIV_DIVRESET			(1 << 7)
+#define LVDDIV_DIVSTP			(1 << 6)
+#define LVDDIV_DIV(n)			((n) << 0)
+
 #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 related	[flat|nested] 118+ messages in thread

* [PATCH v2 06/16] drm: rcar-du: Perform the initial CRTC setup from rcar_du_crtc_get()
  2018-09-14  9:10 ` Laurent Pinchart
@ 2018-09-14  9:10   ` Laurent Pinchart
  -1 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-14  9:10 UTC (permalink / raw)
  To: dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham

The rcar_du_crtc_get() function is always immediately followed by a call
to rcar_du_crtc_setup(). Call the later from the former to simplify the
code, and add a comment to explain how the get and put calls are
balanced.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
---
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 107 +++++++++++++++++----------------
 1 file changed, 56 insertions(+), 51 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index 6288b9ad9e24..c89751c26f9c 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -66,39 +66,6 @@ static void rcar_du_crtc_clr_set(struct rcar_du_crtc *rcrtc, u32 reg,
 	rcar_du_write(rcdu, rcrtc->mmio_offset + reg, (value & ~clr) | set);
 }
 
-static int rcar_du_crtc_get(struct rcar_du_crtc *rcrtc)
-{
-	int ret;
-
-	ret = clk_prepare_enable(rcrtc->clock);
-	if (ret < 0)
-		return ret;
-
-	ret = clk_prepare_enable(rcrtc->extclock);
-	if (ret < 0)
-		goto error_clock;
-
-	ret = rcar_du_group_get(rcrtc->group);
-	if (ret < 0)
-		goto error_group;
-
-	return 0;
-
-error_group:
-	clk_disable_unprepare(rcrtc->extclock);
-error_clock:
-	clk_disable_unprepare(rcrtc->clock);
-	return ret;
-}
-
-static void rcar_du_crtc_put(struct rcar_du_crtc *rcrtc)
-{
-	rcar_du_group_put(rcrtc->group);
-
-	clk_disable_unprepare(rcrtc->extclock);
-	clk_disable_unprepare(rcrtc->clock);
-}
-
 /* -----------------------------------------------------------------------------
  * Hardware Setup
  */
@@ -546,6 +513,51 @@ static void rcar_du_crtc_setup(struct rcar_du_crtc *rcrtc)
 	drm_crtc_vblank_on(&rcrtc->crtc);
 }
 
+static int rcar_du_crtc_get(struct rcar_du_crtc *rcrtc)
+{
+	int ret;
+
+	/*
+	 * Guard against double-get, as the function is called from both the
+	 * .atomic_enable() and .atomic_begin() handlers.
+	 */
+	if (rcrtc->initialized)
+		return 0;
+
+	ret = clk_prepare_enable(rcrtc->clock);
+	if (ret < 0)
+		return ret;
+
+	ret = clk_prepare_enable(rcrtc->extclock);
+	if (ret < 0)
+		goto error_clock;
+
+	ret = rcar_du_group_get(rcrtc->group);
+	if (ret < 0)
+		goto error_group;
+
+	rcar_du_crtc_setup(rcrtc);
+	rcrtc->initialized = true;
+
+	return 0;
+
+error_group:
+	clk_disable_unprepare(rcrtc->extclock);
+error_clock:
+	clk_disable_unprepare(rcrtc->clock);
+	return ret;
+}
+
+static void rcar_du_crtc_put(struct rcar_du_crtc *rcrtc)
+{
+	rcar_du_group_put(rcrtc->group);
+
+	clk_disable_unprepare(rcrtc->extclock);
+	clk_disable_unprepare(rcrtc->clock);
+
+	rcrtc->initialized = false;
+}
+
 static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc)
 {
 	bool interlaced;
@@ -639,16 +651,7 @@ static void rcar_du_crtc_atomic_enable(struct drm_crtc *crtc,
 {
 	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
 
-	/*
-	 * If the CRTC has already been setup by the .atomic_begin() handler we
-	 * can skip the setup stage.
-	 */
-	if (!rcrtc->initialized) {
-		rcar_du_crtc_get(rcrtc);
-		rcar_du_crtc_setup(rcrtc);
-		rcrtc->initialized = true;
-	}
-
+	rcar_du_crtc_get(rcrtc);
 	rcar_du_crtc_start(rcrtc);
 }
 
@@ -667,7 +670,6 @@ static void rcar_du_crtc_atomic_disable(struct drm_crtc *crtc,
 	}
 	spin_unlock_irq(&crtc->dev->event_lock);
 
-	rcrtc->initialized = false;
 	rcrtc->outputs = 0;
 }
 
@@ -680,14 +682,17 @@ static void rcar_du_crtc_atomic_begin(struct drm_crtc *crtc,
 
 	/*
 	 * If a mode set is in progress we can be called with the CRTC disabled.
-	 * We then need to first setup the CRTC in order to configure planes.
-	 * The .atomic_enable() handler will notice and skip the CRTC setup.
+	 * We thus need to first get and setup the CRTC in order to configure
+	 * planes. We must *not* put the CRTC in .atomic_flush(), as it must be
+	 * kept awake until the .atomic_enable() call that will follow. The get
+	 * operation in .atomic_enable() will in that case be a no-op, and the
+	 * CRTC will be put later in .atomic_disable().
+	 *
+	 * If a mode set is not in progress the CRTC is enabled, and the
+	 * following get call will be a no-op. There is thus no need to belance
+	 * it in .atomic_flush() either.
 	 */
-	if (!rcrtc->initialized) {
-		rcar_du_crtc_get(rcrtc);
-		rcar_du_crtc_setup(rcrtc);
-		rcrtc->initialized = true;
-	}
+	rcar_du_crtc_get(rcrtc);
 
 	if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
 		rcar_du_vsp_atomic_begin(rcrtc);
-- 
Regards,

Laurent Pinchart

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

* [PATCH v2 06/16] drm: rcar-du: Perform the initial CRTC setup from rcar_du_crtc_get()
@ 2018-09-14  9:10   ` Laurent Pinchart
  0 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-14  9:10 UTC (permalink / raw)
  To: dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham

The rcar_du_crtc_get() function is always immediately followed by a call
to rcar_du_crtc_setup(). Call the later from the former to simplify the
code, and add a comment to explain how the get and put calls are
balanced.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
---
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 107 +++++++++++++++++----------------
 1 file changed, 56 insertions(+), 51 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index 6288b9ad9e24..c89751c26f9c 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -66,39 +66,6 @@ static void rcar_du_crtc_clr_set(struct rcar_du_crtc *rcrtc, u32 reg,
 	rcar_du_write(rcdu, rcrtc->mmio_offset + reg, (value & ~clr) | set);
 }
 
-static int rcar_du_crtc_get(struct rcar_du_crtc *rcrtc)
-{
-	int ret;
-
-	ret = clk_prepare_enable(rcrtc->clock);
-	if (ret < 0)
-		return ret;
-
-	ret = clk_prepare_enable(rcrtc->extclock);
-	if (ret < 0)
-		goto error_clock;
-
-	ret = rcar_du_group_get(rcrtc->group);
-	if (ret < 0)
-		goto error_group;
-
-	return 0;
-
-error_group:
-	clk_disable_unprepare(rcrtc->extclock);
-error_clock:
-	clk_disable_unprepare(rcrtc->clock);
-	return ret;
-}
-
-static void rcar_du_crtc_put(struct rcar_du_crtc *rcrtc)
-{
-	rcar_du_group_put(rcrtc->group);
-
-	clk_disable_unprepare(rcrtc->extclock);
-	clk_disable_unprepare(rcrtc->clock);
-}
-
 /* -----------------------------------------------------------------------------
  * Hardware Setup
  */
@@ -546,6 +513,51 @@ static void rcar_du_crtc_setup(struct rcar_du_crtc *rcrtc)
 	drm_crtc_vblank_on(&rcrtc->crtc);
 }
 
+static int rcar_du_crtc_get(struct rcar_du_crtc *rcrtc)
+{
+	int ret;
+
+	/*
+	 * Guard against double-get, as the function is called from both the
+	 * .atomic_enable() and .atomic_begin() handlers.
+	 */
+	if (rcrtc->initialized)
+		return 0;
+
+	ret = clk_prepare_enable(rcrtc->clock);
+	if (ret < 0)
+		return ret;
+
+	ret = clk_prepare_enable(rcrtc->extclock);
+	if (ret < 0)
+		goto error_clock;
+
+	ret = rcar_du_group_get(rcrtc->group);
+	if (ret < 0)
+		goto error_group;
+
+	rcar_du_crtc_setup(rcrtc);
+	rcrtc->initialized = true;
+
+	return 0;
+
+error_group:
+	clk_disable_unprepare(rcrtc->extclock);
+error_clock:
+	clk_disable_unprepare(rcrtc->clock);
+	return ret;
+}
+
+static void rcar_du_crtc_put(struct rcar_du_crtc *rcrtc)
+{
+	rcar_du_group_put(rcrtc->group);
+
+	clk_disable_unprepare(rcrtc->extclock);
+	clk_disable_unprepare(rcrtc->clock);
+
+	rcrtc->initialized = false;
+}
+
 static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc)
 {
 	bool interlaced;
@@ -639,16 +651,7 @@ static void rcar_du_crtc_atomic_enable(struct drm_crtc *crtc,
 {
 	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
 
-	/*
-	 * If the CRTC has already been setup by the .atomic_begin() handler we
-	 * can skip the setup stage.
-	 */
-	if (!rcrtc->initialized) {
-		rcar_du_crtc_get(rcrtc);
-		rcar_du_crtc_setup(rcrtc);
-		rcrtc->initialized = true;
-	}
-
+	rcar_du_crtc_get(rcrtc);
 	rcar_du_crtc_start(rcrtc);
 }
 
@@ -667,7 +670,6 @@ static void rcar_du_crtc_atomic_disable(struct drm_crtc *crtc,
 	}
 	spin_unlock_irq(&crtc->dev->event_lock);
 
-	rcrtc->initialized = false;
 	rcrtc->outputs = 0;
 }
 
@@ -680,14 +682,17 @@ static void rcar_du_crtc_atomic_begin(struct drm_crtc *crtc,
 
 	/*
 	 * If a mode set is in progress we can be called with the CRTC disabled.
-	 * We then need to first setup the CRTC in order to configure planes.
-	 * The .atomic_enable() handler will notice and skip the CRTC setup.
+	 * We thus need to first get and setup the CRTC in order to configure
+	 * planes. We must *not* put the CRTC in .atomic_flush(), as it must be
+	 * kept awake until the .atomic_enable() call that will follow. The get
+	 * operation in .atomic_enable() will in that case be a no-op, and the
+	 * CRTC will be put later in .atomic_disable().
+	 *
+	 * If a mode set is not in progress the CRTC is enabled, and the
+	 * following get call will be a no-op. There is thus no need to belance
+	 * it in .atomic_flush() either.
 	 */
-	if (!rcrtc->initialized) {
-		rcar_du_crtc_get(rcrtc);
-		rcar_du_crtc_setup(rcrtc);
-		rcrtc->initialized = true;
-	}
+	rcar_du_crtc_get(rcrtc);
 
 	if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
 		rcar_du_vsp_atomic_begin(rcrtc);
-- 
Regards,

Laurent Pinchart

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

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

* [PATCH v2 07/16] drm: rcar-du: Use LVDS PLL clock as dot clock when possible
  2018-09-14  9:10 ` Laurent Pinchart
@ 2018-09-14  9:10   ` Laurent Pinchart
  -1 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-14  9:10 UTC (permalink / raw)
  To: dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham

On selected SoCs, the DU can use the clock output by the LVDS encoder
PLL as its input dot clock. This feature is optional, but on the D3 and
E3 SoC it is often the only way to obtain a precise dot clock frequency,
as the other available clocks (CPG-generated clock and external clock)
usually have fixed rates.

Add a DU model information field to describe which DU channels can use
the LVDS PLL output clock as their input clock, and configure clock
routing accordingly.

This feature is available on H2, M2-W, M2-N, D3 and E3 SoCs, with D3 and
E3 being the primary targets. It is left disabled in this commit, and
will be enabled per-SoC after careful testing.

At the hardware level, clock routing is configured at runtime in two
steps, first selecting an internal dot clock between the LVDS PLL clock
and the external DOTCLKIN clock, and then selecting between the internal
dot clock and the CPG-generated clock. The first part requires stopping
the whole DU group in order for the change to take effect, thus causing
flickering on the screen. For this reason we currently hardcode the
clock source to the LVDS PLL clock if available, and allow flicker-free
selection of the external DOTCLKIN clock or CPG-generated clock
otherwise. A more dynamic clock selection process can be implemented
later if the need arises.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
---
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c  |  8 +++++
 drivers/gpu/drm/rcar-du/rcar_du_drv.h   |  2 ++
 drivers/gpu/drm/rcar-du/rcar_du_group.c | 64 +++++++++++++++++++++++++--------
 3 files changed, 59 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index c89751c26f9c..2f8776c1ec8f 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -261,6 +261,14 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
 		rcar_du_group_write(rcrtc->group, DPLLCR, dpllcr);
 
 		escr = ESCR_DCLKSEL_DCLKIN | div;
+	} else if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index)) {
+		/*
+		 * Use the LVDS PLL output as the dot clock when outputting to
+		 * the LVDS encoder on an SoC that supports this clock routing
+		 * option. We use the clock directly in that case, without any
+		 * additional divider.
+		 */
+		escr = ESCR_DCLKSEL_DCLKIN;
 	} else {
 		struct du_clk_params params = { .diff = (unsigned long)-1 };
 
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
index fef9ea5c22f3..ebba9aefba6a 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
@@ -53,6 +53,7 @@ struct rcar_du_output_routing {
  * @routes: array of CRTC to output routes, indexed by output (RCAR_DU_OUTPUT_*)
  * @num_lvds: number of internal LVDS encoders
  * @dpll_mask: bit mask of DU channels equipped with a DPLL
+ * @lvds_clk_mask: bitmask of channels that can use the LVDS clock as dot clock
  */
 struct rcar_du_device_info {
 	unsigned int gen;
@@ -62,6 +63,7 @@ struct rcar_du_device_info {
 	struct rcar_du_output_routing routes[RCAR_DU_OUTPUT_MAX];
 	unsigned int num_lvds;
 	unsigned int dpll_mask;
+	unsigned int lvds_clk_mask;
 };
 
 #define RCAR_DU_MAX_CRTCS		4
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c
index ef2c177afb6d..4c62841eff2f 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
@@ -89,6 +89,54 @@ static void rcar_du_group_setup_defr8(struct rcar_du_group *rgrp)
 	rcar_du_group_write(rgrp, DEFR8, defr8);
 }
 
+static void rcar_du_group_setup_didsr(struct rcar_du_group *rgrp)
+{
+	struct rcar_du_device *rcdu = rgrp->dev;
+	struct rcar_du_crtc *rcrtc;
+	unsigned int num_crtcs = 0;
+	unsigned int i;
+	u32 didsr;
+
+	/*
+	 * Configure input dot clock routing with a hardcoded configuration. If
+	 * the DU channel can use the LVDS encoder output clock as the dot
+	 * clock, do so. Otherwise route DU_DOTCLKINn signal to DUn.
+	 *
+	 * Each channel can then select between the dot clock configured here
+	 * and the clock provided by the CPG through the ESCR register.
+	 */
+	if (rcdu->info->gen < 3 && rgrp->index == 0) {
+		/*
+		 * On Gen2 a single register in the first group controls dot
+		 * clock selection for all channels.
+		 */
+		rcrtc = rcdu->crtcs;
+		num_crtcs = rcdu->num_crtcs;
+	} else if (rcdu->info->gen == 3 && rgrp->num_crtcs > 1) {
+		/*
+		 * On Gen3 dot clocks are setup through per-group registers,
+		 * only available when the group has two channels.
+		 */
+		rcrtc = &rcdu->crtcs[rgrp->index * 2];
+		num_crtcs = rgrp->num_crtcs;
+	}
+
+	if (!num_crtcs)
+		return;
+
+	didsr = DIDSR_CODE;
+	for (i = 0; i < num_crtcs; ++i, ++rcrtc) {
+		if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index))
+			didsr |= DIDSR_LCDS_LVDS0(i)
+			      |  DIDSR_PDCS_CLK(i, 0);
+		else
+			didsr |= DIDSR_LCDS_DCLKIN(i)
+			      |  DIDSR_PDCS_CLK(i, 0);
+	}
+
+	rcar_du_group_write(rgrp, DIDSR, didsr);
+}
+
 static void rcar_du_group_setup(struct rcar_du_group *rgrp)
 {
 	struct rcar_du_device *rcdu = rgrp->dev;
@@ -106,21 +154,7 @@ static void rcar_du_group_setup(struct rcar_du_group *rgrp)
 
 	if (rcar_du_has(rgrp->dev, RCAR_DU_FEATURE_EXT_CTRL_REGS)) {
 		rcar_du_group_setup_defr8(rgrp);
-
-		/*
-		 * Configure input dot clock routing. We currently hardcode the
-		 * configuration to routing DOTCLKINn to DUn. Register fields
-		 * depend on the DU generation, but the resulting value is 0 in
-		 * all cases.
-		 *
-		 * On Gen2 a single register in the first group controls dot
-		 * clock selection for all channels, while on Gen3 dot clocks
-		 * 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))
-			rcar_du_group_write(rgrp, DIDSR, DIDSR_CODE);
+		rcar_du_group_setup_didsr(rgrp);
 	}
 
 	if (rcdu->info->gen >= 3)
-- 
Regards,

Laurent Pinchart

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

* [PATCH v2 07/16] drm: rcar-du: Use LVDS PLL clock as dot clock when possible
@ 2018-09-14  9:10   ` Laurent Pinchart
  0 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-14  9:10 UTC (permalink / raw)
  To: dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham

On selected SoCs, the DU can use the clock output by the LVDS encoder
PLL as its input dot clock. This feature is optional, but on the D3 and
E3 SoC it is often the only way to obtain a precise dot clock frequency,
as the other available clocks (CPG-generated clock and external clock)
usually have fixed rates.

Add a DU model information field to describe which DU channels can use
the LVDS PLL output clock as their input clock, and configure clock
routing accordingly.

This feature is available on H2, M2-W, M2-N, D3 and E3 SoCs, with D3 and
E3 being the primary targets. It is left disabled in this commit, and
will be enabled per-SoC after careful testing.

At the hardware level, clock routing is configured at runtime in two
steps, first selecting an internal dot clock between the LVDS PLL clock
and the external DOTCLKIN clock, and then selecting between the internal
dot clock and the CPG-generated clock. The first part requires stopping
the whole DU group in order for the change to take effect, thus causing
flickering on the screen. For this reason we currently hardcode the
clock source to the LVDS PLL clock if available, and allow flicker-free
selection of the external DOTCLKIN clock or CPG-generated clock
otherwise. A more dynamic clock selection process can be implemented
later if the need arises.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
---
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c  |  8 +++++
 drivers/gpu/drm/rcar-du/rcar_du_drv.h   |  2 ++
 drivers/gpu/drm/rcar-du/rcar_du_group.c | 64 +++++++++++++++++++++++++--------
 3 files changed, 59 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index c89751c26f9c..2f8776c1ec8f 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -261,6 +261,14 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
 		rcar_du_group_write(rcrtc->group, DPLLCR, dpllcr);
 
 		escr = ESCR_DCLKSEL_DCLKIN | div;
+	} else if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index)) {
+		/*
+		 * Use the LVDS PLL output as the dot clock when outputting to
+		 * the LVDS encoder on an SoC that supports this clock routing
+		 * option. We use the clock directly in that case, without any
+		 * additional divider.
+		 */
+		escr = ESCR_DCLKSEL_DCLKIN;
 	} else {
 		struct du_clk_params params = { .diff = (unsigned long)-1 };
 
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
index fef9ea5c22f3..ebba9aefba6a 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
@@ -53,6 +53,7 @@ struct rcar_du_output_routing {
  * @routes: array of CRTC to output routes, indexed by output (RCAR_DU_OUTPUT_*)
  * @num_lvds: number of internal LVDS encoders
  * @dpll_mask: bit mask of DU channels equipped with a DPLL
+ * @lvds_clk_mask: bitmask of channels that can use the LVDS clock as dot clock
  */
 struct rcar_du_device_info {
 	unsigned int gen;
@@ -62,6 +63,7 @@ struct rcar_du_device_info {
 	struct rcar_du_output_routing routes[RCAR_DU_OUTPUT_MAX];
 	unsigned int num_lvds;
 	unsigned int dpll_mask;
+	unsigned int lvds_clk_mask;
 };
 
 #define RCAR_DU_MAX_CRTCS		4
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c
index ef2c177afb6d..4c62841eff2f 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
@@ -89,6 +89,54 @@ static void rcar_du_group_setup_defr8(struct rcar_du_group *rgrp)
 	rcar_du_group_write(rgrp, DEFR8, defr8);
 }
 
+static void rcar_du_group_setup_didsr(struct rcar_du_group *rgrp)
+{
+	struct rcar_du_device *rcdu = rgrp->dev;
+	struct rcar_du_crtc *rcrtc;
+	unsigned int num_crtcs = 0;
+	unsigned int i;
+	u32 didsr;
+
+	/*
+	 * Configure input dot clock routing with a hardcoded configuration. If
+	 * the DU channel can use the LVDS encoder output clock as the dot
+	 * clock, do so. Otherwise route DU_DOTCLKINn signal to DUn.
+	 *
+	 * Each channel can then select between the dot clock configured here
+	 * and the clock provided by the CPG through the ESCR register.
+	 */
+	if (rcdu->info->gen < 3 && rgrp->index == 0) {
+		/*
+		 * On Gen2 a single register in the first group controls dot
+		 * clock selection for all channels.
+		 */
+		rcrtc = rcdu->crtcs;
+		num_crtcs = rcdu->num_crtcs;
+	} else if (rcdu->info->gen == 3 && rgrp->num_crtcs > 1) {
+		/*
+		 * On Gen3 dot clocks are setup through per-group registers,
+		 * only available when the group has two channels.
+		 */
+		rcrtc = &rcdu->crtcs[rgrp->index * 2];
+		num_crtcs = rgrp->num_crtcs;
+	}
+
+	if (!num_crtcs)
+		return;
+
+	didsr = DIDSR_CODE;
+	for (i = 0; i < num_crtcs; ++i, ++rcrtc) {
+		if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index))
+			didsr |= DIDSR_LCDS_LVDS0(i)
+			      |  DIDSR_PDCS_CLK(i, 0);
+		else
+			didsr |= DIDSR_LCDS_DCLKIN(i)
+			      |  DIDSR_PDCS_CLK(i, 0);
+	}
+
+	rcar_du_group_write(rgrp, DIDSR, didsr);
+}
+
 static void rcar_du_group_setup(struct rcar_du_group *rgrp)
 {
 	struct rcar_du_device *rcdu = rgrp->dev;
@@ -106,21 +154,7 @@ static void rcar_du_group_setup(struct rcar_du_group *rgrp)
 
 	if (rcar_du_has(rgrp->dev, RCAR_DU_FEATURE_EXT_CTRL_REGS)) {
 		rcar_du_group_setup_defr8(rgrp);
-
-		/*
-		 * Configure input dot clock routing. We currently hardcode the
-		 * configuration to routing DOTCLKINn to DUn. Register fields
-		 * depend on the DU generation, but the resulting value is 0 in
-		 * all cases.
-		 *
-		 * On Gen2 a single register in the first group controls dot
-		 * clock selection for all channels, while on Gen3 dot clocks
-		 * 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))
-			rcar_du_group_write(rgrp, DIDSR, DIDSR_CODE);
+		rcar_du_group_setup_didsr(rgrp);
 	}
 
 	if (rcdu->info->gen >= 3)
-- 
Regards,

Laurent Pinchart

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

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

* [PATCH v2 08/16] drm: rcar-du: Enable configurable DPAD0 routing on Gen3
  2018-09-14  9:10 ` Laurent Pinchart
@ 2018-09-14  9:10   ` Laurent Pinchart
  -1 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-14  9:10 UTC (permalink / raw)
  To: dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham

All Gen3 SoCs supported so far have a fixed association between DPAD0
and DU channels, which led to hardcoding that association when writing
the corresponding hardware register. The D3 and E3 will break that
mechanism as DPAD0 can be dynamically connected to either DU0 or DU1.

Make DPAD0 routing dynamic on Gen3. To ensure a valid hardware
configuration when the DU starts without the RGB output enabled, DPAD0
is associated at initialization time to the first DU channel that it can
be connected to. This makes no change on Gen2 as all Gen2 SoCs can
connected DPAD0 to DU0, which is the current implicit default value.

As the DPAD0 source is always 0 when a single source is possible on
Gen2, we can also simplify the Gen2 code in the same function to remove
a conditional check.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
---
 drivers/gpu/drm/rcar-du/rcar_du_group.c | 17 ++++++-----------
 drivers/gpu/drm/rcar-du/rcar_du_kms.c   | 12 ++++++++++++
 2 files changed, 18 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c
index 4c62841eff2f..f38703e7a10d 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
@@ -56,8 +56,6 @@ static void rcar_du_group_setup_pins(struct rcar_du_group *rgrp)
 static void rcar_du_group_setup_defr8(struct rcar_du_group *rgrp)
 {
 	struct rcar_du_device *rcdu = rgrp->dev;
-	unsigned int possible_crtcs =
-		rcdu->info->routes[RCAR_DU_OUTPUT_DPAD0].possible_crtcs;
 	u32 defr8 = DEFR8_CODE;
 
 	if (rcdu->info->gen < 3) {
@@ -69,21 +67,18 @@ static void rcar_du_group_setup_defr8(struct rcar_du_group *rgrp)
 		 * DU instances that support it.
 		 */
 		if (rgrp->index == 0) {
-			if (possible_crtcs > 1)
-				defr8 |= DEFR8_DRGBS_DU(rcdu->dpad0_source);
+			defr8 |= DEFR8_DRGBS_DU(rcdu->dpad0_source);
 			if (rgrp->dev->vspd1_sink == 2)
 				defr8 |= DEFR8_VSCS;
 		}
 	} else {
 		/*
-		 * On Gen3 VSPD routing can't be configured, but DPAD routing
-		 * needs to be set despite having a single option available.
+		 * On Gen3 VSPD routing can't be configured, and DPAD routing
+		 * is set in the group corresponding to the DPAD output (no Gen3
+		 * SoC has multiple DPAD sources belonging to separate groups).
 		 */
-		unsigned int rgb_crtc = ffs(possible_crtcs) - 1;
-		struct rcar_du_crtc *crtc = &rcdu->crtcs[rgb_crtc];
-
-		if (crtc->index / 2 == rgrp->index)
-			defr8 |= DEFR8_DRGBS_DU(crtc->index);
+		if (rgrp->index == rcdu->dpad0_source / 2)
+			defr8 |= DEFR8_DRGBS_DU(rcdu->dpad0_source);
 	}
 
 	rcar_du_group_write(rgrp, DEFR8, defr8);
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
index ed7fa3204892..bd01197700c5 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
@@ -501,6 +501,7 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
 	struct drm_device *dev = rcdu->ddev;
 	struct drm_encoder *encoder;
 	struct drm_fbdev_cma *fbdev;
+	unsigned int dpad0_sources;
 	unsigned int num_encoders;
 	unsigned int num_groups;
 	unsigned int swindex;
@@ -613,6 +614,17 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
 		encoder->possible_clones = (1 << num_encoders) - 1;
 	}
 
+	/*
+	 * Initialize the default DPAD0 source to the index of the first DU
+	 * channel that can be connected to DPAD0. The exact value doesn't
+	 * matter as it should be overwritten by mode setting for the RGB
+	 * output, but it is nonetheless required to ensure a valid initial
+	 * hardware configuration on Gen3 where DU0 can't always be connected to
+	 * DPAD0.
+	 */
+	dpad0_sources = rcdu->info->routes[RCAR_DU_OUTPUT_DPAD0].possible_crtcs;
+	rcdu->dpad0_source = ffs(dpad0_sources) - 1;
+
 	drm_mode_config_reset(dev);
 
 	drm_kms_helper_poll_init(dev);
-- 
Regards,

Laurent Pinchart

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

* [PATCH v2 08/16] drm: rcar-du: Enable configurable DPAD0 routing on Gen3
@ 2018-09-14  9:10   ` Laurent Pinchart
  0 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-14  9:10 UTC (permalink / raw)
  To: dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham

All Gen3 SoCs supported so far have a fixed association between DPAD0
and DU channels, which led to hardcoding that association when writing
the corresponding hardware register. The D3 and E3 will break that
mechanism as DPAD0 can be dynamically connected to either DU0 or DU1.

Make DPAD0 routing dynamic on Gen3. To ensure a valid hardware
configuration when the DU starts without the RGB output enabled, DPAD0
is associated at initialization time to the first DU channel that it can
be connected to. This makes no change on Gen2 as all Gen2 SoCs can
connected DPAD0 to DU0, which is the current implicit default value.

As the DPAD0 source is always 0 when a single source is possible on
Gen2, we can also simplify the Gen2 code in the same function to remove
a conditional check.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
---
 drivers/gpu/drm/rcar-du/rcar_du_group.c | 17 ++++++-----------
 drivers/gpu/drm/rcar-du/rcar_du_kms.c   | 12 ++++++++++++
 2 files changed, 18 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c
index 4c62841eff2f..f38703e7a10d 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
@@ -56,8 +56,6 @@ static void rcar_du_group_setup_pins(struct rcar_du_group *rgrp)
 static void rcar_du_group_setup_defr8(struct rcar_du_group *rgrp)
 {
 	struct rcar_du_device *rcdu = rgrp->dev;
-	unsigned int possible_crtcs =
-		rcdu->info->routes[RCAR_DU_OUTPUT_DPAD0].possible_crtcs;
 	u32 defr8 = DEFR8_CODE;
 
 	if (rcdu->info->gen < 3) {
@@ -69,21 +67,18 @@ static void rcar_du_group_setup_defr8(struct rcar_du_group *rgrp)
 		 * DU instances that support it.
 		 */
 		if (rgrp->index == 0) {
-			if (possible_crtcs > 1)
-				defr8 |= DEFR8_DRGBS_DU(rcdu->dpad0_source);
+			defr8 |= DEFR8_DRGBS_DU(rcdu->dpad0_source);
 			if (rgrp->dev->vspd1_sink == 2)
 				defr8 |= DEFR8_VSCS;
 		}
 	} else {
 		/*
-		 * On Gen3 VSPD routing can't be configured, but DPAD routing
-		 * needs to be set despite having a single option available.
+		 * On Gen3 VSPD routing can't be configured, and DPAD routing
+		 * is set in the group corresponding to the DPAD output (no Gen3
+		 * SoC has multiple DPAD sources belonging to separate groups).
 		 */
-		unsigned int rgb_crtc = ffs(possible_crtcs) - 1;
-		struct rcar_du_crtc *crtc = &rcdu->crtcs[rgb_crtc];
-
-		if (crtc->index / 2 == rgrp->index)
-			defr8 |= DEFR8_DRGBS_DU(crtc->index);
+		if (rgrp->index == rcdu->dpad0_source / 2)
+			defr8 |= DEFR8_DRGBS_DU(rcdu->dpad0_source);
 	}
 
 	rcar_du_group_write(rgrp, DEFR8, defr8);
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
index ed7fa3204892..bd01197700c5 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
@@ -501,6 +501,7 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
 	struct drm_device *dev = rcdu->ddev;
 	struct drm_encoder *encoder;
 	struct drm_fbdev_cma *fbdev;
+	unsigned int dpad0_sources;
 	unsigned int num_encoders;
 	unsigned int num_groups;
 	unsigned int swindex;
@@ -613,6 +614,17 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
 		encoder->possible_clones = (1 << num_encoders) - 1;
 	}
 
+	/*
+	 * Initialize the default DPAD0 source to the index of the first DU
+	 * channel that can be connected to DPAD0. The exact value doesn't
+	 * matter as it should be overwritten by mode setting for the RGB
+	 * output, but it is nonetheless required to ensure a valid initial
+	 * hardware configuration on Gen3 where DU0 can't always be connected to
+	 * DPAD0.
+	 */
+	dpad0_sources = rcdu->info->routes[RCAR_DU_OUTPUT_DPAD0].possible_crtcs;
+	rcdu->dpad0_source = ffs(dpad0_sources) - 1;
+
 	drm_mode_config_reset(dev);
 
 	drm_kms_helper_poll_init(dev);
-- 
Regards,

Laurent Pinchart

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

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

* [PATCH v2 09/16] drm: rcar-du: Cache DSYSR value to ensure known initial value
  2018-09-14  9:10 ` Laurent Pinchart
@ 2018-09-14  9:10   ` Laurent Pinchart
  -1 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-14  9:10 UTC (permalink / raw)
  To: dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham

DSYSR is a DU channel register that also contains group fields. It is
thus written to by both the group and CRTC code, using read-update-write
sequences. As the register isn't initialized explicitly at startup time,
this can lead to invalid or otherwise unexpected values being written to
some of the fields if they have been modified by the firmware or just
not reset properly.

To fix this we can write a fully known value to the DSYSR register when
turning a channel's functional clock on. However, the mix of group and
channel fields complicate this. A simpler solution is to cache the
register and initialize the cached value to the desired hardware
defaults.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
---
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c  | 16 ++++++++--------
 drivers/gpu/drm/rcar-du/rcar_du_crtc.h  |  5 +++++
 drivers/gpu/drm/rcar-du/rcar_du_group.c |  7 ++++---
 3 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index 2f8776c1ec8f..f827fccf6416 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -57,13 +57,12 @@ static void rcar_du_crtc_set(struct rcar_du_crtc *rcrtc, u32 reg, u32 set)
 		      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)
+void rcar_du_crtc_dsysr_clr_set(struct rcar_du_crtc *rcrtc, u32 clr, u32 set)
 {
 	struct rcar_du_device *rcdu = rcrtc->group->dev;
-	u32 value = rcar_du_read(rcdu, rcrtc->mmio_offset + reg);
 
-	rcar_du_write(rcdu, rcrtc->mmio_offset + reg, (value & ~clr) | set);
+	rcrtc->dsysr = (rcrtc->dsysr & ~clr) | set;
+	rcar_du_write(rcdu, rcrtc->mmio_offset + DSYSR, rcrtc->dsysr);
 }
 
 /* -----------------------------------------------------------------------------
@@ -576,9 +575,9 @@ 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,
-			     (interlaced ? DSYSR_SCM_INT_VIDEO : 0) |
-			     DSYSR_TVM_MASTER);
+	rcar_du_crtc_dsysr_clr_set(rcrtc, DSYSR_TVM_MASK | DSYSR_SCM_MASK,
+				   (interlaced ? DSYSR_SCM_INT_VIDEO : 0) |
+				   DSYSR_TVM_MASTER);
 
 	rcar_du_group_start_stop(rcrtc->group, true);
 }
@@ -645,7 +644,7 @@ 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_dsysr_clr_set(rcrtc, DSYSR_TVM_MASK, DSYSR_TVM_SWITCH);
 
 	rcar_du_group_start_stop(rcrtc->group, false);
 }
@@ -1121,6 +1120,7 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int swindex,
 	rcrtc->group = rgrp;
 	rcrtc->mmio_offset = mmio_offsets[hwindex];
 	rcrtc->index = hwindex;
+	rcrtc->dsysr = (rcrtc->index % 2 ? 0 : DSYSR_DRES) | DSYSR_TVM_TVSYNC;
 
 	if (rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE))
 		primary = &rcrtc->vsp->planes[rcrtc->vsp_pipe].plane;
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
index 4990bbe9ba26..59ac6e7d22c9 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
@@ -30,6 +30,7 @@ struct rcar_du_vsp;
  * @mmio_offset: offset of the CRTC registers in the DU MMIO block
  * @index: CRTC software and hardware index
  * @initialized: whether the CRTC has been initialized and clocks enabled
+ * @dsysr: cached value of the DSYSR register
  * @vblank_enable: whether vblank events are enabled on this CRTC
  * @event: event to post when the pending page flip completes
  * @flip_wait: wait queue used to signal page flip completion
@@ -50,6 +51,8 @@ struct rcar_du_crtc {
 	unsigned int index;
 	bool initialized;
 
+	u32 dsysr;
+
 	bool vblank_enable;
 	struct drm_pending_vblank_event *event;
 	wait_queue_head_t flip_wait;
@@ -103,4 +106,6 @@ void rcar_du_crtc_route_output(struct drm_crtc *crtc,
 			       enum rcar_du_output output);
 void rcar_du_crtc_finish_page_flip(struct rcar_du_crtc *rcrtc);
 
+void rcar_du_crtc_dsysr_clr_set(struct rcar_du_crtc *rcrtc, u32 clr, u32 set);
+
 #endif /* __RCAR_DU_CRTC_H__ */
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c
index f38703e7a10d..d85f0a1c1581 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
@@ -202,9 +202,10 @@ 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)) |
-		(start ? DSYSR_DEN : DSYSR_DRES));
+	struct rcar_du_crtc *rcrtc = &rgrp->dev->crtcs[rgrp->index * 2];
+
+	rcar_du_crtc_dsysr_clr_set(rcrtc, DSYSR_DRES | DSYSR_DEN,
+				   start ? DSYSR_DEN : DSYSR_DRES);
 }
 
 void rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool start)
-- 
Regards,

Laurent Pinchart

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

* [PATCH v2 09/16] drm: rcar-du: Cache DSYSR value to ensure known initial value
@ 2018-09-14  9:10   ` Laurent Pinchart
  0 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-14  9:10 UTC (permalink / raw)
  To: dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham

DSYSR is a DU channel register that also contains group fields. It is
thus written to by both the group and CRTC code, using read-update-write
sequences. As the register isn't initialized explicitly at startup time,
this can lead to invalid or otherwise unexpected values being written to
some of the fields if they have been modified by the firmware or just
not reset properly.

To fix this we can write a fully known value to the DSYSR register when
turning a channel's functional clock on. However, the mix of group and
channel fields complicate this. A simpler solution is to cache the
register and initialize the cached value to the desired hardware
defaults.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
---
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c  | 16 ++++++++--------
 drivers/gpu/drm/rcar-du/rcar_du_crtc.h  |  5 +++++
 drivers/gpu/drm/rcar-du/rcar_du_group.c |  7 ++++---
 3 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index 2f8776c1ec8f..f827fccf6416 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -57,13 +57,12 @@ static void rcar_du_crtc_set(struct rcar_du_crtc *rcrtc, u32 reg, u32 set)
 		      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)
+void rcar_du_crtc_dsysr_clr_set(struct rcar_du_crtc *rcrtc, u32 clr, u32 set)
 {
 	struct rcar_du_device *rcdu = rcrtc->group->dev;
-	u32 value = rcar_du_read(rcdu, rcrtc->mmio_offset + reg);
 
-	rcar_du_write(rcdu, rcrtc->mmio_offset + reg, (value & ~clr) | set);
+	rcrtc->dsysr = (rcrtc->dsysr & ~clr) | set;
+	rcar_du_write(rcdu, rcrtc->mmio_offset + DSYSR, rcrtc->dsysr);
 }
 
 /* -----------------------------------------------------------------------------
@@ -576,9 +575,9 @@ 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,
-			     (interlaced ? DSYSR_SCM_INT_VIDEO : 0) |
-			     DSYSR_TVM_MASTER);
+	rcar_du_crtc_dsysr_clr_set(rcrtc, DSYSR_TVM_MASK | DSYSR_SCM_MASK,
+				   (interlaced ? DSYSR_SCM_INT_VIDEO : 0) |
+				   DSYSR_TVM_MASTER);
 
 	rcar_du_group_start_stop(rcrtc->group, true);
 }
@@ -645,7 +644,7 @@ 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_dsysr_clr_set(rcrtc, DSYSR_TVM_MASK, DSYSR_TVM_SWITCH);
 
 	rcar_du_group_start_stop(rcrtc->group, false);
 }
@@ -1121,6 +1120,7 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int swindex,
 	rcrtc->group = rgrp;
 	rcrtc->mmio_offset = mmio_offsets[hwindex];
 	rcrtc->index = hwindex;
+	rcrtc->dsysr = (rcrtc->index % 2 ? 0 : DSYSR_DRES) | DSYSR_TVM_TVSYNC;
 
 	if (rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE))
 		primary = &rcrtc->vsp->planes[rcrtc->vsp_pipe].plane;
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
index 4990bbe9ba26..59ac6e7d22c9 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
@@ -30,6 +30,7 @@ struct rcar_du_vsp;
  * @mmio_offset: offset of the CRTC registers in the DU MMIO block
  * @index: CRTC software and hardware index
  * @initialized: whether the CRTC has been initialized and clocks enabled
+ * @dsysr: cached value of the DSYSR register
  * @vblank_enable: whether vblank events are enabled on this CRTC
  * @event: event to post when the pending page flip completes
  * @flip_wait: wait queue used to signal page flip completion
@@ -50,6 +51,8 @@ struct rcar_du_crtc {
 	unsigned int index;
 	bool initialized;
 
+	u32 dsysr;
+
 	bool vblank_enable;
 	struct drm_pending_vblank_event *event;
 	wait_queue_head_t flip_wait;
@@ -103,4 +106,6 @@ void rcar_du_crtc_route_output(struct drm_crtc *crtc,
 			       enum rcar_du_output output);
 void rcar_du_crtc_finish_page_flip(struct rcar_du_crtc *rcrtc);
 
+void rcar_du_crtc_dsysr_clr_set(struct rcar_du_crtc *rcrtc, u32 clr, u32 set);
+
 #endif /* __RCAR_DU_CRTC_H__ */
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c
index f38703e7a10d..d85f0a1c1581 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
@@ -202,9 +202,10 @@ 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)) |
-		(start ? DSYSR_DEN : DSYSR_DRES));
+	struct rcar_du_crtc *rcrtc = &rgrp->dev->crtcs[rgrp->index * 2];
+
+	rcar_du_crtc_dsysr_clr_set(rcrtc, DSYSR_DRES | DSYSR_DEN,
+				   start ? DSYSR_DEN : DSYSR_DRES);
 }
 
 void rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool start)
-- 
Regards,

Laurent Pinchart

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

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

* [PATCH v2 10/16] drm: rcar-du: Don't use TV sync mode when not supported by the hardware
  2018-09-14  9:10 ` Laurent Pinchart
@ 2018-09-14  9:10   ` Laurent Pinchart
  -1 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-14  9:10 UTC (permalink / raw)
  To: dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham

The official way to stop the display is to clear the display enable
(DEN) bit in the DSYSR register, but that operates at a group level and
affects the two channels in the group. To disable channels selectively,
the driver uses TV sync mode that stops display operation on the channel
and turns output signals into inputs.

While TV sync mode is available in all DU models currently supported,
the D3 and E3 DUs don't support it. We will thus need to find an
alternative way to turn channels off.

In the meantime, condition the switch to TV sync mode to the
availability of the feature, to avoid writing an invalid value to the
DSYSR register. The display output will turn blank as all planes are
disabled when stopping the CRTC.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
---
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c |  7 ++++++-
 drivers/gpu/drm/rcar-du/rcar_du_drv.c  | 33 ++++++++++++++++++++++-----------
 drivers/gpu/drm/rcar-du/rcar_du_drv.h  |  1 +
 3 files changed, 29 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 f827fccf6416..17741843cf51 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -643,8 +643,13 @@ 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.
+	 *
+	 * TODO: Find another way to stop the display for DUs that don't support
+	 * TVM sync.
 	 */
-	rcar_du_crtc_dsysr_clr_set(rcrtc, DSYSR_TVM_MASK, DSYSR_TVM_SWITCH);
+	if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_TVM_SYNC))
+		rcar_du_crtc_dsysr_clr_set(rcrtc, DSYSR_TVM_MASK,
+					   DSYSR_TVM_SWITCH);
 
 	rcar_du_group_start_stop(rcrtc->group, false);
 }
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
index 0954ecd2f943..fa0d381c2d0f 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
@@ -36,7 +36,8 @@ static const struct rcar_du_device_info rzg1_du_r8a7743_info = {
 	.gen = 2,
 	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
 		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
-		  | RCAR_DU_FEATURE_INTERLACED,
+		  | RCAR_DU_FEATURE_INTERLACED
+		  | RCAR_DU_FEATURE_TVM_SYNC,
 	.channels_mask = BIT(1) | BIT(0),
 	.routes = {
 		/*
@@ -58,7 +59,8 @@ static const struct rcar_du_device_info rzg1_du_r8a7745_info = {
 	.gen = 2,
 	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
 		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
-		  | RCAR_DU_FEATURE_INTERLACED,
+		  | RCAR_DU_FEATURE_INTERLACED
+		  | RCAR_DU_FEATURE_TVM_SYNC,
 	.channels_mask = BIT(1) | BIT(0),
 	.routes = {
 		/*
@@ -77,7 +79,8 @@ static const struct rcar_du_device_info rzg1_du_r8a7745_info = {
 
 static const struct rcar_du_device_info rcar_du_r8a7779_info = {
 	.gen = 2,
-	.features = RCAR_DU_FEATURE_INTERLACED,
+	.features = RCAR_DU_FEATURE_INTERLACED
+		  | RCAR_DU_FEATURE_TVM_SYNC,
 	.channels_mask = BIT(1) | BIT(0),
 	.routes = {
 		/*
@@ -99,7 +102,8 @@ static const struct rcar_du_device_info rcar_du_r8a7790_info = {
 	.gen = 2,
 	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
 		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
-		  | RCAR_DU_FEATURE_INTERLACED,
+		  | RCAR_DU_FEATURE_INTERLACED
+		  | RCAR_DU_FEATURE_TVM_SYNC,
 	.quirks = RCAR_DU_QUIRK_ALIGN_128B,
 	.channels_mask = BIT(2) | BIT(1) | BIT(0),
 	.routes = {
@@ -128,7 +132,8 @@ static const struct rcar_du_device_info rcar_du_r8a7791_info = {
 	.gen = 2,
 	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
 		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
-		  | RCAR_DU_FEATURE_INTERLACED,
+		  | RCAR_DU_FEATURE_INTERLACED
+		  | RCAR_DU_FEATURE_TVM_SYNC,
 	.channels_mask = BIT(1) | BIT(0),
 	.routes = {
 		/*
@@ -151,7 +156,8 @@ static const struct rcar_du_device_info rcar_du_r8a7792_info = {
 	.gen = 2,
 	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
 		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
-		  | RCAR_DU_FEATURE_INTERLACED,
+		  | RCAR_DU_FEATURE_INTERLACED
+		  | RCAR_DU_FEATURE_TVM_SYNC,
 	.channels_mask = BIT(1) | BIT(0),
 	.routes = {
 		/* R8A7792 has two RGB outputs. */
@@ -170,7 +176,8 @@ static const struct rcar_du_device_info rcar_du_r8a7794_info = {
 	.gen = 2,
 	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
 		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
-		  | RCAR_DU_FEATURE_INTERLACED,
+		  | RCAR_DU_FEATURE_INTERLACED
+		  | RCAR_DU_FEATURE_TVM_SYNC,
 	.channels_mask = BIT(1) | BIT(0),
 	.routes = {
 		/*
@@ -193,7 +200,8 @@ static const struct rcar_du_device_info rcar_du_r8a7795_info = {
 	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
 		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
 		  | RCAR_DU_FEATURE_VSP1_SOURCE
-		  | RCAR_DU_FEATURE_INTERLACED,
+		  | RCAR_DU_FEATURE_INTERLACED
+		  | RCAR_DU_FEATURE_TVM_SYNC,
 	.channels_mask = BIT(3) | BIT(2) | BIT(1) | BIT(0),
 	.routes = {
 		/*
@@ -226,7 +234,8 @@ static const struct rcar_du_device_info rcar_du_r8a7796_info = {
 	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
 		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
 		  | RCAR_DU_FEATURE_VSP1_SOURCE
-		  | RCAR_DU_FEATURE_INTERLACED,
+		  | RCAR_DU_FEATURE_INTERLACED
+		  | RCAR_DU_FEATURE_TVM_SYNC,
 	.channels_mask = BIT(2) | BIT(1) | BIT(0),
 	.routes = {
 		/*
@@ -255,7 +264,8 @@ static const struct rcar_du_device_info rcar_du_r8a77965_info = {
 	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
 		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
 		  | RCAR_DU_FEATURE_VSP1_SOURCE
-		  | RCAR_DU_FEATURE_INTERLACED,
+		  | RCAR_DU_FEATURE_INTERLACED
+		  | RCAR_DU_FEATURE_TVM_SYNC,
 	.channels_mask = BIT(3) | BIT(1) | BIT(0),
 	.routes = {
 		/*
@@ -284,7 +294,8 @@ static const struct rcar_du_device_info rcar_du_r8a77970_info = {
 	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
 		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
 		  | RCAR_DU_FEATURE_VSP1_SOURCE
-		  | RCAR_DU_FEATURE_INTERLACED,
+		  | RCAR_DU_FEATURE_INTERLACED
+		  | RCAR_DU_FEATURE_TVM_SYNC,
 	.channels_mask = BIT(0),
 	.routes = {
 		/* R8A77970 has one RGB output and one LVDS output. */
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
index ebba9aefba6a..143c037e2c0f 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
@@ -27,6 +27,7 @@ struct rcar_du_device;
 #define RCAR_DU_FEATURE_EXT_CTRL_REGS	BIT(1)	/* Has extended control registers */
 #define RCAR_DU_FEATURE_VSP1_SOURCE	BIT(2)	/* Has inputs from VSP1 */
 #define RCAR_DU_FEATURE_INTERLACED	BIT(3)	/* HW supports interlaced */
+#define RCAR_DU_FEATURE_TVM_SYNC	BIT(4)	/* Has TV switch/sync modes */
 
 #define RCAR_DU_QUIRK_ALIGN_128B	BIT(0)	/* Align pitches to 128 bytes */
 
-- 
Regards,

Laurent Pinchart

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

* [PATCH v2 10/16] drm: rcar-du: Don't use TV sync mode when not supported by the hardware
@ 2018-09-14  9:10   ` Laurent Pinchart
  0 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-14  9:10 UTC (permalink / raw)
  To: dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham

The official way to stop the display is to clear the display enable
(DEN) bit in the DSYSR register, but that operates at a group level and
affects the two channels in the group. To disable channels selectively,
the driver uses TV sync mode that stops display operation on the channel
and turns output signals into inputs.

While TV sync mode is available in all DU models currently supported,
the D3 and E3 DUs don't support it. We will thus need to find an
alternative way to turn channels off.

In the meantime, condition the switch to TV sync mode to the
availability of the feature, to avoid writing an invalid value to the
DSYSR register. The display output will turn blank as all planes are
disabled when stopping the CRTC.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
---
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c |  7 ++++++-
 drivers/gpu/drm/rcar-du/rcar_du_drv.c  | 33 ++++++++++++++++++++++-----------
 drivers/gpu/drm/rcar-du/rcar_du_drv.h  |  1 +
 3 files changed, 29 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 f827fccf6416..17741843cf51 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -643,8 +643,13 @@ 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.
+	 *
+	 * TODO: Find another way to stop the display for DUs that don't support
+	 * TVM sync.
 	 */
-	rcar_du_crtc_dsysr_clr_set(rcrtc, DSYSR_TVM_MASK, DSYSR_TVM_SWITCH);
+	if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_TVM_SYNC))
+		rcar_du_crtc_dsysr_clr_set(rcrtc, DSYSR_TVM_MASK,
+					   DSYSR_TVM_SWITCH);
 
 	rcar_du_group_start_stop(rcrtc->group, false);
 }
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
index 0954ecd2f943..fa0d381c2d0f 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
@@ -36,7 +36,8 @@ static const struct rcar_du_device_info rzg1_du_r8a7743_info = {
 	.gen = 2,
 	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
 		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
-		  | RCAR_DU_FEATURE_INTERLACED,
+		  | RCAR_DU_FEATURE_INTERLACED
+		  | RCAR_DU_FEATURE_TVM_SYNC,
 	.channels_mask = BIT(1) | BIT(0),
 	.routes = {
 		/*
@@ -58,7 +59,8 @@ static const struct rcar_du_device_info rzg1_du_r8a7745_info = {
 	.gen = 2,
 	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
 		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
-		  | RCAR_DU_FEATURE_INTERLACED,
+		  | RCAR_DU_FEATURE_INTERLACED
+		  | RCAR_DU_FEATURE_TVM_SYNC,
 	.channels_mask = BIT(1) | BIT(0),
 	.routes = {
 		/*
@@ -77,7 +79,8 @@ static const struct rcar_du_device_info rzg1_du_r8a7745_info = {
 
 static const struct rcar_du_device_info rcar_du_r8a7779_info = {
 	.gen = 2,
-	.features = RCAR_DU_FEATURE_INTERLACED,
+	.features = RCAR_DU_FEATURE_INTERLACED
+		  | RCAR_DU_FEATURE_TVM_SYNC,
 	.channels_mask = BIT(1) | BIT(0),
 	.routes = {
 		/*
@@ -99,7 +102,8 @@ static const struct rcar_du_device_info rcar_du_r8a7790_info = {
 	.gen = 2,
 	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
 		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
-		  | RCAR_DU_FEATURE_INTERLACED,
+		  | RCAR_DU_FEATURE_INTERLACED
+		  | RCAR_DU_FEATURE_TVM_SYNC,
 	.quirks = RCAR_DU_QUIRK_ALIGN_128B,
 	.channels_mask = BIT(2) | BIT(1) | BIT(0),
 	.routes = {
@@ -128,7 +132,8 @@ static const struct rcar_du_device_info rcar_du_r8a7791_info = {
 	.gen = 2,
 	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
 		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
-		  | RCAR_DU_FEATURE_INTERLACED,
+		  | RCAR_DU_FEATURE_INTERLACED
+		  | RCAR_DU_FEATURE_TVM_SYNC,
 	.channels_mask = BIT(1) | BIT(0),
 	.routes = {
 		/*
@@ -151,7 +156,8 @@ static const struct rcar_du_device_info rcar_du_r8a7792_info = {
 	.gen = 2,
 	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
 		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
-		  | RCAR_DU_FEATURE_INTERLACED,
+		  | RCAR_DU_FEATURE_INTERLACED
+		  | RCAR_DU_FEATURE_TVM_SYNC,
 	.channels_mask = BIT(1) | BIT(0),
 	.routes = {
 		/* R8A7792 has two RGB outputs. */
@@ -170,7 +176,8 @@ static const struct rcar_du_device_info rcar_du_r8a7794_info = {
 	.gen = 2,
 	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
 		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
-		  | RCAR_DU_FEATURE_INTERLACED,
+		  | RCAR_DU_FEATURE_INTERLACED
+		  | RCAR_DU_FEATURE_TVM_SYNC,
 	.channels_mask = BIT(1) | BIT(0),
 	.routes = {
 		/*
@@ -193,7 +200,8 @@ static const struct rcar_du_device_info rcar_du_r8a7795_info = {
 	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
 		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
 		  | RCAR_DU_FEATURE_VSP1_SOURCE
-		  | RCAR_DU_FEATURE_INTERLACED,
+		  | RCAR_DU_FEATURE_INTERLACED
+		  | RCAR_DU_FEATURE_TVM_SYNC,
 	.channels_mask = BIT(3) | BIT(2) | BIT(1) | BIT(0),
 	.routes = {
 		/*
@@ -226,7 +234,8 @@ static const struct rcar_du_device_info rcar_du_r8a7796_info = {
 	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
 		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
 		  | RCAR_DU_FEATURE_VSP1_SOURCE
-		  | RCAR_DU_FEATURE_INTERLACED,
+		  | RCAR_DU_FEATURE_INTERLACED
+		  | RCAR_DU_FEATURE_TVM_SYNC,
 	.channels_mask = BIT(2) | BIT(1) | BIT(0),
 	.routes = {
 		/*
@@ -255,7 +264,8 @@ static const struct rcar_du_device_info rcar_du_r8a77965_info = {
 	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
 		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
 		  | RCAR_DU_FEATURE_VSP1_SOURCE
-		  | RCAR_DU_FEATURE_INTERLACED,
+		  | RCAR_DU_FEATURE_INTERLACED
+		  | RCAR_DU_FEATURE_TVM_SYNC,
 	.channels_mask = BIT(3) | BIT(1) | BIT(0),
 	.routes = {
 		/*
@@ -284,7 +294,8 @@ static const struct rcar_du_device_info rcar_du_r8a77970_info = {
 	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
 		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
 		  | RCAR_DU_FEATURE_VSP1_SOURCE
-		  | RCAR_DU_FEATURE_INTERLACED,
+		  | RCAR_DU_FEATURE_INTERLACED
+		  | RCAR_DU_FEATURE_TVM_SYNC,
 	.channels_mask = BIT(0),
 	.routes = {
 		/* R8A77970 has one RGB output and one LVDS output. */
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
index ebba9aefba6a..143c037e2c0f 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
@@ -27,6 +27,7 @@ struct rcar_du_device;
 #define RCAR_DU_FEATURE_EXT_CTRL_REGS	BIT(1)	/* Has extended control registers */
 #define RCAR_DU_FEATURE_VSP1_SOURCE	BIT(2)	/* Has inputs from VSP1 */
 #define RCAR_DU_FEATURE_INTERLACED	BIT(3)	/* HW supports interlaced */
+#define RCAR_DU_FEATURE_TVM_SYNC	BIT(4)	/* Has TV switch/sync modes */
 
 #define RCAR_DU_QUIRK_ALIGN_128B	BIT(0)	/* Align pitches to 128 bytes */
 
-- 
Regards,

Laurent Pinchart

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

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

* [PATCH v2 11/16] drm: rcar-du: Add r8a77990 and r8a77995 device support
  2018-09-14  9:10 ` Laurent Pinchart
@ 2018-09-14  9:10   ` Laurent Pinchart
  -1 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-14  9:10 UTC (permalink / raw)
  To: dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham

From: Ulrich Hecht <uli+renesas@fpond.eu>

Add support for the R-Car D3 (R8A77995) and E3 (R8A77990) SoCs to the
R-Car DU driver. The two SoCs instantiate compatible DUs, so a single
information structure is enough.

Signed-off-by: Ulrich Hecht <uli+renesas@fpond.eu>
[Add support for R8A77990]
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
---
 drivers/gpu/drm/rcar-du/rcar_du_drv.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
index fa0d381c2d0f..084f58df4a8c 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
@@ -311,6 +311,34 @@ static const struct rcar_du_device_info rcar_du_r8a77970_info = {
 	.num_lvds = 1,
 };
 
+static const struct rcar_du_device_info rcar_du_r8a7799x_info = {
+	.gen = 3,
+	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
+		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
+		  | RCAR_DU_FEATURE_VSP1_SOURCE,
+	.channels_mask = BIT(1) | BIT(0),
+	.routes = {
+		/*
+		 * R8A77990 and R8A77995 have one RGB output and two LVDS
+		 * outputs.
+		 */
+		[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,
+	.lvds_clk_mask =  BIT(1) | BIT(0),
+};
+
 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 },
@@ -324,6 +352,8 @@ 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-r8a77990", .data = &rcar_du_r8a7799x_info },
+	{ .compatible = "renesas,du-r8a77995", .data = &rcar_du_r8a7799x_info },
 	{ }
 };
 
-- 
Regards,

Laurent Pinchart

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

* [PATCH v2 11/16] drm: rcar-du: Add r8a77990 and r8a77995 device support
@ 2018-09-14  9:10   ` Laurent Pinchart
  0 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-14  9:10 UTC (permalink / raw)
  To: dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham

From: Ulrich Hecht <uli+renesas@fpond.eu>

Add support for the R-Car D3 (R8A77995) and E3 (R8A77990) SoCs to the
R-Car DU driver. The two SoCs instantiate compatible DUs, so a single
information structure is enough.

Signed-off-by: Ulrich Hecht <uli+renesas@fpond.eu>
[Add support for R8A77990]
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
---
 drivers/gpu/drm/rcar-du/rcar_du_drv.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
index fa0d381c2d0f..084f58df4a8c 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
@@ -311,6 +311,34 @@ static const struct rcar_du_device_info rcar_du_r8a77970_info = {
 	.num_lvds = 1,
 };
 
+static const struct rcar_du_device_info rcar_du_r8a7799x_info = {
+	.gen = 3,
+	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
+		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
+		  | RCAR_DU_FEATURE_VSP1_SOURCE,
+	.channels_mask = BIT(1) | BIT(0),
+	.routes = {
+		/*
+		 * R8A77990 and R8A77995 have one RGB output and two LVDS
+		 * outputs.
+		 */
+		[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,
+	.lvds_clk_mask =  BIT(1) | BIT(0),
+};
+
 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 },
@@ -324,6 +352,8 @@ 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-r8a77990", .data = &rcar_du_r8a7799x_info },
+	{ .compatible = "renesas,du-r8a77995", .data = &rcar_du_r8a7799x_info },
 	{ }
 };
 
-- 
Regards,

Laurent Pinchart

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

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

* [PATCH v2 12/16] arm64: dts: renesas: r8a77990: Add I2C device nodes
  2018-09-14  9:10 ` Laurent Pinchart
@ 2018-09-14  9:10   ` Laurent Pinchart
  -1 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-14  9:10 UTC (permalink / raw)
  To: dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham

From: Takeshi Kihara <takeshi.kihara.df@renesas.com>

Add device nodes for I2C ch{0,1,2,3,4,5,6,7} to R-Car E3 R8A77990 device
tree.

Signed-off-by: Takeshi Kihara <takeshi.kihara.df@renesas.com>
Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
---
 arch/arm64/boot/dts/renesas/r8a77990.dtsi | 123 ++++++++++++++++++++++++++++++
 1 file changed, 123 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
index ae89260baad9..abb14af76c0e 100644
--- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
@@ -14,6 +14,17 @@
 	#address-cells = <2>;
 	#size-cells = <2>;
 
+	aliases {
+		i2c0 = &i2c0;
+		i2c1 = &i2c1;
+		i2c2 = &i2c2;
+		i2c3 = &i2c3;
+		i2c4 = &i2c4;
+		i2c5 = &i2c5;
+		i2c6 = &i2c6;
+		i2c7 = &i2c7;
+	};
+
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -185,6 +196,118 @@
 			resets = <&cpg 906>;
 		};
 
+		i2c0: i2c@e6500000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a77990",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe6500000 0 0x40>;
+			interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 931>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			resets = <&cpg 931>;
+			i2c-scl-internal-delay-ns = <110>;
+			status = "disabled";
+		};
+
+		i2c1: i2c@e6508000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a77990",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe6508000 0 0x40>;
+			interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 930>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			resets = <&cpg 930>;
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
+		i2c2: i2c@e6510000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a77990",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe6510000 0 0x40>;
+			interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 929>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			resets = <&cpg 929>;
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
+		i2c3: i2c@e66d0000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a77990",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe66d0000 0 0x40>;
+			interrupts = <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 928>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			resets = <&cpg 928>;
+			i2c-scl-internal-delay-ns = <110>;
+			status = "disabled";
+		};
+
+		i2c4: i2c@e66d8000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a77990",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe66d8000 0 0x40>;
+			interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 927>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			resets = <&cpg 927>;
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
+		i2c5: i2c@e66e0000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a77990",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe66e0000 0 0x40>;
+			interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 919>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			resets = <&cpg 919>;
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
+		i2c6: i2c@e66e8000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a77990",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe66e8000 0 0x40>;
+			interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 918>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			resets = <&cpg 918>;
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
+		i2c7: i2c@e6690000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a77990",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe6690000 0 0x40>;
+			interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 1003>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			resets = <&cpg 1003>;
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
 		pfc: pin-controller@e6060000 {
 			compatible = "renesas,pfc-r8a77990";
 			reg = <0 0xe6060000 0 0x508>;
-- 
Regards,

Laurent Pinchart

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

* [PATCH v2 12/16] arm64: dts: renesas: r8a77990: Add I2C device nodes
@ 2018-09-14  9:10   ` Laurent Pinchart
  0 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-14  9:10 UTC (permalink / raw)
  To: dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham

From: Takeshi Kihara <takeshi.kihara.df@renesas.com>

Add device nodes for I2C ch{0,1,2,3,4,5,6,7} to R-Car E3 R8A77990 device
tree.

Signed-off-by: Takeshi Kihara <takeshi.kihara.df@renesas.com>
Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
---
 arch/arm64/boot/dts/renesas/r8a77990.dtsi | 123 ++++++++++++++++++++++++++++++
 1 file changed, 123 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
index ae89260baad9..abb14af76c0e 100644
--- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
@@ -14,6 +14,17 @@
 	#address-cells = <2>;
 	#size-cells = <2>;
 
+	aliases {
+		i2c0 = &i2c0;
+		i2c1 = &i2c1;
+		i2c2 = &i2c2;
+		i2c3 = &i2c3;
+		i2c4 = &i2c4;
+		i2c5 = &i2c5;
+		i2c6 = &i2c6;
+		i2c7 = &i2c7;
+	};
+
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -185,6 +196,118 @@
 			resets = <&cpg 906>;
 		};
 
+		i2c0: i2c@e6500000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a77990",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe6500000 0 0x40>;
+			interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 931>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			resets = <&cpg 931>;
+			i2c-scl-internal-delay-ns = <110>;
+			status = "disabled";
+		};
+
+		i2c1: i2c@e6508000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a77990",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe6508000 0 0x40>;
+			interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 930>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			resets = <&cpg 930>;
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
+		i2c2: i2c@e6510000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a77990",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe6510000 0 0x40>;
+			interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 929>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			resets = <&cpg 929>;
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
+		i2c3: i2c@e66d0000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a77990",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe66d0000 0 0x40>;
+			interrupts = <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 928>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			resets = <&cpg 928>;
+			i2c-scl-internal-delay-ns = <110>;
+			status = "disabled";
+		};
+
+		i2c4: i2c@e66d8000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a77990",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe66d8000 0 0x40>;
+			interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 927>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			resets = <&cpg 927>;
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
+		i2c5: i2c@e66e0000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a77990",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe66e0000 0 0x40>;
+			interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 919>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			resets = <&cpg 919>;
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
+		i2c6: i2c@e66e8000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a77990",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe66e8000 0 0x40>;
+			interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 918>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			resets = <&cpg 918>;
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
+		i2c7: i2c@e6690000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a77990",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe6690000 0 0x40>;
+			interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 1003>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			resets = <&cpg 1003>;
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
 		pfc: pin-controller@e6060000 {
 			compatible = "renesas,pfc-r8a77990";
 			reg = <0 0xe6060000 0 0x508>;
-- 
Regards,

Laurent Pinchart

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

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

* [PATCH v2 13/16] arm64: dts: renesas: r8a77990: Add display output support
  2018-09-14  9:10 ` Laurent Pinchart
@ 2018-09-14  9:10   ` Laurent Pinchart
  -1 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-14  9:10 UTC (permalink / raw)
  To: dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham

The R8A77990 (E3) platform has one RGB output and two LVDS outputs
connected to the DU. Add the DT nodes for the DU, LVDS encoders and
supporting VSP and FCP.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
---
 arch/arm64/boot/dts/renesas/r8a77990.dtsi | 167 ++++++++++++++++++++++++++++++
 1 file changed, 167 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
index abb14af76c0e..600074ca3ee5 100644
--- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
@@ -537,6 +537,173 @@
 			resets = <&cpg 408>;
 		};
 
+		vspb0: vsp@fe960000 {
+			compatible = "renesas,vsp2";
+			reg = <0 0xfe960000 0 0x8000>;
+			interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 626>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			resets = <&cpg 626>;
+			renesas,fcp = <&fcpvb0>;
+		};
+
+		fcpvb0: fcp@fe96f000 {
+			compatible = "renesas,fcpv";
+			reg = <0 0xfe96f000 0 0x200>;
+			clocks = <&cpg CPG_MOD 607>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			resets = <&cpg 607>;
+			iommus = <&ipmmu_vp0 5>;
+		};
+
+		vspi0: vsp@fe9a0000 {
+			compatible = "renesas,vsp2";
+			reg = <0 0xfe9a0000 0 0x8000>;
+			interrupts = <GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 622>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			resets = <&cpg 631>;
+			renesas,fcp = <&fcpvi0>;
+		};
+
+		fcpvi0: fcp@fe9af000 {
+			compatible = "renesas,fcpv";
+			reg = <0 0xfe9af000 0 0x200>;
+			clocks = <&cpg CPG_MOD 611>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			resets = <&cpg 611>;
+			iommus = <&ipmmu_vp0 8>;
+		};
+
+		vspd0: vsp@fea20000 {
+			compatible = "renesas,vsp2";
+			reg = <0 0xfea20000 0 0x7000>;
+			interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 623>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			resets = <&cpg 623>;
+			renesas,fcp = <&fcpvd0>;
+		};
+
+		fcpvd0: fcp@fea27000 {
+			compatible = "renesas,fcpv";
+			reg = <0 0xfea27000 0 0x200>;
+			clocks = <&cpg CPG_MOD 603>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			resets = <&cpg 603>;
+			iommus = <&ipmmu_vi0 8>;
+		};
+
+		vspd1: vsp@fea28000 {
+			compatible = "renesas,vsp2";
+			reg = <0 0xfea28000 0 0x7000>;
+			interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 622>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			resets = <&cpg 622>;
+			renesas,fcp = <&fcpvd1>;
+		};
+
+		fcpvd1: fcp@fea2f000 {
+			compatible = "renesas,fcpv";
+			reg = <0 0xfea2f000 0 0x200>;
+			clocks = <&cpg CPG_MOD 602>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			resets = <&cpg 602>;
+			iommus = <&ipmmu_vi0 9>;
+		};
+
+		du: display@feb00000 {
+			compatible = "renesas,du-r8a77990";
+			reg = <0 0xfeb00000 0 0x80000>;
+			interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 724>,
+				 <&cpg CPG_MOD 723>;
+			clock-names = "du.0", "du.1";
+			vsps = <&vspd0 0 &vspd1 0>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					du_out_rgb: endpoint {
+					};
+				};
+
+				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,r8a77990-lvds";
+			reg = <0 0xfeb90000 0 0x20>;
+			clocks = <&cpg CPG_MOD 727>;
+			power-domains = <&sysc R8A77990_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,r8a77990-lvds";
+			reg = <0 0xfeb90100 0 0x20>;
+			clocks = <&cpg CPG_MOD 727>;
+			power-domains = <&sysc R8A77990_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 {
+					};
+				};
+			};
+		};
+
 		prr: chipid@fff00044 {
 			compatible = "renesas,prr";
 			reg = <0 0xfff00044 0 4>;
-- 
Regards,

Laurent Pinchart

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

* [PATCH v2 13/16] arm64: dts: renesas: r8a77990: Add display output support
@ 2018-09-14  9:10   ` Laurent Pinchart
  0 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-14  9:10 UTC (permalink / raw)
  To: dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham

The R8A77990 (E3) platform has one RGB output and two LVDS outputs
connected to the DU. Add the DT nodes for the DU, LVDS encoders and
supporting VSP and FCP.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
---
 arch/arm64/boot/dts/renesas/r8a77990.dtsi | 167 ++++++++++++++++++++++++++++++
 1 file changed, 167 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
index abb14af76c0e..600074ca3ee5 100644
--- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
@@ -537,6 +537,173 @@
 			resets = <&cpg 408>;
 		};
 
+		vspb0: vsp@fe960000 {
+			compatible = "renesas,vsp2";
+			reg = <0 0xfe960000 0 0x8000>;
+			interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 626>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			resets = <&cpg 626>;
+			renesas,fcp = <&fcpvb0>;
+		};
+
+		fcpvb0: fcp@fe96f000 {
+			compatible = "renesas,fcpv";
+			reg = <0 0xfe96f000 0 0x200>;
+			clocks = <&cpg CPG_MOD 607>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			resets = <&cpg 607>;
+			iommus = <&ipmmu_vp0 5>;
+		};
+
+		vspi0: vsp@fe9a0000 {
+			compatible = "renesas,vsp2";
+			reg = <0 0xfe9a0000 0 0x8000>;
+			interrupts = <GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 622>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			resets = <&cpg 631>;
+			renesas,fcp = <&fcpvi0>;
+		};
+
+		fcpvi0: fcp@fe9af000 {
+			compatible = "renesas,fcpv";
+			reg = <0 0xfe9af000 0 0x200>;
+			clocks = <&cpg CPG_MOD 611>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			resets = <&cpg 611>;
+			iommus = <&ipmmu_vp0 8>;
+		};
+
+		vspd0: vsp@fea20000 {
+			compatible = "renesas,vsp2";
+			reg = <0 0xfea20000 0 0x7000>;
+			interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 623>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			resets = <&cpg 623>;
+			renesas,fcp = <&fcpvd0>;
+		};
+
+		fcpvd0: fcp@fea27000 {
+			compatible = "renesas,fcpv";
+			reg = <0 0xfea27000 0 0x200>;
+			clocks = <&cpg CPG_MOD 603>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			resets = <&cpg 603>;
+			iommus = <&ipmmu_vi0 8>;
+		};
+
+		vspd1: vsp@fea28000 {
+			compatible = "renesas,vsp2";
+			reg = <0 0xfea28000 0 0x7000>;
+			interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 622>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			resets = <&cpg 622>;
+			renesas,fcp = <&fcpvd1>;
+		};
+
+		fcpvd1: fcp@fea2f000 {
+			compatible = "renesas,fcpv";
+			reg = <0 0xfea2f000 0 0x200>;
+			clocks = <&cpg CPG_MOD 602>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			resets = <&cpg 602>;
+			iommus = <&ipmmu_vi0 9>;
+		};
+
+		du: display@feb00000 {
+			compatible = "renesas,du-r8a77990";
+			reg = <0 0xfeb00000 0 0x80000>;
+			interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 724>,
+				 <&cpg CPG_MOD 723>;
+			clock-names = "du.0", "du.1";
+			vsps = <&vspd0 0 &vspd1 0>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					du_out_rgb: endpoint {
+					};
+				};
+
+				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,r8a77990-lvds";
+			reg = <0 0xfeb90000 0 0x20>;
+			clocks = <&cpg CPG_MOD 727>;
+			power-domains = <&sysc R8A77990_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,r8a77990-lvds";
+			reg = <0 0xfeb90100 0 0x20>;
+			clocks = <&cpg CPG_MOD 727>;
+			power-domains = <&sysc R8A77990_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 {
+					};
+				};
+			};
+		};
+
 		prr: chipid@fff00044 {
 			compatible = "renesas,prr";
 			reg = <0 0xfff00044 0 4>;
-- 
Regards,

Laurent Pinchart

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

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

* [PATCH v2 14/16] arm64: dts: renesas: r8a77995: Add LVDS support
  2018-09-14  9:10 ` Laurent Pinchart
@ 2018-09-14  9:10   ` Laurent Pinchart
  -1 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-14  9:10 UTC (permalink / raw)
  To: dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham

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>
Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
---
 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 fe77bc43c447..32c473143b19 100644
--- a/arch/arm64/boot/dts/renesas/r8a77995.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77995.dtsi
@@ -960,12 +960,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 {
 					};
 				};
 			};
-- 
Regards,

Laurent Pinchart

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

* [PATCH v2 14/16] arm64: dts: renesas: r8a77995: Add LVDS support
@ 2018-09-14  9:10   ` Laurent Pinchart
  0 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-14  9:10 UTC (permalink / raw)
  To: dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham

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>
Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
---
 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 fe77bc43c447..32c473143b19 100644
--- a/arch/arm64/boot/dts/renesas/r8a77995.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77995.dtsi
@@ -960,12 +960,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 {
 					};
 				};
 			};
-- 
Regards,

Laurent Pinchart

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

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

* [PATCH v2 15/16] arm64: dts: renesas: r8a77990: ebisu: Enable VGA and HDMI outputs
  2018-09-14  9:10 ` Laurent Pinchart
@ 2018-09-14  9:10   ` Laurent Pinchart
  -1 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-14  9:10 UTC (permalink / raw)
  To: dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham

Add the LVDS decoder, HDMI encoder, VGA encoder and HDMI and VGA
connectors, and wire up the display-related nodes with clocks, pinmux
and regulators.

The LVDS0 and LVDS1 encoders can use the DU_DOTCLKIN0, DU_DOTCLKIN1 and
EXTAL externals clocks. Two of them are provided to the SoC on the Ebisu
board, hook them up in DT.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
---
 arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts | 166 +++++++++++++++++++++++++
 1 file changed, 166 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts b/arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts
index 2bc3a4884b00..772ea8843d84 100644
--- a/arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts
+++ b/arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts
@@ -28,6 +28,88 @@
 		/* first 128MB is reserved for secure area. */
 		reg = <0x0 0x48000000 0x0 0x38000000>;
 	};
+
+	hdmi-out {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_out: endpoint {
+				remote-endpoint = <&adv7511_out>;
+			};
+		};
+	};
+
+	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>;
+				};
+			};
+		};
+	};
+
+	vga {
+		compatible = "vga-connector";
+
+		port {
+			vga_in: endpoint {
+				remote-endpoint = <&adv7123_out>;
+			};
+		};
+	};
+
+	vga-encoder {
+		compatible = "adi,adv7123";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				adv7123_in: endpoint {
+					remote-endpoint = <&du_out_rgb>;
+				};
+			};
+			port@1 {
+				reg = <1>;
+				adv7123_out: endpoint {
+					remote-endpoint = <&vga_in>;
+				};
+			};
+		};
+	};
+
+	reg_3p3v: regulator1 {
+		compatible = "regulator-fixed";
+		regulator-name = "fixed-3.3V";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+
+	x13_clk: x13 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <74250000>;
+	};
 };
 
 &avb {
@@ -47,6 +129,25 @@
 	};
 };
 
+&du {
+	pinctrl-0 = <&du_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+
+	clocks = <&cpg CPG_MOD 724>,
+		 <&cpg CPG_MOD 723>,
+		 <&x13_clk>;
+	clock-names = "du.0", "du.1", "dclkin.0";
+
+	ports {
+		port@0 {
+			endpoint {
+				remote-endpoint = <&adv7123_in>;
+			};
+		};
+	};
+};
+
 &ehci0 {
 	status = "okay";
 };
@@ -55,6 +156,66 @@
 	clock-frequency = <48000000>;
 };
 
+&i2c0 {
+	status = "okay";
+
+	hdmi-encoder@39 {
+		compatible = "adi,adv7511w";
+		reg = <0x39>;
+		interrupt-parent = <&gpio1>;
+		interrupts = <1 IRQ_TYPE_LEVEL_LOW>;
+
+		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>;
+				};
+			};
+		};
+	};
+};
+
+&lvds0 {
+	status = "okay";
+
+	clocks = <&cpg CPG_MOD 727>,
+		 <&x13_clk>,
+		 <&extal_clk>;
+	clock-names = "fck", "dclkin.0", "extal";
+
+	ports {
+		port@1 {
+			lvds0_out: endpoint {
+				remote-endpoint = <&thc63lvd1024_in>;
+			};
+		};
+	};
+};
+
+&lvds1 {
+	clocks = <&cpg CPG_MOD 727>,
+		 <&x13_clk>,
+		 <&extal_clk>;
+	clock-names = "fck", "dclkin.0", "extal";
+};
+
 &ohci0 {
 	status = "okay";
 };
@@ -67,6 +228,11 @@
 		};
 	};
 
+	du_pins: du {
+		groups = "du_rgb888", "du_sync", "du_disp", "du_clk_out_0";
+		function = "du";
+	};
+
 	usb0_pins: usb {
 		groups = "usb0_b";
 		function = "usb0";
-- 
Regards,

Laurent Pinchart

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

* [PATCH v2 15/16] arm64: dts: renesas: r8a77990: ebisu: Enable VGA and HDMI outputs
@ 2018-09-14  9:10   ` Laurent Pinchart
  0 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-14  9:10 UTC (permalink / raw)
  To: dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham

Add the LVDS decoder, HDMI encoder, VGA encoder and HDMI and VGA
connectors, and wire up the display-related nodes with clocks, pinmux
and regulators.

The LVDS0 and LVDS1 encoders can use the DU_DOTCLKIN0, DU_DOTCLKIN1 and
EXTAL externals clocks. Two of them are provided to the SoC on the Ebisu
board, hook them up in DT.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
---
 arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts | 166 +++++++++++++++++++++++++
 1 file changed, 166 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts b/arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts
index 2bc3a4884b00..772ea8843d84 100644
--- a/arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts
+++ b/arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts
@@ -28,6 +28,88 @@
 		/* first 128MB is reserved for secure area. */
 		reg = <0x0 0x48000000 0x0 0x38000000>;
 	};
+
+	hdmi-out {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_out: endpoint {
+				remote-endpoint = <&adv7511_out>;
+			};
+		};
+	};
+
+	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>;
+				};
+			};
+		};
+	};
+
+	vga {
+		compatible = "vga-connector";
+
+		port {
+			vga_in: endpoint {
+				remote-endpoint = <&adv7123_out>;
+			};
+		};
+	};
+
+	vga-encoder {
+		compatible = "adi,adv7123";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				adv7123_in: endpoint {
+					remote-endpoint = <&du_out_rgb>;
+				};
+			};
+			port@1 {
+				reg = <1>;
+				adv7123_out: endpoint {
+					remote-endpoint = <&vga_in>;
+				};
+			};
+		};
+	};
+
+	reg_3p3v: regulator1 {
+		compatible = "regulator-fixed";
+		regulator-name = "fixed-3.3V";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+
+	x13_clk: x13 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <74250000>;
+	};
 };
 
 &avb {
@@ -47,6 +129,25 @@
 	};
 };
 
+&du {
+	pinctrl-0 = <&du_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+
+	clocks = <&cpg CPG_MOD 724>,
+		 <&cpg CPG_MOD 723>,
+		 <&x13_clk>;
+	clock-names = "du.0", "du.1", "dclkin.0";
+
+	ports {
+		port@0 {
+			endpoint {
+				remote-endpoint = <&adv7123_in>;
+			};
+		};
+	};
+};
+
 &ehci0 {
 	status = "okay";
 };
@@ -55,6 +156,66 @@
 	clock-frequency = <48000000>;
 };
 
+&i2c0 {
+	status = "okay";
+
+	hdmi-encoder@39 {
+		compatible = "adi,adv7511w";
+		reg = <0x39>;
+		interrupt-parent = <&gpio1>;
+		interrupts = <1 IRQ_TYPE_LEVEL_LOW>;
+
+		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>;
+				};
+			};
+		};
+	};
+};
+
+&lvds0 {
+	status = "okay";
+
+	clocks = <&cpg CPG_MOD 727>,
+		 <&x13_clk>,
+		 <&extal_clk>;
+	clock-names = "fck", "dclkin.0", "extal";
+
+	ports {
+		port@1 {
+			lvds0_out: endpoint {
+				remote-endpoint = <&thc63lvd1024_in>;
+			};
+		};
+	};
+};
+
+&lvds1 {
+	clocks = <&cpg CPG_MOD 727>,
+		 <&x13_clk>,
+		 <&extal_clk>;
+	clock-names = "fck", "dclkin.0", "extal";
+};
+
 &ohci0 {
 	status = "okay";
 };
@@ -67,6 +228,11 @@
 		};
 	};
 
+	du_pins: du {
+		groups = "du_rgb888", "du_sync", "du_disp", "du_clk_out_0";
+		function = "du";
+	};
+
 	usb0_pins: usb {
 		groups = "usb0_b";
 		function = "usb0";
-- 
Regards,

Laurent Pinchart

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

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

* [PATCH v2 16/16] arm64: dts: renesas: r8a77995: draak: Enable HDMI display output
  2018-09-14  9:10 ` Laurent Pinchart
@ 2018-09-14  9:10   ` Laurent Pinchart
  -1 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-14  9:10 UTC (permalink / raw)
  To: dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham

From: Ulrich Hecht <uli+renesas@fpond.eu>

Adds LVDS decoder, HDMI encoder and connector for the Draak board.

The LVDS0 and LVDS1 encoders can use the DU_DOTCLKIN0, DU_DOTCLKIN1 and
EXTAL externals clocks. Two of them are provided to the SoC on the Draak
board, hook them up in DT.

Signed-off-by: Ulrich Hecht <uli+renesas@fpond.eu>
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
---
 arch/arm64/boot/dts/renesas/r8a77995-draak.dts | 98 +++++++++++++++++++++++++-
 1 file changed, 97 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/renesas/r8a77995-draak.dts b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts
index a8e8f2669d4c..3055c39bbe07 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
  */
 
@@ -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-encoder@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>;
@@ -281,6 +353,30 @@
 	};
 };
 
+&lvds0 {
+	status = "okay";
+
+	clocks = <&cpg CPG_MOD 727>,
+		 <&x12_clk>,
+		 <&extal_clk>;
+	clock-names = "fck", "dclkin.0", "extal";
+
+	ports {
+		port@1 {
+			lvds0_out: endpoint {
+				remote-endpoint = <&thc63lvd1024_in>;
+			};
+		};
+	};
+};
+
+&lvds1 {
+	clocks = <&cpg CPG_MOD 727>,
+		 <&x12_clk>,
+		 <&extal_clk>;
+	clock-names = "fck", "dclkin.0", "extal";
+};
+
 &ehci0 {
 	status = "okay";
 };
-- 
Regards,

Laurent Pinchart

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

* [PATCH v2 16/16] arm64: dts: renesas: r8a77995: draak: Enable HDMI display output
@ 2018-09-14  9:10   ` Laurent Pinchart
  0 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-14  9:10 UTC (permalink / raw)
  To: dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham

From: Ulrich Hecht <uli+renesas@fpond.eu>

Adds LVDS decoder, HDMI encoder and connector for the Draak board.

The LVDS0 and LVDS1 encoders can use the DU_DOTCLKIN0, DU_DOTCLKIN1 and
EXTAL externals clocks. Two of them are provided to the SoC on the Draak
board, hook them up in DT.

Signed-off-by: Ulrich Hecht <uli+renesas@fpond.eu>
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
---
 arch/arm64/boot/dts/renesas/r8a77995-draak.dts | 98 +++++++++++++++++++++++++-
 1 file changed, 97 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/renesas/r8a77995-draak.dts b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts
index a8e8f2669d4c..3055c39bbe07 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
  */
 
@@ -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-encoder@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>;
@@ -281,6 +353,30 @@
 	};
 };
 
+&lvds0 {
+	status = "okay";
+
+	clocks = <&cpg CPG_MOD 727>,
+		 <&x12_clk>,
+		 <&extal_clk>;
+	clock-names = "fck", "dclkin.0", "extal";
+
+	ports {
+		port@1 {
+			lvds0_out: endpoint {
+				remote-endpoint = <&thc63lvd1024_in>;
+			};
+		};
+	};
+};
+
+&lvds1 {
+	clocks = <&cpg CPG_MOD 727>,
+		 <&x12_clk>,
+		 <&extal_clk>;
+	clock-names = "fck", "dclkin.0", "extal";
+};
+
 &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 related	[flat|nested] 118+ messages in thread

* Re: [PATCH v2 12/16] arm64: dts: renesas: r8a77990: Add I2C device nodes
  2018-09-14  9:10   ` Laurent Pinchart
@ 2018-09-17  7:33     ` Simon Horman
  -1 siblings, 0 replies; 118+ messages in thread
From: Simon Horman @ 2018-09-17  7:33 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: dri-devel, linux-renesas-soc, Ulrich Hecht, Kieran Bingham

On Fri, Sep 14, 2018 at 12:10:42PM +0300, Laurent Pinchart wrote:
> From: Takeshi Kihara <takeshi.kihara.df@renesas.com>
> 
> Add device nodes for I2C ch{0,1,2,3,4,5,6,7} to R-Car E3 R8A77990 device
> tree.
> 
> Signed-off-by: Takeshi Kihara <takeshi.kihara.df@renesas.com>
> Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> ---
>  arch/arm64/boot/dts/renesas/r8a77990.dtsi | 123 ++++++++++++++++++++++++++++++
>  1 file changed, 123 insertions(+)

I believe this duplicates the following patch already queued-up for
v4.20.

Fixes: bc011dfa3065 ("arm64: dts: renesas: r8a77990: Add I2C device nodes")

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

* Re: [PATCH v2 12/16] arm64: dts: renesas: r8a77990: Add I2C device nodes
@ 2018-09-17  7:33     ` Simon Horman
  0 siblings, 0 replies; 118+ messages in thread
From: Simon Horman @ 2018-09-17  7:33 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham, dri-devel

On Fri, Sep 14, 2018 at 12:10:42PM +0300, Laurent Pinchart wrote:
> From: Takeshi Kihara <takeshi.kihara.df@renesas.com>
> 
> Add device nodes for I2C ch{0,1,2,3,4,5,6,7} to R-Car E3 R8A77990 device
> tree.
> 
> Signed-off-by: Takeshi Kihara <takeshi.kihara.df@renesas.com>
> Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> ---
>  arch/arm64/boot/dts/renesas/r8a77990.dtsi | 123 ++++++++++++++++++++++++++++++
>  1 file changed, 123 insertions(+)

I believe this duplicates the following patch already queued-up for
v4.20.

Fixes: bc011dfa3065 ("arm64: dts: renesas: r8a77990: Add I2C device nodes")
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v2 13/16] arm64: dts: renesas: r8a77990: Add display output support
  2018-09-14  9:10   ` Laurent Pinchart
@ 2018-09-17  7:50     ` Simon Horman
  -1 siblings, 0 replies; 118+ messages in thread
From: Simon Horman @ 2018-09-17  7:50 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: dri-devel, linux-renesas-soc, Ulrich Hecht, Kieran Bingham

On Fri, Sep 14, 2018 at 12:10:43PM +0300, Laurent Pinchart wrote:
> The R8A77990 (E3) platform has one RGB output and two LVDS outputs
> connected to the DU. Add the DT nodes for the DU, LVDS encoders and
> supporting VSP and FCP.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> ---
>  arch/arm64/boot/dts/renesas/r8a77990.dtsi | 167 ++++++++++++++++++++++++++++++
>  1 file changed, 167 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> index abb14af76c0e..600074ca3ee5 100644
> --- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> +++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> @@ -537,6 +537,173 @@
>  			resets = <&cpg 408>;
>  		};

These nodes should be placed after the gic to preserve the sorting
of nodes by bus address and then IP block.

> +		vspb0: vsp@fe960000 {
> +			compatible = "renesas,vsp2";
> +			reg = <0 0xfe960000 0 0x8000>;
> +			interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&cpg CPG_MOD 626>;
> +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> +			resets = <&cpg 626>;
> +			renesas,fcp = <&fcpvb0>;
> +		};
> +
> +		fcpvb0: fcp@fe96f000 {
> +			compatible = "renesas,fcpv";
> +			reg = <0 0xfe96f000 0 0x200>;
> +			clocks = <&cpg CPG_MOD 607>;
> +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> +			resets = <&cpg 607>;
> +			iommus = <&ipmmu_vp0 5>;
> +		};
> +
> +		vspi0: vsp@fe9a0000 {
> +			compatible = "renesas,vsp2";
> +			reg = <0 0xfe9a0000 0 0x8000>;
> +			interrupts = <GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&cpg CPG_MOD 622>;

R-Car Series, 3rd Generation, v1.00, Table Table 8A.21 indicates
that this clock should be <&cpg CPG_MOD 631>. The clock above is
(according to my reading of the documentation) correctly
used for vspd1 below.

> +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> +			resets = <&cpg 631>;
> +			renesas,fcp = <&fcpvi0>;
> +		};
> +
> +		fcpvi0: fcp@fe9af000 {
> +			compatible = "renesas,fcpv";
> +			reg = <0 0xfe9af000 0 0x200>;
> +			clocks = <&cpg CPG_MOD 611>;
> +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> +			resets = <&cpg 611>;
> +			iommus = <&ipmmu_vp0 8>;
> +		};
> +
> +		vspd0: vsp@fea20000 {
> +			compatible = "renesas,vsp2";
> +			reg = <0 0xfea20000 0 0x7000>;
> +			interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&cpg CPG_MOD 623>;
> +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> +			resets = <&cpg 623>;
> +			renesas,fcp = <&fcpvd0>;
> +		};
> +
> +		fcpvd0: fcp@fea27000 {
> +			compatible = "renesas,fcpv";
> +			reg = <0 0xfea27000 0 0x200>;
> +			clocks = <&cpg CPG_MOD 603>;
> +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> +			resets = <&cpg 603>;
> +			iommus = <&ipmmu_vi0 8>;
> +		};
> +
> +		vspd1: vsp@fea28000 {
> +			compatible = "renesas,vsp2";
> +			reg = <0 0xfea28000 0 0x7000>;
> +			interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&cpg CPG_MOD 622>;
> +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> +			resets = <&cpg 622>;
> +			renesas,fcp = <&fcpvd1>;
> +		};
> +
> +		fcpvd1: fcp@fea2f000 {
> +			compatible = "renesas,fcpv";
> +			reg = <0 0xfea2f000 0 0x200>;
> +			clocks = <&cpg CPG_MOD 602>;
> +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> +			resets = <&cpg 602>;
> +			iommus = <&ipmmu_vi0 9>;
> +		};
> +
> +		du: display@feb00000 {
> +			compatible = "renesas,du-r8a77990";
> +			reg = <0 0xfeb00000 0 0x80000>;
> +			interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&cpg CPG_MOD 724>,
> +				 <&cpg CPG_MOD 723>;
> +			clock-names = "du.0", "du.1";
> +			vsps = <&vspd0 0 &vspd1 0>;
> +			status = "disabled";
> +
> +			ports {
> +				#address-cells = <1>;
> +				#size-cells = <0>;
> +
> +				port@0 {
> +					reg = <0>;
> +					du_out_rgb: endpoint {
> +					};
> +				};
> +
> +				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,r8a77990-lvds";
> +			reg = <0 0xfeb90000 0 0x20>;
> +			clocks = <&cpg CPG_MOD 727>;
> +			power-domains = <&sysc R8A77990_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,r8a77990-lvds";
> +			reg = <0 0xfeb90100 0 0x20>;
> +			clocks = <&cpg CPG_MOD 727>;
> +			power-domains = <&sysc R8A77990_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 {
> +					};
> +				};
> +			};
> +		};
> +
>  		prr: chipid@fff00044 {
>  			compatible = "renesas,prr";
>  			reg = <0 0xfff00044 0 4>;
> -- 
> Regards,
> 
> Laurent Pinchart
> 

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

* Re: [PATCH v2 13/16] arm64: dts: renesas: r8a77990: Add display output support
@ 2018-09-17  7:50     ` Simon Horman
  0 siblings, 0 replies; 118+ messages in thread
From: Simon Horman @ 2018-09-17  7:50 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham, dri-devel

On Fri, Sep 14, 2018 at 12:10:43PM +0300, Laurent Pinchart wrote:
> The R8A77990 (E3) platform has one RGB output and two LVDS outputs
> connected to the DU. Add the DT nodes for the DU, LVDS encoders and
> supporting VSP and FCP.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> ---
>  arch/arm64/boot/dts/renesas/r8a77990.dtsi | 167 ++++++++++++++++++++++++++++++
>  1 file changed, 167 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> index abb14af76c0e..600074ca3ee5 100644
> --- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> +++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> @@ -537,6 +537,173 @@
>  			resets = <&cpg 408>;
>  		};

These nodes should be placed after the gic to preserve the sorting
of nodes by bus address and then IP block.

> +		vspb0: vsp@fe960000 {
> +			compatible = "renesas,vsp2";
> +			reg = <0 0xfe960000 0 0x8000>;
> +			interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&cpg CPG_MOD 626>;
> +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> +			resets = <&cpg 626>;
> +			renesas,fcp = <&fcpvb0>;
> +		};
> +
> +		fcpvb0: fcp@fe96f000 {
> +			compatible = "renesas,fcpv";
> +			reg = <0 0xfe96f000 0 0x200>;
> +			clocks = <&cpg CPG_MOD 607>;
> +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> +			resets = <&cpg 607>;
> +			iommus = <&ipmmu_vp0 5>;
> +		};
> +
> +		vspi0: vsp@fe9a0000 {
> +			compatible = "renesas,vsp2";
> +			reg = <0 0xfe9a0000 0 0x8000>;
> +			interrupts = <GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&cpg CPG_MOD 622>;

R-Car Series, 3rd Generation, v1.00, Table Table 8A.21 indicates
that this clock should be <&cpg CPG_MOD 631>. The clock above is
(according to my reading of the documentation) correctly
used for vspd1 below.

> +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> +			resets = <&cpg 631>;
> +			renesas,fcp = <&fcpvi0>;
> +		};
> +
> +		fcpvi0: fcp@fe9af000 {
> +			compatible = "renesas,fcpv";
> +			reg = <0 0xfe9af000 0 0x200>;
> +			clocks = <&cpg CPG_MOD 611>;
> +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> +			resets = <&cpg 611>;
> +			iommus = <&ipmmu_vp0 8>;
> +		};
> +
> +		vspd0: vsp@fea20000 {
> +			compatible = "renesas,vsp2";
> +			reg = <0 0xfea20000 0 0x7000>;
> +			interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&cpg CPG_MOD 623>;
> +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> +			resets = <&cpg 623>;
> +			renesas,fcp = <&fcpvd0>;
> +		};
> +
> +		fcpvd0: fcp@fea27000 {
> +			compatible = "renesas,fcpv";
> +			reg = <0 0xfea27000 0 0x200>;
> +			clocks = <&cpg CPG_MOD 603>;
> +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> +			resets = <&cpg 603>;
> +			iommus = <&ipmmu_vi0 8>;
> +		};
> +
> +		vspd1: vsp@fea28000 {
> +			compatible = "renesas,vsp2";
> +			reg = <0 0xfea28000 0 0x7000>;
> +			interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&cpg CPG_MOD 622>;
> +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> +			resets = <&cpg 622>;
> +			renesas,fcp = <&fcpvd1>;
> +		};
> +
> +		fcpvd1: fcp@fea2f000 {
> +			compatible = "renesas,fcpv";
> +			reg = <0 0xfea2f000 0 0x200>;
> +			clocks = <&cpg CPG_MOD 602>;
> +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> +			resets = <&cpg 602>;
> +			iommus = <&ipmmu_vi0 9>;
> +		};
> +
> +		du: display@feb00000 {
> +			compatible = "renesas,du-r8a77990";
> +			reg = <0 0xfeb00000 0 0x80000>;
> +			interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&cpg CPG_MOD 724>,
> +				 <&cpg CPG_MOD 723>;
> +			clock-names = "du.0", "du.1";
> +			vsps = <&vspd0 0 &vspd1 0>;
> +			status = "disabled";
> +
> +			ports {
> +				#address-cells = <1>;
> +				#size-cells = <0>;
> +
> +				port@0 {
> +					reg = <0>;
> +					du_out_rgb: endpoint {
> +					};
> +				};
> +
> +				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,r8a77990-lvds";
> +			reg = <0 0xfeb90000 0 0x20>;
> +			clocks = <&cpg CPG_MOD 727>;
> +			power-domains = <&sysc R8A77990_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,r8a77990-lvds";
> +			reg = <0 0xfeb90100 0 0x20>;
> +			clocks = <&cpg CPG_MOD 727>;
> +			power-domains = <&sysc R8A77990_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 {
> +					};
> +				};
> +			};
> +		};
> +
>  		prr: chipid@fff00044 {
>  			compatible = "renesas,prr";
>  			reg = <0 0xfff00044 0 4>;
> -- 
> 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] 118+ messages in thread

* Re: [PATCH v2 12/16] arm64: dts: renesas: r8a77990: Add I2C device nodes
  2018-09-17  7:33     ` Simon Horman
@ 2018-09-17  8:08       ` Laurent Pinchart
  -1 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-17  8:08 UTC (permalink / raw)
  To: Simon Horman
  Cc: Laurent Pinchart, dri-devel, linux-renesas-soc, Ulrich Hecht,
	Kieran Bingham

Hi Simon,

On Monday, 17 September 2018 10:33:43 EEST Simon Horman wrote:
> On Fri, Sep 14, 2018 at 12:10:42PM +0300, Laurent Pinchart wrote:
> > From: Takeshi Kihara <takeshi.kihara.df@renesas.com>
> > 
> > Add device nodes for I2C ch{0,1,2,3,4,5,6,7} to R-Car E3 R8A77990 device
> > tree.
> > 
> > Signed-off-by: Takeshi Kihara <takeshi.kihara.df@renesas.com>
> > Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> > Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> > ---
> > 
> >  arch/arm64/boot/dts/renesas/r8a77990.dtsi | 123 +++++++++++++++++++++++++
> >  1 file changed, 123 insertions(+)
> 
> I believe this duplicates the following patch already queued-up for
> v4.20.
> 
> Fixes: bc011dfa3065 ("arm64: dts: renesas: r8a77990: Add I2C device nodes")

Yes, it does, it was just included it for completeness of the patch series 
given that the commit queued for v4.20 isn't in the base branch.

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v2 12/16] arm64: dts: renesas: r8a77990: Add I2C device nodes
@ 2018-09-17  8:08       ` Laurent Pinchart
  0 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-17  8:08 UTC (permalink / raw)
  To: Simon Horman
  Cc: linux-renesas-soc, Ulrich Hecht, Laurent Pinchart,
	Kieran Bingham, dri-devel

Hi Simon,

On Monday, 17 September 2018 10:33:43 EEST Simon Horman wrote:
> On Fri, Sep 14, 2018 at 12:10:42PM +0300, Laurent Pinchart wrote:
> > From: Takeshi Kihara <takeshi.kihara.df@renesas.com>
> > 
> > Add device nodes for I2C ch{0,1,2,3,4,5,6,7} to R-Car E3 R8A77990 device
> > tree.
> > 
> > Signed-off-by: Takeshi Kihara <takeshi.kihara.df@renesas.com>
> > Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> > Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> > ---
> > 
> >  arch/arm64/boot/dts/renesas/r8a77990.dtsi | 123 +++++++++++++++++++++++++
> >  1 file changed, 123 insertions(+)
> 
> I believe this duplicates the following patch already queued-up for
> v4.20.
> 
> Fixes: bc011dfa3065 ("arm64: dts: renesas: r8a77990: Add I2C device nodes")

Yes, it does, it was just included it for completeness of the patch series 
given that the commit queued for v4.20 isn't in the base branch.

-- 
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] 118+ messages in thread

* Re: [PATCH v2 13/16] arm64: dts: renesas: r8a77990: Add display output support
  2018-09-17  7:50     ` Simon Horman
@ 2018-09-17  8:14       ` Simon Horman
  -1 siblings, 0 replies; 118+ messages in thread
From: Simon Horman @ 2018-09-17  8:14 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: dri-devel, linux-renesas-soc, Ulrich Hecht, Kieran Bingham

On Mon, Sep 17, 2018 at 09:50:55AM +0200, Simon Horman wrote:
> On Fri, Sep 14, 2018 at 12:10:43PM +0300, Laurent Pinchart wrote:
> > The R8A77990 (E3) platform has one RGB output and two LVDS outputs
> > connected to the DU. Add the DT nodes for the DU, LVDS encoders and
> > supporting VSP and FCP.
> > 
> > Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> > Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> > ---
> >  arch/arm64/boot/dts/renesas/r8a77990.dtsi | 167 ++++++++++++++++++++++++++++++
> >  1 file changed, 167 insertions(+)
> > 
> > diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > index abb14af76c0e..600074ca3ee5 100644
> > --- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > +++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > @@ -537,6 +537,173 @@
> >  			resets = <&cpg 408>;
> >  		};
> 
> These nodes should be placed after the gic to preserve the sorting
> of nodes by bus address and then IP block.
> 
> > +		vspb0: vsp@fe960000 {
> > +			compatible = "renesas,vsp2";
> > +			reg = <0 0xfe960000 0 0x8000>;
> > +			interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
> > +			clocks = <&cpg CPG_MOD 626>;
> > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > +			resets = <&cpg 626>;
> > +			renesas,fcp = <&fcpvb0>;
> > +		};
> > +
> > +		fcpvb0: fcp@fe96f000 {
> > +			compatible = "renesas,fcpv";
> > +			reg = <0 0xfe96f000 0 0x200>;
> > +			clocks = <&cpg CPG_MOD 607>;
> > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > +			resets = <&cpg 607>;
> > +			iommus = <&ipmmu_vp0 5>;
> > +		};
> > +
> > +		vspi0: vsp@fe9a0000 {
> > +			compatible = "renesas,vsp2";
> > +			reg = <0 0xfe9a0000 0 0x8000>;
> > +			interrupts = <GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>;
> > +			clocks = <&cpg CPG_MOD 622>;
> 
> R-Car Series, 3rd Generation, v1.00, Table Table 8A.21 indicates
> that this clock should be <&cpg CPG_MOD 631>. The clock above is
> (according to my reading of the documentation) correctly
> used for vspd1 below.
> 
> > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > +			resets = <&cpg 631>;
> > +			renesas,fcp = <&fcpvi0>;
> > +		};
> > +
> > +		fcpvi0: fcp@fe9af000 {
> > +			compatible = "renesas,fcpv";
> > +			reg = <0 0xfe9af000 0 0x200>;
> > +			clocks = <&cpg CPG_MOD 611>;
> > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > +			resets = <&cpg 611>;
> > +			iommus = <&ipmmu_vp0 8>;
> > +		};
> > +
> > +		vspd0: vsp@fea20000 {
> > +			compatible = "renesas,vsp2";
> > +			reg = <0 0xfea20000 0 0x7000>;
> > +			interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
> > +			clocks = <&cpg CPG_MOD 623>;
> > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > +			resets = <&cpg 623>;
> > +			renesas,fcp = <&fcpvd0>;
> > +		};
> > +
> > +		fcpvd0: fcp@fea27000 {
> > +			compatible = "renesas,fcpv";
> > +			reg = <0 0xfea27000 0 0x200>;
> > +			clocks = <&cpg CPG_MOD 603>;
> > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > +			resets = <&cpg 603>;
> > +			iommus = <&ipmmu_vi0 8>;
> > +		};
> > +
> > +		vspd1: vsp@fea28000 {
> > +			compatible = "renesas,vsp2";
> > +			reg = <0 0xfea28000 0 0x7000>;
> > +			interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
> > +			clocks = <&cpg CPG_MOD 622>;
> > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > +			resets = <&cpg 622>;
> > +			renesas,fcp = <&fcpvd1>;
> > +		};
> > +
> > +		fcpvd1: fcp@fea2f000 {
> > +			compatible = "renesas,fcpv";
> > +			reg = <0 0xfea2f000 0 0x200>;
> > +			clocks = <&cpg CPG_MOD 602>;
> > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > +			resets = <&cpg 602>;
> > +			iommus = <&ipmmu_vi0 9>;
> > +		};
> > +
> > +		du: display@feb00000 {
> > +			compatible = "renesas,du-r8a77990";
> > +			reg = <0 0xfeb00000 0 0x80000>;
> > +			interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
> > +				     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
> > +			clocks = <&cpg CPG_MOD 724>,
> > +				 <&cpg CPG_MOD 723>;
> > +			clock-names = "du.0", "du.1";
> > +			vsps = <&vspd0 0 &vspd1 0>;
> > +			status = "disabled";
> > +
> > +			ports {
> > +				#address-cells = <1>;
> > +				#size-cells = <0>;
> > +
> > +				port@0 {
> > +					reg = <0>;
> > +					du_out_rgb: endpoint {
> > +					};
> > +				};
> > +
> > +				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,r8a77990-lvds";
> > +			reg = <0 0xfeb90000 0 0x20>;
> > +			clocks = <&cpg CPG_MOD 727>;
> > +			power-domains = <&sysc R8A77990_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,r8a77990-lvds";
> > +			reg = <0 0xfeb90100 0 0x20>;
> > +			clocks = <&cpg CPG_MOD 727>;
> > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > +			resets = <&cpg 726>;

Also, is the missmatch between the index for the clock and reset
intentional?

> > +			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 {
> > +					};
> > +				};
> > +			};
> > +		};
> > +
> >  		prr: chipid@fff00044 {
> >  			compatible = "renesas,prr";
> >  			reg = <0 0xfff00044 0 4>;
> > -- 
> > Regards,
> > 
> > Laurent Pinchart
> > 

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

* Re: [PATCH v2 13/16] arm64: dts: renesas: r8a77990: Add display output support
@ 2018-09-17  8:14       ` Simon Horman
  0 siblings, 0 replies; 118+ messages in thread
From: Simon Horman @ 2018-09-17  8:14 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham, dri-devel

On Mon, Sep 17, 2018 at 09:50:55AM +0200, Simon Horman wrote:
> On Fri, Sep 14, 2018 at 12:10:43PM +0300, Laurent Pinchart wrote:
> > The R8A77990 (E3) platform has one RGB output and two LVDS outputs
> > connected to the DU. Add the DT nodes for the DU, LVDS encoders and
> > supporting VSP and FCP.
> > 
> > Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> > Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> > ---
> >  arch/arm64/boot/dts/renesas/r8a77990.dtsi | 167 ++++++++++++++++++++++++++++++
> >  1 file changed, 167 insertions(+)
> > 
> > diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > index abb14af76c0e..600074ca3ee5 100644
> > --- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > +++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > @@ -537,6 +537,173 @@
> >  			resets = <&cpg 408>;
> >  		};
> 
> These nodes should be placed after the gic to preserve the sorting
> of nodes by bus address and then IP block.
> 
> > +		vspb0: vsp@fe960000 {
> > +			compatible = "renesas,vsp2";
> > +			reg = <0 0xfe960000 0 0x8000>;
> > +			interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
> > +			clocks = <&cpg CPG_MOD 626>;
> > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > +			resets = <&cpg 626>;
> > +			renesas,fcp = <&fcpvb0>;
> > +		};
> > +
> > +		fcpvb0: fcp@fe96f000 {
> > +			compatible = "renesas,fcpv";
> > +			reg = <0 0xfe96f000 0 0x200>;
> > +			clocks = <&cpg CPG_MOD 607>;
> > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > +			resets = <&cpg 607>;
> > +			iommus = <&ipmmu_vp0 5>;
> > +		};
> > +
> > +		vspi0: vsp@fe9a0000 {
> > +			compatible = "renesas,vsp2";
> > +			reg = <0 0xfe9a0000 0 0x8000>;
> > +			interrupts = <GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>;
> > +			clocks = <&cpg CPG_MOD 622>;
> 
> R-Car Series, 3rd Generation, v1.00, Table Table 8A.21 indicates
> that this clock should be <&cpg CPG_MOD 631>. The clock above is
> (according to my reading of the documentation) correctly
> used for vspd1 below.
> 
> > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > +			resets = <&cpg 631>;
> > +			renesas,fcp = <&fcpvi0>;
> > +		};
> > +
> > +		fcpvi0: fcp@fe9af000 {
> > +			compatible = "renesas,fcpv";
> > +			reg = <0 0xfe9af000 0 0x200>;
> > +			clocks = <&cpg CPG_MOD 611>;
> > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > +			resets = <&cpg 611>;
> > +			iommus = <&ipmmu_vp0 8>;
> > +		};
> > +
> > +		vspd0: vsp@fea20000 {
> > +			compatible = "renesas,vsp2";
> > +			reg = <0 0xfea20000 0 0x7000>;
> > +			interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
> > +			clocks = <&cpg CPG_MOD 623>;
> > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > +			resets = <&cpg 623>;
> > +			renesas,fcp = <&fcpvd0>;
> > +		};
> > +
> > +		fcpvd0: fcp@fea27000 {
> > +			compatible = "renesas,fcpv";
> > +			reg = <0 0xfea27000 0 0x200>;
> > +			clocks = <&cpg CPG_MOD 603>;
> > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > +			resets = <&cpg 603>;
> > +			iommus = <&ipmmu_vi0 8>;
> > +		};
> > +
> > +		vspd1: vsp@fea28000 {
> > +			compatible = "renesas,vsp2";
> > +			reg = <0 0xfea28000 0 0x7000>;
> > +			interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
> > +			clocks = <&cpg CPG_MOD 622>;
> > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > +			resets = <&cpg 622>;
> > +			renesas,fcp = <&fcpvd1>;
> > +		};
> > +
> > +		fcpvd1: fcp@fea2f000 {
> > +			compatible = "renesas,fcpv";
> > +			reg = <0 0xfea2f000 0 0x200>;
> > +			clocks = <&cpg CPG_MOD 602>;
> > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > +			resets = <&cpg 602>;
> > +			iommus = <&ipmmu_vi0 9>;
> > +		};
> > +
> > +		du: display@feb00000 {
> > +			compatible = "renesas,du-r8a77990";
> > +			reg = <0 0xfeb00000 0 0x80000>;
> > +			interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
> > +				     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
> > +			clocks = <&cpg CPG_MOD 724>,
> > +				 <&cpg CPG_MOD 723>;
> > +			clock-names = "du.0", "du.1";
> > +			vsps = <&vspd0 0 &vspd1 0>;
> > +			status = "disabled";
> > +
> > +			ports {
> > +				#address-cells = <1>;
> > +				#size-cells = <0>;
> > +
> > +				port@0 {
> > +					reg = <0>;
> > +					du_out_rgb: endpoint {
> > +					};
> > +				};
> > +
> > +				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,r8a77990-lvds";
> > +			reg = <0 0xfeb90000 0 0x20>;
> > +			clocks = <&cpg CPG_MOD 727>;
> > +			power-domains = <&sysc R8A77990_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,r8a77990-lvds";
> > +			reg = <0 0xfeb90100 0 0x20>;
> > +			clocks = <&cpg CPG_MOD 727>;
> > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > +			resets = <&cpg 726>;

Also, is the missmatch between the index for the clock and reset
intentional?

> > +			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 {
> > +					};
> > +				};
> > +			};
> > +		};
> > +
> >  		prr: chipid@fff00044 {
> >  			compatible = "renesas,prr";
> >  			reg = <0 0xfff00044 0 4>;
> > -- 
> > 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] 118+ messages in thread

* Re: [PATCH v2 13/16] arm64: dts: renesas: r8a77990: Add display output support
  2018-09-17  7:50     ` Simon Horman
@ 2018-09-17  8:38       ` Laurent Pinchart
  -1 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-17  8:38 UTC (permalink / raw)
  To: Simon Horman
  Cc: Laurent Pinchart, dri-devel, linux-renesas-soc, Ulrich Hecht,
	Kieran Bingham

Hi Simon,

On Monday, 17 September 2018 10:50:55 EEST Simon Horman wrote:
> On Fri, Sep 14, 2018 at 12:10:43PM +0300, Laurent Pinchart wrote:
> > The R8A77990 (E3) platform has one RGB output and two LVDS outputs
> > connected to the DU. Add the DT nodes for the DU, LVDS encoders and
> > supporting VSP and FCP.
> > 
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> > Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> > ---
> > 
> >  arch/arm64/boot/dts/renesas/r8a77990.dtsi | 167 +++++++++++++++++++++++++
> >  1 file changed, 167 insertions(+)
> > 
> > diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > b/arch/arm64/boot/dts/renesas/r8a77990.dtsi index
> > abb14af76c0e..600074ca3ee5 100644
> > --- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > +++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > @@ -537,6 +537,173 @@
> >  			resets = <&cpg 408>;
> >  		};
> 
> These nodes should be placed after the gic to preserve the sorting
> of nodes by bus address and then IP block.

Aren't they already ? :-)

> > +		vspb0: vsp@fe960000 {
> > +			compatible = "renesas,vsp2";
> > +			reg = <0 0xfe960000 0 0x8000>;
> > +			interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
> > +			clocks = <&cpg CPG_MOD 626>;
> > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > +			resets = <&cpg 626>;
> > +			renesas,fcp = <&fcpvb0>;
> > +		};
> > +
> > +		fcpvb0: fcp@fe96f000 {
> > +			compatible = "renesas,fcpv";
> > +			reg = <0 0xfe96f000 0 0x200>;
> > +			clocks = <&cpg CPG_MOD 607>;
> > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > +			resets = <&cpg 607>;
> > +			iommus = <&ipmmu_vp0 5>;
> > +		};
> > +
> > +		vspi0: vsp@fe9a0000 {
> > +			compatible = "renesas,vsp2";
> > +			reg = <0 0xfe9a0000 0 0x8000>;
> > +			interrupts = <GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>;
> > +			clocks = <&cpg CPG_MOD 622>;
> 
> R-Car Series, 3rd Generation, v1.00, Table Table 8A.21 indicates
> that this clock should be <&cpg CPG_MOD 631>. The clock above is
> (according to my reading of the documentation) correctly
> used for vspd1 below.

Bad copy and paste, thank you for pointing it out, it will be fixed in v3.

> > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > +			resets = <&cpg 631>;
> > +			renesas,fcp = <&fcpvi0>;
> > +		};
> > +
> > +		fcpvi0: fcp@fe9af000 {
> > +			compatible = "renesas,fcpv";
> > +			reg = <0 0xfe9af000 0 0x200>;
> > +			clocks = <&cpg CPG_MOD 611>;
> > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > +			resets = <&cpg 611>;
> > +			iommus = <&ipmmu_vp0 8>;
> > +		};
> > +
> > +		vspd0: vsp@fea20000 {
> > +			compatible = "renesas,vsp2";
> > +			reg = <0 0xfea20000 0 0x7000>;
> > +			interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
> > +			clocks = <&cpg CPG_MOD 623>;
> > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > +			resets = <&cpg 623>;
> > +			renesas,fcp = <&fcpvd0>;
> > +		};
> > +
> > +		fcpvd0: fcp@fea27000 {
> > +			compatible = "renesas,fcpv";
> > +			reg = <0 0xfea27000 0 0x200>;
> > +			clocks = <&cpg CPG_MOD 603>;
> > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > +			resets = <&cpg 603>;
> > +			iommus = <&ipmmu_vi0 8>;
> > +		};
> > +
> > +		vspd1: vsp@fea28000 {
> > +			compatible = "renesas,vsp2";
> > +			reg = <0 0xfea28000 0 0x7000>;
> > +			interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
> > +			clocks = <&cpg CPG_MOD 622>;
> > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > +			resets = <&cpg 622>;
> > +			renesas,fcp = <&fcpvd1>;
> > +		};
> > +
> > +		fcpvd1: fcp@fea2f000 {
> > +			compatible = "renesas,fcpv";
> > +			reg = <0 0xfea2f000 0 0x200>;
> > +			clocks = <&cpg CPG_MOD 602>;
> > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > +			resets = <&cpg 602>;
> > +			iommus = <&ipmmu_vi0 9>;
> > +		};
> > +
> > +		du: display@feb00000 {
> > +			compatible = "renesas,du-r8a77990";
> > +			reg = <0 0xfeb00000 0 0x80000>;
> > +			interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
> > +				     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
> > +			clocks = <&cpg CPG_MOD 724>,
> > +				 <&cpg CPG_MOD 723>;
> > +			clock-names = "du.0", "du.1";
> > +			vsps = <&vspd0 0 &vspd1 0>;
> > +			status = "disabled";
> > +
> > +			ports {
> > +				#address-cells = <1>;
> > +				#size-cells = <0>;
> > +
> > +				port@0 {
> > +					reg = <0>;
> > +					du_out_rgb: endpoint {
> > +					};
> > +				};
> > +
> > +				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,r8a77990-lvds";
> > +			reg = <0 0xfeb90000 0 0x20>;
> > +			clocks = <&cpg CPG_MOD 727>;
> > +			power-domains = <&sysc R8A77990_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,r8a77990-lvds";
> > +			reg = <0 0xfeb90100 0 0x20>;
> > +			clocks = <&cpg CPG_MOD 727>;
> > +			power-domains = <&sysc R8A77990_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 {
> > +					};
> > +				};
> > +			};
> > +		};
> > +
> >  		prr: chipid@fff00044 {
> >  			compatible = "renesas,prr";
> >  			reg = <0 0xfff00044 0 4>;

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v2 13/16] arm64: dts: renesas: r8a77990: Add display output support
@ 2018-09-17  8:38       ` Laurent Pinchart
  0 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-17  8:38 UTC (permalink / raw)
  To: Simon Horman
  Cc: linux-renesas-soc, Ulrich Hecht, Laurent Pinchart,
	Kieran Bingham, dri-devel

Hi Simon,

On Monday, 17 September 2018 10:50:55 EEST Simon Horman wrote:
> On Fri, Sep 14, 2018 at 12:10:43PM +0300, Laurent Pinchart wrote:
> > The R8A77990 (E3) platform has one RGB output and two LVDS outputs
> > connected to the DU. Add the DT nodes for the DU, LVDS encoders and
> > supporting VSP and FCP.
> > 
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> > Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> > ---
> > 
> >  arch/arm64/boot/dts/renesas/r8a77990.dtsi | 167 +++++++++++++++++++++++++
> >  1 file changed, 167 insertions(+)
> > 
> > diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > b/arch/arm64/boot/dts/renesas/r8a77990.dtsi index
> > abb14af76c0e..600074ca3ee5 100644
> > --- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > +++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > @@ -537,6 +537,173 @@
> >  			resets = <&cpg 408>;
> >  		};
> 
> These nodes should be placed after the gic to preserve the sorting
> of nodes by bus address and then IP block.

Aren't they already ? :-)

> > +		vspb0: vsp@fe960000 {
> > +			compatible = "renesas,vsp2";
> > +			reg = <0 0xfe960000 0 0x8000>;
> > +			interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
> > +			clocks = <&cpg CPG_MOD 626>;
> > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > +			resets = <&cpg 626>;
> > +			renesas,fcp = <&fcpvb0>;
> > +		};
> > +
> > +		fcpvb0: fcp@fe96f000 {
> > +			compatible = "renesas,fcpv";
> > +			reg = <0 0xfe96f000 0 0x200>;
> > +			clocks = <&cpg CPG_MOD 607>;
> > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > +			resets = <&cpg 607>;
> > +			iommus = <&ipmmu_vp0 5>;
> > +		};
> > +
> > +		vspi0: vsp@fe9a0000 {
> > +			compatible = "renesas,vsp2";
> > +			reg = <0 0xfe9a0000 0 0x8000>;
> > +			interrupts = <GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>;
> > +			clocks = <&cpg CPG_MOD 622>;
> 
> R-Car Series, 3rd Generation, v1.00, Table Table 8A.21 indicates
> that this clock should be <&cpg CPG_MOD 631>. The clock above is
> (according to my reading of the documentation) correctly
> used for vspd1 below.

Bad copy and paste, thank you for pointing it out, it will be fixed in v3.

> > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > +			resets = <&cpg 631>;
> > +			renesas,fcp = <&fcpvi0>;
> > +		};
> > +
> > +		fcpvi0: fcp@fe9af000 {
> > +			compatible = "renesas,fcpv";
> > +			reg = <0 0xfe9af000 0 0x200>;
> > +			clocks = <&cpg CPG_MOD 611>;
> > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > +			resets = <&cpg 611>;
> > +			iommus = <&ipmmu_vp0 8>;
> > +		};
> > +
> > +		vspd0: vsp@fea20000 {
> > +			compatible = "renesas,vsp2";
> > +			reg = <0 0xfea20000 0 0x7000>;
> > +			interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
> > +			clocks = <&cpg CPG_MOD 623>;
> > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > +			resets = <&cpg 623>;
> > +			renesas,fcp = <&fcpvd0>;
> > +		};
> > +
> > +		fcpvd0: fcp@fea27000 {
> > +			compatible = "renesas,fcpv";
> > +			reg = <0 0xfea27000 0 0x200>;
> > +			clocks = <&cpg CPG_MOD 603>;
> > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > +			resets = <&cpg 603>;
> > +			iommus = <&ipmmu_vi0 8>;
> > +		};
> > +
> > +		vspd1: vsp@fea28000 {
> > +			compatible = "renesas,vsp2";
> > +			reg = <0 0xfea28000 0 0x7000>;
> > +			interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
> > +			clocks = <&cpg CPG_MOD 622>;
> > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > +			resets = <&cpg 622>;
> > +			renesas,fcp = <&fcpvd1>;
> > +		};
> > +
> > +		fcpvd1: fcp@fea2f000 {
> > +			compatible = "renesas,fcpv";
> > +			reg = <0 0xfea2f000 0 0x200>;
> > +			clocks = <&cpg CPG_MOD 602>;
> > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > +			resets = <&cpg 602>;
> > +			iommus = <&ipmmu_vi0 9>;
> > +		};
> > +
> > +		du: display@feb00000 {
> > +			compatible = "renesas,du-r8a77990";
> > +			reg = <0 0xfeb00000 0 0x80000>;
> > +			interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
> > +				     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
> > +			clocks = <&cpg CPG_MOD 724>,
> > +				 <&cpg CPG_MOD 723>;
> > +			clock-names = "du.0", "du.1";
> > +			vsps = <&vspd0 0 &vspd1 0>;
> > +			status = "disabled";
> > +
> > +			ports {
> > +				#address-cells = <1>;
> > +				#size-cells = <0>;
> > +
> > +				port@0 {
> > +					reg = <0>;
> > +					du_out_rgb: endpoint {
> > +					};
> > +				};
> > +
> > +				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,r8a77990-lvds";
> > +			reg = <0 0xfeb90000 0 0x20>;
> > +			clocks = <&cpg CPG_MOD 727>;
> > +			power-domains = <&sysc R8A77990_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,r8a77990-lvds";
> > +			reg = <0 0xfeb90100 0 0x20>;
> > +			clocks = <&cpg CPG_MOD 727>;
> > +			power-domains = <&sysc R8A77990_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 {
> > +					};
> > +				};
> > +			};
> > +		};
> > +
> >  		prr: chipid@fff00044 {
> >  			compatible = "renesas,prr";
> >  			reg = <0 0xfff00044 0 4>;

-- 
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] 118+ messages in thread

* Re: [PATCH v2 13/16] arm64: dts: renesas: r8a77990: Add display output support
  2018-09-17  8:14       ` Simon Horman
@ 2018-09-17  8:47         ` Laurent Pinchart
  -1 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-17  8:47 UTC (permalink / raw)
  To: Simon Horman
  Cc: Laurent Pinchart, dri-devel, linux-renesas-soc, Ulrich Hecht,
	Kieran Bingham

Hi Simon,

On Monday, 17 September 2018 11:14:20 EEST Simon Horman wrote:
> On Mon, Sep 17, 2018 at 09:50:55AM +0200, Simon Horman wrote:
> > On Fri, Sep 14, 2018 at 12:10:43PM +0300, Laurent Pinchart wrote:
> > > The R8A77990 (E3) platform has one RGB output and two LVDS outputs
> > > connected to the DU. Add the DT nodes for the DU, LVDS encoders and
> > > supporting VSP and FCP.
> > > 
> > > Signed-off-by: Laurent Pinchart
> > > <laurent.pinchart+renesas@ideasonboard.com>
> > > Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> > > ---
> > > 
> > >  arch/arm64/boot/dts/renesas/r8a77990.dtsi | 167 +++++++++++++++++++++++
> > >  1 file changed, 167 insertions(+)
> > > 
> > > diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > b/arch/arm64/boot/dts/renesas/r8a77990.dtsi index
> > > abb14af76c0e..600074ca3ee5 100644
> > > --- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > +++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > @@ -537,6 +537,173 @@
> > > 
> > >  			resets = <&cpg 408>;
> > >  		
> > >  		};
> > 
> > These nodes should be placed after the gic to preserve the sorting
> > of nodes by bus address and then IP block.
> > 
> > > +		vspb0: vsp@fe960000 {
> > > +			compatible = "renesas,vsp2";
> > > +			reg = <0 0xfe960000 0 0x8000>;
> > > +			interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
> > > +			clocks = <&cpg CPG_MOD 626>;
> > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > +			resets = <&cpg 626>;
> > > +			renesas,fcp = <&fcpvb0>;
> > > +		};
> > > +
> > > +		fcpvb0: fcp@fe96f000 {
> > > +			compatible = "renesas,fcpv";
> > > +			reg = <0 0xfe96f000 0 0x200>;
> > > +			clocks = <&cpg CPG_MOD 607>;
> > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > +			resets = <&cpg 607>;
> > > +			iommus = <&ipmmu_vp0 5>;
> > > +		};
> > > +
> > > +		vspi0: vsp@fe9a0000 {
> > > +			compatible = "renesas,vsp2";
> > > +			reg = <0 0xfe9a0000 0 0x8000>;
> > > +			interrupts = <GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>;
> > > +			clocks = <&cpg CPG_MOD 622>;
> > 
> > R-Car Series, 3rd Generation, v1.00, Table Table 8A.21 indicates
> > that this clock should be <&cpg CPG_MOD 631>. The clock above is
> > (according to my reading of the documentation) correctly
> > used for vspd1 below.
> > 
> > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > +			resets = <&cpg 631>;
> > > +			renesas,fcp = <&fcpvi0>;
> > > +		};
> > > +
> > > +		fcpvi0: fcp@fe9af000 {
> > > +			compatible = "renesas,fcpv";
> > > +			reg = <0 0xfe9af000 0 0x200>;
> > > +			clocks = <&cpg CPG_MOD 611>;
> > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > +			resets = <&cpg 611>;
> > > +			iommus = <&ipmmu_vp0 8>;
> > > +		};
> > > +
> > > +		vspd0: vsp@fea20000 {
> > > +			compatible = "renesas,vsp2";
> > > +			reg = <0 0xfea20000 0 0x7000>;
> > > +			interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
> > > +			clocks = <&cpg CPG_MOD 623>;
> > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > +			resets = <&cpg 623>;
> > > +			renesas,fcp = <&fcpvd0>;
> > > +		};
> > > +
> > > +		fcpvd0: fcp@fea27000 {
> > > +			compatible = "renesas,fcpv";
> > > +			reg = <0 0xfea27000 0 0x200>;
> > > +			clocks = <&cpg CPG_MOD 603>;
> > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > +			resets = <&cpg 603>;
> > > +			iommus = <&ipmmu_vi0 8>;
> > > +		};
> > > +
> > > +		vspd1: vsp@fea28000 {
> > > +			compatible = "renesas,vsp2";
> > > +			reg = <0 0xfea28000 0 0x7000>;
> > > +			interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
> > > +			clocks = <&cpg CPG_MOD 622>;
> > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > +			resets = <&cpg 622>;
> > > +			renesas,fcp = <&fcpvd1>;
> > > +		};
> > > +
> > > +		fcpvd1: fcp@fea2f000 {
> > > +			compatible = "renesas,fcpv";
> > > +			reg = <0 0xfea2f000 0 0x200>;
> > > +			clocks = <&cpg CPG_MOD 602>;
> > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > +			resets = <&cpg 602>;
> > > +			iommus = <&ipmmu_vi0 9>;
> > > +		};
> > > +
> > > +		du: display@feb00000 {
> > > +			compatible = "renesas,du-r8a77990";
> > > +			reg = <0 0xfeb00000 0 0x80000>;
> > > +			interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
> > > +				     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
> > > +			clocks = <&cpg CPG_MOD 724>,
> > > +				 <&cpg CPG_MOD 723>;
> > > +			clock-names = "du.0", "du.1";
> > > +			vsps = <&vspd0 0 &vspd1 0>;
> > > +			status = "disabled";
> > > +
> > > +			ports {
> > > +				#address-cells = <1>;
> > > +				#size-cells = <0>;
> > > +
> > > +				port@0 {
> > > +					reg = <0>;
> > > +					du_out_rgb: endpoint {
> > > +					};
> > > +				};
> > > +
> > > +				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,r8a77990-lvds";
> > > +			reg = <0 0xfeb90000 0 0x20>;
> > > +			clocks = <&cpg CPG_MOD 727>;
> > > +			power-domains = <&sysc R8A77990_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,r8a77990-lvds";
> > > +			reg = <0 0xfeb90100 0 0x20>;
> > > +			clocks = <&cpg CPG_MOD 727>;
> > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > +			resets = <&cpg 726>;
> 
> Also, is the missmatch between the index for the clock and reset
> intentional?

It is. According to the datasheet, the two LVDS encoders have different module 
stop bits, but share the same reset (lovely hardware design, it will be fun to 
support that in the driver :-S).

> > > +			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 {
> > > +					};
> > > +				};
> > > +			};
> > > +		};
> > > +
> > >  		prr: chipid@fff00044 {
> > >  			compatible = "renesas,prr";
> > >  			reg = <0 0xfff00044 0 4>;

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v2 13/16] arm64: dts: renesas: r8a77990: Add display output support
@ 2018-09-17  8:47         ` Laurent Pinchart
  0 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-17  8:47 UTC (permalink / raw)
  To: Simon Horman
  Cc: linux-renesas-soc, Ulrich Hecht, Laurent Pinchart,
	Kieran Bingham, dri-devel

Hi Simon,

On Monday, 17 September 2018 11:14:20 EEST Simon Horman wrote:
> On Mon, Sep 17, 2018 at 09:50:55AM +0200, Simon Horman wrote:
> > On Fri, Sep 14, 2018 at 12:10:43PM +0300, Laurent Pinchart wrote:
> > > The R8A77990 (E3) platform has one RGB output and two LVDS outputs
> > > connected to the DU. Add the DT nodes for the DU, LVDS encoders and
> > > supporting VSP and FCP.
> > > 
> > > Signed-off-by: Laurent Pinchart
> > > <laurent.pinchart+renesas@ideasonboard.com>
> > > Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> > > ---
> > > 
> > >  arch/arm64/boot/dts/renesas/r8a77990.dtsi | 167 +++++++++++++++++++++++
> > >  1 file changed, 167 insertions(+)
> > > 
> > > diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > b/arch/arm64/boot/dts/renesas/r8a77990.dtsi index
> > > abb14af76c0e..600074ca3ee5 100644
> > > --- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > +++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > @@ -537,6 +537,173 @@
> > > 
> > >  			resets = <&cpg 408>;
> > >  		
> > >  		};
> > 
> > These nodes should be placed after the gic to preserve the sorting
> > of nodes by bus address and then IP block.
> > 
> > > +		vspb0: vsp@fe960000 {
> > > +			compatible = "renesas,vsp2";
> > > +			reg = <0 0xfe960000 0 0x8000>;
> > > +			interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
> > > +			clocks = <&cpg CPG_MOD 626>;
> > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > +			resets = <&cpg 626>;
> > > +			renesas,fcp = <&fcpvb0>;
> > > +		};
> > > +
> > > +		fcpvb0: fcp@fe96f000 {
> > > +			compatible = "renesas,fcpv";
> > > +			reg = <0 0xfe96f000 0 0x200>;
> > > +			clocks = <&cpg CPG_MOD 607>;
> > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > +			resets = <&cpg 607>;
> > > +			iommus = <&ipmmu_vp0 5>;
> > > +		};
> > > +
> > > +		vspi0: vsp@fe9a0000 {
> > > +			compatible = "renesas,vsp2";
> > > +			reg = <0 0xfe9a0000 0 0x8000>;
> > > +			interrupts = <GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>;
> > > +			clocks = <&cpg CPG_MOD 622>;
> > 
> > R-Car Series, 3rd Generation, v1.00, Table Table 8A.21 indicates
> > that this clock should be <&cpg CPG_MOD 631>. The clock above is
> > (according to my reading of the documentation) correctly
> > used for vspd1 below.
> > 
> > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > +			resets = <&cpg 631>;
> > > +			renesas,fcp = <&fcpvi0>;
> > > +		};
> > > +
> > > +		fcpvi0: fcp@fe9af000 {
> > > +			compatible = "renesas,fcpv";
> > > +			reg = <0 0xfe9af000 0 0x200>;
> > > +			clocks = <&cpg CPG_MOD 611>;
> > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > +			resets = <&cpg 611>;
> > > +			iommus = <&ipmmu_vp0 8>;
> > > +		};
> > > +
> > > +		vspd0: vsp@fea20000 {
> > > +			compatible = "renesas,vsp2";
> > > +			reg = <0 0xfea20000 0 0x7000>;
> > > +			interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
> > > +			clocks = <&cpg CPG_MOD 623>;
> > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > +			resets = <&cpg 623>;
> > > +			renesas,fcp = <&fcpvd0>;
> > > +		};
> > > +
> > > +		fcpvd0: fcp@fea27000 {
> > > +			compatible = "renesas,fcpv";
> > > +			reg = <0 0xfea27000 0 0x200>;
> > > +			clocks = <&cpg CPG_MOD 603>;
> > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > +			resets = <&cpg 603>;
> > > +			iommus = <&ipmmu_vi0 8>;
> > > +		};
> > > +
> > > +		vspd1: vsp@fea28000 {
> > > +			compatible = "renesas,vsp2";
> > > +			reg = <0 0xfea28000 0 0x7000>;
> > > +			interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
> > > +			clocks = <&cpg CPG_MOD 622>;
> > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > +			resets = <&cpg 622>;
> > > +			renesas,fcp = <&fcpvd1>;
> > > +		};
> > > +
> > > +		fcpvd1: fcp@fea2f000 {
> > > +			compatible = "renesas,fcpv";
> > > +			reg = <0 0xfea2f000 0 0x200>;
> > > +			clocks = <&cpg CPG_MOD 602>;
> > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > +			resets = <&cpg 602>;
> > > +			iommus = <&ipmmu_vi0 9>;
> > > +		};
> > > +
> > > +		du: display@feb00000 {
> > > +			compatible = "renesas,du-r8a77990";
> > > +			reg = <0 0xfeb00000 0 0x80000>;
> > > +			interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
> > > +				     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
> > > +			clocks = <&cpg CPG_MOD 724>,
> > > +				 <&cpg CPG_MOD 723>;
> > > +			clock-names = "du.0", "du.1";
> > > +			vsps = <&vspd0 0 &vspd1 0>;
> > > +			status = "disabled";
> > > +
> > > +			ports {
> > > +				#address-cells = <1>;
> > > +				#size-cells = <0>;
> > > +
> > > +				port@0 {
> > > +					reg = <0>;
> > > +					du_out_rgb: endpoint {
> > > +					};
> > > +				};
> > > +
> > > +				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,r8a77990-lvds";
> > > +			reg = <0 0xfeb90000 0 0x20>;
> > > +			clocks = <&cpg CPG_MOD 727>;
> > > +			power-domains = <&sysc R8A77990_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,r8a77990-lvds";
> > > +			reg = <0 0xfeb90100 0 0x20>;
> > > +			clocks = <&cpg CPG_MOD 727>;
> > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > +			resets = <&cpg 726>;
> 
> Also, is the missmatch between the index for the clock and reset
> intentional?

It is. According to the datasheet, the two LVDS encoders have different module 
stop bits, but share the same reset (lovely hardware design, it will be fun to 
support that in the driver :-S).

> > > +			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 {
> > > +					};
> > > +				};
> > > +			};
> > > +		};
> > > +
> > >  		prr: chipid@fff00044 {
> > >  			compatible = "renesas,prr";
> > >  			reg = <0 0xfff00044 0 4>;

-- 
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] 118+ messages in thread

* Re: [PATCH v2 13/16] arm64: dts: renesas: r8a77990: Add display output support
  2018-09-17  8:38       ` Laurent Pinchart
@ 2018-09-17  8:51         ` Simon Horman
  -1 siblings, 0 replies; 118+ messages in thread
From: Simon Horman @ 2018-09-17  8:51 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Laurent Pinchart, dri-devel, linux-renesas-soc, Ulrich Hecht,
	Kieran Bingham

On Mon, Sep 17, 2018 at 11:38:43AM +0300, Laurent Pinchart wrote:
> Hi Simon,
> 
> On Monday, 17 September 2018 10:50:55 EEST Simon Horman wrote:
> > On Fri, Sep 14, 2018 at 12:10:43PM +0300, Laurent Pinchart wrote:
> > > The R8A77990 (E3) platform has one RGB output and two LVDS outputs
> > > connected to the DU. Add the DT nodes for the DU, LVDS encoders and
> > > supporting VSP and FCP.
> > > 
> > > Signed-off-by: Laurent Pinchart
> > > <laurent.pinchart+renesas@ideasonboard.com>
> > > Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> > > ---
> > > 
> > >  arch/arm64/boot/dts/renesas/r8a77990.dtsi | 167 +++++++++++++++++++++++++
> > >  1 file changed, 167 insertions(+)
> > > 
> > > diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > b/arch/arm64/boot/dts/renesas/r8a77990.dtsi index
> > > abb14af76c0e..600074ca3ee5 100644
> > > --- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > +++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > @@ -537,6 +537,173 @@
> > >  			resets = <&cpg 408>;
> > >  		};
> > 
> > These nodes should be placed after the gic to preserve the sorting
> > of nodes by bus address and then IP block.
> 
> Aren't they already ? :-)

Git didn't seem to think so. But its not a big deal,
I can fix this up locally.

> > > +		vspb0: vsp@fe960000 {
> > > +			compatible = "renesas,vsp2";
> > > +			reg = <0 0xfe960000 0 0x8000>;
> > > +			interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
> > > +			clocks = <&cpg CPG_MOD 626>;
> > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > +			resets = <&cpg 626>;
> > > +			renesas,fcp = <&fcpvb0>;
> > > +		};
> > > +
> > > +		fcpvb0: fcp@fe96f000 {
> > > +			compatible = "renesas,fcpv";
> > > +			reg = <0 0xfe96f000 0 0x200>;
> > > +			clocks = <&cpg CPG_MOD 607>;
> > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > +			resets = <&cpg 607>;
> > > +			iommus = <&ipmmu_vp0 5>;
> > > +		};
> > > +
> > > +		vspi0: vsp@fe9a0000 {
> > > +			compatible = "renesas,vsp2";
> > > +			reg = <0 0xfe9a0000 0 0x8000>;
> > > +			interrupts = <GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>;
> > > +			clocks = <&cpg CPG_MOD 622>;
> > 
> > R-Car Series, 3rd Generation, v1.00, Table Table 8A.21 indicates
> > that this clock should be <&cpg CPG_MOD 631>. The clock above is
> > (according to my reading of the documentation) correctly
> > used for vspd1 below.
> 
> Bad copy and paste, thank you for pointing it out, it will be fixed in v3.
> 
> > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > +			resets = <&cpg 631>;
> > > +			renesas,fcp = <&fcpvi0>;
> > > +		};
> > > +
> > > +		fcpvi0: fcp@fe9af000 {
> > > +			compatible = "renesas,fcpv";
> > > +			reg = <0 0xfe9af000 0 0x200>;
> > > +			clocks = <&cpg CPG_MOD 611>;
> > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > +			resets = <&cpg 611>;
> > > +			iommus = <&ipmmu_vp0 8>;
> > > +		};
> > > +
> > > +		vspd0: vsp@fea20000 {
> > > +			compatible = "renesas,vsp2";
> > > +			reg = <0 0xfea20000 0 0x7000>;
> > > +			interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
> > > +			clocks = <&cpg CPG_MOD 623>;
> > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > +			resets = <&cpg 623>;
> > > +			renesas,fcp = <&fcpvd0>;
> > > +		};
> > > +
> > > +		fcpvd0: fcp@fea27000 {
> > > +			compatible = "renesas,fcpv";
> > > +			reg = <0 0xfea27000 0 0x200>;
> > > +			clocks = <&cpg CPG_MOD 603>;
> > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > +			resets = <&cpg 603>;
> > > +			iommus = <&ipmmu_vi0 8>;
> > > +		};
> > > +
> > > +		vspd1: vsp@fea28000 {
> > > +			compatible = "renesas,vsp2";
> > > +			reg = <0 0xfea28000 0 0x7000>;
> > > +			interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
> > > +			clocks = <&cpg CPG_MOD 622>;
> > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > +			resets = <&cpg 622>;
> > > +			renesas,fcp = <&fcpvd1>;
> > > +		};
> > > +
> > > +		fcpvd1: fcp@fea2f000 {
> > > +			compatible = "renesas,fcpv";
> > > +			reg = <0 0xfea2f000 0 0x200>;
> > > +			clocks = <&cpg CPG_MOD 602>;
> > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > +			resets = <&cpg 602>;
> > > +			iommus = <&ipmmu_vi0 9>;
> > > +		};
> > > +
> > > +		du: display@feb00000 {
> > > +			compatible = "renesas,du-r8a77990";
> > > +			reg = <0 0xfeb00000 0 0x80000>;
> > > +			interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
> > > +				     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
> > > +			clocks = <&cpg CPG_MOD 724>,
> > > +				 <&cpg CPG_MOD 723>;
> > > +			clock-names = "du.0", "du.1";
> > > +			vsps = <&vspd0 0 &vspd1 0>;
> > > +			status = "disabled";
> > > +
> > > +			ports {
> > > +				#address-cells = <1>;
> > > +				#size-cells = <0>;
> > > +
> > > +				port@0 {
> > > +					reg = <0>;
> > > +					du_out_rgb: endpoint {
> > > +					};
> > > +				};
> > > +
> > > +				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,r8a77990-lvds";
> > > +			reg = <0 0xfeb90000 0 0x20>;
> > > +			clocks = <&cpg CPG_MOD 727>;
> > > +			power-domains = <&sysc R8A77990_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,r8a77990-lvds";
> > > +			reg = <0 0xfeb90100 0 0x20>;
> > > +			clocks = <&cpg CPG_MOD 727>;
> > > +			power-domains = <&sysc R8A77990_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 {
> > > +					};
> > > +				};
> > > +			};
> > > +		};
> > > +
> > >  		prr: chipid@fff00044 {
> > >  			compatible = "renesas,prr";
> > >  			reg = <0 0xfff00044 0 4>;
> 
> -- 
> Regards,
> 
> Laurent Pinchart
> 
> 
> 

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

* Re: [PATCH v2 13/16] arm64: dts: renesas: r8a77990: Add display output support
@ 2018-09-17  8:51         ` Simon Horman
  0 siblings, 0 replies; 118+ messages in thread
From: Simon Horman @ 2018-09-17  8:51 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-renesas-soc, Ulrich Hecht, Laurent Pinchart,
	Kieran Bingham, dri-devel

On Mon, Sep 17, 2018 at 11:38:43AM +0300, Laurent Pinchart wrote:
> Hi Simon,
> 
> On Monday, 17 September 2018 10:50:55 EEST Simon Horman wrote:
> > On Fri, Sep 14, 2018 at 12:10:43PM +0300, Laurent Pinchart wrote:
> > > The R8A77990 (E3) platform has one RGB output and two LVDS outputs
> > > connected to the DU. Add the DT nodes for the DU, LVDS encoders and
> > > supporting VSP and FCP.
> > > 
> > > Signed-off-by: Laurent Pinchart
> > > <laurent.pinchart+renesas@ideasonboard.com>
> > > Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> > > ---
> > > 
> > >  arch/arm64/boot/dts/renesas/r8a77990.dtsi | 167 +++++++++++++++++++++++++
> > >  1 file changed, 167 insertions(+)
> > > 
> > > diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > b/arch/arm64/boot/dts/renesas/r8a77990.dtsi index
> > > abb14af76c0e..600074ca3ee5 100644
> > > --- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > +++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > @@ -537,6 +537,173 @@
> > >  			resets = <&cpg 408>;
> > >  		};
> > 
> > These nodes should be placed after the gic to preserve the sorting
> > of nodes by bus address and then IP block.
> 
> Aren't they already ? :-)

Git didn't seem to think so. But its not a big deal,
I can fix this up locally.

> > > +		vspb0: vsp@fe960000 {
> > > +			compatible = "renesas,vsp2";
> > > +			reg = <0 0xfe960000 0 0x8000>;
> > > +			interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
> > > +			clocks = <&cpg CPG_MOD 626>;
> > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > +			resets = <&cpg 626>;
> > > +			renesas,fcp = <&fcpvb0>;
> > > +		};
> > > +
> > > +		fcpvb0: fcp@fe96f000 {
> > > +			compatible = "renesas,fcpv";
> > > +			reg = <0 0xfe96f000 0 0x200>;
> > > +			clocks = <&cpg CPG_MOD 607>;
> > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > +			resets = <&cpg 607>;
> > > +			iommus = <&ipmmu_vp0 5>;
> > > +		};
> > > +
> > > +		vspi0: vsp@fe9a0000 {
> > > +			compatible = "renesas,vsp2";
> > > +			reg = <0 0xfe9a0000 0 0x8000>;
> > > +			interrupts = <GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>;
> > > +			clocks = <&cpg CPG_MOD 622>;
> > 
> > R-Car Series, 3rd Generation, v1.00, Table Table 8A.21 indicates
> > that this clock should be <&cpg CPG_MOD 631>. The clock above is
> > (according to my reading of the documentation) correctly
> > used for vspd1 below.
> 
> Bad copy and paste, thank you for pointing it out, it will be fixed in v3.
> 
> > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > +			resets = <&cpg 631>;
> > > +			renesas,fcp = <&fcpvi0>;
> > > +		};
> > > +
> > > +		fcpvi0: fcp@fe9af000 {
> > > +			compatible = "renesas,fcpv";
> > > +			reg = <0 0xfe9af000 0 0x200>;
> > > +			clocks = <&cpg CPG_MOD 611>;
> > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > +			resets = <&cpg 611>;
> > > +			iommus = <&ipmmu_vp0 8>;
> > > +		};
> > > +
> > > +		vspd0: vsp@fea20000 {
> > > +			compatible = "renesas,vsp2";
> > > +			reg = <0 0xfea20000 0 0x7000>;
> > > +			interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
> > > +			clocks = <&cpg CPG_MOD 623>;
> > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > +			resets = <&cpg 623>;
> > > +			renesas,fcp = <&fcpvd0>;
> > > +		};
> > > +
> > > +		fcpvd0: fcp@fea27000 {
> > > +			compatible = "renesas,fcpv";
> > > +			reg = <0 0xfea27000 0 0x200>;
> > > +			clocks = <&cpg CPG_MOD 603>;
> > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > +			resets = <&cpg 603>;
> > > +			iommus = <&ipmmu_vi0 8>;
> > > +		};
> > > +
> > > +		vspd1: vsp@fea28000 {
> > > +			compatible = "renesas,vsp2";
> > > +			reg = <0 0xfea28000 0 0x7000>;
> > > +			interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
> > > +			clocks = <&cpg CPG_MOD 622>;
> > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > +			resets = <&cpg 622>;
> > > +			renesas,fcp = <&fcpvd1>;
> > > +		};
> > > +
> > > +		fcpvd1: fcp@fea2f000 {
> > > +			compatible = "renesas,fcpv";
> > > +			reg = <0 0xfea2f000 0 0x200>;
> > > +			clocks = <&cpg CPG_MOD 602>;
> > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > +			resets = <&cpg 602>;
> > > +			iommus = <&ipmmu_vi0 9>;
> > > +		};
> > > +
> > > +		du: display@feb00000 {
> > > +			compatible = "renesas,du-r8a77990";
> > > +			reg = <0 0xfeb00000 0 0x80000>;
> > > +			interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
> > > +				     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
> > > +			clocks = <&cpg CPG_MOD 724>,
> > > +				 <&cpg CPG_MOD 723>;
> > > +			clock-names = "du.0", "du.1";
> > > +			vsps = <&vspd0 0 &vspd1 0>;
> > > +			status = "disabled";
> > > +
> > > +			ports {
> > > +				#address-cells = <1>;
> > > +				#size-cells = <0>;
> > > +
> > > +				port@0 {
> > > +					reg = <0>;
> > > +					du_out_rgb: endpoint {
> > > +					};
> > > +				};
> > > +
> > > +				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,r8a77990-lvds";
> > > +			reg = <0 0xfeb90000 0 0x20>;
> > > +			clocks = <&cpg CPG_MOD 727>;
> > > +			power-domains = <&sysc R8A77990_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,r8a77990-lvds";
> > > +			reg = <0 0xfeb90100 0 0x20>;
> > > +			clocks = <&cpg CPG_MOD 727>;
> > > +			power-domains = <&sysc R8A77990_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 {
> > > +					};
> > > +				};
> > > +			};
> > > +		};
> > > +
> > >  		prr: chipid@fff00044 {
> > >  			compatible = "renesas,prr";
> > >  			reg = <0 0xfff00044 0 4>;
> 
> -- 
> 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] 118+ messages in thread

* Re: [PATCH v2 13/16] arm64: dts: renesas: r8a77990: Add display output support
  2018-09-17  8:47         ` Laurent Pinchart
@ 2018-09-17  8:54           ` Laurent Pinchart
  -1 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-17  8:54 UTC (permalink / raw)
  To: Simon Horman
  Cc: Laurent Pinchart, dri-devel, linux-renesas-soc, Ulrich Hecht,
	Kieran Bingham

Hi Simon,

On Monday, 17 September 2018 11:47:15 EEST Laurent Pinchart wrote:
> On Monday, 17 September 2018 11:14:20 EEST Simon Horman wrote:
> > On Mon, Sep 17, 2018 at 09:50:55AM +0200, Simon Horman wrote:
> > > On Fri, Sep 14, 2018 at 12:10:43PM +0300, Laurent Pinchart wrote:
> > > > The R8A77990 (E3) platform has one RGB output and two LVDS outputs
> > > > connected to the DU. Add the DT nodes for the DU, LVDS encoders and
> > > > supporting VSP and FCP.
> > > > 
> > > > Signed-off-by: Laurent Pinchart
> > > > <laurent.pinchart+renesas@ideasonboard.com>
> > > > Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> > > > ---
> > > > 
> > > >  arch/arm64/boot/dts/renesas/r8a77990.dtsi | 167
> > > >  +++++++++++++++++++++++
> > > >  1 file changed, 167 insertions(+)
> > > > 
> > > > diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > > b/arch/arm64/boot/dts/renesas/r8a77990.dtsi index
> > > > abb14af76c0e..600074ca3ee5 100644
> > > > --- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > > +++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > > @@ -537,6 +537,173 @@
> > > > 
> > > >  			resets = <&cpg 408>;
> > > >  		
> > > >  		};
> > > 
> > > These nodes should be placed after the gic to preserve the sorting
> > > of nodes by bus address and then IP block.
> > > 
> > > > +		vspb0: vsp@fe960000 {
> > > > +			compatible = "renesas,vsp2";
> > > > +			reg = <0 0xfe960000 0 0x8000>;
> > > > +			interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
> > > > +			clocks = <&cpg CPG_MOD 626>;
> > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > +			resets = <&cpg 626>;
> > > > +			renesas,fcp = <&fcpvb0>;
> > > > +		};
> > > > +
> > > > +		fcpvb0: fcp@fe96f000 {
> > > > +			compatible = "renesas,fcpv";
> > > > +			reg = <0 0xfe96f000 0 0x200>;
> > > > +			clocks = <&cpg CPG_MOD 607>;
> > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > +			resets = <&cpg 607>;
> > > > +			iommus = <&ipmmu_vp0 5>;
> > > > +		};
> > > > +
> > > > +		vspi0: vsp@fe9a0000 {
> > > > +			compatible = "renesas,vsp2";
> > > > +			reg = <0 0xfe9a0000 0 0x8000>;
> > > > +			interrupts = <GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>;
> > > > +			clocks = <&cpg CPG_MOD 622>;
> > > 
> > > R-Car Series, 3rd Generation, v1.00, Table Table 8A.21 indicates
> > > that this clock should be <&cpg CPG_MOD 631>. The clock above is
> > > (according to my reading of the documentation) correctly
> > > used for vspd1 below.
> > > 
> > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > +			resets = <&cpg 631>;
> > > > +			renesas,fcp = <&fcpvi0>;
> > > > +		};
> > > > +
> > > > +		fcpvi0: fcp@fe9af000 {
> > > > +			compatible = "renesas,fcpv";
> > > > +			reg = <0 0xfe9af000 0 0x200>;
> > > > +			clocks = <&cpg CPG_MOD 611>;
> > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > +			resets = <&cpg 611>;
> > > > +			iommus = <&ipmmu_vp0 8>;
> > > > +		};
> > > > +
> > > > +		vspd0: vsp@fea20000 {
> > > > +			compatible = "renesas,vsp2";
> > > > +			reg = <0 0xfea20000 0 0x7000>;
> > > > +			interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
> > > > +			clocks = <&cpg CPG_MOD 623>;
> > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > +			resets = <&cpg 623>;
> > > > +			renesas,fcp = <&fcpvd0>;
> > > > +		};
> > > > +
> > > > +		fcpvd0: fcp@fea27000 {
> > > > +			compatible = "renesas,fcpv";
> > > > +			reg = <0 0xfea27000 0 0x200>;
> > > > +			clocks = <&cpg CPG_MOD 603>;
> > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > +			resets = <&cpg 603>;
> > > > +			iommus = <&ipmmu_vi0 8>;
> > > > +		};
> > > > +
> > > > +		vspd1: vsp@fea28000 {
> > > > +			compatible = "renesas,vsp2";
> > > > +			reg = <0 0xfea28000 0 0x7000>;
> > > > +			interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
> > > > +			clocks = <&cpg CPG_MOD 622>;
> > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > +			resets = <&cpg 622>;
> > > > +			renesas,fcp = <&fcpvd1>;
> > > > +		};
> > > > +
> > > > +		fcpvd1: fcp@fea2f000 {
> > > > +			compatible = "renesas,fcpv";
> > > > +			reg = <0 0xfea2f000 0 0x200>;
> > > > +			clocks = <&cpg CPG_MOD 602>;
> > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > +			resets = <&cpg 602>;
> > > > +			iommus = <&ipmmu_vi0 9>;
> > > > +		};
> > > > +
> > > > +		du: display@feb00000 {
> > > > +			compatible = "renesas,du-r8a77990";
> > > > +			reg = <0 0xfeb00000 0 0x80000>;
> > > > +			interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
> > > > +				     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
> > > > +			clocks = <&cpg CPG_MOD 724>,
> > > > +				 <&cpg CPG_MOD 723>;
> > > > +			clock-names = "du.0", "du.1";
> > > > +			vsps = <&vspd0 0 &vspd1 0>;
> > > > +			status = "disabled";
> > > > +
> > > > +			ports {
> > > > +				#address-cells = <1>;
> > > > +				#size-cells = <0>;
> > > > +
> > > > +				port@0 {
> > > > +					reg = <0>;
> > > > +					du_out_rgb: endpoint {
> > > > +					};
> > > > +				};
> > > > +
> > > > +				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,r8a77990-lvds";
> > > > +			reg = <0 0xfeb90000 0 0x20>;
> > > > +			clocks = <&cpg CPG_MOD 727>;
> > > > +			power-domains = <&sysc R8A77990_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,r8a77990-lvds";
> > > > +			reg = <0 0xfeb90100 0 0x20>;
> > > > +			clocks = <&cpg CPG_MOD 727>;
> > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > +			resets = <&cpg 726>;
> > 
> > Also, is the missmatch between the index for the clock and reset
> > intentional?
> 
> It is. According to the datasheet, the two LVDS encoders have different
> module stop bits, but share the same reset (lovely hardware design, it will
> be fun to support that in the driver :-S).

Sorry, I got it wrong. it's bit 725 that is shared between the two LVDS 
encoders, to reset the two LVDS PLLs together. The encoders themselves still 
have independent reset bits. I'll fix this.

> > > > +			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 {
> > > > +					};
> > > > +				};
> > > > +			};
> > > > +		};
> > > > +
> > > >  		prr: chipid@fff00044 {
> > > >  			compatible = "renesas,prr";
> > > >  			reg = <0 0xfff00044 0 4>;

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v2 13/16] arm64: dts: renesas: r8a77990: Add display output support
@ 2018-09-17  8:54           ` Laurent Pinchart
  0 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-17  8:54 UTC (permalink / raw)
  To: Simon Horman
  Cc: linux-renesas-soc, Ulrich Hecht, Laurent Pinchart,
	Kieran Bingham, dri-devel

Hi Simon,

On Monday, 17 September 2018 11:47:15 EEST Laurent Pinchart wrote:
> On Monday, 17 September 2018 11:14:20 EEST Simon Horman wrote:
> > On Mon, Sep 17, 2018 at 09:50:55AM +0200, Simon Horman wrote:
> > > On Fri, Sep 14, 2018 at 12:10:43PM +0300, Laurent Pinchart wrote:
> > > > The R8A77990 (E3) platform has one RGB output and two LVDS outputs
> > > > connected to the DU. Add the DT nodes for the DU, LVDS encoders and
> > > > supporting VSP and FCP.
> > > > 
> > > > Signed-off-by: Laurent Pinchart
> > > > <laurent.pinchart+renesas@ideasonboard.com>
> > > > Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> > > > ---
> > > > 
> > > >  arch/arm64/boot/dts/renesas/r8a77990.dtsi | 167
> > > >  +++++++++++++++++++++++
> > > >  1 file changed, 167 insertions(+)
> > > > 
> > > > diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > > b/arch/arm64/boot/dts/renesas/r8a77990.dtsi index
> > > > abb14af76c0e..600074ca3ee5 100644
> > > > --- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > > +++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > > @@ -537,6 +537,173 @@
> > > > 
> > > >  			resets = <&cpg 408>;
> > > >  		
> > > >  		};
> > > 
> > > These nodes should be placed after the gic to preserve the sorting
> > > of nodes by bus address and then IP block.
> > > 
> > > > +		vspb0: vsp@fe960000 {
> > > > +			compatible = "renesas,vsp2";
> > > > +			reg = <0 0xfe960000 0 0x8000>;
> > > > +			interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
> > > > +			clocks = <&cpg CPG_MOD 626>;
> > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > +			resets = <&cpg 626>;
> > > > +			renesas,fcp = <&fcpvb0>;
> > > > +		};
> > > > +
> > > > +		fcpvb0: fcp@fe96f000 {
> > > > +			compatible = "renesas,fcpv";
> > > > +			reg = <0 0xfe96f000 0 0x200>;
> > > > +			clocks = <&cpg CPG_MOD 607>;
> > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > +			resets = <&cpg 607>;
> > > > +			iommus = <&ipmmu_vp0 5>;
> > > > +		};
> > > > +
> > > > +		vspi0: vsp@fe9a0000 {
> > > > +			compatible = "renesas,vsp2";
> > > > +			reg = <0 0xfe9a0000 0 0x8000>;
> > > > +			interrupts = <GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>;
> > > > +			clocks = <&cpg CPG_MOD 622>;
> > > 
> > > R-Car Series, 3rd Generation, v1.00, Table Table 8A.21 indicates
> > > that this clock should be <&cpg CPG_MOD 631>. The clock above is
> > > (according to my reading of the documentation) correctly
> > > used for vspd1 below.
> > > 
> > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > +			resets = <&cpg 631>;
> > > > +			renesas,fcp = <&fcpvi0>;
> > > > +		};
> > > > +
> > > > +		fcpvi0: fcp@fe9af000 {
> > > > +			compatible = "renesas,fcpv";
> > > > +			reg = <0 0xfe9af000 0 0x200>;
> > > > +			clocks = <&cpg CPG_MOD 611>;
> > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > +			resets = <&cpg 611>;
> > > > +			iommus = <&ipmmu_vp0 8>;
> > > > +		};
> > > > +
> > > > +		vspd0: vsp@fea20000 {
> > > > +			compatible = "renesas,vsp2";
> > > > +			reg = <0 0xfea20000 0 0x7000>;
> > > > +			interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
> > > > +			clocks = <&cpg CPG_MOD 623>;
> > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > +			resets = <&cpg 623>;
> > > > +			renesas,fcp = <&fcpvd0>;
> > > > +		};
> > > > +
> > > > +		fcpvd0: fcp@fea27000 {
> > > > +			compatible = "renesas,fcpv";
> > > > +			reg = <0 0xfea27000 0 0x200>;
> > > > +			clocks = <&cpg CPG_MOD 603>;
> > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > +			resets = <&cpg 603>;
> > > > +			iommus = <&ipmmu_vi0 8>;
> > > > +		};
> > > > +
> > > > +		vspd1: vsp@fea28000 {
> > > > +			compatible = "renesas,vsp2";
> > > > +			reg = <0 0xfea28000 0 0x7000>;
> > > > +			interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
> > > > +			clocks = <&cpg CPG_MOD 622>;
> > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > +			resets = <&cpg 622>;
> > > > +			renesas,fcp = <&fcpvd1>;
> > > > +		};
> > > > +
> > > > +		fcpvd1: fcp@fea2f000 {
> > > > +			compatible = "renesas,fcpv";
> > > > +			reg = <0 0xfea2f000 0 0x200>;
> > > > +			clocks = <&cpg CPG_MOD 602>;
> > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > +			resets = <&cpg 602>;
> > > > +			iommus = <&ipmmu_vi0 9>;
> > > > +		};
> > > > +
> > > > +		du: display@feb00000 {
> > > > +			compatible = "renesas,du-r8a77990";
> > > > +			reg = <0 0xfeb00000 0 0x80000>;
> > > > +			interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
> > > > +				     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
> > > > +			clocks = <&cpg CPG_MOD 724>,
> > > > +				 <&cpg CPG_MOD 723>;
> > > > +			clock-names = "du.0", "du.1";
> > > > +			vsps = <&vspd0 0 &vspd1 0>;
> > > > +			status = "disabled";
> > > > +
> > > > +			ports {
> > > > +				#address-cells = <1>;
> > > > +				#size-cells = <0>;
> > > > +
> > > > +				port@0 {
> > > > +					reg = <0>;
> > > > +					du_out_rgb: endpoint {
> > > > +					};
> > > > +				};
> > > > +
> > > > +				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,r8a77990-lvds";
> > > > +			reg = <0 0xfeb90000 0 0x20>;
> > > > +			clocks = <&cpg CPG_MOD 727>;
> > > > +			power-domains = <&sysc R8A77990_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,r8a77990-lvds";
> > > > +			reg = <0 0xfeb90100 0 0x20>;
> > > > +			clocks = <&cpg CPG_MOD 727>;
> > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > +			resets = <&cpg 726>;
> > 
> > Also, is the missmatch between the index for the clock and reset
> > intentional?
> 
> It is. According to the datasheet, the two LVDS encoders have different
> module stop bits, but share the same reset (lovely hardware design, it will
> be fun to support that in the driver :-S).

Sorry, I got it wrong. it's bit 725 that is shared between the two LVDS 
encoders, to reset the two LVDS PLLs together. The encoders themselves still 
have independent reset bits. I'll fix this.

> > > > +			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 {
> > > > +					};
> > > > +				};
> > > > +			};
> > > > +		};
> > > > +
> > > >  		prr: chipid@fff00044 {
> > > >  			compatible = "renesas,prr";
> > > >  			reg = <0 0xfff00044 0 4>;

-- 
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] 118+ messages in thread

* Re: [PATCH v2 13/16] arm64: dts: renesas: r8a77990: Add display output support
  2018-09-17  8:54           ` Laurent Pinchart
@ 2018-09-17  8:59             ` Laurent Pinchart
  -1 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-17  8:59 UTC (permalink / raw)
  To: Simon Horman
  Cc: Laurent Pinchart, dri-devel, linux-renesas-soc, Ulrich Hecht,
	Kieran Bingham

On Monday, 17 September 2018 11:54:04 EEST Laurent Pinchart wrote:
> Hi Simon,
> 
> On Monday, 17 September 2018 11:47:15 EEST Laurent Pinchart wrote:
> > On Monday, 17 September 2018 11:14:20 EEST Simon Horman wrote:
> > > On Mon, Sep 17, 2018 at 09:50:55AM +0200, Simon Horman wrote:
> > > > On Fri, Sep 14, 2018 at 12:10:43PM +0300, Laurent Pinchart wrote:
> > > > > The R8A77990 (E3) platform has one RGB output and two LVDS outputs
> > > > > connected to the DU. Add the DT nodes for the DU, LVDS encoders and
> > > > > supporting VSP and FCP.
> > > > > 
> > > > > Signed-off-by: Laurent Pinchart
> > > > > <laurent.pinchart+renesas@ideasonboard.com>
> > > > > Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> > > > > ---
> > > > > 
> > > > >  arch/arm64/boot/dts/renesas/r8a77990.dtsi | 167
> > > > >  +++++++++++++++++++++++
> > > > >  1 file changed, 167 insertions(+)
> > > > > 
> > > > > diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > > > b/arch/arm64/boot/dts/renesas/r8a77990.dtsi index
> > > > > abb14af76c0e..600074ca3ee5 100644
> > > > > --- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > > > +++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > > > @@ -537,6 +537,173 @@
> > > > > 
> > > > >  			resets = <&cpg 408>;
> > > > >  		
> > > > >  		};
> > > > 
> > > > These nodes should be placed after the gic to preserve the sorting
> > > > of nodes by bus address and then IP block.
> > > > 
> > > > > +		vspb0: vsp@fe960000 {
> > > > > +			compatible = "renesas,vsp2";
> > > > > +			reg = <0 0xfe960000 0 0x8000>;
> > > > > +			interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
> > > > > +			clocks = <&cpg CPG_MOD 626>;
> > > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > > +			resets = <&cpg 626>;
> > > > > +			renesas,fcp = <&fcpvb0>;
> > > > > +		};
> > > > > +
> > > > > +		fcpvb0: fcp@fe96f000 {
> > > > > +			compatible = "renesas,fcpv";
> > > > > +			reg = <0 0xfe96f000 0 0x200>;
> > > > > +			clocks = <&cpg CPG_MOD 607>;
> > > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > > +			resets = <&cpg 607>;
> > > > > +			iommus = <&ipmmu_vp0 5>;
> > > > > +		};
> > > > > +
> > > > > +		vspi0: vsp@fe9a0000 {
> > > > > +			compatible = "renesas,vsp2";
> > > > > +			reg = <0 0xfe9a0000 0 0x8000>;
> > > > > +			interrupts = <GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>;
> > > > > +			clocks = <&cpg CPG_MOD 622>;
> > > > 
> > > > R-Car Series, 3rd Generation, v1.00, Table Table 8A.21 indicates
> > > > that this clock should be <&cpg CPG_MOD 631>. The clock above is
> > > > (according to my reading of the documentation) correctly
> > > > used for vspd1 below.
> > > > 
> > > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > > +			resets = <&cpg 631>;
> > > > > +			renesas,fcp = <&fcpvi0>;
> > > > > +		};
> > > > > +
> > > > > +		fcpvi0: fcp@fe9af000 {
> > > > > +			compatible = "renesas,fcpv";
> > > > > +			reg = <0 0xfe9af000 0 0x200>;
> > > > > +			clocks = <&cpg CPG_MOD 611>;
> > > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > > +			resets = <&cpg 611>;
> > > > > +			iommus = <&ipmmu_vp0 8>;
> > > > > +		};
> > > > > +
> > > > > +		vspd0: vsp@fea20000 {
> > > > > +			compatible = "renesas,vsp2";
> > > > > +			reg = <0 0xfea20000 0 0x7000>;
> > > > > +			interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
> > > > > +			clocks = <&cpg CPG_MOD 623>;
> > > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > > +			resets = <&cpg 623>;
> > > > > +			renesas,fcp = <&fcpvd0>;
> > > > > +		};
> > > > > +
> > > > > +		fcpvd0: fcp@fea27000 {
> > > > > +			compatible = "renesas,fcpv";
> > > > > +			reg = <0 0xfea27000 0 0x200>;
> > > > > +			clocks = <&cpg CPG_MOD 603>;
> > > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > > +			resets = <&cpg 603>;
> > > > > +			iommus = <&ipmmu_vi0 8>;
> > > > > +		};
> > > > > +
> > > > > +		vspd1: vsp@fea28000 {
> > > > > +			compatible = "renesas,vsp2";
> > > > > +			reg = <0 0xfea28000 0 0x7000>;
> > > > > +			interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
> > > > > +			clocks = <&cpg CPG_MOD 622>;
> > > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > > +			resets = <&cpg 622>;
> > > > > +			renesas,fcp = <&fcpvd1>;
> > > > > +		};
> > > > > +
> > > > > +		fcpvd1: fcp@fea2f000 {
> > > > > +			compatible = "renesas,fcpv";
> > > > > +			reg = <0 0xfea2f000 0 0x200>;
> > > > > +			clocks = <&cpg CPG_MOD 602>;
> > > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > > +			resets = <&cpg 602>;
> > > > > +			iommus = <&ipmmu_vi0 9>;
> > > > > +		};
> > > > > +
> > > > > +		du: display@feb00000 {
> > > > > +			compatible = "renesas,du-r8a77990";
> > > > > +			reg = <0 0xfeb00000 0 0x80000>;
> > > > > +			interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
> > > > > +				     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
> > > > > +			clocks = <&cpg CPG_MOD 724>,
> > > > > +				 <&cpg CPG_MOD 723>;
> > > > > +			clock-names = "du.0", "du.1";
> > > > > +			vsps = <&vspd0 0 &vspd1 0>;
> > > > > +			status = "disabled";
> > > > > +
> > > > > +			ports {
> > > > > +				#address-cells = <1>;
> > > > > +				#size-cells = <0>;
> > > > > +
> > > > > +				port@0 {
> > > > > +					reg = <0>;
> > > > > +					du_out_rgb: endpoint {
> > > > > +					};
> > > > > +				};
> > > > > +
> > > > > +				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,r8a77990-lvds";
> > > > > +			reg = <0 0xfeb90000 0 0x20>;
> > > > > +			clocks = <&cpg CPG_MOD 727>;
> > > > > +			power-domains = <&sysc R8A77990_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,r8a77990-lvds";
> > > > > +			reg = <0 0xfeb90100 0 0x20>;
> > > > > +			clocks = <&cpg CPG_MOD 727>;
> > > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > > +			resets = <&cpg 726>;
> > > 
> > > Also, is the missmatch between the index for the clock and reset
> > > intentional?
> > 
> > It is. According to the datasheet, the two LVDS encoders have different
> > module stop bits, but share the same reset (lovely hardware design, it
> > will be fun to support that in the driver :-S).
> 
> Sorry, I got it wrong. it's bit 725 that is shared between the two LVDS
> encoders, to reset the two LVDS PLLs together. The encoders themselves still
> have independent reset bits. I'll fix this.

And of course it's the clock you were commenting on, not the reset. *sigh*

According to the datasheets the two LVDS encoders share one MSTP. Whether 
that's a mistake in the documentation or not I can't tell yet, as I have only 
tested LVDS0.

> > > > > +			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 {
> > > > > +					};
> > > > > +				};
> > > > > +			};
> > > > > +		};
> > > > > +
> > > > > 
> > > > >  		prr: chipid@fff00044 {
> > > > >  		
> > > > >  			compatible = "renesas,prr";
> > > > >  			reg = <0 0xfff00044 0 4>;


-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v2 13/16] arm64: dts: renesas: r8a77990: Add display output support
@ 2018-09-17  8:59             ` Laurent Pinchart
  0 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-17  8:59 UTC (permalink / raw)
  To: Simon Horman
  Cc: linux-renesas-soc, Ulrich Hecht, Laurent Pinchart,
	Kieran Bingham, dri-devel

On Monday, 17 September 2018 11:54:04 EEST Laurent Pinchart wrote:
> Hi Simon,
> 
> On Monday, 17 September 2018 11:47:15 EEST Laurent Pinchart wrote:
> > On Monday, 17 September 2018 11:14:20 EEST Simon Horman wrote:
> > > On Mon, Sep 17, 2018 at 09:50:55AM +0200, Simon Horman wrote:
> > > > On Fri, Sep 14, 2018 at 12:10:43PM +0300, Laurent Pinchart wrote:
> > > > > The R8A77990 (E3) platform has one RGB output and two LVDS outputs
> > > > > connected to the DU. Add the DT nodes for the DU, LVDS encoders and
> > > > > supporting VSP and FCP.
> > > > > 
> > > > > Signed-off-by: Laurent Pinchart
> > > > > <laurent.pinchart+renesas@ideasonboard.com>
> > > > > Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> > > > > ---
> > > > > 
> > > > >  arch/arm64/boot/dts/renesas/r8a77990.dtsi | 167
> > > > >  +++++++++++++++++++++++
> > > > >  1 file changed, 167 insertions(+)
> > > > > 
> > > > > diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > > > b/arch/arm64/boot/dts/renesas/r8a77990.dtsi index
> > > > > abb14af76c0e..600074ca3ee5 100644
> > > > > --- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > > > +++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > > > @@ -537,6 +537,173 @@
> > > > > 
> > > > >  			resets = <&cpg 408>;
> > > > >  		
> > > > >  		};
> > > > 
> > > > These nodes should be placed after the gic to preserve the sorting
> > > > of nodes by bus address and then IP block.
> > > > 
> > > > > +		vspb0: vsp@fe960000 {
> > > > > +			compatible = "renesas,vsp2";
> > > > > +			reg = <0 0xfe960000 0 0x8000>;
> > > > > +			interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
> > > > > +			clocks = <&cpg CPG_MOD 626>;
> > > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > > +			resets = <&cpg 626>;
> > > > > +			renesas,fcp = <&fcpvb0>;
> > > > > +		};
> > > > > +
> > > > > +		fcpvb0: fcp@fe96f000 {
> > > > > +			compatible = "renesas,fcpv";
> > > > > +			reg = <0 0xfe96f000 0 0x200>;
> > > > > +			clocks = <&cpg CPG_MOD 607>;
> > > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > > +			resets = <&cpg 607>;
> > > > > +			iommus = <&ipmmu_vp0 5>;
> > > > > +		};
> > > > > +
> > > > > +		vspi0: vsp@fe9a0000 {
> > > > > +			compatible = "renesas,vsp2";
> > > > > +			reg = <0 0xfe9a0000 0 0x8000>;
> > > > > +			interrupts = <GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>;
> > > > > +			clocks = <&cpg CPG_MOD 622>;
> > > > 
> > > > R-Car Series, 3rd Generation, v1.00, Table Table 8A.21 indicates
> > > > that this clock should be <&cpg CPG_MOD 631>. The clock above is
> > > > (according to my reading of the documentation) correctly
> > > > used for vspd1 below.
> > > > 
> > > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > > +			resets = <&cpg 631>;
> > > > > +			renesas,fcp = <&fcpvi0>;
> > > > > +		};
> > > > > +
> > > > > +		fcpvi0: fcp@fe9af000 {
> > > > > +			compatible = "renesas,fcpv";
> > > > > +			reg = <0 0xfe9af000 0 0x200>;
> > > > > +			clocks = <&cpg CPG_MOD 611>;
> > > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > > +			resets = <&cpg 611>;
> > > > > +			iommus = <&ipmmu_vp0 8>;
> > > > > +		};
> > > > > +
> > > > > +		vspd0: vsp@fea20000 {
> > > > > +			compatible = "renesas,vsp2";
> > > > > +			reg = <0 0xfea20000 0 0x7000>;
> > > > > +			interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
> > > > > +			clocks = <&cpg CPG_MOD 623>;
> > > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > > +			resets = <&cpg 623>;
> > > > > +			renesas,fcp = <&fcpvd0>;
> > > > > +		};
> > > > > +
> > > > > +		fcpvd0: fcp@fea27000 {
> > > > > +			compatible = "renesas,fcpv";
> > > > > +			reg = <0 0xfea27000 0 0x200>;
> > > > > +			clocks = <&cpg CPG_MOD 603>;
> > > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > > +			resets = <&cpg 603>;
> > > > > +			iommus = <&ipmmu_vi0 8>;
> > > > > +		};
> > > > > +
> > > > > +		vspd1: vsp@fea28000 {
> > > > > +			compatible = "renesas,vsp2";
> > > > > +			reg = <0 0xfea28000 0 0x7000>;
> > > > > +			interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
> > > > > +			clocks = <&cpg CPG_MOD 622>;
> > > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > > +			resets = <&cpg 622>;
> > > > > +			renesas,fcp = <&fcpvd1>;
> > > > > +		};
> > > > > +
> > > > > +		fcpvd1: fcp@fea2f000 {
> > > > > +			compatible = "renesas,fcpv";
> > > > > +			reg = <0 0xfea2f000 0 0x200>;
> > > > > +			clocks = <&cpg CPG_MOD 602>;
> > > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > > +			resets = <&cpg 602>;
> > > > > +			iommus = <&ipmmu_vi0 9>;
> > > > > +		};
> > > > > +
> > > > > +		du: display@feb00000 {
> > > > > +			compatible = "renesas,du-r8a77990";
> > > > > +			reg = <0 0xfeb00000 0 0x80000>;
> > > > > +			interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
> > > > > +				     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
> > > > > +			clocks = <&cpg CPG_MOD 724>,
> > > > > +				 <&cpg CPG_MOD 723>;
> > > > > +			clock-names = "du.0", "du.1";
> > > > > +			vsps = <&vspd0 0 &vspd1 0>;
> > > > > +			status = "disabled";
> > > > > +
> > > > > +			ports {
> > > > > +				#address-cells = <1>;
> > > > > +				#size-cells = <0>;
> > > > > +
> > > > > +				port@0 {
> > > > > +					reg = <0>;
> > > > > +					du_out_rgb: endpoint {
> > > > > +					};
> > > > > +				};
> > > > > +
> > > > > +				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,r8a77990-lvds";
> > > > > +			reg = <0 0xfeb90000 0 0x20>;
> > > > > +			clocks = <&cpg CPG_MOD 727>;
> > > > > +			power-domains = <&sysc R8A77990_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,r8a77990-lvds";
> > > > > +			reg = <0 0xfeb90100 0 0x20>;
> > > > > +			clocks = <&cpg CPG_MOD 727>;
> > > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > > +			resets = <&cpg 726>;
> > > 
> > > Also, is the missmatch between the index for the clock and reset
> > > intentional?
> > 
> > It is. According to the datasheet, the two LVDS encoders have different
> > module stop bits, but share the same reset (lovely hardware design, it
> > will be fun to support that in the driver :-S).
> 
> Sorry, I got it wrong. it's bit 725 that is shared between the two LVDS
> encoders, to reset the two LVDS PLLs together. The encoders themselves still
> have independent reset bits. I'll fix this.

And of course it's the clock you were commenting on, not the reset. *sigh*

According to the datasheets the two LVDS encoders share one MSTP. Whether 
that's a mistake in the documentation or not I can't tell yet, as I have only 
tested LVDS0.

> > > > > +			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 {
> > > > > +					};
> > > > > +				};
> > > > > +			};
> > > > > +		};
> > > > > +
> > > > > 
> > > > >  		prr: chipid@fff00044 {
> > > > >  		
> > > > >  			compatible = "renesas,prr";
> > > > >  			reg = <0 0xfff00044 0 4>;


-- 
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] 118+ messages in thread

* Re: [PATCH v2 13/16] arm64: dts: renesas: r8a77990: Add display output support
  2018-09-17  8:51         ` Simon Horman
@ 2018-09-17  9:08           ` Laurent Pinchart
  -1 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-17  9:08 UTC (permalink / raw)
  To: Simon Horman
  Cc: Laurent Pinchart, dri-devel, linux-renesas-soc, Ulrich Hecht,
	Kieran Bingham

Hi Simon,

On Monday, 17 September 2018 11:51:06 EEST Simon Horman wrote:
> On Mon, Sep 17, 2018 at 11:38:43AM +0300, Laurent Pinchart wrote:
> > On Monday, 17 September 2018 10:50:55 EEST Simon Horman wrote:
> > > On Fri, Sep 14, 2018 at 12:10:43PM +0300, Laurent Pinchart wrote:
> > > > The R8A77990 (E3) platform has one RGB output and two LVDS outputs
> > > > connected to the DU. Add the DT nodes for the DU, LVDS encoders and
> > > > supporting VSP and FCP.
> > > > 
> > > > Signed-off-by: Laurent Pinchart
> > > > <laurent.pinchart+renesas@ideasonboard.com>
> > > > Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> > > > ---
> > > > 
> > > >  arch/arm64/boot/dts/renesas/r8a77990.dtsi | 167 +++++++++++++++++++++
> > > >  1 file changed, 167 insertions(+)
> > > > 
> > > > diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > > b/arch/arm64/boot/dts/renesas/r8a77990.dtsi index
> > > > abb14af76c0e..600074ca3ee5 100644
> > > > --- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > > +++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > > @@ -537,6 +537,173 @@
> > > >  			resets = <&cpg 408>;
> > > >  		};
> > > 
> > > These nodes should be placed after the gic to preserve the sorting
> > > of nodes by bus address and then IP block.
> > 
> > Aren't they already ? :-)
> 
> Git didn't seem to think so. But its not a big deal,
> I can fix this up locally.

Did it apply the below hunk to a different location ? 408 is the gic, isn't it 
?

> > > > +		vspb0: vsp@fe960000 {
> > > > +			compatible = "renesas,vsp2";
> > > > +			reg = <0 0xfe960000 0 0x8000>;
> > > > +			interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
> > > > +			clocks = <&cpg CPG_MOD 626>;
> > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > +			resets = <&cpg 626>;
> > > > +			renesas,fcp = <&fcpvb0>;
> > > > +		};
> > > > +
> > > > +		fcpvb0: fcp@fe96f000 {
> > > > +			compatible = "renesas,fcpv";
> > > > +			reg = <0 0xfe96f000 0 0x200>;
> > > > +			clocks = <&cpg CPG_MOD 607>;
> > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > +			resets = <&cpg 607>;
> > > > +			iommus = <&ipmmu_vp0 5>;
> > > > +		};
> > > > +
> > > > +		vspi0: vsp@fe9a0000 {
> > > > +			compatible = "renesas,vsp2";
> > > > +			reg = <0 0xfe9a0000 0 0x8000>;
> > > > +			interrupts = <GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>;
> > > > +			clocks = <&cpg CPG_MOD 622>;
> > > 
> > > R-Car Series, 3rd Generation, v1.00, Table Table 8A.21 indicates
> > > that this clock should be <&cpg CPG_MOD 631>. The clock above is
> > > (according to my reading of the documentation) correctly
> > > used for vspd1 below.
> > 
> > Bad copy and paste, thank you for pointing it out, it will be fixed in v3.
> > 
> > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > +			resets = <&cpg 631>;
> > > > +			renesas,fcp = <&fcpvi0>;
> > > > +		};
> > > > +
> > > > +		fcpvi0: fcp@fe9af000 {
> > > > +			compatible = "renesas,fcpv";
> > > > +			reg = <0 0xfe9af000 0 0x200>;
> > > > +			clocks = <&cpg CPG_MOD 611>;
> > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > +			resets = <&cpg 611>;
> > > > +			iommus = <&ipmmu_vp0 8>;
> > > > +		};
> > > > +
> > > > +		vspd0: vsp@fea20000 {
> > > > +			compatible = "renesas,vsp2";
> > > > +			reg = <0 0xfea20000 0 0x7000>;
> > > > +			interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
> > > > +			clocks = <&cpg CPG_MOD 623>;
> > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > +			resets = <&cpg 623>;
> > > > +			renesas,fcp = <&fcpvd0>;
> > > > +		};
> > > > +
> > > > +		fcpvd0: fcp@fea27000 {
> > > > +			compatible = "renesas,fcpv";
> > > > +			reg = <0 0xfea27000 0 0x200>;
> > > > +			clocks = <&cpg CPG_MOD 603>;
> > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > +			resets = <&cpg 603>;
> > > > +			iommus = <&ipmmu_vi0 8>;
> > > > +		};
> > > > +
> > > > +		vspd1: vsp@fea28000 {
> > > > +			compatible = "renesas,vsp2";
> > > > +			reg = <0 0xfea28000 0 0x7000>;
> > > > +			interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
> > > > +			clocks = <&cpg CPG_MOD 622>;
> > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > +			resets = <&cpg 622>;
> > > > +			renesas,fcp = <&fcpvd1>;
> > > > +		};
> > > > +
> > > > +		fcpvd1: fcp@fea2f000 {
> > > > +			compatible = "renesas,fcpv";
> > > > +			reg = <0 0xfea2f000 0 0x200>;
> > > > +			clocks = <&cpg CPG_MOD 602>;
> > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > +			resets = <&cpg 602>;
> > > > +			iommus = <&ipmmu_vi0 9>;
> > > > +		};
> > > > +
> > > > +		du: display@feb00000 {
> > > > +			compatible = "renesas,du-r8a77990";
> > > > +			reg = <0 0xfeb00000 0 0x80000>;
> > > > +			interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
> > > > +				     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
> > > > +			clocks = <&cpg CPG_MOD 724>,
> > > > +				 <&cpg CPG_MOD 723>;
> > > > +			clock-names = "du.0", "du.1";
> > > > +			vsps = <&vspd0 0 &vspd1 0>;
> > > > +			status = "disabled";
> > > > +
> > > > +			ports {
> > > > +				#address-cells = <1>;
> > > > +				#size-cells = <0>;
> > > > +
> > > > +				port@0 {
> > > > +					reg = <0>;
> > > > +					du_out_rgb: endpoint {
> > > > +					};
> > > > +				};
> > > > +
> > > > +				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,r8a77990-lvds";
> > > > +			reg = <0 0xfeb90000 0 0x20>;
> > > > +			clocks = <&cpg CPG_MOD 727>;
> > > > +			power-domains = <&sysc R8A77990_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,r8a77990-lvds";
> > > > +			reg = <0 0xfeb90100 0 0x20>;
> > > > +			clocks = <&cpg CPG_MOD 727>;
> > > > +			power-domains = <&sysc R8A77990_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 {
> > > > +					};
> > > > +				};
> > > > +			};
> > > > +		};
> > > > +
> > > > 
> > > >  		prr: chipid@fff00044 {
> > > >  		
> > > >  			compatible = "renesas,prr";
> > > >  			reg = <0 0xfff00044 0 4>;


-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v2 13/16] arm64: dts: renesas: r8a77990: Add display output support
@ 2018-09-17  9:08           ` Laurent Pinchart
  0 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-17  9:08 UTC (permalink / raw)
  To: Simon Horman
  Cc: linux-renesas-soc, Ulrich Hecht, Laurent Pinchart,
	Kieran Bingham, dri-devel

Hi Simon,

On Monday, 17 September 2018 11:51:06 EEST Simon Horman wrote:
> On Mon, Sep 17, 2018 at 11:38:43AM +0300, Laurent Pinchart wrote:
> > On Monday, 17 September 2018 10:50:55 EEST Simon Horman wrote:
> > > On Fri, Sep 14, 2018 at 12:10:43PM +0300, Laurent Pinchart wrote:
> > > > The R8A77990 (E3) platform has one RGB output and two LVDS outputs
> > > > connected to the DU. Add the DT nodes for the DU, LVDS encoders and
> > > > supporting VSP and FCP.
> > > > 
> > > > Signed-off-by: Laurent Pinchart
> > > > <laurent.pinchart+renesas@ideasonboard.com>
> > > > Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> > > > ---
> > > > 
> > > >  arch/arm64/boot/dts/renesas/r8a77990.dtsi | 167 +++++++++++++++++++++
> > > >  1 file changed, 167 insertions(+)
> > > > 
> > > > diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > > b/arch/arm64/boot/dts/renesas/r8a77990.dtsi index
> > > > abb14af76c0e..600074ca3ee5 100644
> > > > --- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > > +++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > > @@ -537,6 +537,173 @@
> > > >  			resets = <&cpg 408>;
> > > >  		};
> > > 
> > > These nodes should be placed after the gic to preserve the sorting
> > > of nodes by bus address and then IP block.
> > 
> > Aren't they already ? :-)
> 
> Git didn't seem to think so. But its not a big deal,
> I can fix this up locally.

Did it apply the below hunk to a different location ? 408 is the gic, isn't it 
?

> > > > +		vspb0: vsp@fe960000 {
> > > > +			compatible = "renesas,vsp2";
> > > > +			reg = <0 0xfe960000 0 0x8000>;
> > > > +			interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
> > > > +			clocks = <&cpg CPG_MOD 626>;
> > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > +			resets = <&cpg 626>;
> > > > +			renesas,fcp = <&fcpvb0>;
> > > > +		};
> > > > +
> > > > +		fcpvb0: fcp@fe96f000 {
> > > > +			compatible = "renesas,fcpv";
> > > > +			reg = <0 0xfe96f000 0 0x200>;
> > > > +			clocks = <&cpg CPG_MOD 607>;
> > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > +			resets = <&cpg 607>;
> > > > +			iommus = <&ipmmu_vp0 5>;
> > > > +		};
> > > > +
> > > > +		vspi0: vsp@fe9a0000 {
> > > > +			compatible = "renesas,vsp2";
> > > > +			reg = <0 0xfe9a0000 0 0x8000>;
> > > > +			interrupts = <GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>;
> > > > +			clocks = <&cpg CPG_MOD 622>;
> > > 
> > > R-Car Series, 3rd Generation, v1.00, Table Table 8A.21 indicates
> > > that this clock should be <&cpg CPG_MOD 631>. The clock above is
> > > (according to my reading of the documentation) correctly
> > > used for vspd1 below.
> > 
> > Bad copy and paste, thank you for pointing it out, it will be fixed in v3.
> > 
> > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > +			resets = <&cpg 631>;
> > > > +			renesas,fcp = <&fcpvi0>;
> > > > +		};
> > > > +
> > > > +		fcpvi0: fcp@fe9af000 {
> > > > +			compatible = "renesas,fcpv";
> > > > +			reg = <0 0xfe9af000 0 0x200>;
> > > > +			clocks = <&cpg CPG_MOD 611>;
> > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > +			resets = <&cpg 611>;
> > > > +			iommus = <&ipmmu_vp0 8>;
> > > > +		};
> > > > +
> > > > +		vspd0: vsp@fea20000 {
> > > > +			compatible = "renesas,vsp2";
> > > > +			reg = <0 0xfea20000 0 0x7000>;
> > > > +			interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
> > > > +			clocks = <&cpg CPG_MOD 623>;
> > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > +			resets = <&cpg 623>;
> > > > +			renesas,fcp = <&fcpvd0>;
> > > > +		};
> > > > +
> > > > +		fcpvd0: fcp@fea27000 {
> > > > +			compatible = "renesas,fcpv";
> > > > +			reg = <0 0xfea27000 0 0x200>;
> > > > +			clocks = <&cpg CPG_MOD 603>;
> > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > +			resets = <&cpg 603>;
> > > > +			iommus = <&ipmmu_vi0 8>;
> > > > +		};
> > > > +
> > > > +		vspd1: vsp@fea28000 {
> > > > +			compatible = "renesas,vsp2";
> > > > +			reg = <0 0xfea28000 0 0x7000>;
> > > > +			interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
> > > > +			clocks = <&cpg CPG_MOD 622>;
> > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > +			resets = <&cpg 622>;
> > > > +			renesas,fcp = <&fcpvd1>;
> > > > +		};
> > > > +
> > > > +		fcpvd1: fcp@fea2f000 {
> > > > +			compatible = "renesas,fcpv";
> > > > +			reg = <0 0xfea2f000 0 0x200>;
> > > > +			clocks = <&cpg CPG_MOD 602>;
> > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > +			resets = <&cpg 602>;
> > > > +			iommus = <&ipmmu_vi0 9>;
> > > > +		};
> > > > +
> > > > +		du: display@feb00000 {
> > > > +			compatible = "renesas,du-r8a77990";
> > > > +			reg = <0 0xfeb00000 0 0x80000>;
> > > > +			interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
> > > > +				     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
> > > > +			clocks = <&cpg CPG_MOD 724>,
> > > > +				 <&cpg CPG_MOD 723>;
> > > > +			clock-names = "du.0", "du.1";
> > > > +			vsps = <&vspd0 0 &vspd1 0>;
> > > > +			status = "disabled";
> > > > +
> > > > +			ports {
> > > > +				#address-cells = <1>;
> > > > +				#size-cells = <0>;
> > > > +
> > > > +				port@0 {
> > > > +					reg = <0>;
> > > > +					du_out_rgb: endpoint {
> > > > +					};
> > > > +				};
> > > > +
> > > > +				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,r8a77990-lvds";
> > > > +			reg = <0 0xfeb90000 0 0x20>;
> > > > +			clocks = <&cpg CPG_MOD 727>;
> > > > +			power-domains = <&sysc R8A77990_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,r8a77990-lvds";
> > > > +			reg = <0 0xfeb90100 0 0x20>;
> > > > +			clocks = <&cpg CPG_MOD 727>;
> > > > +			power-domains = <&sysc R8A77990_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 {
> > > > +					};
> > > > +				};
> > > > +			};
> > > > +		};
> > > > +
> > > > 
> > > >  		prr: chipid@fff00044 {
> > > >  		
> > > >  			compatible = "renesas,prr";
> > > >  			reg = <0 0xfff00044 0 4>;


-- 
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] 118+ messages in thread

* Re: [PATCH v2 13/16] arm64: dts: renesas: r8a77990: Add display output support
  2018-09-17  9:08           ` Laurent Pinchart
@ 2018-09-17  9:48             ` Geert Uytterhoeven
  -1 siblings, 0 replies; 118+ messages in thread
From: Geert Uytterhoeven @ 2018-09-17  9:48 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Simon Horman, Laurent Pinchart, DRI Development, Linux-Renesas,
	uli, Kieran Bingham

Hi Laurent,

On Mon, Sep 17, 2018 at 11:09 AM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
> On Monday, 17 September 2018 11:51:06 EEST Simon Horman wrote:
> > On Mon, Sep 17, 2018 at 11:38:43AM +0300, Laurent Pinchart wrote:
> > > On Monday, 17 September 2018 10:50:55 EEST Simon Horman wrote:
> > > > On Fri, Sep 14, 2018 at 12:10:43PM +0300, Laurent Pinchart wrote:
> > > > > The R8A77990 (E3) platform has one RGB output and two LVDS outputs
> > > > > connected to the DU. Add the DT nodes for the DU, LVDS encoders and
> > > > > supporting VSP and FCP.
> > > > >
> > > > > Signed-off-by: Laurent Pinchart
> > > > > <laurent.pinchart+renesas@ideasonboard.com>
> > > > > Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> > > > > ---
> > > > >
> > > > >  arch/arm64/boot/dts/renesas/r8a77990.dtsi | 167 +++++++++++++++++++++
> > > > >  1 file changed, 167 insertions(+)
> > > > >
> > > > > diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > > > b/arch/arm64/boot/dts/renesas/r8a77990.dtsi index
> > > > > abb14af76c0e..600074ca3ee5 100644
> > > > > --- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > > > +++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > > > @@ -537,6 +537,173 @@
> > > > >                         resets = <&cpg 408>;
> > > > >                 };
> > > >
> > > > These nodes should be placed after the gic to preserve the sorting
> > > > of nodes by bus address and then IP block.
> > >
> > > Aren't they already ? :-)
> >
> > Git didn't seem to think so. But its not a big deal,
> > I can fix this up locally.
>
> Did it apply the below hunk to a different location ? 408 is the gic, isn't it
> ?

The "-U <n>" option (with <n> sufficiently large) of "git diff" and "git show"
is a great help for inspecting DT changes.

Gr{oetje,eeting}s,

                        Geert

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

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

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

* Re: [PATCH v2 13/16] arm64: dts: renesas: r8a77990: Add display output support
@ 2018-09-17  9:48             ` Geert Uytterhoeven
  0 siblings, 0 replies; 118+ messages in thread
From: Geert Uytterhoeven @ 2018-09-17  9:48 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: uli, Laurent Pinchart, Kieran Bingham, DRI Development,
	Linux-Renesas, Simon Horman

Hi Laurent,

On Mon, Sep 17, 2018 at 11:09 AM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
> On Monday, 17 September 2018 11:51:06 EEST Simon Horman wrote:
> > On Mon, Sep 17, 2018 at 11:38:43AM +0300, Laurent Pinchart wrote:
> > > On Monday, 17 September 2018 10:50:55 EEST Simon Horman wrote:
> > > > On Fri, Sep 14, 2018 at 12:10:43PM +0300, Laurent Pinchart wrote:
> > > > > The R8A77990 (E3) platform has one RGB output and two LVDS outputs
> > > > > connected to the DU. Add the DT nodes for the DU, LVDS encoders and
> > > > > supporting VSP and FCP.
> > > > >
> > > > > Signed-off-by: Laurent Pinchart
> > > > > <laurent.pinchart+renesas@ideasonboard.com>
> > > > > Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> > > > > ---
> > > > >
> > > > >  arch/arm64/boot/dts/renesas/r8a77990.dtsi | 167 +++++++++++++++++++++
> > > > >  1 file changed, 167 insertions(+)
> > > > >
> > > > > diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > > > b/arch/arm64/boot/dts/renesas/r8a77990.dtsi index
> > > > > abb14af76c0e..600074ca3ee5 100644
> > > > > --- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > > > +++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > > > @@ -537,6 +537,173 @@
> > > > >                         resets = <&cpg 408>;
> > > > >                 };
> > > >
> > > > These nodes should be placed after the gic to preserve the sorting
> > > > of nodes by bus address and then IP block.
> > >
> > > Aren't they already ? :-)
> >
> > Git didn't seem to think so. But its not a big deal,
> > I can fix this up locally.
>
> Did it apply the below hunk to a different location ? 408 is the gic, isn't it
> ?

The "-U <n>" option (with <n> sufficiently large) of "git diff" and "git show"
is a great help for inspecting DT changes.

Gr{oetje,eeting}s,

                        Geert

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

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v2 13/16] arm64: dts: renesas: r8a77990: Add display output support
  2018-09-17  9:48             ` Geert Uytterhoeven
@ 2018-09-17 10:01               ` Laurent Pinchart
  -1 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-17 10:01 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Simon Horman, Laurent Pinchart, DRI Development, Linux-Renesas,
	uli, Kieran Bingham

Hi Geert,

On Monday, 17 September 2018 12:48:12 EEST Geert Uytterhoeven wrote:
> On Mon, Sep 17, 2018 at 11:09 AM Laurent Pinchart wrote:
> > On Monday, 17 September 2018 11:51:06 EEST Simon Horman wrote:
> >> On Mon, Sep 17, 2018 at 11:38:43AM +0300, Laurent Pinchart wrote:
> >>> On Monday, 17 September 2018 10:50:55 EEST Simon Horman wrote:
> >>>> On Fri, Sep 14, 2018 at 12:10:43PM +0300, Laurent Pinchart wrote:
> >>>>> The R8A77990 (E3) platform has one RGB output and two LVDS outputs
> >>>>> connected to the DU. Add the DT nodes for the DU, LVDS encoders
> >>>>> and supporting VSP and FCP.
> >>>>> 
> >>>>> Signed-off-by: Laurent Pinchart
> >>>>> <laurent.pinchart+renesas@ideasonboard.com>
> >>>>> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> >>>>> ---
> >>>>> 
> >>>>>  arch/arm64/boot/dts/renesas/r8a77990.dtsi | 167 +++++++++++++++++
> >>>>>  1 file changed, 167 insertions(+)
> >>>>> 
> >>>>> diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> >>>>> b/arch/arm64/boot/dts/renesas/r8a77990.dtsi index
> >>>>> abb14af76c0e..600074ca3ee5 100644
> >>>>> --- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> >>>>> +++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> >>>>> @@ -537,6 +537,173 @@
> >>>>>                         resets = <&cpg 408>;
> >>>>>                 };
> >>>> 
> >>>> These nodes should be placed after the gic to preserve the sorting
> >>>> of nodes by bus address and then IP block.
> >>> 
> >>> Aren't they already ? :-)
> >> 
> >> Git didn't seem to think so. But its not a big deal,
> >> I can fix this up locally.
> > 
> > Did it apply the below hunk to a different location ? 408 is the gic,
> > isn't it ?
> 
> The "-U <n>" option (with <n> sufficiently large) of "git diff" and "git
> show" is a great help for inspecting DT changes.

I know. This is what I have in my tree:

diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi b/arch/arm64/boot/dts/
renesas/r8a77990.dtsi
index abb14af76c0e..935bb313d29f 100644
--- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
@@ -522,32 +522,199 @@
 
 		gic: interrupt-controller@f1010000 {
 			compatible = "arm,gic-400";
 			#interrupt-cells = <3>;
 			#address-cells = <0>;
 			interrupt-controller;
 			reg = <0x0 0xf1010000 0 0x1000>,
 			      <0x0 0xf1020000 0 0x20000>,
 			      <0x0 0xf1040000 0 0x20000>,
 			      <0x0 0xf1060000 0 0x20000>;
 			interrupts = <GIC_PPI 9
 					(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
 			clocks = <&cpg CPG_MOD 408>;
 			clock-names = "clk";
 			power-domains = <&sysc 32>;
 			resets = <&cpg 408>;
 		};
 
+		vspb0: vsp@fe960000 {
+			compatible = "renesas,vsp2";
+			reg = <0 0xfe960000 0 0x8000>;
+			interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 626>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			resets = <&cpg 626>;
+			renesas,fcp = <&fcpvb0>;
+		};

[snip]

so I don't see where the problem that Simon pointed out is, especially given 
that I took care to sort nodes out properly this time.

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v2 13/16] arm64: dts: renesas: r8a77990: Add display output support
@ 2018-09-17 10:01               ` Laurent Pinchart
  0 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-17 10:01 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: uli, Laurent Pinchart, Kieran Bingham, DRI Development,
	Linux-Renesas, Simon Horman

Hi Geert,

On Monday, 17 September 2018 12:48:12 EEST Geert Uytterhoeven wrote:
> On Mon, Sep 17, 2018 at 11:09 AM Laurent Pinchart wrote:
> > On Monday, 17 September 2018 11:51:06 EEST Simon Horman wrote:
> >> On Mon, Sep 17, 2018 at 11:38:43AM +0300, Laurent Pinchart wrote:
> >>> On Monday, 17 September 2018 10:50:55 EEST Simon Horman wrote:
> >>>> On Fri, Sep 14, 2018 at 12:10:43PM +0300, Laurent Pinchart wrote:
> >>>>> The R8A77990 (E3) platform has one RGB output and two LVDS outputs
> >>>>> connected to the DU. Add the DT nodes for the DU, LVDS encoders
> >>>>> and supporting VSP and FCP.
> >>>>> 
> >>>>> Signed-off-by: Laurent Pinchart
> >>>>> <laurent.pinchart+renesas@ideasonboard.com>
> >>>>> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> >>>>> ---
> >>>>> 
> >>>>>  arch/arm64/boot/dts/renesas/r8a77990.dtsi | 167 +++++++++++++++++
> >>>>>  1 file changed, 167 insertions(+)
> >>>>> 
> >>>>> diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> >>>>> b/arch/arm64/boot/dts/renesas/r8a77990.dtsi index
> >>>>> abb14af76c0e..600074ca3ee5 100644
> >>>>> --- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> >>>>> +++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> >>>>> @@ -537,6 +537,173 @@
> >>>>>                         resets = <&cpg 408>;
> >>>>>                 };
> >>>> 
> >>>> These nodes should be placed after the gic to preserve the sorting
> >>>> of nodes by bus address and then IP block.
> >>> 
> >>> Aren't they already ? :-)
> >> 
> >> Git didn't seem to think so. But its not a big deal,
> >> I can fix this up locally.
> > 
> > Did it apply the below hunk to a different location ? 408 is the gic,
> > isn't it ?
> 
> The "-U <n>" option (with <n> sufficiently large) of "git diff" and "git
> show" is a great help for inspecting DT changes.

I know. This is what I have in my tree:

diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi b/arch/arm64/boot/dts/
renesas/r8a77990.dtsi
index abb14af76c0e..935bb313d29f 100644
--- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
@@ -522,32 +522,199 @@
 
 		gic: interrupt-controller@f1010000 {
 			compatible = "arm,gic-400";
 			#interrupt-cells = <3>;
 			#address-cells = <0>;
 			interrupt-controller;
 			reg = <0x0 0xf1010000 0 0x1000>,
 			      <0x0 0xf1020000 0 0x20000>,
 			      <0x0 0xf1040000 0 0x20000>,
 			      <0x0 0xf1060000 0 0x20000>;
 			interrupts = <GIC_PPI 9
 					(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
 			clocks = <&cpg CPG_MOD 408>;
 			clock-names = "clk";
 			power-domains = <&sysc 32>;
 			resets = <&cpg 408>;
 		};
 
+		vspb0: vsp@fe960000 {
+			compatible = "renesas,vsp2";
+			reg = <0 0xfe960000 0 0x8000>;
+			interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 626>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			resets = <&cpg 626>;
+			renesas,fcp = <&fcpvb0>;
+		};

[snip]

so I don't see where the problem that Simon pointed out is, especially given 
that I took care to sort nodes out properly this time.

-- 
Regards,

Laurent Pinchart



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

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

* Re: [PATCH v2 01/16] dt-bindings: display: renesas: du: Document r8a77990 bindings
  2018-09-14  9:10   ` Laurent Pinchart
@ 2018-09-17 10:53     ` Ulrich Hecht
  -1 siblings, 0 replies; 118+ messages in thread
From: Ulrich Hecht @ 2018-09-17 10:53 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham


> On September 14, 2018 at 11:10 AM Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> wrote:
> 
> 
> Document the E3 (r8a77990) SoC in the R-Car DU bindings.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> ---
>  Documentation/devicetree/bindings/display/renesas,du.txt | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/display/renesas,du.txt b/Documentation/devicetree/bindings/display/renesas,du.txt
> index caae2348a292..9de67be632d1 100644
> --- a/Documentation/devicetree/bindings/display/renesas,du.txt
> +++ b/Documentation/devicetree/bindings/display/renesas,du.txt
> @@ -16,6 +16,7 @@ Required Properties:
>      - "renesas,du-r8a77965" for R8A77965 (R-Car M3-N) compatible DU
>      - "renesas,du-r8a77970" for R8A77970 (R-Car V3M) compatible DU
>      - "renesas,du-r8a77980" for R8A77980 (R-Car V3H) compatible DU
> +    - "renesas,du-r8a77990" for R8A77990 (R-Car E3) compatible DU
>      - "renesas,du-r8a77995" for R8A77995 (R-Car D3) compatible DU
>  
>    - reg: the memory-mapped I/O registers base address and length
> @@ -63,6 +64,7 @@ corresponding to each DU output.
>   R8A77965 (R-Car M3-N)  DPAD 0         HDMI 0         LVDS 0         -
>   R8A77970 (R-Car V3M)   DPAD 0         LVDS 0         -              -
>   R8A77980 (R-Car V3H)   DPAD 0         LVDS 0         -              -
> + R8A77990 (R-Car E3)    DPAD 0         LVDS 0         LVDS 1         -
>   R8A77995 (R-Car D3)    DPAD 0         LVDS 0         LVDS 1         -
>  
>  

Reviewed-by: Ulrich Hecht <uli+renesas@fpond.eu>

CU
Uli

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

* Re: [PATCH v2 01/16] dt-bindings: display: renesas: du: Document r8a77990 bindings
@ 2018-09-17 10:53     ` Ulrich Hecht
  0 siblings, 0 replies; 118+ messages in thread
From: Ulrich Hecht @ 2018-09-17 10:53 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham


> On September 14, 2018 at 11:10 AM Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> wrote:
> 
> 
> Document the E3 (r8a77990) SoC in the R-Car DU bindings.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> ---
>  Documentation/devicetree/bindings/display/renesas,du.txt | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/display/renesas,du.txt b/Documentation/devicetree/bindings/display/renesas,du.txt
> index caae2348a292..9de67be632d1 100644
> --- a/Documentation/devicetree/bindings/display/renesas,du.txt
> +++ b/Documentation/devicetree/bindings/display/renesas,du.txt
> @@ -16,6 +16,7 @@ Required Properties:
>      - "renesas,du-r8a77965" for R8A77965 (R-Car M3-N) compatible DU
>      - "renesas,du-r8a77970" for R8A77970 (R-Car V3M) compatible DU
>      - "renesas,du-r8a77980" for R8A77980 (R-Car V3H) compatible DU
> +    - "renesas,du-r8a77990" for R8A77990 (R-Car E3) compatible DU
>      - "renesas,du-r8a77995" for R8A77995 (R-Car D3) compatible DU
>  
>    - reg: the memory-mapped I/O registers base address and length
> @@ -63,6 +64,7 @@ corresponding to each DU output.
>   R8A77965 (R-Car M3-N)  DPAD 0         HDMI 0         LVDS 0         -
>   R8A77970 (R-Car V3M)   DPAD 0         LVDS 0         -              -
>   R8A77980 (R-Car V3H)   DPAD 0         LVDS 0         -              -
> + R8A77990 (R-Car E3)    DPAD 0         LVDS 0         LVDS 1         -
>   R8A77995 (R-Car D3)    DPAD 0         LVDS 0         LVDS 1         -
>  
>  

Reviewed-by: Ulrich Hecht <uli+renesas@fpond.eu>

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

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

* Re: [PATCH v2 02/16] dt-bindings: display: renesas: lvds: Document r8a77990 bindings
  2018-09-14  9:10   ` Laurent Pinchart
@ 2018-09-17 10:53     ` Ulrich Hecht
  -1 siblings, 0 replies; 118+ messages in thread
From: Ulrich Hecht @ 2018-09-17 10:53 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham


> On September 14, 2018 at 11:10 AM Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> wrote:
> 
> 
> The E3 (r8a77990) supports two LVDS channels. Extend the binding to
> support them.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> ---
>  Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
> index 5a4e379bb414..13af7e2ac7e8 100644
> --- a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
> +++ b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
> @@ -15,6 +15,7 @@ Required properties:
>    - "renesas,r8a7796-lvds" for R8A7796 (R-Car M3-W) compatible LVDS encoders
>    - "renesas,r8a77970-lvds" for R8A77970 (R-Car V3M) compatible LVDS encoders
>    - "renesas,r8a77980-lvds" for R8A77980 (R-Car V3H) compatible LVDS encoders
> +  - "renesas,r8a77990-lvds" for R8A77990 (R-Car E3) compatible LVDS encoders
>    - "renesas,r8a77995-lvds" for R8A77995 (R-Car D3) compatible LVDS encoders
>  
>  - reg: Base address and length for the memory-mapped registers

Reviewed-by: Ulrich Hecht <uli+renesas@fpond.eu>

CU
Uli

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

* Re: [PATCH v2 02/16] dt-bindings: display: renesas: lvds: Document r8a77990 bindings
@ 2018-09-17 10:53     ` Ulrich Hecht
  0 siblings, 0 replies; 118+ messages in thread
From: Ulrich Hecht @ 2018-09-17 10:53 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham


> On September 14, 2018 at 11:10 AM Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> wrote:
> 
> 
> The E3 (r8a77990) supports two LVDS channels. Extend the binding to
> support them.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> ---
>  Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
> index 5a4e379bb414..13af7e2ac7e8 100644
> --- a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
> +++ b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
> @@ -15,6 +15,7 @@ Required properties:
>    - "renesas,r8a7796-lvds" for R8A7796 (R-Car M3-W) compatible LVDS encoders
>    - "renesas,r8a77970-lvds" for R8A77970 (R-Car V3M) compatible LVDS encoders
>    - "renesas,r8a77980-lvds" for R8A77980 (R-Car V3H) compatible LVDS encoders
> +  - "renesas,r8a77990-lvds" for R8A77990 (R-Car E3) compatible LVDS encoders
>    - "renesas,r8a77995-lvds" for R8A77995 (R-Car D3) compatible LVDS encoders
>  
>  - reg: Base address and length for the memory-mapped registers

Reviewed-by: Ulrich Hecht <uli+renesas@fpond.eu>

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

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

* Re: [PATCH v2 03/16] dt-bindings: display: renesas: lvds: Add EXTAL and DU_DOTCLKIN clocks
  2018-09-14  9:10   ` Laurent Pinchart
@ 2018-09-17 10:53     ` Ulrich Hecht
  -1 siblings, 0 replies; 118+ messages in thread
From: Ulrich Hecht @ 2018-09-17 10:53 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham


> On September 14, 2018 at 11:10 AM Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> wrote:
> 
> 
> On the D3 and E3 SoCs, the LVDS encoder can derive its internal pixel
> clock from an externally supplied clock, either through the EXTAL pin or
> through one of the DU_DOTCLKINx pins. Add corresponding clocks to the DT
> bindings.
> 
> To retain backward compatibility with DT that don't specify the
> clock-names property, the functional clock must always be specified
> first, and the clock-names property is optional when only the functional
> clock is specified.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> ---
> Changes since v1:
> 
> - Clarified wording
> ---
>  .../devicetree/bindings/display/bridge/renesas,lvds.txt      | 12 +++++++++++-
>  1 file changed, 11 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
> index 13af7e2ac7e8..3aeb0ec06fd0 100644
> --- a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
> +++ b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
> @@ -19,7 +19,17 @@ Required properties:
>    - "renesas,r8a77995-lvds" for R8A77995 (R-Car D3) compatible LVDS encoders
>  
>  - reg: Base address and length for the memory-mapped registers
> -- clocks: A phandle + clock-specifier pair for the functional clock
> +- clocks: A list of phandles + clock-specifier pairs, one for each entry in
> +  the clock-names property.
> +- clock-names: Name of the clocks. This property is model-dependent.
> +  - The functional clock, which mandatory for all models, shall be listed
> +    first, and shall be named "fck".
> +  - On R8A77990 and R8A77995, the LVDS encoder can use the EXTAL or
> +    DU_DOTCLKINx clocks. Those clocks are optional. When supplied they must be
> +    named "extal" and "dclkin.x" respectively, with "x" being the DU_DOTCLKIN
> +    numerical index.
> +  - When the clocks property only contains the functional clock, the
> +    clock-names property may be omitted.
>  - resets: A phandle + reset specifier for the module reset
>  
>  Required nodes:

Reviewed-by: Ulrich Hecht <uli+renesas@fpond.eu>

CU
Uli

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

* Re: [PATCH v2 03/16] dt-bindings: display: renesas: lvds: Add EXTAL and DU_DOTCLKIN clocks
@ 2018-09-17 10:53     ` Ulrich Hecht
  0 siblings, 0 replies; 118+ messages in thread
From: Ulrich Hecht @ 2018-09-17 10:53 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham


> On September 14, 2018 at 11:10 AM Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> wrote:
> 
> 
> On the D3 and E3 SoCs, the LVDS encoder can derive its internal pixel
> clock from an externally supplied clock, either through the EXTAL pin or
> through one of the DU_DOTCLKINx pins. Add corresponding clocks to the DT
> bindings.
> 
> To retain backward compatibility with DT that don't specify the
> clock-names property, the functional clock must always be specified
> first, and the clock-names property is optional when only the functional
> clock is specified.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> ---
> Changes since v1:
> 
> - Clarified wording
> ---
>  .../devicetree/bindings/display/bridge/renesas,lvds.txt      | 12 +++++++++++-
>  1 file changed, 11 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
> index 13af7e2ac7e8..3aeb0ec06fd0 100644
> --- a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
> +++ b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
> @@ -19,7 +19,17 @@ Required properties:
>    - "renesas,r8a77995-lvds" for R8A77995 (R-Car D3) compatible LVDS encoders
>  
>  - reg: Base address and length for the memory-mapped registers
> -- clocks: A phandle + clock-specifier pair for the functional clock
> +- clocks: A list of phandles + clock-specifier pairs, one for each entry in
> +  the clock-names property.
> +- clock-names: Name of the clocks. This property is model-dependent.
> +  - The functional clock, which mandatory for all models, shall be listed
> +    first, and shall be named "fck".
> +  - On R8A77990 and R8A77995, the LVDS encoder can use the EXTAL or
> +    DU_DOTCLKINx clocks. Those clocks are optional. When supplied they must be
> +    named "extal" and "dclkin.x" respectively, with "x" being the DU_DOTCLKIN
> +    numerical index.
> +  - When the clocks property only contains the functional clock, the
> +    clock-names property may be omitted.
>  - resets: A phandle + reset specifier for the module reset
>  
>  Required nodes:

Reviewed-by: Ulrich Hecht <uli+renesas@fpond.eu>

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

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

* Re: [PATCH v2 04/16] drm: bridge: thc63: Restrict modes based on hardware operating frequency
  2018-09-14  9:10   ` Laurent Pinchart
@ 2018-09-17 10:53     ` Ulrich Hecht
  -1 siblings, 0 replies; 118+ messages in thread
From: Ulrich Hecht @ 2018-09-17 10:53 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham

Thank you for your patch!

> On September 14, 2018 at 11:10 AM Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> wrote:
> 
> 
> The THC63LVD1024 is restricted to a pixel clock frequency in the range
> of 8 to 135 MHz. Implement the bridge .mode_valid() operation
> accordingly.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> ---
>  drivers/gpu/drm/bridge/thc63lvd1024.c | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
> 
> diff --git a/drivers/gpu/drm/bridge/thc63lvd1024.c b/drivers/gpu/drm/bridge/thc63lvd1024.c
> index c8b9edd5a7f4..63609ba16b6d 100644
> --- a/drivers/gpu/drm/bridge/thc63lvd1024.c
> +++ b/drivers/gpu/drm/bridge/thc63lvd1024.c
> @@ -45,6 +45,23 @@ static int thc63_attach(struct drm_bridge *bridge)
>  	return drm_bridge_attach(bridge->encoder, thc63->next, bridge);
>  }
>  
> +static enum drm_mode_status thc63_mode_valid(struct drm_bridge *bridge,
> +					const struct drm_display_mode *mode)
> +{
> +	/*
> +	 * The THC63LVD0124 clock frequency range is 8 to 135 MHz in single-in,

That should be THC63LVD1024.

> +	 * single-out mode.

For the input clock (that's what we're talking about, right?), that also applies to single-in/dual-out. Maybe just omit the "single-out" clause?

> Note that the limits depends on the mode and will
> +	 * need to be adjusted accordingly.
> +	 */

I don't quite understand. Does that refer to the THC63 mode, or the DRM mode?

> +	if (mode->clock < 8000)
> +		return MODE_CLOCK_LOW;
> +
> +	if (mode->clock > 135000)
> +		return MODE_CLOCK_HIGH;
> +
> +	return MODE_OK;
> +}
> +
>  static void thc63_enable(struct drm_bridge *bridge)
>  {
>  	struct thc63_dev *thc63 = to_thc63(bridge);
> @@ -77,6 +94,7 @@ static void thc63_disable(struct drm_bridge *bridge)
>  
>  static const struct drm_bridge_funcs thc63_bridge_func = {
>  	.attach	= thc63_attach,
> +	.mode_valid = thc63_mode_valid,
>  	.enable = thc63_enable,
>  	.disable = thc63_disable,
>  };
> -- 
> Regards,
> 
> Laurent Pinchart
>

CU
Uli

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

* Re: [PATCH v2 04/16] drm: bridge: thc63: Restrict modes based on hardware operating frequency
@ 2018-09-17 10:53     ` Ulrich Hecht
  0 siblings, 0 replies; 118+ messages in thread
From: Ulrich Hecht @ 2018-09-17 10:53 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham

Thank you for your patch!

> On September 14, 2018 at 11:10 AM Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> wrote:
> 
> 
> The THC63LVD1024 is restricted to a pixel clock frequency in the range
> of 8 to 135 MHz. Implement the bridge .mode_valid() operation
> accordingly.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> ---
>  drivers/gpu/drm/bridge/thc63lvd1024.c | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
> 
> diff --git a/drivers/gpu/drm/bridge/thc63lvd1024.c b/drivers/gpu/drm/bridge/thc63lvd1024.c
> index c8b9edd5a7f4..63609ba16b6d 100644
> --- a/drivers/gpu/drm/bridge/thc63lvd1024.c
> +++ b/drivers/gpu/drm/bridge/thc63lvd1024.c
> @@ -45,6 +45,23 @@ static int thc63_attach(struct drm_bridge *bridge)
>  	return drm_bridge_attach(bridge->encoder, thc63->next, bridge);
>  }
>  
> +static enum drm_mode_status thc63_mode_valid(struct drm_bridge *bridge,
> +					const struct drm_display_mode *mode)
> +{
> +	/*
> +	 * The THC63LVD0124 clock frequency range is 8 to 135 MHz in single-in,

That should be THC63LVD1024.

> +	 * single-out mode.

For the input clock (that's what we're talking about, right?), that also applies to single-in/dual-out. Maybe just omit the "single-out" clause?

> Note that the limits depends on the mode and will
> +	 * need to be adjusted accordingly.
> +	 */

I don't quite understand. Does that refer to the THC63 mode, or the DRM mode?

> +	if (mode->clock < 8000)
> +		return MODE_CLOCK_LOW;
> +
> +	if (mode->clock > 135000)
> +		return MODE_CLOCK_HIGH;
> +
> +	return MODE_OK;
> +}
> +
>  static void thc63_enable(struct drm_bridge *bridge)
>  {
>  	struct thc63_dev *thc63 = to_thc63(bridge);
> @@ -77,6 +94,7 @@ static void thc63_disable(struct drm_bridge *bridge)
>  
>  static const struct drm_bridge_funcs thc63_bridge_func = {
>  	.attach	= thc63_attach,
> +	.mode_valid = thc63_mode_valid,
>  	.enable = thc63_enable,
>  	.disable = thc63_disable,
>  };
> -- 
> Regards,
> 
> Laurent Pinchart
>

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

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

* Re: [PATCH v2 05/16] drm: rcar-du: lvds: D3/E3 support
  2018-09-14  9:10   ` Laurent Pinchart
@ 2018-09-17 10:53     ` Ulrich Hecht
  -1 siblings, 0 replies; 118+ messages in thread
From: Ulrich Hecht @ 2018-09-17 10:53 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham

Thank you for your patch!

> On September 14, 2018 at 11:10 AM Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> wrote:
> 
> 
> The LVDS encoders in the D3 and E3 SoCs differ significantly from those
> in the other R-Car Gen3 family members:
> 
> - The LVDS PLL architecture is more complex and requires computing PLL
>   parameters manually.
> - The PLL uses external clocks as inputs, which need to be retrieved
>   from DT.
> - In addition to the different PLL setup, the startup sequence has
>   changed *again* (seems someone had trouble making his/her mind).
> 
> Supporting all this requires DT bindings extensions for external clocks,
> brand new PLL setup code, and a few quirks to handle the differences in
> the startup sequence.
> 
> The implementation doesn't support all hardware features yet, namely
> 
> - Using the LV[01] clocks generated by the CPG as PLL input.
> - Providing the LVDS PLL clock to the DU for use with the RGB output.
> 
> Those features can be added later when the need will arise.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> ---
> Changes since v1:
> 
> - Don't compile-out debug code based on DEBUG and CONFIG_DYNAMIC_DEBUG
> - Test all three input clocks (DOTCLKIN[01] and EXTAL) and pick the best
>   one
> ---
>  drivers/gpu/drm/rcar-du/rcar_lvds.c      | 355 +++++++++++++++++++++++++++----
>  drivers/gpu/drm/rcar-du/rcar_lvds_regs.h |  43 +++-
>  2 files changed, 351 insertions(+), 47 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c b/drivers/gpu/drm/rcar-du/rcar_lvds.c
> index ce0eb68c3416..23e7743144c8 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_lvds.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_lvds.c
> @@ -24,6 +24,8 @@
>  
>  #include "rcar_lvds_regs.h"
>  
> +struct rcar_lvds;
> +
>  /* Keep in sync with the LVDCR0.LVMD hardware register values. */
>  enum rcar_lvds_mode {
>  	RCAR_LVDS_MODE_JEIDA = 0,
> @@ -31,14 +33,16 @@ enum rcar_lvds_mode {
>  	RCAR_LVDS_MODE_VESA = 4,
>  };
>  
> -#define RCAR_LVDS_QUIRK_LANES	(1 << 0)	/* LVDS lanes 1 and 3 inverted */
> -#define RCAR_LVDS_QUIRK_GEN2_PLLCR (1 << 1)	/* LVDPLLCR has gen2 layout */
> -#define RCAR_LVDS_QUIRK_GEN3_LVEN (1 << 2)	/* LVEN bit needs to be set */
> -						/* on R8A77970/R8A7799x */
> +#define RCAR_LVDS_QUIRK_LANES		BIT(0)	/* LVDS lanes 1 and 3 inverted */
> +#define RCAR_LVDS_QUIRK_GEN3_LVEN	BIT(1)	/* LVEN bit needs to be set on R8A77970/R8A7799x */
> +#define RCAR_LVDS_QUIRK_PWD		BIT(2)	/* PWD bit available (all of Gen3 but E3) */
> +#define RCAR_LVDS_QUIRK_EXT_PLL		BIT(3)	/* Has extended PLL */
> +#define RCAR_LVDS_QUIRK_DUAL_LINK	BIT(4)	/* Supports dual-link operation */
>  
>  struct rcar_lvds_device_info {
>  	unsigned int gen;
>  	unsigned int quirks;
> +	void (*pll_setup)(struct rcar_lvds *lvds, unsigned int freq);
>  };
>  
>  struct rcar_lvds {
> @@ -52,7 +56,11 @@ struct rcar_lvds {
>  	struct drm_panel *panel;
>  
>  	void __iomem *mmio;
> -	struct clk *clock;
> +	struct {
> +		struct clk *mod;		/* CPG module clock */
> +		struct clk *extal;		/* External clock */
> +		struct clk *dotclkin[2];	/* External DU clocks */
> +	} clocks;
>  	bool enabled;
>  
>  	struct drm_display_mode display_mode;
> @@ -128,33 +136,212 @@ static const struct drm_connector_funcs rcar_lvds_conn_funcs = {
>  };
>  
>  /* -----------------------------------------------------------------------------
> - * Bridge
> + * PLL Setup
>   */
>  
> -static u32 rcar_lvds_lvdpllcr_gen2(unsigned int freq)
> +static void rcar_lvds_pll_setup_gen2(struct rcar_lvds *lvds, unsigned int freq)
>  {
> -	if (freq < 39000)
> -		return LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_38M;
> -	else if (freq < 61000)
> -		return LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_60M;
> -	else if (freq < 121000)
> -		return LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_121M;
> +	u32 val;
> +
> +	if (freq < 39000000)
> +		val = LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_38M;
> +	else if (freq < 61000000)
> +		val = LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_60M;
> +	else if (freq < 121000000)
> +		val = LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_121M;
>  	else
> -		return LVDPLLCR_PLLDLYCNT_150M;
> +		val = LVDPLLCR_PLLDLYCNT_150M;
> +
> +	rcar_lvds_write(lvds, LVDPLLCR, val);
>  }
>  
> -static u32 rcar_lvds_lvdpllcr_gen3(unsigned int freq)
> +static void rcar_lvds_pll_setup_gen3(struct rcar_lvds *lvds, unsigned int freq)
>  {
> -	if (freq < 42000)
> -		return LVDPLLCR_PLLDIVCNT_42M;
> -	else if (freq < 85000)
> -		return LVDPLLCR_PLLDIVCNT_85M;
> -	else if (freq < 128000)
> -		return LVDPLLCR_PLLDIVCNT_128M;
> +	u32 val;
> +
> +	if (freq < 42000000)
> +		val = LVDPLLCR_PLLDIVCNT_42M;
> +	else if (freq < 85000000)
> +		val = LVDPLLCR_PLLDIVCNT_85M;
> +	else if (freq < 128000000)
> +		val = LVDPLLCR_PLLDIVCNT_128M;
>  	else
> -		return LVDPLLCR_PLLDIVCNT_148M;
> +		val = LVDPLLCR_PLLDIVCNT_148M;
> +
> +	rcar_lvds_write(lvds, LVDPLLCR, val);
>  }
>  
> +struct pll_info {
> +	unsigned long diff;
> +	unsigned int pll_m;
> +	unsigned int pll_n;
> +	unsigned int pll_e;
> +	unsigned int div;
> +	u32 clksel;
> +};
> +
> +static void rcar_lvds_d3_e3_pll_calc(struct rcar_lvds *lvds, struct clk *clk,
> +				     unsigned long target, struct pll_info *pll,
> +				     u32 clksel)
> +{
> +	unsigned long output;
> +	unsigned long fin;
> +	unsigned int m_min;
> +	unsigned int m_max;
> +	unsigned int m;
> +	int error;
> +
> +	if (!clk)
> +		return;
> +
> +	/*
> +	 * The LVDS PLL is made of a pre-divider and a multiplier (strangerly

strangely

> +	 * enough called M and N respectively), followed by a post-divider E.
> +	 *
> +	 *         ,-----.         ,-----.     ,-----.         ,-----.
> +	 * Fin --> | 1/M | -Fpdf-> | PFD | --> | VCO | -Fvco-> | 1/E | --> Fout
> +	 *         `-----'     ,-> |     |     `-----'   |     `-----'
> +	 *                     |   `-----'               |
> +	 *                     |         ,-----.         |
> +	 *                     `-------- | 1/N | <-------'
> +	 *                               `-----'
> +	 *
> +	 * The clock output by the PLL is then further divided by a programmable
> +	 * divider DIV to achieve the desired target frequency. Finally, an
> +	 * optional fixed /7 divider is used to convert the bit clock to a pixel
> +	 * clock (as LVDS transmits 7 bits per lane per clock sample).
> +	 *
> +	 *          ,-------.     ,-----.     |\
> +	 * Fout --> | 1/DIV | --> | 1/7 | --> | |
> +	 *          `-------'  |  `-----'     | | --> dot clock
> +	 *                     `------------> | |
> +	 *                                    |/
> +	 *
> +	 * The /7 divider is optional when the LVDS PLL is used to generate a
> +	 * dot clock for the DU RGB output, without using the LVDS encoder. We
> +	 * don't support this configuration yet.
> +	 *
> +	 * The PLL allowed input frequency range is 12 MHz to 192 MHz.
> +	 */
> +
> +	fin = clk_get_rate(clk);
> +	if (fin < 12000000 || fin > 192000000)
> +		return;
> +
> +	/*
> +	 * The comparison frequency range is 12 MHz to 24 MHz, which limits the
> +	 * allowed values for the pre-divider M (normal range 1-8).
> +	 *
> +	 * Fpfd = Fin / M
> +	 */
> +	m_min = max_t(unsigned int, 1, DIV_ROUND_UP(fin, 24000000));
> +	m_max = min_t(unsigned int, 8, fin / 12000000);
> +
> +	for (m = m_min; m <= m_max; ++m) {
> +		unsigned long fpfd;
> +		unsigned int n_min;
> +		unsigned int n_max;
> +		unsigned int n;
> +
> +		/*
> +		 * The VCO operating range is 900 Mhz to 1800 MHz, which limits
> +		 * the allowed values for the multiplier N (normal range
> +		 * 60-120).
> +		 *
> +		 * Fvco = Fin * N / M
> +		 */
> +		fpfd = fin / m;
> +		n_min = max_t(unsigned int, 60, DIV_ROUND_UP(900000000, fpfd));
> +		n_max = min_t(unsigned int, 120, 1800000000 / fpfd);
> +
> +		for (n = n_min; n < n_max; ++n) {
> +			unsigned long fvco;
> +			unsigned int e_min;
> +			unsigned int e;
> +
> +			/*
> +			 * The output frequency is limited to 1039.5 MHz,
> +			 * limiting again the allowed values for the
> +			 * post-divider E (normal value 1, 2 or 4).
> +			 *
> +			 * Fout = Fvco / E
> +			 */
> +			fvco = fpfd * n;
> +			e_min = fvco > 1039500000 ? 1 : 0;
> +
> +			for (e = e_min; e < 3; ++e) {
> +				unsigned long fout;
> +				unsigned long diff;
> +				unsigned int div;
> +
> +				/*
> +				 * Finally we have a programable divider after
> +				 * the PLL, followed by a an optional fixed /7
> +				 * divider.
> +				 */
> +				fout = fvco / (1 << e) / 7;
> +				div = DIV_ROUND_CLOSEST(fout, target);
> +				diff = abs(fout / div - target);
> +
> +				if (diff < pll->diff) {
> +					pll->diff = diff;
> +					pll->pll_m = m;
> +					pll->pll_n = n;
> +					pll->pll_e = e;
> +					pll->div = div;
> +					pll->clksel = clksel;
> +
> +					if (diff == 0)
> +						goto done;
> +				}
> +			}
> +		}
> +	}
> +
> +done:
> +	output = fin * pll->pll_n / pll->pll_m / (1 << pll->pll_e)
> +	       / 7 / pll->div;
> +	error = (long)(output - target) * 10000 / (long)target;
> +
> +	dev_dbg(lvds->dev,
> +		"%pC %lu Hz -> Fout %lu Hz (target %lu Hz, error %d.%02u%%), PLL M/N/E/DIV %u/%u/%u/%u\n",
> +		clk, fin, output, target, error / 100,
> +		error < 0 ? -error % 100 : error % 100,
> +		pll->pll_m, pll->pll_n, pll->pll_e, pll->div);
> +}
> +
> +static void rcar_lvds_pll_setup_d3_e3(struct rcar_lvds *lvds, unsigned int freq)
> +{
> +	struct pll_info pll = { .diff = (unsigned long)-1 };
> +	u32 lvdpllcr;
> +
> +	rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.dotclkin[0], freq, &pll,
> +				 LVDPLLCR_CKSEL_DU_DOTCLKIN(0));
> +	rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.dotclkin[1], freq, &pll,
> +				 LVDPLLCR_CKSEL_DU_DOTCLKIN(1));
> +	rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.extal, freq, &pll,
> +				 LVDPLLCR_CKSEL_EXTAL);
> +
> +	lvdpllcr = LVDPLLCR_PLLON | pll.clksel | LVDPLLCR_CLKOUT
> +		 | LVDPLLCR_PLLN(pll.pll_n - 1) | LVDPLLCR_PLLM(pll.pll_m - 1);
> +
> +	if (pll.pll_e > 0)
> +		lvdpllcr |= LVDPLLCR_STP_CLKOUTE | LVDPLLCR_OUTCLKSEL
> +			 |  LVDPLLCR_PLLE(pll.pll_e - 1);
> +
> +	rcar_lvds_write(lvds, LVDPLLCR, lvdpllcr);
> +
> +	if (pll.div > 1)
> +		rcar_lvds_write(lvds, LVDDIV, LVDDIV_DIVSEL |
> +				LVDDIV_DIVRESET | LVDDIV_DIV(pll.div - 1));
> +	else
> +		rcar_lvds_write(lvds, LVDDIV, 0);

The datasheet says DIVRESET == 0 is "reset" and DIVRESET == 1 is "clear". I haven't found anything clarifying what that exactly means, but my best guess would have been that this should be the other way round: assert LVDDIV_DIVRESET ("clear" the divider) if the divider is 1, and deassert it ("reset" the divider) otherwise.

The BSP driver, however, does it the same way as above, and the PLL setting examples (table 37.5) in the datasheet also have DIVRESET asserted when the divider is on, so the above code is likely to be correct. Maybe it's the LVDDIV register description that is wrong?

At any rate, I think this is confusing enough to deserve a comment.

> +}
> +
> +/* -----------------------------------------------------------------------------
> + * Bridge
> + */
> +
>  static void rcar_lvds_enable(struct drm_bridge *bridge)
>  {
>  	struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
> @@ -164,14 +351,13 @@ static void rcar_lvds_enable(struct drm_bridge *bridge)
>  	 * do we get a state pointer?
>  	 */
>  	struct drm_crtc *crtc = lvds->bridge.encoder->crtc;
> -	u32 lvdpllcr;
>  	u32 lvdhcr;
>  	u32 lvdcr0;
>  	int ret;
>  
>  	WARN_ON(lvds->enabled);
>  
> -	ret = clk_prepare_enable(lvds->clock);
> +	ret = clk_prepare_enable(lvds->clocks.mod);
>  	if (ret < 0)
>  		return;
>  
> @@ -196,12 +382,13 @@ static void rcar_lvds_enable(struct drm_bridge *bridge)
>  
>  	rcar_lvds_write(lvds, LVDCHCR, lvdhcr);
>  
> +	if (lvds->info->quirks & RCAR_LVDS_QUIRK_DUAL_LINK) {
> +		/* Disable dual-link mode. */
> +		rcar_lvds_write(lvds, LVDSTRIPE, 0);
> +	}
> +
>  	/* PLL clock configuration. */
> -	if (lvds->info->quirks & RCAR_LVDS_QUIRK_GEN2_PLLCR)
> -		lvdpllcr = rcar_lvds_lvdpllcr_gen2(mode->clock);
> -	else
> -		lvdpllcr = rcar_lvds_lvdpllcr_gen3(mode->clock);
> -	rcar_lvds_write(lvds, LVDPLLCR, lvdpllcr);
> +	lvds->info->pll_setup(lvds, mode->clock * 1000);
>  
>  	/* Set the LVDS mode and select the input. */
>  	lvdcr0 = lvds->mode << LVDCR0_LVMD_SHIFT;
> @@ -220,11 +407,16 @@ static void rcar_lvds_enable(struct drm_bridge *bridge)
>  		rcar_lvds_write(lvds, LVDCR0, lvdcr0);
>  	}
>  
> -	/* Turn the PLL on. */
> -	lvdcr0 |= LVDCR0_PLLON;
> -	rcar_lvds_write(lvds, LVDCR0, lvdcr0);
> +	if (!(lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL)) {
> +		/*
> +		 * Turn the PLL on (simple PLL only, extended PLL is fully
> +		 * controlled through LVDPLLCR).
> +		 */
> +		lvdcr0 |= LVDCR0_PLLON;
> +		rcar_lvds_write(lvds, LVDCR0, lvdcr0);
> +	}
>  
> -	if (lvds->info->gen > 2) {
> +	if (lvds->info->quirks & RCAR_LVDS_QUIRK_PWD) {
>  		/* Set LVDS normal mode. */
>  		lvdcr0 |= LVDCR0_PWD;
>  		rcar_lvds_write(lvds, LVDCR0, lvdcr0);
> @@ -236,8 +428,10 @@ static void rcar_lvds_enable(struct drm_bridge *bridge)
>  		rcar_lvds_write(lvds, LVDCR0, lvdcr0);
>  	}
>  
> -	/* Wait for the startup delay. */
> -	usleep_range(100, 150);
> +	if (!(lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL)) {
> +		/* Wait for the PLL startup delay (simple PLL only). */
> +		usleep_range(100, 150);
> +	}
>  
>  	/* Turn the output on. */
>  	lvdcr0 |= LVDCR0_LVRES;
> @@ -264,8 +458,9 @@ 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);
> +	clk_disable_unprepare(lvds->clocks.mod);
>  
>  	lvds->enabled = false;
>  }
> @@ -446,6 +641,60 @@ static int rcar_lvds_parse_dt(struct rcar_lvds *lvds)
>  	return ret;
>  }
>  
> +static struct clk *rcar_lvds_get_clock(struct rcar_lvds *lvds, const char *name,
> +				       bool optional)
> +{
> +	struct clk *clk;
> +
> +	clk = devm_clk_get(lvds->dev, name);
> +	if (!IS_ERR(clk))
> +		return clk;
> +
> +	if (PTR_ERR(clk) == -ENOENT && optional)
> +		return NULL;
> +
> +	if (PTR_ERR(clk) != -EPROBE_DEFER)
> +		dev_err(lvds->dev, "failed to get %s clock\n",
> +			name ? name : "module");
> +
> +	return clk;
> +}
> +
> +static int rcar_lvds_get_clocks(struct rcar_lvds *lvds)
> +{
> +	lvds->clocks.mod = rcar_lvds_get_clock(lvds, NULL, false);
> +	if (IS_ERR(lvds->clocks.mod))
> +		return PTR_ERR(lvds->clocks.mod);
> +
> +	/*
> +	 * LVDS encoders without an extended PLL have no external clock inputs.
> +	 */
> +	if (!(lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL))
> +		return 0;
> +
> +	lvds->clocks.extal = rcar_lvds_get_clock(lvds, "extal", true);
> +	if (IS_ERR(lvds->clocks.extal))
> +		return PTR_ERR(lvds->clocks.extal);
> +
> +	lvds->clocks.dotclkin[0] = rcar_lvds_get_clock(lvds, "dclkin.0", true);
> +	if (IS_ERR(lvds->clocks.dotclkin[0]))
> +		return PTR_ERR(lvds->clocks.dotclkin[0]);
> +
> +	lvds->clocks.dotclkin[1] = rcar_lvds_get_clock(lvds, "dclkin.1", true);
> +	if (IS_ERR(lvds->clocks.dotclkin[1]))
> +		return PTR_ERR(lvds->clocks.dotclkin[1]);
> +
> +	/* At least one input to the PLL must be available. */
> +	if (!lvds->clocks.extal && !lvds->clocks.dotclkin[0] &&
> +	    !lvds->clocks.dotclkin[1]) {
> +		dev_err(lvds->dev,
> +			"no input clock (extal, dclkin.0 or dclkin.1)\n");
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
>  static int rcar_lvds_probe(struct platform_device *pdev)
>  {
>  	struct rcar_lvds *lvds;
> @@ -475,11 +724,9 @@ static int rcar_lvds_probe(struct platform_device *pdev)
>  	if (IS_ERR(lvds->mmio))
>  		return PTR_ERR(lvds->mmio);
>  
> -	lvds->clock = devm_clk_get(&pdev->dev, NULL);
> -	if (IS_ERR(lvds->clock)) {
> -		dev_err(&pdev->dev, "failed to get clock\n");
> -		return PTR_ERR(lvds->clock);
> -	}
> +	ret = rcar_lvds_get_clocks(lvds);
> +	if (ret < 0)
> +		return ret;
>  
>  	drm_bridge_add(&lvds->bridge);
>  
> @@ -497,21 +744,39 @@ static int rcar_lvds_remove(struct platform_device *pdev)
>  
>  static const struct rcar_lvds_device_info rcar_lvds_gen2_info = {
>  	.gen = 2,
> -	.quirks = RCAR_LVDS_QUIRK_GEN2_PLLCR,
> +	.pll_setup = rcar_lvds_pll_setup_gen2,
>  };
>  
>  static const struct rcar_lvds_device_info rcar_lvds_r8a7790_info = {
>  	.gen = 2,
> -	.quirks = RCAR_LVDS_QUIRK_GEN2_PLLCR | RCAR_LVDS_QUIRK_LANES,
> +	.quirks = RCAR_LVDS_QUIRK_LANES,
> +	.pll_setup = rcar_lvds_pll_setup_gen2,
>  };
>  
>  static const struct rcar_lvds_device_info rcar_lvds_gen3_info = {
>  	.gen = 3,
> +	.quirks = RCAR_LVDS_QUIRK_PWD,
> +	.pll_setup = rcar_lvds_pll_setup_gen3,
>  };
>  
>  static const struct rcar_lvds_device_info rcar_lvds_r8a77970_info = {
>  	.gen = 3,
> -	.quirks = RCAR_LVDS_QUIRK_GEN2_PLLCR | RCAR_LVDS_QUIRK_GEN3_LVEN,
> +	.quirks = RCAR_LVDS_QUIRK_PWD | RCAR_LVDS_QUIRK_GEN3_LVEN,
> +	.pll_setup = rcar_lvds_pll_setup_gen2,
> +};
> +
> +static const struct rcar_lvds_device_info rcar_lvds_r8a77990_info = {
> +	.gen = 3,
> +	.quirks = RCAR_LVDS_QUIRK_GEN3_LVEN | RCAR_LVDS_QUIRK_EXT_PLL
> +		| RCAR_LVDS_QUIRK_DUAL_LINK,
> +	.pll_setup = rcar_lvds_pll_setup_d3_e3,
> +};
> +
> +static const struct rcar_lvds_device_info rcar_lvds_r8a77995_info = {
> +	.gen = 3,
> +	.quirks = RCAR_LVDS_QUIRK_GEN3_LVEN | RCAR_LVDS_QUIRK_PWD
> +		| RCAR_LVDS_QUIRK_EXT_PLL | RCAR_LVDS_QUIRK_DUAL_LINK,
> +	.pll_setup = rcar_lvds_pll_setup_d3_e3,
>  };
>  
>  static const struct of_device_id rcar_lvds_of_table[] = {
> @@ -523,6 +788,8 @@ static const struct of_device_id rcar_lvds_of_table[] = {
>  	{ .compatible = "renesas,r8a7796-lvds", .data = &rcar_lvds_gen3_info },
>  	{ .compatible = "renesas,r8a77970-lvds", .data = &rcar_lvds_r8a77970_info },
>  	{ .compatible = "renesas,r8a77980-lvds", .data = &rcar_lvds_gen3_info },
> +	{ .compatible = "renesas,r8a77990-lvds", .data = &rcar_lvds_r8a77990_info },
> +	{ .compatible = "renesas,r8a77995-lvds", .data = &rcar_lvds_r8a77995_info },
>  	{ }
>  };
>  
> diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h b/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
> index 4870f50d9bec..87149f2f8056 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
> @@ -18,7 +18,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
> @@ -27,21 +27,36 @@
>  #define LVDCR1_CLKSTBY			(3 << 0)
>  
>  #define LVDPLLCR			0x0008
> +/* Gen2 & V3M */
>  #define LVDPLLCR_CEEN			(1 << 14)
>  #define LVDPLLCR_FBEN			(1 << 13)
>  #define LVDPLLCR_COSEL			(1 << 12)
> -/* Gen2 */
>  #define LVDPLLCR_PLLDLYCNT_150M		(0x1bf << 0)
>  #define LVDPLLCR_PLLDLYCNT_121M		(0x22c << 0)
>  #define LVDPLLCR_PLLDLYCNT_60M		(0x77b << 0)
>  #define LVDPLLCR_PLLDLYCNT_38M		(0x69a << 0)
>  #define LVDPLLCR_PLLDLYCNT_MASK		(0x7ff << 0)
> -/* Gen3 */
> +/* Gen3 but V3M,D3 and E3 */
>  #define LVDPLLCR_PLLDIVCNT_42M		(0x014cb << 0)
>  #define LVDPLLCR_PLLDIVCNT_85M		(0x00a45 << 0)
>  #define LVDPLLCR_PLLDIVCNT_128M		(0x006c3 << 0)
>  #define LVDPLLCR_PLLDIVCNT_148M		(0x046c1 << 0)
>  #define LVDPLLCR_PLLDIVCNT_MASK		(0x7ffff << 0)
> +/* D3 and E3 */
> +#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_DOTCLKIN(n)	((5 + (n) * 2) << 17)
> +#define LVDPLLCR_OCKSEL			(1 << 16)
> +#define LVDPLLCR_STP_CLKOUTE		(1 << 14)
> +#define LVDPLLCR_OUTCLKSEL		(1 << 12)
> +#define LVDPLLCR_CLKOUT			(1 << 11)
> +#define LVDPLLCR_PLLE(n)		((n) << 10)
> +#define LVDPLLCR_PLLN(n)		((n) << 3)
> +#define LVDPLLCR_PLLM(n)		((n) << 0)
>  
>  #define LVDCTRCR			0x000c
>  #define LVDCTRCR_CTR3SEL_ZERO		(0 << 12)
> @@ -71,4 +86,26 @@
>  #define LVDCHCR_CHSEL_CH(n, c)		((((c) - (n)) & 3) << ((n) * 4))
>  #define LVDCHCR_CHSEL_MASK(n)		(3 << ((n) * 4))
>  
> +/* All registers below are specific to D3 and E3 */
> +#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		(1 << 1)
> +#define LVDSTRIPE_ST_ON			(1 << 0)
> +
> +#define LVDSCR				0x0018
> +#define LVDSCR_DEPTH(n)			(((n) - 1) << 29)
> +#define LVDSCR_BANDSET			(1 << 28)
> +#define LVDSCR_TWGCNT(n)		((((n) - 256) / 16) << 24)
> +#define LVDSCR_SDIV(n)			((n) << 22)
> +#define LVDSCR_MODE			(1 << 21)
> +#define LVDSCR_RSTN			(1 << 20)
> +
> +#define LVDDIV				0x001c
> +#define LVDDIV_DIVSEL			(1 << 8)
> +#define LVDDIV_DIVRESET			(1 << 7)
> +#define LVDDIV_DIVSTP			(1 << 6)
> +#define LVDDIV_DIV(n)			((n) << 0)
> +
>  #endif /* __RCAR_LVDS_REGS_H__ */
> -- 
> Regards,
> 
> Laurent Pinchart
>

With clarification about the meaning of LVDDIV_DIVRESET:

Reviewed-by: Ulrich Hecht <uli+renesas@fpond.eu>

CU
Uli

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

* Re: [PATCH v2 05/16] drm: rcar-du: lvds: D3/E3 support
@ 2018-09-17 10:53     ` Ulrich Hecht
  0 siblings, 0 replies; 118+ messages in thread
From: Ulrich Hecht @ 2018-09-17 10:53 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham

Thank you for your patch!

> On September 14, 2018 at 11:10 AM Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> wrote:
> 
> 
> The LVDS encoders in the D3 and E3 SoCs differ significantly from those
> in the other R-Car Gen3 family members:
> 
> - The LVDS PLL architecture is more complex and requires computing PLL
>   parameters manually.
> - The PLL uses external clocks as inputs, which need to be retrieved
>   from DT.
> - In addition to the different PLL setup, the startup sequence has
>   changed *again* (seems someone had trouble making his/her mind).
> 
> Supporting all this requires DT bindings extensions for external clocks,
> brand new PLL setup code, and a few quirks to handle the differences in
> the startup sequence.
> 
> The implementation doesn't support all hardware features yet, namely
> 
> - Using the LV[01] clocks generated by the CPG as PLL input.
> - Providing the LVDS PLL clock to the DU for use with the RGB output.
> 
> Those features can be added later when the need will arise.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> ---
> Changes since v1:
> 
> - Don't compile-out debug code based on DEBUG and CONFIG_DYNAMIC_DEBUG
> - Test all three input clocks (DOTCLKIN[01] and EXTAL) and pick the best
>   one
> ---
>  drivers/gpu/drm/rcar-du/rcar_lvds.c      | 355 +++++++++++++++++++++++++++----
>  drivers/gpu/drm/rcar-du/rcar_lvds_regs.h |  43 +++-
>  2 files changed, 351 insertions(+), 47 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c b/drivers/gpu/drm/rcar-du/rcar_lvds.c
> index ce0eb68c3416..23e7743144c8 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_lvds.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_lvds.c
> @@ -24,6 +24,8 @@
>  
>  #include "rcar_lvds_regs.h"
>  
> +struct rcar_lvds;
> +
>  /* Keep in sync with the LVDCR0.LVMD hardware register values. */
>  enum rcar_lvds_mode {
>  	RCAR_LVDS_MODE_JEIDA = 0,
> @@ -31,14 +33,16 @@ enum rcar_lvds_mode {
>  	RCAR_LVDS_MODE_VESA = 4,
>  };
>  
> -#define RCAR_LVDS_QUIRK_LANES	(1 << 0)	/* LVDS lanes 1 and 3 inverted */
> -#define RCAR_LVDS_QUIRK_GEN2_PLLCR (1 << 1)	/* LVDPLLCR has gen2 layout */
> -#define RCAR_LVDS_QUIRK_GEN3_LVEN (1 << 2)	/* LVEN bit needs to be set */
> -						/* on R8A77970/R8A7799x */
> +#define RCAR_LVDS_QUIRK_LANES		BIT(0)	/* LVDS lanes 1 and 3 inverted */
> +#define RCAR_LVDS_QUIRK_GEN3_LVEN	BIT(1)	/* LVEN bit needs to be set on R8A77970/R8A7799x */
> +#define RCAR_LVDS_QUIRK_PWD		BIT(2)	/* PWD bit available (all of Gen3 but E3) */
> +#define RCAR_LVDS_QUIRK_EXT_PLL		BIT(3)	/* Has extended PLL */
> +#define RCAR_LVDS_QUIRK_DUAL_LINK	BIT(4)	/* Supports dual-link operation */
>  
>  struct rcar_lvds_device_info {
>  	unsigned int gen;
>  	unsigned int quirks;
> +	void (*pll_setup)(struct rcar_lvds *lvds, unsigned int freq);
>  };
>  
>  struct rcar_lvds {
> @@ -52,7 +56,11 @@ struct rcar_lvds {
>  	struct drm_panel *panel;
>  
>  	void __iomem *mmio;
> -	struct clk *clock;
> +	struct {
> +		struct clk *mod;		/* CPG module clock */
> +		struct clk *extal;		/* External clock */
> +		struct clk *dotclkin[2];	/* External DU clocks */
> +	} clocks;
>  	bool enabled;
>  
>  	struct drm_display_mode display_mode;
> @@ -128,33 +136,212 @@ static const struct drm_connector_funcs rcar_lvds_conn_funcs = {
>  };
>  
>  /* -----------------------------------------------------------------------------
> - * Bridge
> + * PLL Setup
>   */
>  
> -static u32 rcar_lvds_lvdpllcr_gen2(unsigned int freq)
> +static void rcar_lvds_pll_setup_gen2(struct rcar_lvds *lvds, unsigned int freq)
>  {
> -	if (freq < 39000)
> -		return LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_38M;
> -	else if (freq < 61000)
> -		return LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_60M;
> -	else if (freq < 121000)
> -		return LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_121M;
> +	u32 val;
> +
> +	if (freq < 39000000)
> +		val = LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_38M;
> +	else if (freq < 61000000)
> +		val = LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_60M;
> +	else if (freq < 121000000)
> +		val = LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_121M;
>  	else
> -		return LVDPLLCR_PLLDLYCNT_150M;
> +		val = LVDPLLCR_PLLDLYCNT_150M;
> +
> +	rcar_lvds_write(lvds, LVDPLLCR, val);
>  }
>  
> -static u32 rcar_lvds_lvdpllcr_gen3(unsigned int freq)
> +static void rcar_lvds_pll_setup_gen3(struct rcar_lvds *lvds, unsigned int freq)
>  {
> -	if (freq < 42000)
> -		return LVDPLLCR_PLLDIVCNT_42M;
> -	else if (freq < 85000)
> -		return LVDPLLCR_PLLDIVCNT_85M;
> -	else if (freq < 128000)
> -		return LVDPLLCR_PLLDIVCNT_128M;
> +	u32 val;
> +
> +	if (freq < 42000000)
> +		val = LVDPLLCR_PLLDIVCNT_42M;
> +	else if (freq < 85000000)
> +		val = LVDPLLCR_PLLDIVCNT_85M;
> +	else if (freq < 128000000)
> +		val = LVDPLLCR_PLLDIVCNT_128M;
>  	else
> -		return LVDPLLCR_PLLDIVCNT_148M;
> +		val = LVDPLLCR_PLLDIVCNT_148M;
> +
> +	rcar_lvds_write(lvds, LVDPLLCR, val);
>  }
>  
> +struct pll_info {
> +	unsigned long diff;
> +	unsigned int pll_m;
> +	unsigned int pll_n;
> +	unsigned int pll_e;
> +	unsigned int div;
> +	u32 clksel;
> +};
> +
> +static void rcar_lvds_d3_e3_pll_calc(struct rcar_lvds *lvds, struct clk *clk,
> +				     unsigned long target, struct pll_info *pll,
> +				     u32 clksel)
> +{
> +	unsigned long output;
> +	unsigned long fin;
> +	unsigned int m_min;
> +	unsigned int m_max;
> +	unsigned int m;
> +	int error;
> +
> +	if (!clk)
> +		return;
> +
> +	/*
> +	 * The LVDS PLL is made of a pre-divider and a multiplier (strangerly

strangely

> +	 * enough called M and N respectively), followed by a post-divider E.
> +	 *
> +	 *         ,-----.         ,-----.     ,-----.         ,-----.
> +	 * Fin --> | 1/M | -Fpdf-> | PFD | --> | VCO | -Fvco-> | 1/E | --> Fout
> +	 *         `-----'     ,-> |     |     `-----'   |     `-----'
> +	 *                     |   `-----'               |
> +	 *                     |         ,-----.         |
> +	 *                     `-------- | 1/N | <-------'
> +	 *                               `-----'
> +	 *
> +	 * The clock output by the PLL is then further divided by a programmable
> +	 * divider DIV to achieve the desired target frequency. Finally, an
> +	 * optional fixed /7 divider is used to convert the bit clock to a pixel
> +	 * clock (as LVDS transmits 7 bits per lane per clock sample).
> +	 *
> +	 *          ,-------.     ,-----.     |\
> +	 * Fout --> | 1/DIV | --> | 1/7 | --> | |
> +	 *          `-------'  |  `-----'     | | --> dot clock
> +	 *                     `------------> | |
> +	 *                                    |/
> +	 *
> +	 * The /7 divider is optional when the LVDS PLL is used to generate a
> +	 * dot clock for the DU RGB output, without using the LVDS encoder. We
> +	 * don't support this configuration yet.
> +	 *
> +	 * The PLL allowed input frequency range is 12 MHz to 192 MHz.
> +	 */
> +
> +	fin = clk_get_rate(clk);
> +	if (fin < 12000000 || fin > 192000000)
> +		return;
> +
> +	/*
> +	 * The comparison frequency range is 12 MHz to 24 MHz, which limits the
> +	 * allowed values for the pre-divider M (normal range 1-8).
> +	 *
> +	 * Fpfd = Fin / M
> +	 */
> +	m_min = max_t(unsigned int, 1, DIV_ROUND_UP(fin, 24000000));
> +	m_max = min_t(unsigned int, 8, fin / 12000000);
> +
> +	for (m = m_min; m <= m_max; ++m) {
> +		unsigned long fpfd;
> +		unsigned int n_min;
> +		unsigned int n_max;
> +		unsigned int n;
> +
> +		/*
> +		 * The VCO operating range is 900 Mhz to 1800 MHz, which limits
> +		 * the allowed values for the multiplier N (normal range
> +		 * 60-120).
> +		 *
> +		 * Fvco = Fin * N / M
> +		 */
> +		fpfd = fin / m;
> +		n_min = max_t(unsigned int, 60, DIV_ROUND_UP(900000000, fpfd));
> +		n_max = min_t(unsigned int, 120, 1800000000 / fpfd);
> +
> +		for (n = n_min; n < n_max; ++n) {
> +			unsigned long fvco;
> +			unsigned int e_min;
> +			unsigned int e;
> +
> +			/*
> +			 * The output frequency is limited to 1039.5 MHz,
> +			 * limiting again the allowed values for the
> +			 * post-divider E (normal value 1, 2 or 4).
> +			 *
> +			 * Fout = Fvco / E
> +			 */
> +			fvco = fpfd * n;
> +			e_min = fvco > 1039500000 ? 1 : 0;
> +
> +			for (e = e_min; e < 3; ++e) {
> +				unsigned long fout;
> +				unsigned long diff;
> +				unsigned int div;
> +
> +				/*
> +				 * Finally we have a programable divider after
> +				 * the PLL, followed by a an optional fixed /7
> +				 * divider.
> +				 */
> +				fout = fvco / (1 << e) / 7;
> +				div = DIV_ROUND_CLOSEST(fout, target);
> +				diff = abs(fout / div - target);
> +
> +				if (diff < pll->diff) {
> +					pll->diff = diff;
> +					pll->pll_m = m;
> +					pll->pll_n = n;
> +					pll->pll_e = e;
> +					pll->div = div;
> +					pll->clksel = clksel;
> +
> +					if (diff == 0)
> +						goto done;
> +				}
> +			}
> +		}
> +	}
> +
> +done:
> +	output = fin * pll->pll_n / pll->pll_m / (1 << pll->pll_e)
> +	       / 7 / pll->div;
> +	error = (long)(output - target) * 10000 / (long)target;
> +
> +	dev_dbg(lvds->dev,
> +		"%pC %lu Hz -> Fout %lu Hz (target %lu Hz, error %d.%02u%%), PLL M/N/E/DIV %u/%u/%u/%u\n",
> +		clk, fin, output, target, error / 100,
> +		error < 0 ? -error % 100 : error % 100,
> +		pll->pll_m, pll->pll_n, pll->pll_e, pll->div);
> +}
> +
> +static void rcar_lvds_pll_setup_d3_e3(struct rcar_lvds *lvds, unsigned int freq)
> +{
> +	struct pll_info pll = { .diff = (unsigned long)-1 };
> +	u32 lvdpllcr;
> +
> +	rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.dotclkin[0], freq, &pll,
> +				 LVDPLLCR_CKSEL_DU_DOTCLKIN(0));
> +	rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.dotclkin[1], freq, &pll,
> +				 LVDPLLCR_CKSEL_DU_DOTCLKIN(1));
> +	rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.extal, freq, &pll,
> +				 LVDPLLCR_CKSEL_EXTAL);
> +
> +	lvdpllcr = LVDPLLCR_PLLON | pll.clksel | LVDPLLCR_CLKOUT
> +		 | LVDPLLCR_PLLN(pll.pll_n - 1) | LVDPLLCR_PLLM(pll.pll_m - 1);
> +
> +	if (pll.pll_e > 0)
> +		lvdpllcr |= LVDPLLCR_STP_CLKOUTE | LVDPLLCR_OUTCLKSEL
> +			 |  LVDPLLCR_PLLE(pll.pll_e - 1);
> +
> +	rcar_lvds_write(lvds, LVDPLLCR, lvdpllcr);
> +
> +	if (pll.div > 1)
> +		rcar_lvds_write(lvds, LVDDIV, LVDDIV_DIVSEL |
> +				LVDDIV_DIVRESET | LVDDIV_DIV(pll.div - 1));
> +	else
> +		rcar_lvds_write(lvds, LVDDIV, 0);

The datasheet says DIVRESET == 0 is "reset" and DIVRESET == 1 is "clear". I haven't found anything clarifying what that exactly means, but my best guess would have been that this should be the other way round: assert LVDDIV_DIVRESET ("clear" the divider) if the divider is 1, and deassert it ("reset" the divider) otherwise.

The BSP driver, however, does it the same way as above, and the PLL setting examples (table 37.5) in the datasheet also have DIVRESET asserted when the divider is on, so the above code is likely to be correct. Maybe it's the LVDDIV register description that is wrong?

At any rate, I think this is confusing enough to deserve a comment.

> +}
> +
> +/* -----------------------------------------------------------------------------
> + * Bridge
> + */
> +
>  static void rcar_lvds_enable(struct drm_bridge *bridge)
>  {
>  	struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
> @@ -164,14 +351,13 @@ static void rcar_lvds_enable(struct drm_bridge *bridge)
>  	 * do we get a state pointer?
>  	 */
>  	struct drm_crtc *crtc = lvds->bridge.encoder->crtc;
> -	u32 lvdpllcr;
>  	u32 lvdhcr;
>  	u32 lvdcr0;
>  	int ret;
>  
>  	WARN_ON(lvds->enabled);
>  
> -	ret = clk_prepare_enable(lvds->clock);
> +	ret = clk_prepare_enable(lvds->clocks.mod);
>  	if (ret < 0)
>  		return;
>  
> @@ -196,12 +382,13 @@ static void rcar_lvds_enable(struct drm_bridge *bridge)
>  
>  	rcar_lvds_write(lvds, LVDCHCR, lvdhcr);
>  
> +	if (lvds->info->quirks & RCAR_LVDS_QUIRK_DUAL_LINK) {
> +		/* Disable dual-link mode. */
> +		rcar_lvds_write(lvds, LVDSTRIPE, 0);
> +	}
> +
>  	/* PLL clock configuration. */
> -	if (lvds->info->quirks & RCAR_LVDS_QUIRK_GEN2_PLLCR)
> -		lvdpllcr = rcar_lvds_lvdpllcr_gen2(mode->clock);
> -	else
> -		lvdpllcr = rcar_lvds_lvdpllcr_gen3(mode->clock);
> -	rcar_lvds_write(lvds, LVDPLLCR, lvdpllcr);
> +	lvds->info->pll_setup(lvds, mode->clock * 1000);
>  
>  	/* Set the LVDS mode and select the input. */
>  	lvdcr0 = lvds->mode << LVDCR0_LVMD_SHIFT;
> @@ -220,11 +407,16 @@ static void rcar_lvds_enable(struct drm_bridge *bridge)
>  		rcar_lvds_write(lvds, LVDCR0, lvdcr0);
>  	}
>  
> -	/* Turn the PLL on. */
> -	lvdcr0 |= LVDCR0_PLLON;
> -	rcar_lvds_write(lvds, LVDCR0, lvdcr0);
> +	if (!(lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL)) {
> +		/*
> +		 * Turn the PLL on (simple PLL only, extended PLL is fully
> +		 * controlled through LVDPLLCR).
> +		 */
> +		lvdcr0 |= LVDCR0_PLLON;
> +		rcar_lvds_write(lvds, LVDCR0, lvdcr0);
> +	}
>  
> -	if (lvds->info->gen > 2) {
> +	if (lvds->info->quirks & RCAR_LVDS_QUIRK_PWD) {
>  		/* Set LVDS normal mode. */
>  		lvdcr0 |= LVDCR0_PWD;
>  		rcar_lvds_write(lvds, LVDCR0, lvdcr0);
> @@ -236,8 +428,10 @@ static void rcar_lvds_enable(struct drm_bridge *bridge)
>  		rcar_lvds_write(lvds, LVDCR0, lvdcr0);
>  	}
>  
> -	/* Wait for the startup delay. */
> -	usleep_range(100, 150);
> +	if (!(lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL)) {
> +		/* Wait for the PLL startup delay (simple PLL only). */
> +		usleep_range(100, 150);
> +	}
>  
>  	/* Turn the output on. */
>  	lvdcr0 |= LVDCR0_LVRES;
> @@ -264,8 +458,9 @@ 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);
> +	clk_disable_unprepare(lvds->clocks.mod);
>  
>  	lvds->enabled = false;
>  }
> @@ -446,6 +641,60 @@ static int rcar_lvds_parse_dt(struct rcar_lvds *lvds)
>  	return ret;
>  }
>  
> +static struct clk *rcar_lvds_get_clock(struct rcar_lvds *lvds, const char *name,
> +				       bool optional)
> +{
> +	struct clk *clk;
> +
> +	clk = devm_clk_get(lvds->dev, name);
> +	if (!IS_ERR(clk))
> +		return clk;
> +
> +	if (PTR_ERR(clk) == -ENOENT && optional)
> +		return NULL;
> +
> +	if (PTR_ERR(clk) != -EPROBE_DEFER)
> +		dev_err(lvds->dev, "failed to get %s clock\n",
> +			name ? name : "module");
> +
> +	return clk;
> +}
> +
> +static int rcar_lvds_get_clocks(struct rcar_lvds *lvds)
> +{
> +	lvds->clocks.mod = rcar_lvds_get_clock(lvds, NULL, false);
> +	if (IS_ERR(lvds->clocks.mod))
> +		return PTR_ERR(lvds->clocks.mod);
> +
> +	/*
> +	 * LVDS encoders without an extended PLL have no external clock inputs.
> +	 */
> +	if (!(lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL))
> +		return 0;
> +
> +	lvds->clocks.extal = rcar_lvds_get_clock(lvds, "extal", true);
> +	if (IS_ERR(lvds->clocks.extal))
> +		return PTR_ERR(lvds->clocks.extal);
> +
> +	lvds->clocks.dotclkin[0] = rcar_lvds_get_clock(lvds, "dclkin.0", true);
> +	if (IS_ERR(lvds->clocks.dotclkin[0]))
> +		return PTR_ERR(lvds->clocks.dotclkin[0]);
> +
> +	lvds->clocks.dotclkin[1] = rcar_lvds_get_clock(lvds, "dclkin.1", true);
> +	if (IS_ERR(lvds->clocks.dotclkin[1]))
> +		return PTR_ERR(lvds->clocks.dotclkin[1]);
> +
> +	/* At least one input to the PLL must be available. */
> +	if (!lvds->clocks.extal && !lvds->clocks.dotclkin[0] &&
> +	    !lvds->clocks.dotclkin[1]) {
> +		dev_err(lvds->dev,
> +			"no input clock (extal, dclkin.0 or dclkin.1)\n");
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
>  static int rcar_lvds_probe(struct platform_device *pdev)
>  {
>  	struct rcar_lvds *lvds;
> @@ -475,11 +724,9 @@ static int rcar_lvds_probe(struct platform_device *pdev)
>  	if (IS_ERR(lvds->mmio))
>  		return PTR_ERR(lvds->mmio);
>  
> -	lvds->clock = devm_clk_get(&pdev->dev, NULL);
> -	if (IS_ERR(lvds->clock)) {
> -		dev_err(&pdev->dev, "failed to get clock\n");
> -		return PTR_ERR(lvds->clock);
> -	}
> +	ret = rcar_lvds_get_clocks(lvds);
> +	if (ret < 0)
> +		return ret;
>  
>  	drm_bridge_add(&lvds->bridge);
>  
> @@ -497,21 +744,39 @@ static int rcar_lvds_remove(struct platform_device *pdev)
>  
>  static const struct rcar_lvds_device_info rcar_lvds_gen2_info = {
>  	.gen = 2,
> -	.quirks = RCAR_LVDS_QUIRK_GEN2_PLLCR,
> +	.pll_setup = rcar_lvds_pll_setup_gen2,
>  };
>  
>  static const struct rcar_lvds_device_info rcar_lvds_r8a7790_info = {
>  	.gen = 2,
> -	.quirks = RCAR_LVDS_QUIRK_GEN2_PLLCR | RCAR_LVDS_QUIRK_LANES,
> +	.quirks = RCAR_LVDS_QUIRK_LANES,
> +	.pll_setup = rcar_lvds_pll_setup_gen2,
>  };
>  
>  static const struct rcar_lvds_device_info rcar_lvds_gen3_info = {
>  	.gen = 3,
> +	.quirks = RCAR_LVDS_QUIRK_PWD,
> +	.pll_setup = rcar_lvds_pll_setup_gen3,
>  };
>  
>  static const struct rcar_lvds_device_info rcar_lvds_r8a77970_info = {
>  	.gen = 3,
> -	.quirks = RCAR_LVDS_QUIRK_GEN2_PLLCR | RCAR_LVDS_QUIRK_GEN3_LVEN,
> +	.quirks = RCAR_LVDS_QUIRK_PWD | RCAR_LVDS_QUIRK_GEN3_LVEN,
> +	.pll_setup = rcar_lvds_pll_setup_gen2,
> +};
> +
> +static const struct rcar_lvds_device_info rcar_lvds_r8a77990_info = {
> +	.gen = 3,
> +	.quirks = RCAR_LVDS_QUIRK_GEN3_LVEN | RCAR_LVDS_QUIRK_EXT_PLL
> +		| RCAR_LVDS_QUIRK_DUAL_LINK,
> +	.pll_setup = rcar_lvds_pll_setup_d3_e3,
> +};
> +
> +static const struct rcar_lvds_device_info rcar_lvds_r8a77995_info = {
> +	.gen = 3,
> +	.quirks = RCAR_LVDS_QUIRK_GEN3_LVEN | RCAR_LVDS_QUIRK_PWD
> +		| RCAR_LVDS_QUIRK_EXT_PLL | RCAR_LVDS_QUIRK_DUAL_LINK,
> +	.pll_setup = rcar_lvds_pll_setup_d3_e3,
>  };
>  
>  static const struct of_device_id rcar_lvds_of_table[] = {
> @@ -523,6 +788,8 @@ static const struct of_device_id rcar_lvds_of_table[] = {
>  	{ .compatible = "renesas,r8a7796-lvds", .data = &rcar_lvds_gen3_info },
>  	{ .compatible = "renesas,r8a77970-lvds", .data = &rcar_lvds_r8a77970_info },
>  	{ .compatible = "renesas,r8a77980-lvds", .data = &rcar_lvds_gen3_info },
> +	{ .compatible = "renesas,r8a77990-lvds", .data = &rcar_lvds_r8a77990_info },
> +	{ .compatible = "renesas,r8a77995-lvds", .data = &rcar_lvds_r8a77995_info },
>  	{ }
>  };
>  
> diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h b/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
> index 4870f50d9bec..87149f2f8056 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
> @@ -18,7 +18,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
> @@ -27,21 +27,36 @@
>  #define LVDCR1_CLKSTBY			(3 << 0)
>  
>  #define LVDPLLCR			0x0008
> +/* Gen2 & V3M */
>  #define LVDPLLCR_CEEN			(1 << 14)
>  #define LVDPLLCR_FBEN			(1 << 13)
>  #define LVDPLLCR_COSEL			(1 << 12)
> -/* Gen2 */
>  #define LVDPLLCR_PLLDLYCNT_150M		(0x1bf << 0)
>  #define LVDPLLCR_PLLDLYCNT_121M		(0x22c << 0)
>  #define LVDPLLCR_PLLDLYCNT_60M		(0x77b << 0)
>  #define LVDPLLCR_PLLDLYCNT_38M		(0x69a << 0)
>  #define LVDPLLCR_PLLDLYCNT_MASK		(0x7ff << 0)
> -/* Gen3 */
> +/* Gen3 but V3M,D3 and E3 */
>  #define LVDPLLCR_PLLDIVCNT_42M		(0x014cb << 0)
>  #define LVDPLLCR_PLLDIVCNT_85M		(0x00a45 << 0)
>  #define LVDPLLCR_PLLDIVCNT_128M		(0x006c3 << 0)
>  #define LVDPLLCR_PLLDIVCNT_148M		(0x046c1 << 0)
>  #define LVDPLLCR_PLLDIVCNT_MASK		(0x7ffff << 0)
> +/* D3 and E3 */
> +#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_DOTCLKIN(n)	((5 + (n) * 2) << 17)
> +#define LVDPLLCR_OCKSEL			(1 << 16)
> +#define LVDPLLCR_STP_CLKOUTE		(1 << 14)
> +#define LVDPLLCR_OUTCLKSEL		(1 << 12)
> +#define LVDPLLCR_CLKOUT			(1 << 11)
> +#define LVDPLLCR_PLLE(n)		((n) << 10)
> +#define LVDPLLCR_PLLN(n)		((n) << 3)
> +#define LVDPLLCR_PLLM(n)		((n) << 0)
>  
>  #define LVDCTRCR			0x000c
>  #define LVDCTRCR_CTR3SEL_ZERO		(0 << 12)
> @@ -71,4 +86,26 @@
>  #define LVDCHCR_CHSEL_CH(n, c)		((((c) - (n)) & 3) << ((n) * 4))
>  #define LVDCHCR_CHSEL_MASK(n)		(3 << ((n) * 4))
>  
> +/* All registers below are specific to D3 and E3 */
> +#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		(1 << 1)
> +#define LVDSTRIPE_ST_ON			(1 << 0)
> +
> +#define LVDSCR				0x0018
> +#define LVDSCR_DEPTH(n)			(((n) - 1) << 29)
> +#define LVDSCR_BANDSET			(1 << 28)
> +#define LVDSCR_TWGCNT(n)		((((n) - 256) / 16) << 24)
> +#define LVDSCR_SDIV(n)			((n) << 22)
> +#define LVDSCR_MODE			(1 << 21)
> +#define LVDSCR_RSTN			(1 << 20)
> +
> +#define LVDDIV				0x001c
> +#define LVDDIV_DIVSEL			(1 << 8)
> +#define LVDDIV_DIVRESET			(1 << 7)
> +#define LVDDIV_DIVSTP			(1 << 6)
> +#define LVDDIV_DIV(n)			((n) << 0)
> +
>  #endif /* __RCAR_LVDS_REGS_H__ */
> -- 
> Regards,
> 
> Laurent Pinchart
>

With clarification about the meaning of LVDDIV_DIVRESET:

Reviewed-by: Ulrich Hecht <uli+renesas@fpond.eu>

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

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

* Re: [PATCH v2 04/16] drm: bridge: thc63: Restrict modes based on hardware operating frequency
  2018-09-17 10:53     ` Ulrich Hecht
@ 2018-09-17 12:23       ` Laurent Pinchart
  -1 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-17 12:23 UTC (permalink / raw)
  To: Ulrich Hecht
  Cc: Laurent Pinchart, dri-devel, linux-renesas-soc, Kieran Bingham

Hi Ulrich,

On Monday, 17 September 2018 13:53:43 EEST Ulrich Hecht wrote:
> > On September 14, 2018 at 11:10 AM Laurent Pinchart wrote:
> > 
> > The THC63LVD1024 is restricted to a pixel clock frequency in the range
> > of 8 to 135 MHz. Implement the bridge .mode_valid() operation
> > accordingly.
> > 
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> > Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
> > Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> > ---
> > 
> >  drivers/gpu/drm/bridge/thc63lvd1024.c | 18 ++++++++++++++++++
> >  1 file changed, 18 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/bridge/thc63lvd1024.c
> > b/drivers/gpu/drm/bridge/thc63lvd1024.c index c8b9edd5a7f4..63609ba16b6d
> > 100644
> > --- a/drivers/gpu/drm/bridge/thc63lvd1024.c
> > +++ b/drivers/gpu/drm/bridge/thc63lvd1024.c
> > @@ -45,6 +45,23 @@ static int thc63_attach(struct drm_bridge *bridge)
> >  	return drm_bridge_attach(bridge->encoder, thc63->next, bridge);
> >  }
> > 
> > +static enum drm_mode_status thc63_mode_valid(struct drm_bridge *bridge,
> > +					const struct drm_display_mode *mode)
> > +{
> > +	/*
> > +	 * The THC63LVD0124 clock frequency range is 8 to 135 MHz in single-in,
> 
> That should be THC63LVD1024.

Will be fixed in v3.

> > +	 * single-out mode.
> 
> For the input clock (that's what we're talking about, right?), that also
> applies to single-in/dual-out. Maybe just omit the "single-out" clause?

Good point, I'll change that in v3.

> > Note that the limits depends on the mode and will
> > +	 * need to be adjusted accordingly.
> > +	 */
> 
> I don't quite understand. Does that refer to the THC63 mode, or the DRM
> mode?

This refers to the THC63 mode, I'll clarify this in v3 as well.

> > +	if (mode->clock < 8000)
> > +		return MODE_CLOCK_LOW;
> > +
> > +	if (mode->clock > 135000)
> > +		return MODE_CLOCK_HIGH;
> > +
> > +	return MODE_OK;
> > +}
> > +
> >  static void thc63_enable(struct drm_bridge *bridge)
> >  {
> >  	struct thc63_dev *thc63 = to_thc63(bridge);
> > @@ -77,6 +94,7 @@ static void thc63_disable(struct drm_bridge *bridge)
> > 
> >  static const struct drm_bridge_funcs thc63_bridge_func = {
> >  	.attach	= thc63_attach,
> > +	.mode_valid = thc63_mode_valid,
> >  	.enable = thc63_enable,
> >  	.disable = thc63_disable,
> >  };

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v2 04/16] drm: bridge: thc63: Restrict modes based on hardware operating frequency
@ 2018-09-17 12:23       ` Laurent Pinchart
  0 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-17 12:23 UTC (permalink / raw)
  To: Ulrich Hecht
  Cc: linux-renesas-soc, Laurent Pinchart, Kieran Bingham, dri-devel

Hi Ulrich,

On Monday, 17 September 2018 13:53:43 EEST Ulrich Hecht wrote:
> > On September 14, 2018 at 11:10 AM Laurent Pinchart wrote:
> > 
> > The THC63LVD1024 is restricted to a pixel clock frequency in the range
> > of 8 to 135 MHz. Implement the bridge .mode_valid() operation
> > accordingly.
> > 
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> > Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
> > Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> > ---
> > 
> >  drivers/gpu/drm/bridge/thc63lvd1024.c | 18 ++++++++++++++++++
> >  1 file changed, 18 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/bridge/thc63lvd1024.c
> > b/drivers/gpu/drm/bridge/thc63lvd1024.c index c8b9edd5a7f4..63609ba16b6d
> > 100644
> > --- a/drivers/gpu/drm/bridge/thc63lvd1024.c
> > +++ b/drivers/gpu/drm/bridge/thc63lvd1024.c
> > @@ -45,6 +45,23 @@ static int thc63_attach(struct drm_bridge *bridge)
> >  	return drm_bridge_attach(bridge->encoder, thc63->next, bridge);
> >  }
> > 
> > +static enum drm_mode_status thc63_mode_valid(struct drm_bridge *bridge,
> > +					const struct drm_display_mode *mode)
> > +{
> > +	/*
> > +	 * The THC63LVD0124 clock frequency range is 8 to 135 MHz in single-in,
> 
> That should be THC63LVD1024.

Will be fixed in v3.

> > +	 * single-out mode.
> 
> For the input clock (that's what we're talking about, right?), that also
> applies to single-in/dual-out. Maybe just omit the "single-out" clause?

Good point, I'll change that in v3.

> > Note that the limits depends on the mode and will
> > +	 * need to be adjusted accordingly.
> > +	 */
> 
> I don't quite understand. Does that refer to the THC63 mode, or the DRM
> mode?

This refers to the THC63 mode, I'll clarify this in v3 as well.

> > +	if (mode->clock < 8000)
> > +		return MODE_CLOCK_LOW;
> > +
> > +	if (mode->clock > 135000)
> > +		return MODE_CLOCK_HIGH;
> > +
> > +	return MODE_OK;
> > +}
> > +
> >  static void thc63_enable(struct drm_bridge *bridge)
> >  {
> >  	struct thc63_dev *thc63 = to_thc63(bridge);
> > @@ -77,6 +94,7 @@ static void thc63_disable(struct drm_bridge *bridge)
> > 
> >  static const struct drm_bridge_funcs thc63_bridge_func = {
> >  	.attach	= thc63_attach,
> > +	.mode_valid = thc63_mode_valid,
> >  	.enable = thc63_enable,
> >  	.disable = thc63_disable,
> >  };

-- 
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] 118+ messages in thread

* Re: [PATCH v2 05/16] drm: rcar-du: lvds: D3/E3 support
  2018-09-17 10:53     ` Ulrich Hecht
@ 2018-09-17 12:41       ` Laurent Pinchart
  -1 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-17 12:41 UTC (permalink / raw)
  To: Ulrich Hecht
  Cc: Laurent Pinchart, dri-devel, linux-renesas-soc, Kieran Bingham

Hi Ulrich,

On Monday, 17 September 2018 13:53:58 EEST Ulrich Hecht wrote:
> > On September 14, 2018 at 11:10 AM Laurent Pinchart wrote:
> > 
> > The LVDS encoders in the D3 and E3 SoCs differ significantly from those
> > in the other R-Car Gen3 family members:
> > 
> > - The LVDS PLL architecture is more complex and requires computing PLL
> >   parameters manually.
> > 
> > - The PLL uses external clocks as inputs, which need to be retrieved
> >   from DT.
> > 
> > - In addition to the different PLL setup, the startup sequence has
> >   changed *again* (seems someone had trouble making his/her mind).
> > 
> > Supporting all this requires DT bindings extensions for external clocks,
> > brand new PLL setup code, and a few quirks to handle the differences in
> > the startup sequence.
> > 
> > The implementation doesn't support all hardware features yet, namely
> > 
> > - Using the LV[01] clocks generated by the CPG as PLL input.
> > - Providing the LVDS PLL clock to the DU for use with the RGB output.
> > 
> > Those features can be added later when the need will arise.
> > 
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> > Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> > ---
> > Changes since v1:
> > 
> > - Don't compile-out debug code based on DEBUG and CONFIG_DYNAMIC_DEBUG
> > - Test all three input clocks (DOTCLKIN[01] and EXTAL) and pick the best
> >   one
> > 
> > ---
> > 
> >  drivers/gpu/drm/rcar-du/rcar_lvds.c      | 355 ++++++++++++++++++++++----
> >  drivers/gpu/drm/rcar-du/rcar_lvds_regs.h |  43 +++-
> >  2 files changed, 351 insertions(+), 47 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c
> > b/drivers/gpu/drm/rcar-du/rcar_lvds.c index ce0eb68c3416..23e7743144c8
> > 100644
> > --- a/drivers/gpu/drm/rcar-du/rcar_lvds.c
> > +++ b/drivers/gpu/drm/rcar-du/rcar_lvds.c

[snip]

> > +static void rcar_lvds_d3_e3_pll_calc(struct rcar_lvds *lvds, struct clk
> > *clk,
> > +				     unsigned long target, struct pll_info *pll,
> > +				     u32 clksel)
> > +{
> > +	unsigned long output;
> > +	unsigned long fin;
> > +	unsigned int m_min;
> > +	unsigned int m_max;
> > +	unsigned int m;
> > +	int error;
> > +
> > +	if (!clk)
> > +		return;
> > +
> > +	/*
> > +	 * The LVDS PLL is made of a pre-divider and a multiplier (strangerly
> 
> strangely

Will be fixed in v2.

> > +	 * enough called M and N respectively), followed by a post-divider E.
> > +	 *
> > +	 *         ,-----.         ,-----.     ,-----.         ,-----.
> > +	 * Fin --> | 1/M | -Fpdf-> | PFD | --> | VCO | -Fvco-> | 1/E | --> Fout
> > +	 *         `-----'     ,-> |     |     `-----'   |     `-----'
> > +	 *                     |   `-----'               |
> > +	 *                     |         ,-----.         |
> > +	 *                     `-------- | 1/N | <-------'
> > +	 *                               `-----'
> > +	 *
> > +	 * The clock output by the PLL is then further divided by a
> > programmable
> > +	 * divider DIV to achieve the desired target frequency. Finally, an
> > +	 * optional fixed /7 divider is used to convert the bit clock to a
> > pixel
> > +	 * clock (as LVDS transmits 7 bits per lane per clock sample).
> > +	 *
> > +	 *          ,-------.     ,-----.     |\
> > +	 * Fout --> | 1/DIV | --> | 1/7 | --> | |
> > +	 *          `-------'  |  `-----'     | | --> dot clock
> > +	 *                     `------------> | |
> > +	 *                                    |/
> > +	 *
> > +	 * The /7 divider is optional when the LVDS PLL is used to generate a
> > +	 * dot clock for the DU RGB output, without using the LVDS encoder. We
> > +	 * don't support this configuration yet.
> > +	 *
> > +	 * The PLL allowed input frequency range is 12 MHz to 192 MHz.
> > +	 */
> > +
> > +	fin = clk_get_rate(clk);
> > +	if (fin < 12000000 || fin > 192000000)
> > +		return;
> > +
> > +	/*
> > +	 * The comparison frequency range is 12 MHz to 24 MHz, which limits the
> > +	 * allowed values for the pre-divider M (normal range 1-8).
> > +	 *
> > +	 * Fpfd = Fin / M
> > +	 */
> > +	m_min = max_t(unsigned int, 1, DIV_ROUND_UP(fin, 24000000));
> > +	m_max = min_t(unsigned int, 8, fin / 12000000);
> > +
> > +	for (m = m_min; m <= m_max; ++m) {
> > +		unsigned long fpfd;
> > +		unsigned int n_min;
> > +		unsigned int n_max;
> > +		unsigned int n;
> > +
> > +		/*
> > +		 * The VCO operating range is 900 Mhz to 1800 MHz, which limits
> > +		 * the allowed values for the multiplier N (normal range
> > +		 * 60-120).
> > +		 *
> > +		 * Fvco = Fin * N / M
> > +		 */
> > +		fpfd = fin / m;
> > +		n_min = max_t(unsigned int, 60, DIV_ROUND_UP(900000000, fpfd));
> > +		n_max = min_t(unsigned int, 120, 1800000000 / fpfd);
> > +
> > +		for (n = n_min; n < n_max; ++n) {
> > +			unsigned long fvco;
> > +			unsigned int e_min;
> > +			unsigned int e;
> > +
> > +			/*
> > +			 * The output frequency is limited to 1039.5 MHz,
> > +			 * limiting again the allowed values for the
> > +			 * post-divider E (normal value 1, 2 or 4).
> > +			 *
> > +			 * Fout = Fvco / E
> > +			 */
> > +			fvco = fpfd * n;
> > +			e_min = fvco > 1039500000 ? 1 : 0;
> > +
> > +			for (e = e_min; e < 3; ++e) {
> > +				unsigned long fout;
> > +				unsigned long diff;
> > +				unsigned int div;
> > +
> > +				/*
> > +				 * Finally we have a programable divider after
> > +				 * the PLL, followed by a an optional fixed /7
> > +				 * divider.
> > +				 */
> > +				fout = fvco / (1 << e) / 7;
> > +				div = DIV_ROUND_CLOSEST(fout, target);
> > +				diff = abs(fout / div - target);
> > +
> > +				if (diff < pll->diff) {
> > +					pll->diff = diff;
> > +					pll->pll_m = m;
> > +					pll->pll_n = n;
> > +					pll->pll_e = e;
> > +					pll->div = div;
> > +					pll->clksel = clksel;
> > +
> > +					if (diff == 0)
> > +						goto done;
> > +				}
> > +			}
> > +		}
> > +	}
> > +
> > +done:
> > +	output = fin * pll->pll_n / pll->pll_m / (1 << pll->pll_e)
> > +	       / 7 / pll->div;
> > +	error = (long)(output - target) * 10000 / (long)target;
> > +
> > +	dev_dbg(lvds->dev,
> > +		"%pC %lu Hz -> Fout %lu Hz (target %lu Hz, error %d.%02u%%), PLL
> > M/N/E/DIV %u/%u/%u/%u\n", +		clk, fin, output, target, error / 100,
> > +		error < 0 ? -error % 100 : error % 100,
> > +		pll->pll_m, pll->pll_n, pll->pll_e, pll->div);
> > +}
> > +
> > +static void rcar_lvds_pll_setup_d3_e3(struct rcar_lvds *lvds, unsigned
> > int freq)
> > +{
> > +	struct pll_info pll = { .diff = (unsigned long)-1 };
> > +	u32 lvdpllcr;
> > +
> > +	rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.dotclkin[0], freq, &pll,
> > +				 LVDPLLCR_CKSEL_DU_DOTCLKIN(0));
> > +	rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.dotclkin[1], freq, &pll,
> > +				 LVDPLLCR_CKSEL_DU_DOTCLKIN(1));
> > +	rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.extal, freq, &pll,
> > +				 LVDPLLCR_CKSEL_EXTAL);
> > +
> > +	lvdpllcr = LVDPLLCR_PLLON | pll.clksel | LVDPLLCR_CLKOUT
> > +		 | LVDPLLCR_PLLN(pll.pll_n - 1) | LVDPLLCR_PLLM(pll.pll_m - 1);
> > +
> > +	if (pll.pll_e > 0)
> > +		lvdpllcr |= LVDPLLCR_STP_CLKOUTE | LVDPLLCR_OUTCLKSEL
> > +			 |  LVDPLLCR_PLLE(pll.pll_e - 1);
> > +
> > +	rcar_lvds_write(lvds, LVDPLLCR, lvdpllcr);
> > +
> > +	if (pll.div > 1)
> > +		rcar_lvds_write(lvds, LVDDIV, LVDDIV_DIVSEL |
> > +				LVDDIV_DIVRESET | LVDDIV_DIV(pll.div - 1));
> > +	else
> > +		rcar_lvds_write(lvds, LVDDIV, 0);
> 
> The datasheet says DIVRESET == 0 is "reset" and DIVRESET == 1 is "clear". I
> haven't found anything clarifying what that exactly means, but my best
> guess would have been that this should be the other way round: assert
> LVDDIV_DIVRESET ("clear" the divider) if the divider is 1, and deassert it
> ("reset" the divider) otherwise.

My interpretation is opposite, 0 meaning asserting reset and 1 meaning 
clearing reset (and thus deasserting it).

> The BSP driver, however, does it the same way as above, and the PLL setting
> examples (table 37.5) in the datasheet also have DIVRESET asserted when the
> divider is on, so the above code is likely to be correct. Maybe it's the
> LVDDIV register description that is wrong?
> 
> At any rate, I think this is confusing enough to deserve a comment.

I agree, I'll add that.

> > +}

[snip]

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v2 05/16] drm: rcar-du: lvds: D3/E3 support
@ 2018-09-17 12:41       ` Laurent Pinchart
  0 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-17 12:41 UTC (permalink / raw)
  To: Ulrich Hecht
  Cc: linux-renesas-soc, Laurent Pinchart, Kieran Bingham, dri-devel

Hi Ulrich,

On Monday, 17 September 2018 13:53:58 EEST Ulrich Hecht wrote:
> > On September 14, 2018 at 11:10 AM Laurent Pinchart wrote:
> > 
> > The LVDS encoders in the D3 and E3 SoCs differ significantly from those
> > in the other R-Car Gen3 family members:
> > 
> > - The LVDS PLL architecture is more complex and requires computing PLL
> >   parameters manually.
> > 
> > - The PLL uses external clocks as inputs, which need to be retrieved
> >   from DT.
> > 
> > - In addition to the different PLL setup, the startup sequence has
> >   changed *again* (seems someone had trouble making his/her mind).
> > 
> > Supporting all this requires DT bindings extensions for external clocks,
> > brand new PLL setup code, and a few quirks to handle the differences in
> > the startup sequence.
> > 
> > The implementation doesn't support all hardware features yet, namely
> > 
> > - Using the LV[01] clocks generated by the CPG as PLL input.
> > - Providing the LVDS PLL clock to the DU for use with the RGB output.
> > 
> > Those features can be added later when the need will arise.
> > 
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> > Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> > ---
> > Changes since v1:
> > 
> > - Don't compile-out debug code based on DEBUG and CONFIG_DYNAMIC_DEBUG
> > - Test all three input clocks (DOTCLKIN[01] and EXTAL) and pick the best
> >   one
> > 
> > ---
> > 
> >  drivers/gpu/drm/rcar-du/rcar_lvds.c      | 355 ++++++++++++++++++++++----
> >  drivers/gpu/drm/rcar-du/rcar_lvds_regs.h |  43 +++-
> >  2 files changed, 351 insertions(+), 47 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c
> > b/drivers/gpu/drm/rcar-du/rcar_lvds.c index ce0eb68c3416..23e7743144c8
> > 100644
> > --- a/drivers/gpu/drm/rcar-du/rcar_lvds.c
> > +++ b/drivers/gpu/drm/rcar-du/rcar_lvds.c

[snip]

> > +static void rcar_lvds_d3_e3_pll_calc(struct rcar_lvds *lvds, struct clk
> > *clk,
> > +				     unsigned long target, struct pll_info *pll,
> > +				     u32 clksel)
> > +{
> > +	unsigned long output;
> > +	unsigned long fin;
> > +	unsigned int m_min;
> > +	unsigned int m_max;
> > +	unsigned int m;
> > +	int error;
> > +
> > +	if (!clk)
> > +		return;
> > +
> > +	/*
> > +	 * The LVDS PLL is made of a pre-divider and a multiplier (strangerly
> 
> strangely

Will be fixed in v2.

> > +	 * enough called M and N respectively), followed by a post-divider E.
> > +	 *
> > +	 *         ,-----.         ,-----.     ,-----.         ,-----.
> > +	 * Fin --> | 1/M | -Fpdf-> | PFD | --> | VCO | -Fvco-> | 1/E | --> Fout
> > +	 *         `-----'     ,-> |     |     `-----'   |     `-----'
> > +	 *                     |   `-----'               |
> > +	 *                     |         ,-----.         |
> > +	 *                     `-------- | 1/N | <-------'
> > +	 *                               `-----'
> > +	 *
> > +	 * The clock output by the PLL is then further divided by a
> > programmable
> > +	 * divider DIV to achieve the desired target frequency. Finally, an
> > +	 * optional fixed /7 divider is used to convert the bit clock to a
> > pixel
> > +	 * clock (as LVDS transmits 7 bits per lane per clock sample).
> > +	 *
> > +	 *          ,-------.     ,-----.     |\
> > +	 * Fout --> | 1/DIV | --> | 1/7 | --> | |
> > +	 *          `-------'  |  `-----'     | | --> dot clock
> > +	 *                     `------------> | |
> > +	 *                                    |/
> > +	 *
> > +	 * The /7 divider is optional when the LVDS PLL is used to generate a
> > +	 * dot clock for the DU RGB output, without using the LVDS encoder. We
> > +	 * don't support this configuration yet.
> > +	 *
> > +	 * The PLL allowed input frequency range is 12 MHz to 192 MHz.
> > +	 */
> > +
> > +	fin = clk_get_rate(clk);
> > +	if (fin < 12000000 || fin > 192000000)
> > +		return;
> > +
> > +	/*
> > +	 * The comparison frequency range is 12 MHz to 24 MHz, which limits the
> > +	 * allowed values for the pre-divider M (normal range 1-8).
> > +	 *
> > +	 * Fpfd = Fin / M
> > +	 */
> > +	m_min = max_t(unsigned int, 1, DIV_ROUND_UP(fin, 24000000));
> > +	m_max = min_t(unsigned int, 8, fin / 12000000);
> > +
> > +	for (m = m_min; m <= m_max; ++m) {
> > +		unsigned long fpfd;
> > +		unsigned int n_min;
> > +		unsigned int n_max;
> > +		unsigned int n;
> > +
> > +		/*
> > +		 * The VCO operating range is 900 Mhz to 1800 MHz, which limits
> > +		 * the allowed values for the multiplier N (normal range
> > +		 * 60-120).
> > +		 *
> > +		 * Fvco = Fin * N / M
> > +		 */
> > +		fpfd = fin / m;
> > +		n_min = max_t(unsigned int, 60, DIV_ROUND_UP(900000000, fpfd));
> > +		n_max = min_t(unsigned int, 120, 1800000000 / fpfd);
> > +
> > +		for (n = n_min; n < n_max; ++n) {
> > +			unsigned long fvco;
> > +			unsigned int e_min;
> > +			unsigned int e;
> > +
> > +			/*
> > +			 * The output frequency is limited to 1039.5 MHz,
> > +			 * limiting again the allowed values for the
> > +			 * post-divider E (normal value 1, 2 or 4).
> > +			 *
> > +			 * Fout = Fvco / E
> > +			 */
> > +			fvco = fpfd * n;
> > +			e_min = fvco > 1039500000 ? 1 : 0;
> > +
> > +			for (e = e_min; e < 3; ++e) {
> > +				unsigned long fout;
> > +				unsigned long diff;
> > +				unsigned int div;
> > +
> > +				/*
> > +				 * Finally we have a programable divider after
> > +				 * the PLL, followed by a an optional fixed /7
> > +				 * divider.
> > +				 */
> > +				fout = fvco / (1 << e) / 7;
> > +				div = DIV_ROUND_CLOSEST(fout, target);
> > +				diff = abs(fout / div - target);
> > +
> > +				if (diff < pll->diff) {
> > +					pll->diff = diff;
> > +					pll->pll_m = m;
> > +					pll->pll_n = n;
> > +					pll->pll_e = e;
> > +					pll->div = div;
> > +					pll->clksel = clksel;
> > +
> > +					if (diff == 0)
> > +						goto done;
> > +				}
> > +			}
> > +		}
> > +	}
> > +
> > +done:
> > +	output = fin * pll->pll_n / pll->pll_m / (1 << pll->pll_e)
> > +	       / 7 / pll->div;
> > +	error = (long)(output - target) * 10000 / (long)target;
> > +
> > +	dev_dbg(lvds->dev,
> > +		"%pC %lu Hz -> Fout %lu Hz (target %lu Hz, error %d.%02u%%), PLL
> > M/N/E/DIV %u/%u/%u/%u\n", +		clk, fin, output, target, error / 100,
> > +		error < 0 ? -error % 100 : error % 100,
> > +		pll->pll_m, pll->pll_n, pll->pll_e, pll->div);
> > +}
> > +
> > +static void rcar_lvds_pll_setup_d3_e3(struct rcar_lvds *lvds, unsigned
> > int freq)
> > +{
> > +	struct pll_info pll = { .diff = (unsigned long)-1 };
> > +	u32 lvdpllcr;
> > +
> > +	rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.dotclkin[0], freq, &pll,
> > +				 LVDPLLCR_CKSEL_DU_DOTCLKIN(0));
> > +	rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.dotclkin[1], freq, &pll,
> > +				 LVDPLLCR_CKSEL_DU_DOTCLKIN(1));
> > +	rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.extal, freq, &pll,
> > +				 LVDPLLCR_CKSEL_EXTAL);
> > +
> > +	lvdpllcr = LVDPLLCR_PLLON | pll.clksel | LVDPLLCR_CLKOUT
> > +		 | LVDPLLCR_PLLN(pll.pll_n - 1) | LVDPLLCR_PLLM(pll.pll_m - 1);
> > +
> > +	if (pll.pll_e > 0)
> > +		lvdpllcr |= LVDPLLCR_STP_CLKOUTE | LVDPLLCR_OUTCLKSEL
> > +			 |  LVDPLLCR_PLLE(pll.pll_e - 1);
> > +
> > +	rcar_lvds_write(lvds, LVDPLLCR, lvdpllcr);
> > +
> > +	if (pll.div > 1)
> > +		rcar_lvds_write(lvds, LVDDIV, LVDDIV_DIVSEL |
> > +				LVDDIV_DIVRESET | LVDDIV_DIV(pll.div - 1));
> > +	else
> > +		rcar_lvds_write(lvds, LVDDIV, 0);
> 
> The datasheet says DIVRESET == 0 is "reset" and DIVRESET == 1 is "clear". I
> haven't found anything clarifying what that exactly means, but my best
> guess would have been that this should be the other way round: assert
> LVDDIV_DIVRESET ("clear" the divider) if the divider is 1, and deassert it
> ("reset" the divider) otherwise.

My interpretation is opposite, 0 meaning asserting reset and 1 meaning 
clearing reset (and thus deasserting it).

> The BSP driver, however, does it the same way as above, and the PLL setting
> examples (table 37.5) in the datasheet also have DIVRESET asserted when the
> divider is on, so the above code is likely to be correct. Maybe it's the
> LVDDIV register description that is wrong?
> 
> At any rate, I think this is confusing enough to deserve a comment.

I agree, I'll add that.

> > +}

[snip]

-- 
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] 118+ messages in thread

* Re: [PATCH v2 05/16] drm: rcar-du: lvds: D3/E3 support
  2018-09-14  9:10   ` Laurent Pinchart
@ 2018-09-17 12:49     ` jacopo mondi
  -1 siblings, 0 replies; 118+ messages in thread
From: jacopo mondi @ 2018-09-17 12:49 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: dri-devel, linux-renesas-soc, Ulrich Hecht, Kieran Bingham

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

Hi Laurent,

On Fri, Sep 14, 2018 at 12:10:35PM +0300, Laurent Pinchart wrote:
> The LVDS encoders in the D3 and E3 SoCs differ significantly from those
> in the other R-Car Gen3 family members:
>
> - The LVDS PLL architecture is more complex and requires computing PLL
>   parameters manually.
> - The PLL uses external clocks as inputs, which need to be retrieved
>   from DT.
> - In addition to the different PLL setup, the startup sequence has
>   changed *again* (seems someone had trouble making his/her mind).
>
> Supporting all this requires DT bindings extensions for external clocks,
> brand new PLL setup code, and a few quirks to handle the differences in
> the startup sequence.
>
> The implementation doesn't support all hardware features yet, namely
>
> - Using the LV[01] clocks generated by the CPG as PLL input.
> - Providing the LVDS PLL clock to the DU for use with the RGB output.
>
> Those features can be added later when the need will arise.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>

please add my
Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>

> ---
> Changes since v1:
>
> - Don't compile-out debug code based on DEBUG and CONFIG_DYNAMIC_DEBUG
> - Test all three input clocks (DOTCLKIN[01] and EXTAL) and pick the best
>   one
> ---
>  drivers/gpu/drm/rcar-du/rcar_lvds.c      | 355 +++++++++++++++++++++++++++----
>  drivers/gpu/drm/rcar-du/rcar_lvds_regs.h |  43 +++-
>  2 files changed, 351 insertions(+), 47 deletions(-)
>
> diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c b/drivers/gpu/drm/rcar-du/rcar_lvds.c
> index ce0eb68c3416..23e7743144c8 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_lvds.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_lvds.c
> @@ -24,6 +24,8 @@
>
>  #include "rcar_lvds_regs.h"
>
> +struct rcar_lvds;
> +
>  /* Keep in sync with the LVDCR0.LVMD hardware register values. */
>  enum rcar_lvds_mode {
>  	RCAR_LVDS_MODE_JEIDA = 0,
> @@ -31,14 +33,16 @@ enum rcar_lvds_mode {
>  	RCAR_LVDS_MODE_VESA = 4,
>  };
>
> -#define RCAR_LVDS_QUIRK_LANES	(1 << 0)	/* LVDS lanes 1 and 3 inverted */
> -#define RCAR_LVDS_QUIRK_GEN2_PLLCR (1 << 1)	/* LVDPLLCR has gen2 layout */
> -#define RCAR_LVDS_QUIRK_GEN3_LVEN (1 << 2)	/* LVEN bit needs to be set */
> -						/* on R8A77970/R8A7799x */
> +#define RCAR_LVDS_QUIRK_LANES		BIT(0)	/* LVDS lanes 1 and 3 inverted */
> +#define RCAR_LVDS_QUIRK_GEN3_LVEN	BIT(1)	/* LVEN bit needs to be set on R8A77970/R8A7799x */
> +#define RCAR_LVDS_QUIRK_PWD		BIT(2)	/* PWD bit available (all of Gen3 but E3) */
> +#define RCAR_LVDS_QUIRK_EXT_PLL		BIT(3)	/* Has extended PLL */
> +#define RCAR_LVDS_QUIRK_DUAL_LINK	BIT(4)	/* Supports dual-link operation */
>
>  struct rcar_lvds_device_info {
>  	unsigned int gen;
>  	unsigned int quirks;
> +	void (*pll_setup)(struct rcar_lvds *lvds, unsigned int freq);
>  };
>
>  struct rcar_lvds {
> @@ -52,7 +56,11 @@ struct rcar_lvds {
>  	struct drm_panel *panel;
>
>  	void __iomem *mmio;
> -	struct clk *clock;
> +	struct {
> +		struct clk *mod;		/* CPG module clock */
> +		struct clk *extal;		/* External clock */
> +		struct clk *dotclkin[2];	/* External DU clocks */
> +	} clocks;
>  	bool enabled;
>
>  	struct drm_display_mode display_mode;
> @@ -128,33 +136,212 @@ static const struct drm_connector_funcs rcar_lvds_conn_funcs = {
>  };
>
>  /* -----------------------------------------------------------------------------
> - * Bridge
> + * PLL Setup
>   */
>
> -static u32 rcar_lvds_lvdpllcr_gen2(unsigned int freq)
> +static void rcar_lvds_pll_setup_gen2(struct rcar_lvds *lvds, unsigned int freq)
>  {
> -	if (freq < 39000)
> -		return LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_38M;
> -	else if (freq < 61000)
> -		return LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_60M;
> -	else if (freq < 121000)
> -		return LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_121M;
> +	u32 val;
> +
> +	if (freq < 39000000)
> +		val = LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_38M;
> +	else if (freq < 61000000)
> +		val = LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_60M;
> +	else if (freq < 121000000)
> +		val = LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_121M;
>  	else
> -		return LVDPLLCR_PLLDLYCNT_150M;
> +		val = LVDPLLCR_PLLDLYCNT_150M;
> +
> +	rcar_lvds_write(lvds, LVDPLLCR, val);
>  }
>
> -static u32 rcar_lvds_lvdpllcr_gen3(unsigned int freq)
> +static void rcar_lvds_pll_setup_gen3(struct rcar_lvds *lvds, unsigned int freq)
>  {
> -	if (freq < 42000)
> -		return LVDPLLCR_PLLDIVCNT_42M;
> -	else if (freq < 85000)
> -		return LVDPLLCR_PLLDIVCNT_85M;
> -	else if (freq < 128000)
> -		return LVDPLLCR_PLLDIVCNT_128M;
> +	u32 val;
> +
> +	if (freq < 42000000)
> +		val = LVDPLLCR_PLLDIVCNT_42M;
> +	else if (freq < 85000000)
> +		val = LVDPLLCR_PLLDIVCNT_85M;
> +	else if (freq < 128000000)
> +		val = LVDPLLCR_PLLDIVCNT_128M;
>  	else
> -		return LVDPLLCR_PLLDIVCNT_148M;
> +		val = LVDPLLCR_PLLDIVCNT_148M;
> +
> +	rcar_lvds_write(lvds, LVDPLLCR, val);
>  }
>
> +struct pll_info {
> +	unsigned long diff;
> +	unsigned int pll_m;
> +	unsigned int pll_n;
> +	unsigned int pll_e;
> +	unsigned int div;
> +	u32 clksel;
> +};
> +
> +static void rcar_lvds_d3_e3_pll_calc(struct rcar_lvds *lvds, struct clk *clk,
> +				     unsigned long target, struct pll_info *pll,
> +				     u32 clksel)
> +{
> +	unsigned long output;
> +	unsigned long fin;
> +	unsigned int m_min;
> +	unsigned int m_max;
> +	unsigned int m;
> +	int error;
> +
> +	if (!clk)
> +		return;
> +
> +	/*
> +	 * The LVDS PLL is made of a pre-divider and a multiplier (strangerly
> +	 * enough called M and N respectively), followed by a post-divider E.
> +	 *
> +	 *         ,-----.         ,-----.     ,-----.         ,-----.
> +	 * Fin --> | 1/M | -Fpdf-> | PFD | --> | VCO | -Fvco-> | 1/E | --> Fout
> +	 *         `-----'     ,-> |     |     `-----'   |     `-----'
> +	 *                     |   `-----'               |
> +	 *                     |         ,-----.         |
> +	 *                     `-------- | 1/N | <-------'
> +	 *                               `-----'
> +	 *
> +	 * The clock output by the PLL is then further divided by a programmable
> +	 * divider DIV to achieve the desired target frequency. Finally, an
> +	 * optional fixed /7 divider is used to convert the bit clock to a pixel
> +	 * clock (as LVDS transmits 7 bits per lane per clock sample).
> +	 *
> +	 *          ,-------.     ,-----.     |\
> +	 * Fout --> | 1/DIV | --> | 1/7 | --> | |
> +	 *          `-------'  |  `-----'     | | --> dot clock
> +	 *                     `------------> | |
> +	 *                                    |/
> +	 *
> +	 * The /7 divider is optional when the LVDS PLL is used to generate a
> +	 * dot clock for the DU RGB output, without using the LVDS encoder. We
> +	 * don't support this configuration yet.
> +	 *
> +	 * The PLL allowed input frequency range is 12 MHz to 192 MHz.
> +	 */
> +
> +	fin = clk_get_rate(clk);
> +	if (fin < 12000000 || fin > 192000000)
> +		return;
> +
> +	/*
> +	 * The comparison frequency range is 12 MHz to 24 MHz, which limits the
> +	 * allowed values for the pre-divider M (normal range 1-8).
> +	 *
> +	 * Fpfd = Fin / M
> +	 */
> +	m_min = max_t(unsigned int, 1, DIV_ROUND_UP(fin, 24000000));
> +	m_max = min_t(unsigned int, 8, fin / 12000000);
> +
> +	for (m = m_min; m <= m_max; ++m) {
> +		unsigned long fpfd;
> +		unsigned int n_min;
> +		unsigned int n_max;
> +		unsigned int n;
> +
> +		/*
> +		 * The VCO operating range is 900 Mhz to 1800 MHz, which limits
> +		 * the allowed values for the multiplier N (normal range
> +		 * 60-120).
> +		 *
> +		 * Fvco = Fin * N / M
> +		 */
> +		fpfd = fin / m;
> +		n_min = max_t(unsigned int, 60, DIV_ROUND_UP(900000000, fpfd));
> +		n_max = min_t(unsigned int, 120, 1800000000 / fpfd);
> +
> +		for (n = n_min; n < n_max; ++n) {
> +			unsigned long fvco;
> +			unsigned int e_min;
> +			unsigned int e;
> +
> +			/*
> +			 * The output frequency is limited to 1039.5 MHz,
> +			 * limiting again the allowed values for the
> +			 * post-divider E (normal value 1, 2 or 4).
> +			 *
> +			 * Fout = Fvco / E
> +			 */
> +			fvco = fpfd * n;
> +			e_min = fvco > 1039500000 ? 1 : 0;
> +
> +			for (e = e_min; e < 3; ++e) {
> +				unsigned long fout;
> +				unsigned long diff;
> +				unsigned int div;
> +
> +				/*
> +				 * Finally we have a programable divider after
> +				 * the PLL, followed by a an optional fixed /7
> +				 * divider.
> +				 */
> +				fout = fvco / (1 << e) / 7;
> +				div = DIV_ROUND_CLOSEST(fout, target);
> +				diff = abs(fout / div - target);
> +
> +				if (diff < pll->diff) {
> +					pll->diff = diff;
> +					pll->pll_m = m;
> +					pll->pll_n = n;
> +					pll->pll_e = e;
> +					pll->div = div;
> +					pll->clksel = clksel;
> +
> +					if (diff == 0)
> +						goto done;
> +				}
> +			}
> +		}
> +	}
> +
> +done:
> +	output = fin * pll->pll_n / pll->pll_m / (1 << pll->pll_e)
> +	       / 7 / pll->div;
> +	error = (long)(output - target) * 10000 / (long)target;
> +
> +	dev_dbg(lvds->dev,
> +		"%pC %lu Hz -> Fout %lu Hz (target %lu Hz, error %d.%02u%%), PLL M/N/E/DIV %u/%u/%u/%u\n",
> +		clk, fin, output, target, error / 100,
> +		error < 0 ? -error % 100 : error % 100,
> +		pll->pll_m, pll->pll_n, pll->pll_e, pll->div);
> +}
> +
> +static void rcar_lvds_pll_setup_d3_e3(struct rcar_lvds *lvds, unsigned int freq)
> +{
> +	struct pll_info pll = { .diff = (unsigned long)-1 };
> +	u32 lvdpllcr;
> +
> +	rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.dotclkin[0], freq, &pll,
> +				 LVDPLLCR_CKSEL_DU_DOTCLKIN(0));
> +	rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.dotclkin[1], freq, &pll,
> +				 LVDPLLCR_CKSEL_DU_DOTCLKIN(1));
> +	rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.extal, freq, &pll,
> +				 LVDPLLCR_CKSEL_EXTAL);
> +
> +	lvdpllcr = LVDPLLCR_PLLON | pll.clksel | LVDPLLCR_CLKOUT
> +		 | LVDPLLCR_PLLN(pll.pll_n - 1) | LVDPLLCR_PLLM(pll.pll_m - 1);
> +
> +	if (pll.pll_e > 0)
> +		lvdpllcr |= LVDPLLCR_STP_CLKOUTE | LVDPLLCR_OUTCLKSEL
> +			 |  LVDPLLCR_PLLE(pll.pll_e - 1);
> +
> +	rcar_lvds_write(lvds, LVDPLLCR, lvdpllcr);
> +
> +	if (pll.div > 1)
> +		rcar_lvds_write(lvds, LVDDIV, LVDDIV_DIVSEL |
> +				LVDDIV_DIVRESET | LVDDIV_DIV(pll.div - 1));
> +	else
> +		rcar_lvds_write(lvds, LVDDIV, 0);
> +}
> +
> +/* -----------------------------------------------------------------------------
> + * Bridge
> + */
> +
>  static void rcar_lvds_enable(struct drm_bridge *bridge)
>  {
>  	struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
> @@ -164,14 +351,13 @@ static void rcar_lvds_enable(struct drm_bridge *bridge)
>  	 * do we get a state pointer?
>  	 */
>  	struct drm_crtc *crtc = lvds->bridge.encoder->crtc;
> -	u32 lvdpllcr;
>  	u32 lvdhcr;
>  	u32 lvdcr0;
>  	int ret;
>
>  	WARN_ON(lvds->enabled);
>
> -	ret = clk_prepare_enable(lvds->clock);
> +	ret = clk_prepare_enable(lvds->clocks.mod);
>  	if (ret < 0)
>  		return;
>
> @@ -196,12 +382,13 @@ static void rcar_lvds_enable(struct drm_bridge *bridge)
>
>  	rcar_lvds_write(lvds, LVDCHCR, lvdhcr);
>
> +	if (lvds->info->quirks & RCAR_LVDS_QUIRK_DUAL_LINK) {
> +		/* Disable dual-link mode. */
> +		rcar_lvds_write(lvds, LVDSTRIPE, 0);
> +	}
> +
>  	/* PLL clock configuration. */
> -	if (lvds->info->quirks & RCAR_LVDS_QUIRK_GEN2_PLLCR)
> -		lvdpllcr = rcar_lvds_lvdpllcr_gen2(mode->clock);
> -	else
> -		lvdpllcr = rcar_lvds_lvdpllcr_gen3(mode->clock);
> -	rcar_lvds_write(lvds, LVDPLLCR, lvdpllcr);
> +	lvds->info->pll_setup(lvds, mode->clock * 1000);
>
>  	/* Set the LVDS mode and select the input. */
>  	lvdcr0 = lvds->mode << LVDCR0_LVMD_SHIFT;
> @@ -220,11 +407,16 @@ static void rcar_lvds_enable(struct drm_bridge *bridge)
>  		rcar_lvds_write(lvds, LVDCR0, lvdcr0);
>  	}
>
> -	/* Turn the PLL on. */
> -	lvdcr0 |= LVDCR0_PLLON;
> -	rcar_lvds_write(lvds, LVDCR0, lvdcr0);
> +	if (!(lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL)) {
> +		/*
> +		 * Turn the PLL on (simple PLL only, extended PLL is fully
> +		 * controlled through LVDPLLCR).
> +		 */
> +		lvdcr0 |= LVDCR0_PLLON;
> +		rcar_lvds_write(lvds, LVDCR0, lvdcr0);
> +	}
>
> -	if (lvds->info->gen > 2) {
> +	if (lvds->info->quirks & RCAR_LVDS_QUIRK_PWD) {
>  		/* Set LVDS normal mode. */
>  		lvdcr0 |= LVDCR0_PWD;
>  		rcar_lvds_write(lvds, LVDCR0, lvdcr0);
> @@ -236,8 +428,10 @@ static void rcar_lvds_enable(struct drm_bridge *bridge)
>  		rcar_lvds_write(lvds, LVDCR0, lvdcr0);
>  	}
>
> -	/* Wait for the startup delay. */
> -	usleep_range(100, 150);
> +	if (!(lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL)) {
> +		/* Wait for the PLL startup delay (simple PLL only). */
> +		usleep_range(100, 150);
> +	}
>
>  	/* Turn the output on. */
>  	lvdcr0 |= LVDCR0_LVRES;
> @@ -264,8 +458,9 @@ 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);
> +	clk_disable_unprepare(lvds->clocks.mod);
>
>  	lvds->enabled = false;
>  }
> @@ -446,6 +641,60 @@ static int rcar_lvds_parse_dt(struct rcar_lvds *lvds)
>  	return ret;
>  }
>
> +static struct clk *rcar_lvds_get_clock(struct rcar_lvds *lvds, const char *name,
> +				       bool optional)
> +{
> +	struct clk *clk;
> +
> +	clk = devm_clk_get(lvds->dev, name);
> +	if (!IS_ERR(clk))
> +		return clk;
> +
> +	if (PTR_ERR(clk) == -ENOENT && optional)
> +		return NULL;
> +
> +	if (PTR_ERR(clk) != -EPROBE_DEFER)
> +		dev_err(lvds->dev, "failed to get %s clock\n",
> +			name ? name : "module");
> +
> +	return clk;
> +}
> +
> +static int rcar_lvds_get_clocks(struct rcar_lvds *lvds)
> +{
> +	lvds->clocks.mod = rcar_lvds_get_clock(lvds, NULL, false);
> +	if (IS_ERR(lvds->clocks.mod))
> +		return PTR_ERR(lvds->clocks.mod);
> +
> +	/*
> +	 * LVDS encoders without an extended PLL have no external clock inputs.
> +	 */
> +	if (!(lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL))
> +		return 0;
> +
> +	lvds->clocks.extal = rcar_lvds_get_clock(lvds, "extal", true);
> +	if (IS_ERR(lvds->clocks.extal))
> +		return PTR_ERR(lvds->clocks.extal);
> +
> +	lvds->clocks.dotclkin[0] = rcar_lvds_get_clock(lvds, "dclkin.0", true);
> +	if (IS_ERR(lvds->clocks.dotclkin[0]))
> +		return PTR_ERR(lvds->clocks.dotclkin[0]);
> +
> +	lvds->clocks.dotclkin[1] = rcar_lvds_get_clock(lvds, "dclkin.1", true);
> +	if (IS_ERR(lvds->clocks.dotclkin[1]))
> +		return PTR_ERR(lvds->clocks.dotclkin[1]);
> +
> +	/* At least one input to the PLL must be available. */
> +	if (!lvds->clocks.extal && !lvds->clocks.dotclkin[0] &&
> +	    !lvds->clocks.dotclkin[1]) {
> +		dev_err(lvds->dev,
> +			"no input clock (extal, dclkin.0 or dclkin.1)\n");
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
>  static int rcar_lvds_probe(struct platform_device *pdev)
>  {
>  	struct rcar_lvds *lvds;
> @@ -475,11 +724,9 @@ static int rcar_lvds_probe(struct platform_device *pdev)
>  	if (IS_ERR(lvds->mmio))
>  		return PTR_ERR(lvds->mmio);
>
> -	lvds->clock = devm_clk_get(&pdev->dev, NULL);
> -	if (IS_ERR(lvds->clock)) {
> -		dev_err(&pdev->dev, "failed to get clock\n");
> -		return PTR_ERR(lvds->clock);
> -	}
> +	ret = rcar_lvds_get_clocks(lvds);
> +	if (ret < 0)
> +		return ret;
>
>  	drm_bridge_add(&lvds->bridge);
>
> @@ -497,21 +744,39 @@ static int rcar_lvds_remove(struct platform_device *pdev)
>
>  static const struct rcar_lvds_device_info rcar_lvds_gen2_info = {
>  	.gen = 2,
> -	.quirks = RCAR_LVDS_QUIRK_GEN2_PLLCR,
> +	.pll_setup = rcar_lvds_pll_setup_gen2,
>  };
>
>  static const struct rcar_lvds_device_info rcar_lvds_r8a7790_info = {
>  	.gen = 2,
> -	.quirks = RCAR_LVDS_QUIRK_GEN2_PLLCR | RCAR_LVDS_QUIRK_LANES,
> +	.quirks = RCAR_LVDS_QUIRK_LANES,
> +	.pll_setup = rcar_lvds_pll_setup_gen2,
>  };
>
>  static const struct rcar_lvds_device_info rcar_lvds_gen3_info = {
>  	.gen = 3,
> +	.quirks = RCAR_LVDS_QUIRK_PWD,
> +	.pll_setup = rcar_lvds_pll_setup_gen3,
>  };
>
>  static const struct rcar_lvds_device_info rcar_lvds_r8a77970_info = {
>  	.gen = 3,
> -	.quirks = RCAR_LVDS_QUIRK_GEN2_PLLCR | RCAR_LVDS_QUIRK_GEN3_LVEN,
> +	.quirks = RCAR_LVDS_QUIRK_PWD | RCAR_LVDS_QUIRK_GEN3_LVEN,
> +	.pll_setup = rcar_lvds_pll_setup_gen2,
> +};
> +
> +static const struct rcar_lvds_device_info rcar_lvds_r8a77990_info = {
> +	.gen = 3,
> +	.quirks = RCAR_LVDS_QUIRK_GEN3_LVEN | RCAR_LVDS_QUIRK_EXT_PLL
> +		| RCAR_LVDS_QUIRK_DUAL_LINK,
> +	.pll_setup = rcar_lvds_pll_setup_d3_e3,
> +};
> +
> +static const struct rcar_lvds_device_info rcar_lvds_r8a77995_info = {
> +	.gen = 3,
> +	.quirks = RCAR_LVDS_QUIRK_GEN3_LVEN | RCAR_LVDS_QUIRK_PWD
> +		| RCAR_LVDS_QUIRK_EXT_PLL | RCAR_LVDS_QUIRK_DUAL_LINK,
> +	.pll_setup = rcar_lvds_pll_setup_d3_e3,
>  };
>
>  static const struct of_device_id rcar_lvds_of_table[] = {
> @@ -523,6 +788,8 @@ static const struct of_device_id rcar_lvds_of_table[] = {
>  	{ .compatible = "renesas,r8a7796-lvds", .data = &rcar_lvds_gen3_info },
>  	{ .compatible = "renesas,r8a77970-lvds", .data = &rcar_lvds_r8a77970_info },
>  	{ .compatible = "renesas,r8a77980-lvds", .data = &rcar_lvds_gen3_info },
> +	{ .compatible = "renesas,r8a77990-lvds", .data = &rcar_lvds_r8a77990_info },
> +	{ .compatible = "renesas,r8a77995-lvds", .data = &rcar_lvds_r8a77995_info },
>  	{ }
>  };
>
> diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h b/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
> index 4870f50d9bec..87149f2f8056 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
> @@ -18,7 +18,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
> @@ -27,21 +27,36 @@
>  #define LVDCR1_CLKSTBY			(3 << 0)
>
>  #define LVDPLLCR			0x0008
> +/* Gen2 & V3M */
>  #define LVDPLLCR_CEEN			(1 << 14)
>  #define LVDPLLCR_FBEN			(1 << 13)
>  #define LVDPLLCR_COSEL			(1 << 12)
> -/* Gen2 */
>  #define LVDPLLCR_PLLDLYCNT_150M		(0x1bf << 0)
>  #define LVDPLLCR_PLLDLYCNT_121M		(0x22c << 0)
>  #define LVDPLLCR_PLLDLYCNT_60M		(0x77b << 0)
>  #define LVDPLLCR_PLLDLYCNT_38M		(0x69a << 0)
>  #define LVDPLLCR_PLLDLYCNT_MASK		(0x7ff << 0)
> -/* Gen3 */
> +/* Gen3 but V3M,D3 and E3 */
>  #define LVDPLLCR_PLLDIVCNT_42M		(0x014cb << 0)
>  #define LVDPLLCR_PLLDIVCNT_85M		(0x00a45 << 0)
>  #define LVDPLLCR_PLLDIVCNT_128M		(0x006c3 << 0)
>  #define LVDPLLCR_PLLDIVCNT_148M		(0x046c1 << 0)
>  #define LVDPLLCR_PLLDIVCNT_MASK		(0x7ffff << 0)
> +/* D3 and E3 */
> +#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_DOTCLKIN(n)	((5 + (n) * 2) << 17)
> +#define LVDPLLCR_OCKSEL			(1 << 16)
> +#define LVDPLLCR_STP_CLKOUTE		(1 << 14)
> +#define LVDPLLCR_OUTCLKSEL		(1 << 12)
> +#define LVDPLLCR_CLKOUT			(1 << 11)
> +#define LVDPLLCR_PLLE(n)		((n) << 10)
> +#define LVDPLLCR_PLLN(n)		((n) << 3)
> +#define LVDPLLCR_PLLM(n)		((n) << 0)
>
>  #define LVDCTRCR			0x000c
>  #define LVDCTRCR_CTR3SEL_ZERO		(0 << 12)
> @@ -71,4 +86,26 @@
>  #define LVDCHCR_CHSEL_CH(n, c)		((((c) - (n)) & 3) << ((n) * 4))
>  #define LVDCHCR_CHSEL_MASK(n)		(3 << ((n) * 4))
>
> +/* All registers below are specific to D3 and E3 */
> +#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		(1 << 1)
> +#define LVDSTRIPE_ST_ON			(1 << 0)
> +
> +#define LVDSCR				0x0018
> +#define LVDSCR_DEPTH(n)			(((n) - 1) << 29)
> +#define LVDSCR_BANDSET			(1 << 28)
> +#define LVDSCR_TWGCNT(n)		((((n) - 256) / 16) << 24)
> +#define LVDSCR_SDIV(n)			((n) << 22)
> +#define LVDSCR_MODE			(1 << 21)
> +#define LVDSCR_RSTN			(1 << 20)
> +
> +#define LVDDIV				0x001c
> +#define LVDDIV_DIVSEL			(1 << 8)
> +#define LVDDIV_DIVRESET			(1 << 7)
> +#define LVDDIV_DIVSTP			(1 << 6)
> +#define LVDDIV_DIV(n)			((n) << 0)
> +
>  #endif /* __RCAR_LVDS_REGS_H__ */
> --
> Regards,
>
> Laurent Pinchart
>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [PATCH v2 05/16] drm: rcar-du: lvds: D3/E3 support
@ 2018-09-17 12:49     ` jacopo mondi
  0 siblings, 0 replies; 118+ messages in thread
From: jacopo mondi @ 2018-09-17 12:49 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham, dri-devel


[-- Attachment #1.1: Type: text/plain, Size: 20218 bytes --]

Hi Laurent,

On Fri, Sep 14, 2018 at 12:10:35PM +0300, Laurent Pinchart wrote:
> The LVDS encoders in the D3 and E3 SoCs differ significantly from those
> in the other R-Car Gen3 family members:
>
> - The LVDS PLL architecture is more complex and requires computing PLL
>   parameters manually.
> - The PLL uses external clocks as inputs, which need to be retrieved
>   from DT.
> - In addition to the different PLL setup, the startup sequence has
>   changed *again* (seems someone had trouble making his/her mind).
>
> Supporting all this requires DT bindings extensions for external clocks,
> brand new PLL setup code, and a few quirks to handle the differences in
> the startup sequence.
>
> The implementation doesn't support all hardware features yet, namely
>
> - Using the LV[01] clocks generated by the CPG as PLL input.
> - Providing the LVDS PLL clock to the DU for use with the RGB output.
>
> Those features can be added later when the need will arise.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>

please add my
Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>

> ---
> Changes since v1:
>
> - Don't compile-out debug code based on DEBUG and CONFIG_DYNAMIC_DEBUG
> - Test all three input clocks (DOTCLKIN[01] and EXTAL) and pick the best
>   one
> ---
>  drivers/gpu/drm/rcar-du/rcar_lvds.c      | 355 +++++++++++++++++++++++++++----
>  drivers/gpu/drm/rcar-du/rcar_lvds_regs.h |  43 +++-
>  2 files changed, 351 insertions(+), 47 deletions(-)
>
> diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c b/drivers/gpu/drm/rcar-du/rcar_lvds.c
> index ce0eb68c3416..23e7743144c8 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_lvds.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_lvds.c
> @@ -24,6 +24,8 @@
>
>  #include "rcar_lvds_regs.h"
>
> +struct rcar_lvds;
> +
>  /* Keep in sync with the LVDCR0.LVMD hardware register values. */
>  enum rcar_lvds_mode {
>  	RCAR_LVDS_MODE_JEIDA = 0,
> @@ -31,14 +33,16 @@ enum rcar_lvds_mode {
>  	RCAR_LVDS_MODE_VESA = 4,
>  };
>
> -#define RCAR_LVDS_QUIRK_LANES	(1 << 0)	/* LVDS lanes 1 and 3 inverted */
> -#define RCAR_LVDS_QUIRK_GEN2_PLLCR (1 << 1)	/* LVDPLLCR has gen2 layout */
> -#define RCAR_LVDS_QUIRK_GEN3_LVEN (1 << 2)	/* LVEN bit needs to be set */
> -						/* on R8A77970/R8A7799x */
> +#define RCAR_LVDS_QUIRK_LANES		BIT(0)	/* LVDS lanes 1 and 3 inverted */
> +#define RCAR_LVDS_QUIRK_GEN3_LVEN	BIT(1)	/* LVEN bit needs to be set on R8A77970/R8A7799x */
> +#define RCAR_LVDS_QUIRK_PWD		BIT(2)	/* PWD bit available (all of Gen3 but E3) */
> +#define RCAR_LVDS_QUIRK_EXT_PLL		BIT(3)	/* Has extended PLL */
> +#define RCAR_LVDS_QUIRK_DUAL_LINK	BIT(4)	/* Supports dual-link operation */
>
>  struct rcar_lvds_device_info {
>  	unsigned int gen;
>  	unsigned int quirks;
> +	void (*pll_setup)(struct rcar_lvds *lvds, unsigned int freq);
>  };
>
>  struct rcar_lvds {
> @@ -52,7 +56,11 @@ struct rcar_lvds {
>  	struct drm_panel *panel;
>
>  	void __iomem *mmio;
> -	struct clk *clock;
> +	struct {
> +		struct clk *mod;		/* CPG module clock */
> +		struct clk *extal;		/* External clock */
> +		struct clk *dotclkin[2];	/* External DU clocks */
> +	} clocks;
>  	bool enabled;
>
>  	struct drm_display_mode display_mode;
> @@ -128,33 +136,212 @@ static const struct drm_connector_funcs rcar_lvds_conn_funcs = {
>  };
>
>  /* -----------------------------------------------------------------------------
> - * Bridge
> + * PLL Setup
>   */
>
> -static u32 rcar_lvds_lvdpllcr_gen2(unsigned int freq)
> +static void rcar_lvds_pll_setup_gen2(struct rcar_lvds *lvds, unsigned int freq)
>  {
> -	if (freq < 39000)
> -		return LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_38M;
> -	else if (freq < 61000)
> -		return LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_60M;
> -	else if (freq < 121000)
> -		return LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_121M;
> +	u32 val;
> +
> +	if (freq < 39000000)
> +		val = LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_38M;
> +	else if (freq < 61000000)
> +		val = LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_60M;
> +	else if (freq < 121000000)
> +		val = LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_121M;
>  	else
> -		return LVDPLLCR_PLLDLYCNT_150M;
> +		val = LVDPLLCR_PLLDLYCNT_150M;
> +
> +	rcar_lvds_write(lvds, LVDPLLCR, val);
>  }
>
> -static u32 rcar_lvds_lvdpllcr_gen3(unsigned int freq)
> +static void rcar_lvds_pll_setup_gen3(struct rcar_lvds *lvds, unsigned int freq)
>  {
> -	if (freq < 42000)
> -		return LVDPLLCR_PLLDIVCNT_42M;
> -	else if (freq < 85000)
> -		return LVDPLLCR_PLLDIVCNT_85M;
> -	else if (freq < 128000)
> -		return LVDPLLCR_PLLDIVCNT_128M;
> +	u32 val;
> +
> +	if (freq < 42000000)
> +		val = LVDPLLCR_PLLDIVCNT_42M;
> +	else if (freq < 85000000)
> +		val = LVDPLLCR_PLLDIVCNT_85M;
> +	else if (freq < 128000000)
> +		val = LVDPLLCR_PLLDIVCNT_128M;
>  	else
> -		return LVDPLLCR_PLLDIVCNT_148M;
> +		val = LVDPLLCR_PLLDIVCNT_148M;
> +
> +	rcar_lvds_write(lvds, LVDPLLCR, val);
>  }
>
> +struct pll_info {
> +	unsigned long diff;
> +	unsigned int pll_m;
> +	unsigned int pll_n;
> +	unsigned int pll_e;
> +	unsigned int div;
> +	u32 clksel;
> +};
> +
> +static void rcar_lvds_d3_e3_pll_calc(struct rcar_lvds *lvds, struct clk *clk,
> +				     unsigned long target, struct pll_info *pll,
> +				     u32 clksel)
> +{
> +	unsigned long output;
> +	unsigned long fin;
> +	unsigned int m_min;
> +	unsigned int m_max;
> +	unsigned int m;
> +	int error;
> +
> +	if (!clk)
> +		return;
> +
> +	/*
> +	 * The LVDS PLL is made of a pre-divider and a multiplier (strangerly
> +	 * enough called M and N respectively), followed by a post-divider E.
> +	 *
> +	 *         ,-----.         ,-----.     ,-----.         ,-----.
> +	 * Fin --> | 1/M | -Fpdf-> | PFD | --> | VCO | -Fvco-> | 1/E | --> Fout
> +	 *         `-----'     ,-> |     |     `-----'   |     `-----'
> +	 *                     |   `-----'               |
> +	 *                     |         ,-----.         |
> +	 *                     `-------- | 1/N | <-------'
> +	 *                               `-----'
> +	 *
> +	 * The clock output by the PLL is then further divided by a programmable
> +	 * divider DIV to achieve the desired target frequency. Finally, an
> +	 * optional fixed /7 divider is used to convert the bit clock to a pixel
> +	 * clock (as LVDS transmits 7 bits per lane per clock sample).
> +	 *
> +	 *          ,-------.     ,-----.     |\
> +	 * Fout --> | 1/DIV | --> | 1/7 | --> | |
> +	 *          `-------'  |  `-----'     | | --> dot clock
> +	 *                     `------------> | |
> +	 *                                    |/
> +	 *
> +	 * The /7 divider is optional when the LVDS PLL is used to generate a
> +	 * dot clock for the DU RGB output, without using the LVDS encoder. We
> +	 * don't support this configuration yet.
> +	 *
> +	 * The PLL allowed input frequency range is 12 MHz to 192 MHz.
> +	 */
> +
> +	fin = clk_get_rate(clk);
> +	if (fin < 12000000 || fin > 192000000)
> +		return;
> +
> +	/*
> +	 * The comparison frequency range is 12 MHz to 24 MHz, which limits the
> +	 * allowed values for the pre-divider M (normal range 1-8).
> +	 *
> +	 * Fpfd = Fin / M
> +	 */
> +	m_min = max_t(unsigned int, 1, DIV_ROUND_UP(fin, 24000000));
> +	m_max = min_t(unsigned int, 8, fin / 12000000);
> +
> +	for (m = m_min; m <= m_max; ++m) {
> +		unsigned long fpfd;
> +		unsigned int n_min;
> +		unsigned int n_max;
> +		unsigned int n;
> +
> +		/*
> +		 * The VCO operating range is 900 Mhz to 1800 MHz, which limits
> +		 * the allowed values for the multiplier N (normal range
> +		 * 60-120).
> +		 *
> +		 * Fvco = Fin * N / M
> +		 */
> +		fpfd = fin / m;
> +		n_min = max_t(unsigned int, 60, DIV_ROUND_UP(900000000, fpfd));
> +		n_max = min_t(unsigned int, 120, 1800000000 / fpfd);
> +
> +		for (n = n_min; n < n_max; ++n) {
> +			unsigned long fvco;
> +			unsigned int e_min;
> +			unsigned int e;
> +
> +			/*
> +			 * The output frequency is limited to 1039.5 MHz,
> +			 * limiting again the allowed values for the
> +			 * post-divider E (normal value 1, 2 or 4).
> +			 *
> +			 * Fout = Fvco / E
> +			 */
> +			fvco = fpfd * n;
> +			e_min = fvco > 1039500000 ? 1 : 0;
> +
> +			for (e = e_min; e < 3; ++e) {
> +				unsigned long fout;
> +				unsigned long diff;
> +				unsigned int div;
> +
> +				/*
> +				 * Finally we have a programable divider after
> +				 * the PLL, followed by a an optional fixed /7
> +				 * divider.
> +				 */
> +				fout = fvco / (1 << e) / 7;
> +				div = DIV_ROUND_CLOSEST(fout, target);
> +				diff = abs(fout / div - target);
> +
> +				if (diff < pll->diff) {
> +					pll->diff = diff;
> +					pll->pll_m = m;
> +					pll->pll_n = n;
> +					pll->pll_e = e;
> +					pll->div = div;
> +					pll->clksel = clksel;
> +
> +					if (diff == 0)
> +						goto done;
> +				}
> +			}
> +		}
> +	}
> +
> +done:
> +	output = fin * pll->pll_n / pll->pll_m / (1 << pll->pll_e)
> +	       / 7 / pll->div;
> +	error = (long)(output - target) * 10000 / (long)target;
> +
> +	dev_dbg(lvds->dev,
> +		"%pC %lu Hz -> Fout %lu Hz (target %lu Hz, error %d.%02u%%), PLL M/N/E/DIV %u/%u/%u/%u\n",
> +		clk, fin, output, target, error / 100,
> +		error < 0 ? -error % 100 : error % 100,
> +		pll->pll_m, pll->pll_n, pll->pll_e, pll->div);
> +}
> +
> +static void rcar_lvds_pll_setup_d3_e3(struct rcar_lvds *lvds, unsigned int freq)
> +{
> +	struct pll_info pll = { .diff = (unsigned long)-1 };
> +	u32 lvdpllcr;
> +
> +	rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.dotclkin[0], freq, &pll,
> +				 LVDPLLCR_CKSEL_DU_DOTCLKIN(0));
> +	rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.dotclkin[1], freq, &pll,
> +				 LVDPLLCR_CKSEL_DU_DOTCLKIN(1));
> +	rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.extal, freq, &pll,
> +				 LVDPLLCR_CKSEL_EXTAL);
> +
> +	lvdpllcr = LVDPLLCR_PLLON | pll.clksel | LVDPLLCR_CLKOUT
> +		 | LVDPLLCR_PLLN(pll.pll_n - 1) | LVDPLLCR_PLLM(pll.pll_m - 1);
> +
> +	if (pll.pll_e > 0)
> +		lvdpllcr |= LVDPLLCR_STP_CLKOUTE | LVDPLLCR_OUTCLKSEL
> +			 |  LVDPLLCR_PLLE(pll.pll_e - 1);
> +
> +	rcar_lvds_write(lvds, LVDPLLCR, lvdpllcr);
> +
> +	if (pll.div > 1)
> +		rcar_lvds_write(lvds, LVDDIV, LVDDIV_DIVSEL |
> +				LVDDIV_DIVRESET | LVDDIV_DIV(pll.div - 1));
> +	else
> +		rcar_lvds_write(lvds, LVDDIV, 0);
> +}
> +
> +/* -----------------------------------------------------------------------------
> + * Bridge
> + */
> +
>  static void rcar_lvds_enable(struct drm_bridge *bridge)
>  {
>  	struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
> @@ -164,14 +351,13 @@ static void rcar_lvds_enable(struct drm_bridge *bridge)
>  	 * do we get a state pointer?
>  	 */
>  	struct drm_crtc *crtc = lvds->bridge.encoder->crtc;
> -	u32 lvdpllcr;
>  	u32 lvdhcr;
>  	u32 lvdcr0;
>  	int ret;
>
>  	WARN_ON(lvds->enabled);
>
> -	ret = clk_prepare_enable(lvds->clock);
> +	ret = clk_prepare_enable(lvds->clocks.mod);
>  	if (ret < 0)
>  		return;
>
> @@ -196,12 +382,13 @@ static void rcar_lvds_enable(struct drm_bridge *bridge)
>
>  	rcar_lvds_write(lvds, LVDCHCR, lvdhcr);
>
> +	if (lvds->info->quirks & RCAR_LVDS_QUIRK_DUAL_LINK) {
> +		/* Disable dual-link mode. */
> +		rcar_lvds_write(lvds, LVDSTRIPE, 0);
> +	}
> +
>  	/* PLL clock configuration. */
> -	if (lvds->info->quirks & RCAR_LVDS_QUIRK_GEN2_PLLCR)
> -		lvdpllcr = rcar_lvds_lvdpllcr_gen2(mode->clock);
> -	else
> -		lvdpllcr = rcar_lvds_lvdpllcr_gen3(mode->clock);
> -	rcar_lvds_write(lvds, LVDPLLCR, lvdpllcr);
> +	lvds->info->pll_setup(lvds, mode->clock * 1000);
>
>  	/* Set the LVDS mode and select the input. */
>  	lvdcr0 = lvds->mode << LVDCR0_LVMD_SHIFT;
> @@ -220,11 +407,16 @@ static void rcar_lvds_enable(struct drm_bridge *bridge)
>  		rcar_lvds_write(lvds, LVDCR0, lvdcr0);
>  	}
>
> -	/* Turn the PLL on. */
> -	lvdcr0 |= LVDCR0_PLLON;
> -	rcar_lvds_write(lvds, LVDCR0, lvdcr0);
> +	if (!(lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL)) {
> +		/*
> +		 * Turn the PLL on (simple PLL only, extended PLL is fully
> +		 * controlled through LVDPLLCR).
> +		 */
> +		lvdcr0 |= LVDCR0_PLLON;
> +		rcar_lvds_write(lvds, LVDCR0, lvdcr0);
> +	}
>
> -	if (lvds->info->gen > 2) {
> +	if (lvds->info->quirks & RCAR_LVDS_QUIRK_PWD) {
>  		/* Set LVDS normal mode. */
>  		lvdcr0 |= LVDCR0_PWD;
>  		rcar_lvds_write(lvds, LVDCR0, lvdcr0);
> @@ -236,8 +428,10 @@ static void rcar_lvds_enable(struct drm_bridge *bridge)
>  		rcar_lvds_write(lvds, LVDCR0, lvdcr0);
>  	}
>
> -	/* Wait for the startup delay. */
> -	usleep_range(100, 150);
> +	if (!(lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL)) {
> +		/* Wait for the PLL startup delay (simple PLL only). */
> +		usleep_range(100, 150);
> +	}
>
>  	/* Turn the output on. */
>  	lvdcr0 |= LVDCR0_LVRES;
> @@ -264,8 +458,9 @@ 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);
> +	clk_disable_unprepare(lvds->clocks.mod);
>
>  	lvds->enabled = false;
>  }
> @@ -446,6 +641,60 @@ static int rcar_lvds_parse_dt(struct rcar_lvds *lvds)
>  	return ret;
>  }
>
> +static struct clk *rcar_lvds_get_clock(struct rcar_lvds *lvds, const char *name,
> +				       bool optional)
> +{
> +	struct clk *clk;
> +
> +	clk = devm_clk_get(lvds->dev, name);
> +	if (!IS_ERR(clk))
> +		return clk;
> +
> +	if (PTR_ERR(clk) == -ENOENT && optional)
> +		return NULL;
> +
> +	if (PTR_ERR(clk) != -EPROBE_DEFER)
> +		dev_err(lvds->dev, "failed to get %s clock\n",
> +			name ? name : "module");
> +
> +	return clk;
> +}
> +
> +static int rcar_lvds_get_clocks(struct rcar_lvds *lvds)
> +{
> +	lvds->clocks.mod = rcar_lvds_get_clock(lvds, NULL, false);
> +	if (IS_ERR(lvds->clocks.mod))
> +		return PTR_ERR(lvds->clocks.mod);
> +
> +	/*
> +	 * LVDS encoders without an extended PLL have no external clock inputs.
> +	 */
> +	if (!(lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL))
> +		return 0;
> +
> +	lvds->clocks.extal = rcar_lvds_get_clock(lvds, "extal", true);
> +	if (IS_ERR(lvds->clocks.extal))
> +		return PTR_ERR(lvds->clocks.extal);
> +
> +	lvds->clocks.dotclkin[0] = rcar_lvds_get_clock(lvds, "dclkin.0", true);
> +	if (IS_ERR(lvds->clocks.dotclkin[0]))
> +		return PTR_ERR(lvds->clocks.dotclkin[0]);
> +
> +	lvds->clocks.dotclkin[1] = rcar_lvds_get_clock(lvds, "dclkin.1", true);
> +	if (IS_ERR(lvds->clocks.dotclkin[1]))
> +		return PTR_ERR(lvds->clocks.dotclkin[1]);
> +
> +	/* At least one input to the PLL must be available. */
> +	if (!lvds->clocks.extal && !lvds->clocks.dotclkin[0] &&
> +	    !lvds->clocks.dotclkin[1]) {
> +		dev_err(lvds->dev,
> +			"no input clock (extal, dclkin.0 or dclkin.1)\n");
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
>  static int rcar_lvds_probe(struct platform_device *pdev)
>  {
>  	struct rcar_lvds *lvds;
> @@ -475,11 +724,9 @@ static int rcar_lvds_probe(struct platform_device *pdev)
>  	if (IS_ERR(lvds->mmio))
>  		return PTR_ERR(lvds->mmio);
>
> -	lvds->clock = devm_clk_get(&pdev->dev, NULL);
> -	if (IS_ERR(lvds->clock)) {
> -		dev_err(&pdev->dev, "failed to get clock\n");
> -		return PTR_ERR(lvds->clock);
> -	}
> +	ret = rcar_lvds_get_clocks(lvds);
> +	if (ret < 0)
> +		return ret;
>
>  	drm_bridge_add(&lvds->bridge);
>
> @@ -497,21 +744,39 @@ static int rcar_lvds_remove(struct platform_device *pdev)
>
>  static const struct rcar_lvds_device_info rcar_lvds_gen2_info = {
>  	.gen = 2,
> -	.quirks = RCAR_LVDS_QUIRK_GEN2_PLLCR,
> +	.pll_setup = rcar_lvds_pll_setup_gen2,
>  };
>
>  static const struct rcar_lvds_device_info rcar_lvds_r8a7790_info = {
>  	.gen = 2,
> -	.quirks = RCAR_LVDS_QUIRK_GEN2_PLLCR | RCAR_LVDS_QUIRK_LANES,
> +	.quirks = RCAR_LVDS_QUIRK_LANES,
> +	.pll_setup = rcar_lvds_pll_setup_gen2,
>  };
>
>  static const struct rcar_lvds_device_info rcar_lvds_gen3_info = {
>  	.gen = 3,
> +	.quirks = RCAR_LVDS_QUIRK_PWD,
> +	.pll_setup = rcar_lvds_pll_setup_gen3,
>  };
>
>  static const struct rcar_lvds_device_info rcar_lvds_r8a77970_info = {
>  	.gen = 3,
> -	.quirks = RCAR_LVDS_QUIRK_GEN2_PLLCR | RCAR_LVDS_QUIRK_GEN3_LVEN,
> +	.quirks = RCAR_LVDS_QUIRK_PWD | RCAR_LVDS_QUIRK_GEN3_LVEN,
> +	.pll_setup = rcar_lvds_pll_setup_gen2,
> +};
> +
> +static const struct rcar_lvds_device_info rcar_lvds_r8a77990_info = {
> +	.gen = 3,
> +	.quirks = RCAR_LVDS_QUIRK_GEN3_LVEN | RCAR_LVDS_QUIRK_EXT_PLL
> +		| RCAR_LVDS_QUIRK_DUAL_LINK,
> +	.pll_setup = rcar_lvds_pll_setup_d3_e3,
> +};
> +
> +static const struct rcar_lvds_device_info rcar_lvds_r8a77995_info = {
> +	.gen = 3,
> +	.quirks = RCAR_LVDS_QUIRK_GEN3_LVEN | RCAR_LVDS_QUIRK_PWD
> +		| RCAR_LVDS_QUIRK_EXT_PLL | RCAR_LVDS_QUIRK_DUAL_LINK,
> +	.pll_setup = rcar_lvds_pll_setup_d3_e3,
>  };
>
>  static const struct of_device_id rcar_lvds_of_table[] = {
> @@ -523,6 +788,8 @@ static const struct of_device_id rcar_lvds_of_table[] = {
>  	{ .compatible = "renesas,r8a7796-lvds", .data = &rcar_lvds_gen3_info },
>  	{ .compatible = "renesas,r8a77970-lvds", .data = &rcar_lvds_r8a77970_info },
>  	{ .compatible = "renesas,r8a77980-lvds", .data = &rcar_lvds_gen3_info },
> +	{ .compatible = "renesas,r8a77990-lvds", .data = &rcar_lvds_r8a77990_info },
> +	{ .compatible = "renesas,r8a77995-lvds", .data = &rcar_lvds_r8a77995_info },
>  	{ }
>  };
>
> diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h b/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
> index 4870f50d9bec..87149f2f8056 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
> @@ -18,7 +18,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
> @@ -27,21 +27,36 @@
>  #define LVDCR1_CLKSTBY			(3 << 0)
>
>  #define LVDPLLCR			0x0008
> +/* Gen2 & V3M */
>  #define LVDPLLCR_CEEN			(1 << 14)
>  #define LVDPLLCR_FBEN			(1 << 13)
>  #define LVDPLLCR_COSEL			(1 << 12)
> -/* Gen2 */
>  #define LVDPLLCR_PLLDLYCNT_150M		(0x1bf << 0)
>  #define LVDPLLCR_PLLDLYCNT_121M		(0x22c << 0)
>  #define LVDPLLCR_PLLDLYCNT_60M		(0x77b << 0)
>  #define LVDPLLCR_PLLDLYCNT_38M		(0x69a << 0)
>  #define LVDPLLCR_PLLDLYCNT_MASK		(0x7ff << 0)
> -/* Gen3 */
> +/* Gen3 but V3M,D3 and E3 */
>  #define LVDPLLCR_PLLDIVCNT_42M		(0x014cb << 0)
>  #define LVDPLLCR_PLLDIVCNT_85M		(0x00a45 << 0)
>  #define LVDPLLCR_PLLDIVCNT_128M		(0x006c3 << 0)
>  #define LVDPLLCR_PLLDIVCNT_148M		(0x046c1 << 0)
>  #define LVDPLLCR_PLLDIVCNT_MASK		(0x7ffff << 0)
> +/* D3 and E3 */
> +#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_DOTCLKIN(n)	((5 + (n) * 2) << 17)
> +#define LVDPLLCR_OCKSEL			(1 << 16)
> +#define LVDPLLCR_STP_CLKOUTE		(1 << 14)
> +#define LVDPLLCR_OUTCLKSEL		(1 << 12)
> +#define LVDPLLCR_CLKOUT			(1 << 11)
> +#define LVDPLLCR_PLLE(n)		((n) << 10)
> +#define LVDPLLCR_PLLN(n)		((n) << 3)
> +#define LVDPLLCR_PLLM(n)		((n) << 0)
>
>  #define LVDCTRCR			0x000c
>  #define LVDCTRCR_CTR3SEL_ZERO		(0 << 12)
> @@ -71,4 +86,26 @@
>  #define LVDCHCR_CHSEL_CH(n, c)		((((c) - (n)) & 3) << ((n) * 4))
>  #define LVDCHCR_CHSEL_MASK(n)		(3 << ((n) * 4))
>
> +/* All registers below are specific to D3 and E3 */
> +#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		(1 << 1)
> +#define LVDSTRIPE_ST_ON			(1 << 0)
> +
> +#define LVDSCR				0x0018
> +#define LVDSCR_DEPTH(n)			(((n) - 1) << 29)
> +#define LVDSCR_BANDSET			(1 << 28)
> +#define LVDSCR_TWGCNT(n)		((((n) - 256) / 16) << 24)
> +#define LVDSCR_SDIV(n)			((n) << 22)
> +#define LVDSCR_MODE			(1 << 21)
> +#define LVDSCR_RSTN			(1 << 20)
> +
> +#define LVDDIV				0x001c
> +#define LVDDIV_DIVSEL			(1 << 8)
> +#define LVDDIV_DIVRESET			(1 << 7)
> +#define LVDDIV_DIVSTP			(1 << 6)
> +#define LVDDIV_DIV(n)			((n) << 0)
> +
>  #endif /* __RCAR_LVDS_REGS_H__ */
> --
> Regards,
>
> Laurent Pinchart
>

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

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

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

* Re: [PATCH v2 06/16] drm: rcar-du: Perform the initial CRTC setup from rcar_du_crtc_get()
  2018-09-14  9:10   ` Laurent Pinchart
@ 2018-09-17 12:50     ` jacopo mondi
  -1 siblings, 0 replies; 118+ messages in thread
From: jacopo mondi @ 2018-09-17 12:50 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: dri-devel, linux-renesas-soc, Ulrich Hecht, Kieran Bingham

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

Hi Laurent,

On Fri, Sep 14, 2018 at 12:10:36PM +0300, Laurent Pinchart wrote:
> The rcar_du_crtc_get() function is always immediately followed by a call
> to rcar_du_crtc_setup(). Call the later from the former to simplify the
> code, and add a comment to explain how the get and put calls are
> balanced.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>

Please add my
Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>

> ---
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 107 +++++++++++++++++----------------
>  1 file changed, 56 insertions(+), 51 deletions(-)
>
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> index 6288b9ad9e24..c89751c26f9c 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> @@ -66,39 +66,6 @@ static void rcar_du_crtc_clr_set(struct rcar_du_crtc *rcrtc, u32 reg,
>  	rcar_du_write(rcdu, rcrtc->mmio_offset + reg, (value & ~clr) | set);
>  }
>
> -static int rcar_du_crtc_get(struct rcar_du_crtc *rcrtc)
> -{
> -	int ret;
> -
> -	ret = clk_prepare_enable(rcrtc->clock);
> -	if (ret < 0)
> -		return ret;
> -
> -	ret = clk_prepare_enable(rcrtc->extclock);
> -	if (ret < 0)
> -		goto error_clock;
> -
> -	ret = rcar_du_group_get(rcrtc->group);
> -	if (ret < 0)
> -		goto error_group;
> -
> -	return 0;
> -
> -error_group:
> -	clk_disable_unprepare(rcrtc->extclock);
> -error_clock:
> -	clk_disable_unprepare(rcrtc->clock);
> -	return ret;
> -}
> -
> -static void rcar_du_crtc_put(struct rcar_du_crtc *rcrtc)
> -{
> -	rcar_du_group_put(rcrtc->group);
> -
> -	clk_disable_unprepare(rcrtc->extclock);
> -	clk_disable_unprepare(rcrtc->clock);
> -}
> -
>  /* -----------------------------------------------------------------------------
>   * Hardware Setup
>   */
> @@ -546,6 +513,51 @@ static void rcar_du_crtc_setup(struct rcar_du_crtc *rcrtc)
>  	drm_crtc_vblank_on(&rcrtc->crtc);
>  }
>
> +static int rcar_du_crtc_get(struct rcar_du_crtc *rcrtc)
> +{
> +	int ret;
> +
> +	/*
> +	 * Guard against double-get, as the function is called from both the
> +	 * .atomic_enable() and .atomic_begin() handlers.
> +	 */
> +	if (rcrtc->initialized)
> +		return 0;
> +
> +	ret = clk_prepare_enable(rcrtc->clock);
> +	if (ret < 0)
> +		return ret;
> +
> +	ret = clk_prepare_enable(rcrtc->extclock);
> +	if (ret < 0)
> +		goto error_clock;
> +
> +	ret = rcar_du_group_get(rcrtc->group);
> +	if (ret < 0)
> +		goto error_group;
> +
> +	rcar_du_crtc_setup(rcrtc);
> +	rcrtc->initialized = true;
> +
> +	return 0;
> +
> +error_group:
> +	clk_disable_unprepare(rcrtc->extclock);
> +error_clock:
> +	clk_disable_unprepare(rcrtc->clock);
> +	return ret;
> +}
> +
> +static void rcar_du_crtc_put(struct rcar_du_crtc *rcrtc)
> +{
> +	rcar_du_group_put(rcrtc->group);
> +
> +	clk_disable_unprepare(rcrtc->extclock);
> +	clk_disable_unprepare(rcrtc->clock);
> +
> +	rcrtc->initialized = false;
> +}
> +
>  static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc)
>  {
>  	bool interlaced;
> @@ -639,16 +651,7 @@ static void rcar_du_crtc_atomic_enable(struct drm_crtc *crtc,
>  {
>  	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
>
> -	/*
> -	 * If the CRTC has already been setup by the .atomic_begin() handler we
> -	 * can skip the setup stage.
> -	 */
> -	if (!rcrtc->initialized) {
> -		rcar_du_crtc_get(rcrtc);
> -		rcar_du_crtc_setup(rcrtc);
> -		rcrtc->initialized = true;
> -	}
> -
> +	rcar_du_crtc_get(rcrtc);
>  	rcar_du_crtc_start(rcrtc);
>  }
>
> @@ -667,7 +670,6 @@ static void rcar_du_crtc_atomic_disable(struct drm_crtc *crtc,
>  	}
>  	spin_unlock_irq(&crtc->dev->event_lock);
>
> -	rcrtc->initialized = false;
>  	rcrtc->outputs = 0;
>  }
>
> @@ -680,14 +682,17 @@ static void rcar_du_crtc_atomic_begin(struct drm_crtc *crtc,
>
>  	/*
>  	 * If a mode set is in progress we can be called with the CRTC disabled.
> -	 * We then need to first setup the CRTC in order to configure planes.
> -	 * The .atomic_enable() handler will notice and skip the CRTC setup.
> +	 * We thus need to first get and setup the CRTC in order to configure
> +	 * planes. We must *not* put the CRTC in .atomic_flush(), as it must be
> +	 * kept awake until the .atomic_enable() call that will follow. The get
> +	 * operation in .atomic_enable() will in that case be a no-op, and the
> +	 * CRTC will be put later in .atomic_disable().
> +	 *
> +	 * If a mode set is not in progress the CRTC is enabled, and the
> +	 * following get call will be a no-op. There is thus no need to belance
> +	 * it in .atomic_flush() either.
>  	 */
> -	if (!rcrtc->initialized) {
> -		rcar_du_crtc_get(rcrtc);
> -		rcar_du_crtc_setup(rcrtc);
> -		rcrtc->initialized = true;
> -	}
> +	rcar_du_crtc_get(rcrtc);
>
>  	if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
>  		rcar_du_vsp_atomic_begin(rcrtc);
> --
> Regards,
>
> Laurent Pinchart
>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [PATCH v2 06/16] drm: rcar-du: Perform the initial CRTC setup from rcar_du_crtc_get()
@ 2018-09-17 12:50     ` jacopo mondi
  0 siblings, 0 replies; 118+ messages in thread
From: jacopo mondi @ 2018-09-17 12:50 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham, dri-devel


[-- Attachment #1.1: Type: text/plain, Size: 4924 bytes --]

Hi Laurent,

On Fri, Sep 14, 2018 at 12:10:36PM +0300, Laurent Pinchart wrote:
> The rcar_du_crtc_get() function is always immediately followed by a call
> to rcar_du_crtc_setup(). Call the later from the former to simplify the
> code, and add a comment to explain how the get and put calls are
> balanced.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>

Please add my
Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>

> ---
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 107 +++++++++++++++++----------------
>  1 file changed, 56 insertions(+), 51 deletions(-)
>
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> index 6288b9ad9e24..c89751c26f9c 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> @@ -66,39 +66,6 @@ static void rcar_du_crtc_clr_set(struct rcar_du_crtc *rcrtc, u32 reg,
>  	rcar_du_write(rcdu, rcrtc->mmio_offset + reg, (value & ~clr) | set);
>  }
>
> -static int rcar_du_crtc_get(struct rcar_du_crtc *rcrtc)
> -{
> -	int ret;
> -
> -	ret = clk_prepare_enable(rcrtc->clock);
> -	if (ret < 0)
> -		return ret;
> -
> -	ret = clk_prepare_enable(rcrtc->extclock);
> -	if (ret < 0)
> -		goto error_clock;
> -
> -	ret = rcar_du_group_get(rcrtc->group);
> -	if (ret < 0)
> -		goto error_group;
> -
> -	return 0;
> -
> -error_group:
> -	clk_disable_unprepare(rcrtc->extclock);
> -error_clock:
> -	clk_disable_unprepare(rcrtc->clock);
> -	return ret;
> -}
> -
> -static void rcar_du_crtc_put(struct rcar_du_crtc *rcrtc)
> -{
> -	rcar_du_group_put(rcrtc->group);
> -
> -	clk_disable_unprepare(rcrtc->extclock);
> -	clk_disable_unprepare(rcrtc->clock);
> -}
> -
>  /* -----------------------------------------------------------------------------
>   * Hardware Setup
>   */
> @@ -546,6 +513,51 @@ static void rcar_du_crtc_setup(struct rcar_du_crtc *rcrtc)
>  	drm_crtc_vblank_on(&rcrtc->crtc);
>  }
>
> +static int rcar_du_crtc_get(struct rcar_du_crtc *rcrtc)
> +{
> +	int ret;
> +
> +	/*
> +	 * Guard against double-get, as the function is called from both the
> +	 * .atomic_enable() and .atomic_begin() handlers.
> +	 */
> +	if (rcrtc->initialized)
> +		return 0;
> +
> +	ret = clk_prepare_enable(rcrtc->clock);
> +	if (ret < 0)
> +		return ret;
> +
> +	ret = clk_prepare_enable(rcrtc->extclock);
> +	if (ret < 0)
> +		goto error_clock;
> +
> +	ret = rcar_du_group_get(rcrtc->group);
> +	if (ret < 0)
> +		goto error_group;
> +
> +	rcar_du_crtc_setup(rcrtc);
> +	rcrtc->initialized = true;
> +
> +	return 0;
> +
> +error_group:
> +	clk_disable_unprepare(rcrtc->extclock);
> +error_clock:
> +	clk_disable_unprepare(rcrtc->clock);
> +	return ret;
> +}
> +
> +static void rcar_du_crtc_put(struct rcar_du_crtc *rcrtc)
> +{
> +	rcar_du_group_put(rcrtc->group);
> +
> +	clk_disable_unprepare(rcrtc->extclock);
> +	clk_disable_unprepare(rcrtc->clock);
> +
> +	rcrtc->initialized = false;
> +}
> +
>  static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc)
>  {
>  	bool interlaced;
> @@ -639,16 +651,7 @@ static void rcar_du_crtc_atomic_enable(struct drm_crtc *crtc,
>  {
>  	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
>
> -	/*
> -	 * If the CRTC has already been setup by the .atomic_begin() handler we
> -	 * can skip the setup stage.
> -	 */
> -	if (!rcrtc->initialized) {
> -		rcar_du_crtc_get(rcrtc);
> -		rcar_du_crtc_setup(rcrtc);
> -		rcrtc->initialized = true;
> -	}
> -
> +	rcar_du_crtc_get(rcrtc);
>  	rcar_du_crtc_start(rcrtc);
>  }
>
> @@ -667,7 +670,6 @@ static void rcar_du_crtc_atomic_disable(struct drm_crtc *crtc,
>  	}
>  	spin_unlock_irq(&crtc->dev->event_lock);
>
> -	rcrtc->initialized = false;
>  	rcrtc->outputs = 0;
>  }
>
> @@ -680,14 +682,17 @@ static void rcar_du_crtc_atomic_begin(struct drm_crtc *crtc,
>
>  	/*
>  	 * If a mode set is in progress we can be called with the CRTC disabled.
> -	 * We then need to first setup the CRTC in order to configure planes.
> -	 * The .atomic_enable() handler will notice and skip the CRTC setup.
> +	 * We thus need to first get and setup the CRTC in order to configure
> +	 * planes. We must *not* put the CRTC in .atomic_flush(), as it must be
> +	 * kept awake until the .atomic_enable() call that will follow. The get
> +	 * operation in .atomic_enable() will in that case be a no-op, and the
> +	 * CRTC will be put later in .atomic_disable().
> +	 *
> +	 * If a mode set is not in progress the CRTC is enabled, and the
> +	 * following get call will be a no-op. There is thus no need to belance
> +	 * it in .atomic_flush() either.
>  	 */
> -	if (!rcrtc->initialized) {
> -		rcar_du_crtc_get(rcrtc);
> -		rcar_du_crtc_setup(rcrtc);
> -		rcrtc->initialized = true;
> -	}
> +	rcar_du_crtc_get(rcrtc);
>
>  	if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
>  		rcar_du_vsp_atomic_begin(rcrtc);
> --
> Regards,
>
> Laurent Pinchart
>

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

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

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

* Re: [PATCH v2 07/16] drm: rcar-du: Use LVDS PLL clock as dot clock when possible
  2018-09-14  9:10   ` Laurent Pinchart
@ 2018-09-17 12:55     ` jacopo mondi
  -1 siblings, 0 replies; 118+ messages in thread
From: jacopo mondi @ 2018-09-17 12:55 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: dri-devel, linux-renesas-soc, Ulrich Hecht, Kieran Bingham

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

Hi Laurent,

On Fri, Sep 14, 2018 at 12:10:37PM +0300, Laurent Pinchart wrote:
> On selected SoCs, the DU can use the clock output by the LVDS encoder
> PLL as its input dot clock. This feature is optional, but on the D3 and
> E3 SoC it is often the only way to obtain a precise dot clock frequency,
> as the other available clocks (CPG-generated clock and external clock)
> usually have fixed rates.
>
> Add a DU model information field to describe which DU channels can use
> the LVDS PLL output clock as their input clock, and configure clock
> routing accordingly.
>
> This feature is available on H2, M2-W, M2-N, D3 and E3 SoCs, with D3 and
> E3 being the primary targets. It is left disabled in this commit, and
> will be enabled per-SoC after careful testing.
>
> At the hardware level, clock routing is configured at runtime in two
> steps, first selecting an internal dot clock between the LVDS PLL clock
> and the external DOTCLKIN clock, and then selecting between the internal
> dot clock and the CPG-generated clock. The first part requires stopping
> the whole DU group in order for the change to take effect, thus causing
> flickering on the screen. For this reason we currently hardcode the
> clock source to the LVDS PLL clock if available, and allow flicker-free
> selection of the external DOTCLKIN clock or CPG-generated clock
> otherwise. A more dynamic clock selection process can be implemented
> later if the need arises.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>

Please add my
Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>

> ---
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.c  |  8 +++++
>  drivers/gpu/drm/rcar-du/rcar_du_drv.h   |  2 ++
>  drivers/gpu/drm/rcar-du/rcar_du_group.c | 64 +++++++++++++++++++++++++--------
>  3 files changed, 59 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> index c89751c26f9c..2f8776c1ec8f 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> @@ -261,6 +261,14 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
>  		rcar_du_group_write(rcrtc->group, DPLLCR, dpllcr);
>
>  		escr = ESCR_DCLKSEL_DCLKIN | div;
> +	} else if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index)) {
> +		/*
> +		 * Use the LVDS PLL output as the dot clock when outputting to
> +		 * the LVDS encoder on an SoC that supports this clock routing
> +		 * option. We use the clock directly in that case, without any
> +		 * additional divider.
> +		 */
> +		escr = ESCR_DCLKSEL_DCLKIN;
>  	} else {
>  		struct du_clk_params params = { .diff = (unsigned long)-1 };
>
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> index fef9ea5c22f3..ebba9aefba6a 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> @@ -53,6 +53,7 @@ struct rcar_du_output_routing {
>   * @routes: array of CRTC to output routes, indexed by output (RCAR_DU_OUTPUT_*)
>   * @num_lvds: number of internal LVDS encoders
>   * @dpll_mask: bit mask of DU channels equipped with a DPLL
> + * @lvds_clk_mask: bitmask of channels that can use the LVDS clock as dot clock
>   */
>  struct rcar_du_device_info {
>  	unsigned int gen;
> @@ -62,6 +63,7 @@ struct rcar_du_device_info {
>  	struct rcar_du_output_routing routes[RCAR_DU_OUTPUT_MAX];
>  	unsigned int num_lvds;
>  	unsigned int dpll_mask;
> +	unsigned int lvds_clk_mask;
>  };
>
>  #define RCAR_DU_MAX_CRTCS		4
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c
> index ef2c177afb6d..4c62841eff2f 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
> @@ -89,6 +89,54 @@ static void rcar_du_group_setup_defr8(struct rcar_du_group *rgrp)
>  	rcar_du_group_write(rgrp, DEFR8, defr8);
>  }
>
> +static void rcar_du_group_setup_didsr(struct rcar_du_group *rgrp)
> +{
> +	struct rcar_du_device *rcdu = rgrp->dev;
> +	struct rcar_du_crtc *rcrtc;
> +	unsigned int num_crtcs = 0;
> +	unsigned int i;
> +	u32 didsr;
> +
> +	/*
> +	 * Configure input dot clock routing with a hardcoded configuration. If
> +	 * the DU channel can use the LVDS encoder output clock as the dot
> +	 * clock, do so. Otherwise route DU_DOTCLKINn signal to DUn.
> +	 *
> +	 * Each channel can then select between the dot clock configured here
> +	 * and the clock provided by the CPG through the ESCR register.
> +	 */
> +	if (rcdu->info->gen < 3 && rgrp->index == 0) {
> +		/*
> +		 * On Gen2 a single register in the first group controls dot
> +		 * clock selection for all channels.
> +		 */
> +		rcrtc = rcdu->crtcs;
> +		num_crtcs = rcdu->num_crtcs;
> +	} else if (rcdu->info->gen == 3 && rgrp->num_crtcs > 1) {
> +		/*
> +		 * On Gen3 dot clocks are setup through per-group registers,
> +		 * only available when the group has two channels.
> +		 */
> +		rcrtc = &rcdu->crtcs[rgrp->index * 2];
> +		num_crtcs = rgrp->num_crtcs;
> +	}
> +
> +	if (!num_crtcs)
> +		return;
> +
> +	didsr = DIDSR_CODE;
> +	for (i = 0; i < num_crtcs; ++i, ++rcrtc) {
> +		if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index))
> +			didsr |= DIDSR_LCDS_LVDS0(i)
> +			      |  DIDSR_PDCS_CLK(i, 0);
> +		else
> +			didsr |= DIDSR_LCDS_DCLKIN(i)
> +			      |  DIDSR_PDCS_CLK(i, 0);
> +	}
> +
> +	rcar_du_group_write(rgrp, DIDSR, didsr);
> +}
> +
>  static void rcar_du_group_setup(struct rcar_du_group *rgrp)
>  {
>  	struct rcar_du_device *rcdu = rgrp->dev;
> @@ -106,21 +154,7 @@ static void rcar_du_group_setup(struct rcar_du_group *rgrp)
>
>  	if (rcar_du_has(rgrp->dev, RCAR_DU_FEATURE_EXT_CTRL_REGS)) {
>  		rcar_du_group_setup_defr8(rgrp);
> -
> -		/*
> -		 * Configure input dot clock routing. We currently hardcode the
> -		 * configuration to routing DOTCLKINn to DUn. Register fields
> -		 * depend on the DU generation, but the resulting value is 0 in
> -		 * all cases.
> -		 *
> -		 * On Gen2 a single register in the first group controls dot
> -		 * clock selection for all channels, while on Gen3 dot clocks
> -		 * 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))
> -			rcar_du_group_write(rgrp, DIDSR, DIDSR_CODE);
> +		rcar_du_group_setup_didsr(rgrp);
>  	}
>
>  	if (rcdu->info->gen >= 3)
> --
> Regards,
>
> Laurent Pinchart
>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [PATCH v2 07/16] drm: rcar-du: Use LVDS PLL clock as dot clock when possible
@ 2018-09-17 12:55     ` jacopo mondi
  0 siblings, 0 replies; 118+ messages in thread
From: jacopo mondi @ 2018-09-17 12:55 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham, dri-devel


[-- Attachment #1.1: Type: text/plain, Size: 6555 bytes --]

Hi Laurent,

On Fri, Sep 14, 2018 at 12:10:37PM +0300, Laurent Pinchart wrote:
> On selected SoCs, the DU can use the clock output by the LVDS encoder
> PLL as its input dot clock. This feature is optional, but on the D3 and
> E3 SoC it is often the only way to obtain a precise dot clock frequency,
> as the other available clocks (CPG-generated clock and external clock)
> usually have fixed rates.
>
> Add a DU model information field to describe which DU channels can use
> the LVDS PLL output clock as their input clock, and configure clock
> routing accordingly.
>
> This feature is available on H2, M2-W, M2-N, D3 and E3 SoCs, with D3 and
> E3 being the primary targets. It is left disabled in this commit, and
> will be enabled per-SoC after careful testing.
>
> At the hardware level, clock routing is configured at runtime in two
> steps, first selecting an internal dot clock between the LVDS PLL clock
> and the external DOTCLKIN clock, and then selecting between the internal
> dot clock and the CPG-generated clock. The first part requires stopping
> the whole DU group in order for the change to take effect, thus causing
> flickering on the screen. For this reason we currently hardcode the
> clock source to the LVDS PLL clock if available, and allow flicker-free
> selection of the external DOTCLKIN clock or CPG-generated clock
> otherwise. A more dynamic clock selection process can be implemented
> later if the need arises.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>

Please add my
Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>

> ---
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.c  |  8 +++++
>  drivers/gpu/drm/rcar-du/rcar_du_drv.h   |  2 ++
>  drivers/gpu/drm/rcar-du/rcar_du_group.c | 64 +++++++++++++++++++++++++--------
>  3 files changed, 59 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> index c89751c26f9c..2f8776c1ec8f 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> @@ -261,6 +261,14 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
>  		rcar_du_group_write(rcrtc->group, DPLLCR, dpllcr);
>
>  		escr = ESCR_DCLKSEL_DCLKIN | div;
> +	} else if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index)) {
> +		/*
> +		 * Use the LVDS PLL output as the dot clock when outputting to
> +		 * the LVDS encoder on an SoC that supports this clock routing
> +		 * option. We use the clock directly in that case, without any
> +		 * additional divider.
> +		 */
> +		escr = ESCR_DCLKSEL_DCLKIN;
>  	} else {
>  		struct du_clk_params params = { .diff = (unsigned long)-1 };
>
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> index fef9ea5c22f3..ebba9aefba6a 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> @@ -53,6 +53,7 @@ struct rcar_du_output_routing {
>   * @routes: array of CRTC to output routes, indexed by output (RCAR_DU_OUTPUT_*)
>   * @num_lvds: number of internal LVDS encoders
>   * @dpll_mask: bit mask of DU channels equipped with a DPLL
> + * @lvds_clk_mask: bitmask of channels that can use the LVDS clock as dot clock
>   */
>  struct rcar_du_device_info {
>  	unsigned int gen;
> @@ -62,6 +63,7 @@ struct rcar_du_device_info {
>  	struct rcar_du_output_routing routes[RCAR_DU_OUTPUT_MAX];
>  	unsigned int num_lvds;
>  	unsigned int dpll_mask;
> +	unsigned int lvds_clk_mask;
>  };
>
>  #define RCAR_DU_MAX_CRTCS		4
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c
> index ef2c177afb6d..4c62841eff2f 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
> @@ -89,6 +89,54 @@ static void rcar_du_group_setup_defr8(struct rcar_du_group *rgrp)
>  	rcar_du_group_write(rgrp, DEFR8, defr8);
>  }
>
> +static void rcar_du_group_setup_didsr(struct rcar_du_group *rgrp)
> +{
> +	struct rcar_du_device *rcdu = rgrp->dev;
> +	struct rcar_du_crtc *rcrtc;
> +	unsigned int num_crtcs = 0;
> +	unsigned int i;
> +	u32 didsr;
> +
> +	/*
> +	 * Configure input dot clock routing with a hardcoded configuration. If
> +	 * the DU channel can use the LVDS encoder output clock as the dot
> +	 * clock, do so. Otherwise route DU_DOTCLKINn signal to DUn.
> +	 *
> +	 * Each channel can then select between the dot clock configured here
> +	 * and the clock provided by the CPG through the ESCR register.
> +	 */
> +	if (rcdu->info->gen < 3 && rgrp->index == 0) {
> +		/*
> +		 * On Gen2 a single register in the first group controls dot
> +		 * clock selection for all channels.
> +		 */
> +		rcrtc = rcdu->crtcs;
> +		num_crtcs = rcdu->num_crtcs;
> +	} else if (rcdu->info->gen == 3 && rgrp->num_crtcs > 1) {
> +		/*
> +		 * On Gen3 dot clocks are setup through per-group registers,
> +		 * only available when the group has two channels.
> +		 */
> +		rcrtc = &rcdu->crtcs[rgrp->index * 2];
> +		num_crtcs = rgrp->num_crtcs;
> +	}
> +
> +	if (!num_crtcs)
> +		return;
> +
> +	didsr = DIDSR_CODE;
> +	for (i = 0; i < num_crtcs; ++i, ++rcrtc) {
> +		if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index))
> +			didsr |= DIDSR_LCDS_LVDS0(i)
> +			      |  DIDSR_PDCS_CLK(i, 0);
> +		else
> +			didsr |= DIDSR_LCDS_DCLKIN(i)
> +			      |  DIDSR_PDCS_CLK(i, 0);
> +	}
> +
> +	rcar_du_group_write(rgrp, DIDSR, didsr);
> +}
> +
>  static void rcar_du_group_setup(struct rcar_du_group *rgrp)
>  {
>  	struct rcar_du_device *rcdu = rgrp->dev;
> @@ -106,21 +154,7 @@ static void rcar_du_group_setup(struct rcar_du_group *rgrp)
>
>  	if (rcar_du_has(rgrp->dev, RCAR_DU_FEATURE_EXT_CTRL_REGS)) {
>  		rcar_du_group_setup_defr8(rgrp);
> -
> -		/*
> -		 * Configure input dot clock routing. We currently hardcode the
> -		 * configuration to routing DOTCLKINn to DUn. Register fields
> -		 * depend on the DU generation, but the resulting value is 0 in
> -		 * all cases.
> -		 *
> -		 * On Gen2 a single register in the first group controls dot
> -		 * clock selection for all channels, while on Gen3 dot clocks
> -		 * 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))
> -			rcar_du_group_write(rgrp, DIDSR, DIDSR_CODE);
> +		rcar_du_group_setup_didsr(rgrp);
>  	}
>
>  	if (rcdu->info->gen >= 3)
> --
> Regards,
>
> Laurent Pinchart
>

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

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

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

* Re: [PATCH v2 08/16] drm: rcar-du: Enable configurable DPAD0 routing on Gen3
  2018-09-14  9:10   ` Laurent Pinchart
@ 2018-09-17 12:56     ` jacopo mondi
  -1 siblings, 0 replies; 118+ messages in thread
From: jacopo mondi @ 2018-09-17 12:56 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: dri-devel, linux-renesas-soc, Ulrich Hecht, Kieran Bingham

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

Hi Laurent,

On Fri, Sep 14, 2018 at 12:10:38PM +0300, Laurent Pinchart wrote:
> All Gen3 SoCs supported so far have a fixed association between DPAD0
> and DU channels, which led to hardcoding that association when writing
> the corresponding hardware register. The D3 and E3 will break that
> mechanism as DPAD0 can be dynamically connected to either DU0 or DU1.
>
> Make DPAD0 routing dynamic on Gen3. To ensure a valid hardware
> configuration when the DU starts without the RGB output enabled, DPAD0
> is associated at initialization time to the first DU channel that it can
> be connected to. This makes no change on Gen2 as all Gen2 SoCs can
> connected DPAD0 to DU0, which is the current implicit default value.
>
> As the DPAD0 source is always 0 when a single source is possible on
> Gen2, we can also simplify the Gen2 code in the same function to remove
> a conditional check.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>

Please add my:
Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>



> ---
>  drivers/gpu/drm/rcar-du/rcar_du_group.c | 17 ++++++-----------
>  drivers/gpu/drm/rcar-du/rcar_du_kms.c   | 12 ++++++++++++
>  2 files changed, 18 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c
> index 4c62841eff2f..f38703e7a10d 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
> @@ -56,8 +56,6 @@ static void rcar_du_group_setup_pins(struct rcar_du_group *rgrp)
>  static void rcar_du_group_setup_defr8(struct rcar_du_group *rgrp)
>  {
>  	struct rcar_du_device *rcdu = rgrp->dev;
> -	unsigned int possible_crtcs =
> -		rcdu->info->routes[RCAR_DU_OUTPUT_DPAD0].possible_crtcs;
>  	u32 defr8 = DEFR8_CODE;
>
>  	if (rcdu->info->gen < 3) {
> @@ -69,21 +67,18 @@ static void rcar_du_group_setup_defr8(struct rcar_du_group *rgrp)
>  		 * DU instances that support it.
>  		 */
>  		if (rgrp->index == 0) {
> -			if (possible_crtcs > 1)
> -				defr8 |= DEFR8_DRGBS_DU(rcdu->dpad0_source);
> +			defr8 |= DEFR8_DRGBS_DU(rcdu->dpad0_source);
>  			if (rgrp->dev->vspd1_sink == 2)
>  				defr8 |= DEFR8_VSCS;
>  		}
>  	} else {
>  		/*
> -		 * On Gen3 VSPD routing can't be configured, but DPAD routing
> -		 * needs to be set despite having a single option available.
> +		 * On Gen3 VSPD routing can't be configured, and DPAD routing
> +		 * is set in the group corresponding to the DPAD output (no Gen3
> +		 * SoC has multiple DPAD sources belonging to separate groups).
>  		 */
> -		unsigned int rgb_crtc = ffs(possible_crtcs) - 1;
> -		struct rcar_du_crtc *crtc = &rcdu->crtcs[rgb_crtc];
> -
> -		if (crtc->index / 2 == rgrp->index)
> -			defr8 |= DEFR8_DRGBS_DU(crtc->index);
> +		if (rgrp->index == rcdu->dpad0_source / 2)
> +			defr8 |= DEFR8_DRGBS_DU(rcdu->dpad0_source);
>  	}
>
>  	rcar_du_group_write(rgrp, DEFR8, defr8);
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
> index ed7fa3204892..bd01197700c5 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
> @@ -501,6 +501,7 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
>  	struct drm_device *dev = rcdu->ddev;
>  	struct drm_encoder *encoder;
>  	struct drm_fbdev_cma *fbdev;
> +	unsigned int dpad0_sources;
>  	unsigned int num_encoders;
>  	unsigned int num_groups;
>  	unsigned int swindex;
> @@ -613,6 +614,17 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
>  		encoder->possible_clones = (1 << num_encoders) - 1;
>  	}
>
> +	/*
> +	 * Initialize the default DPAD0 source to the index of the first DU
> +	 * channel that can be connected to DPAD0. The exact value doesn't
> +	 * matter as it should be overwritten by mode setting for the RGB
> +	 * output, but it is nonetheless required to ensure a valid initial
> +	 * hardware configuration on Gen3 where DU0 can't always be connected to
> +	 * DPAD0.
> +	 */
> +	dpad0_sources = rcdu->info->routes[RCAR_DU_OUTPUT_DPAD0].possible_crtcs;
> +	rcdu->dpad0_source = ffs(dpad0_sources) - 1;
> +
>  	drm_mode_config_reset(dev);
>
>  	drm_kms_helper_poll_init(dev);
> --
> Regards,
>
> Laurent Pinchart
>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [PATCH v2 08/16] drm: rcar-du: Enable configurable DPAD0 routing on Gen3
@ 2018-09-17 12:56     ` jacopo mondi
  0 siblings, 0 replies; 118+ messages in thread
From: jacopo mondi @ 2018-09-17 12:56 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham, dri-devel


[-- Attachment #1.1: Type: text/plain, Size: 4271 bytes --]

Hi Laurent,

On Fri, Sep 14, 2018 at 12:10:38PM +0300, Laurent Pinchart wrote:
> All Gen3 SoCs supported so far have a fixed association between DPAD0
> and DU channels, which led to hardcoding that association when writing
> the corresponding hardware register. The D3 and E3 will break that
> mechanism as DPAD0 can be dynamically connected to either DU0 or DU1.
>
> Make DPAD0 routing dynamic on Gen3. To ensure a valid hardware
> configuration when the DU starts without the RGB output enabled, DPAD0
> is associated at initialization time to the first DU channel that it can
> be connected to. This makes no change on Gen2 as all Gen2 SoCs can
> connected DPAD0 to DU0, which is the current implicit default value.
>
> As the DPAD0 source is always 0 when a single source is possible on
> Gen2, we can also simplify the Gen2 code in the same function to remove
> a conditional check.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>

Please add my:
Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>



> ---
>  drivers/gpu/drm/rcar-du/rcar_du_group.c | 17 ++++++-----------
>  drivers/gpu/drm/rcar-du/rcar_du_kms.c   | 12 ++++++++++++
>  2 files changed, 18 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c
> index 4c62841eff2f..f38703e7a10d 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
> @@ -56,8 +56,6 @@ static void rcar_du_group_setup_pins(struct rcar_du_group *rgrp)
>  static void rcar_du_group_setup_defr8(struct rcar_du_group *rgrp)
>  {
>  	struct rcar_du_device *rcdu = rgrp->dev;
> -	unsigned int possible_crtcs =
> -		rcdu->info->routes[RCAR_DU_OUTPUT_DPAD0].possible_crtcs;
>  	u32 defr8 = DEFR8_CODE;
>
>  	if (rcdu->info->gen < 3) {
> @@ -69,21 +67,18 @@ static void rcar_du_group_setup_defr8(struct rcar_du_group *rgrp)
>  		 * DU instances that support it.
>  		 */
>  		if (rgrp->index == 0) {
> -			if (possible_crtcs > 1)
> -				defr8 |= DEFR8_DRGBS_DU(rcdu->dpad0_source);
> +			defr8 |= DEFR8_DRGBS_DU(rcdu->dpad0_source);
>  			if (rgrp->dev->vspd1_sink == 2)
>  				defr8 |= DEFR8_VSCS;
>  		}
>  	} else {
>  		/*
> -		 * On Gen3 VSPD routing can't be configured, but DPAD routing
> -		 * needs to be set despite having a single option available.
> +		 * On Gen3 VSPD routing can't be configured, and DPAD routing
> +		 * is set in the group corresponding to the DPAD output (no Gen3
> +		 * SoC has multiple DPAD sources belonging to separate groups).
>  		 */
> -		unsigned int rgb_crtc = ffs(possible_crtcs) - 1;
> -		struct rcar_du_crtc *crtc = &rcdu->crtcs[rgb_crtc];
> -
> -		if (crtc->index / 2 == rgrp->index)
> -			defr8 |= DEFR8_DRGBS_DU(crtc->index);
> +		if (rgrp->index == rcdu->dpad0_source / 2)
> +			defr8 |= DEFR8_DRGBS_DU(rcdu->dpad0_source);
>  	}
>
>  	rcar_du_group_write(rgrp, DEFR8, defr8);
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
> index ed7fa3204892..bd01197700c5 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
> @@ -501,6 +501,7 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
>  	struct drm_device *dev = rcdu->ddev;
>  	struct drm_encoder *encoder;
>  	struct drm_fbdev_cma *fbdev;
> +	unsigned int dpad0_sources;
>  	unsigned int num_encoders;
>  	unsigned int num_groups;
>  	unsigned int swindex;
> @@ -613,6 +614,17 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
>  		encoder->possible_clones = (1 << num_encoders) - 1;
>  	}
>
> +	/*
> +	 * Initialize the default DPAD0 source to the index of the first DU
> +	 * channel that can be connected to DPAD0. The exact value doesn't
> +	 * matter as it should be overwritten by mode setting for the RGB
> +	 * output, but it is nonetheless required to ensure a valid initial
> +	 * hardware configuration on Gen3 where DU0 can't always be connected to
> +	 * DPAD0.
> +	 */
> +	dpad0_sources = rcdu->info->routes[RCAR_DU_OUTPUT_DPAD0].possible_crtcs;
> +	rcdu->dpad0_source = ffs(dpad0_sources) - 1;
> +
>  	drm_mode_config_reset(dev);
>
>  	drm_kms_helper_poll_init(dev);
> --
> Regards,
>
> Laurent Pinchart
>

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

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

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

* Re: [PATCH v2 13/16] arm64: dts: renesas: r8a77990: Add display output support
  2018-09-17  8:59             ` Laurent Pinchart
@ 2018-09-19  8:35               ` Simon Horman
  -1 siblings, 0 replies; 118+ messages in thread
From: Simon Horman @ 2018-09-19  8:35 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Laurent Pinchart, dri-devel, linux-renesas-soc, Ulrich Hecht,
	Kieran Bingham

On Mon, Sep 17, 2018 at 11:59:32AM +0300, Laurent Pinchart wrote:
> On Monday, 17 September 2018 11:54:04 EEST Laurent Pinchart wrote:
> > Hi Simon,
> > 
> > On Monday, 17 September 2018 11:47:15 EEST Laurent Pinchart wrote:
> > > On Monday, 17 September 2018 11:14:20 EEST Simon Horman wrote:
> > > > On Mon, Sep 17, 2018 at 09:50:55AM +0200, Simon Horman wrote:
> > > > > On Fri, Sep 14, 2018 at 12:10:43PM +0300, Laurent Pinchart wrote:
> > > > > > The R8A77990 (E3) platform has one RGB output and two LVDS outputs
> > > > > > connected to the DU. Add the DT nodes for the DU, LVDS encoders and
> > > > > > supporting VSP and FCP.
> > > > > > 
> > > > > > Signed-off-by: Laurent Pinchart
> > > > > > <laurent.pinchart+renesas@ideasonboard.com>
> > > > > > Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> > > > > > ---
> > > > > > 
> > > > > >  arch/arm64/boot/dts/renesas/r8a77990.dtsi | 167
> > > > > >  +++++++++++++++++++++++
> > > > > >  1 file changed, 167 insertions(+)
> > > > > > 
> > > > > > diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > > > > b/arch/arm64/boot/dts/renesas/r8a77990.dtsi index
> > > > > > abb14af76c0e..600074ca3ee5 100644
> > > > > > --- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > > > > +++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > > > > @@ -537,6 +537,173 @@
> > > > > > 
> > > > > >  			resets = <&cpg 408>;
> > > > > >  		
> > > > > >  		};
> > > > > 
> > > > > These nodes should be placed after the gic to preserve the sorting
> > > > > of nodes by bus address and then IP block.
> > > > > 
> > > > > > +		vspb0: vsp@fe960000 {
> > > > > > +			compatible = "renesas,vsp2";
> > > > > > +			reg = <0 0xfe960000 0 0x8000>;
> > > > > > +			interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
> > > > > > +			clocks = <&cpg CPG_MOD 626>;
> > > > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > > > +			resets = <&cpg 626>;
> > > > > > +			renesas,fcp = <&fcpvb0>;
> > > > > > +		};
> > > > > > +
> > > > > > +		fcpvb0: fcp@fe96f000 {
> > > > > > +			compatible = "renesas,fcpv";
> > > > > > +			reg = <0 0xfe96f000 0 0x200>;
> > > > > > +			clocks = <&cpg CPG_MOD 607>;
> > > > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > > > +			resets = <&cpg 607>;
> > > > > > +			iommus = <&ipmmu_vp0 5>;
> > > > > > +		};
> > > > > > +
> > > > > > +		vspi0: vsp@fe9a0000 {
> > > > > > +			compatible = "renesas,vsp2";
> > > > > > +			reg = <0 0xfe9a0000 0 0x8000>;
> > > > > > +			interrupts = <GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>;
> > > > > > +			clocks = <&cpg CPG_MOD 622>;
> > > > > 
> > > > > R-Car Series, 3rd Generation, v1.00, Table Table 8A.21 indicates
> > > > > that this clock should be <&cpg CPG_MOD 631>. The clock above is
> > > > > (according to my reading of the documentation) correctly
> > > > > used for vspd1 below.
> > > > > 
> > > > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > > > +			resets = <&cpg 631>;
> > > > > > +			renesas,fcp = <&fcpvi0>;
> > > > > > +		};
> > > > > > +
> > > > > > +		fcpvi0: fcp@fe9af000 {
> > > > > > +			compatible = "renesas,fcpv";
> > > > > > +			reg = <0 0xfe9af000 0 0x200>;
> > > > > > +			clocks = <&cpg CPG_MOD 611>;
> > > > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > > > +			resets = <&cpg 611>;
> > > > > > +			iommus = <&ipmmu_vp0 8>;
> > > > > > +		};
> > > > > > +
> > > > > > +		vspd0: vsp@fea20000 {
> > > > > > +			compatible = "renesas,vsp2";
> > > > > > +			reg = <0 0xfea20000 0 0x7000>;
> > > > > > +			interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
> > > > > > +			clocks = <&cpg CPG_MOD 623>;
> > > > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > > > +			resets = <&cpg 623>;
> > > > > > +			renesas,fcp = <&fcpvd0>;
> > > > > > +		};
> > > > > > +
> > > > > > +		fcpvd0: fcp@fea27000 {
> > > > > > +			compatible = "renesas,fcpv";
> > > > > > +			reg = <0 0xfea27000 0 0x200>;
> > > > > > +			clocks = <&cpg CPG_MOD 603>;
> > > > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > > > +			resets = <&cpg 603>;
> > > > > > +			iommus = <&ipmmu_vi0 8>;
> > > > > > +		};
> > > > > > +
> > > > > > +		vspd1: vsp@fea28000 {
> > > > > > +			compatible = "renesas,vsp2";
> > > > > > +			reg = <0 0xfea28000 0 0x7000>;
> > > > > > +			interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
> > > > > > +			clocks = <&cpg CPG_MOD 622>;
> > > > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > > > +			resets = <&cpg 622>;
> > > > > > +			renesas,fcp = <&fcpvd1>;
> > > > > > +		};
> > > > > > +
> > > > > > +		fcpvd1: fcp@fea2f000 {
> > > > > > +			compatible = "renesas,fcpv";
> > > > > > +			reg = <0 0xfea2f000 0 0x200>;
> > > > > > +			clocks = <&cpg CPG_MOD 602>;
> > > > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > > > +			resets = <&cpg 602>;
> > > > > > +			iommus = <&ipmmu_vi0 9>;
> > > > > > +		};
> > > > > > +
> > > > > > +		du: display@feb00000 {
> > > > > > +			compatible = "renesas,du-r8a77990";
> > > > > > +			reg = <0 0xfeb00000 0 0x80000>;
> > > > > > +			interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
> > > > > > +				     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
> > > > > > +			clocks = <&cpg CPG_MOD 724>,
> > > > > > +				 <&cpg CPG_MOD 723>;
> > > > > > +			clock-names = "du.0", "du.1";
> > > > > > +			vsps = <&vspd0 0 &vspd1 0>;
> > > > > > +			status = "disabled";
> > > > > > +
> > > > > > +			ports {
> > > > > > +				#address-cells = <1>;
> > > > > > +				#size-cells = <0>;
> > > > > > +
> > > > > > +				port@0 {
> > > > > > +					reg = <0>;
> > > > > > +					du_out_rgb: endpoint {
> > > > > > +					};
> > > > > > +				};
> > > > > > +
> > > > > > +				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,r8a77990-lvds";
> > > > > > +			reg = <0 0xfeb90000 0 0x20>;
> > > > > > +			clocks = <&cpg CPG_MOD 727>;
> > > > > > +			power-domains = <&sysc R8A77990_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,r8a77990-lvds";
> > > > > > +			reg = <0 0xfeb90100 0 0x20>;
> > > > > > +			clocks = <&cpg CPG_MOD 727>;
> > > > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > > > +			resets = <&cpg 726>;
> > > > 
> > > > Also, is the missmatch between the index for the clock and reset
> > > > intentional?
> > > 
> > > It is. According to the datasheet, the two LVDS encoders have different
> > > module stop bits, but share the same reset (lovely hardware design, it
> > > will be fun to support that in the driver :-S).
> > 
> > Sorry, I got it wrong. it's bit 725 that is shared between the two LVDS
> > encoders, to reset the two LVDS PLLs together. The encoders themselves still
> > have independent reset bits. I'll fix this.
> 
> And of course it's the clock you were commenting on, not the reset. *sigh*
> 
> According to the datasheets the two LVDS encoders share one MSTP. Whether 
> that's a mistake in the documentation or not I can't tell yet, as I have only 
> tested LVDS0.

Could we follow-up with the HW team?
I'm not opposed to taking the patch with this portion as-is
but it would be good to clarify this somehow.

> > > > > > +			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 {
> > > > > > +					};
> > > > > > +				};
> > > > > > +			};
> > > > > > +		};
> > > > > > +
> > > > > > 
> > > > > >  		prr: chipid@fff00044 {
> > > > > >  		
> > > > > >  			compatible = "renesas,prr";
> > > > > >  			reg = <0 0xfff00044 0 4>;
> 
> 
> -- 
> Regards,
> 
> Laurent Pinchart
> 
> 
> 

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

* Re: [PATCH v2 13/16] arm64: dts: renesas: r8a77990: Add display output support
@ 2018-09-19  8:35               ` Simon Horman
  0 siblings, 0 replies; 118+ messages in thread
From: Simon Horman @ 2018-09-19  8:35 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-renesas-soc, Ulrich Hecht, Laurent Pinchart,
	Kieran Bingham, dri-devel

On Mon, Sep 17, 2018 at 11:59:32AM +0300, Laurent Pinchart wrote:
> On Monday, 17 September 2018 11:54:04 EEST Laurent Pinchart wrote:
> > Hi Simon,
> > 
> > On Monday, 17 September 2018 11:47:15 EEST Laurent Pinchart wrote:
> > > On Monday, 17 September 2018 11:14:20 EEST Simon Horman wrote:
> > > > On Mon, Sep 17, 2018 at 09:50:55AM +0200, Simon Horman wrote:
> > > > > On Fri, Sep 14, 2018 at 12:10:43PM +0300, Laurent Pinchart wrote:
> > > > > > The R8A77990 (E3) platform has one RGB output and two LVDS outputs
> > > > > > connected to the DU. Add the DT nodes for the DU, LVDS encoders and
> > > > > > supporting VSP and FCP.
> > > > > > 
> > > > > > Signed-off-by: Laurent Pinchart
> > > > > > <laurent.pinchart+renesas@ideasonboard.com>
> > > > > > Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> > > > > > ---
> > > > > > 
> > > > > >  arch/arm64/boot/dts/renesas/r8a77990.dtsi | 167
> > > > > >  +++++++++++++++++++++++
> > > > > >  1 file changed, 167 insertions(+)
> > > > > > 
> > > > > > diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > > > > b/arch/arm64/boot/dts/renesas/r8a77990.dtsi index
> > > > > > abb14af76c0e..600074ca3ee5 100644
> > > > > > --- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > > > > +++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > > > > > @@ -537,6 +537,173 @@
> > > > > > 
> > > > > >  			resets = <&cpg 408>;
> > > > > >  		
> > > > > >  		};
> > > > > 
> > > > > These nodes should be placed after the gic to preserve the sorting
> > > > > of nodes by bus address and then IP block.
> > > > > 
> > > > > > +		vspb0: vsp@fe960000 {
> > > > > > +			compatible = "renesas,vsp2";
> > > > > > +			reg = <0 0xfe960000 0 0x8000>;
> > > > > > +			interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
> > > > > > +			clocks = <&cpg CPG_MOD 626>;
> > > > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > > > +			resets = <&cpg 626>;
> > > > > > +			renesas,fcp = <&fcpvb0>;
> > > > > > +		};
> > > > > > +
> > > > > > +		fcpvb0: fcp@fe96f000 {
> > > > > > +			compatible = "renesas,fcpv";
> > > > > > +			reg = <0 0xfe96f000 0 0x200>;
> > > > > > +			clocks = <&cpg CPG_MOD 607>;
> > > > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > > > +			resets = <&cpg 607>;
> > > > > > +			iommus = <&ipmmu_vp0 5>;
> > > > > > +		};
> > > > > > +
> > > > > > +		vspi0: vsp@fe9a0000 {
> > > > > > +			compatible = "renesas,vsp2";
> > > > > > +			reg = <0 0xfe9a0000 0 0x8000>;
> > > > > > +			interrupts = <GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>;
> > > > > > +			clocks = <&cpg CPG_MOD 622>;
> > > > > 
> > > > > R-Car Series, 3rd Generation, v1.00, Table Table 8A.21 indicates
> > > > > that this clock should be <&cpg CPG_MOD 631>. The clock above is
> > > > > (according to my reading of the documentation) correctly
> > > > > used for vspd1 below.
> > > > > 
> > > > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > > > +			resets = <&cpg 631>;
> > > > > > +			renesas,fcp = <&fcpvi0>;
> > > > > > +		};
> > > > > > +
> > > > > > +		fcpvi0: fcp@fe9af000 {
> > > > > > +			compatible = "renesas,fcpv";
> > > > > > +			reg = <0 0xfe9af000 0 0x200>;
> > > > > > +			clocks = <&cpg CPG_MOD 611>;
> > > > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > > > +			resets = <&cpg 611>;
> > > > > > +			iommus = <&ipmmu_vp0 8>;
> > > > > > +		};
> > > > > > +
> > > > > > +		vspd0: vsp@fea20000 {
> > > > > > +			compatible = "renesas,vsp2";
> > > > > > +			reg = <0 0xfea20000 0 0x7000>;
> > > > > > +			interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
> > > > > > +			clocks = <&cpg CPG_MOD 623>;
> > > > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > > > +			resets = <&cpg 623>;
> > > > > > +			renesas,fcp = <&fcpvd0>;
> > > > > > +		};
> > > > > > +
> > > > > > +		fcpvd0: fcp@fea27000 {
> > > > > > +			compatible = "renesas,fcpv";
> > > > > > +			reg = <0 0xfea27000 0 0x200>;
> > > > > > +			clocks = <&cpg CPG_MOD 603>;
> > > > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > > > +			resets = <&cpg 603>;
> > > > > > +			iommus = <&ipmmu_vi0 8>;
> > > > > > +		};
> > > > > > +
> > > > > > +		vspd1: vsp@fea28000 {
> > > > > > +			compatible = "renesas,vsp2";
> > > > > > +			reg = <0 0xfea28000 0 0x7000>;
> > > > > > +			interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
> > > > > > +			clocks = <&cpg CPG_MOD 622>;
> > > > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > > > +			resets = <&cpg 622>;
> > > > > > +			renesas,fcp = <&fcpvd1>;
> > > > > > +		};
> > > > > > +
> > > > > > +		fcpvd1: fcp@fea2f000 {
> > > > > > +			compatible = "renesas,fcpv";
> > > > > > +			reg = <0 0xfea2f000 0 0x200>;
> > > > > > +			clocks = <&cpg CPG_MOD 602>;
> > > > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > > > +			resets = <&cpg 602>;
> > > > > > +			iommus = <&ipmmu_vi0 9>;
> > > > > > +		};
> > > > > > +
> > > > > > +		du: display@feb00000 {
> > > > > > +			compatible = "renesas,du-r8a77990";
> > > > > > +			reg = <0 0xfeb00000 0 0x80000>;
> > > > > > +			interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
> > > > > > +				     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
> > > > > > +			clocks = <&cpg CPG_MOD 724>,
> > > > > > +				 <&cpg CPG_MOD 723>;
> > > > > > +			clock-names = "du.0", "du.1";
> > > > > > +			vsps = <&vspd0 0 &vspd1 0>;
> > > > > > +			status = "disabled";
> > > > > > +
> > > > > > +			ports {
> > > > > > +				#address-cells = <1>;
> > > > > > +				#size-cells = <0>;
> > > > > > +
> > > > > > +				port@0 {
> > > > > > +					reg = <0>;
> > > > > > +					du_out_rgb: endpoint {
> > > > > > +					};
> > > > > > +				};
> > > > > > +
> > > > > > +				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,r8a77990-lvds";
> > > > > > +			reg = <0 0xfeb90000 0 0x20>;
> > > > > > +			clocks = <&cpg CPG_MOD 727>;
> > > > > > +			power-domains = <&sysc R8A77990_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,r8a77990-lvds";
> > > > > > +			reg = <0 0xfeb90100 0 0x20>;
> > > > > > +			clocks = <&cpg CPG_MOD 727>;
> > > > > > +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > > > > > +			resets = <&cpg 726>;
> > > > 
> > > > Also, is the missmatch between the index for the clock and reset
> > > > intentional?
> > > 
> > > It is. According to the datasheet, the two LVDS encoders have different
> > > module stop bits, but share the same reset (lovely hardware design, it
> > > will be fun to support that in the driver :-S).
> > 
> > Sorry, I got it wrong. it's bit 725 that is shared between the two LVDS
> > encoders, to reset the two LVDS PLLs together. The encoders themselves still
> > have independent reset bits. I'll fix this.
> 
> And of course it's the clock you were commenting on, not the reset. *sigh*
> 
> According to the datasheets the two LVDS encoders share one MSTP. Whether 
> that's a mistake in the documentation or not I can't tell yet, as I have only 
> tested LVDS0.

Could we follow-up with the HW team?
I'm not opposed to taking the patch with this portion as-is
but it would be good to clarify this somehow.

> > > > > > +			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 {
> > > > > > +					};
> > > > > > +				};
> > > > > > +			};
> > > > > > +		};
> > > > > > +
> > > > > > 
> > > > > >  		prr: chipid@fff00044 {
> > > > > >  		
> > > > > >  			compatible = "renesas,prr";
> > > > > >  			reg = <0 0xfff00044 0 4>;
> 
> 
> -- 
> 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] 118+ messages in thread

* Re: [PATCH v2 13/16] arm64: dts: renesas: r8a77990: Add display output support
  2018-09-19  8:35               ` Simon Horman
@ 2018-09-19 13:11                 ` Laurent Pinchart
  -1 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-19 13:11 UTC (permalink / raw)
  To: Simon Horman
  Cc: Laurent Pinchart, dri-devel, linux-renesas-soc, Ulrich Hecht,
	Kieran Bingham

Hi Simon,

On Wednesday, 19 September 2018 11:35:07 EEST Simon Horman wrote:
> On Mon, Sep 17, 2018 at 11:59:32AM +0300, Laurent Pinchart wrote:
> > On Monday, 17 September 2018 11:54:04 EEST Laurent Pinchart wrote:
> >> On Monday, 17 September 2018 11:47:15 EEST Laurent Pinchart wrote:
> >>> On Monday, 17 September 2018 11:14:20 EEST Simon Horman wrote:
> >>>> On Mon, Sep 17, 2018 at 09:50:55AM +0200, Simon Horman wrote:
> >>>>> On Fri, Sep 14, 2018 at 12:10:43PM +0300, Laurent Pinchart wrote:
> >>>>>> The R8A77990 (E3) platform has one RGB output and two LVDS
> >>>>>> outputs connected to the DU. Add the DT nodes for the DU, LVDS
> >>>>>> encoders and supporting VSP and FCP.
> >>>>>> 
> >>>>>> Signed-off-by: Laurent Pinchart
> >>>>>> <laurent.pinchart+renesas@ideasonboard.com>
> >>>>>> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> >>>>>> ---
> >>>>>> 
> >>>>>>  arch/arm64/boot/dts/renesas/r8a77990.dtsi | 167 ++++++++++++++++++++
> >>>>>>  1 file changed, 167 insertions(+)
> >>>>>> 
> >>>>>> diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> >>>>>> b/arch/arm64/boot/dts/renesas/r8a77990.dtsi index
> >>>>>> abb14af76c0e..600074ca3ee5 100644
> >>>>>> --- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> >>>>>> +++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi

[snip]

> >>>>>> +		lvds0: lvds-encoder@feb90000 {
> >>>>>> +			compatible = "renesas,r8a77990-lvds";
> >>>>>> +			reg = <0 0xfeb90000 0 0x20>;
> >>>>>> +			clocks = <&cpg CPG_MOD 727>;
> >>>>>> +			power-domains = <&sysc R8A77990_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,r8a77990-lvds";
> >>>>>> +			reg = <0 0xfeb90100 0 0x20>;
> >>>>>> +			clocks = <&cpg CPG_MOD 727>;
> >>>>>> +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> >>>>>> +			resets = <&cpg 726>;
> >>>> 
> >>>> Also, is the missmatch between the index for the clock and reset
> >>>> intentional?
> >>> 
> >>> It is. According to the datasheet, the two LVDS encoders have
> >>> different module stop bits, but share the same reset (lovely hardware
> >>> design, it will be fun to support that in the driver :-S).
> >> 
> >> Sorry, I got it wrong. it's bit 725 that is shared between the two LVDS
> >> encoders, to reset the two LVDS PLLs together. The encoders themselves
> >> still have independent reset bits. I'll fix this.
> > 
> > And of course it's the clock you were commenting on, not the reset. *sigh*
> > 
> > According to the datasheets the two LVDS encoders share one MSTP. Whether
> > that's a mistake in the documentation or not I can't tell yet, as I have
> > only tested LVDS0.
> 
> Could we follow-up with the HW team?
> I'm not opposed to taking the patch with this portion as-is
> but it would be good to clarify this somehow.

I tried setting the clock to MSTP 726, and I then get vblank interrupt 
timeouts. Furthermore I've now tested the LVDS1 output with a display panel, 
and while I still can't get the backlight to work, the panel displays the 
correct image with MSTP 727. I thus conclude that the above is correct.

> >>>>>> +			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 {
> >>>>>> +					};
> >>>>>> +				};
> >>>>>> +			};
> >>>>>> +		};

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v2 13/16] arm64: dts: renesas: r8a77990: Add display output support
@ 2018-09-19 13:11                 ` Laurent Pinchart
  0 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-19 13:11 UTC (permalink / raw)
  To: Simon Horman
  Cc: linux-renesas-soc, Ulrich Hecht, Laurent Pinchart,
	Kieran Bingham, dri-devel

Hi Simon,

On Wednesday, 19 September 2018 11:35:07 EEST Simon Horman wrote:
> On Mon, Sep 17, 2018 at 11:59:32AM +0300, Laurent Pinchart wrote:
> > On Monday, 17 September 2018 11:54:04 EEST Laurent Pinchart wrote:
> >> On Monday, 17 September 2018 11:47:15 EEST Laurent Pinchart wrote:
> >>> On Monday, 17 September 2018 11:14:20 EEST Simon Horman wrote:
> >>>> On Mon, Sep 17, 2018 at 09:50:55AM +0200, Simon Horman wrote:
> >>>>> On Fri, Sep 14, 2018 at 12:10:43PM +0300, Laurent Pinchart wrote:
> >>>>>> The R8A77990 (E3) platform has one RGB output and two LVDS
> >>>>>> outputs connected to the DU. Add the DT nodes for the DU, LVDS
> >>>>>> encoders and supporting VSP and FCP.
> >>>>>> 
> >>>>>> Signed-off-by: Laurent Pinchart
> >>>>>> <laurent.pinchart+renesas@ideasonboard.com>
> >>>>>> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> >>>>>> ---
> >>>>>> 
> >>>>>>  arch/arm64/boot/dts/renesas/r8a77990.dtsi | 167 ++++++++++++++++++++
> >>>>>>  1 file changed, 167 insertions(+)
> >>>>>> 
> >>>>>> diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> >>>>>> b/arch/arm64/boot/dts/renesas/r8a77990.dtsi index
> >>>>>> abb14af76c0e..600074ca3ee5 100644
> >>>>>> --- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> >>>>>> +++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi

[snip]

> >>>>>> +		lvds0: lvds-encoder@feb90000 {
> >>>>>> +			compatible = "renesas,r8a77990-lvds";
> >>>>>> +			reg = <0 0xfeb90000 0 0x20>;
> >>>>>> +			clocks = <&cpg CPG_MOD 727>;
> >>>>>> +			power-domains = <&sysc R8A77990_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,r8a77990-lvds";
> >>>>>> +			reg = <0 0xfeb90100 0 0x20>;
> >>>>>> +			clocks = <&cpg CPG_MOD 727>;
> >>>>>> +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> >>>>>> +			resets = <&cpg 726>;
> >>>> 
> >>>> Also, is the missmatch between the index for the clock and reset
> >>>> intentional?
> >>> 
> >>> It is. According to the datasheet, the two LVDS encoders have
> >>> different module stop bits, but share the same reset (lovely hardware
> >>> design, it will be fun to support that in the driver :-S).
> >> 
> >> Sorry, I got it wrong. it's bit 725 that is shared between the two LVDS
> >> encoders, to reset the two LVDS PLLs together. The encoders themselves
> >> still have independent reset bits. I'll fix this.
> > 
> > And of course it's the clock you were commenting on, not the reset. *sigh*
> > 
> > According to the datasheets the two LVDS encoders share one MSTP. Whether
> > that's a mistake in the documentation or not I can't tell yet, as I have
> > only tested LVDS0.
> 
> Could we follow-up with the HW team?
> I'm not opposed to taking the patch with this portion as-is
> but it would be good to clarify this somehow.

I tried setting the clock to MSTP 726, and I then get vblank interrupt 
timeouts. Furthermore I've now tested the LVDS1 output with a display panel, 
and while I still can't get the backlight to work, the panel displays the 
correct image with MSTP 727. I thus conclude that the above is correct.

> >>>>>> +			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 {
> >>>>>> +					};
> >>>>>> +				};
> >>>>>> +			};
> >>>>>> +		};

-- 
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] 118+ messages in thread

* Re: [PATCH v2 13/16] arm64: dts: renesas: r8a77990: Add display output support
  2018-09-19 13:11                 ` Laurent Pinchart
@ 2018-09-21  7:16                   ` Simon Horman
  -1 siblings, 0 replies; 118+ messages in thread
From: Simon Horman @ 2018-09-21  7:16 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Laurent Pinchart, dri-devel, linux-renesas-soc, Ulrich Hecht,
	Kieran Bingham

On Wed, Sep 19, 2018 at 04:11:36PM +0300, Laurent Pinchart wrote:
> Hi Simon,
> 
> On Wednesday, 19 September 2018 11:35:07 EEST Simon Horman wrote:
> > On Mon, Sep 17, 2018 at 11:59:32AM +0300, Laurent Pinchart wrote:
> > > On Monday, 17 September 2018 11:54:04 EEST Laurent Pinchart wrote:
> > >> On Monday, 17 September 2018 11:47:15 EEST Laurent Pinchart wrote:
> > >>> On Monday, 17 September 2018 11:14:20 EEST Simon Horman wrote:
> > >>>> On Mon, Sep 17, 2018 at 09:50:55AM +0200, Simon Horman wrote:
> > >>>>> On Fri, Sep 14, 2018 at 12:10:43PM +0300, Laurent Pinchart wrote:
> > >>>>>> The R8A77990 (E3) platform has one RGB output and two LVDS
> > >>>>>> outputs connected to the DU. Add the DT nodes for the DU, LVDS
> > >>>>>> encoders and supporting VSP and FCP.
> > >>>>>> 
> > >>>>>> Signed-off-by: Laurent Pinchart
> > >>>>>> <laurent.pinchart+renesas@ideasonboard.com>
> > >>>>>> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> > >>>>>> ---
> > >>>>>> 
> > >>>>>>  arch/arm64/boot/dts/renesas/r8a77990.dtsi | 167 ++++++++++++++++++++
> > >>>>>>  1 file changed, 167 insertions(+)
> > >>>>>> 
> > >>>>>> diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > >>>>>> b/arch/arm64/boot/dts/renesas/r8a77990.dtsi index
> > >>>>>> abb14af76c0e..600074ca3ee5 100644
> > >>>>>> --- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > >>>>>> +++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> 
> [snip]
> 
> > >>>>>> +		lvds0: lvds-encoder@feb90000 {
> > >>>>>> +			compatible = "renesas,r8a77990-lvds";
> > >>>>>> +			reg = <0 0xfeb90000 0 0x20>;
> > >>>>>> +			clocks = <&cpg CPG_MOD 727>;
> > >>>>>> +			power-domains = <&sysc R8A77990_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,r8a77990-lvds";
> > >>>>>> +			reg = <0 0xfeb90100 0 0x20>;
> > >>>>>> +			clocks = <&cpg CPG_MOD 727>;
> > >>>>>> +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > >>>>>> +			resets = <&cpg 726>;
> > >>>> 
> > >>>> Also, is the missmatch between the index for the clock and reset
> > >>>> intentional?
> > >>> 
> > >>> It is. According to the datasheet, the two LVDS encoders have
> > >>> different module stop bits, but share the same reset (lovely hardware
> > >>> design, it will be fun to support that in the driver :-S).
> > >> 
> > >> Sorry, I got it wrong. it's bit 725 that is shared between the two LVDS
> > >> encoders, to reset the two LVDS PLLs together. The encoders themselves
> > >> still have independent reset bits. I'll fix this.
> > > 
> > > And of course it's the clock you were commenting on, not the reset. *sigh*
> > > 
> > > According to the datasheets the two LVDS encoders share one MSTP. Whether
> > > that's a mistake in the documentation or not I can't tell yet, as I have
> > > only tested LVDS0.
> > 
> > Could we follow-up with the HW team?
> > I'm not opposed to taking the patch with this portion as-is
> > but it would be good to clarify this somehow.
> 
> I tried setting the clock to MSTP 726, and I then get vblank interrupt 
> timeouts. Furthermore I've now tested the LVDS1 output with a display panel, 
> and while I still can't get the backlight to work, the panel displays the 
> correct image with MSTP 727. I thus conclude that the above is correct.

Thanks for the follow-up, that sounds reasonable to me.

Am I correct in thinking a v3 of this patchset is on its way regardless?

> 
> > >>>>>> +			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 {
> > >>>>>> +					};
> > >>>>>> +				};
> > >>>>>> +			};
> > >>>>>> +		};
> 
> -- 
> Regards,
> 
> Laurent Pinchart
> 
> 
> 

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

* Re: [PATCH v2 13/16] arm64: dts: renesas: r8a77990: Add display output support
@ 2018-09-21  7:16                   ` Simon Horman
  0 siblings, 0 replies; 118+ messages in thread
From: Simon Horman @ 2018-09-21  7:16 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-renesas-soc, Ulrich Hecht, Laurent Pinchart,
	Kieran Bingham, dri-devel

On Wed, Sep 19, 2018 at 04:11:36PM +0300, Laurent Pinchart wrote:
> Hi Simon,
> 
> On Wednesday, 19 September 2018 11:35:07 EEST Simon Horman wrote:
> > On Mon, Sep 17, 2018 at 11:59:32AM +0300, Laurent Pinchart wrote:
> > > On Monday, 17 September 2018 11:54:04 EEST Laurent Pinchart wrote:
> > >> On Monday, 17 September 2018 11:47:15 EEST Laurent Pinchart wrote:
> > >>> On Monday, 17 September 2018 11:14:20 EEST Simon Horman wrote:
> > >>>> On Mon, Sep 17, 2018 at 09:50:55AM +0200, Simon Horman wrote:
> > >>>>> On Fri, Sep 14, 2018 at 12:10:43PM +0300, Laurent Pinchart wrote:
> > >>>>>> The R8A77990 (E3) platform has one RGB output and two LVDS
> > >>>>>> outputs connected to the DU. Add the DT nodes for the DU, LVDS
> > >>>>>> encoders and supporting VSP and FCP.
> > >>>>>> 
> > >>>>>> Signed-off-by: Laurent Pinchart
> > >>>>>> <laurent.pinchart+renesas@ideasonboard.com>
> > >>>>>> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> > >>>>>> ---
> > >>>>>> 
> > >>>>>>  arch/arm64/boot/dts/renesas/r8a77990.dtsi | 167 ++++++++++++++++++++
> > >>>>>>  1 file changed, 167 insertions(+)
> > >>>>>> 
> > >>>>>> diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > >>>>>> b/arch/arm64/boot/dts/renesas/r8a77990.dtsi index
> > >>>>>> abb14af76c0e..600074ca3ee5 100644
> > >>>>>> --- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > >>>>>> +++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> 
> [snip]
> 
> > >>>>>> +		lvds0: lvds-encoder@feb90000 {
> > >>>>>> +			compatible = "renesas,r8a77990-lvds";
> > >>>>>> +			reg = <0 0xfeb90000 0 0x20>;
> > >>>>>> +			clocks = <&cpg CPG_MOD 727>;
> > >>>>>> +			power-domains = <&sysc R8A77990_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,r8a77990-lvds";
> > >>>>>> +			reg = <0 0xfeb90100 0 0x20>;
> > >>>>>> +			clocks = <&cpg CPG_MOD 727>;
> > >>>>>> +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> > >>>>>> +			resets = <&cpg 726>;
> > >>>> 
> > >>>> Also, is the missmatch between the index for the clock and reset
> > >>>> intentional?
> > >>> 
> > >>> It is. According to the datasheet, the two LVDS encoders have
> > >>> different module stop bits, but share the same reset (lovely hardware
> > >>> design, it will be fun to support that in the driver :-S).
> > >> 
> > >> Sorry, I got it wrong. it's bit 725 that is shared between the two LVDS
> > >> encoders, to reset the two LVDS PLLs together. The encoders themselves
> > >> still have independent reset bits. I'll fix this.
> > > 
> > > And of course it's the clock you were commenting on, not the reset. *sigh*
> > > 
> > > According to the datasheets the two LVDS encoders share one MSTP. Whether
> > > that's a mistake in the documentation or not I can't tell yet, as I have
> > > only tested LVDS0.
> > 
> > Could we follow-up with the HW team?
> > I'm not opposed to taking the patch with this portion as-is
> > but it would be good to clarify this somehow.
> 
> I tried setting the clock to MSTP 726, and I then get vblank interrupt 
> timeouts. Furthermore I've now tested the LVDS1 output with a display panel, 
> and while I still can't get the backlight to work, the panel displays the 
> correct image with MSTP 727. I thus conclude that the above is correct.

Thanks for the follow-up, that sounds reasonable to me.

Am I correct in thinking a v3 of this patchset is on its way regardless?

> 
> > >>>>>> +			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 {
> > >>>>>> +					};
> > >>>>>> +				};
> > >>>>>> +			};
> > >>>>>> +		};
> 
> -- 
> 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] 118+ messages in thread

* Re: [PATCH v2 13/16] arm64: dts: renesas: r8a77990: Add display output support
  2018-09-21  7:16                   ` Simon Horman
@ 2018-09-21  8:41                     ` Laurent Pinchart
  -1 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-21  8:41 UTC (permalink / raw)
  To: Simon Horman
  Cc: Laurent Pinchart, dri-devel, linux-renesas-soc, Ulrich Hecht,
	Kieran Bingham

Hi Simon,

On Friday, 21 September 2018 10:16:44 EEST Simon Horman wrote:
> On Wed, Sep 19, 2018 at 04:11:36PM +0300, Laurent Pinchart wrote:
> > On Wednesday, 19 September 2018 11:35:07 EEST Simon Horman wrote:
> >> On Mon, Sep 17, 2018 at 11:59:32AM +0300, Laurent Pinchart wrote:
> >>> On Monday, 17 September 2018 11:54:04 EEST Laurent Pinchart wrote:
> >>>> On Monday, 17 September 2018 11:47:15 EEST Laurent Pinchart wrote:
> >>>>> On Monday, 17 September 2018 11:14:20 EEST Simon Horman wrote:
> >>>>>> On Mon, Sep 17, 2018 at 09:50:55AM +0200, Simon Horman wrote:
> >>>>>>> On Fri, Sep 14, 2018 at 12:10:43PM +0300, Laurent Pinchart wrote:
> >>>>>>>> The R8A77990 (E3) platform has one RGB output and two LVDS
> >>>>>>>> outputs connected to the DU. Add the DT nodes for the DU, LVDS
> >>>>>>>> encoders and supporting VSP and FCP.
> >>>>>>>> 
> >>>>>>>> Signed-off-by: Laurent Pinchart
> >>>>>>>> <laurent.pinchart+renesas@ideasonboard.com>
> >>>>>>>> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> >>>>>>>> ---
> >>>>>>>> 
> >>>>>>>>  arch/arm64/boot/dts/renesas/r8a77990.dtsi | 167 +++++++++++++++++
> >>>>>>>>  1 file changed, 167 insertions(+)
> >>>>>>>> 
> >>>>>>>> diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> >>>>>>>> b/arch/arm64/boot/dts/renesas/r8a77990.dtsi index
> >>>>>>>> abb14af76c0e..600074ca3ee5 100644
> >>>>>>>> --- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> >>>>>>>> +++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > 
> > [snip]
> > 
> >>>>>>>> +		lvds0: lvds-encoder@feb90000 {
> >>>>>>>> +			compatible = "renesas,r8a77990-lvds";
> >>>>>>>> +			reg = <0 0xfeb90000 0 0x20>;
> >>>>>>>> +			clocks = <&cpg CPG_MOD 727>;
> >>>>>>>> +			power-domains = <&sysc R8A77990_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,r8a77990-lvds";
> >>>>>>>> +			reg = <0 0xfeb90100 0 0x20>;
> >>>>>>>> +			clocks = <&cpg CPG_MOD 727>;
> >>>>>>>> +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> >>>>>>>> +			resets = <&cpg 726>;
> >>>>>> 
> >>>>>> Also, is the missmatch between the index for the clock and reset
> >>>>>> intentional?
> >>>>> 
> >>>>> It is. According to the datasheet, the two LVDS encoders have
> >>>>> different module stop bits, but share the same reset (lovely
> >>>>> hardware design, it will be fun to support that in the driver :-S).
> >>>> 
> >>>> Sorry, I got it wrong. it's bit 725 that is shared between the two
> >>>> LVDS encoders, to reset the two LVDS PLLs together. The encoders
> >>>> themselves still have independent reset bits. I'll fix this.
> >>> 
> >>> And of course it's the clock you were commenting on, not the reset.
> >>> *sigh*
> >>> 
> >>> According to the datasheets the two LVDS encoders share one MSTP.
> >>> Whether that's a mistake in the documentation or not I can't tell yet,
> >>> as I have only tested LVDS0.
> >> 
> >> Could we follow-up with the HW team?
> >> I'm not opposed to taking the patch with this portion as-is
> >> but it would be good to clarify this somehow.
> > 
> > I tried setting the clock to MSTP 726, and I then get vblank interrupt
> > timeouts. Furthermore I've now tested the LVDS1 output with a display
> > panel, and while I still can't get the backlight to work, the panel
> > displays the correct image with MSTP 727. I thus conclude that the above
> > is correct.
> 
> Thanks for the follow-up, that sounds reasonable to me.
> 
> Am I correct in thinking a v3 of this patchset is on its way regardless?

Yes, you're correct.

> >>>>>>>> +			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 {
> >>>>>>>> +					};
> >>>>>>>> +				};
> >>>>>>>> +			};
> >>>>>>>> +		};

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v2 13/16] arm64: dts: renesas: r8a77990: Add display output support
@ 2018-09-21  8:41                     ` Laurent Pinchart
  0 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-21  8:41 UTC (permalink / raw)
  To: Simon Horman
  Cc: linux-renesas-soc, Ulrich Hecht, Laurent Pinchart,
	Kieran Bingham, dri-devel

Hi Simon,

On Friday, 21 September 2018 10:16:44 EEST Simon Horman wrote:
> On Wed, Sep 19, 2018 at 04:11:36PM +0300, Laurent Pinchart wrote:
> > On Wednesday, 19 September 2018 11:35:07 EEST Simon Horman wrote:
> >> On Mon, Sep 17, 2018 at 11:59:32AM +0300, Laurent Pinchart wrote:
> >>> On Monday, 17 September 2018 11:54:04 EEST Laurent Pinchart wrote:
> >>>> On Monday, 17 September 2018 11:47:15 EEST Laurent Pinchart wrote:
> >>>>> On Monday, 17 September 2018 11:14:20 EEST Simon Horman wrote:
> >>>>>> On Mon, Sep 17, 2018 at 09:50:55AM +0200, Simon Horman wrote:
> >>>>>>> On Fri, Sep 14, 2018 at 12:10:43PM +0300, Laurent Pinchart wrote:
> >>>>>>>> The R8A77990 (E3) platform has one RGB output and two LVDS
> >>>>>>>> outputs connected to the DU. Add the DT nodes for the DU, LVDS
> >>>>>>>> encoders and supporting VSP and FCP.
> >>>>>>>> 
> >>>>>>>> Signed-off-by: Laurent Pinchart
> >>>>>>>> <laurent.pinchart+renesas@ideasonboard.com>
> >>>>>>>> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> >>>>>>>> ---
> >>>>>>>> 
> >>>>>>>>  arch/arm64/boot/dts/renesas/r8a77990.dtsi | 167 +++++++++++++++++
> >>>>>>>>  1 file changed, 167 insertions(+)
> >>>>>>>> 
> >>>>>>>> diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> >>>>>>>> b/arch/arm64/boot/dts/renesas/r8a77990.dtsi index
> >>>>>>>> abb14af76c0e..600074ca3ee5 100644
> >>>>>>>> --- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> >>>>>>>> +++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> > 
> > [snip]
> > 
> >>>>>>>> +		lvds0: lvds-encoder@feb90000 {
> >>>>>>>> +			compatible = "renesas,r8a77990-lvds";
> >>>>>>>> +			reg = <0 0xfeb90000 0 0x20>;
> >>>>>>>> +			clocks = <&cpg CPG_MOD 727>;
> >>>>>>>> +			power-domains = <&sysc R8A77990_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,r8a77990-lvds";
> >>>>>>>> +			reg = <0 0xfeb90100 0 0x20>;
> >>>>>>>> +			clocks = <&cpg CPG_MOD 727>;
> >>>>>>>> +			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
> >>>>>>>> +			resets = <&cpg 726>;
> >>>>>> 
> >>>>>> Also, is the missmatch between the index for the clock and reset
> >>>>>> intentional?
> >>>>> 
> >>>>> It is. According to the datasheet, the two LVDS encoders have
> >>>>> different module stop bits, but share the same reset (lovely
> >>>>> hardware design, it will be fun to support that in the driver :-S).
> >>>> 
> >>>> Sorry, I got it wrong. it's bit 725 that is shared between the two
> >>>> LVDS encoders, to reset the two LVDS PLLs together. The encoders
> >>>> themselves still have independent reset bits. I'll fix this.
> >>> 
> >>> And of course it's the clock you were commenting on, not the reset.
> >>> *sigh*
> >>> 
> >>> According to the datasheets the two LVDS encoders share one MSTP.
> >>> Whether that's a mistake in the documentation or not I can't tell yet,
> >>> as I have only tested LVDS0.
> >> 
> >> Could we follow-up with the HW team?
> >> I'm not opposed to taking the patch with this portion as-is
> >> but it would be good to clarify this somehow.
> > 
> > I tried setting the clock to MSTP 726, and I then get vblank interrupt
> > timeouts. Furthermore I've now tested the LVDS1 output with a display
> > panel, and while I still can't get the backlight to work, the panel
> > displays the correct image with MSTP 727. I thus conclude that the above
> > is correct.
> 
> Thanks for the follow-up, that sounds reasonable to me.
> 
> Am I correct in thinking a v3 of this patchset is on its way regardless?

Yes, you're correct.

> >>>>>>>> +			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 {
> >>>>>>>> +					};
> >>>>>>>> +				};
> >>>>>>>> +			};
> >>>>>>>> +		};

-- 
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] 118+ messages in thread

* Re: [PATCH v2 09/16] drm: rcar-du: Cache DSYSR value to ensure known initial value
  2018-09-14  9:10   ` Laurent Pinchart
@ 2018-09-24 11:18     ` Kieran Bingham
  -1 siblings, 0 replies; 118+ messages in thread
From: Kieran Bingham @ 2018-09-24 11:18 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht

Hi Laurent,

On 14/09/18 10:10, Laurent Pinchart wrote:
> DSYSR is a DU channel register that also contains group fields. It is
> thus written to by both the group and CRTC code, using read-update-write
> sequences. As the register isn't initialized explicitly at startup time,
> this can lead to invalid or otherwise unexpected values being written to
> some of the fields if they have been modified by the firmware or just
> not reset properly.
> 
> To fix this we can write a fully known value to the DSYSR register when
> turning a channel's functional clock on. However, the mix of group and
> channel fields complicate this. A simpler solution is to cache the
> register and initialize the cached value to the desired hardware
> defaults.

Great, this looks good to me, and is less overhead than pulling in a
full reg-cache when we only need a single register handled.

> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>

Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>

> ---
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.c  | 16 ++++++++--------
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.h  |  5 +++++
>  drivers/gpu/drm/rcar-du/rcar_du_group.c |  7 ++++---
>  3 files changed, 17 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> index 2f8776c1ec8f..f827fccf6416 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> @@ -57,13 +57,12 @@ static void rcar_du_crtc_set(struct rcar_du_crtc *rcrtc, u32 reg, u32 set)
>  		      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)
> +void rcar_du_crtc_dsysr_clr_set(struct rcar_du_crtc *rcrtc, u32 clr, u32 set)
>  {
>  	struct rcar_du_device *rcdu = rcrtc->group->dev;
> -	u32 value = rcar_du_read(rcdu, rcrtc->mmio_offset + reg);
>  
> -	rcar_du_write(rcdu, rcrtc->mmio_offset + reg, (value & ~clr) | set);
> +	rcrtc->dsysr = (rcrtc->dsysr & ~clr) | set;
> +	rcar_du_write(rcdu, rcrtc->mmio_offset + DSYSR, rcrtc->dsysr);
>  }
>  
>  /* -----------------------------------------------------------------------------
> @@ -576,9 +575,9 @@ 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,
> -			     (interlaced ? DSYSR_SCM_INT_VIDEO : 0) |
> -			     DSYSR_TVM_MASTER);
> +	rcar_du_crtc_dsysr_clr_set(rcrtc, DSYSR_TVM_MASK | DSYSR_SCM_MASK,
> +				   (interlaced ? DSYSR_SCM_INT_VIDEO : 0) |
> +				   DSYSR_TVM_MASTER);
>  
>  	rcar_du_group_start_stop(rcrtc->group, true);
>  }
> @@ -645,7 +644,7 @@ 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_dsysr_clr_set(rcrtc, DSYSR_TVM_MASK, DSYSR_TVM_SWITCH);
>  
>  	rcar_du_group_start_stop(rcrtc->group, false);
>  }
> @@ -1121,6 +1120,7 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int swindex,
>  	rcrtc->group = rgrp;
>  	rcrtc->mmio_offset = mmio_offsets[hwindex];
>  	rcrtc->index = hwindex;
> +	rcrtc->dsysr = (rcrtc->index % 2 ? 0 : DSYSR_DRES) | DSYSR_TVM_TVSYNC;
>  
>  	if (rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE))
>  		primary = &rcrtc->vsp->planes[rcrtc->vsp_pipe].plane;
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> index 4990bbe9ba26..59ac6e7d22c9 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> @@ -30,6 +30,7 @@ struct rcar_du_vsp;
>   * @mmio_offset: offset of the CRTC registers in the DU MMIO block
>   * @index: CRTC software and hardware index
>   * @initialized: whether the CRTC has been initialized and clocks enabled
> + * @dsysr: cached value of the DSYSR register
>   * @vblank_enable: whether vblank events are enabled on this CRTC
>   * @event: event to post when the pending page flip completes
>   * @flip_wait: wait queue used to signal page flip completion
> @@ -50,6 +51,8 @@ struct rcar_du_crtc {
>  	unsigned int index;
>  	bool initialized;
>  
> +	u32 dsysr;
> +
>  	bool vblank_enable;
>  	struct drm_pending_vblank_event *event;
>  	wait_queue_head_t flip_wait;
> @@ -103,4 +106,6 @@ void rcar_du_crtc_route_output(struct drm_crtc *crtc,
>  			       enum rcar_du_output output);
>  void rcar_du_crtc_finish_page_flip(struct rcar_du_crtc *rcrtc);
>  
> +void rcar_du_crtc_dsysr_clr_set(struct rcar_du_crtc *rcrtc, u32 clr, u32 set);
> +
>  #endif /* __RCAR_DU_CRTC_H__ */
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c
> index f38703e7a10d..d85f0a1c1581 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
> @@ -202,9 +202,10 @@ 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)) |
> -		(start ? DSYSR_DEN : DSYSR_DRES));
> +	struct rcar_du_crtc *rcrtc = &rgrp->dev->crtcs[rgrp->index * 2];
> +
> +	rcar_du_crtc_dsysr_clr_set(rcrtc, DSYSR_DRES | DSYSR_DEN,
> +				   start ? DSYSR_DEN : DSYSR_DRES);
>  }
>  
>  void rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool start)
> 

-- 
Regards
--
Kieran

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

* Re: [PATCH v2 09/16] drm: rcar-du: Cache DSYSR value to ensure known initial value
@ 2018-09-24 11:18     ` Kieran Bingham
  0 siblings, 0 replies; 118+ messages in thread
From: Kieran Bingham @ 2018-09-24 11:18 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht

Hi Laurent,

On 14/09/18 10:10, Laurent Pinchart wrote:
> DSYSR is a DU channel register that also contains group fields. It is
> thus written to by both the group and CRTC code, using read-update-write
> sequences. As the register isn't initialized explicitly at startup time,
> this can lead to invalid or otherwise unexpected values being written to
> some of the fields if they have been modified by the firmware or just
> not reset properly.
> 
> To fix this we can write a fully known value to the DSYSR register when
> turning a channel's functional clock on. However, the mix of group and
> channel fields complicate this. A simpler solution is to cache the
> register and initialize the cached value to the desired hardware
> defaults.

Great, this looks good to me, and is less overhead than pulling in a
full reg-cache when we only need a single register handled.

> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>

Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>

> ---
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.c  | 16 ++++++++--------
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.h  |  5 +++++
>  drivers/gpu/drm/rcar-du/rcar_du_group.c |  7 ++++---
>  3 files changed, 17 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> index 2f8776c1ec8f..f827fccf6416 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> @@ -57,13 +57,12 @@ static void rcar_du_crtc_set(struct rcar_du_crtc *rcrtc, u32 reg, u32 set)
>  		      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)
> +void rcar_du_crtc_dsysr_clr_set(struct rcar_du_crtc *rcrtc, u32 clr, u32 set)
>  {
>  	struct rcar_du_device *rcdu = rcrtc->group->dev;
> -	u32 value = rcar_du_read(rcdu, rcrtc->mmio_offset + reg);
>  
> -	rcar_du_write(rcdu, rcrtc->mmio_offset + reg, (value & ~clr) | set);
> +	rcrtc->dsysr = (rcrtc->dsysr & ~clr) | set;
> +	rcar_du_write(rcdu, rcrtc->mmio_offset + DSYSR, rcrtc->dsysr);
>  }
>  
>  /* -----------------------------------------------------------------------------
> @@ -576,9 +575,9 @@ 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,
> -			     (interlaced ? DSYSR_SCM_INT_VIDEO : 0) |
> -			     DSYSR_TVM_MASTER);
> +	rcar_du_crtc_dsysr_clr_set(rcrtc, DSYSR_TVM_MASK | DSYSR_SCM_MASK,
> +				   (interlaced ? DSYSR_SCM_INT_VIDEO : 0) |
> +				   DSYSR_TVM_MASTER);
>  
>  	rcar_du_group_start_stop(rcrtc->group, true);
>  }
> @@ -645,7 +644,7 @@ 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_dsysr_clr_set(rcrtc, DSYSR_TVM_MASK, DSYSR_TVM_SWITCH);
>  
>  	rcar_du_group_start_stop(rcrtc->group, false);
>  }
> @@ -1121,6 +1120,7 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int swindex,
>  	rcrtc->group = rgrp;
>  	rcrtc->mmio_offset = mmio_offsets[hwindex];
>  	rcrtc->index = hwindex;
> +	rcrtc->dsysr = (rcrtc->index % 2 ? 0 : DSYSR_DRES) | DSYSR_TVM_TVSYNC;
>  
>  	if (rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE))
>  		primary = &rcrtc->vsp->planes[rcrtc->vsp_pipe].plane;
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> index 4990bbe9ba26..59ac6e7d22c9 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> @@ -30,6 +30,7 @@ struct rcar_du_vsp;
>   * @mmio_offset: offset of the CRTC registers in the DU MMIO block
>   * @index: CRTC software and hardware index
>   * @initialized: whether the CRTC has been initialized and clocks enabled
> + * @dsysr: cached value of the DSYSR register
>   * @vblank_enable: whether vblank events are enabled on this CRTC
>   * @event: event to post when the pending page flip completes
>   * @flip_wait: wait queue used to signal page flip completion
> @@ -50,6 +51,8 @@ struct rcar_du_crtc {
>  	unsigned int index;
>  	bool initialized;
>  
> +	u32 dsysr;
> +
>  	bool vblank_enable;
>  	struct drm_pending_vblank_event *event;
>  	wait_queue_head_t flip_wait;
> @@ -103,4 +106,6 @@ void rcar_du_crtc_route_output(struct drm_crtc *crtc,
>  			       enum rcar_du_output output);
>  void rcar_du_crtc_finish_page_flip(struct rcar_du_crtc *rcrtc);
>  
> +void rcar_du_crtc_dsysr_clr_set(struct rcar_du_crtc *rcrtc, u32 clr, u32 set);
> +
>  #endif /* __RCAR_DU_CRTC_H__ */
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c
> index f38703e7a10d..d85f0a1c1581 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
> @@ -202,9 +202,10 @@ 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)) |
> -		(start ? DSYSR_DEN : DSYSR_DRES));
> +	struct rcar_du_crtc *rcrtc = &rgrp->dev->crtcs[rgrp->index * 2];
> +
> +	rcar_du_crtc_dsysr_clr_set(rcrtc, DSYSR_DRES | DSYSR_DEN,
> +				   start ? DSYSR_DEN : DSYSR_DRES);
>  }
>  
>  void rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool start)
> 

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

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

* Re: [PATCH v2 10/16] drm: rcar-du: Don't use TV sync mode when not supported by the hardware
  2018-09-14  9:10   ` Laurent Pinchart
@ 2018-09-24 11:26     ` Kieran Bingham
  -1 siblings, 0 replies; 118+ messages in thread
From: Kieran Bingham @ 2018-09-24 11:26 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht

Hi Laurent,

On 14/09/18 10:10, Laurent Pinchart wrote:
> The official way to stop the display is to clear the display enable
> (DEN) bit in the DSYSR register, but that operates at a group level and
> affects the two channels in the group. To disable channels selectively,
> the driver uses TV sync mode that stops display operation on the channel
> and turns output signals into inputs.
> 
> While TV sync mode is available in all DU models currently supported,
> the D3 and E3 DUs don't support it. We will thus need to find an
> alternative way to turn channels off.
> 
> In the meantime, condition the switch to TV sync mode to the
> availability of the feature, to avoid writing an invalid value to the
> DSYSR register.

(Perhaps for leading into the next sentence)

When the feature is unavailable ...
> The display output will turn blank as all planes are
> disabled when stopping the CRTC.

Otherwise your sentence sounds like it will affect existing platforms.

> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>

But that's a minor and possibly not relevant nit so:

Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>

> ---
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.c |  7 ++++++-
>  drivers/gpu/drm/rcar-du/rcar_du_drv.c  | 33 ++++++++++++++++++++++-----------
>  drivers/gpu/drm/rcar-du/rcar_du_drv.h  |  1 +
>  3 files changed, 29 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 f827fccf6416..17741843cf51 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> @@ -643,8 +643,13 @@ 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.
> +	 *
> +	 * TODO: Find another way to stop the display for DUs that don't support
> +	 * TVM sync.
>  	 */
> -	rcar_du_crtc_dsysr_clr_set(rcrtc, DSYSR_TVM_MASK, DSYSR_TVM_SWITCH);
> +	if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_TVM_SYNC))
> +		rcar_du_crtc_dsysr_clr_set(rcrtc, DSYSR_TVM_MASK,
> +					   DSYSR_TVM_SWITCH);
>  
>  	rcar_du_group_start_stop(rcrtc->group, false);
>  }
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> index 0954ecd2f943..fa0d381c2d0f 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> @@ -36,7 +36,8 @@ static const struct rcar_du_device_info rzg1_du_r8a7743_info = {
>  	.gen = 2,
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(1) | BIT(0),
>  	.routes = {
>  		/*
> @@ -58,7 +59,8 @@ static const struct rcar_du_device_info rzg1_du_r8a7745_info = {
>  	.gen = 2,
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(1) | BIT(0),
>  	.routes = {
>  		/*
> @@ -77,7 +79,8 @@ static const struct rcar_du_device_info rzg1_du_r8a7745_info = {
>  
>  static const struct rcar_du_device_info rcar_du_r8a7779_info = {
>  	.gen = 2,
> -	.features = RCAR_DU_FEATURE_INTERLACED,
> +	.features = RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(1) | BIT(0),
>  	.routes = {
>  		/*
> @@ -99,7 +102,8 @@ static const struct rcar_du_device_info rcar_du_r8a7790_info = {
>  	.gen = 2,
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.quirks = RCAR_DU_QUIRK_ALIGN_128B,
>  	.channels_mask = BIT(2) | BIT(1) | BIT(0),
>  	.routes = {
> @@ -128,7 +132,8 @@ static const struct rcar_du_device_info rcar_du_r8a7791_info = {
>  	.gen = 2,
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(1) | BIT(0),
>  	.routes = {
>  		/*
> @@ -151,7 +156,8 @@ static const struct rcar_du_device_info rcar_du_r8a7792_info = {
>  	.gen = 2,
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(1) | BIT(0),
>  	.routes = {
>  		/* R8A7792 has two RGB outputs. */
> @@ -170,7 +176,8 @@ static const struct rcar_du_device_info rcar_du_r8a7794_info = {
>  	.gen = 2,
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(1) | BIT(0),
>  	.routes = {
>  		/*
> @@ -193,7 +200,8 @@ static const struct rcar_du_device_info rcar_du_r8a7795_info = {
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
>  		  | RCAR_DU_FEATURE_VSP1_SOURCE
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(3) | BIT(2) | BIT(1) | BIT(0),
>  	.routes = {
>  		/*
> @@ -226,7 +234,8 @@ static const struct rcar_du_device_info rcar_du_r8a7796_info = {
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
>  		  | RCAR_DU_FEATURE_VSP1_SOURCE
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(2) | BIT(1) | BIT(0),
>  	.routes = {
>  		/*
> @@ -255,7 +264,8 @@ static const struct rcar_du_device_info rcar_du_r8a77965_info = {
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
>  		  | RCAR_DU_FEATURE_VSP1_SOURCE
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(3) | BIT(1) | BIT(0),
>  	.routes = {
>  		/*
> @@ -284,7 +294,8 @@ static const struct rcar_du_device_info rcar_du_r8a77970_info = {
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
>  		  | RCAR_DU_FEATURE_VSP1_SOURCE
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(0),
>  	.routes = {
>  		/* R8A77970 has one RGB output and one LVDS output. */
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> index ebba9aefba6a..143c037e2c0f 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> @@ -27,6 +27,7 @@ struct rcar_du_device;
>  #define RCAR_DU_FEATURE_EXT_CTRL_REGS	BIT(1)	/* Has extended control registers */
>  #define RCAR_DU_FEATURE_VSP1_SOURCE	BIT(2)	/* Has inputs from VSP1 */
>  #define RCAR_DU_FEATURE_INTERLACED	BIT(3)	/* HW supports interlaced */
> +#define RCAR_DU_FEATURE_TVM_SYNC	BIT(4)	/* Has TV switch/sync modes */
>  
>  #define RCAR_DU_QUIRK_ALIGN_128B	BIT(0)	/* Align pitches to 128 bytes */
>  
> 

-- 
Regards
--
Kieran

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

* Re: [PATCH v2 10/16] drm: rcar-du: Don't use TV sync mode when not supported by the hardware
@ 2018-09-24 11:26     ` Kieran Bingham
  0 siblings, 0 replies; 118+ messages in thread
From: Kieran Bingham @ 2018-09-24 11:26 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht

Hi Laurent,

On 14/09/18 10:10, Laurent Pinchart wrote:
> The official way to stop the display is to clear the display enable
> (DEN) bit in the DSYSR register, but that operates at a group level and
> affects the two channels in the group. To disable channels selectively,
> the driver uses TV sync mode that stops display operation on the channel
> and turns output signals into inputs.
> 
> While TV sync mode is available in all DU models currently supported,
> the D3 and E3 DUs don't support it. We will thus need to find an
> alternative way to turn channels off.
> 
> In the meantime, condition the switch to TV sync mode to the
> availability of the feature, to avoid writing an invalid value to the
> DSYSR register.

(Perhaps for leading into the next sentence)

When the feature is unavailable ...
> The display output will turn blank as all planes are
> disabled when stopping the CRTC.

Otherwise your sentence sounds like it will affect existing platforms.

> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>

But that's a minor and possibly not relevant nit so:

Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>

> ---
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.c |  7 ++++++-
>  drivers/gpu/drm/rcar-du/rcar_du_drv.c  | 33 ++++++++++++++++++++++-----------
>  drivers/gpu/drm/rcar-du/rcar_du_drv.h  |  1 +
>  3 files changed, 29 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 f827fccf6416..17741843cf51 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> @@ -643,8 +643,13 @@ 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.
> +	 *
> +	 * TODO: Find another way to stop the display for DUs that don't support
> +	 * TVM sync.
>  	 */
> -	rcar_du_crtc_dsysr_clr_set(rcrtc, DSYSR_TVM_MASK, DSYSR_TVM_SWITCH);
> +	if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_TVM_SYNC))
> +		rcar_du_crtc_dsysr_clr_set(rcrtc, DSYSR_TVM_MASK,
> +					   DSYSR_TVM_SWITCH);
>  
>  	rcar_du_group_start_stop(rcrtc->group, false);
>  }
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> index 0954ecd2f943..fa0d381c2d0f 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> @@ -36,7 +36,8 @@ static const struct rcar_du_device_info rzg1_du_r8a7743_info = {
>  	.gen = 2,
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(1) | BIT(0),
>  	.routes = {
>  		/*
> @@ -58,7 +59,8 @@ static const struct rcar_du_device_info rzg1_du_r8a7745_info = {
>  	.gen = 2,
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(1) | BIT(0),
>  	.routes = {
>  		/*
> @@ -77,7 +79,8 @@ static const struct rcar_du_device_info rzg1_du_r8a7745_info = {
>  
>  static const struct rcar_du_device_info rcar_du_r8a7779_info = {
>  	.gen = 2,
> -	.features = RCAR_DU_FEATURE_INTERLACED,
> +	.features = RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(1) | BIT(0),
>  	.routes = {
>  		/*
> @@ -99,7 +102,8 @@ static const struct rcar_du_device_info rcar_du_r8a7790_info = {
>  	.gen = 2,
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.quirks = RCAR_DU_QUIRK_ALIGN_128B,
>  	.channels_mask = BIT(2) | BIT(1) | BIT(0),
>  	.routes = {
> @@ -128,7 +132,8 @@ static const struct rcar_du_device_info rcar_du_r8a7791_info = {
>  	.gen = 2,
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(1) | BIT(0),
>  	.routes = {
>  		/*
> @@ -151,7 +156,8 @@ static const struct rcar_du_device_info rcar_du_r8a7792_info = {
>  	.gen = 2,
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(1) | BIT(0),
>  	.routes = {
>  		/* R8A7792 has two RGB outputs. */
> @@ -170,7 +176,8 @@ static const struct rcar_du_device_info rcar_du_r8a7794_info = {
>  	.gen = 2,
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(1) | BIT(0),
>  	.routes = {
>  		/*
> @@ -193,7 +200,8 @@ static const struct rcar_du_device_info rcar_du_r8a7795_info = {
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
>  		  | RCAR_DU_FEATURE_VSP1_SOURCE
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(3) | BIT(2) | BIT(1) | BIT(0),
>  	.routes = {
>  		/*
> @@ -226,7 +234,8 @@ static const struct rcar_du_device_info rcar_du_r8a7796_info = {
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
>  		  | RCAR_DU_FEATURE_VSP1_SOURCE
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(2) | BIT(1) | BIT(0),
>  	.routes = {
>  		/*
> @@ -255,7 +264,8 @@ static const struct rcar_du_device_info rcar_du_r8a77965_info = {
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
>  		  | RCAR_DU_FEATURE_VSP1_SOURCE
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(3) | BIT(1) | BIT(0),
>  	.routes = {
>  		/*
> @@ -284,7 +294,8 @@ static const struct rcar_du_device_info rcar_du_r8a77970_info = {
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
>  		  | RCAR_DU_FEATURE_VSP1_SOURCE
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(0),
>  	.routes = {
>  		/* R8A77970 has one RGB output and one LVDS output. */
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> index ebba9aefba6a..143c037e2c0f 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> @@ -27,6 +27,7 @@ struct rcar_du_device;
>  #define RCAR_DU_FEATURE_EXT_CTRL_REGS	BIT(1)	/* Has extended control registers */
>  #define RCAR_DU_FEATURE_VSP1_SOURCE	BIT(2)	/* Has inputs from VSP1 */
>  #define RCAR_DU_FEATURE_INTERLACED	BIT(3)	/* HW supports interlaced */
> +#define RCAR_DU_FEATURE_TVM_SYNC	BIT(4)	/* Has TV switch/sync modes */
>  
>  #define RCAR_DU_QUIRK_ALIGN_128B	BIT(0)	/* Align pitches to 128 bytes */
>  
> 

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

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

* Re: [PATCH v2 02/16] dt-bindings: display: renesas: lvds: Document r8a77990 bindings
  2018-09-14  9:10   ` Laurent Pinchart
@ 2018-09-24 11:36     ` Kieran Bingham
  -1 siblings, 0 replies; 118+ messages in thread
From: Kieran Bingham @ 2018-09-24 11:36 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht

Hi Laurent,

On 14/09/18 10:10, Laurent Pinchart wrote:
> The E3 (r8a77990) supports two LVDS channels. Extend the binding to
> support them.

This commit message sounds rather like we are modifying the bindings,
rather than just adding a compatible string. I went looking for extra
changes - but I see we only need a compatible addition.

> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>

Still, the change looks accurate to me - and at the moment I can't think
of a better description so:

Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>


> ---
>  Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
> index 5a4e379bb414..13af7e2ac7e8 100644
> --- a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
> +++ b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
> @@ -15,6 +15,7 @@ Required properties:
>    - "renesas,r8a7796-lvds" for R8A7796 (R-Car M3-W) compatible LVDS encoders
>    - "renesas,r8a77970-lvds" for R8A77970 (R-Car V3M) compatible LVDS encoders
>    - "renesas,r8a77980-lvds" for R8A77980 (R-Car V3H) compatible LVDS encoders
> +  - "renesas,r8a77990-lvds" for R8A77990 (R-Car E3) compatible LVDS encoders
>    - "renesas,r8a77995-lvds" for R8A77995 (R-Car D3) compatible LVDS encoders
>  
>  - reg: Base address and length for the memory-mapped registers
> 

-- 
Regards
--
Kieran

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

* Re: [PATCH v2 02/16] dt-bindings: display: renesas: lvds: Document r8a77990 bindings
@ 2018-09-24 11:36     ` Kieran Bingham
  0 siblings, 0 replies; 118+ messages in thread
From: Kieran Bingham @ 2018-09-24 11:36 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht

Hi Laurent,

On 14/09/18 10:10, Laurent Pinchart wrote:
> The E3 (r8a77990) supports two LVDS channels. Extend the binding to
> support them.

This commit message sounds rather like we are modifying the bindings,
rather than just adding a compatible string. I went looking for extra
changes - but I see we only need a compatible addition.

> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>

Still, the change looks accurate to me - and at the moment I can't think
of a better description so:

Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>


> ---
>  Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
> index 5a4e379bb414..13af7e2ac7e8 100644
> --- a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
> +++ b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
> @@ -15,6 +15,7 @@ Required properties:
>    - "renesas,r8a7796-lvds" for R8A7796 (R-Car M3-W) compatible LVDS encoders
>    - "renesas,r8a77970-lvds" for R8A77970 (R-Car V3M) compatible LVDS encoders
>    - "renesas,r8a77980-lvds" for R8A77980 (R-Car V3H) compatible LVDS encoders
> +  - "renesas,r8a77990-lvds" for R8A77990 (R-Car E3) compatible LVDS encoders
>    - "renesas,r8a77995-lvds" for R8A77995 (R-Car D3) compatible LVDS encoders
>  
>  - reg: Base address and length for the memory-mapped registers
> 

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

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

* Re: [PATCH v2 11/16] drm: rcar-du: Add r8a77990 and r8a77995 device support
  2018-09-14  9:10   ` Laurent Pinchart
@ 2018-09-24 11:41     ` Kieran Bingham
  -1 siblings, 0 replies; 118+ messages in thread
From: Kieran Bingham @ 2018-09-24 11:41 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht

Hi Laurent, Uli,

On 14/09/18 10:10, Laurent Pinchart wrote:
> From: Ulrich Hecht <uli+renesas@fpond.eu>
> 
> Add support for the R-Car D3 (R8A77995) and E3 (R8A77990) SoCs to the
> R-Car DU driver. The two SoCs instantiate compatible DUs, so a single
> information structure is enough.
> 
> Signed-off-by: Ulrich Hecht <uli+renesas@fpond.eu>
> [Add support for R8A77990]
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>

Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>

> ---
>  drivers/gpu/drm/rcar-du/rcar_du_drv.c | 30 ++++++++++++++++++++++++++++++
>  1 file changed, 30 insertions(+)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> index fa0d381c2d0f..084f58df4a8c 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> @@ -311,6 +311,34 @@ static const struct rcar_du_device_info rcar_du_r8a77970_info = {
>  	.num_lvds = 1,
>  };
>  
> +static const struct rcar_du_device_info rcar_du_r8a7799x_info = {
> +	.gen = 3,
> +	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
> +		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
> +		  | RCAR_DU_FEATURE_VSP1_SOURCE,
> +	.channels_mask = BIT(1) | BIT(0),
> +	.routes = {
> +		/*
> +		 * R8A77990 and R8A77995 have one RGB output and two LVDS
> +		 * outputs.
> +		 */
> +		[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,
> +	.lvds_clk_mask =  BIT(1) | BIT(0),
> +};
> +
>  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 },
> @@ -324,6 +352,8 @@ 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-r8a77990", .data = &rcar_du_r8a7799x_info },
> +	{ .compatible = "renesas,du-r8a77995", .data = &rcar_du_r8a7799x_info },
>  	{ }
>  };
>  
> 

-- 
Regards
--
Kieran

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

* Re: [PATCH v2 11/16] drm: rcar-du: Add r8a77990 and r8a77995 device support
@ 2018-09-24 11:41     ` Kieran Bingham
  0 siblings, 0 replies; 118+ messages in thread
From: Kieran Bingham @ 2018-09-24 11:41 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht

Hi Laurent, Uli,

On 14/09/18 10:10, Laurent Pinchart wrote:
> From: Ulrich Hecht <uli+renesas@fpond.eu>
> 
> Add support for the R-Car D3 (R8A77995) and E3 (R8A77990) SoCs to the
> R-Car DU driver. The two SoCs instantiate compatible DUs, so a single
> information structure is enough.
> 
> Signed-off-by: Ulrich Hecht <uli+renesas@fpond.eu>
> [Add support for R8A77990]
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>

Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>

> ---
>  drivers/gpu/drm/rcar-du/rcar_du_drv.c | 30 ++++++++++++++++++++++++++++++
>  1 file changed, 30 insertions(+)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> index fa0d381c2d0f..084f58df4a8c 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> @@ -311,6 +311,34 @@ static const struct rcar_du_device_info rcar_du_r8a77970_info = {
>  	.num_lvds = 1,
>  };
>  
> +static const struct rcar_du_device_info rcar_du_r8a7799x_info = {
> +	.gen = 3,
> +	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
> +		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
> +		  | RCAR_DU_FEATURE_VSP1_SOURCE,
> +	.channels_mask = BIT(1) | BIT(0),
> +	.routes = {
> +		/*
> +		 * R8A77990 and R8A77995 have one RGB output and two LVDS
> +		 * outputs.
> +		 */
> +		[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,
> +	.lvds_clk_mask =  BIT(1) | BIT(0),
> +};
> +
>  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 },
> @@ -324,6 +352,8 @@ 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-r8a77990", .data = &rcar_du_r8a7799x_info },
> +	{ .compatible = "renesas,du-r8a77995", .data = &rcar_du_r8a7799x_info },
>  	{ }
>  };
>  
> 

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

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

* Re: [PATCH v2 03/16] dt-bindings: display: renesas: lvds: Add EXTAL and DU_DOTCLKIN clocks
  2018-09-14  9:10   ` Laurent Pinchart
@ 2018-09-24 19:04     ` Kieran Bingham
  -1 siblings, 0 replies; 118+ messages in thread
From: Kieran Bingham @ 2018-09-24 19:04 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht

Hi Laurent,

Thank you for the patch,

On 14/09/18 10:10, Laurent Pinchart wrote:
> On the D3 and E3 SoCs, the LVDS encoder can derive its internal pixel
> clock from an externally supplied clock, either through the EXTAL pin or
> through one of the DU_DOTCLKINx pins. Add corresponding clocks to the DT
> bindings.
> 
> To retain backward compatibility with DT that don't specify the
> clock-names property, the functional clock must always be specified
> first, and the clock-names property is optional when only the functional
> clock is specified.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> ---
> Changes since v1:
> 
> - Clarified wording
> ---
>  .../devicetree/bindings/display/bridge/renesas,lvds.txt      | 12 +++++++++++-
>  1 file changed, 11 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
> index 13af7e2ac7e8..3aeb0ec06fd0 100644
> --- a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
> +++ b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
> @@ -19,7 +19,17 @@ Required properties:
>    - "renesas,r8a77995-lvds" for R8A77995 (R-Car D3) compatible LVDS encoders
>  
>  - reg: Base address and length for the memory-mapped registers
> -- clocks: A phandle + clock-specifier pair for the functional clock
> +- clocks: A list of phandles + clock-specifier pairs, one for each entry in
> +  the clock-names property.
> +- clock-names: Name of the clocks. This property is model-dependent.
> +  - The functional clock, which mandatory for all models, shall be listed
> +    first, and shall be named "fck".
> +  - On R8A77990 and R8A77995, the LVDS encoder can use the EXTAL or
> +    DU_DOTCLKINx clocks. Those clocks are optional. When supplied they must be
> +    named "extal" and "dclkin.x" respectively, with "x" being the DU_DOTCLKIN
> +    numerical index.
> +  - When the clocks property only contains the functional clock, the
> +    clock-names property may be omitted.

This all reads well to me.

Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>

>  - resets: A phandle + reset specifier for the module reset
>  
>  Required nodes:
> 

-- 
Regards
--
Kieran

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

* Re: [PATCH v2 03/16] dt-bindings: display: renesas: lvds: Add EXTAL and DU_DOTCLKIN clocks
@ 2018-09-24 19:04     ` Kieran Bingham
  0 siblings, 0 replies; 118+ messages in thread
From: Kieran Bingham @ 2018-09-24 19:04 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel; +Cc: linux-renesas-soc, Ulrich Hecht

Hi Laurent,

Thank you for the patch,

On 14/09/18 10:10, Laurent Pinchart wrote:
> On the D3 and E3 SoCs, the LVDS encoder can derive its internal pixel
> clock from an externally supplied clock, either through the EXTAL pin or
> through one of the DU_DOTCLKINx pins. Add corresponding clocks to the DT
> bindings.
> 
> To retain backward compatibility with DT that don't specify the
> clock-names property, the functional clock must always be specified
> first, and the clock-names property is optional when only the functional
> clock is specified.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> ---
> Changes since v1:
> 
> - Clarified wording
> ---
>  .../devicetree/bindings/display/bridge/renesas,lvds.txt      | 12 +++++++++++-
>  1 file changed, 11 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
> index 13af7e2ac7e8..3aeb0ec06fd0 100644
> --- a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
> +++ b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
> @@ -19,7 +19,17 @@ Required properties:
>    - "renesas,r8a77995-lvds" for R8A77995 (R-Car D3) compatible LVDS encoders
>  
>  - reg: Base address and length for the memory-mapped registers
> -- clocks: A phandle + clock-specifier pair for the functional clock
> +- clocks: A list of phandles + clock-specifier pairs, one for each entry in
> +  the clock-names property.
> +- clock-names: Name of the clocks. This property is model-dependent.
> +  - The functional clock, which mandatory for all models, shall be listed
> +    first, and shall be named "fck".
> +  - On R8A77990 and R8A77995, the LVDS encoder can use the EXTAL or
> +    DU_DOTCLKINx clocks. Those clocks are optional. When supplied they must be
> +    named "extal" and "dclkin.x" respectively, with "x" being the DU_DOTCLKIN
> +    numerical index.
> +  - When the clocks property only contains the functional clock, the
> +    clock-names property may be omitted.

This all reads well to me.

Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>

>  - resets: A phandle + reset specifier for the module reset
>  
>  Required nodes:
> 

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

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

* Re: [PATCH v2 06/16] drm: rcar-du: Perform the initial CRTC setup from rcar_du_crtc_get()
  2018-09-14  9:10   ` Laurent Pinchart
@ 2018-09-26 15:55     ` Ulrich Hecht
  -1 siblings, 0 replies; 118+ messages in thread
From: Ulrich Hecht @ 2018-09-26 15:55 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham

Thank you for your patch.

> On September 14, 2018 at 11:10 AM Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> wrote:
> 
> 
> The rcar_du_crtc_get() function is always immediately followed by a call
> to rcar_du_crtc_setup(). Call the later from the former to simplify the
> code, and add a comment to explain how the get and put calls are
> balanced.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> ---
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 107 +++++++++++++++++----------------
>  1 file changed, 56 insertions(+), 51 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> index 6288b9ad9e24..c89751c26f9c 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> @@ -66,39 +66,6 @@ static void rcar_du_crtc_clr_set(struct rcar_du_crtc *rcrtc, u32 reg,
>  	rcar_du_write(rcdu, rcrtc->mmio_offset + reg, (value & ~clr) | set);
>  }
>  
> -static int rcar_du_crtc_get(struct rcar_du_crtc *rcrtc)
> -{
> -	int ret;
> -
> -	ret = clk_prepare_enable(rcrtc->clock);
> -	if (ret < 0)
> -		return ret;
> -
> -	ret = clk_prepare_enable(rcrtc->extclock);
> -	if (ret < 0)
> -		goto error_clock;
> -
> -	ret = rcar_du_group_get(rcrtc->group);
> -	if (ret < 0)
> -		goto error_group;
> -
> -	return 0;
> -
> -error_group:
> -	clk_disable_unprepare(rcrtc->extclock);
> -error_clock:
> -	clk_disable_unprepare(rcrtc->clock);
> -	return ret;
> -}
> -
> -static void rcar_du_crtc_put(struct rcar_du_crtc *rcrtc)
> -{
> -	rcar_du_group_put(rcrtc->group);
> -
> -	clk_disable_unprepare(rcrtc->extclock);
> -	clk_disable_unprepare(rcrtc->clock);
> -}
> -
>  /* -----------------------------------------------------------------------------
>   * Hardware Setup
>   */
> @@ -546,6 +513,51 @@ static void rcar_du_crtc_setup(struct rcar_du_crtc *rcrtc)
>  	drm_crtc_vblank_on(&rcrtc->crtc);
>  }
>  
> +static int rcar_du_crtc_get(struct rcar_du_crtc *rcrtc)
> +{
> +	int ret;
> +
> +	/*
> +	 * Guard against double-get, as the function is called from both the
> +	 * .atomic_enable() and .atomic_begin() handlers.
> +	 */
> +	if (rcrtc->initialized)
> +		return 0;
> +
> +	ret = clk_prepare_enable(rcrtc->clock);
> +	if (ret < 0)
> +		return ret;
> +
> +	ret = clk_prepare_enable(rcrtc->extclock);
> +	if (ret < 0)
> +		goto error_clock;
> +
> +	ret = rcar_du_group_get(rcrtc->group);
> +	if (ret < 0)
> +		goto error_group;
> +
> +	rcar_du_crtc_setup(rcrtc);
> +	rcrtc->initialized = true;
> +
> +	return 0;
> +
> +error_group:
> +	clk_disable_unprepare(rcrtc->extclock);
> +error_clock:
> +	clk_disable_unprepare(rcrtc->clock);
> +	return ret;
> +}
> +
> +static void rcar_du_crtc_put(struct rcar_du_crtc *rcrtc)
> +{
> +	rcar_du_group_put(rcrtc->group);
> +
> +	clk_disable_unprepare(rcrtc->extclock);
> +	clk_disable_unprepare(rcrtc->clock);
> +
> +	rcrtc->initialized = false;
> +}
> +
>  static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc)
>  {
>  	bool interlaced;
> @@ -639,16 +651,7 @@ static void rcar_du_crtc_atomic_enable(struct drm_crtc *crtc,
>  {
>  	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
>  
> -	/*
> -	 * If the CRTC has already been setup by the .atomic_begin() handler we
> -	 * can skip the setup stage.
> -	 */
> -	if (!rcrtc->initialized) {
> -		rcar_du_crtc_get(rcrtc);
> -		rcar_du_crtc_setup(rcrtc);
> -		rcrtc->initialized = true;
> -	}
> -
> +	rcar_du_crtc_get(rcrtc);
>  	rcar_du_crtc_start(rcrtc);
>  }
>  
> @@ -667,7 +670,6 @@ static void rcar_du_crtc_atomic_disable(struct drm_crtc *crtc,
>  	}
>  	spin_unlock_irq(&crtc->dev->event_lock);
>  
> -	rcrtc->initialized = false;
>  	rcrtc->outputs = 0;
>  }
>  
> @@ -680,14 +682,17 @@ static void rcar_du_crtc_atomic_begin(struct drm_crtc *crtc,
>  
>  	/*
>  	 * If a mode set is in progress we can be called with the CRTC disabled.
> -	 * We then need to first setup the CRTC in order to configure planes.
> -	 * The .atomic_enable() handler will notice and skip the CRTC setup.
> +	 * We thus need to first get and setup the CRTC in order to configure
> +	 * planes. We must *not* put the CRTC in .atomic_flush(), as it must be
> +	 * kept awake until the .atomic_enable() call that will follow. The get
> +	 * operation in .atomic_enable() will in that case be a no-op, and the
> +	 * CRTC will be put later in .atomic_disable().
> +	 *
> +	 * If a mode set is not in progress the CRTC is enabled, and the
> +	 * following get call will be a no-op. There is thus no need to belance

*balance

> +	 * it in .atomic_flush() either.
>  	 */
> -	if (!rcrtc->initialized) {
> -		rcar_du_crtc_get(rcrtc);
> -		rcar_du_crtc_setup(rcrtc);
> -		rcrtc->initialized = true;
> -	}
> +	rcar_du_crtc_get(rcrtc);
>  
>  	if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
>  		rcar_du_vsp_atomic_begin(rcrtc);
> -- 
> Regards,
> 
> Laurent Pinchart
>

With typo fixed:
Reviewed-by: Ulrich Hecht <uli+renesas@fpond.eu>

CU
Uli

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

* Re: [PATCH v2 06/16] drm: rcar-du: Perform the initial CRTC setup from rcar_du_crtc_get()
@ 2018-09-26 15:55     ` Ulrich Hecht
  0 siblings, 0 replies; 118+ messages in thread
From: Ulrich Hecht @ 2018-09-26 15:55 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham

Thank you for your patch.

> On September 14, 2018 at 11:10 AM Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> wrote:
> 
> 
> The rcar_du_crtc_get() function is always immediately followed by a call
> to rcar_du_crtc_setup(). Call the later from the former to simplify the
> code, and add a comment to explain how the get and put calls are
> balanced.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> ---
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 107 +++++++++++++++++----------------
>  1 file changed, 56 insertions(+), 51 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> index 6288b9ad9e24..c89751c26f9c 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> @@ -66,39 +66,6 @@ static void rcar_du_crtc_clr_set(struct rcar_du_crtc *rcrtc, u32 reg,
>  	rcar_du_write(rcdu, rcrtc->mmio_offset + reg, (value & ~clr) | set);
>  }
>  
> -static int rcar_du_crtc_get(struct rcar_du_crtc *rcrtc)
> -{
> -	int ret;
> -
> -	ret = clk_prepare_enable(rcrtc->clock);
> -	if (ret < 0)
> -		return ret;
> -
> -	ret = clk_prepare_enable(rcrtc->extclock);
> -	if (ret < 0)
> -		goto error_clock;
> -
> -	ret = rcar_du_group_get(rcrtc->group);
> -	if (ret < 0)
> -		goto error_group;
> -
> -	return 0;
> -
> -error_group:
> -	clk_disable_unprepare(rcrtc->extclock);
> -error_clock:
> -	clk_disable_unprepare(rcrtc->clock);
> -	return ret;
> -}
> -
> -static void rcar_du_crtc_put(struct rcar_du_crtc *rcrtc)
> -{
> -	rcar_du_group_put(rcrtc->group);
> -
> -	clk_disable_unprepare(rcrtc->extclock);
> -	clk_disable_unprepare(rcrtc->clock);
> -}
> -
>  /* -----------------------------------------------------------------------------
>   * Hardware Setup
>   */
> @@ -546,6 +513,51 @@ static void rcar_du_crtc_setup(struct rcar_du_crtc *rcrtc)
>  	drm_crtc_vblank_on(&rcrtc->crtc);
>  }
>  
> +static int rcar_du_crtc_get(struct rcar_du_crtc *rcrtc)
> +{
> +	int ret;
> +
> +	/*
> +	 * Guard against double-get, as the function is called from both the
> +	 * .atomic_enable() and .atomic_begin() handlers.
> +	 */
> +	if (rcrtc->initialized)
> +		return 0;
> +
> +	ret = clk_prepare_enable(rcrtc->clock);
> +	if (ret < 0)
> +		return ret;
> +
> +	ret = clk_prepare_enable(rcrtc->extclock);
> +	if (ret < 0)
> +		goto error_clock;
> +
> +	ret = rcar_du_group_get(rcrtc->group);
> +	if (ret < 0)
> +		goto error_group;
> +
> +	rcar_du_crtc_setup(rcrtc);
> +	rcrtc->initialized = true;
> +
> +	return 0;
> +
> +error_group:
> +	clk_disable_unprepare(rcrtc->extclock);
> +error_clock:
> +	clk_disable_unprepare(rcrtc->clock);
> +	return ret;
> +}
> +
> +static void rcar_du_crtc_put(struct rcar_du_crtc *rcrtc)
> +{
> +	rcar_du_group_put(rcrtc->group);
> +
> +	clk_disable_unprepare(rcrtc->extclock);
> +	clk_disable_unprepare(rcrtc->clock);
> +
> +	rcrtc->initialized = false;
> +}
> +
>  static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc)
>  {
>  	bool interlaced;
> @@ -639,16 +651,7 @@ static void rcar_du_crtc_atomic_enable(struct drm_crtc *crtc,
>  {
>  	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
>  
> -	/*
> -	 * If the CRTC has already been setup by the .atomic_begin() handler we
> -	 * can skip the setup stage.
> -	 */
> -	if (!rcrtc->initialized) {
> -		rcar_du_crtc_get(rcrtc);
> -		rcar_du_crtc_setup(rcrtc);
> -		rcrtc->initialized = true;
> -	}
> -
> +	rcar_du_crtc_get(rcrtc);
>  	rcar_du_crtc_start(rcrtc);
>  }
>  
> @@ -667,7 +670,6 @@ static void rcar_du_crtc_atomic_disable(struct drm_crtc *crtc,
>  	}
>  	spin_unlock_irq(&crtc->dev->event_lock);
>  
> -	rcrtc->initialized = false;
>  	rcrtc->outputs = 0;
>  }
>  
> @@ -680,14 +682,17 @@ static void rcar_du_crtc_atomic_begin(struct drm_crtc *crtc,
>  
>  	/*
>  	 * If a mode set is in progress we can be called with the CRTC disabled.
> -	 * We then need to first setup the CRTC in order to configure planes.
> -	 * The .atomic_enable() handler will notice and skip the CRTC setup.
> +	 * We thus need to first get and setup the CRTC in order to configure
> +	 * planes. We must *not* put the CRTC in .atomic_flush(), as it must be
> +	 * kept awake until the .atomic_enable() call that will follow. The get
> +	 * operation in .atomic_enable() will in that case be a no-op, and the
> +	 * CRTC will be put later in .atomic_disable().
> +	 *
> +	 * If a mode set is not in progress the CRTC is enabled, and the
> +	 * following get call will be a no-op. There is thus no need to belance

*balance

> +	 * it in .atomic_flush() either.
>  	 */
> -	if (!rcrtc->initialized) {
> -		rcar_du_crtc_get(rcrtc);
> -		rcar_du_crtc_setup(rcrtc);
> -		rcrtc->initialized = true;
> -	}
> +	rcar_du_crtc_get(rcrtc);
>  
>  	if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
>  		rcar_du_vsp_atomic_begin(rcrtc);
> -- 
> Regards,
> 
> Laurent Pinchart
>

With typo fixed:
Reviewed-by: Ulrich Hecht <uli+renesas@fpond.eu>

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

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

* Re: [PATCH v2 07/16] drm: rcar-du: Use LVDS PLL clock as dot clock when possible
  2018-09-14  9:10   ` Laurent Pinchart
@ 2018-09-26 15:55     ` Ulrich Hecht
  -1 siblings, 0 replies; 118+ messages in thread
From: Ulrich Hecht @ 2018-09-26 15:55 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham


> On September 14, 2018 at 11:10 AM Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> wrote:
> 
> 
> On selected SoCs, the DU can use the clock output by the LVDS encoder
> PLL as its input dot clock. This feature is optional, but on the D3 and
> E3 SoC it is often the only way to obtain a precise dot clock frequency,
> as the other available clocks (CPG-generated clock and external clock)
> usually have fixed rates.
> 
> Add a DU model information field to describe which DU channels can use
> the LVDS PLL output clock as their input clock, and configure clock
> routing accordingly.
> 
> This feature is available on H2, M2-W, M2-N, D3 and E3 SoCs, with D3 and
> E3 being the primary targets. It is left disabled in this commit, and
> will be enabled per-SoC after careful testing.
> 
> At the hardware level, clock routing is configured at runtime in two
> steps, first selecting an internal dot clock between the LVDS PLL clock
> and the external DOTCLKIN clock, and then selecting between the internal
> dot clock and the CPG-generated clock. The first part requires stopping
> the whole DU group in order for the change to take effect, thus causing
> flickering on the screen. For this reason we currently hardcode the
> clock source to the LVDS PLL clock if available, and allow flicker-free
> selection of the external DOTCLKIN clock or CPG-generated clock
> otherwise. A more dynamic clock selection process can be implemented
> later if the need arises.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> ---
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.c  |  8 +++++
>  drivers/gpu/drm/rcar-du/rcar_du_drv.h   |  2 ++
>  drivers/gpu/drm/rcar-du/rcar_du_group.c | 64 +++++++++++++++++++++++++--------
>  3 files changed, 59 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> index c89751c26f9c..2f8776c1ec8f 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> @@ -261,6 +261,14 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
>  		rcar_du_group_write(rcrtc->group, DPLLCR, dpllcr);
>  
>  		escr = ESCR_DCLKSEL_DCLKIN | div;
> +	} else if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index)) {
> +		/*
> +		 * Use the LVDS PLL output as the dot clock when outputting to
> +		 * the LVDS encoder on an SoC that supports this clock routing
> +		 * option. We use the clock directly in that case, without any
> +		 * additional divider.
> +		 */
> +		escr = ESCR_DCLKSEL_DCLKIN;
>  	} else {
>  		struct du_clk_params params = { .diff = (unsigned long)-1 };
>  
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> index fef9ea5c22f3..ebba9aefba6a 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> @@ -53,6 +53,7 @@ struct rcar_du_output_routing {
>   * @routes: array of CRTC to output routes, indexed by output (RCAR_DU_OUTPUT_*)
>   * @num_lvds: number of internal LVDS encoders
>   * @dpll_mask: bit mask of DU channels equipped with a DPLL
> + * @lvds_clk_mask: bitmask of channels that can use the LVDS clock as dot clock
>   */
>  struct rcar_du_device_info {
>  	unsigned int gen;
> @@ -62,6 +63,7 @@ struct rcar_du_device_info {
>  	struct rcar_du_output_routing routes[RCAR_DU_OUTPUT_MAX];
>  	unsigned int num_lvds;
>  	unsigned int dpll_mask;
> +	unsigned int lvds_clk_mask;
>  };
>  
>  #define RCAR_DU_MAX_CRTCS		4
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c
> index ef2c177afb6d..4c62841eff2f 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
> @@ -89,6 +89,54 @@ static void rcar_du_group_setup_defr8(struct rcar_du_group *rgrp)
>  	rcar_du_group_write(rgrp, DEFR8, defr8);
>  }
>  
> +static void rcar_du_group_setup_didsr(struct rcar_du_group *rgrp)
> +{
> +	struct rcar_du_device *rcdu = rgrp->dev;
> +	struct rcar_du_crtc *rcrtc;
> +	unsigned int num_crtcs = 0;
> +	unsigned int i;
> +	u32 didsr;
> +
> +	/*
> +	 * Configure input dot clock routing with a hardcoded configuration. If
> +	 * the DU channel can use the LVDS encoder output clock as the dot
> +	 * clock, do so. Otherwise route DU_DOTCLKINn signal to DUn.
> +	 *
> +	 * Each channel can then select between the dot clock configured here
> +	 * and the clock provided by the CPG through the ESCR register.
> +	 */
> +	if (rcdu->info->gen < 3 && rgrp->index == 0) {
> +		/*
> +		 * On Gen2 a single register in the first group controls dot
> +		 * clock selection for all channels.
> +		 */
> +		rcrtc = rcdu->crtcs;
> +		num_crtcs = rcdu->num_crtcs;
> +	} else if (rcdu->info->gen == 3 && rgrp->num_crtcs > 1) {
> +		/*
> +		 * On Gen3 dot clocks are setup through per-group registers,
> +		 * only available when the group has two channels.
> +		 */
> +		rcrtc = &rcdu->crtcs[rgrp->index * 2];
> +		num_crtcs = rgrp->num_crtcs;
> +	}
> +
> +	if (!num_crtcs)
> +		return;
> +
> +	didsr = DIDSR_CODE;
> +	for (i = 0; i < num_crtcs; ++i, ++rcrtc) {
> +		if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index))
> +			didsr |= DIDSR_LCDS_LVDS0(i)
> +			      |  DIDSR_PDCS_CLK(i, 0);
> +		else
> +			didsr |= DIDSR_LCDS_DCLKIN(i)
> +			      |  DIDSR_PDCS_CLK(i, 0);
> +	}
> +
> +	rcar_du_group_write(rgrp, DIDSR, didsr);
> +}
> +
>  static void rcar_du_group_setup(struct rcar_du_group *rgrp)
>  {
>  	struct rcar_du_device *rcdu = rgrp->dev;
> @@ -106,21 +154,7 @@ static void rcar_du_group_setup(struct rcar_du_group *rgrp)
>  
>  	if (rcar_du_has(rgrp->dev, RCAR_DU_FEATURE_EXT_CTRL_REGS)) {
>  		rcar_du_group_setup_defr8(rgrp);
> -
> -		/*
> -		 * Configure input dot clock routing. We currently hardcode the
> -		 * configuration to routing DOTCLKINn to DUn. Register fields
> -		 * depend on the DU generation, but the resulting value is 0 in
> -		 * all cases.
> -		 *
> -		 * On Gen2 a single register in the first group controls dot
> -		 * clock selection for all channels, while on Gen3 dot clocks
> -		 * 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))
> -			rcar_du_group_write(rgrp, DIDSR, DIDSR_CODE);
> +		rcar_du_group_setup_didsr(rgrp);
>  	}
>  
>  	if (rcdu->info->gen >= 3)
> -- 

Reviewed-by: Ulrich Hecht <uli+renesas@fpond.eu>

CU
Uli

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

* Re: [PATCH v2 07/16] drm: rcar-du: Use LVDS PLL clock as dot clock when possible
@ 2018-09-26 15:55     ` Ulrich Hecht
  0 siblings, 0 replies; 118+ messages in thread
From: Ulrich Hecht @ 2018-09-26 15:55 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham


> On September 14, 2018 at 11:10 AM Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> wrote:
> 
> 
> On selected SoCs, the DU can use the clock output by the LVDS encoder
> PLL as its input dot clock. This feature is optional, but on the D3 and
> E3 SoC it is often the only way to obtain a precise dot clock frequency,
> as the other available clocks (CPG-generated clock and external clock)
> usually have fixed rates.
> 
> Add a DU model information field to describe which DU channels can use
> the LVDS PLL output clock as their input clock, and configure clock
> routing accordingly.
> 
> This feature is available on H2, M2-W, M2-N, D3 and E3 SoCs, with D3 and
> E3 being the primary targets. It is left disabled in this commit, and
> will be enabled per-SoC after careful testing.
> 
> At the hardware level, clock routing is configured at runtime in two
> steps, first selecting an internal dot clock between the LVDS PLL clock
> and the external DOTCLKIN clock, and then selecting between the internal
> dot clock and the CPG-generated clock. The first part requires stopping
> the whole DU group in order for the change to take effect, thus causing
> flickering on the screen. For this reason we currently hardcode the
> clock source to the LVDS PLL clock if available, and allow flicker-free
> selection of the external DOTCLKIN clock or CPG-generated clock
> otherwise. A more dynamic clock selection process can be implemented
> later if the need arises.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> ---
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.c  |  8 +++++
>  drivers/gpu/drm/rcar-du/rcar_du_drv.h   |  2 ++
>  drivers/gpu/drm/rcar-du/rcar_du_group.c | 64 +++++++++++++++++++++++++--------
>  3 files changed, 59 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> index c89751c26f9c..2f8776c1ec8f 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> @@ -261,6 +261,14 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
>  		rcar_du_group_write(rcrtc->group, DPLLCR, dpllcr);
>  
>  		escr = ESCR_DCLKSEL_DCLKIN | div;
> +	} else if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index)) {
> +		/*
> +		 * Use the LVDS PLL output as the dot clock when outputting to
> +		 * the LVDS encoder on an SoC that supports this clock routing
> +		 * option. We use the clock directly in that case, without any
> +		 * additional divider.
> +		 */
> +		escr = ESCR_DCLKSEL_DCLKIN;
>  	} else {
>  		struct du_clk_params params = { .diff = (unsigned long)-1 };
>  
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> index fef9ea5c22f3..ebba9aefba6a 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> @@ -53,6 +53,7 @@ struct rcar_du_output_routing {
>   * @routes: array of CRTC to output routes, indexed by output (RCAR_DU_OUTPUT_*)
>   * @num_lvds: number of internal LVDS encoders
>   * @dpll_mask: bit mask of DU channels equipped with a DPLL
> + * @lvds_clk_mask: bitmask of channels that can use the LVDS clock as dot clock
>   */
>  struct rcar_du_device_info {
>  	unsigned int gen;
> @@ -62,6 +63,7 @@ struct rcar_du_device_info {
>  	struct rcar_du_output_routing routes[RCAR_DU_OUTPUT_MAX];
>  	unsigned int num_lvds;
>  	unsigned int dpll_mask;
> +	unsigned int lvds_clk_mask;
>  };
>  
>  #define RCAR_DU_MAX_CRTCS		4
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c
> index ef2c177afb6d..4c62841eff2f 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
> @@ -89,6 +89,54 @@ static void rcar_du_group_setup_defr8(struct rcar_du_group *rgrp)
>  	rcar_du_group_write(rgrp, DEFR8, defr8);
>  }
>  
> +static void rcar_du_group_setup_didsr(struct rcar_du_group *rgrp)
> +{
> +	struct rcar_du_device *rcdu = rgrp->dev;
> +	struct rcar_du_crtc *rcrtc;
> +	unsigned int num_crtcs = 0;
> +	unsigned int i;
> +	u32 didsr;
> +
> +	/*
> +	 * Configure input dot clock routing with a hardcoded configuration. If
> +	 * the DU channel can use the LVDS encoder output clock as the dot
> +	 * clock, do so. Otherwise route DU_DOTCLKINn signal to DUn.
> +	 *
> +	 * Each channel can then select between the dot clock configured here
> +	 * and the clock provided by the CPG through the ESCR register.
> +	 */
> +	if (rcdu->info->gen < 3 && rgrp->index == 0) {
> +		/*
> +		 * On Gen2 a single register in the first group controls dot
> +		 * clock selection for all channels.
> +		 */
> +		rcrtc = rcdu->crtcs;
> +		num_crtcs = rcdu->num_crtcs;
> +	} else if (rcdu->info->gen == 3 && rgrp->num_crtcs > 1) {
> +		/*
> +		 * On Gen3 dot clocks are setup through per-group registers,
> +		 * only available when the group has two channels.
> +		 */
> +		rcrtc = &rcdu->crtcs[rgrp->index * 2];
> +		num_crtcs = rgrp->num_crtcs;
> +	}
> +
> +	if (!num_crtcs)
> +		return;
> +
> +	didsr = DIDSR_CODE;
> +	for (i = 0; i < num_crtcs; ++i, ++rcrtc) {
> +		if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index))
> +			didsr |= DIDSR_LCDS_LVDS0(i)
> +			      |  DIDSR_PDCS_CLK(i, 0);
> +		else
> +			didsr |= DIDSR_LCDS_DCLKIN(i)
> +			      |  DIDSR_PDCS_CLK(i, 0);
> +	}
> +
> +	rcar_du_group_write(rgrp, DIDSR, didsr);
> +}
> +
>  static void rcar_du_group_setup(struct rcar_du_group *rgrp)
>  {
>  	struct rcar_du_device *rcdu = rgrp->dev;
> @@ -106,21 +154,7 @@ static void rcar_du_group_setup(struct rcar_du_group *rgrp)
>  
>  	if (rcar_du_has(rgrp->dev, RCAR_DU_FEATURE_EXT_CTRL_REGS)) {
>  		rcar_du_group_setup_defr8(rgrp);
> -
> -		/*
> -		 * Configure input dot clock routing. We currently hardcode the
> -		 * configuration to routing DOTCLKINn to DUn. Register fields
> -		 * depend on the DU generation, but the resulting value is 0 in
> -		 * all cases.
> -		 *
> -		 * On Gen2 a single register in the first group controls dot
> -		 * clock selection for all channels, while on Gen3 dot clocks
> -		 * 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))
> -			rcar_du_group_write(rgrp, DIDSR, DIDSR_CODE);
> +		rcar_du_group_setup_didsr(rgrp);
>  	}
>  
>  	if (rcdu->info->gen >= 3)
> -- 

Reviewed-by: Ulrich Hecht <uli+renesas@fpond.eu>

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

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

* Re: [PATCH v2 08/16] drm: rcar-du: Enable configurable DPAD0 routing on Gen3
  2018-09-14  9:10   ` Laurent Pinchart
@ 2018-09-26 15:55     ` Ulrich Hecht
  -1 siblings, 0 replies; 118+ messages in thread
From: Ulrich Hecht @ 2018-09-26 15:55 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham


> On September 14, 2018 at 11:10 AM Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> wrote:
> 
> 
> All Gen3 SoCs supported so far have a fixed association between DPAD0
> and DU channels, which led to hardcoding that association when writing
> the corresponding hardware register. The D3 and E3 will break that
> mechanism as DPAD0 can be dynamically connected to either DU0 or DU1.
> 
> Make DPAD0 routing dynamic on Gen3. To ensure a valid hardware
> configuration when the DU starts without the RGB output enabled, DPAD0
> is associated at initialization time to the first DU channel that it can
> be connected to. This makes no change on Gen2 as all Gen2 SoCs can
> connected DPAD0 to DU0, which is the current implicit default value.
> 
> As the DPAD0 source is always 0 when a single source is possible on
> Gen2, we can also simplify the Gen2 code in the same function to remove
> a conditional check.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> ---
>  drivers/gpu/drm/rcar-du/rcar_du_group.c | 17 ++++++-----------
>  drivers/gpu/drm/rcar-du/rcar_du_kms.c   | 12 ++++++++++++
>  2 files changed, 18 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c
> index 4c62841eff2f..f38703e7a10d 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
> @@ -56,8 +56,6 @@ static void rcar_du_group_setup_pins(struct rcar_du_group *rgrp)
>  static void rcar_du_group_setup_defr8(struct rcar_du_group *rgrp)
>  {
>  	struct rcar_du_device *rcdu = rgrp->dev;
> -	unsigned int possible_crtcs =
> -		rcdu->info->routes[RCAR_DU_OUTPUT_DPAD0].possible_crtcs;
>  	u32 defr8 = DEFR8_CODE;
>  
>  	if (rcdu->info->gen < 3) {
> @@ -69,21 +67,18 @@ static void rcar_du_group_setup_defr8(struct rcar_du_group *rgrp)
>  		 * DU instances that support it.
>  		 */
>  		if (rgrp->index == 0) {
> -			if (possible_crtcs > 1)
> -				defr8 |= DEFR8_DRGBS_DU(rcdu->dpad0_source);
> +			defr8 |= DEFR8_DRGBS_DU(rcdu->dpad0_source);
>  			if (rgrp->dev->vspd1_sink == 2)
>  				defr8 |= DEFR8_VSCS;
>  		}
>  	} else {
>  		/*
> -		 * On Gen3 VSPD routing can't be configured, but DPAD routing
> -		 * needs to be set despite having a single option available.
> +		 * On Gen3 VSPD routing can't be configured, and DPAD routing
> +		 * is set in the group corresponding to the DPAD output (no Gen3
> +		 * SoC has multiple DPAD sources belonging to separate groups).
>  		 */
> -		unsigned int rgb_crtc = ffs(possible_crtcs) - 1;
> -		struct rcar_du_crtc *crtc = &rcdu->crtcs[rgb_crtc];
> -
> -		if (crtc->index / 2 == rgrp->index)
> -			defr8 |= DEFR8_DRGBS_DU(crtc->index);
> +		if (rgrp->index == rcdu->dpad0_source / 2)
> +			defr8 |= DEFR8_DRGBS_DU(rcdu->dpad0_source);
>  	}
>  
>  	rcar_du_group_write(rgrp, DEFR8, defr8);
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
> index ed7fa3204892..bd01197700c5 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
> @@ -501,6 +501,7 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
>  	struct drm_device *dev = rcdu->ddev;
>  	struct drm_encoder *encoder;
>  	struct drm_fbdev_cma *fbdev;
> +	unsigned int dpad0_sources;
>  	unsigned int num_encoders;
>  	unsigned int num_groups;
>  	unsigned int swindex;
> @@ -613,6 +614,17 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
>  		encoder->possible_clones = (1 << num_encoders) - 1;
>  	}
>  
> +	/*
> +	 * Initialize the default DPAD0 source to the index of the first DU
> +	 * channel that can be connected to DPAD0. The exact value doesn't
> +	 * matter as it should be overwritten by mode setting for the RGB
> +	 * output, but it is nonetheless required to ensure a valid initial
> +	 * hardware configuration on Gen3 where DU0 can't always be connected to
> +	 * DPAD0.
> +	 */
> +	dpad0_sources = rcdu->info->routes[RCAR_DU_OUTPUT_DPAD0].possible_crtcs;
> +	rcdu->dpad0_source = ffs(dpad0_sources) - 1;
> +
>  	drm_mode_config_reset(dev);
>  
>  	drm_kms_helper_poll_init(dev);
> -- 

Reviewed-by: Ulrich Hecht <uli+renesas@fpond.eu>

CU
Uli

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

* Re: [PATCH v2 08/16] drm: rcar-du: Enable configurable DPAD0 routing on Gen3
@ 2018-09-26 15:55     ` Ulrich Hecht
  0 siblings, 0 replies; 118+ messages in thread
From: Ulrich Hecht @ 2018-09-26 15:55 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham


> On September 14, 2018 at 11:10 AM Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> wrote:
> 
> 
> All Gen3 SoCs supported so far have a fixed association between DPAD0
> and DU channels, which led to hardcoding that association when writing
> the corresponding hardware register. The D3 and E3 will break that
> mechanism as DPAD0 can be dynamically connected to either DU0 or DU1.
> 
> Make DPAD0 routing dynamic on Gen3. To ensure a valid hardware
> configuration when the DU starts without the RGB output enabled, DPAD0
> is associated at initialization time to the first DU channel that it can
> be connected to. This makes no change on Gen2 as all Gen2 SoCs can
> connected DPAD0 to DU0, which is the current implicit default value.
> 
> As the DPAD0 source is always 0 when a single source is possible on
> Gen2, we can also simplify the Gen2 code in the same function to remove
> a conditional check.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> ---
>  drivers/gpu/drm/rcar-du/rcar_du_group.c | 17 ++++++-----------
>  drivers/gpu/drm/rcar-du/rcar_du_kms.c   | 12 ++++++++++++
>  2 files changed, 18 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c
> index 4c62841eff2f..f38703e7a10d 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
> @@ -56,8 +56,6 @@ static void rcar_du_group_setup_pins(struct rcar_du_group *rgrp)
>  static void rcar_du_group_setup_defr8(struct rcar_du_group *rgrp)
>  {
>  	struct rcar_du_device *rcdu = rgrp->dev;
> -	unsigned int possible_crtcs =
> -		rcdu->info->routes[RCAR_DU_OUTPUT_DPAD0].possible_crtcs;
>  	u32 defr8 = DEFR8_CODE;
>  
>  	if (rcdu->info->gen < 3) {
> @@ -69,21 +67,18 @@ static void rcar_du_group_setup_defr8(struct rcar_du_group *rgrp)
>  		 * DU instances that support it.
>  		 */
>  		if (rgrp->index == 0) {
> -			if (possible_crtcs > 1)
> -				defr8 |= DEFR8_DRGBS_DU(rcdu->dpad0_source);
> +			defr8 |= DEFR8_DRGBS_DU(rcdu->dpad0_source);
>  			if (rgrp->dev->vspd1_sink == 2)
>  				defr8 |= DEFR8_VSCS;
>  		}
>  	} else {
>  		/*
> -		 * On Gen3 VSPD routing can't be configured, but DPAD routing
> -		 * needs to be set despite having a single option available.
> +		 * On Gen3 VSPD routing can't be configured, and DPAD routing
> +		 * is set in the group corresponding to the DPAD output (no Gen3
> +		 * SoC has multiple DPAD sources belonging to separate groups).
>  		 */
> -		unsigned int rgb_crtc = ffs(possible_crtcs) - 1;
> -		struct rcar_du_crtc *crtc = &rcdu->crtcs[rgb_crtc];
> -
> -		if (crtc->index / 2 == rgrp->index)
> -			defr8 |= DEFR8_DRGBS_DU(crtc->index);
> +		if (rgrp->index == rcdu->dpad0_source / 2)
> +			defr8 |= DEFR8_DRGBS_DU(rcdu->dpad0_source);
>  	}
>  
>  	rcar_du_group_write(rgrp, DEFR8, defr8);
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
> index ed7fa3204892..bd01197700c5 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
> @@ -501,6 +501,7 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
>  	struct drm_device *dev = rcdu->ddev;
>  	struct drm_encoder *encoder;
>  	struct drm_fbdev_cma *fbdev;
> +	unsigned int dpad0_sources;
>  	unsigned int num_encoders;
>  	unsigned int num_groups;
>  	unsigned int swindex;
> @@ -613,6 +614,17 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
>  		encoder->possible_clones = (1 << num_encoders) - 1;
>  	}
>  
> +	/*
> +	 * Initialize the default DPAD0 source to the index of the first DU
> +	 * channel that can be connected to DPAD0. The exact value doesn't
> +	 * matter as it should be overwritten by mode setting for the RGB
> +	 * output, but it is nonetheless required to ensure a valid initial
> +	 * hardware configuration on Gen3 where DU0 can't always be connected to
> +	 * DPAD0.
> +	 */
> +	dpad0_sources = rcdu->info->routes[RCAR_DU_OUTPUT_DPAD0].possible_crtcs;
> +	rcdu->dpad0_source = ffs(dpad0_sources) - 1;
> +
>  	drm_mode_config_reset(dev);
>  
>  	drm_kms_helper_poll_init(dev);
> -- 

Reviewed-by: Ulrich Hecht <uli+renesas@fpond.eu>

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

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

* Re: [PATCH v2 09/16] drm: rcar-du: Cache DSYSR value to ensure known initial value
  2018-09-14  9:10   ` Laurent Pinchart
@ 2018-09-26 15:55     ` Ulrich Hecht
  -1 siblings, 0 replies; 118+ messages in thread
From: Ulrich Hecht @ 2018-09-26 15:55 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham


> On September 14, 2018 at 11:10 AM Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> wrote:
> 
> 
> DSYSR is a DU channel register that also contains group fields. It is
> thus written to by both the group and CRTC code, using read-update-write
> sequences. As the register isn't initialized explicitly at startup time,
> this can lead to invalid or otherwise unexpected values being written to
> some of the fields if they have been modified by the firmware or just
> not reset properly.
> 
> To fix this we can write a fully known value to the DSYSR register when
> turning a channel's functional clock on. However, the mix of group and
> channel fields complicate this. A simpler solution is to cache the
> register and initialize the cached value to the desired hardware
> defaults.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> ---
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.c  | 16 ++++++++--------
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.h  |  5 +++++
>  drivers/gpu/drm/rcar-du/rcar_du_group.c |  7 ++++---
>  3 files changed, 17 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> index 2f8776c1ec8f..f827fccf6416 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> @@ -57,13 +57,12 @@ static void rcar_du_crtc_set(struct rcar_du_crtc *rcrtc, u32 reg, u32 set)
>  		      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)
> +void rcar_du_crtc_dsysr_clr_set(struct rcar_du_crtc *rcrtc, u32 clr, u32 set)
>  {
>  	struct rcar_du_device *rcdu = rcrtc->group->dev;
> -	u32 value = rcar_du_read(rcdu, rcrtc->mmio_offset + reg);
>  
> -	rcar_du_write(rcdu, rcrtc->mmio_offset + reg, (value & ~clr) | set);
> +	rcrtc->dsysr = (rcrtc->dsysr & ~clr) | set;
> +	rcar_du_write(rcdu, rcrtc->mmio_offset + DSYSR, rcrtc->dsysr);
>  }
>  
>  /* -----------------------------------------------------------------------------
> @@ -576,9 +575,9 @@ 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,
> -			     (interlaced ? DSYSR_SCM_INT_VIDEO : 0) |
> -			     DSYSR_TVM_MASTER);
> +	rcar_du_crtc_dsysr_clr_set(rcrtc, DSYSR_TVM_MASK | DSYSR_SCM_MASK,
> +				   (interlaced ? DSYSR_SCM_INT_VIDEO : 0) |
> +				   DSYSR_TVM_MASTER);
>  
>  	rcar_du_group_start_stop(rcrtc->group, true);
>  }
> @@ -645,7 +644,7 @@ 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_dsysr_clr_set(rcrtc, DSYSR_TVM_MASK, DSYSR_TVM_SWITCH);
>  
>  	rcar_du_group_start_stop(rcrtc->group, false);
>  }
> @@ -1121,6 +1120,7 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int swindex,
>  	rcrtc->group = rgrp;
>  	rcrtc->mmio_offset = mmio_offsets[hwindex];
>  	rcrtc->index = hwindex;
> +	rcrtc->dsysr = (rcrtc->index % 2 ? 0 : DSYSR_DRES) | DSYSR_TVM_TVSYNC;
>  
>  	if (rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE))
>  		primary = &rcrtc->vsp->planes[rcrtc->vsp_pipe].plane;
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> index 4990bbe9ba26..59ac6e7d22c9 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> @@ -30,6 +30,7 @@ struct rcar_du_vsp;
>   * @mmio_offset: offset of the CRTC registers in the DU MMIO block
>   * @index: CRTC software and hardware index
>   * @initialized: whether the CRTC has been initialized and clocks enabled
> + * @dsysr: cached value of the DSYSR register
>   * @vblank_enable: whether vblank events are enabled on this CRTC
>   * @event: event to post when the pending page flip completes
>   * @flip_wait: wait queue used to signal page flip completion
> @@ -50,6 +51,8 @@ struct rcar_du_crtc {
>  	unsigned int index;
>  	bool initialized;
>  
> +	u32 dsysr;
> +
>  	bool vblank_enable;
>  	struct drm_pending_vblank_event *event;
>  	wait_queue_head_t flip_wait;
> @@ -103,4 +106,6 @@ void rcar_du_crtc_route_output(struct drm_crtc *crtc,
>  			       enum rcar_du_output output);
>  void rcar_du_crtc_finish_page_flip(struct rcar_du_crtc *rcrtc);
>  
> +void rcar_du_crtc_dsysr_clr_set(struct rcar_du_crtc *rcrtc, u32 clr, u32 set);
> +
>  #endif /* __RCAR_DU_CRTC_H__ */
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c
> index f38703e7a10d..d85f0a1c1581 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
> @@ -202,9 +202,10 @@ 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)) |
> -		(start ? DSYSR_DEN : DSYSR_DRES));
> +	struct rcar_du_crtc *rcrtc = &rgrp->dev->crtcs[rgrp->index * 2];
> +
> +	rcar_du_crtc_dsysr_clr_set(rcrtc, DSYSR_DRES | DSYSR_DEN,
> +				   start ? DSYSR_DEN : DSYSR_DRES);
>  }
>  
>  void rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool start)
> -- 

Reviewed-by: Ulrich Hecht <uli+renesas@fpond.eu>

CU
Uli

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

* Re: [PATCH v2 09/16] drm: rcar-du: Cache DSYSR value to ensure known initial value
@ 2018-09-26 15:55     ` Ulrich Hecht
  0 siblings, 0 replies; 118+ messages in thread
From: Ulrich Hecht @ 2018-09-26 15:55 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham


> On September 14, 2018 at 11:10 AM Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> wrote:
> 
> 
> DSYSR is a DU channel register that also contains group fields. It is
> thus written to by both the group and CRTC code, using read-update-write
> sequences. As the register isn't initialized explicitly at startup time,
> this can lead to invalid or otherwise unexpected values being written to
> some of the fields if they have been modified by the firmware or just
> not reset properly.
> 
> To fix this we can write a fully known value to the DSYSR register when
> turning a channel's functional clock on. However, the mix of group and
> channel fields complicate this. A simpler solution is to cache the
> register and initialize the cached value to the desired hardware
> defaults.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> ---
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.c  | 16 ++++++++--------
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.h  |  5 +++++
>  drivers/gpu/drm/rcar-du/rcar_du_group.c |  7 ++++---
>  3 files changed, 17 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> index 2f8776c1ec8f..f827fccf6416 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> @@ -57,13 +57,12 @@ static void rcar_du_crtc_set(struct rcar_du_crtc *rcrtc, u32 reg, u32 set)
>  		      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)
> +void rcar_du_crtc_dsysr_clr_set(struct rcar_du_crtc *rcrtc, u32 clr, u32 set)
>  {
>  	struct rcar_du_device *rcdu = rcrtc->group->dev;
> -	u32 value = rcar_du_read(rcdu, rcrtc->mmio_offset + reg);
>  
> -	rcar_du_write(rcdu, rcrtc->mmio_offset + reg, (value & ~clr) | set);
> +	rcrtc->dsysr = (rcrtc->dsysr & ~clr) | set;
> +	rcar_du_write(rcdu, rcrtc->mmio_offset + DSYSR, rcrtc->dsysr);
>  }
>  
>  /* -----------------------------------------------------------------------------
> @@ -576,9 +575,9 @@ 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,
> -			     (interlaced ? DSYSR_SCM_INT_VIDEO : 0) |
> -			     DSYSR_TVM_MASTER);
> +	rcar_du_crtc_dsysr_clr_set(rcrtc, DSYSR_TVM_MASK | DSYSR_SCM_MASK,
> +				   (interlaced ? DSYSR_SCM_INT_VIDEO : 0) |
> +				   DSYSR_TVM_MASTER);
>  
>  	rcar_du_group_start_stop(rcrtc->group, true);
>  }
> @@ -645,7 +644,7 @@ 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_dsysr_clr_set(rcrtc, DSYSR_TVM_MASK, DSYSR_TVM_SWITCH);
>  
>  	rcar_du_group_start_stop(rcrtc->group, false);
>  }
> @@ -1121,6 +1120,7 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int swindex,
>  	rcrtc->group = rgrp;
>  	rcrtc->mmio_offset = mmio_offsets[hwindex];
>  	rcrtc->index = hwindex;
> +	rcrtc->dsysr = (rcrtc->index % 2 ? 0 : DSYSR_DRES) | DSYSR_TVM_TVSYNC;
>  
>  	if (rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE))
>  		primary = &rcrtc->vsp->planes[rcrtc->vsp_pipe].plane;
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> index 4990bbe9ba26..59ac6e7d22c9 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> @@ -30,6 +30,7 @@ struct rcar_du_vsp;
>   * @mmio_offset: offset of the CRTC registers in the DU MMIO block
>   * @index: CRTC software and hardware index
>   * @initialized: whether the CRTC has been initialized and clocks enabled
> + * @dsysr: cached value of the DSYSR register
>   * @vblank_enable: whether vblank events are enabled on this CRTC
>   * @event: event to post when the pending page flip completes
>   * @flip_wait: wait queue used to signal page flip completion
> @@ -50,6 +51,8 @@ struct rcar_du_crtc {
>  	unsigned int index;
>  	bool initialized;
>  
> +	u32 dsysr;
> +
>  	bool vblank_enable;
>  	struct drm_pending_vblank_event *event;
>  	wait_queue_head_t flip_wait;
> @@ -103,4 +106,6 @@ void rcar_du_crtc_route_output(struct drm_crtc *crtc,
>  			       enum rcar_du_output output);
>  void rcar_du_crtc_finish_page_flip(struct rcar_du_crtc *rcrtc);
>  
> +void rcar_du_crtc_dsysr_clr_set(struct rcar_du_crtc *rcrtc, u32 clr, u32 set);
> +
>  #endif /* __RCAR_DU_CRTC_H__ */
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c
> index f38703e7a10d..d85f0a1c1581 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
> @@ -202,9 +202,10 @@ 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)) |
> -		(start ? DSYSR_DEN : DSYSR_DRES));
> +	struct rcar_du_crtc *rcrtc = &rgrp->dev->crtcs[rgrp->index * 2];
> +
> +	rcar_du_crtc_dsysr_clr_set(rcrtc, DSYSR_DRES | DSYSR_DEN,
> +				   start ? DSYSR_DEN : DSYSR_DRES);
>  }
>  
>  void rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool start)
> -- 

Reviewed-by: Ulrich Hecht <uli+renesas@fpond.eu>

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

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

* Re: [PATCH v2 10/16] drm: rcar-du: Don't use TV sync mode when not supported by the hardware
  2018-09-14  9:10   ` Laurent Pinchart
@ 2018-09-26 15:55     ` Ulrich Hecht
  -1 siblings, 0 replies; 118+ messages in thread
From: Ulrich Hecht @ 2018-09-26 15:55 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham


> On September 14, 2018 at 11:10 AM Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> wrote:
> 
> 
> The official way to stop the display is to clear the display enable
> (DEN) bit in the DSYSR register, but that operates at a group level and
> affects the two channels in the group. To disable channels selectively,
> the driver uses TV sync mode that stops display operation on the channel
> and turns output signals into inputs.
> 
> While TV sync mode is available in all DU models currently supported,
> the D3 and E3 DUs don't support it. We will thus need to find an
> alternative way to turn channels off.
> 
> In the meantime, condition the switch to TV sync mode to the
> availability of the feature, to avoid writing an invalid value to the
> DSYSR register. The display output will turn blank as all planes are
> disabled when stopping the CRTC.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> ---
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.c |  7 ++++++-
>  drivers/gpu/drm/rcar-du/rcar_du_drv.c  | 33 ++++++++++++++++++++++-----------
>  drivers/gpu/drm/rcar-du/rcar_du_drv.h  |  1 +
>  3 files changed, 29 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 f827fccf6416..17741843cf51 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> @@ -643,8 +643,13 @@ 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.
> +	 *
> +	 * TODO: Find another way to stop the display for DUs that don't support
> +	 * TVM sync.
>  	 */
> -	rcar_du_crtc_dsysr_clr_set(rcrtc, DSYSR_TVM_MASK, DSYSR_TVM_SWITCH);
> +	if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_TVM_SYNC))
> +		rcar_du_crtc_dsysr_clr_set(rcrtc, DSYSR_TVM_MASK,
> +					   DSYSR_TVM_SWITCH);
>  
>  	rcar_du_group_start_stop(rcrtc->group, false);
>  }
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> index 0954ecd2f943..fa0d381c2d0f 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> @@ -36,7 +36,8 @@ static const struct rcar_du_device_info rzg1_du_r8a7743_info = {
>  	.gen = 2,
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(1) | BIT(0),
>  	.routes = {
>  		/*
> @@ -58,7 +59,8 @@ static const struct rcar_du_device_info rzg1_du_r8a7745_info = {
>  	.gen = 2,
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(1) | BIT(0),
>  	.routes = {
>  		/*
> @@ -77,7 +79,8 @@ static const struct rcar_du_device_info rzg1_du_r8a7745_info = {
>  
>  static const struct rcar_du_device_info rcar_du_r8a7779_info = {
>  	.gen = 2,
> -	.features = RCAR_DU_FEATURE_INTERLACED,
> +	.features = RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(1) | BIT(0),
>  	.routes = {
>  		/*
> @@ -99,7 +102,8 @@ static const struct rcar_du_device_info rcar_du_r8a7790_info = {
>  	.gen = 2,
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.quirks = RCAR_DU_QUIRK_ALIGN_128B,
>  	.channels_mask = BIT(2) | BIT(1) | BIT(0),
>  	.routes = {
> @@ -128,7 +132,8 @@ static const struct rcar_du_device_info rcar_du_r8a7791_info = {
>  	.gen = 2,
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(1) | BIT(0),
>  	.routes = {
>  		/*
> @@ -151,7 +156,8 @@ static const struct rcar_du_device_info rcar_du_r8a7792_info = {
>  	.gen = 2,
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(1) | BIT(0),
>  	.routes = {
>  		/* R8A7792 has two RGB outputs. */
> @@ -170,7 +176,8 @@ static const struct rcar_du_device_info rcar_du_r8a7794_info = {
>  	.gen = 2,
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(1) | BIT(0),
>  	.routes = {
>  		/*
> @@ -193,7 +200,8 @@ static const struct rcar_du_device_info rcar_du_r8a7795_info = {
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
>  		  | RCAR_DU_FEATURE_VSP1_SOURCE
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(3) | BIT(2) | BIT(1) | BIT(0),
>  	.routes = {
>  		/*
> @@ -226,7 +234,8 @@ static const struct rcar_du_device_info rcar_du_r8a7796_info = {
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
>  		  | RCAR_DU_FEATURE_VSP1_SOURCE
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(2) | BIT(1) | BIT(0),
>  	.routes = {
>  		/*
> @@ -255,7 +264,8 @@ static const struct rcar_du_device_info rcar_du_r8a77965_info = {
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
>  		  | RCAR_DU_FEATURE_VSP1_SOURCE
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(3) | BIT(1) | BIT(0),
>  	.routes = {
>  		/*
> @@ -284,7 +294,8 @@ static const struct rcar_du_device_info rcar_du_r8a77970_info = {
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
>  		  | RCAR_DU_FEATURE_VSP1_SOURCE
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(0),
>  	.routes = {
>  		/* R8A77970 has one RGB output and one LVDS output. */
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> index ebba9aefba6a..143c037e2c0f 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> @@ -27,6 +27,7 @@ struct rcar_du_device;
>  #define RCAR_DU_FEATURE_EXT_CTRL_REGS	BIT(1)	/* Has extended control registers */
>  #define RCAR_DU_FEATURE_VSP1_SOURCE	BIT(2)	/* Has inputs from VSP1 */
>  #define RCAR_DU_FEATURE_INTERLACED	BIT(3)	/* HW supports interlaced */
> +#define RCAR_DU_FEATURE_TVM_SYNC	BIT(4)	/* Has TV switch/sync modes */
>  
>  #define RCAR_DU_QUIRK_ALIGN_128B	BIT(0)	/* Align pitches to 128 bytes */
>  
> -- 

Reviewed-by: Ulrich Hecht <uli+renesas@fpond.eu>

CU
Uli

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

* Re: [PATCH v2 10/16] drm: rcar-du: Don't use TV sync mode when not supported by the hardware
@ 2018-09-26 15:55     ` Ulrich Hecht
  0 siblings, 0 replies; 118+ messages in thread
From: Ulrich Hecht @ 2018-09-26 15:55 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham


> On September 14, 2018 at 11:10 AM Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> wrote:
> 
> 
> The official way to stop the display is to clear the display enable
> (DEN) bit in the DSYSR register, but that operates at a group level and
> affects the two channels in the group. To disable channels selectively,
> the driver uses TV sync mode that stops display operation on the channel
> and turns output signals into inputs.
> 
> While TV sync mode is available in all DU models currently supported,
> the D3 and E3 DUs don't support it. We will thus need to find an
> alternative way to turn channels off.
> 
> In the meantime, condition the switch to TV sync mode to the
> availability of the feature, to avoid writing an invalid value to the
> DSYSR register. The display output will turn blank as all planes are
> disabled when stopping the CRTC.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> ---
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.c |  7 ++++++-
>  drivers/gpu/drm/rcar-du/rcar_du_drv.c  | 33 ++++++++++++++++++++++-----------
>  drivers/gpu/drm/rcar-du/rcar_du_drv.h  |  1 +
>  3 files changed, 29 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 f827fccf6416..17741843cf51 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> @@ -643,8 +643,13 @@ 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.
> +	 *
> +	 * TODO: Find another way to stop the display for DUs that don't support
> +	 * TVM sync.
>  	 */
> -	rcar_du_crtc_dsysr_clr_set(rcrtc, DSYSR_TVM_MASK, DSYSR_TVM_SWITCH);
> +	if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_TVM_SYNC))
> +		rcar_du_crtc_dsysr_clr_set(rcrtc, DSYSR_TVM_MASK,
> +					   DSYSR_TVM_SWITCH);
>  
>  	rcar_du_group_start_stop(rcrtc->group, false);
>  }
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> index 0954ecd2f943..fa0d381c2d0f 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> @@ -36,7 +36,8 @@ static const struct rcar_du_device_info rzg1_du_r8a7743_info = {
>  	.gen = 2,
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(1) | BIT(0),
>  	.routes = {
>  		/*
> @@ -58,7 +59,8 @@ static const struct rcar_du_device_info rzg1_du_r8a7745_info = {
>  	.gen = 2,
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(1) | BIT(0),
>  	.routes = {
>  		/*
> @@ -77,7 +79,8 @@ static const struct rcar_du_device_info rzg1_du_r8a7745_info = {
>  
>  static const struct rcar_du_device_info rcar_du_r8a7779_info = {
>  	.gen = 2,
> -	.features = RCAR_DU_FEATURE_INTERLACED,
> +	.features = RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(1) | BIT(0),
>  	.routes = {
>  		/*
> @@ -99,7 +102,8 @@ static const struct rcar_du_device_info rcar_du_r8a7790_info = {
>  	.gen = 2,
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.quirks = RCAR_DU_QUIRK_ALIGN_128B,
>  	.channels_mask = BIT(2) | BIT(1) | BIT(0),
>  	.routes = {
> @@ -128,7 +132,8 @@ static const struct rcar_du_device_info rcar_du_r8a7791_info = {
>  	.gen = 2,
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(1) | BIT(0),
>  	.routes = {
>  		/*
> @@ -151,7 +156,8 @@ static const struct rcar_du_device_info rcar_du_r8a7792_info = {
>  	.gen = 2,
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(1) | BIT(0),
>  	.routes = {
>  		/* R8A7792 has two RGB outputs. */
> @@ -170,7 +176,8 @@ static const struct rcar_du_device_info rcar_du_r8a7794_info = {
>  	.gen = 2,
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(1) | BIT(0),
>  	.routes = {
>  		/*
> @@ -193,7 +200,8 @@ static const struct rcar_du_device_info rcar_du_r8a7795_info = {
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
>  		  | RCAR_DU_FEATURE_VSP1_SOURCE
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(3) | BIT(2) | BIT(1) | BIT(0),
>  	.routes = {
>  		/*
> @@ -226,7 +234,8 @@ static const struct rcar_du_device_info rcar_du_r8a7796_info = {
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
>  		  | RCAR_DU_FEATURE_VSP1_SOURCE
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(2) | BIT(1) | BIT(0),
>  	.routes = {
>  		/*
> @@ -255,7 +264,8 @@ static const struct rcar_du_device_info rcar_du_r8a77965_info = {
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
>  		  | RCAR_DU_FEATURE_VSP1_SOURCE
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(3) | BIT(1) | BIT(0),
>  	.routes = {
>  		/*
> @@ -284,7 +294,8 @@ static const struct rcar_du_device_info rcar_du_r8a77970_info = {
>  	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
>  		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
>  		  | RCAR_DU_FEATURE_VSP1_SOURCE
> -		  | RCAR_DU_FEATURE_INTERLACED,
> +		  | RCAR_DU_FEATURE_INTERLACED
> +		  | RCAR_DU_FEATURE_TVM_SYNC,
>  	.channels_mask = BIT(0),
>  	.routes = {
>  		/* R8A77970 has one RGB output and one LVDS output. */
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> index ebba9aefba6a..143c037e2c0f 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> @@ -27,6 +27,7 @@ struct rcar_du_device;
>  #define RCAR_DU_FEATURE_EXT_CTRL_REGS	BIT(1)	/* Has extended control registers */
>  #define RCAR_DU_FEATURE_VSP1_SOURCE	BIT(2)	/* Has inputs from VSP1 */
>  #define RCAR_DU_FEATURE_INTERLACED	BIT(3)	/* HW supports interlaced */
> +#define RCAR_DU_FEATURE_TVM_SYNC	BIT(4)	/* Has TV switch/sync modes */
>  
>  #define RCAR_DU_QUIRK_ALIGN_128B	BIT(0)	/* Align pitches to 128 bytes */
>  
> -- 

Reviewed-by: Ulrich Hecht <uli+renesas@fpond.eu>

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

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

* Re: [PATCH v2 15/16] arm64: dts: renesas: r8a77990: ebisu: Enable VGA and HDMI outputs
  2018-09-14  9:10   ` Laurent Pinchart
@ 2018-09-26 15:55     ` Ulrich Hecht
  -1 siblings, 0 replies; 118+ messages in thread
From: Ulrich Hecht @ 2018-09-26 15:55 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham


> On September 14, 2018 at 11:10 AM Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> wrote:
> 
> 
> Add the LVDS decoder, HDMI encoder, VGA encoder and HDMI and VGA
> connectors, and wire up the display-related nodes with clocks, pinmux
> and regulators.
> 
> The LVDS0 and LVDS1 encoders can use the DU_DOTCLKIN0, DU_DOTCLKIN1 and
> EXTAL externals clocks. Two of them are provided to the SoC on the Ebisu
> board, hook them up in DT.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> ---
>  arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts | 166 +++++++++++++++++++++++++
>  1 file changed, 166 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts b/arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts
> index 2bc3a4884b00..772ea8843d84 100644
> --- a/arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts
> +++ b/arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts
> @@ -28,6 +28,88 @@
>  		/* first 128MB is reserved for secure area. */
>  		reg = <0x0 0x48000000 0x0 0x38000000>;
>  	};
> +
> +	hdmi-out {
> +		compatible = "hdmi-connector";
> +		type = "a";
> +
> +		port {
> +			hdmi_con_out: endpoint {
> +				remote-endpoint = <&adv7511_out>;
> +			};
> +		};
> +	};
> +
> +	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>;
> +				};
> +			};
> +		};
> +	};
> +
> +	vga {
> +		compatible = "vga-connector";
> +
> +		port {
> +			vga_in: endpoint {
> +				remote-endpoint = <&adv7123_out>;
> +			};
> +		};
> +	};
> +
> +	vga-encoder {
> +		compatible = "adi,adv7123";
> +
> +		ports {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			port@0 {
> +				reg = <0>;
> +				adv7123_in: endpoint {
> +					remote-endpoint = <&du_out_rgb>;
> +				};
> +			};
> +			port@1 {
> +				reg = <1>;
> +				adv7123_out: endpoint {
> +					remote-endpoint = <&vga_in>;
> +				};
> +			};
> +		};
> +	};
> +
> +	reg_3p3v: regulator1 {
> +		compatible = "regulator-fixed";
> +		regulator-name = "fixed-3.3V";
> +		regulator-min-microvolt = <3300000>;
> +		regulator-max-microvolt = <3300000>;
> +		regulator-boot-on;
> +		regulator-always-on;
> +	};
> +
> +	x13_clk: x13 {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <74250000>;
> +	};
>  };
>  
>  &avb {
> @@ -47,6 +129,25 @@
>  	};
>  };
>  
> +&du {
> +	pinctrl-0 = <&du_pins>;
> +	pinctrl-names = "default";
> +	status = "okay";
> +
> +	clocks = <&cpg CPG_MOD 724>,
> +		 <&cpg CPG_MOD 723>,
> +		 <&x13_clk>;
> +	clock-names = "du.0", "du.1", "dclkin.0";
> +
> +	ports {
> +		port@0 {
> +			endpoint {
> +				remote-endpoint = <&adv7123_in>;
> +			};
> +		};
> +	};
> +};
> +
>  &ehci0 {
>  	status = "okay";
>  };
> @@ -55,6 +156,66 @@
>  	clock-frequency = <48000000>;
>  };
>  
> +&i2c0 {
> +	status = "okay";
> +
> +	hdmi-encoder@39 {
> +		compatible = "adi,adv7511w";
> +		reg = <0x39>;
> +		interrupt-parent = <&gpio1>;
> +		interrupts = <1 IRQ_TYPE_LEVEL_LOW>;
> +
> +		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>;
> +				};
> +			};
> +		};
> +	};
> +};
> +
> +&lvds0 {
> +	status = "okay";
> +
> +	clocks = <&cpg CPG_MOD 727>,
> +		 <&x13_clk>,
> +		 <&extal_clk>;
> +	clock-names = "fck", "dclkin.0", "extal";
> +
> +	ports {
> +		port@1 {
> +			lvds0_out: endpoint {
> +				remote-endpoint = <&thc63lvd1024_in>;
> +			};
> +		};
> +	};
> +};
> +
> +&lvds1 {
> +	clocks = <&cpg CPG_MOD 727>,
> +		 <&x13_clk>,
> +		 <&extal_clk>;
> +	clock-names = "fck", "dclkin.0", "extal";
> +};
> +
>  &ohci0 {
>  	status = "okay";
>  };
> @@ -67,6 +228,11 @@
>  		};
>  	};
>  
> +	du_pins: du {
> +		groups = "du_rgb888", "du_sync", "du_disp", "du_clk_out_0";
> +		function = "du";
> +	};
> +
>  	usb0_pins: usb {
>  		groups = "usb0_b";
>  		function = "usb0";
> -- 

Reviewed-by: Ulrich Hecht <uli+renesas@fpond.eu>

CU
Uli

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

* Re: [PATCH v2 15/16] arm64: dts: renesas: r8a77990: ebisu: Enable VGA and HDMI outputs
@ 2018-09-26 15:55     ` Ulrich Hecht
  0 siblings, 0 replies; 118+ messages in thread
From: Ulrich Hecht @ 2018-09-26 15:55 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham


> On September 14, 2018 at 11:10 AM Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> wrote:
> 
> 
> Add the LVDS decoder, HDMI encoder, VGA encoder and HDMI and VGA
> connectors, and wire up the display-related nodes with clocks, pinmux
> and regulators.
> 
> The LVDS0 and LVDS1 encoders can use the DU_DOTCLKIN0, DU_DOTCLKIN1 and
> EXTAL externals clocks. Two of them are provided to the SoC on the Ebisu
> board, hook them up in DT.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> ---
>  arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts | 166 +++++++++++++++++++++++++
>  1 file changed, 166 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts b/arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts
> index 2bc3a4884b00..772ea8843d84 100644
> --- a/arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts
> +++ b/arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts
> @@ -28,6 +28,88 @@
>  		/* first 128MB is reserved for secure area. */
>  		reg = <0x0 0x48000000 0x0 0x38000000>;
>  	};
> +
> +	hdmi-out {
> +		compatible = "hdmi-connector";
> +		type = "a";
> +
> +		port {
> +			hdmi_con_out: endpoint {
> +				remote-endpoint = <&adv7511_out>;
> +			};
> +		};
> +	};
> +
> +	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>;
> +				};
> +			};
> +		};
> +	};
> +
> +	vga {
> +		compatible = "vga-connector";
> +
> +		port {
> +			vga_in: endpoint {
> +				remote-endpoint = <&adv7123_out>;
> +			};
> +		};
> +	};
> +
> +	vga-encoder {
> +		compatible = "adi,adv7123";
> +
> +		ports {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			port@0 {
> +				reg = <0>;
> +				adv7123_in: endpoint {
> +					remote-endpoint = <&du_out_rgb>;
> +				};
> +			};
> +			port@1 {
> +				reg = <1>;
> +				adv7123_out: endpoint {
> +					remote-endpoint = <&vga_in>;
> +				};
> +			};
> +		};
> +	};
> +
> +	reg_3p3v: regulator1 {
> +		compatible = "regulator-fixed";
> +		regulator-name = "fixed-3.3V";
> +		regulator-min-microvolt = <3300000>;
> +		regulator-max-microvolt = <3300000>;
> +		regulator-boot-on;
> +		regulator-always-on;
> +	};
> +
> +	x13_clk: x13 {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <74250000>;
> +	};
>  };
>  
>  &avb {
> @@ -47,6 +129,25 @@
>  	};
>  };
>  
> +&du {
> +	pinctrl-0 = <&du_pins>;
> +	pinctrl-names = "default";
> +	status = "okay";
> +
> +	clocks = <&cpg CPG_MOD 724>,
> +		 <&cpg CPG_MOD 723>,
> +		 <&x13_clk>;
> +	clock-names = "du.0", "du.1", "dclkin.0";
> +
> +	ports {
> +		port@0 {
> +			endpoint {
> +				remote-endpoint = <&adv7123_in>;
> +			};
> +		};
> +	};
> +};
> +
>  &ehci0 {
>  	status = "okay";
>  };
> @@ -55,6 +156,66 @@
>  	clock-frequency = <48000000>;
>  };
>  
> +&i2c0 {
> +	status = "okay";
> +
> +	hdmi-encoder@39 {
> +		compatible = "adi,adv7511w";
> +		reg = <0x39>;
> +		interrupt-parent = <&gpio1>;
> +		interrupts = <1 IRQ_TYPE_LEVEL_LOW>;
> +
> +		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>;
> +				};
> +			};
> +		};
> +	};
> +};
> +
> +&lvds0 {
> +	status = "okay";
> +
> +	clocks = <&cpg CPG_MOD 727>,
> +		 <&x13_clk>,
> +		 <&extal_clk>;
> +	clock-names = "fck", "dclkin.0", "extal";
> +
> +	ports {
> +		port@1 {
> +			lvds0_out: endpoint {
> +				remote-endpoint = <&thc63lvd1024_in>;
> +			};
> +		};
> +	};
> +};
> +
> +&lvds1 {
> +	clocks = <&cpg CPG_MOD 727>,
> +		 <&x13_clk>,
> +		 <&extal_clk>;
> +	clock-names = "fck", "dclkin.0", "extal";
> +};
> +
>  &ohci0 {
>  	status = "okay";
>  };
> @@ -67,6 +228,11 @@
>  		};
>  	};
>  
> +	du_pins: du {
> +		groups = "du_rgb888", "du_sync", "du_disp", "du_clk_out_0";
> +		function = "du";
> +	};
> +
>  	usb0_pins: usb {
>  		groups = "usb0_b";
>  		function = "usb0";
> -- 

Reviewed-by: Ulrich Hecht <uli+renesas@fpond.eu>

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

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

* Re: [PATCH v2 06/16] drm: rcar-du: Perform the initial CRTC setup from rcar_du_crtc_get()
  2018-09-26 15:55     ` Ulrich Hecht
@ 2018-09-28 15:14       ` Laurent Pinchart
  -1 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-28 15:14 UTC (permalink / raw)
  To: Ulrich Hecht
  Cc: Laurent Pinchart, dri-devel, linux-renesas-soc, Kieran Bingham

Hi Ulrich,

Thank you for the review. Patches have however landed upstream already, so I 
can't add any Reviewed-by tag anymore. I will submit a follow-up patch, unless 
you would prefer doing it yourself.

On Wednesday, 26 September 2018 18:55:14 EEST Ulrich Hecht wrote:
> Thank you for your patch.
> 
> > On September 14, 2018 at 11:10 AM Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com> wrote:
> > 
> > 
> > The rcar_du_crtc_get() function is always immediately followed by a call
> > to rcar_du_crtc_setup(). Call the later from the former to simplify the
> > code, and add a comment to explain how the get and put calls are
> > balanced.
> > 
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> > Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> > ---
> > 
> >  drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 107 +++++++++++++++-------------
> >  1 file changed, 56 insertions(+), 51 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> > b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c index 6288b9ad9e24..c89751c26f9c
> > 100644
> > --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> > +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> > @@ -66,39 +66,6 @@ static void rcar_du_crtc_clr_set(struct rcar_du_crtc
> > *rcrtc, u32 reg,> 
> >  	rcar_du_write(rcdu, rcrtc->mmio_offset + reg, (value & ~clr) | set);
> >  
> >  }
> > 
> > -static int rcar_du_crtc_get(struct rcar_du_crtc *rcrtc)
> > -{
> > -	int ret;
> > -
> > -	ret = clk_prepare_enable(rcrtc->clock);
> > -	if (ret < 0)
> > -		return ret;
> > -
> > -	ret = clk_prepare_enable(rcrtc->extclock);
> > -	if (ret < 0)
> > -		goto error_clock;
> > -
> > -	ret = rcar_du_group_get(rcrtc->group);
> > -	if (ret < 0)
> > -		goto error_group;
> > -
> > -	return 0;
> > -
> > -error_group:
> > -	clk_disable_unprepare(rcrtc->extclock);
> > -error_clock:
> > -	clk_disable_unprepare(rcrtc->clock);
> > -	return ret;
> > -}
> > -
> > -static void rcar_du_crtc_put(struct rcar_du_crtc *rcrtc)
> > -{
> > -	rcar_du_group_put(rcrtc->group);
> > -
> > -	clk_disable_unprepare(rcrtc->extclock);
> > -	clk_disable_unprepare(rcrtc->clock);
> > -}
> > -
> > 
> >  /*
> >  ------------------------------------------------------------------------
> >  ----->  
> >   * Hardware Setup
> >   */
> > 
> > @@ -546,6 +513,51 @@ static void rcar_du_crtc_setup(struct rcar_du_crtc
> > *rcrtc)> 
> >  	drm_crtc_vblank_on(&rcrtc->crtc);
> >  
> >  }
> > 
> > +static int rcar_du_crtc_get(struct rcar_du_crtc *rcrtc)
> > +{
> > +	int ret;
> > +
> > +	/*
> > +	 * Guard against double-get, as the function is called from both the
> > +	 * .atomic_enable() and .atomic_begin() handlers.
> > +	 */
> > +	if (rcrtc->initialized)
> > +		return 0;
> > +
> > +	ret = clk_prepare_enable(rcrtc->clock);
> > +	if (ret < 0)
> > +		return ret;
> > +
> > +	ret = clk_prepare_enable(rcrtc->extclock);
> > +	if (ret < 0)
> > +		goto error_clock;
> > +
> > +	ret = rcar_du_group_get(rcrtc->group);
> > +	if (ret < 0)
> > +		goto error_group;
> > +
> > +	rcar_du_crtc_setup(rcrtc);
> > +	rcrtc->initialized = true;
> > +
> > +	return 0;
> > +
> > +error_group:
> > +	clk_disable_unprepare(rcrtc->extclock);
> > +error_clock:
> > +	clk_disable_unprepare(rcrtc->clock);
> > +	return ret;
> > +}
> > +
> > +static void rcar_du_crtc_put(struct rcar_du_crtc *rcrtc)
> > +{
> > +	rcar_du_group_put(rcrtc->group);
> > +
> > +	clk_disable_unprepare(rcrtc->extclock);
> > +	clk_disable_unprepare(rcrtc->clock);
> > +
> > +	rcrtc->initialized = false;
> > +}
> > +
> > 
> >  static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc)
> >  {
> >  
> >  	bool interlaced;
> > 
> > @@ -639,16 +651,7 @@ static void rcar_du_crtc_atomic_enable(struct
> > drm_crtc *crtc,> 
> >  {
> >  
> >  	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
> > 
> > -	/*
> > -	 * If the CRTC has already been setup by the .atomic_begin() handler we
> > -	 * can skip the setup stage.
> > -	 */
> > -	if (!rcrtc->initialized) {
> > -		rcar_du_crtc_get(rcrtc);
> > -		rcar_du_crtc_setup(rcrtc);
> > -		rcrtc->initialized = true;
> > -	}
> > -
> > +	rcar_du_crtc_get(rcrtc);
> > 
> >  	rcar_du_crtc_start(rcrtc);
> >  
> >  }
> > 
> > @@ -667,7 +670,6 @@ static void rcar_du_crtc_atomic_disable(struct
> > drm_crtc *crtc,> 
> >  	}
> >  	spin_unlock_irq(&crtc->dev->event_lock);
> > 
> > -	rcrtc->initialized = false;
> > 
> >  	rcrtc->outputs = 0;
> >  
> >  }
> > 
> > @@ -680,14 +682,17 @@ static void rcar_du_crtc_atomic_begin(struct
> > drm_crtc *crtc,> 
> >  	/*
> >  	
> >  	 * If a mode set is in progress we can be called with the CRTC 
disabled.
> > 
> > -	 * We then need to first setup the CRTC in order to configure planes.
> > -	 * The .atomic_enable() handler will notice and skip the CRTC setup.
> > +	 * We thus need to first get and setup the CRTC in order to configure
> > +	 * planes. We must *not* put the CRTC in .atomic_flush(), as it must be
> > +	 * kept awake until the .atomic_enable() call that will follow. The get
> > +	 * operation in .atomic_enable() will in that case be a no-op, and the
> > +	 * CRTC will be put later in .atomic_disable().
> > +	 *
> > +	 * If a mode set is not in progress the CRTC is enabled, and the
> > +	 * following get call will be a no-op. There is thus no need to belance
> 
> *balance
> 
> > +	 * it in .atomic_flush() either.
> > 
> >  	 */
> > 
> > -	if (!rcrtc->initialized) {
> > -		rcar_du_crtc_get(rcrtc);
> > -		rcar_du_crtc_setup(rcrtc);
> > -		rcrtc->initialized = true;
> > -	}
> > +	rcar_du_crtc_get(rcrtc);
> > 
> >  	if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
> >  	
> >  		rcar_du_vsp_atomic_begin(rcrtc);
> 
> With typo fixed:
> Reviewed-by: Ulrich Hecht <uli+renesas@fpond.eu>

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v2 06/16] drm: rcar-du: Perform the initial CRTC setup from rcar_du_crtc_get()
@ 2018-09-28 15:14       ` Laurent Pinchart
  0 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-09-28 15:14 UTC (permalink / raw)
  To: Ulrich Hecht
  Cc: linux-renesas-soc, Laurent Pinchart, Kieran Bingham, dri-devel

Hi Ulrich,

Thank you for the review. Patches have however landed upstream already, so I 
can't add any Reviewed-by tag anymore. I will submit a follow-up patch, unless 
you would prefer doing it yourself.

On Wednesday, 26 September 2018 18:55:14 EEST Ulrich Hecht wrote:
> Thank you for your patch.
> 
> > On September 14, 2018 at 11:10 AM Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com> wrote:
> > 
> > 
> > The rcar_du_crtc_get() function is always immediately followed by a call
> > to rcar_du_crtc_setup(). Call the later from the former to simplify the
> > code, and add a comment to explain how the get and put calls are
> > balanced.
> > 
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> > Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> > ---
> > 
> >  drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 107 +++++++++++++++-------------
> >  1 file changed, 56 insertions(+), 51 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> > b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c index 6288b9ad9e24..c89751c26f9c
> > 100644
> > --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> > +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> > @@ -66,39 +66,6 @@ static void rcar_du_crtc_clr_set(struct rcar_du_crtc
> > *rcrtc, u32 reg,> 
> >  	rcar_du_write(rcdu, rcrtc->mmio_offset + reg, (value & ~clr) | set);
> >  
> >  }
> > 
> > -static int rcar_du_crtc_get(struct rcar_du_crtc *rcrtc)
> > -{
> > -	int ret;
> > -
> > -	ret = clk_prepare_enable(rcrtc->clock);
> > -	if (ret < 0)
> > -		return ret;
> > -
> > -	ret = clk_prepare_enable(rcrtc->extclock);
> > -	if (ret < 0)
> > -		goto error_clock;
> > -
> > -	ret = rcar_du_group_get(rcrtc->group);
> > -	if (ret < 0)
> > -		goto error_group;
> > -
> > -	return 0;
> > -
> > -error_group:
> > -	clk_disable_unprepare(rcrtc->extclock);
> > -error_clock:
> > -	clk_disable_unprepare(rcrtc->clock);
> > -	return ret;
> > -}
> > -
> > -static void rcar_du_crtc_put(struct rcar_du_crtc *rcrtc)
> > -{
> > -	rcar_du_group_put(rcrtc->group);
> > -
> > -	clk_disable_unprepare(rcrtc->extclock);
> > -	clk_disable_unprepare(rcrtc->clock);
> > -}
> > -
> > 
> >  /*
> >  ------------------------------------------------------------------------
> >  ----->  
> >   * Hardware Setup
> >   */
> > 
> > @@ -546,6 +513,51 @@ static void rcar_du_crtc_setup(struct rcar_du_crtc
> > *rcrtc)> 
> >  	drm_crtc_vblank_on(&rcrtc->crtc);
> >  
> >  }
> > 
> > +static int rcar_du_crtc_get(struct rcar_du_crtc *rcrtc)
> > +{
> > +	int ret;
> > +
> > +	/*
> > +	 * Guard against double-get, as the function is called from both the
> > +	 * .atomic_enable() and .atomic_begin() handlers.
> > +	 */
> > +	if (rcrtc->initialized)
> > +		return 0;
> > +
> > +	ret = clk_prepare_enable(rcrtc->clock);
> > +	if (ret < 0)
> > +		return ret;
> > +
> > +	ret = clk_prepare_enable(rcrtc->extclock);
> > +	if (ret < 0)
> > +		goto error_clock;
> > +
> > +	ret = rcar_du_group_get(rcrtc->group);
> > +	if (ret < 0)
> > +		goto error_group;
> > +
> > +	rcar_du_crtc_setup(rcrtc);
> > +	rcrtc->initialized = true;
> > +
> > +	return 0;
> > +
> > +error_group:
> > +	clk_disable_unprepare(rcrtc->extclock);
> > +error_clock:
> > +	clk_disable_unprepare(rcrtc->clock);
> > +	return ret;
> > +}
> > +
> > +static void rcar_du_crtc_put(struct rcar_du_crtc *rcrtc)
> > +{
> > +	rcar_du_group_put(rcrtc->group);
> > +
> > +	clk_disable_unprepare(rcrtc->extclock);
> > +	clk_disable_unprepare(rcrtc->clock);
> > +
> > +	rcrtc->initialized = false;
> > +}
> > +
> > 
> >  static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc)
> >  {
> >  
> >  	bool interlaced;
> > 
> > @@ -639,16 +651,7 @@ static void rcar_du_crtc_atomic_enable(struct
> > drm_crtc *crtc,> 
> >  {
> >  
> >  	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
> > 
> > -	/*
> > -	 * If the CRTC has already been setup by the .atomic_begin() handler we
> > -	 * can skip the setup stage.
> > -	 */
> > -	if (!rcrtc->initialized) {
> > -		rcar_du_crtc_get(rcrtc);
> > -		rcar_du_crtc_setup(rcrtc);
> > -		rcrtc->initialized = true;
> > -	}
> > -
> > +	rcar_du_crtc_get(rcrtc);
> > 
> >  	rcar_du_crtc_start(rcrtc);
> >  
> >  }
> > 
> > @@ -667,7 +670,6 @@ static void rcar_du_crtc_atomic_disable(struct
> > drm_crtc *crtc,> 
> >  	}
> >  	spin_unlock_irq(&crtc->dev->event_lock);
> > 
> > -	rcrtc->initialized = false;
> > 
> >  	rcrtc->outputs = 0;
> >  
> >  }
> > 
> > @@ -680,14 +682,17 @@ static void rcar_du_crtc_atomic_begin(struct
> > drm_crtc *crtc,> 
> >  	/*
> >  	
> >  	 * If a mode set is in progress we can be called with the CRTC 
disabled.
> > 
> > -	 * We then need to first setup the CRTC in order to configure planes.
> > -	 * The .atomic_enable() handler will notice and skip the CRTC setup.
> > +	 * We thus need to first get and setup the CRTC in order to configure
> > +	 * planes. We must *not* put the CRTC in .atomic_flush(), as it must be
> > +	 * kept awake until the .atomic_enable() call that will follow. The get
> > +	 * operation in .atomic_enable() will in that case be a no-op, and the
> > +	 * CRTC will be put later in .atomic_disable().
> > +	 *
> > +	 * If a mode set is not in progress the CRTC is enabled, and the
> > +	 * following get call will be a no-op. There is thus no need to belance
> 
> *balance
> 
> > +	 * it in .atomic_flush() either.
> > 
> >  	 */
> > 
> > -	if (!rcrtc->initialized) {
> > -		rcar_du_crtc_get(rcrtc);
> > -		rcar_du_crtc_setup(rcrtc);
> > -		rcrtc->initialized = true;
> > -	}
> > +	rcar_du_crtc_get(rcrtc);
> > 
> >  	if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
> >  	
> >  		rcar_du_vsp_atomic_begin(rcrtc);
> 
> With typo fixed:
> Reviewed-by: Ulrich Hecht <uli+renesas@fpond.eu>

-- 
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] 118+ messages in thread

* Re: [PATCH v2 07/16] drm: rcar-du: Use LVDS PLL clock as dot clock when possible
  2018-09-14  9:10   ` Laurent Pinchart
@ 2018-11-27  0:44     ` Kuninori Morimoto
  -1 siblings, 0 replies; 118+ messages in thread
From: Kuninori Morimoto @ 2018-11-27  0:44 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: dri-devel, linux-renesas-soc, Ulrich Hecht, Kieran Bingham,
	KOJI MATSUOKA


Hi Laurent

Sorry for super late response.
I got opinion from BSP team about this patch.

> On selected SoCs, the DU can use the clock output by the LVDS encoder
> PLL as its input dot clock. This feature is optional, but on the D3 and
> E3 SoC it is often the only way to obtain a precise dot clock frequency,
> as the other available clocks (CPG-generated clock and external clock)
> usually have fixed rates.
> 
> Add a DU model information field to describe which DU channels can use
> the LVDS PLL output clock as their input clock, and configure clock
> routing accordingly.
> 
> This feature is available on H2, M2-W, M2-N, D3 and E3 SoCs, with D3 and
> E3 being the primary targets. It is left disabled in this commit, and
> will be enabled per-SoC after careful testing.
> 
> At the hardware level, clock routing is configured at runtime in two
> steps, first selecting an internal dot clock between the LVDS PLL clock
> and the external DOTCLKIN clock, and then selecting between the internal
> dot clock and the CPG-generated clock. The first part requires stopping
> the whole DU group in order for the change to take effect, thus causing
> flickering on the screen. For this reason we currently hardcode the
> clock source to the LVDS PLL clock if available, and allow flicker-free
> selection of the external DOTCLKIN clock or CPG-generated clock
> otherwise. A more dynamic clock selection process can be implemented
> later if the need arises.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> ---
(snip)
> +	didsr = DIDSR_CODE;
> +	for (i = 0; i < num_crtcs; ++i, ++rcrtc) {
> +		if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index))
> +			didsr |= DIDSR_LCDS_LVDS0(i)
> +			      |  DIDSR_PDCS_CLK(i, 0);
> +		else
> +			didsr |= DIDSR_LCDS_DCLKIN(i)
> +			      |  DIDSR_PDCS_CLK(i, 0);
> +	}

Here, this is for DU pin settings, and fixed for

	DU_DOTCLKIN0 -> DU0
	DU_DOTCLKIN1 -> DU1

But on E3 (Ebisu) board, it has only DU_DOTCLKIN0.
We might use like this

	DU_DOTCLKIN0 -> DU0
	DU_DOTCLKIN0 -> DU1

It is possible to adjust to this situation ?
DIDSR :: PDCSn allows only 0

Best regards
---
Kuninori Morimoto

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

* Re: [PATCH v2 07/16] drm: rcar-du: Use LVDS PLL clock as dot clock when possible
@ 2018-11-27  0:44     ` Kuninori Morimoto
  0 siblings, 0 replies; 118+ messages in thread
From: Kuninori Morimoto @ 2018-11-27  0:44 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham, dri-devel,
	KOJI MATSUOKA


Hi Laurent

Sorry for super late response.
I got opinion from BSP team about this patch.

> On selected SoCs, the DU can use the clock output by the LVDS encoder
> PLL as its input dot clock. This feature is optional, but on the D3 and
> E3 SoC it is often the only way to obtain a precise dot clock frequency,
> as the other available clocks (CPG-generated clock and external clock)
> usually have fixed rates.
> 
> Add a DU model information field to describe which DU channels can use
> the LVDS PLL output clock as their input clock, and configure clock
> routing accordingly.
> 
> This feature is available on H2, M2-W, M2-N, D3 and E3 SoCs, with D3 and
> E3 being the primary targets. It is left disabled in this commit, and
> will be enabled per-SoC after careful testing.
> 
> At the hardware level, clock routing is configured at runtime in two
> steps, first selecting an internal dot clock between the LVDS PLL clock
> and the external DOTCLKIN clock, and then selecting between the internal
> dot clock and the CPG-generated clock. The first part requires stopping
> the whole DU group in order for the change to take effect, thus causing
> flickering on the screen. For this reason we currently hardcode the
> clock source to the LVDS PLL clock if available, and allow flicker-free
> selection of the external DOTCLKIN clock or CPG-generated clock
> otherwise. A more dynamic clock selection process can be implemented
> later if the need arises.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> ---
(snip)
> +	didsr = DIDSR_CODE;
> +	for (i = 0; i < num_crtcs; ++i, ++rcrtc) {
> +		if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index))
> +			didsr |= DIDSR_LCDS_LVDS0(i)
> +			      |  DIDSR_PDCS_CLK(i, 0);
> +		else
> +			didsr |= DIDSR_LCDS_DCLKIN(i)
> +			      |  DIDSR_PDCS_CLK(i, 0);
> +	}

Here, this is for DU pin settings, and fixed for

	DU_DOTCLKIN0 -> DU0
	DU_DOTCLKIN1 -> DU1

But on E3 (Ebisu) board, it has only DU_DOTCLKIN0.
We might use like this

	DU_DOTCLKIN0 -> DU0
	DU_DOTCLKIN0 -> DU1

It is possible to adjust to this situation ?
DIDSR :: PDCSn allows only 0

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

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

* Re: [PATCH v2 07/16] drm: rcar-du: Use LVDS PLL clock as dot clock when possible
  2018-11-27  0:44     ` Kuninori Morimoto
@ 2018-12-06  9:50       ` Laurent Pinchart
  -1 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-12-06  9:50 UTC (permalink / raw)
  To: Kuninori Morimoto
  Cc: Laurent Pinchart, dri-devel, linux-renesas-soc, Ulrich Hecht,
	Kieran Bingham, KOJI MATSUOKA

Hi Morimoto-san,

On Tuesday, 27 November 2018 02:44:58 EET Kuninori Morimoto wrote:
> Hi Laurent
> 
> Sorry for super late response.
> I got opinion from BSP team about this patch.

No worries. My reply is late too I'm afraid :-S

> > On selected SoCs, the DU can use the clock output by the LVDS encoder
> > PLL as its input dot clock. This feature is optional, but on the D3 and
> > E3 SoC it is often the only way to obtain a precise dot clock frequency,
> > as the other available clocks (CPG-generated clock and external clock)
> > usually have fixed rates.
> > 
> > Add a DU model information field to describe which DU channels can use
> > the LVDS PLL output clock as their input clock, and configure clock
> > routing accordingly.
> > 
> > This feature is available on H2, M2-W, M2-N, D3 and E3 SoCs, with D3 and
> > E3 being the primary targets. It is left disabled in this commit, and
> > will be enabled per-SoC after careful testing.
> > 
> > At the hardware level, clock routing is configured at runtime in two
> > steps, first selecting an internal dot clock between the LVDS PLL clock
> > and the external DOTCLKIN clock, and then selecting between the internal
> > dot clock and the CPG-generated clock. The first part requires stopping
> > the whole DU group in order for the change to take effect, thus causing
> > flickering on the screen. For this reason we currently hardcode the
> > clock source to the LVDS PLL clock if available, and allow flicker-free
> > selection of the external DOTCLKIN clock or CPG-generated clock
> > otherwise. A more dynamic clock selection process can be implemented
> > later if the need arises.
> > 
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> > Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> > ---
> 
> (snip)
> 
> > +	didsr = DIDSR_CODE;
> > +	for (i = 0; i < num_crtcs; ++i, ++rcrtc) {
> > +		if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index))
> > +			didsr |= DIDSR_LCDS_LVDS0(i)
> > +			      |  DIDSR_PDCS_CLK(i, 0);
> > +		else
> > +			didsr |= DIDSR_LCDS_DCLKIN(i)
> > +			      |  DIDSR_PDCS_CLK(i, 0);
> > +	}
> 
> Here, this is for DU pin settings, and fixed for
> 
> 	DU_DOTCLKIN0 -> DU0
> 	DU_DOTCLKIN1 -> DU1
> 
> But on E3 (Ebisu) board, it has only DU_DOTCLKIN0.
> We might use like this
> 
> 	DU_DOTCLKIN0 -> DU0
> 	DU_DOTCLKIN0 -> DU1
> 
> It is possible to adjust to this situation ?
> DIDSR :: PDCSn allows only 0

I think this would make sense. I'm not sure how to implement that, but I'll 
give it a try. What is the priority ?

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v2 07/16] drm: rcar-du: Use LVDS PLL clock as dot clock when possible
@ 2018-12-06  9:50       ` Laurent Pinchart
  0 siblings, 0 replies; 118+ messages in thread
From: Laurent Pinchart @ 2018-12-06  9:50 UTC (permalink / raw)
  To: Kuninori Morimoto
  Cc: Ulrich Hecht, Laurent Pinchart, Kieran Bingham, dri-devel,
	KOJI MATSUOKA, linux-renesas-soc

Hi Morimoto-san,

On Tuesday, 27 November 2018 02:44:58 EET Kuninori Morimoto wrote:
> Hi Laurent
> 
> Sorry for super late response.
> I got opinion from BSP team about this patch.

No worries. My reply is late too I'm afraid :-S

> > On selected SoCs, the DU can use the clock output by the LVDS encoder
> > PLL as its input dot clock. This feature is optional, but on the D3 and
> > E3 SoC it is often the only way to obtain a precise dot clock frequency,
> > as the other available clocks (CPG-generated clock and external clock)
> > usually have fixed rates.
> > 
> > Add a DU model information field to describe which DU channels can use
> > the LVDS PLL output clock as their input clock, and configure clock
> > routing accordingly.
> > 
> > This feature is available on H2, M2-W, M2-N, D3 and E3 SoCs, with D3 and
> > E3 being the primary targets. It is left disabled in this commit, and
> > will be enabled per-SoC after careful testing.
> > 
> > At the hardware level, clock routing is configured at runtime in two
> > steps, first selecting an internal dot clock between the LVDS PLL clock
> > and the external DOTCLKIN clock, and then selecting between the internal
> > dot clock and the CPG-generated clock. The first part requires stopping
> > the whole DU group in order for the change to take effect, thus causing
> > flickering on the screen. For this reason we currently hardcode the
> > clock source to the LVDS PLL clock if available, and allow flicker-free
> > selection of the external DOTCLKIN clock or CPG-generated clock
> > otherwise. A more dynamic clock selection process can be implemented
> > later if the need arises.
> > 
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> > Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> > ---
> 
> (snip)
> 
> > +	didsr = DIDSR_CODE;
> > +	for (i = 0; i < num_crtcs; ++i, ++rcrtc) {
> > +		if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index))
> > +			didsr |= DIDSR_LCDS_LVDS0(i)
> > +			      |  DIDSR_PDCS_CLK(i, 0);
> > +		else
> > +			didsr |= DIDSR_LCDS_DCLKIN(i)
> > +			      |  DIDSR_PDCS_CLK(i, 0);
> > +	}
> 
> Here, this is for DU pin settings, and fixed for
> 
> 	DU_DOTCLKIN0 -> DU0
> 	DU_DOTCLKIN1 -> DU1
> 
> But on E3 (Ebisu) board, it has only DU_DOTCLKIN0.
> We might use like this
> 
> 	DU_DOTCLKIN0 -> DU0
> 	DU_DOTCLKIN0 -> DU1
> 
> It is possible to adjust to this situation ?
> DIDSR :: PDCSn allows only 0

I think this would make sense. I'm not sure how to implement that, but I'll 
give it a try. What is the priority ?

-- 
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] 118+ messages in thread

* Re: [PATCH v2 07/16] drm: rcar-du: Use LVDS PLL clock as dot clock when possible
  2018-12-06  9:50       ` Laurent Pinchart
@ 2018-12-07  1:25         ` Kuninori Morimoto
  -1 siblings, 0 replies; 118+ messages in thread
From: Kuninori Morimoto @ 2018-12-07  1:25 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Laurent Pinchart, dri-devel, linux-renesas-soc, Ulrich Hecht,
	Kieran Bingham, KOJI MATSUOKA


Hi Laurent

> > > +	didsr = DIDSR_CODE;
> > > +	for (i = 0; i < num_crtcs; ++i, ++rcrtc) {
> > > +		if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index))
> > > +			didsr |= DIDSR_LCDS_LVDS0(i)
> > > +			      |  DIDSR_PDCS_CLK(i, 0);
> > > +		else
> > > +			didsr |= DIDSR_LCDS_DCLKIN(i)
> > > +			      |  DIDSR_PDCS_CLK(i, 0);
> > > +	}
> > 
> > Here, this is for DU pin settings, and fixed for
> > 
> > 	DU_DOTCLKIN0 -> DU0
> > 	DU_DOTCLKIN1 -> DU1
> > 
> > But on E3 (Ebisu) board, it has only DU_DOTCLKIN0.
> > We might use like this
> > 
> > 	DU_DOTCLKIN0 -> DU0
> > 	DU_DOTCLKIN0 -> DU1
> > 
> > It is possible to adjust to this situation ?
> > DIDSR :: PDCSn allows only 0
> 
> I think this would make sense. I'm not sure how to implement that, but I'll 
> give it a try. What is the priority ?

Normal priority is very OK, so far.
Thank you

Best regards
---
Kuninori Morimoto

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

* Re: [PATCH v2 07/16] drm: rcar-du: Use LVDS PLL clock as dot clock when possible
@ 2018-12-07  1:25         ` Kuninori Morimoto
  0 siblings, 0 replies; 118+ messages in thread
From: Kuninori Morimoto @ 2018-12-07  1:25 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Ulrich Hecht, Laurent Pinchart, Kieran Bingham, dri-devel,
	KOJI MATSUOKA, linux-renesas-soc


Hi Laurent

> > > +	didsr = DIDSR_CODE;
> > > +	for (i = 0; i < num_crtcs; ++i, ++rcrtc) {
> > > +		if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index))
> > > +			didsr |= DIDSR_LCDS_LVDS0(i)
> > > +			      |  DIDSR_PDCS_CLK(i, 0);
> > > +		else
> > > +			didsr |= DIDSR_LCDS_DCLKIN(i)
> > > +			      |  DIDSR_PDCS_CLK(i, 0);
> > > +	}
> > 
> > Here, this is for DU pin settings, and fixed for
> > 
> > 	DU_DOTCLKIN0 -> DU0
> > 	DU_DOTCLKIN1 -> DU1
> > 
> > But on E3 (Ebisu) board, it has only DU_DOTCLKIN0.
> > We might use like this
> > 
> > 	DU_DOTCLKIN0 -> DU0
> > 	DU_DOTCLKIN0 -> DU1
> > 
> > It is possible to adjust to this situation ?
> > DIDSR :: PDCSn allows only 0
> 
> I think this would make sense. I'm not sure how to implement that, but I'll 
> give it a try. What is the priority ?

Normal priority is very OK, so far.
Thank you

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

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

end of thread, other threads:[~2018-12-07  1:25 UTC | newest]

Thread overview: 118+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-14  9:10 [PATCH v2 00/16] R-Car D3/E3 display support (with LVDS PLL) Laurent Pinchart
2018-09-14  9:10 ` Laurent Pinchart
2018-09-14  9:10 ` [PATCH v2 01/16] dt-bindings: display: renesas: du: Document r8a77990 bindings Laurent Pinchart
2018-09-14  9:10   ` Laurent Pinchart
2018-09-17 10:53   ` Ulrich Hecht
2018-09-17 10:53     ` Ulrich Hecht
2018-09-14  9:10 ` [PATCH v2 02/16] dt-bindings: display: renesas: lvds: " Laurent Pinchart
2018-09-14  9:10   ` Laurent Pinchart
2018-09-17 10:53   ` Ulrich Hecht
2018-09-17 10:53     ` Ulrich Hecht
2018-09-24 11:36   ` Kieran Bingham
2018-09-24 11:36     ` Kieran Bingham
2018-09-14  9:10 ` [PATCH v2 03/16] dt-bindings: display: renesas: lvds: Add EXTAL and DU_DOTCLKIN clocks Laurent Pinchart
2018-09-14  9:10   ` Laurent Pinchart
2018-09-17 10:53   ` Ulrich Hecht
2018-09-17 10:53     ` Ulrich Hecht
2018-09-24 19:04   ` Kieran Bingham
2018-09-24 19:04     ` Kieran Bingham
2018-09-14  9:10 ` [PATCH v2 04/16] drm: bridge: thc63: Restrict modes based on hardware operating frequency Laurent Pinchart
2018-09-14  9:10   ` Laurent Pinchart
2018-09-17 10:53   ` Ulrich Hecht
2018-09-17 10:53     ` Ulrich Hecht
2018-09-17 12:23     ` Laurent Pinchart
2018-09-17 12:23       ` Laurent Pinchart
2018-09-14  9:10 ` [PATCH v2 05/16] drm: rcar-du: lvds: D3/E3 support Laurent Pinchart
2018-09-14  9:10   ` Laurent Pinchart
2018-09-17 10:53   ` Ulrich Hecht
2018-09-17 10:53     ` Ulrich Hecht
2018-09-17 12:41     ` Laurent Pinchart
2018-09-17 12:41       ` Laurent Pinchart
2018-09-17 12:49   ` jacopo mondi
2018-09-17 12:49     ` jacopo mondi
2018-09-14  9:10 ` [PATCH v2 06/16] drm: rcar-du: Perform the initial CRTC setup from rcar_du_crtc_get() Laurent Pinchart
2018-09-14  9:10   ` Laurent Pinchart
2018-09-17 12:50   ` jacopo mondi
2018-09-17 12:50     ` jacopo mondi
2018-09-26 15:55   ` Ulrich Hecht
2018-09-26 15:55     ` Ulrich Hecht
2018-09-28 15:14     ` Laurent Pinchart
2018-09-28 15:14       ` Laurent Pinchart
2018-09-14  9:10 ` [PATCH v2 07/16] drm: rcar-du: Use LVDS PLL clock as dot clock when possible Laurent Pinchart
2018-09-14  9:10   ` Laurent Pinchart
2018-09-17 12:55   ` jacopo mondi
2018-09-17 12:55     ` jacopo mondi
2018-09-26 15:55   ` Ulrich Hecht
2018-09-26 15:55     ` Ulrich Hecht
2018-11-27  0:44   ` Kuninori Morimoto
2018-11-27  0:44     ` Kuninori Morimoto
2018-12-06  9:50     ` Laurent Pinchart
2018-12-06  9:50       ` Laurent Pinchart
2018-12-07  1:25       ` Kuninori Morimoto
2018-12-07  1:25         ` Kuninori Morimoto
2018-09-14  9:10 ` [PATCH v2 08/16] drm: rcar-du: Enable configurable DPAD0 routing on Gen3 Laurent Pinchart
2018-09-14  9:10   ` Laurent Pinchart
2018-09-17 12:56   ` jacopo mondi
2018-09-17 12:56     ` jacopo mondi
2018-09-26 15:55   ` Ulrich Hecht
2018-09-26 15:55     ` Ulrich Hecht
2018-09-14  9:10 ` [PATCH v2 09/16] drm: rcar-du: Cache DSYSR value to ensure known initial value Laurent Pinchart
2018-09-14  9:10   ` Laurent Pinchart
2018-09-24 11:18   ` Kieran Bingham
2018-09-24 11:18     ` Kieran Bingham
2018-09-26 15:55   ` Ulrich Hecht
2018-09-26 15:55     ` Ulrich Hecht
2018-09-14  9:10 ` [PATCH v2 10/16] drm: rcar-du: Don't use TV sync mode when not supported by the hardware Laurent Pinchart
2018-09-14  9:10   ` Laurent Pinchart
2018-09-24 11:26   ` Kieran Bingham
2018-09-24 11:26     ` Kieran Bingham
2018-09-26 15:55   ` Ulrich Hecht
2018-09-26 15:55     ` Ulrich Hecht
2018-09-14  9:10 ` [PATCH v2 11/16] drm: rcar-du: Add r8a77990 and r8a77995 device support Laurent Pinchart
2018-09-14  9:10   ` Laurent Pinchart
2018-09-24 11:41   ` Kieran Bingham
2018-09-24 11:41     ` Kieran Bingham
2018-09-14  9:10 ` [PATCH v2 12/16] arm64: dts: renesas: r8a77990: Add I2C device nodes Laurent Pinchart
2018-09-14  9:10   ` Laurent Pinchart
2018-09-17  7:33   ` Simon Horman
2018-09-17  7:33     ` Simon Horman
2018-09-17  8:08     ` Laurent Pinchart
2018-09-17  8:08       ` Laurent Pinchart
2018-09-14  9:10 ` [PATCH v2 13/16] arm64: dts: renesas: r8a77990: Add display output support Laurent Pinchart
2018-09-14  9:10   ` Laurent Pinchart
2018-09-17  7:50   ` Simon Horman
2018-09-17  7:50     ` Simon Horman
2018-09-17  8:14     ` Simon Horman
2018-09-17  8:14       ` Simon Horman
2018-09-17  8:47       ` Laurent Pinchart
2018-09-17  8:47         ` Laurent Pinchart
2018-09-17  8:54         ` Laurent Pinchart
2018-09-17  8:54           ` Laurent Pinchart
2018-09-17  8:59           ` Laurent Pinchart
2018-09-17  8:59             ` Laurent Pinchart
2018-09-19  8:35             ` Simon Horman
2018-09-19  8:35               ` Simon Horman
2018-09-19 13:11               ` Laurent Pinchart
2018-09-19 13:11                 ` Laurent Pinchart
2018-09-21  7:16                 ` Simon Horman
2018-09-21  7:16                   ` Simon Horman
2018-09-21  8:41                   ` Laurent Pinchart
2018-09-21  8:41                     ` Laurent Pinchart
2018-09-17  8:38     ` Laurent Pinchart
2018-09-17  8:38       ` Laurent Pinchart
2018-09-17  8:51       ` Simon Horman
2018-09-17  8:51         ` Simon Horman
2018-09-17  9:08         ` Laurent Pinchart
2018-09-17  9:08           ` Laurent Pinchart
2018-09-17  9:48           ` Geert Uytterhoeven
2018-09-17  9:48             ` Geert Uytterhoeven
2018-09-17 10:01             ` Laurent Pinchart
2018-09-17 10:01               ` Laurent Pinchart
2018-09-14  9:10 ` [PATCH v2 14/16] arm64: dts: renesas: r8a77995: Add LVDS support Laurent Pinchart
2018-09-14  9:10   ` Laurent Pinchart
2018-09-14  9:10 ` [PATCH v2 15/16] arm64: dts: renesas: r8a77990: ebisu: Enable VGA and HDMI outputs Laurent Pinchart
2018-09-14  9:10   ` Laurent Pinchart
2018-09-26 15:55   ` Ulrich Hecht
2018-09-26 15:55     ` Ulrich Hecht
2018-09-14  9:10 ` [PATCH v2 16/16] arm64: dts: renesas: r8a77995: draak: Enable HDMI display output Laurent Pinchart
2018-09-14  9:10   ` Laurent Pinchart

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.