testing/linux-amlogic: upgrade to 4.19.8

This commit is contained in:
He Yangxuan 2018-12-12 04:18:06 +00:00 committed by Natanael Copa
parent 27ddcaeab2
commit 468ce5d3db
75 changed files with 8854 additions and 8704 deletions

View File

@ -1,4 +1,4 @@
From e41c06328d1cd0989899d6a0897c6857d0cf9a4b Mon Sep 17 00:00:00 2001
From 0c815d66dbaa54b53e4b54105992ce44dfe8c36f Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Mon, 13 Nov 2017 12:09:40 +0100
Subject: [PATCH] ARM64: defconfig: enable CEC support
@ -9,15 +9,16 @@ Turn on CONFIG_DRM_DW_HDMI_CEC as module
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
arch/arm64/configs/defconfig | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index f9a186f..2584605 100644
index db8d364..ab1cb51 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -402,6 +402,7 @@ CONFIG_MEDIA_SUPPORT=m
@@ -413,6 +413,7 @@ CONFIG_MEDIA_SUPPORT=m
CONFIG_MEDIA_CAMERA_SUPPORT=y
CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
@ -25,7 +26,7 @@ index f9a186f..2584605 100644
CONFIG_MEDIA_CONTROLLER=y
CONFIG_VIDEO_V4L2_SUBDEV_API=y
# CONFIG_DVB_NET is not set
@@ -411,6 +412,8 @@ CONFIG_VIDEO_SAMSUNG_S5P_MFC=m
@@ -424,6 +425,8 @@ CONFIG_VIDEO_SAMSUNG_S5P_MFC=m
CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC=m
CONFIG_VIDEO_RENESAS_FCP=m
CONFIG_VIDEO_RENESAS_VSP1=m
@ -34,7 +35,7 @@ index f9a186f..2584605 100644
CONFIG_DRM=m
CONFIG_DRM_NOUVEAU=m
CONFIG_DRM_EXYNOS=m
@@ -431,6 +434,7 @@ CONFIG_DRM_RCAR_LVDS=m
@@ -444,6 +447,7 @@ CONFIG_DRM_RCAR_LVDS=m
CONFIG_DRM_TEGRA=m
CONFIG_DRM_PANEL_SIMPLE=m
CONFIG_DRM_I2C_ADV7511=m

View File

@ -1,81 +0,0 @@
From 6c5aaf27886c9b308e9c4e4d613990e540f23ec8 Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Tue, 26 Jun 2018 09:37:39 +0200
Subject: [PATCH] ARM64: dts: meson-gxbb-nanopi-k2: Add HDMI, CEC and CVBS
nodes
The Amlogic Meson GXBB based Nanopi-K2 board has an HDMI connector
with CEC and CVBS available on the 40pin header.
This patch adds the nodes to enable HDMI, CEC and CVBS functionnalities.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
.../boot/dts/amlogic/meson-gxbb-nanopi-k2.dts | 48 ++++++++++++++++++++++
1 file changed, 48 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts
index 7d5709c..cbe99bd 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts
@@ -106,6 +106,42 @@
compatible = "mmc-pwrseq-emmc";
reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>;
};
+
+ /* CVBS is available on CON1 pin 36, disabled by default */
+ cvbs-connector {
+ compatible = "composite-video-connector";
+ status = "disabled";
+
+ port {
+ cvbs_connector_in: endpoint {
+ remote-endpoint = <&cvbs_vdac_out>;
+ };
+ };
+ };
+
+ hdmi-connector {
+ compatible = "hdmi-connector";
+ type = "a";
+
+ port {
+ hdmi_connector_in: endpoint {
+ remote-endpoint = <&hdmi_tx_tmds_out>;
+ };
+ };
+ };
+};
+
+&cec_AO {
+ status = "okay";
+ pinctrl-0 = <&ao_cec_pins>;
+ pinctrl-names = "default";
+ hdmi-phandle = <&hdmi_tx>;
+};
+
+&cvbs_vdac_port {
+ cvbs_vdac_out: endpoint {
+ remote-endpoint = <&cvbs_connector_in>;
+ };
};
&ethmac {
@@ -137,6 +173,18 @@
};
};
+&hdmi_tx {
+ status = "okay";
+ pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>;
+ pinctrl-names = "default";
+};
+
+&hdmi_tx_tmds_port {
+ hdmi_tx_tmds_out: endpoint {
+ remote-endpoint = <&hdmi_connector_in>;
+ };
+};
+
&ir {
status = "okay";
pinctrl-0 = <&remote_input_ao_pins>;

View File

@ -0,0 +1,62 @@
From e2c70445f3533e8fa62f8c645713508148f8e4f6 Mon Sep 17 00:00:00 2001
From: Carlo Caione <ccaione@baylibre.com>
Date: Tue, 4 Dec 2018 16:04:46 +0000
Subject: [PATCH] arm64: dts: meson: Fix IRQ trigger type for macirq
A long running stress test on a custom board shipping an AXG SoCs and a
Realtek RTL8211F PHY revealed that after a few hours the connection
speed would drop drastically, from ~1000Mbps to ~3Mbps. At the same time
the 'macirq' (eth0) IRQ would stop being triggered at all and as
consequence the GMAC IRQs never ACKed.
After a painful investigation the problem seemed to be due to a wrong
defined IRQ type for the GMAC IRQ that should be LEVEL_HIGH instead of
EDGE_RISING.
Signed-off-by: Carlo Caione <ccaione@baylibre.com>
Acked-by: Neil Armstrong <narmstrong@baylibre.com>
---
arch/arm/boot/dts/meson.dtsi | 2 +-
arch/arm64/boot/dts/amlogic/meson-axg.dtsi | 2 +-
arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm/boot/dts/meson.dtsi b/arch/arm/boot/dts/meson.dtsi
index 0d9faf1a51ea..a86b89086334 100644
--- a/arch/arm/boot/dts/meson.dtsi
+++ b/arch/arm/boot/dts/meson.dtsi
@@ -263,7 +263,7 @@
compatible = "amlogic,meson6-dwmac", "snps,dwmac";
reg = <0xc9410000 0x10000
0xc1108108 0x4>;
- interrupts = <GIC_SPI 8 IRQ_TYPE_EDGE_RISING>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "macirq";
status = "disabled";
};
diff --git a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
index c518130e5ce7..81dcbde9e674 100644
--- a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
@@ -461,7 +461,7 @@
compatible = "amlogic,meson-gxbb-dwmac", "snps,dwmac";
reg = <0x0 0xff3f0000 0x0 0x10000
0x0 0xff634540 0x0 0x8>;
- interrupts = <GIC_SPI 8 IRQ_TYPE_EDGE_RISING>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "macirq";
clocks = <&clkc CLKID_ETH>,
<&clkc CLKID_FCLK_DIV2>,
diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
index 5d2820ef9a88..d03737acbae1 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
@@ -511,7 +511,7 @@
compatible = "amlogic,meson-gx-dwmac", "amlogic,meson-gxbb-dwmac", "snps,dwmac";
reg = <0x0 0xc9410000 0x0 0x10000
0x0 0xc8834540 0x0 0x4>;
- interrupts = <GIC_SPI 8 IRQ_TYPE_EDGE_RISING>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "macirq";
status = "disabled";
};

View File

@ -0,0 +1,33 @@
From a2b8a766c2fb57096c065e539d93f9f4fbd7ace4 Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Thu, 4 Oct 2018 10:42:43 +0200
Subject: [PATCH] drm/meson: fix max mode_config height/width
The mode_config max_width/max_height determines the maximum framebuffer
size the pixel reader can handle. But the values were set thinking they
were determining the maximum screen dimensions.
This patch changes the values to the maximum height/width the CANVAS block
can handle rounded to some coherent values.
Fixes: a41e82e6c457 ("drm/meson: Add support for components")
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/gpu/drm/meson/meson_drv.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
index 3ee4d4a4ecba..b3c04ecc75f3 100644
--- a/drivers/gpu/drm/meson/meson_drv.c
+++ b/drivers/gpu/drm/meson/meson_drv.c
@@ -263,8 +263,8 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
goto free_drm;
drm_mode_config_init(drm);
- drm->mode_config.max_width = 3840;
- drm->mode_config.max_height = 2160;
+ drm->mode_config.max_width = 16384;
+ drm->mode_config.max_height = 8192;
drm->mode_config.funcs = &meson_mode_config_funcs;
/* Hardware Initialization */

View File

@ -1,24 +0,0 @@
From baa0a8ee8b8a0a14ddab6b14c37846dfed261007 Mon Sep 17 00:00:00 2001
From: Koen Kooi <koen@dominion.thruhere.net>
Date: Fri, 11 May 2018 13:51:20 +0200
Subject: [PATCH] libretech-cc: disable CVBS connector
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
---
arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts
index f56969e..ac3a150 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts
@@ -24,7 +24,8 @@
stdout-path = "serial0:115200n8";
};
- cvbs-connector {
+ cvbs_connector: cvbs-connector {
+ status = "disabled";
compatible = "composite-video-connector";
port {

View File

@ -1,4 +1,4 @@
From 878d41be386f0bcbe1475f65acd8b9fb304529a0 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,49 +15,25 @@ 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/Kconfig | 1 +
sound/soc/Makefile | 1 +
sound/soc/meson/Kconfig | 9 ++
sound/soc/meson/Makefile | 3 +
sound/soc/meson/Kconfig | 10 +++
sound/soc/meson/Makefile | 4 +
sound/soc/meson/audio-core.c | 190 +++++++++++++++++++++++++++++++++++++++++++
sound/soc/meson/audio-core.h | 28 +++++++
6 files changed, 232 insertions(+)
create mode 100644 sound/soc/meson/Kconfig
create mode 100644 sound/soc/meson/Makefile
4 files changed, 232 insertions(+)
create mode 100644 sound/soc/meson/audio-core.c
create mode 100644 sound/soc/meson/audio-core.h
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 41af6b9..1cf11cf 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -57,6 +57,7 @@ source "sound/soc/kirkwood/Kconfig"
source "sound/soc/img/Kconfig"
source "sound/soc/intel/Kconfig"
source "sound/soc/mediatek/Kconfig"
+source "sound/soc/meson/Kconfig"
source "sound/soc/mxs/Kconfig"
source "sound/soc/pxa/Kconfig"
source "sound/soc/qcom/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 06389a5..62a5f87 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -38,6 +38,7 @@ obj-$(CONFIG_SND_SOC) += jz4740/
obj-$(CONFIG_SND_SOC) += img/
obj-$(CONFIG_SND_SOC) += intel/
obj-$(CONFIG_SND_SOC) += mediatek/
+obj-$(CONFIG_SND_SOC) += meson/
obj-$(CONFIG_SND_SOC) += mxs/
obj-$(CONFIG_SND_SOC) += nuc900/
obj-$(CONFIG_SND_SOC) += omap/
diff --git a/sound/soc/meson/Kconfig b/sound/soc/meson/Kconfig
new file mode 100644
index 0000000..ca0e3e9
--- /dev/null
index 8af8bc3..ed432d4 100644
--- a/sound/soc/meson/Kconfig
+++ b/sound/soc/meson/Kconfig
@@ -0,0 +1,9 @@
@@ -63,3 +63,13 @@ config SND_MESON_AXG_SPDIFOUT
in the Amlogic AXG SoC family
endmenu
+
+menuconfig SND_SOC_MESON
+ tristate "ASoC support for Amlogic Meson SoCs"
+ depends on ARCH_MESON
@ -68,14 +44,18 @@ index 0000000..ca0e3e9
+ the Amlogic Meson SoCs Audio interfaces. You will also need to
+ select the audio interfaces to support below.
diff --git a/sound/soc/meson/Makefile b/sound/soc/meson/Makefile
new file mode 100644
index 0000000..22028ab
--- /dev/null
index c5e003b..768d7c4 100644
--- a/sound/soc/meson/Makefile
+++ b/sound/soc/meson/Makefile
@@ -0,0 +1,3 @@
@@ -19,3 +19,7 @@ obj-$(CONFIG_SND_MESON_AXG_TDMIN) += snd-soc-meson-axg-tdmin.o
obj-$(CONFIG_SND_MESON_AXG_TDMOUT) += snd-soc-meson-axg-tdmout.o
obj-$(CONFIG_SND_MESON_AXG_SOUND_CARD) += snd-soc-meson-axg-sound-card.o
obj-$(CONFIG_SND_MESON_AXG_SPDIFOUT) += snd-soc-meson-axg-spdifout.o
+
+snd-soc-meson-audio-core-objs := audio-core.o
+
+obj-$(CONFIG_SND_SOC_MESON) += snd-soc-meson-audio-core.o
+obj-$(CONFIG_SND_SOC_MESON) += snd-soc-meson-audio-core.o
\ No newline at end of file
diff --git a/sound/soc/meson/audio-core.c b/sound/soc/meson/audio-core.c
new file mode 100644
index 0000000..99993ec

View File

@ -1,4 +1,4 @@
From f6c0ce626b08f5ba85bd9bfe000044c4f9e7da24 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 bb5102086db1579c1289440fa8aa184a70cb7c64 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,18 +6,19 @@ 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 | 2 +
sound/soc/meson/Makefile | 4 +-
sound/soc/meson/aiu-i2s-dma.c | 370 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 379 insertions(+)
3 files changed, 380 insertions(+), 1 deletion(-)
create mode 100644 sound/soc/meson/aiu-i2s-dma.c
diff --git a/sound/soc/meson/Kconfig b/sound/soc/meson/Kconfig
index ca0e3e9..88fbfc2 100644
index ed432d4..6e030b5 100644
--- a/sound/soc/meson/Kconfig
+++ b/sound/soc/meson/Kconfig
@@ -7,3 +7,10 @@ menuconfig SND_SOC_MESON
@@ -73,3 +73,10 @@ menuconfig SND_SOC_MESON
Say Y or M if you want to add support for codecs attached to
the Amlogic Meson SoCs Audio interfaces. You will also need to
select the audio interfaces to support below.
@ -29,15 +30,20 @@ index ca0e3e9..88fbfc2 100644
+ Say Y or M if you want to add support for i2s dma driver for Amlogic
+ Meson SoCs.
diff --git a/sound/soc/meson/Makefile b/sound/soc/meson/Makefile
index 22028ab..273f275 100644
index 768d7c4..5796007 100644
--- a/sound/soc/meson/Makefile
+++ b/sound/soc/meson/Makefile
@@ -1,3 +1,5 @@
@@ -21,5 +21,7 @@ obj-$(CONFIG_SND_MESON_AXG_SOUND_CARD) += snd-soc-meson-axg-sound-card.o
obj-$(CONFIG_SND_MESON_AXG_SPDIFOUT) += snd-soc-meson-axg-spdifout.o
snd-soc-meson-audio-core-objs := audio-core.o
+snd-soc-meson-aiu-i2s-dma-objs := aiu-i2s-dma.o
obj-$(CONFIG_SND_SOC_MESON) += snd-soc-meson-audio-core.o
+obj-$(CONFIG_SND_SOC_MESON_I2S) += snd-soc-meson-aiu-i2s-dma.o
-obj-$(CONFIG_SND_SOC_MESON) += snd-soc-meson-audio-core.o
\ No newline at end of file
+obj-$(CONFIG_SND_SOC_MESON) += snd-soc-meson-audio-core.o
+obj-$(CONFIG_SND_SOC_MESON_I2S) += snd-soc-meson-aiu-i2s-dma.o
\ No newline at end of file
diff --git a/sound/soc/meson/aiu-i2s-dma.c b/sound/soc/meson/aiu-i2s-dma.c
new file mode 100644
index 0000000..2684bd0

View File

@ -1,44 +0,0 @@
From 0cecf963b9d815699fe50b7a7ee4a93ece3ed834 Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Tue, 19 Jun 2018 18:14:49 +0200
Subject: [PATCH] clk: meson: switch gxbb cts-amclk div to the generic divider
clk-audio-divider was a (poor) attempt to use CCF rate propagation
while making sure the PLL rate would be high enough to work with
audio use cases. The result is far from optimal. We can do better
by carefully choosing the PLL rates for the audio use cases.
Doing so, we don't need to use clk-audio-divider anymore. The
generic will do
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
drivers/clk/meson/gxbb.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
index 177fffb..69a58cb 100644
--- a/drivers/clk/meson/gxbb.c
+++ b/drivers/clk/meson/gxbb.c
@@ -982,17 +982,15 @@ static struct clk_regmap gxbb_cts_amclk_sel = {
};
static struct clk_regmap gxbb_cts_amclk_div = {
- .data = &(struct meson_clk_audio_div_data){
- .div = {
- .reg_off = HHI_AUD_CLK_CNTL,
- .shift = 0,
- .width = 8,
- },
+ .data = &(struct clk_regmap_div_data) {
+ .offset = HHI_AUD_CLK_CNTL,
+ .shift = 0,
+ .width = 8,
.flags = CLK_DIVIDER_ROUND_CLOSEST,
},
.hw.init = &(struct clk_init_data){
.name = "cts_amclk_div",
- .ops = &meson_clk_audio_divider_ops,
+ .ops = &clk_regmap_divider_ops,
.parent_names = (const char *[]){ "cts_amclk_sel" },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,

View File

@ -1,4 +1,4 @@
From 6a5036e9f7dbd99023c6f9482fed3a747868b1c2 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,18 +8,19 @@ 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 | 2 +
sound/soc/meson/Makefile | 4 +-
sound/soc/meson/i2s-dai.c | 465 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 468 insertions(+), 1 deletion(-)
3 files changed, 469 insertions(+), 2 deletions(-)
create mode 100644 sound/soc/meson/i2s-dai.c
diff --git a/sound/soc/meson/Kconfig b/sound/soc/meson/Kconfig
index 88fbfc2..478f29a 100644
index 6e030b5..5904e9e 100644
--- a/sound/soc/meson/Kconfig
+++ b/sound/soc/meson/Kconfig
@@ -12,5 +12,5 @@ config SND_SOC_MESON_I2S
@@ -78,5 +78,5 @@ config SND_SOC_MESON_I2S
tristate "Meson i2s interface"
depends on SND_SOC_MESON
help
@ -27,17 +28,21 @@ index 88fbfc2..478f29a 100644
+ Say Y or M if you want to add support for i2s driver for Amlogic
Meson SoCs.
diff --git a/sound/soc/meson/Makefile b/sound/soc/meson/Makefile
index 273f275..ea06dde 100644
index 5796007..b8641f9 100644
--- a/sound/soc/meson/Makefile
+++ b/sound/soc/meson/Makefile
@@ -1,5 +1,7 @@
@@ -22,6 +22,8 @@ obj-$(CONFIG_SND_MESON_AXG_SPDIFOUT) += snd-soc-meson-axg-spdifout.o
snd-soc-meson-audio-core-objs := audio-core.o
snd-soc-meson-aiu-i2s-dma-objs := aiu-i2s-dma.o
+snd-soc-meson-i2s-dai-objs := i2s-dai.o
obj-$(CONFIG_SND_SOC_MESON) += snd-soc-meson-audio-core.o
obj-$(CONFIG_SND_SOC_MESON_I2S) += snd-soc-meson-aiu-i2s-dma.o
+obj-$(CONFIG_SND_SOC_MESON_I2S) += snd-soc-meson-i2s-dai.o
obj-$(CONFIG_SND_SOC_MESON) += snd-soc-meson-audio-core.o
-obj-$(CONFIG_SND_SOC_MESON_I2S) += snd-soc-meson-aiu-i2s-dma.o
\ No newline at end of file
+obj-$(CONFIG_SND_SOC_MESON_I2S) += snd-soc-meson-aiu-i2s-dma.o
+obj-$(CONFIG_SND_SOC_MESON_I2S) += snd-soc-meson-i2s-dai.o
\ No newline at end of file
diff --git a/sound/soc/meson/i2s-dai.c b/sound/soc/meson/i2s-dai.c
new file mode 100644
index 0000000..1008af8

View File

@ -1,48 +0,0 @@
From e87dd7b11611e4ac5279ba4ad4f1fea4d0900273 Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Tue, 19 Jun 2018 18:23:28 +0200
Subject: [PATCH] clk: meson: remove unused clk-audio-divider driver
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
drivers/clk/meson/Makefile | 2 +-
drivers/clk/meson/clkc.h | 7 -------
2 files changed, 1 insertion(+), 8 deletions(-)
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index d0d13ae..e40fea9 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -2,7 +2,7 @@
# Makefile for Meson specific clk
#
-obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-mpll.o clk-audio-divider.o
+obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-mpll.o
obj-$(CONFIG_COMMON_CLK_MESON_AO) += meson-aoclk.o
obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o
obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o gxbb-aoclk-32k.o
diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h
index 2fb0843..48db024 100644
--- a/drivers/clk/meson/clkc.h
+++ b/drivers/clk/meson/clkc.h
@@ -91,11 +91,6 @@ struct meson_clk_mpll_data {
#define CLK_MESON_MPLL_ROUND_CLOSEST BIT(0)
-struct meson_clk_audio_div_data {
- struct parm div;
- u8 flags;
-};
-
#define MESON_GATE(_name, _reg, _bit) \
struct clk_regmap _name = { \
.data = &(struct clk_regmap_gate_data){ \
@@ -117,7 +112,5 @@ extern const struct clk_ops meson_clk_pll_ops;
extern const struct clk_ops meson_clk_cpu_ops;
extern const struct clk_ops meson_clk_mpll_ro_ops;
extern const struct clk_ops meson_clk_mpll_ops;
-extern const struct clk_ops meson_clk_audio_divider_ro_ops;
-extern const struct clk_ops meson_clk_audio_divider_ops;
#endif /* __CLKC_H */

View File

@ -1,4 +1,4 @@
From 8dd5edaf984e4c8d6f7ca1e7709b3109cf7dd780 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,18 +6,19 @@ 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 | 2 +
sound/soc/meson/Makefile | 4 +-
sound/soc/meson/aiu-spdif-dma.c | 388 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 397 insertions(+)
3 files changed, 398 insertions(+), 1 deletion(-)
create mode 100644 sound/soc/meson/aiu-spdif-dma.c
diff --git a/sound/soc/meson/Kconfig b/sound/soc/meson/Kconfig
index 478f29a..3fb93b9 100644
index 5904e9e..712303f 100644
--- a/sound/soc/meson/Kconfig
+++ b/sound/soc/meson/Kconfig
@@ -14,3 +14,10 @@ config SND_SOC_MESON_I2S
@@ -80,3 +80,10 @@ config SND_SOC_MESON_I2S
help
Say Y or M if you want to add support for i2s driver for Amlogic
Meson SoCs.
@ -29,19 +30,23 @@ index 478f29a..3fb93b9 100644
+ Say Y or M if you want to add support for spdif dma driver for Amlogic
+ Meson SoCs.
diff --git a/sound/soc/meson/Makefile b/sound/soc/meson/Makefile
index ea06dde..cef9a9d 100644
index b8641f9..dc5164a7 100644
--- a/sound/soc/meson/Makefile
+++ b/sound/soc/meson/Makefile
@@ -1,7 +1,9 @@
@@ -22,8 +22,10 @@ obj-$(CONFIG_SND_MESON_AXG_SPDIFOUT) += snd-soc-meson-axg-spdifout.o
snd-soc-meson-audio-core-objs := audio-core.o
snd-soc-meson-aiu-i2s-dma-objs := aiu-i2s-dma.o
+snd-soc-meson-aiu-spdif-dma-objs := aiu-spdif-dma.o
snd-soc-meson-i2s-dai-objs := i2s-dai.o
obj-$(CONFIG_SND_SOC_MESON) += snd-soc-meson-audio-core.o
obj-$(CONFIG_SND_SOC_MESON_I2S) += snd-soc-meson-aiu-i2s-dma.o
obj-$(CONFIG_SND_SOC_MESON_I2S) += snd-soc-meson-i2s-dai.o
+obj-$(CONFIG_SND_SOC_MESON_SPDIF) += snd-soc-meson-aiu-spdif-dma.o
obj-$(CONFIG_SND_SOC_MESON) += snd-soc-meson-audio-core.o
obj-$(CONFIG_SND_SOC_MESON_I2S) += snd-soc-meson-aiu-i2s-dma.o
-obj-$(CONFIG_SND_SOC_MESON_I2S) += snd-soc-meson-i2s-dai.o
\ No newline at end of file
+obj-$(CONFIG_SND_SOC_MESON_I2S) += snd-soc-meson-i2s-dai.o
+obj-$(CONFIG_SND_SOC_MESON_SPDIF) += snd-soc-meson-aiu-spdif-dma.o
\ No newline at end of file
diff --git a/sound/soc/meson/aiu-spdif-dma.c b/sound/soc/meson/aiu-spdif-dma.c
new file mode 100644
index 0000000..81c3b85

View File

@ -1,4 +1,4 @@
From e635299f76dc27b97a768f2a044d04c1917b9ad1 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,18 +9,19 @@ 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 | 2 +
sound/soc/meson/Makefile | 4 +-
sound/soc/meson/spdif-dai.c | 374 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 378 insertions(+), 1 deletion(-)
3 files changed, 379 insertions(+), 2 deletions(-)
create mode 100644 sound/soc/meson/spdif-dai.c
diff --git a/sound/soc/meson/Kconfig b/sound/soc/meson/Kconfig
index 3fb93b9..301d3a3 100644
index 712303f..bc3d6f2 100644
--- a/sound/soc/meson/Kconfig
+++ b/sound/soc/meson/Kconfig
@@ -18,6 +18,7 @@ config SND_SOC_MESON_I2S
@@ -84,6 +84,7 @@ config SND_SOC_MESON_I2S
config SND_SOC_MESON_SPDIF
tristate "Meson spdif interface"
depends on SND_SOC_MESON
@ -30,20 +31,23 @@ index 3fb93b9..301d3a3 100644
+ Say Y or M if you want to add support for spdif driver for Amlogic
Meson SoCs.
diff --git a/sound/soc/meson/Makefile b/sound/soc/meson/Makefile
index cef9a9d..bc4391c 100644
index dc5164a7..44f79d8 100644
--- a/sound/soc/meson/Makefile
+++ b/sound/soc/meson/Makefile
@@ -2,8 +2,10 @@ snd-soc-meson-audio-core-objs := audio-core.o
@@ -24,8 +24,10 @@ snd-soc-meson-audio-core-objs := audio-core.o
snd-soc-meson-aiu-i2s-dma-objs := aiu-i2s-dma.o
snd-soc-meson-aiu-spdif-dma-objs := aiu-spdif-dma.o
snd-soc-meson-i2s-dai-objs := i2s-dai.o
+snd-soc-meson-spdif-dai-objs := spdif-dai.o
obj-$(CONFIG_SND_SOC_MESON) += snd-soc-meson-audio-core.o
obj-$(CONFIG_SND_SOC_MESON_I2S) += snd-soc-meson-aiu-i2s-dma.o
obj-$(CONFIG_SND_SOC_MESON_I2S) += snd-soc-meson-i2s-dai.o
obj-$(CONFIG_SND_SOC_MESON_SPDIF) += snd-soc-meson-aiu-spdif-dma.o
+obj-$(CONFIG_SND_SOC_MESON_SPDIF) += snd-soc-meson-spdif-dai.o
obj-$(CONFIG_SND_SOC_MESON) += snd-soc-meson-audio-core.o
obj-$(CONFIG_SND_SOC_MESON_I2S) += snd-soc-meson-aiu-i2s-dma.o
obj-$(CONFIG_SND_SOC_MESON_I2S) += snd-soc-meson-i2s-dai.o
-obj-$(CONFIG_SND_SOC_MESON_SPDIF) += snd-soc-meson-aiu-spdif-dma.o
\ No newline at end of file
+obj-$(CONFIG_SND_SOC_MESON_SPDIF) += snd-soc-meson-aiu-spdif-dma.o
+obj-$(CONFIG_SND_SOC_MESON_SPDIF) += snd-soc-meson-spdif-dai.o
\ No newline at end of file
diff --git a/sound/soc/meson/spdif-dai.c b/sound/soc/meson/spdif-dai.c
new file mode 100644
index 0000000..e763000

View File

@ -1,4 +1,4 @@
From 5ddca63ac5c5d81c6d6a6745670a3f136970eaef Mon Sep 17 00:00:00 2001
From 93621178cb2f756c8ca8901801c2ce914ac7dc6b Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Fri, 31 Mar 2017 15:55:03 +0200
Subject: [PATCH] ARM64: defconfig: enable audio support for meson SoCs as
@ -8,22 +8,22 @@ Add audio support for meson SoCs. This includes the audio core
driver and the i2s and spdif output interfaces
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
arch/arm64/configs/defconfig | 4 ++++
1 file changed, 4 insertions(+)
arch/arm64/configs/defconfig | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 2584605..ae1f774 100644
index ab1cb51..a4bf54b 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -451,6 +451,10 @@ CONFIG_SOUND=y
@@ -464,6 +464,9 @@ CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_SND_SOC=y
CONFIG_SND_BCM2835_SOC_I2S=m
+CONFIG_SND_SOC_MESON=m
+CONFIG_SND_SOC_MESON_I2S=m
+CONFIG_SND_SOC_MESON_SPDIF=m
+CONFIG_SND_SOC_RCAR=y
CONFIG_SND_SOC_SAMSUNG=y
CONFIG_SND_SOC_RCAR=m
CONFIG_SND_SOC_AK4613=m
CONFIG_SND_SOC_ROCKCHIP=m
CONFIG_SND_SOC_ROCKCHIP_I2S=m
CONFIG_SND_SOC_ROCKCHIP_SPDIF=m

View File

@ -0,0 +1,165 @@
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] 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 14aac66..d68ccbf 100644
--- a/drivers/gpu/drm/meson/meson_venc.c
+++ b/drivers/gpu/drm/meson/meson_venc.c
@@ -698,6 +698,132 @@ union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p60 = {
},
};
+union meson_hdmi_venc_mode meson_hdmi_encp_mode_2160p24 = {
+ .encp = {
+ .dvi_settings = 0x1,
+ .video_mode = 0x4040,
+ .video_mode_adv = 0x8,
+ /* video_sync_mode */
+ /* video_yc_dly */
+ /* video_rgb_ctrl */
+ .video_filt_ctrl = 0x1000,
+ .video_filt_ctrl_present = true,
+ /* video_ofld_voav_ofst */
+ .yfp1_htime = 140,
+ .yfp2_htime = 140+3840,
+ .max_pxcnt = 3840+1660-1,
+ .hspuls_begin = 2156+1920,
+ .hspuls_end = 44,
+ .hspuls_switch = 44,
+ .vspuls_begin = 140,
+ .vspuls_end = 2059+1920,
+ .vspuls_bline = 0,
+ .vspuls_eline = 4,
+ .havon_begin = 148,
+ .havon_end = 3987,
+ .vavon_bline = 89,
+ .vavon_eline = 2248,
+ /* eqpuls_begin */
+ /* eqpuls_end */
+ /* eqpuls_bline */
+ /* eqpuls_eline */
+ .hso_begin = 44,
+ .hso_end = 2156+1920,
+ .vso_begin = 2100+1920,
+ .vso_end = 2164+1920,
+ .vso_bline = 51,
+ .vso_eline = 53,
+ .vso_eline_present = true,
+ /* sy_val */
+ /* sy2_val */
+ .max_lncnt = 2249,
+ },
+};
+
+union meson_hdmi_venc_mode meson_hdmi_encp_mode_2160p25 = {
+ .encp = {
+ .dvi_settings = 0x1,
+ .video_mode = 0x4040,
+ .video_mode_adv = 0x8,
+ /* video_sync_mode */
+ /* video_yc_dly */
+ /* video_rgb_ctrl */
+ .video_filt_ctrl = 0x1000,
+ .video_filt_ctrl_present = true,
+ /* video_ofld_voav_ofst */
+ .yfp1_htime = 140,
+ .yfp2_htime = 140+3840,
+ .max_pxcnt = 3840+1440-1,
+ .hspuls_begin = 2156+1920,
+ .hspuls_end = 44,
+ .hspuls_switch = 44,
+ .vspuls_begin = 140,
+ .vspuls_end = 2059+1920,
+ .vspuls_bline = 0,
+ .vspuls_eline = 4,
+ .havon_begin = 148,
+ .havon_end = 3987,
+ .vavon_bline = 89,
+ .vavon_eline = 2248,
+ /* eqpuls_begin */
+ /* eqpuls_end */
+ /* eqpuls_bline */
+ /* eqpuls_eline */
+ .hso_begin = 44,
+ .hso_end = 2156+1920,
+ .vso_begin = 2100+1920,
+ .vso_end = 2164+1920,
+ .vso_bline = 51,
+ .vso_eline = 53,
+ .vso_eline_present = true,
+ /* sy_val */
+ /* sy2_val */
+ .max_lncnt = 2249,
+ },
+};
+
+union meson_hdmi_venc_mode meson_hdmi_encp_mode_2160p30 = {
+ .encp = {
+ .dvi_settings = 0x1,
+ .video_mode = 0x4040,
+ .video_mode_adv = 0x8,
+ /* video_sync_mode */
+ /* video_yc_dly */
+ /* video_rgb_ctrl */
+ .video_filt_ctrl = 0x1000,
+ .video_filt_ctrl_present = true,
+ /* video_ofld_voav_ofst */
+ .yfp1_htime = 140,
+ .yfp2_htime = 140+3840,
+ .max_pxcnt = 3840+560-1,
+ .hspuls_begin = 2156+1920,
+ .hspuls_end = 44,
+ .hspuls_switch = 44,
+ .vspuls_begin = 140,
+ .vspuls_end = 2059+1920,
+ .vspuls_bline = 0,
+ .vspuls_eline = 4,
+ .havon_begin = 148,
+ .havon_end = 3987,
+ .vavon_bline = 89,
+ .vavon_eline = 2248,
+ /* eqpuls_begin */
+ /* eqpuls_end */
+ /* eqpuls_bline */
+ /* eqpuls_eline */
+ .hso_begin = 44,
+ .hso_end = 2156+1920,
+ .vso_begin = 2100+1920,
+ .vso_end = 2164+1920,
+ .vso_bline = 51,
+ .vso_eline = 53,
+ .vso_eline_present = true,
+ /* sy_val */
+ /* sy2_val */
+ .max_lncnt = 2249,
+ },
+};
+
struct meson_hdmi_venc_vic_mode {
unsigned int vic;
union meson_hdmi_venc_mode *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 },
+ { 93, &meson_hdmi_encp_mode_2160p24 },
+ { 94, &meson_hdmi_encp_mode_2160p25 },
+ { 95, &meson_hdmi_encp_mode_2160p30 },
{ 0, NULL}, /* sentinel */
};

View File

@ -1,4 +1,4 @@
From f4d7ad156ad2253d5ec3e79ea36309e27b8fabc7 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

@ -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

@ -1,9 +1,10 @@
From 69d2f200d91fbd48e2388a8c5346f10d889a2928 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 223d7ef1a49981c597094e8519e150108cba9ef9 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 00ce6fbb804c6aaecd3bde8f2978d091fbc0546c 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

@ -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

@ -1,4 +1,4 @@
From 2df1a3a93bc1ce2d04fa0f0743c9c30195c7057a 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 ++++++++++++++++++++++
@ -27,10 +28,10 @@ Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
12 files changed, 540 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi
index 88e712e..319512e 100644
index 765247b..fb9ad6f 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi
@@ -95,6 +95,39 @@
@@ -102,6 +102,39 @@
};
};
};
@ -70,7 +71,7 @@ index 88e712e..319512e 100644
};
&cec_AO {
@@ -104,6 +137,14 @@
@@ -111,6 +144,14 @@
hdmi-phandle = <&hdmi_tx>;
};
@ -85,7 +86,7 @@ index 88e712e..319512e 100644
&cvbs_vdac_port {
cvbs_vdac_out: endpoint {
remote-endpoint = <&cvbs_connector_in>;
@@ -126,6 +167,10 @@
@@ -133,6 +174,10 @@
};
};
@ -719,7 +720,7 @@ index 5896e8a..f8c66a7 100644
status = "okay";
pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts
index 0868da4..ea71261 100644
index 313f88f..4fbfa5a 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts
@@ -85,6 +85,39 @@
@ -777,7 +778,7 @@ index 0868da4..ea71261 100644
&cpu0 {
#cooling-cells = <2>;
};
@@ -255,6 +296,10 @@
@@ -279,6 +320,10 @@
};
};

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

