[PATCH v2 0/5] sunxi: video: Add V3S simple-framebuffer

There are patches to enable "allwinner,simple-framebuffer" with "mixer0-lcd0" pipeline for V3s.
First patch updates V3s dts(i) from Linux-v5.9. Second patch enable simple-framebuffer in V3s dtsi (planed merge in Linux-v5.11) Third patch enable PWM0 (for backlight support). Fourth patch is the main extension to code and build: - V3s has 2x VI and 1x UI channels (use UI channel), so use third channel. - V3s uses PLL3 (PLL_VIDEO) for both DE2 and TCON0 pixelclock. PLL10 is used for DDR2. PLL3 does not support doubleclock. - V3s supports resolution upto 1024x1024. Also scale down memory requirements for V3s (64MB embedded DDR2) - V3s does not support HDMI. Fifth patch enable PWM drivers and corrects CONFIG_VIDEO_LCD_DCLK_PHASE.
Tested with "Lichee Zero" V3s and 800x600 LCD (not configured DRM DE2/TCON0/panel in linux DTS). To enable functionality see TESTING patch at - https://github.com/mcerveny/u-boot/tree/simplefb_v3s_v2
Changes since v1: - problematic patch for generic DE2 suppress of doubleclock search was redesigned for V3s only - changes dts(i) was synced from Linux-v5.9 and additional patch to enable simple-framebuffer
Martin Cerveny (5): ARM: dts: sun8i: Update V3s dts(i) files from Linux-v5.9 ARM: dts: sun8i: v3s: Add simple-framebuffer pwm: sunxi: v3s: Enable PWM0 sunxi: video: v3s: Enable LCD support sunxi: add drivers and configs needed for LCD display
arch/arm/dts/sun8i-v3s-licheepi-zero.dts | 26 ++- arch/arm/dts/sun8i-v3s.dtsi | 216 +++++++++++++++--- arch/arm/include/asm/arch-sunxi/clock_sun6i.h | 5 +- arch/arm/include/asm/arch-sunxi/gpio.h | 2 + arch/arm/mach-sunxi/Kconfig | 1 + configs/LicheePi_Zero_defconfig | 4 + drivers/pwm/sunxi_pwm.c | 3 + drivers/video/sunxi/lcdc.c | 5 +- drivers/video/sunxi/sunxi_de2.c | 25 +- drivers/video/sunxi/sunxi_dw_hdmi.c | 2 + drivers/video/sunxi/sunxi_lcd.c | 9 +- 11 files changed, 260 insertions(+), 38 deletions(-)

