646 lines
19 KiB
Diff
646 lines
19 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Radoslav <[email protected]>
|
|
Date: Sat, 15 Apr 2023 22:47:26 +0200
|
|
Subject: enable TV Output on OrangePi Zero LTE
|
|
|
|
Credits to sorce https://github.com/robertojguerra/orangepi-zero-full-setup/blob/main/README2.md
|
|
Merged:
|
|
1. sunxi-6.1/0036-wip-h3-h5-cvbs-armbian.patch : makes additions to the "dts", which tells the kernel where are the new devices. Adds kernel code to interact with the tv encoder. With my modifications, now it is applicable to Armbian (this patch came from the LibreElec github).
|
|
https://github.com/robertojguerra/orangepi-zero-full-setup/blob/main/sunxi-6.1/0036-wip-h3-h5-cvbs-armbian.patch
|
|
2. sunxi-6.1/zzzz2-tv.patch : by Armbian user "gleam2003", adds directives to make sure that the dtbo (device tree binary overlay) is compiled
|
|
https://github.com/robertojguerra/orangepi-zero-full-setup/blob/main/sunxi-6.1/zzzz2-tv.patch
|
|
3. sunxi-6.1/zzzz3-tv.patch : more additions to the "dts" and "dtsi" (like C include files), which I noticed were included in "yam" patch, but missing from the LibreElec patch
|
|
https://github.com/robertojguerra/orangepi-zero-full-setup/blob/main/sunxi-6.1/zzzz3-tv.patch
|
|
|
|
> X-Git-Archeology: - Revision 41260ac309b487d241fec97ffbdeced730bc2d04: https://github.com/armbian/build/commit/41260ac309b487d241fec97ffbdeced730bc2d04
|
|
> X-Git-Archeology: Date: Sat, 15 Apr 2023 22:47:26 +0200
|
|
> X-Git-Archeology: From: Radoslav <[email protected]>
|
|
> X-Git-Archeology: Subject: h3-tve (arm-dts-sun8i-h3-orangepizero-add_tve.patch)
|
|
---
|
|
arch/arm/boot/dts/allwinner/overlay/Makefile | 1 +
|
|
arch/arm/boot/dts/allwinner/overlay/README.sun8i-h3-overlays | 10 +
|
|
arch/arm/boot/dts/allwinner/overlay/sun8i-h3-tve.dtso | 34 ++++
|
|
arch/arm/boot/dts/allwinner/sun8i-h2-plus-orangepi-zero.dts | 4 +
|
|
arch/arm/boot/dts/allwinner/sun8i-h3-orangepi-pc.dts | 4 +
|
|
arch/arm/boot/dts/allwinner/sun8i-h3.dtsi | 22 +++
|
|
arch/arm/boot/dts/allwinner/sunxi-h3-h5.dtsi | 95 +++++++++-
|
|
arch/arm64/boot/dts/allwinner/overlay/Makefile | 1 +
|
|
arch/arm64/boot/dts/allwinner/overlay/README.sun50i-h5-overlays | 5 +
|
|
arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-tve.dtso | 34 ++++
|
|
arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi | 22 +++
|
|
drivers/clk/sunxi-ng/ccu-sun8i-h3.c | 14 +-
|
|
drivers/gpu/drm/sun4i/Makefile | 2 +-
|
|
drivers/gpu/drm/sun4i/sun4i_tv.c | 35 +++-
|
|
drivers/gpu/drm/sun4i/sun8i_mixer.c | 30 ++-
|
|
drivers/gpu/drm/sun4i/sun8i_mixer.h | 2 +
|
|
16 files changed, 305 insertions(+), 10 deletions(-)
|
|
|
|
diff --git a/arch/arm/boot/dts/allwinner/overlay/Makefile b/arch/arm/boot/dts/allwinner/overlay/Makefile
|
|
index 111111111111..222222222222 100644
|
|
--- a/arch/arm/boot/dts/allwinner/overlay/Makefile
|
|
+++ b/arch/arm/boot/dts/allwinner/overlay/Makefile
|
|
@@ -80,6 +80,7 @@ dtb-$(CONFIG_MACH_SUN8I) += \
|
|
sun8i-h3-usbhost2.dtbo \
|
|
sun8i-h3-usbhost3.dtbo \
|
|
sun8i-h3-w1-gpio.dtbo \
|
|
+ sun8i-h3-tve.dtbo \
|
|
sun8i-r40-i2c2.dtbo \
|
|
sun8i-r40-i2c3.dtbo \
|
|
sun8i-r40-spi-spidev0.dtbo \
|
|
diff --git a/arch/arm/boot/dts/allwinner/overlay/README.sun8i-h3-overlays b/arch/arm/boot/dts/allwinner/overlay/README.sun8i-h3-overlays
|
|
index 111111111111..222222222222 100644
|
|
--- a/arch/arm/boot/dts/allwinner/overlay/README.sun8i-h3-overlays
|
|
+++ b/arch/arm/boot/dts/allwinner/overlay/README.sun8i-h3-overlays
|
|
@@ -34,6 +34,7 @@ adding fixed software (GPIO) chip selects is possible with a separate overlay
|
|
- usbhost2
|
|
- usbhost3
|
|
- w1-gpio
|
|
+- tve
|
|
|
|
### Overlay details:
|
|
|
|
@@ -248,3 +249,12 @@ param_w1_pin_int_pullup (bool)
|
|
Set to 1 to enable the pull-up
|
|
This option should not be used with multiple devices, parasite power setup
|
|
or long wires - please use external pull-up resistor instead
|
|
+
|
|
+### tve
|
|
+
|
|
+Activates Composite TV Encoder
|
|
+
|
|
+Parameters:
|
|
+ Unknown at this stage.
|
|
+ Maybe none.
|
|
+ Not sure how to change the mode between PAL/NTSC.
|
|
diff --git a/arch/arm/boot/dts/allwinner/overlay/sun8i-h3-tve.dtso b/arch/arm/boot/dts/allwinner/overlay/sun8i-h3-tve.dtso
|
|
new file mode 100644
|
|
index 000000000000..111111111111
|
|
--- /dev/null
|
|
+++ b/arch/arm/boot/dts/allwinner/overlay/sun8i-h3-tve.dtso
|
|
@@ -0,0 +1,34 @@
|
|
+/dts-v1/;
|
|
+/plugin/;
|
|
+
|
|
+/ {
|
|
+ compatible = "allwinner,sun8i-h3";
|
|
+
|
|
+ fragment@0 {
|
|
+ target = <&de>;
|
|
+ __overlay__ {
|
|
+ status = "okay";
|
|
+ };
|
|
+ };
|
|
+
|
|
+ fragment@1 {
|
|
+ target = <&mixer1>;
|
|
+ __overlay__ {
|
|
+ status = "okay";
|
|
+ };
|
|
+ };
|
|
+
|
|
+ fragment@2 {
|
|
+ target = <&tcon1>;
|
|
+ __overlay__ {
|
|
+ status = "okay";
|
|
+ };
|
|
+ };
|
|
+
|
|
+ fragment@3 {
|
|
+ target = <&tve>;
|
|
+ __overlay__ {
|
|
+ status = "okay";
|
|
+ };
|
|
+ };
|
|
+};
|
|
diff --git a/arch/arm/boot/dts/allwinner/sun8i-h2-plus-orangepi-zero.dts b/arch/arm/boot/dts/allwinner/sun8i-h2-plus-orangepi-zero.dts
|
|
index 111111111111..222222222222 100644
|
|
--- a/arch/arm/boot/dts/allwinner/sun8i-h2-plus-orangepi-zero.dts
|
|
+++ b/arch/arm/boot/dts/allwinner/sun8i-h2-plus-orangepi-zero.dts
|
|
@@ -180,6 +180,10 @@ flash@0 {
|
|
};
|
|
};
|
|
|
|
+&tve {
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
&uart0 {
|
|
pinctrl-names = "default";
|
|
pinctrl-0 = <&uart0_pa_pins>;
|
|
diff --git a/arch/arm/boot/dts/allwinner/sun8i-h3-orangepi-pc.dts b/arch/arm/boot/dts/allwinner/sun8i-h3-orangepi-pc.dts
|
|
index 111111111111..222222222222 100644
|
|
--- a/arch/arm/boot/dts/allwinner/sun8i-h3-orangepi-pc.dts
|
|
+++ b/arch/arm/boot/dts/allwinner/sun8i-h3-orangepi-pc.dts
|
|
@@ -214,6 +214,10 @@ &sound_hdmi {
|
|
status = "okay";
|
|
};
|
|
|
|
+&tve {
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
&uart0 {
|
|
pinctrl-names = "default";
|
|
pinctrl-0 = <&uart0_pa_pins>;
|
|
diff --git a/arch/arm/boot/dts/allwinner/sun8i-h3.dtsi b/arch/arm/boot/dts/allwinner/sun8i-h3.dtsi
|
|
index 111111111111..222222222222 100644
|
|
--- a/arch/arm/boot/dts/allwinner/sun8i-h3.dtsi
|
|
+++ b/arch/arm/boot/dts/allwinner/sun8i-h3.dtsi
|
|
@@ -295,6 +295,20 @@ ths: thermal-sensor@1c25000 {
|
|
nvmem-cell-names = "calibration";
|
|
#thermal-sensor-cells = <0>;
|
|
};
|
|
+
|
|
+ tve: tv-encoder@1e00000 {
|
|
+ compatible = "allwinner,sun8i-h3-tv-encoder";
|
|
+ reg = <0x01e00000 0x1000>;
|
|
+ clocks = <&ccu CLK_BUS_TVE>;
|
|
+ resets = <&ccu RST_BUS_TVE>;
|
|
+ status = "disabled";
|
|
+
|
|
+ port {
|
|
+ tve_in_tcon1: endpoint {
|
|
+ remote-endpoint = <&tcon1_out_tve>;
|
|
+ };
|
|
+ };
|
|
+ };
|
|
};
|
|
|
|
thermal-zones {
|
|
@@ -384,6 +398,10 @@ &mbus {
|
|
compatible = "allwinner,sun8i-h3-mbus";
|
|
};
|
|
|
|
+&mixer1 {
|
|
+ resets = <&display_clocks RST_WB>;
|
|
+};
|
|
+
|
|
&mmc0 {
|
|
compatible = "allwinner,sun7i-a20-mmc";
|
|
clocks = <&ccu CLK_BUS_MMC0>,
|
|
@@ -431,3 +449,7 @@ &rtc {
|
|
&sid {
|
|
compatible = "allwinner,sun8i-h3-sid";
|
|
};
|
|
+
|
|
+&tcon1_out_tve {
|
|
+ remote-endpoint = <&tve_in_tcon1>;
|
|
+};
|
|
diff --git a/arch/arm/boot/dts/allwinner/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/allwinner/sunxi-h3-h5.dtsi
|
|
index 111111111111..222222222222 100644
|
|
--- a/arch/arm/boot/dts/allwinner/sunxi-h3-h5.dtsi
|
|
+++ b/arch/arm/boot/dts/allwinner/sunxi-h3-h5.dtsi
|
|
@@ -116,7 +116,7 @@ cpu {
|
|
|
|
de: display-engine {
|
|
compatible = "allwinner,sun8i-h3-display-engine";
|
|
- allwinner,pipelines = <&mixer0>;
|
|
+ allwinner,pipelines = <&mixer0>, <&mixer1>;
|
|
status = "disabled";
|
|
};
|
|
|
|
@@ -160,11 +160,50 @@ ports {
|
|
#size-cells = <0>;
|
|
|
|
mixer0_out: port@1 {
|
|
+ #address-cells = <1>;
|
|
+ #size-cells = <0>;
|
|
reg = <1>;
|
|
|
|
- mixer0_out_tcon0: endpoint {
|
|
+ mixer0_out_tcon0: endpoint@0 {
|
|
+ reg = <0>;
|
|
remote-endpoint = <&tcon0_in_mixer0>;
|
|
};
|
|
+
|
|
+ mixer0_out_tcon1: endpoint@1 {
|
|
+ reg = <1>;
|
|
+ remote-endpoint = <&tcon1_in_mixer0>;
|
|
+ };
|
|
+ };
|
|
+ };
|
|
+ };
|
|
+
|
|
+ mixer1: mixer@1200000 {
|
|
+ compatible = "allwinner,sun8i-h3-de2-mixer-1";
|
|
+ reg = <0x01200000 0x100000>;
|
|
+ clocks = <&display_clocks CLK_BUS_MIXER1>,
|
|
+ <&display_clocks CLK_MIXER1>;
|
|
+ clock-names = "bus",
|
|
+ "mod";
|
|
+ /* reset is added by SoC dtsi */
|
|
+
|
|
+ ports {
|
|
+ #address-cells = <1>;
|
|
+ #size-cells = <0>;
|
|
+
|
|
+ mixer1_out: port@1 {
|
|
+ #address-cells = <1>;
|
|
+ #size-cells = <0>;
|
|
+ reg = <1>;
|
|
+
|
|
+ mixer1_out_tcon0: endpoint@0 {
|
|
+ reg = <0>;
|
|
+ remote-endpoint = <&tcon0_in_mixer1>;
|
|
+ };
|
|
+
|
|
+ mixer1_out_tcon1: endpoint@1 {
|
|
+ reg = <1>;
|
|
+ remote-endpoint = <&tcon1_in_mixer1>;
|
|
+ };
|
|
};
|
|
};
|
|
};
|
|
@@ -193,11 +232,19 @@ ports {
|
|
#size-cells = <0>;
|
|
|
|
tcon0_in: port@0 {
|
|
+ #address-cells = <1>;
|
|
+ #size-cells = <0>;
|
|
reg = <0>;
|
|
|
|
- tcon0_in_mixer0: endpoint {
|
|
+ tcon0_in_mixer0: endpoint@0 {
|
|
+ reg = <0>;
|
|
remote-endpoint = <&mixer0_out_tcon0>;
|
|
};
|
|
+
|
|
+ tcon0_in_mixer1: endpoint@1 {
|
|
+ reg = <1>;
|
|
+ remote-endpoint = <&mixer1_out_tcon0>;
|
|
+ };
|
|
};
|
|
|
|
tcon0_out: port@1 {
|
|
@@ -213,6 +260,48 @@ tcon0_out_hdmi: endpoint@1 {
|
|
};
|
|
};
|
|
|
|
+ tcon1: lcd-controller@1c0d000 {
|
|
+ compatible = "allwinner,sun8i-h3-tcon-tv",
|
|
+ "allwinner,sun8i-a83t-tcon-tv";
|
|
+ reg = <0x01c0d000 0x1000>;
|
|
+ interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
|
|
+ clocks = <&ccu CLK_BUS_TCON1>, <&ccu CLK_TVE>;
|
|
+ clock-names = "ahb", "tcon-ch1";
|
|
+ resets = <&ccu RST_BUS_TCON1>;
|
|
+ reset-names = "lcd";
|
|
+
|
|
+ ports {
|
|
+ #address-cells = <1>;
|
|
+ #size-cells = <0>;
|
|
+
|
|
+ tcon1_in: port@0 {
|
|
+ #address-cells = <1>;
|
|
+ #size-cells = <0>;
|
|
+ reg = <0>;
|
|
+
|
|
+ tcon1_in_mixer0: endpoint@0 {
|
|
+ reg = <0>;
|
|
+ remote-endpoint = <&mixer0_out_tcon1>;
|
|
+ };
|
|
+
|
|
+ tcon1_in_mixer1: endpoint@1 {
|
|
+ reg = <1>;
|
|
+ remote-endpoint = <&mixer1_out_tcon1>;
|
|
+ };
|
|
+ };
|
|
+
|
|
+ tcon1_out: port@1 {
|
|
+ #address-cells = <1>;
|
|
+ #size-cells = <0>;
|
|
+ reg = <1>;
|
|
+
|
|
+ tcon1_out_tve: endpoint@1 {
|
|
+ reg = <1>;
|
|
+ };
|
|
+ };
|
|
+ };
|
|
+ };
|
|
+
|
|
mmc0: mmc@1c0f000 {
|
|
/* compatible and clocks are in per SoC .dtsi file */
|
|
reg = <0x01c0f000 0x1000>;
|
|
diff --git a/arch/arm64/boot/dts/allwinner/overlay/Makefile b/arch/arm64/boot/dts/allwinner/overlay/Makefile
|
|
index 111111111111..222222222222 100644
|
|
--- a/arch/arm64/boot/dts/allwinner/overlay/Makefile
|
|
+++ b/arch/arm64/boot/dts/allwinner/overlay/Makefile
|
|
@@ -27,6 +27,7 @@ dtb-$(CONFIG_ARCH_SUNXI) += \
|
|
sun50i-h5-spi-add-cs1.dtbo \
|
|
sun50i-h5-spi-jedec-nor.dtbo \
|
|
sun50i-h5-spi-spidev.dtbo \
|
|
+ sun50i-h5-tve.dtbo \
|
|
sun50i-h5-uart1.dtbo \
|
|
sun50i-h5-uart2.dtbo \
|
|
sun50i-h5-uart3.dtbo \
|
|
diff --git a/arch/arm64/boot/dts/allwinner/overlay/README.sun50i-h5-overlays b/arch/arm64/boot/dts/allwinner/overlay/README.sun50i-h5-overlays
|
|
index 111111111111..222222222222 100644
|
|
--- a/arch/arm64/boot/dts/allwinner/overlay/README.sun50i-h5-overlays
|
|
+++ b/arch/arm64/boot/dts/allwinner/overlay/README.sun50i-h5-overlays
|
|
@@ -26,6 +26,7 @@ adding fixed software (GPIO) chip selects is possible with a separate overlay
|
|
- spi-add-cs1
|
|
- spi-jedec-nor
|
|
- spi-spidev
|
|
+- tve
|
|
- uart1
|
|
- uart2
|
|
- uart3
|
|
@@ -170,6 +171,10 @@ param_spidev_max_freq (int)
|
|
Default: 1000000
|
|
Range: 3000 - 100000000
|
|
|
|
+### tve
|
|
+
|
|
+Activates Composite TV Encoder
|
|
+
|
|
### uart1
|
|
|
|
Activates serial port 1 (/dev/ttyS1)
|
|
diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-tve.dtso b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-tve.dtso
|
|
new file mode 100644
|
|
index 000000000000..111111111111
|
|
--- /dev/null
|
|
+++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-tve.dtso
|
|
@@ -0,0 +1,34 @@
|
|
+/dts-v1/;
|
|
+/plugin/;
|
|
+
|
|
+/ {
|
|
+ compatible = "allwinner,sun8i-h5";
|
|
+
|
|
+ fragment@0 {
|
|
+ target = <&de>;
|
|
+ __overlay__ {
|
|
+ status = "okay";
|
|
+ };
|
|
+ };
|
|
+
|
|
+ fragment@1 {
|
|
+ target = <&mixer1>;
|
|
+ __overlay__ {
|
|
+ status = "okay";
|
|
+ };
|
|
+ };
|
|
+
|
|
+ fragment@2 {
|
|
+ target = <&tcon1>;
|
|
+ __overlay__ {
|
|
+ status = "okay";
|
|
+ };
|
|
+ };
|
|
+
|
|
+ fragment@3 {
|
|
+ target = <&tve>;
|
|
+ __overlay__ {
|
|
+ status = "okay";
|
|
+ };
|
|
+ };
|
|
+};
|
|
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
|
|
index 111111111111..222222222222 100644
|
|
--- a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
|
|
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
|
|
@@ -199,6 +199,20 @@ ths: thermal-sensor@1c25000 {
|
|
nvmem-cell-names = "calibration";
|
|
#thermal-sensor-cells = <1>;
|
|
};
|
|
+
|
|
+ tve: tv-encoder@1e40000 {
|
|
+ compatible = "allwinner,sun50i-h5-tv-encoder";
|
|
+ reg = <0x01e40000 0x1000>;
|
|
+ clocks = <&ccu CLK_BUS_TVE>;
|
|
+ resets = <&ccu RST_BUS_TVE>;
|
|
+ status = "disabled";
|
|
+
|
|
+ port {
|
|
+ tve_in_tcon1: endpoint {
|
|
+ remote-endpoint = <&tcon1_out_tve>;
|
|
+ };
|
|
+ };
|
|
+ };
|
|
};
|
|
|
|
thermal-zones {
|
|
@@ -303,6 +317,10 @@ &mbus {
|
|
compatible = "allwinner,sun50i-h5-mbus";
|
|
};
|
|
|
|
+&mixer1 {
|
|
+ resets = <&display_clocks RST_MIXER1>;
|
|
+};
|
|
+
|
|
&mmc0 {
|
|
compatible = "allwinner,sun50i-h5-mmc",
|
|
"allwinner,sun50i-a64-mmc";
|
|
@@ -338,3 +356,7 @@ &rtc {
|
|
&sid {
|
|
compatible = "allwinner,sun50i-h5-sid";
|
|
};
|
|
+
|
|
+&tcon1_out_tve {
|
|
+ remote-endpoint = <&tve_in_tcon1>;
|
|
+};
|
|
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c
|
|
index 111111111111..222222222222 100644
|
|
--- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c
|
|
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c
|
|
@@ -469,8 +469,18 @@ static SUNXI_CCU_M_WITH_MUX_GATE(tcon_clk, "tcon", tcon_parents,
|
|
CLK_SET_RATE_PARENT);
|
|
|
|
static const char * const tve_parents[] = { "pll-de", "pll-periph1" };
|
|
-static SUNXI_CCU_M_WITH_MUX_GATE(tve_clk, "tve", tve_parents,
|
|
- 0x120, 0, 4, 24, 3, BIT(31), 0);
|
|
+struct ccu_div tve_clk = {
|
|
+ .enable = BIT(31),
|
|
+ .div = _SUNXI_CCU_DIV(0, 4),
|
|
+ .mux = _SUNXI_CCU_MUX(24, 3),
|
|
+ .fixed_post_div = 16,
|
|
+ .common = {
|
|
+ .reg = 0x120,
|
|
+ .features = CCU_FEATURE_FIXED_POSTDIV,
|
|
+ .hw.init = CLK_HW_INIT_PARENTS("tve", tve_parents,
|
|
+ &ccu_div_ops, 0),
|
|
+ },
|
|
+};
|
|
|
|
static const char * const deinterlace_parents[] = { "pll-periph0", "pll-periph1" };
|
|
static SUNXI_CCU_M_WITH_MUX_GATE(deinterlace_clk, "deinterlace", deinterlace_parents,
|
|
diff --git a/drivers/gpu/drm/sun4i/Makefile b/drivers/gpu/drm/sun4i/Makefile
|
|
index 111111111111..222222222222 100644
|
|
--- a/drivers/gpu/drm/sun4i/Makefile
|
|
+++ b/drivers/gpu/drm/sun4i/Makefile
|
|
@@ -20,7 +20,7 @@ sun8i-drm-hdmi-y += sun8i_hdmi_phy_clk.o
|
|
sun8i-mixer-y += sun8i_mixer.o sun8i_ui_layer.o \
|
|
sun8i_vi_layer.o sun8i_ui_scaler.o \
|
|
sun8i_vi_scaler.o sun8i_csc.o \
|
|
- sun50i_fmt.o sun50i_afbc.o
|
|
+ sun50i_fmt.o sun50i_afbc.o sun4i_tv.o
|
|
|
|
sun4i-tcon-y += sun4i_crtc.o
|
|
sun4i-tcon-y += sun4i_tcon_dclk.o
|
|
diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c b/drivers/gpu/drm/sun4i/sun4i_tv.c
|
|
index 111111111111..222222222222 100644
|
|
--- a/drivers/gpu/drm/sun4i/sun4i_tv.c
|
|
+++ b/drivers/gpu/drm/sun4i/sun4i_tv.c
|
|
@@ -10,6 +10,7 @@
|
|
#include <linux/component.h>
|
|
#include <linux/module.h>
|
|
#include <linux/of_address.h>
|
|
+#include <linux/of_device.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/regmap.h>
|
|
#include <linux/reset.h>
|
|
@@ -159,6 +160,11 @@ struct tv_mode {
|
|
const struct resync_parameters *resync_params;
|
|
};
|
|
|
|
+struct sun4i_tv_quirks {
|
|
+ unsigned int calibration;
|
|
+ unsigned int unknown : 1;
|
|
+};
|
|
+
|
|
struct sun4i_tv {
|
|
struct drm_connector connector;
|
|
struct drm_encoder encoder;
|
|
@@ -419,7 +425,7 @@ static const struct regmap_config sun4i_tv_regmap_config = {
|
|
.reg_bits = 32,
|
|
.val_bits = 32,
|
|
.reg_stride = 4,
|
|
- .max_register = SUN4I_TVE_WSS_DATA2_REG,
|
|
+ .max_register = 0x400,
|
|
.name = "tv-encoder",
|
|
};
|
|
|
|
@@ -429,13 +435,19 @@ static int sun4i_tv_bind(struct device *dev, struct device *master,
|
|
struct platform_device *pdev = to_platform_device(dev);
|
|
struct drm_device *drm = data;
|
|
struct sun4i_drv *drv = drm->dev_private;
|
|
+ const struct sun4i_tv_quirks *quirks;
|
|
struct sun4i_tv *tv;
|
|
void __iomem *regs;
|
|
int ret;
|
|
|
|
+ quirks = of_device_get_match_data(dev);
|
|
+ if (!quirks)
|
|
+ return -EINVAL;
|
|
+
|
|
tv = devm_kzalloc(dev, sizeof(*tv), GFP_KERNEL);
|
|
if (!tv)
|
|
return -ENOMEM;
|
|
+
|
|
tv->drv = drv;
|
|
dev_set_drvdata(dev, tv);
|
|
|
|
@@ -472,6 +484,11 @@ static int sun4i_tv_bind(struct device *dev, struct device *master,
|
|
}
|
|
clk_prepare_enable(tv->clk);
|
|
|
|
+ if (quirks->calibration)
|
|
+ regmap_write(tv->regs, 0x304, quirks->calibration);
|
|
+ if (quirks->unknown)
|
|
+ regmap_write(tv->regs, 0x30c, 0x00101110);
|
|
+
|
|
drm_encoder_helper_add(&tv->encoder,
|
|
&sun4i_tv_helper_funcs);
|
|
ret = drm_simple_encoder_init(drm, &tv->encoder,
|
|
@@ -551,8 +568,22 @@ static void sun4i_tv_remove(struct platform_device *pdev)
|
|
component_del(&pdev->dev, &sun4i_tv_ops);
|
|
}
|
|
|
|
+static const struct sun4i_tv_quirks a10_quirks = {
|
|
+};
|
|
+
|
|
+static const struct sun4i_tv_quirks h3_quirks = {
|
|
+ .calibration = 0x02000c00,
|
|
+};
|
|
+
|
|
+static const struct sun4i_tv_quirks h5_quirks = {
|
|
+ .calibration = 0x02850000,
|
|
+ .unknown = 1,
|
|
+};
|
|
+
|
|
static const struct of_device_id sun4i_tv_of_table[] = {
|
|
- { .compatible = "allwinner,sun4i-a10-tv-encoder" },
|
|
+ { .compatible = "allwinner,sun4i-a10-tv-encoder", .data = &a10_quirks },
|
|
+ { .compatible = "allwinner,sun8i-h3-tv-encoder", .data = &h3_quirks },
|
|
+ { .compatible = "allwinner,sun50i-h5-tv-encoder", .data = &h5_quirks },
|
|
{ }
|
|
};
|
|
MODULE_DEVICE_TABLE(of, sun4i_tv_of_table);
|
|
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c
|
|
index 111111111111..222222222222 100644
|
|
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
|
|
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
|
|
@@ -38,6 +38,12 @@ struct de2_fmt_info {
|
|
u32 de2_fmt;
|
|
};
|
|
|
|
+static const u32 sun8i_rgb2yuv_coef[12] = {
|
|
+ 0x00000107, 0x00000204, 0x00000064, 0x00004200,
|
|
+ 0x00001f68, 0x00001ed6, 0x000001c2, 0x00020200,
|
|
+ 0x000001c2, 0x00001e87, 0x00001fb7, 0x00020200,
|
|
+};
|
|
+
|
|
static bool hw_preconfigured;
|
|
|
|
static const struct de2_fmt_info de2_formats[] = {
|
|
@@ -475,11 +481,30 @@ static u32 *sun8i_mixer_get_supported_fmts(struct sunxi_engine *engine, u32 *num
|
|
return formats;
|
|
}
|
|
|
|
+static void sun8i_mixer_apply_color_correction(struct sunxi_engine *engine)
|
|
+{
|
|
+ DRM_DEBUG_DRIVER("Applying RGB to YUV color correction\n");
|
|
+
|
|
+ regmap_bulk_write(engine->regs, SUN8I_MIXER_DCSC_COEF_REG(0),
|
|
+ sun8i_rgb2yuv_coef, 12);
|
|
+ regmap_write(engine->regs, SUN8I_MIXER_DCSC_EN, 1);
|
|
+}
|
|
+
|
|
+static void sun8i_mixer_disable_color_correction(struct sunxi_engine *engine)
|
|
+{
|
|
+ DRM_DEBUG_DRIVER("Disabling color correction\n");
|
|
+
|
|
+ /* Disable color correction */
|
|
+ regmap_write(engine->regs, SUN8I_MIXER_DCSC_EN, 0);
|
|
+}
|
|
+
|
|
static const struct sunxi_engine_ops sun8i_engine_ops = {
|
|
.commit = sun8i_mixer_commit,
|
|
.layers_init = sun8i_layers_init,
|
|
.mode_set = sun8i_mixer_mode_set,
|
|
.get_supported_fmts = sun8i_mixer_get_supported_fmts,
|
|
+ .apply_color_correction = sun8i_mixer_apply_color_correction,
|
|
+ .disable_color_correction = sun8i_mixer_disable_color_correction,
|
|
};
|
|
|
|
static const struct regmap_config sun8i_mixer_regmap_config = {
|
|
@@ -826,8 +851,9 @@ static const struct sun8i_mixer_cfg sun8i_h3_mixer0_cfg = {
|
|
static const struct sun8i_mixer_cfg sun8i_h3_mixer1_cfg = {
|
|
.ccsc = CCSC_MIXER1_LAYOUT,
|
|
.mod_rate = 432000000,
|
|
- .scaler_mask = 0xf,
|
|
- .ui_num = 3,
|
|
+ .scaler_mask = 0x3,
|
|
+ .scanline_yuv = 2048,
|
|
+ .ui_num = 1,
|
|
.vi_num = 1,
|
|
};
|
|
|
|
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h
|
|
index 111111111111..222222222222 100644
|
|
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.h
|
|
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h
|
|
@@ -134,6 +134,8 @@
|
|
#define SUN8I_MIXER_ASE_EN 0xa8000
|
|
#define SUN8I_MIXER_FCC_EN 0xaa000
|
|
#define SUN8I_MIXER_DCSC_EN 0xb0000
|
|
+/* The DCSC sub-engine is used to do color space conversation */
|
|
+#define SUN8I_MIXER_DCSC_COEF_REG(x) (0xb0010 + 0x4 * (x))
|
|
|
|
#define SUN50I_MIXER_FCE_EN 0x70000
|
|
#define SUN50I_MIXER_PEAK_EN 0x70800
|
|
--
|
|
Armbian
|
|
|