@ -1,16 +1,17 @@
From e282ad866be628951a95d297207c9a5580f4101d 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(-)
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 3c136f2b..a68ffbb 100644
index 5971976..1fc1270 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -430,8 +430,12 @@ static void hdmi_set_cts_n(struct dw_hdmi *hdmi, unsigned int cts,

View File

@ -0,0 +1,61 @@
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
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 | 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..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,
priv->io_base + _REG(VPP_MISC));
priv->viu.osd1_enabled = true;
+
+ drm_crtc_vblank_on(crtc);
}
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_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

@ -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,314 @@
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
Amlogic SoCs have a repository of 256 canvas which they use to
describe pixel buffers.
They contain metadata like width, height, block mode, endianness [..]
Many IPs within those SoCs like vdec/vpu rely on those canvas to read/write
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 +
drivers/soc/amlogic/meson-canvas.c | 185 +++++++++++++++++++++++++++++++
include/linux/soc/amlogic/meson-canvas.h | 65 +++++++++++
4 files changed, 258 insertions(+)
create mode 100644 drivers/soc/amlogic/meson-canvas.c
create mode 100644 include/linux/soc/amlogic/meson-canvas.h
diff --git a/drivers/soc/amlogic/Kconfig b/drivers/soc/amlogic/Kconfig
index b04f6e4..2f282b4 100644
--- a/drivers/soc/amlogic/Kconfig
+++ b/drivers/soc/amlogic/Kconfig
@@ -1,5 +1,12 @@
menu "Amlogic SoC drivers"
+config MESON_CANVAS
+ tristate "Amlogic Meson Canvas driver"
+ depends on ARCH_MESON || COMPILE_TEST
+ default n
+ help
+ Say yes to support the canvas IP for Amlogic SoCs.
+
config MESON_GX_SOCINFO
bool "Amlogic Meson GX SoC Information driver"
depends on ARCH_MESON || COMPILE_TEST
diff --git a/drivers/soc/amlogic/Makefile b/drivers/soc/amlogic/Makefile
index 8fa3218..0ab16d3 100644
--- a/drivers/soc/amlogic/Makefile
+++ b/drivers/soc/amlogic/Makefile
@@ -1,3 +1,4 @@
+obj-$(CONFIG_MESON_CANVAS) += meson-canvas.o
obj-$(CONFIG_MESON_GX_SOCINFO) += meson-gx-socinfo.o
obj-$(CONFIG_MESON_GX_PM_DOMAINS) += meson-gx-pwrc-vpu.o
obj-$(CONFIG_MESON_MX_SOCINFO) += meson-mx-socinfo.o
diff --git a/drivers/soc/amlogic/meson-canvas.c b/drivers/soc/amlogic/meson-canvas.c
new file mode 100644
index 0000000..fce33ca
--- /dev/null
+++ b/drivers/soc/amlogic/meson-canvas.c
@@ -0,0 +1,185 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 BayLibre, SAS
+ * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ * Copyright (C) 2014 Endless Mobile
+ */
+
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/soc/amlogic/meson-canvas.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/io.h>
+
+#define NUM_CANVAS 256
+
+/* DMC Registers */
+#define DMC_CAV_LUT_DATAL 0x00
+ #define CANVAS_WIDTH_LBIT 29
+ #define CANVAS_WIDTH_LWID 3
+#define DMC_CAV_LUT_DATAH 0x04
+ #define CANVAS_WIDTH_HBIT 0
+ #define CANVAS_HEIGHT_BIT 9
+ #define CANVAS_WRAP_BIT 22
+ #define CANVAS_BLKMODE_BIT 24
+ #define CANVAS_ENDIAN_BIT 26
+#define DMC_CAV_LUT_ADDR 0x08
+ #define CANVAS_LUT_WR_EN BIT(9)
+ #define CANVAS_LUT_RD_EN BIT(8)
+
+struct meson_canvas {
+ struct device *dev;
+ void __iomem *reg_base;
+ spinlock_t lock; /* canvas device lock */
+ u8 used[NUM_CANVAS];
+};
+
+static void canvas_write(struct meson_canvas *canvas, u32 reg, u32 val)
+{
+ writel_relaxed(val, canvas->reg_base + reg);
+}
+
+static u32 canvas_read(struct meson_canvas *canvas, u32 reg)
+{
+ return readl_relaxed(canvas->reg_base + reg);
+}
+
+struct meson_canvas *meson_canvas_get(struct device *dev)
+{
+ struct device_node *canvas_node;
+ struct platform_device *canvas_pdev;
+
+ canvas_node = of_parse_phandle(dev->of_node, "amlogic,canvas", 0);
+ if (!canvas_node)
+ return ERR_PTR(-ENODEV);
+
+ canvas_pdev = of_find_device_by_node(canvas_node);
+ if (!canvas_pdev)
+ return ERR_PTR(-EPROBE_DEFER);
+
+ return dev_get_drvdata(&canvas_pdev->dev);
+}
+EXPORT_SYMBOL_GPL(meson_canvas_get);
+
+int meson_canvas_config(struct meson_canvas *canvas, u8 canvas_index,
+ u32 addr, u32 stride, u32 height,
+ unsigned int wrap,
+ unsigned int blkmode,
+ unsigned int endian)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&canvas->lock, flags);
+ if (!canvas->used[canvas_index]) {
+ dev_err(canvas->dev,
+ "Trying to setup non allocated canvas %u\n",
+ canvas_index);
+ spin_unlock_irqrestore(&canvas->lock, flags);
+ return -EINVAL;
+ }
+
+ canvas_write(canvas, DMC_CAV_LUT_DATAL,
+ ((addr + 7) >> 3) |
+ (((stride + 7) >> 3) << CANVAS_WIDTH_LBIT));
+
+ canvas_write(canvas, DMC_CAV_LUT_DATAH,
+ ((((stride + 7) >> 3) >> CANVAS_WIDTH_LWID) <<
+ CANVAS_WIDTH_HBIT) |
+ (height << CANVAS_HEIGHT_BIT) |
+ (wrap << CANVAS_WRAP_BIT) |
+ (blkmode << CANVAS_BLKMODE_BIT) |
+ (endian << CANVAS_ENDIAN_BIT));
+
+ canvas_write(canvas, DMC_CAV_LUT_ADDR,
+ CANVAS_LUT_WR_EN | canvas_index);
+
+ /* Force a read-back to make sure everything is flushed. */
+ canvas_read(canvas, DMC_CAV_LUT_DATAH);
+ spin_unlock_irqrestore(&canvas->lock, flags);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(meson_canvas_config);
+
+int meson_canvas_alloc(struct meson_canvas *canvas, u8 *canvas_index)
+{
+ int i;
+ unsigned long flags;
+
+ spin_lock_irqsave(&canvas->lock, flags);
+ for (i = 0; i < NUM_CANVAS; ++i) {
+ if (!canvas->used[i]) {
+ canvas->used[i] = 1;
+ spin_unlock_irqrestore(&canvas->lock, flags);
+ *canvas_index = i;
+ return 0;
+ }
+ }
+ spin_unlock_irqrestore(&canvas->lock, flags);
+
+ dev_err(canvas->dev, "No more canvas available\n");
+ return -ENODEV;
+}
+EXPORT_SYMBOL_GPL(meson_canvas_alloc);
+
+int meson_canvas_free(struct meson_canvas *canvas, u8 canvas_index)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&canvas->lock, flags);
+ if (!canvas->used[canvas_index]) {
+ dev_err(canvas->dev,
+ "Trying to free unused canvas %u\n", canvas_index);
+ spin_unlock_irqrestore(&canvas->lock, flags);
+ return -EINVAL;
+ }
+ canvas->used[canvas_index] = 0;
+ spin_unlock_irqrestore(&canvas->lock, flags);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(meson_canvas_free);
+
+static int meson_canvas_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ struct meson_canvas *canvas;
+ struct device *dev = &pdev->dev;
+
+ canvas = devm_kzalloc(dev, sizeof(*canvas), GFP_KERNEL);
+ if (!canvas)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ canvas->reg_base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(canvas->reg_base))
+ return PTR_ERR(canvas->reg_base);
+
+ canvas->dev = dev;
+ spin_lock_init(&canvas->lock);
+ dev_set_drvdata(dev, canvas);
+
+ return 0;
+}
+
+static const struct of_device_id canvas_dt_match[] = {
+ { .compatible = "amlogic,canvas" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, canvas_dt_match);
+
+static struct platform_driver meson_canvas_driver = {
+ .probe = meson_canvas_probe,
+ .driver = {
+ .name = "amlogic-canvas",
+ .of_match_table = canvas_dt_match,
+ },
+};
+module_platform_driver(meson_canvas_driver);
+
+MODULE_DESCRIPTION("Amlogic Canvas driver");
+MODULE_AUTHOR("Maxime Jourdan <mjourdan@baylibre.com>");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/soc/amlogic/meson-canvas.h b/include/linux/soc/amlogic/meson-canvas.h
new file mode 100644
index 0000000..b4dde2f
--- /dev/null
+++ b/include/linux/soc/amlogic/meson-canvas.h
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2018 BayLibre, SAS
+ */
+#ifndef __SOC_MESON_CANVAS_H
+#define __SOC_MESON_CANVAS_H
+
+#include <linux/kernel.h>
+
+#define MESON_CANVAS_WRAP_NONE 0x00
+#define MESON_CANVAS_WRAP_X 0x01
+#define MESON_CANVAS_WRAP_Y 0x02
+
+#define MESON_CANVAS_BLKMODE_LINEAR 0x00
+#define MESON_CANVAS_BLKMODE_32x32 0x01
+#define MESON_CANVAS_BLKMODE_64x64 0x02
+
+#define MESON_CANVAS_ENDIAN_SWAP16 0x1
+#define MESON_CANVAS_ENDIAN_SWAP32 0x3
+#define MESON_CANVAS_ENDIAN_SWAP64 0x7
+#define MESON_CANVAS_ENDIAN_SWAP128 0xf
+
+struct meson_canvas;
+
+/**
+ * meson_canvas_get() - get a canvas provider instance
+ *
+ * @dev: consumer device pointer
+ */
+struct meson_canvas *meson_canvas_get(struct device *dev);
+
+/**
+ * meson_canvas_alloc() - take ownership of a canvas
+ *
+ * @canvas: canvas provider instance retrieved from meson_canvas_get()
+ * @canvas_index: will be filled with the canvas ID
+ */
+int meson_canvas_alloc(struct meson_canvas *canvas, u8 *canvas_index);
+
+/**
+ * meson_canvas_free() - remove ownership from a canvas
+ *
+ * @canvas: canvas provider instance retrieved from meson_canvas_get()
+ * @canvas_index: canvas ID that was obtained via meson_canvas_alloc()
+ */
+int meson_canvas_free(struct meson_canvas *canvas, u8 canvas_index);
+
+/**
+ * meson_canvas_config() - configure a canvas
+ *
+ * @canvas: canvas provider instance retrieved from meson_canvas_get()
+ * @canvas_index: canvas ID that was obtained via meson_canvas_alloc()
+ * @addr: physical address to the pixel buffer
+ * @stride: width of the buffer
+ * @height: height of the buffer
+ * @wrap: undocumented
+ * @blkmode: block mode (linear, 32x32, 64x64)
+ * @endian: byte swapping (swap16, swap32, swap64, swap128)
+ */
+int meson_canvas_config(struct meson_canvas *canvas, u8 canvas_index,
+ u32 addr, u32 stride, u32 height,
+ unsigned int wrap, unsigned int blkmode,
+ unsigned int endian);
+
+#endif

View File

@ -0,0 +1,39 @@
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.
DMC is a small memory region with various registers,
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(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
index 6b64b63..fb64354 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
@@ -458,6 +458,19 @@
};
};
+ dmcbus: bus@c8838000 {
+ compatible = "simple-bus";
+ reg = <0x0 0xc8838000 0x0 0x400>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges = <0x0 0x0 0x0 0xc8838000 0x0 0x400>;
+
+ canvas: video-lut@48 {
+ compatible = "amlogic,canvas";
+ reg = <0x0 0x48 0x0 0x14>;
+ };
+ };
+
hiubus: bus@c883c000 {
compatible = "simple-bus";
reg = <0x0 0xc883c000 0x0 0x2000>;

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

@ -1,36 +0,0 @@
From 4a3a6d04d4996ff0a0acc8405fdd0b0347a62138 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
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(+)
diff --git a/drivers/gpu/drm/meson/meson_crtc.c b/drivers/gpu/drm/meson/meson_crtc.c
index 0552020..4dd0df0 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,
priv->io_base + _REG(VPP_MISC));
priv->viu.osd1_enabled = true;
+
+ drm_crtc_vblank_on(crtc);
}
static void meson_crtc_atomic_disable(struct drm_crtc *crtc,
@@ -110,6 +112,10 @@ 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;

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,172 @@
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
This is the first step into converting the meson/drm driver to use
the canvas module.
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 +++++++----
drivers/gpu/drm/meson/meson_drv.c | 46 +++++++++++++++++++++++--------------
drivers/gpu/drm/meson/meson_drv.h | 4 ++++
drivers/gpu/drm/meson/meson_plane.c | 8 ++++++-
5 files changed, 51 insertions(+), 22 deletions(-)
diff --git a/drivers/gpu/drm/meson/Kconfig b/drivers/gpu/drm/meson/Kconfig
index 02d400b..8929058 100644
--- a/drivers/gpu/drm/meson/Kconfig
+++ b/drivers/gpu/drm/meson/Kconfig
@@ -7,6 +7,7 @@ config DRM_MESON
select DRM_GEM_CMA_HELPER
select VIDEOMODE_HELPERS
select REGMAP_MMIO
+ select MESON_CANVAS
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 7c0bdc8..8744244 100644
--- a/drivers/gpu/drm/meson/meson_crtc.c
+++ b/drivers/gpu/drm/meson/meson_crtc.c
@@ -197,10 +197,16 @@ void meson_crtc_irq(struct meson_drm *priv)
} else
meson_vpp_disable_interlace_vscaler_osd1(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,
- MESON_CANVAS_BLKMODE_LINEAR);
+ if (priv->canvas)
+ meson_canvas_config(priv->canvas, priv->canvas_id_osd1,
+ priv->viu.osd1_addr, priv->viu.osd1_stride,
+ priv->viu.osd1_height, MESON_CANVAS_WRAP_NONE,
+ MESON_CANVAS_BLKMODE_LINEAR, 0);
+ else
+ meson_canvas_setup(priv, MESON_CANVAS_ID_OSD1,
+ priv->viu.osd1_addr, priv->viu.osd1_stride,
+ priv->viu.osd1_height, MESON_CANVAS_WRAP_NONE,
+ MESON_CANVAS_BLKMODE_LINEAR);
/* Enable OSD1 */
writel_bits_relaxed(VPP_OSD1_POSTBLEND, VPP_OSD1_POSTBLEND,
diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
index d344312..b39c38c 100644
--- a/drivers/gpu/drm/meson/meson_drv.c
+++ b/drivers/gpu/drm/meson/meson_drv.c
@@ -216,24 +216,33 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
goto free_drm;
}
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dmc");
- if (!res) {
- ret = -EINVAL;
- goto free_drm;
- }
- /* Simply ioremap since it may be a shared register zone */
- regs = devm_ioremap(dev, res->start, resource_size(res));
- if (!regs) {
- ret = -EADDRNOTAVAIL;
- goto free_drm;
- }
+ priv->canvas = meson_canvas_get(dev);
+ if (!IS_ERR(priv->canvas)) {
+ ret = meson_canvas_alloc(priv->canvas, &priv->canvas_id_osd1);
+ if (ret)
+ goto free_drm;
+ } else {
+ priv->canvas = NULL;
- priv->dmc = devm_regmap_init_mmio(dev, regs,
- &meson_regmap_config);
- if (IS_ERR(priv->dmc)) {
- dev_err(&pdev->dev, "Couldn't create the DMC regmap\n");
- ret = PTR_ERR(priv->dmc);
- goto free_drm;
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dmc");
+ if (!res) {
+ ret = -EINVAL;
+ goto free_drm;
+ }
+ /* Simply ioremap since it may be a shared register zone */
+ regs = devm_ioremap(dev, res->start, resource_size(res));
+ if (!regs) {
+ ret = -EADDRNOTAVAIL;
+ goto free_drm;
+ }
+
+ priv->dmc = devm_regmap_init_mmio(dev, regs,
+ &meson_regmap_config);
+ if (IS_ERR(priv->dmc)) {
+ dev_err(&pdev->dev, "Couldn't create the DMC regmap\n");
+ ret = PTR_ERR(priv->dmc);
+ goto free_drm;
+ }
}
priv->vsync_irq = platform_get_irq(pdev, 0);
@@ -315,6 +324,9 @@ 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);
+
drm_dev_unregister(drm);
drm_kms_helper_poll_fini(drm);
drm_fbdev_cma_fini(priv->fbdev);
diff --git a/drivers/gpu/drm/meson/meson_drv.h b/drivers/gpu/drm/meson/meson_drv.h
index 8450d6ac..728d0ca 100644
--- a/drivers/gpu/drm/meson/meson_drv.h
+++ b/drivers/gpu/drm/meson/meson_drv.h
@@ -22,6 +22,7 @@
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/of.h>
+#include <linux/soc/amlogic/meson-canvas.h>
#include <drm/drmP.h>
struct meson_drm {
@@ -31,6 +32,9 @@ struct meson_drm {
struct regmap *dmc;
int vsync_irq;
+ struct meson_canvas *canvas;
+ u8 canvas_id_osd1;
+
struct drm_device *drm;
struct drm_crtc *crtc;
struct drm_fbdev_cma *fbdev;
diff --git a/drivers/gpu/drm/meson/meson_plane.c b/drivers/gpu/drm/meson/meson_plane.c
index 12c80df..51bec8e 100644
--- a/drivers/gpu/drm/meson/meson_plane.c
+++ b/drivers/gpu/drm/meson/meson_plane.c
@@ -90,6 +90,7 @@ static void meson_plane_atomic_update(struct drm_plane *plane,
.y2 = state->crtc_y + state->crtc_h,
};
unsigned long flags;
+ u8 canvas_id_osd1;
/*
* Update Coordinates
@@ -104,8 +105,13 @@ static void meson_plane_atomic_update(struct drm_plane *plane,
(0xFF << OSD_GLOBAL_ALPHA_SHIFT) |
OSD_BLK0_ENABLE;
+ if (priv->canvas)
+ canvas_id_osd1 = priv->canvas_id_osd1;
+ else
+ canvas_id_osd1 = MESON_CANVAS_ID_OSD1;
+
/* Set up BLK0 to point to the right canvas */
- priv->viu.osd1_blk0_cfg[0] = ((MESON_CANVAS_ID_OSD1 << OSD_CANVAS_SEL) |
+ priv->viu.osd1_blk0_cfg[0] = ((canvas_id_osd1 << OSD_CANVAS_SEL) |
OSD_ENDIANNESS_LE);
/* On GXBB, Use the old non-HDR RGB2YUV converter */

View File

@ -1,32 +0,0 @@
From 830bb1ab9ee8999566a4d98086590ac824cdeb4e Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Tue, 10 Jul 2018 15:00:45 +0200
Subject: [PATCH] media: platform: meson-ao-cec: make busy TX warning silent
Switch to dev_dbg for the busy TX message to avoid having a flood of:
[ 228.064570] meson-ao-cec c8100100.cec: meson_ao_cec_transmit: busy TX: aborting
[ 230.368489] meson-ao-cec c8100100.cec: meson_ao_cec_transmit: busy TX: aborting
[ 234.208655] meson-ao-cec c8100100.cec: meson_ao_cec_transmit: busy TX: aborting
[ 236.512558] meson-ao-cec c8100100.cec: meson_ao_cec_transmit: busy TX: aborting
This message is only a debug hint and not an error.
Fixes: 7ec2c0f72cb1 ("media: platform: Add Amlogic Meson AO CEC Controller driver")
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/media/platform/meson/ao-cec.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/platform/meson/ao-cec.c b/drivers/media/platform/meson/ao-cec.c
index 8040a62..cd4be38 100644
--- a/drivers/media/platform/meson/ao-cec.c
+++ b/drivers/media/platform/meson/ao-cec.c
@@ -524,7 +524,7 @@ static int meson_ao_cec_transmit(struct cec_adapter *adap, u8 attempts,
return ret;
if (reg == TX_BUSY) {
- dev_err(&ao_cec->pdev->dev, "%s: busy TX: aborting\n",
+ dev_dbg(&ao_cec->pdev->dev, "%s: busy TX: aborting\n",
__func__);
meson_ao_cec_write(ao_cec, CEC_TX_MSG_CMD, TX_ABORT, &ret);
}

View File

@ -0,0 +1,25 @@
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
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(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
index fb64354..5012607 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
@@ -540,6 +540,7 @@
interrupts = <GIC_SPI 3 IRQ_TYPE_EDGE_RISING>;
#address-cells = <1>;
#size-cells = <0>;
+ amlogic,canvas = <&canvas>;
/* CVBS VDAC output port */
cvbs_vdac_port: port@0 {

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

@ -1,280 +0,0 @@
From 8d7247813f02cad15a67980c2631d9ee37d7b76b Mon Sep 17 00:00:00 2001
From: Maxime Jourdan <maxi.jourdan@wanadoo.fr>
Date: Wed, 1 Aug 2018 20:51:25 +0200
Subject: [PATCH] soc: amlogic: add meson-canvas driver
Amlogic SoCs have a repository of 256 canvas which they use to
describe pixel buffers.
They contain metadata like width, height, block mode, endianness [..]
Many IPs within those SoCs like vdec/vpu rely on those canvas to read/write
pixels.
Signed-off-by: Maxime Jourdan <maxi.jourdan@wanadoo.fr>
---
drivers/soc/amlogic/Kconfig | 7 ++
drivers/soc/amlogic/Makefile | 1 +
drivers/soc/amlogic/meson-canvas.c | 182 +++++++++++++++++++++++++++++++
include/linux/soc/amlogic/meson-canvas.h | 37 +++++++
4 files changed, 227 insertions(+)
create mode 100644 drivers/soc/amlogic/meson-canvas.c
create mode 100644 include/linux/soc/amlogic/meson-canvas.h
diff --git a/drivers/soc/amlogic/Kconfig b/drivers/soc/amlogic/Kconfig
index b04f6e4..5bd0498 100644
--- a/drivers/soc/amlogic/Kconfig
+++ b/drivers/soc/amlogic/Kconfig
@@ -1,5 +1,12 @@
menu "Amlogic SoC drivers"
+config MESON_CANVAS
+ bool "Amlogic Meson Canvas driver"
+ depends on ARCH_MESON || COMPILE_TEST
+ default ARCH_MESON
+ help
+ Say yes to support the canvas IP within Amlogic Meson Soc family.
+
config MESON_GX_SOCINFO
bool "Amlogic Meson GX SoC Information driver"
depends on ARCH_MESON || COMPILE_TEST
diff --git a/drivers/soc/amlogic/Makefile b/drivers/soc/amlogic/Makefile
index 8fa3218..0ab16d3 100644
--- a/drivers/soc/amlogic/Makefile
+++ b/drivers/soc/amlogic/Makefile
@@ -1,3 +1,4 @@
+obj-$(CONFIG_MESON_CANVAS) += meson-canvas.o
obj-$(CONFIG_MESON_GX_SOCINFO) += meson-gx-socinfo.o
obj-$(CONFIG_MESON_GX_PM_DOMAINS) += meson-gx-pwrc-vpu.o
obj-$(CONFIG_MESON_MX_SOCINFO) += meson-mx-socinfo.o
diff --git a/drivers/soc/amlogic/meson-canvas.c b/drivers/soc/amlogic/meson-canvas.c
new file mode 100644
index 0000000..671eb89
--- /dev/null
+++ b/drivers/soc/amlogic/meson-canvas.c
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2018 Maxime Jourdan
+ * Copyright (C) 2016 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ * Copyright (C) 2014 Endless Mobile
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+#include <linux/soc/amlogic/meson-canvas.h>
+#include <asm/io.h>
+
+#define NUM_CANVAS 256
+
+/* DMC Registers */
+#define DMC_CAV_LUT_DATAL 0x48 /* 0x12 offset in data sheet */
+ #define CANVAS_WIDTH_LBIT 29
+ #define CANVAS_WIDTH_LWID 3
+#define DMC_CAV_LUT_DATAH 0x4c /* 0x13 offset in data sheet */
+ #define CANVAS_WIDTH_HBIT 0
+ #define CANVAS_HEIGHT_BIT 9
+ #define CANVAS_BLKMODE_BIT 24
+#define DMC_CAV_LUT_ADDR 0x50 /* 0x14 offset in data sheet */
+ #define CANVAS_LUT_WR_EN (0x2 << 8)
+ #define CANVAS_LUT_RD_EN (0x1 << 8)
+
+struct meson_canvas {
+ struct device *dev;
+ struct regmap *regmap_dmc;
+ struct mutex lock;
+ u8 used[NUM_CANVAS];
+};
+
+static struct meson_canvas canvas = { 0 };
+
+static int meson_canvas_setup(uint8_t canvas_index, uint32_t addr,
+ uint32_t stride, uint32_t height,
+ unsigned int wrap,
+ unsigned int blkmode,
+ unsigned int endian)
+{
+ struct regmap *regmap = canvas.regmap_dmc;
+ u32 val;
+
+ mutex_lock(&canvas.lock);
+
+ if (!canvas.used[canvas_index]) {
+ dev_err(canvas.dev,
+ "Trying to setup non allocated canvas %u\n",
+ canvas_index);
+ mutex_unlock(&canvas.lock);
+ return -EINVAL;
+ }
+
+ regmap_write(regmap, DMC_CAV_LUT_DATAL,
+ ((addr + 7) >> 3) |
+ (((stride + 7) >> 3) << CANVAS_WIDTH_LBIT));
+
+ regmap_write(regmap, DMC_CAV_LUT_DATAH,
+ ((((stride + 7) >> 3) >> CANVAS_WIDTH_LWID) <<
+ CANVAS_WIDTH_HBIT) |
+ (height << CANVAS_HEIGHT_BIT) |
+ (wrap << 22) |
+ (blkmode << CANVAS_BLKMODE_BIT) |
+ (endian << 26));
+
+ regmap_write(regmap, DMC_CAV_LUT_ADDR,
+ CANVAS_LUT_WR_EN | canvas_index);
+
+ /* Force a read-back to make sure everything is flushed. */
+ regmap_read(regmap, DMC_CAV_LUT_DATAH, &val);
+ mutex_unlock(&canvas.lock);
+
+ return 0;
+}
+
+static int meson_canvas_alloc(uint8_t *canvas_index)
+{
+ int i;
+
+ mutex_lock(&canvas.lock);
+ for (i = 0; i < NUM_CANVAS; ++i) {
+ if (!canvas.used[i]) {
+ canvas.used[i] = 1;
+ mutex_unlock(&canvas.lock);
+ *canvas_index = i;
+ return 0;
+ }
+ }
+ mutex_unlock(&canvas.lock);
+ dev_err(canvas.dev, "No more canvas available\n");
+
+ return -ENODEV;
+}
+
+static int meson_canvas_free(uint8_t canvas_index)
+{
+ mutex_lock(&canvas.lock);
+ if (!canvas.used[canvas_index]) {
+ dev_err(canvas.dev,
+ "Trying to free unused canvas %u\n", canvas_index);
+ mutex_unlock(&canvas.lock);
+ return -EINVAL;
+ }
+ canvas.used[canvas_index] = 0;
+ mutex_unlock(&canvas.lock);
+
+ return 0;
+}
+
+static struct meson_canvas_platform_data canvas_platform_data = {
+ .alloc = meson_canvas_alloc,
+ .free = meson_canvas_free,
+ .setup = meson_canvas_setup,
+};
+
+static int meson_canvas_probe(struct platform_device *pdev)
+{
+ struct regmap *regmap_dmc;
+ struct device *dev;
+
+ dev = &pdev->dev;
+
+ regmap_dmc = syscon_node_to_regmap(of_get_parent(dev->of_node));
+ if (IS_ERR(regmap_dmc)) {
+ dev_err(&pdev->dev, "failed to get DMC regmap\n");
+ return PTR_ERR(regmap_dmc);
+ }
+
+ canvas.dev = dev;
+ canvas.regmap_dmc = regmap_dmc;
+ mutex_init(&canvas.lock);
+
+ dev->platform_data = &canvas_platform_data;
+
+ return 0;
+}
+
+static int meson_canvas_remove(struct platform_device *pdev)
+{
+ mutex_destroy(&canvas.lock);
+ return 0;
+}
+
+static const struct of_device_id canvas_dt_match[] = {
+ { .compatible = "amlogic,meson-canvas" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, canvas_dt_match);
+
+static struct platform_driver meson_canvas_driver = {
+ .probe = meson_canvas_probe,
+ .remove = meson_canvas_remove,
+ .driver = {
+ .name = "meson-canvas",
+ .of_match_table = canvas_dt_match,
+ },
+};
+module_platform_driver(meson_canvas_driver);
+
+MODULE_ALIAS("platform:meson-canvas");
+MODULE_DESCRIPTION("AMLogic Meson Canvas driver");
+MODULE_AUTHOR("Maxime Jourdan <maxi.jourdan@wanadoo.fr>");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/soc/amlogic/meson-canvas.h b/include/linux/soc/amlogic/meson-canvas.h
new file mode 100644
index 0000000..af9e241
--- /dev/null
+++ b/include/linux/soc/amlogic/meson-canvas.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2018 Maxime Jourdan
+ * Author: Maxime Jourdan <maxi.jourdan@wanadoo.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#ifndef MESON_CANVAS_H
+#define MESON_CANVAS_H
+
+#include <linux/kernel.h>
+
+#define MESON_CANVAS_WRAP_NONE 0x00
+#define MESON_CANVAS_WRAP_X 0x01
+#define MESON_CANVAS_WRAP_Y 0x02
+
+#define MESON_CANVAS_BLKMODE_LINEAR 0x00
+#define MESON_CANVAS_BLKMODE_32x32 0x01
+#define MESON_CANVAS_BLKMODE_64x64 0x02
+
+struct meson_canvas_platform_data {
+ int (*alloc)(uint8_t *canvas_index);
+ int (*free) (uint8_t canvas_index);
+ int (*setup)(uint8_t canvas_index, uint32_t addr,
+ uint32_t stride, uint32_t height,
+ unsigned int wrap,
+ unsigned int blkmode,
+ unsigned int endian);
+};
+
+#endif

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

@ -1,40 +1,122 @@
From 5d0ab03232cdda74b9eb4ce283e98aa60c40b0c9 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] [WIP] drm/meson: Support Overlay plane for video rendering
Subject: [PATCH] drm/meson: Support Overlay plane for video rendering
The Amlogic Meson GX SoCs support an Overlay plane behind the primary
plan for video rendering.
This Overlay plane support various YUV layouts and a non-alpha RGB32
layout.
plane for video rendering.
This Overlay plane support various YUV layouts :
- YUYV
- NV12 / NV21
- YUV444 / 422 / 420 / 411 / 410
The scaler supports a wide range of scaling ratios, but for simplicity,
plane atomic check limits the scaling from x5 to /5 in vertical and
horizontal scaling.
The z-order is fixed and always behind the primary plane and cannot be changed.
The scaling parameter algorithm was taken from the Amlogic vendor kernel
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_crtc.c | 170 ++++++++-
drivers/gpu/drm/meson/meson_drv.c | 14 +
drivers/gpu/drm/meson/meson_canvas.c | 7 +-
drivers/gpu/drm/meson/meson_canvas.h | 11 +-
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 | 595 ++++++++++++++++++++++++++++++++
drivers/gpu/drm/meson/meson_overlay.c | 586 ++++++++++++++++++++++++++++++++
drivers/gpu/drm/meson/meson_overlay.h | 14 +
drivers/gpu/drm/meson/meson_registers.h | 3 +
drivers/gpu/drm/meson/meson_viu.c | 15 +
drivers/gpu/drm/meson/meson_vpp.c | 44 ++-
drivers/soc/amlogic/meson-gx-pwrc-vpu.c | 8 +-
10 files changed, 910 insertions(+), 7 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
diff --git a/drivers/gpu/drm/meson/Makefile b/drivers/gpu/drm/meson/Makefile
index bd67429..d4ea82f 100644
index c5c4cc3..7709f2f 100644
--- a/drivers/gpu/drm/meson/Makefile
+++ b/drivers/gpu/drm/meson/Makefile
@@ -1,5 +1,5 @@
meson-drm-y := meson_drv.o meson_plane.o meson_crtc.o meson_venc_cvbs.o
-meson-drm-y += meson_viu.o meson_vpp.o meson_venc.o meson_vclk.o
+meson-drm-y += meson_viu.o meson_vpp.o meson_venc.o meson_vclk.o meson_overlay.o
-meson-drm-y += meson_viu.o meson_vpp.o meson_venc.o meson_vclk.o meson_canvas.o
+meson-drm-y += meson_viu.o meson_vpp.o meson_venc.o meson_vclk.o meson_canvas.o meson_overlay.o
obj-$(CONFIG_DRM_MESON) += meson-drm.o
obj-$(CONFIG_DRM_MESON_DW_HDMI) += meson_dw_hdmi.o
diff --git a/drivers/gpu/drm/meson/meson_canvas.c b/drivers/gpu/drm/meson/meson_canvas.c
index 08f6073..5de11aa 100644
--- a/drivers/gpu/drm/meson/meson_canvas.c
+++ b/drivers/gpu/drm/meson/meson_canvas.c
@@ -39,6 +39,7 @@
#define CANVAS_WIDTH_HBIT 0
#define CANVAS_HEIGHT_BIT 9
#define CANVAS_BLKMODE_BIT 24
+#define CANVAS_ENDIAN_BIT 26
#define DMC_CAV_LUT_ADDR 0x50 /* 0x14 offset in data sheet */
#define CANVAS_LUT_WR_EN (0x2 << 8)
#define CANVAS_LUT_RD_EN (0x1 << 8)
@@ -47,7 +48,8 @@ void meson_canvas_setup(struct meson_drm *priv,
uint32_t canvas_index, uint32_t addr,
uint32_t stride, uint32_t height,
unsigned int wrap,
- unsigned int blkmode)
+ unsigned int blkmode,
+ unsigned int endian)
{
unsigned int val;
@@ -60,7 +62,8 @@ void meson_canvas_setup(struct meson_drm *priv,
CANVAS_WIDTH_HBIT) |
(height << CANVAS_HEIGHT_BIT) |
(wrap << 22) |
- (blkmode << CANVAS_BLKMODE_BIT));
+ (blkmode << CANVAS_BLKMODE_BIT) |
+ (endian << CANVAS_ENDIAN_BIT));
regmap_write(priv->dmc, DMC_CAV_LUT_ADDR,
CANVAS_LUT_WR_EN | canvas_index);
diff --git a/drivers/gpu/drm/meson/meson_canvas.h b/drivers/gpu/drm/meson/meson_canvas.h
index af1759d..85dbf26 100644
--- a/drivers/gpu/drm/meson/meson_canvas.h
+++ b/drivers/gpu/drm/meson/meson_canvas.h
@@ -23,6 +23,9 @@
#define __MESON_CANVAS_H
#define MESON_CANVAS_ID_OSD1 0x4e
+#define MESON_CANVAS_ID_VD1_0 0x60
+#define MESON_CANVAS_ID_VD1_1 0x61
+#define MESON_CANVAS_ID_VD1_2 0x62
/* Canvas configuration. */
#define MESON_CANVAS_WRAP_NONE 0x00
@@ -33,10 +36,16 @@
#define MESON_CANVAS_BLKMODE_32x32 0x01
#define MESON_CANVAS_BLKMODE_64x64 0x02
+#define MESON_CANVAS_ENDIAN_SWAP16 0x1
+#define MESON_CANVAS_ENDIAN_SWAP32 0x3
+#define MESON_CANVAS_ENDIAN_SWAP64 0x7
+#define MESON_CANVAS_ENDIAN_SWAP128 0xf
+
void meson_canvas_setup(struct meson_drm *priv,
uint32_t canvas_index, uint32_t addr,
uint32_t stride, uint32_t height,
unsigned int wrap,
- unsigned int blkmode);
+ unsigned int blkmode,
+ unsigned int endian);
#endif /* __MESON_CANVAS_H */
diff --git a/drivers/gpu/drm/meson/meson_crtc.c b/drivers/gpu/drm/meson/meson_crtc.c
index 7c8ad06..90c826b 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 @@
@ -45,7 +127,7 @@ index 7c8ad06..90c826b 100644
#include <drm/drmP.h>
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
@@ -97,6 +98,10 @@ static void meson_crtc_atomic_enable(struct drm_crtc *crtc,
@@ -98,6 +99,10 @@ static void meson_crtc_atomic_enable(struct drm_crtc *crtc,
writel(crtc_state->mode.hdisplay,
priv->io_base + _REG(VPP_POSTBLEND_H_SIZE));
@ -56,7 +138,12 @@ index 7c8ad06..90c826b 100644
writel_bits_relaxed(VPP_POSTBLEND_ENABLE, VPP_POSTBLEND_ENABLE,
priv->io_base + _REG(VPP_MISC));
@@ -118,8 +123,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;
@ -70,7 +157,7 @@ index 7c8ad06..90c826b 100644
priv->io_base + _REG(VPP_MISC));
if (crtc->state->event && !crtc->state->active) {
@@ -154,6 +163,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;
@ -78,7 +165,16 @@ index 7c8ad06..90c826b 100644
}
static const struct drm_crtc_helper_funcs meson_crtc_helper_funcs = {
@@ -210,6 +220,164 @@ 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,
- MESON_CANVAS_BLKMODE_LINEAR);
+ MESON_CANVAS_BLKMODE_LINEAR, 0);
/* Enable OSD1 */
writel_bits_relaxed(VPP_OSD1_POSTBLEND, VPP_OSD1_POSTBLEND,
@@ -215,6 +227,206 @@ void meson_crtc_irq(struct meson_drm *priv)
priv->viu.osd1_commit = false;
}
@ -87,20 +183,61 @@ index 7c8ad06..90c826b 100644
+
+ switch (priv->viu.vd1_planes) {
+ case 3:
+ priv->canvas_ops->setup(priv->canvas_id_vd1_2,
+ priv->viu.vd1_addr2, priv->viu.vd1_stride2,
+ priv->viu.vd1_height2, MESON_CANVAS_WRAP_NONE,
+ MESON_CANVAS_BLKMODE_LINEAR, 7);
+ if (priv->canvas)
+ meson_canvas_config(priv->canvas,
+ priv->canvas_id_vd1_2,
+ priv->viu.vd1_addr2,
+ priv->viu.vd1_stride2,
+ priv->viu.vd1_height2,
+ MESON_CANVAS_WRAP_NONE,
+ MESON_CANVAS_BLKMODE_LINEAR,
+ MESON_CANVAS_ENDIAN_SWAP64);
+ else
+ meson_canvas_setup(priv, MESON_CANVAS_ID_VD1_2,
+ priv->viu.vd1_addr2,
+ priv->viu.vd1_stride2,
+ priv->viu.vd1_height2,
+ MESON_CANVAS_WRAP_NONE,
+ MESON_CANVAS_BLKMODE_LINEAR,
+ MESON_CANVAS_ENDIAN_SWAP64);
+ /* fallthrough */
+ case 2:
+ priv->canvas_ops->setup(priv->canvas_id_vd1_1,
+ priv->viu.vd1_addr1, priv->viu.vd1_stride1,
+ priv->viu.vd1_height1, MESON_CANVAS_WRAP_NONE,
+ MESON_CANVAS_BLKMODE_LINEAR, 7);
+ if (priv->canvas)
+ meson_canvas_config(priv->canvas,
+ priv->canvas_id_vd1_1,
+ priv->viu.vd1_addr1,
+ priv->viu.vd1_stride1,
+ priv->viu.vd1_height1,
+ MESON_CANVAS_WRAP_NONE,
+ MESON_CANVAS_BLKMODE_LINEAR,
+ MESON_CANVAS_ENDIAN_SWAP64);
+ else
+ meson_canvas_setup(priv, MESON_CANVAS_ID_VD1_1,
+ priv->viu.vd1_addr2,
+ priv->viu.vd1_stride2,
+ priv->viu.vd1_height2,
+ MESON_CANVAS_WRAP_NONE,
+ MESON_CANVAS_BLKMODE_LINEAR,
+ MESON_CANVAS_ENDIAN_SWAP64);
+ /* fallthrough */
+ case 1:
+ priv->canvas_ops->setup(priv->canvas_id_vd1_0,
+ priv->viu.vd1_addr0, priv->viu.vd1_stride0,
+ priv->viu.vd1_height0, MESON_CANVAS_WRAP_NONE,
+ MESON_CANVAS_BLKMODE_LINEAR, 7);
+ if (priv->canvas)
+ meson_canvas_config(priv->canvas,
+ priv->canvas_id_vd1_0,
+ priv->viu.vd1_addr0,
+ priv->viu.vd1_stride0,
+ priv->viu.vd1_height0,
+ MESON_CANVAS_WRAP_NONE,
+ MESON_CANVAS_BLKMODE_LINEAR,
+ MESON_CANVAS_ENDIAN_SWAP64);
+ else
+ meson_canvas_setup(priv, MESON_CANVAS_ID_VD1_0,
+ priv->viu.vd1_addr2,
+ priv->viu.vd1_stride2,
+ priv->viu.vd1_height2,
+ MESON_CANVAS_WRAP_NONE,
+ MESON_CANVAS_BLKMODE_LINEAR,
+ MESON_CANVAS_ENDIAN_SWAP64);
+ };
+
+ writel_relaxed(priv->viu.vd1_if0_gen_reg,
@ -192,13 +329,13 @@ index 7c8ad06..90c826b 100644
+ writel_relaxed(priv->viu.vpp_pic_in_height,
+ priv->io_base + _REG(VPP_PIC_IN_HEIGHT));
+ writel_relaxed(priv->viu.vpp_postblend_vd1_h_start_end,
+ priv->io_base + _REG(VPP_POSTBLEND_VD1_H_START_END));
+ priv->io_base + _REG(VPP_POSTBLEND_VD1_H_START_END));
+ writel_relaxed(priv->viu.vpp_blend_vd2_h_start_end,
+ priv->io_base + _REG(VPP_BLEND_VD2_H_START_END));
+ priv->io_base + _REG(VPP_BLEND_VD2_H_START_END));
+ writel_relaxed(priv->viu.vpp_postblend_vd1_v_start_end,
+ priv->io_base + _REG(VPP_POSTBLEND_VD1_V_START_END));
+ priv->io_base + _REG(VPP_POSTBLEND_VD1_V_START_END));
+ writel_relaxed(priv->viu.vpp_blend_vd2_v_start_end,
+ priv->io_base + _REG(VPP_BLEND_VD2_V_START_END));
+ priv->io_base + _REG(VPP_BLEND_VD2_V_START_END));
+ writel_relaxed(priv->viu.vpp_hsc_region12_startp,
+ priv->io_base + _REG(VPP_HSC_REGION12_STARTP));
+ writel_relaxed(priv->viu.vpp_hsc_region34_startp,
@ -208,9 +345,9 @@ index 7c8ad06..90c826b 100644
+ writel_relaxed(priv->viu.vpp_hsc_start_phase_step,
+ priv->io_base + _REG(VPP_HSC_START_PHASE_STEP));
+ writel_relaxed(priv->viu.vpp_hsc_region1_phase_slope,
+ priv->io_base + _REG(VPP_HSC_REGION1_PHASE_SLOPE));
+ priv->io_base + _REG(VPP_HSC_REGION1_PHASE_SLOPE));
+ writel_relaxed(priv->viu.vpp_hsc_region3_phase_slope,
+ priv->io_base + _REG(VPP_HSC_REGION3_PHASE_SLOPE));
+ priv->io_base + _REG(VPP_HSC_REGION3_PHASE_SLOPE));
+ writel_relaxed(priv->viu.vpp_line_in_length,
+ priv->io_base + _REG(VPP_LINE_IN_LENGTH));
+ writel_relaxed(priv->viu.vpp_preblend_h_size,
@ -229,12 +366,13 @@ index 7c8ad06..90c826b 100644
+ priv->io_base + _REG(VPP_VSC_PHASE_CTRL));
+ writel_relaxed(priv->viu.vpp_hsc_phase_ctrl,
+ priv->io_base + _REG(VPP_HSC_PHASE_CTRL));
+ writel_relaxed(0x00000042,
+ priv->io_base + _REG(VPP_SCALE_COEF_IDX));
+ writel_relaxed(0x42, priv->io_base + _REG(VPP_SCALE_COEF_IDX));
+
+ /* Enable VD1 */
+ writel_bits_relaxed(VPP_VD1_PREBLEND | VPP_VD1_POSTBLEND | VPP_COLOR_MNG_ENABLE,
+ VPP_VD1_PREBLEND | VPP_VD1_POSTBLEND | VPP_COLOR_MNG_ENABLE,
+ writel_bits_relaxed(VPP_VD1_PREBLEND | VPP_VD1_POSTBLEND |
+ VPP_COLOR_MNG_ENABLE,
+ VPP_VD1_PREBLEND | VPP_VD1_POSTBLEND |
+ VPP_COLOR_MNG_ENABLE,
+ priv->io_base + _REG(VPP_MISC));
+
+ priv->viu.vd1_commit = false;
@ -244,10 +382,10 @@ index 7c8ad06..90c826b 100644
spin_lock_irqsave(&priv->drm->event_lock, flags);
diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
index de46833..2a002cc 100644
index b39c38c..b55e03d 100644
--- a/drivers/gpu/drm/meson/meson_drv.c
+++ b/drivers/gpu/drm/meson/meson_drv.c
@@ -42,6 +42,7 @@
@@ -41,6 +41,7 @@
#include "meson_drv.h"
#include "meson_plane.h"
@ -255,23 +393,32 @@ index de46833..2a002cc 100644
#include "meson_crtc.h"
#include "meson_venc_cvbs.h"
@@ -241,6 +242,15 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
ret = priv->canvas_ops->alloc(&priv->canvas_id_osd1);
if (ret)
goto free_drm;
+ ret = priv->canvas_ops->alloc(&priv->canvas_id_vd1_0);
+ if (ret)
+ goto free_drm;
+ ret = priv->canvas_ops->alloc(&priv->canvas_id_vd1_1);
+ if (ret)
+ goto free_drm;
+ ret = priv->canvas_ops->alloc(&priv->canvas_id_vd1_2);
+ if (ret)
+ goto free_drm;
@@ -221,6 +222,24 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
ret = meson_canvas_alloc(priv->canvas, &priv->canvas_id_osd1);
if (ret)
goto free_drm;
+ ret = meson_canvas_alloc(priv->canvas, &priv->canvas_id_vd1_0);
+ if (ret) {
+ meson_canvas_free(priv->canvas, priv->canvas_id_osd1);
+ goto free_drm;
+ }
+ ret = meson_canvas_alloc(priv->canvas, &priv->canvas_id_vd1_1);
+ if (ret) {
+ meson_canvas_free(priv->canvas, priv->canvas_id_osd1);
+ meson_canvas_free(priv->canvas, priv->canvas_id_vd1_0);
+ goto free_drm;
+ }
+ ret = meson_canvas_alloc(priv->canvas, &priv->canvas_id_vd1_2);
+ if (ret) {
+ meson_canvas_free(priv->canvas, priv->canvas_id_osd1);
+ meson_canvas_free(priv->canvas, priv->canvas_id_vd1_0);
+ meson_canvas_free(priv->canvas, priv->canvas_id_vd1_1);
+ goto free_drm;
+ }
} else {
priv->canvas = NULL;
priv->vsync_irq = platform_get_irq(pdev, 0);
@@ -278,6 +288,10 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
@@ -281,6 +300,10 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
if (ret)
goto free_drm;
@ -282,17 +429,31 @@ index de46833..2a002cc 100644
ret = meson_crtc_create(priv);
if (ret)
goto free_drm;
@@ -324,8 +347,12 @@ 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)
+ if (priv->canvas) {
meson_canvas_free(priv->canvas, priv->canvas_id_osd1);
+ meson_canvas_free(priv->canvas, priv->canvas_id_vd1_0);
+ meson_canvas_free(priv->canvas, priv->canvas_id_vd1_1);
+ meson_canvas_free(priv->canvas, priv->canvas_id_vd1_2);
+ }
drm_dev_unregister(drm);
drm_kms_helper_poll_fini(drm);
diff --git a/drivers/gpu/drm/meson/meson_drv.h b/drivers/gpu/drm/meson/meson_drv.h
index dfea959..e9305d7 100644
index 728d0ca..c971557 100644
--- a/drivers/gpu/drm/meson/meson_drv.h
+++ b/drivers/gpu/drm/meson/meson_drv.h
@@ -33,11 +33,15 @@ struct meson_drm {
@@ -34,11 +34,15 @@ struct meson_drm {
struct meson_canvas_platform_data *canvas_ops;
uint8_t canvas_id_osd1;
+ uint8_t canvas_id_vd1_0;
+ uint8_t canvas_id_vd1_1;
+ uint8_t canvas_id_vd1_2;
struct meson_canvas *canvas;
u8 canvas_id_osd1;
+ u8 canvas_id_vd1_0;
+ u8 canvas_id_vd1_1;
+ u8 canvas_id_vd1_2;
struct drm_device *drm;
struct drm_crtc *crtc;
@ -302,7 +463,7 @@ index dfea959..e9305d7 100644
/* Components Data */
struct {
@@ -49,6 +53,54 @@ struct meson_drm {
@@ -50,6 +54,54 @@ struct meson_drm {
uint32_t osd1_addr;
uint32_t osd1_stride;
uint32_t osd1_height;
@ -359,10 +520,10 @@ index dfea959..e9305d7 100644
struct {
diff --git a/drivers/gpu/drm/meson/meson_overlay.c b/drivers/gpu/drm/meson/meson_overlay.c
new file mode 100644
index 0000000..ea7261a
index 0000000..9aebc5e
--- /dev/null
+++ b/drivers/gpu/drm/meson/meson_overlay.c
@@ -0,0 +1,595 @@
@@ -0,0 +1,586 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 BayLibre, SAS
@ -386,6 +547,7 @@ index 0000000..ea7261a
+#include "meson_overlay.h"
+#include "meson_vpp.h"
+#include "meson_viu.h"
+#include "meson_canvas.h"
+#include "meson_registers.h"
+
+/* VD1_IF0_GEN_REG */
@ -452,7 +614,7 @@ index 0000000..ea7261a
+#define FRAC_16_16(mult, div) (((mult) << 16) / (div))
+
+static int meson_overlay_atomic_check(struct drm_plane *plane,
+ struct drm_plane_state *state)
+ struct drm_plane_state *state)
+{
+ struct drm_crtc_state *crtc_state;
+
@ -475,20 +637,19 @@ index 0000000..ea7261a
+ return value >> 16;
+}
+
+static const uint8_t skip_tab[6] = {0x24, 0x04, 0x68, 0x48, 0x28, 0x08};
+static const uint8_t skip_tab[6] = {
+ 0x24, 0x04, 0x68, 0x48, 0x28, 0x08,
+};
+
+static void meson_overlay_get_vertical_phase(unsigned ratio_y,
+ int *phase,
+ int *repeat,
+ bool interlace)
+static void meson_overlay_get_vertical_phase(unsigned int ratio_y, int *phase,
+ int *repeat, bool interlace)
+{
+ int offset_in = 0;
+ int offset_out = 0;
+ int repeat_skip = 0;
+
+ if (!interlace && ratio_y > (1 << 18)) {
+ if (!interlace && ratio_y > (1 << 18))
+ offset_out = (1 * ratio_y) >> 10;
+ }
+
+ while ((offset_in + (4 << 8)) <= offset_out) {
+ repeat_skip++;
@ -512,19 +673,19 @@ index 0000000..ea7261a
+ struct drm_plane *plane,
+ bool interlace_mode)
+{
+ struct drm_plane_state *state = plane->state;
+ struct drm_crtc_state *crtc_state = priv->crtc->state;
+ int video_top, video_left, video_width, video_height;
+ unsigned int crop_top, crop_left;
+ unsigned int crtc_height, crtc_width;
+ struct drm_plane_state *state = plane->state;
+ unsigned int vd_start_lines, vd_end_lines;
+ unsigned int hd_start_lines, hd_end_lines;
+ unsigned int crtc_height, crtc_width;
+ unsigned int vsc_startp, vsc_endp;
+ unsigned int hsc_startp, hsc_endp;
+ unsigned int ratio_x, ratio_y;
+ unsigned int w_in, h_in;
+ unsigned int crop_top, crop_left;
+ int vphase, vphase_repeat_skip;
+ unsigned int ratio_x, ratio_y;
+ int temp_height, temp_width;
+ unsigned int w_in, h_in;
+ int temp, start, end;
+
+ if (!crtc_state) {
@ -546,19 +707,15 @@ index 0000000..ea7261a
+ video_height = state->crtc_h;
+
+ DRM_DEBUG("crtc_width %d crtc_height %d interlace %d\n",
+ crtc_width, crtc_height, interlace_mode);
+ crtc_width, crtc_height, interlace_mode);
+ DRM_DEBUG("w_in %d h_in %d crop_top %d crop_left %d\n",
+ w_in, h_in, crop_top, crop_left);
+ w_in, h_in, crop_top, crop_left);
+ DRM_DEBUG("video top %d left %d width %d height %d\n",
+ video_top, video_left, video_width, video_height);
+ video_top, video_left, video_width, video_height);
+
+ ratio_x = (w_in << 18) / video_width;
+ ratio_y = (h_in << 18) / video_height;
+
+ /* TOFIX Interlace output */
+ if (interlace_mode)
+ ratio_y <<= 1;
+
+ if (ratio_x * video_width < (w_in << 18))
+ ratio_x++;
+
@ -571,7 +728,7 @@ index 0000000..ea7261a
+
+ /* Vertical */
+
+ start = video_top + video_height / 2 - ((h_in << 17) / ratio_x);
+ start = video_top + video_height / 2 - ((h_in << 17) / ratio_y);
+ end = (h_in << 18) / ratio_y + start - 1;
+
+ if (video_top < 0 && start < 0)
@ -582,11 +739,13 @@ index 0000000..ea7261a
+ vd_start_lines = 0;
+
+ if (video_top < 0)
+ temp_height = min_t(unsigned int, (video_top + video_height - 1),
+ (crtc_height - 1));
+ temp_height = min_t(unsigned int,
+ video_top + video_height - 1,
+ crtc_height - 1);
+ else
+ temp_height = min_t(unsigned int, (video_top + video_height - 1),
+ (crtc_height - 1)) - video_top + 1;
+ temp_height = min_t(unsigned int,
+ video_top + video_height - 1,
+ crtc_height - 1) - video_top + 1;
+
+ temp = vd_start_lines + (temp_height * ratio_y >> 18);
+ vd_end_lines = (temp <= (h_in - 1)) ? temp : (h_in - 1);
@ -594,6 +753,11 @@ index 0000000..ea7261a
+ vd_start_lines += crop_left;
+ vd_end_lines += crop_left;
+
+ /*
+ * TOFIX: Input frames are handled and scaled like progressive frames,
+ * proper handling of interlaced field input frames need to be figured
+ * out using the proper framebuffer flags set by userspace.
+ */
+ if (interlace_mode) {
+ start >>= 1;
+ end >>= 1;
@ -621,21 +785,21 @@ index 0000000..ea7261a
+ hd_start_lines = 0;
+
+ if (video_left < 0)
+ temp_width = min_t(unsigned int, (video_left + video_width - 1),
+ (crtc_width - 1));
+ temp_width = min_t(unsigned int,
+ video_left + video_width - 1,
+ crtc_width - 1);
+ else
+ temp_width = min_t(unsigned int, (video_left + video_width - 1),
+ (crtc_width - 1)) - video_left + 1;
+ temp_width = min_t(unsigned int,
+ video_left + video_width - 1,
+ crtc_width - 1) - video_left + 1;
+
+ temp = hd_start_lines + (temp_width * ratio_x >> 18);
+ hd_end_lines = (temp <= (w_in - 1)) ? temp : (w_in - 1);
+
+ priv->viu.vpp_line_in_length = hd_end_lines - hd_start_lines + 1;
+ hsc_startp = max_t(int, start,
+ max_t(int, 0, video_left));
+ hsc_endp = min_t(int, end,
+ min_t(int, crtc_width - 1,
+ video_left + video_width - 1));
+ hsc_startp = max_t(int, start, max_t(int, 0, video_left));
+ hsc_endp = min_t(int, end, min_t(int, crtc_width - 1,
+ video_left + video_width - 1));
+
+ hd_start_lines += crop_top;
+ hd_end_lines += crop_top;
@ -654,8 +818,9 @@ index 0000000..ea7261a
+ priv->viu.vd1_if0_chroma_x0 = VD_X_START(hd_start_lines >> 1) |
+ VD_X_END(hd_end_lines >> 1);
+
+ priv->viu.viu_vd1_fmt_w = VD_H_WIDTH(hd_end_lines - hd_start_lines + 1) |
+ VD_V_WIDTH(hd_end_lines/2 - hd_start_lines/2 + 1);
+ priv->viu.viu_vd1_fmt_w =
+ VD_H_WIDTH(hd_end_lines - hd_start_lines + 1) |
+ VD_V_WIDTH(hd_end_lines/2 - hd_start_lines/2 + 1);
+
+ priv->viu.vd1_if0_luma_y0 = VD_Y_START(vd_start_lines) |
+ VD_Y_END(vd_end_lines);
@ -671,7 +836,8 @@ index 0000000..ea7261a
+ VD_H_END(hd_end_lines);
+ priv->viu.vpp_hsc_region12_startp = VD_REGION13_END(0) |
+ VD_REGION24_START(hsc_startp);
+ priv->viu.vpp_hsc_region34_startp = VD_REGION13_END(hsc_startp) |
+ priv->viu.vpp_hsc_region34_startp =
+ VD_REGION13_END(hsc_startp) |
+ VD_REGION24_START(hsc_endp - hsc_startp);
+ priv->viu.vpp_hsc_region4_endp = hsc_endp - hsc_startp;
+ priv->viu.vpp_hsc_start_phase_step = ratio_x << 6;
@ -690,8 +856,8 @@ index 0000000..ea7261a
+
+ priv->viu.vpp_vsc_region12_startp = 0;
+ priv->viu.vpp_vsc_region34_startp =
+ VD_REGION13_END(vsc_endp - vsc_startp) |
+ VD_REGION24_START(vsc_endp - vsc_startp);
+ VD_REGION13_END(vsc_endp - vsc_startp) |
+ VD_REGION24_START(vsc_endp - vsc_startp);
+ priv->viu.vpp_vsc_region4_endp = vsc_endp - vsc_startp;
+ priv->viu.vpp_vsc_start_phase_step = ratio_y << 6;
+}
@ -709,14 +875,15 @@ index 0000000..ea7261a
+
+ DRM_DEBUG_DRIVER("\n");
+
+ /* Fallback is canvas provider is not available */
+ if (!priv->canvas) {
+ priv->canvas_id_vd1_0 = MESON_CANVAS_ID_VD1_0;
+ priv->canvas_id_vd1_1 = MESON_CANVAS_ID_VD1_1;
+ priv->canvas_id_vd1_2 = MESON_CANVAS_ID_VD1_2;
+ }
+
+ interlace_mode = state->crtc->mode.flags & DRM_MODE_FLAG_INTERLACE;
+
+ /*
+ * Update Coordinates
+ * Update Formats
+ * Update Buffer
+ * Enable Plane
+ */
+ spin_lock_irqsave(&priv->drm->event_lock, flags);
+
+ priv->viu.vd1_if0_gen_reg = VD_URGENT_CHROMA |
@ -728,17 +895,9 @@ index 0000000..ea7261a
+ /* Setup scaler params */
+ meson_overlay_setup_scaler_params(priv, plane, interlace_mode);
+
+ //VD1_IF0_CANVAS1=0
+ //VD1_IF0_CHROMA_X1=0
+ //VD1_IF0_CHROMA_Y1=0
+ priv->viu.vd1_if0_repeat_loop = 0;
+ priv->viu.vd1_if0_luma0_rpt_pat = interlace_mode ? 8 : 0;
+ priv->viu.vd1_if0_chroma0_rpt_pat = interlace_mode ? 8 : 0;
+ //VD1_IF0_LUMA1_RPT_PAT=0
+ //VD1_IF0_CHROMA1_RPT_PAT=0
+ //VD1_IF0_LUMA_PSEL=0
+ //VD1_IF0_CHROMA_PSEL=0
+ //VD1_IF0_DUMMY_PIXEL=?
+ priv->viu.vd1_range_map_y = 0;
+ priv->viu.vd1_range_map_cb = 0;
+ priv->viu.vd1_range_map_cr = 0;
@ -748,15 +907,7 @@ index 0000000..ea7261a
+ priv->viu.viu_vd1_fmt_ctrl = 0;
+
+ switch (fb->format->format) {
+ case DRM_FORMAT_RGB888:
+ /* TOFIX enable RGB2YUV somewhere ! */
+ priv->viu.vd1_if0_gen_reg |= VD_DEMUX_MODE_RGB |
+ VD_BYTES_PER_PIXEL(2);
+ priv->viu.vd1_if0_canvas0 =
+ CANVAS_ADDR2(priv->canvas_id_vd1_0) |
+ CANVAS_ADDR1(priv->canvas_id_vd1_0) |
+ CANVAS_ADDR0(priv->canvas_id_vd1_0);
+ break;
+ /* TOFIX DRM_FORMAT_RGB888 should be supported */
+ case DRM_FORMAT_YUYV:
+ priv->viu.vd1_if0_gen_reg |= VD_BYTES_PER_PIXEL(1);
+ priv->viu.vd1_if0_canvas0 =
@ -854,6 +1005,7 @@ index 0000000..ea7261a
+ priv->viu.vd1_addr2,
+ priv->viu.vd1_stride2,
+ priv->viu.vd1_height2);
+ /* fallthrough */
+ case 2:
+ gem = drm_fb_cma_get_gem_obj(fb, 1);
+ priv->viu.vd1_addr1 = gem->paddr + fb->offsets[1];
@ -865,6 +1017,7 @@ index 0000000..ea7261a
+ priv->viu.vd1_addr1,
+ priv->viu.vd1_stride1,
+ priv->viu.vd1_height1);
+ /* fallthrough */
+ case 1:
+ gem = drm_fb_cma_get_gem_obj(fb, 0);
+ priv->viu.vd1_addr0 = gem->paddr + fb->offsets[0];
@ -917,7 +1070,6 @@ index 0000000..ea7261a
+};
+
+static const uint32_t supported_drm_formats[] = {
+ DRM_FORMAT_RGB888,
+ DRM_FORMAT_YUYV,
+ DRM_FORMAT_NV12,
+ DRM_FORMAT_NV21,
@ -960,11 +1112,11 @@ index 0000000..ea7261a
+}
diff --git a/drivers/gpu/drm/meson/meson_overlay.h b/drivers/gpu/drm/meson/meson_overlay.h
new file mode 100644
index 0000000..0fd63da
index 0000000..dae24f5
--- /dev/null
+++ b/drivers/gpu/drm/meson/meson_overlay.h
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2018 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
@ -1007,10 +1159,10 @@ index bca8714..5c7e02c 100644
#define VPP_FIFO_STATUS 0x1d28
#define VPP_SMOKE_CTRL 0x1d29
diff --git a/drivers/gpu/drm/meson/meson_viu.c b/drivers/gpu/drm/meson/meson_viu.c
index 5b48c4c..a423e7a 100644
index 6bcfa52..2dffb98 100644
--- a/drivers/gpu/drm/meson/meson_viu.c
+++ b/drivers/gpu/drm/meson/meson_viu.c
@@ -328,6 +328,21 @@ void meson_viu_init(struct meson_drm *priv)
@@ -329,6 +329,21 @@ void meson_viu_init(struct meson_drm *priv)
0xff << OSD_REPLACE_SHIFT,
priv->io_base + _REG(VIU_OSD2_CTRL_STAT2));
@ -1104,38 +1256,3 @@ index 27356f8..5dc24a9 100644
+ meson_vpp_write_vd_scaling_filter_coefs(priv, vpp_filter_coefs_bicubic,
+ true);
}
diff --git a/drivers/soc/amlogic/meson-gx-pwrc-vpu.c b/drivers/soc/amlogic/meson-gx-pwrc-vpu.c
index 6289965..05421d0 100644
--- a/drivers/soc/amlogic/meson-gx-pwrc-vpu.c
+++ b/drivers/soc/amlogic/meson-gx-pwrc-vpu.c
@@ -54,12 +54,12 @@ static int meson_gx_pwrc_vpu_power_off(struct generic_pm_domain *genpd)
/* Power Down Memories */
for (i = 0; i < 32; i += 2) {
regmap_update_bits(pd->regmap_hhi, HHI_VPU_MEM_PD_REG0,
- 0x2 << i, 0x3 << i);
+ 0x3 << i, 0x3 << i);
udelay(5);
}
for (i = 0; i < 32; i += 2) {
regmap_update_bits(pd->regmap_hhi, HHI_VPU_MEM_PD_REG1,
- 0x2 << i, 0x3 << i);
+ 0x3 << i, 0x3 << i);
udelay(5);
}
for (i = 8; i < 16; i++) {
@@ -108,13 +108,13 @@ static int meson_gx_pwrc_vpu_power_on(struct generic_pm_domain *genpd)
/* Power Up Memories */
for (i = 0; i < 32; i += 2) {
regmap_update_bits(pd->regmap_hhi, HHI_VPU_MEM_PD_REG0,
- 0x2 << i, 0);
+ 0x3 << i, 0);
udelay(5);
}
for (i = 0; i < 32; i += 2) {
regmap_update_bits(pd->regmap_hhi, HHI_VPU_MEM_PD_REG1,
- 0x2 << i, 0);
+ 0x3 << i, 0);
udelay(5);
}