Update all V3s devicetree dts and dtsi files from Linux-v5.9.
Signed-off-by: Martin Cerveny m.cerveny@computer.org --- arch/arm/dts/sun8i-v3s-licheepi-zero.dts | 26 ++- arch/arm/dts/sun8i-v3s.dtsi | 200 ++++++++++++++++++++--- 2 files changed, 196 insertions(+), 30 deletions(-)
diff --git a/arch/arm/dts/sun8i-v3s-licheepi-zero.dts b/arch/arm/dts/sun8i-v3s-licheepi-zero.dts index 3d9168cbae..2e4587d26c 100644 --- a/arch/arm/dts/sun8i-v3s-licheepi-zero.dts +++ b/arch/arm/dts/sun8i-v3s-licheepi-zero.dts @@ -55,11 +55,29 @@ chosen { stdout-path = "serial0:115200n8"; }; + + leds { + compatible = "gpio-leds"; + + blue_led { + label = "licheepi:blue:usr"; + gpios = <&pio 6 1 GPIO_ACTIVE_LOW>; /* PG1 */ + }; + + green_led { + label = "licheepi:green:usr"; + gpios = <&pio 6 0 GPIO_ACTIVE_LOW>; /* PG0 */ + default-state = "on"; + }; + + red_led { + label = "licheepi:red:usr"; + gpios = <&pio 6 2 GPIO_ACTIVE_LOW>; /* PG2 */ + }; + }; };
&mmc0 { - pinctrl-0 = <&mmc0_pins_a>; - pinctrl-names = "default"; broken-cd; bus-width = <4>; vmmc-supply = <®_vcc3v3>; @@ -67,7 +85,7 @@ };
&uart0 { - pinctrl-0 = <&uart0_pins_a>; + pinctrl-0 = <&uart0_pb_pins>; pinctrl-names = "default"; status = "okay"; }; @@ -78,6 +96,6 @@ };
&usbphy { - usb0_id_det-gpio = <&pio 5 6 GPIO_ACTIVE_HIGH>; + usb0_id_det-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; status = "okay"; }; diff --git a/arch/arm/dts/sun8i-v3s.dtsi b/arch/arm/dts/sun8i-v3s.dtsi index ebefc0fefe..e5312869c0 100644 --- a/arch/arm/dts/sun8i-v3s.dtsi +++ b/arch/arm/dts/sun8i-v3s.dtsi @@ -40,10 +40,9 @@ * OTHER DEALINGS IN THE SOFTWARE. */
+#include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/clock/sun8i-v3s-ccu.h> #include <dt-bindings/reset/sun8i-v3s-ccu.h> -#include <dt-bindings/interrupt-controller/arm-gic.h> -#include <dt-bindings/pinctrl/sun4i-a10.h>
/ { #address-cells = <1>; @@ -62,6 +61,12 @@ }; };
+ de: display-engine { + compatible = "allwinner,sun8i-v3s-display-engine"; + allwinner,pipelines = <&mixer0>; + status = "disabled"; + }; + timer { compatible = "arm,armv7-timer"; interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, @@ -79,6 +84,7 @@ #clock-cells = <0>; compatible = "fixed-clock"; clock-frequency = <24000000>; + clock-accuracy = <50000>; clock-output-names = "osc24M"; };
@@ -86,7 +92,8 @@ #clock-cells = <0>; compatible = "fixed-clock"; clock-frequency = <32768>; - clock-output-names = "osc32k"; + clock-accuracy = <50000>; + clock-output-names = "ext-osc32k"; }; };
@@ -96,7 +103,77 @@ #size-cells = <1>; ranges;
- mmc0: mmc@01c0f000 { + display_clocks: clock@1000000 { + compatible = "allwinner,sun8i-v3s-de2-clk"; + reg = <0x01000000 0x10000>; + clocks = <&ccu CLK_BUS_DE>, + <&ccu CLK_DE>; + clock-names = "bus", + "mod"; + resets = <&ccu RST_BUS_DE>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + mixer0: mixer@1100000 { + compatible = "allwinner,sun8i-v3s-de2-mixer"; + reg = <0x01100000 0x100000>; + clocks = <&display_clocks 0>, + <&display_clocks 6>; + clock-names = "bus", + "mod"; + resets = <&display_clocks 0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + mixer0_out: port@1 { + reg = <1>; + + mixer0_out_tcon0: endpoint { + remote-endpoint = <&tcon0_in_mixer0>; + }; + }; + }; + }; + + tcon0: lcd-controller@1c0c000 { + compatible = "allwinner,sun8i-v3s-tcon"; + reg = <0x01c0c000 0x1000>; + interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_TCON0>, + <&ccu CLK_TCON0>; + clock-names = "ahb", + "tcon-ch0"; + clock-output-names = "tcon-pixel-clock"; + #clock-cells = <0>; + resets = <&ccu RST_BUS_TCON0>; + reset-names = "lcd"; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + tcon0_in: port@0 { + reg = <0>; + + tcon0_in_mixer0: endpoint { + remote-endpoint = <&mixer0_out_tcon0>; + }; + }; + + tcon0_out: port@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + }; + }; + + + mmc0: mmc@1c0f000 { compatible = "allwinner,sun7i-a20-mmc"; reg = <0x01c0f000 0x1000>; clocks = <&ccu CLK_BUS_MMC0>, @@ -110,12 +187,14 @@ resets = <&ccu RST_BUS_MMC0>; reset-names = "ahb"; interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins>; status = "disabled"; #address-cells = <1>; #size-cells = <0>; };
- mmc1: mmc@01c10000 { + mmc1: mmc@1c10000 { compatible = "allwinner,sun7i-a20-mmc"; reg = <0x01c10000 0x1000>; clocks = <&ccu CLK_BUS_MMC1>, @@ -129,12 +208,14 @@ resets = <&ccu RST_BUS_MMC1>; reset-names = "ahb"; interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&mmc1_pins>; status = "disabled"; #address-cells = <1>; #size-cells = <0>; };
- mmc2: mmc@01c11000 { + mmc2: mmc@1c11000 { compatible = "allwinner,sun7i-a20-mmc"; reg = <0x01c11000 0x1000>; clocks = <&ccu CLK_BUS_MMC2>, @@ -153,7 +234,7 @@ #size-cells = <0>; };
- usb_otg: usb@01c19000 { + usb_otg: usb@1c19000 { compatible = "allwinner,sun8i-h3-musb"; reg = <0x01c19000 0x0400>; clocks = <&ccu CLK_BUS_OTG>; @@ -166,7 +247,7 @@ status = "disabled"; };
- usbphy: phy@01c19400 { + usbphy: phy@1c19400 { compatible = "allwinner,sun8i-v3s-usb-phy"; reg = <0x01c19400 0x2c>, <0x01c1a800 0x4>; @@ -180,64 +261,93 @@ #phy-cells = <1>; };
- ccu: clock@01c20000 { + ccu: clock@1c20000 { compatible = "allwinner,sun8i-v3s-ccu"; reg = <0x01c20000 0x400>; - clocks = <&osc24M>, <&osc32k>; + clocks = <&osc24M>, <&rtc 0>; clock-names = "hosc", "losc"; #clock-cells = <1>; #reset-cells = <1>; };
- rtc: rtc@01c20400 { - compatible = "allwinner,sun6i-a31-rtc"; + rtc: rtc@1c20400 { + #clock-cells = <1>; + compatible = "allwinner,sun8i-v3-rtc"; reg = <0x01c20400 0x54>; interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&osc32k>; + clock-output-names = "osc32k", "osc32k-out"; };
- pio: pinctrl@01c20800 { + pio: pinctrl@1c20800 { compatible = "allwinner,sun8i-v3s-pinctrl"; reg = <0x01c20800 0x400>; interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&ccu CLK_BUS_PIO>, <&osc24M>, <&osc32k>; + clocks = <&ccu CLK_BUS_PIO>, <&osc24M>, <&rtc 0>; clock-names = "apb", "hosc", "losc"; gpio-controller; #gpio-cells = <3>; interrupt-controller; #interrupt-cells = <3>;
- uart0_pins_a: uart0@0 { + i2c0_pins: i2c0-pins { + pins = "PB6", "PB7"; + function = "i2c0"; + }; + + uart0_pb_pins: uart0-pb-pins { pins = "PB8", "PB9"; function = "uart0"; - bias-pull-up; };
- mmc0_pins_a: mmc0@0 { + mmc0_pins: mmc0-pins { pins = "PF0", "PF1", "PF2", "PF3", "PF4", "PF5"; function = "mmc0"; drive-strength = <30>; bias-pull-up; }; + + mmc1_pins: mmc1-pins { + pins = "PG0", "PG1", "PG2", "PG3", + "PG4", "PG5"; + function = "mmc1"; + drive-strength = <30>; + bias-pull-up; + }; + + spi0_pins: spi0-pins { + pins = "PC0", "PC1", "PC2", "PC3"; + function = "spi0"; + }; };
- timer@01c20c00 { - compatible = "allwinner,sun4i-a10-timer"; + timer@1c20c00 { + compatible = "allwinner,sun8i-v3s-timer"; reg = <0x01c20c00 0xa0>; interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>; + <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>; clocks = <&osc24M>; };
- wdt0: watchdog@01c20ca0 { + wdt0: watchdog@1c20ca0 { compatible = "allwinner,sun6i-a31-wdt"; reg = <0x01c20ca0 0x20>; interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&osc24M>; };
- uart0: serial@01c28000 { + lradc: lradc@1c22800 { + compatible = "allwinner,sun4i-a10-lradc-keys"; + reg = <0x01c22800 0x400>; + interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + uart0: serial@1c28000 { compatible = "snps,dw-apb-uart"; reg = <0x01c28000 0x400>; interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>; @@ -248,7 +358,7 @@ status = "disabled"; };
- uart1: serial@01c28400 { + uart1: serial@1c28400 { compatible = "snps,dw-apb-uart"; reg = <0x01c28400 0x400>; interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>; @@ -259,7 +369,7 @@ status = "disabled"; };
- uart2: serial@01c28800 { + uart2: serial@1c28800 { compatible = "snps,dw-apb-uart"; reg = <0x01c28800 0x400>; interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>; @@ -270,8 +380,46 @@ status = "disabled"; };
- gic: interrupt-controller@01c81000 { - compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic"; + i2c0: i2c@1c2ac00 { + compatible = "allwinner,sun6i-a31-i2c"; + reg = <0x01c2ac00 0x400>; + interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_I2C0>; + resets = <&ccu RST_BUS_I2C0>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c1: i2c@1c2b000 { + compatible = "allwinner,sun6i-a31-i2c"; + reg = <0x01c2b000 0x400>; + interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_I2C1>; + resets = <&ccu RST_BUS_I2C1>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + spi0: spi@1c68000 { + compatible = "allwinner,sun8i-h3-spi"; + reg = <0x01c68000 0x1000>; + interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_SPI0>, <&ccu CLK_SPI0>; + clock-names = "ahb", "mod"; + pinctrl-names = "default"; + pinctrl-0 = <&spi0_pins>; + resets = <&ccu RST_BUS_SPI0>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + gic: interrupt-controller@1c81000 { + compatible = "arm,gic-400"; reg = <0x01c81000 0x1000>, <0x01c82000 0x1000>, <0x01c84000 0x2000>,

Add support for "allwinner,simple-framebuffer" with "mixer0-lcd0" pipeline.
Signed-off-by: Martin Cerveny m.cerveny@computer.org --- arch/arm/dts/sun8i-v3s.dtsi | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
diff --git a/arch/arm/dts/sun8i-v3s.dtsi b/arch/arm/dts/sun8i-v3s.dtsi index e5312869c0..b93dd69bf3 100644 --- a/arch/arm/dts/sun8i-v3s.dtsi +++ b/arch/arm/dts/sun8i-v3s.dtsi @@ -43,12 +43,28 @@ #include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/clock/sun8i-v3s-ccu.h> #include <dt-bindings/reset/sun8i-v3s-ccu.h> +#include <dt-bindings/clock/sun8i-de2.h>
/ { #address-cells = <1>; #size-cells = <1>; interrupt-parent = <&gic>;
+ chosen { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + framebuffer-lcd { + compatible = "allwinner,simple-framebuffer", + "simple-framebuffer"; + allwinner,pipeline = "mixer0-lcd0"; + clocks = <&display_clocks CLK_MIXER0>, + <&ccu CLK_TCON0>; + status = "disabled"; + }; + }; + cpus { #address-cells = <1>; #size-cells = <0>;

On Fri, Oct 16, 2020 at 07:17:02PM +0200, Martin Cerveny wrote:
Add support for "allwinner,simple-framebuffer" with "mixer0-lcd0" pipeline.
Signed-off-by: Martin Cerveny m.cerveny@computer.org
Acked-by: Maxime Ripard mripard@kernel.org
Maxime

Enable PWM0 for V3S (for backlight LCD support).
Signed-off-by: Martin Cerveny m.cerveny@computer.org --- arch/arm/include/asm/arch-sunxi/gpio.h | 1 + drivers/pwm/sunxi_pwm.c | 3 +++ 2 files changed, 4 insertions(+)
diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h index a646ea6a3c..d83dfdf605 100644 --- a/arch/arm/include/asm/arch-sunxi/gpio.h +++ b/arch/arm/include/asm/arch-sunxi/gpio.h @@ -164,6 +164,7 @@ enum sunxi_gpio_number { #define SUN8I_A33_GPB_UART0 3 #define SUN8I_A83T_GPB_UART0 2 #define SUN8I_V3S_GPB_UART0 3 +#define SUN8I_V3S_GPB_PWM0 2 #define SUN50I_GPB_UART0 4
#define SUNXI_GPC_NAND 2 diff --git a/drivers/pwm/sunxi_pwm.c b/drivers/pwm/sunxi_pwm.c index e2ae1a8009..136e7c63d3 100644 --- a/drivers/pwm/sunxi_pwm.c +++ b/drivers/pwm/sunxi_pwm.c @@ -48,6 +48,8 @@ static int sunxi_pwm_config_pinmux(void) { #ifdef CONFIG_MACH_SUN50I sunxi_gpio_set_cfgpin(SUNXI_GPD(22), SUNXI_GPD_PWM); +#elif defined CONFIG_MACH_SUN8I_V3S + sunxi_gpio_set_cfgpin(SUNXI_GPB(4), SUN8I_V3S_GPB_PWM0); #endif return 0; } @@ -171,6 +173,7 @@ static const struct pwm_ops sunxi_pwm_ops = { static const struct udevice_id sunxi_pwm_ids[] = { { .compatible = "allwinner,sun5i-a13-pwm" }, { .compatible = "allwinner,sun50i-a64-pwm" }, + { .compatible = "allwinner,sun7i-a20-pwm" }, { } };

Enable support for V3s LCD display with following changes:
V3s has 2x VI and 1x UI channels (use UI channel). V3s uses PLL3 (PLL_VIDEO) for both DE2 and TCON0 pixelclock. V3s does not support doubleclock for PLL3. V3s supports resolution upto 1024x1024. V3s does not support HDMI.
Signed-off-by: Martin Cerveny m.cerveny@computer.org --- arch/arm/include/asm/arch-sunxi/clock_sun6i.h | 5 ++-- arch/arm/include/asm/arch-sunxi/gpio.h | 1 + arch/arm/mach-sunxi/Kconfig | 1 + drivers/video/sunxi/lcdc.c | 5 ++-- drivers/video/sunxi/sunxi_de2.c | 25 ++++++++++++++++--- drivers/video/sunxi/sunxi_dw_hdmi.c | 2 ++ drivers/video/sunxi/sunxi_lcd.c | 9 ++++++- 7 files changed, 40 insertions(+), 8 deletions(-)
diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h index ee387127f3..9efe05d103 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h @@ -329,7 +329,7 @@ struct sunxi_ccm_reg { #define AHB_GATE_OFFSET_DE 12 #define AHB_GATE_OFFSET_HDMI 11 #define AHB_GATE_OFFSET_TVE 9 -#ifndef CONFIG_SUNXI_DE2 +#if !defined(CONFIG_SUNXI_DE2) || defined(CONFIG_MACH_SUN8I_V3S) #define AHB_GATE_OFFSET_LCD1 5 #define AHB_GATE_OFFSET_LCD0 4 #else @@ -476,7 +476,7 @@ struct sunxi_ccm_reg { #define AHB_RESET_OFFSET_HDMI 11 #define AHB_RESET_OFFSET_HDMI2 10 #define AHB_RESET_OFFSET_TVE 9 -#ifndef CONFIG_SUNXI_DE2 +#if !defined(CONFIG_SUNXI_DE2) || defined(CONFIG_MACH_SUN8I_V3S) #define AHB_RESET_OFFSET_LCD1 5 #define AHB_RESET_OFFSET_LCD0 4 #else @@ -510,6 +510,7 @@ struct sunxi_ccm_reg { #define CCM_DE2_CTRL_PLL_MASK (3 << 24) #define CCM_DE2_CTRL_PLL6_2X (0 << 24) #define CCM_DE2_CTRL_PLL10 (1 << 24) +#define CCM_DE2_CTRL_PLL3_V3S (0 << 24) #define CCM_DE2_CTRL_GATE (0x1 << 31)
/* CCU security switch, H3 only */ diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h index d83dfdf605..9b580fbe26 100644 --- a/arch/arm/include/asm/arch-sunxi/gpio.h +++ b/arch/arm/include/asm/arch-sunxi/gpio.h @@ -181,6 +181,7 @@ enum sunxi_gpio_number { #define SUN5I_GPE_SDC2 3 #define SUN8I_GPE_TWI2 3 #define SUN50I_GPE_TWI2 3 +#define SUN8I_V3S_GPE_LCD0 3
#define SUNXI_GPF_SDC0 2 #define SUNXI_GPF_UART0 4 diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index be0822bfb7..dc0ee2cdef 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig @@ -258,6 +258,7 @@ config MACH_SUN8I_V3S select CPU_V7_HAS_NONSEC select CPU_V7_HAS_VIRT select ARCH_SUPPORT_PSCI + select SUNXI_DE2 select SUNXI_GEN_SUN6I select SUNXI_DRAM_DW select SUNXI_DRAM_DW_16BIT diff --git a/drivers/video/sunxi/lcdc.c b/drivers/video/sunxi/lcdc.c index 73033c3b85..3d50f9d567 100644 --- a/drivers/video/sunxi/lcdc.c +++ b/drivers/video/sunxi/lcdc.c @@ -244,7 +244,7 @@ void lcdc_pll_set(struct sunxi_ccm_reg *ccm, int tcon, int dotclock, * not sync to higher frequencies. */ for (m = min_m; m <= max_m; m++) { -#ifndef CONFIG_SUNXI_DE2 +#if !defined(CONFIG_SUNXI_DE2) || defined(CONFIG_MACH_SUN8I_V3S) n = (m * dotclock) / step;
if ((n >= 9) && (n <= 127)) { @@ -262,7 +262,7 @@ void lcdc_pll_set(struct sunxi_ccm_reg *ccm, int tcon, int dotclock, if (!(m & 1)) continue; #endif - +#ifndef CONFIG_MACH_SUN8I_V3S /* No double clock on DE2 */ n = (m * dotclock) / (step * 2); if ((n >= 9) && (n <= 127)) { @@ -275,6 +275,7 @@ void lcdc_pll_set(struct sunxi_ccm_reg *ccm, int tcon, int dotclock, best_double = 1; } } +#endif }
#ifdef CONFIG_MACH_SUN6I diff --git a/drivers/video/sunxi/sunxi_de2.c b/drivers/video/sunxi/sunxi_de2.c index b657e163f0..49d41eb243 100644 --- a/drivers/video/sunxi/sunxi_de2.c +++ b/drivers/video/sunxi/sunxi_de2.c @@ -26,12 +26,21 @@
DECLARE_GLOBAL_DATA_PTR;
+#ifdef CONFIG_MACH_SUN8I_V3S +enum { + /* Maximum LCD size we support */ + LCD_MAX_WIDTH = 1024, + LCD_MAX_HEIGHT = 1024, + LCD_MAX_LOG2_BPP = VIDEO_BPP32, +}; +#else enum { /* Maximum LCD size we support */ LCD_MAX_WIDTH = 3840, LCD_MAX_HEIGHT = 2160, LCD_MAX_LOG2_BPP = VIDEO_BPP32, }; +#endif
static void sunxi_de2_composer_init(void) { @@ -47,11 +56,19 @@ static void sunxi_de2_composer_init(void) writel(reg_value, SUNXI_SRAMC_BASE + 0x04); #endif
+#ifdef CONFIG_MACH_SUN8I_V3S + clock_set_pll3(50000000); + /* pll3 is also used for pixelclock and speed will be recomputed */ + /* Set DE parent to pll3 */ + clrsetbits_le32(&ccm->de_clk_cfg, CCM_DE2_CTRL_PLL_MASK, + CCM_DE2_CTRL_PLL3_V3S); +#else clock_set_pll10(432000000);
/* Set DE parent to pll10 */ clrsetbits_le32(&ccm->de_clk_cfg, CCM_DE2_CTRL_PLL_MASK, CCM_DE2_CTRL_PLL10); +#endif
/* Set ahb gating to pass */ setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_DE); @@ -77,7 +94,8 @@ static void sunxi_de2_mode_set(int mux, const struct display_timing *mode, struct de_ui * const de_ui_regs = (struct de_ui *)(de_mux_base + SUNXI_DE2_MUX_CHAN_REGS + - SUNXI_DE2_MUX_CHAN_SZ * 1); + SUNXI_DE2_MUX_CHAN_SZ * + (IS_ENABLED(CONFIG_MACH_SUN8I_V3S) ? 2 : 1)); struct de_csc * const de_csc_regs = (struct de_csc *)(de_mux_base + SUNXI_DE2_MUX_DCSC_REGS); @@ -104,14 +122,15 @@ static void sunxi_de2_mode_set(int mux, const struct display_timing *mode, for (channel = 0; channel < 4; channel++) { void *ch = (void *)(de_mux_base + SUNXI_DE2_MUX_CHAN_REGS + SUNXI_DE2_MUX_CHAN_SZ * channel); - memset(ch, 0, (channel == 0) ? + memset(ch, 0, (channel == 0 || + (IS_ENABLED(CONFIG_MACH_SUN8I_V3S) && channel == 1)) ? sizeof(struct de_vi) : sizeof(struct de_ui)); } memset(de_bld_regs, 0, sizeof(struct de_bld));
writel(0x00000101, &de_bld_regs->fcolor_ctl);
- writel(1, &de_bld_regs->route); + writel(IS_ENABLED(CONFIG_MACH_SUN8I_V3S) ? 2 : 1, &de_bld_regs->route);
writel(0, &de_bld_regs->premultiply); writel(0xff000000, &de_bld_regs->bkcolor); diff --git a/drivers/video/sunxi/sunxi_dw_hdmi.c b/drivers/video/sunxi/sunxi_dw_hdmi.c index 01d4b7a11c..899fbe2f7f 100644 --- a/drivers/video/sunxi/sunxi_dw_hdmi.c +++ b/drivers/video/sunxi/sunxi_dw_hdmi.c @@ -398,6 +398,8 @@ U_BOOT_DRIVER(sunxi_dw_hdmi) = { .priv_auto_alloc_size = sizeof(struct sunxi_dw_hdmi_priv), };
+#ifndef CONFIG_MACH_SUN8I_V3S U_BOOT_DEVICE(sunxi_dw_hdmi) = { .name = "sunxi_dw_hdmi" }; +#endif diff --git a/drivers/video/sunxi/sunxi_lcd.c b/drivers/video/sunxi/sunxi_lcd.c index 49bf083a8d..2543da3feb 100644 --- a/drivers/video/sunxi/sunxi_lcd.c +++ b/drivers/video/sunxi/sunxi_lcd.c @@ -32,6 +32,13 @@ static void sunxi_lcdc_config_pinmux(void) sunxi_gpio_set_cfgpin(pin, SUNXI_GPD_LCD0); sunxi_gpio_set_drv(pin, 3); } +#elif defined(CONFIG_MACH_SUN8I_V3S) + int pin; + + for (pin = SUNXI_GPE(0); pin <= SUNXI_GPE(19); pin++) + sunxi_gpio_set_cfgpin(pin, SUN8I_V3S_GPE_LCD0); + sunxi_gpio_set_cfgpin(SUNXI_GPE(23), SUN8I_V3S_GPE_LCD0); + sunxi_gpio_set_cfgpin(SUNXI_GPE(24), SUN8I_V3S_GPE_LCD0); #endif }
@@ -145,7 +152,7 @@ U_BOOT_DRIVER(sunxi_lcd) = { .priv_auto_alloc_size = sizeof(struct sunxi_lcd_priv), };
-#ifdef CONFIG_MACH_SUN50I +#if defined(CONFIG_MACH_SUN50I) || defined(CONFIG_MACH_SUN8I_V3S) U_BOOT_DEVICE(sunxi_lcd) = { .name = "sunxi_lcd" };

On Fri, Oct 16, 2020 at 07:17:04PM +0200, Martin Cerveny wrote:
Enable support for V3s LCD display with following changes:
V3s has 2x VI and 1x UI channels (use UI channel). V3s uses PLL3 (PLL_VIDEO) for both DE2 and TCON0 pixelclock. V3s does not support doubleclock for PLL3. V3s supports resolution upto 1024x1024. V3s does not support HDMI.
Signed-off-by: Martin Cerveny m.cerveny@computer.org
arch/arm/include/asm/arch-sunxi/clock_sun6i.h | 5 ++-- arch/arm/include/asm/arch-sunxi/gpio.h | 1 + arch/arm/mach-sunxi/Kconfig | 1 + drivers/video/sunxi/lcdc.c | 5 ++-- drivers/video/sunxi/sunxi_de2.c | 25 ++++++++++++++++--- drivers/video/sunxi/sunxi_dw_hdmi.c | 2 ++ drivers/video/sunxi/sunxi_lcd.c | 9 ++++++- 7 files changed, 40 insertions(+), 8 deletions(-)
diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h index ee387127f3..9efe05d103 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h @@ -329,7 +329,7 @@ struct sunxi_ccm_reg { #define AHB_GATE_OFFSET_DE 12 #define AHB_GATE_OFFSET_HDMI 11 #define AHB_GATE_OFFSET_TVE 9 -#ifndef CONFIG_SUNXI_DE2 +#if !defined(CONFIG_SUNXI_DE2) || defined(CONFIG_MACH_SUN8I_V3S) #define AHB_GATE_OFFSET_LCD1 5 #define AHB_GATE_OFFSET_LCD0 4 #else @@ -476,7 +476,7 @@ struct sunxi_ccm_reg { #define AHB_RESET_OFFSET_HDMI 11 #define AHB_RESET_OFFSET_HDMI2 10 #define AHB_RESET_OFFSET_TVE 9 -#ifndef CONFIG_SUNXI_DE2 +#if !defined(CONFIG_SUNXI_DE2) || defined(CONFIG_MACH_SUN8I_V3S)
These two changes are confusing. The V3S has a DE2, so having that condition is weird. I'd just add an elif there
#define AHB_RESET_OFFSET_LCD1 5 #define AHB_RESET_OFFSET_LCD0 4 #else @@ -510,6 +510,7 @@ struct sunxi_ccm_reg { #define CCM_DE2_CTRL_PLL_MASK (3 << 24) #define CCM_DE2_CTRL_PLL6_2X (0 << 24) #define CCM_DE2_CTRL_PLL10 (1 << 24) +#define CCM_DE2_CTRL_PLL3_V3S (0 << 24) #define CCM_DE2_CTRL_GATE (0x1 << 31)
/* CCU security switch, H3 only */ diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h index d83dfdf605..9b580fbe26 100644 --- a/arch/arm/include/asm/arch-sunxi/gpio.h +++ b/arch/arm/include/asm/arch-sunxi/gpio.h @@ -181,6 +181,7 @@ enum sunxi_gpio_number { #define SUN5I_GPE_SDC2 3 #define SUN8I_GPE_TWI2 3 #define SUN50I_GPE_TWI2 3 +#define SUN8I_V3S_GPE_LCD0 3
#define SUNXI_GPF_SDC0 2 #define SUNXI_GPF_UART0 4 diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index be0822bfb7..dc0ee2cdef 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig @@ -258,6 +258,7 @@ config MACH_SUN8I_V3S select CPU_V7_HAS_NONSEC select CPU_V7_HAS_VIRT select ARCH_SUPPORT_PSCI
- select SUNXI_DE2 select SUNXI_GEN_SUN6I select SUNXI_DRAM_DW select SUNXI_DRAM_DW_16BIT
diff --git a/drivers/video/sunxi/lcdc.c b/drivers/video/sunxi/lcdc.c index 73033c3b85..3d50f9d567 100644 --- a/drivers/video/sunxi/lcdc.c +++ b/drivers/video/sunxi/lcdc.c @@ -244,7 +244,7 @@ void lcdc_pll_set(struct sunxi_ccm_reg *ccm, int tcon, int dotclock, * not sync to higher frequencies. */ for (m = min_m; m <= max_m; m++) { -#ifndef CONFIG_SUNXI_DE2 +#if !defined(CONFIG_SUNXI_DE2) || defined(CONFIG_MACH_SUN8I_V3S) n = (m * dotclock) / step;
if ((n >= 9) && (n <= 127)) {
@@ -262,7 +262,7 @@ void lcdc_pll_set(struct sunxi_ccm_reg *ccm, int tcon, int dotclock, if (!(m & 1)) continue; #endif
+#ifndef CONFIG_MACH_SUN8I_V3S /* No double clock on DE2 */ n = (m * dotclock) / (step * 2); if ((n >= 9) && (n <= 127)) { @@ -275,6 +275,7 @@ void lcdc_pll_set(struct sunxi_ccm_reg *ccm, int tcon, int dotclock, best_double = 1; } } +#endif
I'm still not seeing any indication as to where you're getting this from
}
#ifdef CONFIG_MACH_SUN6I diff --git a/drivers/video/sunxi/sunxi_de2.c b/drivers/video/sunxi/sunxi_de2.c index b657e163f0..49d41eb243 100644 --- a/drivers/video/sunxi/sunxi_de2.c +++ b/drivers/video/sunxi/sunxi_de2.c @@ -26,12 +26,21 @@
DECLARE_GLOBAL_DATA_PTR;
+#ifdef CONFIG_MACH_SUN8I_V3S +enum {
- /* Maximum LCD size we support */
- LCD_MAX_WIDTH = 1024,
- LCD_MAX_HEIGHT = 1024,
- LCD_MAX_LOG2_BPP = VIDEO_BPP32,
+}; +#else enum { /* Maximum LCD size we support */ LCD_MAX_WIDTH = 3840, LCD_MAX_HEIGHT = 2160, LCD_MAX_LOG2_BPP = VIDEO_BPP32, }; +#endif
static void sunxi_de2_composer_init(void) { @@ -47,11 +56,19 @@ static void sunxi_de2_composer_init(void) writel(reg_value, SUNXI_SRAMC_BASE + 0x04); #endif
+#ifdef CONFIG_MACH_SUN8I_V3S
- clock_set_pll3(50000000);
- /* pll3 is also used for pixelclock and speed will be recomputed */
- /* Set DE parent to pll3 */
- clrsetbits_le32(&ccm->de_clk_cfg, CCM_DE2_CTRL_PLL_MASK,
CCM_DE2_CTRL_PLL3_V3S);
+#else clock_set_pll10(432000000);
/* Set DE parent to pll10 */ clrsetbits_le32(&ccm->de_clk_cfg, CCM_DE2_CTRL_PLL_MASK, CCM_DE2_CTRL_PLL10); +#endif
/* Set ahb gating to pass */ setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_DE); @@ -77,7 +94,8 @@ static void sunxi_de2_mode_set(int mux, const struct display_timing *mode, struct de_ui * const de_ui_regs = (struct de_ui *)(de_mux_base + SUNXI_DE2_MUX_CHAN_REGS +
SUNXI_DE2_MUX_CHAN_SZ * 1);
SUNXI_DE2_MUX_CHAN_SZ *
(IS_ENABLED(CONFIG_MACH_SUN8I_V3S) ? 2 : 1));
Why do you need to use two UI channels? Isn't one enough?
Maxime

On Mon, 19 Oct 2020, Maxime Ripard wrote:
On Fri, Oct 16, 2020 at 07:17:04PM +0200, Martin Cerveny wrote:
Enable support for V3s LCD display with following changes:
V3s has 2x VI and 1x UI channels (use UI channel). V3s uses PLL3 (PLL_VIDEO) for both DE2 and TCON0 pixelclock. V3s does not support doubleclock for PLL3. V3s supports resolution upto 1024x1024. V3s does not support HDMI.
Signed-off-by: Martin Cerveny m.cerveny@computer.org
arch/arm/include/asm/arch-sunxi/clock_sun6i.h | 5 ++-- arch/arm/include/asm/arch-sunxi/gpio.h | 1 + arch/arm/mach-sunxi/Kconfig | 1 + drivers/video/sunxi/lcdc.c | 5 ++-- drivers/video/sunxi/sunxi_de2.c | 25 ++++++++++++++++--- drivers/video/sunxi/sunxi_dw_hdmi.c | 2 ++ drivers/video/sunxi/sunxi_lcd.c | 9 ++++++- 7 files changed, 40 insertions(+), 8 deletions(-)
diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h index ee387127f3..9efe05d103 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h @@ -329,7 +329,7 @@ struct sunxi_ccm_reg { #define AHB_GATE_OFFSET_DE 12 #define AHB_GATE_OFFSET_HDMI 11 #define AHB_GATE_OFFSET_TVE 9 -#ifndef CONFIG_SUNXI_DE2 +#if !defined(CONFIG_SUNXI_DE2) || defined(CONFIG_MACH_SUN8I_V3S) #define AHB_GATE_OFFSET_LCD1 5 #define AHB_GATE_OFFSET_LCD0 4 #else @@ -476,7 +476,7 @@ struct sunxi_ccm_reg { #define AHB_RESET_OFFSET_HDMI 11 #define AHB_RESET_OFFSET_HDMI2 10 #define AHB_RESET_OFFSET_TVE 9 -#ifndef CONFIG_SUNXI_DE2 +#if !defined(CONFIG_SUNXI_DE2) || defined(CONFIG_MACH_SUN8I_V3S)
These two changes are confusing. The V3S has a DE2, so having that condition is weird. I'd just add an elif there
The use of "CONFIG_SUNXI_DE2" is misleading. The platform connectivity (AHB) depends on platform not on DE2. Names are also weird. Should be "TCON". AHB gating is described in platform docs and not in DE2 docs.
header:
ahb_gate1; /* 0x64 ahb module clock gating 1 */ u32 ahb_reset1_cfg; /* 0x2c4 AHB1 Reset 1 config */ /* ahb_gate1 offsets */ #define AHB_GATE_OFFSET_LCD0 ... /* ahb_reset1 offsets */ #define AHB_RESET_OFFSET_LCD0
V3S datasheet: ("LCD0" (it is fixed used in drivers/video/sunxi/lcdc.c) is TCON (==TCON0) and does not have "LCD1" (==TCON1))
Offset: 0x0064 Register Name: BUS_CLK_GATING_REG1 Bit: 4 TCON_GATING Offset: 0x02C4 Register Name: BUS_SOFT_RST_REG1 Bit: 4 TCON_RST
#define AHB_RESET_OFFSET_LCD1 5 #define AHB_RESET_OFFSET_LCD0 4 #else @@ -510,6 +510,7 @@ struct sunxi_ccm_reg { #define CCM_DE2_CTRL_PLL_MASK (3 << 24) #define CCM_DE2_CTRL_PLL6_2X (0 << 24) #define CCM_DE2_CTRL_PLL10 (1 << 24) +#define CCM_DE2_CTRL_PLL3_V3S (0 << 24) #define CCM_DE2_CTRL_GATE (0x1 << 31)
/* CCU security switch, H3 only */ diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h index d83dfdf605..9b580fbe26 100644 --- a/arch/arm/include/asm/arch-sunxi/gpio.h +++ b/arch/arm/include/asm/arch-sunxi/gpio.h @@ -181,6 +181,7 @@ enum sunxi_gpio_number { #define SUN5I_GPE_SDC2 3 #define SUN8I_GPE_TWI2 3 #define SUN50I_GPE_TWI2 3 +#define SUN8I_V3S_GPE_LCD0 3
#define SUNXI_GPF_SDC0 2 #define SUNXI_GPF_UART0 4 diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index be0822bfb7..dc0ee2cdef 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig @@ -258,6 +258,7 @@ config MACH_SUN8I_V3S select CPU_V7_HAS_NONSEC select CPU_V7_HAS_VIRT select ARCH_SUPPORT_PSCI
- select SUNXI_DE2 select SUNXI_GEN_SUN6I select SUNXI_DRAM_DW select SUNXI_DRAM_DW_16BIT
diff --git a/drivers/video/sunxi/lcdc.c b/drivers/video/sunxi/lcdc.c index 73033c3b85..3d50f9d567 100644 --- a/drivers/video/sunxi/lcdc.c +++ b/drivers/video/sunxi/lcdc.c @@ -244,7 +244,7 @@ void lcdc_pll_set(struct sunxi_ccm_reg *ccm, int tcon, int dotclock, * not sync to higher frequencies. */ for (m = min_m; m <= max_m; m++) { -#ifndef CONFIG_SUNXI_DE2 +#if !defined(CONFIG_SUNXI_DE2) || defined(CONFIG_MACH_SUN8I_V3S) n = (m * dotclock) / step;
if ((n >= 9) && (n <= 127)) {
@@ -262,7 +262,7 @@ void lcdc_pll_set(struct sunxi_ccm_reg *ccm, int tcon, int dotclock, if (!(m & 1)) continue; #endif
+#ifndef CONFIG_MACH_SUN8I_V3S /* No double clock on DE2 */ n = (m * dotclock) / (step * 2); if ((n >= 9) && (n <= 127)) { @@ -275,6 +275,7 @@ void lcdc_pll_set(struct sunxi_ccm_reg *ccm, int tcon, int dotclock, best_double = 1; } } +#endif
I'm still not seeing any indication as to where you're getting this from
Again. The use of "CONFIG_SUNXI_DE2" is misleading. The platform PLL3 functions depends on platform not on DE2.
PLL3 on V3S platform does not support double speed. "best_double" should not be set.
header:
u32 lcd0_ch0_clk_cfg; /* 0x118 LCD0 CH0 module clock */ #define CCM_LCD_CH0_CTRL_PLL3 (0 << 24) #define CCM_LCD_CH0_CTRL_PLL7 (1 << 24) #define CCM_LCD_CH0_CTRL_PLL3_2X (2 << 24) #define CCM_LCD_CH0_CTRL_PLL7_2X (3 << 24) #define CCM_LCD_CH0_CTRL_MIPI_PLL (4 << 24) /* No reset bit in ch0_clk_cfg (reset is controlled through ahb_reset1) */ #define CCM_LCD_CH0_CTRL_RST 0 #define CCM_LCD_CH0_CTRL_GATE (0x1 << 31)
V3s datasheet:
Offset: 0x0118 Register Name: TCON_CLK_REG Bit: 31 SCLK_GATING Bit: 26:24 CLK_SRC_SEL - valid values: 000: PLL_VIDEO (PLL3) 001: PLL_PERIPH0 (PLL6) Bit: 3:0 CLK_DIV_RATIO_M
}
#ifdef CONFIG_MACH_SUN6I diff --git a/drivers/video/sunxi/sunxi_de2.c b/drivers/video/sunxi/sunxi_de2.c index b657e163f0..49d41eb243 100644 --- a/drivers/video/sunxi/sunxi_de2.c +++ b/drivers/video/sunxi/sunxi_de2.c @@ -26,12 +26,21 @@
DECLARE_GLOBAL_DATA_PTR;
+#ifdef CONFIG_MACH_SUN8I_V3S +enum {
- /* Maximum LCD size we support */
- LCD_MAX_WIDTH = 1024,
- LCD_MAX_HEIGHT = 1024,
- LCD_MAX_LOG2_BPP = VIDEO_BPP32,
+}; +#else enum { /* Maximum LCD size we support */ LCD_MAX_WIDTH = 3840, LCD_MAX_HEIGHT = 2160, LCD_MAX_LOG2_BPP = VIDEO_BPP32, }; +#endif
static void sunxi_de2_composer_init(void) { @@ -47,11 +56,19 @@ static void sunxi_de2_composer_init(void) writel(reg_value, SUNXI_SRAMC_BASE + 0x04); #endif
+#ifdef CONFIG_MACH_SUN8I_V3S
- clock_set_pll3(50000000);
- /* pll3 is also used for pixelclock and speed will be recomputed */
- /* Set DE parent to pll3 */
- clrsetbits_le32(&ccm->de_clk_cfg, CCM_DE2_CTRL_PLL_MASK,
CCM_DE2_CTRL_PLL3_V3S);
+#else clock_set_pll10(432000000);
/* Set DE parent to pll10 */ clrsetbits_le32(&ccm->de_clk_cfg, CCM_DE2_CTRL_PLL_MASK, CCM_DE2_CTRL_PLL10); +#endif
/* Set ahb gating to pass */ setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_DE); @@ -77,7 +94,8 @@ static void sunxi_de2_mode_set(int mux, const struct display_timing *mode, struct de_ui * const de_ui_regs = (struct de_ui *)(de_mux_base + SUNXI_DE2_MUX_CHAN_REGS +
SUNXI_DE2_MUX_CHAN_SZ * 1);
SUNXI_DE2_MUX_CHAN_SZ *
(IS_ENABLED(CONFIG_MACH_SUN8I_V3S) ? 2 : 1));
Why do you need to use two UI channels? Isn't one enough?
Maxime
Not "two" but I am using third (0,1,_2_) channel. Third channel is only UI channel on V3s platform. (first two channels are VI channels).
see: https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/sun4i/sun8i_m...
Regards, M.C>

On Sun, Oct 25, 2020 at 10:46:04AM +0100, Martin Cerveny wrote:
On Mon, 19 Oct 2020, Maxime Ripard wrote:
On Fri, Oct 16, 2020 at 07:17:04PM +0200, Martin Cerveny wrote:
Enable support for V3s LCD display with following changes:
V3s has 2x VI and 1x UI channels (use UI channel). V3s uses PLL3 (PLL_VIDEO) for both DE2 and TCON0 pixelclock. V3s does not support doubleclock for PLL3. V3s supports resolution upto 1024x1024. V3s does not support HDMI.
Signed-off-by: Martin Cerveny m.cerveny@computer.org
arch/arm/include/asm/arch-sunxi/clock_sun6i.h | 5 ++-- arch/arm/include/asm/arch-sunxi/gpio.h | 1 + arch/arm/mach-sunxi/Kconfig | 1 + drivers/video/sunxi/lcdc.c | 5 ++-- drivers/video/sunxi/sunxi_de2.c | 25 ++++++++++++++++--- drivers/video/sunxi/sunxi_dw_hdmi.c | 2 ++ drivers/video/sunxi/sunxi_lcd.c | 9 ++++++- 7 files changed, 40 insertions(+), 8 deletions(-)
diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h index ee387127f3..9efe05d103 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h @@ -329,7 +329,7 @@ struct sunxi_ccm_reg { #define AHB_GATE_OFFSET_DE 12 #define AHB_GATE_OFFSET_HDMI 11 #define AHB_GATE_OFFSET_TVE 9 -#ifndef CONFIG_SUNXI_DE2 +#if !defined(CONFIG_SUNXI_DE2) || defined(CONFIG_MACH_SUN8I_V3S) #define AHB_GATE_OFFSET_LCD1 5 #define AHB_GATE_OFFSET_LCD0 4 #else @@ -476,7 +476,7 @@ struct sunxi_ccm_reg { #define AHB_RESET_OFFSET_HDMI 11 #define AHB_RESET_OFFSET_HDMI2 10 #define AHB_RESET_OFFSET_TVE 9 -#ifndef CONFIG_SUNXI_DE2 +#if !defined(CONFIG_SUNXI_DE2) || defined(CONFIG_MACH_SUN8I_V3S)
These two changes are confusing. The V3S has a DE2, so having that condition is weird. I'd just add an elif there
The use of "CONFIG_SUNXI_DE2" is misleading. The platform connectivity (AHB) depends on platform not on DE2.
Feel free to fix it :)
Names are also weird. Should be "TCON".
That one is less weird. TCON used to be called LCDC as well in the older SoCs.
AHB gating is described in platform docs and not in DE2 docs.
header:
ahb_gate1; /* 0x64 ahb module clock gating 1 */ u32 ahb_reset1_cfg; /* 0x2c4 AHB1 Reset 1 config */ /* ahb_gate1 offsets */ #define AHB_GATE_OFFSET_LCD0 ... /* ahb_reset1 offsets */ #define AHB_RESET_OFFSET_LCD0
V3S datasheet: ("LCD0" (it is fixed used in drivers/video/sunxi/lcdc.c) is TCON (==TCON0) and does not have "LCD1" (==TCON1))
Offset: 0x0064 Register Name: BUS_CLK_GATING_REG1 Bit: 4 TCON_GATING Offset: 0x02C4 Register Name: BUS_SOFT_RST_REG1 Bit: 4 TCON_RST
#define AHB_RESET_OFFSET_LCD1 5 #define AHB_RESET_OFFSET_LCD0 4 #else @@ -510,6 +510,7 @@ struct sunxi_ccm_reg { #define CCM_DE2_CTRL_PLL_MASK (3 << 24) #define CCM_DE2_CTRL_PLL6_2X (0 << 24) #define CCM_DE2_CTRL_PLL10 (1 << 24) +#define CCM_DE2_CTRL_PLL3_V3S (0 << 24) #define CCM_DE2_CTRL_GATE (0x1 << 31)
/* CCU security switch, H3 only */ diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h index d83dfdf605..9b580fbe26 100644 --- a/arch/arm/include/asm/arch-sunxi/gpio.h +++ b/arch/arm/include/asm/arch-sunxi/gpio.h @@ -181,6 +181,7 @@ enum sunxi_gpio_number { #define SUN5I_GPE_SDC2 3 #define SUN8I_GPE_TWI2 3 #define SUN50I_GPE_TWI2 3 +#define SUN8I_V3S_GPE_LCD0 3
#define SUNXI_GPF_SDC0 2 #define SUNXI_GPF_UART0 4 diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index be0822bfb7..dc0ee2cdef 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig @@ -258,6 +258,7 @@ config MACH_SUN8I_V3S select CPU_V7_HAS_NONSEC select CPU_V7_HAS_VIRT select ARCH_SUPPORT_PSCI
- select SUNXI_DE2 select SUNXI_GEN_SUN6I select SUNXI_DRAM_DW select SUNXI_DRAM_DW_16BIT
diff --git a/drivers/video/sunxi/lcdc.c b/drivers/video/sunxi/lcdc.c index 73033c3b85..3d50f9d567 100644 --- a/drivers/video/sunxi/lcdc.c +++ b/drivers/video/sunxi/lcdc.c @@ -244,7 +244,7 @@ void lcdc_pll_set(struct sunxi_ccm_reg *ccm, int tcon, int dotclock, * not sync to higher frequencies. */ for (m = min_m; m <= max_m; m++) { -#ifndef CONFIG_SUNXI_DE2 +#if !defined(CONFIG_SUNXI_DE2) || defined(CONFIG_MACH_SUN8I_V3S) n = (m * dotclock) / step;
if ((n >= 9) && (n <= 127)) {
@@ -262,7 +262,7 @@ void lcdc_pll_set(struct sunxi_ccm_reg *ccm, int tcon, int dotclock, if (!(m & 1)) continue; #endif
+#ifndef CONFIG_MACH_SUN8I_V3S /* No double clock on DE2 */ n = (m * dotclock) / (step * 2); if ((n >= 9) && (n <= 127)) { @@ -275,6 +275,7 @@ void lcdc_pll_set(struct sunxi_ccm_reg *ccm, int tcon, int dotclock, best_double = 1; } } +#endif
I'm still not seeing any indication as to where you're getting this from
Again. The use of "CONFIG_SUNXI_DE2" is misleading. The platform PLL3 functions depends on platform not on DE2.
PLL3 on V3S platform does not support double speed. "best_double" should not be set.
header:
u32 lcd0_ch0_clk_cfg; /* 0x118 LCD0 CH0 module clock */ #define CCM_LCD_CH0_CTRL_PLL3 (0 << 24) #define CCM_LCD_CH0_CTRL_PLL7 (1 << 24) #define CCM_LCD_CH0_CTRL_PLL3_2X (2 << 24) #define CCM_LCD_CH0_CTRL_PLL7_2X (3 << 24) #define CCM_LCD_CH0_CTRL_MIPI_PLL (4 << 24) /* No reset bit in ch0_clk_cfg (reset is controlled through ahb_reset1) */ #define CCM_LCD_CH0_CTRL_RST 0 #define CCM_LCD_CH0_CTRL_GATE (0x1 << 31)
V3s datasheet:
Offset: 0x0118 Register Name: TCON_CLK_REG Bit: 31 SCLK_GATING Bit: 26:24 CLK_SRC_SEL
- valid values: 000: PLL_VIDEO (PLL3) 001: PLL_PERIPH0 (PLL6)
Bit: 3:0 CLK_DIV_RATIO_M
Then that's your source. It should be in the commit log.
}
#ifdef CONFIG_MACH_SUN6I diff --git a/drivers/video/sunxi/sunxi_de2.c b/drivers/video/sunxi/sunxi_de2.c index b657e163f0..49d41eb243 100644 --- a/drivers/video/sunxi/sunxi_de2.c +++ b/drivers/video/sunxi/sunxi_de2.c @@ -26,12 +26,21 @@
DECLARE_GLOBAL_DATA_PTR;
+#ifdef CONFIG_MACH_SUN8I_V3S +enum {
- /* Maximum LCD size we support */
- LCD_MAX_WIDTH = 1024,
- LCD_MAX_HEIGHT = 1024,
- LCD_MAX_LOG2_BPP = VIDEO_BPP32,
+}; +#else enum { /* Maximum LCD size we support */ LCD_MAX_WIDTH = 3840, LCD_MAX_HEIGHT = 2160, LCD_MAX_LOG2_BPP = VIDEO_BPP32, }; +#endif
static void sunxi_de2_composer_init(void) { @@ -47,11 +56,19 @@ static void sunxi_de2_composer_init(void) writel(reg_value, SUNXI_SRAMC_BASE + 0x04); #endif
+#ifdef CONFIG_MACH_SUN8I_V3S
- clock_set_pll3(50000000);
- /* pll3 is also used for pixelclock and speed will be recomputed */
- /* Set DE parent to pll3 */
- clrsetbits_le32(&ccm->de_clk_cfg, CCM_DE2_CTRL_PLL_MASK,
CCM_DE2_CTRL_PLL3_V3S);
+#else clock_set_pll10(432000000);
/* Set DE parent to pll10 */ clrsetbits_le32(&ccm->de_clk_cfg, CCM_DE2_CTRL_PLL_MASK, CCM_DE2_CTRL_PLL10); +#endif
/* Set ahb gating to pass */ setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_DE); @@ -77,7 +94,8 @@ static void sunxi_de2_mode_set(int mux, const struct display_timing *mode, struct de_ui * const de_ui_regs = (struct de_ui *)(de_mux_base + SUNXI_DE2_MUX_CHAN_REGS +
SUNXI_DE2_MUX_CHAN_SZ * 1);
SUNXI_DE2_MUX_CHAN_SZ *
(IS_ENABLED(CONFIG_MACH_SUN8I_V3S) ? 2 : 1));
Why do you need to use two UI channels? Isn't one enough?
Not "two" but I am using third (0,1,_2_) channel. Third channel is only UI channel on V3s platform. (first two channels are VI channels).
see: https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/sun4i/sun8i_m...
This should also be in the commit log
Maxime

Add PWM and dummy power regulator support. Modify phase of data signal for LCD display.
Signed-off-by: Martin Cerveny m.cerveny@computer.org --- configs/LicheePi_Zero_defconfig | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/configs/LicheePi_Zero_defconfig b/configs/LicheePi_Zero_defconfig index 04d7b64504..ba1c085ec3 100644 --- a/configs/LicheePi_Zero_defconfig +++ b/configs/LicheePi_Zero_defconfig @@ -3,5 +3,9 @@ CONFIG_ARCH_SUNXI=y CONFIG_SPL=y CONFIG_MACH_SUN8I_V3S=y CONFIG_DRAM_CLK=360 +CONFIG_VIDEO_LCD_DCLK_PHASE=0 CONFIG_DEFAULT_DEVICE_TREE="sun8i-v3s-licheepi-zero" # CONFIG_NETDEVICES is not set +CONFIG_DM_REGULATOR=y +CONFIG_DM_PWM=y +CONFIG_PWM_SUNXI=y

On Fri, Oct 16, 2020 at 07:17:05PM +0200, Martin Cerveny wrote:
Add PWM and dummy power regulator support. Modify phase of data signal for LCD display.
Signed-off-by: Martin Cerveny m.cerveny@computer.org
configs/LicheePi_Zero_defconfig | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/configs/LicheePi_Zero_defconfig b/configs/LicheePi_Zero_defconfig index 04d7b64504..ba1c085ec3 100644 --- a/configs/LicheePi_Zero_defconfig +++ b/configs/LicheePi_Zero_defconfig @@ -3,5 +3,9 @@ CONFIG_ARCH_SUNXI=y CONFIG_SPL=y CONFIG_MACH_SUN8I_V3S=y CONFIG_DRAM_CLK=360 +CONFIG_VIDEO_LCD_DCLK_PHASE=0
I'm not sure you answered on that one either, but you'd need some display timings as well, right? If so, why do we need that change in the first place if we're expected to change it anyway?
Maxime

On Mon, 19 Oct 2020, Maxime Ripard wrote:
On Fri, Oct 16, 2020 at 07:17:05PM +0200, Martin Cerveny wrote:
Add PWM and dummy power regulator support. Modify phase of data signal for LCD display.
Signed-off-by: Martin Cerveny m.cerveny@computer.org
configs/LicheePi_Zero_defconfig | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/configs/LicheePi_Zero_defconfig b/configs/LicheePi_Zero_defconfig index 04d7b64504..ba1c085ec3 100644 --- a/configs/LicheePi_Zero_defconfig +++ b/configs/LicheePi_Zero_defconfig @@ -3,5 +3,9 @@ CONFIG_ARCH_SUNXI=y CONFIG_SPL=y CONFIG_MACH_SUN8I_V3S=y CONFIG_DRAM_CLK=360 +CONFIG_VIDEO_LCD_DCLK_PHASE=0
I'm not sure you answered on that one either, but you'd need some display timings as well, right? If so, why do we need that change in the first place if we're expected to change it anyway?
Maxime
I done in config all needed setup to enable LCD (PHASE and PWM drivers).
Enabling LCD (with different display timimgs) depends now only on DTS/DTB. The right extension of DTS is not part of patch series. As I wrote in cover letter: - To enable functionality see TESTING patch at https://github.com/mcerveny/u-boot/tree/simplefb_v3s_v2 (for display 800x480)
or use timmings from previous patch for display (480x472) https://github.com/mcerveny/u-boot/commit/b9a743f421ae6f3786eca008e5ebdab431...

On Sun, Oct 25, 2020 at 10:56:32AM +0100, Martin Cerveny wrote:
On Mon, 19 Oct 2020, Maxime Ripard wrote:
On Fri, Oct 16, 2020 at 07:17:05PM +0200, Martin Cerveny wrote:
Add PWM and dummy power regulator support. Modify phase of data signal for LCD display.
Signed-off-by: Martin Cerveny m.cerveny@computer.org
configs/LicheePi_Zero_defconfig | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/configs/LicheePi_Zero_defconfig b/configs/LicheePi_Zero_defconfig index 04d7b64504..ba1c085ec3 100644 --- a/configs/LicheePi_Zero_defconfig +++ b/configs/LicheePi_Zero_defconfig @@ -3,5 +3,9 @@ CONFIG_ARCH_SUNXI=y CONFIG_SPL=y CONFIG_MACH_SUN8I_V3S=y CONFIG_DRAM_CLK=360 +CONFIG_VIDEO_LCD_DCLK_PHASE=0
I'm not sure you answered on that one either, but you'd need some display timings as well, right? If so, why do we need that change in the first place if we're expected to change it anyway?
I done in config all needed setup to enable LCD (PHASE and PWM drivers).
Enabling LCD (with different display timimgs) depends now only on DTS/DTB.
Indeed, I missed that one.
With that being said, it doesn't really change the fact that you'd still need some changes to the DT (and thus the code) to enable it.
And those changes wouldn't follow the DT bindings of the display controller either, so there's no chance of them getting upstream at any point in time.
So yeah, while your first patches should definitely go in, this one doesn't seem that interesting
Maxime
participants (3)
-
Martin Cerveny
-
Martin Cerveny
-
Maxime Ripard