[ Meson64-dev ] update patchset

- update to latest patchset from Baylibre
	- Some bugs addressed
	- Open items:
		- HDMI does not want to work on boot
		- If a "problematic" monitor is present at boot HDMI will not respond to replug
		- changing monitors after boot results in 1/2 of the display appearing, second replug and it's ok.
		- Changing HDMI resolution results in corrupted screen (aliasing, static, "lines" etc.)
This commit is contained in:
Thomas McKahan 2018-12-06 00:46:10 -05:00
parent b7327c1315
commit b21cf05f6f
55 changed files with 1755 additions and 142 deletions

View file

@ -1,6 +1,6 @@
#
# Automatically generated file; DO NOT EDIT.
# Linux/arm64 4.19.5 Kernel Configuration
# Linux/arm64 4.19.7 Kernel Configuration
#
#
@ -3083,6 +3083,8 @@ CONFIG_REGULATOR_S2MPS11=y
# CONFIG_REGULATOR_TPS6524X is not set
# CONFIG_REGULATOR_VCTRL is not set
# CONFIG_REGULATOR_VEXPRESS is not set
CONFIG_CEC_CORE=m
CONFIG_CEC_NOTIFIER=y
CONFIG_RC_CORE=m
CONFIG_RC_MAP=m
# CONFIG_LIRC is not set
@ -3123,7 +3125,8 @@ CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
# CONFIG_MEDIA_RADIO_SUPPORT is not set
# CONFIG_MEDIA_SDR_SUPPORT is not set
# CONFIG_MEDIA_CEC_SUPPORT is not set
CONFIG_MEDIA_CEC_SUPPORT=y
# CONFIG_MEDIA_CEC_RC is not set
CONFIG_MEDIA_CONTROLLER=y
# CONFIG_MEDIA_CONTROLLER_DVB is not set
CONFIG_VIDEO_DEV=m
@ -3298,6 +3301,12 @@ CONFIG_VIDEO_EM28XX_V4L2=m
CONFIG_VIDEO_EM28XX_ALSA=m
CONFIG_VIDEO_EM28XX_DVB=m
CONFIG_VIDEO_EM28XX_RC=m
#
# USB HDMI CEC adapters
#
# CONFIG_USB_PULSE8_CEC is not set
# CONFIG_USB_RAINSHADOW_CEC is not set
CONFIG_V4L_PLATFORM_DRIVERS=y
# CONFIG_VIDEO_CADENCE is not set
# CONFIG_VIDEO_MUX is not set
@ -3315,6 +3324,10 @@ CONFIG_VIDEO_VIVID_MAX_DEVS=64
CONFIG_VIDEO_VIM2M=m
# CONFIG_VIDEO_VICODEC is not set
CONFIG_DVB_PLATFORM_DRIVERS=y
CONFIG_CEC_PLATFORM_DRIVERS=y
# CONFIG_VIDEO_CROS_EC_CEC is not set
CONFIG_VIDEO_MESON_AO_CEC=m
# CONFIG_CEC_GPIO is not set
#
# Supported MMC/SDIO adapters
@ -3642,7 +3655,7 @@ CONFIG_DRM_PANEL_BRIDGE=y
CONFIG_DRM_DW_HDMI=m
# CONFIG_DRM_DW_HDMI_AHB_AUDIO is not set
CONFIG_DRM_DW_HDMI_I2S_AUDIO=m
# CONFIG_DRM_DW_HDMI_CEC is not set
CONFIG_DRM_DW_HDMI_CEC=m
# CONFIG_DRM_ARCPGU is not set
# CONFIG_DRM_HISI_KIRIN is not set
# CONFIG_DRM_MXSFB is not set

View file

@ -1,4 +1,4 @@
From b0dae92632d5f77908e01dc30863bb8aa6218202 Mon Sep 17 00:00:00 2001
From 4770a464de7b87bc849e4e110f197ef9fa7bccf6 Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Thu, 30 Mar 2017 11:49:55 +0200
Subject: [PATCH] ASoC: meson: add meson audio core driver
@ -15,6 +15,7 @@ of the S905 (gxbb). This datasheet is available here: [0].
[0]: http://dn.odroid.com/S905/DataSheet/S905_Public_Datasheet_V1.1.4.pdf
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
sound/soc/meson/Kconfig | 10 +++
sound/soc/meson/Makefile | 4 +

View file

@ -1,4 +1,4 @@
From 4551d6702a5eedee054ece9bd1a276b3423449aa Mon Sep 17 00:00:00 2001
From dc1d93ea8dc61686364e2659c1ac1392681b64b4 Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Thu, 30 Mar 2017 12:00:10 +0200
Subject: [PATCH] ASoC: meson: add register definitions
@ -6,6 +6,7 @@ Subject: [PATCH] ASoC: meson: add register definitions
Add the register definition for the AIU and AUDIN blocks
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
sound/soc/meson/aiu-regs.h | 182 +++++++++++++++++++++++++++++++++++++++++++
sound/soc/meson/audin-regs.h | 148 +++++++++++++++++++++++++++++++++++

View file

@ -1,4 +1,4 @@
From 7c84e827ffe2d39d384f3c5c6e08a5abb3d3f422 Mon Sep 17 00:00:00 2001
From ef53207463b1ffa58dbc8b994cb470f35bf12420 Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Thu, 30 Mar 2017 12:14:40 +0200
Subject: [PATCH] ASoC: meson: add aiu i2s dma support
@ -6,6 +6,7 @@ Subject: [PATCH] ASoC: meson: add aiu i2s dma support
Add support for the i2s output dma which is part of the AIU block
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
sound/soc/meson/Kconfig | 7 +
sound/soc/meson/Makefile | 4 +-

View file

@ -1,4 +1,4 @@
From c1307280e950dd02e07bbc4951127b1355ffb4b7 Mon Sep 17 00:00:00 2001
From 9031b415030a316ec4ca513185e2d2c0fbb894c4 Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Thu, 30 Mar 2017 12:17:27 +0200
Subject: [PATCH] ASoC: meson: add initial i2s dai support
@ -8,6 +8,7 @@ With this initial implementation, only playback is supported.
Capture will be part of furture work.
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
sound/soc/meson/Kconfig | 2 +-
sound/soc/meson/Makefile | 4 +-

View file

@ -1,4 +1,4 @@
From 6969282247e4447e484941bc0830b9a13d22d055 Mon Sep 17 00:00:00 2001
From 32a55958cc2d89e2feee831ca4e6ceae8458e950 Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Thu, 30 Mar 2017 13:43:52 +0200
Subject: [PATCH] ASoC: meson: add aiu spdif dma support
@ -6,6 +6,7 @@ Subject: [PATCH] ASoC: meson: add aiu spdif dma support
Add support for the spdif output dma which is part of the AIU block
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
sound/soc/meson/Kconfig | 7 +
sound/soc/meson/Makefile | 4 +-

View file

@ -1,4 +1,4 @@
From 10cd10546c1f0e75910d5139d1fdfacdf814d5f7 Mon Sep 17 00:00:00 2001
From 67e2a1601f80648f5c318728218b788c51081fa3 Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Thu, 30 Mar 2017 13:46:03 +0200
Subject: [PATCH] ASoC: meson: add initial spdif dai support
@ -9,6 +9,7 @@ from the spdif dma is supported. Future work will add compressed
support, pcm playback from i2s dma and capture.
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
sound/soc/meson/Kconfig | 3 +-
sound/soc/meson/Makefile | 4 +-

View file

@ -1,4 +1,4 @@
From 23200da5413b35ff27f22ead266bd980b295dcc9 Mon Sep 17 00:00:00 2001
From 7ecd280bd317cff3c608b32b2a185929b2ec17ca Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Thu, 30 Mar 2017 15:19:04 +0200
Subject: [PATCH] ARM64: dts: meson-gx: add audio controller nodes
@ -11,6 +11,7 @@ Audio on this SoC family is still a work in progress. More nodes are likely
to be added later on (pcm DAIs, input DMAs, etc ...)
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 35 ++++++++++++++++++++++++++
arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 39 +++++++++++++++++++++++++++++

View file

@ -1,9 +1,10 @@
From c730657bfb2ba97e0f9ae7df50da494643fe8a09 Mon Sep 17 00:00:00 2001
From c89e4a9d376b72bb00c1c71795b86fe81914a3ea Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Fri, 7 Jul 2017 17:39:21 +0200
Subject: [PATCH] snd: meson: activate HDMI audio path
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
sound/soc/meson/i2s-dai.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)

View file

@ -1,9 +1,10 @@
From 7cd52c9e5d78c981f6cf7009d8240fe7286c7c00 Mon Sep 17 00:00:00 2001
From d46542e83265b476b32b94729e609a9a7767deac Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Tue, 14 Feb 2017 19:18:04 +0100
Subject: [PATCH] drm/meson: select dw-hdmi i2s audio for meson hdmi
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
drivers/gpu/drm/meson/Kconfig | 1 +
1 file changed, 1 insertion(+)

View file

@ -1,9 +1,10 @@
From aef100bfca7f4364380c08e5d9a4f646a85740c3 Mon Sep 17 00:00:00 2001
From 0eb1a7bb3fd9e1ff2f368bb20490c7a032fc96e6 Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Wed, 20 Sep 2017 18:01:26 +0200
Subject: [PATCH] ARM64: dts: meson-gx: add sound-dai-cells to HDMI node
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 1 +
arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 1 +

View file

@ -1,4 +1,4 @@
From 28ba04d755cf99d41d12e068b11ffc56994728a6 Mon Sep 17 00:00:00 2001
From f0417a0c309fb02a5896abb868a52a1a3e23d610 Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Wed, 20 Sep 2017 18:10:08 +0200
Subject: [PATCH] ARM64: dts: meson: activate hdmi audio HDMI enabled boards
@ -11,6 +11,7 @@ the audio I expect to see merged
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
.../arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi | 45 ++++++++++++++++++++++
.../boot/dts/amlogic/meson-gxbb-nanopi-k2.dts | 45 ++++++++++++++++++++++

View file

@ -1,10 +1,11 @@
From 6430f92c78a50a880a14a7de5831fbdc72fcb33f Mon Sep 17 00:00:00 2001
From 68854b3c7771ad5754ad46d42f45f626ca87b4ac Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Mon, 2 Jul 2018 12:21:55 +0200
Subject: [PATCH] drm: bridge: dw-hdmi: Use AUTO CTS setup mode when non-AHB
audio
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 41 ++++++++++++++++++++-----------
1 file changed, 26 insertions(+), 15 deletions(-)

View file