View File

@ -1,55 +0,0 @@
From c50c3a3d2cb0d563757a8b8b1a3e52acdf68910e Mon Sep 17 00:00:00 2001
From: Maxime Jourdan <maxi.jourdan@wanadoo.fr>
Date: Wed, 1 Aug 2018 20:51:26 +0200
Subject: [PATCH] dt-bindings: soc: amlogic: add meson-canvas documentation
DT bindings doc for amlogic,meson-canvas
Signed-off-by: Maxime Jourdan <maxi.jourdan@wanadoo.fr>
---
.../bindings/soc/amlogic/amlogic,meson-canvas.txt | 36 ++++++++++++++++++++++
1 file changed, 36 insertions(+)
create mode 100644 Documentation/devicetree/bindings/soc/amlogic/amlogic,meson-canvas.txt
diff --git a/Documentation/devicetree/bindings/soc/amlogic/amlogic,meson-canvas.txt b/Documentation/devicetree/bindings/soc/amlogic/amlogic,meson-canvas.txt
new file mode 100644
index 0000000..96e1437
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/amlogic/amlogic,meson-canvas.txt
@@ -0,0 +1,36 @@
+Amlogic Meson 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:
+---------------------
+
+Canvas Provider
+--------------------------
+
+Required properties:
+- compatible: "amlogic,meson-canvas"
+
+Parent node should have the following properties :
+- compatible: "amlogic,meson-gx-dmc-sysctrl", "syscon", "simple-mfd"
+- reg: base address and size of the DMC system control register space.
+
+Example:
+
+sysctrl_DMC: system-controller@0 {
+ compatible = "amlogic,meson-gx-dmc-sysctrl", "syscon", "simple-mfd";
+ reg = <0x0 0x0 0x0 0x1000>;
+
+ canvas: canvas-provider@0 {
+ compatible = "amlogic,meson-canvas";
+ };
+};

