cip-dev.lists.cip-project.org archive mirror
 help / color / mirror / Atom feed
* [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874
@ 2019-10-01  8:24 Fabrizio Castro
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 01/32] media: vsp1: Add RZ/G support Fabrizio Castro
                   ` (33 more replies)
  0 siblings, 34 replies; 35+ messages in thread
From: Fabrizio Castro @ 2019-10-01  8:24 UTC (permalink / raw)
  To: cip-dev

Dear All,

this series adds HDMI video and audio support to the EK874 board.

Thanks,
Fab

Christophe JAILLET (1):
  drm: rcar-du: Fix the return value in case of error in
    'rcar_du_crtc_set_crc_source()'

Fabrizio Castro (10):
  media: vsp1: Add RZ/G support
  media: dt-bindings: media: renesas-fcp: Add RZ/G2 support
  dt-bindings: display: renesas: du: Document r8a774c0 bindings
  dt-bindings: display: renesas: lvds: Document r8a774c0 bindings
  drm: rcar-du: Add r8a774c0 device support
  drm: rcar-du: lvds: add R8A774C0 support
  arm64: dts: renesas: r8a774c0: Add display output support
  arm64: defconfig: Enable TDA19988
  arm64: dts: renesas: cat874: Add HDMI video support
  arm64: dts: renesas: cat874: Add HDMI audio

Jacopo Mondi (1):
  drm: rcar-du: Improve non-DPLL clock selection

Laurent Pinchart (17):
  dt-bindings: display: renesas: lvds: Add EXTAL and DU_DOTCLKIN clocks
  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: Move CRTC outputs bitmask to private CRTC state
  drm: rcar-du: Simplify encoder registration
  drm: rcar-du: lvds: Don't fail probe if output is not connected on
    D3/E3
  drm: rcar-du: lvds: Add API to enable/disable clock output
  drm: rcar-du: Turn LVDS clock output on/off for DPAD0 output on D3/E3
  drm: rcar-du: lvds: Fix post-DLL divider calculation
  drm: rcar-du: lvds: Adjust operating frequency for D3 and E3
  drm: rcar-du: Enable configurable DPAD0 routing on Gen3
  drm: rcar-du: Fix vblank initialization
  drm: rcar-du: Fix external clock error checks
  drm: rcar-du: Reject modes that fail CRTC timing requirements
  drm: rcar-du: Disable unused DPAD outputs
  drm: rcar-du: Replace EXT_CTRL_REGS feature flag with generation check

Mauro Carvalho Chehab (1):
  media: use strscpy() instead of strlcpy()

Noralf Tr?nnes (1):
  drm/rcar-du: Use drm_fbdev_generic_setup()

Thomas Zimmermann (1):
  drm/rcar-du: Replace drm_dev_unref with drm_dev_put

 .../bindings/display/bridge/renesas,lvds.txt       |  12 +-
 .../devicetree/bindings/display/renesas,du.txt     |   2 +
 .../devicetree/bindings/media/renesas,fcp.txt      |   5 +-
 .../devicetree/bindings/media/renesas,vsp1.txt     |   6 +-
 arch/arm64/boot/dts/renesas/r8a774c0-cat874.dts    | 137 +++++++
 arch/arm64/boot/dts/renesas/r8a774c0.dtsi          | 167 ++++++++
 arch/arm64/configs/defconfig                       |   1 +
 drivers/gpu/drm/Makefile                           |   2 +-
 drivers/gpu/drm/rcar-du/Kconfig                    |   1 +
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c             | 294 +++++++++-----
 drivers/gpu/drm/rcar-du/rcar_du_crtc.h             |   7 +-
 drivers/gpu/drm/rcar-du/rcar_du_drv.c              |  55 +--
 drivers/gpu/drm/rcar-du/rcar_du_drv.h              |  14 +-
 drivers/gpu/drm/rcar-du/rcar_du_encoder.c          |  14 +-
 drivers/gpu/drm/rcar-du/rcar_du_encoder.h          |   3 +-
 drivers/gpu/drm/rcar-du/rcar_du_group.c            | 132 ++++--
 drivers/gpu/drm/rcar-du/rcar_du_kms.c              | 109 ++---
 drivers/gpu/drm/rcar-du/rcar_du_vsp.c              |   1 -
 drivers/gpu/drm/rcar-du/rcar_lvds.c                | 441 ++++++++++++++++++---
 drivers/gpu/drm/rcar-du/rcar_lvds.h                |  27 ++
 drivers/gpu/drm/rcar-du/rcar_lvds_regs.h           |  43 +-
 drivers/media/platform/vsp1/vsp1_drv.c             |   2 +-
 22 files changed, 1163 insertions(+), 312 deletions(-)
 create mode 100644 drivers/gpu/drm/rcar-du/rcar_lvds.h

-- 
2.7.4

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

* [cip-dev] [PATCH 4.19.y-cip 01/32] media: vsp1: Add RZ/G support
  2019-10-01  8:24 [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874 Fabrizio Castro
@ 2019-10-01  8:25 ` Fabrizio Castro
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 02/32] media: dt-bindings: media: renesas-fcp: Add RZ/G2 support Fabrizio Castro
                   ` (32 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: Fabrizio Castro @ 2019-10-01  8:25 UTC (permalink / raw)
  To: cip-dev

commit e260d78736db0c74240df2243c299be7b0d0b182 upstream.

Document RZ/G1 and RZ/G2 support.

Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
---
 Documentation/devicetree/bindings/media/renesas,vsp1.txt | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/media/renesas,vsp1.txt b/Documentation/devicetree/bindings/media/renesas,vsp1.txt
index 1642701..cd5a955 100644
--- a/Documentation/devicetree/bindings/media/renesas,vsp1.txt
+++ b/Documentation/devicetree/bindings/media/renesas,vsp1.txt
@@ -2,13 +2,13 @@
 
 The VSP is a video processing engine that supports up-/down-scaling, alpha
 blending, color space conversion and various other image processing features.
-It can be found in the Renesas R-Car second generation SoCs.
+It can be found in the Renesas R-Car Gen2, R-Car Gen3, RZ/G1, and RZ/G2 SoCs.
 
 Required properties:
 
   - compatible: Must contain one of the following values
-    - "renesas,vsp1" for the R-Car Gen2 VSP1
-    - "renesas,vsp2" for the R-Car Gen3 VSP2
+    - "renesas,vsp1" for the R-Car Gen2 and RZ/G1 VSP1
+    - "renesas,vsp2" for the R-Car Gen3 and RZ/G2 VSP2
 
   - reg: Base address and length of the registers block for the VSP.
   - interrupts: VSP interrupt specifier.
-- 
2.7.4

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

* [cip-dev] [PATCH 4.19.y-cip 02/32] media: dt-bindings: media: renesas-fcp: Add RZ/G2 support
  2019-10-01  8:24 [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874 Fabrizio Castro
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 01/32] media: vsp1: Add RZ/G support Fabrizio Castro
@ 2019-10-01  8:25 ` Fabrizio Castro
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 03/32] dt-bindings: display: renesas: du: Document r8a774c0 bindings Fabrizio Castro
                   ` (31 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: Fabrizio Castro @ 2019-10-01  8:25 UTC (permalink / raw)
  To: cip-dev

commit b8eb83457e79fc745abea3abcd6c95b1428a05ee upstream.

Document RZ/G2 support.

Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
---
 Documentation/devicetree/bindings/media/renesas,fcp.txt | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/media/renesas,fcp.txt b/Documentation/devicetree/bindings/media/renesas,fcp.txt
index 3ec9180..79c3739 100644
--- a/Documentation/devicetree/bindings/media/renesas,fcp.txt
+++ b/Documentation/devicetree/bindings/media/renesas,fcp.txt
@@ -2,8 +2,9 @@ Renesas R-Car Frame Compression Processor (FCP)
 -----------------------------------------------
 
 The FCP is a companion module of video processing modules in the Renesas R-Car
-Gen3 SoCs. It provides data compression and decompression, data caching, and
-conversion of AXI transactions in order to reduce the memory bandwidth.
+Gen3 and RZ/G2 SoCs. It provides data compression and decompression, data
+caching, and conversion of AXI transactions in order to reduce the memory
+bandwidth.
 
 There are three types of FCP: FCP for Codec (FCPC), FCP for VSP (FCPV) and FCP
 for FDP (FCPF). Their configuration and behaviour depend on the module they
-- 
2.7.4

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

* [cip-dev] [PATCH 4.19.y-cip 03/32] dt-bindings: display: renesas: du: Document r8a774c0 bindings
  2019-10-01  8:24 [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874 Fabrizio Castro
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 01/32] media: vsp1: Add RZ/G support Fabrizio Castro
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 02/32] media: dt-bindings: media: renesas-fcp: Add RZ/G2 support Fabrizio Castro
@ 2019-10-01  8:25 ` Fabrizio Castro
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 04/32] dt-bindings: display: renesas: lvds: Add EXTAL and DU_DOTCLKIN clocks Fabrizio Castro
                   ` (30 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: Fabrizio Castro @ 2019-10-01  8:25 UTC (permalink / raw)
  To: cip-dev

commit 8c9fde42c5d386165d96593d8cc16fca48813589 upstream.

Document the RZ/G2E (a.k.a. r8a774c0) SoC in the R-Car DU bindings.

Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
[fab: backported to v4.19,y-cip]
Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
---
 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 e01acc6..8f9d65c 100644
--- a/Documentation/devicetree/bindings/display/renesas,du.txt
+++ b/Documentation/devicetree/bindings/display/renesas,du.txt
@@ -6,6 +6,7 @@ Required Properties:
     - "renesas,du-r8a7743" for R8A7743 (RZ/G1M) compatible DU
     - "renesas,du-r8a7745" for R8A7745 (RZ/G1E) compatible DU
     - "renesas,du-r8a774a1" for R8A774A1 (RZ/G2M) compatible DU
+    - "renesas,du-r8a774c0" for R8A774C0 (RZ/G2E) compatible DU
     - "renesas,du-r8a7779" for R8A7779 (R-Car H1) compatible DU
     - "renesas,du-r8a7790" for R8A7790 (R-Car H2) compatible DU
     - "renesas,du-r8a7791" for R8A7791 (R-Car M2-W) compatible DU
@@ -53,6 +54,7 @@ corresponding to each DU output.
  R8A7743 (RZ/G1M)       DPAD 0         LVDS 0         -              -
  R8A7745 (RZ/G1E)       DPAD 0         DPAD 1         -              -
  R8A774A1 (RZ/G2M)      DPAD 0         HDMI 0         LVDS 0         -
+ R8A774C0 (RZ/G2E)      DPAD 0         LVDS 0         LVDS 1         -
  R8A7779 (R-Car H1)     DPAD 0         DPAD 1         -              -
  R8A7790 (R-Car H2)     DPAD 0         LVDS 0         LVDS 1         -
  R8A7791 (R-Car M2-W)   DPAD 0         LVDS 0         -              -
-- 
2.7.4

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

* [cip-dev] [PATCH 4.19.y-cip 04/32] dt-bindings: display: renesas: lvds: Add EXTAL and DU_DOTCLKIN clocks
  2019-10-01  8:24 [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874 Fabrizio Castro
                   ` (2 preceding siblings ...)
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 03/32] dt-bindings: display: renesas: du: Document r8a774c0 bindings Fabrizio Castro
@ 2019-10-01  8:25 ` Fabrizio Castro
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 05/32] dt-bindings: display: renesas: lvds: Document r8a774c0 bindings Fabrizio Castro
                   ` (29 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: Fabrizio Castro @ 2019-10-01  8:25 UTC (permalink / raw)
  To: cip-dev

From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

commit 9734a7009de62c05e9b08fa65efb7c5214ab3f30 upstream.

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>
Reviewed-by: Ulrich Hecht <uli+renesas@fpond.eu>
Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
[fab: removed reference to r8a77990]
Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
---
 .../devicetree/bindings/display/bridge/renesas,lvds.txt       | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
index 3ede032..77912c6 100644
--- a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
+++ b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
@@ -18,7 +18,16 @@ 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 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:
-- 
2.7.4

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

* [cip-dev] [PATCH 4.19.y-cip 05/32] dt-bindings: display: renesas: lvds: Document r8a774c0 bindings
  2019-10-01  8:24 [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874 Fabrizio Castro
                   ` (3 preceding siblings ...)
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 04/32] dt-bindings: display: renesas: lvds: Add EXTAL and DU_DOTCLKIN clocks Fabrizio Castro
@ 2019-10-01  8:25 ` Fabrizio Castro
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 06/32] drm: rcar-du: lvds: D3/E3 support Fabrizio Castro
                   ` (28 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: Fabrizio Castro @ 2019-10-01  8:25 UTC (permalink / raw)
  To: cip-dev

commit 1cac4f267b60ae9c8ce17a85c4bd9a8c6d760f83 upstream.

The RZ/G2E (r8a774c0) supports two LVDS channels. Extend the binding to
support them.

Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
[fab: backported to v4.19.y-cip]
Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
---
 Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
index 77912c6..d06c25e 100644
--- a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
+++ b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
@@ -9,6 +9,7 @@ Required properties:
 - compatible : Shall contain one of
   - "renesas,r8a7743-lvds" for R8A7743 (RZ/G1M) compatible LVDS encoders
   - "renesas,r8a774a1-lvds" for R8A774A1 (RZ/G2M) compatible LVDS encoders
+  - "renesas,r8a774c0-lvds" for R8A774C0 (RZ/G2E) compatible LVDS encoders
   - "renesas,r8a7790-lvds" for R8A7790 (R-Car H2) compatible LVDS encoders
   - "renesas,r8a7791-lvds" for R8A7791 (R-Car M2-W) compatible LVDS encoders
   - "renesas,r8a7793-lvds" for R8A7793 (R-Car M2-N) compatible LVDS encoders
@@ -23,9 +24,9 @@ Required properties:
 - 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 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.
+  - On R8A77995 and R8A774C0, 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
-- 
2.7.4

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

* [cip-dev] [PATCH 4.19.y-cip 06/32] drm: rcar-du: lvds: D3/E3 support
  2019-10-01  8:24 [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874 Fabrizio Castro
                   ` (4 preceding siblings ...)
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 05/32] dt-bindings: display: renesas: lvds: Document r8a774c0 bindings Fabrizio Castro
@ 2019-10-01  8:25 ` Fabrizio Castro
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 07/32] drm: rcar-du: Perform the initial CRTC setup from rcar_du_crtc_get() Fabrizio Castro
                   ` (27 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: Fabrizio Castro @ 2019-10-01  8:25 UTC (permalink / raw)
  To: cip-dev

From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

commit c25c0136119990c62c160d95592714833bc214a5 upstream.

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>
Reviewed-by: Ulrich Hecht <uli+renesas@fpond.eu>
Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
[fab: removed compatible strings related to r8a77990 and r8a77995]
Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
---
 drivers/gpu/drm/rcar-du/rcar_lvds.c      | 357 +++++++++++++++++++++++++++----
 drivers/gpu/drm/rcar-du/rcar_lvds_regs.h |  43 +++-
 2 files changed, 353 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c b/drivers/gpu/drm/rcar-du/rcar_lvds.c
index 61a1dc2..00d2fb3 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,216 @@ 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 (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)
+		/*
+		 * The DIVRESET bit is a misnomer, setting it to 1 deasserts the
+		 * divisor reset.
+		 */
+		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 +355,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 +386,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 +411,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 +432,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 +462,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 +645,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 +728,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 +748,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[] = {
diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h b/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
index 2896835..2b959f0 100644
--- a/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
+++ b/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
@@ -21,7 +21,7 @@
 #define LVDCR0_PLLON			(1 << 4)
 #define LVDCR0_PWD			(1 << 2)		/* Gen3 only */
 #define LVDCR0_BEN			(1 << 2)		/* Gen2 only */
-#define LVDCR0_LVEN			(1 << 1)		/* Gen2 only */
+#define LVDCR0_LVEN			(1 << 1)
 #define LVDCR0_LVRES			(1 << 0)
 
 #define LVDCR1				0x0004
@@ -30,21 +30,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)
@@ -74,4 +89,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__ */
-- 
2.7.4

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

* [cip-dev] [PATCH 4.19.y-cip 07/32] drm: rcar-du: Perform the initial CRTC setup from rcar_du_crtc_get()
  2019-10-01  8:24 [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874 Fabrizio Castro
                   ` (5 preceding siblings ...)
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 06/32] drm: rcar-du: lvds: D3/E3 support Fabrizio Castro
@ 2019-10-01  8:25 ` Fabrizio Castro
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 08/32] drm: rcar-du: Use LVDS PLL clock as dot clock when possible Fabrizio Castro
                   ` (26 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: Fabrizio Castro @ 2019-10-01  8:25 UTC (permalink / raw)
  To: cip-dev

From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

commit 0bb63534fdf3bc9a82bcfe9f5c6a9653b8b2a3f1 upstream.

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>
Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
---
 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 107cbf2..57cdc5f 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -69,39 +69,6 @@ void rcar_du_crtc_dsysr_clr_set(struct rcar_du_crtc *rcrtc, u32 clr, u32 set)
 	rcar_du_write(rcdu, rcrtc->mmio_offset + DSYSR, rcrtc->dsysr);
 }
 
-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
  */
@@ -527,6 +494,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;
@@ -625,16 +637,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);
 }
 
@@ -653,7 +656,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;
 }
 
@@ -666,14 +668,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);
-- 
2.7.4

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

* [cip-dev] [PATCH 4.19.y-cip 08/32] drm: rcar-du: Use LVDS PLL clock as dot clock when possible
  2019-10-01  8:24 [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874 Fabrizio Castro
                   ` (6 preceding siblings ...)
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 07/32] drm: rcar-du: Perform the initial CRTC setup from rcar_du_crtc_get() Fabrizio Castro
@ 2019-10-01  8:25 ` Fabrizio Castro
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 09/32] drm: rcar-du: Add r8a774c0 device support Fabrizio Castro
                   ` (25 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: Fabrizio Castro @ 2019-10-01  8:25 UTC (permalink / raw)
  To: cip-dev

From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

commit b4734f43f3cadfaa423ce6aceb1e9faea07b8eb8 upstream.

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>
Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
---
 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 57cdc5f..c330730 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -223,6 +223,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 {
 		unsigned long clk;
 		u32 div;
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
index a6e6316..7edf4a9 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
@@ -58,6 +58,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;
@@ -67,6 +68,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 5966d94..15dbef3 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
@@ -93,6 +93,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;
@@ -110,21 +158,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)
-- 
2.7.4

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

* [cip-dev] [PATCH 4.19.y-cip 09/32] drm: rcar-du: Add r8a774c0 device support
  2019-10-01  8:24 [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874 Fabrizio Castro
                   ` (7 preceding siblings ...)
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 08/32] drm: rcar-du: Use LVDS PLL clock as dot clock when possible Fabrizio Castro
@ 2019-10-01  8:25 ` Fabrizio Castro
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 10/32] drm: rcar-du: lvds: add R8A774C0 support Fabrizio Castro
                   ` (24 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: Fabrizio Castro @ 2019-10-01  8:25 UTC (permalink / raw)
  To: cip-dev

commit 939ef2a586e5f7bce4e4465cfd5afe7758fb9f74 upstream.

Add support for the RZ/G2E (R8A774C0) SoC to the R-Car DU driver.

Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/gpu/drm/rcar-du/rcar_du_drv.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
index 5380f0e..708ebd9 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
@@ -110,6 +110,32 @@ static const struct rcar_du_device_info rcar_du_r8a774a1_info = {
 	.dpll_mask =  BIT(1),
 };
 
+static const struct rcar_du_device_info rcar_du_r8a774c0_info = {
+	.gen = 3,
+	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
+		  | RCAR_DU_FEATURE_VSP1_SOURCE,
+	.channels_mask = BIT(1) | BIT(0),
+	.routes = {
+		/*
+		 * R8A774C0 has 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 rcar_du_device_info rcar_du_r8a7779_info = {
 	.gen = 2,
 	.features = RCAR_DU_FEATURE_INTERLACED
@@ -348,6 +374,7 @@ 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 },
 	{ .compatible = "renesas,du-r8a774a1", .data = &rcar_du_r8a774a1_info },
+	{ .compatible = "renesas,du-r8a774c0", .data = &rcar_du_r8a774c0_info },
 	{ .compatible = "renesas,du-r8a7779", .data = &rcar_du_r8a7779_info },
 	{ .compatible = "renesas,du-r8a7790", .data = &rcar_du_r8a7790_info },
 	{ .compatible = "renesas,du-r8a7791", .data = &rcar_du_r8a7791_info },
-- 
2.7.4

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

* [cip-dev] [PATCH 4.19.y-cip 10/32] drm: rcar-du: lvds: add R8A774C0 support
  2019-10-01  8:24 [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874 Fabrizio Castro
                   ` (8 preceding siblings ...)
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 09/32] drm: rcar-du: Add r8a774c0 device support Fabrizio Castro
@ 2019-10-01  8:25 ` Fabrizio Castro
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 11/32] drm: rcar-du: Move CRTC outputs bitmask to private CRTC state Fabrizio Castro
                   ` (23 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: Fabrizio Castro @ 2019-10-01  8:25 UTC (permalink / raw)
  To: cip-dev

commit 90b5f679ef16e7461a2ff4ea11495541a5f6fe93 upstream.

The LVDS implementation on the RZ/G2E (a.k.a. R8A774C0) is very similar
to the one found on R-Car E3 (a.k.a. R8A77990), therefore add RZ/G2E
LVDS support to the LVDS encoder driver in a similar fashion to what is
done for R-Car E3.

Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
[fab: backported to v4.19.y-cip]
Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
---
 drivers/gpu/drm/rcar-du/rcar_lvds.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c b/drivers/gpu/drm/rcar-du/rcar_lvds.c
index 00d2fb3..694a627 100644
--- a/drivers/gpu/drm/rcar-du/rcar_lvds.c
+++ b/drivers/gpu/drm/rcar-du/rcar_lvds.c
@@ -786,6 +786,7 @@ static const struct rcar_lvds_device_info rcar_lvds_r8a77995_info = {
 static const struct of_device_id rcar_lvds_of_table[] = {
 	{ .compatible = "renesas,r8a7743-lvds", .data = &rcar_lvds_gen2_info },
 	{ .compatible = "renesas,r8a774a1-lvds", .data = &rcar_lvds_gen3_info },
+	{ .compatible = "renesas,r8a774c0-lvds", .data = &rcar_lvds_r8a77990_info },
 	{ .compatible = "renesas,r8a7790-lvds", .data = &rcar_lvds_r8a7790_info },
 	{ .compatible = "renesas,r8a7791-lvds", .data = &rcar_lvds_gen2_info },
 	{ .compatible = "renesas,r8a7793-lvds", .data = &rcar_lvds_gen2_info },
-- 
2.7.4

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

* [cip-dev] [PATCH 4.19.y-cip 11/32] drm: rcar-du: Move CRTC outputs bitmask to private CRTC state
  2019-10-01  8:24 [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874 Fabrizio Castro
                   ` (9 preceding siblings ...)
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 10/32] drm: rcar-du: lvds: add R8A774C0 support Fabrizio Castro
@ 2019-10-01  8:25 ` Fabrizio Castro
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 12/32] drm: rcar-du: Simplify encoder registration Fabrizio Castro
                   ` (22 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: Fabrizio Castro @ 2019-10-01  8:25 UTC (permalink / raw)
  To: cip-dev

From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

commit b8a43032a7b8d7e8e7c65dfa987d8374a0de7a6e upstream.

The rcar_du_crtc outputs field stores a bitmask of the outputs driven by
the CRTC. This changes based on the configuration requested by
userspace, and is used for the sole purpose of configuring the hardware.
The field thus belongs to the CRTC state. Move it to the
rcar_du_crtc_state structure.

As a result the rcar_du_crtc_route_output() function loses most of its
purpose. In order to remove it, move dpad0_source calculation to
rcar_du_atomic_commit_tail(), until the field gets moved to a state
structure. In order to simplify the rcar_du_group_set_routing()
implementation, we also store the DPAD1 source in a new dpad1_source
field which will move to a state structure with dpad0_source.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
---
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c    | 42 +++++++++++++++----------------
 drivers/gpu/drm/rcar-du/rcar_du_crtc.h    |  7 ++----
 drivers/gpu/drm/rcar-du/rcar_du_drv.h     |  1 +
 drivers/gpu/drm/rcar-du/rcar_du_encoder.c | 10 --------
 drivers/gpu/drm/rcar-du/rcar_du_group.c   |  4 +--
 drivers/gpu/drm/rcar-du/rcar_du_kms.c     | 22 ++++++++++++++++
 6 files changed, 47 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index c330730..d679818 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -26,6 +26,7 @@
 
 #include "rcar_du_crtc.h"
 #include "rcar_du_drv.h"
+#include "rcar_du_encoder.h"
 #include "rcar_du_kms.h"
 #include "rcar_du_plane.h"
 #include "rcar_du_regs.h"
@@ -301,26 +302,6 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
 	rcar_du_crtc_write(rcrtc, DEWR,  mode->hdisplay);
 }
 
-void rcar_du_crtc_route_output(struct drm_crtc *crtc,
-			       enum rcar_du_output output)
-{
-	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
-	struct rcar_du_device *rcdu = rcrtc->group->dev;
-
-	/*
-	 * Store the route from the CRTC output to the DU output. The DU will be
-	 * configured when starting the CRTC.
-	 */
-	rcrtc->outputs |= BIT(output);
-
-	/*
-	 * Store RGB routing to DPAD0, the hardware will be configured when
-	 * starting the CRTC.
-	 */
-	if (output == RCAR_DU_OUTPUT_DPAD0)
-		rcdu->dpad0_source = rcrtc->index;
-}
-
 static unsigned int plane_zpos(struct rcar_du_plane *plane)
 {
 	return plane->plane.state->normalized_zpos;
@@ -640,6 +621,24 @@ static void rcar_du_crtc_stop(struct rcar_du_crtc *rcrtc)
  * CRTC Functions
  */
 
+static int rcar_du_crtc_atomic_check(struct drm_crtc *crtc,
+				     struct drm_crtc_state *state)
+{
+	struct rcar_du_crtc_state *rstate = to_rcar_crtc_state(state);
+	struct drm_encoder *encoder;
+
+	/* Store the routes from the CRTC output to the DU outputs. */
+	rstate->outputs = 0;
+
+	drm_for_each_encoder_mask(encoder, crtc->dev, state->encoder_mask) {
+		struct rcar_du_encoder *renc = to_rcar_encoder(encoder);
+
+		rstate->outputs |= BIT(renc->output);
+	}
+
+	return 0;
+}
+
 static void rcar_du_crtc_atomic_enable(struct drm_crtc *crtc,
 				       struct drm_crtc_state *old_state)
 {
@@ -663,8 +662,6 @@ static void rcar_du_crtc_atomic_disable(struct drm_crtc *crtc,
 		crtc->state->event = NULL;
 	}
 	spin_unlock_irq(&crtc->dev->event_lock);
-
-	rcrtc->outputs = 0;
 }
 
 static void rcar_du_crtc_atomic_begin(struct drm_crtc *crtc,
@@ -728,6 +725,7 @@ enum drm_mode_status rcar_du_crtc_mode_valid(struct drm_crtc *crtc,
 }
 
 static const struct drm_crtc_helper_funcs crtc_helper_funcs = {
+	.atomic_check = rcar_du_crtc_atomic_check,
 	.atomic_begin = rcar_du_crtc_atomic_begin,
 	.atomic_flush = rcar_du_crtc_atomic_flush,
 	.atomic_enable = rcar_du_crtc_atomic_enable,
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
index 2c1eaa3..6baa4c0 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
@@ -41,7 +41,6 @@ struct rcar_du_vsp;
  * @vblank_lock: protects vblank_wait and vblank_count
  * @vblank_wait: wait queue used to signal vertical blanking
  * @vblank_count: number of vertical blanking interrupts to wait for
- * @outputs: bitmask of the outputs (enum rcar_du_output) driven by this CRTC
  * @group: CRTC group this CRTC belongs to
  * @vsp: VSP feeding video to this CRTC
  * @vsp_pipe: index of the VSP pipeline feeding video to this CRTC
@@ -65,8 +64,6 @@ struct rcar_du_crtc {
 	wait_queue_head_t vblank_wait;
 	unsigned int vblank_count;
 
-	unsigned int outputs;
-
 	struct rcar_du_group *group;
 	struct rcar_du_vsp *vsp;
 	unsigned int vsp_pipe;
@@ -78,11 +75,13 @@ struct rcar_du_crtc {
  * struct rcar_du_crtc_state - Driver-specific CRTC state
  * @state: base DRM CRTC state
  * @crc: CRC computation configuration
+ * @outputs: bitmask of the outputs (enum rcar_du_output) driven by this CRTC
  */
 struct rcar_du_crtc_state {
 	struct drm_crtc_state state;
 
 	struct vsp1_du_crc_config crc;
+	unsigned int outputs;
 };
 
 #define to_rcar_crtc_state(s) container_of(s, struct rcar_du_crtc_state, state)
@@ -103,8 +102,6 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int swindex,
 void rcar_du_crtc_suspend(struct rcar_du_crtc *rcrtc);
 void rcar_du_crtc_resume(struct rcar_du_crtc *rcrtc);
 
-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);
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
index 7edf4a9..d9cf398 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
@@ -96,6 +96,7 @@ struct rcar_du_device {
 	} props;
 
 	unsigned int dpad0_source;
+	unsigned int dpad1_source;
 	unsigned int vspd1_sink;
 };
 
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
index f9c933d..0ffa6d6 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
@@ -26,17 +26,7 @@
  * Encoder
  */
 
-static void rcar_du_encoder_mode_set(struct drm_encoder *encoder,
-				     struct drm_crtc_state *crtc_state,
-				     struct drm_connector_state *conn_state)
-{
-	struct rcar_du_encoder *renc = to_rcar_encoder(encoder);
-
-	rcar_du_crtc_route_output(crtc_state->crtc, renc->output);
-}
-
 static const struct drm_encoder_helper_funcs encoder_helper_funcs = {
-	.atomic_mode_set = rcar_du_encoder_mode_set,
 };
 
 static const struct drm_encoder_funcs encoder_funcs = {
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c
index 15dbef3..d35743f 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
@@ -283,7 +283,7 @@ int rcar_du_set_dpad0_vsp1_routing(struct rcar_du_device *rcdu)
 
 int rcar_du_group_set_routing(struct rcar_du_group *rgrp)
 {
-	struct rcar_du_crtc *crtc0 = &rgrp->dev->crtcs[rgrp->index * 2];
+	struct rcar_du_device *rcdu = rgrp->dev;
 	u32 dorcr = rcar_du_group_read(rgrp, DORCR);
 
 	dorcr &= ~(DORCR_PG2T | DORCR_DK2S | DORCR_PG2D_MASK);
@@ -293,7 +293,7 @@ int rcar_du_group_set_routing(struct rcar_du_group *rgrp)
 	 * CRTC 1 in all other cases to avoid cloning CRTC 0 to DPAD0 and DPAD1
 	 * by default.
 	 */
-	if (crtc0->outputs & BIT(RCAR_DU_OUTPUT_DPAD1))
+	if (rcdu->dpad1_source == rgrp->index * 2)
 		dorcr |= DORCR_PG2D_DS1;
 	else
 		dorcr |= DORCR_PG2T | DORCR_DK2S | DORCR_PG2D_DS2;
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
index 27783f6..29a322d 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
@@ -314,6 +314,28 @@ static int rcar_du_atomic_check(struct drm_device *dev,
 static void rcar_du_atomic_commit_tail(struct drm_atomic_state *old_state)
 {
 	struct drm_device *dev = old_state->dev;
+	struct rcar_du_device *rcdu = dev->dev_private;
+	struct drm_crtc_state *crtc_state;
+	struct drm_crtc *crtc;
+	unsigned int i;
+
+	/*
+	 * Store RGB routing to DPAD0 and DPAD1, the hardware will be configured
+	 * when starting the CRTCs.
+	 */
+	rcdu->dpad1_source = -1;
+
+	for_each_new_crtc_in_state(old_state, crtc, crtc_state, i) {
+		struct rcar_du_crtc_state *rcrtc_state =
+			to_rcar_crtc_state(crtc_state);
+		struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
+
+		if (rcrtc_state->outputs & BIT(RCAR_DU_OUTPUT_DPAD0))
+			rcdu->dpad0_source = rcrtc->index;
+
+		if (rcrtc_state->outputs & BIT(RCAR_DU_OUTPUT_DPAD1))
+			rcdu->dpad1_source = rcrtc->index;
+	}
 
 	/* Apply the atomic update. */
 	drm_atomic_helper_commit_modeset_disables(dev, old_state);
-- 
2.7.4

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

* [cip-dev] [PATCH 4.19.y-cip 12/32] drm: rcar-du: Simplify encoder registration
  2019-10-01  8:24 [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874 Fabrizio Castro
                   ` (10 preceding siblings ...)
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 11/32] drm: rcar-du: Move CRTC outputs bitmask to private CRTC state Fabrizio Castro
@ 2019-10-01  8:25 ` Fabrizio Castro
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 13/32] drm: rcar-du: lvds: Don't fail probe if output is not connected on D3/E3 Fabrizio Castro
                   ` (21 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: Fabrizio Castro @ 2019-10-01  8:25 UTC (permalink / raw)
  To: cip-dev

From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

commit 5aebc852af25d8e1bacee664a1e3abae13dab799 upstream.

Before the driver fully moved to drm_bridge and drm_panel, it was
necessary to parse DT and locate encoder and connector nodes. The
connector node is now unused and can be removed as a parameter to
rcar_du_encoder_init(). As a consequence rcar_du_encoders_init_one() can
be greatly simplified, removing most of the DT parsing.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
---
 drivers/gpu/drm/rcar-du/rcar_du_encoder.c |  3 +-
 drivers/gpu/drm/rcar-du/rcar_du_encoder.h |  3 +-
 drivers/gpu/drm/rcar-du/rcar_du_kms.c     | 52 +++----------------------------
 3 files changed, 6 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
index 0ffa6d6..dc2750e 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
@@ -35,8 +35,7 @@ static const struct drm_encoder_funcs encoder_funcs = {
 
 int rcar_du_encoder_init(struct rcar_du_device *rcdu,
 			 enum rcar_du_output output,
-			 struct device_node *enc_node,
-			 struct device_node *con_node)
+			 struct device_node *enc_node)
 {
 	struct rcar_du_encoder *renc;
 	struct drm_encoder *encoder;
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_encoder.h b/drivers/gpu/drm/rcar-du/rcar_du_encoder.h
index 2d2abca..6a00da2 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_encoder.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_encoder.h
@@ -32,7 +32,6 @@ struct rcar_du_encoder {
 
 int rcar_du_encoder_init(struct rcar_du_device *rcdu,
 			 enum rcar_du_output output,
-			 struct device_node *enc_node,
-			 struct device_node *con_node);
+			 struct device_node *enc_node);
 
 #endif /* __RCAR_DU_ENCODER_H__ */
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
index 29a322d..4dc5e20 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
@@ -368,17 +368,10 @@ static int rcar_du_encoders_init_one(struct rcar_du_device *rcdu,
 				     enum rcar_du_output output,
 				     struct of_endpoint *ep)
 {
-	struct device_node *connector = NULL;
-	struct device_node *encoder = NULL;
-	struct device_node *ep_node = NULL;
-	struct device_node *entity_ep_node;
 	struct device_node *entity;
 	int ret;
 
-	/*
-	 * Locate the connected entity and infer its type from the number of
-	 * endpoints.
-	 */
+	/* Locate the connected entity and initialize the encoder. */
 	entity = of_graph_get_remote_port_parent(ep->local_node);
 	if (!entity) {
 		dev_dbg(rcdu->dev, "unconnected endpoint %pOF, skipping\n",
@@ -394,50 +387,13 @@ static int rcar_du_encoders_init_one(struct rcar_du_device *rcdu,
 		return -ENODEV;
 	}
 
-	entity_ep_node = of_graph_get_remote_endpoint(ep->local_node);
-
-	for_each_endpoint_of_node(entity, ep_node) {
-		if (ep_node == entity_ep_node)
-			continue;
-
-		/*
-		 * We've found one endpoint other than the input, this must
-		 * be an encoder. Locate the connector.
-		 */
-		encoder = entity;
-		connector = of_graph_get_remote_port_parent(ep_node);
-		of_node_put(ep_node);
-
-		if (!connector) {
-			dev_warn(rcdu->dev,
-				 "no connector for encoder %pOF, skipping\n",
-				 encoder);
-			of_node_put(entity_ep_node);
-			of_node_put(encoder);
-			return -ENODEV;
-		}
-
-		break;
-	}
-
-	of_node_put(entity_ep_node);
-
-	if (!encoder) {
-		dev_warn(rcdu->dev,
-			 "no encoder found for endpoint %pOF, skipping\n",
-			 ep->local_node);
-		of_node_put(entity);
-		return -ENODEV;
-	}
-
-	ret = rcar_du_encoder_init(rcdu, output, encoder, connector);
+	ret = rcar_du_encoder_init(rcdu, output, entity);
 	if (ret && ret != -EPROBE_DEFER)
 		dev_warn(rcdu->dev,
 			 "failed to initialize encoder %pOF on output %u (%d), skipping\n",
-			 encoder, output, ret);
+			 entity, output, ret);
 
-	of_node_put(encoder);
-	of_node_put(connector);
+	of_node_put(entity);
 
 	return ret;
 }
-- 
2.7.4

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

* [cip-dev] [PATCH 4.19.y-cip 13/32] drm: rcar-du: lvds: Don't fail probe if output is not connected on D3/E3
  2019-10-01  8:24 [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874 Fabrizio Castro
                   ` (11 preceding siblings ...)
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 12/32] drm: rcar-du: Simplify encoder registration Fabrizio Castro
@ 2019-10-01  8:25 ` Fabrizio Castro
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 14/32] drm: rcar-du: lvds: Add API to enable/disable clock output Fabrizio Castro
                   ` (20 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: Fabrizio Castro @ 2019-10-01  8:25 UTC (permalink / raw)
  To: cip-dev

From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

commit 6e1f8557818f3c2476404ba1d4a5157b823b79f0 upstream.

On the D3 and E3 SoCs the LVDS encoder has an extended internal PLL and
supplies a clock to the DU. That clock is used not only for the LVDS
outputs but also for the DPAD output. The LVDS encoder thus needs to be
available to the DU even when its output is disabled. Don't fail probe
in that case on D3 and E3.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
---
 drivers/gpu/drm/rcar-du/rcar_lvds.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c b/drivers/gpu/drm/rcar-du/rcar_lvds.c
index 694a627..8b08d61 100644
--- a/drivers/gpu/drm/rcar-du/rcar_lvds.c
+++ b/drivers/gpu/drm/rcar-du/rcar_lvds.c
@@ -544,7 +544,10 @@ static int rcar_lvds_attach(struct drm_bridge *bridge)
 		return drm_bridge_attach(bridge->encoder, lvds->next_bridge,
 					 bridge);
 
-	/* Otherwise we have a panel, create a connector. */
+	/* Otherwise if we have a panel, create a connector. */
+	if (!lvds->panel)
+		return 0;
+
 	ret = drm_connector_init(bridge->dev, connector, &rcar_lvds_conn_funcs,
 				 DRM_MODE_CONNECTOR_LVDS);
 	if (ret < 0)
@@ -592,7 +595,8 @@ static int rcar_lvds_parse_dt(struct rcar_lvds *lvds)
 	local_output = of_graph_get_endpoint_by_regs(lvds->dev->of_node, 1, 0);
 	if (!local_output) {
 		dev_dbg(lvds->dev, "unconnected port at 1\n");
-		return -ENODEV;
+		ret = -ENODEV;
+		goto done;
 	}
 
 	/*
@@ -642,6 +646,15 @@ static int rcar_lvds_parse_dt(struct rcar_lvds *lvds)
 	of_node_put(remote_input);
 	of_node_put(remote);
 
+	/*
+	 * On D3/E3 the LVDS encoder provides a clock to the DU, which can be
+	 * used for the DPAD output even when the LVDS output is not connected.
+	 * Don't fail probe in that case as the DU will need the bridge to
+	 * control the clock.
+	 */
+	if (lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL)
+		return ret == -ENODEV ? 0 : ret;
+
 	return ret;
 }
 
-- 
2.7.4

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

* [cip-dev] [PATCH 4.19.y-cip 14/32] drm: rcar-du: lvds: Add API to enable/disable clock output
  2019-10-01  8:24 [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874 Fabrizio Castro
                   ` (12 preceding siblings ...)
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 13/32] drm: rcar-du: lvds: Don't fail probe if output is not connected on D3/E3 Fabrizio Castro
@ 2019-10-01  8:25 ` Fabrizio Castro
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 15/32] drm: rcar-du: Turn LVDS clock output on/off for DPAD0 output on D3/E3 Fabrizio Castro
                   ` (19 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: Fabrizio Castro @ 2019-10-01  8:25 UTC (permalink / raw)
  To: cip-dev

From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

commit 02f2b30032c12b1b91abe5f2bd0d74ba1f700ea1 upstream.

On the D3 and E3 platforms, the LVDS internal PLL supplies the pixel
clock to the DU. This works automatically for LVDS outputs as the LVDS
encoder is enabled through the bridge API, enabling the internal PLL and
clock output. However, when using the DU DPAD output with the LVDS
outputs turned off, the LVDS PLL needs to be controlled manually. Add an
API to do so, to be called by the DU driver.

The drivers/gpu/drm/rcar-du/ directory has to be treated as obj-y
unconditionally, as the LVDS driver could be built-in while the DU
driver is compiled as a module.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
---
 drivers/gpu/drm/Makefile            |  2 +-
 drivers/gpu/drm/rcar-du/Kconfig     |  1 +
 drivers/gpu/drm/rcar-du/rcar_lvds.c | 77 ++++++++++++++++++++++++++++++++-----
 drivers/gpu/drm/rcar-du/rcar_lvds.h | 27 +++++++++++++
 4 files changed, 96 insertions(+), 11 deletions(-)
 create mode 100644 drivers/gpu/drm/rcar-du/rcar_lvds.h

diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index a6771ce..cde02d2 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -79,7 +79,7 @@ obj-$(CONFIG_DRM_UDL) += udl/
 obj-$(CONFIG_DRM_AST) += ast/
 obj-$(CONFIG_DRM_ARMADA) += armada/
 obj-$(CONFIG_DRM_ATMEL_HLCDC)	+= atmel-hlcdc/
-obj-$(CONFIG_DRM_RCAR_DU) += rcar-du/
+obj-y			+= rcar-du/
 obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/
 obj-y			+= omapdrm/
 obj-$(CONFIG_DRM_SUN4I) += sun4i/
diff --git a/drivers/gpu/drm/rcar-du/Kconfig b/drivers/gpu/drm/rcar-du/Kconfig
index edde8d4..a9de227 100644
--- a/drivers/gpu/drm/rcar-du/Kconfig
+++ b/drivers/gpu/drm/rcar-du/Kconfig
@@ -3,6 +3,7 @@ config DRM_RCAR_DU
 	depends on DRM && OF
 	depends on ARM || ARM64
 	depends on ARCH_RENESAS || COMPILE_TEST
+	imply DRM_RCAR_LVDS
 	select DRM_KMS_HELPER
 	select DRM_KMS_CMA_HELPER
 	select DRM_GEM_CMA_HELPER
diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c b/drivers/gpu/drm/rcar-du/rcar_lvds.c
index 8b08d61..7f82bde 100644
--- a/drivers/gpu/drm/rcar-du/rcar_lvds.c
+++ b/drivers/gpu/drm/rcar-du/rcar_lvds.c
@@ -22,6 +22,7 @@
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_panel.h>
 
+#include "rcar_lvds.h"
 #include "rcar_lvds_regs.h"
 
 struct rcar_lvds;
@@ -182,8 +183,9 @@ struct pll_info {
 
 static void rcar_lvds_d3_e3_pll_calc(struct rcar_lvds *lvds, struct clk *clk,
 				     unsigned long target, struct pll_info *pll,
-				     u32 clksel)
+				     u32 clksel, bool dot_clock_only)
 {
+	unsigned int div7 = dot_clock_only ? 1 : 7;
 	unsigned long output;
 	unsigned long fin;
 	unsigned int m_min;
@@ -217,9 +219,9 @@ static void rcar_lvds_d3_e3_pll_calc(struct rcar_lvds *lvds, struct clk *clk,
 	 *                     `------------> | |
 	 *                                    |/
 	 *
-	 * 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 /7 divider is optional, it is enabled when the LVDS PLL is used
+	 * to drive the LVDS encoder, and disabled when  used to generate a dot
+	 * clock for the DU RGB output, without using the LVDS encoder.
 	 *
 	 * The PLL allowed input frequency range is 12 MHz to 192 MHz.
 	 */
@@ -279,7 +281,7 @@ static void rcar_lvds_d3_e3_pll_calc(struct rcar_lvds *lvds, struct clk *clk,
 				 * the PLL, followed by a an optional fixed /7
 				 * divider.
 				 */
-				fout = fvco / (1 << e) / 7;
+				fout = fvco / (1 << e) / div7;
 				div = DIV_ROUND_CLOSEST(fout, target);
 				diff = abs(fout / div - target);
 
@@ -300,7 +302,7 @@ static void rcar_lvds_d3_e3_pll_calc(struct rcar_lvds *lvds, struct clk *clk,
 
 done:
 	output = fin * pll->pll_n / pll->pll_m / (1 << pll->pll_e)
-	       / 7 / pll->div;
+	       / div7 / pll->div;
 	error = (long)(output - target) * 10000 / (long)target;
 
 	dev_dbg(lvds->dev,
@@ -310,17 +312,18 @@ static void rcar_lvds_d3_e3_pll_calc(struct rcar_lvds *lvds, struct clk *clk,
 		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)
+static void __rcar_lvds_pll_setup_d3_e3(struct rcar_lvds *lvds,
+					unsigned int freq, bool dot_clock_only)
 {
 	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));
+				 LVDPLLCR_CKSEL_DU_DOTCLKIN(0), dot_clock_only);
 	rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.dotclkin[1], freq, &pll,
-				 LVDPLLCR_CKSEL_DU_DOTCLKIN(1));
+				 LVDPLLCR_CKSEL_DU_DOTCLKIN(1), dot_clock_only);
 	rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.extal, freq, &pll,
-				 LVDPLLCR_CKSEL_EXTAL);
+				 LVDPLLCR_CKSEL_EXTAL, dot_clock_only);
 
 	lvdpllcr = LVDPLLCR_PLLON | pll.clksel | LVDPLLCR_CLKOUT
 		 | LVDPLLCR_PLLN(pll.pll_n - 1) | LVDPLLCR_PLLM(pll.pll_m - 1);
@@ -329,6 +332,9 @@ static void rcar_lvds_pll_setup_d3_e3(struct rcar_lvds *lvds, unsigned int freq)
 		lvdpllcr |= LVDPLLCR_STP_CLKOUTE | LVDPLLCR_OUTCLKSEL
 			 |  LVDPLLCR_PLLE(pll.pll_e - 1);
 
+	if (dot_clock_only)
+		lvdpllcr |= LVDPLLCR_OCKSEL;
+
 	rcar_lvds_write(lvds, LVDPLLCR, lvdpllcr);
 
 	if (pll.div > 1)
@@ -342,6 +348,57 @@ static void rcar_lvds_pll_setup_d3_e3(struct rcar_lvds *lvds, unsigned int freq)
 		rcar_lvds_write(lvds, LVDDIV, 0);
 }
 
+static void rcar_lvds_pll_setup_d3_e3(struct rcar_lvds *lvds, unsigned int freq)
+{
+	__rcar_lvds_pll_setup_d3_e3(lvds, freq, false);
+}
+
+/* -----------------------------------------------------------------------------
+ * Clock - D3/E3 only
+ */
+
+int rcar_lvds_clk_enable(struct drm_bridge *bridge, unsigned long freq)
+{
+	struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
+	int ret;
+
+	if (WARN_ON(!(lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL)))
+		return -ENODEV;
+
+	dev_dbg(lvds->dev, "enabling LVDS PLL, freq=%luHz\n", freq);
+
+	WARN_ON(lvds->enabled);
+
+	ret = clk_prepare_enable(lvds->clocks.mod);
+	if (ret < 0)
+		return ret;
+
+	__rcar_lvds_pll_setup_d3_e3(lvds, freq, true);
+
+	lvds->enabled = true;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(rcar_lvds_clk_enable);
+
+void rcar_lvds_clk_disable(struct drm_bridge *bridge)
+{
+	struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
+
+	if (WARN_ON(!(lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL)))
+		return;
+
+	dev_dbg(lvds->dev, "disabling LVDS PLL\n");
+
+	WARN_ON(!lvds->enabled);
+
+	rcar_lvds_write(lvds, LVDPLLCR, 0);
+
+	clk_disable_unprepare(lvds->clocks.mod);
+
+	lvds->enabled = false;
+}
+EXPORT_SYMBOL_GPL(rcar_lvds_clk_disable);
+
 /* -----------------------------------------------------------------------------
  * Bridge
  */
diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.h b/drivers/gpu/drm/rcar-du/rcar_lvds.h
new file mode 100644
index 0000000..a709cae
--- /dev/null
+++ b/drivers/gpu/drm/rcar-du/rcar_lvds.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * rcar_lvds.h  --  R-Car LVDS Encoder
+ *
+ * Copyright (C) 2013-2018 Renesas Electronics Corporation
+ *
+ * Contact: Laurent Pinchart (laurent.pinchart at ideasonboard.com)
+ */
+
+#ifndef __RCAR_LVDS_H__
+#define __RCAR_LVDS_H__
+
+struct drm_bridge;
+
+#if IS_ENABLED(CONFIG_DRM_RCAR_LVDS)
+int rcar_lvds_clk_enable(struct drm_bridge *bridge, unsigned long freq);
+void rcar_lvds_clk_disable(struct drm_bridge *bridge);
+#else
+static inline int rcar_lvds_clk_enable(struct drm_bridge *bridge,
+				       unsigned long freq)
+{
+	return -ENOSYS;
+}
+static inline void rcar_lvds_clk_disable(struct drm_bridge *bridge) { }
+#endif /* CONFIG_DRM_RCAR_LVDS */
+
+#endif /* __RCAR_LVDS_H__ */
-- 
2.7.4

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

* [cip-dev] [PATCH 4.19.y-cip 15/32] drm: rcar-du: Turn LVDS clock output on/off for DPAD0 output on D3/E3
  2019-10-01  8:24 [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874 Fabrizio Castro
                   ` (13 preceding siblings ...)
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 14/32] drm: rcar-du: lvds: Add API to enable/disable clock output Fabrizio Castro
@ 2019-10-01  8:25 ` Fabrizio Castro
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 16/32] drm: rcar-du: lvds: Fix post-DLL divider calculation Fabrizio Castro
                   ` (18 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: Fabrizio Castro @ 2019-10-01  8:25 UTC (permalink / raw)
  To: cip-dev

From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

commit a6cc417d3eee4ac37aa9547cf82d4ff155d1780c upstream.

On the D3 and E3 SoCs the LVDS PLL clock output provides the dot clock
to the DU channels, even when the LVDS outputs are not in use. Enable
and disable the LVDS clock output when enabling or disabling a CRTC
connected to the DPAD0 output.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
---
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c    | 34 +++++++++++++++++++++++++++++++
 drivers/gpu/drm/rcar-du/rcar_du_drv.h     |  3 +++
 drivers/gpu/drm/rcar-du/rcar_du_encoder.c |  1 +
 3 files changed, 38 insertions(+)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index d679818..7079d94 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -31,6 +31,7 @@
 #include "rcar_du_plane.h"
 #include "rcar_du_regs.h"
 #include "rcar_du_vsp.h"
+#include "rcar_lvds.h"
 
 static u32 rcar_du_crtc_read(struct rcar_du_crtc *rcrtc, u32 reg)
 {
@@ -643,8 +644,27 @@ static void rcar_du_crtc_atomic_enable(struct drm_crtc *crtc,
 				       struct drm_crtc_state *old_state)
 {
 	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
+	struct rcar_du_crtc_state *rstate = to_rcar_crtc_state(crtc->state);
+	struct rcar_du_device *rcdu = rcrtc->group->dev;
 
 	rcar_du_crtc_get(rcrtc);
+
+	/*
+	 * On D3/E3 the dot clock is provided by the LVDS encoder attached to
+	 * the DU channel. We need to enable its clock output explicitly if
+	 * the LVDS output is disabled.
+	 */
+	if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index) &&
+	    rstate->outputs == BIT(RCAR_DU_OUTPUT_DPAD0)) {
+		struct rcar_du_encoder *encoder =
+			rcdu->encoders[RCAR_DU_OUTPUT_LVDS0 + rcrtc->index];
+		const struct drm_display_mode *mode =
+			&crtc->state->adjusted_mode;
+
+		rcar_lvds_clk_enable(encoder->base.bridge,
+				     mode->clock * 1000);
+	}
+
 	rcar_du_crtc_start(rcrtc);
 }
 
@@ -652,10 +672,24 @@ static void rcar_du_crtc_atomic_disable(struct drm_crtc *crtc,
 					struct drm_crtc_state *old_state)
 {
 	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
+	struct rcar_du_crtc_state *rstate = to_rcar_crtc_state(old_state);
+	struct rcar_du_device *rcdu = rcrtc->group->dev;
 
 	rcar_du_crtc_stop(rcrtc);
 	rcar_du_crtc_put(rcrtc);
 
+	if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index) &&
+	    rstate->outputs == BIT(RCAR_DU_OUTPUT_DPAD0)) {
+		struct rcar_du_encoder *encoder =
+			rcdu->encoders[RCAR_DU_OUTPUT_LVDS0 + rcrtc->index];
+
+		/*
+		 * Disable the LVDS clock output, see
+		 * rcar_du_crtc_atomic_enable().
+		 */
+		rcar_lvds_clk_disable(encoder->base.bridge);
+	}
+
 	spin_lock_irq(&crtc->dev->event_lock);
 	if (crtc->state->event) {
 		drm_crtc_send_vblank_event(crtc, crtc->state->event);
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
index d9cf398..b8c4abd 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
@@ -26,6 +26,7 @@ struct device;
 struct drm_device;
 struct drm_fbdev_cma;
 struct rcar_du_device;
+struct rcar_du_encoder;
 
 #define RCAR_DU_FEATURE_CRTC_IRQ_CLOCK	BIT(0)	/* Per-CRTC IRQ and clock */
 #define RCAR_DU_FEATURE_EXT_CTRL_REGS	BIT(1)	/* Has extended control registers */
@@ -88,6 +89,8 @@ struct rcar_du_device {
 	struct rcar_du_crtc crtcs[RCAR_DU_MAX_CRTCS];
 	unsigned int num_crtcs;
 
+	struct rcar_du_encoder *encoders[RCAR_DU_OUTPUT_MAX];
+
 	struct rcar_du_group groups[RCAR_DU_MAX_GROUPS];
 	struct rcar_du_vsp vsps[RCAR_DU_MAX_VSPS];
 
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
index dc2750e..5cca7f7 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
@@ -46,6 +46,7 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu,
 	if (renc == NULL)
 		return -ENOMEM;
 
+	rcdu->encoders[output] = renc;
 	renc->output = output;
 	encoder = rcar_encoder_to_drm_encoder(renc);
 
-- 
2.7.4

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

* [cip-dev] [PATCH 4.19.y-cip 16/32] drm: rcar-du: lvds: Fix post-DLL divider calculation
  2019-10-01  8:24 [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874 Fabrizio Castro
                   ` (14 preceding siblings ...)
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 15/32] drm: rcar-du: Turn LVDS clock output on/off for DPAD0 output on D3/E3 Fabrizio Castro
@ 2019-10-01  8:25 ` Fabrizio Castro
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 17/32] drm: rcar-du: lvds: Adjust operating frequency for D3 and E3 Fabrizio Castro
                   ` (17 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: Fabrizio Castro @ 2019-10-01  8:25 UTC (permalink / raw)
  To: cip-dev

From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

commit 167e535438ecc73d299340bb1269616432020dfb upstream.

The PLL parameters are computed by looping over the range of acceptable
M, N and E values, and selecting the combination that produces the
output frequency closest to the target. The internal frequency
constraints are taken into account by restricting the tested values for
the PLL parameters, reducing the search space. The target frequency,
however, is only taken into account when computing the post-PLL divider,
which can result in a 0 value for the divider when the PLL output
frequency being tested is lower than half of the target frequency.
Subsequent loops will produce a better set of PLL parameters, but for
some of the iterations this can result in a division by 0.

Fix it by clamping the divider value. We could instead restrict the E
values being tested in the inner loop, but that would require additional
calculation that would likely be less efficient as the E parameter can
only take three different values.

Fixes: c25c01361199 ("drm: rcar-du: lvds: D3/E3 support")
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
---
 drivers/gpu/drm/rcar-du/rcar_lvds.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c b/drivers/gpu/drm/rcar-du/rcar_lvds.c
index 7f82bde..27a382f 100644
--- a/drivers/gpu/drm/rcar-du/rcar_lvds.c
+++ b/drivers/gpu/drm/rcar-du/rcar_lvds.c
@@ -282,7 +282,7 @@ static void rcar_lvds_d3_e3_pll_calc(struct rcar_lvds *lvds, struct clk *clk,
 				 * divider.
 				 */
 				fout = fvco / (1 << e) / div7;
-				div = DIV_ROUND_CLOSEST(fout, target);
+				div = max(1UL, DIV_ROUND_CLOSEST(fout, target));
 				diff = abs(fout / div - target);
 
 				if (diff < pll->diff) {
-- 
2.7.4

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

* [cip-dev] [PATCH 4.19.y-cip 17/32] drm: rcar-du: lvds: Adjust operating frequency for D3 and E3
  2019-10-01  8:24 [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874 Fabrizio Castro
                   ` (15 preceding siblings ...)
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 16/32] drm: rcar-du: lvds: Fix post-DLL divider calculation Fabrizio Castro
@ 2019-10-01  8:25 ` Fabrizio Castro
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 18/32] drm: rcar-du: Improve non-DPLL clock selection Fabrizio Castro
                   ` (16 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: Fabrizio Castro @ 2019-10-01  8:25 UTC (permalink / raw)
  To: cip-dev

From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

commit 871370308675e477abd57a69ce66ca4730a4249c upstream.

The D3 and E3 SoCs have different pixel clock frequency limits for the
LVDS encoder than the other SoCs in the Gen3 family. Adjust the mode
fixup implementation accordingly.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
---
 drivers/gpu/drm/rcar-du/rcar_lvds.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c b/drivers/gpu/drm/rcar-du/rcar_lvds.c
index 27a382f..3b5884a 100644
--- a/drivers/gpu/drm/rcar-du/rcar_lvds.c
+++ b/drivers/gpu/drm/rcar-du/rcar_lvds.c
@@ -530,11 +530,16 @@ static bool rcar_lvds_mode_fixup(struct drm_bridge *bridge,
 				 const struct drm_display_mode *mode,
 				 struct drm_display_mode *adjusted_mode)
 {
+	struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
+	int min_freq;
+
 	/*
 	 * The internal LVDS encoder has a restricted clock frequency operating
-	 * range (31MHz to 148.5MHz). Clamp the clock accordingly.
+	 * range, from 5MHz to 148.5MHz on D3 and E3, and from 31MHz to
+	 * 148.5MHz on all other platforms. Clamp the clock accordingly.
 	 */
-	adjusted_mode->clock = clamp(adjusted_mode->clock, 31000, 148500);
+	min_freq = lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL ? 5000 : 31000;
+	adjusted_mode->clock = clamp(adjusted_mode->clock, min_freq, 148500);
 
 	return true;
 }
-- 
2.7.4

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

* [cip-dev] [PATCH 4.19.y-cip 18/32] drm: rcar-du: Improve non-DPLL clock selection
  2019-10-01  8:24 [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874 Fabrizio Castro
                   ` (16 preceding siblings ...)
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 17/32] drm: rcar-du: lvds: Adjust operating frequency for D3 and E3 Fabrizio Castro
@ 2019-10-01  8:25 ` Fabrizio Castro
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 19/32] drm: rcar-du: Enable configurable DPAD0 routing on Gen3 Fabrizio Castro
                   ` (15 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: Fabrizio Castro @ 2019-10-01  8:25 UTC (permalink / raw)
  To: cip-dev

From: Jacopo Mondi <jacopo@jmondi.org>

commit 8c74c4561f05f57fca2957b1d98676a0454df1ca upstream.

DU channels not equipped with a DPLL use an SoC internal (provided by
the CPG) or external clock source combined with a DU internal divider to
generate the desired output dot clock frequency.

The current clock selection procedure does not fully exploit the ability
of external clock sources to generate the exact dot clock frequency by
themselves, but relies instead on tuning the internal DU clock divider
only, resulting in a less precise clock generation process.

When possible, and desirable, ask the external clock source for the
exact output dot clock frequency, and select the clock source that
produces the frequency closest to the desired output dot clock.

This patch specifically targets platforms (like Salvator-X[S] and ULCBs)
where the DU's input dotclock.in is generated by the versaclock VC5
clock source, which is capable of generating the exact rate the DU needs
as pixel clock output.

This patch fixes higher resolution modes which requires an high pixel
clock output currently not working on non-HDMI DU channel (such as
1920x1080 at 60Hz on the VGA output).

Fixes: 1b30dbde8596 ("drm: rcar-du: Add support for external pixel clock")
Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
[Factor out code to a helper function]
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Acked-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
---
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 85 +++++++++++++++++++++-------------
 1 file changed, 54 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index 7079d94..1ea4bc2 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -166,6 +166,47 @@ static void rcar_du_dpll_divider(struct rcar_du_crtc *rcrtc,
 		 best_diff);
 }
 
+struct du_clk_params {
+	struct clk *clk;
+	unsigned long rate;
+	unsigned long diff;
+	u32 escr;
+};
+
+static void rcar_du_escr_divider(struct clk *clk, unsigned long target,
+				 u32 escr, struct du_clk_params *params)
+{
+	unsigned long rate;
+	unsigned long diff;
+	u32 div;
+
+	/*
+	 * If the target rate has already been achieved perfectly we can't do
+	 * better.
+	 */
+	if (params->diff == 0)
+		return;
+
+	/*
+	 * Compute the input clock rate and internal divisor values to obtain
+	 * the clock rate closest to the target frequency.
+	 */
+	rate = clk_round_rate(clk, target);
+	div = clamp(DIV_ROUND_CLOSEST(rate, target), 1UL, 64UL) - 1;
+	diff = abs(rate / (div + 1) - target);
+
+	/*
+	 * Store the parameters if the resulting frequency is better than any
+	 * previously calculated value.
+	 */
+	if (diff < params->diff) {
+		params->clk = clk;
+		params->rate = rate;
+		params->diff = diff;
+		params->escr = escr | div;
+	}
+}
+
 static const struct soc_device_attribute rcar_du_r8a7795_es1[] = {
 	{ .soc_id = "r8a7795", .revision = "ES1.*" },
 	{ /* sentinel */ }
@@ -234,42 +275,24 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
 		 */
 		escr = ESCR_DCLKSEL_DCLKIN;
 	} else {
-		unsigned long clk;
-		u32 div;
-
-		/*
-		 * Compute the clock divisor and select the internal or external
-		 * dot clock based on the requested frequency.
-		 */
-		clk = clk_get_rate(rcrtc->clock);
-		div = DIV_ROUND_CLOSEST(clk, mode_clock);
-		div = clamp(div, 1U, 64U) - 1;
-
-		escr = ESCR_DCLKSEL_CLKS | div;
-
-		if (rcrtc->extclock) {
-			unsigned long extclk;
-			unsigned long extrate;
-			unsigned long rate;
-			u32 extdiv;
+		struct du_clk_params params = { .diff = (unsigned long)-1 };
 
-			extclk = clk_get_rate(rcrtc->extclock);
-			extdiv = DIV_ROUND_CLOSEST(extclk, mode_clock);
-			extdiv = clamp(extdiv, 1U, 64U) - 1;
+		rcar_du_escr_divider(rcrtc->clock, mode_clock,
+				     ESCR_DCLKSEL_CLKS, &params);
+		if (rcrtc->extclock)
+			rcar_du_escr_divider(rcrtc->extclock, mode_clock,
+					     ESCR_DCLKSEL_DCLKIN, &params);
 
-			extrate = extclk / (extdiv + 1);
-			rate = clk / (div + 1);
+		dev_dbg(rcrtc->group->dev->dev,	"mode clock %lu %s rate %lu\n",
+			mode_clock, params.clk == rcrtc->clock ? "cpg" : "ext",
+			params.rate);
 
-			if (abs((long)extrate - (long)mode_clock) <
-			    abs((long)rate - (long)mode_clock))
-				escr = ESCR_DCLKSEL_DCLKIN | extdiv;
-
-			dev_dbg(rcrtc->group->dev->dev,
-				"mode clock %lu extrate %lu rate %lu ESCR 0x%08x\n",
-				mode_clock, extrate, rate, escr);
-		}
+		clk_set_rate(params.clk, params.rate);
+		escr = params.escr;
 	}
 
+	dev_dbg(rcrtc->group->dev->dev, "%s: ESCR 0x%08x\n", __func__, escr);
+
 	rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? ESCR2 : ESCR,
 			    escr);
 	rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? OTAR2 : OTAR, 0);
-- 
2.7.4

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

* [cip-dev] [PATCH 4.19.y-cip 19/32] drm: rcar-du: Enable configurable DPAD0 routing on Gen3
  2019-10-01  8:24 [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874 Fabrizio Castro
                   ` (17 preceding siblings ...)
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 18/32] drm: rcar-du: Improve non-DPLL clock selection Fabrizio Castro
@ 2019-10-01  8:25 ` Fabrizio Castro
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 20/32] drm/rcar-du: Replace drm_dev_unref with drm_dev_put Fabrizio Castro
                   ` (14 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: Fabrizio Castro @ 2019-10-01  8:25 UTC (permalink / raw)
  To: cip-dev

From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

commit 1f98b2a4fd4632db3b585a624032b7ec785a5255 upstream.

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>
Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
---
 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 d35743f..cc3782e 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
@@ -60,8 +60,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) {
@@ -73,21 +71,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 4dc5e20..3fd12ab 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
@@ -553,6 +553,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;
@@ -675,6 +676,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);
-- 
2.7.4

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

* [cip-dev] [PATCH 4.19.y-cip 20/32] drm/rcar-du: Replace drm_dev_unref with drm_dev_put
  2019-10-01  8:24 [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874 Fabrizio Castro
                   ` (18 preceding siblings ...)
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 19/32] drm: rcar-du: Enable configurable DPAD0 routing on Gen3 Fabrizio Castro
@ 2019-10-01  8:25 ` Fabrizio Castro
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 21/32] drm: rcar-du: Fix the return value in case of error in 'rcar_du_crtc_set_crc_source()' Fabrizio Castro
                   ` (13 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: Fabrizio Castro @ 2019-10-01  8:25 UTC (permalink / raw)
  To: cip-dev

From: Thomas Zimmermann <tzimmermann@suse.de>

commit 06fa0d46b181e762f22d0742839200e7235d32ce upstream.

This patch unifies the naming of DRM functions for reference counting
of struct drm_device. The resulting code is more aligned with the rest
of the Linux kernel interfaces.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
---
 drivers/gpu/drm/rcar-du/rcar_du_drv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
index 708ebd9..94d0213 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
@@ -485,7 +485,7 @@ static int rcar_du_remove(struct platform_device *pdev)
 	drm_kms_helper_poll_fini(ddev);
 	drm_mode_config_cleanup(ddev);
 
-	drm_dev_unref(ddev);
+	drm_dev_put(ddev);
 
 	return 0;
 }
-- 
2.7.4

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

* [cip-dev] [PATCH 4.19.y-cip 21/32] drm: rcar-du: Fix the return value in case of error in 'rcar_du_crtc_set_crc_source()'
  2019-10-01  8:24 [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874 Fabrizio Castro
                   ` (19 preceding siblings ...)
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 20/32] drm/rcar-du: Replace drm_dev_unref with drm_dev_put Fabrizio Castro
@ 2019-10-01  8:25 ` Fabrizio Castro
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 22/32] drm: rcar-du: Fix vblank initialization Fabrizio Castro
                   ` (12 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: Fabrizio Castro @ 2019-10-01  8:25 UTC (permalink / raw)
  To: cip-dev

From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>

commit 4d486f18d91b1876040bf87e9ad78981a08b15a6 upstream.

We return 0 unconditionally in 'rcar_du_crtc_set_crc_source()'.
However, 'ret' is set to some error codes if some function calls fail.

Return 'ret' instead to propagate the error code.

Fixes: 47a52d024e89 ("media: drm: rcar-du: Add support for CRC computation")
Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
---
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index 1ea4bc2..0cfb015 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -936,7 +936,7 @@ static int rcar_du_crtc_set_crc_source(struct drm_crtc *crtc,
 	drm_modeset_drop_locks(&ctx);
 	drm_modeset_acquire_fini(&ctx);
 
-	return 0;
+	return ret;
 }
 
 static const struct drm_crtc_funcs crtc_funcs_gen2 = {
-- 
2.7.4

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

* [cip-dev] [PATCH 4.19.y-cip 22/32] drm: rcar-du: Fix vblank initialization
  2019-10-01  8:24 [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874 Fabrizio Castro
                   ` (20 preceding siblings ...)
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 21/32] drm: rcar-du: Fix the return value in case of error in 'rcar_du_crtc_set_crc_source()' Fabrizio Castro
@ 2019-10-01  8:25 ` Fabrizio Castro
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 23/32] drm: rcar-du: Fix external clock error checks Fabrizio Castro
                   ` (11 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: Fabrizio Castro @ 2019-10-01  8:25 UTC (permalink / raw)
  To: cip-dev

From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

commit 3d61fe5f59dd3e6f96fc0772156d257cb04dc656 upstream.

The drm_vblank_init() takes the total number of CRTCs as an argument,
but the rcar-du driver passes a bitmask of the CRTC indices. Fix it.

Fixes: 4bf8e1962f91 ("drm: Renesas R-Car Display Unit DRM driver")
Reported-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
---
 drivers/gpu/drm/rcar-du/rcar_du_kms.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
index 3fd12ab..2c2d57c 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
@@ -591,7 +591,7 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
 	 * Initialize vertical blanking interrupts handling. Start with vblank
 	 * disabled for all CRTCs.
 	 */
-	ret = drm_vblank_init(dev, (1 << rcdu->num_crtcs) - 1);
+	ret = drm_vblank_init(dev, rcdu->num_crtcs);
 	if (ret < 0)
 		return ret;
 
-- 
2.7.4

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

* [cip-dev] [PATCH 4.19.y-cip 23/32] drm: rcar-du: Fix external clock error checks
  2019-10-01  8:24 [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874 Fabrizio Castro
                   ` (21 preceding siblings ...)
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 22/32] drm: rcar-du: Fix vblank initialization Fabrizio Castro
@ 2019-10-01  8:25 ` Fabrizio Castro
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 24/32] drm: rcar-du: Reject modes that fail CRTC timing requirements Fabrizio Castro
                   ` (10 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: Fabrizio Castro @ 2019-10-01  8:25 UTC (permalink / raw)
  To: cip-dev

From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

commit 63a298f22a6183b5b7536a203596c6570dfcfe8e upstream.

The rcar-du driver supports probe deferral for external clocks, but
implements it badly by checking the wrong pointer due to a bad copy and
paste. Fix it.

While at it, reject invalid clocks outright for DU channels that have a
display PLL, as the external clock is mandatory in that case. This
avoids a WARN_ON() at runtime.

Fixes: 1b30dbde8596 ("drm: rcar-du: Add support for external pixel clock")
Reported-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
---
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index 0cfb015..3763f8c 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -232,9 +232,6 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
 		 * system clock, and have no internal clock divider.
 		 */
 
-		if (WARN_ON(!rcrtc->extclock))
-			return;
-
 		/*
 		 * The H3 ES1.x exhibits dot clock duty cycle stability issues.
 		 * We can work around them by configuring the DPLL to twice the
@@ -1045,9 +1042,16 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int swindex,
 	clk = devm_clk_get(rcdu->dev, clk_name);
 	if (!IS_ERR(clk)) {
 		rcrtc->extclock = clk;
-	} else if (PTR_ERR(rcrtc->clock) == -EPROBE_DEFER) {
-		dev_info(rcdu->dev, "can't get external clock %u\n", hwindex);
+	} else if (PTR_ERR(clk) == -EPROBE_DEFER) {
 		return -EPROBE_DEFER;
+	} else if (rcdu->info->dpll_mask & BIT(hwindex)) {
+		/*
+		 * DU channels that have a display PLL can't use the internal
+		 * system clock and thus require an external clock.
+		 */
+		ret = PTR_ERR(clk);
+		dev_err(rcdu->dev, "can't get dclkin.%u: %d\n", hwindex, ret);
+		return ret;
 	}
 
 	init_waitqueue_head(&rcrtc->flip_wait);
-- 
2.7.4

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

* [cip-dev] [PATCH 4.19.y-cip 24/32] drm: rcar-du: Reject modes that fail CRTC timing requirements
  2019-10-01  8:24 [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874 Fabrizio Castro
                   ` (22 preceding siblings ...)
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 23/32] drm: rcar-du: Fix external clock error checks Fabrizio Castro
@ 2019-10-01  8:25 ` Fabrizio Castro
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 25/32] drm/rcar-du: Use drm_fbdev_generic_setup() Fabrizio Castro
                   ` (9 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: Fabrizio Castro @ 2019-10-01  8:25 UTC (permalink / raw)
  To: cip-dev

From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

commit 256856efb8cc2b5468c69edf45eb0ab579833ce7 upstream.

The hardware requires the HDSR and VDSR registers to be set to 1 or
higher. This translates to a minimum combined horizontal sync and back
porch of 20 pixels and a minimum vertical back porch of 3 lines. Reject
modes that fail those requirements.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
---
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index 3763f8c..cec4b5c 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -771,10 +771,22 @@ enum drm_mode_status rcar_du_crtc_mode_valid(struct drm_crtc *crtc,
 	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
 	struct rcar_du_device *rcdu = rcrtc->group->dev;
 	bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
+	unsigned int vbp;
 
 	if (interlaced && !rcar_du_has(rcdu, RCAR_DU_FEATURE_INTERLACED))
 		return MODE_NO_INTERLACE;
 
+	/*
+	 * The hardware requires a minimum combined horizontal sync and back
+	 * porch of 20 pixels and a minimum vertical back porch of 3 lines.
+	 */
+	if (mode->htotal - mode->hsync_start < 20)
+		return MODE_HBLANK_NARROW;
+
+	vbp = (mode->vtotal - mode->vsync_end) / (interlaced ? 2 : 1);
+	if (vbp < 3)
+		return MODE_VBLANK_NARROW;
+
 	return MODE_OK;
 }
 
-- 
2.7.4

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

* [cip-dev] [PATCH 4.19.y-cip 25/32] drm/rcar-du: Use drm_fbdev_generic_setup()
  2019-10-01  8:24 [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874 Fabrizio Castro
                   ` (23 preceding siblings ...)
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 24/32] drm: rcar-du: Reject modes that fail CRTC timing requirements Fabrizio Castro
@ 2019-10-01  8:25 ` Fabrizio Castro
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 26/32] drm: rcar-du: Disable unused DPAD outputs Fabrizio Castro
                   ` (8 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: Fabrizio Castro @ 2019-10-01  8:25 UTC (permalink / raw)
  To: cip-dev

From: Noralf Tr?nnes <noralf@tronnes.org>

commit 2f690fad237adea1bdce8ed9026cbf43cd9d8c46 upstream.

The CMA helper is already using the drm_fb_helper_generic_probe part of
the generic fbdev emulation. This patch makes full use of the generic
fbdev emulation by using its drm_client callbacks. This means that
drm_mode_config_funcs->output_poll_changed and drm_driver->lastclose are
now handled by the emulation code. Additionally fbdev unregister happens
automatically on drm_dev_unregister().

The drm_fbdev_generic_setup() call is put after drm_dev_register() in the
driver. This is done to highlight the fact that fbdev emulation is an
internal client that makes use of the driver, it is not part of the
driver as such. If fbdev setup fails, an error is printed, but the driver
succeeds probing.

drm_fbdev_generic_setup() handles mode_config.num_connector being zero.
In that case it retries fbdev setup on the next .output_poll_changed.

Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Noralf Tr?nnes <noralf@tronnes.org>
Acked-by: Sam Ravnborg <sam@ravnborg.org>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181128212713.43500-4-noralf at tronnes.org
Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
---
 drivers/gpu/drm/rcar-du/rcar_du_drv.c | 14 +++-----------
 drivers/gpu/drm/rcar-du/rcar_du_drv.h |  1 -
 drivers/gpu/drm/rcar-du/rcar_du_kms.c | 21 ---------------------
 drivers/gpu/drm/rcar-du/rcar_du_vsp.c |  1 -
 4 files changed, 3 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
index 94d0213..a665679 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
@@ -25,6 +25,7 @@
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_fb_cma_helper.h>
+#include <drm/drm_fb_helper.h>
 #include <drm/drm_gem_cma_helper.h>
 
 #include "rcar_du_drv.h"
@@ -394,19 +395,11 @@ MODULE_DEVICE_TABLE(of, rcar_du_of_table);
  * DRM operations
  */
 
-static void rcar_du_lastclose(struct drm_device *dev)
-{
-	struct rcar_du_device *rcdu = dev->dev_private;
-
-	drm_fbdev_cma_restore_mode(rcdu->fbdev);
-}
-
 DEFINE_DRM_GEM_CMA_FOPS(rcar_du_fops);
 
 static struct drm_driver rcar_du_driver = {
 	.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME
 				| DRIVER_ATOMIC,
-	.lastclose		= rcar_du_lastclose,
 	.gem_free_object_unlocked = drm_gem_cma_free_object,
 	.gem_vm_ops		= &drm_gem_cma_vm_ops,
 	.prime_handle_to_fd	= drm_gem_prime_handle_to_fd,
@@ -479,9 +472,6 @@ static int rcar_du_remove(struct platform_device *pdev)
 
 	drm_dev_unregister(ddev);
 
-	if (rcdu->fbdev)
-		drm_fbdev_cma_fini(rcdu->fbdev);
-
 	drm_kms_helper_poll_fini(ddev);
 	drm_mode_config_cleanup(ddev);
 
@@ -541,6 +531,8 @@ static int rcar_du_probe(struct platform_device *pdev)
 
 	DRM_INFO("Device %s probed\n", dev_name(&pdev->dev));
 
+	drm_fbdev_generic_setup(ddev, 32);
+
 	return 0;
 
 error:
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
index b8c4abd..eb05bbd 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
@@ -24,7 +24,6 @@
 struct clk;
 struct device;
 struct drm_device;
-struct drm_fbdev_cma;
 struct rcar_du_device;
 struct rcar_du_encoder;
 
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
index 2c2d57c..3257aca 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
@@ -284,13 +284,6 @@ rcar_du_fb_create(struct drm_device *dev, struct drm_file *file_priv,
 	return drm_gem_fb_create(dev, file_priv, mode_cmd);
 }
 
-static void rcar_du_output_poll_changed(struct drm_device *dev)
-{
-	struct rcar_du_device *rcdu = dev->dev_private;
-
-	drm_fbdev_cma_hotplug_event(rcdu->fbdev);
-}
-
 /* -----------------------------------------------------------------------------
  * Atomic Check and Update
  */
@@ -359,7 +352,6 @@ static const struct drm_mode_config_helper_funcs rcar_du_mode_config_helper = {
 
 static const struct drm_mode_config_funcs rcar_du_mode_config_funcs = {
 	.fb_create = rcar_du_fb_create,
-	.output_poll_changed = rcar_du_output_poll_changed,
 	.atomic_check = rcar_du_atomic_check,
 	.atomic_commit = drm_atomic_helper_commit,
 };
@@ -552,7 +544,6 @@ 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;
@@ -691,17 +682,5 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
 
 	drm_kms_helper_poll_init(dev);
 
-	if (dev->mode_config.num_connector) {
-		fbdev = drm_fbdev_cma_init(dev, 32,
-					   dev->mode_config.num_connector);
-		if (IS_ERR(fbdev))
-			return PTR_ERR(fbdev);
-
-		rcdu->fbdev = fbdev;
-	} else {
-		dev_info(rcdu->dev,
-			 "no connector found, disabling fbdev emulation\n");
-	}
-
 	return 0;
 }
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
index e325c965..173a47f 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
@@ -129,7 +129,6 @@ static const u32 rcar_du_vsp_formats[] = {
 	DRM_FORMAT_ARGB8888,
 	DRM_FORMAT_XRGB8888,
 	DRM_FORMAT_UYVY,
-	DRM_FORMAT_VYUY,
 	DRM_FORMAT_YUYV,
 	DRM_FORMAT_YVYU,
 	DRM_FORMAT_NV12,
-- 
2.7.4

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

* [cip-dev] [PATCH 4.19.y-cip 26/32] drm: rcar-du: Disable unused DPAD outputs
  2019-10-01  8:24 [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874 Fabrizio Castro
                   ` (24 preceding siblings ...)
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 25/32] drm/rcar-du: Use drm_fbdev_generic_setup() Fabrizio Castro
@ 2019-10-01  8:25 ` Fabrizio Castro
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 27/32] drm: rcar-du: Replace EXT_CTRL_REGS feature flag with generation check Fabrizio Castro
                   ` (7 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: Fabrizio Castro @ 2019-10-01  8:25 UTC (permalink / raw)
  To: cip-dev

From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

commit dedd876c949e56351f27aa52bf2eddd4a447f5bb upstream.

DU channels are routed to DPAD outputs in an SoC-dependent way. The
routing can be fixed (e.g. DU3 to DPAD0 on H3) or configurable (e.g. DU0
or DU1 to DPAD0 on D3/E3). The hardware offers no option to disconnect
DPAD outputs, which are thus always driven by a DU channel.

On SoCs that have less DU channels than DU outputs, such as D3 and E3,
the DPAD output is always driven when all channels are in use by other
outputs (such as the internal LVDS and HDMI encoders). This creates an
unwanted clone on the DPAD output.

However, the parallel output of the DU channels routed to DPAD can be
set to fixed levels in the DU channels themselves through the DOFLR
group register. Use this to turn the DPAD on or off by driving fixed
signals at the output of any DU channel not routed to a DPAD output.
This doesn't affect the DU output signals going to other outputs.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
---
 drivers/gpu/drm/rcar-du/rcar_du_group.c | 43 +++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c
index cc3782e..7379899 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
@@ -276,6 +276,47 @@ int rcar_du_set_dpad0_vsp1_routing(struct rcar_du_device *rcdu)
 	return 0;
 }
 
+static void rcar_du_group_set_dpad_levels(struct rcar_du_group *rgrp)
+{
+	static const u32 doflr_values[2] = {
+		DOFLR_HSYCFL0 | DOFLR_VSYCFL0 | DOFLR_ODDFL0 |
+		DOFLR_DISPFL0 | DOFLR_CDEFL0  | DOFLR_RGBFL0,
+		DOFLR_HSYCFL1 | DOFLR_VSYCFL1 | DOFLR_ODDFL1 |
+		DOFLR_DISPFL1 | DOFLR_CDEFL1  | DOFLR_RGBFL1,
+	};
+	static const u32 dpad_mask = BIT(RCAR_DU_OUTPUT_DPAD1)
+				   | BIT(RCAR_DU_OUTPUT_DPAD0);
+	struct rcar_du_device *rcdu = rgrp->dev;
+	u32 doflr = DOFLR_CODE;
+	unsigned int i;
+
+	if (rcdu->info->gen < 2)
+		return;
+
+	/*
+	 * The DPAD outputs can't be controlled directly. However, the parallel
+	 * output of the DU channels routed to DPAD can be set to fixed levels
+	 * through the DOFLR group register. Use this to turn the DPAD on or off
+	 * by driving fixed low-level signals@the output of any DU channel
+	 * not routed to a DPAD output. This doesn't affect the DU output
+	 * signals going to other outputs, such as the internal LVDS and HDMI
+	 * encoders.
+	 */
+
+	for (i = 0; i < rgrp->num_crtcs; ++i) {
+		struct rcar_du_crtc_state *rstate;
+		struct rcar_du_crtc *rcrtc;
+
+		rcrtc = &rcdu->crtcs[rgrp->index * 2 + i];
+		rstate = to_rcar_crtc_state(rcrtc->crtc.state);
+
+		if (!(rstate->outputs & dpad_mask))
+			doflr |= doflr_values[i];
+	}
+
+	rcar_du_group_write(rgrp, DOFLR, doflr);
+}
+
 int rcar_du_group_set_routing(struct rcar_du_group *rgrp)
 {
 	struct rcar_du_device *rcdu = rgrp->dev;
@@ -295,5 +336,7 @@ int rcar_du_group_set_routing(struct rcar_du_group *rgrp)
 
 	rcar_du_group_write(rgrp, DORCR, dorcr);
 
+	rcar_du_group_set_dpad_levels(rgrp);
+
 	return rcar_du_set_dpad0_vsp1_routing(rgrp->dev);
 }
-- 
2.7.4

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

* [cip-dev] [PATCH 4.19.y-cip 27/32] drm: rcar-du: Replace EXT_CTRL_REGS feature flag with generation check
  2019-10-01  8:24 [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874 Fabrizio Castro
                   ` (25 preceding siblings ...)
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 26/32] drm: rcar-du: Disable unused DPAD outputs Fabrizio Castro
@ 2019-10-01  8:25 ` Fabrizio Castro
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 28/32] media: use strscpy() instead of strlcpy() Fabrizio Castro
                   ` (6 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: Fabrizio Castro @ 2019-10-01  8:25 UTC (permalink / raw)
  To: cip-dev

From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

commit cef0d9cfe4e5b6c756c268c1b7dda7fa257336fc upstream.

The RCAR_DU_FEATURE_EXT_CTRL_REGS feature flag is missing for H1 only,
which is a first generation device, not a second generation device as
reported in the device information table. Fix the H1 generation and use
generation checks to replace the feature flag.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
[fab: backported to 4.19.y-cip]
Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
---
 drivers/gpu/drm/rcar-du/rcar_du_drv.c   | 12 +-----------
 drivers/gpu/drm/rcar-du/rcar_du_drv.h   |  7 +++----
 drivers/gpu/drm/rcar-du/rcar_du_group.c |  4 ++--
 3 files changed, 6 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
index a665679..d22b381 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
@@ -40,7 +40,6 @@
 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_TVM_SYNC,
 	.channels_mask = BIT(1) | BIT(0),
@@ -63,7 +62,6 @@ static const struct rcar_du_device_info rzg1_du_r8a7743_info = {
 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_TVM_SYNC,
 	.channels_mask = BIT(1) | BIT(0),
@@ -138,7 +136,7 @@ static const struct rcar_du_device_info rcar_du_r8a774c0_info = {
 };
 
 static const struct rcar_du_device_info rcar_du_r8a7779_info = {
-	.gen = 2,
+	.gen = 1,
 	.features = RCAR_DU_FEATURE_INTERLACED
 		  | RCAR_DU_FEATURE_TVM_SYNC,
 	.channels_mask = BIT(1) | BIT(0),
@@ -161,7 +159,6 @@ static const struct rcar_du_device_info rcar_du_r8a7779_info = {
 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_TVM_SYNC,
 	.quirks = RCAR_DU_QUIRK_ALIGN_128B,
@@ -191,7 +188,6 @@ static const struct rcar_du_device_info rcar_du_r8a7790_info = {
 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_TVM_SYNC,
 	.channels_mask = BIT(1) | BIT(0),
@@ -215,7 +211,6 @@ static const struct rcar_du_device_info rcar_du_r8a7791_info = {
 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_TVM_SYNC,
 	.channels_mask = BIT(1) | BIT(0),
@@ -235,7 +230,6 @@ static const struct rcar_du_device_info rcar_du_r8a7792_info = {
 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_TVM_SYNC,
 	.channels_mask = BIT(1) | BIT(0),
@@ -258,7 +252,6 @@ static const struct rcar_du_device_info rcar_du_r8a7794_info = {
 static const struct rcar_du_device_info rcar_du_r8a7795_info = {
 	.gen = 3,
 	.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_TVM_SYNC,
@@ -292,7 +285,6 @@ static const struct rcar_du_device_info rcar_du_r8a7795_info = {
 static const struct rcar_du_device_info rcar_du_r8a7796_info = {
 	.gen = 3,
 	.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_TVM_SYNC,
@@ -322,7 +314,6 @@ static const struct rcar_du_device_info rcar_du_r8a7796_info = {
 static const struct rcar_du_device_info rcar_du_r8a77965_info = {
 	.gen = 3,
 	.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_TVM_SYNC,
@@ -352,7 +343,6 @@ static const struct rcar_du_device_info rcar_du_r8a77965_info = {
 static const struct rcar_du_device_info rcar_du_r8a77970_info = {
 	.gen = 3,
 	.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_TVM_SYNC,
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
index eb05bbd..f16cd26 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
@@ -28,10 +28,9 @@ struct rcar_du_device;
 struct rcar_du_encoder;
 
 #define RCAR_DU_FEATURE_CRTC_IRQ_CLOCK	BIT(0)	/* Per-CRTC IRQ and clock */
-#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_FEATURE_VSP1_SOURCE	BIT(1)	/* Has inputs from VSP1 */
+#define RCAR_DU_FEATURE_INTERLACED	BIT(2)	/* HW supports interlaced */
+#define RCAR_DU_FEATURE_TVM_SYNC	BIT(3)	/* Has TV switch/sync modes */
 
 #define RCAR_DU_QUIRK_ALIGN_128B	BIT(0)	/* Align pitches to 128 bytes */
 
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c
index 7379899..3e87fbf 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
@@ -151,7 +151,7 @@ static void rcar_du_group_setup(struct rcar_du_group *rgrp)
 
 	rcar_du_group_setup_pins(rgrp);
 
-	if (rcar_du_has(rgrp->dev, RCAR_DU_FEATURE_EXT_CTRL_REGS)) {
+	if (rcdu->info->gen >= 2) {
 		rcar_du_group_setup_defr8(rgrp);
 		rcar_du_group_setup_didsr(rgrp);
 	}
@@ -251,7 +251,7 @@ int rcar_du_set_dpad0_vsp1_routing(struct rcar_du_device *rcdu)
 	unsigned int index;
 	int ret;
 
-	if (!rcar_du_has(rcdu, RCAR_DU_FEATURE_EXT_CTRL_REGS))
+	if (rcdu->info->gen < 2)
 		return 0;
 
 	/*
-- 
2.7.4

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

* [cip-dev] [PATCH 4.19.y-cip 28/32] media: use strscpy() instead of strlcpy()
  2019-10-01  8:24 [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874 Fabrizio Castro
                   ` (26 preceding siblings ...)
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 27/32] drm: rcar-du: Replace EXT_CTRL_REGS feature flag with generation check Fabrizio Castro
@ 2019-10-01  8:25 ` Fabrizio Castro
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 29/32] arm64: dts: renesas: r8a774c0: Add display output support Fabrizio Castro
                   ` (5 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: Fabrizio Castro @ 2019-10-01  8:25 UTC (permalink / raw)
  To: cip-dev

From: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>

commit c0decac19da3906d9b66291e57b7759489e1170f upstream.

The implementation of strscpy() is more robust and safer.

That's now the recommended way to copy NUL terminated strings.

Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Reviewed-by: Kees Cook <keescook@chromium.org>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
[fab: cherry-picked changes for vsp1_drv.c only]
Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
---
 drivers/media/platform/vsp1/vsp1_drv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
index b6619c9..8c9d9d6 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -242,7 +242,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
 
 	mdev->dev = vsp1->dev;
 	mdev->hw_revision = vsp1->version;
-	strlcpy(mdev->model, vsp1->info->model, sizeof(mdev->model));
+	strscpy(mdev->model, vsp1->info->model, sizeof(mdev->model));
 	snprintf(mdev->bus_info, sizeof(mdev->bus_info), "platform:%s",
 		 dev_name(mdev->dev));
 	media_device_init(mdev);
-- 
2.7.4

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

* [cip-dev] [PATCH 4.19.y-cip 29/32] arm64: dts: renesas: r8a774c0: Add display output support
  2019-10-01  8:24 [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874 Fabrizio Castro
                   ` (27 preceding siblings ...)
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 28/32] media: use strscpy() instead of strlcpy() Fabrizio Castro
@ 2019-10-01  8:25 ` Fabrizio Castro
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 30/32] arm64: defconfig: Enable TDA19988 Fabrizio Castro
                   ` (4 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: Fabrizio Castro @ 2019-10-01  8:25 UTC (permalink / raw)
  To: cip-dev

commit 8ed3a6b223159df3eb52e85f59819ba1a1459940 upstream.

The RZ/G2E (a.k.a. R8A774C0) has one RGB output and two LVDS
outputs connected to DU.
This patch add support for DU, LVDS encoders, VSP and FCP.

Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
[fab: improved sorting of nodes]
Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
---
 arch/arm64/boot/dts/renesas/r8a774c0.dtsi | 167 ++++++++++++++++++++++++++++++
 1 file changed, 167 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a774c0.dtsi b/arch/arm64/boot/dts/renesas/r8a774c0.dtsi
index b92c60c..1d1bd65 100644
--- a/arch/arm64/boot/dts/renesas/r8a774c0.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a774c0.dtsi
@@ -1667,6 +1667,82 @@
 			status = "disabled";
 		};
 
+		vspb0: vsp at 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 R8A774C0_PD_ALWAYS_ON>;
+			resets = <&cpg 626>;
+			renesas,fcp = <&fcpvb0>;
+		};
+
+		vspd0: vsp at 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 R8A774C0_PD_ALWAYS_ON>;
+			resets = <&cpg 623>;
+			renesas,fcp = <&fcpvd0>;
+		};
+
+		vspd1: vsp at 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 R8A774C0_PD_ALWAYS_ON>;
+			resets = <&cpg 622>;
+			renesas,fcp = <&fcpvd1>;
+		};
+
+		vspi0: vsp at fe9a0000 {
+			compatible = "renesas,vsp2";
+			reg = <0 0xfe9a0000 0 0x8000>;
+			interrupts = <GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 631>;
+			power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+			resets = <&cpg 631>;
+			renesas,fcp = <&fcpvi0>;
+		};
+
+		fcpvb0: fcp at fe96f000 {
+			compatible = "renesas,fcpv";
+			reg = <0 0xfe96f000 0 0x200>;
+			clocks = <&cpg CPG_MOD 607>;
+			power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+			resets = <&cpg 607>;
+			iommus = <&ipmmu_vp0 5>;
+		};
+
+		fcpvd0: fcp at fea27000 {
+			compatible = "renesas,fcpv";
+			reg = <0 0xfea27000 0 0x200>;
+			clocks = <&cpg CPG_MOD 603>;
+			power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+			resets = <&cpg 603>;
+			iommus = <&ipmmu_vi0 8>;
+		};
+
+		fcpvd1: fcp at fea2f000 {
+			compatible = "renesas,fcpv";
+			reg = <0 0xfea2f000 0 0x200>;
+			clocks = <&cpg CPG_MOD 602>;
+			power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+			resets = <&cpg 602>;
+			iommus = <&ipmmu_vi0 9>;
+		};
+
+		fcpvi0: fcp at fe9af000 {
+			compatible = "renesas,fcpv";
+			reg = <0 0xfe9af000 0 0x200>;
+			clocks = <&cpg CPG_MOD 611>;
+			power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+			resets = <&cpg 611>;
+			iommus = <&ipmmu_vp0 8>;
+		};
+
 		csi40: csi2 at feaa0000 {
 			compatible = "renesas,r8a774c0-csi2";
 			reg = <0 0xfeaa0000 0 0x10000>;
@@ -1698,6 +1774,97 @@
 			};
 		};
 
+		du: display at feb00000 {
+			compatible = "renesas,du-r8a774c0";
+			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 at 0 {
+					reg = <0>;
+					du_out_rgb: endpoint {
+					};
+				};
+
+				port at 1 {
+					reg = <1>;
+					du_out_lvds0: endpoint {
+						remote-endpoint = <&lvds0_in>;
+					};
+				};
+
+				port at 2 {
+					reg = <2>;
+					du_out_lvds1: endpoint {
+						remote-endpoint = <&lvds1_in>;
+					};
+				};
+			};
+		};
+
+		lvds0: lvds-encoder at feb90000 {
+			compatible = "renesas,r8a774c0-lvds";
+			reg = <0 0xfeb90000 0 0x20>;
+			clocks = <&cpg CPG_MOD 727>;
+			power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+			resets = <&cpg 727>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port at 0 {
+					reg = <0>;
+					lvds0_in: endpoint {
+						remote-endpoint = <&du_out_lvds0>;
+					};
+				};
+
+				port at 1 {
+					reg = <1>;
+					lvds0_out: endpoint {
+					};
+				};
+			};
+		};
+
+		lvds1: lvds-encoder at feb90100 {
+			compatible = "renesas,r8a774c0-lvds";
+			reg = <0 0xfeb90100 0 0x20>;
+			clocks = <&cpg CPG_MOD 727>;
+			power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+			resets = <&cpg 726>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port at 0 {
+					reg = <0>;
+					lvds1_in: endpoint {
+						remote-endpoint = <&du_out_lvds1>;
+					};
+				};
+
+				port at 1 {
+					reg = <1>;
+					lvds1_out: endpoint {
+					};
+				};
+			};
+		};
+
 		prr: chipid at fff00044 {
 			compatible = "renesas,prr";
 			reg = <0 0xfff00044 0 4>;
-- 
2.7.4

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

* [cip-dev] [PATCH 4.19.y-cip 30/32] arm64: defconfig: Enable TDA19988
  2019-10-01  8:24 [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874 Fabrizio Castro
                   ` (28 preceding siblings ...)
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 29/32] arm64: dts: renesas: r8a774c0: Add display output support Fabrizio Castro
@ 2019-10-01  8:25 ` Fabrizio Castro
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 31/32] arm64: dts: renesas: cat874: Add HDMI video support Fabrizio Castro
                   ` (3 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: Fabrizio Castro @ 2019-10-01  8:25 UTC (permalink / raw)
  To: cip-dev

commit 998960be3a2e1b3b00387b42052127a8e6342de0 upstream.

The EK874 board comes with a TDA19988 chip on board, therefore
enable it in the defconfig.

Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 8561bef..dbe83fd 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -428,6 +428,7 @@ CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC=m
 CONFIG_VIDEO_RENESAS_FCP=m
 CONFIG_VIDEO_RENESAS_VSP1=m
 CONFIG_DRM=m
+CONFIG_DRM_I2C_NXP_TDA998X=m
 CONFIG_DRM_NOUVEAU=m
 CONFIG_DRM_EXYNOS=m
 CONFIG_DRM_EXYNOS5433_DECON=y
-- 
2.7.4

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

* [cip-dev] [PATCH 4.19.y-cip 31/32] arm64: dts: renesas: cat874: Add HDMI video support
  2019-10-01  8:24 [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874 Fabrizio Castro
                   ` (29 preceding siblings ...)
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 30/32] arm64: defconfig: Enable TDA19988 Fabrizio Castro
@ 2019-10-01  8:25 ` Fabrizio Castro
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 32/32] arm64: dts: renesas: cat874: Add HDMI audio Fabrizio Castro
                   ` (2 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: Fabrizio Castro @ 2019-10-01  8:25 UTC (permalink / raw)
  To: cip-dev

commit 94fc0ee22a5cb3a744a38906a55323fd6ac793fa upstream.

The CAT874 board comes with a HDMI connector, managed by
a TDA19988BET chip, connected to the RZ/G2E SoC via DPAD.
This patch adds the necessary support to the board DT.

Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
 arch/arm64/boot/dts/renesas/r8a774c0-cat874.dts | 81 +++++++++++++++++++++++++
 1 file changed, 81 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a774c0-cat874.dts b/arch/arm64/boot/dts/renesas/r8a774c0-cat874.dts
index 9241407..0623950 100644
--- a/arch/arm64/boot/dts/renesas/r8a774c0-cat874.dts
+++ b/arch/arm64/boot/dts/renesas/r8a774c0-cat874.dts
@@ -22,6 +22,17 @@
 		stdout-path = "serial0:115200n8";
 	};
 
+	hdmi-out {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_out: endpoint {
+				remote-endpoint = <&tda19988_out>;
+			};
+		};
+	};
+
 	leds {
 		compatible = "gpio-leds";
 
@@ -74,6 +85,31 @@
 		states = <3300000 1
 			  1800000 0>;
 	};
+
+	x13_clk: x13 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <74250000>;
+	};
+};
+
+&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 at 0 {
+			endpoint {
+				remote-endpoint = <&tda19988_in>;
+			};
+		};
+	};
 };
 
 &ehci0 {
@@ -85,6 +121,39 @@
 	clock-frequency = <48000000>;
 };
 
+&i2c0 {
+	status = "okay";
+	clock-frequency = <100000>;
+
+	tda19988: tda19988 at 70 {
+		compatible = "nxp,tda998x";
+		reg = <0x70>;
+		interrupt-parent = <&gpio1>;
+		interrupts = <1 IRQ_TYPE_LEVEL_LOW>;
+
+		video-ports = <0x234501>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port at 0 {
+				reg = <0>;
+				tda19988_in: endpoint {
+					remote-endpoint = <&du_out_rgb>;
+				};
+			};
+
+			port at 1 {
+				reg = <1>;
+				tda19988_out: endpoint {
+					remote-endpoint = <&hdmi_con_out>;
+				};
+			};
+		};
+	};
+};
+
 &i2c1 {
 	pinctrl-0 = <&i2c1_pins>;
 	pinctrl-names = "default";
@@ -98,6 +167,13 @@
 	};
 };
 
+&lvds0 {
+	status = "okay";
+
+	clocks = <&cpg CPG_MOD 727>, <&x13_clk>, <&extal_clk>;
+	clock-names = "fck", "dclkin.0", "extal";
+};
+
 &ohci0 {
 	dr_mode = "host";
 	status = "okay";
@@ -113,6 +189,11 @@
 };
 
 &pfc {
+	du_pins: du {
+		groups = "du_rgb888", "du_clk_out_0", "du_sync", "du_disp",
+			 "du_clk_in_0";
+		function = "du";
+	};
 
 	i2c1_pins: i2c1 {
 		groups = "i2c1_b";
-- 
2.7.4

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

* [cip-dev] [PATCH 4.19.y-cip 32/32] arm64: dts: renesas: cat874: Add HDMI audio
  2019-10-01  8:24 [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874 Fabrizio Castro
                   ` (30 preceding siblings ...)
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 31/32] arm64: dts: renesas: cat874: Add HDMI video support Fabrizio Castro
@ 2019-10-01  8:25 ` Fabrizio Castro
  2019-10-01 12:55 ` [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874 nobuhiro1.iwamatsu at toshiba.co.jp
  2019-10-02  6:55 ` nobuhiro1.iwamatsu at toshiba.co.jp
  33 siblings, 0 replies; 35+ messages in thread
From: Fabrizio Castro @ 2019-10-01  8:25 UTC (permalink / raw)
  To: cip-dev

commit a597dcb1d4ab7ddbba7e80b023eff892926f146c upstream.

The CAT874 board pushes sound via I2S over SSI0 into the
TDA19988BET chip.
This commit wires things up so that we can get sound out of
the HDMI interface.

Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
 arch/arm64/boot/dts/renesas/r8a774c0-cat874.dts | 56 +++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a774c0-cat874.dts b/arch/arm64/boot/dts/renesas/r8a774c0-cat874.dts
index 0623950..b7183f1 100644
--- a/arch/arm64/boot/dts/renesas/r8a774c0-cat874.dts
+++ b/arch/arm64/boot/dts/renesas/r8a774c0-cat874.dts
@@ -8,6 +8,7 @@
 /dts-v1/;
 #include "r8a774c0.dtsi"
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/display/tda998x.h>
 
 / {
 	model = "Silicon Linux RZ/G2E 96board platform (CAT874)";
@@ -63,6 +64,23 @@
 		reg = <0x0 0x48000000 0x0 0x78000000>;
 	};
 
+	sound: sound {
+		compatible = "simple-audio-card";
+
+		simple-audio-card,name = "CAT874 HDMI sound";
+		simple-audio-card,format = "i2s";
+		simple-audio-card,bitclock-master = <&sndcpu>;
+		simple-audio-card,frame-master = <&sndcpu>;
+
+		sndcpu: simple-audio-card,cpu {
+			sound-dai = <&rcar_sound>;
+		};
+
+		sndcodec: simple-audio-card,codec {
+			sound-dai = <&tda19988>;
+		};
+	};
+
 	vcc_sdhi0: regulator-vcc-sdhi0 {
 		compatible = "regulator-fixed";
 
@@ -93,6 +111,10 @@
 	};
 };
 
+&audio_clk_a {
+	clock-frequency = <22579200>;
+};
+
 &du {
 	pinctrl-0 = <&du_pins>;
 	pinctrl-names = "default";
@@ -133,6 +155,10 @@
 
 		video-ports = <0x234501>;
 
+		#sound-dai-cells = <0>;
+		audio-ports = <TDA998x_I2S 0x03>;
+		clocks = <&rcar_sound 1>;
+
 		ports {
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -216,6 +242,36 @@
 		function = "sdhi0";
 		power-source = <1800>;
 	};
+
+	sound_pins: sound {
+		groups = "ssi01239_ctrl", "ssi0_data";
+		function = "ssi";
+	};
+
+	sound_clk_pins: sound_clk {
+		groups = "audio_clkout1_a";
+		function = "audio_clk";
+	};
+};
+
+&rcar_sound {
+	pinctrl-0 = <&sound_pins &sound_clk_pins>;
+	pinctrl-names = "default";
+
+	/* Single DAI */
+	#sound-dai-cells = <0>;
+
+	/* audio_clkout0/1/2/3 */
+	#clock-cells = <1>;
+	clock-frequency = <11289600>;
+
+	status = "okay";
+
+	rcar_sound,dai {
+		dai0 {
+			playback = <&ssi0 &src0 &dvc0>;
+		};
+	};
 };
 
 &rwdt {
-- 
2.7.4

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

* [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874
  2019-10-01  8:24 [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874 Fabrizio Castro
                   ` (31 preceding siblings ...)
  2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 32/32] arm64: dts: renesas: cat874: Add HDMI audio Fabrizio Castro
@ 2019-10-01 12:55 ` nobuhiro1.iwamatsu at toshiba.co.jp
  2019-10-02  6:55 ` nobuhiro1.iwamatsu at toshiba.co.jp
  33 siblings, 0 replies; 35+ messages in thread
From: nobuhiro1.iwamatsu at toshiba.co.jp @ 2019-10-01 12:55 UTC (permalink / raw)
  To: cip-dev

Hi Fabrizio,


> -----Original Message-----
> From: Fabrizio Castro [mailto:fabrizio.castro at bp.renesas.com]
> Sent: Tuesday, October 1, 2019 5:25 PM
> To: cip-dev at lists.cip-project.org
> Cc: iwamatsu nobuhiro(?? ?? ????????)
> <nobuhiro1.iwamatsu@toshiba.co.jp>; pavel at denx.de; Chris Paterson
> <Chris.Paterson2@renesas.com>; Biju Das <biju.das@bp.renesas.com>;
> Fabrizio Castro <fabrizio.castro@bp.renesas.com>
> Subject: [cip-dev][PATCH 4.19.y-cip 00/32] Add HDMI support to EK874
> 
> Dear All,
> 
> this series adds HDMI video and audio support to the EK874 board.

I will check this seriese.

Best regards,
  Nobuhiro


> 
> Thanks,
> Fab
> 
> Christophe JAILLET (1):
>   drm: rcar-du: Fix the return value in case of error in
>     'rcar_du_crtc_set_crc_source()'
> 
> Fabrizio Castro (10):
>   media: vsp1: Add RZ/G support
>   media: dt-bindings: media: renesas-fcp: Add RZ/G2 support
>   dt-bindings: display: renesas: du: Document r8a774c0 bindings
>   dt-bindings: display: renesas: lvds: Document r8a774c0 bindings
>   drm: rcar-du: Add r8a774c0 device support
>   drm: rcar-du: lvds: add R8A774C0 support
>   arm64: dts: renesas: r8a774c0: Add display output support
>   arm64: defconfig: Enable TDA19988
>   arm64: dts: renesas: cat874: Add HDMI video support
>   arm64: dts: renesas: cat874: Add HDMI audio
> 
> Jacopo Mondi (1):
>   drm: rcar-du: Improve non-DPLL clock selection
> 
> Laurent Pinchart (17):
>   dt-bindings: display: renesas: lvds: Add EXTAL and DU_DOTCLKIN clocks
>   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: Move CRTC outputs bitmask to private CRTC state
>   drm: rcar-du: Simplify encoder registration
>   drm: rcar-du: lvds: Don't fail probe if output is not connected on
>     D3/E3
>   drm: rcar-du: lvds: Add API to enable/disable clock output
>   drm: rcar-du: Turn LVDS clock output on/off for DPAD0 output on D3/E3
>   drm: rcar-du: lvds: Fix post-DLL divider calculation
>   drm: rcar-du: lvds: Adjust operating frequency for D3 and E3
>   drm: rcar-du: Enable configurable DPAD0 routing on Gen3
>   drm: rcar-du: Fix vblank initialization
>   drm: rcar-du: Fix external clock error checks
>   drm: rcar-du: Reject modes that fail CRTC timing requirements
>   drm: rcar-du: Disable unused DPAD outputs
>   drm: rcar-du: Replace EXT_CTRL_REGS feature flag with generation check
> 
> Mauro Carvalho Chehab (1):
>   media: use strscpy() instead of strlcpy()
> 
> Noralf Tr?nnes (1):
>   drm/rcar-du: Use drm_fbdev_generic_setup()
> 
> Thomas Zimmermann (1):
>   drm/rcar-du: Replace drm_dev_unref with drm_dev_put
> 
>  .../bindings/display/bridge/renesas,lvds.txt       |  12 +-
>  .../devicetree/bindings/display/renesas,du.txt     |   2 +
>  .../devicetree/bindings/media/renesas,fcp.txt      |   5 +-
>  .../devicetree/bindings/media/renesas,vsp1.txt     |   6 +-
>  arch/arm64/boot/dts/renesas/r8a774c0-cat874.dts    | 137 +++++++
>  arch/arm64/boot/dts/renesas/r8a774c0.dtsi          | 167 ++++++++
>  arch/arm64/configs/defconfig                       |   1 +
>  drivers/gpu/drm/Makefile                           |   2 +-
>  drivers/gpu/drm/rcar-du/Kconfig                    |   1 +
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.c             | 294
> +++++++++-----
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.h             |   7 +-
>  drivers/gpu/drm/rcar-du/rcar_du_drv.c              |  55 +--
>  drivers/gpu/drm/rcar-du/rcar_du_drv.h              |  14 +-
>  drivers/gpu/drm/rcar-du/rcar_du_encoder.c          |  14 +-
>  drivers/gpu/drm/rcar-du/rcar_du_encoder.h          |   3 +-
>  drivers/gpu/drm/rcar-du/rcar_du_group.c            | 132 ++++--
>  drivers/gpu/drm/rcar-du/rcar_du_kms.c              | 109 ++---
>  drivers/gpu/drm/rcar-du/rcar_du_vsp.c              |   1 -
>  drivers/gpu/drm/rcar-du/rcar_lvds.c                | 441
> ++++++++++++++++++---
>  drivers/gpu/drm/rcar-du/rcar_lvds.h                |  27 ++
>  drivers/gpu/drm/rcar-du/rcar_lvds_regs.h           |  43 +-
>  drivers/media/platform/vsp1/vsp1_drv.c             |   2 +-
>  22 files changed, 1163 insertions(+), 312 deletions(-)  create mode
> 100644 drivers/gpu/drm/rcar-du/rcar_lvds.h
> 
> --
> 2.7.4

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

* [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874
  2019-10-01  8:24 [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874 Fabrizio Castro
                   ` (32 preceding siblings ...)
  2019-10-01 12:55 ` [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874 nobuhiro1.iwamatsu at toshiba.co.jp
@ 2019-10-02  6:55 ` nobuhiro1.iwamatsu at toshiba.co.jp
  33 siblings, 0 replies; 35+ messages in thread
From: nobuhiro1.iwamatsu at toshiba.co.jp @ 2019-10-02  6:55 UTC (permalink / raw)
  To: cip-dev

Hi Fabrizio,

> -----Original Message-----
> From: Fabrizio Castro [mailto:fabrizio.castro at bp.renesas.com]
> Sent: Tuesday, October 1, 2019 5:25 PM
> To: cip-dev at lists.cip-project.org
> Cc: iwamatsu nobuhiro(?? ?? ????????)
> <nobuhiro1.iwamatsu@toshiba.co.jp>; pavel at denx.de; Chris Paterson
> <Chris.Paterson2@renesas.com>; Biju Das <biju.das@bp.renesas.com>;
> Fabrizio Castro <fabrizio.castro@bp.renesas.com>
> Subject: [cip-dev][PATCH 4.19.y-cip 00/32] Add HDMI support to EK874
> 
> Dear All,
> 
> this series adds HDMI video and audio support to the EK874 board.
> 
> Thanks,
> Fab
> 
> Christophe JAILLET (1):
>   drm: rcar-du: Fix the return value in case of error in
>     'rcar_du_crtc_set_crc_source()'
> 
> Fabrizio Castro (10):
>   media: vsp1: Add RZ/G support
>   media: dt-bindings: media: renesas-fcp: Add RZ/G2 support
>   dt-bindings: display: renesas: du: Document r8a774c0 bindings
>   dt-bindings: display: renesas: lvds: Document r8a774c0 bindings
>   drm: rcar-du: Add r8a774c0 device support
>   drm: rcar-du: lvds: add R8A774C0 support
>   arm64: dts: renesas: r8a774c0: Add display output support
>   arm64: defconfig: Enable TDA19988
>   arm64: dts: renesas: cat874: Add HDMI video support
>   arm64: dts: renesas: cat874: Add HDMI audio
> 
> Jacopo Mondi (1):
>   drm: rcar-du: Improve non-DPLL clock selection
> 
> Laurent Pinchart (17):
>   dt-bindings: display: renesas: lvds: Add EXTAL and DU_DOTCLKIN clocks
>   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: Move CRTC outputs bitmask to private CRTC state
>   drm: rcar-du: Simplify encoder registration
>   drm: rcar-du: lvds: Don't fail probe if output is not connected on
>     D3/E3
>   drm: rcar-du: lvds: Add API to enable/disable clock output
>   drm: rcar-du: Turn LVDS clock output on/off for DPAD0 output on D3/E3
>   drm: rcar-du: lvds: Fix post-DLL divider calculation
>   drm: rcar-du: lvds: Adjust operating frequency for D3 and E3
>   drm: rcar-du: Enable configurable DPAD0 routing on Gen3
>   drm: rcar-du: Fix vblank initialization
>   drm: rcar-du: Fix external clock error checks
>   drm: rcar-du: Reject modes that fail CRTC timing requirements
>   drm: rcar-du: Disable unused DPAD outputs
>   drm: rcar-du: Replace EXT_CTRL_REGS feature flag with generation check
> 
> Mauro Carvalho Chehab (1):
>   media: use strscpy() instead of strlcpy()
> 
> Noralf Tr?nnes (1):
>   drm/rcar-du: Use drm_fbdev_generic_setup()
> 
> Thomas Zimmermann (1):
>   drm/rcar-du: Replace drm_dev_unref with drm_dev_put
> 
>  .../bindings/display/bridge/renesas,lvds.txt       |  12 +-
>  .../devicetree/bindings/display/renesas,du.txt     |   2 +
>  .../devicetree/bindings/media/renesas,fcp.txt      |   5 +-
>  .../devicetree/bindings/media/renesas,vsp1.txt     |   6 +-
>  arch/arm64/boot/dts/renesas/r8a774c0-cat874.dts    | 137 +++++++
>  arch/arm64/boot/dts/renesas/r8a774c0.dtsi          | 167 ++++++++
>  arch/arm64/configs/defconfig                       |   1 +
>  drivers/gpu/drm/Makefile                           |   2 +-
>  drivers/gpu/drm/rcar-du/Kconfig                    |   1 +
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.c             | 294
> +++++++++-----
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.h             |   7 +-
>  drivers/gpu/drm/rcar-du/rcar_du_drv.c              |  55 +--
>  drivers/gpu/drm/rcar-du/rcar_du_drv.h              |  14 +-
>  drivers/gpu/drm/rcar-du/rcar_du_encoder.c          |  14 +-
>  drivers/gpu/drm/rcar-du/rcar_du_encoder.h          |   3 +-
>  drivers/gpu/drm/rcar-du/rcar_du_group.c            | 132 ++++--
>  drivers/gpu/drm/rcar-du/rcar_du_kms.c              | 109 ++---
>  drivers/gpu/drm/rcar-du/rcar_du_vsp.c              |   1 -
>  drivers/gpu/drm/rcar-du/rcar_lvds.c                | 441
> ++++++++++++++++++---
>  drivers/gpu/drm/rcar-du/rcar_lvds.h                |  27 ++
>  drivers/gpu/drm/rcar-du/rcar_lvds_regs.h           |  43 +-
>  drivers/media/platform/vsp1/vsp1_drv.c             |   2 +-
>  22 files changed, 1163 insertions(+), 312 deletions(-)  create mode
> 100644 drivers/gpu/drm/rcar-du/rcar_lvds.h
> 

Applied, thanks.

Best regards,
  Nobuhiro

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

end of thread, other threads:[~2019-10-02  6:55 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-01  8:24 [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874 Fabrizio Castro
2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 01/32] media: vsp1: Add RZ/G support Fabrizio Castro
2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 02/32] media: dt-bindings: media: renesas-fcp: Add RZ/G2 support Fabrizio Castro
2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 03/32] dt-bindings: display: renesas: du: Document r8a774c0 bindings Fabrizio Castro
2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 04/32] dt-bindings: display: renesas: lvds: Add EXTAL and DU_DOTCLKIN clocks Fabrizio Castro
2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 05/32] dt-bindings: display: renesas: lvds: Document r8a774c0 bindings Fabrizio Castro
2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 06/32] drm: rcar-du: lvds: D3/E3 support Fabrizio Castro
2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 07/32] drm: rcar-du: Perform the initial CRTC setup from rcar_du_crtc_get() Fabrizio Castro
2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 08/32] drm: rcar-du: Use LVDS PLL clock as dot clock when possible Fabrizio Castro
2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 09/32] drm: rcar-du: Add r8a774c0 device support Fabrizio Castro
2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 10/32] drm: rcar-du: lvds: add R8A774C0 support Fabrizio Castro
2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 11/32] drm: rcar-du: Move CRTC outputs bitmask to private CRTC state Fabrizio Castro
2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 12/32] drm: rcar-du: Simplify encoder registration Fabrizio Castro
2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 13/32] drm: rcar-du: lvds: Don't fail probe if output is not connected on D3/E3 Fabrizio Castro
2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 14/32] drm: rcar-du: lvds: Add API to enable/disable clock output Fabrizio Castro
2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 15/32] drm: rcar-du: Turn LVDS clock output on/off for DPAD0 output on D3/E3 Fabrizio Castro
2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 16/32] drm: rcar-du: lvds: Fix post-DLL divider calculation Fabrizio Castro
2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 17/32] drm: rcar-du: lvds: Adjust operating frequency for D3 and E3 Fabrizio Castro
2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 18/32] drm: rcar-du: Improve non-DPLL clock selection Fabrizio Castro
2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 19/32] drm: rcar-du: Enable configurable DPAD0 routing on Gen3 Fabrizio Castro
2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 20/32] drm/rcar-du: Replace drm_dev_unref with drm_dev_put Fabrizio Castro
2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 21/32] drm: rcar-du: Fix the return value in case of error in 'rcar_du_crtc_set_crc_source()' Fabrizio Castro
2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 22/32] drm: rcar-du: Fix vblank initialization Fabrizio Castro
2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 23/32] drm: rcar-du: Fix external clock error checks Fabrizio Castro
2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 24/32] drm: rcar-du: Reject modes that fail CRTC timing requirements Fabrizio Castro
2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 25/32] drm/rcar-du: Use drm_fbdev_generic_setup() Fabrizio Castro
2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 26/32] drm: rcar-du: Disable unused DPAD outputs Fabrizio Castro
2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 27/32] drm: rcar-du: Replace EXT_CTRL_REGS feature flag with generation check Fabrizio Castro
2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 28/32] media: use strscpy() instead of strlcpy() Fabrizio Castro
2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 29/32] arm64: dts: renesas: r8a774c0: Add display output support Fabrizio Castro
2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 30/32] arm64: defconfig: Enable TDA19988 Fabrizio Castro
2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 31/32] arm64: dts: renesas: cat874: Add HDMI video support Fabrizio Castro
2019-10-01  8:25 ` [cip-dev] [PATCH 4.19.y-cip 32/32] arm64: dts: renesas: cat874: Add HDMI audio Fabrizio Castro
2019-10-01 12:55 ` [cip-dev] [PATCH 4.19.y-cip 00/32] Add HDMI support to EK874 nobuhiro1.iwamatsu at toshiba.co.jp
2019-10-02  6:55 ` nobuhiro1.iwamatsu at toshiba.co.jp

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