@ -1,4 +1,4 @@
From 6325b4c1b777359fe7557475d94abaf59b714647 Mon Sep 17 00:00:00 2001
From 40bfd476f6bb44f9bf88bbbc0bd4cfd9591bedc9 Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Wed, 28 Feb 2018 16:07:18 +0100
Subject: [PATCH] drm/meson: Call drm_crtc_vblank_on / drm_crtc_vblank_off
@ -6,12 +6,14 @@ Subject: [PATCH] drm/meson: Call drm_crtc_vblank_on / drm_crtc_vblank_off
Make sure that the CRTC code will call the enable/disable_vblank hooks.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/gpu/drm/meson/meson_crtc.c | 6 ++++++
1 file changed, 6 insertions(+)
drivers/gpu/drm/meson/meson_crtc.c | 4 ++++
drivers/gpu/drm/meson/meson_venc.c | 3 +++
2 files changed, 7 insertions(+)
diff --git a/drivers/gpu/drm/meson/meson_crtc.c b/drivers/gpu/drm/meson/meson_crtc.c
index 0552020..4dd0df0 100644
index 0552020..7c0bdc8 100644
--- a/drivers/gpu/drm/meson/meson_crtc.c
+++ b/drivers/gpu/drm/meson/meson_crtc.c
@@ -102,6 +102,8 @@ static void meson_crtc_atomic_enable(struct drm_crtc *crtc,
@ -23,14 +25,37 @@ index 0552020..4dd0df0 100644
}
static void meson_crtc_atomic_disable(struct drm_crtc *crtc,
@@ -110,6 +112,10 @@ static void meson_crtc_atomic_disable(struct drm_crtc *crtc,
@@ -110,6 +112,8 @@ static void meson_crtc_atomic_disable(struct drm_crtc *crtc,
struct meson_crtc *meson_crtc = to_meson_crtc(crtc);
struct meson_drm *priv = meson_crtc->priv;
+ DRM_DEBUG_DRIVER("\n");
+
+ drm_crtc_vblank_off(crtc);
+
priv->viu.osd1_enabled = false;
priv->viu.osd1_commit = false;
diff --git a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c
index 514245e..14aac66 100644
--- a/drivers/gpu/drm/meson/meson_venc.c
+++ b/drivers/gpu/drm/meson/meson_venc.c
@@ -71,6 +71,7 @@
*/
/* HHI Registers */
+#define HHI_GCLK_MPEG2 0x148 /* 0x52 offset in data sheet */
#define HHI_VDAC_CNTL0 0x2F4 /* 0xbd offset in data sheet */
#define HHI_VDAC_CNTL1 0x2F8 /* 0xbe offset in data sheet */
#define HHI_HDMI_PHY_CNTL0 0x3a0 /* 0xe8 offset in data sheet */
@@ -1529,10 +1530,12 @@ unsigned int meson_venci_get_field(struct meson_drm *priv)
void meson_venc_enable_vsync(struct meson_drm *priv)
{
writel_relaxed(2, priv->io_base + _REG(VENC_INTCTRL));
+ regmap_update_bits(priv->hhi, HHI_GCLK_MPEG2, BIT(25), BIT(25));
}
void meson_venc_disable_vsync(struct meson_drm *priv)
{
+ regmap_update_bits(priv->hhi, HHI_GCLK_MPEG2, BIT(25), 0);
writel_relaxed(0, priv->io_base + _REG(VENC_INTCTRL));
}

View file

@ -1,49 +0,0 @@
From 926a9328494aae7a94241a494b0d6ea27c300d3a Mon Sep 17 00:00:00 2001
From: Maxime Jourdan <maxi.jourdan@wanadoo.fr>
Date: Sat, 28 Jul 2018 22:40:27 +0200
Subject: [PATCH] dt-bindings: soc: amlogic: add meson-canvas documentation
DT bindings doc for amlogic,meson-canvas
Reviewed-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Maxime Jourdan <mjourdan@baylibre.com>
---
.../bindings/soc/amlogic/amlogic,canvas.txt | 29 ++++++++++++++++++++++
1 file changed, 29 insertions(+)
create mode 100644 Documentation/devicetree/bindings/soc/amlogic/amlogic,canvas.txt
diff --git a/Documentation/devicetree/bindings/soc/amlogic/amlogic,canvas.txt b/Documentation/devicetree/bindings/soc/amlogic/amlogic,canvas.txt
new file mode 100644
index 0000000..436d210
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/amlogic/amlogic,canvas.txt
@@ -0,0 +1,29 @@
+Amlogic Canvas
+================================
+
+A canvas is a collection of metadata that describes a pixel buffer.
+Those metadata include: width, height, phyaddr, wrapping, block mode
+and endianness.
+
+Many IPs within Amlogic SoCs rely on canvas indexes to read/write pixel data
+rather than use the phy addresses directly. For instance, this is the case for
+the video decoders and the display.
+
+Amlogic SoCs have 256 canvas.
+
+Device Tree Bindings:
+---------------------
+
+Video Lookup Table
+--------------------------
+
+Required properties:
+- compatible: "amlogic,canvas"
+- reg: Base physical address and size of the canvas registers.
+
+Example:
+
+canvas: video-lut@48 {
+ compatible = "amlogic,canvas";
+ reg = <0x0 0x48 0x0 0x14>;
+};

View file

@ -1,4 +1,4 @@
From 556eda8255f623746f7379a3286b8600a7c9de4b Mon Sep 17 00:00:00 2001
From 47756c823298bef3895fa2837c4b3e97062e9842 Mon Sep 17 00:00:00 2001
From: Maxime Jourdan <maxi.jourdan@wanadoo.fr>
Date: Fri, 20 Apr 2018 13:17:07 +0200
Subject: [PATCH] soc: amlogic: add meson-canvas driver
@ -14,6 +14,7 @@ pixels.
Reviewed-by: Jerome Brunet <jbrunet@baylibre.com>
Tested-by: Neil Armstrong <narmstrong@baylibre.com>
Signed-off-by: Maxime Jourdan <mjourdan@baylibre.com>
---
drivers/soc/amlogic/Kconfig | 7 ++
drivers/soc/amlogic/Makefile | 1 +

View file

@ -1,4 +1,4 @@
From aa08bea6fe68d96e7d310ee64416e9a345c4cc01 Mon Sep 17 00:00:00 2001
From b2b84d801a2e8145b2a08e0d310682fc5e88b0ad Mon Sep 17 00:00:00 2001
From: Maxime Jourdan <maxi.jourdan@wanadoo.fr>
Date: Fri, 20 Apr 2018 16:09:09 +0200
Subject: [PATCH] ARM64: dts: meson-gx: add dmcbus and canvas nodes.
@ -8,6 +8,7 @@ including the ones needed for the canvas module.
Reviewed-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Maxime Jourdan <mjourdan@baylibre.com>
---
arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 13 +++++++++++++
1 file changed, 13 insertions(+)

View file

@ -1,25 +0,0 @@
From 78b5e8bc5c97e5adeee4f9487f8e0b0dffe5da18 Mon Sep 17 00:00:00 2001
From: Maxime Jourdan <mjourdan@baylibre.com>
Date: Fri, 12 Oct 2018 15:45:13 +0200
Subject: [PATCH] dt-bindings: display: amlogic, meson-vpu: Add optional canvas
provider node
Allows using the new canvas provider module if present.
Signed-off-by: Maxime Jourdan <mjourdan@baylibre.com>
---
Documentation/devicetree/bindings/display/amlogic,meson-vpu.txt | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/display/amlogic,meson-vpu.txt b/Documentation/devicetree/bindings/display/amlogic,meson-vpu.txt
index 057b813..83f3b7b 100644
--- a/Documentation/devicetree/bindings/display/amlogic,meson-vpu.txt
+++ b/Documentation/devicetree/bindings/display/amlogic,meson-vpu.txt
@@ -67,6 +67,7 @@ Required properties:
Optional properties:
- power-domains: Optional phandle to associated power domain as described in
the file ../power/power_domain.txt
+- amlogic,canvas: phandle to canvas provider node
Required nodes:

View file

@ -1,4 +1,4 @@
From 4c455045fd038dafcb1b0e03fb1c1e350874c882 Mon Sep 17 00:00:00 2001
From 21a926d5d6a2973c1a1665482accac7548c1a67d Mon Sep 17 00:00:00 2001
From: Maxime Jourdan <mjourdan@baylibre.com>
Date: Mon, 15 Oct 2018 14:37:18 +0200
Subject: [PATCH] drm/meson: Use optional canvas provider
@ -10,6 +10,7 @@ If a canvas provider node is detected in DT, use it. Otherwise,
fall back to what is currently being done.
Signed-off-by: Maxime Jourdan <mjourdan@baylibre.com>
---
drivers/gpu/drm/meson/Kconfig | 1 +
drivers/gpu/drm/meson/meson_crtc.c | 14 +++++++----
@ -31,10 +32,10 @@ index 02d400b..8929058 100644
config DRM_MESON_DW_HDMI
tristate "HDMI Synopsys Controller support for Amlogic Meson Display"
diff --git a/drivers/gpu/drm/meson/meson_crtc.c b/drivers/gpu/drm/meson/meson_crtc.c
index 4dd0df0..33175e7 100644
index 7c0bdc8..8744244 100644
--- a/drivers/gpu/drm/meson/meson_crtc.c
+++ b/drivers/gpu/drm/meson/meson_crtc.c
@@ -199,10 +199,16 @@ void meson_crtc_irq(struct meson_drm *priv)
@@ -197,10 +197,16 @@ void meson_crtc_irq(struct meson_drm *priv)
} else
meson_vpp_disable_interlace_vscaler_osd1(priv);

View file

@ -1,4 +1,4 @@
From b89d9d4c05561753ed77cc673d4e7d31c11c36b5 Mon Sep 17 00:00:00 2001
From 7d3414ae548dd7d6e7caad845322b0dedcf05cb1 Mon Sep 17 00:00:00 2001
From: Maxime Jourdan <mjourdan@baylibre.com>
Date: Mon, 15 Oct 2018 14:38:24 +0200
Subject: [PATCH] arm64: dts: meson-gx: Add canvas provider node to the vpu
@ -6,6 +6,7 @@ Subject: [PATCH] arm64: dts: meson-gx: Add canvas provider node to the vpu
Allows the vpu driver to optionally use a canvas provider node.
Signed-off-by: Maxime Jourdan <mjourdan@baylibre.com>
---
arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 1 +
1 file changed, 1 insertion(+)

View file

@ -1,4 +1,4 @@
From aedc6019809eeb9f7502509664adc547b849ae83 Mon Sep 17 00:00:00 2001
From cfcbd82639be569a7ef6f71e991d7506b5e372ab Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Thu, 2 Aug 2018 10:00:01 +0200
Subject: [PATCH] drm/meson: Support Overlay plane for video rendering
@ -23,11 +23,12 @@ code and rewritten to match the atomic universal plane requirements.
The video rendering using this overlay plane support has been tested using
the new Kodi DRM-KMS Prime rendering path along the in-review V4L2 Mem2Mem
Hardware Video Decoder up to 3840x2160 NV12 frames on various display modes.
---
drivers/gpu/drm/meson/Makefile | 2 +-
drivers/gpu/drm/meson/meson_canvas.c | 7 +-
drivers/gpu/drm/meson/meson_canvas.h | 11 +-
drivers/gpu/drm/meson/meson_crtc.c | 214 +++++++++++-
drivers/gpu/drm/meson/meson_crtc.c | 216 +++++++++++-
drivers/gpu/drm/meson/meson_drv.c | 29 +-
drivers/gpu/drm/meson/meson_drv.h | 52 +++
drivers/gpu/drm/meson/meson_overlay.c | 586 ++++++++++++++++++++++++++++++++
@ -35,7 +36,7 @@ Hardware Video Decoder up to 3840x2160 NV12 frames on various display modes.
drivers/gpu/drm/meson/meson_registers.h | 3 +
drivers/gpu/drm/meson/meson_viu.c | 15 +
drivers/gpu/drm/meson/meson_vpp.c | 44 ++-
11 files changed, 969 insertions(+), 8 deletions(-)
11 files changed, 971 insertions(+), 8 deletions(-)
create mode 100644 drivers/gpu/drm/meson/meson_overlay.c
create mode 100644 drivers/gpu/drm/meson/meson_overlay.h
@ -115,7 +116,7 @@ index af1759d..85dbf26 100644
#endif /* __MESON_CANVAS_H */
diff --git a/drivers/gpu/drm/meson/meson_crtc.c b/drivers/gpu/drm/meson/meson_crtc.c
index 33175e7..988118d 100644
index 8744244..1d9d22c 100644
--- a/drivers/gpu/drm/meson/meson_crtc.c
+++ b/drivers/gpu/drm/meson/meson_crtc.c
@@ -25,6 +25,7 @@
@ -137,7 +138,12 @@ index 33175e7..988118d 100644
writel_bits_relaxed(VPP_POSTBLEND_ENABLE, VPP_POSTBLEND_ENABLE,
priv->io_base + _REG(VPP_MISC));
@@ -119,8 +124,12 @@ static void meson_crtc_atomic_disable(struct drm_crtc *crtc,
@@ -114,11 +119,17 @@ static void meson_crtc_atomic_disable(struct drm_crtc *crtc,
drm_crtc_vblank_off(crtc);
+ DRM_DEBUG_DRIVER("\n");
+
priv->viu.osd1_enabled = false;
priv->viu.osd1_commit = false;
@ -151,7 +157,7 @@ index 33175e7..988118d 100644
priv->io_base + _REG(VPP_MISC));
if (crtc->state->event && !crtc->state->active) {
@@ -155,6 +164,7 @@ static void meson_crtc_atomic_flush(struct drm_crtc *crtc,
@@ -153,6 +164,7 @@ static void meson_crtc_atomic_flush(struct drm_crtc *crtc,
struct meson_drm *priv = meson_crtc->priv;
priv->viu.osd1_commit = true;
@ -159,7 +165,7 @@ index 33175e7..988118d 100644
}
static const struct drm_crtc_helper_funcs meson_crtc_helper_funcs = {
@@ -208,7 +218,7 @@ void meson_crtc_irq(struct meson_drm *priv)
@@ -206,7 +218,7 @@ void meson_crtc_irq(struct meson_drm *priv)
meson_canvas_setup(priv, MESON_CANVAS_ID_OSD1,
priv->viu.osd1_addr, priv->viu.osd1_stride,
priv->viu.osd1_height, MESON_CANVAS_WRAP_NONE,
@ -168,7 +174,7 @@ index 33175e7..988118d 100644
/* Enable OSD1 */
writel_bits_relaxed(VPP_OSD1_POSTBLEND, VPP_OSD1_POSTBLEND,
@@ -217,6 +227,206 @@ void meson_crtc_irq(struct meson_drm *priv)
@@ -215,6 +227,206 @@ void meson_crtc_irq(struct meson_drm *priv)
priv->viu.osd1_commit = false;
}

View file

@ -1,4 +1,4 @@
From 5dbf8264e41eaa3e72e3b671c389924ee8dcfe81 Mon Sep 17 00:00:00 2001
From b92e7773bdb2d5c86091cbb2d03cc55ec6365115 Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Mon, 29 Oct 2018 17:04:05 +0100
Subject: [PATCH] drm/meson: move OSD scaler management into plane atomic
@ -8,6 +8,7 @@ In preparation to support the Primary Plane scaling, move the basic
OSD Interlace-Only scaler setup code into the primary plane atomic
update callback and handle the vsync scaler update like the overlay
plane scaling registers update.
---
drivers/gpu/drm/meson/meson_crtc.c | 35 ++++++++++++++++------------
drivers/gpu/drm/meson/meson_drv.h | 10 ++++++++
@ -16,7 +17,7 @@ plane scaling registers update.
4 files changed, 68 insertions(+), 62 deletions(-)
diff --git a/drivers/gpu/drm/meson/meson_crtc.c b/drivers/gpu/drm/meson/meson_crtc.c
index 988118d..332bb3b 100644
index 1d9d22c..6099997 100644
--- a/drivers/gpu/drm/meson/meson_crtc.c
+++ b/drivers/gpu/drm/meson/meson_crtc.c
@@ -193,21 +193,26 @@ void meson_crtc_irq(struct meson_drm *priv)

View file

@ -1,4 +1,4 @@
From f27c6434030c13a7ac474354f831ff15c3eda9d4 Mon Sep 17 00:00:00 2001
From 7489078416fdb581625f99ec87b828c2e22794ee Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Tue, 30 Oct 2018 14:29:10 +0100
Subject: [PATCH] drm/meson: Add primary plane scaling
@ -19,6 +19,7 @@ at 1920x1080 and upscaled to 3840x2160 in hardware.
The primary plane atomic check still allow 1:1 scaling, allowing native
3840x2160 if needed by user-space applications.
---
drivers/gpu/drm/meson/meson_plane.c | 186 +++++++++++++++++++++++++++---------
1 file changed, 141 insertions(+), 45 deletions(-)

View file

@ -1,4 +1,4 @@
From 5ba78fb13dd4d0664370dbaa638b1183d8893809 Mon Sep 17 00:00:00 2001
From 90af79faeb239f3a32974d99a2b58d4ce37cd0c1 Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Wed, 7 Nov 2018 11:34:47 +0100
Subject: [PATCH] pinctrl: meson-gxl: remove invalid GPIOX tsin_a pins
@ -8,12 +8,13 @@ patch completely removes these pins entries until we find out what
are the correct bits and registers to be used instead.
Fixes: 5a6ae9b80139 ("pinctrl: meson-gxl: add tsin_a pins")
---
drivers/pinctrl/meson/pinctrl-meson-gxl.c | 12 ++----------
1 file changed, 2 insertions(+), 10 deletions(-)
diff --git a/drivers/pinctrl/meson/pinctrl-meson-gxl.c b/drivers/pinctrl/meson/pinctrl-meson-gxl.c
index 7dae1d7..3277d17 100644
index 158f618..0c0a501 100644
--- a/drivers/pinctrl/meson/pinctrl-meson-gxl.c
+++ b/drivers/pinctrl/meson/pinctrl-meson-gxl.c
@@ -239,13 +239,9 @@ static const unsigned int eth_link_led_pins[] = { GPIOZ_14 };

View file

@ -1,4 +1,4 @@
From dce891a9e5d603bed54ee514f59162efe68c6ff7 Mon Sep 17 00:00:00 2001
From 6c4496753e3bea38dd4b42266c8402d048bde635 Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Thu, 8 Nov 2018 14:24:38 +0100
Subject: [PATCH] arm64: dts: meson-gx: Add hdmi_5v regulator as hdmi tx supply
@ -8,6 +8,7 @@ PHY and enables the HDMI 5V presence loopback for the monitor.
Fixes: b409f625a6d5 ("ARM64: dts: meson-gx: Add HDMI_5V regulator on selected boards")
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi | 1 +
arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts | 1 +

View file

@ -1,4 +1,4 @@
From f3f5e39c8f02f29fa3be209b0a7614f6531b71fd Mon Sep 17 00:00:00 2001
From a0d84363005399bb41b3eee556aa813a129bbcdf Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Wed, 7 Nov 2018 11:45:47 +0100
Subject: [PATCH] arm64: dts: meson-gxl-libretech-cc: fix GPIO lines names
@ -9,6 +9,7 @@ This patch moves the properties to the gpio nodes.
Fixes: 47884c5c746e ("ARM64: dts: meson-gxl-libretech-cc: Add GPIO lines names")
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

View file

@ -1,4 +1,4 @@
From c600988a4191261beaff6b0fdc1f84928b8f7a5d Mon Sep 17 00:00:00 2001
From 29cf4c3c228fd4cea4f46db9fa5e9386b3e794e6 Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Wed, 7 Nov 2018 11:45:48 +0100
Subject: [PATCH] arm64: dts: meson-gxbb-nanopi-k2: fix GPIO lines names
@ -9,6 +9,7 @@ This patch moves the properties to the gpio nodes.
Fixes: 12ada0513d7a ("ARM64: dts: meson-gxbb-nanopi-k2: Add GPIO lines names")
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

View file

@ -1,4 +1,4 @@
From 732bb87ee14975c42587a13e52bd8a1ebccfd8ee Mon Sep 17 00:00:00 2001
From fe156961d17219329389eee52306a731b8151b49 Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Wed, 7 Nov 2018 11:45:49 +0100
Subject: [PATCH] arm64: dts: meson-gxbb-odroidc2: fix GPIO lines names
@ -9,6 +9,7 @@ This patch moves the properties to the gpio nodes.
Fixes: b03c7d6438bb ("ARM64: dts: meson-gxbb-odroidc2: Add GPIO lines names")
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

View file

@ -1,4 +1,4 @@
From d1914d0c00cb04045ea8d303d750a268de683240 Mon Sep 17 00:00:00 2001
From 06df453970ccfbd1affb8ecd6ea50808fa132774 Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Wed, 7 Nov 2018 11:45:50 +0100
Subject: [PATCH] arm64: dts: meson-gxl-khadas-vim: fix GPIO lines names
@ -9,6 +9,7 @@ This patch moves the properties to the gpio nodes.
Fixes: 60795933b709 ("ARM64: dts: meson-gxl-khadas-vim: Add GPIO lines names")
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

View file

@ -1,4 +1,4 @@
From d670e3f855cfec66fd39dd5897cdeb55ef9ed0af Mon Sep 17 00:00:00 2001
From 96c3cc9c6943cb27ee519cafe17cb563c3fcc28d Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Tue, 6 Nov 2018 11:54:35 +0100
Subject: [PATCH] drm/meson: Add support for VIC alternate timings
@ -13,6 +13,7 @@ then these alternate timings will be handled in the same time in a cleaner
fashion.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/gpu/drm/meson/meson_dw_hdmi.c | 12 +---
drivers/gpu/drm/meson/meson_vclk.c | 127 +++++++++++++++++++++++-----------

View file

@ -1,4 +1,4 @@
From f6b21873bef4309b16caaf2fa2878e13297b0c96 Mon Sep 17 00:00:00 2001
From 2c28b1d1f1487bf4aecb36986c2d7b73eb8ac94d Mon Sep 17 00:00:00 2001
From: Maxime Jourdan <mjourdan@baylibre.com>
Date: Wed, 29 Aug 2018 15:17:22 +0200
Subject: [PATCH] media: meson: add v4l2 m2m video decoder driver
@ -17,6 +17,7 @@ Supported SoCs are: GXBB (S905), GXL (S905X/W/D), GXM (S912)
There is also a hardware bitstream parser (ESPARSER) that is handled here.
Signed-off-by: Maxime Jourdan <mjourdan@baylibre.com>
---
drivers/media/platform/Kconfig | 10 +
drivers/media/platform/meson/Makefile | 1 +

View file

@ -1,4 +1,4 @@
From 6824911bf6e50cb63d9d404e7c96fd75b96e7cca Mon Sep 17 00:00:00 2001
From a4089c61b05e61349ff10539fc20ee480d44b303 Mon Sep 17 00:00:00 2001
From: Maxime Jourdan <mjourdan@baylibre.com>
Date: Tue, 4 Sep 2018 10:07:08 +0200
Subject: [PATCH] MAINTAINERS: Add meson video decoder
@ -6,12 +6,13 @@ Subject: [PATCH] MAINTAINERS: Add meson video decoder
Add an entry for the meson video decoder for amlogic SoCs.
Signed-off-by: Maxime Jourdan <mjourdan@baylibre.com>
---
MAINTAINERS | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index b2f710e..5a7fa6a 100644
index 9e9b19e..ede389b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9520,6 +9520,14 @@ F: drivers/media/platform/meson/ao-cec.c

View file

@ -1,4 +1,4 @@
From 945ace6ce143dd1c8f0df74978219a948729d65c Mon Sep 17 00:00:00 2001
From 771e9830bdd1361594a874ded57fe497f443d7dd Mon Sep 17 00:00:00 2001
From: Maxime Jourdan <mjourdan@baylibre.com>
Date: Wed, 29 Aug 2018 15:24:02 +0200
Subject: [PATCH] arm64: dts: meson-gx: add vdec entry
@ -6,6 +6,7 @@ Subject: [PATCH] arm64: dts: meson-gx: add vdec entry
Add the video decoder dts entry
Signed-off-by: Maxime Jourdan <mjourdan@baylibre.com>
---
arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 14 ++++++++++++++
1 file changed, 14 insertions(+)

View file

@ -1,4 +1,4 @@
From 6cefc2d7963313061ce6b3a219295763e4bdf83e Mon Sep 17 00:00:00 2001
From 75863ab0baf29e4b0212a34f9ab7ef2763a38824 Mon Sep 17 00:00:00 2001
From: Maxime Jourdan <mjourdan@baylibre.com>
Date: Wed, 29 Aug 2018 15:24:22 +0200
Subject: [PATCH] arm64: dts: meson: add vdec entries
@ -6,6 +6,7 @@ Subject: [PATCH] arm64: dts: meson: add vdec entries
This enables the video decoder for gxbb, gxl and gxm chips
Signed-off-by: Maxime Jourdan <mjourdan@baylibre.com>
---
arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 10 ++++++++++
arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 10 ++++++++++

View file

@ -1,4 +1,4 @@
From d02f83d78521c4c41e8dd6367c021febea68a3df Mon Sep 17 00:00:00 2001
From e36802c6297adb0c560f3a6c1672546eb380c458 Mon Sep 17 00:00:00 2001
From: Maxime Jourdan <mjourdan@baylibre.com>
Date: Wed, 10 Oct 2018 17:22:27 +0200
Subject: [PATCH] meson: vdec: introduce controls and

View file

@ -1,4 +1,4 @@
From 32f02b96a4fe193b6eae7c327f0744755d1b375e Mon Sep 17 00:00:00 2001
From 80f9e75b2fce22552fdf56ade990f3f98567e29e Mon Sep 17 00:00:00 2001
From: Maxime Jourdan <mjourdan@baylibre.com>
Date: Thu, 4 Oct 2018 15:37:39 +0200
Subject: [PATCH] media: videodev2: add V4L2_FMT_FLAG_NO_SOURCE_CHANGE
@ -9,6 +9,7 @@ OUTPUT) formats may not be able to trigger this event.
Add a enum_fmt format flag to tag those specific formats.
Signed-off-by: Maxime Jourdan <mjourdan@baylibre.com>
---
Documentation/media/uapi/v4l/vidioc-enum-fmt.rst | 5 +++++
include/uapi/linux/videodev2.h | 5 +++--
@ -31,10 +32,10 @@ index 019c513..e0040b3 100644
Return Value
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 5d1a368..aa90a9a 100644
index 1aae2e4..f44bdef 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -722,8 +722,9 @@ struct v4l2_fmtdesc {
@@ -733,8 +733,9 @@ struct v4l2_fmtdesc {
__u32 reserved[4];
};

View file

@ -1,9 +1,10 @@
From d98b0e03a95932651f0d25fc742bd3b4a4736ee9 Mon Sep 17 00:00:00 2001
From 4ba289cf4940b6b8ddf1e332fc7248a27f54cfc8 Mon Sep 17 00:00:00 2001
From: Maxime Jourdan <mjourdan@baylibre.com>
Date: Wed, 10 Oct 2018 15:44:56 +0200
Subject: [PATCH] meson: vdec: allow subscribing to V4L2_EVENT_SOURCE_CHANGE
Flag MPEG1/MPEG2 as NO_SOURCE_CHANGE.
---
drivers/media/platform/meson/vdec/vdec.c | 20 ++++++++++++++--
drivers/media/platform/meson/vdec/vdec.h | 13 +++++++++++

View file

@ -1,9 +1,10 @@
From 1ab2baeaa6e310e8137aedbbd6a50b49c5a319dc Mon Sep 17 00:00:00 2001
From a41f52edc3681c11517c4d7ceb374f3189ea3310 Mon Sep 17 00:00:00 2001
From: Maxime Jourdan <mjourdan@baylibre.com>
Date: Wed, 29 Aug 2018 15:42:56 +0200
Subject: [PATCH] media: meson: vdec: add H.264 decoding support
Add support for V4L2_PIX_FMT_H264
---
drivers/media/platform/meson/vdec/Makefile | 2 +-
drivers/media/platform/meson/vdec/codec_h264.c | 478 ++++++++++++++++++++++

View file

@ -1,10 +1,11 @@
From ae02fb5afe0afa103392b9f571ce524f6e6e9b55 Mon Sep 17 00:00:00 2001
From e222a1cf4bd62745407a9404565d76b8a5770f12 Mon Sep 17 00:00:00 2001
From: Maxime Jourdan <mjourdan@baylibre.com>
Date: Wed, 29 Aug 2018 16:01:55 +0200
Subject: [PATCH] media: meson: vdec: add MPEG4 decoding support
Add support for V4L2_PIX_FMT_MPEG4, V4L2_PIX_FMT_XVID and
V4L2_PIX_FMT_H.263
---
drivers/media/platform/meson/vdec/Makefile | 2 +-
drivers/media/platform/meson/vdec/codec_mpeg4.c | 139 ++++++++++++++++++++++

View file

@ -1,9 +1,10 @@
From dfbf2530e950c655f0e837f1eb17caa59dea31ca Mon Sep 17 00:00:00 2001
From 9a662159440cf5e0f55275ef63588e35c91c581e Mon Sep 17 00:00:00 2001
From: Maxime Jourdan <mjourdan@baylibre.com>
Date: Sun, 21 Oct 2018 15:14:27 +0200
Subject: [PATCH] media: meson: vdec: add MJPEG decoding support
Add support for V4L2_PIX_FMT_MJPEG
---
drivers/media/platform/meson/vdec/Makefile | 2 +-
drivers/media/platform/meson/vdec/codec_mjpeg.c | 140 ++++++++++++++++++++++

View file

@ -1,4 +1,4 @@
From d903289c9d9b718ae85ae57cfda06c28ae558101 Mon Sep 17 00:00:00 2001
From 6b98d7c6cd508cfb4a2d4a1e87e192ffcabeda9e Mon Sep 17 00:00:00 2001
From: Christian Hewitt <christianshewitt@gmail.com>
Date: Sat, 13 Oct 2018 14:04:46 +0400
Subject: [PATCH] clk: meson-gxbb: set fclk_div3 as CLK_IS_CRITICAL
@ -23,15 +23,16 @@ This change simply sets the FCLK_DIV3 gate as critical to ensure
nothing can disable it.
Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
---
drivers/clk/meson/gxbb.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
index 86d3ae5..4c8925d 100644
index 6628ffa..01f7615 100644
--- a/drivers/clk/meson/gxbb.c
+++ b/drivers/clk/meson/gxbb.c
@@ -509,6 +509,7 @@ static struct clk_fixed_factor gxbb_fclk_div3_div = {
@@ -513,6 +513,7 @@ static struct clk_fixed_factor gxbb_fclk_div3_div = {
.ops = &clk_fixed_factor_ops,
.parent_names = (const char *[]){ "fixed_pll" },
.num_parents = 1,

View file

@ -1,17 +1,26 @@
From 5e4f446d520ddbbd27fce0efa2548d2aab6c9a38 Mon Sep 17 00:00:00 2001
From 24b38ca3bd2579d4bac18f57526c93bc63354959 Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Fri, 20 Jul 2018 15:29:18 +0200
Subject: [PATCH] [WIP] drm/meson: Add HDMI 1.4 4k modes
Subject: [PATCH] drm/meson: Add HDMI 1.4 4k modes
Add the timings for the HDMI 1.4 4K modes support :
- 3840x2160@30
- 3840x2160@25
- 3840x2160@24
Since the 297000Hz pixel clock is already managed and the modes are
compatible with the HDMI 1.4 current HDMI PHY+Controller support, only
the missing timings values needs to be added.
---
drivers/gpu/drm/meson/meson_venc.c | 129 +++++++++++++++++++++++++++++++++++++
1 file changed, 129 insertions(+)
diff --git a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c
index 514245e..bcffe8e 100644
index 14aac66..d68ccbf 100644
--- a/drivers/gpu/drm/meson/meson_venc.c
+++ b/drivers/gpu/drm/meson/meson_venc.c
@@ -697,6 +697,132 @@ union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p60 = {
@@ -698,6 +698,132 @@ union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p60 = {
},
};
@ -144,7 +153,7 @@ index 514245e..bcffe8e 100644
struct meson_hdmi_venc_vic_mode {
unsigned int vic;
union meson_hdmi_venc_mode *mode;
@@ -717,6 +843,9 @@ struct meson_hdmi_venc_vic_mode {
@@ -718,6 +844,9 @@ struct meson_hdmi_venc_vic_mode {
{ 34, &meson_hdmi_encp_mode_1080p30 },
{ 31, &meson_hdmi_encp_mode_1080p50 },
{ 16, &meson_hdmi_encp_mode_1080p60 },

View file

@ -0,0 +1,100 @@
From a753ec94679503680fcf86ffad3f3d3eb817c6b9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Sat, 8 Sep 2018 15:46:33 +0200
Subject: [PATCH] drm/meson: Use drm_fbdev_generic_setup()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
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.
Cc: Neil Armstrong <narmstrong@baylibre.com>
Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
---
drivers/gpu/drm/meson/meson_drv.c | 19 ++-----------------
drivers/gpu/drm/meson/meson_drv.h | 1 -
2 files changed, 2 insertions(+), 18 deletions(-)
diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
index b55e03d..3997e3e 100644
--- a/drivers/gpu/drm/meson/meson_drv.c
+++ b/drivers/gpu/drm/meson/meson_drv.c
@@ -69,15 +69,7 @@
* - Powering Up HDMI controller and PHY
*/
-static void meson_fb_output_poll_changed(struct drm_device *dev)
-{
- struct meson_drm *priv = dev->dev_private;
-
- drm_fbdev_cma_hotplug_event(priv->fbdev);
-}
-
static const struct drm_mode_config_funcs meson_mode_config_funcs = {
- .output_poll_changed = meson_fb_output_poll_changed,
.atomic_check = drm_atomic_helper_check,
.atomic_commit = drm_atomic_helper_commit,
.fb_create = drm_gem_fb_create,
@@ -314,13 +306,6 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
drm_mode_config_reset(drm);
- priv->fbdev = drm_fbdev_cma_init(drm, 32,
- drm->mode_config.num_connector);
- if (IS_ERR(priv->fbdev)) {
- ret = PTR_ERR(priv->fbdev);
- goto free_drm;
- }
-
drm_kms_helper_poll_init(drm);
platform_set_drvdata(pdev, priv);
@@ -329,6 +314,8 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
if (ret)
goto free_drm;
+ drm_fbdev_generic_setup(drm, 32);
+
return 0;
free_drm:
@@ -345,7 +332,6 @@ static int meson_drv_bind(struct device *dev)
static void meson_drv_unbind(struct device *dev)
{
struct drm_device *drm = dev_get_drvdata(dev);
- struct meson_drm *priv = drm->dev_private;
if (priv->canvas) {
meson_canvas_free(priv->canvas, priv->canvas_id_osd1);
@@ -356,7 +342,6 @@ static void meson_drv_unbind(struct device *dev)
drm_dev_unregister(drm);
drm_kms_helper_poll_fini(drm);
- drm_fbdev_cma_fini(priv->fbdev);
drm_mode_config_cleanup(drm);
drm_dev_put(drm);
diff --git a/drivers/gpu/drm/meson/meson_drv.h b/drivers/gpu/drm/meson/meson_drv.h
index a955354..4dccf4c 100644
--- a/drivers/gpu/drm/meson/meson_drv.h
+++ b/drivers/gpu/drm/meson/meson_drv.h
@@ -40,7 +40,6 @@ struct meson_drm {
struct drm_device *drm;
struct drm_crtc *crtc;
- struct drm_fbdev_cma *fbdev;
struct drm_plane *primary_plane;
struct drm_plane *overlay_plane;

View file

@ -0,0 +1,21 @@
From 07145ad0791209d3782eca4800406e7028e40a24 Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Wed, 7 Nov 2018 11:24:43 +0100
Subject: [PATCH] fixup! drm/meson: Use optional canvas provider
---
drivers/gpu/drm/meson/meson_drv.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
index 3997e3e..3ee4d4a4e 100644
--- a/drivers/gpu/drm/meson/meson_drv.c
+++ b/drivers/gpu/drm/meson/meson_drv.c
@@ -332,6 +332,7 @@ static int meson_drv_bind(struct device *dev)
static void meson_drv_unbind(struct device *dev)
{
struct drm_device *drm = dev_get_drvdata(dev);
+ struct meson_drm *priv = drm->dev_private;
if (priv->canvas) {
meson_canvas_free(priv->canvas, priv->canvas_id_osd1);

View file

@ -0,0 +1,21 @@
From 1f929f36f48f0f957f6c73cec309235243bd42f9 Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Mon, 12 Nov 2018 16:10:31 +0100
Subject: [PATCH] drm/meson: add support for 1080p25 mode
---
drivers/gpu/drm/meson/meson_venc.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c
index d68ccbf..0fbe525 100644
--- a/drivers/gpu/drm/meson/meson_venc.c
+++ b/drivers/gpu/drm/meson/meson_venc.c
@@ -841,6 +841,7 @@ struct meson_hdmi_venc_vic_mode {
{ 5, &meson_hdmi_encp_mode_1080i60 },
{ 20, &meson_hdmi_encp_mode_1080i50 },
{ 32, &meson_hdmi_encp_mode_1080p24 },
+ { 33, &meson_hdmi_encp_mode_1080p50 },
{ 34, &meson_hdmi_encp_mode_1080p30 },
{ 31, &meson_hdmi_encp_mode_1080p50 },
{ 16, &meson_hdmi_encp_mode_1080p60 },

View file

@ -0,0 +1,147 @@
From 2ffa6ba6e67706f195b1938c5f7e8a385252bd8e Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Wed, 14 Nov 2018 16:48:50 +0100
Subject: [PATCH] drm/bridge: dw-hdmi: Add SCDC and TMDS Scrambling support
Add support for SCDC Setup for TMDS Clock > 3.4GHz and enable TMDS
Scrambling when supported or mandatory.
This patch also adds an helper to setup the control bit to support
the hight TMDS Bit Period/TMDS Clock-Period Ratio as required with
TMDS Clock > 3.4GHz for HDMI2.0 3840x2160@60/50 modes.
These changes were based on work done by Huicong Xu <xhc@rock-chips.com>
and Nickey Yang <nickey.yang@rock-chips.com> to support HDMI2.0 modes
on the Rockchip 4.4 BSP kernel at [1]
[1] https://github.com/rockchip-linux/kernel/tree/release-4.4
Cc: Nickey Yang <nickey.yang@rock-chips.com>
Cc: Huicong Xu <xhc@rock-chips.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 45 ++++++++++++++++++++++++++++---
drivers/gpu/drm/bridge/synopsys/dw-hdmi.h | 1 +
include/drm/bridge/dw_hdmi.h | 1 +
3 files changed, 44 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 1fc1270..2a30d83 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -28,6 +28,7 @@
#include <drm/drm_crtc_helper.h>
#include <drm/drm_edid.h>
#include <drm/drm_encoder_slave.h>
+#include <drm/drm_scdc_helper.h>
#include <drm/bridge/dw_hdmi.h>
#include <uapi/linux/media-bus-format.h>
@@ -1026,6 +1027,20 @@ void dw_hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data,
}
EXPORT_SYMBOL_GPL(dw_hdmi_phy_i2c_write);
+void dw_hdmi_set_high_tmds_clock_ratio(struct dw_hdmi *hdmi)
+{
+ unsigned long mtmdsclock = hdmi->hdmi_data.video_mode.mpixelclock;
+
+ /* Control for TMDS Bit Period/TMDS Clock-Period Ratio */
+ if (hdmi->connector.display_info.hdmi.scdc.supported) {
+ if (mtmdsclock > 340000000)
+ drm_scdc_set_high_tmds_clock_ratio(hdmi->ddc, 1);
+ else
+ drm_scdc_set_high_tmds_clock_ratio(hdmi->ddc, 0);
+ }
+}
+EXPORT_SYMBOL_GPL(dw_hdmi_set_high_tmds_clock_ratio);
+
static void dw_hdmi_phy_enable_powerdown(struct dw_hdmi *hdmi, bool enable)
{
hdmi_mask_writeb(hdmi, !enable, HDMI_PHY_CONF0,
@@ -1351,11 +1366,12 @@ static void hdmi_tx_hdcp_config(struct dw_hdmi *hdmi)
static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
{
+ bool is_hdmi2_sink = hdmi->connector.display_info.hdmi.scdc.supported;
struct hdmi_avi_infoframe frame;
u8 val;
/* Initialise info frame from DRM mode */
- drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, false);
+ drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, is_hdmi2_sink);
if (hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_out_bus_format))
frame.colorspace = HDMI_COLORSPACE_YUV444;
@@ -1514,7 +1530,8 @@ static void hdmi_config_vendor_specific_infoframe(struct dw_hdmi *hdmi,
static void hdmi_av_composer(struct dw_hdmi *hdmi,
const struct drm_display_mode *mode)
{
- u8 inv_val;
+ u8 inv_val, bytes;
+ struct drm_hdmi_info *hdmi_info = &hdmi->connector.display_info.hdmi;
struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode;
int hblank, vblank, h_de_hs, v_de_vs, hsync_len, vsync_len;
unsigned int vdisplay;
@@ -1524,7 +1541,9 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
dev_dbg(hdmi->dev, "final pixclk = %d\n", vmode->mpixelclock);
/* Set up HDMI_FC_INVIDCONF */
- inv_val = (hdmi->hdmi_data.hdcp_enable ?
+ inv_val = (hdmi->hdmi_data.hdcp_enable ||
+ vmode->mpixelclock > 340000000 ||
+ hdmi_info->scdc.scrambling.low_rates ?
HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE :
HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE);
@@ -1573,6 +1592,26 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
vsync_len /= 2;
}
+ /* Scrambling Control */
+ if (hdmi_info->scdc.supported) {
+ if (vmode->mpixelclock > 340000000 ||
+ hdmi_info->scdc.scrambling.low_rates) {
+ drm_scdc_readb(&hdmi->i2c->adap, SCDC_SINK_VERSION,
+ &bytes);
+ drm_scdc_writeb(&hdmi->i2c->adap, SCDC_SOURCE_VERSION,
+ bytes);
+ drm_scdc_set_scrambling(&hdmi->i2c->adap, 1);
+ hdmi_writeb(hdmi, (u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ,
+ HDMI_MC_SWRSTZ);
+ hdmi_writeb(hdmi, 1, HDMI_FC_SCRAMBLER_CTRL);
+ } else {
+ hdmi_writeb(hdmi, 0, HDMI_FC_SCRAMBLER_CTRL);
+ hdmi_writeb(hdmi, (u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ,
+ HDMI_MC_SWRSTZ);
+ drm_scdc_set_scrambling(&hdmi->i2c->adap, 0);
+ }
+ }
+
/* Set up horizontal active pixel width */
hdmi_writeb(hdmi, mode->hdisplay >> 8, HDMI_FC_INHACTV1);
hdmi_writeb(hdmi, mode->hdisplay, HDMI_FC_INHACTV0);
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
index 9d90eb9..3f3c616 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
@@ -255,6 +255,7 @@
#define HDMI_FC_MASK2 0x10DA
#define HDMI_FC_POL2 0x10DB
#define HDMI_FC_PRCONF 0x10E0
+#define HDMI_FC_SCRAMBLER_CTRL 0x10E1
#define HDMI_FC_GMD_STAT 0x1100
#define HDMI_FC_GMD_EN 0x1101
diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
index ccb5aa8..d7cc5d0 100644
--- a/include/drm/bridge/dw_hdmi.h
+++ b/include/drm/bridge/dw_hdmi.h
@@ -156,6 +156,7 @@ void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense);
void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate);
void dw_hdmi_audio_enable(struct dw_hdmi *hdmi);
void dw_hdmi_audio_disable(struct dw_hdmi *hdmi);
+void dw_hdmi_set_high_tmds_clock_ratio(struct dw_hdmi *hdmi);
/* PHY configuration */
void dw_hdmi_phy_i2c_set_addr(struct dw_hdmi *hdmi, u8 address);

View file

@ -0,0 +1,69 @@
From cd02f4b3e7ad491111dbd6e1eccf3db9bbc1bc81 Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Mon, 12 Nov 2018 16:08:13 +0100
Subject: [PATCH] drm/meson: add HDMI div40 TMDS mode
Add support for TMDS Clock > 3.4GHz for HDMI2.0 display modes.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/gpu/drm/meson/meson_dw_hdmi.c | 24 ++++++++++++++++++++----
1 file changed, 20 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c
index d8c5cc3..118c49e 100644
--- a/drivers/gpu/drm/meson/meson_dw_hdmi.c
+++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c
@@ -365,7 +365,8 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
unsigned int wr_clk =
readl_relaxed(priv->io_base + _REG(VPU_HDMI_SETTING));
- DRM_DEBUG_DRIVER("%d:\"%s\"\n", mode->base.id, mode->name);
+ DRM_DEBUG_DRIVER("%d:\"%s\" div%d\n", mode->base.id, mode->name,
+ mode->clock > 340000 ? 40 : 10);
/* Enable clocks */
regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, 0xffff, 0x100);
@@ -385,9 +386,17 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
/* Enable normal output to PHY */
dw_hdmi_top_write(dw_hdmi, HDMITX_TOP_BIST_CNTL, BIT(12));
- /* TMDS pattern setup (TOFIX pattern for 4k2k scrambling) */
- dw_hdmi_top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_01, 0x001f001f);
- dw_hdmi_top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_23, 0x001f001f);
+ /* TMDS pattern setup (TOFIX Handle the YUV420 case) */
+ if (mode->clock > 340000) {
+ dw_hdmi_top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_01, 0);
+ dw_hdmi_top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_23,
+ 0x03ff03ff);
+ } else {
+ dw_hdmi_top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_01,
+ 0x001f001f);
+ dw_hdmi_top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_23,
+ 0x001f001f);
+ }
/* Load TMDS pattern */
dw_hdmi_top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_CNTL, 0x1);
@@ -413,6 +422,8 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
/* Disable clock, fifo, fifo_wr */
regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, 0xf, 0);
+ dw_hdmi_set_high_tmds_clock_ratio(hdmi);
+
msleep(100);
/* Reset PHY 3 times in a row */
@@ -562,6 +573,11 @@ dw_hdmi_mode_valid(struct drm_connector *connector,
mode->vdisplay, mode->vsync_start,
mode->vsync_end, mode->vtotal, mode->type, mode->flags);
+ /* If sink max TMDS clock < 340MHz, we reject the HDMI2.0 modes */
+ if (mode->clock > 340000 &&
+ connector->display_info.max_tmds_clock < 340000)
+ return MODE_BAD;
+
/* Check against non-VIC supported modes */
if (!vic) {
status = meson_venc_hdmi_supported_mode(mode);

View file

@ -0,0 +1,28 @@
From b48d4a78b2c3dd2db65ac391be3e12e323b6759e Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Mon, 12 Nov 2018 16:10:07 +0100
Subject: [PATCH] drm/meson: add support for HDMI2.0 2160p modes
Now we support the TMDS Clock > 3.4GHz and support the SCDC Control
operation in the DW-HDMI Controller, we can enable support for the
HDMI2.0 3840x2160@60/50 RGB444 display modes.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/gpu/drm/meson/meson_venc.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c
index 0fbe525..1bcd642 100644
--- a/drivers/gpu/drm/meson/meson_venc.c
+++ b/drivers/gpu/drm/meson/meson_venc.c
@@ -848,6 +848,8 @@ struct meson_hdmi_venc_vic_mode {
{ 93, &meson_hdmi_encp_mode_2160p24 },
{ 94, &meson_hdmi_encp_mode_2160p25 },
{ 95, &meson_hdmi_encp_mode_2160p30 },
+ { 96, &meson_hdmi_encp_mode_2160p25 },
+ { 97, &meson_hdmi_encp_mode_2160p30 },
{ 0, NULL}, /* sentinel */
};

View file

@ -0,0 +1,198 @@
From 3e7f3ec3de8753faefdeb02ed6d00cc580e6ad52 Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Wed, 14 Nov 2018 17:19:36 +0100
Subject: [PATCH] drm/bridge: dw-hdmi: add support for YUV420 output
In order to support the HDMI2.0 YUV420 display modes, this patch
adds support for the YUV420 TMDS Clock divided by 2 and the controller
passthrough mode.
This patch is based on work from Zheng Yang <zhengyang@rock-chips.com> in
the Rockchip Linux 4.4 BSP at [1]
[1] https://github.com/rockchip-linux/kernel/tree/release-4.4
Cc: Zheng Yang <zhengyang@rock-chips.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 63 ++++++++++++++++++++++++-------
1 file changed, 50 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 2a30d83..c3e4ed1 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -94,6 +94,7 @@ struct hdmi_vmode {
unsigned int mpixelclock;
unsigned int mpixelrepetitioninput;
unsigned int mpixelrepetitionoutput;
+ unsigned int mtmdsclock;
};
struct hdmi_data_info {
@@ -549,7 +550,7 @@ static void hdmi_init_clk_regenerator(struct dw_hdmi *hdmi)
static void hdmi_clk_regenerator_update_pixel_clock(struct dw_hdmi *hdmi)
{
mutex_lock(&hdmi->audio_mutex);
- hdmi_set_clk_regenerator(hdmi, hdmi->hdmi_data.video_mode.mpixelclock,
+ hdmi_set_clk_regenerator(hdmi, hdmi->hdmi_data.video_mode.mtmdsclock,
hdmi->sample_rate);
mutex_unlock(&hdmi->audio_mutex);
}
@@ -558,7 +559,7 @@ void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate)
{
mutex_lock(&hdmi->audio_mutex);
hdmi->sample_rate = rate;
- hdmi_set_clk_regenerator(hdmi, hdmi->hdmi_data.video_mode.mpixelclock,
+ hdmi_set_clk_regenerator(hdmi, hdmi->hdmi_data.video_mode.mtmdsclock,
hdmi->sample_rate);
mutex_unlock(&hdmi->audio_mutex);
}
@@ -659,6 +660,20 @@ static bool hdmi_bus_fmt_is_yuv422(unsigned int bus_format)
}
}
+static bool hdmi_bus_fmt_is_yuv420(unsigned int bus_format)
+{
+ switch (bus_format) {
+ case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
+ case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
+ case MEDIA_BUS_FMT_UYYVYY12_0_5X36:
+ case MEDIA_BUS_FMT_UYYVYY16_0_5X48:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
static int hdmi_bus_fmt_color_depth(unsigned int bus_format)
{
switch (bus_format) {
@@ -888,7 +903,8 @@ static void hdmi_video_packetize(struct dw_hdmi *hdmi)
u8 val, vp_conf;
if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format) ||
- hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_out_bus_format)) {
+ hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_out_bus_format) ||
+ hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format)) {
switch (hdmi_bus_fmt_color_depth(
hdmi->hdmi_data.enc_out_bus_format)) {
case 8:
@@ -1029,7 +1045,7 @@ EXPORT_SYMBOL_GPL(dw_hdmi_phy_i2c_write);
void dw_hdmi_set_high_tmds_clock_ratio(struct dw_hdmi *hdmi)
{
- unsigned long mtmdsclock = hdmi->hdmi_data.video_mode.mpixelclock;
+ unsigned long mtmdsclock = hdmi->hdmi_data.video_mode.mtmdsclock;
/* Control for TMDS Bit Period/TMDS Clock-Period Ratio */
if (hdmi->connector.display_info.hdmi.scdc.supported) {
@@ -1370,6 +1386,9 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
struct hdmi_avi_infoframe frame;
u8 val;
+ if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format))
+ is_hdmi2_sink = true;
+
/* Initialise info frame from DRM mode */
drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, is_hdmi2_sink);
@@ -1377,6 +1396,8 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
frame.colorspace = HDMI_COLORSPACE_YUV444;
else if (hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format))
frame.colorspace = HDMI_COLORSPACE_YUV422;
+ else if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format))
+ frame.colorspace = HDMI_COLORSPACE_YUV420;
else
frame.colorspace = HDMI_COLORSPACE_RGB;
@@ -1534,15 +1555,18 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
struct drm_hdmi_info *hdmi_info = &hdmi->connector.display_info.hdmi;
struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode;
int hblank, vblank, h_de_hs, v_de_vs, hsync_len, vsync_len;
- unsigned int vdisplay;
+ unsigned int vdisplay, hdisplay;
- vmode->mpixelclock = mode->clock * 1000;
+ vmode->mtmdsclock = vmode->mpixelclock = mode->clock * 1000;
dev_dbg(hdmi->dev, "final pixclk = %d\n", vmode->mpixelclock);
+ if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format))
+ vmode->mtmdsclock /= 2;
+
/* Set up HDMI_FC_INVIDCONF */
inv_val = (hdmi->hdmi_data.hdcp_enable ||
- vmode->mpixelclock > 340000000 ||
+ vmode->mtmdsclock > 340000000 ||
hdmi_info->scdc.scrambling.low_rates ?
HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE :
HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE);
@@ -1576,6 +1600,22 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
hdmi_writeb(hdmi, inv_val, HDMI_FC_INVIDCONF);
+ hdisplay = mode->hdisplay;
+ hblank = mode->htotal - mode->hdisplay;
+ h_de_hs = mode->hsync_start - mode->hdisplay;
+ hsync_len = mode->hsync_end - mode->hsync_start;
+
+ /*
+ * When we're setting a YCbCr420 mode, we need
+ * to adjust the horizontal timing to suit.
+ */
+ if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format)) {
+ hdisplay /= 2;
+ hblank /= 2;
+ h_de_hs /= 2;
+ hsync_len /= 2;
+ }
+
vdisplay = mode->vdisplay;
vblank = mode->vtotal - mode->vdisplay;
v_de_vs = mode->vsync_start - mode->vdisplay;
@@ -1594,7 +1634,7 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
/* Scrambling Control */
if (hdmi_info->scdc.supported) {
- if (vmode->mpixelclock > 340000000 ||
+ if (vmode->mtmdsclock > 340000000 ||
hdmi_info->scdc.scrambling.low_rates) {
drm_scdc_readb(&hdmi->i2c->adap, SCDC_SINK_VERSION,
&bytes);
@@ -1613,15 +1653,14 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
}
/* Set up horizontal active pixel width */
- hdmi_writeb(hdmi, mode->hdisplay >> 8, HDMI_FC_INHACTV1);
- hdmi_writeb(hdmi, mode->hdisplay, HDMI_FC_INHACTV0);
+ hdmi_writeb(hdmi, hdisplay >> 8, HDMI_FC_INHACTV1);
+ hdmi_writeb(hdmi, hdisplay, HDMI_FC_INHACTV0);
/* Set up vertical active lines */
hdmi_writeb(hdmi, vdisplay >> 8, HDMI_FC_INVACTV1);
hdmi_writeb(hdmi, vdisplay, HDMI_FC_INVACTV0);
/* Set up horizontal blanking pixel region width */
- hblank = mode->htotal - mode->hdisplay;
hdmi_writeb(hdmi, hblank >> 8, HDMI_FC_INHBLANK1);
hdmi_writeb(hdmi, hblank, HDMI_FC_INHBLANK0);
@@ -1629,7 +1668,6 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
hdmi_writeb(hdmi, vblank, HDMI_FC_INVBLANK);
/* Set up HSYNC active edge delay width (in pixel clks) */
- h_de_hs = mode->hsync_start - mode->hdisplay;
hdmi_writeb(hdmi, h_de_hs >> 8, HDMI_FC_HSYNCINDELAY1);
hdmi_writeb(hdmi, h_de_hs, HDMI_FC_HSYNCINDELAY0);
@@ -1637,7 +1675,6 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
hdmi_writeb(hdmi, v_de_vs, HDMI_FC_VSYNCINDELAY);
/* Set up HSYNC active pulse width (in pixel clks) */
- hsync_len = mode->hsync_end - mode->hsync_start;
hdmi_writeb(hdmi, hsync_len >> 8, HDMI_FC_HSYNCINWIDTH1);
hdmi_writeb(hdmi, hsync_len, HDMI_FC_HSYNCINWIDTH0);

View file

@ -0,0 +1,102 @@
From 2dcf2d31652207dfe20d7606804ca3b763b7f094 Mon Sep 17 00:00:00 2001
From: Zheng Yang <zhengyang@rock-chips.com>
Date: Tue, 27 Jun 2017 16:22:01 +0800
Subject: [PATCH] drm/bridge: dw-hdmi: support dynamically get input/out color
info
To get input/output bus_format/enc_format dynamically, this patch
introduce following funstion in plat_data:
- get_input_bus_format
- get_output_bus_format
- get_enc_in_encoding
- get_enc_out_encoding
Signed-off-by: Zheng Yang <zhengyang@rock-chips.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 28 +++++++++++++++++++++-------
include/drm/bridge/dw_hdmi.h | 5 +++++
2 files changed, 26 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index c3e4ed1..6473df3 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -1774,6 +1774,7 @@ static void hdmi_disable_overflow_interrupts(struct dw_hdmi *hdmi)
static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
{
int ret;
+ void *data = hdmi->plat_data->phy_data;
hdmi_disable_overflow_interrupts(hdmi);
@@ -1785,10 +1786,13 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
dev_dbg(hdmi->dev, "CEA mode used vic=%d\n", hdmi->vic);
}
- if ((hdmi->vic == 6) || (hdmi->vic == 7) ||
- (hdmi->vic == 21) || (hdmi->vic == 22) ||
- (hdmi->vic == 2) || (hdmi->vic == 3) ||
- (hdmi->vic == 17) || (hdmi->vic == 18))
+ if (hdmi->plat_data->get_enc_out_encoding)
+ hdmi->hdmi_data.enc_out_encoding =
+ hdmi->plat_data->get_enc_out_encoding(data);
+ else if ((hdmi->vic == 6) || (hdmi->vic == 7) ||
+ (hdmi->vic == 21) || (hdmi->vic == 22) ||
+ (hdmi->vic == 2) || (hdmi->vic == 3) ||
+ (hdmi->vic == 17) || (hdmi->vic == 18))
hdmi->hdmi_data.enc_out_encoding = V4L2_YCBCR_ENC_601;
else
hdmi->hdmi_data.enc_out_encoding = V4L2_YCBCR_ENC_709;
@@ -1797,21 +1801,31 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 0;
/* TOFIX: Get input format from plat data or fallback to RGB888 */
- if (hdmi->plat_data->input_bus_format)
+ if (hdmi->plat_data->get_input_bus_format)
+ hdmi->hdmi_data.enc_in_bus_format =
+ hdmi->plat_data->get_input_bus_format(data);
+ else if (hdmi->plat_data->input_bus_format)
hdmi->hdmi_data.enc_in_bus_format =
hdmi->plat_data->input_bus_format;
else
hdmi->hdmi_data.enc_in_bus_format = MEDIA_BUS_FMT_RGB888_1X24;
/* TOFIX: Get input encoding from plat data or fallback to none */
- if (hdmi->plat_data->input_bus_encoding)
+ if (hdmi->plat_data->get_enc_in_encoding)
+ hdmi->hdmi_data.enc_in_encoding =
+ hdmi->plat_data->get_enc_in_encoding(data);
+ else if (hdmi->plat_data->input_bus_encoding)
hdmi->hdmi_data.enc_in_encoding =
hdmi->plat_data->input_bus_encoding;
else
hdmi->hdmi_data.enc_in_encoding = V4L2_YCBCR_ENC_DEFAULT;
/* TOFIX: Default to RGB888 output format */
- hdmi->hdmi_data.enc_out_bus_format = MEDIA_BUS_FMT_RGB888_1X24;
+ if (hdmi->plat_data->get_output_bus_format)
+ hdmi->hdmi_data.enc_out_bus_format =
+ hdmi->plat_data->get_output_bus_format(data);
+ else
+ hdmi->hdmi_data.enc_out_bus_format = MEDIA_BUS_FMT_RGB888_1X24;
hdmi->hdmi_data.pix_repet_factor = 0;
hdmi->hdmi_data.hdcp_enable = 0;
diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
index d7cc5d0..27f9cce 100644
--- a/include/drm/bridge/dw_hdmi.h
+++ b/include/drm/bridge/dw_hdmi.h
@@ -141,6 +141,11 @@ struct dw_hdmi_plat_data {
int (*configure_phy)(struct dw_hdmi *hdmi,
const struct dw_hdmi_plat_data *pdata,
unsigned long mpixelclock);
+
+ unsigned long (*get_input_bus_format)(void *data);
+ unsigned long (*get_output_bus_format)(void *data);
+ unsigned long (*get_enc_in_encoding)(void *data);
+ unsigned long (*get_enc_out_encoding)(void *data);
};
struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,

View file

@ -0,0 +1,46 @@
From 94d815707144fb76f2e6f718a864f10a8d3f6306 Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Wed, 14 Nov 2018 17:39:46 +0100
Subject: [PATCH] drm/bridge: dw-hdmi: allow ycbcr420 modes for >= 0x200a
Now the DW-HDMI Controller supports the HDMI2.0 modes, enable support
for these modes in the connector if the platform supports them.
We limit these modes to DW-HDMI IP version >= 0x200a which
are designed to support HDMI2.0 display modes.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 6 ++++++
include/drm/bridge/dw_hdmi.h | 1 +
2 files changed, 7 insertions(+)
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 6473df3..d10277f 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -2575,6 +2575,12 @@ __dw_hdmi_probe(struct platform_device *pdev,
if (hdmi->phy.ops->setup_hpd)
hdmi->phy.ops->setup_hpd(hdmi, hdmi->phy.data);
+ if (hdmi->version >= 0x200a)
+ hdmi->connector.ycbcr_420_allowed =
+ hdmi->plat_data->ycbcr_420_allowed;
+ else
+ hdmi->connector.ycbcr_420_allowed = false;
+
memset(&pdevinfo, 0, sizeof(pdevinfo));
pdevinfo.parent = dev;
pdevinfo.id = PLATFORM_DEVID_AUTO;
diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
index 27f9cce..c04f497a 100644
--- a/include/drm/bridge/dw_hdmi.h
+++ b/include/drm/bridge/dw_hdmi.h
@@ -128,6 +128,7 @@ struct dw_hdmi_plat_data {
const struct drm_display_mode *mode);
unsigned long input_bus_format;
unsigned long input_bus_encoding;
+ bool ycbcr_420_allowed;
/* Vendor PHY support */
const struct dw_hdmi_phy_ops *phy_ops;

View file

@ -0,0 +1,582 @@
From fb1abdc9ba8015b1a5c2a6c53ffc08fa0676db04 Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Thu, 15 Nov 2018 16:41:23 +0100
Subject: [PATCH] drm/meson: Add YUV420 output support
This patch adds support for the YUV420 output from the Amlogic Meson SoCs
Video Processing Unit to the HDMI Controller.
The YUV420 is obtained by generating a YUV444 pixel stream like
the classic HDMI display modes, but then the Video Encoder output
can be configured to down-sample the YUV444 pixel stream to a YUV420
stream.
In addition if pixel stream down-sampling, the Y Cb Cr components must
also be mapped differently to align with the HDMI2.0 specifications.
This mode needs a different clock generation scheme since the TMDS PHY
clock must match the 10x ration with the YUV420 pixel clock, but
the video encoder must run at 2x the pixel clock.
This patch adds the TMDS PHY clock value in all the video clock setup
in order to better support these specific uses cases and switch
to the Common Clock framework for clocks handling in the future.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/gpu/drm/meson/meson_dw_hdmi.c | 108 +++++++++++++++++++++++++++-----
drivers/gpu/drm/meson/meson_vclk.c | 95 +++++++++++++++++++++-------
drivers/gpu/drm/meson/meson_vclk.h | 7 ++-
drivers/gpu/drm/meson/meson_venc.c | 6 +-
drivers/gpu/drm/meson/meson_venc.h | 11 ++++
drivers/gpu/drm/meson/meson_venc_cvbs.c | 3 +-
6 files changed, 184 insertions(+), 46 deletions(-)
diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c
index 118c49e..0b9ecbf 100644
--- a/drivers/gpu/drm/meson/meson_dw_hdmi.c
+++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c
@@ -141,6 +141,8 @@ struct meson_dw_hdmi {
struct regulator *hdmi_supply;
u32 irq_stat;
struct dw_hdmi *hdmi;
+ unsigned long input_bus_format;
+ unsigned long output_bus_format;
};
#define encoder_to_meson_dw_hdmi(x) \
container_of(x, struct meson_dw_hdmi, encoder)
@@ -323,25 +325,36 @@ static void dw_hdmi_set_vclk(struct meson_dw_hdmi *dw_hdmi,
{
struct meson_drm *priv = dw_hdmi->priv;
int vic = drm_match_cea_mode(mode);
+ unsigned int phy_freq;
unsigned int vclk_freq;
unsigned int venc_freq;
unsigned int hdmi_freq;
vclk_freq = mode->clock;
+ /* For 420, pixel clock is half unlike venc clock */
+ if (dw_hdmi->input_bus_format == MEDIA_BUS_FMT_UYYVYY8_0_5X24)
+ vclk_freq /= 2;
+
+ /* TMDS clock is pixel_clock * 10 */
+ phy_freq = vclk_freq * 10;
+
if (!vic) {
- meson_vclk_setup(priv, MESON_VCLK_TARGET_DMT, vclk_freq,
- vclk_freq, vclk_freq, false);
+ meson_vclk_setup(priv, MESON_VCLK_TARGET_DMT, phy_freq,
+ vclk_freq, vclk_freq, vclk_freq, false);
return;
}
+ /* 480i/576i needs global pixel doubling */
if (mode->flags & DRM_MODE_FLAG_DBLCLK)
vclk_freq *= 2;
venc_freq = vclk_freq;
hdmi_freq = vclk_freq;
- if (meson_venc_hdmi_venc_repeat(vic))
+ /* VENC double pixels for 1080i, 720p and YUV420 modes */
+ if (meson_venc_hdmi_venc_repeat(vic) ||
+ dw_hdmi->input_bus_format == MEDIA_BUS_FMT_UYYVYY8_0_5X24)
venc_freq *= 2;
vclk_freq = max(venc_freq, hdmi_freq);
@@ -349,11 +362,11 @@ static void dw_hdmi_set_vclk(struct meson_dw_hdmi *dw_hdmi,
if (mode->flags & DRM_MODE_FLAG_DBLCLK)
venc_freq /= 2;
- DRM_DEBUG_DRIVER("vclk:%d venc=%d hdmi=%d enci=%d\n",
- vclk_freq, venc_freq, hdmi_freq,
+ DRM_DEBUG_DRIVER("vclk:%d phy=%d venc=%d hdmi=%d enci=%d\n",
+ phy_freq, vclk_freq, venc_freq, hdmi_freq,
priv->venc.hdmi_use_enci);
- meson_vclk_setup(priv, MESON_VCLK_TARGET_HDMI, vclk_freq,
+ meson_vclk_setup(priv, MESON_VCLK_TARGET_HDMI, phy_freq, vclk_freq,
venc_freq, hdmi_freq, priv->venc.hdmi_use_enci);
}
@@ -387,7 +400,8 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
dw_hdmi_top_write(dw_hdmi, HDMITX_TOP_BIST_CNTL, BIT(12));
/* TMDS pattern setup (TOFIX Handle the YUV420 case) */
- if (mode->clock > 340000) {
+ if (mode->clock > 340000 &&
+ dw_hdmi->input_bus_format == MEDIA_BUS_FMT_YUV8_1X24) {
dw_hdmi_top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_01, 0);
dw_hdmi_top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_23,
0x03ff03ff);
@@ -560,6 +574,8 @@ dw_hdmi_mode_valid(struct drm_connector *connector,
const struct drm_display_mode *mode)
{
struct meson_drm *priv = connector->dev->dev_private;
+ bool is_hdmi2_sink = connector->display_info.hdmi.scdc.supported;
+ unsigned int phy_freq;
unsigned int vclk_freq;
unsigned int venc_freq;
unsigned int hdmi_freq;
@@ -573,9 +589,11 @@ dw_hdmi_mode_valid(struct drm_connector *connector,
mode->vdisplay, mode->vsync_start,
mode->vsync_end, mode->vtotal, mode->type, mode->flags);
- /* If sink max TMDS clock < 340MHz, we reject the HDMI2.0 modes */
+ /* If sink does not support 540MHz, reject the non-420 HDMI2 modes */
if (mode->clock > 340000 &&
- connector->display_info.max_tmds_clock < 340000)
+ connector->display_info.max_tmds_clock < 340000 &&
+ !drm_mode_is_420_only(&connector->display_info, mode) &&
+ !drm_mode_is_420_also(&connector->display_info, mode))
return MODE_BAD;
/* Check against non-VIC supported modes */
@@ -591,6 +609,15 @@ dw_hdmi_mode_valid(struct drm_connector *connector,
vclk_freq = mode->clock;
+ /* For 420, pixel clock is half unlike venc clock */
+ if (drm_mode_is_420_only(&connector->display_info, mode) ||
+ (!is_hdmi2_sink &&
+ drm_mode_is_420_also(&connector->display_info, mode)))
+ vclk_freq /= 2;
+
+ /* TMDS clock is pixel_clock * 10 */
+ phy_freq = vclk_freq * 10;
+
/* 480i/576i needs global pixel doubling */
if (mode->flags & DRM_MODE_FLAG_DBLCLK)
vclk_freq *= 2;
@@ -598,8 +625,11 @@ dw_hdmi_mode_valid(struct drm_connector *connector,
venc_freq = vclk_freq;
hdmi_freq = vclk_freq;
- /* VENC double pixels for 1080i and 720p modes */
- if (meson_venc_hdmi_venc_repeat(vic))
+ /* VENC double pixels for 1080i, 720p and YUV420 modes */
+ if (meson_venc_hdmi_venc_repeat(vic) ||
+ drm_mode_is_420_only(&connector->display_info, mode) ||
+ (!is_hdmi2_sink &&
+ drm_mode_is_420_also(&connector->display_info, mode)))
venc_freq *= 2;
vclk_freq = max(venc_freq, hdmi_freq);
@@ -607,10 +637,10 @@ dw_hdmi_mode_valid(struct drm_connector *connector,
if (mode->flags & DRM_MODE_FLAG_DBLCLK)
venc_freq /= 2;
- dev_dbg(connector->dev->dev, "%s: vclk:%d venc=%d hdmi=%d\n", __func__,
- vclk_freq, venc_freq, hdmi_freq);
+ dev_dbg(connector->dev->dev, "%s: vclk:%d phy=%d venc=%d hdmi=%d\n",
+ __func__, phy_freq, vclk_freq, venc_freq, hdmi_freq);
- return meson_vclk_vic_supported_freq(vclk_freq);
+ return meson_vclk_vic_supported_freq(phy_freq, vclk_freq);
}
/* Encoder */
@@ -628,6 +658,21 @@ static int meson_venc_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
struct drm_crtc_state *crtc_state,
struct drm_connector_state *conn_state)
{
+ struct meson_dw_hdmi *dw_hdmi = encoder_to_meson_dw_hdmi(encoder);
+ struct drm_display_info *info = &conn_state->connector->display_info;
+ struct drm_display_mode *mode = &crtc_state->mode;
+ bool is_hdmi2_sink =
+ conn_state->connector->display_info.hdmi.scdc.supported;
+
+ if (drm_mode_is_420_only(info, mode) ||
+ (!is_hdmi2_sink && drm_mode_is_420_also(info, mode))) {
+ dw_hdmi->input_bus_format = MEDIA_BUS_FMT_UYYVYY8_0_5X24;
+ dw_hdmi->output_bus_format = MEDIA_BUS_FMT_UYYVYY8_0_5X24;
+ } else {
+ dw_hdmi->input_bus_format = MEDIA_BUS_FMT_YUV8_1X24;
+ dw_hdmi->output_bus_format = MEDIA_BUS_FMT_RGB888_1X24;
+ }
+
return 0;
}
@@ -665,18 +710,30 @@ static void meson_venc_hdmi_encoder_mode_set(struct drm_encoder *encoder,
struct meson_dw_hdmi *dw_hdmi = encoder_to_meson_dw_hdmi(encoder);
struct meson_drm *priv = dw_hdmi->priv;
int vic = drm_match_cea_mode(mode);
+ unsigned int ycrcb_map = MESON_VENC_MAP_CB_Y_CR;
+ bool yuv420_mode = false;
DRM_DEBUG_DRIVER("%d:\"%s\" vic %d\n",
mode->base.id, mode->name, vic);
+ if (dw_hdmi->input_bus_format == MEDIA_BUS_FMT_UYYVYY8_0_5X24) {
+ ycrcb_map = MESON_VENC_MAP_CR_Y_CB;
+ yuv420_mode = true;
+ }
+
/* VENC + VENC-DVI Mode setup */
- meson_venc_hdmi_mode_set(priv, vic, mode);
+ meson_venc_hdmi_mode_set(priv, vic, ycrcb_map, yuv420_mode, mode);
/* VCLK Set clock */
dw_hdmi_set_vclk(dw_hdmi, mode);
- /* Setup YUV444 to HDMI-TX, no 10bit diphering */
- writel_relaxed(0, priv->io_base + _REG(VPU_HDMI_FMT_CTRL));
+ if (dw_hdmi->input_bus_format == MEDIA_BUS_FMT_UYYVYY8_0_5X24)
+ /* Setup YUV420 to HDMI-TX, no 10bit diphering */
+ writel_relaxed(2 | (2 << 2),
+ priv->io_base + _REG(VPU_HDMI_FMT_CTRL));
+ else
+ /* Setup YUV444 to HDMI-TX, no 10bit diphering */
+ writel_relaxed(0, priv->io_base + _REG(VPU_HDMI_FMT_CTRL));
}
static const struct drm_encoder_helper_funcs
@@ -714,6 +771,20 @@ static const struct regmap_config meson_dw_hdmi_regmap_config = {
.max_register = 0x10000,
};
+static unsigned long meson_dw_hdmi_get_in_bus_format(void *data)
+{
+ struct meson_dw_hdmi *dw_hdmi = (struct meson_dw_hdmi *)data;
+
+ return dw_hdmi->input_bus_format;
+}
+
+static unsigned long meson_dw_hdmi_get_out_bus_format(void *data)
+{
+ struct meson_dw_hdmi *dw_hdmi = (struct meson_dw_hdmi *)data;
+
+ return dw_hdmi->output_bus_format;
+}
+
static bool meson_hdmi_connector_is_available(struct device *dev)
{
struct device_node *ep, *remote;
@@ -890,6 +961,9 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master,
dw_plat_data->phy_data = meson_dw_hdmi;
dw_plat_data->input_bus_format = MEDIA_BUS_FMT_YUV8_1X24;
dw_plat_data->input_bus_encoding = V4L2_YCBCR_ENC_709;
+ dw_plat_data->get_input_bus_format = meson_dw_hdmi_get_in_bus_format;
+ dw_plat_data->get_output_bus_format = meson_dw_hdmi_get_out_bus_format;
+ dw_plat_data->ycbcr_420_allowed = true;
platform_set_drvdata(pdev, meson_dw_hdmi);
diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c
index 5accceb..27c9c5e 100644
--- a/drivers/gpu/drm/meson/meson_vclk.c
+++ b/drivers/gpu/drm/meson/meson_vclk.c
@@ -337,12 +337,17 @@ enum {
/* 2970 /1 /1 /1 /5 /2 => /1 /1 */
MESON_VCLK_HDMI_297000,
/* 5940 /1 /1 /2 /5 /1 => /1 /1 */
- MESON_VCLK_HDMI_594000
+ MESON_VCLK_HDMI_594000,
+/* 2970 /1 /1 /1 /5 /1 => /1 /2 */
+ MESON_VCLK_HDMI_594000_YUV420,
};
struct meson_vclk_params {
+ unsigned int pll_freq;
+ unsigned int phy_freq;
+ unsigned int vclk_freq;
+ unsigned int venc_freq;
unsigned int pixel_freq;
- unsigned int pll_base_freq;
unsigned int pll_od1;
unsigned int pll_od2;
unsigned int pll_od3;
@@ -350,8 +355,11 @@ struct meson_vclk_params {
unsigned int vclk_div;
} params[] = {
[MESON_VCLK_HDMI_ENCI_54000] = {
+ .pll_freq = 4320000,
+ .phy_freq = 270000,
+ .vclk_freq = 54000,
+ .venc_freq = 54000,
.pixel_freq = 54000,
- .pll_base_freq = 4320000,
.pll_od1 = 4,
.pll_od2 = 4,
.pll_od3 = 1,
@@ -359,8 +367,11 @@ struct meson_vclk_params {
.vclk_div = 1,
},
[MESON_VCLK_HDMI_DDR_54000] = {
- .pixel_freq = 54000,
- .pll_base_freq = 4320000,
+ .pll_freq = 4320000,
+ .phy_freq = 270000,
+ .vclk_freq = 54000,
+ .venc_freq = 54000,
+ .pixel_freq = 27000,
.pll_od1 = 4,
.pll_od2 = 4,
.pll_od3 = 1,
@@ -368,8 +379,11 @@ struct meson_vclk_params {
.vclk_div = 1,
},
[MESON_VCLK_HDMI_DDR_148500] = {
- .pixel_freq = 148500,
- .pll_base_freq = 2970000,
+ .pll_freq = 2970000,
+ .phy_freq = 742500,
+ .vclk_freq = 148500,
+ .venc_freq = 148500,
+ .pixel_freq = 74250,
.pll_od1 = 4,
.pll_od2 = 1,
.pll_od3 = 1,
@@ -377,8 +391,11 @@ struct meson_vclk_params {
.vclk_div = 1,
},
[MESON_VCLK_HDMI_74250] = {
+ .pll_freq = 2970000,
+ .phy_freq = 742500,
+ .vclk_freq = 74250,
+ .venc_freq = 74250,
.pixel_freq = 74250,
- .pll_base_freq = 2970000,
.pll_od1 = 2,
.pll_od2 = 2,
.pll_od3 = 2,
@@ -386,8 +403,11 @@ struct meson_vclk_params {
.vclk_div = 1,
},
[MESON_VCLK_HDMI_148500] = {
+ .pll_freq = 2970000,
+ .phy_freq = 1485000,
+ .vclk_freq = 148500,
+ .venc_freq = 148500,
.pixel_freq = 148500,
- .pll_base_freq = 2970000,
.pll_od1 = 1,
.pll_od2 = 2,
.pll_od3 = 2,
@@ -395,8 +415,11 @@ struct meson_vclk_params {
.vclk_div = 1,
},
[MESON_VCLK_HDMI_297000] = {
+ .pll_freq = 2970000,
+ .phy_freq = 2970000,
+ .venc_freq = 297000,
+ .vclk_freq = 297000,
.pixel_freq = 297000,
- .pll_base_freq = 2970000,
.pll_od1 = 1,
.pll_od2 = 1,
.pll_od3 = 1,
@@ -404,14 +427,29 @@ struct meson_vclk_params {
.vclk_div = 2,
},
[MESON_VCLK_HDMI_594000] = {
+ .pll_freq = 5940000,
+ .phy_freq = 5940000,
+ .venc_freq = 594000,
+ .vclk_freq = 594000,
.pixel_freq = 594000,
- .pll_base_freq = 5940000,
.pll_od1 = 1,
.pll_od2 = 1,
.pll_od3 = 2,
.vid_pll_div = VID_PLL_DIV_5,
.vclk_div = 1,
},
+ [MESON_VCLK_HDMI_594000_YUV420] = {
+ .pll_freq = 2970000,
+ .phy_freq = 2970000,
+ .venc_freq = 594000,
+ .vclk_freq = 594000,
+ .pixel_freq = 297000,
+ .pll_od1 = 1,
+ .pll_od2 = 1,
+ .pll_od3 = 1,
+ .vid_pll_div = VID_PLL_DIV_5,
+ .vclk_div = 1,
+ },
{ /* sentinel */ },
};
@@ -616,6 +654,7 @@ static void meson_hdmi_pll_generic_set(struct meson_drm *priv,
unsigned int od, m, frac, od1, od2, od3;
if (meson_hdmi_pll_find_params(priv, pll_freq, &m, &frac, &od)) {
+ /* OD2 goes to the PHY, and needs to be *10, so keep OD3=1 */
od3 = 1;
if (od < 4) {
od1 = 2;
@@ -638,21 +677,28 @@ static void meson_hdmi_pll_generic_set(struct meson_drm *priv,
}
enum drm_mode_status
-meson_vclk_vic_supported_freq(unsigned int freq)
+meson_vclk_vic_supported_freq(unsigned int phy_freq,
+ unsigned int vclk_freq)
{
int i;
- DRM_DEBUG_DRIVER("freq = %d\n", freq);
+ DRM_DEBUG_DRIVER("phy_freq = %d vclk_freq = %d\n",
+ phy_freq, vclk_freq);
for (i = 0 ; params[i].pixel_freq ; ++i) {
DRM_DEBUG_DRIVER("i = %d pixel_freq = %d alt = %d\n",
i, params[i].pixel_freq,
FREQ_1000_1001(params[i].pixel_freq));
+ DRM_DEBUG_DRIVER("i = %d phy_freq = %d alt = %d\n",
+ i, params[i].phy_freq,
+ FREQ_1000_1001(params[i].phy_freq/10)*10);
/* Match strict frequency */
- if (freq == params[i].pixel_freq)
+ if (phy_freq == params[i].phy_freq &&
+ vclk_freq == params[i].vclk_freq)
return MODE_OK;
/* Match 1000/1001 variant */
- if (freq == FREQ_1000_1001(params[i].pixel_freq))
+ if (phy_freq == (FREQ_1000_1001(params[i].phy_freq/10)*10) &&
+ vclk_freq == FREQ_1000_1001(params[i].vclk_freq))
return MODE_OK;
}
@@ -666,7 +712,7 @@ static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq,
unsigned int hdmi_tx_div, unsigned int venc_div,
bool hdmi_use_enci, bool vic_alternate_clock)
{
- unsigned int m, frac;
+ unsigned int m = 0, frac = 0;
/* Set HDMI-TX sys clock */
regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
@@ -863,8 +909,9 @@ static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq,
}
void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
- unsigned int vclk_freq, unsigned int venc_freq,
- unsigned int dac_freq, bool hdmi_use_enci)
+ unsigned int phy_freq, unsigned int vclk_freq,
+ unsigned int venc_freq, unsigned int dac_freq,
+ bool hdmi_use_enci)
{
bool vic_alternate_clock = false;
unsigned int freq;
@@ -883,7 +930,7 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
* - venc_div = 1
* - encp encoder
*/
- meson_vclk_set(priv, vclk_freq * 10, 0, 0, 0,
+ meson_vclk_set(priv, phy_freq, 0, 0, 0,
VID_PLL_DIV_5, 2, 1, 1, false, false);
return;
}
@@ -905,9 +952,11 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
}
for (freq = 0 ; params[freq].pixel_freq ; ++freq) {
- if (vclk_freq == params[freq].pixel_freq ||
- vclk_freq == FREQ_1000_1001(params[freq].pixel_freq)) {
- if (vclk_freq != params[freq].pixel_freq)
+ if ((phy_freq == params[freq].phy_freq ||
+ phy_freq == FREQ_1000_1001(params[freq].phy_freq/10)*10) &&
+ (vclk_freq == params[freq].vclk_freq ||
+ vclk_freq == FREQ_1000_1001(params[freq].vclk_freq))) {
+ if (vclk_freq != params[freq].vclk_freq)
vic_alternate_clock = true;
else
vic_alternate_clock = false;
@@ -936,7 +985,7 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
return;
}
- meson_vclk_set(priv, params[freq].pll_base_freq,
+ meson_vclk_set(priv, params[freq].pll_freq,
params[freq].pll_od1, params[freq].pll_od2,
params[freq].pll_od3, params[freq].vid_pll_div,
params[freq].vclk_div, hdmi_tx_div, venc_div,
diff --git a/drivers/gpu/drm/meson/meson_vclk.h b/drivers/gpu/drm/meson/meson_vclk.h
index 4bd8752..c4d19dd 100644
--- a/drivers/gpu/drm/meson/meson_vclk.h
+++ b/drivers/gpu/drm/meson/meson_vclk.h
@@ -33,10 +33,11 @@ enum {
enum drm_mode_status
meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned int freq);
enum drm_mode_status
-meson_vclk_vic_supported_freq(unsigned int freq);
+meson_vclk_vic_supported_freq(unsigned int phy_freq, unsigned int vclk_freq);
void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
- unsigned int vclk_freq, unsigned int venc_freq,
- unsigned int dac_freq, bool hdmi_use_enci);
+ unsigned int phy_freq, unsigned int vclk_freq,
+ unsigned int venc_freq, unsigned int dac_freq,
+ bool hdmi_use_enci);
#endif /* __MESON_VCLK_H */
diff --git a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c
index 1bcd642..ab72ddd 100644
--- a/drivers/gpu/drm/meson/meson_venc.c
+++ b/drivers/gpu/drm/meson/meson_venc.c
@@ -956,6 +956,8 @@ bool meson_venc_hdmi_venc_repeat(int vic)
EXPORT_SYMBOL_GPL(meson_venc_hdmi_venc_repeat);
void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
+ unsigned int ycrcb_map,
+ bool yuv420_mode,
struct drm_display_mode *mode)
{
union meson_hdmi_venc_mode *vmode = NULL;
@@ -1505,8 +1507,8 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
writel_relaxed((use_enci ? 1 : 2) |
(mode->flags & DRM_MODE_FLAG_PHSYNC ? 1 << 2 : 0) |
(mode->flags & DRM_MODE_FLAG_PVSYNC ? 1 << 3 : 0) |
- 4 << 5 |
- (venc_repeat ? 1 << 8 : 0) |
+ (ycrcb_map << 5) |
+ (venc_repeat || yuv420_mode ? 1 << 8 : 0) |
(hdmi_repeat ? 1 << 12 : 0),
priv->io_base + _REG(VPU_HDMI_SETTING));
diff --git a/drivers/gpu/drm/meson/meson_venc.h b/drivers/gpu/drm/meson/meson_venc.h
index 97eaebb..5580bf3 100644
--- a/drivers/gpu/drm/meson/meson_venc.h
+++ b/drivers/gpu/drm/meson/meson_venc.h
@@ -33,6 +33,15 @@ enum {
MESON_VENC_MODE_HDMI,
};
+enum {
+ MESON_VENC_MAP_CR_Y_CB = 0,
+ MESON_VENC_MAP_Y_CB_CR,
+ MESON_VENC_MAP_Y_CR_CB,
+ MESON_VENC_MAP_CB_CR_Y,
+ MESON_VENC_MAP_CB_Y_CR,
+ MESON_VENC_MAP_CR_CB_Y,
+};
+
struct meson_cvbs_enci_mode {
unsigned int mode_tag;
unsigned int hso_begin; /* HSO begin position */
@@ -70,6 +79,8 @@ extern struct meson_cvbs_enci_mode meson_cvbs_enci_ntsc;
void meson_venci_cvbs_mode_set(struct meson_drm *priv,
struct meson_cvbs_enci_mode *mode);
void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
+ unsigned int ycrcb_map,
+ bool yuv420_mode,
struct drm_display_mode *mode);
unsigned int meson_venci_get_field(struct meson_drm *priv);
diff --git a/drivers/gpu/drm/meson/meson_venc_cvbs.c b/drivers/gpu/drm/meson/meson_venc_cvbs.c
index f7945ba..38a1117 100644
--- a/drivers/gpu/drm/meson/meson_venc_cvbs.c
+++ b/drivers/gpu/drm/meson/meson_venc_cvbs.c
@@ -207,7 +207,8 @@ static void meson_venc_cvbs_encoder_mode_set(struct drm_encoder *encoder,
/* Setup 27MHz vclk2 for ENCI and VDAC */
meson_vclk_setup(priv, MESON_VCLK_TARGET_CVBS,
MESON_VCLK_CVBS, MESON_VCLK_CVBS,
- MESON_VCLK_CVBS, true);
+ MESON_VCLK_CVBS, MESON_VCLK_CVBS,
+ true);
break;
}
}

View file

@ -0,0 +1,31 @@
From c9cf1e80259276c3da76bc03ab0aaa9dfac481ae Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Sun, 18 Nov 2018 14:06:11 +0100
Subject: [PATCH] drm/meson: Output in YUV444 if sink supports it
With the YUV420 handling, we can no dynamically setup the HDMI output
pixel format depending on the mode and connector info.
So now, we can output in YUV444, which is the native video pipeline
format, directly the the HDMI Sink it it's supported, without
involving the HDMI Controller CSC.
---
drivers/gpu/drm/meson/meson_dw_hdmi.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c
index 0b9ecbf..6df124c 100644
--- a/drivers/gpu/drm/meson/meson_dw_hdmi.c
+++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c
@@ -670,7 +670,10 @@ static int meson_venc_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
dw_hdmi->output_bus_format = MEDIA_BUS_FMT_UYYVYY8_0_5X24;
} else {
dw_hdmi->input_bus_format = MEDIA_BUS_FMT_YUV8_1X24;
- dw_hdmi->output_bus_format = MEDIA_BUS_FMT_RGB888_1X24;
+ if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
+ dw_hdmi->output_bus_format = MEDIA_BUS_FMT_YUV8_1X24;
+ else
+ dw_hdmi->output_bus_format = MEDIA_BUS_FMT_RGB888_1X24;
}
return 0;

View file

@ -0,0 +1,130 @@
From 5a258bd31dab2dad8afcced8a7a85fa92e04edab Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Wed, 28 Feb 2018 16:07:18 +0100
Subject: [PATCH] drm/meson: Fixes for drm_crtc_vblank_on/off support
Since Linux 4.17, calls to drm_crtc_vblank_on/off are mandatory, and we get
a warning when ctrc is disabled :
driver forgot to call drm_crtc_vblank_off()
But, the vsync IRQ was not totally disabled due the transient hardware
state, thus adding proper IRQ masking from the HHI system control registers.
The last change fixes a race condition introduced by calling the added
drm_crtc_vblank_on/off when an HPD event occurs from the HDMI connector,
triggering a WARN_ON() in the _atomic_bebin() callback when the CRTC
is disabled, thus also triggering a WARN_ON() in drm_vblank_put() :
WARNING: CPU: 0 PID: 1185 at drivers/gpu/drm/meson/meson_crtc.c:157 meson_crtc_atomic_begin+0x78/0x80
[...]
Call trace:
meson_crtc_atomic_begin+0x78/0x80
drm_atomic_helper_commit_planes+0x140/0x218
drm_atomic_helper_commit_tail+0x38/0x80
commit_tail+0x7c/0x80
drm_atomic_helper_commit+0xdc/0x150
drm_atomic_commit+0x54/0x60
restore_fbdev_mode_atomic+0x198/0x238
restore_fbdev_mode+0x6c/0x1c0
drm_fb_helper_restore_fbdev_mode_unlocked+0x7c/0xf0
drm_fb_helper_set_par+0x34/0x60
drm_fb_helper_hotplug_event.part.28+0xb8/0xc8
drm_fbdev_client_hotplug+0xa4/0xe0
drm_client_dev_hotplug+0x90/0xe0
drm_kms_helper_hotplug_event+0x3c/0x48
drm_helper_hpd_irq_event+0x134/0x168
dw_hdmi_top_thread_irq+0x3c/0x50
[...]
WARNING: CPU: 0 PID: 1185 at drivers/gpu/drm/drm_vblank.c:1026 drm_vblank_put+0xb4/0xc8
[...]
Call trace:
drm_vblank_put+0xb4/0xc8
drm_crtc_vblank_put+0x24/0x30
drm_atomic_helper_wait_for_vblanks.part.9+0x130/0x2b8
drm_atomic_helper_commit_tail+0x68/0x80
[...]
The issue is the vblank need to be enabled in any occurence of :
- atomic_enable()
- atomic_begin() and state->enable == true, which was not the case
Moving the CRTC enable code to a common function and calling in one
of these occurence solves this race condition and makes sure vblank
is enabled in each call to _atomic_begin() from the HPD event leading
to drm_atomic_helper_commit_planes().
To Summarize :
- Make sure that the CRTC code will calls the drm_crtc_vblank_on/off
- *Really* mask the Vsync IRQ
- Initialize and enable vblank at the first _atomic_begin()/_atomic_enable()
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/gpu/drm/meson/meson_crtc.c | 25 +++++++++++++++++++++++--
1 file changed, 23 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/meson/meson_crtc.c b/drivers/gpu/drm/meson/meson_crtc.c
index 6099997..f8e260b 100644
--- a/drivers/gpu/drm/meson/meson_crtc.c
+++ b/drivers/gpu/drm/meson/meson_crtc.c
@@ -46,6 +46,7 @@ struct meson_crtc {
struct drm_crtc base;
struct drm_pending_vblank_event *event;
struct meson_drm *priv;
+ bool enabled;
};
#define to_meson_crtc(x) container_of(x, struct meson_crtc, base)
@@ -81,8 +82,7 @@ static const struct drm_crtc_funcs meson_crtc_funcs = {
};
-static void meson_crtc_atomic_enable(struct drm_crtc *crtc,
- struct drm_crtc_state *old_state)
+static void meson_crtc_enable(struct drm_crtc *crtc)
{
struct meson_crtc *meson_crtc = to_meson_crtc(crtc);
struct drm_crtc_state *crtc_state = crtc->state;
@@ -106,6 +106,22 @@ static void meson_crtc_atomic_enable(struct drm_crtc *crtc,
writel_bits_relaxed(VPP_POSTBLEND_ENABLE, VPP_POSTBLEND_ENABLE,
priv->io_base + _REG(VPP_MISC));
+ drm_crtc_vblank_on(crtc);
+
+ meson_crtc->enabled = true;
+}
+
+static void meson_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
+{
+ struct meson_crtc *meson_crtc = to_meson_crtc(crtc);
+ struct meson_drm *priv = meson_crtc->priv;
+
+ DRM_DEBUG_DRIVER("\n");
+
+ if (!meson_crtc->enabled)
+ meson_crtc_enable(crtc);
+
priv->viu.osd1_enabled = true;
drm_crtc_vblank_on(crtc);
@@ -139,6 +155,8 @@ static void meson_crtc_atomic_disable(struct drm_crtc *crtc,
crtc->state->event = NULL;
}
+
+ meson_crtc->enabled = false;
}
static void meson_crtc_atomic_begin(struct drm_crtc *crtc,
@@ -147,6 +165,9 @@ static void meson_crtc_atomic_begin(struct drm_crtc *crtc,
struct meson_crtc *meson_crtc = to_meson_crtc(crtc);
unsigned long flags;
+ if (crtc->state->enable && !meson_crtc->enabled)
+ meson_crtc_enable(crtc);
+
if (crtc->state->event) {
WARN_ON(drm_crtc_vblank_get(crtc) != 0);

View file

@ -0,0 +1,124 @@
From 90c2e40067b0591a1419472da186463f3f84613b Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Thu, 22 Nov 2018 17:27:20 +0100
Subject: [PATCH] drm/meson: Fix an Alpha Primary Plane bug on Meson GXL/GXM
SoCs
On the Amlogic GXL & GXM SoCs, a bug occurs in the OSD1 plane when
alpha is used where the alpha is not aligned with the pixel content.
The woraround Amlogic implemented is the reset the OSD1 plane hardware
block each time the plane is updated, solving the issue.
In the reset, we still need to save the content of 2 registers which
depends on the status of the plane, in addition to reload the scaler
conversion matrix in the same time.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/gpu/drm/meson/meson_crtc.c | 1 +
drivers/gpu/drm/meson/meson_plane.c | 12 ++++++++++++
drivers/gpu/drm/meson/meson_viu.c | 27 +++++++++++++++++++++++++++
drivers/gpu/drm/meson/meson_viu.h | 1 +
4 files changed, 41 insertions(+)
diff --git a/drivers/gpu/drm/meson/meson_crtc.c b/drivers/gpu/drm/meson/meson_crtc.c
index f8e260b..5312cce 100644
--- a/drivers/gpu/drm/meson/meson_crtc.c
+++ b/drivers/gpu/drm/meson/meson_crtc.c
@@ -202,6 +202,7 @@ void meson_crtc_irq(struct meson_drm *priv)
/* Update the OSD registers */
if (priv->viu.osd1_enabled && priv->viu.osd1_commit) {
+
writel_relaxed(priv->viu.osd1_ctrl_stat,
priv->io_base + _REG(VIU_OSD1_CTRL_STAT));
writel_relaxed(priv->viu.osd1_blk0_cfg[0],
diff --git a/drivers/gpu/drm/meson/meson_plane.c b/drivers/gpu/drm/meson/meson_plane.c
index 12a47b4..8372288 100644
--- a/drivers/gpu/drm/meson/meson_plane.c
+++ b/drivers/gpu/drm/meson/meson_plane.c
@@ -79,6 +79,7 @@
struct meson_plane {
struct drm_plane base;
struct meson_drm *priv;
+ bool enabled;
};
#define to_meson_plane(x) container_of(x, struct meson_plane, base)
@@ -303,6 +304,15 @@ static void meson_plane_atomic_update(struct drm_plane *plane,
priv->viu.osd1_stride = fb->pitches[0];
priv->viu.osd1_height = fb->height;
+ if (!meson_plane->enabled) {
+ /* Reset OSD1 at updates on GXL+ SoCs */
+ if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
+ meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu"))
+ meson_viu_reset(priv);
+
+ meson_plane->enabled = true;
+ }
+
spin_unlock_irqrestore(&priv->drm->event_lock, flags);
}
@@ -316,6 +326,8 @@ static void meson_plane_atomic_disable(struct drm_plane *plane,
writel_bits_relaxed(VPP_OSD1_POSTBLEND, 0,
priv->io_base + _REG(VPP_MISC));
+ meson_plane->enabled = false;
+
}
static const struct drm_plane_helper_funcs meson_plane_helper_funcs = {
diff --git a/drivers/gpu/drm/meson/meson_viu.c b/drivers/gpu/drm/meson/meson_viu.c
index 2dffb98..a41dd6c 100644
--- a/drivers/gpu/drm/meson/meson_viu.c
+++ b/drivers/gpu/drm/meson/meson_viu.c
@@ -296,6 +296,33 @@ static void meson_viu_load_matrix(struct meson_drm *priv)
true);
}
+/* VIU OSD1 Reset as workaround for GXL+ Alpha OSD Bug */
+void meson_viu_reset(struct meson_drm *priv)
+{
+ uint32_t osd1_fifo_ctrl_stat, osd1_ctrl_stat2;
+
+ /* Save these 2 registers state */
+ osd1_fifo_ctrl_stat = readl_relaxed(
+ priv->io_base + _REG(VIU_OSD1_FIFO_CTRL_STAT));
+ osd1_ctrl_stat2 = readl_relaxed(
+ priv->io_base + _REG(VIU_OSD1_CTRL_STAT2));
+
+ /* Reset OSD1 */
+ writel_bits_relaxed(BIT(0), BIT(0),
+ priv->io_base + _REG(VIU_SW_RESET));
+ writel_bits_relaxed(BIT(0), 0,
+ priv->io_base + _REG(VIU_SW_RESET));
+
+ /* Rewrite these registers state lost in the reset */
+ writel_relaxed(osd1_fifo_ctrl_stat,
+ priv->io_base + _REG(VIU_OSD1_FIFO_CTRL_STAT));
+ writel_relaxed(osd1_ctrl_stat2,
+ priv->io_base + _REG(VIU_OSD1_CTRL_STAT2));
+
+ /* Reload the conversion matrix */
+ meson_viu_load_matrix(priv);
+}
+
void meson_viu_init(struct meson_drm *priv)
{
uint32_t reg;
diff --git a/drivers/gpu/drm/meson/meson_viu.h b/drivers/gpu/drm/meson/meson_viu.h
index 073b191..e4a6e2f 100644
--- a/drivers/gpu/drm/meson/meson_viu.h
+++ b/drivers/gpu/drm/meson/meson_viu.h
@@ -59,6 +59,7 @@
#define OSD_REPLACE_EN BIT(14)
#define OSD_REPLACE_SHIFT 6
+void meson_viu_reset(struct meson_drm *priv);
void meson_viu_init(struct meson_drm *priv);
#endif /* __MESON_VIU_H */