View File

@ -1,40 +0,0 @@
From 2c6aee7a14a22d1d042dc7ddafe72c44a4da501f Mon Sep 17 00:00:00 2001
From: Maxime Jourdan <maxi.jourdan@wanadoo.fr>
Date: Wed, 1 Aug 2018 20:51:27 +0200
Subject: [PATCH] ARM64: dts: meson-gx: add dmcbus and canvas nodes.
Wrap the canvas node in a syscon node.
Signed-off-by: Maxime Jourdan <maxi.jourdan@wanadoo.fr>
---
arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
index 6b64b63..25e195f 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
@@ -458,6 +458,23 @@
};
};
+ dmcbus: bus@c8838000 {
+ compatible = "simple-bus";
+ reg = <0x0 0xc8838000 0x0 0x1000>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges = <0x0 0x0 0x0 0xc8838000 0x0 0x1000>;
+
+ sysctrl_DMC: system-controller@0 {
+ compatible = "amlogic,meson-gx-dmc-sysctrl", "syscon", "simple-mfd";
+ reg = <0x0 0x0 0x0 0x1000>;
+
+ canvas: canvas-provider@0 {
+ compatible = "amlogic,meson-canvas";
+ };
+ };
+ };
+
hiubus: bus@c883c000 {
compatible = "simple-bus";
reg = <0x0 0xc883c000 0x0 0x2000>;

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 */

View File

@ -0,0 +1,198 @@
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
update
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 ++++++++
drivers/gpu/drm/meson/meson_plane.c | 39 ++++++++++++++++++++++++++++++-
drivers/gpu/drm/meson/meson_vpp.c | 46 -------------------------------------
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 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)
priv->io_base + _REG(VIU_OSD1_BLK0_CFG_W3));
writel_relaxed(priv->viu.osd1_blk0_cfg[4],
priv->io_base + _REG(VIU_OSD1_BLK0_CFG_W4));
-
- /* If output is interlace, make use of the Scaler */
- if (priv->viu.osd1_interlace) {
- struct drm_plane *plane = priv->primary_plane;
- struct drm_plane_state *state = plane->state;
- struct drm_rect dest = {
- .x1 = state->crtc_x,
- .y1 = state->crtc_y,
- .x2 = state->crtc_x + state->crtc_w,
- .y2 = state->crtc_y + state->crtc_h,
- };
-
- meson_vpp_setup_interlace_vscaler_osd1(priv, &dest);
- } else
- meson_vpp_disable_interlace_vscaler_osd1(priv);
+ writel_relaxed(priv->viu.osd_sc_ctrl0,
+ priv->io_base + _REG(VPP_OSD_SC_CTRL0));
+ writel_relaxed(priv->viu.osd_sc_i_wh_m1,
+ priv->io_base + _REG(VPP_OSD_SCI_WH_M1));
+ writel_relaxed(priv->viu.osd_sc_o_h_start_end,
+ priv->io_base + _REG(VPP_OSD_SCO_H_START_END));
+ writel_relaxed(priv->viu.osd_sc_o_v_start_end,
+ priv->io_base + _REG(VPP_OSD_SCO_V_START_END));
+ writel_relaxed(priv->viu.osd_sc_v_ini_phase,
+ priv->io_base + _REG(VPP_OSD_VSC_INI_PHASE));
+ writel_relaxed(priv->viu.osd_sc_v_phase_step,
+ priv->io_base + _REG(VPP_OSD_VSC_PHASE_STEP));
+ writel_relaxed(priv->viu.osd_sc_h_ini_phase,
+ priv->io_base + _REG(VPP_OSD_HSC_INI_PHASE));
+ writel_relaxed(priv->viu.osd_sc_h_phase_step,
+ priv->io_base + _REG(VPP_OSD_HSC_PHASE_STEP));
+ writel_relaxed(priv->viu.osd_sc_h_ctrl0,
+ priv->io_base + _REG(VPP_OSD_HSC_CTRL0));
+ writel_relaxed(priv->viu.osd_sc_v_ctrl0,
+ priv->io_base + _REG(VPP_OSD_VSC_CTRL0));
if (priv->canvas)
meson_canvas_config(priv->canvas, priv->canvas_id_osd1,
diff --git a/drivers/gpu/drm/meson/meson_drv.h b/drivers/gpu/drm/meson/meson_drv.h
index c971557..a955354 100644
--- a/drivers/gpu/drm/meson/meson_drv.h
+++ b/drivers/gpu/drm/meson/meson_drv.h
@@ -54,6 +54,16 @@ struct meson_drm {
uint32_t osd1_addr;
uint32_t osd1_stride;
uint32_t osd1_height;
+ uint32_t osd_sc_ctrl0;
+ uint32_t osd_sc_i_wh_m1;
+ uint32_t osd_sc_o_h_start_end;
+ uint32_t osd_sc_o_v_start_end;
+ uint32_t osd_sc_v_ini_phase;
+ uint32_t osd_sc_v_phase_step;
+ uint32_t osd_sc_h_ini_phase;
+ uint32_t osd_sc_h_phase_step;
+ uint32_t osd_sc_h_ctrl0;
+ uint32_t osd_sc_v_ctrl0;
bool vd1_enabled;
bool vd1_commit;
diff --git a/drivers/gpu/drm/meson/meson_plane.c b/drivers/gpu/drm/meson/meson_plane.c
index 51bec8e..f915a79 100644
--- a/drivers/gpu/drm/meson/meson_plane.c
+++ b/drivers/gpu/drm/meson/meson_plane.c
@@ -143,13 +143,50 @@ static void meson_plane_atomic_update(struct drm_plane *plane,
break;
};
+ /*
+ * When the output is interlaced, the OSD must switch between
+ * each field using the INTERLACE_SEL_ODD (0) of VIU_OSD1_BLK0_CFG_W0
+ * at each vsync.
+ * But the vertical scaler can provide such funtionnality if
+ * is configured for 2:1 scaling with interlace options enabled.
+ */
if (state->crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) {
priv->viu.osd1_interlace = true;
dest.y1 /= 2;
dest.y2 /= 2;
- } else
+
+ priv->viu.osd_sc_ctrl0 = BIT(3)| /* Enable scaler */
+ BIT(2); /* Select OSD1 */
+
+ /* 2:1 scaling */
+ priv->viu.osd_sc_i_wh_m1 = ((drm_rect_width(&dest) - 1) << 16) |
+ (drm_rect_height(&dest) - 1);
+ priv->viu.osd_sc_o_h_start_end = (dest.x1 << 16) | dest.x2;
+ priv->viu.osd_sc_o_v_start_end = (dest.y1 << 16) | dest.y2;
+
+ /* 2:1 vertical scaling values */
+ priv->viu.osd_sc_v_ini_phase = BIT(16);
+ priv->viu.osd_sc_v_phase_step = BIT(25);
+ priv->viu.osd_sc_v_ctrl0 =
+ (4 << 0) | /* osd_vsc_bank_length */
+ (4 << 3) | /* osd_vsc_top_ini_rcv_num0 */
+ (1 << 8) | /* osd_vsc_top_rpt_p0_num0 */
+ (6 << 11) | /* osd_vsc_bot_ini_rcv_num0 */
+ (2 << 16) | /* osd_vsc_bot_rpt_p0_num0 */
+ BIT(23) | /* osd_prog_interlace */
+ BIT(24); /* Enable vertical scaler */
+
+ /* No horizontal scaling */
+ priv->viu.osd_sc_h_ini_phase = 0;
+ priv->viu.osd_sc_h_phase_step = 0;
+ priv->viu.osd_sc_h_ctrl0 = 0;
+ } else {
priv->viu.osd1_interlace = false;
+ priv->viu.osd_sc_ctrl0 = 0;
+ priv->viu.osd_sc_h_ctrl0 = 0;
+ priv->viu.osd_sc_v_ctrl0 = 0;
+ }
/*
* The format of these registers is (x2 << 16 | x1),
diff --git a/drivers/gpu/drm/meson/meson_vpp.c b/drivers/gpu/drm/meson/meson_vpp.c
index 5dc24a9..f9efb43 100644
--- a/drivers/gpu/drm/meson/meson_vpp.c
+++ b/drivers/gpu/drm/meson/meson_vpp.c
@@ -51,52 +51,6 @@ void meson_vpp_setup_mux(struct meson_drm *priv, unsigned int mux)
writel(mux, priv->io_base + _REG(VPU_VIU_VENC_MUX_CTRL));
}
-/*
- * When the output is interlaced, the OSD must switch between
- * each field using the INTERLACE_SEL_ODD (0) of VIU_OSD1_BLK0_CFG_W0
- * at each vsync.
- * But the vertical scaler can provide such funtionnality if
- * is configured for 2:1 scaling with interlace options enabled.
- */
-void meson_vpp_setup_interlace_vscaler_osd1(struct meson_drm *priv,
- struct drm_rect *input)
-{
- writel_relaxed(BIT(3) /* Enable scaler */ |
- BIT(2), /* Select OSD1 */
- priv->io_base + _REG(VPP_OSD_SC_CTRL0));
-
- writel_relaxed(((drm_rect_width(input) - 1) << 16) |
- (drm_rect_height(input) - 1),
- priv->io_base + _REG(VPP_OSD_SCI_WH_M1));
- /* 2:1 scaling */
- writel_relaxed(((input->x1) << 16) | (input->x2),
- priv->io_base + _REG(VPP_OSD_SCO_H_START_END));
- writel_relaxed(((input->y1 >> 1) << 16) | (input->y2 >> 1),
- priv->io_base + _REG(VPP_OSD_SCO_V_START_END));
-
- /* 2:1 scaling values */
- writel_relaxed(BIT(16), priv->io_base + _REG(VPP_OSD_VSC_INI_PHASE));
- writel_relaxed(BIT(25), priv->io_base + _REG(VPP_OSD_VSC_PHASE_STEP));
-
- writel_relaxed(0, priv->io_base + _REG(VPP_OSD_HSC_CTRL0));
-
- writel_relaxed((4 << 0) /* osd_vsc_bank_length */ |
- (4 << 3) /* osd_vsc_top_ini_rcv_num0 */ |
- (1 << 8) /* osd_vsc_top_rpt_p0_num0 */ |
- (6 << 11) /* osd_vsc_bot_ini_rcv_num0 */ |
- (2 << 16) /* osd_vsc_bot_rpt_p0_num0 */ |
- BIT(23) /* osd_prog_interlace */ |
- BIT(24), /* Enable vertical scaler */
- priv->io_base + _REG(VPP_OSD_VSC_CTRL0));
-}
-
-void meson_vpp_disable_interlace_vscaler_osd1(struct meson_drm *priv)
-{
- writel_relaxed(0, priv->io_base + _REG(VPP_OSD_SC_CTRL0));
- writel_relaxed(0, priv->io_base + _REG(VPP_OSD_VSC_CTRL0));
- writel_relaxed(0, priv->io_base + _REG(VPP_OSD_HSC_CTRL0));
-}
-
static unsigned int vpp_filter_coefs_4point_bspline[] = {
0x15561500, 0x14561600, 0x13561700, 0x12561800,
0x11551a00, 0x11541b00, 0x10541c00, 0x0f541d00,

View File

@ -0,0 +1,285 @@
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
This patch adds support for the Primary Plane scaling.
On the Amlogic GX SoCs, the primary plane is used as On-Screen-Display
layer on top of video, and it's needed to keep the OSD layer to a lower
size as the physical display size to :
- lower the memory bandwidth
- lower the OSD rendering
- lower the memory usage
This use-case is used when setting the display mode to 3840x2160 and the
OSD layer is rendered using the GPU. In this case, the GXBB & GXL cannot
work on more than 2000x2000 buffer, thus needing the OSD layer to be kept
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(-)
diff --git a/drivers/gpu/drm/meson/meson_plane.c b/drivers/gpu/drm/meson/meson_plane.c
index f915a79..12a47b4 100644
--- a/drivers/gpu/drm/meson/meson_plane.c
+++ b/drivers/gpu/drm/meson/meson_plane.c
@@ -24,6 +24,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mutex.h>
+#include <linux/bitfield.h>
#include <linux/platform_device.h>
#include <drm/drmP.h>
#include <drm/drm_atomic.h>
@@ -39,12 +40,50 @@
#include "meson_canvas.h"
#include "meson_registers.h"
+/* OSD_SCI_WH_M1 */
+#define SCI_WH_M1_W(w) FIELD_PREP(GENMASK(28, 16), w)
+#define SCI_WH_M1_H(h) FIELD_PREP(GENMASK(12, 0), h)
+
+/* OSD_SCO_H_START_END */
+/* OSD_SCO_V_START_END */
+#define SCO_HV_START(start) FIELD_PREP(GENMASK(27, 16), start)
+#define SCO_HV_END(end) FIELD_PREP(GENMASK(11, 0), end)
+
+/* OSD_SC_CTRL0 */
+#define SC_CTRL0_PATH_EN BIT(3)
+#define SC_CTRL0_SEL_OSD1 BIT(2)
+
+/* OSD_VSC_CTRL0 */
+#define VSC_BANK_LEN(value) FIELD_PREP(GENMASK(2, 0), value)
+#define VSC_TOP_INI_RCV_NUM(value) FIELD_PREP(GENMASK(6, 3), value)
+#define VSC_TOP_RPT_L0_NUM(value) FIELD_PREP(GENMASK(9, 8), value)
+#define VSC_BOT_INI_RCV_NUM(value) FIELD_PREP(GENMASK(14, 11), value)
+#define VSC_BOT_RPT_L0_NUM(value) FIELD_PREP(GENMASK(17, 16), value)
+#define VSC_PROG_INTERLACE BIT(23)
+#define VSC_VERTICAL_SCALER_EN BIT(24)
+
+/* OSD_VSC_INI_PHASE */
+#define VSC_INI_PHASE_BOT(bottom) FIELD_PREP(GENMASK(31, 16), bottom)
+#define VSC_INI_PHASE_TOP(top) FIELD_PREP(GENMASK(15, 0), top)
+
+/* OSD_HSC_CTRL0 */
+#define HSC_BANK_LENGTH(value) FIELD_PREP(GENMASK(2, 0), value)
+#define HSC_INI_RCV_NUM0(value) FIELD_PREP(GENMASK(6, 3), value)
+#define HSC_RPT_P0_NUM0(value) FIELD_PREP(GENMASK(9, 8), value)
+#define HSC_HORIZ_SCALER_EN BIT(22)
+
+/* VPP_OSD_VSC_PHASE_STEP */
+/* VPP_OSD_HSC_PHASE_STEP */
+#define SC_PHASE_STEP(value) FIELD_PREP(GENMASK(27, 0), value)
+
struct meson_plane {
struct drm_plane base;
struct meson_drm *priv;
};
#define to_meson_plane(x) container_of(x, struct meson_plane, base)
+#define FRAC_16_16(mult, div) (((mult) << 16) / (div))
+
static int meson_plane_atomic_check(struct drm_plane *plane,
struct drm_plane_state *state)
{
@@ -57,10 +96,15 @@ static int meson_plane_atomic_check(struct drm_plane *plane,
if (IS_ERR(crtc_state))
return PTR_ERR(crtc_state);
+ /*
+ * Only allow :
+ * - Upscaling up to 5x, vertical and horizontal
+ * - Final coordinates must match crtc size
+ */
return drm_atomic_helper_check_plane_state(state, crtc_state,
+ FRAC_16_16(1, 5),
DRM_PLANE_HELPER_NO_SCALING,
- DRM_PLANE_HELPER_NO_SCALING,
- true, true);
+ false, true);
}
/* Takes a fixed 16.16 number and converts it to integer. */
@@ -74,22 +118,19 @@ static void meson_plane_atomic_update(struct drm_plane *plane,
{
struct meson_plane *meson_plane = to_meson_plane(plane);
struct drm_plane_state *state = plane->state;
- struct drm_framebuffer *fb = state->fb;
+ struct drm_rect dest = drm_plane_state_dest(state);
struct meson_drm *priv = meson_plane->priv;
+ struct drm_framebuffer *fb = state->fb;
struct drm_gem_cma_object *gem;
- struct drm_rect src = {
- .x1 = (state->src_x),
- .y1 = (state->src_y),
- .x2 = (state->src_x + state->src_w),
- .y2 = (state->src_y + state->src_h),
- };
- struct drm_rect dest = {
- .x1 = state->crtc_x,
- .y1 = state->crtc_y,
- .x2 = state->crtc_x + state->crtc_w,
- .y2 = state->crtc_y + state->crtc_h,
- };
unsigned long flags;
+ int vsc_ini_rcv_num, vsc_ini_rpt_p0_num;
+ int vsc_bot_rcv_num, vsc_bot_rpt_p0_num;
+ int hsc_ini_rcv_num, hsc_ini_rpt_p0_num;
+ int hf_phase_step, vf_phase_step;
+ int src_w, src_h, dst_w, dst_h;
+ int bot_ini_phase;
+ int hf_bank_len;
+ int vf_bank_len;
u8 canvas_id_osd1;
/*
@@ -143,6 +184,27 @@ static void meson_plane_atomic_update(struct drm_plane *plane,
break;
};
+ /* Default scaler parameters */
+ vsc_bot_rcv_num = 0;
+ vsc_bot_rpt_p0_num = 0;
+ hf_bank_len = 4;
+ vf_bank_len = 4;
+
+ if (state->crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) {
+ vsc_bot_rcv_num = 6;
+ vsc_bot_rpt_p0_num = 2;
+ }
+
+ hsc_ini_rcv_num = hf_bank_len;
+ vsc_ini_rcv_num = vf_bank_len;
+ hsc_ini_rpt_p0_num = (hf_bank_len / 2) - 1;
+ vsc_ini_rpt_p0_num = (vf_bank_len / 2) - 1;
+
+ src_w = fixed16_to_int(state->src_w);
+ src_h = fixed16_to_int(state->src_h);
+ dst_w = state->crtc_w;
+ dst_h = state->crtc_h;
+
/*
* When the output is interlaced, the OSD must switch between
* each field using the INTERLACE_SEL_ODD (0) of VIU_OSD1_BLK0_CFG_W0
@@ -151,41 +213,73 @@ static void meson_plane_atomic_update(struct drm_plane *plane,
* is configured for 2:1 scaling with interlace options enabled.
*/
if (state->crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) {
- priv->viu.osd1_interlace = true;
-
dest.y1 /= 2;
dest.y2 /= 2;
+ dst_h /= 2;
+ }
- priv->viu.osd_sc_ctrl0 = BIT(3)| /* Enable scaler */
- BIT(2); /* Select OSD1 */
+ hf_phase_step = ((src_w << 18) / dst_w) << 6;
+ vf_phase_step = (src_h << 20) / dst_h;
- /* 2:1 scaling */
- priv->viu.osd_sc_i_wh_m1 = ((drm_rect_width(&dest) - 1) << 16) |
- (drm_rect_height(&dest) - 1);
- priv->viu.osd_sc_o_h_start_end = (dest.x1 << 16) | dest.x2;
- priv->viu.osd_sc_o_v_start_end = (dest.y1 << 16) | dest.y2;
+ if (state->crtc->mode.flags & DRM_MODE_FLAG_INTERLACE)
+ bot_ini_phase = ((vf_phase_step / 2) >> 4);
+ else
+ bot_ini_phase = 0;
+
+ vf_phase_step = (vf_phase_step << 4);
+
+ /* In interlaced mode, scaler is always active */
+ if (src_h != dst_h || src_w != dst_w) {
+ priv->viu.osd_sc_i_wh_m1 = SCI_WH_M1_W(src_w - 1) |
+ SCI_WH_M1_H(src_h - 1);
+ priv->viu.osd_sc_o_h_start_end = SCO_HV_START(dest.x1) |
+ SCO_HV_END(dest.x2 - 1);
+ priv->viu.osd_sc_o_v_start_end = SCO_HV_START(dest.y1) |
+ SCO_HV_END(dest.y2 - 1);
+ /* Enable OSD Scaler */
+ priv->viu.osd_sc_ctrl0 = SC_CTRL0_PATH_EN | SC_CTRL0_SEL_OSD1;
+ } else {
+ priv->viu.osd_sc_i_wh_m1 = 0;
+ priv->viu.osd_sc_o_h_start_end = 0;
+ priv->viu.osd_sc_o_v_start_end = 0;
+ priv->viu.osd_sc_ctrl0 = 0;
+ }
- /* 2:1 vertical scaling values */
- priv->viu.osd_sc_v_ini_phase = BIT(16);
- priv->viu.osd_sc_v_phase_step = BIT(25);
+ /* In interlaced mode, vertical scaler is always active */
+ if (src_h != dst_h) {
priv->viu.osd_sc_v_ctrl0 =
- (4 << 0) | /* osd_vsc_bank_length */
- (4 << 3) | /* osd_vsc_top_ini_rcv_num0 */
- (1 << 8) | /* osd_vsc_top_rpt_p0_num0 */
- (6 << 11) | /* osd_vsc_bot_ini_rcv_num0 */
- (2 << 16) | /* osd_vsc_bot_rpt_p0_num0 */
- BIT(23) | /* osd_prog_interlace */
- BIT(24); /* Enable vertical scaler */
-
- /* No horizontal scaling */
+ VSC_BANK_LEN(vf_bank_len) |
+ VSC_TOP_INI_RCV_NUM(vsc_ini_rcv_num) |
+ VSC_TOP_RPT_L0_NUM(vsc_ini_rpt_p0_num) |
+ VSC_VERTICAL_SCALER_EN;
+
+ if (state->crtc->mode.flags & DRM_MODE_FLAG_INTERLACE)
+ priv->viu.osd_sc_v_ctrl0 |=
+ VSC_BOT_INI_RCV_NUM(vsc_bot_rcv_num) |
+ VSC_BOT_RPT_L0_NUM(vsc_bot_rpt_p0_num) |
+ VSC_PROG_INTERLACE;
+
+ priv->viu.osd_sc_v_phase_step = SC_PHASE_STEP(vf_phase_step);
+ priv->viu.osd_sc_v_ini_phase = VSC_INI_PHASE_BOT(bot_ini_phase);
+ } else {
+ priv->viu.osd_sc_v_ctrl0 = 0;
+ priv->viu.osd_sc_v_phase_step = 0;
+ priv->viu.osd_sc_v_ini_phase = 0;
+ }
+
+ /* Horizontal scaler is only used if width does not match */
+ if (src_w != dst_w) {
+ priv->viu.osd_sc_h_ctrl0 =
+ HSC_BANK_LENGTH(hf_bank_len) |
+ HSC_INI_RCV_NUM0(hsc_ini_rcv_num) |
+ HSC_RPT_P0_NUM0(hsc_ini_rpt_p0_num) |
+ HSC_HORIZ_SCALER_EN;
+ priv->viu.osd_sc_h_phase_step = SC_PHASE_STEP(hf_phase_step);
priv->viu.osd_sc_h_ini_phase = 0;
- priv->viu.osd_sc_h_phase_step = 0;
- priv->viu.osd_sc_h_ctrl0 = 0;
} else {
- priv->viu.osd1_interlace = false;
- priv->viu.osd_sc_ctrl0 = 0;
priv->viu.osd_sc_h_ctrl0 = 0;
- priv->viu.osd_sc_v_ctrl0 = 0;
+ priv->viu.osd_sc_h_phase_step = 0;
+ priv->viu.osd_sc_h_ini_phase = 0;
}
/*
@@ -193,10 +287,12 @@ static void meson_plane_atomic_update(struct drm_plane *plane,
* where x2 is exclusive.
* e.g. +30x1920 would be (1919 << 16) | 30
*/
- priv->viu.osd1_blk0_cfg[1] = ((fixed16_to_int(src.x2) - 1) << 16) |
- fixed16_to_int(src.x1);
- priv->viu.osd1_blk0_cfg[2] = ((fixed16_to_int(src.y2) - 1) << 16) |
- fixed16_to_int(src.y1);
+ priv->viu.osd1_blk0_cfg[1] =
+ ((fixed16_to_int(state->src.x2) - 1) << 16) |
+ fixed16_to_int(state->src.x1);
+ priv->viu.osd1_blk0_cfg[2] =
+ ((fixed16_to_int(state->src.y2) - 1) << 16) |
+ fixed16_to_int(state->src.y1);
priv->viu.osd1_blk0_cfg[3] = ((dest.x2 - 1) << 16) | dest.x1;
priv->viu.osd1_blk0_cfg[4] = ((dest.y2 - 1) << 16) | dest.y1;

View File

@ -1,399 +0,0 @@
From c71ba17b0625595a2c0268cb76b7032694550fb3 Mon Sep 17 00:00:00 2001
From: Maxime Jourdan <maxi.jourdan@wanadoo.fr>
Date: Wed, 1 Aug 2018 20:51:28 +0200
Subject: [PATCH] drm/meson: convert to the new canvas module
This removes the meson_canvas files within the meson/drm layer
and makes use of the new canvas module that is referenced in the dts.
Canvases can be used by different IPs and modules, and it is as such
preferable to rely on a module that can safely dispatch canvases on
demand.
Signed-off-by: Maxime Jourdan <maxi.jourdan@wanadoo.fr>
---
.../bindings/display/amlogic,meson-vpu.txt | 9 +--
arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 7 ++-
drivers/gpu/drm/meson/Kconfig | 1 +
drivers/gpu/drm/meson/Makefile | 2 +-
drivers/gpu/drm/meson/meson_canvas.c | 70 ----------------------
drivers/gpu/drm/meson/meson_canvas.h | 42 -------------
drivers/gpu/drm/meson/meson_crtc.c | 5 +-
drivers/gpu/drm/meson/meson_drv.c | 35 ++++++-----
drivers/gpu/drm/meson/meson_drv.h | 5 +-
drivers/gpu/drm/meson/meson_plane.c | 3 +-
drivers/gpu/drm/meson/meson_viu.c | 1 -
11 files changed, 39 insertions(+), 141 deletions(-)
delete mode 100644 drivers/gpu/drm/meson/meson_canvas.c
delete mode 100644 drivers/gpu/drm/meson/meson_canvas.h
diff --git a/Documentation/devicetree/bindings/display/amlogic,meson-vpu.txt b/Documentation/devicetree/bindings/display/amlogic,meson-vpu.txt
index 057b813..60b6e13 100644
--- a/Documentation/devicetree/bindings/display/amlogic,meson-vpu.txt
+++ b/Documentation/devicetree/bindings/display/amlogic,meson-vpu.txt
@@ -60,9 +60,9 @@ Required properties:
- reg: base address and size of he following memory-mapped regions :
- vpu
- hhi
- - dmc
- reg-names: should contain the names of the previous memory regions
- interrupts: should contain the VENC Vsync interrupt number
+- amlogic,canvas: should point to a meson canvas provider node
Optional properties:
- power-domains: Optional phandle to associated power domain as described in
@@ -98,13 +98,14 @@ tv-connector {
vpu: vpu@d0100000 {
compatible = "amlogic,meson-gxbb-vpu";
reg = <0x0 0xd0100000 0x0 0x100000>,
- <0x0 0xc883c000 0x0 0x1000>,
- <0x0 0xc8838000 0x0 0x1000>;
- reg-names = "vpu", "hhi", "dmc";
+ <0x0 0xc883c000 0x0 0x1000>;
+ reg-names = "vpu", "hhi";
interrupts = <GIC_SPI 3 IRQ_TYPE_EDGE_RISING>;
#address-cells = <1>;
#size-cells = <0>;
+ amlogic,canvas = <&canvas>;
+
/* CVBS VDAC output port */
port@0 {
reg = <0>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
index 25e195f..7296b4f 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
@@ -538,13 +538,14 @@
vpu: vpu@d0100000 {
compatible = "amlogic,meson-gx-vpu";
reg = <0x0 0xd0100000 0x0 0x100000>,
- <0x0 0xc883c000 0x0 0x1000>,
- <0x0 0xc8838000 0x0 0x1000>;
- reg-names = "vpu", "hhi", "dmc";
+ <0x0 0xc883c000 0x0 0x1000>;
+ reg-names = "vpu", "hhi";
interrupts = <GIC_SPI 3 IRQ_TYPE_EDGE_RISING>;
#address-cells = <1>;
#size-cells = <0>;
+ amlogic,canvas = <&canvas>;
+
/* CVBS VDAC output port */
cvbs_vdac_port: port@0 {
reg = <0>;
diff --git a/drivers/gpu/drm/meson/Kconfig b/drivers/gpu/drm/meson/Kconfig
index 02d400b..8929058 100644
--- a/drivers/gpu/drm/meson/Kconfig
+++ b/drivers/gpu/drm/meson/Kconfig
@@ -7,6 +7,7 @@ config DRM_MESON
select DRM_GEM_CMA_HELPER
select VIDEOMODE_HELPERS
select REGMAP_MMIO
+ select MESON_CANVAS
config DRM_MESON_DW_HDMI
tristate "HDMI Synopsys Controller support for Amlogic Meson Display"
diff --git a/drivers/gpu/drm/meson/Makefile b/drivers/gpu/drm/meson/Makefile
index c5c4cc3..bd67429 100644
--- a/drivers/gpu/drm/meson/Makefile
+++ b/drivers/gpu/drm/meson/Makefile
@@ -1,5 +1,5 @@
meson-drm-y := meson_drv.o meson_plane.o meson_crtc.o meson_venc_cvbs.o
-meson-drm-y += meson_viu.o meson_vpp.o meson_venc.o meson_vclk.o meson_canvas.o
+meson-drm-y += meson_viu.o meson_vpp.o meson_venc.o meson_vclk.o
obj-$(CONFIG_DRM_MESON) += meson-drm.o
obj-$(CONFIG_DRM_MESON_DW_HDMI) += meson_dw_hdmi.o
diff --git a/drivers/gpu/drm/meson/meson_canvas.c b/drivers/gpu/drm/meson/meson_canvas.c
deleted file mode 100644
index 08f6073..0000000
--- a/drivers/gpu/drm/meson/meson_canvas.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2016 BayLibre, SAS
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
- * Copyright (C) 2014 Endless Mobile
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include "meson_drv.h"
-#include "meson_canvas.h"
-#include "meson_registers.h"
-
-/**
- * DOC: Canvas
- *
- * CANVAS is a memory zone where physical memory frames information
- * are stored for the VIU to scanout.
- */
-
-/* DMC Registers */
-#define DMC_CAV_LUT_DATAL 0x48 /* 0x12 offset in data sheet */
-#define CANVAS_WIDTH_LBIT 29
-#define CANVAS_WIDTH_LWID 3
-#define DMC_CAV_LUT_DATAH 0x4c /* 0x13 offset in data sheet */
-#define CANVAS_WIDTH_HBIT 0
-#define CANVAS_HEIGHT_BIT 9
-#define CANVAS_BLKMODE_BIT 24
-#define DMC_CAV_LUT_ADDR 0x50 /* 0x14 offset in data sheet */
-#define CANVAS_LUT_WR_EN (0x2 << 8)
-#define CANVAS_LUT_RD_EN (0x1 << 8)
-
-void meson_canvas_setup(struct meson_drm *priv,
- uint32_t canvas_index, uint32_t addr,
- uint32_t stride, uint32_t height,
- unsigned int wrap,
- unsigned int blkmode)
-{
- unsigned int val;
-
- regmap_write(priv->dmc, DMC_CAV_LUT_DATAL,
- (((addr + 7) >> 3)) |
- (((stride + 7) >> 3) << CANVAS_WIDTH_LBIT));
-
- regmap_write(priv->dmc, DMC_CAV_LUT_DATAH,
- ((((stride + 7) >> 3) >> CANVAS_WIDTH_LWID) <<
- CANVAS_WIDTH_HBIT) |
- (height << CANVAS_HEIGHT_BIT) |
- (wrap << 22) |
- (blkmode << CANVAS_BLKMODE_BIT));
-
- regmap_write(priv->dmc, DMC_CAV_LUT_ADDR,
- CANVAS_LUT_WR_EN | canvas_index);
-
- /* Force a read-back to make sure everything is flushed. */
- regmap_read(priv->dmc, DMC_CAV_LUT_DATAH, &val);
-}
diff --git a/drivers/gpu/drm/meson/meson_canvas.h b/drivers/gpu/drm/meson/meson_canvas.h
deleted file mode 100644
index af1759d..0000000
--- a/drivers/gpu/drm/meson/meson_canvas.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2016 BayLibre, SAS
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- * Copyright (C) 2014 Endless Mobile
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-/* Canvas LUT Memory */
-
-#ifndef __MESON_CANVAS_H
-#define __MESON_CANVAS_H
-
-#define MESON_CANVAS_ID_OSD1 0x4e
-
-/* Canvas configuration. */
-#define MESON_CANVAS_WRAP_NONE 0x00
-#define MESON_CANVAS_WRAP_X 0x01
-#define MESON_CANVAS_WRAP_Y 0x02
-
-#define MESON_CANVAS_BLKMODE_LINEAR 0x00
-#define MESON_CANVAS_BLKMODE_32x32 0x01
-#define MESON_CANVAS_BLKMODE_64x64 0x02
-
-void meson_canvas_setup(struct meson_drm *priv,
- uint32_t canvas_index, uint32_t addr,
- uint32_t stride, uint32_t height,
- unsigned int wrap,
- unsigned int blkmode);
-
-#endif /* __MESON_CANVAS_H */
diff --git a/drivers/gpu/drm/meson/meson_crtc.c b/drivers/gpu/drm/meson/meson_crtc.c
index 4dd0df0..7c8ad06 100644
--- a/drivers/gpu/drm/meson/meson_crtc.c
+++ b/drivers/gpu/drm/meson/meson_crtc.c
@@ -36,7 +36,6 @@
#include "meson_venc.h"
#include "meson_vpp.h"
#include "meson_viu.h"
-#include "meson_canvas.h"
#include "meson_registers.h"
/* CRTC definition */
@@ -199,10 +198,10 @@ void meson_crtc_irq(struct meson_drm *priv)
} else
meson_vpp_disable_interlace_vscaler_osd1(priv);
- meson_canvas_setup(priv, MESON_CANVAS_ID_OSD1,
+ priv->canvas_ops->setup(priv->canvas_id_osd1,
priv->viu.osd1_addr, priv->viu.osd1_stride,
priv->viu.osd1_height, MESON_CANVAS_WRAP_NONE,
- MESON_CANVAS_BLKMODE_LINEAR);
+ MESON_CANVAS_BLKMODE_LINEAR, 0);
/* Enable OSD1 */
writel_bits_relaxed(VPP_OSD1_POSTBLEND, VPP_OSD1_POSTBLEND,
diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
index d344312..de46833 100644
--- a/drivers/gpu/drm/meson/meson_drv.c
+++ b/drivers/gpu/drm/meson/meson_drv.c
@@ -26,6 +26,7 @@
#include <linux/platform_device.h>
#include <linux/component.h>
#include <linux/of_graph.h>
+#include <linux/of_platform.h>
#include <drm/drmP.h>
#include <drm/drm_atomic.h>
@@ -47,7 +48,6 @@
#include "meson_vpp.h"
#include "meson_viu.h"
#include "meson_venc.h"
-#include "meson_canvas.h"
#include "meson_registers.h"
#define DRIVER_NAME "meson"
@@ -165,6 +165,8 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
struct meson_drm *priv;
struct drm_device *drm;
struct resource *res;
+ struct device_node *canvas;
+ struct platform_device *canvas_pdev;
void __iomem *regs;
int ret;
@@ -211,31 +213,35 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
priv->hhi = devm_regmap_init_mmio(dev, regs,
&meson_regmap_config);
if (IS_ERR(priv->hhi)) {
- dev_err(&pdev->dev, "Couldn't create the HHI regmap\n");
+ dev_err(dev, "Couldn't create the HHI regmap\n");
ret = PTR_ERR(priv->hhi);
goto free_drm;
}
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dmc");
- if (!res) {
- ret = -EINVAL;
+ canvas = of_parse_phandle(dev->of_node, "amlogic,canvas", 0);
+ if (!canvas) {
+ ret = -ENODEV;
goto free_drm;
}
- /* Simply ioremap since it may be a shared register zone */
- regs = devm_ioremap(dev, res->start, resource_size(res));
- if (!regs) {
- ret = -EADDRNOTAVAIL;
+
+ canvas_pdev = of_find_device_by_node(canvas);
+ if (!canvas_pdev) {
+ dev_err(dev, "Unable to find canvas pdev\n");
+ ret = -ENODEV;
goto free_drm;
}
- priv->dmc = devm_regmap_init_mmio(dev, regs,
- &meson_regmap_config);
- if (IS_ERR(priv->dmc)) {
- dev_err(&pdev->dev, "Couldn't create the DMC regmap\n");
- ret = PTR_ERR(priv->dmc);
+ priv->canvas_ops = dev_get_platdata(&canvas_pdev->dev);
+ if (!priv->canvas_ops) {
+ dev_err(dev, "canvas pdata structure NULL\n");
+ ret = -EINVAL;
goto free_drm;
}
+ ret = priv->canvas_ops->alloc(&priv->canvas_id_osd1);
+ if (ret)
+ goto free_drm;
+
priv->vsync_irq = platform_get_irq(pdev, 0);
ret = drm_vblank_init(drm, 1);
@@ -315,6 +321,7 @@ static void meson_drv_unbind(struct device *dev)
struct drm_device *drm = dev_get_drvdata(dev);
struct meson_drm *priv = drm->dev_private;
+ priv->canvas_ops->free(priv->canvas_id_osd1);
drm_dev_unregister(drm);
drm_kms_helper_poll_fini(drm);
drm_fbdev_cma_fini(priv->fbdev);
diff --git a/drivers/gpu/drm/meson/meson_drv.h b/drivers/gpu/drm/meson/meson_drv.h
index 8450d6ac..dfea959 100644
--- a/drivers/gpu/drm/meson/meson_drv.h
+++ b/drivers/gpu/drm/meson/meson_drv.h
@@ -22,15 +22,18 @@
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/of.h>
+#include <linux/soc/amlogic/meson-canvas.h>
#include <drm/drmP.h>
struct meson_drm {
struct device *dev;
void __iomem *io_base;
struct regmap *hhi;
- struct regmap *dmc;
int vsync_irq;
+ struct meson_canvas_platform_data *canvas_ops;
+ uint8_t canvas_id_osd1;
+
struct drm_device *drm;
struct drm_crtc *crtc;
struct drm_fbdev_cma *fbdev;
diff --git a/drivers/gpu/drm/meson/meson_plane.c b/drivers/gpu/drm/meson/meson_plane.c
index 12c80df..8745f92 100644
--- a/drivers/gpu/drm/meson/meson_plane.c
+++ b/drivers/gpu/drm/meson/meson_plane.c
@@ -36,7 +36,6 @@
#include "meson_plane.h"
#include "meson_vpp.h"
#include "meson_viu.h"
-#include "meson_canvas.h"
#include "meson_registers.h"
struct meson_plane {
@@ -105,7 +104,7 @@ static void meson_plane_atomic_update(struct drm_plane *plane,
OSD_BLK0_ENABLE;
/* Set up BLK0 to point to the right canvas */
- priv->viu.osd1_blk0_cfg[0] = ((MESON_CANVAS_ID_OSD1 << OSD_CANVAS_SEL) |
+ priv->viu.osd1_blk0_cfg[0] = ((priv->canvas_id_osd1 << OSD_CANVAS_SEL) |
OSD_ENDIANNESS_LE);
/* On GXBB, Use the old non-HDR RGB2YUV converter */
diff --git a/drivers/gpu/drm/meson/meson_viu.c b/drivers/gpu/drm/meson/meson_viu.c
index 6bcfa52..5b48c4c 100644
--- a/drivers/gpu/drm/meson/meson_viu.c
+++ b/drivers/gpu/drm/meson/meson_viu.c
@@ -25,7 +25,6 @@
#include "meson_viu.h"
#include "meson_vpp.h"
#include "meson_venc.h"
-#include "meson_canvas.h"
#include "meson_registers.h"
/**

View File

@ -0,0 +1,55 @@
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
The GPIOX tsin_a pins wrongly uses the SDCard pinctrl bits, this
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 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 };
static const unsigned int eth_act_led_pins[] = { GPIOZ_15 };
static const unsigned int tsin_a_d0_pins[] = { GPIODV_0 };
-static const unsigned int tsin_a_d0_x_pins[] = { GPIOX_10 };
static const unsigned int tsin_a_clk_pins[] = { GPIODV_8 };
-static const unsigned int tsin_a_clk_x_pins[] = { GPIOX_11 };
static const unsigned int tsin_a_sop_pins[] = { GPIODV_9 };
-static const unsigned int tsin_a_sop_x_pins[] = { GPIOX_8 };
static const unsigned int tsin_a_d_valid_pins[] = { GPIODV_10 };
-static const unsigned int tsin_a_d_valid_x_pins[] = { GPIOX_9 };
static const unsigned int tsin_a_fail_pins[] = { GPIODV_11 };
static const unsigned int tsin_a_dp_pins[] = {
GPIODV_1, GPIODV_2, GPIODV_3, GPIODV_4, GPIODV_5, GPIODV_6, GPIODV_7,
@@ -432,10 +428,6 @@ static struct meson_pmx_group meson_gxl_periphs_groups[] = {
GROUP(spi_miso, 5, 2),
GROUP(spi_ss0, 5, 1),
GROUP(spi_sclk, 5, 0),
- GROUP(tsin_a_sop_x, 6, 3),
- GROUP(tsin_a_d_valid_x, 6, 2),
- GROUP(tsin_a_d0_x, 6, 1),
- GROUP(tsin_a_clk_x, 6, 0),
/* Bank Z */
GROUP(eth_mdio, 4, 23),
@@ -698,8 +690,8 @@ static const char * const eth_led_groups[] = {
};
static const char * const tsin_a_groups[] = {
- "tsin_a_clk", "tsin_a_clk_x", "tsin_a_sop", "tsin_a_sop_x",
- "tsin_a_d_valid", "tsin_a_d_valid_x", "tsin_a_d0", "tsin_a_d0_x",
+ "tsin_a_clk", "tsin_a_sop",
+ "tsin_a_d_valid", "tsin_a_d0",
"tsin_a_dp", "tsin_a_fail",
};

View File

@ -1,35 +0,0 @@
From 862bb56b65dccfa92e29d58f006f7bd22f68186e Mon Sep 17 00:00:00 2001
From: Maxime Jourdan <maxi.jourdan@wanadoo.fr>
Date: Thu, 26 Jul 2018 21:51:54 +0200
Subject: [PATCH] ARM64: dts: meson-gx: add vdec entry
Add the video decoder dts entry
---
arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
index 7296b4f..739dc49 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
@@ -535,6 +535,20 @@
};
};
+ vdec: video-decoder@0xd0050000 {
+ compatible = "amlogic,meson-gx-vdec";
+ reg = <0x0 0xc8820000 0x0 0x10000
+ 0x0 0xc110a580 0x0 0xe4
+ 0x0 0xc8838000 0x0 0x60>;
+ reg-names = "dos", "esparser", "dmc";
+
+ interrupts = <GIC_SPI 44 IRQ_TYPE_EDGE_RISING
+ GIC_SPI 32 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "vdec", "esparser";
+
+ amlogic,ao-sysctrl = <&sysctrl_AO>;
+ };
+
vpu: vpu@d0100000 {
compatible = "amlogic,meson-gx-vpu";
reg = <0x0 0xd0100000 0x0 0x100000>,

View File

@ -0,0 +1,79 @@
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
The hdmi_5v regulator must be enabled to provide power to the physical HDMI
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 +
arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts | 1 +
arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts | 1 +
arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts | 1 +
5 files changed, 5 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi
index fb9ad6f..774f8af 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi
@@ -166,6 +166,7 @@
status = "okay";
pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>;
pinctrl-names = "default";
+ hdmi-supply = <&hdmi_5v>;
};
&hdmi_tx_tmds_port {
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
index f053595..e5ef9b0 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
@@ -119,6 +119,7 @@
status = "okay";
pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>;
pinctrl-names = "default";
+ hdmi-supply = <&hdmi_5v>;
};
&hdmi_tx_tmds_port {
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts
index f56969e..ca0228e 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts
@@ -200,6 +200,7 @@
status = "okay";
pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>;
pinctrl-names = "default";
+ hdmi-supply = <&hdmi_5v>;
};
&hdmi_tx_tmds_port {
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts
index f8c66a7..29c9837 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts
@@ -96,6 +96,7 @@
status = "okay";
pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>;
pinctrl-names = "default";
+ hdmi-supply = <&hdmi_5v>;
};
&hdmi_tx_tmds_port {
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts
index 4fbfa5a..fe8e726 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts
@@ -312,6 +312,7 @@
status = "okay";
pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>;
pinctrl-names = "default";
+ hdmi-supply = <&hdmi_5v>;
};
&hdmi_tx_tmds_port {

View File

@ -0,0 +1,38 @@
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
The gpio line names were set in the pinctrl node instead of the gpio node,
at the time it was merged, it worked, but was obviously wrong.
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(-)
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts
index ca0228e..bb2a8c7 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts
@@ -209,7 +209,7 @@
};
};
-&pinctrl_aobus {
+&gpio_ao {
gpio-line-names = "UART TX",
"UART RX",
"Blue LED",
@@ -224,7 +224,7 @@
"7J1 Header Pin15";
};
-&pinctrl_periphs {
+&gpio {
gpio-line-names = /* Bank GPIOZ */
"", "", "", "", "", "", "",
"", "", "", "", "", "", "",

View File

@ -0,0 +1,38 @@
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
The gpio line names were set in the pinctrl node instead of the gpio node,
at the time it was merged, it worked, but was obviously wrong.
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(-)
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts
index 5b10de9..8ea5ed5 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts
@@ -236,7 +236,7 @@
pinctrl-names = "default";
};
-&pinctrl_aobus {
+&gpio_ao {
gpio-line-names = "UART TX", "UART RX", "Power Control", "Power Key In",
"VCCK En", "CON1 Header Pin31",
"I2S Header Pin6", "IR In", "I2S Header Pin7",
@@ -246,7 +246,7 @@
"";
};
-&pinctrl_periphs {
+&gpio {
gpio-line-names = /* Bank GPIOZ */
"Eth MDIO", "Eth MDC", "Eth RGMII RX Clk",
"Eth RX DV", "Eth RX D0", "Eth RX D1", "Eth RX D2",

View File

@ -0,0 +1,38 @@
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
The gpio line names were set in the pinctrl node instead of the gpio node,
at the time it was merged, it worked, but was obviously wrong.
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(-)
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
index 3da3309..73cc801 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
@@ -232,7 +232,7 @@
pinctrl-names = "default";
};
-&pinctrl_aobus {
+&gpio_ao {
gpio-line-names = "UART TX", "UART RX", "VCCK En", "TF 3V3/1V8 En",
"USB HUB nRESET", "USB OTG Power En",
"J7 Header Pin2", "IR In", "J7 Header Pin4",
@@ -242,7 +242,7 @@
"";
};
-&pinctrl_periphs {
+&gpio {
gpio-line-names = /* Bank GPIOZ */
"Eth MDIO", "Eth MDC", "Eth RGMII RX Clk",
"Eth RX DV", "Eth RX D0", "Eth RX D1", "Eth RX D2",

View File

@ -0,0 +1,38 @@
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
The gpio line names were set in the pinctrl node instead of the gpio node,
at the time it was merged, it worked, but was obviously wrong.
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(-)
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
index e5ef9b0..1a4b3f3 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
@@ -158,7 +158,7 @@
linux,rc-map-name = "rc-geekbox";
};
-&pinctrl_aobus {
+&gpio_ao {
gpio-line-names = "UART TX",
"UART RX",
"Power Key In",
@@ -173,7 +173,7 @@
"";
};
-&pinctrl_periphs {
+&gpio {
gpio-line-names = /* Bank GPIOZ */
"", "", "", "", "", "", "",
"", "", "", "", "", "", "",

View File

@ -0,0 +1,328 @@
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
This change is an attempt to handle the alternate clock for the CEA mode.
60Hz vs. 59.94Hz, 30Hz vs 29.97Hz or 24Hz vs 23.97Hz on the Amlogic Meson SoC
DRM Driver pixel clock generation.
The actual clock generation will be moved to the Common Clock framework once
all the video clock are handled by the Amlogic Meson SoC clock driver,
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 +++++++++++++++++++++++-----------
drivers/gpu/drm/meson/meson_vclk.h | 2 +
3 files changed, 89 insertions(+), 52 deletions(-)
diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c
index df7247c..d8c5cc3 100644
--- a/drivers/gpu/drm/meson/meson_dw_hdmi.c
+++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c
@@ -594,17 +594,7 @@ dw_hdmi_mode_valid(struct drm_connector *connector,
dev_dbg(connector->dev->dev, "%s: vclk:%d venc=%d hdmi=%d\n", __func__,
vclk_freq, venc_freq, hdmi_freq);
- /* Finally filter by configurable vclk frequencies for VIC modes */
- switch (vclk_freq) {
- case 54000:
- case 74250:
- case 148500:
- case 297000:
- case 594000:
- return MODE_OK;
- }
-
- return MODE_CLOCK_RANGE;
+ return meson_vclk_vic_supported_freq(vclk_freq);
}
/* Encoder */
diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c
index ae54732..5accceb 100644
--- a/drivers/gpu/drm/meson/meson_vclk.c
+++ b/drivers/gpu/drm/meson/meson_vclk.c
@@ -117,6 +117,8 @@
#define HDMI_PLL_RESET BIT(28)
#define HDMI_PLL_LOCK BIT(31)
+#define FREQ_1000_1001(_freq) DIV_ROUND_CLOSEST(_freq * 1000, 1001)
+
/* VID PLL Dividers */
enum {
VID_PLL_DIV_1 = 0,
@@ -323,7 +325,7 @@ static void meson_venci_cvbs_clock_config(struct meson_drm *priv)
enum {
/* PLL O1 O2 O3 VP DV EN TX */
/* 4320 /4 /4 /1 /5 /1 => /2 /2 */
- MESON_VCLK_HDMI_ENCI_54000 = 1,
+ MESON_VCLK_HDMI_ENCI_54000 = 0,
/* 4320 /4 /4 /1 /5 /1 => /1 /2 */
MESON_VCLK_HDMI_DDR_54000,
/* 2970 /4 /1 /1 /5 /1 => /1 /2 */
@@ -339,6 +341,7 @@ enum {
};
struct meson_vclk_params {
+ unsigned int pixel_freq;
unsigned int pll_base_freq;
unsigned int pll_od1;
unsigned int pll_od2;
@@ -347,6 +350,7 @@ struct meson_vclk_params {
unsigned int vclk_div;
} params[] = {
[MESON_VCLK_HDMI_ENCI_54000] = {
+ .pixel_freq = 54000,
.pll_base_freq = 4320000,
.pll_od1 = 4,
.pll_od2 = 4,
@@ -355,6 +359,7 @@ struct meson_vclk_params {
.vclk_div = 1,
},
[MESON_VCLK_HDMI_DDR_54000] = {
+ .pixel_freq = 54000,
.pll_base_freq = 4320000,
.pll_od1 = 4,
.pll_od2 = 4,
@@ -363,6 +368,7 @@ struct meson_vclk_params {
.vclk_div = 1,
},
[MESON_VCLK_HDMI_DDR_148500] = {
+ .pixel_freq = 148500,
.pll_base_freq = 2970000,
.pll_od1 = 4,
.pll_od2 = 1,
@@ -371,6 +377,7 @@ struct meson_vclk_params {
.vclk_div = 1,
},
[MESON_VCLK_HDMI_74250] = {
+ .pixel_freq = 74250,
.pll_base_freq = 2970000,
.pll_od1 = 2,
.pll_od2 = 2,
@@ -379,6 +386,7 @@ struct meson_vclk_params {
.vclk_div = 1,
},
[MESON_VCLK_HDMI_148500] = {
+ .pixel_freq = 148500,
.pll_base_freq = 2970000,
.pll_od1 = 1,
.pll_od2 = 2,
@@ -387,6 +395,7 @@ struct meson_vclk_params {
.vclk_div = 1,
},
[MESON_VCLK_HDMI_297000] = {
+ .pixel_freq = 297000,
.pll_base_freq = 2970000,
.pll_od1 = 1,
.pll_od2 = 1,
@@ -395,6 +404,7 @@ struct meson_vclk_params {
.vclk_div = 2,
},
[MESON_VCLK_HDMI_594000] = {
+ .pixel_freq = 594000,
.pll_base_freq = 5940000,
.pll_od1 = 1,
.pll_od2 = 1,
@@ -402,6 +412,7 @@ struct meson_vclk_params {
.vid_pll_div = VID_PLL_DIV_5,
.vclk_div = 1,
},
+ { /* sentinel */ },
};
static inline unsigned int pll_od_to_reg(unsigned int od)
@@ -626,12 +637,37 @@ static void meson_hdmi_pll_generic_set(struct meson_drm *priv,
pll_freq);
}
+enum drm_mode_status
+meson_vclk_vic_supported_freq(unsigned int freq)
+{
+ int i;
+
+ DRM_DEBUG_DRIVER("freq = %d\n", 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));
+ /* Match strict frequency */
+ if (freq == params[i].pixel_freq)
+ return MODE_OK;
+ /* Match 1000/1001 variant */
+ if (freq == FREQ_1000_1001(params[i].pixel_freq))
+ return MODE_OK;
+ }
+
+ return MODE_CLOCK_RANGE;
+}
+EXPORT_SYMBOL_GPL(meson_vclk_vic_supported_freq);
+
static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq,
unsigned int od1, unsigned int od2, unsigned int od3,
unsigned int vid_pll_div, unsigned int vclk_div,
unsigned int hdmi_tx_div, unsigned int venc_div,
- bool hdmi_use_enci)
+ bool hdmi_use_enci, bool vic_alternate_clock)
{
+ unsigned int m, frac;
+
/* Set HDMI-TX sys clock */
regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
CTS_HDMI_SYS_SEL_MASK, 0);
@@ -646,34 +682,38 @@ static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq,
} else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) {
switch (pll_base_freq) {
case 2970000:
- meson_hdmi_pll_set_params(priv, 0x3d, 0xe00,
- od1, od2, od3);
+ m = 0x3d;
+ frac = vic_alternate_clock ? 0xd02 : 0xe00;
break;
case 4320000:
- meson_hdmi_pll_set_params(priv, 0x5a, 0,
- od1, od2, od3);
+ m = vic_alternate_clock ? 0x59 : 0x5a;
+ frac = vic_alternate_clock ? 0xe8f : 0;
break;
case 5940000:
- meson_hdmi_pll_set_params(priv, 0x7b, 0xc00,
- od1, od2, od3);
+ m = 0x7b;
+ frac = vic_alternate_clock ? 0xa05 : 0xc00;
break;
}
+
+ meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3);
} else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) {
switch (pll_base_freq) {
case 2970000:
- meson_hdmi_pll_set_params(priv, 0x7b, 0x300,
- od1, od2, od3);
+ m = 0x7b;
+ frac = vic_alternate_clock ? 0x281 : 0x300;
break;
case 4320000:
- meson_hdmi_pll_set_params(priv, 0xb4, 0,
- od1, od2, od3);
+ m = vic_alternate_clock ? 0xb3 : 0xb4;
+ frac = vic_alternate_clock ? 0x347 : 0;
break;
case 5940000:
- meson_hdmi_pll_set_params(priv, 0xf7, 0x200,
- od1, od2, od3);
+ m = 0xf7;
+ frac = vic_alternate_clock ? 0x102 : 0x200;
break;
}
+
+ meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3);
}
/* Setup vid_pll divider */
@@ -826,6 +866,7 @@ 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)
{
+ bool vic_alternate_clock = false;
unsigned int freq;
unsigned int hdmi_tx_div;
unsigned int venc_div;
@@ -843,7 +884,7 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
* - encp encoder
*/
meson_vclk_set(priv, vclk_freq * 10, 0, 0, 0,
- VID_PLL_DIV_5, 2, 1, 1, false);
+ VID_PLL_DIV_5, 2, 1, 1, false, false);
return;
}
@@ -863,31 +904,35 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
return;
}
- switch (vclk_freq) {
- case 54000:
- if (hdmi_use_enci)
- freq = MESON_VCLK_HDMI_ENCI_54000;
- else
- freq = MESON_VCLK_HDMI_DDR_54000;
- break;
- case 74250:
- freq = MESON_VCLK_HDMI_74250;
- break;
- case 148500:
- if (dac_freq != 148500)
- freq = MESON_VCLK_HDMI_DDR_148500;
- else
- freq = MESON_VCLK_HDMI_148500;
- break;
- case 297000:
- freq = MESON_VCLK_HDMI_297000;
- break;
- case 594000:
- freq = MESON_VCLK_HDMI_594000;
- break;
- default:
- pr_err("Fatal Error, invalid HDMI vclk freq %d\n",
- vclk_freq);
+ 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)
+ vic_alternate_clock = true;
+ else
+ vic_alternate_clock = false;
+
+ if (freq == MESON_VCLK_HDMI_ENCI_54000 &&
+ !hdmi_use_enci)
+ continue;
+
+ if (freq == MESON_VCLK_HDMI_DDR_54000 &&
+ hdmi_use_enci)
+ continue;
+
+ if (freq == MESON_VCLK_HDMI_DDR_148500 &&
+ dac_freq == vclk_freq)
+ continue;
+
+ if (freq == MESON_VCLK_HDMI_148500 &&
+ dac_freq != vclk_freq)
+ continue;
+ break;
+ }
+ }
+
+ if (!params[freq].pixel_freq) {
+ pr_err("Fatal Error, invalid HDMI vclk freq %d\n", vclk_freq);
return;
}
@@ -895,6 +940,6 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
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,
- hdmi_use_enci);
+ hdmi_use_enci, vic_alternate_clock);
}
EXPORT_SYMBOL_GPL(meson_vclk_setup);
diff --git a/drivers/gpu/drm/meson/meson_vclk.h b/drivers/gpu/drm/meson/meson_vclk.h
index 869fa3a..4bd8752 100644
--- a/drivers/gpu/drm/meson/meson_vclk.h
+++ b/drivers/gpu/drm/meson/meson_vclk.h
@@ -32,6 +32,8 @@ 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);
void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
unsigned int vclk_freq, unsigned int venc_freq,

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,32 @@
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
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 9e9b19e..ede389b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9520,6 +9520,14 @@ F: drivers/media/platform/meson/ao-cec.c
F: Documentation/devicetree/bindings/media/meson-ao-cec.txt
T: git git://linuxtv.org/media_tree.git
+MESON VIDEO DECODER DRIVER FOR AMLOGIC SOCS
+M: Maxime Jourdan <mjourdan@baylibre.com>
+L: linux-media@lists.freedesktop.org
+L: linux-amlogic@lists.infradead.org
+S: Supported
+F: drivers/media/platform/meson/vdec/
+T: git git://linuxtv.org/media_tree.git
+
MICROBLAZE ARCHITECTURE
M: Michal Simek <monstr@monstr.eu>
W: http://www.monstr.eu/fdt/

View File

@ -0,0 +1,38 @@
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
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(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
index 5012607..5d2820e 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
@@ -445,6 +445,20 @@
};
};
+ vdec: video-decoder@c8820000 {
+ compatible = "amlogic,gx-vdec";
+ reg = <0x0 0xc8820000 0x0 0x10000>,
+ <0x0 0xc110a580 0x0 0xe4>;
+ reg-names = "dos", "esparser";
+
+ interrupts = <GIC_SPI 44 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 32 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "vdec", "esparser";
+
+ amlogic,ao-sysctrl = <&sysctrl_AO>;
+ amlogic,canvas = <&canvas>;
+ };
+
periphs: periphs@c8834000 {
compatible = "simple-bus";
reg = <0x0 0xc8834000 0x0 0x2000>;

View File

@ -1,47 +1,56 @@
From f7fd519b2188e86d212234cf3f2c8606917afd0a Mon Sep 17 00:00:00 2001
From: Maxime Jourdan <maxi.jourdan@wanadoo.fr>
Date: Thu, 26 Jul 2018 23:30:30 +0200
Subject: [PATCH] ARM64: dts: meson: add vdec entries
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
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 | 7 +++++++
arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 7 +++++++
arch/arm64/boot/dts/amlogic/meson-gxm.dtsi | 4 ++++
3 files changed, 18 insertions(+)
arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 10 ++++++++++
arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 10 ++++++++++
arch/arm64/boot/dts/amlogic/meson-gxm.dtsi | 4 ++++
3 files changed, 24 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
index 2a4d506..c34ecca 100644
index 2a4d506..96145e4 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
@@ -814,3 +814,10 @@
@@ -814,3 +814,13 @@
power-domains = <&pwrc_vpu>;
};
+&vdec {
+ compatible = "amlogic,meson-gxbb-vdec";
+ clocks = <&clkc CLKID_DOS_PARSER>, <&clkc CLKID_DOS>, <&clkc CLKID_VDEC_1>, <&clkc CLKID_VDEC_HEVC>;
+ compatible = "amlogic,gxbb-vdec";
+ clocks = <&clkc CLKID_DOS_PARSER>,
+ <&clkc CLKID_DOS>,
+ <&clkc CLKID_VDEC_1>,
+ <&clkc CLKID_VDEC_HEVC>;
+ clock-names = "dos_parser", "dos", "vdec_1", "vdec_hevc";
+ resets = <&reset RESET_PARSER>;
+ reset-names = "esparser";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
index 9f4b618..7b95db8 100644
index 9f4b618..6ca93ae 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
@@ -814,3 +814,10 @@
@@ -814,3 +814,13 @@
power-domains = <&pwrc_vpu>;
};
+&vdec {
+ compatible = "amlogic,meson-gxl-vdec";
+ clocks = <&clkc CLKID_DOS_PARSER>, <&clkc CLKID_DOS>, <&clkc CLKID_VDEC_1>, <&clkc CLKID_VDEC_HEVC>;
+ compatible = "amlogic,gxl-vdec";
+ clocks = <&clkc CLKID_DOS_PARSER>,
+ <&clkc CLKID_DOS>,
+ <&clkc CLKID_VDEC_1>,
+ <&clkc CLKID_VDEC_HEVC>;
+ clock-names = "dos_parser", "dos", "vdec_1", "vdec_hevc";
+ resets = <&reset RESET_PARSER>;
+ reset-names = "esparser";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi
index 247888d..4ce7b12 100644
index 247888d..2f35649 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi
@@ -117,3 +117,7 @@
@ -50,5 +59,5 @@ index 247888d..4ce7b12 100644
};
+
+&vdec {
+ compatible = "amlogic,meson-gxm-vdec";
+ compatible = "amlogic,gxm-vdec";
+};

View File

@ -0,0 +1,153 @@
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
V4L2_CID_MIN_BUFFERS_FOR_CAPTURE
---
drivers/media/platform/meson/vdec/Makefile | 2 +-
drivers/media/platform/meson/vdec/vdec.c | 7 ++++
drivers/media/platform/meson/vdec/vdec.h | 2 ++
drivers/media/platform/meson/vdec/vdec_ctrls.c | 45 ++++++++++++++++++++++++++
drivers/media/platform/meson/vdec/vdec_ctrls.h | 8 +++++
5 files changed, 63 insertions(+), 1 deletion(-)
create mode 100644 drivers/media/platform/meson/vdec/vdec_ctrls.c
create mode 100644 drivers/media/platform/meson/vdec/vdec_ctrls.h
diff --git a/drivers/media/platform/meson/vdec/Makefile b/drivers/media/platform/meson/vdec/Makefile
index 6bea129..eba8608 100644
--- a/drivers/media/platform/meson/vdec/Makefile
+++ b/drivers/media/platform/meson/vdec/Makefile
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
# Makefile for Amlogic meson video decoder driver
-meson-vdec-objs = esparser.o vdec.o vdec_helpers.o vdec_platform.o
+meson-vdec-objs = esparser.o vdec.o vdec_ctrls.o vdec_helpers.o vdec_platform.o
meson-vdec-objs += vdec_1.o
meson-vdec-objs += codec_mpeg12.o
diff --git a/drivers/media/platform/meson/vdec/vdec.c b/drivers/media/platform/meson/vdec/vdec.c
index d8db52c..1c5d3e9 100644
--- a/drivers/media/platform/meson/vdec/vdec.c
+++ b/drivers/media/platform/meson/vdec/vdec.c
@@ -21,6 +21,7 @@
#include "vdec.h"
#include "esparser.h"
#include "vdec_helpers.h"
+#include "vdec_ctrls.h"
struct dummy_buf {
struct vb2_v4l2_buffer vb;
@@ -290,6 +291,7 @@ static int vdec_start_streaming(struct vb2_queue *q, unsigned int count)
sess->keyframe_found = 0;
sess->last_offset = 0;
sess->wrap_count = 0;
+ sess->dpb_size = 0;
sess->pixelaspect.numerator = 1;
sess->pixelaspect.denominator = 1;
atomic_set(&sess->esparser_queued_bufs, 0);
@@ -812,6 +814,10 @@ static int vdec_open(struct file *file)
goto err_m2m_release;
}
+ ret = amvdec_init_ctrls(&sess->ctrl_handler);
+ if (ret)
+ goto err_m2m_release;
+
sess->pixfmt_cap = formats[0].pixfmts_cap[0];
sess->fmt_out = &formats[0];
sess->width = 1280;
@@ -827,6 +833,7 @@ static int vdec_open(struct file *file)
spin_lock_init(&sess->ts_spinlock);
v4l2_fh_init(&sess->fh, core->vdev_dec);
+ sess->fh.ctrl_handler = &sess->ctrl_handler;
v4l2_fh_add(&sess->fh);
sess->fh.m2m_ctx = sess->m2m_ctx;
file->private_data = &sess->fh;
diff --git a/drivers/media/platform/meson/vdec/vdec.h b/drivers/media/platform/meson/vdec/vdec.h
index 4e8c3f1..6be7de2 100644
--- a/drivers/media/platform/meson/vdec/vdec.h
+++ b/drivers/media/platform/meson/vdec/vdec.h
@@ -203,6 +203,7 @@ struct amvdec_session {
struct v4l2_fh fh;
struct v4l2_m2m_dev *m2m_dev;
struct v4l2_m2m_ctx *m2m_ctx;
+ struct v4l2_ctrl_handler ctrl_handler;
struct mutex lock;
const struct amvdec_format *fmt_out;
@@ -242,6 +243,7 @@ struct amvdec_session {
u64 last_irq_jiffies;
u32 last_offset;
u32 wrap_count;
+ u32 dpb_size;
void *priv;
};
diff --git a/drivers/media/platform/meson/vdec/vdec_ctrls.c b/drivers/media/platform/meson/vdec/vdec_ctrls.c
new file mode 100644
index 0000000..cd6dd6d
--- /dev/null
+++ b/drivers/media/platform/meson/vdec/vdec_ctrls.c
@@ -0,0 +1,45 @@
+#include "vdec_ctrls.h"
+
+static int vdec_op_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct amvdec_session *sess =
+ container_of(ctrl->handler, struct amvdec_session, ctrl_handler);
+
+ switch (ctrl->id) {
+ case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
+ ctrl->val = sess->dpb_size;
+ break;
+ default:
+ return -EINVAL;
+ };
+
+ return 0;
+}
+
+static const struct v4l2_ctrl_ops vdec_ctrl_ops = {
+ .g_volatile_ctrl = vdec_op_g_volatile_ctrl,
+};
+
+int amvdec_init_ctrls(struct v4l2_ctrl_handler *ctrl_handler)
+{
+ int ret;
+ struct v4l2_ctrl *ctrl;
+
+ ret = v4l2_ctrl_handler_init(ctrl_handler, 1);
+ if (ret)
+ return ret;
+
+ ctrl = v4l2_ctrl_new_std(ctrl_handler, &vdec_ctrl_ops,
+ V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 1);
+ if (ctrl)
+ ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+
+ ret = ctrl_handler->error;
+ if (ret) {
+ v4l2_ctrl_handler_free(ctrl_handler);
+ return ret;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(amvdec_init_ctrls);
diff --git a/drivers/media/platform/meson/vdec/vdec_ctrls.h b/drivers/media/platform/meson/vdec/vdec_ctrls.h
new file mode 100644
index 0000000..4bcc5e6
--- /dev/null
+++ b/drivers/media/platform/meson/vdec/vdec_ctrls.h
@@ -0,0 +1,8 @@
+#ifndef __MESON_VDEC_CTRLS_H_
+#define __MESON_VDEC_CTRLS_H_
+
+#include "vdec.h"
+
+int amvdec_init_ctrls(struct v4l2_ctrl_handler *ctrl_handler);
+
+#endif

View File

@ -0,0 +1,49 @@
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
When a v4l2 driver exposes V4L2_EVENT_SOURCE_CHANGE, some (usually
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 +++--
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/Documentation/media/uapi/v4l/vidioc-enum-fmt.rst b/Documentation/media/uapi/v4l/vidioc-enum-fmt.rst
index 019c513..e0040b3 100644
--- a/Documentation/media/uapi/v4l/vidioc-enum-fmt.rst
+++ b/Documentation/media/uapi/v4l/vidioc-enum-fmt.rst
@@ -116,6 +116,11 @@ one until ``EINVAL`` is returned.
- This format is not native to the device but emulated through
software (usually libv4l2), where possible try to use a native
format instead for better performance.
+ * - ``V4L2_FMT_FLAG_NO_SOURCE_CHANGE``
+ - 0x0004
+ - The event ``V4L2_EVENT_SOURCE_CHANGE`` is not supported
+ for this format.
+
Return Value
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 1aae2e4..f44bdef 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -733,8 +733,9 @@ struct v4l2_fmtdesc {
__u32 reserved[4];
};
-#define V4L2_FMT_FLAG_COMPRESSED 0x0001
-#define V4L2_FMT_FLAG_EMULATED 0x0002
+#define V4L2_FMT_FLAG_COMPRESSED 0x0001
+#define V4L2_FMT_FLAG_EMULATED 0x0002
+#define V4L2_FMT_FLAG_NO_SOURCE_CHANGE 0x0004
/* Frame Size and frame rate enumeration */
/*

View File

@ -0,0 +1,270 @@
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 +++++++++++
drivers/media/platform/meson/vdec/vdec_helpers.c | 28 +++++++++++++++++++++++
drivers/media/platform/meson/vdec/vdec_helpers.h | 1 +
drivers/media/platform/meson/vdec/vdec_platform.c | 6 +++++
5 files changed, 66 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/meson/vdec/vdec.c b/drivers/media/platform/meson/vdec/vdec.c
index 1c5d3e9..ca64045 100644
--- a/drivers/media/platform/meson/vdec/vdec.c
+++ b/drivers/media/platform/meson/vdec/vdec.c
@@ -230,7 +230,8 @@ static int vdec_queue_setup(struct vb2_queue *q,
* are free to choose any of them to write frames to. As such,
* we need all of them to be queued into the driver
*/
- q->min_buffers_needed = q->num_buffers + *num_buffers;
+ sess->num_dst_bufs = q->num_buffers + *num_buffers;
+ q->min_buffers_needed = sess->num_dst_bufs;
break;
default:
return -EINVAL;
@@ -260,6 +261,7 @@ static void vdec_vb2_buf_queue(struct vb2_buffer *vb)
static int vdec_start_streaming(struct vb2_queue *q, unsigned int count)
{
struct amvdec_session *sess = vb2_get_drv_priv(q);
+ struct amvdec_codec_ops *codec_ops = sess->fmt_out->codec_ops;
struct amvdec_core *core = sess->core;
struct vb2_v4l2_buffer *buf;
int ret;
@@ -277,6 +279,13 @@ static int vdec_start_streaming(struct vb2_queue *q, unsigned int count)
if (!sess->streamon_out || !sess->streamon_cap)
return 0;
+ if (sess->status == STATUS_NEEDS_RESUME &&
+ q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ codec_ops->resume(sess);
+ sess->status = STATUS_RUNNING;
+ return 0;
+ }
+
sess->vififo_size = SIZE_VIFIFO;
sess->vififo_vaddr =
dma_alloc_coherent(sess->core->dev, sess->vififo_size,
@@ -305,6 +314,7 @@ static int vdec_start_streaming(struct vb2_queue *q, unsigned int count)
sess->recycle_thread = kthread_run(vdec_recycle_thread, sess,
"vdec_recycle");
+ sess->status = STATUS_RUNNING;
core->cur_sess = sess;
return 0;
@@ -362,7 +372,9 @@ static void vdec_stop_streaming(struct vb2_queue *q)
struct amvdec_core *core = sess->core;
struct vb2_v4l2_buffer *buf;
- if (sess->streamon_out && sess->streamon_cap) {
+ if (sess->status == STATUS_RUNNING ||
+ (sess->status == STATUS_NEEDS_RESUME &&
+ (!sess->streamon_out || !sess->streamon_cap))) {
if (vdec_codec_needs_recycle(sess))
kthread_stop(sess->recycle_thread);
@@ -375,6 +387,7 @@ static void vdec_stop_streaming(struct vb2_queue *q)
kfree(sess->priv);
sess->priv = NULL;
core->cur_sess = NULL;
+ sess->status = STATUS_STOPPED;
}
if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
@@ -611,6 +624,7 @@ static int vdec_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f)
fmt_out = &platform->formats[f->index];
f->pixelformat = fmt_out->pixfmt;
+ f->flags = fmt_out->flags;
} else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
fmt_out = sess->fmt_out;
if (f->index >= 4 || !fmt_out->pixfmts_cap[f->index])
@@ -703,6 +717,8 @@ static int vdec_subscribe_event(struct v4l2_fh *fh,
switch (sub->type) {
case V4L2_EVENT_EOS:
return v4l2_event_subscribe(fh, sub, 2, NULL);
+ case V4L2_EVENT_SOURCE_CHANGE:
+ return v4l2_src_change_event_subscribe(fh, sub);
default:
return -EINVAL;
}
diff --git a/drivers/media/platform/meson/vdec/vdec.h b/drivers/media/platform/meson/vdec/vdec.h
index 6be7de2..8f8ce62 100644
--- a/drivers/media/platform/meson/vdec/vdec.h
+++ b/drivers/media/platform/meson/vdec/vdec.h
@@ -101,6 +101,7 @@ struct amvdec_ops {
u32 (*vififo_level)(struct amvdec_session *sess);
};
+
/**
* struct amvdec_codec_ops - codec operations
*
@@ -127,6 +128,7 @@ struct amvdec_codec_ops {
int (*can_recycle)(struct amvdec_core *core);
void (*recycle)(struct amvdec_core *core, u32 buf_idx);
void (*drain)(struct amvdec_session *sess);
+ void (*resume)(struct amvdec_session *sess);
const u8 * (*eos_sequence)(u32 *len);
irqreturn_t (*isr)(struct amvdec_session *sess);
irqreturn_t (*threaded_isr)(struct amvdec_session *sess);
@@ -140,6 +142,7 @@ struct amvdec_codec_ops {
* @max_buffers: maximum amount of CAPTURE (dst) buffers
* @max_width: maximum picture width supported
* @max_height: maximum picture height supported
+ * @flags: enum flags associated with this pixfmt
* @vdec_ops: the VDEC operations that support this format
* @codec_ops: the codec operations that support this format
* @firmware_path: Path to the firmware that supports this format
@@ -151,6 +154,7 @@ struct amvdec_format {
u32 max_buffers;
u32 max_width;
u32 max_height;
+ u32 flags;
struct amvdec_ops *vdec_ops;
struct amvdec_codec_ops *codec_ops;
@@ -159,6 +163,12 @@ struct amvdec_format {
u32 pixfmts_cap[4];
};
+enum amvdec_status {
+ STATUS_STOPPED,
+ STATUS_RUNNING,
+ STATUS_NEEDS_RESUME,
+};
+
/**
* struct amvdec_session - decoding session parameters
*
@@ -195,6 +205,7 @@ struct amvdec_format {
* @timestamps: chronological list of src timestamps
* @ts_spinlock: spinlock for the timestamps list
* @last_irq_jiffies: tracks last time the vdec triggered an IRQ
+ * @status: current decoding status
* @priv: codec private data
*/
struct amvdec_session {
@@ -225,6 +236,7 @@ struct amvdec_session {
unsigned int sequence_cap;
unsigned int should_stop;
unsigned int keyframe_found;
+ unsigned int num_dst_bufs;
u8 canvas_alloc[MAX_CANVAS];
u32 canvas_num;
@@ -245,6 +257,7 @@ struct amvdec_session {
u32 wrap_count;
u32 dpb_size;
+ enum amvdec_status status;
void *priv;
};
diff --git a/drivers/media/platform/meson/vdec/vdec_helpers.c b/drivers/media/platform/meson/vdec/vdec_helpers.c
index 02090c5..b982b28 100644
--- a/drivers/media/platform/meson/vdec/vdec_helpers.c
+++ b/drivers/media/platform/meson/vdec/vdec_helpers.c
@@ -403,6 +403,34 @@ void amvdec_set_par_from_dar(struct amvdec_session *sess,
}
EXPORT_SYMBOL_GPL(amvdec_set_par_from_dar);
+void amvdec_src_change(struct amvdec_session *sess, u32 width, u32 height, u32 dpb_size)
+{
+ static const struct v4l2_event ev = {
+ .type = V4L2_EVENT_SOURCE_CHANGE,
+ .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION };
+
+ sess->dpb_size = dpb_size;
+
+ /* Check if the capture queue is already configured well for our
+ * usecase. If so, keep decoding with it and do not send the event
+ */
+ if (sess->width == width &&
+ sess->height == height &&
+ dpb_size <= sess->num_dst_bufs) {
+ sess->fmt_out->codec_ops->resume(sess);
+ return;
+ }
+
+ sess->width = width;
+ sess->height = height;
+ sess->status = STATUS_NEEDS_RESUME;
+
+ dev_dbg(sess->core->dev, "Res. changed (%ux%u), DPB size %u\n",
+ width, height, dpb_size);
+ v4l2_event_queue_fh(&sess->fh, &ev);
+}
+EXPORT_SYMBOL_GPL(amvdec_src_change);
+
void amvdec_abort(struct amvdec_session *sess)
{
dev_info(sess->core->dev, "Aborting decoding session!\n");
diff --git a/drivers/media/platform/meson/vdec/vdec_helpers.h b/drivers/media/platform/meson/vdec/vdec_helpers.h
index b9250a8..060799b 100644
--- a/drivers/media/platform/meson/vdec/vdec_helpers.h
+++ b/drivers/media/platform/meson/vdec/vdec_helpers.h
@@ -44,5 +44,6 @@ void amvdec_remove_ts(struct amvdec_session *sess, u64 ts);
void amvdec_set_par_from_dar(struct amvdec_session *sess,
u32 dar_num, u32 dar_den);
+void amvdec_src_change(struct amvdec_session *sess, u32 width, u32 height, u32 dpb_size);
void amvdec_abort(struct amvdec_session *sess);
#endif
diff --git a/drivers/media/platform/meson/vdec/vdec_platform.c b/drivers/media/platform/meson/vdec/vdec_platform.c
index 46eeb74..291f1ee 100644
--- a/drivers/media/platform/meson/vdec/vdec_platform.c
+++ b/drivers/media/platform/meson/vdec/vdec_platform.c
@@ -17,6 +17,7 @@ static const struct amvdec_format vdec_formats_gxbb[] = {
.max_buffers = 8,
.max_width = 1920,
.max_height = 1080,
+ .flags = V4L2_FMT_FLAG_NO_SOURCE_CHANGE,
.vdec_ops = &vdec_1_ops,
.codec_ops = &codec_mpeg12_ops,
.firmware_path = "meson/gx/vmpeg12_mc",
@@ -27,6 +28,7 @@ static const struct amvdec_format vdec_formats_gxbb[] = {
.max_buffers = 8,
.max_width = 1920,
.max_height = 1080,
+ .flags = V4L2_FMT_FLAG_NO_SOURCE_CHANGE,
.vdec_ops = &vdec_1_ops,
.codec_ops = &codec_mpeg12_ops,
.firmware_path = "meson/gx/vmpeg12_mc",
@@ -41,6 +43,7 @@ static const struct amvdec_format vdec_formats_gxl[] = {
.max_buffers = 8,
.max_width = 1920,
.max_height = 1080,
+ .flags = V4L2_FMT_FLAG_NO_SOURCE_CHANGE,
.vdec_ops = &vdec_1_ops,
.codec_ops = &codec_mpeg12_ops,
.firmware_path = "meson/gx/vmpeg12_mc",
@@ -51,6 +54,7 @@ static const struct amvdec_format vdec_formats_gxl[] = {
.max_buffers = 8,
.max_width = 1920,
.max_height = 1080,
+ .flags = V4L2_FMT_FLAG_NO_SOURCE_CHANGE,
.vdec_ops = &vdec_1_ops,
.codec_ops = &codec_mpeg12_ops,
.firmware_path = "meson/gx/vmpeg12_mc",
@@ -65,6 +69,7 @@ static const struct amvdec_format vdec_formats_gxm[] = {
.max_buffers = 8,
.max_width = 1920,
.max_height = 1080,
+ .flags = V4L2_FMT_FLAG_NO_SOURCE_CHANGE,
.vdec_ops = &vdec_1_ops,
.codec_ops = &codec_mpeg12_ops,
.firmware_path = "meson/gx/vmpeg12_mc",
@@ -75,6 +80,7 @@ static const struct amvdec_format vdec_formats_gxm[] = {
.max_buffers = 8,
.max_width = 1920,
.max_height = 1080,
+ .flags = V4L2_FMT_FLAG_NO_SOURCE_CHANGE,
.vdec_ops = &vdec_1_ops,
.codec_ops = &codec_mpeg12_ops,
.firmware_path = "meson/gx/vmpeg12_mc",

View File

@ -0,0 +1,591 @@
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 ++++++++++++++++++++++
drivers/media/platform/meson/vdec/codec_h264.h | 13 +
drivers/media/platform/meson/vdec/vdec_platform.c | 31 ++
4 files changed, 523 insertions(+), 1 deletion(-)
create mode 100644 drivers/media/platform/meson/vdec/codec_h264.c
create mode 100644 drivers/media/platform/meson/vdec/codec_h264.h
diff --git a/drivers/media/platform/meson/vdec/Makefile b/drivers/media/platform/meson/vdec/Makefile
index eba8608..01dc960 100644
--- a/drivers/media/platform/meson/vdec/Makefile
+++ b/drivers/media/platform/meson/vdec/Makefile
@@ -3,6 +3,6 @@
meson-vdec-objs = esparser.o vdec.o vdec_ctrls.o vdec_helpers.o vdec_platform.o
meson-vdec-objs += vdec_1.o
-meson-vdec-objs += codec_mpeg12.o
+meson-vdec-objs += codec_mpeg12.o codec_h264.o
obj-$(CONFIG_VIDEO_MESON_VDEC) += meson-vdec.o
diff --git a/drivers/media/platform/meson/vdec/codec_h264.c b/drivers/media/platform/meson/vdec/codec_h264.c
new file mode 100644
index 0000000..6ac0115
--- /dev/null
+++ b/drivers/media/platform/meson/vdec/codec_h264.c
@@ -0,0 +1,478 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Maxime Jourdan <maxi.jourdan@wanadoo.fr>
+ */
+
+#include <media/v4l2-mem2mem.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "vdec_helpers.h"
+#include "dos_regs.h"
+
+#define SIZE_EXT_FW (20 * SZ_1K)
+#define SIZE_WORKSPACE 0x1ee000
+#define SIZE_SEI (8 * SZ_1K)
+
+/* Offset added by the firmware which must be substracted
+ * from the workspace phyaddr
+ */
+#define WORKSPACE_BUF_OFFSET 0x1000000
+
+/* ISR status */
+#define CMD_MASK GENMASK(7, 0)
+#define CMD_SRC_CHANGE 1
+#define CMD_FRAMES_READY 2
+#define CMD_FATAL_ERROR 6
+#define CMD_BAD_WIDTH 7
+#define CMD_BAD_HEIGHT 8
+
+#define SEI_DATA_READY BIT(15)
+
+/* Picture type */
+#define PIC_TOP_BOT 5
+#define PIC_BOT_TOP 6
+
+/* Size of Motion Vector per macroblock */
+#define MB_MV_SIZE 96
+
+/* Frame status data */
+#define PIC_STRUCT_BIT 5
+#define PIC_STRUCT_MASK GENMASK(2, 0)
+#define BUF_IDX_MASK GENMASK(4, 0)
+#define ERROR_FLAG BIT(9)
+#define OFFSET_BIT 16
+#define OFFSET_MASK GENMASK(15, 0)
+
+/* Bitstream parsed data */
+#define MB_TOTAL_BIT 8
+#define MB_TOTAL_MASK GENMASK(15, 0)
+#define MB_WIDTH_MASK GENMASK(7, 0)
+#define MAX_REF_BIT 24
+#define MAX_REF_MASK GENMASK(6, 0)
+#define AR_IDC_BIT 16
+#define AR_IDC_MASK GENMASK(7, 0)
+#define AR_PRESENT_FLAG BIT(0)
+#define AR_EXTEND 0xff
+
+/* Buffer to send to the ESPARSER to signal End Of Stream for H.264.
+ * This is a 16x16 encoded picture that will trigger drain firmware-side.
+ * There is no known alternative.
+ */
+static const u8 eos_sequence[SZ_1K] = {
+ 0x00, 0x00, 0x00, 0x01, 0x06, 0x05, 0xff, 0xe4, 0xdc, 0x45, 0xe9, 0xbd,
+ 0xe6, 0xd9, 0x48, 0xb7, 0x96, 0x2c, 0xd8, 0x20, 0xd9, 0x23, 0xee, 0xef,
+ 0x78, 0x32, 0x36, 0x34, 0x20, 0x2d, 0x20, 0x63, 0x6f, 0x72, 0x65, 0x20,
+ 0x36, 0x37, 0x20, 0x72, 0x31, 0x31, 0x33, 0x30, 0x20, 0x38, 0x34, 0x37,
+ 0x35, 0x39, 0x37, 0x37, 0x20, 0x2d, 0x20, 0x48, 0x2e, 0x32, 0x36, 0x34,
+ 0x2f, 0x4d, 0x50, 0x45, 0x47, 0x2d, 0x34, 0x20, 0x41, 0x56, 0x43, 0x20,
+ 0x63, 0x6f, 0x64, 0x65, 0x63, 0x20, 0x2d, 0x20, 0x43, 0x6f, 0x70, 0x79,
+ 0x6c, 0x65, 0x66, 0x74, 0x20, 0x32, 0x30, 0x30, 0x33, 0x2d, 0x32, 0x30,
+ 0x30, 0x39, 0x20, 0x2d, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
+ 0x77, 0x77, 0x77, 0x2e, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x6c, 0x61, 0x6e,
+ 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x78, 0x32, 0x36, 0x34, 0x2e, 0x68, 0x74,
+ 0x6d, 0x6c, 0x20, 0x2d, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73,
+ 0x3a, 0x20, 0x63, 0x61, 0x62, 0x61, 0x63, 0x3d, 0x31, 0x20, 0x72, 0x65,
+ 0x66, 0x3d, 0x31, 0x20, 0x64, 0x65, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x3d,
+ 0x31, 0x3a, 0x30, 0x3a, 0x30, 0x20, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73,
+ 0x65, 0x3d, 0x30, 0x78, 0x31, 0x3a, 0x30, 0x78, 0x31, 0x31, 0x31, 0x20,
+ 0x6d, 0x65, 0x3d, 0x68, 0x65, 0x78, 0x20, 0x73, 0x75, 0x62, 0x6d, 0x65,
+ 0x3d, 0x36, 0x20, 0x70, 0x73, 0x79, 0x5f, 0x72, 0x64, 0x3d, 0x31, 0x2e,
+ 0x30, 0x3a, 0x30, 0x2e, 0x30, 0x20, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x5f,
+ 0x72, 0x65, 0x66, 0x3d, 0x30, 0x20, 0x6d, 0x65, 0x5f, 0x72, 0x61, 0x6e,
+ 0x67, 0x65, 0x3d, 0x31, 0x36, 0x20, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x61,
+ 0x5f, 0x6d, 0x65, 0x3d, 0x31, 0x20, 0x74, 0x72, 0x65, 0x6c, 0x6c, 0x69,
+ 0x73, 0x3d, 0x30, 0x20, 0x38, 0x78, 0x38, 0x64, 0x63, 0x74, 0x3d, 0x30,
+ 0x20, 0x63, 0x71, 0x6d, 0x3d, 0x30, 0x20, 0x64, 0x65, 0x61, 0x64, 0x7a,
+ 0x6f, 0x6e, 0x65, 0x3d, 0x32, 0x31, 0x2c, 0x31, 0x31, 0x20, 0x63, 0x68,
+ 0x72, 0x6f, 0x6d, 0x61, 0x5f, 0x71, 0x70, 0x5f, 0x6f, 0x66, 0x66, 0x73,
+ 0x65, 0x74, 0x3d, 0x2d, 0x32, 0x20, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64,
+ 0x73, 0x3d, 0x31, 0x20, 0x6e, 0x72, 0x3d, 0x30, 0x20, 0x64, 0x65, 0x63,
+ 0x69, 0x6d, 0x61, 0x74, 0x65, 0x3d, 0x31, 0x20, 0x6d, 0x62, 0x61, 0x66,
+ 0x66, 0x3d, 0x30, 0x20, 0x62, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x3d,
+ 0x30, 0x20, 0x6b, 0x65, 0x79, 0x69, 0x6e, 0x74, 0x3d, 0x32, 0x35, 0x30,
+ 0x20, 0x6b, 0x65, 0x79, 0x69, 0x6e, 0x74, 0x5f, 0x6d, 0x69, 0x6e, 0x3d,
+ 0x32, 0x35, 0x20, 0x73, 0x63, 0x65, 0x6e, 0x65, 0x63, 0x75, 0x74, 0x3d,
+ 0x34, 0x30, 0x20, 0x72, 0x63, 0x3d, 0x61, 0x62, 0x72, 0x20, 0x62, 0x69,
+ 0x74, 0x72, 0x61, 0x74, 0x65, 0x3d, 0x31, 0x30, 0x20, 0x72, 0x61, 0x74,
+ 0x65, 0x74, 0x6f, 0x6c, 0x3d, 0x31, 0x2e, 0x30, 0x20, 0x71, 0x63, 0x6f,
+ 0x6d, 0x70, 0x3d, 0x30, 0x2e, 0x36, 0x30, 0x20, 0x71, 0x70, 0x6d, 0x69,
+ 0x6e, 0x3d, 0x31, 0x30, 0x20, 0x71, 0x70, 0x6d, 0x61, 0x78, 0x3d, 0x35,
+ 0x31, 0x20, 0x71, 0x70, 0x73, 0x74, 0x65, 0x70, 0x3d, 0x34, 0x20, 0x69,
+ 0x70, 0x5f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x3d, 0x31, 0x2e, 0x34, 0x30,
+ 0x20, 0x61, 0x71, 0x3d, 0x31, 0x3a, 0x31, 0x2e, 0x30, 0x30, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x01, 0x67, 0x4d, 0x40, 0x0a, 0x9a, 0x74, 0xf4, 0x20,
+ 0x00, 0x00, 0x03, 0x00, 0x20, 0x00, 0x00, 0x06, 0x51, 0xe2, 0x44, 0xd4,
+ 0x00, 0x00, 0x00, 0x01, 0x68, 0xee, 0x32, 0xc8, 0x00, 0x00, 0x00, 0x01,
+ 0x65, 0x88, 0x80, 0x20, 0x00, 0x08, 0x7f, 0xea, 0x6a, 0xe2, 0x99, 0xb6,
+ 0x57, 0xae, 0x49, 0x30, 0xf5, 0xfe, 0x5e, 0x46, 0x0b, 0x72, 0x44, 0xc4,
+ 0xe1, 0xfc, 0x62, 0xda, 0xf1, 0xfb, 0xa2, 0xdb, 0xd6, 0xbe, 0x5c, 0xd7,
+ 0x24, 0xa3, 0xf5, 0xb9, 0x2f, 0x57, 0x16, 0x49, 0x75, 0x47, 0x77, 0x09,
+ 0x5c, 0xa1, 0xb4, 0xc3, 0x4f, 0x60, 0x2b, 0xb0, 0x0c, 0xc8, 0xd6, 0x66,
+ 0xba, 0x9b, 0x82, 0x29, 0x33, 0x92, 0x26, 0x99, 0x31, 0x1c, 0x7f, 0x9b
+};
+
+static const u8 *codec_h264_eos_sequence(u32 *len)
+{
+ *len = ARRAY_SIZE(eos_sequence);
+ return eos_sequence;
+}
+
+struct codec_h264 {
+ /* H.264 decoder requires an extended firmware */
+ void *ext_fw_vaddr;
+ dma_addr_t ext_fw_paddr;
+
+ /* Buffer for the H.264 Workspace */
+ void *workspace_vaddr;
+ dma_addr_t workspace_paddr;
+
+ /* Buffer for the H.264 references MV */
+ void *ref_vaddr;
+ dma_addr_t ref_paddr;
+ u32 ref_size;
+
+ /* Buffer for parsed SEI data */
+ void *sei_vaddr;
+ dma_addr_t sei_paddr;
+
+ u32 mb_width;
+ u32 mb_height;
+ u32 max_refs;
+};
+
+static int codec_h264_can_recycle(struct amvdec_core *core)
+{
+ return !amvdec_read_dos(core, AV_SCRATCH_7) ||
+ !amvdec_read_dos(core, AV_SCRATCH_8);
+}
+
+static void codec_h264_recycle(struct amvdec_core *core, u32 buf_idx)
+{
+ /* Tell the decoder he can recycle this buffer.
+ * AV_SCRATCH_8 serves the same purpose.
+ */
+ if (!amvdec_read_dos(core, AV_SCRATCH_7))
+ amvdec_write_dos(core, AV_SCRATCH_7, buf_idx + 1);
+ else
+ amvdec_write_dos(core, AV_SCRATCH_8, buf_idx + 1);
+}
+
+static int codec_h264_start(struct amvdec_session *sess) {
+ u32 workspace_offset;
+ struct amvdec_core *core = sess->core;
+ struct codec_h264 *h264 = sess->priv;
+
+ /* Allocate some memory for the H.264 decoder's state */
+ h264->workspace_vaddr = dma_alloc_coherent(core->dev, SIZE_WORKSPACE,
+ &h264->workspace_paddr, GFP_KERNEL);
+ if (!h264->workspace_vaddr) {
+ dev_err(core->dev, "Failed to alloc H.264 Workspace\n");
+ return -ENOMEM;
+ }
+
+ /* Allocate some memory for the H.264 SEI dump */
+ h264->sei_vaddr = dma_alloc_coherent(core->dev, SIZE_SEI,
+ &h264->sei_paddr, GFP_KERNEL);
+ if (!h264->sei_vaddr) {
+ dev_err(core->dev, "Failed to alloc H.264 SEI\n");
+ return -ENOMEM;
+ }
+
+ amvdec_write_dos_bits(core, POWER_CTL_VLD, BIT(9) | BIT(6));
+
+ workspace_offset = h264->workspace_paddr - WORKSPACE_BUF_OFFSET;
+ amvdec_write_dos(core, AV_SCRATCH_1, workspace_offset);
+ amvdec_write_dos(core, AV_SCRATCH_G, h264->ext_fw_paddr);
+ amvdec_write_dos(core, AV_SCRATCH_I, h264->sei_paddr - workspace_offset);
+
+ /* Enable "error correction" */
+ amvdec_write_dos(core, AV_SCRATCH_F,
+ (amvdec_read_dos(core, AV_SCRATCH_F) & 0xffffffc3) |
+ BIT(4) | BIT(7));
+
+ amvdec_write_dos(core, MDEC_PIC_DC_THRESH, 0x404038aa);
+
+ return 0;
+}
+
+static int codec_h264_stop(struct amvdec_session *sess)
+{
+ struct codec_h264 *h264 = sess->priv;
+ struct amvdec_core *core = sess->core;
+
+ if (h264->ext_fw_vaddr)
+ dma_free_coherent(core->dev, SIZE_EXT_FW,
+ h264->ext_fw_vaddr, h264->ext_fw_paddr);
+
+ if (h264->workspace_vaddr)
+ dma_free_coherent(core->dev, SIZE_WORKSPACE,
+ h264->workspace_vaddr, h264->workspace_paddr);
+
+ if (h264->ref_vaddr)
+ dma_free_coherent(core->dev, h264->ref_size,
+ h264->ref_vaddr, h264->ref_paddr);
+
+ if (h264->sei_vaddr)
+ dma_free_coherent(core->dev, SIZE_SEI,
+ h264->sei_vaddr, h264->sei_paddr);
+
+ return 0;
+}
+
+static int codec_h264_load_extended_firmware(struct amvdec_session *sess,
+ const u8 *data, u32 len)
+{
+ struct codec_h264 *h264;
+ struct amvdec_core *core = sess->core;
+
+ if (len < SIZE_EXT_FW)
+ return -EINVAL;
+
+ h264 = kzalloc(sizeof(*h264), GFP_KERNEL);
+ if (!h264)
+ return -ENOMEM;
+
+ h264->ext_fw_vaddr = dma_alloc_coherent(core->dev, SIZE_EXT_FW,
+ &h264->ext_fw_paddr, GFP_KERNEL);
+ if (!h264->ext_fw_vaddr) {
+ dev_err(core->dev, "Failed to alloc H.264 extended fw\n");
+ kfree(h264);
+ return -ENOMEM;
+ }
+
+ memcpy(h264->ext_fw_vaddr, data, SIZE_EXT_FW);
+ sess->priv = h264;
+
+ return 0;
+}
+
+static const struct v4l2_fract par_table[] = {
+ { 1, 1 }, { 1, 1 }, { 12, 11 }, { 10, 11 },
+ { 16, 11 }, { 40, 33 }, { 24, 11 }, { 20, 11 },
+ { 32, 11 }, { 80, 33 }, { 18, 11 }, { 15, 11 },
+ { 64, 33 }, { 160, 99 }, { 4, 3 }, { 3, 2 },
+ { 2, 1 }
+};
+
+static void codec_h264_set_par(struct amvdec_session *sess)
+{
+ struct amvdec_core *core = sess->core;
+ u32 seq_info = amvdec_read_dos(core, AV_SCRATCH_2);
+ u32 ar_idc = (seq_info >> AR_IDC_BIT) & AR_IDC_MASK;
+
+ if (!(seq_info & AR_PRESENT_FLAG))
+ return;
+
+ if (ar_idc == AR_EXTEND) {
+ u32 ar_info = amvdec_read_dos(core, AV_SCRATCH_3);
+ sess->pixelaspect.numerator = ar_info & 0xffff;
+ sess->pixelaspect.denominator = (ar_info >> 16) & 0xffff;
+ return;
+ }
+
+ if (ar_idc >= ARRAY_SIZE(par_table))
+ return;
+
+ sess->pixelaspect = par_table[ar_idc];
+}
+
+static void codec_h264_resume(struct amvdec_session *sess)
+{
+ struct amvdec_core *core = sess->core;
+ struct codec_h264 *h264 = sess->priv;
+ u32 mb_width, mb_height, mb_total;
+
+ amvdec_set_canvases(sess, (u32[]){ ANC0_CANVAS_ADDR, 0 },
+ (u32[]){ 24, 0 });
+
+ dev_dbg(core->dev,
+ "max_refs = %u; actual_dpb_size = %u\n",
+ h264->max_refs, sess->num_dst_bufs);
+
+ /* Align to a multiple of 4 macroblocks */
+ mb_width = ALIGN(h264->mb_width, 4);
+ mb_height = ALIGN(h264->mb_height, 4);
+ mb_total = mb_width * mb_height;
+
+ h264->ref_size = mb_total * MB_MV_SIZE * h264->max_refs;
+ h264->ref_vaddr = dma_alloc_coherent(core->dev, h264->ref_size,
+ &h264->ref_paddr, GFP_KERNEL);
+ if (!h264->ref_vaddr) {
+ dev_err(core->dev, "Failed to alloc refs (%u)\n",
+ h264->ref_size);
+ amvdec_abort(sess);
+ return;
+ }
+
+ /* Address to store the references' MVs */
+ amvdec_write_dos(core, AV_SCRATCH_1, h264->ref_paddr);
+ /* End of ref MV */
+ amvdec_write_dos(core, AV_SCRATCH_4, h264->ref_paddr + h264->ref_size);
+
+ amvdec_write_dos(core, AV_SCRATCH_0, (h264->max_refs << 24) |
+ (sess->num_dst_bufs << 16) |
+ ((h264->max_refs - 1) << 8));
+}
+
+/* Configure the H.264 decoder when the parser detected a parameter set change
+ */
+static void codec_h264_src_change(struct amvdec_session *sess)
+{
+ struct amvdec_core *core = sess->core;
+ struct codec_h264 *h264 = sess->priv;
+ u32 parsed_info, mb_total;
+ u32 crop_infor, crop_bottom, crop_right;
+ u32 frame_width, frame_height;
+
+ sess->keyframe_found = 1;
+
+ parsed_info = amvdec_read_dos(core, AV_SCRATCH_1);
+
+ /* Total number of 16x16 macroblocks */
+ mb_total = (parsed_info >> MB_TOTAL_BIT) & MB_TOTAL_MASK;
+ /* Number of macroblocks per line */
+ h264->mb_width = parsed_info & MB_WIDTH_MASK;
+ /* Number of macroblock lines */
+ h264->mb_height = mb_total / h264->mb_width;
+
+ h264->max_refs = ((parsed_info >> MAX_REF_BIT) & MAX_REF_MASK) + 1;
+
+ crop_infor = amvdec_read_dos(core, AV_SCRATCH_6);
+ crop_bottom = (crop_infor & 0xff);
+ crop_right = (crop_infor >> 16) & 0xff;
+
+ frame_width = h264->mb_width * 16 - crop_right;
+ frame_height = h264->mb_height * 16 - crop_bottom;
+
+ dev_info(core->dev, "frame: %ux%u; crop: %u %u\n",
+ frame_width, frame_height, crop_right, crop_bottom);
+
+ codec_h264_set_par(sess);
+ amvdec_src_change(sess, frame_width, frame_height, h264->max_refs + 5);
+}
+
+/**
+ * The offset is split in half in 2 different registers
+ */
+static u32 get_offset_msb(struct amvdec_core *core, int frame_num)
+{
+ int take_msb = frame_num % 2;
+ int reg_offset = (frame_num / 2) * 4;
+ u32 offset_msb = amvdec_read_dos(core, AV_SCRATCH_A + reg_offset);
+
+ if (take_msb)
+ return offset_msb & 0xffff0000;
+
+ return (offset_msb & 0x0000ffff) << 16;
+}
+
+static void codec_h264_frames_ready(struct amvdec_session *sess, u32 status)
+{
+ struct amvdec_core *core = sess->core;
+ int error_count;
+ int num_frames;
+ int i;
+
+ error_count = amvdec_read_dos(core, AV_SCRATCH_D);
+ num_frames = (status >> 8) & 0xff;
+ if (error_count) {
+ dev_warn(core->dev,
+ "decoder error(s) happened, count %d\n", error_count);
+ amvdec_write_dos(core, AV_SCRATCH_D, 0);
+ }
+
+ for (i = 0; i < num_frames; i++) {
+ u32 frame_status = amvdec_read_dos(core, AV_SCRATCH_1 + i * 4);
+ u32 buffer_index = frame_status & BUF_IDX_MASK;
+ u32 pic_struct = (frame_status >> PIC_STRUCT_BIT) &
+ PIC_STRUCT_MASK;
+ u32 offset = (frame_status >> OFFSET_BIT) & OFFSET_MASK;
+ u32 field = V4L2_FIELD_NONE;
+
+ /* A buffer decode error means it was decoded,
+ * but part of the picture will have artifacts.
+ * Typical reason is a temporarily corrupted bitstream
+ */
+ if (frame_status & ERROR_FLAG)
+ dev_dbg(core->dev, "Buffer %d decode error\n",
+ buffer_index);
+
+ if (pic_struct == PIC_TOP_BOT)
+ field = V4L2_FIELD_INTERLACED_TB;
+ else if (pic_struct == PIC_BOT_TOP)
+ field = V4L2_FIELD_INTERLACED_BT;
+
+ offset |= get_offset_msb(core, i);
+ amvdec_dst_buf_done_idx(sess, buffer_index, offset, field);
+ }
+}
+
+static irqreturn_t codec_h264_threaded_isr(struct amvdec_session *sess)
+{
+ struct amvdec_core *core = sess->core;
+ u32 status;
+ u32 size;
+ u8 cmd;
+
+ status = amvdec_read_dos(core, AV_SCRATCH_0);
+ cmd = status & CMD_MASK;
+
+ switch (cmd) {
+ case CMD_SRC_CHANGE:
+ codec_h264_src_change(sess);
+ break;
+ case CMD_FRAMES_READY:
+ codec_h264_frames_ready(sess, status);
+ break;
+ case CMD_FATAL_ERROR:
+ dev_err(core->dev, "H.264 decoder fatal error\n");
+ goto abort;
+ case CMD_BAD_WIDTH:
+ size = (amvdec_read_dos(core, AV_SCRATCH_1) + 1) * 16;
+ dev_err(core->dev, "Unsupported video width: %u\n", size);
+ goto abort;
+ case CMD_BAD_HEIGHT:
+ size = (amvdec_read_dos(core, AV_SCRATCH_1) + 1) * 16;
+ dev_err(core->dev, "Unsupported video height: %u\n", size);
+ goto abort;
+ case 0: /* Unused but not worth printing for */
+ case 9:
+ break;
+ default:
+ dev_info(core->dev, "Unexpected H264 ISR: %08X\n", cmd);
+ break;
+ }
+
+ if (cmd && cmd != CMD_SRC_CHANGE)
+ amvdec_write_dos(core, AV_SCRATCH_0, 0);
+
+ /* Decoder has some SEI data for us ; ignore */
+ if (amvdec_read_dos(core, AV_SCRATCH_J) & SEI_DATA_READY)
+ amvdec_write_dos(core, AV_SCRATCH_J, 0);
+
+ return IRQ_HANDLED;
+abort:
+ amvdec_abort(sess);
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t codec_h264_isr(struct amvdec_session *sess)
+{
+ struct amvdec_core *core = sess->core;
+
+ amvdec_write_dos(core, ASSIST_MBOX1_CLR_REG, 1);
+
+ return IRQ_WAKE_THREAD;
+}
+
+struct amvdec_codec_ops codec_h264_ops = {
+ .start = codec_h264_start,
+ .stop = codec_h264_stop,
+ .load_extended_firmware = codec_h264_load_extended_firmware,
+ .isr = codec_h264_isr,
+ .threaded_isr = codec_h264_threaded_isr,
+ .can_recycle = codec_h264_can_recycle,
+ .recycle = codec_h264_recycle,
+ .eos_sequence = codec_h264_eos_sequence,
+ .resume = codec_h264_resume,
+};
diff --git a/drivers/media/platform/meson/vdec/codec_h264.h b/drivers/media/platform/meson/vdec/codec_h264.h
new file mode 100644
index 0000000..7a15976
--- /dev/null
+++ b/drivers/media/platform/meson/vdec/codec_h264.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2018 Maxime Jourdan <maxi.jourdan@wanadoo.fr>
+ */
+
+#ifndef __MESON_VDEC_CODEC_H264_H_
+#define __MESON_VDEC_CODEC_H264_H_
+
+#include "vdec.h"
+
+extern struct amvdec_codec_ops codec_h264_ops;
+
+#endif
\ No newline at end of file
diff --git a/drivers/media/platform/meson/vdec/vdec_platform.c b/drivers/media/platform/meson/vdec/vdec_platform.c
index 291f1ee..baecf59 100644
--- a/drivers/media/platform/meson/vdec/vdec_platform.c
+++ b/drivers/media/platform/meson/vdec/vdec_platform.c
@@ -9,9 +9,20 @@
#include "vdec_1.h"
#include "codec_mpeg12.h"
+#include "codec_h264.h"
static const struct amvdec_format vdec_formats_gxbb[] = {
{
+ .pixfmt = V4L2_PIX_FMT_H264,
+ .min_buffers = 2,
+ .max_buffers = 24,
+ .max_width = 1920,
+ .max_height = 1080,
+ .vdec_ops = &vdec_1_ops,
+ .codec_ops = &codec_h264_ops,
+ .firmware_path = "meson/gxbb/vh264_mc",
+ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, 0 },
+ }, {
.pixfmt = V4L2_PIX_FMT_MPEG1,
.min_buffers = 8,
.max_buffers = 8,
@@ -38,6 +49,16 @@ static const struct amvdec_format vdec_formats_gxbb[] = {
static const struct amvdec_format vdec_formats_gxl[] = {
{
+ .pixfmt = V4L2_PIX_FMT_H264,
+ .min_buffers = 2,
+ .max_buffers = 24,
+ .max_width = 3840,
+ .max_height = 2160,
+ .vdec_ops = &vdec_1_ops,
+ .codec_ops = &codec_h264_ops,
+ .firmware_path = "meson/gxl/vh264_mc",
+ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, 0 },
+ }, {
.pixfmt = V4L2_PIX_FMT_MPEG1,
.min_buffers = 8,
.max_buffers = 8,
@@ -64,6 +85,16 @@ static const struct amvdec_format vdec_formats_gxl[] = {
static const struct amvdec_format vdec_formats_gxm[] = {
{
+ .pixfmt = V4L2_PIX_FMT_H264,
+ .min_buffers = 2,
+ .max_buffers = 24,
+ .max_width = 3840,
+ .max_height = 2160,
+ .vdec_ops = &vdec_1_ops,
+ .codec_ops = &codec_h264_ops,
+ .firmware_path = "meson/gxm/vh264_mc",
+ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, 0 },
+ }, {
.pixfmt = V4L2_PIX_FMT_MPEG1,
.min_buffers = 8,
.max_buffers = 8,

View File

@ -0,0 +1,313 @@
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 ++++++++++++++++++++++
drivers/media/platform/meson/vdec/codec_mpeg4.h | 13 ++
drivers/media/platform/meson/vdec/vdec_platform.c | 91 ++++++++++++++
4 files changed, 244 insertions(+), 1 deletion(-)
create mode 100644 drivers/media/platform/meson/vdec/codec_mpeg4.c
create mode 100644 drivers/media/platform/meson/vdec/codec_mpeg4.h
diff --git a/drivers/media/platform/meson/vdec/Makefile b/drivers/media/platform/meson/vdec/Makefile
index 01dc960..bb7a134 100644
--- a/drivers/media/platform/meson/vdec/Makefile
+++ b/drivers/media/platform/meson/vdec/Makefile
@@ -3,6 +3,6 @@
meson-vdec-objs = esparser.o vdec.o vdec_ctrls.o vdec_helpers.o vdec_platform.o
meson-vdec-objs += vdec_1.o
-meson-vdec-objs += codec_mpeg12.o codec_h264.o
+meson-vdec-objs += codec_mpeg12.o codec_h264.o codec_mpeg4.o
obj-$(CONFIG_VIDEO_MESON_VDEC) += meson-vdec.o
diff --git a/drivers/media/platform/meson/vdec/codec_mpeg4.c b/drivers/media/platform/meson/vdec/codec_mpeg4.c
new file mode 100644
index 0000000..1d574e5
--- /dev/null
+++ b/drivers/media/platform/meson/vdec/codec_mpeg4.c
@@ -0,0 +1,139 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Maxime Jourdan <maxi.jourdan@wanadoo.fr>
+ */
+
+#include <media/v4l2-mem2mem.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "vdec_helpers.h"
+#include "dos_regs.h"
+
+#define SIZE_WORKSPACE SZ_1M
+/* Offset added by firmware, to substract from workspace paddr */
+#define DCAC_BUFF_START_IP 0x02b00000
+
+/* map firmware registers to known MPEG4 functions */
+#define MREG_BUFFERIN AV_SCRATCH_8
+#define MREG_BUFFEROUT AV_SCRATCH_9
+#define MP4_NOT_CODED_CNT AV_SCRATCH_A
+#define MP4_OFFSET_REG AV_SCRATCH_C
+#define MEM_OFFSET_REG AV_SCRATCH_F
+#define MREG_FATAL_ERROR AV_SCRATCH_L
+
+#define BUF_IDX_MASK GENMASK(2, 0)
+#define INTERLACE_FLAG BIT(7)
+#define TOP_FIELD_FIRST_FLAG BIT(6)
+
+struct codec_mpeg4 {
+ /* Buffer for the MPEG4 Workspace */
+ void *workspace_vaddr;
+ dma_addr_t workspace_paddr;
+};
+
+static int codec_mpeg4_can_recycle(struct amvdec_core *core)
+{
+ return !amvdec_read_dos(core, MREG_BUFFERIN);
+}
+
+static void codec_mpeg4_recycle(struct amvdec_core *core, u32 buf_idx)
+{
+ amvdec_write_dos(core, MREG_BUFFERIN, ~BIT(buf_idx));
+}
+
+static int codec_mpeg4_start(struct amvdec_session *sess) {
+ struct amvdec_core *core = sess->core;
+ struct codec_mpeg4 *mpeg4 = sess->priv;
+ int ret;
+
+ mpeg4 = kzalloc(sizeof(*mpeg4), GFP_KERNEL);
+ if (!mpeg4)
+ return -ENOMEM;
+
+ /* Allocate some memory for the MPEG4 decoder's state */
+ mpeg4->workspace_vaddr = dma_alloc_coherent(core->dev, SIZE_WORKSPACE,
+ &mpeg4->workspace_paddr,
+ GFP_KERNEL);
+ if (!mpeg4->workspace_vaddr) {
+ dev_err(core->dev, "Failed to request MPEG4 Workspace\n");
+ ret = -ENOMEM;
+ goto free_mpeg4;
+ }
+
+ /* Canvas regs: AV_SCRATCH_0-AV_SCRATCH_4;AV_SCRATCH_G-AV_SCRATCH_J */
+ amvdec_set_canvases(sess, (u32[]){ AV_SCRATCH_0, AV_SCRATCH_G, 0 },
+ (u32[]){ 4, 4, 0 });
+
+ amvdec_write_dos(core, MEM_OFFSET_REG,
+ mpeg4->workspace_paddr - DCAC_BUFF_START_IP);
+ amvdec_write_dos(core, PSCALE_CTRL, 0);
+ amvdec_write_dos(core, MP4_NOT_CODED_CNT, 0);
+ amvdec_write_dos(core, MREG_BUFFERIN, 0);
+ amvdec_write_dos(core, MREG_BUFFEROUT, 0);
+ amvdec_write_dos(core, MREG_FATAL_ERROR, 0);
+ amvdec_write_dos(core, MDEC_PIC_DC_THRESH, 0x404038aa);
+
+ sess->keyframe_found = 1;
+ sess->priv = mpeg4;
+
+ return 0;
+
+free_mpeg4:
+ kfree(mpeg4);
+ return ret;
+}
+
+static int codec_mpeg4_stop(struct amvdec_session *sess)
+{
+ struct codec_mpeg4 *mpeg4 = sess->priv;
+ struct amvdec_core *core = sess->core;
+
+ if (mpeg4->workspace_vaddr) {
+ dma_free_coherent(core->dev, SIZE_WORKSPACE,
+ mpeg4->workspace_vaddr,
+ mpeg4->workspace_paddr);
+ mpeg4->workspace_vaddr = 0;
+ }
+
+ return 0;
+}
+
+static irqreturn_t codec_mpeg4_isr(struct amvdec_session *sess)
+{
+ struct amvdec_core *core = sess->core;
+ u32 reg;
+ u32 buffer_index;
+ u32 field = V4L2_FIELD_NONE;
+
+ reg = amvdec_read_dos(core, MREG_FATAL_ERROR);
+ if (reg == 1) {
+ dev_err(core->dev, "mpeg4 fatal error\n");
+ amvdec_abort(sess);
+ return IRQ_HANDLED;
+ }
+
+ reg = amvdec_read_dos(core, MREG_BUFFEROUT);
+ if (!reg)
+ goto end;
+
+ buffer_index = reg & BUF_IDX_MASK;
+ if (reg & INTERLACE_FLAG)
+ field = (reg & TOP_FIELD_FIRST_FLAG) ?
+ V4L2_FIELD_INTERLACED_TB :
+ V4L2_FIELD_INTERLACED_BT;
+
+ amvdec_dst_buf_done_idx(sess, buffer_index, -1, field);
+ amvdec_write_dos(core, MREG_BUFFEROUT, 0);
+
+end:
+ amvdec_write_dos(core, ASSIST_MBOX1_CLR_REG, 1);
+ return IRQ_HANDLED;
+}
+
+struct amvdec_codec_ops codec_mpeg4_ops = {
+ .start = codec_mpeg4_start,
+ .stop = codec_mpeg4_stop,
+ .isr = codec_mpeg4_isr,
+ .can_recycle = codec_mpeg4_can_recycle,
+ .recycle = codec_mpeg4_recycle,
+};
diff --git a/drivers/media/platform/meson/vdec/codec_mpeg4.h b/drivers/media/platform/meson/vdec/codec_mpeg4.h
new file mode 100644
index 0000000..b91b26413
--- /dev/null
+++ b/drivers/media/platform/meson/vdec/codec_mpeg4.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2018 Maxime Jourdan <maxi.jourdan@wanadoo.fr>
+ */
+
+#ifndef __MESON_VDEC_CODEC_MPEG4_H_
+#define __MESON_VDEC_CODEC_MPEG4_H_
+
+#include "vdec.h"
+
+extern struct amvdec_codec_ops codec_mpeg4_ops;
+
+#endif
\ No newline at end of file
diff --git a/drivers/media/platform/meson/vdec/vdec_platform.c b/drivers/media/platform/meson/vdec/vdec_platform.c
index baecf59..80b43fd 100644
--- a/drivers/media/platform/meson/vdec/vdec_platform.c
+++ b/drivers/media/platform/meson/vdec/vdec_platform.c
@@ -10,9 +10,40 @@
#include "vdec_1.h"
#include "codec_mpeg12.h"
#include "codec_h264.h"
+#include "codec_mpeg4.h"
static const struct amvdec_format vdec_formats_gxbb[] = {
{
+ .pixfmt = V4L2_PIX_FMT_MPEG4,
+ .min_buffers = 8,
+ .max_buffers = 8,
+ .max_width = 1920,
+ .max_height = 1080,
+ .vdec_ops = &vdec_1_ops,
+ .codec_ops = &codec_mpeg4_ops,
+ .firmware_path = "meson/gx/vmpeg4_mc_5",
+ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_YUV420M, 0 },
+ }, {
+ .pixfmt = V4L2_PIX_FMT_H263,
+ .min_buffers = 8,
+ .max_buffers = 8,
+ .max_width = 1920,
+ .max_height = 1080,
+ .vdec_ops = &vdec_1_ops,
+ .codec_ops = &codec_mpeg4_ops,
+ .firmware_path = "meson/gx/h263_mc",
+ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_YUV420M, 0 },
+ }, {
+ .pixfmt = V4L2_PIX_FMT_XVID,
+ .min_buffers = 8,
+ .max_buffers = 8,
+ .max_width = 1920,
+ .max_height = 1080,
+ .vdec_ops = &vdec_1_ops,
+ .codec_ops = &codec_mpeg4_ops,
+ .firmware_path = "meson/gx/vmpeg4_mc_5",
+ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_YUV420M, 0 },
+ }, {
.pixfmt = V4L2_PIX_FMT_H264,
.min_buffers = 2,
.max_buffers = 24,
@@ -49,6 +80,36 @@ static const struct amvdec_format vdec_formats_gxbb[] = {
static const struct amvdec_format vdec_formats_gxl[] = {
{
+ .pixfmt = V4L2_PIX_FMT_MPEG4,
+ .min_buffers = 8,
+ .max_buffers = 8,
+ .max_width = 1920,
+ .max_height = 1080,
+ .vdec_ops = &vdec_1_ops,
+ .codec_ops = &codec_mpeg4_ops,
+ .firmware_path = "meson/gx/vmpeg4_mc_5",
+ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_YUV420M, 0 },
+ }, {
+ .pixfmt = V4L2_PIX_FMT_H263,
+ .min_buffers = 8,
+ .max_buffers = 8,
+ .max_width = 1920,
+ .max_height = 1080,
+ .vdec_ops = &vdec_1_ops,
+ .codec_ops = &codec_mpeg4_ops,
+ .firmware_path = "meson/gx/h263_mc",
+ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_YUV420M, 0 },
+ }, {
+ .pixfmt = V4L2_PIX_FMT_XVID,
+ .min_buffers = 8,
+ .max_buffers = 8,
+ .max_width = 1920,
+ .max_height = 1080,
+ .vdec_ops = &vdec_1_ops,
+ .codec_ops = &codec_mpeg4_ops,
+ .firmware_path = "meson/gx/vmpeg4_mc_5",
+ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_YUV420M, 0 },
+ }, {
.pixfmt = V4L2_PIX_FMT_H264,
.min_buffers = 2,
.max_buffers = 24,
@@ -85,6 +146,36 @@ static const struct amvdec_format vdec_formats_gxl[] = {
static const struct amvdec_format vdec_formats_gxm[] = {
{
+ .pixfmt = V4L2_PIX_FMT_MPEG4,
+ .min_buffers = 8,
+ .max_buffers = 8,
+ .max_width = 1920,
+ .max_height = 1080,
+ .vdec_ops = &vdec_1_ops,
+ .codec_ops = &codec_mpeg4_ops,
+ .firmware_path = "meson/gx/vmpeg4_mc_5",
+ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_YUV420M, 0 },
+ }, {
+ .pixfmt = V4L2_PIX_FMT_H263,
+ .min_buffers = 8,
+ .max_buffers = 8,
+ .max_width = 1920,
+ .max_height = 1080,
+ .vdec_ops = &vdec_1_ops,
+ .codec_ops = &codec_mpeg4_ops,
+ .firmware_path = "meson/gx/h263_mc",
+ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_YUV420M, 0 },
+ }, {
+ .pixfmt = V4L2_PIX_FMT_XVID,
+ .min_buffers = 8,
+ .max_buffers = 8,
+ .max_width = 1920,
+ .max_height = 1080,
+ .vdec_ops = &vdec_1_ops,
+ .codec_ops = &codec_mpeg4_ops,
+ .firmware_path = "meson/gx/vmpeg4_mc_5",
+ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_YUV420M, 0 },
+ }, {
.pixfmt = V4L2_PIX_FMT_H264,
.min_buffers = 2,
.max_buffers = 24,

View File

@ -0,0 +1,253 @@
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 ++++++++++++++++++++++
drivers/media/platform/meson/vdec/codec_mjpeg.h | 13 ++
drivers/media/platform/meson/vdec/vdec_platform.c | 31 +++++
4 files changed, 185 insertions(+), 1 deletion(-)
create mode 100644 drivers/media/platform/meson/vdec/codec_mjpeg.c
create mode 100644 drivers/media/platform/meson/vdec/codec_mjpeg.h
diff --git a/drivers/media/platform/meson/vdec/Makefile b/drivers/media/platform/meson/vdec/Makefile
index bb7a134..acf07f3 100644
--- a/drivers/media/platform/meson/vdec/Makefile
+++ b/drivers/media/platform/meson/vdec/Makefile
@@ -3,6 +3,6 @@
meson-vdec-objs = esparser.o vdec.o vdec_ctrls.o vdec_helpers.o vdec_platform.o
meson-vdec-objs += vdec_1.o
-meson-vdec-objs += codec_mpeg12.o codec_h264.o codec_mpeg4.o
+meson-vdec-objs += codec_mpeg12.o codec_h264.o codec_mpeg4.o codec_mjpeg.o
obj-$(CONFIG_VIDEO_MESON_VDEC) += meson-vdec.o
diff --git a/drivers/media/platform/meson/vdec/codec_mjpeg.c b/drivers/media/platform/meson/vdec/codec_mjpeg.c
new file mode 100644
index 0000000..abea9e3
--- /dev/null
+++ b/drivers/media/platform/meson/vdec/codec_mjpeg.c
@@ -0,0 +1,140 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Maxime Jourdan <maxi.jourdan@wanadoo.fr>
+ */
+
+#include <media/v4l2-mem2mem.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "vdec_helpers.h"
+#include "dos_regs.h"
+
+/* map FW registers to known MJPEG functions */
+#define MREG_DECODE_PARAM AV_SCRATCH_2
+#define MREG_TO_AMRISC AV_SCRATCH_8
+#define MREG_FROM_AMRISC AV_SCRATCH_9
+#define MREG_FRAME_OFFSET AV_SCRATCH_A
+
+static int codec_mjpeg_can_recycle(struct amvdec_core *core)
+{
+ return !amvdec_read_dos(core, MREG_TO_AMRISC);
+}
+
+static void codec_mjpeg_recycle(struct amvdec_core *core, u32 buf_idx)
+{
+ amvdec_write_dos(core, MREG_TO_AMRISC, buf_idx + 1);
+}
+
+/* 4 point triangle */
+static const uint32_t filt_coef[] = {
+ 0x20402000, 0x20402000, 0x1f3f2101, 0x1f3f2101,
+ 0x1e3e2202, 0x1e3e2202, 0x1d3d2303, 0x1d3d2303,
+ 0x1c3c2404, 0x1c3c2404, 0x1b3b2505, 0x1b3b2505,
+ 0x1a3a2606, 0x1a3a2606, 0x19392707, 0x19392707,
+ 0x18382808, 0x18382808, 0x17372909, 0x17372909,
+ 0x16362a0a, 0x16362a0a, 0x15352b0b, 0x15352b0b,
+ 0x14342c0c, 0x14342c0c, 0x13332d0d, 0x13332d0d,
+ 0x12322e0e, 0x12322e0e, 0x11312f0f, 0x11312f0f,
+ 0x10303010
+};
+
+static void codec_mjpeg_init_scaler(struct amvdec_core *core)
+{
+ int i;
+
+ /* PSCALE cbus bmem enable */
+ amvdec_write_dos(core, PSCALE_CTRL, 0xc000);
+
+ amvdec_write_dos(core, PSCALE_BMEM_ADDR, 0);
+ for (i = 0; i < ARRAY_SIZE(filt_coef); ++i) {
+ amvdec_write_dos(core, PSCALE_BMEM_DAT, 0);
+ amvdec_write_dos(core, PSCALE_BMEM_DAT, filt_coef[i]);
+ }
+
+ amvdec_write_dos(core, PSCALE_BMEM_ADDR, 74);
+ amvdec_write_dos(core, PSCALE_BMEM_DAT, 0x0008);
+ amvdec_write_dos(core, PSCALE_BMEM_DAT, 0x60000000);
+
+ amvdec_write_dos(core, PSCALE_BMEM_ADDR, 82);
+ amvdec_write_dos(core, PSCALE_BMEM_DAT, 0x0008);
+ amvdec_write_dos(core, PSCALE_BMEM_DAT, 0x60000000);
+
+ amvdec_write_dos(core, PSCALE_BMEM_ADDR, 78);
+ amvdec_write_dos(core, PSCALE_BMEM_DAT, 0x0008);
+ amvdec_write_dos(core, PSCALE_BMEM_DAT, 0x60000000);
+
+ amvdec_write_dos(core, PSCALE_BMEM_ADDR, 86);
+ amvdec_write_dos(core, PSCALE_BMEM_DAT, 0x0008);
+ amvdec_write_dos(core, PSCALE_BMEM_DAT, 0x60000000);
+
+ amvdec_write_dos(core, PSCALE_BMEM_ADDR, 73);
+ amvdec_write_dos(core, PSCALE_BMEM_DAT, 0x10000);
+ amvdec_write_dos(core, PSCALE_BMEM_ADDR, 81);
+ amvdec_write_dos(core, PSCALE_BMEM_DAT, 0x10000);
+
+ amvdec_write_dos(core, PSCALE_BMEM_ADDR, 77);
+ amvdec_write_dos(core, PSCALE_BMEM_DAT, 0x10000);
+ amvdec_write_dos(core, PSCALE_BMEM_ADDR, 85);
+ amvdec_write_dos(core, PSCALE_BMEM_DAT, 0x10000);
+
+ amvdec_write_dos(core, PSCALE_RST, 0x7);
+ amvdec_write_dos(core, PSCALE_RST, 0);
+}
+
+static int codec_mjpeg_start(struct amvdec_session *sess)
+{
+ struct amvdec_core *core = sess->core;
+
+ amvdec_write_dos(core, AV_SCRATCH_0, 12);
+ amvdec_write_dos(core, AV_SCRATCH_1, 0x031a);
+
+ amvdec_set_canvases(sess, (u32[]){ AV_SCRATCH_4, 0 },
+ (u32[]){ 4, 0 });
+ codec_mjpeg_init_scaler(core);
+
+ amvdec_write_dos(core, MREG_TO_AMRISC, 0);
+ amvdec_write_dos(core, MREG_FROM_AMRISC, 0);
+ amvdec_write_dos(core, MCPU_INTR_MSK, 0xffff);
+ amvdec_write_dos(core, MREG_DECODE_PARAM,
+ (sess->height << 4) | 0x8000);
+ amvdec_write_dos(core, VDEC_ASSIST_AMR1_INT8, 8);
+
+ /* Intra-only codec */
+ sess->keyframe_found = 1;
+
+ return 0;
+}
+
+static int codec_mjpeg_stop(struct amvdec_session *sess)
+{
+ return 0;
+}
+
+static irqreturn_t codec_mjpeg_isr(struct amvdec_session *sess)
+{
+ struct amvdec_core *core = sess->core;
+ u32 reg;
+ u32 buffer_index;
+ u32 offset;
+
+ amvdec_write_dos(core, ASSIST_MBOX1_CLR_REG, 1);
+
+ reg = amvdec_read_dos(core, MREG_FROM_AMRISC);
+ if (!(reg & 0x7))
+ return IRQ_HANDLED;
+
+ buffer_index = ((reg & 0x7) - 1) & 3;
+ offset = amvdec_read_dos(core, MREG_FRAME_OFFSET);
+ amvdec_dst_buf_done_idx(sess, buffer_index, offset, V4L2_FIELD_NONE);
+
+ amvdec_write_dos(core, MREG_FROM_AMRISC, 0);
+ return IRQ_HANDLED;
+}
+
+struct amvdec_codec_ops codec_mjpeg_ops = {
+ .start = codec_mjpeg_start,
+ .stop = codec_mjpeg_stop,
+ .isr = codec_mjpeg_isr,
+ .can_recycle = codec_mjpeg_can_recycle,
+ .recycle = codec_mjpeg_recycle,
+};
diff --git a/drivers/media/platform/meson/vdec/codec_mjpeg.h b/drivers/media/platform/meson/vdec/codec_mjpeg.h
new file mode 100644
index 0000000..cc1cf73
--- /dev/null
+++ b/drivers/media/platform/meson/vdec/codec_mjpeg.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2018 Maxime Jourdan <maxi.jourdan@wanadoo.fr>
+ */
+
+#ifndef __MESON_VDEC_CODEC_MJPEG_H_
+#define __MESON_VDEC_CODEC_MJPEG_H_
+
+#include "vdec.h"
+
+extern struct amvdec_codec_ops codec_mjpeg_ops;
+
+#endif
\ No newline at end of file
diff --git a/drivers/media/platform/meson/vdec/vdec_platform.c b/drivers/media/platform/meson/vdec/vdec_platform.c
index 80b43fd..61def15 100644
--- a/drivers/media/platform/meson/vdec/vdec_platform.c
+++ b/drivers/media/platform/meson/vdec/vdec_platform.c
@@ -11,9 +11,20 @@
#include "codec_mpeg12.h"
#include "codec_h264.h"
#include "codec_mpeg4.h"
+#include "codec_mjpeg.h"
static const struct amvdec_format vdec_formats_gxbb[] = {
{
+ .pixfmt = V4L2_PIX_FMT_MJPEG,
+ .min_buffers = 4,
+ .max_buffers = 4,
+ .max_width = 1920,
+ .max_height = 1080,
+ .vdec_ops = &vdec_1_ops,
+ .codec_ops = &codec_mjpeg_ops,
+ .firmware_path = "meson/gx/vmjpeg_mc",
+ .pixfmts_cap = { V4L2_PIX_FMT_YUV420M, 0 },
+ }, {
.pixfmt = V4L2_PIX_FMT_MPEG4,
.min_buffers = 8,
.max_buffers = 8,
@@ -80,6 +91,16 @@ static const struct amvdec_format vdec_formats_gxbb[] = {
static const struct amvdec_format vdec_formats_gxl[] = {
{
+ .pixfmt = V4L2_PIX_FMT_MJPEG,
+ .min_buffers = 4,
+ .max_buffers = 4,
+ .max_width = 1920,
+ .max_height = 1080,
+ .vdec_ops = &vdec_1_ops,
+ .codec_ops = &codec_mjpeg_ops,
+ .firmware_path = "meson/gx/vmjpeg_mc",
+ .pixfmts_cap = { V4L2_PIX_FMT_YUV420M, 0 },
+ }, {
.pixfmt = V4L2_PIX_FMT_MPEG4,
.min_buffers = 8,
.max_buffers = 8,
@@ -146,6 +167,16 @@ static const struct amvdec_format vdec_formats_gxl[] = {
static const struct amvdec_format vdec_formats_gxm[] = {
{
+ .pixfmt = V4L2_PIX_FMT_MJPEG,
+ .min_buffers = 4,
+ .max_buffers = 4,
+ .max_width = 1920,
+ .max_height = 1080,
+ .vdec_ops = &vdec_1_ops,
+ .codec_ops = &codec_mjpeg_ops,
+ .firmware_path = "meson/gx/vmjpeg_mc",
+ .pixfmts_cap = { V4L2_PIX_FMT_YUV420M, 0 },
+ }, {
.pixfmt = V4L2_PIX_FMT_MPEG4,
.min_buffers = 8,
.max_buffers = 8,

View File

@ -0,0 +1,42 @@
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
On the Khadas VIM2 (GXM) and LePotato (GXL) board there are problems
with reboot; e.g. a ~60 second delay between issuing reboot and the
board power cycling (and in some OS configurations reboot will fail
and require manual power cycling).
Similar to 'commit c987ac6f1f088663b6dad39281071aeb31d450a8 ("clk:
meson-gxbb: set fclk_div2 as CLK_IS_CRITICAL")' the SCPI Cortex-M4
Co-Processor seems to depend on FCLK_DIV3 being operational.
Bisect gives 'commit 05f814402d6174369b3b29832cbb5eb5ed287059 ("clk:
meson: add fdiv clock gates") between 4.16 and 4.16-rc1 as the first
bad commit. This added support for the missing clock gates before the
fixed PLL fixed dividers (FCLK_DIVx) and the clock framework which
disabled all the unused fixed dividers, thus it disabled a critical
clock path for the SCPI Co-Processor.
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 6628ffa..01f7615 100644
--- a/drivers/clk/meson/gxbb.c
+++ b/drivers/clk/meson/gxbb.c
@@ -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,
+ .flags = CLK_IS_CRITICAL,
},
};

View File

@ -1,7 +1,7 @@
# Maintainer: He Yangxuan <yangxuan8282@gmail.com>
pkgname=linux-amlogic
pkgver=4.18.14
pkgver=4.19.8
case $pkgver in
*.*.*) _kernver=${pkgver%.*};;
*.*) _kernver=${pkgver};;
@ -9,7 +9,7 @@ esac
pkgrel=0
pkgdesc="Linux kernel for Amlogic"
url=https://github.com/torvalds/linux
_commit=e7d199e92956587695510d147c8de795f944cec9
_commit=178574b66509c9ff7df4ad26c84a8884567e93b4
depends="mkinitfs"
_depends_dev="perl gmp-dev elfutils-dev bash"
makedepends="$_depends_dev sed installkernel bc linux-headers linux-firmware openssl-dev bison flex"
@ -17,40 +17,63 @@ options="!strip !check"
source="$url/archive/${_commit}.tar.gz
config-changes-amlogic.aarch64
defconfig
0001-ARM64-dts-meson-gxbb-nanopi-k2-Add-HDMI-CEC-and-CVBS.patch
0002-drm-meson-Make-DMT-timings-parameters-and-pixel-cloc.patch
0003-ARM64-defconfig-enable-CEC-support.patch
0004-clk-meson-switch-gxbb-cts-amclk-div-to-the-generic-d.patch
0005-clk-meson-remove-unused-clk-audio-divider-driver.patch
0006-ASoC-meson-add-meson-audio-core-driver.patch
0007-ASoC-meson-add-register-definitions.patch
0008-ASoC-meson-add-aiu-i2s-dma-support.patch
0009-ASoC-meson-add-initial-i2s-dai-support.patch
0010-ASoC-meson-add-aiu-spdif-dma-support.patch
0011-ASoC-meson-add-initial-spdif-dai-support.patch
0012-ARM64-defconfig-enable-audio-support-for-meson-SoCs-.patch
0013-ARM64-dts-meson-gx-add-audio-controller-nodes.patch
0014-snd-meson-activate-HDMI-audio-path.patch
0015-drm-meson-select-dw-hdmi-i2s-audio-for-meson-hdmi.patch
0016-ARM64-dts-meson-gx-add-sound-dai-cells-to-HDMI-node.patch
0017-ARM64-dts-meson-activate-hdmi-audio-HDMI-enabled-boa.patch
0018-drm-bridge-dw-hdmi-Use-AUTO-CTS-setup-mode-when-non-.patch
0019-drm-meson-Call-drm_crtc_vblank_on-drm_crtc_vblank_of.patch
0020-media-platform-meson-ao-cec-make-busy-TX-warning-sil.patch
0021-soc-amlogic-add-meson-canvas-driver.patch
0022-dt-bindings-soc-amlogic-add-meson-canvas-documentati.patch
0023-ARM64-dts-meson-gx-add-dmcbus-and-canvas-nodes.patch
0024-drm-meson-convert-to-the-new-canvas-module.patch
0025-WIP-drm-meson-Support-Overlay-plane-for-video-render.patch
0026-media-meson-add-v4l2-m2m-video-decoder-driver.patch
0027-ARM64-dts-meson-gx-add-vdec-entry.patch
0001-libretech-cc-disable-CVBS-connector.patch
0001-ARM64-dts-meson-add-vdec-entries.patch
0001-ARM64-defconfig-enable-CEC-support.patch
0002-ASoC-meson-add-meson-audio-core-driver.patch
0003-ASoC-meson-add-register-definitions.patch
0004-ASoC-meson-add-aiu-i2s-dma-support.patch
0005-ASoC-meson-add-initial-i2s-dai-support.patch
0006-ASoC-meson-add-aiu-spdif-dma-support.patch
0007-ASoC-meson-add-initial-spdif-dai-support.patch
0008-ARM64-defconfig-enable-audio-support-for-meson-SoCs-.patch
0009-ARM64-dts-meson-gx-add-audio-controller-nodes.patch
0010-snd-meson-activate-HDMI-audio-path.patch
0011-drm-meson-select-dw-hdmi-i2s-audio-for-meson-hdmi.patch
0012-ARM64-dts-meson-gx-add-sound-dai-cells-to-HDMI-node.patch
0013-ARM64-dts-meson-activate-hdmi-audio-HDMI-enabled-boa.patch
0014-drm-bridge-dw-hdmi-Use-AUTO-CTS-setup-mode-when-non-.patch
0017-soc-amlogic-add-meson-canvas-driver.patch
0018-ARM64-dts-meson-gx-add-dmcbus-and-canvas-nodes.patch
0020-drm-meson-Use-optional-canvas-provider.patch
0021-arm64-dts-meson-gx-Add-canvas-provider-node-to-the-v.patch
0022-drm-meson-Support-Overlay-plane-for-video-rendering.patch
0023-drm-meson-move-OSD-scaler-management-into-plane-atom.patch
0024-drm-meson-Add-primary-plane-scaling.patch
0026-pinctrl-meson-gxl-remove-invalid-GPIOX-tsin_a-pins.patch
0027-arm64-dts-meson-gx-Add-hdmi_5v-regulator-as-hdmi-tx-.patch
0028-arm64-dts-meson-gxl-libretech-cc-fix-GPIO-lines-name.patch
0029-arm64-dts-meson-gxbb-nanopi-k2-fix-GPIO-lines-names.patch
0030-arm64-dts-meson-gxbb-odroidc2-fix-GPIO-lines-names.patch
0031-arm64-dts-meson-gxl-khadas-vim-fix-GPIO-lines-names.patch
0032-drm-meson-Add-support-for-VIC-alternate-timings.patch
0033-media-meson-add-v4l2-m2m-video-decoder-driver.patch
0034-MAINTAINERS-Add-meson-video-decoder.patch
0035-arm64-dts-meson-gx-add-vdec-entry.patch
0036-arm64-dts-meson-add-vdec-entries.patch
0037-meson-vdec-introduce-controls-and-V4L2_CID_MIN_BUFFE.patch
0038-media-videodev2-add-V4L2_FMT_FLAG_NO_SOURCE_CHANGE.patch
0039-meson-vdec-allow-subscribing-to-V4L2_EVENT_SOURCE_CH.patch
0040-media-meson-vdec-add-H.264-decoding-support.patch
0041-media-meson-vdec-add-MPEG4-decoding-support.patch
0042-media-meson-vdec-add-MJPEG-decoding-support.patch
0043-clk-meson-gxbb-set-fclk_div3-as-CLK_IS_CRITICAL.patch
0008-drm-meson-Add-HDMI-1.4-4k-modes.patch
0009-drm-meson-Use-drm_fbdev_generic_setup.patch
0010-fixup-drm-meson-Use-optional-canvas-provider.patch
0012-drm-meson-add-support-for-1080p25-mode.patch
0014-drm-bridge-dw-hdmi-Add-SCDC-and-TMDS-Scrambling-supp.patch
0015-drm-meson-add-HDMI-div40-TMDS-mode.patch
0016-drm-meson-add-support-for-HDMI2.0-2160p-modes.patch
0017-drm-bridge-dw-hdmi-add-support-for-YUV420-output.patch
0018-drm-bridge-dw-hdmi-support-dynamically-get-input-out.patch
0019-drm-bridge-dw-hdmi-allow-ycbcr420-modes-for-0x200a.patch
0020-drm-meson-Add-YUV420-output-support.patch
0021-drm-meson-Output-in-YUV444-if-sink-supports-it.patch
0023-drm-meson-Fix-an-Alpha-Primary-Plane-bug-on-Meson-GX.patch
0001-arm64-dts-meson-Fix-IRQ-trigger-type-for-macirq.patch
0001-drm-meson-fix-max-mode_config-height-width.patch
add-phicomm-n1.patch
bt-btbcm.patch
brcmfmac-Disable-power-management.patch
offset.patch
off_error_text_offset.patch
text_offset.patch
"
subpackages=""
arch="aarch64"
@ -274,40 +297,63 @@ _dev() {
"$subpkgdir"/lib/modules/${_abi_release}/build
}
sha512sums="b65dc14801b987b4d8ca786aa6571da12fd929ab147ed2f71f366b32313cd72d3047830e502b3fe51f9f1f3963d46b7f5b45ed937a4bdfee14dc216b32de2d3a e7d199e92956587695510d147c8de795f944cec9.tar.gz
sha512sums="642e3de14702d3034f9108c7b6661294722f4cf455b9167c349111642586d9a48732070e46092e7084f3ffbc26f01bae50f8da52eeceb7cf0f40e1441f9d895e 178574b66509c9ff7df4ad26c84a8884567e93b4.tar.gz
7186849193386fc06caab6db9ebf3d5b7efe2511f1c3836bb70d713340eb69b1f123f8372f15ee7f8dd61eeff5ce772b35db8557133ef64a2a1a5ca9e7cd30c9 config-changes-amlogic.aarch64
2784f8c05c1c66f2bff73d0cdd415781e6529f269223607c18302803125092e7cb6c94083146deecc3226672f7f4754246cc62808f9384f697782ec55786883d defconfig
94f944448156e435030d84d787d1489cdab4a6733b1fd27cd4ecd1284337d2b3e68bb3f74b3268a4cac01587e96019d4ad2a354c59d1422b6caae3f97849717f 0001-ARM64-dts-meson-gxbb-nanopi-k2-Add-HDMI-CEC-and-CVBS.patch
997fee925f07735e635fdd2d2474500ca5a81a80a7817c079174e2508eec223264c97b79cfc057d6b4e428c4d9392405f79befd242dc9b21e020f544ffd84c9d 0002-drm-meson-Make-DMT-timings-parameters-and-pixel-cloc.patch
3294e40073360e9f6daf3360022a8443bdab960ba0f261e5858e36e7b838af0304888eef9992ef93f67a5dc97f0a26c46f08da1c2f32ca1fe01b9754f55ae975 0003-ARM64-defconfig-enable-CEC-support.patch
02c5a7b99be3a180eb40716735ced4ba5f9da1897cb9132c3376b660ba1c005df60b9da1ad7808f53027b7d37b89ef007c71aa2fdfd5ad77be4425886348c3b2 0004-clk-meson-switch-gxbb-cts-amclk-div-to-the-generic-d.patch
8d4d3bead45b420b0920eb4eb77fc938c2bcb64a3304d5690432aec7a235f348deba4246b737742901102f256313ab34f95caa8932184099ed20baaf23913f6f 0005-clk-meson-remove-unused-clk-audio-divider-driver.patch
7057d93953fe9bb83415ac82fe63bacc64161f295e1340dc8b56330a74655c44e9f7feb621f12b74e7d92497115abd918e7b087bc0ece7d0322e384fbd5acd95 0006-ASoC-meson-add-meson-audio-core-driver.patch
42ba176a6198fae2146f871dc469fb94b40382ff966b167f976d5e28375f4849bda6141b01e786d37cf14ca71ba159ee0a0316ec477150040517cebf0f638334 0007-ASoC-meson-add-register-definitions.patch
720c21f11514edba0164ecfe260b8d2409ccea5eaaf4d98013e42a7e4f160fbe30d6a25fd94ae1fae115742fff298ebab1a079ac1f54ae0dc39cfb5567eb693c 0008-ASoC-meson-add-aiu-i2s-dma-support.patch
19d3afeae370201d513c98137bd3833ec3bb8fbd43dee5a391a6e4926a31b381746725e3abdc907a2f24f72ae6757687083d0b99ba1e27a34d90e0f06e506573 0009-ASoC-meson-add-initial-i2s-dai-support.patch
d9da5fc3cf9d6942aa995c06e6c22bfeac89add9dc7d0dd4f58cb4d8e07ceb3679d8af1dd68ba1510bc964cc6303cdf38954b7364ccd9bf22de4c379f12cfbe3 0010-ASoC-meson-add-aiu-spdif-dma-support.patch
9cbab78248da16985ac64c3ee58652df36ae3a8313d7723a168ed36cb23c6d488dd21a603b09ac2fc7ee88aaa4d248c49768821af065f627e8bad671a961a58a 0011-ASoC-meson-add-initial-spdif-dai-support.patch
f7e1b85b59f4347918b626fd373cb23bc5ede17f52f7c8d0f29d6f80a22d28966060c7842363393505b8c059b11ee15297e3b429976a7e6e5f0189a14223a480 0012-ARM64-defconfig-enable-audio-support-for-meson-SoCs-.patch
52a9eaaf61daa1923ed91a20fc7088d532060d180755c257122b6d897a07812249fefe6f5cd568551b9b8656071be3f2f6922f34d691003d8146bb5307e7522b 0013-ARM64-dts-meson-gx-add-audio-controller-nodes.patch
5c31a60457ccc4e6fc1c6f005b9c70583a03797cd56cca3e9799d2717312fd8610ec13cd7d83eadd134379788e9655b4e95b90462076adf10ff39b71dc7c9a10 0014-snd-meson-activate-HDMI-audio-path.patch
afd396bd828a87fb001956ce7369ac8c34e51a684f7be486995463cf4d912a39b242b51af7f3a841b6ecb42ab7e4366c5f9d163992ccaf370fedd842f7a4b2c6 0015-drm-meson-select-dw-hdmi-i2s-audio-for-meson-hdmi.patch
b6ac2f340d57cd0514a8fbd54f3d17942e794f20bfe3402c64a98fdf7cca7ab487cc2bac884436324eda21482bebbdfe7633bd9f9708bc84adb720161a555b89 0016-ARM64-dts-meson-gx-add-sound-dai-cells-to-HDMI-node.patch
b55f9b3370d1c7b75c52f8f75f12a5033402d3a7f0f5be591cd6268b280a39959464570c8868e94586034f48a90f50ac17e414b191e12f7725175dca6fee2a1f 0017-ARM64-dts-meson-activate-hdmi-audio-HDMI-enabled-boa.patch
5814fcf935365b7975ae21f416122a341cef4e54dc8556a03882915d908586e42ec966b18ab5abb85b1533a1c494eeebbb237df3a4ebde28f15449bab66fa421 0018-drm-bridge-dw-hdmi-Use-AUTO-CTS-setup-mode-when-non-.patch
95da882661e07c40d726797b570b2407c94862278a2148f8ff1d3ce7ffe00ba6f83d1f06be77a1fbc59c5f1f5620c1346bd565903b49e5d657e8d143eb247af8 0019-drm-meson-Call-drm_crtc_vblank_on-drm_crtc_vblank_of.patch
8371d3c08ba0029e7c29a5171eb53ba175c0909f1a90a17967f2ca68c1d9a2dbc49a39d1102a62470d237a50a99307b7475a4ba243a0a0d6881684705f428e2b 0020-media-platform-meson-ao-cec-make-busy-TX-warning-sil.patch
896a8ba7c44744e067d3d5216d28df241c6796f1aff01b9648ea2e54e5798f25436328cdb173f00de2f998903ae01b3785a37ed07aea576ccada4590925de10f 0021-soc-amlogic-add-meson-canvas-driver.patch
ad723a68e02b2d4fd708fab3b61aba3ad888b25de9d5e73f3f00dc81bf778d1b59061aa25b840bc790903a8dc9ce180da5aca6312c9f7c8b724a18c80866e174 0022-dt-bindings-soc-amlogic-add-meson-canvas-documentati.patch
0854014aaf150468b14a739649e1461fa66450d168f3f430756bcf6d2e34158be922824d2eb62fd867e5ac28340ef120fb13504183984da7a4bd3a6fe59724b8 0023-ARM64-dts-meson-gx-add-dmcbus-and-canvas-nodes.patch
f01e6fd7a319c75c85803e1deb1681772385640fd10ef4a24b164af6e708d0d29e8118bf2be12a82e6587587a87a6b5b7331bd160c32ae9e3d5f4c1a4e62ce79 0024-drm-meson-convert-to-the-new-canvas-module.patch
783a1c4c0deb352b699faa5f572d38737c1c67983a84822b900a984e9aec521f7a762d6f139d5ce7546503af4a76fd2b604ef79a2aef5105d23fc33919fa13de 0025-WIP-drm-meson-Support-Overlay-plane-for-video-render.patch
34b404bbb4b1e2c3ae1c9fba8e297ed48d382d59208bb00340a5e9f2a86ef0f12d0fc6f347a68915cffc141e19bd4b086a1bbdc440b4bd8a1edef5a7fb79c46e 0026-media-meson-add-v4l2-m2m-video-decoder-driver.patch
608bb5d25c94e9d8e0a1ea9d9fc2eb4436870d72e39f9446322dbdc62a5b7a3fd07d735613a425e1853cf9dd3e61fc860f4310858f9cfbea62a3ba69378b653c 0027-ARM64-dts-meson-gx-add-vdec-entry.patch
0ab00106ab3a15ef884d0d08c4e947037007a4af7b03fc204346e9487f1f8841140dead1f6b8704b74f7fd955deaaa58cc7ce81c42a847bcdc5c13aac627f3e4 0001-libretech-cc-disable-CVBS-connector.patch
7715e9c35072f60856d5ab6940874f053cd5e64f09ae97c79eef98bf0856f3a27643dae1154eec787c94a8c7c84b39c580324540db37d9bf2cf70b2bfa66595a 0001-ARM64-dts-meson-add-vdec-entries.patch
6262ecd89164edcfc58ef7d50c0b027a2263e6e78f51f033b611734a8e8db0436e1b132aee65546717dd5c79635ef38c9be11cffd7808491687494df9fdcb08e add-phicomm-n1.patch
09e8d284608ac0e86db8b36bdefdb17c8ad8e9b3bdf443ee5a687f1591d88d26cffef1a36919b0547acef49394d903ff8067d46f75b55eccadec415971bf0b34 0001-ARM64-defconfig-enable-CEC-support.patch
55d3e84c4e01b94a3bf256a980bd23a8d02c3ea7f4103d350400eb28cc31336bb35f9404ee34ba80f7d3d7427d73ed4ee75119a916ae0e88d911bb83b0303229 0002-ASoC-meson-add-meson-audio-core-driver.patch
b5a65140612b011f22d4bfbb4ab41a4c0fe07bab43f8033195a42b02c5d74c69c7fbc2b186f8d6ff08ed7b66ccbfd9d8d7945f81812ae5021b1d37154acdb12f 0003-ASoC-meson-add-register-definitions.patch
441b0385e88bb7ddb324363536413e6538d4b0367181ae5ceada806a8efe3d1b5daa643bd3ab99db6fa7a2d5ea0944a15a63672fa26bfc7850959ce2d7238aa1 0004-ASoC-meson-add-aiu-i2s-dma-support.patch
4615d01a2548ce5057446ff32c52bca1cea189fc74d902ea22dc90e73c2eb21ef5b4b58c6a4ebbdf3c6cad5bac483dabdee025438ebc0bdf1b4368af0fce1b87 0005-ASoC-meson-add-initial-i2s-dai-support.patch
d1dc1d99393a885776144dea27c0789d9e7968de1164bc85b07cc8d444cdcc898ce2f7ff1f9515ae2424789cbb76b84a8ed56008c1880fef60be79000bf55452 0006-ASoC-meson-add-aiu-spdif-dma-support.patch
b101c64312509738b078732f73b265fa81bb94806bb39524e85d171949505dc0548fc3ece498cca6586b8ca4af08b271b6c02f028040f8cf16ec5eee94ddafa1 0007-ASoC-meson-add-initial-spdif-dai-support.patch
98fd62a02fa76a957d15da9456c85def94a790429c3357b4b06a63d4224b624ffe763410ffdbc09ff560ba0a17a5299b722e2c9cefbb4a59455cfbe7379850b3 0008-ARM64-defconfig-enable-audio-support-for-meson-SoCs-.patch
a286d6ecb284f505ebd29c04c5e95b1e7ba1a4a3c5ffb17580c2387ab78360cba7be6806772a058be8326f7a299f59c84051ed022b2c99372412d935f12f7c6a 0009-ARM64-dts-meson-gx-add-audio-controller-nodes.patch
e84ab2a28d08570590ad06219e1a99a8cc47a589d4170f5ff1bf6eeb1b50c1e4e21857a5633495d2271ae702b9bfdc8aa76bb56d572b236d54a4ec08566f13d6 0010-snd-meson-activate-HDMI-audio-path.patch
35962172f6c2682f0e3ba438ca9e62ddd679a0cd665e6bc6208167a753877a02a1d4db8d78b230de44ab494016cf9d47f0e61d31121cb0b8b676b689f1258f71 0011-drm-meson-select-dw-hdmi-i2s-audio-for-meson-hdmi.patch
db2c10c9e4b58e7f0b72a0b8b81ef39544d0e14ef5814dda4d6d5d98d181c9c0f5993ac0e6bc98ea8c79b5d22a3c4eb38793ddb22e7e2553f4643027767a597e 0012-ARM64-dts-meson-gx-add-sound-dai-cells-to-HDMI-node.patch
4f0073aa0a4ed1297b00817bb6cad704362c32fda284780e7a73505dab8e3cfdec5eb851fccdf7e6bf16c1788bc0f8f6ca58b0898adacca678f46ca940aa493a 0013-ARM64-dts-meson-activate-hdmi-audio-HDMI-enabled-boa.patch
998c39cf37d2258582d6d60a7e6a702601430645b01c971c162bb219684e363fd11d0572cefb15f00551fe6bc95d97d1c101e6f36b1ae015083edeb5742b3df3 0014-drm-bridge-dw-hdmi-Use-AUTO-CTS-setup-mode-when-non-.patch
03c2649558bedc2bf34f0e139db489d6891bda6041384d0023cf700be31d1fb1f983c8bc7d58754acd0a57986432b0330996c82f7dc7fd4a6044589725fc4c9c 0017-soc-amlogic-add-meson-canvas-driver.patch
7c1e84356a62a175326f56e71e6984aa4a00ab4b50ac09cce8a078890f2c2ac700d53c53b1229e8dbfb82f36bac32b3082ccdf91a8f92545148bd705784b38e4 0018-ARM64-dts-meson-gx-add-dmcbus-and-canvas-nodes.patch
f2a94fde352734e1de54f10703d792c62c95ae4b68c2c0ce9eb78fded934084fab4b999c930f7228982044052e5b331cce60cf72dcc1f181bcc88eaf68116bb8 0020-drm-meson-Use-optional-canvas-provider.patch
635410e2f6476ee1f1114d31c06f997d5997e117d857ef67f7acb456b52941a4b4aa0cdd94ce9788a017a07d75143d783e900e03eac009d030c90fbe95798003 0021-arm64-dts-meson-gx-Add-canvas-provider-node-to-the-v.patch
df666c95cc1d0dc4c9dd93f79778c5880afd89c320a0edb22dc3f017388cd2df88806aae4c7cde4c412e6643fcd1a8df4c6f15b41b0b0e6b020eced9cedf8d9a 0022-drm-meson-Support-Overlay-plane-for-video-rendering.patch
8e3f62fc50c8478951f8a2e6c5d8c8f38f56ed4d68f9c0fb55c23c46d3ae2182e8a6e5f23171aac08867da4bb16d7c98741a80a3ae6a3acfc41568350be59a57 0023-drm-meson-move-OSD-scaler-management-into-plane-atom.patch
63c41b6db1386530339bd3b6d87849bb38a8d51ec8fcd0bf3c1bcb77c567c589e069dee02f066030f608288fd510e3af244ff45b346e0addc31614867daab334 0024-drm-meson-Add-primary-plane-scaling.patch
64682336c72ac1e505e19e4a099bb2c6f8ba6e8df2ed3b149e355c50b27a29337ac1de7768dd0fd3274bda4fe2f6cc53d068d8a1e6325d27c42e372a0324cbd2 0026-pinctrl-meson-gxl-remove-invalid-GPIOX-tsin_a-pins.patch
332aa83ae3c581b81dae9b37df047fa5e553b0c31790713395ab562aa03ac32fbf909ab6372aba22d06cb82c509efef68af90aeaf66ca5cf70c0861c69039139 0027-arm64-dts-meson-gx-Add-hdmi_5v-regulator-as-hdmi-tx-.patch
0cb8ed9fb52cfdcfac8dbbab5b08f4b5fe1b8716655fe77f37ff1ee39355fac89314dd318856582c62dce1fd56232b4a2725c60a2d07ef15efba86160eb093f0 0028-arm64-dts-meson-gxl-libretech-cc-fix-GPIO-lines-name.patch
f4d251863ac20a95642a60f7c6c51694d36a12f745864fccbb6513b2e53fb0039fa316f4bcd245abe306d2d0aeb0037498f9e21333ab1d84e58fb5d287632093 0029-arm64-dts-meson-gxbb-nanopi-k2-fix-GPIO-lines-names.patch
c481cde9a8bf2609b99e1a7a94bdfead78afe8665347dfffcde8747b8e2817356123e0e44b71de4c5b85224aa20c3c63d5ce3f44e49e3969f0ea28f4df94dc62 0030-arm64-dts-meson-gxbb-odroidc2-fix-GPIO-lines-names.patch
768d954c5580b68e999bf3ed051219187c96de88f27be54e52242687f2ef505c0616dabbc5bee42fdc6d20d53d973f2e64ef4809649fb2e666d8727ed314f3fd 0031-arm64-dts-meson-gxl-khadas-vim-fix-GPIO-lines-names.patch
e23b9303036d736a3f9abed22712848da514f6388de66b3029bde551a85b7d42d1506ee960a539457c8dd7d8b6c07e80919ca0714a9435bdcaa85ca2e201d69f 0032-drm-meson-Add-support-for-VIC-alternate-timings.patch
671da78856f524f7e491e35dcb2764acb6ff0e99eee4df6c9e9538dc321c6c2e4481fd8c39daa2cb32d23d38c96823e5ab04db0342b2daabd5d1b7efdb0d6288 0033-media-meson-add-v4l2-m2m-video-decoder-driver.patch
8d13b4e5c503a196b29263a85d3bc2d9cd1b95d186e6347532b8ae7efc35c93ed72d3f9c4a7ff12b5c2186b3f7d3b35247858e66a96382ba3a2630db35cdf794 0034-MAINTAINERS-Add-meson-video-decoder.patch
c1817a1b59a4a38f7a0689c1e2603398f538d9270a93b40e2ce3e9633b71943beb385206d802673b18f244fb5d9a6c9b2e0498d7803432cf98750843fb91ce5f 0035-arm64-dts-meson-gx-add-vdec-entry.patch
bdd5bd9e4203e3e7bd6412b2068963e22a974316b8ee1a707933808f1ec03ab43aa174804e7fd21f2f7062dc25226e4f2047a863366f132d8687d098a203c6d1 0036-arm64-dts-meson-add-vdec-entries.patch
9c3b9170bbc5fbf3331052e5a99864b76cee6c2c50629f22d33d6e0b01de164e34db4a57c3864e6cb10ff9486999842c9d5f5d38bcb65ef98ccca34c3a6366be 0037-meson-vdec-introduce-controls-and-V4L2_CID_MIN_BUFFE.patch
6bd52ae9872d79b5b2199d23bbef6f73b7530c54df702edf0ce040ba799c60265d199f75fcd4301587100fe60a6d43988bdffdfcb6f98be0c0d8a79f27d206bf 0038-media-videodev2-add-V4L2_FMT_FLAG_NO_SOURCE_CHANGE.patch
516113c435158775f85a3904e5941bcfe641428cfce1945722a2ab8f7897a8493dca634f3527fa4d8fb0433635efcd48353a2feadee94e3467057ce4ff966964 0039-meson-vdec-allow-subscribing-to-V4L2_EVENT_SOURCE_CH.patch
0332979243ae7c182006050c3c2b34c9035ce9f3b084659ec0c3fd39c6772d42c0f5420628150113d2d149d8b1a2481d42650aae08ac054d25cf19178ba64ebc 0040-media-meson-vdec-add-H.264-decoding-support.patch
d696a4a726801786e65fcb69f70c5271a982b2d494a8036d7d8a3e201f910d0e1dc411283128b3460bf2371cb43817d760c0de866cfc22a985f1ff052b98cbff 0041-media-meson-vdec-add-MPEG4-decoding-support.patch
1381cbabd3e040d6e14c1f270904b2c41c6758f2757c3871d1a09d41ab4ce8f85cde95ed1cc989fe59addfa3eae6246f7cc25b63f213f9b28cc73ec86a1c3deb 0042-media-meson-vdec-add-MJPEG-decoding-support.patch
36281f344133b7f4130d69685b1802524a597e110e792f0cae43991eb3a15282d77779cca8033679b943660cd23c9da54c62178b99999e91dc8581052cb53945 0043-clk-meson-gxbb-set-fclk_div3-as-CLK_IS_CRITICAL.patch
ddcb198b0e052975764dfaf140763247e80632eee5f49e3316dc4f1b6220da80fdca0dc32ec618b27fb0487b3ff0676f2a2ed07d5cecfad350bafba0b79ddfed 0008-drm-meson-Add-HDMI-1.4-4k-modes.patch
a58680d93e56fbc95e9e255b79822fcb7960d1f58dbf819dda729b21b61949f42ac58454a6403e77b0d12708613425f331531de700a74c18b262f1336849d5a1 0009-drm-meson-Use-drm_fbdev_generic_setup.patch
b103daed449e59ce1d73e929c694f042e461241ef9d09592828414ab04a9c7ce07c16f636461d8bc5ba49650b9f584a861d5bd4267e90899b8bd72ec113bee4e 0010-fixup-drm-meson-Use-optional-canvas-provider.patch
5e25559535d0a1529c8b5e31e9dab82c0d41f70e515a2ca4ed614177e127c0933cc1d54566ef6f063b19dbd19f3b1d67cb51ad4d8a87877140cf166c5969a6f0 0012-drm-meson-add-support-for-1080p25-mode.patch
8de5c1f61e8467504f96db3c615658f40bb217d57a1a0c03b505cd8e310961dce38a191cd40ccecd48ed204fac1c3d3facb371e07ff590b8683afc4420e7f303 0014-drm-bridge-dw-hdmi-Add-SCDC-and-TMDS-Scrambling-supp.patch
8fe6432a889ee13081185eeb8602ea48465b7d858f0b573f5a5c4d35e6ed76edc47f697b0c1729a31e9a319e0712bb0eaa111077d86570d2954dcbe6fceb7b60 0015-drm-meson-add-HDMI-div40-TMDS-mode.patch
358f064f42c9e21afeccb867c062fc18484f91ed7805752edaf74492774962c16348099de004ce130134610f8c5d076fd715ca0de3eb30d0abd23f90236c6a7b 0016-drm-meson-add-support-for-HDMI2.0-2160p-modes.patch
9bd13d763a007ffb9d0e9f9f4c9b5018752c010a39780e467d463153cc79a32774120d7af83496ba706b971dd3bd9bb600fad4795b3c0796e22eb42b23374a90 0017-drm-bridge-dw-hdmi-add-support-for-YUV420-output.patch
f15dd5116fe7464009ade33a9c6d305a7720767e1b31acbf7653cd9d2f83b428e734712739e8bb4cfd04407640187f5528f80d7e8b89992a75f2316b6f8513c6 0018-drm-bridge-dw-hdmi-support-dynamically-get-input-out.patch
2399c1c95455f2e4d0d03d2c84cf454251b7c8a151da555e7665bede91b7b62f96391efac3ca9a5b90761e105409bd033f348e25bc163a439a2ff7efd82e2184 0019-drm-bridge-dw-hdmi-allow-ycbcr420-modes-for-0x200a.patch
26eb2b101ab563558649f38a5102773b2d79eeb39cf04a3f8d512361beed70ad585825233716acb58853887bc863ba76ce87f6eaf6d8c5c22e4caa99a5ce294a 0020-drm-meson-Add-YUV420-output-support.patch
fac806a77816f655354499ab597974659e5d6dc74d04ac74cd81bacd6a264ac13ab33bc230a2c233d98d6e3b0342f329c2af0c6359d9ae8b6b456add06809822 0021-drm-meson-Output-in-YUV444-if-sink-supports-it.patch
e365ba0479201f1c4fb08f872447f2496d4c8d75c8e3f632eeb3f7091e56d0659d4b6f580d384183e0e9c80ccf659b1704ecbaca88b66ca34c78c250c0f55a29 0023-drm-meson-Fix-an-Alpha-Primary-Plane-bug-on-Meson-GX.patch
0aca4ad6af15ea8f8e2e8a05aa3c5a16e1a909ee0f80cb1f64e0ee027a7050b0bbd5815520e146f96641b92e5d39688677de39d4294be6a25ea1a2e519df257b 0001-arm64-dts-meson-Fix-IRQ-trigger-type-for-macirq.patch
613d619e86883d83d53d045ed589d91c74a9f2031de953d2f3e4cdf374ae32841a69b28abfd0d8314a5739f51fbd3ab02c7f8baf4c5060db725d21f7a677db7f 0001-drm-meson-fix-max-mode_config-height-width.patch
ea41c0b63d8890cf5db69a37ead0fb9863299a344cee2d3606cc8c049405a563e139dceb6c908abc57b5b545d3daee16f7b9c6f7f1284cb9cf676ff5830d5c96 add-phicomm-n1.patch
dcc02a2e35e530490f18dd1f7e304aebd7c268ed8a46971d94e9da7dfd65b287002e6b921e46db5ce118177c9ab79fbe3640565cb2df19809b6eff514122fb43 bt-btbcm.patch
007075ca40915f20c6c8f5e04825c3433a52621deb689a9a690a3fcc618ca9629bc089a1a2ad5141fc47a8aa0aabb302ecf75e81ef8cae466e978074156231ac brcmfmac-Disable-power-management.patch
cb2ec80ae38c4cc46ea2a4ca6d157498632f8154ef6a1dedb898c70593c812743a69a4c0d36a4e146a71c588e30e9f9b2feb415e00166850c2cf79797048b032 offset.patch
e5d214788f9a28d79a9ef135fbed3b3c87982941788ca74d31d919534d1627c1265b268982f67de6c14b331d1a38938b4c2772f17b3db3bddd3983f919fe73ca off_error_text_offset.patch"
298ded76cf87f08c9357505e9dd7582d886a5e59111eee81ecb136b2dd1f3f404899a32029696038cb2299760568b2b0345c92dfd961591b28ec2964460f09b1 text_offset.patch"

View File

@ -1,5 +1,5 @@
diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
index 34dd0e9..773f415 100644
index a97c0e2..ebd96da 100644
--- a/arch/arm64/boot/dts/amlogic/Makefile
+++ b/arch/arm64/boot/dts/amlogic/Makefile
@@ -17,6 +17,7 @@ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-nexbox-a95x.dtb
@ -7,9 +7,9 @@ index 34dd0e9..773f415 100644
dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905d-p230.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905d-p231.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905d-phicomm-n1.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-gxm-khadas-vim2.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-gxm-nexbox-a1.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-gxm-q200.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s805x-p241.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905w-p281.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905w-tx3-mini.dtb
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-phicomm-n1.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-phicomm-n1.dts
new file mode 100644
index 0000000..7903dad

View File

@ -1,13 +0,0 @@
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index b6122aa..e2098ad 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -2697,6 +2697,8 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
* preference in cfg struct to apply this to
* FW later while initializing the dongle
*/
+ pr_info("power management disabled\n");
+ enabled = false;
cfg->pwr_save = enabled;
if (!check_vif_up(ifp->vif)) {

View File

@ -1,13 +0,0 @@
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index b085306..68edc91 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -51,7 +51,7 @@
#elif (PAGE_OFFSET & 0x1fffff) != 0
#error PAGE_OFFSET must be at least 2MB aligned
#elif TEXT_OFFSET > 0x1fffff
-#error TEXT_OFFSET must be less than 2MB
+//#error TEXT_OFFSET must be less than 2MB
#endif
/*

View File

@ -1,13 +0,0 @@
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index e7101b1..deabd29 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -87,7 +87,7 @@ TEXT_OFFSET := $(shell awk "BEGIN {srand(); printf \"0x%06x\n\", \
int(2 * 1024 * 1024 / (2 ^ $(CONFIG_ARM64_PAGE_SHIFT)) * \
rand()) * (2 ^ $(CONFIG_ARM64_PAGE_SHIFT))}")
else
-TEXT_OFFSET := 0x00080000
+TEXT_OFFSET := 0x01080000
endif
# KASAN_SHADOW_OFFSET = VA_START + (1 << (VA_BITS - KASAN_SHADOW_SCALE_SHIFT))

View File

@ -0,0 +1,26 @@
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index 106039d..651d990 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -88,7 +88,7 @@ TEXT_OFFSET := $(shell awk "BEGIN {srand(); printf \"0x%06x\n\", \
int(2 * 1024 * 1024 / (2 ^ $(CONFIG_ARM64_PAGE_SHIFT)) * \
rand()) * (2 ^ $(CONFIG_ARM64_PAGE_SHIFT))}")
else
-TEXT_OFFSET := 0x00080000
+TEXT_OFFSET := 0x01080000
endif
# KASAN_SHADOW_OFFSET = VA_START + (1 << (VA_BITS - KASAN_SHADOW_SCALE_SHIFT))
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index b085306..68edc91 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -51,7 +51,7 @@
#elif (PAGE_OFFSET & 0x1fffff) != 0
#error PAGE_OFFSET must be at least 2MB aligned
#elif TEXT_OFFSET > 0x1fffff
-#error TEXT_OFFSET must be less than 2MB
+//#error TEXT_OFFSET must be less than 2MB
#endif
/*