diff --git a/board/anbernic/rg35xx-plus/fs-overlay/usr/local/bin/scaling_setspeed.sh b/board/anbernic/rg35xx-plus/fs-overlay/usr/local/bin/scaling_setspeed.sh new file mode 100755 index 000000000000..b54e7cc1599d --- /dev/null +++ b/board/anbernic/rg35xx-plus/fs-overlay/usr/local/bin/scaling_setspeed.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +available_freq=("480000" "720000" "1008000" "1032000" "1104000" "1200000" "1416000") + +# Seed random generator +RANDOM=$$$(date +%s) + +echo userspace > /sys/devices/system/cpu/cpufreq/policy0/scaling_governor +stress-ng -c4 & + +for (( ; ; )) +do + CHOICE_FREQ=${available_freq[$RANDOM % ${#available_freq[@]}]} + echo $CHOICE_FREQ + echo "$CHOICE_FREQ" > /sys/devices/system/cpu/cpufreq/policy0/scaling_setspeed + sleep 0.1 +done + diff --git a/board/anbernic/rg35xx-plus/fs-overlay/usr/local/bin/scaling_setspeed_1.5.sh b/board/anbernic/rg35xx-plus/fs-overlay/usr/local/bin/scaling_setspeed_1.5.sh new file mode 100755 index 000000000000..ef77ea318f03 --- /dev/null +++ b/board/anbernic/rg35xx-plus/fs-overlay/usr/local/bin/scaling_setspeed_1.5.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +available_freq=("480000" "720000" "1008000" "1032000" "1104000" "1200000" "1416000" "1512000") + +# Seed random generator +RANDOM=$$$(date +%s) + +echo userspace > /sys/devices/system/cpu/cpufreq/policy0/scaling_governor +stress-ng -c4 & + +for (( ; ; )) +do + CHOICE_FREQ=${available_freq[$RANDOM % ${#available_freq[@]}]} + echo $CHOICE_FREQ + echo "$CHOICE_FREQ" > /sys/devices/system/cpu/cpufreq/policy0/scaling_setspeed + sleep 0.1 +done + diff --git a/board/anbernic/rg35xx-plus/patches/linux/0001-add-opp-bsp-dts.patch b/board/anbernic/rg35xx-plus/patches/linux/0001-add-opp-bsp-dts.patch new file mode 100644 index 000000000000..12e28d0abefe --- /dev/null +++ b/board/anbernic/rg35xx-plus/patches/linux/0001-add-opp-bsp-dts.patch @@ -0,0 +1,562 @@ +From af7823092341d2747dc89a382567db7758ad12ab Mon Sep 17 00:00:00 2001 +From: Philippe Simons +Date: Fri, 29 Nov 2024 00:05:48 +0100 +Subject: [PATCH] add opp-bsp dts + +--- + .../allwinner/sun50i-h616-cpu-opp-bsp.dtsi | 125 +++++++ + .../dts/allwinner/sun50i-h616-cpu-opp.dtsi | 19 +- + .../sun50i-h700-anbernic-rg35xx-2024-bsp.dts | 348 ++++++++++++++++++ + .../sun50i-h700-anbernic-rg35xx-plus-bsp.dts | 53 +++ + 4 files changed, 536 insertions(+), 9 deletions(-) + create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h616-cpu-opp-bsp.dtsi + create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024-bsp.dts + create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-plus-bsp.dts + +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616-cpu-opp-bsp.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616-cpu-opp-bsp.dtsi +new file mode 100644 +index 000000000..ac13fe169 +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-cpu-opp-bsp.dtsi +@@ -0,0 +1,125 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++// Copyright (C) 2023 Martin Botka ++ ++/ { ++ cpu_opp_table: opp-table-cpu { ++ compatible = "allwinner,sun50i-h616-operating-points"; ++ nvmem-cells = <&cpu_speed_grade>; ++ opp-shared; ++ ++ opp-480000000 { ++ opp-hz = /bits/ 64 <480000000>; ++ opp-microvolt = <900000>; ++ clock-latency-ns = <244144>; /* 8 32k periods */ ++ opp-supported-hw = <0x3f>; ++ }; ++ ++ opp-600000000 { ++ opp-hz = /bits/ 64 <600000000>; ++ opp-microvolt = <900000>; ++ clock-latency-ns = <244144>; /* 8 32k periods */ ++ opp-supported-hw = <0x12>; ++ }; ++ ++ opp-720000000 { ++ opp-hz = /bits/ 64 <720000000>; ++ opp-microvolt = <900000>; ++ clock-latency-ns = <244144>; /* 8 32k periods */ ++ opp-supported-hw = <0x2d>; ++ }; ++ ++ opp-792000000 { ++ opp-hz = /bits/ 64 <792000000>; ++ opp-microvolt-speed1 = <900000>; ++ opp-microvolt-speed4 = <940000>; ++ clock-latency-ns = <244144>; /* 8 32k periods */ ++ opp-supported-hw = <0x12>; ++ }; ++ ++ opp-936000000 { ++ opp-hz = /bits/ 64 <936000000>; ++ opp-microvolt = <900000>; ++ clock-latency-ns = <244144>; /* 8 32k periods */ ++ opp-supported-hw = <0x0d>; ++ }; ++ ++ opp-1008000000 { ++ opp-hz = /bits/ 64 <1008000000>; ++ opp-microvolt-speed0 = <950000>; ++ opp-microvolt-speed1 = <940000>; ++ opp-microvolt-speed2 = <950000>; ++ opp-microvolt-speed3 = <950000>; ++ opp-microvolt-speed4 = <1020000>; ++ opp-microvolt-speed5 = <950000>; ++ clock-latency-ns = <244144>; /* 8 32k periods */ ++ opp-supported-hw = <0x3f>; ++ }; ++ ++ opp-1032000000 { ++ opp-hz = /bits/ 64 <1032000000>; ++ opp-microvolt = <950000>; ++ clock-latency-ns = <244144>; /* 8 32k periods */ ++ opp-supported-hw = <0x20>; ++ }; ++ ++ opp-1104000000 { ++ opp-hz = /bits/ 64 <1104000000>; ++ opp-microvolt = <1000000>; ++ clock-latency-ns = <244144>; /* 8 32k periods */ ++ opp-supported-hw = <0x2d>; ++ }; ++ ++ opp-1200000000 { ++ opp-hz = /bits/ 64 <1200000000>; ++ opp-microvolt-speed0 = <1050000>; ++ opp-microvolt-speed1 = <1020000>; ++ opp-microvolt-speed2 = <1050000>; ++ opp-microvolt-speed3 = <1050000>; ++ opp-microvolt-speed4 = <1100000>; ++ opp-microvolt-speed5 = <1050000>; ++ clock-latency-ns = <244144>; /* 8 32k periods */ ++ opp-supported-hw = <0x3f>; ++ }; ++ ++ opp-1320000000 { ++ opp-hz = /bits/ 64 <1320000000>; ++ opp-microvolt = <1100000>; ++ clock-latency-ns = <244144>; /* 8 32k periods */ ++ opp-supported-hw = <0x1d>; ++ }; ++ ++ opp-1416000000 { ++ opp-hz = /bits/ 64 <1416000000>; ++ opp-microvolt-speed0 = <1100000>; ++ opp-microvolt-speed2 = <1100000>; ++ opp-microvolt-speed3 = <1100000>; ++ opp-microvolt-speed5 = <1160000>; ++ clock-latency-ns = <244144>; /* 8 32k periods */ ++ opp-supported-hw = <0x2d>; ++ }; ++ ++ opp-1512000000 { ++ opp-hz = /bits/ 64 <1512000000>; ++ opp-microvolt-speed1 = <1100000>; ++ opp-microvolt-speed3 = <1100000>; ++ clock-latency-ns = <244144>; /* 8 32k periods */ ++ opp-supported-hw = <0x0a>; ++ }; ++ }; ++}; ++ ++&cpu0 { ++ operating-points-v2 = <&cpu_opp_table>; ++}; ++ ++&cpu1 { ++ operating-points-v2 = <&cpu_opp_table>; ++}; ++ ++&cpu2 { ++ operating-points-v2 = <&cpu_opp_table>; ++}; ++ ++&cpu3 { ++ operating-points-v2 = <&cpu_opp_table>; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024-bsp.dts b/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024-bsp.dts +new file mode 100644 +index 000000000..9471d4606 +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024-bsp.dts +@@ -0,0 +1,348 @@ ++// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) ++/* ++ * Copyright (C) 2024 Ryan Walklin . ++ */ ++ ++/dts-v1/; ++ ++#include "sun50i-h616.dtsi" ++#include "sun50i-h616-cpu-opp-bsp.dtsi" ++#include ++#include ++#include ++#include ++ ++/ { ++ model = "Anbernic RG35XX 2024"; ++ chassis-type = "handset"; ++ compatible = "anbernic,rg35xx-2024", "allwinner,sun50i-h700"; ++ ++ aliases { ++ serial0 = &uart0; ++ }; ++ ++ battery: battery { ++ compatible = "simple-battery"; ++ constant-charge-current-max-microamp = <1024000>; ++ voltage-max-design-microvolt = <4200000>; ++ }; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ gpio_keys_gamepad: gpio-keys-gamepad { ++ compatible = "gpio-keys"; ++ ++ button-a { ++ label = "Action-Pad A"; ++ gpios = <&pio 0 0 GPIO_ACTIVE_LOW>; /* PA0 */ ++ linux,input-type = ; ++ linux,code = ; ++ }; ++ ++ button-b { ++ label = "Action-Pad B"; ++ gpios = <&pio 0 1 GPIO_ACTIVE_LOW>; /* PA1 */ ++ linux,input-type = ; ++ linux,code = ; ++ }; ++ ++ button-down { ++ label = "D-Pad Down"; ++ gpios = <&pio 4 0 GPIO_ACTIVE_LOW>; /* PE0 */ ++ linux,input-type = ; ++ linux,code = ; ++ }; ++ ++ button-l1 { ++ label = "Key L1"; ++ gpios = <&pio 0 10 GPIO_ACTIVE_LOW>; /* PA10 */ ++ linux,input-type = ; ++ linux,code = ; ++ }; ++ ++ button-l2 { ++ label = "Key L2"; ++ gpios = <&pio 0 11 GPIO_ACTIVE_LOW>; /* PA11 */ ++ linux,input-type = ; ++ linux,code = ; ++ }; ++ ++ button-left { ++ label = "D-Pad left"; ++ gpios = <&pio 0 8 GPIO_ACTIVE_LOW>; /* PA8 */ ++ linux,input-type = ; ++ linux,code = ; ++ }; ++ ++ button-menu { ++ label = "Key Menu"; ++ gpios = <&pio 4 3 GPIO_ACTIVE_LOW>; /* PE3 */ ++ linux,input-type = ; ++ linux,code = ; ++ }; ++ ++ button-r1 { ++ label = "Key R1"; ++ gpios = <&pio 0 12 GPIO_ACTIVE_LOW>; /* PA12 */ ++ linux,input-type = ; ++ linux,code = ; ++ }; ++ ++ button-r2 { ++ label = "Key R2"; ++ gpios = <&pio 0 7 GPIO_ACTIVE_LOW>; /* PA7 */ ++ linux,input-type = ; ++ linux,code = ; ++ }; ++ ++ button-right { ++ label = "D-Pad Right"; ++ gpios = <&pio 0 9 GPIO_ACTIVE_LOW>; /* PA9 */ ++ linux,input-type = ; ++ linux,code = ; ++ }; ++ ++ button-select { ++ label = "Key Select"; ++ gpios = <&pio 0 5 GPIO_ACTIVE_LOW>; /* PA5 */ ++ linux,input-type = ; ++ linux,code = ; ++ }; ++ button-start { ++ label = "Key Start"; ++ gpios = <&pio 0 4 GPIO_ACTIVE_LOW>; /* PA4 */ ++ linux,input-type = ; ++ linux,code = ; ++ }; ++ ++ button-up { ++ label = "D-Pad Up"; ++ gpios = <&pio 0 6 GPIO_ACTIVE_LOW>; /* PA6 */ ++ linux,input-type = ; ++ linux,code = ; ++ }; ++ ++ button-x { ++ label = "Action-Pad X"; ++ gpios = <&pio 0 3 GPIO_ACTIVE_LOW>; /* PA3 */ ++ linux,input-type = ; ++ linux,code = ; ++ }; ++ ++ button-y { ++ label = "Action Pad Y"; ++ gpios = <&pio 0 2 GPIO_ACTIVE_LOW>; /* PA2 */ ++ linux,input-type = ; ++ linux,code = ; ++ }; ++ }; ++ ++ gpio-keys-volume { ++ compatible = "gpio-keys"; ++ autorepeat; ++ ++ button-vol-up { ++ label = "Key Volume Up"; ++ gpios = <&pio 4 1 GPIO_ACTIVE_LOW>; /* PE1 */ ++ linux,input-type = ; ++ linux,code = ; ++ }; ++ ++ button-vol-down { ++ label = "Key Volume Down"; ++ gpios = <&pio 4 2 GPIO_ACTIVE_LOW>; /* PE2 */ ++ linux,input-type = ; ++ linux,code = ; ++ }; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ led-0 { ++ function = LED_FUNCTION_POWER; ++ color = ; ++ gpios = <&pio 8 12 GPIO_ACTIVE_HIGH>; /* PI12 */ ++ default-state = "on"; ++ }; ++ }; ++ ++ reg_vcc5v: regulator-vcc5v { /* USB-C power input */ ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc-5v"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ }; ++}; ++ ++&cpu0 { ++ cpu-supply = <®_dcdc1>; ++}; ++ ++&ehci0 { ++ status = "okay"; ++}; ++ ++&mmc0 { ++ vmmc-supply = <®_cldo3>; ++ disable-wp; ++ cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */ ++ bus-width = <4>; ++ status = "okay"; ++}; ++ ++&ohci0 { ++ status = "okay"; ++}; ++ ++&pio { ++ vcc-pa-supply = <®_cldo3>; ++ vcc-pc-supply = <®_cldo3>; ++ vcc-pe-supply = <®_cldo3>; ++ vcc-pf-supply = <®_cldo3>; ++ vcc-pg-supply = <®_aldo4>; ++ vcc-ph-supply = <®_cldo3>; ++ vcc-pi-supply = <®_cldo3>; ++}; ++ ++&r_i2c { ++ status = "okay"; ++ ++ axp717: pmic@34 { ++ compatible = "x-powers,axp717"; ++ reg = <0x34>; ++ interrupt-controller; ++ #interrupt-cells = <1>; ++ interrupt-parent = <&nmi_intc>; ++ interrupts = <0 IRQ_TYPE_LEVEL_LOW>; ++ ++ vin1-supply = <®_vcc5v>; ++ vin2-supply = <®_vcc5v>; ++ vin3-supply = <®_vcc5v>; ++ vin4-supply = <®_vcc5v>; ++ ++ axp_adc: adc { ++ compatible = "x-powers,axp717-adc"; ++ #io-channel-cells = <1>; ++ }; ++ ++ battery_power: battery-power { ++ compatible = "x-powers,axp717-battery-power-supply"; ++ monitored-battery = <&battery>; ++ }; ++ ++ regulators { ++ reg_dcdc1: dcdc1 { ++ regulator-always-on; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <1160000>; ++ regulator-name = "vdd-cpu"; ++ }; ++ ++ reg_dcdc2: dcdc2 { ++ regulator-always-on; ++ regulator-min-microvolt = <940000>; ++ regulator-max-microvolt = <940000>; ++ regulator-name = "vdd-gpu-sys"; ++ }; ++ ++ reg_dcdc3: dcdc3 { ++ regulator-always-on; ++ regulator-min-microvolt = <1100000>; ++ regulator-max-microvolt = <1100000>; ++ regulator-name = "vdd-dram"; ++ }; ++ ++ reg_aldo1: aldo1 { ++ /* 1.8v - unused */ ++ }; ++ ++ reg_aldo2: aldo2 { ++ /* 1.8v - unused */ ++ }; ++ ++ reg_aldo3: aldo3 { ++ /* 1.8v - unused */ ++ }; ++ ++ reg_aldo4: aldo4 { ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-name = "vcc-pg"; ++ }; ++ ++ reg_bldo1: bldo1 { ++ /* 1.8v - unused */ ++ }; ++ ++ reg_bldo2: bldo2 { ++ regulator-always-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-name = "vcc-pll"; ++ }; ++ ++ reg_bldo3: bldo3 { ++ /* 2.8v - unused */ ++ }; ++ ++ reg_bldo4: bldo4 { ++ /* 1.2v - unused */ ++ }; ++ ++ reg_cldo1: cldo1 { ++ /* 3.3v - audio codec - not yet implemented */ ++ }; ++ ++ reg_cldo2: cldo2 { ++ /* 3.3v - unused */ ++ }; ++ ++ reg_cldo3: cldo3 { ++ regulator-always-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-name = "vcc-io"; ++ }; ++ ++ reg_cldo4: cldo4 { ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-name = "vcc-wifi"; ++ }; ++ ++ reg_boost: boost { ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5200000>; ++ regulator-name = "boost"; ++ }; ++ ++ reg_cpusldo: cpusldo { ++ /* unused */ ++ }; ++ }; ++ ++ usb_power: usb-power { ++ compatible = "x-powers,axp717-usb-power-supply"; ++ input-current-limit-microamp = <1500000>; ++ }; ++ }; ++}; ++ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_ph_pins>; ++ status = "okay"; ++}; ++ ++/* the AXP717 has USB type-C role switch functionality, not yet described by the binding */ ++&usbotg { ++ dr_mode = "peripheral"; /* USB type-C receptable */ ++ status = "okay"; ++}; ++ ++&usbphy { ++ status = "okay"; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-plus-bsp.dts b/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-plus-bsp.dts +new file mode 100644 +index 000000000..087fe1865 +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-plus-bsp.dts +@@ -0,0 +1,53 @@ ++// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) ++/* ++ * Copyright (C) 2024 Ryan Walklin . ++ */ ++ ++#include "sun50i-h700-anbernic-rg35xx-2024-bsp.dts" ++ ++/ { ++ model = "Anbernic RG35XX Plus"; ++ compatible = "anbernic,rg35xx-plus", "allwinner,sun50i-h700"; ++ ++ wifi_pwrseq: pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ clocks = <&rtc CLK_OSC32K_FANOUT>; ++ clock-names = "ext_clock"; ++ pinctrl-0 = <&x32clk_fanout_pin>; ++ pinctrl-names = "default"; ++ post-power-on-delay-ms = <200>; ++ reset-gpios = <&pio 6 18 GPIO_ACTIVE_LOW>; /* PG18 */ ++ }; ++}; ++ ++/* SDIO WiFi RTL8821CS */ ++&mmc1 { ++ vmmc-supply = <®_cldo4>; ++ vqmmc-supply = <®_aldo4>; ++ mmc-pwrseq = <&wifi_pwrseq>; ++ bus-width = <4>; ++ non-removable; ++ status = "okay"; ++ ++ sdio_wifi: wifi@1 { ++ reg = <1>; ++ interrupt-parent = <&pio>; ++ interrupts = <6 15 IRQ_TYPE_LEVEL_LOW>; /* PG15 */ ++ interrupt-names = "host-wake"; ++ }; ++}; ++ ++/* Bluetooth RTL8821CS */ ++&uart1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>; ++ uart-has-rtscts; ++ status = "okay"; ++ ++ bluetooth { ++ compatible = "realtek,rtl8821cs-bt", "realtek,rtl8723bs-bt"; ++ device-wake-gpios = <&pio 6 17 GPIO_ACTIVE_HIGH>; /* PG17 */ ++ enable-gpios = <&pio 6 19 GPIO_ACTIVE_HIGH>; /* PG19 */ ++ host-wake-gpios = <&pio 6 16 GPIO_ACTIVE_HIGH>; /* PG16 */ ++ }; ++}; +-- +2.46.1 + diff --git a/board/anbernic/rg35xx-plus/patches/linux/0001-v5_20240929_ryan_drm_sun4i_add_display_engine_3_3_de33_support.patch b/board/anbernic/rg35xx-plus/patches/linux/0001-v5_20240929_ryan_drm_sun4i_add_display_engine_3_3_de33_support.patch deleted file mode 100644 index 9cabb8faddaf..000000000000 --- a/board/anbernic/rg35xx-plus/patches/linux/0001-v5_20240929_ryan_drm_sun4i_add_display_engine_3_3_de33_support.patch +++ /dev/null @@ -1,3652 +0,0 @@ -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH v5 1/26] drm: sun4i: de2/de3: Change CSC argument -From: Jernej Skrabec -Date: Sun, 29 Sep 2024 22:04:33 +1300 -Message-Id: <20240929091107.838023-2-ryan@testtoast.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -Currently, CSC module takes care only for converting YUV to RGB. -However, DE3 is more suited to work in YUV color space. Change CSC mode -argument to format type to be more neutral. New argument only tells -layer format type and doesn't imply output type. - -This commit doesn't make any functional change. - -Signed-off-by: Jernej Skrabec -Signed-off-by: Ryan Walklin -Reviewed-by: Andre Przywara -Reviewed-by: Chen-Yu Tsai -Acked-by: Conor Dooley ---- - drivers/gpu/drm/sun4i/sun8i_csc.c | 22 +++++++++++----------- - drivers/gpu/drm/sun4i/sun8i_csc.h | 10 +++++----- - drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 16 ++++++++-------- - 3 files changed, 24 insertions(+), 24 deletions(-) - -diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c b/drivers/gpu/drm/sun4i/sun8i_csc.c -index 58480d8e4f704..6ebd1c3aa3ab5 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_csc.c -+++ b/drivers/gpu/drm/sun4i/sun8i_csc.c -@@ -108,7 +108,7 @@ static const u32 yuv2rgb_de3[2][3][12] = { - }; - - static void sun8i_csc_set_coefficients(struct regmap *map, u32 base, -- enum sun8i_csc_mode mode, -+ enum format_type fmt_type, - enum drm_color_encoding encoding, - enum drm_color_range range) - { -@@ -118,12 +118,12 @@ static void sun8i_csc_set_coefficients(struct regmap *map, u32 base, - - table = yuv2rgb[range][encoding]; - -- switch (mode) { -- case SUN8I_CSC_MODE_YUV2RGB: -+ switch (fmt_type) { -+ case FORMAT_TYPE_YUV: - base_reg = SUN8I_CSC_COEFF(base, 0); - regmap_bulk_write(map, base_reg, table, 12); - break; -- case SUN8I_CSC_MODE_YVU2RGB: -+ case FORMAT_TYPE_YVU: - for (i = 0; i < 12; i++) { - if ((i & 3) == 1) - base_reg = SUN8I_CSC_COEFF(base, i + 1); -@@ -141,7 +141,7 @@ static void sun8i_csc_set_coefficients(struct regmap *map, u32 base, - } - - static void sun8i_de3_ccsc_set_coefficients(struct regmap *map, int layer, -- enum sun8i_csc_mode mode, -+ enum format_type fmt_type, - enum drm_color_encoding encoding, - enum drm_color_range range) - { -@@ -151,12 +151,12 @@ static void sun8i_de3_ccsc_set_coefficients(struct regmap *map, int layer, - - table = yuv2rgb_de3[range][encoding]; - -- switch (mode) { -- case SUN8I_CSC_MODE_YUV2RGB: -+ switch (fmt_type) { -+ case FORMAT_TYPE_YUV: - addr = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE, layer, 0); - regmap_bulk_write(map, addr, table, 12); - break; -- case SUN8I_CSC_MODE_YVU2RGB: -+ case FORMAT_TYPE_YVU: - for (i = 0; i < 12; i++) { - if ((i & 3) == 1) - addr = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE, -@@ -206,7 +206,7 @@ static void sun8i_de3_ccsc_enable(struct regmap *map, int layer, bool enable) - } - - void sun8i_csc_set_ccsc_coefficients(struct sun8i_mixer *mixer, int layer, -- enum sun8i_csc_mode mode, -+ enum format_type fmt_type, - enum drm_color_encoding encoding, - enum drm_color_range range) - { -@@ -214,14 +214,14 @@ void sun8i_csc_set_ccsc_coefficients(struct sun8i_mixer *mixer, int layer, - - if (mixer->cfg->is_de3) { - sun8i_de3_ccsc_set_coefficients(mixer->engine.regs, layer, -- mode, encoding, range); -+ fmt_type, encoding, range); - return; - } - - base = ccsc_base[mixer->cfg->ccsc][layer]; - - sun8i_csc_set_coefficients(mixer->engine.regs, base, -- mode, encoding, range); -+ fmt_type, encoding, range); - } - - void sun8i_csc_enable_ccsc(struct sun8i_mixer *mixer, int layer, bool enable) -diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.h b/drivers/gpu/drm/sun4i/sun8i_csc.h -index 828b86fd0cabb..7322770f39f03 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_csc.h -+++ b/drivers/gpu/drm/sun4i/sun8i_csc.h -@@ -22,14 +22,14 @@ struct sun8i_mixer; - - #define SUN8I_CSC_CTRL_EN BIT(0) - --enum sun8i_csc_mode { -- SUN8I_CSC_MODE_OFF, -- SUN8I_CSC_MODE_YUV2RGB, -- SUN8I_CSC_MODE_YVU2RGB, -+enum format_type { -+ FORMAT_TYPE_RGB, -+ FORMAT_TYPE_YUV, -+ FORMAT_TYPE_YVU, - }; - - void sun8i_csc_set_ccsc_coefficients(struct sun8i_mixer *mixer, int layer, -- enum sun8i_csc_mode mode, -+ enum format_type fmt_type, - enum drm_color_encoding encoding, - enum drm_color_range range); - void sun8i_csc_enable_ccsc(struct sun8i_mixer *mixer, int layer, bool enable); -diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c -index 9c09d9c08496d..8a80934e928fe 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c -+++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c -@@ -193,19 +193,19 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel, - return 0; - } - --static u32 sun8i_vi_layer_get_csc_mode(const struct drm_format_info *format) -+static u32 sun8i_vi_layer_get_format_type(const struct drm_format_info *format) - { - if (!format->is_yuv) -- return SUN8I_CSC_MODE_OFF; -+ return FORMAT_TYPE_RGB; - - switch (format->format) { - case DRM_FORMAT_YVU411: - case DRM_FORMAT_YVU420: - case DRM_FORMAT_YVU422: - case DRM_FORMAT_YVU444: -- return SUN8I_CSC_MODE_YVU2RGB; -+ return FORMAT_TYPE_YVU; - default: -- return SUN8I_CSC_MODE_YUV2RGB; -+ return FORMAT_TYPE_YUV; - } - } - -@@ -213,7 +213,7 @@ static int sun8i_vi_layer_update_formats(struct sun8i_mixer *mixer, int channel, - int overlay, struct drm_plane *plane) - { - struct drm_plane_state *state = plane->state; -- u32 val, ch_base, csc_mode, hw_fmt; -+ u32 val, ch_base, fmt_type, hw_fmt; - const struct drm_format_info *fmt; - int ret; - -@@ -231,9 +231,9 @@ static int sun8i_vi_layer_update_formats(struct sun8i_mixer *mixer, int channel, - SUN8I_MIXER_CHAN_VI_LAYER_ATTR(ch_base, overlay), - SUN8I_MIXER_CHAN_VI_LAYER_ATTR_FBFMT_MASK, val); - -- csc_mode = sun8i_vi_layer_get_csc_mode(fmt); -- if (csc_mode != SUN8I_CSC_MODE_OFF) { -- sun8i_csc_set_ccsc_coefficients(mixer, channel, csc_mode, -+ fmt_type = sun8i_vi_layer_get_format_type(fmt); -+ if (fmt_type != FORMAT_TYPE_RGB) { -+ sun8i_csc_set_ccsc_coefficients(mixer, channel, fmt_type, - state->color_encoding, - state->color_range); - sun8i_csc_enable_ccsc(mixer, channel, true); --- -2.46.1 - -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH v5 2/26] drm: sun4i: de2/de3: Merge CSC functions into one -From: Jernej Skrabec -Date: Sun, 29 Sep 2024 22:04:34 +1300 -Message-Id: <20240929091107.838023-3-ryan@testtoast.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -At the moment the colour space conversion is handled by two functions: -one to setup the conversion parameters, and another one to enable the -conversion. Merging both into one gives more flexibility for upcoming -extensions to support whole YUV pipelines, in the DE33. - -Signed-off-by: Jernej Skrabec -Signed-off-by: Ryan Walklin -Reviewed-by: Andre Przywara -Reviewed-by: Chen-Yu Tsai -Acked-by: Conor Dooley ---- - drivers/gpu/drm/sun4i/sun8i_csc.c | 89 ++++++++++---------------- - drivers/gpu/drm/sun4i/sun8i_csc.h | 9 ++- - drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 11 +--- - 3 files changed, 40 insertions(+), 69 deletions(-) - -diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c b/drivers/gpu/drm/sun4i/sun8i_csc.c -index 6ebd1c3aa3ab5..0dcbc0866ae82 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_csc.c -+++ b/drivers/gpu/drm/sun4i/sun8i_csc.c -@@ -107,23 +107,28 @@ static const u32 yuv2rgb_de3[2][3][12] = { - }, - }; - --static void sun8i_csc_set_coefficients(struct regmap *map, u32 base, -- enum format_type fmt_type, -- enum drm_color_encoding encoding, -- enum drm_color_range range) -+static void sun8i_csc_setup(struct regmap *map, u32 base, -+ enum format_type fmt_type, -+ enum drm_color_encoding encoding, -+ enum drm_color_range range) - { -+ u32 base_reg, val; - const u32 *table; -- u32 base_reg; - int i; - - table = yuv2rgb[range][encoding]; - - switch (fmt_type) { -+ case FORMAT_TYPE_RGB: -+ val = 0; -+ break; - case FORMAT_TYPE_YUV: -+ val = SUN8I_CSC_CTRL_EN; - base_reg = SUN8I_CSC_COEFF(base, 0); - regmap_bulk_write(map, base_reg, table, 12); - break; - case FORMAT_TYPE_YVU: -+ val = SUN8I_CSC_CTRL_EN; - for (i = 0; i < 12; i++) { - if ((i & 3) == 1) - base_reg = SUN8I_CSC_COEFF(base, i + 1); -@@ -135,28 +140,37 @@ static void sun8i_csc_set_coefficients(struct regmap *map, u32 base, - } - break; - default: -+ val = 0; - DRM_WARN("Wrong CSC mode specified.\n"); - return; - } -+ -+ regmap_write(map, SUN8I_CSC_CTRL(base), val); - } - --static void sun8i_de3_ccsc_set_coefficients(struct regmap *map, int layer, -- enum format_type fmt_type, -- enum drm_color_encoding encoding, -- enum drm_color_range range) -+static void sun8i_de3_ccsc_setup(struct regmap *map, int layer, -+ enum format_type fmt_type, -+ enum drm_color_encoding encoding, -+ enum drm_color_range range) - { -+ u32 addr, val, mask; - const u32 *table; -- u32 addr; - int i; - -+ mask = SUN50I_MIXER_BLEND_CSC_CTL_EN(layer); - table = yuv2rgb_de3[range][encoding]; - - switch (fmt_type) { -+ case FORMAT_TYPE_RGB: -+ val = 0; -+ break; - case FORMAT_TYPE_YUV: -+ val = mask; - addr = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE, layer, 0); - regmap_bulk_write(map, addr, table, 12); - break; - case FORMAT_TYPE_YVU: -+ val = mask; - for (i = 0; i < 12; i++) { - if ((i & 3) == 1) - addr = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE, -@@ -173,67 +187,30 @@ static void sun8i_de3_ccsc_set_coefficients(struct regmap *map, int layer, - } - break; - default: -+ val = 0; - DRM_WARN("Wrong CSC mode specified.\n"); - return; - } --} -- --static void sun8i_csc_enable(struct regmap *map, u32 base, bool enable) --{ -- u32 val; -- -- if (enable) -- val = SUN8I_CSC_CTRL_EN; -- else -- val = 0; -- -- regmap_update_bits(map, SUN8I_CSC_CTRL(base), SUN8I_CSC_CTRL_EN, val); --} -- --static void sun8i_de3_ccsc_enable(struct regmap *map, int layer, bool enable) --{ -- u32 val, mask; -- -- mask = SUN50I_MIXER_BLEND_CSC_CTL_EN(layer); -- -- if (enable) -- val = mask; -- else -- val = 0; - - regmap_update_bits(map, SUN50I_MIXER_BLEND_CSC_CTL(DE3_BLD_BASE), - mask, val); - } - --void sun8i_csc_set_ccsc_coefficients(struct sun8i_mixer *mixer, int layer, -- enum format_type fmt_type, -- enum drm_color_encoding encoding, -- enum drm_color_range range) --{ -- u32 base; -- -- if (mixer->cfg->is_de3) { -- sun8i_de3_ccsc_set_coefficients(mixer->engine.regs, layer, -- fmt_type, encoding, range); -- return; -- } -- -- base = ccsc_base[mixer->cfg->ccsc][layer]; -- -- sun8i_csc_set_coefficients(mixer->engine.regs, base, -- fmt_type, encoding, range); --} -- --void sun8i_csc_enable_ccsc(struct sun8i_mixer *mixer, int layer, bool enable) -+void sun8i_csc_set_ccsc(struct sun8i_mixer *mixer, int layer, -+ enum format_type fmt_type, -+ enum drm_color_encoding encoding, -+ enum drm_color_range range) - { - u32 base; - - if (mixer->cfg->is_de3) { -- sun8i_de3_ccsc_enable(mixer->engine.regs, layer, enable); -+ sun8i_de3_ccsc_setup(mixer->engine.regs, layer, -+ fmt_type, encoding, range); - return; - } - - base = ccsc_base[mixer->cfg->ccsc][layer]; - -- sun8i_csc_enable(mixer->engine.regs, base, enable); -+ sun8i_csc_setup(mixer->engine.regs, base, -+ fmt_type, encoding, range); - } -diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.h b/drivers/gpu/drm/sun4i/sun8i_csc.h -index 7322770f39f03..b7546e06e315c 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_csc.h -+++ b/drivers/gpu/drm/sun4i/sun8i_csc.h -@@ -28,10 +28,9 @@ enum format_type { - FORMAT_TYPE_YVU, - }; - --void sun8i_csc_set_ccsc_coefficients(struct sun8i_mixer *mixer, int layer, -- enum format_type fmt_type, -- enum drm_color_encoding encoding, -- enum drm_color_range range); --void sun8i_csc_enable_ccsc(struct sun8i_mixer *mixer, int layer, bool enable); -+void sun8i_csc_set_ccsc(struct sun8i_mixer *mixer, int layer, -+ enum format_type fmt_type, -+ enum drm_color_encoding encoding, -+ enum drm_color_range range); - - #endif -diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c -index 8a80934e928fe..f3a5329351caa 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c -+++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c -@@ -232,14 +232,9 @@ static int sun8i_vi_layer_update_formats(struct sun8i_mixer *mixer, int channel, - SUN8I_MIXER_CHAN_VI_LAYER_ATTR_FBFMT_MASK, val); - - fmt_type = sun8i_vi_layer_get_format_type(fmt); -- if (fmt_type != FORMAT_TYPE_RGB) { -- sun8i_csc_set_ccsc_coefficients(mixer, channel, fmt_type, -- state->color_encoding, -- state->color_range); -- sun8i_csc_enable_ccsc(mixer, channel, true); -- } else { -- sun8i_csc_enable_ccsc(mixer, channel, false); -- } -+ sun8i_csc_set_ccsc(mixer, channel, fmt_type, -+ state->color_encoding, -+ state->color_range); - - if (!fmt->is_yuv) - val = SUN8I_MIXER_CHAN_VI_LAYER_ATTR_RGB_MODE; --- -2.46.1 - -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH v5 3/26] drm: sun4i: de2/de3: call csc setup also for UI - layer -From: Jernej Skrabec -Date: Sun, 29 Sep 2024 22:04:35 +1300 -Message-Id: <20240929091107.838023-4-ryan@testtoast.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -Currently, only VI layer calls CSC setup function. This comes from DE2 -limitation, which doesn't have CSC unit for UI layers. However, DE3 has -separate CSC units for each layer. This allows display pipeline to make -output signal in different color spaces. To support both use cases, add -a call to CSC setup function also in UI layer code. For DE2, this will -be a no-op, but it will allow DE3 to output signal in multiple formats. - -Signed-off-by: Jernej Skrabec -Signed-off-by: Ryan Walklin -Reviewed-by: Chen-Yu Tsai -Acked-by: Conor Dooley -Reviewed-by: Andre Przywara ---- - drivers/gpu/drm/sun4i/sun8i_csc.c | 8 +++++--- - drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 6 ++++++ - 2 files changed, 11 insertions(+), 3 deletions(-) - -diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c b/drivers/gpu/drm/sun4i/sun8i_csc.c -index 0dcbc0866ae82..68d955c63b05b 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_csc.c -+++ b/drivers/gpu/drm/sun4i/sun8i_csc.c -@@ -209,8 +209,10 @@ void sun8i_csc_set_ccsc(struct sun8i_mixer *mixer, int layer, - return; - } - -- base = ccsc_base[mixer->cfg->ccsc][layer]; -+ if (layer < mixer->cfg->vi_num) { -+ base = ccsc_base[mixer->cfg->ccsc][layer]; - -- sun8i_csc_setup(mixer->engine.regs, base, -- fmt_type, encoding, range); -+ sun8i_csc_setup(mixer->engine.regs, base, -+ fmt_type, encoding, range); -+ } - } -diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c -index b90e5edef4e88..aa987bca1dbb9 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c -+++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c -@@ -20,6 +20,7 @@ - #include - #include - -+#include "sun8i_csc.h" - #include "sun8i_mixer.h" - #include "sun8i_ui_layer.h" - #include "sun8i_ui_scaler.h" -@@ -135,6 +136,11 @@ static int sun8i_ui_layer_update_formats(struct sun8i_mixer *mixer, int channel, - SUN8I_MIXER_CHAN_UI_LAYER_ATTR(ch_base, overlay), - SUN8I_MIXER_CHAN_UI_LAYER_ATTR_FBFMT_MASK, val); - -+ /* Note: encoding and range arguments are ignored for RGB */ -+ sun8i_csc_set_ccsc(mixer, channel, FORMAT_TYPE_RGB, -+ DRM_COLOR_YCBCR_BT601, -+ DRM_COLOR_YCBCR_FULL_RANGE); -+ - return 0; - } - --- -2.46.1 - -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH v5 4/26] drm: sun4i: de2: Initialize layer fields earlier -From: Jernej Skrabec -Date: Sun, 29 Sep 2024 22:04:36 +1300 -Message-Id: <20240929091107.838023-5-ryan@testtoast.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -drm_universal_plane_init() can already call some callbacks, like -format_mod_supported, during initialization. Because of that, fields -should be initialized beforehand. - -Signed-off-by: Jernej Skrabec -Co-developed-by: Ryan Walklin -Signed-off-by: Ryan Walklin -Reviewed-by: Chen-Yu Tsai ---- - drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 9 +++++---- - drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 9 +++++---- - 2 files changed, 10 insertions(+), 8 deletions(-) - -diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c -index aa987bca1dbb9..cb9b694fef101 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c -+++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c -@@ -295,6 +295,11 @@ struct sun8i_layer *sun8i_ui_layer_init_one(struct drm_device *drm, - if (!layer) - return ERR_PTR(-ENOMEM); - -+ layer->mixer = mixer; -+ layer->type = SUN8I_LAYER_TYPE_UI; -+ layer->channel = channel; -+ layer->overlay = 0; -+ - if (index == 0) - type = DRM_PLANE_TYPE_PRIMARY; - -@@ -325,10 +330,6 @@ struct sun8i_layer *sun8i_ui_layer_init_one(struct drm_device *drm, - } - - drm_plane_helper_add(&layer->plane, &sun8i_ui_layer_helper_funcs); -- layer->mixer = mixer; -- layer->type = SUN8I_LAYER_TYPE_UI; -- layer->channel = channel; -- layer->overlay = 0; - - return layer; - } -diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c -index f3a5329351caa..3c657b069d1f4 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c -+++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c -@@ -478,6 +478,11 @@ struct sun8i_layer *sun8i_vi_layer_init_one(struct drm_device *drm, - if (!layer) - return ERR_PTR(-ENOMEM); - -+ layer->mixer = mixer; -+ layer->type = SUN8I_LAYER_TYPE_VI; -+ layer->channel = index; -+ layer->overlay = 0; -+ - if (mixer->cfg->is_de3) { - formats = sun8i_vi_layer_de3_formats; - format_count = ARRAY_SIZE(sun8i_vi_layer_de3_formats); -@@ -536,10 +541,6 @@ struct sun8i_layer *sun8i_vi_layer_init_one(struct drm_device *drm, - } - - drm_plane_helper_add(&layer->plane, &sun8i_vi_layer_helper_funcs); -- layer->mixer = mixer; -- layer->type = SUN8I_LAYER_TYPE_VI; -- layer->channel = index; -- layer->overlay = 0; - - return layer; - } --- -2.46.1 - -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH v5 5/26] drm: sun4i: de3: Add YUV formatter module -From: Jernej Skrabec -Date: Sun, 29 Sep 2024 22:04:37 +1300 -Message-Id: <20240929091107.838023-6-ryan@testtoast.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -The display engine formatter (FMT) module is present in the DE3 engine -and provides YUV444 to YUV422/YUV420 conversion, format re-mapping and -color depth conversion. - -Add support for this module. - -Signed-off-by: Jernej Skrabec -Signed-off-by: Ryan Walklin -Reviewed-by: Chen-Yu Tsai -Acked-by: Conor Dooley -Reviewed-by: Andre Przywara ---- - drivers/gpu/drm/sun4i/Makefile | 3 +- - drivers/gpu/drm/sun4i/sun50i_fmt.c | 82 ++++++++++++++++++++++++++++++ - drivers/gpu/drm/sun4i/sun50i_fmt.h | 32 ++++++++++++ - 3 files changed, 116 insertions(+), 1 deletion(-) - create mode 100644 drivers/gpu/drm/sun4i/sun50i_fmt.c - create mode 100644 drivers/gpu/drm/sun4i/sun50i_fmt.h - -diff --git a/drivers/gpu/drm/sun4i/Makefile b/drivers/gpu/drm/sun4i/Makefile -index bad7497a0d11e..3f516329f51ee 100644 ---- a/drivers/gpu/drm/sun4i/Makefile -+++ b/drivers/gpu/drm/sun4i/Makefile -@@ -16,7 +16,8 @@ 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 -+ sun8i_vi_scaler.o sun8i_csc.o \ -+ sun50i_fmt.o - - sun4i-tcon-y += sun4i_crtc.o - sun4i-tcon-y += sun4i_tcon_dclk.o -diff --git a/drivers/gpu/drm/sun4i/sun50i_fmt.c b/drivers/gpu/drm/sun4i/sun50i_fmt.c -new file mode 100644 -index 0000000000000..050a8716ae862 ---- /dev/null -+++ b/drivers/gpu/drm/sun4i/sun50i_fmt.c -@@ -0,0 +1,82 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+/* -+ * Copyright (C) Jernej Skrabec -+ */ -+ -+#include -+ -+#include "sun50i_fmt.h" -+ -+static bool sun50i_fmt_is_10bit(u32 format) -+{ -+ switch (format) { -+ case MEDIA_BUS_FMT_RGB101010_1X30: -+ case MEDIA_BUS_FMT_YUV10_1X30: -+ case MEDIA_BUS_FMT_UYYVYY10_0_5X30: -+ case MEDIA_BUS_FMT_UYVY10_1X20: -+ return true; -+ default: -+ return false; -+ } -+} -+ -+static u32 sun50i_fmt_get_colorspace(u32 format) -+{ -+ switch (format) { -+ case MEDIA_BUS_FMT_UYYVYY8_0_5X24: -+ case MEDIA_BUS_FMT_UYYVYY10_0_5X30: -+ return SUN50I_FMT_CS_YUV420; -+ case MEDIA_BUS_FMT_UYVY8_1X16: -+ case MEDIA_BUS_FMT_UYVY10_1X20: -+ return SUN50I_FMT_CS_YUV422; -+ default: -+ return SUN50I_FMT_CS_YUV444RGB; -+ } -+} -+ -+static void sun50i_fmt_de3_limits(u32 *limits, u32 colorspace, bool bit10) -+{ -+ if (colorspace != SUN50I_FMT_CS_YUV444RGB) { -+ limits[0] = SUN50I_FMT_LIMIT(64, 940); -+ limits[1] = SUN50I_FMT_LIMIT(64, 960); -+ limits[2] = SUN50I_FMT_LIMIT(64, 960); -+ } else if (bit10) { -+ limits[0] = SUN50I_FMT_LIMIT(0, 1023); -+ limits[1] = SUN50I_FMT_LIMIT(0, 1023); -+ limits[2] = SUN50I_FMT_LIMIT(0, 1023); -+ } else { -+ limits[0] = SUN50I_FMT_LIMIT(0, 1021); -+ limits[1] = SUN50I_FMT_LIMIT(0, 1021); -+ limits[2] = SUN50I_FMT_LIMIT(0, 1021); -+ } -+} -+ -+void sun50i_fmt_setup(struct sun8i_mixer *mixer, u16 width, -+ u16 height, u32 format) -+{ -+ u32 colorspace, limit[3], base; -+ struct regmap *regs; -+ bool bit10; -+ -+ colorspace = sun50i_fmt_get_colorspace(format); -+ bit10 = sun50i_fmt_is_10bit(format); -+ base = SUN50I_FMT_DE3; -+ regs = sun8i_blender_regmap(mixer); -+ -+ sun50i_fmt_de3_limits(limit, colorspace, bit10); -+ -+ regmap_write(regs, SUN50I_FMT_CTRL(base), 0); -+ -+ regmap_write(regs, SUN50I_FMT_SIZE(base), -+ SUN8I_MIXER_SIZE(width, height)); -+ regmap_write(regs, SUN50I_FMT_SWAP(base), 0); -+ regmap_write(regs, SUN50I_FMT_DEPTH(base), bit10); -+ regmap_write(regs, SUN50I_FMT_FORMAT(base), colorspace); -+ regmap_write(regs, SUN50I_FMT_COEF(base), 0); -+ -+ regmap_write(regs, SUN50I_FMT_LMT_Y(base), limit[0]); -+ regmap_write(regs, SUN50I_FMT_LMT_C0(base), limit[1]); -+ regmap_write(regs, SUN50I_FMT_LMT_C1(base), limit[2]); -+ -+ regmap_write(regs, SUN50I_FMT_CTRL(base), 1); -+} -diff --git a/drivers/gpu/drm/sun4i/sun50i_fmt.h b/drivers/gpu/drm/sun4i/sun50i_fmt.h -new file mode 100644 -index 0000000000000..4127f7206aade ---- /dev/null -+++ b/drivers/gpu/drm/sun4i/sun50i_fmt.h -@@ -0,0 +1,32 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+/* -+ * Copyright (C) Jernej Skrabec -+ */ -+ -+#ifndef _SUN50I_FMT_H_ -+#define _SUN50I_FMT_H_ -+ -+#include "sun8i_mixer.h" -+ -+#define SUN50I_FMT_DE3 0xa8000 -+ -+#define SUN50I_FMT_CTRL(base) ((base) + 0x00) -+#define SUN50I_FMT_SIZE(base) ((base) + 0x04) -+#define SUN50I_FMT_SWAP(base) ((base) + 0x08) -+#define SUN50I_FMT_DEPTH(base) ((base) + 0x0c) -+#define SUN50I_FMT_FORMAT(base) ((base) + 0x10) -+#define SUN50I_FMT_COEF(base) ((base) + 0x14) -+#define SUN50I_FMT_LMT_Y(base) ((base) + 0x20) -+#define SUN50I_FMT_LMT_C0(base) ((base) + 0x24) -+#define SUN50I_FMT_LMT_C1(base) ((base) + 0x28) -+ -+#define SUN50I_FMT_LIMIT(low, high) (((high) << 16) | (low)) -+ -+#define SUN50I_FMT_CS_YUV444RGB 0 -+#define SUN50I_FMT_CS_YUV422 1 -+#define SUN50I_FMT_CS_YUV420 2 -+ -+void sun50i_fmt_setup(struct sun8i_mixer *mixer, u16 width, -+ u16 height, u32 format); -+ -+#endif --- -2.46.1 - -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH v5 6/26] drm: sun4i: de3: add format enumeration function - to engine -From: Jernej Skrabec -Date: Sun, 29 Sep 2024 22:04:38 +1300 -Message-Id: <20240929091107.838023-7-ryan@testtoast.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -The DE3 display engine supports YUV formats in addition to RGB. - -Add an optional format enumeration function to the engine. - -Signed-off-by: Jernej Skrabec -Signed-off-by: Ryan Walklin -Reviewed-by: Chen-Yu Tsai -Acked-by: Conor Dooley -Reviewed-by: Andre Przywara ---- - drivers/gpu/drm/sun4i/sunxi_engine.h | 29 ++++++++++++++++++++++++++++ - 1 file changed, 29 insertions(+) - -diff --git a/drivers/gpu/drm/sun4i/sunxi_engine.h b/drivers/gpu/drm/sun4i/sunxi_engine.h -index ec0c4932f15cf..c48cbc1aceb80 100644 ---- a/drivers/gpu/drm/sun4i/sunxi_engine.h -+++ b/drivers/gpu/drm/sun4i/sunxi_engine.h -@@ -123,6 +123,17 @@ struct sunxi_engine_ops { - */ - void (*mode_set)(struct sunxi_engine *engine, - const struct drm_display_mode *mode); -+ -+ /** -+ * @get_supported_fmts -+ * -+ * This callback is used to enumerate all supported output -+ * formats by the engine. They are used for bridge format -+ * negotiation. -+ * -+ * This function is optional. -+ */ -+ u32 *(*get_supported_fmts)(struct sunxi_engine *engine, u32 *num); - }; - - /** -@@ -215,4 +226,22 @@ sunxi_engine_mode_set(struct sunxi_engine *engine, - if (engine->ops && engine->ops->mode_set) - engine->ops->mode_set(engine, mode); - } -+ -+/** -+ * sunxi_engine_get_supported_formats - Provide array of supported formats -+ * @engine: pointer to the engine -+ * @num: pointer to variable, which will hold number of formats -+ * -+ * This list can be used for format negotiation by bridge. -+ */ -+static inline u32 * -+sunxi_engine_get_supported_formats(struct sunxi_engine *engine, u32 *num) -+{ -+ if (engine->ops && engine->ops->get_supported_fmts) -+ return engine->ops->get_supported_fmts(engine, num); -+ -+ *num = 0; -+ -+ return NULL; -+} - #endif /* _SUNXI_ENGINE_H_ */ --- -2.46.1 - -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH v5 7/26] drm: sun4i: de3: add formatter flag to mixer - config -From: Jernej Skrabec -Date: Sun, 29 Sep 2024 22:04:39 +1300 -Message-Id: <20240929091107.838023-8-ryan@testtoast.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -Only the DE3 (and newer) display engines have a formatter module. This -could be inferred from the is_de3 flag alone, however this will not -scale with addition of future DE versions in subsequent patches. - -Add a separate flag to signal this in the mixer configuration. - -Signed-off-by: Jernej Skrabec -Signed-off-by: Ryan Walklin -Reviewed-by: Chen-Yu Tsai -Acked-by: Conor Dooley -Reviewed-by: Andre Przywara ---- - drivers/gpu/drm/sun4i/sun8i_mixer.c | 1 + - drivers/gpu/drm/sun4i/sun8i_mixer.h | 2 ++ - 2 files changed, 3 insertions(+) - -diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c -index bd0fe2c6624e6..252827715de1d 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_mixer.c -+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c -@@ -717,6 +717,7 @@ static const struct sun8i_mixer_cfg sun50i_a64_mixer1_cfg = { - static const struct sun8i_mixer_cfg sun50i_h6_mixer0_cfg = { - .ccsc = CCSC_MIXER0_LAYOUT, - .is_de3 = true, -+ .has_formatter = 1, - .mod_rate = 600000000, - .scaler_mask = 0xf, - .scanline_yuv = 4096, -diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h -index d7898c9c9cc0c..8417b8fef2e1f 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_mixer.h -+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h -@@ -163,6 +163,7 @@ enum { - * @mod_rate: module clock rate that needs to be set in order to have - * a functional block. - * @is_de3: true, if this is next gen display engine 3.0, false otherwise. -+ * @has_formatter: true, if mixer has formatter core, for 10-bit and YUV handling - * @scaline_yuv: size of a scanline for VI scaler for YUV formats. - */ - struct sun8i_mixer_cfg { -@@ -172,6 +173,7 @@ struct sun8i_mixer_cfg { - int ccsc; - unsigned long mod_rate; - unsigned int is_de3 : 1; -+ unsigned int has_formatter : 1; - unsigned int scanline_yuv; - }; - --- -2.46.1 - -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH v5 8/26] drm: sun4i: de3: add YUV support to the DE3 mixer -From: Jernej Skrabec -Date: Sun, 29 Sep 2024 22:04:40 +1300 -Message-Id: <20240929091107.838023-9-ryan@testtoast.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -The mixer in the DE3 display engine supports YUV 8 and 10 bit -formats in addition to 8-bit RGB. Add the required register -configuration and format enumeration callback functions to the mixer, -and store the in-use output format (defaulting to RGB) and color -encoding in engine variables. - -Signed-off-by: Jernej Skrabec -Signed-off-by: Ryan Walklin ---- -Changelog v4..v5: -- Remove trailing whitespace ---- - drivers/gpu/drm/sun4i/sun8i_mixer.c | 53 ++++++++++++++++++++++++++-- - drivers/gpu/drm/sun4i/sunxi_engine.h | 5 +++ - 2 files changed, 55 insertions(+), 3 deletions(-) - -diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c -index 252827715de1d..a50c583852edf 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_mixer.c -+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c -@@ -23,7 +23,10 @@ - #include - #include - -+#include -+ - #include "sun4i_drv.h" -+#include "sun50i_fmt.h" - #include "sun8i_mixer.h" - #include "sun8i_ui_layer.h" - #include "sun8i_vi_layer.h" -@@ -390,12 +393,52 @@ static void sun8i_mixer_mode_set(struct sunxi_engine *engine, - - DRM_DEBUG_DRIVER("Switching display mixer interlaced mode %s\n", - interlaced ? "on" : "off"); -+ -+ if (engine->format == MEDIA_BUS_FMT_RGB888_1X24) -+ val = SUN8I_MIXER_BLEND_COLOR_BLACK; -+ else -+ val = 0xff108080; -+ -+ regmap_write(mixer->engine.regs, -+ SUN8I_MIXER_BLEND_BKCOLOR(bld_base), val); -+ regmap_write(mixer->engine.regs, -+ SUN8I_MIXER_BLEND_ATTR_FCOLOR(bld_base, 0), val); -+ -+ if (mixer->cfg->has_formatter) -+ sun50i_fmt_setup(mixer, mode->hdisplay, -+ mode->vdisplay, mixer->engine.format); -+} -+ -+static u32 *sun8i_mixer_get_supported_fmts(struct sunxi_engine *engine, u32 *num) -+{ -+ struct sun8i_mixer *mixer = engine_to_sun8i_mixer(engine); -+ u32 *formats, count; -+ -+ count = 0; -+ -+ formats = kcalloc(5, sizeof(*formats), GFP_KERNEL); -+ if (!formats) -+ return NULL; -+ -+ if (mixer->cfg->has_formatter) { -+ formats[count++] = MEDIA_BUS_FMT_UYYVYY10_0_5X30; -+ formats[count++] = MEDIA_BUS_FMT_YUV8_1X24; -+ formats[count++] = MEDIA_BUS_FMT_UYVY8_1X16; -+ formats[count++] = MEDIA_BUS_FMT_UYYVYY8_0_5X24; -+ } -+ -+ formats[count++] = MEDIA_BUS_FMT_RGB888_1X24; -+ -+ *num = count; -+ -+ return formats; - } - - static const struct sunxi_engine_ops sun8i_engine_ops = { -- .commit = sun8i_mixer_commit, -- .layers_init = sun8i_layers_init, -- .mode_set = sun8i_mixer_mode_set, -+ .commit = sun8i_mixer_commit, -+ .layers_init = sun8i_layers_init, -+ .mode_set = sun8i_mixer_mode_set, -+ .get_supported_fmts = sun8i_mixer_get_supported_fmts, - }; - - static const struct regmap_config sun8i_mixer_regmap_config = { -@@ -456,6 +499,10 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master, - dev_set_drvdata(dev, mixer); - mixer->engine.ops = &sun8i_engine_ops; - mixer->engine.node = dev->of_node; -+ /* default output format, supported by all mixers */ -+ mixer->engine.format = MEDIA_BUS_FMT_RGB888_1X24; -+ /* default color encoding, ignored with RGB I/O */ -+ mixer->engine.encoding = DRM_COLOR_YCBCR_BT601; - - if (of_property_present(dev->of_node, "iommus")) { - /* -diff --git a/drivers/gpu/drm/sun4i/sunxi_engine.h b/drivers/gpu/drm/sun4i/sunxi_engine.h -index c48cbc1aceb80..ffafc29b3a0c3 100644 ---- a/drivers/gpu/drm/sun4i/sunxi_engine.h -+++ b/drivers/gpu/drm/sun4i/sunxi_engine.h -@@ -6,6 +6,8 @@ - #ifndef _SUNXI_ENGINE_H_ - #define _SUNXI_ENGINE_H_ - -+#include -+ - struct drm_plane; - struct drm_crtc; - struct drm_device; -@@ -151,6 +153,9 @@ struct sunxi_engine { - - int id; - -+ u32 format; -+ enum drm_color_encoding encoding; -+ - /* Engine list management */ - struct list_head list; - }; --- -2.46.1 - -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH v5 9/26] drm: sun4i: de3: pass engine reference to ccsc - setup function -From: Jernej Skrabec -Date: Sun, 29 Sep 2024 22:04:41 +1300 -Message-Id: <20240929091107.838023-10-ryan@testtoast.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -Configuration of the DE3 colorspace and dynamic range correction module -requires knowledge of the current video format and encoding. - -Pass the display engine by reference to the csc setup function, rather -than the register map alone, to allow access to this information. - -Signed-off-by: Jernej Skrabec -Signed-off-by: Ryan Walklin -Reviewed-by: Chen-Yu Tsai -Acked-by: Conor Dooley -Reviewed-by: Andre Przywara ---- - drivers/gpu/drm/sun4i/sun8i_csc.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c b/drivers/gpu/drm/sun4i/sun8i_csc.c -index 68d955c63b05b..8a336ccb27d33 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_csc.c -+++ b/drivers/gpu/drm/sun4i/sun8i_csc.c -@@ -148,17 +148,19 @@ static void sun8i_csc_setup(struct regmap *map, u32 base, - regmap_write(map, SUN8I_CSC_CTRL(base), val); - } - --static void sun8i_de3_ccsc_setup(struct regmap *map, int layer, -+static void sun8i_de3_ccsc_setup(struct sunxi_engine *engine, int layer, - enum format_type fmt_type, - enum drm_color_encoding encoding, - enum drm_color_range range) - { - u32 addr, val, mask; -+ struct regmap *map; - const u32 *table; - int i; - - mask = SUN50I_MIXER_BLEND_CSC_CTL_EN(layer); - table = yuv2rgb_de3[range][encoding]; -+ map = engine->regs; - - switch (fmt_type) { - case FORMAT_TYPE_RGB: -@@ -204,7 +206,7 @@ void sun8i_csc_set_ccsc(struct sun8i_mixer *mixer, int layer, - u32 base; - - if (mixer->cfg->is_de3) { -- sun8i_de3_ccsc_setup(mixer->engine.regs, layer, -+ sun8i_de3_ccsc_setup(&mixer->engine, layer, - fmt_type, encoding, range); - return; - } --- -2.46.1 - -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH v5 10/26] drm: sun4i: de3: add YUV support to the color - space correction module -From: Jernej Skrabec -Date: Sun, 29 Sep 2024 22:04:42 +1300 -Message-Id: <20240929091107.838023-11-ryan@testtoast.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -Add coefficients and support for YUV formats to the display engine -colorspace and dynamic range correction submodule. - -Signed-off-by: Jernej Skrabec -Signed-off-by: Ryan Walklin -Reviewed-by: Chen-Yu Tsai -Acked-by: Conor Dooley -Reviewed-by: Andre Przywara ---- - drivers/gpu/drm/sun4i/sun8i_csc.c | 164 +++++++++++++++++++++++++++++- - 1 file changed, 162 insertions(+), 2 deletions(-) - -diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c b/drivers/gpu/drm/sun4i/sun8i_csc.c -index 8a336ccb27d33..e12a81fa91083 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_csc.c -+++ b/drivers/gpu/drm/sun4i/sun8i_csc.c -@@ -5,6 +5,8 @@ - - #include - -+#include -+ - #include "sun8i_csc.h" - #include "sun8i_mixer.h" - -@@ -107,6 +109,135 @@ static const u32 yuv2rgb_de3[2][3][12] = { - }, - }; - -+/* always convert to limited mode */ -+static const u32 rgb2yuv_de3[3][12] = { -+ [DRM_COLOR_YCBCR_BT601] = { -+ 0x0000837A, 0x0001021D, 0x00003221, 0x00000040, -+ 0xFFFFB41C, 0xFFFF6B03, 0x0000E0E1, 0x00000200, -+ 0x0000E0E1, 0xFFFF43B1, 0xFFFFDB6E, 0x00000200, -+ }, -+ [DRM_COLOR_YCBCR_BT709] = { -+ 0x00005D7C, 0x00013A7C, 0x00001FBF, 0x00000040, -+ 0xFFFFCC78, 0xFFFF52A7, 0x0000E0E1, 0x00000200, -+ 0x0000E0E1, 0xFFFF33BE, 0xFFFFEB61, 0x00000200, -+ }, -+ [DRM_COLOR_YCBCR_BT2020] = { -+ 0x00007384, 0x00012A21, 0x00001A13, 0x00000040, -+ 0xFFFFC133, 0xFFFF5DEC, 0x0000E0E1, 0x00000200, -+ 0x0000E0E1, 0xFFFF3135, 0xFFFFEDEA, 0x00000200, -+ }, -+}; -+ -+/* always convert to limited mode */ -+static const u32 yuv2yuv_de3[2][3][3][12] = { -+ [DRM_COLOR_YCBCR_LIMITED_RANGE] = { -+ [DRM_COLOR_YCBCR_BT601] = { -+ [DRM_COLOR_YCBCR_BT601] = { -+ 0x00020000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00020000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00020000, 0x00000000, -+ }, -+ [DRM_COLOR_YCBCR_BT709] = { -+ 0x00020000, 0xFFFFC4D7, 0xFFFF9589, 0xFFC00040, -+ 0x00000000, 0x0002098B, 0x00003AAF, 0xFE000200, -+ 0x00000000, 0x0000266D, 0x00020CF8, 0xFE000200, -+ }, -+ [DRM_COLOR_YCBCR_BT2020] = { -+ 0x00020000, 0xFFFFBFCE, 0xFFFFC5FF, 0xFFC00040, -+ 0x00000000, 0x00020521, 0x00001F89, 0xFE000200, -+ 0x00000000, 0x00002C87, 0x00020F07, 0xFE000200, -+ }, -+ }, -+ [DRM_COLOR_YCBCR_BT709] = { -+ [DRM_COLOR_YCBCR_BT601] = { -+ 0x00020000, 0x000032D9, 0x00006226, 0xFFC00040, -+ 0x00000000, 0x0001FACE, 0xFFFFC759, 0xFE000200, -+ 0x00000000, 0xFFFFDAE7, 0x0001F780, 0xFE000200, -+ }, -+ [DRM_COLOR_YCBCR_BT709] = { -+ 0x00020000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00020000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00020000, 0x00000000, -+ }, -+ [DRM_COLOR_YCBCR_BT2020] = { -+ 0x00020000, 0xFFFFF782, 0x00003036, 0xFFC00040, -+ 0x00000000, 0x0001FD99, 0xFFFFE5CA, 0xFE000200, -+ 0x00000000, 0x000005E4, 0x0002015A, 0xFE000200, -+ }, -+ }, -+ [DRM_COLOR_YCBCR_BT2020] = { -+ [DRM_COLOR_YCBCR_BT601] = { -+ 0x00020000, 0x00003B03, 0x000034D2, 0xFFC00040, -+ 0x00000000, 0x0001FD8C, 0xFFFFE183, 0xFE000200, -+ 0x00000000, 0xFFFFD4F3, 0x0001F3FA, 0xFE000200, -+ }, -+ [DRM_COLOR_YCBCR_BT709] = { -+ 0x00020000, 0x00000916, 0xFFFFD061, 0xFFC00040, -+ 0x00000000, 0x0002021C, 0x00001A40, 0xFE000200, -+ 0x00000000, 0xFFFFFA19, 0x0001FE5A, 0xFE000200, -+ }, -+ [DRM_COLOR_YCBCR_BT2020] = { -+ 0x00020000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00020000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00020000, 0x00000000, -+ }, -+ }, -+ }, -+ [DRM_COLOR_YCBCR_FULL_RANGE] = { -+ [DRM_COLOR_YCBCR_BT601] = { -+ [DRM_COLOR_YCBCR_BT601] = { -+ 0x0001B7B8, 0x00000000, 0x00000000, 0x00000040, -+ 0x00000000, 0x0001C1C2, 0x00000000, 0xFE000200, -+ 0x00000000, 0x00000000, 0x0001C1C2, 0xFE000200, -+ }, -+ [DRM_COLOR_YCBCR_BT709] = { -+ 0x0001B7B8, 0xFFFFCC08, 0xFFFFA27B, 0x00000040, -+ 0x00000000, 0x0001CA24, 0x0000338D, 0xFE000200, -+ 0x00000000, 0x000021C1, 0x0001CD26, 0xFE000200, -+ }, -+ [DRM_COLOR_YCBCR_BT2020] = { -+ 0x0001B7B8, 0xFFFFC79C, 0xFFFFCD0C, 0x00000040, -+ 0x00000000, 0x0001C643, 0x00001BB4, 0xFE000200, -+ 0x00000000, 0x0000271D, 0x0001CEF5, 0xFE000200, -+ }, -+ }, -+ [DRM_COLOR_YCBCR_BT709] = { -+ [DRM_COLOR_YCBCR_BT601] = { -+ 0x0001B7B8, 0x00002CAB, 0x00005638, 0x00000040, -+ 0x00000000, 0x0001BD32, 0xFFFFCE3C, 0xFE000200, -+ 0x00000000, 0xFFFFDF6A, 0x0001BA4A, 0xFE000200, -+ }, -+ [DRM_COLOR_YCBCR_BT709] = { -+ 0x0001B7B8, 0x00000000, 0x00000000, 0x00000040, -+ 0x00000000, 0x0001C1C2, 0x00000000, 0xFE000200, -+ 0x00000000, 0x00000000, 0x0001C1C2, 0xFE000200, -+ }, -+ [DRM_COLOR_YCBCR_BT2020] = { -+ 0x0001B7B8, 0xFFFFF88A, 0x00002A5A, 0x00000040, -+ 0x00000000, 0x0001BFA5, 0xFFFFE8FA, 0xFE000200, -+ 0x00000000, 0x0000052D, 0x0001C2F1, 0xFE000200, -+ }, -+ }, -+ [DRM_COLOR_YCBCR_BT2020] = { -+ [DRM_COLOR_YCBCR_BT601] = { -+ 0x0001B7B8, 0x000033D6, 0x00002E66, 0x00000040, -+ 0x00000000, 0x0001BF9A, 0xFFFFE538, 0xFE000200, -+ 0x00000000, 0xFFFFDA2F, 0x0001B732, 0xFE000200, -+ }, -+ [DRM_COLOR_YCBCR_BT709] = { -+ 0x0001B7B8, 0x000007FB, 0xFFFFD62B, 0x00000040, -+ 0x00000000, 0x0001C39D, 0x0000170F, 0xFE000200, -+ 0x00000000, 0xFFFFFAD1, 0x0001C04F, 0xFE000200, -+ }, -+ [DRM_COLOR_YCBCR_BT2020] = { -+ 0x0001B7B8, 0x00000000, 0x00000000, 0x00000040, -+ 0x00000000, 0x0001C1C2, 0x00000000, 0xFE000200, -+ 0x00000000, 0x00000000, 0x0001C1C2, 0xFE000200, -+ }, -+ }, -+ }, -+}; -+ - static void sun8i_csc_setup(struct regmap *map, u32 base, - enum format_type fmt_type, - enum drm_color_encoding encoding, -@@ -148,12 +279,27 @@ static void sun8i_csc_setup(struct regmap *map, u32 base, - regmap_write(map, SUN8I_CSC_CTRL(base), val); - } - -+static const u32 *sun8i_csc_get_de3_yuv_table(enum drm_color_encoding in_enc, -+ enum drm_color_range in_range, -+ u32 out_format, -+ enum drm_color_encoding out_enc) -+{ -+ if (out_format == MEDIA_BUS_FMT_RGB888_1X24) -+ return yuv2rgb_de3[in_range][in_enc]; -+ -+ /* check for identity transformation */ -+ if (in_range == DRM_COLOR_YCBCR_LIMITED_RANGE && out_enc == in_enc) -+ return NULL; -+ -+ return yuv2yuv_de3[in_range][in_enc][out_enc]; -+} -+ - static void sun8i_de3_ccsc_setup(struct sunxi_engine *engine, int layer, - enum format_type fmt_type, - enum drm_color_encoding encoding, - enum drm_color_range range) - { -- u32 addr, val, mask; -+ u32 addr, val = 0, mask; - struct regmap *map; - const u32 *table; - int i; -@@ -164,14 +310,28 @@ static void sun8i_de3_ccsc_setup(struct sunxi_engine *engine, int layer, - - switch (fmt_type) { - case FORMAT_TYPE_RGB: -- val = 0; -+ if (engine->format == MEDIA_BUS_FMT_RGB888_1X24) -+ break; -+ val = mask; -+ addr = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE, layer, 0); -+ regmap_bulk_write(map, addr, rgb2yuv_de3[engine->encoding], 12); - break; - case FORMAT_TYPE_YUV: -+ table = sun8i_csc_get_de3_yuv_table(encoding, range, -+ engine->format, -+ engine->encoding); -+ if (!table) -+ break; - val = mask; - addr = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE, layer, 0); - regmap_bulk_write(map, addr, table, 12); - break; - case FORMAT_TYPE_YVU: -+ table = sun8i_csc_get_de3_yuv_table(encoding, range, -+ engine->format, -+ engine->encoding); -+ if (!table) -+ table = yuv2yuv_de3[range][encoding][encoding]; - val = mask; - for (i = 0; i < 12; i++) { - if ((i & 3) == 1) --- -2.46.1 - -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH v5 11/26] drm: sun4i: de3: add YUV support to the TCON -From: Jernej Skrabec -Date: Sun, 29 Sep 2024 22:04:43 +1300 -Message-Id: <20240929091107.838023-12-ryan@testtoast.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -Account for U/V channel subsampling by reducing the dot clock and -resolution with a divider in the DE3 timing controller if a YUV format -is selected. - -Signed-off-by: Jernej Skrabec -Signed-off-by: Ryan Walklin -Reviewed-by: Chen-Yu Tsai -Acked-by: Conor Dooley -Reviewed-by: Andre Przywara ---- - drivers/gpu/drm/sun4i/sun4i_tcon.c | 26 +++++++++++++++++++------- - 1 file changed, 19 insertions(+), 7 deletions(-) - -diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c -index a1a2c845ade0c..e39926e9f0b5d 100644 ---- a/drivers/gpu/drm/sun4i/sun4i_tcon.c -+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c -@@ -598,14 +598,26 @@ static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon *tcon, - static void sun4i_tcon1_mode_set(struct sun4i_tcon *tcon, - const struct drm_display_mode *mode) - { -- unsigned int bp, hsync, vsync, vtotal; -+ unsigned int bp, hsync, vsync, vtotal, div; -+ struct sun4i_crtc *scrtc = tcon->crtc; -+ struct sunxi_engine *engine = scrtc->engine; - u8 clk_delay; - u32 val; - - WARN_ON(!tcon->quirks->has_channel_1); - -+ switch (engine->format) { -+ case MEDIA_BUS_FMT_UYYVYY8_0_5X24: -+ case MEDIA_BUS_FMT_UYYVYY10_0_5X30: -+ div = 2; -+ break; -+ default: -+ div = 1; -+ break; -+ } -+ - /* Configure the dot clock */ -- clk_set_rate(tcon->sclk1, mode->crtc_clock * 1000); -+ clk_set_rate(tcon->sclk1, mode->crtc_clock * 1000 / div); - - /* Adjust clock delay */ - clk_delay = sun4i_tcon_get_clk_delay(mode, 1); -@@ -624,17 +636,17 @@ static void sun4i_tcon1_mode_set(struct sun4i_tcon *tcon, - - /* Set the input resolution */ - regmap_write(tcon->regs, SUN4I_TCON1_BASIC0_REG, -- SUN4I_TCON1_BASIC0_X(mode->crtc_hdisplay) | -+ SUN4I_TCON1_BASIC0_X(mode->crtc_hdisplay / div) | - SUN4I_TCON1_BASIC0_Y(mode->crtc_vdisplay)); - - /* Set the upscaling resolution */ - regmap_write(tcon->regs, SUN4I_TCON1_BASIC1_REG, -- SUN4I_TCON1_BASIC1_X(mode->crtc_hdisplay) | -+ SUN4I_TCON1_BASIC1_X(mode->crtc_hdisplay / div) | - SUN4I_TCON1_BASIC1_Y(mode->crtc_vdisplay)); - - /* Set the output resolution */ - regmap_write(tcon->regs, SUN4I_TCON1_BASIC2_REG, -- SUN4I_TCON1_BASIC2_X(mode->crtc_hdisplay) | -+ SUN4I_TCON1_BASIC2_X(mode->crtc_hdisplay / div) | - SUN4I_TCON1_BASIC2_Y(mode->crtc_vdisplay)); - - /* Set horizontal display timings */ -@@ -642,8 +654,8 @@ static void sun4i_tcon1_mode_set(struct sun4i_tcon *tcon, - DRM_DEBUG_DRIVER("Setting horizontal total %d, backporch %d\n", - mode->htotal, bp); - regmap_write(tcon->regs, SUN4I_TCON1_BASIC3_REG, -- SUN4I_TCON1_BASIC3_H_TOTAL(mode->crtc_htotal) | -- SUN4I_TCON1_BASIC3_H_BACKPORCH(bp)); -+ SUN4I_TCON1_BASIC3_H_TOTAL(mode->crtc_htotal / div) | -+ SUN4I_TCON1_BASIC3_H_BACKPORCH(bp / div)); - - bp = mode->crtc_vtotal - mode->crtc_vsync_start; - DRM_DEBUG_DRIVER("Setting vertical total %d, backporch %d\n", --- -2.46.1 - -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH v5 12/26] drm: sun4i: support YUV formats in VI scaler -From: Jernej Skrabec -Date: Sun, 29 Sep 2024 22:04:44 +1300 -Message-Id: <20240929091107.838023-13-ryan@testtoast.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -Now that YUV formats are available, enable support in the VI scaler. - -Signed-off-by: Jernej Skrabec -Signed-off-by: Ryan Walklin - -Changelog v4..v5: -- Add commit description - -Reviewed-by: Chen-Yu Tsai -Acked-by: Conor Dooley -Reviewed-by: Andre Przywara ---- - drivers/gpu/drm/sun4i/sun8i_vi_scaler.c | 85 +++++++++++++++++-------- - 1 file changed, 58 insertions(+), 27 deletions(-) - -diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c -index 7ba75011adf9f..2e49a6e5f1f1c 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c -+++ b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c -@@ -843,6 +843,11 @@ static u32 sun8i_vi_scaler_base(struct sun8i_mixer *mixer, int channel) - DE2_VI_SCALER_UNIT_SIZE * channel; - } - -+static bool sun8i_vi_scaler_is_vi_plane(struct sun8i_mixer *mixer, int channel) -+{ -+ return true; -+} -+ - static int sun8i_vi_scaler_coef_index(unsigned int step) - { - unsigned int scale, int_part, float_part; -@@ -867,44 +872,65 @@ static int sun8i_vi_scaler_coef_index(unsigned int step) - } - } - --static void sun8i_vi_scaler_set_coeff(struct regmap *map, u32 base, -- u32 hstep, u32 vstep, -- const struct drm_format_info *format) -+static void sun8i_vi_scaler_set_coeff_vi(struct regmap *map, u32 base, -+ u32 hstep, u32 vstep, -+ const struct drm_format_info *format) - { - const u32 *ch_left, *ch_right, *cy; -- int offset, i; -+ int offset; - -- if (format->hsub == 1 && format->vsub == 1) { -- ch_left = lan3coefftab32_left; -- ch_right = lan3coefftab32_right; -- cy = lan2coefftab32; -- } else { -+ if (format->is_yuv) { - ch_left = bicubic8coefftab32_left; - ch_right = bicubic8coefftab32_right; - cy = bicubic4coefftab32; -+ } else { -+ ch_left = lan3coefftab32_left; -+ ch_right = lan3coefftab32_right; -+ cy = lan2coefftab32; - } - - offset = sun8i_vi_scaler_coef_index(hstep) * - SUN8I_VI_SCALER_COEFF_COUNT; -- for (i = 0; i < SUN8I_VI_SCALER_COEFF_COUNT; i++) { -- regmap_write(map, SUN8I_SCALER_VSU_YHCOEFF0(base, i), -- lan3coefftab32_left[offset + i]); -- regmap_write(map, SUN8I_SCALER_VSU_YHCOEFF1(base, i), -- lan3coefftab32_right[offset + i]); -- regmap_write(map, SUN8I_SCALER_VSU_CHCOEFF0(base, i), -- ch_left[offset + i]); -- regmap_write(map, SUN8I_SCALER_VSU_CHCOEFF1(base, i), -- ch_right[offset + i]); -- } -+ regmap_bulk_write(map, SUN8I_SCALER_VSU_YHCOEFF0(base, 0), -+ &lan3coefftab32_left[offset], -+ SUN8I_VI_SCALER_COEFF_COUNT); -+ regmap_bulk_write(map, SUN8I_SCALER_VSU_YHCOEFF1(base, 0), -+ &lan3coefftab32_right[offset], -+ SUN8I_VI_SCALER_COEFF_COUNT); -+ regmap_bulk_write(map, SUN8I_SCALER_VSU_CHCOEFF0(base, 0), -+ &ch_left[offset], SUN8I_VI_SCALER_COEFF_COUNT); -+ regmap_bulk_write(map, SUN8I_SCALER_VSU_CHCOEFF1(base, 0), -+ &ch_right[offset], SUN8I_VI_SCALER_COEFF_COUNT); - - offset = sun8i_vi_scaler_coef_index(hstep) * - SUN8I_VI_SCALER_COEFF_COUNT; -- for (i = 0; i < SUN8I_VI_SCALER_COEFF_COUNT; i++) { -- regmap_write(map, SUN8I_SCALER_VSU_YVCOEFF(base, i), -- lan2coefftab32[offset + i]); -- regmap_write(map, SUN8I_SCALER_VSU_CVCOEFF(base, i), -- cy[offset + i]); -- } -+ regmap_bulk_write(map, SUN8I_SCALER_VSU_YVCOEFF(base, 0), -+ &lan2coefftab32[offset], SUN8I_VI_SCALER_COEFF_COUNT); -+ regmap_bulk_write(map, SUN8I_SCALER_VSU_CVCOEFF(base, 0), -+ &cy[offset], SUN8I_VI_SCALER_COEFF_COUNT); -+} -+ -+static void sun8i_vi_scaler_set_coeff_ui(struct regmap *map, u32 base, -+ u32 hstep, u32 vstep, -+ const struct drm_format_info *format) -+{ -+ const u32 *table; -+ int offset; -+ -+ offset = sun8i_vi_scaler_coef_index(hstep) * -+ SUN8I_VI_SCALER_COEFF_COUNT; -+ regmap_bulk_write(map, SUN8I_SCALER_VSU_YHCOEFF0(base, 0), -+ &lan2coefftab32[offset], SUN8I_VI_SCALER_COEFF_COUNT); -+ offset = sun8i_vi_scaler_coef_index(vstep) * -+ SUN8I_VI_SCALER_COEFF_COUNT; -+ regmap_bulk_write(map, SUN8I_SCALER_VSU_YVCOEFF(base, 0), -+ &lan2coefftab32[offset], SUN8I_VI_SCALER_COEFF_COUNT); -+ -+ table = format->is_yuv ? bicubic4coefftab32 : lan2coefftab32; -+ offset = sun8i_vi_scaler_coef_index(hstep) * -+ SUN8I_VI_SCALER_COEFF_COUNT; -+ regmap_bulk_write(map, SUN8I_SCALER_VSU_CHCOEFF0(base, 0), -+ &table[offset], SUN8I_VI_SCALER_COEFF_COUNT); - } - - void sun8i_vi_scaler_enable(struct sun8i_mixer *mixer, int layer, bool enable) -@@ -994,6 +1020,11 @@ void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer, int layer, - SUN8I_SCALER_VSU_CHPHASE(base), chphase); - regmap_write(mixer->engine.regs, - SUN8I_SCALER_VSU_CVPHASE(base), cvphase); -- sun8i_vi_scaler_set_coeff(mixer->engine.regs, base, -- hscale, vscale, format); -+ -+ if (sun8i_vi_scaler_is_vi_plane(mixer, layer)) -+ sun8i_vi_scaler_set_coeff_vi(mixer->engine.regs, base, -+ hscale, vscale, format); -+ else -+ sun8i_vi_scaler_set_coeff_ui(mixer->engine.regs, base, -+ hscale, vscale, format); - } --- -2.46.1 - -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH v5 13/26] drm: sun4i: de2/de3: add mixer version enum -From: Jernej Skrabec -Date: Sun, 29 Sep 2024 22:04:45 +1300 -Message-Id: <20240929091107.838023-14-ryan@testtoast.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -The Allwinner DE2 and DE3 display engine mixers are currently identified -by a simple boolean flag. This will not scale to support additional DE -variants. - -Convert the boolean flag to an enum. - -Signed-off-by: Jernej Skrabec -Signed-off-by: Ryan Walklin -Reviewed-by: Andre Przywara -Reviewed-by: Chen-Yu Tsai -Acked-by: Conor Dooley ---- - drivers/gpu/drm/sun4i/sun8i_csc.c | 2 +- - drivers/gpu/drm/sun4i/sun8i_mixer.c | 14 ++++++++++++-- - drivers/gpu/drm/sun4i/sun8i_mixer.h | 11 ++++++++--- - drivers/gpu/drm/sun4i/sun8i_ui_scaler.c | 2 +- - drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 8 ++++---- - drivers/gpu/drm/sun4i/sun8i_vi_scaler.c | 4 ++-- - 6 files changed, 28 insertions(+), 13 deletions(-) - -diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c b/drivers/gpu/drm/sun4i/sun8i_csc.c -index e12a81fa91083..2d5a2cf7cba24 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_csc.c -+++ b/drivers/gpu/drm/sun4i/sun8i_csc.c -@@ -365,7 +365,7 @@ void sun8i_csc_set_ccsc(struct sun8i_mixer *mixer, int layer, - { - u32 base; - -- if (mixer->cfg->is_de3) { -+ if (mixer->cfg->de_type == sun8i_mixer_de3) { - sun8i_de3_ccsc_setup(&mixer->engine, layer, - fmt_type, encoding, range); - return; -diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c -index a50c583852edf..16e018aa4aae9 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_mixer.c -+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c -@@ -584,7 +584,7 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master, - base = sun8i_blender_base(mixer); - - /* Reset registers and disable unused sub-engines */ -- if (mixer->cfg->is_de3) { -+ if (mixer->cfg->de_type == sun8i_mixer_de3) { - for (i = 0; i < DE3_MIXER_UNIT_SIZE; i += 4) - regmap_write(mixer->engine.regs, i, 0); - -@@ -675,6 +675,7 @@ static void sun8i_mixer_remove(struct platform_device *pdev) - - static const struct sun8i_mixer_cfg sun8i_a83t_mixer0_cfg = { - .ccsc = CCSC_MIXER0_LAYOUT, -+ .de_type = sun8i_mixer_de2, - .scaler_mask = 0xf, - .scanline_yuv = 2048, - .ui_num = 3, -@@ -683,6 +684,7 @@ static const struct sun8i_mixer_cfg sun8i_a83t_mixer0_cfg = { - - static const struct sun8i_mixer_cfg sun8i_a83t_mixer1_cfg = { - .ccsc = CCSC_MIXER1_LAYOUT, -+ .de_type = sun8i_mixer_de2, - .scaler_mask = 0x3, - .scanline_yuv = 2048, - .ui_num = 1, -@@ -691,6 +693,7 @@ static const struct sun8i_mixer_cfg sun8i_a83t_mixer1_cfg = { - - static const struct sun8i_mixer_cfg sun8i_h3_mixer0_cfg = { - .ccsc = CCSC_MIXER0_LAYOUT, -+ .de_type = sun8i_mixer_de2, - .mod_rate = 432000000, - .scaler_mask = 0xf, - .scanline_yuv = 2048, -@@ -700,6 +703,7 @@ static const struct sun8i_mixer_cfg sun8i_h3_mixer0_cfg = { - - static const struct sun8i_mixer_cfg sun8i_r40_mixer0_cfg = { - .ccsc = CCSC_MIXER0_LAYOUT, -+ .de_type = sun8i_mixer_de2, - .mod_rate = 297000000, - .scaler_mask = 0xf, - .scanline_yuv = 2048, -@@ -709,6 +713,7 @@ static const struct sun8i_mixer_cfg sun8i_r40_mixer0_cfg = { - - static const struct sun8i_mixer_cfg sun8i_r40_mixer1_cfg = { - .ccsc = CCSC_MIXER1_LAYOUT, -+ .de_type = sun8i_mixer_de2, - .mod_rate = 297000000, - .scaler_mask = 0x3, - .scanline_yuv = 2048, -@@ -717,6 +722,7 @@ static const struct sun8i_mixer_cfg sun8i_r40_mixer1_cfg = { - }; - - static const struct sun8i_mixer_cfg sun8i_v3s_mixer_cfg = { -+ .de_type = sun8i_mixer_de2, - .vi_num = 2, - .ui_num = 1, - .scaler_mask = 0x3, -@@ -727,6 +733,7 @@ static const struct sun8i_mixer_cfg sun8i_v3s_mixer_cfg = { - - static const struct sun8i_mixer_cfg sun20i_d1_mixer0_cfg = { - .ccsc = CCSC_D1_MIXER0_LAYOUT, -+ .de_type = sun8i_mixer_de2, - .mod_rate = 297000000, - .scaler_mask = 0x3, - .scanline_yuv = 2048, -@@ -736,6 +743,7 @@ static const struct sun8i_mixer_cfg sun20i_d1_mixer0_cfg = { - - static const struct sun8i_mixer_cfg sun20i_d1_mixer1_cfg = { - .ccsc = CCSC_MIXER1_LAYOUT, -+ .de_type = sun8i_mixer_de2, - .mod_rate = 297000000, - .scaler_mask = 0x1, - .scanline_yuv = 1024, -@@ -745,6 +753,7 @@ static const struct sun8i_mixer_cfg sun20i_d1_mixer1_cfg = { - - static const struct sun8i_mixer_cfg sun50i_a64_mixer0_cfg = { - .ccsc = CCSC_MIXER0_LAYOUT, -+ .de_type = sun8i_mixer_de2, - .mod_rate = 297000000, - .scaler_mask = 0xf, - .scanline_yuv = 4096, -@@ -754,6 +763,7 @@ static const struct sun8i_mixer_cfg sun50i_a64_mixer0_cfg = { - - static const struct sun8i_mixer_cfg sun50i_a64_mixer1_cfg = { - .ccsc = CCSC_MIXER1_LAYOUT, -+ .de_type = sun8i_mixer_de2, - .mod_rate = 297000000, - .scaler_mask = 0x3, - .scanline_yuv = 2048, -@@ -763,7 +773,7 @@ static const struct sun8i_mixer_cfg sun50i_a64_mixer1_cfg = { - - static const struct sun8i_mixer_cfg sun50i_h6_mixer0_cfg = { - .ccsc = CCSC_MIXER0_LAYOUT, -- .is_de3 = true, -+ .de_type = sun8i_mixer_de3, - .has_formatter = 1, - .mod_rate = 600000000, - .scaler_mask = 0xf, -diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h -index 8417b8fef2e1f..82956cb97cfd9 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_mixer.h -+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h -@@ -151,6 +151,11 @@ enum { - CCSC_D1_MIXER0_LAYOUT, - }; - -+enum sun8i_mixer_type { -+ sun8i_mixer_de2, -+ sun8i_mixer_de3, -+}; -+ - /** - * struct sun8i_mixer_cfg - mixer HW configuration - * @vi_num: number of VI channels -@@ -172,7 +177,7 @@ struct sun8i_mixer_cfg { - int scaler_mask; - int ccsc; - unsigned long mod_rate; -- unsigned int is_de3 : 1; -+ unsigned int de_type; - unsigned int has_formatter : 1; - unsigned int scanline_yuv; - }; -@@ -216,13 +221,13 @@ engine_to_sun8i_mixer(struct sunxi_engine *engine) - static inline u32 - sun8i_blender_base(struct sun8i_mixer *mixer) - { -- return mixer->cfg->is_de3 ? DE3_BLD_BASE : DE2_BLD_BASE; -+ return mixer->cfg->de_type == sun8i_mixer_de3 ? DE3_BLD_BASE : DE2_BLD_BASE; - } - - static inline u32 - sun8i_channel_base(struct sun8i_mixer *mixer, int channel) - { -- if (mixer->cfg->is_de3) -+ if (mixer->cfg->de_type == sun8i_mixer_de3) - return DE3_CH_BASE + channel * DE3_CH_SIZE; - else - return DE2_CH_BASE + channel * DE2_CH_SIZE; -diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c b/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c -index ae0806bccac7f..504ffa0971a4f 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c -+++ b/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c -@@ -93,7 +93,7 @@ static u32 sun8i_ui_scaler_base(struct sun8i_mixer *mixer, int channel) - { - int vi_num = mixer->cfg->vi_num; - -- if (mixer->cfg->is_de3) -+ if (mixer->cfg->de_type == sun8i_mixer_de3) - return DE3_VI_SCALER_UNIT_BASE + - DE3_VI_SCALER_UNIT_SIZE * vi_num + - DE3_UI_SCALER_UNIT_SIZE * (channel - vi_num); -diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c -index 3c657b069d1f4..4647e9bcccaa7 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c -+++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c -@@ -25,7 +25,7 @@ static void sun8i_vi_layer_update_alpha(struct sun8i_mixer *mixer, int channel, - - ch_base = sun8i_channel_base(mixer, channel); - -- if (mixer->cfg->is_de3) { -+ if (mixer->cfg->de_type >= sun8i_mixer_de3) { - mask = SUN50I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA_MASK | - SUN50I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA_MODE_MASK; - val = SUN50I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA -@@ -483,7 +483,7 @@ struct sun8i_layer *sun8i_vi_layer_init_one(struct drm_device *drm, - layer->channel = index; - layer->overlay = 0; - -- if (mixer->cfg->is_de3) { -+ if (mixer->cfg->de_type >= sun8i_mixer_de3) { - formats = sun8i_vi_layer_de3_formats; - format_count = ARRAY_SIZE(sun8i_vi_layer_de3_formats); - } else { -@@ -507,7 +507,7 @@ struct sun8i_layer *sun8i_vi_layer_init_one(struct drm_device *drm, - - plane_cnt = mixer->cfg->ui_num + mixer->cfg->vi_num; - -- if (mixer->cfg->vi_num == 1 || mixer->cfg->is_de3) { -+ if (mixer->cfg->vi_num == 1 || mixer->cfg->de_type >= sun8i_mixer_de3) { - ret = drm_plane_create_alpha_property(&layer->plane); - if (ret) { - dev_err(drm->dev, "Couldn't add alpha property\n"); -@@ -524,7 +524,7 @@ struct sun8i_layer *sun8i_vi_layer_init_one(struct drm_device *drm, - - supported_encodings = BIT(DRM_COLOR_YCBCR_BT601) | - BIT(DRM_COLOR_YCBCR_BT709); -- if (mixer->cfg->is_de3) -+ if (mixer->cfg->de_type >= sun8i_mixer_de3) - supported_encodings |= BIT(DRM_COLOR_YCBCR_BT2020); - - supported_ranges = BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) | -diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c -index 2e49a6e5f1f1c..aa346c3beb303 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c -+++ b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c -@@ -835,7 +835,7 @@ static const u32 bicubic4coefftab32[480] = { - - static u32 sun8i_vi_scaler_base(struct sun8i_mixer *mixer, int channel) - { -- if (mixer->cfg->is_de3) -+ if (mixer->cfg->de_type == sun8i_mixer_de3) - return DE3_VI_SCALER_UNIT_BASE + - DE3_VI_SCALER_UNIT_SIZE * channel; - else -@@ -982,7 +982,7 @@ void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer, int layer, - cvphase = vphase; - } - -- if (mixer->cfg->is_de3) { -+ if (mixer->cfg->de_type >= sun8i_mixer_de3) { - u32 val; - - if (format->hsub == 1 && format->vsub == 1) --- -2.46.1 - -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH v5 14/26] drm: sun4i: de2/de3: refactor mixer - initialisation -From: Jernej Skrabec -Date: Sun, 29 Sep 2024 22:04:46 +1300 -Message-Id: <20240929091107.838023-15-ryan@testtoast.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -Now that the DE variant can be selected by enum, take the oppportunity -to factor out some common initialisation code to a separate function. - -Signed-off-by: Jernej Skrabec -Signed-off-by: Ryan Walklin -Reviewed-by: Andre Przywara ---- -Changelog v1..v2: -- Combine base register allocation and initialisation in sun8i_mixer_init -- Whitespace fix - -Changelog v4..v5: -- Remove trailing whitespace ---- - drivers/gpu/drm/sun4i/sun8i_mixer.c | 64 +++++++++++++++-------------- - 1 file changed, 34 insertions(+), 30 deletions(-) - -diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c -index 16e018aa4aae9..18745af089545 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_mixer.c -+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c -@@ -468,6 +468,38 @@ static int sun8i_mixer_of_get_id(struct device_node *node) - return of_ep.id; - } - -+static void sun8i_mixer_init(struct sun8i_mixer *mixer) -+{ -+ unsigned int base = sun8i_blender_base(mixer); -+ int plane_cnt, i; -+ -+ /* Enable the mixer */ -+ regmap_write(mixer->engine.regs, SUN8I_MIXER_GLOBAL_CTL, -+ SUN8I_MIXER_GLOBAL_CTL_RT_EN); -+ -+ /* Set background color to black */ -+ regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_BKCOLOR(base), -+ SUN8I_MIXER_BLEND_COLOR_BLACK); -+ -+ /* -+ * Set fill color of bottom plane to black. Generally not needed -+ * except when VI plane is at bottom (zpos = 0) and enabled. -+ */ -+ regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(base), -+ SUN8I_MIXER_BLEND_PIPE_CTL_FC_EN(0)); -+ regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ATTR_FCOLOR(base, 0), -+ SUN8I_MIXER_BLEND_COLOR_BLACK); -+ -+ plane_cnt = mixer->cfg->vi_num + mixer->cfg->ui_num; -+ for (i = 0; i < plane_cnt; i++) -+ regmap_write(mixer->engine.regs, -+ SUN8I_MIXER_BLEND_MODE(base, i), -+ SUN8I_MIXER_BLEND_MODE_DEF); -+ -+ regmap_update_bits(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(base), -+ SUN8I_MIXER_BLEND_PIPE_CTL_EN_MSK, 0); -+} -+ - static int sun8i_mixer_bind(struct device *dev, struct device *master, - void *data) - { -@@ -476,8 +508,6 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master, - struct sun4i_drv *drv = drm->dev_private; - struct sun8i_mixer *mixer; - void __iomem *regs; -- unsigned int base; -- int plane_cnt; - int i, ret; - - /* -@@ -581,8 +611,6 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master, - - list_add_tail(&mixer->engine.list, &drv->engine_list); - -- base = sun8i_blender_base(mixer); -- - /* Reset registers and disable unused sub-engines */ - if (mixer->cfg->de_type == sun8i_mixer_de3) { - for (i = 0; i < DE3_MIXER_UNIT_SIZE; i += 4) -@@ -598,7 +626,7 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master, - regmap_write(mixer->engine.regs, SUN50I_MIXER_FMT_EN, 0); - regmap_write(mixer->engine.regs, SUN50I_MIXER_CDC0_EN, 0); - regmap_write(mixer->engine.regs, SUN50I_MIXER_CDC1_EN, 0); -- } else { -+ } else if (mixer->cfg->de_type == sun8i_mixer_de2) { - for (i = 0; i < DE2_MIXER_UNIT_SIZE; i += 4) - regmap_write(mixer->engine.regs, i, 0); - -@@ -611,31 +639,7 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master, - regmap_write(mixer->engine.regs, SUN8I_MIXER_DCSC_EN, 0); - } - -- /* Enable the mixer */ -- regmap_write(mixer->engine.regs, SUN8I_MIXER_GLOBAL_CTL, -- SUN8I_MIXER_GLOBAL_CTL_RT_EN); -- -- /* Set background color to black */ -- regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_BKCOLOR(base), -- SUN8I_MIXER_BLEND_COLOR_BLACK); -- -- /* -- * Set fill color of bottom plane to black. Generally not needed -- * except when VI plane is at bottom (zpos = 0) and enabled. -- */ -- regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(base), -- SUN8I_MIXER_BLEND_PIPE_CTL_FC_EN(0)); -- regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ATTR_FCOLOR(base, 0), -- SUN8I_MIXER_BLEND_COLOR_BLACK); -- -- plane_cnt = mixer->cfg->vi_num + mixer->cfg->ui_num; -- for (i = 0; i < plane_cnt; i++) -- regmap_write(mixer->engine.regs, -- SUN8I_MIXER_BLEND_MODE(base, i), -- SUN8I_MIXER_BLEND_MODE_DEF); -- -- regmap_update_bits(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(base), -- SUN8I_MIXER_BLEND_PIPE_CTL_EN_MSK, 0); -+ sun8i_mixer_init(mixer); - - return 0; - --- -2.46.1 - -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH v5 15/26] drm: sun4i: vi_scaler refactor vi_scaler - enablement -From: Jernej Skrabec -Date: Sun, 29 Sep 2024 22:04:47 +1300 -Message-Id: <20240929091107.838023-16-ryan@testtoast.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -If the video scaler is required, then it is obligatory to set the -relevant register to enable it, so move this to the -sun8i_vi_scaler_setup() function. - -This simplifies the alternate case (scaler not required) so replace the -vi_scaler_enable() function with a vi_scaler_disable() function. - -Signed-off-by: Jernej Skrabec -Signed-off-by: Ryan Walklin -Reviewed-by: Chen-Yu Tsai -Acked-by: Conor Dooley -Reviewed-by: Andre Przywara ---- - drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 3 +-- - drivers/gpu/drm/sun4i/sun8i_vi_scaler.c | 21 +++++++++++---------- - drivers/gpu/drm/sun4i/sun8i_vi_scaler.h | 2 +- - 3 files changed, 13 insertions(+), 13 deletions(-) - -diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c -index 4647e9bcccaa7..e348fd0a3d81c 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c -+++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c -@@ -156,10 +156,9 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel, - sun8i_vi_scaler_setup(mixer, channel, src_w, src_h, dst_w, - dst_h, hscale, vscale, hphase, vphase, - format); -- sun8i_vi_scaler_enable(mixer, channel, true); - } else { - DRM_DEBUG_DRIVER("HW scaling is not needed\n"); -- sun8i_vi_scaler_enable(mixer, channel, false); -+ sun8i_vi_scaler_disable(mixer, channel); - } - - regmap_write(mixer->engine.regs, -diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c -index aa346c3beb303..e7242301b312c 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c -+++ b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c -@@ -933,20 +933,13 @@ static void sun8i_vi_scaler_set_coeff_ui(struct regmap *map, u32 base, - &table[offset], SUN8I_VI_SCALER_COEFF_COUNT); - } - --void sun8i_vi_scaler_enable(struct sun8i_mixer *mixer, int layer, bool enable) -+void sun8i_vi_scaler_disable(struct sun8i_mixer *mixer, int layer) - { -- u32 val, base; -+ u32 base; - - base = sun8i_vi_scaler_base(mixer, layer); - -- if (enable) -- val = SUN8I_SCALER_VSU_CTRL_EN | -- SUN8I_SCALER_VSU_CTRL_COEFF_RDY; -- else -- val = 0; -- -- regmap_write(mixer->engine.regs, -- SUN8I_SCALER_VSU_CTRL(base), val); -+ regmap_write(mixer->engine.regs, SUN8I_SCALER_VSU_CTRL(base), 0); - } - - void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer, int layer, -@@ -982,6 +975,9 @@ void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer, int layer, - cvphase = vphase; - } - -+ regmap_write(mixer->engine.regs, SUN8I_SCALER_VSU_CTRL(base), -+ SUN8I_SCALER_VSU_CTRL_EN); -+ - if (mixer->cfg->de_type >= sun8i_mixer_de3) { - u32 val; - -@@ -1027,4 +1023,9 @@ void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer, int layer, - else - sun8i_vi_scaler_set_coeff_ui(mixer->engine.regs, base, - hscale, vscale, format); -+ -+ if (mixer->cfg->de_type <= sun8i_mixer_de3) -+ regmap_write(mixer->engine.regs, SUN8I_SCALER_VSU_CTRL(base), -+ SUN8I_SCALER_VSU_CTRL_EN | -+ SUN8I_SCALER_VSU_CTRL_COEFF_RDY); - } -diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h -index 68f6593b369ab..e801bc7a4189e 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h -+++ b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h -@@ -69,7 +69,7 @@ - #define SUN50I_SCALER_VSU_ANGLE_SHIFT(x) (((x) << 16) & 0xF) - #define SUN50I_SCALER_VSU_ANGLE_OFFSET(x) ((x) & 0xFF) - --void sun8i_vi_scaler_enable(struct sun8i_mixer *mixer, int layer, bool enable); -+void sun8i_vi_scaler_disable(struct sun8i_mixer *mixer, int layer); - void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer, int layer, - u32 src_w, u32 src_h, u32 dst_w, u32 dst_h, - u32 hscale, u32 vscale, u32 hphase, u32 vphase, --- -2.46.1 - -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH v5 16/26] drm: sun4i: de2/de3: add generic blender register - reference function -From: Jernej Skrabec -Date: Sun, 29 Sep 2024 22:04:48 +1300 -Message-Id: <20240929091107.838023-17-ryan@testtoast.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -The DE2 and DE3 engines have a blender register range within the -mixer engine register map, whereas the DE33 separates this out into -a separate display group. - -Prepare for this by adding a function to look the blender reference up, -with a subsequent patch to add a conditional based on the DE type. - -Signed-off-by: Jernej Skrabec -Signed-off-by: Ryan Walklin -Reviewed-by: Chen-Yu Tsai ---- - drivers/gpu/drm/sun4i/sun8i_mixer.h | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h -index 82956cb97cfd9..75facc7d1fa66 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_mixer.h -+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h -@@ -224,6 +224,12 @@ sun8i_blender_base(struct sun8i_mixer *mixer) - return mixer->cfg->de_type == sun8i_mixer_de3 ? DE3_BLD_BASE : DE2_BLD_BASE; - } - -+static inline struct regmap * -+sun8i_blender_regmap(struct sun8i_mixer *mixer) -+{ -+ return mixer->engine.regs; -+} -+ - static inline u32 - sun8i_channel_base(struct sun8i_mixer *mixer, int channel) - { --- -2.46.1 - -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH v5 17/26] drm: sun4i: de2/de3: use generic register - reference function for layer configuration -From: Jernej Skrabec -Date: Sun, 29 Sep 2024 22:04:49 +1300 -Message-Id: <20240929091107.838023-18-ryan@testtoast.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -Use the new blender register lookup function where required in the layer -commit and update code. - -Signed-off-by: Jernej Skrabec -Signed-off-by: Ryan Walklin -Reviewed-by: Chen-Yu Tsai ---- -Changelog v2..v3: -- Refactor for 6.11 layer init/modesetting changes ---- - drivers/gpu/drm/sun4i/sun8i_mixer.c | 5 +++-- - drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 7 +++++-- - drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 6 ++++-- - 3 files changed, 12 insertions(+), 6 deletions(-) - -diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c -index 18745af089545..600084286b39d 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_mixer.c -+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c -@@ -277,6 +277,7 @@ static void sun8i_mixer_commit(struct sunxi_engine *engine, - { - struct sun8i_mixer *mixer = engine_to_sun8i_mixer(engine); - u32 bld_base = sun8i_blender_base(mixer); -+ struct regmap *bld_regs = sun8i_blender_regmap(mixer); - struct drm_plane_state *plane_state; - struct drm_plane *plane; - u32 route = 0, pipe_en = 0; -@@ -316,8 +317,8 @@ static void sun8i_mixer_commit(struct sunxi_engine *engine, - pipe_en |= SUN8I_MIXER_BLEND_PIPE_CTL_EN(zpos); - } - -- regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ROUTE(bld_base), route); -- regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(bld_base), -+ regmap_write(bld_regs, SUN8I_MIXER_BLEND_ROUTE(bld_base), route); -+ regmap_write(bld_regs, SUN8I_MIXER_BLEND_PIPE_CTL(bld_base), - pipe_en | SUN8I_MIXER_BLEND_PIPE_CTL_FC_EN(0)); - - regmap_write(engine->regs, SUN8I_MIXER_GLOBAL_DBUFF, -diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c -index cb9b694fef101..7f1231cf0f012 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c -+++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c -@@ -24,6 +24,7 @@ - #include "sun8i_mixer.h" - #include "sun8i_ui_layer.h" - #include "sun8i_ui_scaler.h" -+#include "sun8i_vi_scaler.h" - - static void sun8i_ui_layer_update_alpha(struct sun8i_mixer *mixer, int channel, - int overlay, struct drm_plane *plane) -@@ -52,6 +53,7 @@ static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel, - { - struct drm_plane_state *state = plane->state; - u32 src_w, src_h, dst_w, dst_h; -+ struct regmap *bld_regs; - u32 bld_base, ch_base; - u32 outsize, insize; - u32 hphase, vphase; -@@ -60,6 +62,7 @@ static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel, - channel, overlay); - - bld_base = sun8i_blender_base(mixer); -+ bld_regs = sun8i_blender_regmap(mixer); - ch_base = sun8i_channel_base(mixer, channel); - - src_w = drm_rect_width(&state->src) >> 16; -@@ -104,10 +107,10 @@ static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel, - DRM_DEBUG_DRIVER("Layer destination coordinates X: %d Y: %d\n", - state->dst.x1, state->dst.y1); - DRM_DEBUG_DRIVER("Layer destination size W: %d H: %d\n", dst_w, dst_h); -- regmap_write(mixer->engine.regs, -+ regmap_write(bld_regs, - SUN8I_MIXER_BLEND_ATTR_COORD(bld_base, zpos), - SUN8I_MIXER_COORD(state->dst.x1, state->dst.y1)); -- regmap_write(mixer->engine.regs, -+ regmap_write(bld_regs, - SUN8I_MIXER_BLEND_ATTR_INSIZE(bld_base, zpos), - outsize); - -diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c -index e348fd0a3d81c..d19349eecc9de 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c -+++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c -@@ -55,6 +55,7 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel, - struct drm_plane_state *state = plane->state; - const struct drm_format_info *format = state->fb->format; - u32 src_w, src_h, dst_w, dst_h; -+ struct regmap *bld_regs; - u32 bld_base, ch_base; - u32 outsize, insize; - u32 hphase, vphase; -@@ -66,6 +67,7 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel, - channel, overlay); - - bld_base = sun8i_blender_base(mixer); -+ bld_regs = sun8i_blender_regmap(mixer); - ch_base = sun8i_channel_base(mixer, channel); - - src_w = drm_rect_width(&state->src) >> 16; -@@ -182,10 +184,10 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel, - DRM_DEBUG_DRIVER("Layer destination coordinates X: %d Y: %d\n", - state->dst.x1, state->dst.y1); - DRM_DEBUG_DRIVER("Layer destination size W: %d H: %d\n", dst_w, dst_h); -- regmap_write(mixer->engine.regs, -+ regmap_write(bld_regs, - SUN8I_MIXER_BLEND_ATTR_COORD(bld_base, zpos), - SUN8I_MIXER_COORD(state->dst.x1, state->dst.y1)); -- regmap_write(mixer->engine.regs, -+ regmap_write(bld_regs, - SUN8I_MIXER_BLEND_ATTR_INSIZE(bld_base, zpos), - outsize); - --- -2.46.1 - -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH v5 18/26] drm: sun4i: de3: Implement AFBC support -From: Jernej Skrabec -Date: Sun, 29 Sep 2024 22:04:50 +1300 -Message-Id: <20240929091107.838023-19-ryan@testtoast.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -Buffers, compressed with AFBC, are supported by the DE3 and above, and -are generally more efficient for memory transfers. Add support for them. - -Currently it's implemented only for VI layers, but vendor code and -documentation suggest UI layers can have them too. However, I haven't -observed any SoC with such feature. - -Signed-off-by: Jernej Skrabec -Signed-off-by: Ryan Walklin ---- -Changelog v4..v5: -- Correct strict mode warnings from checkpatch.pl ---- - drivers/gpu/drm/sun4i/Makefile | 2 +- - drivers/gpu/drm/sun4i/sun50i_afbc.c | 250 +++++++++++++++++++++++++ - drivers/gpu/drm/sun4i/sun50i_afbc.h | 87 +++++++++ - drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 84 +++++++-- - 4 files changed, 409 insertions(+), 14 deletions(-) - create mode 100644 drivers/gpu/drm/sun4i/sun50i_afbc.c - create mode 100644 drivers/gpu/drm/sun4i/sun50i_afbc.h - -diff --git a/drivers/gpu/drm/sun4i/Makefile b/drivers/gpu/drm/sun4i/Makefile -index 3f516329f51ee..78290f1660fbd 100644 ---- a/drivers/gpu/drm/sun4i/Makefile -+++ b/drivers/gpu/drm/sun4i/Makefile -@@ -17,7 +17,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_fmt.o sun50i_afbc.o - - sun4i-tcon-y += sun4i_crtc.o - sun4i-tcon-y += sun4i_tcon_dclk.o -diff --git a/drivers/gpu/drm/sun4i/sun50i_afbc.c b/drivers/gpu/drm/sun4i/sun50i_afbc.c -new file mode 100644 -index 0000000000000..b55e1c5533714 ---- /dev/null -+++ b/drivers/gpu/drm/sun4i/sun50i_afbc.c -@@ -0,0 +1,250 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+/* -+ * Copyright (C) Jernej Skrabec -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "sun50i_afbc.h" -+#include "sun8i_mixer.h" -+ -+static u32 sun50i_afbc_get_base(struct sun8i_mixer *mixer, unsigned int channel) -+{ -+ u32 base = sun8i_channel_base(mixer, channel); -+ -+ if (mixer->cfg->de_type == sun8i_mixer_de3) -+ return base + SUN50I_AFBC_CH_OFFSET; -+ -+ return base + 0x4000; -+} -+ -+bool sun50i_afbc_format_mod_supported(struct sun8i_mixer *mixer, -+ u32 format, u64 modifier) -+{ -+ u64 mode; -+ -+ if (modifier == DRM_FORMAT_MOD_INVALID) -+ return false; -+ -+ if (modifier == DRM_FORMAT_MOD_LINEAR) { -+ if (format == DRM_FORMAT_YUV420_8BIT || -+ format == DRM_FORMAT_YUV420_10BIT || -+ format == DRM_FORMAT_Y210) -+ return false; -+ return true; -+ } -+ -+ if (mixer->cfg->de_type == sun8i_mixer_de2) -+ return false; -+ -+ mode = AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | -+ AFBC_FORMAT_MOD_SPARSE | -+ AFBC_FORMAT_MOD_SPLIT; -+ -+ switch (format) { -+ case DRM_FORMAT_RGBA8888: -+ case DRM_FORMAT_RGB888: -+ case DRM_FORMAT_RGB565: -+ case DRM_FORMAT_RGBA4444: -+ case DRM_FORMAT_RGBA5551: -+ case DRM_FORMAT_RGBA1010102: -+ mode |= AFBC_FORMAT_MOD_YTR; -+ break; -+ case DRM_FORMAT_YUYV: -+ case DRM_FORMAT_Y210: -+ case DRM_FORMAT_YUV420_8BIT: -+ case DRM_FORMAT_YUV420_10BIT: -+ break; -+ default: -+ return false; -+ } -+ -+ return modifier == DRM_FORMAT_MOD_ARM_AFBC(mode); -+} -+ -+void sun50i_afbc_atomic_update(struct sun8i_mixer *mixer, unsigned int channel, -+ struct drm_plane *plane) -+{ -+ struct drm_plane_state *state = plane->state; -+ struct drm_framebuffer *fb = state->fb; -+ const struct drm_format_info *format = fb->format; -+ struct drm_gem_dma_object *gem; -+ u32 base, val, src_w, src_h; -+ u32 def_color0, def_color1; -+ struct regmap *regs; -+ dma_addr_t dma_addr; -+ -+ base = sun50i_afbc_get_base(mixer, channel); -+ regs = mixer->engine.regs; -+ -+ src_w = drm_rect_width(&state->src) >> 16; -+ src_h = drm_rect_height(&state->src) >> 16; -+ -+ val = SUN50I_FBD_SIZE_HEIGHT(src_h); -+ val |= SUN50I_FBD_SIZE_WIDTH(src_w); -+ regmap_write(regs, SUN50I_FBD_SIZE(base), val); -+ -+ val = SUN50I_FBD_BLK_SIZE_HEIGHT(DIV_ROUND_UP(src_h, 16)); -+ val = SUN50I_FBD_BLK_SIZE_WIDTH(DIV_ROUND_UP(src_w, 16)); -+ regmap_write(regs, SUN50I_FBD_BLK_SIZE(base), val); -+ -+ val = SUN50I_FBD_SRC_CROP_TOP(0); -+ val |= SUN50I_FBD_SRC_CROP_LEFT(0); -+ regmap_write(regs, SUN50I_FBD_SRC_CROP(base), val); -+ -+ val = SUN50I_FBD_LAY_CROP_TOP(state->src.y1 >> 16); -+ val |= SUN50I_FBD_LAY_CROP_LEFT(state->src.x1 >> 16); -+ regmap_write(regs, SUN50I_FBD_LAY_CROP(base), val); -+ -+ /* -+ * Default color is always set to white, in colorspace and bitness -+ * that coresponds to used format. If it is actually used or not -+ * depends on AFBC buffer. At least in Cedrus it can be turned on -+ * or off. -+ * NOTE: G and B channels are off by 1 (up). It's unclear if this -+ * is because HW need such value or it is due to good enough code -+ * in vendor driver and HW clips the value anyway. -+ */ -+ def_color0 = 0; -+ def_color1 = 0; -+ -+ val = 0; -+ switch (format->format) { -+ case DRM_FORMAT_YUYV: -+ case DRM_FORMAT_YUV420_10BIT: -+ val |= SUN50I_FBD_FMT_SBS1(2); -+ val |= SUN50I_FBD_FMT_SBS0(1); -+ break; -+ case DRM_FORMAT_Y210: -+ val |= SUN50I_FBD_FMT_SBS1(3); -+ val |= SUN50I_FBD_FMT_SBS0(2); -+ break; -+ default: -+ val |= SUN50I_FBD_FMT_SBS1(1); -+ val |= SUN50I_FBD_FMT_SBS0(1); -+ break; -+ } -+ switch (format->format) { -+ case DRM_FORMAT_RGBA8888: -+ val |= SUN50I_FBD_FMT_YUV_TRAN; -+ val |= SUN50I_FBD_FMT_IN_FMT(SUN50I_AFBC_RGBA_8888); -+ def_color0 = SUN50I_FBD_DEFAULT_COLOR0_ALPHA(255) | -+ SUN50I_FBD_DEFAULT_COLOR0_YR(255); -+ def_color1 = SUN50I_FBD_DEFAULT_COLOR1_UG(256) | -+ SUN50I_FBD_DEFAULT_COLOR1_VB(256); -+ break; -+ case DRM_FORMAT_RGB888: -+ val |= SUN50I_FBD_FMT_YUV_TRAN; -+ val |= SUN50I_FBD_FMT_IN_FMT(SUN50I_AFBC_RGB_888); -+ def_color0 = SUN50I_FBD_DEFAULT_COLOR0_ALPHA(0) | -+ SUN50I_FBD_DEFAULT_COLOR0_YR(255); -+ def_color1 = SUN50I_FBD_DEFAULT_COLOR1_UG(256) | -+ SUN50I_FBD_DEFAULT_COLOR1_VB(256); -+ break; -+ case DRM_FORMAT_RGB565: -+ val |= SUN50I_FBD_FMT_YUV_TRAN; -+ val |= SUN50I_FBD_FMT_IN_FMT(SUN50I_AFBC_RGB_565); -+ def_color0 = SUN50I_FBD_DEFAULT_COLOR0_ALPHA(0) | -+ SUN50I_FBD_DEFAULT_COLOR0_YR(31); -+ def_color1 = SUN50I_FBD_DEFAULT_COLOR1_UG(64) | -+ SUN50I_FBD_DEFAULT_COLOR1_VB(32); -+ break; -+ case DRM_FORMAT_RGBA4444: -+ val |= SUN50I_FBD_FMT_YUV_TRAN; -+ val |= SUN50I_FBD_FMT_IN_FMT(SUN50I_AFBC_RGBA_4444); -+ def_color0 = SUN50I_FBD_DEFAULT_COLOR0_ALPHA(15) | -+ SUN50I_FBD_DEFAULT_COLOR0_YR(15); -+ def_color1 = SUN50I_FBD_DEFAULT_COLOR1_UG(16) | -+ SUN50I_FBD_DEFAULT_COLOR1_VB(16); -+ break; -+ case DRM_FORMAT_RGBA5551: -+ val |= SUN50I_FBD_FMT_YUV_TRAN; -+ val |= SUN50I_FBD_FMT_IN_FMT(SUN50I_AFBC_RGBA_5551); -+ def_color0 = SUN50I_FBD_DEFAULT_COLOR0_ALPHA(1) | -+ SUN50I_FBD_DEFAULT_COLOR0_YR(31); -+ def_color1 = SUN50I_FBD_DEFAULT_COLOR1_UG(32) | -+ SUN50I_FBD_DEFAULT_COLOR1_VB(32); -+ break; -+ case DRM_FORMAT_RGBA1010102: -+ val |= SUN50I_FBD_FMT_YUV_TRAN; -+ val |= SUN50I_FBD_FMT_IN_FMT(SUN50I_AFBC_RGBA1010102); -+ def_color0 = SUN50I_FBD_DEFAULT_COLOR0_ALPHA(3) | -+ SUN50I_FBD_DEFAULT_COLOR0_YR(1023); -+ def_color1 = SUN50I_FBD_DEFAULT_COLOR1_UG(1024) | -+ SUN50I_FBD_DEFAULT_COLOR1_VB(1024); -+ break; -+ case DRM_FORMAT_YUV420_8BIT: -+ val |= SUN50I_FBD_FMT_IN_FMT(SUN50I_AFBC_YUV420); -+ def_color0 = SUN50I_FBD_DEFAULT_COLOR0_ALPHA(0) | -+ SUN50I_FBD_DEFAULT_COLOR0_YR(255); -+ def_color1 = SUN50I_FBD_DEFAULT_COLOR1_UG(128) | -+ SUN50I_FBD_DEFAULT_COLOR1_VB(128); -+ break; -+ case DRM_FORMAT_YUYV: -+ val |= SUN50I_FBD_FMT_IN_FMT(SUN50I_AFBC_YUV422); -+ def_color0 = SUN50I_FBD_DEFAULT_COLOR0_ALPHA(0) | -+ SUN50I_FBD_DEFAULT_COLOR0_YR(255); -+ def_color1 = SUN50I_FBD_DEFAULT_COLOR1_UG(128) | -+ SUN50I_FBD_DEFAULT_COLOR1_VB(128); -+ break; -+ case DRM_FORMAT_YUV420_10BIT: -+ val |= SUN50I_FBD_FMT_IN_FMT(SUN50I_AFBC_P010); -+ def_color0 = SUN50I_FBD_DEFAULT_COLOR0_ALPHA(0) | -+ SUN50I_FBD_DEFAULT_COLOR0_YR(1023); -+ def_color1 = SUN50I_FBD_DEFAULT_COLOR1_UG(512) | -+ SUN50I_FBD_DEFAULT_COLOR1_VB(512); -+ break; -+ case DRM_FORMAT_Y210: -+ val |= SUN50I_FBD_FMT_IN_FMT(SUN50I_AFBC_P210); -+ def_color0 = SUN50I_FBD_DEFAULT_COLOR0_ALPHA(0) | -+ SUN50I_FBD_DEFAULT_COLOR0_YR(1023); -+ def_color1 = SUN50I_FBD_DEFAULT_COLOR1_UG(512) | -+ SUN50I_FBD_DEFAULT_COLOR1_VB(512); -+ break; -+ } -+ regmap_write(regs, SUN50I_FBD_FMT(base), val); -+ -+ /* Get the physical address of the buffer in memory */ -+ gem = drm_fb_dma_get_gem_obj(fb, 0); -+ -+ DRM_DEBUG_DRIVER("Using GEM @ %pad\n", &gem->dma_addr); -+ -+ /* Compute the start of the displayed memory */ -+ dma_addr = gem->dma_addr + fb->offsets[0]; -+ -+ regmap_write(regs, SUN50I_FBD_LADDR(base), lower_32_bits(dma_addr)); -+ regmap_write(regs, SUN50I_FBD_HADDR(base), upper_32_bits(dma_addr)); -+ -+ val = SUN50I_FBD_OVL_SIZE_HEIGHT(src_h); -+ val |= SUN50I_FBD_OVL_SIZE_WIDTH(src_w); -+ regmap_write(regs, SUN50I_FBD_OVL_SIZE(base), val); -+ -+ val = SUN50I_FBD_OVL_COOR_Y(0); -+ val |= SUN50I_FBD_OVL_COOR_X(0); -+ regmap_write(regs, SUN50I_FBD_OVL_COOR(base), val); -+ -+ regmap_write(regs, SUN50I_FBD_OVL_BG_COLOR(base), -+ SUN8I_MIXER_BLEND_COLOR_BLACK); -+ regmap_write(regs, SUN50I_FBD_DEFAULT_COLOR0(base), def_color0); -+ regmap_write(regs, SUN50I_FBD_DEFAULT_COLOR1(base), def_color1); -+ -+ val = SUN50I_FBD_CTL_GLB_ALPHA(state->alpha >> 16); -+ val |= SUN50I_FBD_CTL_CLK_GATE; -+ val |= (state->alpha == DRM_BLEND_ALPHA_OPAQUE) ? -+ SUN50I_FBD_CTL_ALPHA_MODE_PIXEL : -+ SUN50I_FBD_CTL_ALPHA_MODE_COMBINED; -+ val |= SUN50I_FBD_CTL_FBD_EN; -+ regmap_write(regs, SUN50I_FBD_CTL(base), val); -+} -+ -+void sun50i_afbc_disable(struct sun8i_mixer *mixer, unsigned int channel) -+{ -+ u32 base = sun50i_afbc_get_base(mixer, channel); -+ -+ regmap_write(mixer->engine.regs, SUN50I_FBD_CTL(base), 0); -+} -diff --git a/drivers/gpu/drm/sun4i/sun50i_afbc.h b/drivers/gpu/drm/sun4i/sun50i_afbc.h -new file mode 100644 -index 0000000000000..cea685c868550 ---- /dev/null -+++ b/drivers/gpu/drm/sun4i/sun50i_afbc.h -@@ -0,0 +1,87 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+/* -+ * Copyright (C) Jernej Skrabec -+ */ -+ -+#ifndef _SUN50I_AFBC_H_ -+#define _SUN50I_AFBC_H_ -+ -+#include -+ -+#define SUN50I_AFBC_CH_OFFSET 0x300 -+ -+#define SUN50I_AFBC_RGBA_8888 0x02 -+#define SUN50I_AFBC_RGB_888 0x08 -+#define SUN50I_AFBC_RGB_565 0x0a -+#define SUN50I_AFBC_RGBA_4444 0x0e -+#define SUN50I_AFBC_RGBA_5551 0x12 -+#define SUN50I_AFBC_RGBA1010102 0x16 -+#define SUN50I_AFBC_YUV422 0x26 -+#define SUN50I_AFBC_YUV420 0x2a -+#define SUN50I_AFBC_P010 0x30 -+#define SUN50I_AFBC_P210 0x32 -+ -+#define SUN50I_FBD_CTL(base) ((base) + 0x00) -+#define SUN50I_FBD_CTL_GLB_ALPHA(v) ((v) << 24) -+#define SUN50I_FBD_CTL_CLK_GATE BIT(4) -+#define SUN50I_FBD_CTL_ALPHA_MODE_PIXEL ((0) << 2) -+#define SUN50I_FBD_CTL_ALPHA_MODE_LAYER ((1) << 2) -+#define SUN50I_FBD_CTL_ALPHA_MODE_COMBINED ((2) << 2) -+#define SUN50I_FBD_CTL_FBD_FCEN BIT(1) -+#define SUN50I_FBD_CTL_FBD_EN BIT(0) -+ -+#define SUN50I_FBD_SIZE(base) ((base) + 0x08) -+#define SUN50I_FBD_SIZE_HEIGHT(v) (((v) - 1) << 16) -+#define SUN50I_FBD_SIZE_WIDTH(v) (((v) - 1) << 0) -+ -+#define SUN50I_FBD_BLK_SIZE(base) ((base) + 0x0c) -+#define SUN50I_FBD_BLK_SIZE_HEIGHT(v) ((v) << 16) -+#define SUN50I_FBD_BLK_SIZE_WIDTH(v) ((v) << 0) -+ -+#define SUN50I_FBD_SRC_CROP(base) ((base) + 0x10) -+#define SUN50I_FBD_SRC_CROP_TOP(v) ((v) << 16) -+#define SUN50I_FBD_SRC_CROP_LEFT(v) ((v) << 0) -+ -+#define SUN50I_FBD_LAY_CROP(base) ((base) + 0x14) -+#define SUN50I_FBD_LAY_CROP_TOP(v) ((v) << 16) -+#define SUN50I_FBD_LAY_CROP_LEFT(v) ((v) << 0) -+ -+#define SUN50I_FBD_FMT(base) ((base) + 0x18) -+#define SUN50I_FBD_FMT_SBS1(v) ((v) << 18) -+#define SUN50I_FBD_FMT_SBS0(v) ((v) << 16) -+#define SUN50I_FBD_FMT_YUV_TRAN BIT(7) -+#define SUN50I_FBD_FMT_IN_FMT(v) ((v) << 0) -+ -+#define SUN50I_FBD_LADDR(base) ((base) + 0x20) -+#define SUN50I_FBD_HADDR(base) ((base) + 0x24) -+ -+#define SUN50I_FBD_OVL_SIZE(base) ((base) + 0x30) -+#define SUN50I_FBD_OVL_SIZE_HEIGHT(v) (((v) - 1) << 16) -+#define SUN50I_FBD_OVL_SIZE_WIDTH(v) (((v) - 1) << 0) -+ -+#define SUN50I_FBD_OVL_COOR(base) ((base) + 0x34) -+#define SUN50I_FBD_OVL_COOR_Y(v) ((v) << 16) -+#define SUN50I_FBD_OVL_COOR_X(v) ((v) << 0) -+ -+#define SUN50I_FBD_OVL_BG_COLOR(base) ((base) + 0x38) -+#define SUN50I_FBD_OVL_FILL_COLOR(base) ((base) + 0x3c) -+ -+#define SUN50I_FBD_DEFAULT_COLOR0(base) ((base) + 0x50) -+#define SUN50I_FBD_DEFAULT_COLOR0_ALPHA(v) ((v) << 16) -+#define SUN50I_FBD_DEFAULT_COLOR0_YR(v) ((v) << 0) -+ -+#define SUN50I_FBD_DEFAULT_COLOR1(base) ((base) + 0x54) -+#define SUN50I_FBD_DEFAULT_COLOR1_VB(v) ((v) << 16) -+#define SUN50I_FBD_DEFAULT_COLOR1_UG(v) ((v) << 0) -+ -+struct sun8i_mixer; -+struct drm_plane; -+ -+bool sun50i_afbc_format_mod_supported(struct sun8i_mixer *mixer, -+ u32 format, u64 modifier); -+ -+void sun50i_afbc_atomic_update(struct sun8i_mixer *mixer, unsigned int channel, -+ struct drm_plane *plane); -+void sun50i_afbc_disable(struct sun8i_mixer *mixer, unsigned int channel); -+ -+#endif -diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c -index d19349eecc9de..84f8917e2dd87 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c -+++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c -@@ -11,8 +11,10 @@ - #include - #include - #include -+#include - #include - -+#include "sun50i_afbc.h" - #include "sun8i_csc.h" - #include "sun8i_mixer.h" - #include "sun8i_vi_layer.h" -@@ -50,7 +52,7 @@ static void sun8i_vi_layer_update_alpha(struct sun8i_mixer *mixer, int channel, - - static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel, - int overlay, struct drm_plane *plane, -- unsigned int zpos) -+ unsigned int zpos, bool afbc) - { - struct drm_plane_state *state = plane->state; - const struct drm_format_info *format = state->fb->format; -@@ -135,7 +137,7 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel, - - required = src_h * 100 / dst_h; - -- if (ability < required) { -+ if (!afbc && ability < required) { - DRM_DEBUG_DRIVER("Using vertical coarse scaling\n"); - vm = src_h; - vn = (u32)ability * dst_h / 100; -@@ -145,7 +147,7 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel, - /* it seems that every RGB scaler has buffer for 2048 pixels */ - scanline = subsampled ? mixer->cfg->scanline_yuv : 2048; - -- if (src_w > scanline) { -+ if (!afbc && src_w > scanline) { - DRM_DEBUG_DRIVER("Using horizontal coarse scaling\n"); - hm = src_w; - hn = scanline; -@@ -308,6 +310,15 @@ static int sun8i_vi_layer_update_buffer(struct sun8i_mixer *mixer, int channel, - return 0; - } - -+static void sun8i_vi_layer_prepare_non_linear(struct sun8i_mixer *mixer, -+ int channel, int overlay) -+{ -+ u32 base = sun8i_channel_base(mixer, channel); -+ -+ regmap_write(mixer->engine.regs, -+ SUN8I_MIXER_CHAN_VI_LAYER_ATTR(base, overlay), 0); -+} -+ - static int sun8i_vi_layer_atomic_check(struct drm_plane *plane, - struct drm_atomic_state *state) - { -@@ -348,18 +359,45 @@ static void sun8i_vi_layer_atomic_update(struct drm_plane *plane, - struct sun8i_layer *layer = plane_to_sun8i_layer(plane); - unsigned int zpos = new_state->normalized_zpos; - struct sun8i_mixer *mixer = layer->mixer; -+ struct drm_framebuffer *fb = plane->state->fb; -+ bool afbc = drm_is_afbc(fb->modifier); - -- if (!new_state->crtc || !new_state->visible) -+ if (!new_state->crtc || !new_state->visible) { -+ if (mixer->cfg->de_type >= sun8i_mixer_de3) -+ sun50i_afbc_disable(mixer, layer->channel); - return; -+ } - - sun8i_vi_layer_update_coord(mixer, layer->channel, -- layer->overlay, plane, zpos); -- sun8i_vi_layer_update_alpha(mixer, layer->channel, -- layer->overlay, plane); -- sun8i_vi_layer_update_formats(mixer, layer->channel, -- layer->overlay, plane); -- sun8i_vi_layer_update_buffer(mixer, layer->channel, -- layer->overlay, plane); -+ layer->overlay, plane, zpos, afbc); -+ -+ if (afbc) { -+ u32 fmt_type; -+ -+ sun8i_vi_layer_prepare_non_linear(mixer, layer->channel, -+ layer->overlay); -+ sun50i_afbc_atomic_update(mixer, layer->channel, plane); -+ -+ fmt_type = sun8i_vi_layer_get_format_type(fb->format); -+ sun8i_csc_set_ccsc(mixer, layer->channel, fmt_type, -+ plane->state->color_encoding, -+ plane->state->color_range); -+ } else { -+ sun8i_vi_layer_update_alpha(mixer, layer->channel, -+ layer->overlay, plane); -+ sun8i_vi_layer_update_formats(mixer, layer->channel, -+ layer->overlay, plane); -+ sun8i_vi_layer_update_buffer(mixer, layer->channel, -+ layer->overlay, plane); -+ } -+} -+ -+static bool sun8i_vi_layer_format_mod_supported(struct drm_plane *plane, -+ u32 format, u64 modifier) -+{ -+ struct sun8i_layer *layer = plane_to_sun8i_layer(plane); -+ -+ return sun50i_afbc_format_mod_supported(layer->mixer, format, modifier); - } - - static const struct drm_plane_helper_funcs sun8i_vi_layer_helper_funcs = { -@@ -374,6 +412,7 @@ static const struct drm_plane_funcs sun8i_vi_layer_funcs = { - .disable_plane = drm_atomic_helper_disable_plane, - .reset = drm_atomic_helper_plane_reset, - .update_plane = drm_atomic_helper_update_plane, -+ .format_mod_supported = sun8i_vi_layer_format_mod_supported, - }; - - /* -@@ -457,6 +496,11 @@ static const u32 sun8i_vi_layer_de3_formats[] = { - DRM_FORMAT_YVU411, - DRM_FORMAT_YVU420, - DRM_FORMAT_YVU422, -+ -+ /* AFBC only formats */ -+ DRM_FORMAT_YUV420_8BIT, -+ DRM_FORMAT_YUV420_10BIT, -+ DRM_FORMAT_Y210, - }; - - static const uint64_t sun8i_layer_modifiers[] = { -@@ -464,6 +508,18 @@ static const uint64_t sun8i_layer_modifiers[] = { - DRM_FORMAT_MOD_INVALID - }; - -+static const uint64_t sun50i_layer_de3_modifiers[] = { -+ DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | -+ AFBC_FORMAT_MOD_SPARSE | -+ AFBC_FORMAT_MOD_SPLIT), -+ DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | -+ AFBC_FORMAT_MOD_YTR | -+ AFBC_FORMAT_MOD_SPARSE | -+ AFBC_FORMAT_MOD_SPLIT), -+ DRM_FORMAT_MOD_LINEAR, -+ DRM_FORMAT_MOD_INVALID -+}; -+ - struct sun8i_layer *sun8i_vi_layer_init_one(struct drm_device *drm, - struct sun8i_mixer *mixer, - int index) -@@ -472,6 +528,7 @@ struct sun8i_layer *sun8i_vi_layer_init_one(struct drm_device *drm, - u32 supported_encodings, supported_ranges; - unsigned int plane_cnt, format_count; - struct sun8i_layer *layer; -+ const uint64_t *modifiers; - const u32 *formats; - int ret; - -@@ -487,9 +544,11 @@ struct sun8i_layer *sun8i_vi_layer_init_one(struct drm_device *drm, - if (mixer->cfg->de_type >= sun8i_mixer_de3) { - formats = sun8i_vi_layer_de3_formats; - format_count = ARRAY_SIZE(sun8i_vi_layer_de3_formats); -+ modifiers = sun50i_layer_de3_modifiers; - } else { - formats = sun8i_vi_layer_formats; - format_count = ARRAY_SIZE(sun8i_vi_layer_formats); -+ modifiers = sun8i_layer_modifiers; - } - - if (!mixer->cfg->ui_num && index == 0) -@@ -499,8 +558,7 @@ struct sun8i_layer *sun8i_vi_layer_init_one(struct drm_device *drm, - ret = drm_universal_plane_init(drm, &layer->plane, 0, - &sun8i_vi_layer_funcs, - formats, format_count, -- sun8i_layer_modifiers, -- type, NULL); -+ modifiers, type, NULL); - if (ret) { - dev_err(drm->dev, "Couldn't initialize layer\n"); - return ERR_PTR(ret); --- -2.46.1 - -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH v5 19/26] dt-bindings: allwinner: add H616 DE33 bus binding -From: Ryan Walklin -Date: Sun, 29 Sep 2024 22:04:51 +1300 -Message-Id: <20240929091107.838023-20-ryan@testtoast.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -The Allwinner H616 and variants have a new display engine revision -(DE33). - -Add a display engine bus binding for the DE33. - -Signed-off-by: Ryan Walklin -Acked-by: Conor Dooley -Reviewed-by: Chen-Yu Tsai ---- -Changelog v1..v2: -- Correct DE2 bus enum to reflect fallback devices accurately. - -Changelog v2..v3: -- Separate content into three patches for three separate subsystems ---- - .../devicetree/bindings/bus/allwinner,sun50i-a64-de2.yaml | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/Documentation/devicetree/bindings/bus/allwinner,sun50i-a64-de2.yaml b/Documentation/devicetree/bindings/bus/allwinner,sun50i-a64-de2.yaml -index 9845a187bdf65..ea7ee89158c61 100644 ---- a/Documentation/devicetree/bindings/bus/allwinner,sun50i-a64-de2.yaml -+++ b/Documentation/devicetree/bindings/bus/allwinner,sun50i-a64-de2.yaml -@@ -24,7 +24,9 @@ properties: - oneOf: - - const: allwinner,sun50i-a64-de2 - - items: -- - const: allwinner,sun50i-h6-de3 -+ - enum: -+ - allwinner,sun50i-h6-de3 -+ - allwinner,sun50i-h616-de33 - - const: allwinner,sun50i-a64-de2 - - reg: --- -2.46.1 - -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH v5 20/26] dt-bindings: allwinner: add H616 DE33 clock - binding -From: Ryan Walklin -Date: Sun, 29 Sep 2024 22:04:52 +1300 -Message-Id: <20240929091107.838023-21-ryan@testtoast.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -The Allwinner H616 and variants have a new display engine revision -(DE33). - -Add a clock binding for the DE33. - -Signed-off-by: Ryan Walklin -Acked-by: Conor Dooley -Reviewed-by: Chen-Yu Tsai ---- -Changelog v2..v3: -- Separate content into three patches for three separate subsystems ---- - .../devicetree/bindings/clock/allwinner,sun8i-a83t-de2-clk.yaml | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/Documentation/devicetree/bindings/clock/allwinner,sun8i-a83t-de2-clk.yaml b/Documentation/devicetree/bindings/clock/allwinner,sun8i-a83t-de2-clk.yaml -index 70369bd633e40..7fcd55d468d49 100644 ---- a/Documentation/devicetree/bindings/clock/allwinner,sun8i-a83t-de2-clk.yaml -+++ b/Documentation/devicetree/bindings/clock/allwinner,sun8i-a83t-de2-clk.yaml -@@ -25,6 +25,7 @@ properties: - - const: allwinner,sun50i-a64-de2-clk - - const: allwinner,sun50i-h5-de2-clk - - const: allwinner,sun50i-h6-de3-clk -+ - const: allwinner,sun50i-h616-de33-clk - - items: - - const: allwinner,sun8i-r40-de2-clk - - const: allwinner,sun8i-h3-de2-clk --- -2.46.1 - -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH v5 21/26] dt-bindings: allwinner: add H616 DE33 mixer - binding -From: Ryan Walklin -Date: Sun, 29 Sep 2024 22:04:53 +1300 -Message-Id: <20240929091107.838023-22-ryan@testtoast.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -The Allwinner H616 and variants have a new display engine revision -(DE33). - -The mixer configuration registers are significantly different to the DE3 -and DE2 revisions, being split into separate top and display blocks, -therefore a fallback for the mixer compatible is not provided. - -Add a display engine mixer binding for the DE33. - -Signed-off-by: Ryan Walklin -Acked-by: Conor Dooley -Reviewed-by: Chen-Yu Tsai ---- -Changelog v2..v3: -- Separate content into three patches for three separate subsystems ---- - .../bindings/display/allwinner,sun8i-a83t-de2-mixer.yaml | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/Documentation/devicetree/bindings/display/allwinner,sun8i-a83t-de2-mixer.yaml b/Documentation/devicetree/bindings/display/allwinner,sun8i-a83t-de2-mixer.yaml -index b75c1ec686ad2..c37eb8ae1b8ee 100644 ---- a/Documentation/devicetree/bindings/display/allwinner,sun8i-a83t-de2-mixer.yaml -+++ b/Documentation/devicetree/bindings/display/allwinner,sun8i-a83t-de2-mixer.yaml -@@ -24,6 +24,7 @@ properties: - - allwinner,sun50i-a64-de2-mixer-0 - - allwinner,sun50i-a64-de2-mixer-1 - - allwinner,sun50i-h6-de3-mixer-0 -+ - allwinner,sun50i-h616-de33-mixer-0 - - reg: - maxItems: 1 --- -2.46.1 - -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH v5 22/26] clk: sunxi-ng: ccu: add Display Engine 3.3 (DE33) - support -From: Ryan Walklin -Date: Sun, 29 Sep 2024 22:04:54 +1300 -Message-Id: <20240929091107.838023-23-ryan@testtoast.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -The DE33 is a newer version of the Allwinner Display Engine IP block, -found in the H616, H618, H700 and T507 SoCs. DE2 and DE3 are already -supported by the mainline driver. - -The DE33 in the H616 has mixer0 and writeback units. The clocks -and resets required are identical to the H3 and H5 respectively, so use -those existing structs for the H616 description. - -There are two additional 32-bit registers (at offsets 0x24 and 0x28) -which require clearing and setting respectively to bring up the -hardware. The function of these registers is currently unknown, and the -values are taken from the out-of-tree driver. - -Add the required clock description struct and compatible string to the -DE2 driver. - -Signed-off-by: Ryan Walklin ---- -Changelog v2..v3: -- Lowercase hex value - -Changelog v2..v3: -- Correct #include for writel() - -Changelog v4..v5: -- Whitespace fix ---- - drivers/clk/sunxi-ng/ccu-sun8i-de2.c | 25 +++++++++++++++++++++++++ - 1 file changed, 25 insertions(+) - -diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c -index 7683ea08d8e30..83eab6f132aad 100644 ---- a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c -+++ b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c -@@ -5,6 +5,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -239,6 +240,16 @@ static const struct sunxi_ccu_desc sun50i_h5_de2_clk_desc = { - .num_resets = ARRAY_SIZE(sun50i_h5_de2_resets), - }; - -+static const struct sunxi_ccu_desc sun50i_h616_de33_clk_desc = { -+ .ccu_clks = sun8i_de2_ccu_clks, -+ .num_ccu_clks = ARRAY_SIZE(sun8i_de2_ccu_clks), -+ -+ .hw_clks = &sun8i_h3_de2_hw_clks, -+ -+ .resets = sun50i_h5_de2_resets, -+ .num_resets = ARRAY_SIZE(sun50i_h5_de2_resets), -+}; -+ - static int sunxi_de2_clk_probe(struct platform_device *pdev) - { - struct clk *bus_clk, *mod_clk; -@@ -291,6 +302,16 @@ static int sunxi_de2_clk_probe(struct platform_device *pdev) - goto err_disable_mod_clk; - } - -+ /* -+ * The DE33 requires these additional (unknown) registers set -+ * during initialisation. -+ */ -+ if (of_device_is_compatible(pdev->dev.of_node, -+ "allwinner,sun50i-h616-de33-clk")) { -+ writel(0, reg + 0x24); -+ writel(0x0000a980, reg + 0x28); -+ } -+ - ret = devm_sunxi_ccu_probe(&pdev->dev, reg, ccu_desc); - if (ret) - goto err_assert_reset; -@@ -335,6 +356,10 @@ static const struct of_device_id sunxi_de2_clk_ids[] = { - .compatible = "allwinner,sun50i-h6-de3-clk", - .data = &sun50i_h5_de2_clk_desc, - }, -+ { -+ .compatible = "allwinner,sun50i-h616-de33-clk", -+ .data = &sun50i_h616_de33_clk_desc, -+ }, - { } - }; - MODULE_DEVICE_TABLE(of, sunxi_de2_clk_ids); --- -2.46.1 - -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH v5 23/26] drm: sun4i: de33: mixer: add Display Engine 3.3 - (DE33) support -From: Jernej Skrabec -Date: Sun, 29 Sep 2024 22:04:55 +1300 -Message-Id: <20240929091107.838023-24-ryan@testtoast.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -The DE33 is a newer version of the Allwinner Display Engine IP block, -found in the H616, H618, H700 and T507 SoCs. DE2 and DE3 are already -supported by the mainline driver. - -Notable features (from the H616 datasheet and implemented): -- 4096 x 2048 (4K) output support -- AFBC ARM Frame Buffer Compression support -- YUV420 input support - -The DE2 and DE3 engines have a blender register range within the -mixer engine register map, whereas the DE33 separates this out into -a separate display group, and adds a top register map. - -Extend the mixer to support the DE33. - -Signed-off-by: Jernej Skrabec -Signed-off-by: Ryan Walklin ---- -Changelog v4..v5: -- Whitespace fixes -- Correct strict mode warnings from checkpatch.pl ---- - drivers/gpu/drm/sun4i/sun8i_mixer.c | 109 ++++++++++++++++++++++++---- - drivers/gpu/drm/sun4i/sun8i_mixer.h | 16 +++- - 2 files changed, 108 insertions(+), 17 deletions(-) - -diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c -index 600084286b39d..204fc8055b32a 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_mixer.c -+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c -@@ -321,8 +321,12 @@ static void sun8i_mixer_commit(struct sunxi_engine *engine, - regmap_write(bld_regs, SUN8I_MIXER_BLEND_PIPE_CTL(bld_base), - pipe_en | SUN8I_MIXER_BLEND_PIPE_CTL_FC_EN(0)); - -- regmap_write(engine->regs, SUN8I_MIXER_GLOBAL_DBUFF, -- SUN8I_MIXER_GLOBAL_DBUFF_ENABLE); -+ if (mixer->cfg->de_type == sun8i_mixer_de33) -+ regmap_write(mixer->top_regs, SUN50I_MIXER_GLOBAL_DBUFF, -+ SUN8I_MIXER_GLOBAL_DBUFF_ENABLE); -+ else -+ regmap_write(engine->regs, SUN8I_MIXER_GLOBAL_DBUFF, -+ SUN8I_MIXER_GLOBAL_DBUFF_ENABLE); - } - - static struct drm_plane **sun8i_layers_init(struct drm_device *drm, -@@ -371,25 +375,33 @@ static void sun8i_mixer_mode_set(struct sunxi_engine *engine, - const struct drm_display_mode *mode) - { - struct sun8i_mixer *mixer = engine_to_sun8i_mixer(engine); -+ struct regmap *bld_regs, *disp_regs; - u32 bld_base, size, val; - bool interlaced; - - bld_base = sun8i_blender_base(mixer); -+ bld_regs = sun8i_blender_regmap(mixer); - interlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE); - size = SUN8I_MIXER_SIZE(mode->hdisplay, mode->vdisplay); - - DRM_DEBUG_DRIVER("Updating global size W: %u H: %u\n", - mode->hdisplay, mode->vdisplay); - -- regmap_write(engine->regs, SUN8I_MIXER_GLOBAL_SIZE, size); -- regmap_write(engine->regs, SUN8I_MIXER_BLEND_OUTSIZE(bld_base), size); -+ if (mixer->cfg->de_type == sun8i_mixer_de33) { -+ disp_regs = mixer->disp_regs; -+ regmap_write(mixer->top_regs, SUN50I_MIXER_GLOBAL_SIZE, size); -+ } else { -+ disp_regs = mixer->engine.regs; -+ regmap_write(mixer->engine.regs, SUN8I_MIXER_GLOBAL_SIZE, size); -+ } -+ regmap_write(bld_regs, SUN8I_MIXER_BLEND_OUTSIZE(bld_base), size); - - if (interlaced) - val = SUN8I_MIXER_BLEND_OUTCTL_INTERLACED; - else - val = 0; - -- regmap_update_bits(engine->regs, SUN8I_MIXER_BLEND_OUTCTL(bld_base), -+ regmap_update_bits(bld_regs, SUN8I_MIXER_BLEND_OUTCTL(bld_base), - SUN8I_MIXER_BLEND_OUTCTL_INTERLACED, val); - - DRM_DEBUG_DRIVER("Switching display mixer interlaced mode %s\n", -@@ -400,10 +412,8 @@ static void sun8i_mixer_mode_set(struct sunxi_engine *engine, - else - val = 0xff108080; - -- regmap_write(mixer->engine.regs, -- SUN8I_MIXER_BLEND_BKCOLOR(bld_base), val); -- regmap_write(mixer->engine.regs, -- SUN8I_MIXER_BLEND_ATTR_FCOLOR(bld_base, 0), val); -+ regmap_write(disp_regs, SUN8I_MIXER_BLEND_BKCOLOR(bld_base), val); -+ regmap_write(disp_regs, SUN8I_MIXER_BLEND_ATTR_FCOLOR(bld_base, 0), val); - - if (mixer->cfg->has_formatter) - sun50i_fmt_setup(mixer, mode->hdisplay, -@@ -443,12 +453,29 @@ static const struct sunxi_engine_ops sun8i_engine_ops = { - }; - - static const struct regmap_config sun8i_mixer_regmap_config = { -+ .name = "layers", - .reg_bits = 32, - .val_bits = 32, - .reg_stride = 4, - .max_register = 0xffffc, /* guessed */ - }; - -+static const struct regmap_config sun8i_top_regmap_config = { -+ .name = "top", -+ .reg_bits = 32, -+ .val_bits = 32, -+ .reg_stride = 4, -+ .max_register = 0x3c, -+}; -+ -+static const struct regmap_config sun8i_disp_regmap_config = { -+ .name = "display", -+ .reg_bits = 32, -+ .val_bits = 32, -+ .reg_stride = 4, -+ .max_register = 0x20000, -+}; -+ - static int sun8i_mixer_of_get_id(struct device_node *node) - { - struct device_node *ep, *remote; -@@ -471,33 +498,45 @@ static int sun8i_mixer_of_get_id(struct device_node *node) - - static void sun8i_mixer_init(struct sun8i_mixer *mixer) - { -+ struct regmap *top_regs, *disp_regs; - unsigned int base = sun8i_blender_base(mixer); - int plane_cnt, i; - -+ if (mixer->cfg->de_type == sun8i_mixer_de33) { -+ top_regs = mixer->top_regs; -+ disp_regs = mixer->disp_regs; -+ } else { -+ top_regs = mixer->engine.regs; -+ disp_regs = mixer->engine.regs; -+ } -+ - /* Enable the mixer */ -- regmap_write(mixer->engine.regs, SUN8I_MIXER_GLOBAL_CTL, -+ regmap_write(top_regs, SUN8I_MIXER_GLOBAL_CTL, - SUN8I_MIXER_GLOBAL_CTL_RT_EN); - -+ if (mixer->cfg->de_type == sun8i_mixer_de33) -+ regmap_write(top_regs, SUN50I_MIXER_GLOBAL_CLK, 1); -+ - /* Set background color to black */ -- regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_BKCOLOR(base), -+ regmap_write(disp_regs, SUN8I_MIXER_BLEND_BKCOLOR(base), - SUN8I_MIXER_BLEND_COLOR_BLACK); - - /* - * Set fill color of bottom plane to black. Generally not needed - * except when VI plane is at bottom (zpos = 0) and enabled. - */ -- regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(base), -+ regmap_write(disp_regs, SUN8I_MIXER_BLEND_PIPE_CTL(base), - SUN8I_MIXER_BLEND_PIPE_CTL_FC_EN(0)); -- regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ATTR_FCOLOR(base, 0), -+ regmap_write(disp_regs, SUN8I_MIXER_BLEND_ATTR_FCOLOR(base, 0), - SUN8I_MIXER_BLEND_COLOR_BLACK); - - plane_cnt = mixer->cfg->vi_num + mixer->cfg->ui_num; - for (i = 0; i < plane_cnt; i++) -- regmap_write(mixer->engine.regs, -+ regmap_write(disp_regs, - SUN8I_MIXER_BLEND_MODE(base, i), - SUN8I_MIXER_BLEND_MODE_DEF); - -- regmap_update_bits(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(base), -+ regmap_update_bits(disp_regs, SUN8I_MIXER_BLEND_PIPE_CTL(base), - SUN8I_MIXER_BLEND_PIPE_CTL_EN_MSK, 0); - } - -@@ -573,6 +612,30 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master, - return PTR_ERR(mixer->engine.regs); - } - -+ if (mixer->cfg->de_type == sun8i_mixer_de33) { -+ regs = devm_platform_ioremap_resource(pdev, 1); -+ if (IS_ERR(regs)) -+ return PTR_ERR(regs); -+ -+ mixer->top_regs = devm_regmap_init_mmio(dev, regs, -+ &sun8i_top_regmap_config); -+ if (IS_ERR(mixer->top_regs)) { -+ dev_err(dev, "Couldn't create the top regmap\n"); -+ return PTR_ERR(mixer->top_regs); -+ } -+ -+ regs = devm_platform_ioremap_resource(pdev, 2); -+ if (IS_ERR(regs)) -+ return PTR_ERR(regs); -+ -+ mixer->disp_regs = devm_regmap_init_mmio(dev, regs, -+ &sun8i_disp_regmap_config); -+ if (IS_ERR(mixer->disp_regs)) { -+ dev_err(dev, "Couldn't create the disp regmap\n"); -+ return PTR_ERR(mixer->disp_regs); -+ } -+ } -+ - mixer->reset = devm_reset_control_get(dev, NULL); - if (IS_ERR(mixer->reset)) { - dev_err(dev, "Couldn't get our reset line\n"); -@@ -787,6 +850,18 @@ static const struct sun8i_mixer_cfg sun50i_h6_mixer0_cfg = { - .vi_num = 1, - }; - -+static const struct sun8i_mixer_cfg sun50i_h616_mixer0_cfg = { -+ .ccsc = CCSC_MIXER0_LAYOUT, -+ .de_type = sun8i_mixer_de33, -+ .has_formatter = 1, -+ .mod_rate = 600000000, -+ .scaler_mask = 0xf, -+ .scanline_yuv = 4096, -+ .ui_num = 3, -+ .vi_num = 1, -+ .map = {0, 6, 7, 8}, -+}; -+ - static const struct of_device_id sun8i_mixer_of_table[] = { - { - .compatible = "allwinner,sun8i-a83t-de2-mixer-0", -@@ -832,6 +907,10 @@ static const struct of_device_id sun8i_mixer_of_table[] = { - .compatible = "allwinner,sun50i-h6-de3-mixer-0", - .data = &sun50i_h6_mixer0_cfg, - }, -+ { -+ .compatible = "allwinner,sun50i-h616-de33-mixer-0", -+ .data = &sun50i_h616_mixer0_cfg, -+ }, - { } - }; - MODULE_DEVICE_TABLE(of, sun8i_mixer_of_table); -diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h -index 75facc7d1fa66..26b001164647c 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_mixer.h -+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h -@@ -21,6 +21,10 @@ - #define SUN8I_MIXER_GLOBAL_DBUFF 0x8 - #define SUN8I_MIXER_GLOBAL_SIZE 0xc - -+#define SUN50I_MIXER_GLOBAL_SIZE 0x8 -+#define SUN50I_MIXER_GLOBAL_CLK 0xc -+#define SUN50I_MIXER_GLOBAL_DBUFF 0x10 -+ - #define SUN8I_MIXER_GLOBAL_CTL_RT_EN BIT(0) - - #define SUN8I_MIXER_GLOBAL_DBUFF_ENABLE BIT(0) -@@ -154,6 +158,7 @@ enum { - enum sun8i_mixer_type { - sun8i_mixer_de2, - sun8i_mixer_de3, -+ sun8i_mixer_de33, - }; - - /** -@@ -180,6 +185,7 @@ struct sun8i_mixer_cfg { - unsigned int de_type; - unsigned int has_formatter : 1; - unsigned int scanline_yuv; -+ unsigned int map[6]; - }; - - struct sun8i_mixer { -@@ -191,6 +197,9 @@ struct sun8i_mixer { - - struct clk *bus_clk; - struct clk *mod_clk; -+ -+ struct regmap *top_regs; -+ struct regmap *disp_regs; - }; - - enum { -@@ -227,13 +236,16 @@ sun8i_blender_base(struct sun8i_mixer *mixer) - static inline struct regmap * - sun8i_blender_regmap(struct sun8i_mixer *mixer) - { -- return mixer->engine.regs; -+ return mixer->cfg->de_type == sun8i_mixer_de33 ? -+ mixer->disp_regs : mixer->engine.regs; - } - - static inline u32 - sun8i_channel_base(struct sun8i_mixer *mixer, int channel) - { -- if (mixer->cfg->de_type == sun8i_mixer_de3) -+ if (mixer->cfg->de_type == sun8i_mixer_de33) -+ return mixer->cfg->map[channel] * 0x20000 + DE2_CH_SIZE; -+ else if (mixer->cfg->de_type == sun8i_mixer_de3) - return DE3_CH_BASE + channel * DE3_CH_SIZE; - else - return DE2_CH_BASE + channel * DE2_CH_SIZE; --- -2.46.1 - -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH v5 24/26] drm: sun4i: de33: vi_scaler: add Display Engine - 3.3 (DE33) support -From: Jernej Skrabec -Date: Sun, 29 Sep 2024 22:04:56 +1300 -Message-Id: <20240929091107.838023-25-ryan@testtoast.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -The vi_scaler appears to be used in preference to the ui_scaler module -for hardware video scaling in the DE33. - -Enable support for this scaler. - -Signed-off-by: Jernej Skrabec -Signed-off-by: Ryan Walklin -Reviewed-by: Chen-Yu Tsai -Acked-by: Conor Dooley -Reviewed-by: Andre Przywara ---- - drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 19 +++++++++++++++---- - drivers/gpu/drm/sun4i/sun8i_vi_scaler.c | 7 ++++++- - 2 files changed, 21 insertions(+), 5 deletions(-) - -diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c -index 7f1231cf0f012..180be9d67d9c3 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c -+++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c -@@ -95,12 +95,23 @@ static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel, - hscale = state->src_w / state->crtc_w; - vscale = state->src_h / state->crtc_h; - -- sun8i_ui_scaler_setup(mixer, channel, src_w, src_h, dst_w, -- dst_h, hscale, vscale, hphase, vphase); -- sun8i_ui_scaler_enable(mixer, channel, true); -+ if (mixer->cfg->de_type == sun8i_mixer_de33) { -+ sun8i_vi_scaler_setup(mixer, channel, src_w, src_h, -+ dst_w, dst_h, hscale, vscale, -+ hphase, vphase, -+ state->fb->format); -+ } else { -+ sun8i_ui_scaler_setup(mixer, channel, src_w, src_h, -+ dst_w, dst_h, hscale, vscale, -+ hphase, vphase); -+ sun8i_ui_scaler_enable(mixer, channel, true); -+ } - } else { - DRM_DEBUG_DRIVER("HW scaling is not needed\n"); -- sun8i_ui_scaler_enable(mixer, channel, false); -+ if (mixer->cfg->de_type == sun8i_mixer_de33) -+ sun8i_vi_scaler_disable(mixer, channel); -+ else -+ sun8i_ui_scaler_enable(mixer, channel, false); - } - - /* Set base coordinates */ -diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c -index e7242301b312c..9c7f6e7d71d50 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c -+++ b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c -@@ -835,7 +835,9 @@ static const u32 bicubic4coefftab32[480] = { - - static u32 sun8i_vi_scaler_base(struct sun8i_mixer *mixer, int channel) - { -- if (mixer->cfg->de_type == sun8i_mixer_de3) -+ if (mixer->cfg->de_type == sun8i_mixer_de33) -+ return sun8i_channel_base(mixer, channel) + 0x3000; -+ else if (mixer->cfg->de_type == sun8i_mixer_de3) - return DE3_VI_SCALER_UNIT_BASE + - DE3_VI_SCALER_UNIT_SIZE * channel; - else -@@ -845,6 +847,9 @@ static u32 sun8i_vi_scaler_base(struct sun8i_mixer *mixer, int channel) - - static bool sun8i_vi_scaler_is_vi_plane(struct sun8i_mixer *mixer, int channel) - { -+ if (mixer->cfg->de_type == sun8i_mixer_de33) -+ return mixer->cfg->map[channel] < mixer->cfg->vi_num; -+ - return true; - } - --- -2.46.1 - -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH v5 25/26] drm: sun4i: de33: fmt: add Display Engine 3.3 - (DE33) support -From: Jernej Skrabec -Date: Sun, 29 Sep 2024 22:04:57 +1300 -Message-Id: <20240929091107.838023-26-ryan@testtoast.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -Like the DE3, the DE33 has a FMT (formatter) module, which -provides YUV444 to YUV422/YUV420 conversion, format re-mapping and color -depth conversion, although the DE33 module appears significantly more -capable, including up to 4K video support. - -Add support for the DE33. - -Signed-off-by: Jernej Skrabec -Signed-off-by: Ryan Walklin -Reviewed-by: Chen-Yu Tsai -Acked-by: Conor Dooley -Reviewed-by: Andre Przywara ---- - drivers/gpu/drm/sun4i/sun50i_fmt.c | 21 +++++++++++++++++++-- - drivers/gpu/drm/sun4i/sun50i_fmt.h | 1 + - 2 files changed, 20 insertions(+), 2 deletions(-) - -diff --git a/drivers/gpu/drm/sun4i/sun50i_fmt.c b/drivers/gpu/drm/sun4i/sun50i_fmt.c -index 050a8716ae862..39682d4e6d208 100644 ---- a/drivers/gpu/drm/sun4i/sun50i_fmt.c -+++ b/drivers/gpu/drm/sun4i/sun50i_fmt.c -@@ -51,6 +51,19 @@ static void sun50i_fmt_de3_limits(u32 *limits, u32 colorspace, bool bit10) - } - } - -+static void sun50i_fmt_de33_limits(u32 *limits, u32 colorspace) -+{ -+ if (colorspace == SUN50I_FMT_CS_YUV444RGB) { -+ limits[0] = SUN50I_FMT_LIMIT(0, 4095); -+ limits[1] = SUN50I_FMT_LIMIT(0, 4095); -+ limits[2] = SUN50I_FMT_LIMIT(0, 4095); -+ } else { -+ limits[0] = SUN50I_FMT_LIMIT(256, 3840); -+ limits[1] = SUN50I_FMT_LIMIT(256, 3840); -+ limits[2] = SUN50I_FMT_LIMIT(256, 3840); -+ } -+} -+ - void sun50i_fmt_setup(struct sun8i_mixer *mixer, u16 width, - u16 height, u32 format) - { -@@ -60,10 +73,14 @@ void sun50i_fmt_setup(struct sun8i_mixer *mixer, u16 width, - - colorspace = sun50i_fmt_get_colorspace(format); - bit10 = sun50i_fmt_is_10bit(format); -- base = SUN50I_FMT_DE3; -+ base = mixer->cfg->de_type == sun8i_mixer_de3 ? -+ SUN50I_FMT_DE3 : SUN50I_FMT_DE33; - regs = sun8i_blender_regmap(mixer); - -- sun50i_fmt_de3_limits(limit, colorspace, bit10); -+ if (mixer->cfg->de_type == sun8i_mixer_de3) -+ sun50i_fmt_de3_limits(limit, colorspace, bit10); -+ else -+ sun50i_fmt_de33_limits(limit, colorspace); - - regmap_write(regs, SUN50I_FMT_CTRL(base), 0); - -diff --git a/drivers/gpu/drm/sun4i/sun50i_fmt.h b/drivers/gpu/drm/sun4i/sun50i_fmt.h -index 4127f7206aade..3e60d5c788b39 100644 ---- a/drivers/gpu/drm/sun4i/sun50i_fmt.h -+++ b/drivers/gpu/drm/sun4i/sun50i_fmt.h -@@ -9,6 +9,7 @@ - #include "sun8i_mixer.h" - - #define SUN50I_FMT_DE3 0xa8000 -+#define SUN50I_FMT_DE33 0x5000 - - #define SUN50I_FMT_CTRL(base) ((base) + 0x00) - #define SUN50I_FMT_SIZE(base) ((base) + 0x04) --- -2.46.1 - -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH v5 26/26] drm: sun4i: de33: csc: add Display Engine 3.3 - (DE33) support -From: Jernej Skrabec -Date: Sun, 29 Sep 2024 22:04:58 +1300 -Message-Id: <20240929091107.838023-27-ryan@testtoast.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -Like earlier DE versions, the DE33 has a CSC (Color Space Correction) -module. which provides color space conversion between BT2020/BT709, and -dynamic range conversion between SDR/ST2084/HLG. - -Add support for the DE33. - -Signed-off-by: Jernej Skrabec -Signed-off-by: Ryan Walklin -Reviewed-by: Chen-Yu Tsai -Acked-by: Conor Dooley -Reviewed-by: Andre Przywara ---- - drivers/gpu/drm/sun4i/sun8i_csc.c | 96 +++++++++++++++++++++++++++++++ - drivers/gpu/drm/sun4i/sun8i_csc.h | 3 + - 2 files changed, 99 insertions(+) - -diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c b/drivers/gpu/drm/sun4i/sun8i_csc.c -index 2d5a2cf7cba24..45bd1ca06400e 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_csc.c -+++ b/drivers/gpu/drm/sun4i/sun8i_csc.c -@@ -238,6 +238,14 @@ static const u32 yuv2yuv_de3[2][3][3][12] = { - }, - }; - -+static u32 sun8i_csc_base(struct sun8i_mixer *mixer, int layer) -+{ -+ if (mixer->cfg->de_type == sun8i_mixer_de33) -+ return sun8i_channel_base(mixer, layer) - 0x800; -+ else -+ return ccsc_base[mixer->cfg->ccsc][layer]; -+} -+ - static void sun8i_csc_setup(struct regmap *map, u32 base, - enum format_type fmt_type, - enum drm_color_encoding encoding, -@@ -358,6 +366,90 @@ static void sun8i_de3_ccsc_setup(struct sunxi_engine *engine, int layer, - mask, val); - } - -+/* extract constant from high word and invert sign if necessary */ -+static u32 sun8i_de33_ccsc_get_constant(u32 value) -+{ -+ value >>= 16; -+ -+ if (value & BIT(15)) -+ return 0x400 - (value & 0x3ff); -+ -+ return value; -+} -+ -+static void sun8i_de33_convert_table(const u32 *src, u32 *dst) -+{ -+ dst[0] = sun8i_de33_ccsc_get_constant(src[3]); -+ dst[1] = sun8i_de33_ccsc_get_constant(src[7]); -+ dst[2] = sun8i_de33_ccsc_get_constant(src[11]); -+ memcpy(&dst[3], src, sizeof(u32) * 12); -+ dst[6] &= 0xffff; -+ dst[10] &= 0xffff; -+ dst[14] &= 0xffff; -+} -+ -+static void sun8i_de33_ccsc_setup(struct sun8i_mixer *mixer, int layer, -+ enum format_type fmt_type, -+ enum drm_color_encoding encoding, -+ enum drm_color_range range) -+{ -+ u32 addr, val = 0, base, csc[15]; -+ struct sunxi_engine *engine; -+ struct regmap *map; -+ const u32 *table; -+ int i; -+ -+ table = yuv2rgb_de3[range][encoding]; -+ base = sun8i_csc_base(mixer, layer); -+ engine = &mixer->engine; -+ map = engine->regs; -+ -+ switch (fmt_type) { -+ case FORMAT_TYPE_RGB: -+ if (engine->format == MEDIA_BUS_FMT_RGB888_1X24) -+ break; -+ val = SUN8I_CSC_CTRL_EN; -+ sun8i_de33_convert_table(rgb2yuv_de3[engine->encoding], csc); -+ regmap_bulk_write(map, SUN50I_CSC_COEFF(base, 0), csc, 15); -+ break; -+ case FORMAT_TYPE_YUV: -+ table = sun8i_csc_get_de3_yuv_table(encoding, range, -+ engine->format, -+ engine->encoding); -+ if (!table) -+ break; -+ val = SUN8I_CSC_CTRL_EN; -+ sun8i_de33_convert_table(table, csc); -+ regmap_bulk_write(map, SUN50I_CSC_COEFF(base, 0), csc, 15); -+ break; -+ case FORMAT_TYPE_YVU: -+ table = sun8i_csc_get_de3_yuv_table(encoding, range, -+ engine->format, -+ engine->encoding); -+ if (!table) -+ table = yuv2yuv_de3[range][encoding][encoding]; -+ val = SUN8I_CSC_CTRL_EN; -+ sun8i_de33_convert_table(table, csc); -+ for (i = 0; i < 15; i++) { -+ addr = SUN50I_CSC_COEFF(base, i); -+ if (i > 3) { -+ if (((i - 3) & 3) == 1) -+ addr = SUN50I_CSC_COEFF(base, i + 1); -+ else if (((i - 3) & 3) == 2) -+ addr = SUN50I_CSC_COEFF(base, i - 1); -+ } -+ regmap_write(map, addr, csc[i]); -+ } -+ break; -+ default: -+ val = 0; -+ DRM_WARN("Wrong CSC mode specified.\n"); -+ return; -+ } -+ -+ regmap_write(map, SUN8I_CSC_CTRL(base), val); -+} -+ - void sun8i_csc_set_ccsc(struct sun8i_mixer *mixer, int layer, - enum format_type fmt_type, - enum drm_color_encoding encoding, -@@ -369,6 +461,10 @@ void sun8i_csc_set_ccsc(struct sun8i_mixer *mixer, int layer, - sun8i_de3_ccsc_setup(&mixer->engine, layer, - fmt_type, encoding, range); - return; -+ } else if (mixer->cfg->de_type == sun8i_mixer_de33) { -+ sun8i_de33_ccsc_setup(mixer, layer, fmt_type, -+ encoding, range); -+ return; - } - - if (layer < mixer->cfg->vi_num) { -diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.h b/drivers/gpu/drm/sun4i/sun8i_csc.h -index b7546e06e315c..2b762cb79f02c 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_csc.h -+++ b/drivers/gpu/drm/sun4i/sun8i_csc.h -@@ -20,6 +20,9 @@ struct sun8i_mixer; - #define SUN8I_CSC_CTRL(base) ((base) + 0x0) - #define SUN8I_CSC_COEFF(base, i) ((base) + 0x10 + 4 * (i)) - -+#define SUN50I_CSC_COEFF(base, i) ((base) + 0x04 + 4 * (i)) -+#define SUN50I_CSC_ALPHA(base) ((base) + 0x40) -+ - #define SUN8I_CSC_CTRL_EN BIT(0) - - enum format_type { --- -2.46.1 - diff --git a/board/anbernic/rg35xx-plus/patches/linux/0002-20240929_ryan_drm_panel_nv3052c_correct_spi_device_id_for_rg35xx_panel.patch b/board/anbernic/rg35xx-plus/patches/linux/0002-20240929_ryan_drm_panel_nv3052c_correct_spi_device_id_for_rg35xx_panel.patch deleted file mode 100644 index a4a191eff527..000000000000 --- a/board/anbernic/rg35xx-plus/patches/linux/0002-20240929_ryan_drm_panel_nv3052c_correct_spi_device_id_for_rg35xx_panel.patch +++ /dev/null @@ -1,42 +0,0 @@ -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH] drm: panel: nv3052c: correct spi_device_id for RG35XX - panel -From: Ryan Walklin -Date: Sun, 29 Sep 2024 21:19:38 +1300 -Message-Id: <20240929081940.823995-1-ryan@testtoast.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -The Anbernic RG35XX devices use an SPI LCD panel from an unknown OEM, -with an NV3052C driver chip. - -As discussed previously, the integrating vendor and device name are -preferred instead of the OEM serial. A previous patch corrected the -device tree binding and of_device_id in the NV3052C driver, however the -spi_device_id also needs correction. - -Correct the spi_device_id for the RG35XX panel. - -Signed-off-by: Ryan Walklin -Fixes: 76dce2a9 ("drm: panel: nv3052c: Correct WL-355608-A8 panel compatible") ---- - drivers/gpu/drm/panel/panel-newvision-nv3052c.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/gpu/drm/panel/panel-newvision-nv3052c.c b/drivers/gpu/drm/panel/panel-newvision-nv3052c.c -index d3baccfe6286b..06e16a7c14a75 100644 ---- a/drivers/gpu/drm/panel/panel-newvision-nv3052c.c -+++ b/drivers/gpu/drm/panel/panel-newvision-nv3052c.c -@@ -917,7 +917,7 @@ static const struct nv3052c_panel_info wl_355608_a8_panel_info = { - static const struct spi_device_id nv3052c_ids[] = { - { "ltk035c5444t", }, - { "fs035vg158", }, -- { "wl-355608-a8", }, -+ { "rg35xx-plus-panel", }, - { /* sentinel */ } - }; - MODULE_DEVICE_TABLE(spi, nv3052c_ids); --- -2.46.1 - diff --git a/board/anbernic/rg35xx-plus/patches/linux/0003-20240727_ryan_enable_LCD.patch b/board/anbernic/rg35xx-plus/patches/linux/0003-20240727_ryan_enable_LCD.patch deleted file mode 100644 index c50bc4d1ee13..000000000000 --- a/board/anbernic/rg35xx-plus/patches/linux/0003-20240727_ryan_enable_LCD.patch +++ /dev/null @@ -1,556 +0,0 @@ -From 5d7e213c4b4e67f1c4e1a63bed86ccbeb9d05953 Mon Sep 17 00:00:00 2001 -From: Ryan Walklin -Date: Sat, 27 Jul 2024 21:33:49 +1200 -Subject: [PATCH] Just stuff in all the LCD commits - -Signed-off-by: Ryan Walklin ---- - .../arm64/boot/dts/allwinner/sun50i-h616.dtsi | 220 ++++++++++++++++++ - .../sun50i-h700-anbernic-rg35xx-2024.dts | 70 ++++++ - drivers/bus/sun50i-de2.c | 1 + - drivers/clk/sunxi-ng/ccu-sun50i-h616.c | 26 +++ - drivers/clk/sunxi-ng/ccu-sun50i-h616.h | 2 +- - drivers/gpu/drm/sun4i/sun4i_tcon.c | 9 + - include/dt-bindings/clock/sun50i-h616-ccu.h | 4 + - include/dt-bindings/clock/sun8i-tcon-top.h | 2 + - include/dt-bindings/reset/sun50i-h616-ccu.h | 2 + - 9 files changed, 335 insertions(+), 1 deletion(-) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi -index b29ce7321317..6d0b49d560ab 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi -@@ -7,9 +7,12 @@ - #include - #include - #include -+#include -+#include - #include - #include - #include -+#include - - / { - interrupt-parent = <&gic>; -@@ -94,6 +97,12 @@ l2_cache: l2-cache { - }; - }; - -+ de: display-engine { -+ compatible = "allwinner,sun50i-h6-display-engine"; -+ allwinner,pipelines = <&mixer0>; -+ status = "disabled"; -+ }; -+ - reserved-memory { - #address-cells = <2>; - #size-cells = <2>; -@@ -150,6 +159,50 @@ soc { - #size-cells = <1>; - ranges = <0x0 0x0 0x0 0x40000000>; - -+ bus: bus@1000000 { -+ compatible = "allwinner,sun50i-h616-de33", -+ "allwinner,sun50i-a64-de2"; -+ reg = <0x1000000 0x400000>; -+ allwinner,sram = <&de3_sram 1>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges = <0 0x1000000 0x400000>; -+ -+ display_clocks: clock@8000 { -+ compatible = "allwinner,sun50i-h616-de33-clk"; -+ reg = <0x8000 0x100>; -+ clocks = <&ccu CLK_DE>, <&ccu CLK_BUS_DE>; -+ clock-names = "mod", "bus"; -+ resets = <&ccu RST_BUS_DE>; -+ #clock-cells = <1>; -+ #reset-cells = <1>; -+ }; -+ -+ mixer0: mixer@100000 { -+ compatible = "allwinner,sun50i-h616-de33-mixer-0"; -+ reg = <0x100000 0x100000>, -+ <0x8100 0x40>, -+ <0x280000 0x20000>; -+ clocks = <&display_clocks CLK_BUS_MIXER0>, -+ <&display_clocks CLK_MIXER0>; -+ clock-names = "bus", "mod"; -+ resets = <&display_clocks RST_MIXER0>; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ mixer0_out: port@1 { -+ reg = <1>; -+ -+ mixer0_out_tcon_top_mixer0: endpoint { -+ remote-endpoint = <&tcon_top_mixer0_in_mixer0>; -+ }; -+ }; -+ }; -+ }; -+ }; -+ - crypto: crypto@1904000 { - compatible = "allwinner,sun50i-h616-crypto"; - reg = <0x01904000 0x800>; -@@ -173,6 +226,11 @@ sram_c: sram@28000 { - #address-cells = <1>; - #size-cells = <1>; - ranges = <0 0x00028000 0x30000>; -+ -+ de3_sram: sram-section@0 { -+ compatible = "allwinner,sun50i-a64-sram-c"; -+ reg = <0x0000 0x1e000>; -+ }; - }; - }; - -@@ -263,6 +321,32 @@ ir_rx_pin: ir-rx-pin { - function = "ir_rx"; - }; - -+ /omit-if-no-ref/ -+ lcd0_rgb888_pins: lcd0-rgb888-pins { -+ pins = "PD0", "PD1", "PD2", "PD3", -+ "PD4", "PD5", "PD6", "PD7", -+ "PD8", "PD9", "PD10", "PD11", -+ "PD12", "PD13", "PD14", "PD15", -+ "PD16", "PD17", "PD18", "PD19", -+ "PD20", "PD21", "PD22", "PD23", -+ "PD24", "PD25", "PD26", "PD27"; -+ function = "lcd0"; -+ }; -+ -+ /omit-if-no-ref/ -+ lvds0_pins: lvds0-pins { -+ pins = "PD0", "PD1", "PD2", "PD3", "PD4", -+ "PD5", "PD6", "PD7", "PD8", "PD9"; -+ function = "lvds0"; -+ }; -+ -+ /omit-if-no-ref/ -+ lvds1_pins: lvds1-pins { -+ pins = "PD10", "PD11", "PD12", "PD13", "PD14", -+ "PD15", "PD16", "PD17", "PD18", "PD19"; -+ function = "lvds1"; -+ }; -+ - mmc0_pins: mmc0-pins { - pins = "PF0", "PF1", "PF2", "PF3", - "PF4", "PF5"; -@@ -289,6 +373,12 @@ mmc2_pins: mmc2-pins { - bias-pull-up; - }; - -+ /omit-if-no-ref/ -+ pwm0_pin: pwm0-pin { -+ pins = "PD28"; -+ function = "pwm0"; -+ }; -+ - /omit-if-no-ref/ - spi0_pins: spi0-pins { - pins = "PC0", "PC2", "PC4"; -@@ -839,6 +929,136 @@ ohci3: usb@5311400 { - status = "disabled"; - }; - -+ tcon_top: tcon-top@6510000 { -+ compatible = "allwinner,sun50i-h6-tcon-top"; -+ reg = <0x06510000 0x1000>; -+ clocks = <&ccu CLK_BUS_TCON_TOP>, -+ <&ccu CLK_TCON_TV0>; -+ clock-names = "bus", "tcon-tv0"; -+ clock-output-names = "tcon-top-tv0"; -+ #clock-cells = <0>; -+ resets = <&ccu RST_BUS_TCON_TOP>; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ tcon_top_mixer0_in: port@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ -+ tcon_top_mixer0_in_mixer0: endpoint@0 { -+ reg = <0>; -+ remote-endpoint = <&mixer0_out_tcon_top_mixer0>; -+ }; -+ }; -+ -+ tcon_top_mixer0_out: port@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ -+ tcon_top_mixer0_out_tcon_lcd0: endpoint@0 { -+ reg = <0>; -+ remote-endpoint = <&tcon_lcd0_in_tcon_top_mixer0>; -+ }; -+ -+ tcon_top_mixer0_out_tcon_tv0: endpoint@2 { -+ reg = <2>; -+ remote-endpoint = <&tcon_tv0_in_tcon_top_mixer0>; -+ }; -+ }; -+ -+ tcon_top_hdmi_in: port@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ -+ tcon_top_hdmi_in_tcon_tv0: endpoint@0 { -+ reg = <0>; -+ remote-endpoint = <&tcon_tv0_out_tcon_top>; -+ }; -+ }; -+ -+ tcon_top_hdmi_out: port@5 { -+ reg = <5>; -+ -+ tcon_top_hdmi_out_hdmi: endpoint { -+ /* placeholder for HDMI - remote-endpoint = <&hdmi_in_tcon_top>;*/ -+ }; -+ }; -+ }; -+ }; -+ -+ tcon_lcd0: lcd-controller@6511000 { -+ compatible = "allwinner,sun8i-r40-tcon-lcd"; -+ reg = <0x06511000 0x1000>; -+ interrupts = ; -+ clocks = <&ccu CLK_BUS_TCON_LCD0>, <&ccu CLK_TCON_LCD0>; -+ clock-names = "ahb", "tcon-ch0"; -+ clock-output-names = "tcon-data-clock"; -+ #clock-cells = <0>; -+ resets = <&ccu RST_BUS_TCON_LCD0>, <&ccu RST_BUS_TCON_LCD1>; -+ reset-names = "lcd", "lvds"; -+ status = "disabled"; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ tcon_lcd0_in: port@0 { -+ reg = <0>; -+ -+ tcon_lcd0_in_tcon_top_mixer0: endpoint { -+ remote-endpoint = <&tcon_top_mixer0_out_tcon_lcd0>; -+ }; -+ }; -+ -+ tcon_lcd0_out: port@1 { -+ reg = <1>; -+ }; -+ }; -+ }; -+ -+ tcon_tv0: lcd-controller@6515000 { -+ compatible = "allwinner,sun50i-h6-tcon-tv", -+ "allwinner,sun8i-r40-tcon-tv"; -+ reg = <0x06515000 0x1000>; -+ interrupts = ; -+ clocks = <&ccu CLK_BUS_TCON_TV0>, -+ <&tcon_top CLK_TCON_TOP_TV0>; -+ clock-names = "ahb", "tcon-ch1"; -+ #clock-cells = <0>; -+ resets = <&ccu RST_BUS_TCON_TV0>; -+ reset-names = "lcd"; -+ status = "disabled"; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ tcon_tv0_in: port@0 { -+ reg = <0>; -+ -+ tcon_tv0_in_tcon_top_mixer0: endpoint { -+ remote-endpoint = <&tcon_top_mixer0_out_tcon_tv0>; -+ }; -+ }; -+ -+ tcon_tv0_out: port@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ -+ tcon_tv0_out_tcon_top: endpoint@1 { -+ reg = <1>; -+ remote-endpoint = <&tcon_top_hdmi_in_tcon_tv0>; -+ }; -+ }; -+ }; -+ }; -+ - rtc: rtc@7000000 { - compatible = "allwinner,sun50i-h616-rtc"; - reg = <0x07000000 0x400>; -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts b/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts -index afb49e65859f..270c562bbd59 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts -@@ -21,6 +21,18 @@ aliases { - serial0 = &uart0; - }; - -+ backlight: backlight { -+ compatible = "gpio-backlight"; -+ gpios = <&pio 3 28 GPIO_ACTIVE_HIGH>; // PD28 -+ default-on; -+ }; -+ -+ battery: battery { -+ compatible = "simple-battery"; -+ constant-charge-current-max-microamp = <1024000>; -+ voltage-max-design-microvolt = <4200000>; -+ }; -+ - chosen { - stdout-path = "serial0:115200n8"; - }; -@@ -169,12 +181,59 @@ reg_vcc5v: regulator-vcc5v { /* USB-C power input */ - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - }; -+ -+ reg_lcd: regulator-gpio-lcd-vdd { -+ compatible = "regulator-fixed"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-name = "vdd-lcd"; -+ gpio = <&pio 8 15 GPIO_ACTIVE_HIGH>; // PI15 -+ enable-active-high; -+ }; -+ -+ spi_lcd: spi { -+ compatible = "spi-gpio"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ sck-gpios = <&pio 8 9 GPIO_ACTIVE_HIGH>; // PI9 -+ mosi-gpios = <&pio 8 10 GPIO_ACTIVE_HIGH>; // PI10 -+ cs-gpios = <&pio 8 8 GPIO_ACTIVE_HIGH>; // PI8 -+ num-chipselects = <1>; -+ -+ panel: panel@0 { -+ compatible = "anbernic,rg35xx-plus-panel"; -+ -+ reg = <0>; -+ -+ spi-max-frequency = <3125000>; -+ spi-3wire; -+ -+ reset-gpios = <&pio 8 14 GPIO_ACTIVE_LOW>; // PI14 -+ -+ backlight = <&backlight>; -+ power-supply = <®_lcd>; -+ -+ pinctrl-0 = <&lcd0_rgb888_pins>; -+ pinctrl-names = "default"; -+ -+ port { -+ panel_in_rgb: endpoint { -+ remote-endpoint = <&tcon_lcd0_out_lcd>; -+ }; -+ }; -+ }; -+ }; - }; - - &cpu0 { - cpu-supply = <®_dcdc1>; - }; - -+&de { -+ status = "okay"; -+}; -+ - &ehci0 { - status = "okay"; - }; -@@ -194,6 +253,7 @@ &ohci0 { - &pio { - vcc-pa-supply = <®_cldo3>; - vcc-pc-supply = <®_cldo3>; -+ vcc-pd-supply = <®_cldo3>; - vcc-pe-supply = <®_cldo3>; - vcc-pf-supply = <®_cldo3>; - vcc-pg-supply = <®_aldo4>; -@@ -310,6 +370,16 @@ reg_cpusldo: cpusldo { - }; - }; - -+&tcon_lcd0 { -+ status = "okay"; -+}; -+ -+&tcon_lcd0_out { -+ tcon_lcd0_out_lcd: endpoint@1 { -+ remote-endpoint = <&panel_in_rgb>; -+ }; -+}; -+ - &uart0 { - pinctrl-names = "default"; - pinctrl-0 = <&uart0_ph_pins>; -diff --git a/drivers/bus/sun50i-de2.c b/drivers/bus/sun50i-de2.c -index 3339311ce068..4747a87cae91 100644 ---- a/drivers/bus/sun50i-de2.c -+++ b/drivers/bus/sun50i-de2.c -@@ -31,6 +31,7 @@ static void sun50i_de2_bus_remove(struct platform_device *pdev) - - static const struct of_device_id sun50i_de2_bus_of_match[] = { - { .compatible = "allwinner,sun50i-a64-de2", }, -+ { .compatible = "allwinner,sun50i-h616-de33", }, - { /* sentinel */ } - }; - -diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h616.c b/drivers/clk/sunxi-ng/ccu-sun50i-h616.c -index 84e406ddf9d1..6c7623d4c59e 100644 ---- a/drivers/clk/sunxi-ng/ccu-sun50i-h616.c -+++ b/drivers/clk/sunxi-ng/ccu-sun50i-h616.c -@@ -635,6 +635,22 @@ static const char * const tcon_tv_parents[] = { "pll-video0", - "pll-video0-4x", - "pll-video1", - "pll-video1-4x" }; -+ -+static SUNXI_CCU_MUX_WITH_GATE(tcon_lcd0_clk, "tcon-lcd0", -+ tcon_tv_parents, 0xb60, -+ 24, 3, /* mux */ -+ BIT(31), /* gate */ -+ CLK_SET_RATE_PARENT); -+static SUNXI_CCU_MUX_WITH_GATE(tcon_lcd1_clk, "tcon-lcd1", -+ tcon_tv_parents, 0xb64, -+ 24, 3, /* mux */ -+ BIT(31), /* gate */ -+ CLK_SET_RATE_PARENT); -+static SUNXI_CCU_GATE(bus_tcon_lcd0_clk, "bus-tcon-lcd0", "ahb3", -+ 0xb7c, BIT(0), 0); -+static SUNXI_CCU_GATE(bus_tcon_lcd1_clk, "bus-tcon-lcd1", "ahb3", -+ 0xb7c, BIT(1), 0); -+ - static SUNXI_CCU_MP_WITH_MUX_GATE(tcon_tv0_clk, "tcon-tv0", - tcon_tv_parents, 0xb80, - 0, 4, /* M */ -@@ -843,8 +859,12 @@ static struct ccu_common *sun50i_h616_ccu_clks[] = { - &hdmi_cec_clk.common, - &bus_hdmi_clk.common, - &bus_tcon_top_clk.common, -+ &tcon_lcd0_clk.common, -+ &tcon_lcd1_clk.common, - &tcon_tv0_clk.common, - &tcon_tv1_clk.common, -+ &bus_tcon_lcd0_clk.common, -+ &bus_tcon_lcd1_clk.common, - &bus_tcon_tv0_clk.common, - &bus_tcon_tv1_clk.common, - &tve0_clk.common, -@@ -977,8 +997,12 @@ static struct clk_hw_onecell_data sun50i_h616_hw_clks = { - [CLK_HDMI_CEC] = &hdmi_cec_clk.common.hw, - [CLK_BUS_HDMI] = &bus_hdmi_clk.common.hw, - [CLK_BUS_TCON_TOP] = &bus_tcon_top_clk.common.hw, -+ [CLK_TCON_LCD0] = &tcon_lcd0_clk.common.hw, -+ [CLK_TCON_LCD1] = &tcon_lcd1_clk.common.hw, - [CLK_TCON_TV0] = &tcon_tv0_clk.common.hw, - [CLK_TCON_TV1] = &tcon_tv1_clk.common.hw, -+ [CLK_BUS_TCON_LCD0] = &bus_tcon_lcd0_clk.common.hw, -+ [CLK_BUS_TCON_LCD1] = &bus_tcon_lcd1_clk.common.hw, - [CLK_BUS_TCON_TV0] = &bus_tcon_tv0_clk.common.hw, - [CLK_BUS_TCON_TV1] = &bus_tcon_tv1_clk.common.hw, - [CLK_TVE0] = &tve0_clk.common.hw, -@@ -1050,6 +1074,8 @@ static struct ccu_reset_map sun50i_h616_ccu_resets[] = { - [RST_BUS_HDMI] = { 0xb1c, BIT(16) }, - [RST_BUS_HDMI_SUB] = { 0xb1c, BIT(17) }, - [RST_BUS_TCON_TOP] = { 0xb5c, BIT(16) }, -+ [RST_BUS_TCON_LCD0] = { 0xb7c, BIT(16) }, -+ [RST_BUS_TCON_LCD1] = { 0xb7c, BIT(17) }, - [RST_BUS_TCON_TV0] = { 0xb9c, BIT(16) }, - [RST_BUS_TCON_TV1] = { 0xb9c, BIT(17) }, - [RST_BUS_TVE_TOP] = { 0xbbc, BIT(16) }, -diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h616.h b/drivers/clk/sunxi-ng/ccu-sun50i-h616.h -index a75803b49f6a..7056f293a8e0 100644 ---- a/drivers/clk/sunxi-ng/ccu-sun50i-h616.h -+++ b/drivers/clk/sunxi-ng/ccu-sun50i-h616.h -@@ -51,6 +51,6 @@ - - #define CLK_BUS_DRAM 56 - --#define CLK_NUMBER (CLK_BUS_GPADC + 1) -+#define CLK_NUMBER (CLK_BUS_TCON_LCD1 + 1) - - #endif /* _CCU_SUN50I_H616_H_ */ -diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c -index e39926e9f0b5..a046f9dae49b 100644 ---- a/drivers/gpu/drm/sun4i/sun4i_tcon.c -+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c -@@ -1526,6 +1526,14 @@ static const struct sun4i_tcon_quirks sun8i_a83t_tv_quirks = { - .has_channel_1 = true, - }; - -+static const struct sun4i_tcon_quirks sun8i_r40_lcd_quirks = { -+ .supports_lvds = true, -+ .has_channel_0 = true, -+ .set_mux = sun8i_r40_tcon_tv_set_mux, -+ .dclk_min_div = 1, -+ .setup_lvds_phy = sun6i_tcon_setup_lvds_phy, -+}; -+ - static const struct sun4i_tcon_quirks sun8i_r40_tv_quirks = { - .has_channel_1 = true, - .polarity_in_ch0 = true, -@@ -1567,6 +1575,7 @@ const struct of_device_id sun4i_tcon_of_table[] = { - { .compatible = "allwinner,sun8i-a33-tcon", .data = &sun8i_a33_quirks }, - { .compatible = "allwinner,sun8i-a83t-tcon-lcd", .data = &sun8i_a83t_lcd_quirks }, - { .compatible = "allwinner,sun8i-a83t-tcon-tv", .data = &sun8i_a83t_tv_quirks }, -+ { .compatible = "allwinner,sun8i-r40-tcon-lcd", .data = &sun8i_r40_lcd_quirks }, - { .compatible = "allwinner,sun8i-r40-tcon-tv", .data = &sun8i_r40_tv_quirks }, - { .compatible = "allwinner,sun8i-v3s-tcon", .data = &sun8i_v3s_quirks }, - { .compatible = "allwinner,sun9i-a80-tcon-lcd", .data = &sun9i_a80_tcon_lcd_quirks }, -diff --git a/include/dt-bindings/clock/sun50i-h616-ccu.h b/include/dt-bindings/clock/sun50i-h616-ccu.h -index ebb146ab7f8c..6889405f9fec 100644 ---- a/include/dt-bindings/clock/sun50i-h616-ccu.h -+++ b/include/dt-bindings/clock/sun50i-h616-ccu.h -@@ -113,5 +113,9 @@ - #define CLK_BUS_HDCP 127 - #define CLK_PLL_SYSTEM_32K 128 - #define CLK_BUS_GPADC 129 -+#define CLK_TCON_LCD0 130 -+#define CLK_BUS_TCON_LCD0 131 -+#define CLK_TCON_LCD1 132 -+#define CLK_BUS_TCON_LCD1 133 - - #endif /* _DT_BINDINGS_CLK_SUN50I_H616_H_ */ -diff --git a/include/dt-bindings/clock/sun8i-tcon-top.h b/include/dt-bindings/clock/sun8i-tcon-top.h -index 25164d767835..2a12d047d2e1 100644 ---- a/include/dt-bindings/clock/sun8i-tcon-top.h -+++ b/include/dt-bindings/clock/sun8i-tcon-top.h -@@ -7,5 +7,7 @@ - #define CLK_TCON_TOP_TV0 0 - #define CLK_TCON_TOP_TV1 1 - #define CLK_TCON_TOP_DSI 2 -+#define CLK_TCON_TOP_LCD0 3 -+#define CLK_TCON_TOP_LCD1 4 - - #endif /* _DT_BINDINGS_CLOCK_SUN8I_TCON_TOP_H_ */ -diff --git a/include/dt-bindings/reset/sun50i-h616-ccu.h b/include/dt-bindings/reset/sun50i-h616-ccu.h -index ed177c04afdd..81b1eba2a7f7 100644 ---- a/include/dt-bindings/reset/sun50i-h616-ccu.h -+++ b/include/dt-bindings/reset/sun50i-h616-ccu.h -@@ -67,5 +67,7 @@ - #define RST_BUS_HDCP 58 - #define RST_BUS_KEYADC 59 - #define RST_BUS_GPADC 60 -+#define RST_BUS_TCON_LCD0 61 -+#define RST_BUS_TCON_LCD1 62 - - #endif /* _DT_BINDINGS_RESET_SUN50I_H616_H_ */ --- -2.45.2 - diff --git a/board/anbernic/rg35xx-plus/patches/linux/0004-20240929_ryan_asoc_add_allwinner_h616_audio_codec_support.patch b/board/anbernic/rg35xx-plus/patches/linux/0004-20240929_ryan_asoc_add_allwinner_h616_audio_codec_support.patch deleted file mode 100644 index 8e69ae88e513..000000000000 --- a/board/anbernic/rg35xx-plus/patches/linux/0004-20240929_ryan_asoc_add_allwinner_h616_audio_codec_support.patch +++ /dev/null @@ -1,821 +0,0 @@ -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH 1/6] ASoC: sun4i-codec: Add support for different DAC FIFOC - addresses to quirks -From: Marcus Cooper -Date: Sun, 29 Sep 2024 23:06:02 +1300 -Message-Id: <20240929100750.860329-2-ryan@testtoast.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -The Allwinner H616 SoC uses a different register address to control the -output FIFO. - -Allow this to be specified separately from the ADC FIFO control -register. - -Signed-off-by: Marcus Cooper -Signed-off-by: Ryan Walklin ---- - sound/soc/sunxi/sun4i-codec.c | 83 +++++++++++++++++++++-------------- - 1 file changed, 51 insertions(+), 32 deletions(-) - -diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c -index 330bc0c09f56b..37f5678b55291 100644 ---- a/sound/soc/sunxi/sun4i-codec.c -+++ b/sound/soc/sunxi/sun4i-codec.c -@@ -238,6 +238,8 @@ struct sun4i_codec { - - /* ADC_FIFOC register is at different offset on different SoCs */ - struct regmap_field *reg_adc_fifoc; -+ /* DAC_FIFOC register is at different offset on different SoCs */ -+ struct regmap_field *reg_dac_fifoc; - - struct snd_dmaengine_dai_dma_data capture_dma_data; - struct snd_dmaengine_dai_dma_data playback_dma_data; -@@ -246,19 +248,19 @@ struct sun4i_codec { - static void sun4i_codec_start_playback(struct sun4i_codec *scodec) - { - /* Flush TX FIFO */ -- regmap_set_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, -- BIT(SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH)); -+ regmap_field_set_bits(scodec->reg_dac_fifoc, -+ BIT(SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH)); - - /* Enable DAC DRQ */ -- regmap_set_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, -- BIT(SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN)); -+ regmap_field_set_bits(scodec->reg_dac_fifoc, -+ BIT(SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN)); - } - - static void sun4i_codec_stop_playback(struct sun4i_codec *scodec) - { - /* Disable DAC DRQ */ -- regmap_clear_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, -- BIT(SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN)); -+ regmap_field_clear_bits(scodec->reg_dac_fifoc, -+ BIT(SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN)); - } - - static void sun4i_codec_start_capture(struct sun4i_codec *scodec) -@@ -356,13 +358,13 @@ static int sun4i_codec_prepare_playback(struct snd_pcm_substream *substream, - u32 val; - - /* Flush the TX FIFO */ -- regmap_set_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, -- BIT(SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH)); -+ regmap_field_set_bits(scodec->reg_dac_fifoc, -+ BIT(SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH)); - - /* Set TX FIFO Empty Trigger Level */ -- regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, -- 0x3f << SUN4I_CODEC_DAC_FIFOC_TX_TRIG_LEVEL, -- 0xf << SUN4I_CODEC_DAC_FIFOC_TX_TRIG_LEVEL); -+ regmap_field_update_bits(scodec->reg_dac_fifoc, -+ 0x3f << SUN4I_CODEC_DAC_FIFOC_TX_TRIG_LEVEL, -+ 0xf << SUN4I_CODEC_DAC_FIFOC_TX_TRIG_LEVEL); - - if (substream->runtime->rate > 32000) - /* Use 64 bits FIR filter */ -@@ -371,13 +373,13 @@ static int sun4i_codec_prepare_playback(struct snd_pcm_substream *substream, - /* Use 32 bits FIR filter */ - val = BIT(SUN4I_CODEC_DAC_FIFOC_FIR_VERSION); - -- regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, -- BIT(SUN4I_CODEC_DAC_FIFOC_FIR_VERSION), -- val); -+ regmap_field_update_bits(scodec->reg_dac_fifoc, -+ BIT(SUN4I_CODEC_DAC_FIFOC_FIR_VERSION), -+ val); - - /* Send zeros when we have an underrun */ -- regmap_clear_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, -- BIT(SUN4I_CODEC_DAC_FIFOC_SEND_LASAT)); -+ regmap_field_clear_bits(scodec->reg_dac_fifoc, -+ BIT(SUN4I_CODEC_DAC_FIFOC_SEND_LASAT)); - - return 0; - }; -@@ -510,9 +512,9 @@ static int sun4i_codec_hw_params_playback(struct sun4i_codec *scodec, - u32 val; - - /* Set DAC sample rate */ -- regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, -- 7 << SUN4I_CODEC_DAC_FIFOC_DAC_FS, -- hwrate << SUN4I_CODEC_DAC_FIFOC_DAC_FS); -+ regmap_field_update_bits(scodec->reg_dac_fifoc, -+ 7 << SUN4I_CODEC_DAC_FIFOC_DAC_FS, -+ hwrate << SUN4I_CODEC_DAC_FIFOC_DAC_FS); - - /* Set the number of channels we want to use */ - if (params_channels(params) == 1) -@@ -520,27 +522,27 @@ static int sun4i_codec_hw_params_playback(struct sun4i_codec *scodec, - else - val = 0; - -- regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, -- BIT(SUN4I_CODEC_DAC_FIFOC_MONO_EN), -- val); -+ regmap_field_update_bits(scodec->reg_dac_fifoc, -+ BIT(SUN4I_CODEC_DAC_FIFOC_MONO_EN), -+ val); - - /* Set the number of sample bits to either 16 or 24 bits */ - if (hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min == 32) { -- regmap_set_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, -- BIT(SUN4I_CODEC_DAC_FIFOC_TX_SAMPLE_BITS)); -+ regmap_field_set_bits(scodec->reg_dac_fifoc, -+ BIT(SUN4I_CODEC_DAC_FIFOC_TX_SAMPLE_BITS)); - - /* Set TX FIFO mode to padding the LSBs with 0 */ -- regmap_clear_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, -- BIT(SUN4I_CODEC_DAC_FIFOC_TX_FIFO_MODE)); -+ regmap_field_clear_bits(scodec->reg_dac_fifoc, -+ BIT(SUN4I_CODEC_DAC_FIFOC_TX_FIFO_MODE)); - - scodec->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - } else { -- regmap_clear_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, -- BIT(SUN4I_CODEC_DAC_FIFOC_TX_SAMPLE_BITS)); -+ regmap_field_clear_bits(scodec->reg_dac_fifoc, -+ BIT(SUN4I_CODEC_DAC_FIFOC_TX_SAMPLE_BITS)); - - /* Set TX FIFO mode to repeat the MSB */ -- regmap_set_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, -- BIT(SUN4I_CODEC_DAC_FIFOC_TX_FIFO_MODE)); -+ regmap_field_set_bits(scodec->reg_dac_fifoc, -+ BIT(SUN4I_CODEC_DAC_FIFOC_TX_FIFO_MODE)); - - scodec->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; - } -@@ -587,8 +589,8 @@ static int sun4i_codec_startup(struct snd_pcm_substream *substream, - * Stop issuing DRQ when we have room for less than 16 samples - * in our TX FIFO - */ -- regmap_set_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, -- 3 << SUN4I_CODEC_DAC_FIFOC_DRQ_CLR_CNT); -+ regmap_field_set_bits(scodec->reg_dac_fifoc, -+ 3 << SUN4I_CODEC_DAC_FIFOC_DRQ_CLR_CNT); - - return clk_prepare_enable(scodec->clk_module); - } -@@ -1565,6 +1567,7 @@ struct sun4i_codec_quirks { - const struct snd_soc_component_driver *codec; - struct snd_soc_card * (*create_card)(struct device *dev); - struct reg_field reg_adc_fifoc; /* used for regmap_field */ -+ struct reg_field reg_dac_fifoc; /* used for regmap_field */ - unsigned int reg_dac_txdata; /* TX FIFO offset for DMA config */ - unsigned int reg_adc_rxdata; /* RX FIFO offset for DMA config */ - bool has_reset; -@@ -1575,6 +1578,7 @@ static const struct sun4i_codec_quirks sun4i_codec_quirks = { - .codec = &sun4i_codec_codec, - .create_card = sun4i_codec_create_card, - .reg_adc_fifoc = REG_FIELD(SUN4I_CODEC_ADC_FIFOC, 0, 31), -+ .reg_dac_fifoc = REG_FIELD(SUN4I_CODEC_DAC_FIFOC, 0, 31), - .reg_dac_txdata = SUN4I_CODEC_DAC_TXDATA, - .reg_adc_rxdata = SUN4I_CODEC_ADC_RXDATA, - }; -@@ -1584,6 +1588,7 @@ static const struct sun4i_codec_quirks sun6i_a31_codec_quirks = { - .codec = &sun6i_codec_codec, - .create_card = sun6i_codec_create_card, - .reg_adc_fifoc = REG_FIELD(SUN6I_CODEC_ADC_FIFOC, 0, 31), -+ .reg_dac_fifoc = REG_FIELD(SUN4I_CODEC_DAC_FIFOC, 0, 31), - .reg_dac_txdata = SUN4I_CODEC_DAC_TXDATA, - .reg_adc_rxdata = SUN6I_CODEC_ADC_RXDATA, - .has_reset = true, -@@ -1594,6 +1599,7 @@ static const struct sun4i_codec_quirks sun7i_codec_quirks = { - .codec = &sun7i_codec_codec, - .create_card = sun4i_codec_create_card, - .reg_adc_fifoc = REG_FIELD(SUN4I_CODEC_ADC_FIFOC, 0, 31), -+ .reg_dac_fifoc = REG_FIELD(SUN4I_CODEC_DAC_FIFOC, 0, 31), - .reg_dac_txdata = SUN4I_CODEC_DAC_TXDATA, - .reg_adc_rxdata = SUN4I_CODEC_ADC_RXDATA, - }; -@@ -1603,6 +1609,7 @@ static const struct sun4i_codec_quirks sun8i_a23_codec_quirks = { - .codec = &sun8i_a23_codec_codec, - .create_card = sun8i_a23_codec_create_card, - .reg_adc_fifoc = REG_FIELD(SUN6I_CODEC_ADC_FIFOC, 0, 31), -+ .reg_dac_fifoc = REG_FIELD(SUN4I_CODEC_DAC_FIFOC, 0, 31), - .reg_dac_txdata = SUN4I_CODEC_DAC_TXDATA, - .reg_adc_rxdata = SUN6I_CODEC_ADC_RXDATA, - .has_reset = true, -@@ -1618,6 +1625,7 @@ static const struct sun4i_codec_quirks sun8i_h3_codec_quirks = { - .codec = &sun8i_a23_codec_codec, - .create_card = sun8i_h3_codec_create_card, - .reg_adc_fifoc = REG_FIELD(SUN6I_CODEC_ADC_FIFOC, 0, 31), -+ .reg_dac_fifoc = REG_FIELD(SUN4I_CODEC_DAC_FIFOC, 0, 31), - .reg_dac_txdata = SUN8I_H3_CODEC_DAC_TXDATA, - .reg_adc_rxdata = SUN6I_CODEC_ADC_RXDATA, - .has_reset = true, -@@ -1632,6 +1640,7 @@ static const struct sun4i_codec_quirks sun8i_v3s_codec_quirks = { - .codec = &sun8i_a23_codec_codec, - .create_card = sun8i_v3s_codec_create_card, - .reg_adc_fifoc = REG_FIELD(SUN6I_CODEC_ADC_FIFOC, 0, 31), -+ .reg_dac_fifoc = REG_FIELD(SUN4I_CODEC_DAC_FIFOC, 0, 31), - .reg_dac_txdata = SUN8I_H3_CODEC_DAC_TXDATA, - .reg_adc_rxdata = SUN6I_CODEC_ADC_RXDATA, - .has_reset = true, -@@ -1739,6 +1748,16 @@ static int sun4i_codec_probe(struct platform_device *pdev) - return ret; - } - -+ scodec->reg_dac_fifoc = devm_regmap_field_alloc(&pdev->dev, -+ scodec->regmap, -+ quirks->reg_dac_fifoc); -+ if (IS_ERR(scodec->reg_dac_fifoc)) { -+ ret = PTR_ERR(scodec->reg_dac_fifoc); -+ dev_err(&pdev->dev, "Failed to create regmap fields: %d\n", -+ ret); -+ return ret; -+ } -+ - /* Enable the bus clock */ - if (clk_prepare_enable(scodec->clk_apb)) { - dev_err(&pdev->dev, "Failed to enable the APB clock\n"); --- -2.46.1 - -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH 2/6] ASoC: sun4i-codec: Add playback only flag to quirks -From: Marcus Cooper -Date: Sun, 29 Sep 2024 23:06:03 +1300 -Message-Id: <20240929100750.860329-3-ryan@testtoast.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -Some devices only have the playback side of the codec implemented -so add a quirk to check for this. - -Signed-off-by: Marcus Cooper -Signed-off-by: Ryan Walklin ---- - sound/soc/sunxi/sun4i-codec.c | 12 ++++++++---- - 1 file changed, 8 insertions(+), 4 deletions(-) - -diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c -index 37f5678b55291..312d2655c3f4e 100644 ---- a/sound/soc/sunxi/sun4i-codec.c -+++ b/sound/soc/sunxi/sun4i-codec.c -@@ -1571,6 +1571,7 @@ struct sun4i_codec_quirks { - unsigned int reg_dac_txdata; /* TX FIFO offset for DMA config */ - unsigned int reg_adc_rxdata; /* RX FIFO offset for DMA config */ - bool has_reset; -+ bool playback_only; - }; - - static const struct sun4i_codec_quirks sun4i_codec_quirks = { -@@ -1779,10 +1780,13 @@ static int sun4i_codec_probe(struct platform_device *pdev) - scodec->playback_dma_data.maxburst = 8; - scodec->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; - -- /* DMA configuration for RX FIFO */ -- scodec->capture_dma_data.addr = res->start + quirks->reg_adc_rxdata; -- scodec->capture_dma_data.maxburst = 8; -- scodec->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; -+ if (!quirks->playback_only) { -+ /* DMA configuration for RX FIFO */ -+ scodec->capture_dma_data.addr = res->start + -+ quirks->reg_adc_rxdata; -+ scodec->capture_dma_data.maxburst = 8; -+ scodec->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; -+ } - - ret = devm_snd_soc_register_component(&pdev->dev, quirks->codec, - &sun4i_codec_dai, 1); --- -2.46.1 - -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH 3/6] clk: sunxi-ng: h616: Add sigma-delta modulation - settings for audio PLL -From: Ryan Walklin -Date: Sun, 29 Sep 2024 23:06:04 +1300 -Message-Id: <20240929100750.860329-4-ryan@testtoast.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -Allwinner has previously released a H616 audio driver which also -provides sigma-delta modulation for the audio PLL clocks. This approach -is used in other Allwinner SoCs, including the H3 and A64. - -One change from the vendor code is made to the PLL clocks, the -vendor-specified dividers of 4/2/1 for the 1/2/4x clocks respectively result -in audio playback that is too slow by 50%. Therefore the dividers are simply -doubled to 8/4/2 which results in correct playback rates. - -Add SDM to the H616 clock control unit driver. - -Signed-off-by: Ryan Walklin ---- - drivers/clk/sunxi-ng/ccu-sun50i-h616.c | 36 +++++++++++++------------- - 1 file changed, 18 insertions(+), 18 deletions(-) - -diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h616.c b/drivers/clk/sunxi-ng/ccu-sun50i-h616.c -index 84e406ddf9d12..be272947b0fee 100644 ---- a/drivers/clk/sunxi-ng/ccu-sun50i-h616.c -+++ b/drivers/clk/sunxi-ng/ccu-sun50i-h616.c -@@ -215,20 +215,23 @@ static struct ccu_nkmp pll_de_clk = { - }, - }; - --/* -- * TODO: Determine SDM settings for the audio PLL. The manual suggests -- * PLL_FACTOR_N=16, PLL_POST_DIV_P=2, OUTPUT_DIV=2, pattern=0xe000c49b -- * for 24.576 MHz, and PLL_FACTOR_N=22, PLL_POST_DIV_P=3, OUTPUT_DIV=2, -- * pattern=0xe001288c for 22.5792 MHz. -- * This clashes with our fixed PLL_POST_DIV_P. -- */ - #define SUN50I_H616_PLL_AUDIO_REG 0x078 -+ -+static struct ccu_sdm_setting pll_audio_sdm_table[] = { -+ { .rate = 90316800, .pattern = 0xc001288d, .m = 3, .n = 22 }, -+ { .rate = 98304000, .pattern = 0xc001eb85, .m = 5, .n = 40 }, -+}; -+ - static struct ccu_nm pll_audio_hs_clk = { - .enable = BIT(31), - .lock = BIT(28), -- .n = _SUNXI_CCU_MULT_MIN(8, 8, 12), -- .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ -+ .n = _SUNXI_CCU_MULT_MIN(8, 8, 12), -+ .m = _SUNXI_CCU_DIV(16, 6), -+ .sdm = _SUNXI_CCU_SDM(pll_audio_sdm_table, -+ BIT(24), 0x178, BIT(31)), -+ - .common = { -+ .features = CCU_FEATURE_SIGMA_DELTA_MOD, - .reg = 0x078, - .hw.init = CLK_HW_INIT("pll-audio-hs", "osc24M", - &ccu_nm_ops, -@@ -690,13 +693,13 @@ static const struct clk_hw *clk_parent_pll_audio[] = { - */ - static CLK_FIXED_FACTOR_HWS(pll_audio_1x_clk, "pll-audio-1x", - clk_parent_pll_audio, -- 96, 1, CLK_SET_RATE_PARENT); -+ 8, 1, CLK_SET_RATE_PARENT); - static CLK_FIXED_FACTOR_HWS(pll_audio_2x_clk, "pll-audio-2x", - clk_parent_pll_audio, -- 48, 1, CLK_SET_RATE_PARENT); -+ 4, 1, CLK_SET_RATE_PARENT); - static CLK_FIXED_FACTOR_HWS(pll_audio_4x_clk, "pll-audio-4x", - clk_parent_pll_audio, -- 24, 1, CLK_SET_RATE_PARENT); -+ 2, 1, CLK_SET_RATE_PARENT); - - static const struct clk_hw *pll_periph0_parents[] = { - &pll_periph0_clk.common.hw -@@ -1135,13 +1138,10 @@ static int sun50i_h616_ccu_probe(struct platform_device *pdev) - writel(val, reg + usb2_clk_regs[i]); - } - -- /* -- * Force the post-divider of pll-audio to 12 and the output divider -- * of it to 2, so 24576000 and 22579200 rates can be set exactly. -- */ - val = readl(reg + SUN50I_H616_PLL_AUDIO_REG); -- val &= ~(GENMASK(21, 16) | BIT(0)); -- writel(val | (11 << 16) | BIT(0), reg + SUN50I_H616_PLL_AUDIO_REG); -+ val &= ~BIT(1); -+ val |= BIT(0); -+ writel(val, reg + SUN50I_H616_PLL_AUDIO_REG); - - /* - * First clock parent (osc32K) is unusable for CEC. But since there --- -2.46.1 - -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH 4/6] dt-bindings: allwinner: add H616 sun4i audio codec - binding -From: Ryan Walklin -Date: Sun, 29 Sep 2024 23:06:05 +1300 -Message-Id: <20240929100750.860329-5-ryan@testtoast.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -The H616 has an audio codec compatible with the sun4i-a10 driver. - -The codec is relatively cut down compared to some of the other Allwinner -SoCs and only has a single line-out route (relying on a separate digital -microphone IP block for input). HDMI and SPDIF audio are handled -separately by an audio hub IP block, which is not currently implemented -in mainline kernels. This and the use of SDM requires some additional -flexibility to the DMA and clock bindings. - -Add compatible string and routing for the H616 audio codec, and update -the required clock and DMA descriptions. - -Signed-off-by: Ryan Walklin ---- - .../sound/allwinner,sun4i-a10-codec.yaml | 55 +++++++++++++++---- - 1 file changed, 43 insertions(+), 12 deletions(-) - -diff --git a/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-codec.yaml b/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-codec.yaml -index 78273647f7665..5838600dbc730 100644 ---- a/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-codec.yaml -+++ b/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-codec.yaml -@@ -22,6 +22,7 @@ properties: - - allwinner,sun8i-a23-codec - - allwinner,sun8i-h3-codec - - allwinner,sun8i-v3s-codec -+ - allwinner,sun50i-h616-codec - - reg: - maxItems: 1 -@@ -30,24 +31,40 @@ properties: - maxItems: 1 - - clocks: -- items: -- - description: Bus Clock -- - description: Module Clock -+ oneOf: -+ - items: -+ - description: Bus Clock -+ - description: Module Clock -+ - items: -+ - description: Bus Clock -+ - description: Module Clock -+ - description: Module Clock (4X) - - clock-names: -- items: -- - const: apb -- - const: codec -+ oneOf: -+ - items: -+ - const: apb -+ - const: codec -+ - items: -+ - const: apb -+ - const: codec -+ - const: audio-codec-4x - - dmas: -- items: -- - description: RX DMA Channel -- - description: TX DMA Channel -+ oneOf: -+ - items: -+ - description: RX DMA Channel -+ - description: TX DMA Channel -+ - items: -+ - description: TX DMA Channel - - dma-names: -- items: -- - const: rx -- - const: tx -+ oneOf: -+ - items: -+ - const: rx -+ - const: tx -+ - items: -+ - const: tx - - resets: - maxItems: 1 -@@ -229,6 +246,20 @@ allOf: - - Mic - - Speaker - -+ - if: -+ properties: -+ compatible: -+ enum: -+ - allwinner,sun50i-h616-codec -+ -+ then: -+ properties: -+ allwinner,audio-routing: -+ items: -+ enum: -+ - LINEOUT -+ - Line Out -+ - unevaluatedProperties: false - - examples: --- -2.46.1 - -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH 5/6] ASoC: sun4i-codec: support allwinner H616 codec -From: Ryan Walklin -Date: Sun, 29 Sep 2024 23:06:06 +1300 -Message-Id: <20240929100750.860329-6-ryan@testtoast.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 8bit - -The H616 SoC codec is playback-only with a single line-out route, and -has some register differences from prior codecs. - -Add the required compatible string, registers, quirks, DAPM widgets, -codec controls and routes, based on existing devices and the H616 -datasheet. - -Signed-off-by: Ryan Walklin ---- - sound/soc/sunxi/sun4i-codec.c | 202 ++++++++++++++++++++++++++++++++++ - 1 file changed, 202 insertions(+) - -diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c -index 312d2655c3f4e..1cdda20e8ed59 100644 ---- a/sound/soc/sunxi/sun4i-codec.c -+++ b/sound/soc/sunxi/sun4i-codec.c -@@ -226,6 +226,43 @@ - #define SUN8I_H3_CODEC_DAC_DBG (0x48) - #define SUN8I_H3_CODEC_ADC_DBG (0x4c) - -+/* H616 specific registers */ -+#define SUN50I_H616_CODEC_DAC_FIFOC (0x10) -+ -+#define SUN50I_DAC_FIFO_STA (0x14) -+#define SUN50I_DAC_TXE_INT (3) -+#define SUN50I_DAC_TXU_INT (2) -+#define SUN50I_DAC_TXO_INT (1) -+ -+#define SUN50I_DAC_CNT (0x24) -+#define SUN50I_DAC_DG_REG (0x28) -+#define SUN50I_DAC_DAP_CTL (0xf0) -+ -+#define SUN50I_H616_DAC_AC_DAC_REG (0x310) -+#define SUN50I_H616_DAC_LEN (15) -+#define SUN50I_H616_DAC_REN (14) -+#define SUN50I_H616_LINEOUTL_EN (13) -+#define SUN50I_H616_LMUTE (12) -+#define SUN50I_H616_LINEOUTR_EN (11) -+#define SUN50I_H616_RMUTE (10) -+#define SUN50I_H616_RSWITCH (9) -+#define SUN50I_H616_RAMPEN (8) -+#define SUN50I_H616_LINEOUTL_SEL (6) -+#define SUN50I_H616_LINEOUTR_SEL (5) -+#define SUN50I_H616_LINEOUT_VOL (0) -+ -+#define SUN50I_H616_DAC_AC_MIXER_REG (0x314) -+#define SUN50I_H616_LMIX_LDAC (21) -+#define SUN50I_H616_LMIX_RDAC (20) -+#define SUN50I_H616_RMIX_RDAC (17) -+#define SUN50I_H616_RMIX_LDAC (16) -+#define SUN50I_H616_LMIXEN (11) -+#define SUN50I_H616_RMIXEN (10) -+ -+#define SUN50I_H616_DAC_AC_RAMP_REG (0x31c) -+#define SUN50I_H616_RAMP_STEP (4) -+#define SUN50I_H616_RDEN (0) -+ - /* TODO H3 DAP (Digital Audio Processing) bits */ - - struct sun4i_codec { -@@ -1520,6 +1557,149 @@ static struct snd_soc_card *sun8i_v3s_codec_create_card(struct device *dev) - return card; - }; - -+static const struct snd_kcontrol_new sun50i_h616_codec_codec_controls[] = { -+ SOC_SINGLE_TLV("DAC Playback Volume", SUN4I_CODEC_DAC_DPC, -+ SUN4I_CODEC_DAC_DPC_DVOL, 0x3f, 1, -+ sun6i_codec_dvol_scale), -+ SOC_SINGLE_TLV("Line Out Playback Volume", -+ SUN50I_H616_DAC_AC_DAC_REG, -+ SUN50I_H616_LINEOUT_VOL, 0x1f, 0, -+ sun6i_codec_lineout_vol_scale), -+ SOC_DOUBLE("Line Out Playback Switch", -+ SUN50I_H616_DAC_AC_DAC_REG, -+ SUN50I_H616_LINEOUTL_EN, -+ SUN50I_H616_LINEOUTR_EN, 1, 0), -+}; -+ -+static const struct snd_kcontrol_new sun50i_h616_codec_mixer_controls[] = { -+ SOC_DAPM_DOUBLE("DAC Playback Switch", -+ SUN50I_H616_DAC_AC_MIXER_REG, -+ SUN50I_H616_LMIX_LDAC, -+ SUN50I_H616_RMIX_RDAC, 1, 0), -+ SOC_DAPM_DOUBLE("DAC Reversed Playback Switch", -+ SUN50I_H616_DAC_AC_MIXER_REG, -+ SUN50I_H616_LMIX_RDAC, -+ SUN50I_H616_RMIX_LDAC, 1, 0), -+}; -+ -+static SOC_ENUM_DOUBLE_DECL(sun50i_h616_codec_lineout_src_enum, -+ SUN50I_H616_DAC_AC_DAC_REG, -+ SUN50I_H616_LINEOUTL_SEL, -+ SUN50I_H616_LINEOUTR_SEL, -+ sun6i_codec_lineout_src_enum_text); -+ -+static const struct snd_kcontrol_new sun50i_h616_codec_lineout_src[] = { -+ SOC_DAPM_ENUM("Line Out Source Playback Route", -+ sun50i_h616_codec_lineout_src_enum), -+}; -+ -+static const struct snd_soc_dapm_widget sun50i_h616_codec_codec_widgets[] = { -+ /* Digital parts of the DACs */ -+ SND_SOC_DAPM_SUPPLY("DAC Enable", SUN4I_CODEC_DAC_DPC, -+ SUN4I_CODEC_DAC_DPC_EN_DA, 0, -+ NULL, 0), -+ -+ /* Analog parts of the DACs */ -+ SND_SOC_DAPM_DAC("Left DAC", "Codec Playback", -+ SUN50I_H616_DAC_AC_DAC_REG, -+ SUN50I_H616_DAC_LEN, 0), -+ SND_SOC_DAPM_DAC("Right DAC", "Codec Playback", -+ SUN50I_H616_DAC_AC_DAC_REG, -+ SUN50I_H616_DAC_REN, 0), -+ -+ /* Mixers */ -+ SOC_MIXER_ARRAY("Left Mixer", SUN50I_H616_DAC_AC_MIXER_REG, -+ SUN50I_H616_LMIXEN, 0, -+ sun50i_h616_codec_mixer_controls), -+ SOC_MIXER_ARRAY("Right Mixer", SUN50I_H616_DAC_AC_MIXER_REG, -+ SUN50I_H616_RMIXEN, 0, -+ sun50i_h616_codec_mixer_controls), -+ -+ /* Line Out path */ -+ SND_SOC_DAPM_MUX("Line Out Source Playback Route", -+ SND_SOC_NOPM, 0, 0, sun50i_h616_codec_lineout_src), -+ SND_SOC_DAPM_OUT_DRV("Line Out Ramp Controller", -+ SUN50I_H616_DAC_AC_RAMP_REG, -+ SUN50I_H616_RDEN, 0, NULL, 0), -+ SND_SOC_DAPM_OUTPUT("LINEOUT"), -+}; -+ -+static const struct snd_soc_component_driver sun50i_h616_codec_codec = { -+ .controls = sun50i_h616_codec_codec_controls, -+ .num_controls = ARRAY_SIZE(sun50i_h616_codec_codec_controls), -+ .dapm_widgets = sun50i_h616_codec_codec_widgets, -+ .num_dapm_widgets = ARRAY_SIZE(sun50i_h616_codec_codec_widgets), -+ .idle_bias_on = 1, -+ .use_pmdown_time = 1, -+ .endianness = 1, -+}; -+ -+static const struct snd_kcontrol_new sun50i_h616_card_controls[] = { -+ SOC_DAPM_PIN_SWITCH("LINEOUT"), -+}; -+ -+static const struct snd_soc_dapm_widget sun50i_h616_codec_card_dapm_widgets[] = { -+ SND_SOC_DAPM_LINE("Line Out", NULL), -+ SND_SOC_DAPM_SPK("Speaker", sun4i_codec_spk_event), -+}; -+ -+/* Connect digital side enables to analog side widgets */ -+static const struct snd_soc_dapm_route sun50i_h616_codec_card_routes[] = { -+ /* DAC Routes */ -+ { "Left DAC", NULL, "DAC Enable" }, -+ { "Right DAC", NULL, "DAC Enable" }, -+ -+ /* Left Mixer Routes */ -+ { "Left Mixer", "DAC Playback Switch", "Left DAC" }, -+ { "Left Mixer", "DAC Reversed Playback Switch", "Right DAC" }, -+ -+ /* Right Mixer Routes */ -+ { "Right Mixer", "DAC Playback Switch", "Right DAC" }, -+ { "Right Mixer", "DAC Reversed Playback Switch", "Left DAC" }, -+ -+ /* Line Out Routes */ -+ { "Line Out Source Playback Route", "Stereo", "Left Mixer" }, -+ { "Line Out Source Playback Route", "Stereo", "Right Mixer" }, -+ { "Line Out Source Playback Route", "Mono Differential", "Left Mixer" }, -+ { "Line Out Source Playback Route", "Mono Differential", "Right Mixer" }, -+ { "Line Out Ramp Controller", NULL, "Line Out Source Playback Route" }, -+ { "LINEOUT", NULL, "Line Out Ramp Controller" }, -+}; -+ -+static struct snd_soc_card *sun50i_h616_codec_create_card(struct device *dev) -+{ -+ struct snd_soc_card *card; -+ int ret; -+ -+ card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); -+ if (!card) -+ return ERR_PTR(-ENOMEM); -+ -+ card->dai_link = sun4i_codec_create_link(dev, &card->num_links); -+ if (!card->dai_link) -+ return ERR_PTR(-ENOMEM); -+ -+ card->dai_link->playback_only = true; -+ card->dai_link->capture_only = false; -+ -+ card->dev = dev; -+ card->owner = THIS_MODULE; -+ card->name = "H616 Audio Codec"; -+ card->controls = sun50i_h616_card_controls; -+ card->num_controls = ARRAY_SIZE(sun50i_h616_card_controls); -+ card->dapm_widgets = sun50i_h616_codec_card_dapm_widgets; -+ card->num_dapm_widgets = ARRAY_SIZE(sun50i_h616_codec_card_dapm_widgets); -+ card->dapm_routes = sun50i_h616_codec_card_routes; -+ card->num_dapm_routes = ARRAY_SIZE(sun50i_h616_codec_card_routes); -+ card->fully_routed = true; -+ -+ ret = snd_soc_of_parse_audio_routing(card, "allwinner,audio-routing"); -+ if (ret) -+ dev_warn(dev, "failed to parse audio-routing: %d\n", ret); -+ -+ return card; -+}; -+ - static const struct regmap_config sun4i_codec_regmap_config = { - .reg_bits = 32, - .reg_stride = 4, -@@ -1562,6 +1742,14 @@ static const struct regmap_config sun8i_v3s_codec_regmap_config = { - .max_register = SUN8I_H3_CODEC_ADC_DBG, - }; - -+static const struct regmap_config sun50i_h616_codec_regmap_config = { -+ .reg_bits = 32, -+ .reg_stride = 4, -+ .val_bits = 32, -+ .max_register = SUN50I_H616_DAC_AC_RAMP_REG, -+ .cache_type = REGCACHE_NONE, -+}; -+ - struct sun4i_codec_quirks { - const struct regmap_config *regmap_config; - const struct snd_soc_component_driver *codec; -@@ -1647,6 +1835,15 @@ static const struct sun4i_codec_quirks sun8i_v3s_codec_quirks = { - .has_reset = true, - }; - -+static const struct sun4i_codec_quirks sun50i_h616_codec_quirks = { -+ .regmap_config = &sun50i_h616_codec_regmap_config, -+ .codec = &sun50i_h616_codec_codec, -+ .create_card = sun50i_h616_codec_create_card, -+ .reg_dac_fifoc = REG_FIELD(SUN50I_H616_CODEC_DAC_FIFOC, 0, 31), -+ .reg_dac_txdata = SUN8I_H3_CODEC_DAC_TXDATA, -+ .has_reset = true, -+}; -+ - static const struct of_device_id sun4i_codec_of_match[] = { - { - .compatible = "allwinner,sun4i-a10-codec", -@@ -1672,6 +1869,10 @@ static const struct of_device_id sun4i_codec_of_match[] = { - .compatible = "allwinner,sun8i-v3s-codec", - .data = &sun8i_v3s_codec_quirks, - }, -+ { -+ .compatible = "allwinner,sun50i-h616-codec", -+ .data = &sun50i_h616_codec_quirks, -+ }, - {} - }; - MODULE_DEVICE_TABLE(of, sun4i_codec_of_match); -@@ -1860,4 +2061,5 @@ MODULE_AUTHOR("Emilio López "); - MODULE_AUTHOR("Jon Smirl "); - MODULE_AUTHOR("Maxime Ripard "); - MODULE_AUTHOR("Chen-Yu Tsai "); -+MODULE_AUTHOR("Ryan Walklin -Date: Sun, 29 Sep 2024 23:06:07 +1300 -Message-Id: <20240929100750.860329-7-ryan@testtoast.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -Now that the sun4i codec driver supports the H616, add a node in the -device tree for it. - -Signed-off-by: Ryan Walklin ---- - arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi | 15 +++++++++++++++ - 1 file changed, 15 insertions(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi -index e88c1fbac6acc..006fdb7e7e0ae 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi -@@ -645,6 +645,21 @@ spdif: spdif@5093000 { - status = "disabled"; - }; - -+ codec: codec@05096000 { -+ #sound-dai-cells = <0>; -+ compatible = "allwinner,sun50i-h616-codec"; -+ reg = <0x05096000 0x31c>; -+ interrupts = ; -+ clocks = <&ccu CLK_BUS_AUDIO_CODEC>, -+ <&ccu CLK_AUDIO_CODEC_1X>, -+ <&ccu CLK_AUDIO_CODEC_4X>; -+ clock-names = "apb", "codec", "audio-codec-4x"; -+ resets = <&ccu RST_BUS_AUDIO_CODEC>; -+ dmas = <&dma 6>; -+ dma-names = "tx"; -+ status = "disabled"; -+ }; -+ - gpadc: adc@5070000 { - compatible = "allwinner,sun50i-h616-gpadc", - "allwinner,sun20i-d1-gpadc"; --- -2.46.1 - diff --git a/board/anbernic/rg35xx-plus/patches/linux/0005-enable-codec-for-rg35xx-2024.patch b/board/anbernic/rg35xx-plus/patches/linux/0005-enable-codec-for-rg35xx-2024.patch deleted file mode 100644 index 05087ca9beec..000000000000 --- a/board/anbernic/rg35xx-plus/patches/linux/0005-enable-codec-for-rg35xx-2024.patch +++ /dev/null @@ -1,51 +0,0 @@ -From fcaf6ba347c42ab1f99de0b927104587e1da61f0 Mon Sep 17 00:00:00 2001 -From: Philippe Simons -Date: Tue, 1 Oct 2024 23:22:15 +0200 -Subject: [PATCH] enable codec for rg35xx-2024 - ---- - .../allwinner/sun50i-h700-anbernic-rg35xx-2024.dts | 14 +++++++++++++- - 1 file changed, 13 insertions(+), 1 deletion(-) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts b/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts -index 80ccab7b5..36d826a1f 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts -@@ -197,6 +197,14 @@ &ohci0 { - status = "okay"; - }; - -+&codec { -+ allwinner,audio-routing = "Line Out", "LINEOUT", -+ "Speaker", "LINEOUT"; -+ allwinner,pa-gpios = <&pio 8 5 GPIO_ACTIVE_HIGH>; // PI5 -+ //allwinner,hp-detect-gpios = <&pio 8 3 GPIO_ACTIVE_LOW>; // PI3 -+ status = "okay"; -+}; -+ - &pio { - vcc-pa-supply = <®_cldo3>; - vcc-pc-supply = <®_cldo3>; -@@ -270,7 +278,7 @@ reg_aldo3: aldo3 { - reg_aldo4: aldo4 { - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; -- regulator-name = "vcc-pg"; -+ regulator-name = "avcc"; - }; - - reg_bldo1: bldo1 { -@@ -294,6 +302,10 @@ reg_bldo4: bldo4 { - - reg_cldo1: cldo1 { - /* 3.3v - audio codec - not yet implemented */ -+ regulator-always-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-name = "vcc-audio-codec"; - }; - - reg_cldo2: cldo2 { --- -2.46.0 - diff --git a/board/anbernic/rg35xx-plus/patches/linux/0006-20240225_andre_przywara_clk_sunxi_ng_h6_r_add_gpu_power_domain.patch b/board/anbernic/rg35xx-plus/patches/linux/0006-20240225_andre_przywara_clk_sunxi_ng_h6_r_add_gpu_power_domain.patch deleted file mode 100644 index 31e7ef543df2..000000000000 --- a/board/anbernic/rg35xx-plus/patches/linux/0006-20240225_andre_przywara_clk_sunxi_ng_h6_r_add_gpu_power_domain.patch +++ /dev/null @@ -1,142 +0,0 @@ -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH RFC 1/1] clk: sunxi-ng: h6-r: add GPU power domain -From: Andre Przywara -Date: Sun, 25 Feb 2024 16:06:16 +0000 -Message-Id: <20240225160616.15001-2-andre.przywara@arm.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -The Allwinner H616 features register 0x7010254 in the PRCM MMIO frame, -where bit 0 needs to be cleared to enable operation of the Mali GPU. -With this bit set (the reset default), any access to the Mali registers -hangs the bus and thus the whole system. The BSP code clears this bit -in U-Boot and their kernel never touches it again. - -Register a power-domain device to control this bit. Since we claim this -MMIO region in the H6 R-CCU driver, add the code here, so that we don't -need to artificially split the MMIO range in the DT. -Since there seems to be at least one other register with similar behaviour -nearby (0x7010260), make the power domain take one cell, even though we -only support domain #0 for now. - -Signed-off-by: Andre Przywara ---- - drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c | 84 ++++++++++++++++++++++++++ - 1 file changed, 84 insertions(+) - -diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c -index 02b28cfc5525e..363fb7a71e9f5 100644 ---- a/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c -+++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c -@@ -4,9 +4,11 @@ - */ - - #include -+#include - #include - #include - #include -+#include - - #include "ccu_common.h" - #include "ccu_reset.h" -@@ -217,6 +219,86 @@ static const struct sunxi_ccu_desc sun50i_h616_r_ccu_desc = { - .num_resets = ARRAY_SIZE(sun50i_h616_r_ccu_resets), - }; - -+#define PD_H616_GPU_REG 0x254 -+ -+struct sun50i_h616_ppu_pd { -+ struct generic_pm_domain genpd; -+ void __iomem *base; -+}; -+ -+#define to_sun50i_h616_ppu_pd(_genpd) \ -+ container_of(_genpd, struct sun50i_h616_ppu_pd, genpd) -+ -+static bool sun50i_h616_ppu_power_status(const struct sun50i_h616_ppu_pd *pd) -+{ -+ return !readl(pd->base + PD_H616_GPU_REG); -+} -+ -+static int sun50i_h616_ppu_pd_set_power(const struct sun50i_h616_ppu_pd *pd, -+ bool power_on) -+{ -+ if (power_on) -+ writel(0, pd->base + PD_H616_GPU_REG); -+ else -+ writel(1, pd->base + PD_H616_GPU_REG); -+ -+ return 0; -+} -+ -+static int sun50i_h616_ppu_pd_power_on(struct generic_pm_domain *genpd) -+{ -+ const struct sun50i_h616_ppu_pd *pd = to_sun50i_h616_ppu_pd(genpd); -+ -+ return sun50i_h616_ppu_pd_set_power(pd, true); -+} -+ -+static int sun50i_h616_ppu_pd_power_off(struct generic_pm_domain *genpd) -+{ -+ const struct sun50i_h616_ppu_pd *pd = to_sun50i_h616_ppu_pd(genpd); -+ -+ return sun50i_h616_ppu_pd_set_power(pd, false); -+} -+ -+static int sun50i_h616_register_ppu(struct platform_device *pdev, -+ void __iomem *base) -+{ -+ struct device *dev = &pdev->dev; -+ struct genpd_onecell_data *ppu; -+ struct sun50i_h616_ppu_pd *pd; -+ int ret; -+ -+ pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL); -+ if (!pd) -+ return -ENOMEM; -+ -+ ppu = devm_kzalloc(dev, sizeof(*ppu), GFP_KERNEL); -+ if (!ppu) -+ return -ENOMEM; -+ -+ ppu->domains = devm_kzalloc(dev, sizeof(*ppu->domains), GFP_KERNEL); -+ if (!ppu->domains) -+ return -ENOMEM; -+ -+ ppu->num_domains = 1; -+ pd->genpd.name = "GPU"; -+ pd->genpd.power_off = sun50i_h616_ppu_pd_power_off; -+ pd->genpd.power_on = sun50i_h616_ppu_pd_power_on; -+ pd->base = base; -+ -+ ret = pm_genpd_init(&pd->genpd, NULL, !sun50i_h616_ppu_power_status(pd)); -+ if (ret) { -+ dev_warn(dev, "Failed to add GPU power domain: %d\n", ret); -+ return ret; -+ } -+ -+ ppu->domains[0] = &pd->genpd; -+ ret = of_genpd_add_provider_onecell(dev->of_node, ppu); -+ if (ret) -+ dev_warn(dev, "Failed to add provider: %d\n", ret); -+ -+ return 0; -+} -+ - static int sun50i_h6_r_ccu_probe(struct platform_device *pdev) - { - const struct sunxi_ccu_desc *desc; -@@ -230,6 +312,8 @@ static int sun50i_h6_r_ccu_probe(struct platform_device *pdev) - if (IS_ERR(reg)) - return PTR_ERR(reg); - -+ sun50i_h616_register_ppu(pdev, reg); -+ - return devm_sunxi_ccu_probe(&pdev->dev, reg, desc); - } - --- -2.35.8 - diff --git a/board/anbernic/rg35xx-plus/patches/linux/0007-h6-r_dont_disable_GPU_power_domain.patch b/board/anbernic/rg35xx-plus/patches/linux/0007-h6-r_dont_disable_GPU_power_domain.patch deleted file mode 100644 index 65373b9801d7..000000000000 --- a/board/anbernic/rg35xx-plus/patches/linux/0007-h6-r_dont_disable_GPU_power_domain.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 16418f7d23805d055a6d14e189170be6fbd8205f Mon Sep 17 00:00:00 2001 -From: Ryan Walklin -Date: Tue, 28 May 2024 14:17:06 +1200 -Subject: [PATCH] clk: sunxi-ng: h6-r: don't disable GPU power domain? - ---- - drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c -index 991658fe8e84..b5af0ba8ae1b 100644 ---- a/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c -+++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c -@@ -239,8 +239,6 @@ static int sun50i_h616_ppu_pd_set_power(const struct sun50i_h616_ppu_pd *pd, - { - if (power_on) - writel(0, pd->base + PD_H616_GPU_REG); -- else -- writel(1, pd->base + PD_H616_GPU_REG); - - return 0; - } --- -2.45.2 - diff --git a/board/anbernic/rg35xx-plus/patches/linux/0008-h616_add_GPU_node.patch b/board/anbernic/rg35xx-plus/patches/linux/0008-h616_add_GPU_node.patch deleted file mode 100644 index 7bbb29c8352c..000000000000 --- a/board/anbernic/rg35xx-plus/patches/linux/0008-h616_add_GPU_node.patch +++ /dev/null @@ -1,45 +0,0 @@ -From bab10bd04e0661372fb522ba1a708b2bf3552e5a Mon Sep 17 00:00:00 2001 -From: Ryan Walklin -Date: Sun, 21 Jul 2024 22:19:13 +1200 -Subject: [PATCH] arm64: dts: allwinner: h616: add GPU node - ---- - arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi | 15 +++++++++++++++ - 1 file changed, 15 insertions(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi -index 83a1c4befab0..4717d60abd2f 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi -@@ -112,6 +112,20 @@ soc { - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x0 0x0 0x0 0x40000000>; -+ -+ gpu: gpu@1800000 { -+ compatible = "allwinner,sun50i-h616-mali", -+ "arm,mali-bifrost"; -+ reg = <0x1800000 0x40000>; -+ interrupts = , -+ , -+ ; -+ interrupt-names = "job", "mmu", "gpu"; -+ clocks = <&ccu CLK_GPU0>, <&ccu CLK_BUS_GPU>; -+ clock-names = "core", "bus"; -+ resets = <&ccu RST_BUS_GPU>; -+ status = "disabled"; -+ }; - - crypto: crypto@1904000 { - compatible = "allwinner,sun50i-h616-crypto"; -@@ -811,6 +825,7 @@ r_ccu: clock@7010000 { - clock-names = "hosc", "losc", "iosc", "pll-periph"; - #clock-cells = <1>; - #reset-cells = <1>; -+ #power-domain-cells = <1>; - }; - - nmi_intc: interrupt-controller@7010320 { --- -2.45.2 - diff --git a/board/anbernic/rg35xx-plus/patches/linux/0009-rg35xx-enable-gpu.patch b/board/anbernic/rg35xx-plus/patches/linux/0009-rg35xx-enable-gpu.patch deleted file mode 100644 index 77c8b9e24d3c..000000000000 --- a/board/anbernic/rg35xx-plus/patches/linux/0009-rg35xx-enable-gpu.patch +++ /dev/null @@ -1,65 +0,0 @@ -From cb4cf770d993d14e87ee20a74f66bc4cec77b528 Mon Sep 17 00:00:00 2001 -From: Philippe Simons -Date: Wed, 14 Aug 2024 19:01:59 +0200 -Subject: [PATCH] rg35xx: enable gpu - ---- - .../sun50i-h700-anbernic-rg35xx-2024.dts | 36 +++++++++++++++++++ - 1 file changed, 36 insertions(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts b/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts -index 99974e28c..37f852f4d 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts -@@ -224,12 +224,48 @@ panel_in_rgb: endpoint { - }; - }; - }; -+ -+ gpu_opp_table: opp-table-1 { -+ compatible = "operating-points-v2"; -+ -+ opp-420000000 { -+ opp-hz = /bits/ 64 <420000000>; -+ opp-microvolt = <940000>; -+ }; -+ opp-456000000 { -+ opp-hz = /bits/ 64 <456000000>; -+ opp-microvolt = <940000>; -+ }; -+ opp-504000000 { -+ opp-hz = /bits/ 64 <504000000>; -+ opp-microvolt = <940000>; -+ }; -+ opp-552000000 { -+ opp-hz = /bits/ 64 <552000000>; -+ opp-microvolt = <940000>; -+ }; -+ opp-600000000 { -+ opp-hz = /bits/ 64 <600000000>; -+ opp-microvolt = <940000>; -+ }; -+ opp-648000000 { -+ opp-hz = /bits/ 64 <648000000>; -+ opp-microvolt = <940000>; -+ }; -+ }; - }; - - &cpu0 { - cpu-supply = <®_dcdc1>; - }; - -+&gpu { -+ mali-supply = <®_dcdc2>; -+ power-domains = <&r_ccu 0>; -+ operating-points-v2 = <&gpu_opp_table>; -+ status = "okay"; -+}; -+ - &de { - status = "okay"; - }; --- -2.34.1 - diff --git a/board/anbernic/rg35xx-plus/patches/linux/9999-update-H700-opp-values.patch b/board/anbernic/rg35xx-plus/patches/linux/9999-update-H700-opp-values.patch deleted file mode 100644 index b038c3ec5baf..000000000000 --- a/board/anbernic/rg35xx-plus/patches/linux/9999-update-H700-opp-values.patch +++ /dev/null @@ -1,79 +0,0 @@ -From d3abcb2852ddc9edd4ebf42efdb1b41e56f41aea Mon Sep 17 00:00:00 2001 -From: Philippe Simons -Date: Thu, 28 Nov 2024 09:26:44 +0100 -Subject: [PATCH] update H700 opp values - -H700 devices are very unstable, especially with some OPPs. -Manufacturer (Anbernic) is using more conservative values, so let's use these. -Also, drop 1.5Ghz frequency. ---- - .../dts/allwinner/sun50i-h616-cpu-opp.dtsi | 19 +++++++++---------- - 1 file changed, 9 insertions(+), 10 deletions(-) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616-cpu-opp.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616-cpu-opp.dtsi -index dd10aaf47..ac13fe169 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h616-cpu-opp.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-cpu-opp.dtsi -@@ -50,24 +50,21 @@ opp-1008000000 { - opp-microvolt-speed2 = <950000>; - opp-microvolt-speed3 = <950000>; - opp-microvolt-speed4 = <1020000>; -- opp-microvolt-speed5 = <900000>; -+ opp-microvolt-speed5 = <950000>; - clock-latency-ns = <244144>; /* 8 32k periods */ - opp-supported-hw = <0x3f>; - }; - - opp-1032000000 { - opp-hz = /bits/ 64 <1032000000>; -- opp-microvolt = <900000>; -+ opp-microvolt = <950000>; - clock-latency-ns = <244144>; /* 8 32k periods */ - opp-supported-hw = <0x20>; - }; - - opp-1104000000 { - opp-hz = /bits/ 64 <1104000000>; -- opp-microvolt-speed0 = <1000000>; -- opp-microvolt-speed2 = <1000000>; -- opp-microvolt-speed3 = <1000000>; -- opp-microvolt-speed5 = <950000>; -+ opp-microvolt = <1000000>; - clock-latency-ns = <244144>; /* 8 32k periods */ - opp-supported-hw = <0x2d>; - }; -@@ -79,7 +76,7 @@ opp-1200000000 { - opp-microvolt-speed2 = <1050000>; - opp-microvolt-speed3 = <1050000>; - opp-microvolt-speed4 = <1100000>; -- opp-microvolt-speed5 = <1020000>; -+ opp-microvolt-speed5 = <1050000>; - clock-latency-ns = <244144>; /* 8 32k periods */ - opp-supported-hw = <0x3f>; - }; -@@ -93,7 +90,10 @@ opp-1320000000 { - - opp-1416000000 { - opp-hz = /bits/ 64 <1416000000>; -- opp-microvolt = <1100000>; -+ opp-microvolt-speed0 = <1100000>; -+ opp-microvolt-speed2 = <1100000>; -+ opp-microvolt-speed3 = <1100000>; -+ opp-microvolt-speed5 = <1160000>; - clock-latency-ns = <244144>; /* 8 32k periods */ - opp-supported-hw = <0x2d>; - }; -@@ -102,9 +102,8 @@ opp-1512000000 { - opp-hz = /bits/ 64 <1512000000>; - opp-microvolt-speed1 = <1100000>; - opp-microvolt-speed3 = <1100000>; -- opp-microvolt-speed5 = <1160000>; - clock-latency-ns = <244144>; /* 8 32k periods */ -- opp-supported-hw = <0x2a>; -+ opp-supported-hw = <0x0a>; - }; - }; - }; --- -2.46.1 - diff --git a/board/anbernic/rg35xx-plus/rocknix-h700.config b/board/anbernic/rg35xx-plus/rocknix-h700.config index 6f6d87d295a9..a0ae9d6634e9 100644 --- a/board/anbernic/rg35xx-plus/rocknix-h700.config +++ b/board/anbernic/rg35xx-plus/rocknix-h700.config @@ -599,8 +599,8 @@ CONFIG_CPU_FREQ=y CONFIG_CPU_FREQ_GOV_ATTR_SET=y CONFIG_CPU_FREQ_GOV_COMMON=y CONFIG_CPU_FREQ_STAT=y -CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE=y # CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set diff --git a/configs/anbernic_rg35xx_plus_defconfig b/configs/anbernic_rg35xx_plus_defconfig index 7c9396a61bb3..2b7a0101fae2 100644 --- a/configs/anbernic_rg35xx_plus_defconfig +++ b/configs/anbernic_rg35xx_plus_defconfig @@ -45,7 +45,7 @@ BR2_LINUX_KERNEL=y BR2_LINUX_KERNEL_CUSTOM_TARBALL=y BR2_LINUX_KERNEL_CUSTOM_TARBALL_LOCATION="https://git.kernel.org/torvalds/t/linux-6.12-rc1.tar.gz" BR2_LINUX_KERNEL_DTS_SUPPORT=y -BR2_LINUX_KERNEL_INTREE_DTS_NAME="allwinner/sun50i-h700-anbernic-rg35xx-plus" +BR2_LINUX_KERNEL_INTREE_DTS_NAME="allwinner/sun50i-h700-anbernic-rg35xx-plus allwinner/sun50i-h700-anbernic-rg35xx-plus-bsp" BR2_LINUX_KERNEL_NEEDS_HOST_OPENSSL=y BR2_LINUX_KERNEL_INSTALL_TARGET=y BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y @@ -88,21 +88,3 @@ BR2_PACKAGE_IWD=y BR2_PACKAGE_BUSYBOX_SHOW_OTHERS=y BR2_PACKAGE_BASH=y BR2_PACKAGE_STRESS_NG=y -BR2_PACKAGE_RNG_TOOLS=y - -BR2_PACKAGE_ALSA_UTILS=y -BR2_PACKAGE_ALSA_UTILS_ALSAMIXER=y -BR2_PACKAGE_ALSA_UTILS_AMIXER=y -BR2_PACKAGE_ALSA_UTILS_APLAY=y -BR2_PACKAGE_ALSA_UTILS_SPEAKER_TEST=y - -BR2_TOOLCHAIN_BUILDROOT_CXX=y -BR2_PACKAGE_EUDEV=y -BR2_ROOTFS_DEVICE_CREATION_DYNAMIC_EUDEV=y - -BR2_PACKAGE_MESA3D=y -BR2_PACKAGE_MESA3D_OPENGL_EGL=y -BR2_PACKAGE_MESA3D_OPENGL_ES=y -BR2_PACKAGE_MESA3D_GALLIUM_DRIVER_PANFROST=y -BR2_PACKAGE_GLMARK2=y -BR2_PACKAGE_GLMARK2_FLAVOR_DRM_GLESV2=y \ No newline at end of file