[linux-sunxi] [PATCH] arm64: dts: allwinner: h6: beelink-gs1: Remove ext. 32 kHz osc reference
Although every Beelink GS1 seems to have external 32768 Hz oscillator, it works only on one from four tested. There are more reports of RTC issues elsewhere, like Armbian forum. One Beelink GS1 owner read RTC osc status register on Android which shipped with the box. Reported value indicated problems with external oscillator. In order to fix RTC and related issues (HDMI-CEC and suspend/resume with Crust) on all boards, switch to internal oscillator. Fixes: 32507b868119 ("arm64: dts: allwinner: h6: Move ext. oscillator to board DTs") Signed-off-by: Jernej Skrabec --- arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts | 4 1 file changed, 4 deletions(-) diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts index 669d39fc716a..6249e9e02928 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts @@ -289,10 +289,6 @@ sw { }; }; - { - clocks = <_osc32k>; -}; - { status = "okay"; }; -- 2.31.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210330184218.279738-1-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2] ARM: dts: sun8i: h3: beelink-x2: Add power button
Beelink X2 has power button. Add node for it. Signed-off-by: Jernej Skrabec --- Changes from v1: - renamed node name so it doesn't contain underscores arch/arm/boot/dts/sun8i-h3-beelink-x2.dts | 11 +++ 1 file changed, 11 insertions(+) diff --git a/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts b/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts index 62b5280ec093..f0e591e1c771 100644 --- a/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts +++ b/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts @@ -111,6 +111,17 @@ spdif_out: spdif-out { #sound-dai-cells = <0>; compatible = "linux,spdif-dit"; }; + + r-gpio-keys { + compatible = "gpio-keys"; + + power { + label = "power"; + linux,code = ; + gpios = <_pio 0 3 GPIO_ACTIVE_LOW>; + wakeup-source; + }; + }; }; { -- 2.31.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210323204341.28825-1-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2] sunxi: add fdtoverlay_addr_r environment variable
Commit 69076dff2284 ("cmd: pxe: add support for FDT overlays") added support for loading DT overlay files to PXE boot. However, it needs additional environment variable which points to memory location which can be used to temporary store overlay data. Add it and in the process unify alignment using spaces and fix comment. Reviewed-by: Andre Przywara Signed-off-by: Jernej Skrabec --- Changes from v1: - added r-b tag - fixed comment include/configs/sunxi-common.h | 49 ++ 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index ded5aea551d3..3e1dc47c9c55 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -62,7 +62,7 @@ #define SDRAM_OFFSET(x) 0x2##x #define CONFIG_SYS_SDRAM_BASE 0x2000 #define CONFIG_SYS_LOAD_ADDR 0x2200 /* default load address */ -/* Note SPL_STACK_R_ADDR is set through Kconfig, we include it here +/* Note SPL_STACK_R_ADDR is set through Kconfig, we include it here * since it needs to fit in with the other values. By also #defining it * we get warnings if the Kconfig value mismatches. */ #define CONFIG_SPL_STACK_R_ADDR0x2fe0 @@ -72,7 +72,7 @@ #define CONFIG_SYS_SDRAM_BASE 0x4000 #define CONFIG_SYS_LOAD_ADDR 0x4200 /* default load address */ /* V3s do not have enough memory to place code at 0x4a00 */ -/* Note SPL_STACK_R_ADDR is set through Kconfig, we include it here +/* Note SPL_STACK_R_ADDR is set through Kconfig, we include it here * since it needs to fit in with the other values. By also #defining it * we get warnings if the Kconfig value mismatches. */ #define CONFIG_SPL_STACK_R_ADDR0x4fe0 @@ -257,40 +257,42 @@ extern int soft_i2c_gpio_scl; * There is no compression for arm64 kernels (yet), so leave some space * for really big kernels, say 256MB for now. * Scripts, PXE and DTBs should go afterwards, leaving the rest for the initrd. - * Align the initrd to a 2MB page. */ -#define BOOTM_SIZE __stringify(0xa00) -#define KERNEL_ADDR_R __stringify(SDRAM_OFFSET(008)) -#define FDT_ADDR_R __stringify(SDRAM_OFFSET(FA0)) -#define SCRIPT_ADDR_R __stringify(SDRAM_OFFSET(FC0)) -#define PXEFILE_ADDR_R __stringify(SDRAM_OFFSET(FD0)) -#define RAMDISK_ADDR_R __stringify(SDRAM_OFFSET(FE0)) +#define BOOTM_SIZE__stringify(0xa00) +#define KERNEL_ADDR_R __stringify(SDRAM_OFFSET(008)) +#define FDT_ADDR_R__stringify(SDRAM_OFFSET(FA0)) +#define SCRIPT_ADDR_R __stringify(SDRAM_OFFSET(FC0)) +#define PXEFILE_ADDR_R__stringify(SDRAM_OFFSET(FD0)) +#define FDTOVERLAY_ADDR_R __stringify(SDRAM_OFFSET(FE0)) +#define RAMDISK_ADDR_R__stringify(SDRAM_OFFSET(FF0)) #else /* * 160M RAM (256M minimum minus 64MB heap + 32MB for u-boot, stack, fb, etc. * 32M uncompressed kernel, 16M compressed kernel, 1M fdt, - * 1M script, 1M pxe and the ramdisk at the end. + * 1M script, 1M pxe, 1M dt overlay and the ramdisk at the end. */ #ifndef CONFIG_MACH_SUN8I_V3S -#define BOOTM_SIZE __stringify(0xa00) -#define KERNEL_ADDR_R __stringify(SDRAM_OFFSET(200)) -#define FDT_ADDR_R __stringify(SDRAM_OFFSET(300)) -#define SCRIPT_ADDR_R __stringify(SDRAM_OFFSET(310)) -#define PXEFILE_ADDR_R __stringify(SDRAM_OFFSET(320)) -#define RAMDISK_ADDR_R __stringify(SDRAM_OFFSET(330)) +#define BOOTM_SIZE__stringify(0xa00) +#define KERNEL_ADDR_R __stringify(SDRAM_OFFSET(200)) +#define FDT_ADDR_R__stringify(SDRAM_OFFSET(300)) +#define SCRIPT_ADDR_R __stringify(SDRAM_OFFSET(310)) +#define PXEFILE_ADDR_R__stringify(SDRAM_OFFSET(320)) +#define FDTOVERLAY_ADDR_R __stringify(SDRAM_OFFSET(330)) +#define RAMDISK_ADDR_R__stringify(SDRAM_OFFSET(340)) #else /* * 64M RAM minus 2MB heap + 16MB for u-boot, stack, fb, etc. * 16M uncompressed kernel, 8M compressed kernel, 1M fdt, - * 1M script, 1M pxe and the ramdisk at the end. + * 1M script, 1M pxe, 1M dt overlay and the ramdisk at the end. */ -#define BOOTM_SIZE __stringify(0x2e0) -#define KERNEL_ADDR_R __stringify(SDRAM_OFFSET(100)) -#define FDT_ADDR_R __stringify(SDRAM_OFFSET(180)) -#define SCRIPT_ADDR_R __stringify(SDRAM_OFFSET(190)) -#define PXEFILE_ADDR_R __stringify(SDRAM_OFFSET(1A0)) -#define RAMDISK_ADDR_R __stringify(SDRAM_OFFSET(1B0)) +#define BOOTM_SIZE__stringify(0x2e0) +#define KERNEL_ADDR_R __stringify(SDRAM_OFFSET(100)) +#define FDT_ADDR_R__stringify(SDRAM_OFFSET(180)) +#define SCRIPT_ADDR_R __stringify(SDRAM_OFFSET(190)) +#define PXEFILE_ADDR_R__stringify(SDRAM_OFFSET(1A0)) +#define FDTOVERLAY_ADDR_R __stringify(SDRAM_OFFSET(1B0)) +#define RAMDISK_ADDR_R__stringify(SDRAM_OFFSET(1C0)) #endif #endif @@ -300,6 +302,7 @@
[linux-sunxi] [PATCH] ARM: dts: sun8i: h3: beelink-x2: Add power button
Beelink X2 has power button. Add node for it. Signed-off-by: Jernej Skrabec --- arch/arm/boot/dts/sun8i-h3-beelink-x2.dts | 11 +++ 1 file changed, 11 insertions(+) diff --git a/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts b/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts index 62b5280ec093..4a2cb072ecf6 100644 --- a/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts +++ b/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts @@ -111,6 +111,17 @@ spdif_out: spdif-out { #sound-dai-cells = <0>; compatible = "linux,spdif-dit"; }; + + r_gpio_keys { + compatible = "gpio-keys"; + + power { + label = "power"; + linux,code = ; + gpios = <_pio 0 3 GPIO_ACTIVE_LOW>; + wakeup-source; + }; + }; }; { -- 2.30.1 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210306203611.15534-1-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2 19/19] video: sunxi: dw-hdmi: Use new PHY driver
Remove direct PHY managing from dw-hdmi platform driver and use dedicated driver instead. While at it, enable clocks and deassert reset lines through clk and reset framework instead of manually configuring bits. Signed-off-by: Jernej Skrabec --- drivers/video/sunxi/sunxi_dw_hdmi.c | 225 +--- 1 file changed, 36 insertions(+), 189 deletions(-) diff --git a/drivers/video/sunxi/sunxi_dw_hdmi.c b/drivers/video/sunxi/sunxi_dw_hdmi.c index 483d57293155..16051baca8c5 100644 --- a/drivers/video/sunxi/sunxi_dw_hdmi.c +++ b/drivers/video/sunxi/sunxi_dw_hdmi.c @@ -5,190 +5,26 @@ * (C) Copyright 2017 Jernej Skrabec */ +#include #include #include #include #include #include -#include -#include +#include +#include #include #include #include #include -#include +#include "sunxi_dw_hdmi_phy.h" struct sunxi_dw_hdmi_priv { struct dw_hdmi hdmi; int mux; + struct phy phy; }; -struct sunxi_hdmi_phy { - u32 pol; - u32 res1[3]; - u32 read_en; - u32 unscramble; - u32 res2[2]; - u32 ctrl; - u32 unk1; - u32 unk2; - u32 pll; - u32 clk; - u32 unk3; - u32 status; -}; - -#define HDMI_PHY_OFFS 0x1 - -static int sunxi_dw_hdmi_get_divider(uint clock) -{ - /* -* Due to missing documentaion of HDMI PHY, we know correct -* settings only for following four PHY dividers. Select one -* based on clock speed. -*/ - if (clock <= 2700) - return 11; - else if (clock <= 7425) - return 4; - else if (clock <= 14850) - return 2; - else - return 1; -} - -static void sunxi_dw_hdmi_phy_init(struct dw_hdmi *hdmi) -{ - struct sunxi_hdmi_phy * const phy = - (struct sunxi_hdmi_phy *)(hdmi->ioaddr + HDMI_PHY_OFFS); - unsigned long tmo; - u32 tmp; - - /* -* HDMI PHY settings are taken as-is from Allwinner BSP code. -* There is no documentation. -*/ - writel(0, >ctrl); - setbits_le32(>ctrl, BIT(0)); - udelay(5); - setbits_le32(>ctrl, BIT(16)); - setbits_le32(>ctrl, BIT(1)); - udelay(10); - setbits_le32(>ctrl, BIT(2)); - udelay(5); - setbits_le32(>ctrl, BIT(3)); - udelay(40); - setbits_le32(>ctrl, BIT(19)); - udelay(100); - setbits_le32(>ctrl, BIT(18)); - setbits_le32(>ctrl, 7 << 4); - - /* Note that Allwinner code doesn't fail in case of timeout */ - tmo = timer_get_us() + 2000; - while ((readl(>status) & 0x80) == 0) { - if (timer_get_us() > tmo) { - printf("Warning: HDMI PHY init timeout!\n"); - break; - } - } - - setbits_le32(>ctrl, 0xf << 8); - setbits_le32(>ctrl, BIT(7)); - - writel(0x39dc5040, >pll); - writel(0x80084343, >clk); - udelay(1); - writel(1, >unk3); - setbits_le32(>pll, BIT(25)); - udelay(10); - tmp = (readl(>status) & 0x1f800) >> 11; - setbits_le32(>pll, BIT(31) | BIT(30)); - setbits_le32(>pll, tmp); - writel(0x01FF0F7F, >ctrl); - writel(0x80639000, >unk1); - writel(0x0F81C405, >unk2); - - /* enable read access to HDMI controller */ - writel(0x54524545, >read_en); - /* descramble register offsets */ - writel(0x42494E47, >unscramble); -} - -static void sunxi_dw_hdmi_phy_set(struct dw_hdmi *hdmi, uint clock, int phy_div) -{ - struct sunxi_hdmi_phy * const phy = - (struct sunxi_hdmi_phy *)(hdmi->ioaddr + HDMI_PHY_OFFS); - int div = sunxi_dw_hdmi_get_divider(clock); - u32 tmp; - - /* -* Unfortunately, we don't know much about those magic -* numbers. They are taken from Allwinner BSP driver. -*/ - switch (div) { - case 1: - writel(0x30dc5fc0, >pll); - writel(0x800863C0 | (phy_div - 1), >clk); - mdelay(10); - writel(0x0001, >unk3); - setbits_le32(>pll, BIT(25)); - mdelay(200); - tmp = (readl(>status) & 0x1f800) >> 11; - setbits_le32(>pll, BIT(31) | BIT(30)); - if (tmp < 0x3d) - setbits_le32(>pll, tmp + 2); - else - setbits_le32(>pll, 0x3f); - mdelay(100); - writel(0x017F, >ctrl); - writel(0x8063b000, >unk1); - writel(0x0F8246B5, >unk2); - break; - case 2: - writel(0x39dc5040, >pll); - writel(0x80084380 | (phy_div - 1), >clk); -
[linux-sunxi] [PATCH v2 18/19] video: sunxi: Add DW HDMI PHY driver
This commit adds standalone driver for DW HDMI PHY. It deprecates code which is included in sunxi dw-hdmi platform driver. Signed-off-by: Jernej Skrabec --- arch/arm/mach-sunxi/Kconfig | 1 + drivers/video/sunxi/Makefile| 2 +- drivers/video/sunxi/sunxi_dw_hdmi_phy.c | 423 drivers/video/sunxi/sunxi_dw_hdmi_phy.h | 24 ++ 4 files changed, 449 insertions(+), 1 deletion(-) create mode 100644 drivers/video/sunxi/sunxi_dw_hdmi_phy.c create mode 100644 drivers/video/sunxi/sunxi_dw_hdmi_phy.h diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index 34ef1f4b030f..5f2df7727357 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig @@ -973,6 +973,7 @@ config VIDEO_DE2 select CLK_SUN8I_DE2 select DM_VIDEO select DISPLAY + select PHY select VIDEO_DW_HDMI imply VIDEO_DT_SIMPLEFB default y diff --git a/drivers/video/sunxi/Makefile b/drivers/video/sunxi/Makefile index 4321673312bf..22ec17fb4fd2 100644 --- a/drivers/video/sunxi/Makefile +++ b/drivers/video/sunxi/Makefile @@ -4,4 +4,4 @@ # Wolfgang Denk, DENX Software Engineering, w...@denx.de. obj-$(CONFIG_VIDEO_SUNXI) += sunxi_display.o simplefb_common.o lcdc.o tve_common.o ../videomodes.o -obj-$(CONFIG_VIDEO_DE2) += sunxi_de2.o sunxi_dw_hdmi.o simplefb_common.o lcdc.o sunxi_lcd.o +obj-$(CONFIG_VIDEO_DE2) += sunxi_de2.o sunxi_dw_hdmi.o sunxi_dw_hdmi_phy.o simplefb_common.o lcdc.o sunxi_lcd.o diff --git a/drivers/video/sunxi/sunxi_dw_hdmi_phy.c b/drivers/video/sunxi/sunxi_dw_hdmi_phy.c new file mode 100644 index ..bed5c2fdfe81 --- /dev/null +++ b/drivers/video/sunxi/sunxi_dw_hdmi_phy.c @@ -0,0 +1,423 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Allwinner DW HDMI PHY driver + * + * (C) Copyright 2021 Jernej Skrabec + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "sunxi_dw_hdmi_phy.h" + +#define SUN8I_HDMI_PHY_DBG_CTRL_PX_LOCKBIT(0) +#define SUN8I_HDMI_PHY_DBG_CTRL_POL_MASK GENMASK(15, 8) +#define SUN8I_HDMI_PHY_DBG_CTRL_POL_NHSYNC BIT(8) +#define SUN8I_HDMI_PHY_DBG_CTRL_POL_NVSYNC BIT(9) +#define SUN8I_HDMI_PHY_DBG_CTRL_ADDR_MASK GENMASK(23, 16) +#define SUN8I_HDMI_PHY_DBG_CTRL_ADDR(addr) (addr << 16) + +#define SUN8I_HDMI_PHY_REXT_CTRL_REXT_EN BIT(31) + +#define SUN8I_HDMI_PHY_READ_EN_MAGIC 0x54524545 + +#define SUN8I_HDMI_PHY_UNSCRAMBLE_MAGIC0x42494E47 + +#define SUN8I_HDMI_PHY_ANA_CFG1_REG_SWIBIT(31) +#define SUN8I_HDMI_PHY_ANA_CFG1_REG_PWEND BIT(30) +#define SUN8I_HDMI_PHY_ANA_CFG1_REG_PWENC BIT(29) +#define SUN8I_HDMI_PHY_ANA_CFG1_REG_CALSW BIT(28) +#define SUN8I_HDMI_PHY_ANA_CFG1_REG_SVRCAL(x) ((x) << 26) +#define SUN8I_HDMI_PHY_ANA_CFG1_REG_SVBH(x)((x) << 24) +#define SUN8I_HDMI_PHY_ANA_CFG1_AMP_OPTBIT(23) +#define SUN8I_HDMI_PHY_ANA_CFG1_EMP_OPTBIT(22) +#define SUN8I_HDMI_PHY_ANA_CFG1_AMPCK_OPT BIT(21) +#define SUN8I_HDMI_PHY_ANA_CFG1_EMPCK_OPT BIT(20) +#define SUN8I_HDMI_PHY_ANA_CFG1_ENRCAL BIT(19) +#define SUN8I_HDMI_PHY_ANA_CFG1_ENCALOGBIT(18) +#define SUN8I_HDMI_PHY_ANA_CFG1_REG_SCKTMDSBIT(17) +#define SUN8I_HDMI_PHY_ANA_CFG1_TMDSCLK_EN BIT(16) +#define SUN8I_HDMI_PHY_ANA_CFG1_TXEN_MASK GENMASK(15, 12) +#define SUN8I_HDMI_PHY_ANA_CFG1_TXEN_ALL (0xf << 12) +#define SUN8I_HDMI_PHY_ANA_CFG1_BIASEN_TMDSCLK BIT(11) +#define SUN8I_HDMI_PHY_ANA_CFG1_BIASEN_TMDS2 BIT(10) +#define SUN8I_HDMI_PHY_ANA_CFG1_BIASEN_TMDS1 BIT(9) +#define SUN8I_HDMI_PHY_ANA_CFG1_BIASEN_TMDS0 BIT(8) +#define SUN8I_HDMI_PHY_ANA_CFG1_ENP2S_TMDSCLK BIT(7) +#define SUN8I_HDMI_PHY_ANA_CFG1_ENP2S_TMDS2BIT(6) +#define SUN8I_HDMI_PHY_ANA_CFG1_ENP2S_TMDS1BIT(5) +#define SUN8I_HDMI_PHY_ANA_CFG1_ENP2S_TMDS0BIT(4) +#define SUN8I_HDMI_PHY_ANA_CFG1_CKEN BIT(3) +#define SUN8I_HDMI_PHY_ANA_CFG1_LDOEN BIT(2) +#define SUN8I_HDMI_PHY_ANA_CFG1_ENVBS BIT(1) +#define SUN8I_HDMI_PHY_ANA_CFG1_ENBI BIT(0) + +#define SUN8I_HDMI_PHY_ANA_CFG2_M_EN BIT(31) +#define SUN8I_HDMI_PHY_ANA_CFG2_PLLDBENBIT(30) +#define SUN8I_HDMI_PHY_ANA_CFG2_SENBIT(29) +#define SUN8I_HDMI_PHY_ANA_CFG2_REG_HPDPD BIT(28) +#define SUN8I_HDMI_PHY_ANA_CFG2_REG_HPDEN BIT(27) +#define SUN8I_HDMI_PHY_ANA_CFG2_REG_PLRCK BIT(26) +#define SUN8I_HDMI_PHY_ANA_CFG2_REG_PLR(x) ((x) << 23) +#define SUN8I_HDMI_PHY_ANA_CFG2_REG_DENCK BIT(22) +#define SUN8I_HDMI_PHY_ANA_CFG2_REG_DENBIT(21) +#define SUN8I_HDMI_PHY_ANA_CFG2_REG_CD(x) ((x) << 19) +#define SUN8I_HDMI_PHY_ANA_CFG2_REG_CKSS(x)((x) << 17) +#define SUN8I_HDMI_PHY_ANA_CFG2_REG_BIGSWCKBIT(16) +#define SUN8I_HDMI_PHY_ANA_CFG2_REG_BIGSW BIT(15) +#define SUN8I_H
[linux-sunxi] [PATCH v2 12/19] video: sunxi: de2: switch to DT probing
Currently DE2 driver is probed via driver info. Switch probing to device tree compatible string method. Display is now searched via driver name which has same limitation as previous method. This can be improved only when all drivers in chain are probed via device tree compatible strings. Signed-off-by: Jernej Skrabec --- drivers/video/sunxi/sunxi_de2.c | 88 +++-- 1 file changed, 52 insertions(+), 36 deletions(-) diff --git a/drivers/video/sunxi/sunxi_de2.c b/drivers/video/sunxi/sunxi_de2.c index e02d359cd259..81576e45e9ef 100644 --- a/drivers/video/sunxi/sunxi_de2.c +++ b/drivers/video/sunxi/sunxi_de2.c @@ -31,6 +31,11 @@ enum { LCD_MAX_LOG2_BPP= VIDEO_BPP32, }; +struct sunxi_de2_data { + int id; + const char *disp_drv_name; +}; + static void sunxi_de2_composer_init(void) { struct sunxi_ccm_reg * const ccm = @@ -228,51 +233,34 @@ static int sunxi_de2_init(struct udevice *dev, ulong fbbase, static int sunxi_de2_probe(struct udevice *dev) { + const struct sunxi_de2_data *data = + (const struct sunxi_de2_data *)dev_get_driver_data(dev); struct video_uc_plat *plat = dev_get_uclass_plat(dev); struct udevice *disp; - int ret; + int ret, index = 0; /* Before relocation we don't need to do anything */ if (!(gd->flags & GD_FLG_RELOC)) return 0; - ret = uclass_get_device_by_driver(UCLASS_DISPLAY, - DM_DRIVER_GET(sunxi_lcd), ); - if (!ret) { - int mux; + while (!(ret = uclass_get_device(UCLASS_DISPLAY, index++, ))) { + if (strcmp(disp->driver->name, data->disp_drv_name)) + continue; - mux = 0; + ret = sunxi_de2_init(dev, plat->base, VIDEO_BPP32, disp, +data->id, false); + if (ret) + return ret; - ret = sunxi_de2_init(dev, plat->base, VIDEO_BPP32, disp, mux, -false); - if (!ret) { - video_set_flush_dcache(dev, 1); - return 0; - } - } - - debug("%s: lcd display not found (ret=%d)\n", __func__, ret); - - ret = uclass_get_device_by_driver(UCLASS_DISPLAY, - DM_DRIVER_GET(sunxi_dw_hdmi), ); - if (!ret) { - int mux; - if (IS_ENABLED(CONFIG_MACH_SUNXI_H3_H5)) - mux = 0; - else - mux = 1; + video_set_flush_dcache(dev, 1); - ret = sunxi_de2_init(dev, plat->base, VIDEO_BPP32, disp, mux, -false); - if (!ret) { - video_set_flush_dcache(dev, 1); - return 0; - } + return 0; } - debug("%s: hdmi display not found (ret=%d)\n", __func__, ret); + debug("%s: %s not found (ret=%d)\n", __func__, + data->disp_drv_name, ret); - return -ENODEV; + return ret; } static int sunxi_de2_bind(struct udevice *dev) @@ -285,22 +273,50 @@ static int sunxi_de2_bind(struct udevice *dev) return 0; } +const struct sunxi_de2_data h3_mixer_0 = { + .id = 0, + .disp_drv_name = "sunxi_dw_hdmi", +}; + +const struct sunxi_de2_data a64_mixer_0 = { + .id = 0, + .disp_drv_name = "sunxi_lcd", +}; + +const struct sunxi_de2_data a64_mixer_1 = { + .id = 1, + .disp_drv_name = "sunxi_dw_hdmi", +}; + +static const struct udevice_id sunxi_de2_ids[] = { + { + .compatible = "allwinner,sun8i-h3-de2-mixer-0", + .data = (ulong)_mixer_0, + }, + { + .compatible = "allwinner,sun50i-a64-de2-mixer-0", + .data = (ulong)_mixer_0, + }, + { + .compatible = "allwinner,sun50i-a64-de2-mixer-1", + .data = (ulong)_mixer_1, + }, + { } +}; + static const struct video_ops sunxi_de2_ops = { }; U_BOOT_DRIVER(sunxi_de2) = { .name = "sunxi_de2", .id = UCLASS_VIDEO, + .of_match = sunxi_de2_ids, .ops= _de2_ops, .bind = sunxi_de2_bind, .probe = sunxi_de2_probe, .flags = DM_FLAG_PRE_RELOC, }; -U_BOOT_DRVINFO(sunxi_de2) = { - .name = "sunxi_de2" -}; - /* * Simplefb support. */ -- 2.30.1 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210306195437.9740-13-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2 13/19] video: sunxi: de2: read address from DT node
Currently DE2 uses hardcoded address based on SoC for which U-Boot is built. Read it from DT instead so there is no need to specify it when support for new SoC is added. Signed-off-by: Jernej Skrabec --- drivers/video/sunxi/sunxi_de2.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/video/sunxi/sunxi_de2.c b/drivers/video/sunxi/sunxi_de2.c index 81576e45e9ef..f6c8ca075aba 100644 --- a/drivers/video/sunxi/sunxi_de2.c +++ b/drivers/video/sunxi/sunxi_de2.c @@ -64,11 +64,10 @@ static void sunxi_de2_composer_init(void) setbits_le32(>de_clk_cfg, CCM_DE2_CTRL_GATE); } -static void sunxi_de2_mode_set(int mux, const struct display_timing *mode, +static void sunxi_de2_mode_set(ulong de_mux_base, int mux, + const struct display_timing *mode, int bpp, ulong address, bool is_composite) { - ulong de_mux_base = (mux == 0) ? - SUNXI_DE2_MUX0_BASE : SUNXI_DE2_MUX1_BASE; struct de_clk * const de_clk_regs = (struct de_clk *)(SUNXI_DE2_BASE); struct de_glb * const de_glb_regs = @@ -208,7 +207,8 @@ static int sunxi_de2_init(struct udevice *dev, ulong fbbase, } sunxi_de2_composer_init(); - sunxi_de2_mode_set(mux, , 1 << l2bpp, fbbase, is_composite); + sunxi_de2_mode_set((ulong)dev_read_addr(dev), mux, , + 1 << l2bpp, fbbase, is_composite); ret = display_enable(disp, 1 << l2bpp, ); if (ret) { -- 2.30.1 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210306195437.9740-14-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2 16/19] video: sunxi: de2: switch clock setup to DM model
Now that proper DM clock and reset driver exists for Display Engine 2 and 3, remove all clock and reset related code and use appropriate framework instead. Signed-off-by: Jernej Skrabec --- arch/arm/mach-sunxi/Kconfig | 1 + drivers/video/sunxi/sunxi_de2.c | 67 +++-- 2 files changed, 23 insertions(+), 45 deletions(-) diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index 9149196b223e..34ef1f4b030f 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig @@ -970,6 +970,7 @@ config SUNXI_DE2 config VIDEO_DE2 bool "Display Engine 2 video driver" depends on SUNXI_DE2 + select CLK_SUN8I_DE2 select DM_VIDEO select DISPLAY select VIDEO_DW_HDMI diff --git a/drivers/video/sunxi/sunxi_de2.c b/drivers/video/sunxi/sunxi_de2.c index f6c8ca075aba..cee9b46b1259 100644 --- a/drivers/video/sunxi/sunxi_de2.c +++ b/drivers/video/sunxi/sunxi_de2.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -14,10 +15,10 @@ #include #include #include +#include #include #include #include -#include #include #include #include "simplefb_common.h" @@ -36,40 +37,10 @@ struct sunxi_de2_data { const char *disp_drv_name; }; -static void sunxi_de2_composer_init(void) -{ - struct sunxi_ccm_reg * const ccm = - (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; - -#ifdef CONFIG_MACH_SUN50I - u32 reg_value; - - /* set SRAM for video use (A64 only) */ - reg_value = readl(SUNXI_SRAMC_BASE + 0x04); - reg_value &= ~(0x01 << 24); - writel(reg_value, SUNXI_SRAMC_BASE + 0x04); -#endif - - clock_set_pll10(43200); - - /* Set DE parent to pll10 */ - clrsetbits_le32(>de_clk_cfg, CCM_DE2_CTRL_PLL_MASK, - CCM_DE2_CTRL_PLL10); - - /* Set ahb gating to pass */ - setbits_le32(>ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_DE); - setbits_le32(>ahb_gate1, 1 << AHB_GATE_OFFSET_DE); - - /* Clock on */ - setbits_le32(>de_clk_cfg, CCM_DE2_CTRL_GATE); -} - -static void sunxi_de2_mode_set(ulong de_mux_base, int mux, +static void sunxi_de2_mode_set(ulong de_mux_base, const struct display_timing *mode, int bpp, ulong address, bool is_composite) { - struct de_clk * const de_clk_regs = - (struct de_clk *)(SUNXI_DE2_BASE); struct de_glb * const de_glb_regs = (struct de_glb *)(de_mux_base + SUNXI_DE2_MUX_GLB_REGS); @@ -87,17 +58,6 @@ static void sunxi_de2_mode_set(ulong de_mux_base, int mux, int channel; u32 format; - /* enable clock */ -#ifdef CONFIG_MACH_SUN8I_H3 - setbits_le32(_clk_regs->rst_cfg, (mux == 0) ? 1 : 4); -#else - setbits_le32(_clk_regs->rst_cfg, BIT(mux)); -#endif - setbits_le32(_clk_regs->gate_cfg, BIT(mux)); - setbits_le32(_clk_regs->bus_cfg, BIT(mux)); - - clrbits_le32(_clk_regs->sel_cfg, 1); - writel(SUNXI_DE2_MUX_GLB_CTL_EN, _glb_regs->ctl); writel(0, _glb_regs->status); writel(1, _glb_regs->dbuff); @@ -189,6 +149,8 @@ static int sunxi_de2_init(struct udevice *dev, ulong fbbase, struct video_priv *uc_priv = dev_get_uclass_priv(dev); struct display_timing timing; struct display_plat *disp_uc_plat; + struct reset_ctl_bulk resets; + struct clk_bulk clocks; int ret; disp_uc_plat = dev_get_uclass_plat(disp); @@ -206,8 +168,23 @@ static int sunxi_de2_init(struct udevice *dev, ulong fbbase, return ret; } - sunxi_de2_composer_init(); - sunxi_de2_mode_set((ulong)dev_read_addr(dev), mux, , + ret = reset_get_bulk(dev, ); + if (ret) + return ret; + + ret = clk_get_bulk(dev, ); + if (ret) + return ret; + + ret = clk_enable_bulk(); + if (ret) + return ret; + + ret = reset_deassert_bulk(); + if (ret) + return ret; + + sunxi_de2_mode_set((ulong)dev_read_addr(dev), , 1 << l2bpp, fbbase, is_composite); ret = display_enable(disp, 1 << l2bpp, ); -- 2.30.1 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210306195437.9740-17-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2 17/19] video: dw-hdmi: modify phy init callback to include full timings
Currently PHY init callback has only pixel clock as a parameter, but other timing parameters may be needed for custom PHYs. Modify callback signature to include full timings. Cc: Neil Armstrong Signed-off-by: Jernej Skrabec --- drivers/video/dw_hdmi.c | 6 +++--- drivers/video/meson/meson_dw_hdmi.c | 5 +++-- drivers/video/sunxi/sunxi_dw_hdmi.c | 7 --- include/dw_hdmi.h | 4 ++-- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/video/dw_hdmi.c b/drivers/video/dw_hdmi.c index c4fbb1829446..8d71f713f99f 100644 --- a/drivers/video/dw_hdmi.c +++ b/drivers/video/dw_hdmi.c @@ -901,7 +901,7 @@ static const u8 pre_buf[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe9, }; -int dw_hdmi_phy_cfg(struct dw_hdmi *hdmi, uint mpixelclock) +int dw_hdmi_phy_cfg(struct dw_hdmi *hdmi, const struct display_timing *edid) { int i, ret; @@ -912,7 +912,7 @@ int dw_hdmi_phy_cfg(struct dw_hdmi *hdmi, uint mpixelclock) hdmi_phy_enable_tmds(hdmi, 0); hdmi_phy_enable_power(hdmi, 0); - ret = hdmi_phy_configure(hdmi, mpixelclock); + ret = hdmi_phy_configure(hdmi, edid->pixelclock.typ); if (ret) { debug("hdmi phy config failure %d\n", ret); return ret; @@ -988,7 +988,7 @@ int dw_hdmi_enable(struct dw_hdmi *hdmi, const struct display_timing *edid) hdmi_av_composer(hdmi, edid); - ret = hdmi->phy_set(hdmi, edid->pixelclock.typ); + ret = hdmi->phy_set(hdmi, edid); if (ret) return ret; diff --git a/drivers/video/meson/meson_dw_hdmi.c b/drivers/video/meson/meson_dw_hdmi.c index e5f281320534..7558814b3491 100644 --- a/drivers/video/meson/meson_dw_hdmi.c +++ b/drivers/video/meson/meson_dw_hdmi.c @@ -292,7 +292,8 @@ static void meson_dw_hdmi_phy_setup_mode(struct meson_dw_hdmi *priv, } } -static int meson_dw_hdmi_phy_init(struct dw_hdmi *hdmi, uint pixel_clock) +static int meson_dw_hdmi_phy_init(struct dw_hdmi *hdmi, + const struct display_timing *edid) { struct meson_dw_hdmi *priv = container_of(hdmi, struct meson_dw_hdmi, hdmi); @@ -322,7 +323,7 @@ static int meson_dw_hdmi_phy_init(struct dw_hdmi *hdmi, uint pixel_clock) dw_hdmi_top_write(hdmi, HDMITX_TOP_TMDS_CLK_PTTN_CNTL, 0x2); /* Setup PHY parameters */ - meson_dw_hdmi_phy_setup_mode(priv, pixel_clock); + meson_dw_hdmi_phy_setup_mode(priv, edid->pixelclock.typ); /* Setup PHY */ dw_hdmi_hhi_update_bits(priv, HHI_HDMI_PHY_CNTL1, diff --git a/drivers/video/sunxi/sunxi_dw_hdmi.c b/drivers/video/sunxi/sunxi_dw_hdmi.c index 0744954fa15f..483d57293155 100644 --- a/drivers/video/sunxi/sunxi_dw_hdmi.c +++ b/drivers/video/sunxi/sunxi_dw_hdmi.c @@ -266,12 +266,13 @@ static void sunxi_dw_hdmi_lcdc_init(int mux, const struct display_timing *edid, lcdc_enable(lcdc, bpp); } -static int sunxi_dw_hdmi_phy_cfg(struct dw_hdmi *hdmi, uint mpixelclock) +static int sunxi_dw_hdmi_phy_cfg(struct dw_hdmi *hdmi, +const struct display_timing *edid) { int phy_div; - sunxi_dw_hdmi_pll_set(mpixelclock / 1000, _div); - sunxi_dw_hdmi_phy_set(hdmi, mpixelclock, phy_div); + sunxi_dw_hdmi_pll_set(edid->pixelclock.typ / 1000, _div); + sunxi_dw_hdmi_phy_set(hdmi, edid->pixelclock.typ, phy_div); return 0; } diff --git a/include/dw_hdmi.h b/include/dw_hdmi.h index 8acae3839fb3..46b87916b8bb 100644 --- a/include/dw_hdmi.h +++ b/include/dw_hdmi.h @@ -544,12 +544,12 @@ struct dw_hdmi { struct hdmi_data_info hdmi_data; struct udevice *ddc_bus; - int (*phy_set)(struct dw_hdmi *hdmi, uint mpixelclock); + int (*phy_set)(struct dw_hdmi *hdmi, const struct display_timing *edid); void (*write_reg)(struct dw_hdmi *hdmi, u8 val, int offset); u8 (*read_reg)(struct dw_hdmi *hdmi, int offset); }; -int dw_hdmi_phy_cfg(struct dw_hdmi *hdmi, uint mpixelclock); +int dw_hdmi_phy_cfg(struct dw_hdmi *hdmi, const struct display_timing *edid); int dw_hdmi_phy_wait_for_hpd(struct dw_hdmi *hdmi); void dw_hdmi_phy_init(struct dw_hdmi *hdmi); -- 2.30.1 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210306195437.9740-18-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2 11/19] video: sunxi: dw-hdmi: read address from DT node
Currently HDMI controller MMIO address is hardcoded. Change that so address is read from DT node. That will make adding support for new variants a bit easier. Signed-off-by: Jernej Skrabec --- drivers/video/sunxi/sunxi_dw_hdmi.c | 38 ++--- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/drivers/video/sunxi/sunxi_dw_hdmi.c b/drivers/video/sunxi/sunxi_dw_hdmi.c index 6f77b2a43b40..0744954fa15f 100644 --- a/drivers/video/sunxi/sunxi_dw_hdmi.c +++ b/drivers/video/sunxi/sunxi_dw_hdmi.c @@ -57,10 +57,10 @@ static int sunxi_dw_hdmi_get_divider(uint clock) return 1; } -static void sunxi_dw_hdmi_phy_init(void) +static void sunxi_dw_hdmi_phy_init(struct dw_hdmi *hdmi) { struct sunxi_hdmi_phy * const phy = - (struct sunxi_hdmi_phy *)(SUNXI_HDMI_BASE + HDMI_PHY_OFFS); + (struct sunxi_hdmi_phy *)(hdmi->ioaddr + HDMI_PHY_OFFS); unsigned long tmo; u32 tmp; @@ -114,10 +114,10 @@ static void sunxi_dw_hdmi_phy_init(void) writel(0x42494E47, >unscramble); } -static void sunxi_dw_hdmi_phy_set(uint clock, int phy_div) +static void sunxi_dw_hdmi_phy_set(struct dw_hdmi *hdmi, uint clock, int phy_div) { struct sunxi_hdmi_phy * const phy = - (struct sunxi_hdmi_phy *)(SUNXI_HDMI_BASE + HDMI_PHY_OFFS); + (struct sunxi_hdmi_phy *)(hdmi->ioaddr + HDMI_PHY_OFFS); int div = sunxi_dw_hdmi_get_divider(clock); u32 tmp; @@ -271,7 +271,7 @@ static int sunxi_dw_hdmi_phy_cfg(struct dw_hdmi *hdmi, uint mpixelclock) int phy_div; sunxi_dw_hdmi_pll_set(mpixelclock / 1000, _div); - sunxi_dw_hdmi_phy_set(mpixelclock, phy_div); + sunxi_dw_hdmi_phy_set(hdmi, mpixelclock, phy_div); return 0; } @@ -292,9 +292,9 @@ static bool sunxi_dw_hdmi_mode_valid(struct udevice *dev, static int sunxi_dw_hdmi_enable(struct udevice *dev, int panel_bpp, const struct display_timing *edid) { - struct sunxi_hdmi_phy * const phy = - (struct sunxi_hdmi_phy *)(SUNXI_HDMI_BASE + HDMI_PHY_OFFS); struct sunxi_dw_hdmi_priv *priv = dev_get_priv(dev); + struct sunxi_hdmi_phy * const phy = + (struct sunxi_hdmi_phy *)(priv->hdmi.ioaddr + HDMI_PHY_OFFS); int ret; ret = dw_hdmi_enable(>hdmi, edid); @@ -316,12 +316,26 @@ static int sunxi_dw_hdmi_enable(struct udevice *dev, int panel_bpp, * again or othwerwise BSP driver won't work. Dummy read is * needed or otherwise last write doesn't get written correctly. */ - (void)readb(SUNXI_HDMI_BASE); + (void)readb(priv->hdmi.ioaddr); writel(0, >unscramble); return 0; } +static int sunxi_dw_hdmi_of_to_plat(struct udevice *dev) +{ + struct sunxi_dw_hdmi_priv *priv = dev_get_priv(dev); + struct dw_hdmi *hdmi = >hdmi; + + hdmi->ioaddr = (ulong)dev_read_addr(dev); + hdmi->i2c_clk_high = 0xd8; + hdmi->i2c_clk_low = 0xfe; + hdmi->reg_io_width = 1; + hdmi->phy_set = sunxi_dw_hdmi_phy_cfg; + + return 0; +} + static int sunxi_dw_hdmi_probe(struct udevice *dev) { struct display_plat *uc_plat = dev_get_uclass_plat(dev); @@ -346,13 +360,8 @@ static int sunxi_dw_hdmi_probe(struct udevice *dev) /* Clock on */ setbits_le32(>hdmi_clk_cfg, CCM_HDMI_CTRL_GATE); - sunxi_dw_hdmi_phy_init(); + sunxi_dw_hdmi_phy_init(>hdmi); - priv->hdmi.ioaddr = SUNXI_HDMI_BASE; - priv->hdmi.i2c_clk_high = 0xd8; - priv->hdmi.i2c_clk_low = 0xfe; - priv->hdmi.reg_io_width = 1; - priv->hdmi.phy_set = sunxi_dw_hdmi_phy_cfg; priv->mux = uc_plat->source_id; ret = dw_hdmi_phy_wait_for_hpd(>hdmi); @@ -382,6 +391,7 @@ U_BOOT_DRIVER(sunxi_dw_hdmi) = { .id = UCLASS_DISPLAY, .of_match = sunxi_dw_hdmi_ids, .ops= _dw_hdmi_ops, + .of_to_plat = sunxi_dw_hdmi_of_to_plat, .probe = sunxi_dw_hdmi_probe, .priv_auto = sizeof(struct sunxi_dw_hdmi_priv), }; -- 2.30.1 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210306195437.9740-12-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2 15/19] clk: sunxi: add DE2 clock driver
Video driver currently manages clocks and resets by directly writing to registers. This is already a bit messy because each SoC has some specifics. It's much better to implement proper clock and reset driver which takes information from device tree file. Note that this driver is not perfect yet. It still sets PLL and parent by hand. Sunxi clock framework still doesn't know how to set parents or rates. However, this is already big step in right direction. Cc: Lukasz Majewski Signed-off-by: Jernej Skrabec --- drivers/clk/sunxi/Kconfig | 5 +++ drivers/clk/sunxi/Makefile | 1 + drivers/clk/sunxi/clk_de2.c | 85 + 3 files changed, 91 insertions(+) create mode 100644 drivers/clk/sunxi/clk_de2.c diff --git a/drivers/clk/sunxi/Kconfig b/drivers/clk/sunxi/Kconfig index bf084fa7a84a..6c96affb1f87 100644 --- a/drivers/clk/sunxi/Kconfig +++ b/drivers/clk/sunxi/Kconfig @@ -44,6 +44,11 @@ config CLK_SUN8I_A83T This enables common clock driver support for platforms based on Allwinner A83T SoC. +config CLK_SUN8I_DE2 + bool "Clock driver for Allwinner Display Engine 2 and 3" + help + This enables common clock driver support for Display Engine 2 and 3. + config CLK_SUN8I_R40 bool "Clock driver for Allwinner R40" default MACH_SUN8I_R40 diff --git a/drivers/clk/sunxi/Makefile b/drivers/clk/sunxi/Makefile index 0dfc0593fb1c..620ff96ac6f5 100644 --- a/drivers/clk/sunxi/Makefile +++ b/drivers/clk/sunxi/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_CLK_SUN5I_A10S) += clk_a10s.o obj-$(CONFIG_CLK_SUN6I_A31) += clk_a31.o obj-$(CONFIG_CLK_SUN8I_A23) += clk_a23.o obj-$(CONFIG_CLK_SUN8I_A83T) += clk_a83t.o +obj-$(CONFIG_CLK_SUN8I_DE2) += clk_de2.o obj-$(CONFIG_CLK_SUN8I_R40) += clk_r40.o obj-$(CONFIG_CLK_SUN8I_V3S) += clk_v3s.o obj-$(CONFIG_CLK_SUN9I_A80) += clk_a80.o diff --git a/drivers/clk/sunxi/clk_de2.c b/drivers/clk/sunxi/clk_de2.c new file mode 100644 index ..b8c45404c1b6 --- /dev/null +++ b/drivers/clk/sunxi/clk_de2.c @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2021 Jernej Skrabec + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct ccu_clk_gate de2_gates[] = { + [CLK_MIXER0]= GATE(0x00, BIT(0)), + [CLK_MIXER1]= GATE(0x00, BIT(1)), + [CLK_WB]= GATE(0x00, BIT(2)), + + [CLK_BUS_MIXER0]= GATE(0x04, BIT(0)), + [CLK_BUS_MIXER1]= GATE(0x04, BIT(1)), + [CLK_BUS_WB]= GATE(0x04, BIT(2)), +}; + +static struct ccu_reset de2_resets[] = { + [RST_MIXER0]= RESET(0x08, BIT(0)), + [RST_MIXER1]= RESET(0x08, BIT(1)), + [RST_WB]= RESET(0x08, BIT(2)), +}; + +static const struct ccu_desc de2_ccu_desc = { + .gates = de2_gates, + .resets = de2_resets, +}; + +static int de2_clk_probe(struct udevice *dev) +{ + struct sunxi_ccm_reg * const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + u32 val; + + if (device_is_compatible(dev_get_parent(dev), +"allwinner,sun50i-a64-de2")) { + /* set SRAM for video use */ + val = readl(SUNXI_SRAMC_BASE + 0x04); + val &= ~(0x01 << 24); + writel(val, SUNXI_SRAMC_BASE + 0x04); + } + + /* clock driver doesn't know how to set rate or parent yet */ + clock_set_pll10(43200); + + /* Set DE parent to pll10 */ + clrsetbits_le32(>de_clk_cfg, CCM_DE2_CTRL_PLL_MASK, + CCM_DE2_CTRL_PLL10); + + return sunxi_clk_probe(dev); +} + +static int de2_clk_bind(struct udevice *dev) +{ + return sunxi_reset_bind(dev, ARRAY_SIZE(de2_resets)); +} + +static const struct udevice_id de2_ccu_ids[] = { + { .compatible = "allwinner,sun8i-h3-de2-clk", + .data = (ulong)_ccu_desc }, + { .compatible = "allwinner,sun50i-a64-de2-clk", + .data = (ulong)_ccu_desc }, + { .compatible = "allwinner,sun50i-h5-de2-clk", + .data = (ulong)_ccu_desc }, + { } +}; + +U_BOOT_DRIVER(clk_sun8i_de2) = { + .name = "sun8i_de2_ccu", + .id = UCLASS_CLK, + .of_match = de2_ccu_ids, + .priv_auto = sizeof(struct ccu_priv), + .ops= _clk_ops, + .probe = de2_clk_probe, + .bind = de2_clk_bind, +}; -- 2.30.1 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210306195437.9740-16-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2 14/19] clk: sunxi: Add DE2 and HDMI clocks to H3 and A64
These clocks and resets are needed for video drivers. Cc: Lukasz Majewski Signed-off-by: Jernej Skrabec --- drivers/clk/sunxi/clk_a64.c | 12 drivers/clk/sunxi/clk_h3.c | 12 2 files changed, 24 insertions(+) diff --git a/drivers/clk/sunxi/clk_a64.c b/drivers/clk/sunxi/clk_a64.c index 0553ffa4399a..28131240652f 100644 --- a/drivers/clk/sunxi/clk_a64.c +++ b/drivers/clk/sunxi/clk_a64.c @@ -26,6 +26,9 @@ static const struct ccu_clk_gate a64_gates[] = { [CLK_BUS_OHCI0] = GATE(0x060, BIT(28)), [CLK_BUS_OHCI1] = GATE(0x060, BIT(29)), + [CLK_BUS_HDMI] = GATE(0x064, BIT(11)), + [CLK_BUS_DE]= GATE(0x064, BIT(12)), + [CLK_BUS_UART0] = GATE(0x06c, BIT(16)), [CLK_BUS_UART1] = GATE(0x06c, BIT(17)), [CLK_BUS_UART2] = GATE(0x06c, BIT(18)), @@ -41,6 +44,11 @@ static const struct ccu_clk_gate a64_gates[] = { [CLK_USB_HSIC_12M] = GATE(0x0cc, BIT(11)), [CLK_USB_OHCI0] = GATE(0x0cc, BIT(16)), [CLK_USB_OHCI1] = GATE(0x0cc, BIT(17)), + + [CLK_DE]= GATE(0x104, BIT(31)), + + [CLK_HDMI] = GATE(0x150, BIT(31)), + [CLK_HDMI_DDC] = GATE(0x154, BIT(31)), }; static const struct ccu_reset a64_resets[] = { @@ -60,6 +68,10 @@ static const struct ccu_reset a64_resets[] = { [RST_BUS_OHCI0] = RESET(0x2c0, BIT(28)), [RST_BUS_OHCI1] = RESET(0x2c0, BIT(29)), + [RST_BUS_HDMI0] = RESET(0x2c4, BIT(10)), + [RST_BUS_HDMI1] = RESET(0x2c4, BIT(11)), + [RST_BUS_DE]= RESET(0x2c4, BIT(12)), + [RST_BUS_UART0] = RESET(0x2d8, BIT(16)), [RST_BUS_UART1] = RESET(0x2d8, BIT(17)), [RST_BUS_UART2] = RESET(0x2d8, BIT(18)), diff --git a/drivers/clk/sunxi/clk_h3.c b/drivers/clk/sunxi/clk_h3.c index f81633b92d5a..806a35b37435 100644 --- a/drivers/clk/sunxi/clk_h3.c +++ b/drivers/clk/sunxi/clk_h3.c @@ -30,6 +30,9 @@ static struct ccu_clk_gate h3_gates[] = { [CLK_BUS_OHCI2] = GATE(0x060, BIT(30)), [CLK_BUS_OHCI3] = GATE(0x060, BIT(31)), + [CLK_BUS_HDMI] = GATE(0x064, BIT(11)), + [CLK_BUS_DE]= GATE(0x064, BIT(12)), + [CLK_BUS_UART0] = GATE(0x06c, BIT(16)), [CLK_BUS_UART1] = GATE(0x06c, BIT(17)), [CLK_BUS_UART2] = GATE(0x06c, BIT(18)), @@ -48,6 +51,11 @@ static struct ccu_clk_gate h3_gates[] = { [CLK_USB_OHCI1] = GATE(0x0cc, BIT(17)), [CLK_USB_OHCI2] = GATE(0x0cc, BIT(18)), [CLK_USB_OHCI3] = GATE(0x0cc, BIT(19)), + + [CLK_DE]= GATE(0x104, BIT(31)), + + [CLK_HDMI] = GATE(0x150, BIT(31)), + [CLK_HDMI_DDC] = GATE(0x154, BIT(31)), }; static struct ccu_reset h3_resets[] = { @@ -72,6 +80,10 @@ static struct ccu_reset h3_resets[] = { [RST_BUS_OHCI2] = RESET(0x2c0, BIT(30)), [RST_BUS_OHCI3] = RESET(0x2c0, BIT(31)), + [RST_BUS_HDMI0] = RESET(0x2c4, BIT(10)), + [RST_BUS_HDMI1] = RESET(0x2c4, BIT(11)), + [RST_BUS_DE]= RESET(0x2c4, BIT(12)), + [RST_BUS_EPHY] = RESET(0x2c8, BIT(2)), [RST_BUS_UART0] = RESET(0x2d8, BIT(16)), -- 2.30.1 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210306195437.9740-15-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2 10/19] video: sunxi: dw-hdmi: probe driver by compatible
Currently sunxi dw-hdmi driver is probed unconditionally, even if there is no such device. Switch driver to probing via compatible string. This brings many benefits - driver can read DT node and allows driver to be always enabled. Signed-off-by: Jernej Skrabec --- drivers/video/sunxi/sunxi_dw_hdmi.c | 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/video/sunxi/sunxi_dw_hdmi.c b/drivers/video/sunxi/sunxi_dw_hdmi.c index 6d2bc206fc2c..6f77b2a43b40 100644 --- a/drivers/video/sunxi/sunxi_dw_hdmi.c +++ b/drivers/video/sunxi/sunxi_dw_hdmi.c @@ -372,14 +372,16 @@ static const struct dm_display_ops sunxi_dw_hdmi_ops = { .mode_valid = sunxi_dw_hdmi_mode_valid, }; +static const struct udevice_id sunxi_dw_hdmi_ids[] = { + { .compatible = "allwinner,sun8i-a83t-dw-hdmi" }, + { } +}; + U_BOOT_DRIVER(sunxi_dw_hdmi) = { .name = "sunxi_dw_hdmi", .id = UCLASS_DISPLAY, + .of_match = sunxi_dw_hdmi_ids, .ops= _dw_hdmi_ops, .probe = sunxi_dw_hdmi_probe, .priv_auto = sizeof(struct sunxi_dw_hdmi_priv), }; - -U_BOOT_DRVINFO(sunxi_dw_hdmi) = { - .name = "sunxi_dw_hdmi" -}; -- 2.30.1 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210306195437.9740-11-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2 09/19] video: sunxi: de2: switch to public uclass functions
Currently DE2 driver uses functions which are defined in internal headers. They are not meant to be used outside of uclass framework. Switch DE2 driver to public ones. This has additional benefit that device_probe doesn't need to be called manually. Signed-off-by: Jernej Skrabec --- drivers/video/sunxi/sunxi_de2.c | 29 ++--- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/drivers/video/sunxi/sunxi_de2.c b/drivers/video/sunxi/sunxi_de2.c index 6b836a011944..e02d359cd259 100644 --- a/drivers/video/sunxi/sunxi_de2.c +++ b/drivers/video/sunxi/sunxi_de2.c @@ -19,8 +19,6 @@ #include #include #include -#include -#include #include #include "simplefb_common.h" @@ -198,13 +196,6 @@ static int sunxi_de2_init(struct udevice *dev, ulong fbbase, disp_uc_plat->source_id = mux; - ret = device_probe(disp); - if (ret) { - debug("%s: device '%s' display won't probe (ret=%d)\n", - __func__, dev->name, ret); - return ret; - } - ret = display_read_timing(disp, ); if (ret) { debug("%s: Failed to read timings\n", __func__); @@ -245,8 +236,8 @@ static int sunxi_de2_probe(struct udevice *dev) if (!(gd->flags & GD_FLG_RELOC)) return 0; - ret = uclass_find_device_by_name(UCLASS_DISPLAY, -"sunxi_lcd", ); + ret = uclass_get_device_by_driver(UCLASS_DISPLAY, + DM_DRIVER_GET(sunxi_lcd), ); if (!ret) { int mux; @@ -262,8 +253,8 @@ static int sunxi_de2_probe(struct udevice *dev) debug("%s: lcd display not found (ret=%d)\n", __func__, ret); - ret = uclass_find_device_by_name(UCLASS_DISPLAY, -"sunxi_dw_hdmi", ); + ret = uclass_get_device_by_driver(UCLASS_DISPLAY, + DM_DRIVER_GET(sunxi_dw_hdmi), ); if (!ret) { int mux; if (IS_ENABLED(CONFIG_MACH_SUNXI_H3_H5)) @@ -332,8 +323,8 @@ int sunxi_simplefb_setup(void *blob) mux = 1; /* Skip simplefb setting if DE2 / HDMI is not present */ - ret = uclass_find_device_by_name(UCLASS_VIDEO, -"sunxi_de2", ); + ret = uclass_get_device_by_driver(UCLASS_VIDEO, + DM_DRIVER_GET(sunxi_de2), ); if (ret) { debug("DE2 not present\n"); return 0; @@ -342,8 +333,8 @@ int sunxi_simplefb_setup(void *blob) return 0; } - ret = uclass_find_device_by_name(UCLASS_DISPLAY, -"sunxi_dw_hdmi", ); + ret = uclass_get_device_by_driver(UCLASS_DISPLAY, + DM_DRIVER_GET(sunxi_dw_hdmi), ); if (ret) { debug("HDMI not present\n"); } else if (device_active(hdmi)) { @@ -355,8 +346,8 @@ int sunxi_simplefb_setup(void *blob) debug("HDMI present but not probed\n"); } - ret = uclass_find_device_by_name(UCLASS_DISPLAY, -"sunxi_lcd", ); + ret = uclass_get_device_by_driver(UCLASS_DISPLAY, + DM_DRIVER_GET(sunxi_lcd), ); if (ret) debug("LCD not present\n"); else if (device_active(lcd)) -- 2.30.1 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210306195437.9740-10-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2 08/19] video: sunxi: Remove TV probe from DE2
TV driver was never fully implemented. Remove search for it from DE2 driver. Signed-off-by: Jernej Skrabec --- drivers/video/sunxi/sunxi_de2.c | 15 +-- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/drivers/video/sunxi/sunxi_de2.c b/drivers/video/sunxi/sunxi_de2.c index a3e21aa5f13e..6b836a011944 100644 --- a/drivers/video/sunxi/sunxi_de2.c +++ b/drivers/video/sunxi/sunxi_de2.c @@ -281,20 +281,7 @@ static int sunxi_de2_probe(struct udevice *dev) debug("%s: hdmi display not found (ret=%d)\n", __func__, ret); - ret = uclass_find_device_by_name(UCLASS_DISPLAY, - "sunxi_tve", ); - if (ret) { - debug("%s: tv not found (ret=%d)\n", __func__, ret); - return ret; - } - - ret = sunxi_de2_init(dev, plat->base, VIDEO_BPP32, disp, 1, true); - if (ret) - return ret; - - video_set_flush_dcache(dev, 1); - - return 0; + return -ENODEV; } static int sunxi_de2_bind(struct udevice *dev) -- 2.30.1 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210306195437.9740-9-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2 07/19] video: sunxi: Remove check for ddc-i2c-bus property
No Allwinner board with DW-HDMI controller use separate I2C bus for EDID read. Remove that check. Reviewed-by: Andre Przywara Signed-off-by: Jernej Skrabec --- drivers/video/sunxi/sunxi_dw_hdmi.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/video/sunxi/sunxi_dw_hdmi.c b/drivers/video/sunxi/sunxi_dw_hdmi.c index 37e78ff24111..6d2bc206fc2c 100644 --- a/drivers/video/sunxi/sunxi_dw_hdmi.c +++ b/drivers/video/sunxi/sunxi_dw_hdmi.c @@ -361,9 +361,6 @@ static int sunxi_dw_hdmi_probe(struct udevice *dev) return -1; } - uclass_get_device_by_phandle(UCLASS_I2C, dev, "ddc-i2c-bus", ->hdmi.ddc_bus); - dw_hdmi_init(>hdmi); return 0; -- 2.30.1 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210306195437.9740-8-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2 06/19] video: sunxi: Use DW-HDMI hpd function
It turns out that there are two ways how hot plug detection can be done. One is standard way for DW HDMI controller - checking bit 2 in 0x3004 register. Another way is applicable only to Allwinner custom PHY - by checking bit 19 in register 0x10038. Both method are equally good as far as we know. Use standard method in order to reduce amount of custom code. Signed-off-by: Jernej Skrabec --- drivers/video/sunxi/sunxi_dw_hdmi.c | 34 + 1 file changed, 6 insertions(+), 28 deletions(-) diff --git a/drivers/video/sunxi/sunxi_dw_hdmi.c b/drivers/video/sunxi/sunxi_dw_hdmi.c index e3811a2ec15f..37e78ff24111 100644 --- a/drivers/video/sunxi/sunxi_dw_hdmi.c +++ b/drivers/video/sunxi/sunxi_dw_hdmi.c @@ -114,28 +114,6 @@ static void sunxi_dw_hdmi_phy_init(void) writel(0x42494E47, >unscramble); } -static int sunxi_dw_hdmi_get_plug_in_status(void) -{ - struct sunxi_hdmi_phy * const phy = - (struct sunxi_hdmi_phy *)(SUNXI_HDMI_BASE + HDMI_PHY_OFFS); - - return !!(readl(>status) & (1 << 19)); -} - -static int sunxi_dw_hdmi_wait_for_hpd(void) -{ - ulong start; - - start = get_timer(0); - do { - if (sunxi_dw_hdmi_get_plug_in_status()) - return 0; - udelay(100); - } while (get_timer(start) < 300); - - return -1; -} - static void sunxi_dw_hdmi_phy_set(uint clock, int phy_div) { struct sunxi_hdmi_phy * const phy = @@ -370,12 +348,6 @@ static int sunxi_dw_hdmi_probe(struct udevice *dev) sunxi_dw_hdmi_phy_init(); - ret = sunxi_dw_hdmi_wait_for_hpd(); - if (ret < 0) { - debug("hdmi can not get hpd signal\n"); - return -1; - } - priv->hdmi.ioaddr = SUNXI_HDMI_BASE; priv->hdmi.i2c_clk_high = 0xd8; priv->hdmi.i2c_clk_low = 0xfe; @@ -383,6 +355,12 @@ static int sunxi_dw_hdmi_probe(struct udevice *dev) priv->hdmi.phy_set = sunxi_dw_hdmi_phy_cfg; priv->mux = uc_plat->source_id; + ret = dw_hdmi_phy_wait_for_hpd(>hdmi); + if (ret < 0) { + debug("hdmi can not get hpd signal\n"); + return -1; + } + uclass_get_device_by_phandle(UCLASS_I2C, dev, "ddc-i2c-bus", >hdmi.ddc_bus); -- 2.30.1 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210306195437.9740-7-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2 05/19] common: edid: Search for valid timing in extension block
One of my monitors have only 4k@60 timing in base EDID block which is out of range for devices with HDMI 1.4. It turns out that it has additional detailed timings in CTA-861 Extension Block and two of them are appropriate for HDMI 1.4. Add additional search for valid detailed timing in extension block. Signed-off-by: Jernej Skrabec --- common/edid.c | 18 ++ 1 file changed, 18 insertions(+) diff --git a/common/edid.c b/common/edid.c index a6c875d9c8e8..14d8836c360e 100644 --- a/common/edid.c +++ b/common/edid.c @@ -220,6 +220,24 @@ int edid_get_timing_validate(u8 *buf, int buf_size, /* Look for detailed timing in base EDID */ found = edid_find_valid_timing(edid->monitor_details.descriptor, 4, timing, mode_valid, mode_valid_priv); + + /* Look for detailed timing in CTA-861 Extension Block */ + if (!found && edid->extension_flag && buf_size >= EDID_EXT_SIZE) { + struct edid_cea861_info *info = + (struct edid_cea861_info *)(buf + sizeof(*edid)); + + if (info->extension_tag == EDID_CEA861_EXTENSION_TAG) { + int count = EDID_CEA861_DTD_COUNT(*info); + int offset = info->dtd_offset; + int size = count * sizeof(struct edid_detailed_timing); + + if (offset >= 4 && offset + size < EDID_SIZE) + found = edid_find_valid_timing( + (u8*)info + offset, count, timing, + mode_valid, mode_valid_priv); + } + } + if (!found) return -EINVAL; -- 2.30.1 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210306195437.9740-6-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2 04/19] common: edid: extract code for detailed timing search
Code which searches for valid detailed timing entry will be used in more places. Extract it. No functional change is made. However, descriptors are casted to edid_detailed_timing instead of edid_monitor_descriptor. Descriptor can be of either type, but since we're interested only in DTD, it is more fitting to cast to edid_detailed_timing. Signed-off-by: Jernej Skrabec --- common/edid.c | 49 - 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/common/edid.c b/common/edid.c index 1cb7177742e8..a6c875d9c8e8 100644 --- a/common/edid.c +++ b/common/edid.c @@ -169,6 +169,29 @@ static bool cea_is_hdmi_vsdb_present(struct edid_cea861_info *info) return false; } +static bool edid_find_valid_timing(void *buf, int count, + struct display_timing *timing, + bool (*mode_valid)(void *priv, + const struct display_timing *timing), + void *mode_valid_priv) +{ + struct edid_detailed_timing *t = buf; + bool found = false; + int i; + + for (i = 0; i < count && !found; i++, t++) + if (EDID_DETAILED_TIMING_PIXEL_CLOCK(*t) != 0) { + decode_timing((u8 *)t, timing); + if (mode_valid) + found = mode_valid(mode_valid_priv, + timing); + else + found = true; + } + + return found; +} + int edid_get_timing_validate(u8 *buf, int buf_size, struct display_timing *timing, int *panel_bits_per_colourp, @@ -177,8 +200,7 @@ int edid_get_timing_validate(u8 *buf, int buf_size, void *mode_valid_priv) { struct edid1_info *edid = (struct edid1_info *)buf; - bool timing_done; - int i; + bool found; if (buf_size < sizeof(*edid) || edid_check_info(edid)) { debug("%s: Invalid buffer\n", __func__); @@ -195,25 +217,10 @@ int edid_get_timing_validate(u8 *buf, int buf_size, return -ENOENT; } - /* Look for detailed timing */ - timing_done = false; - for (i = 0; i < 4; i++) { - struct edid_monitor_descriptor *desc; - - desc = >monitor_details.descriptor[i]; - if (desc->zero_flag_1 != 0) { - decode_timing((u8 *)desc, timing); - if (mode_valid) - timing_done = mode_valid(mode_valid_priv, -timing); - else - timing_done = true; - - if (timing_done) - break; - } - } - if (!timing_done) + /* Look for detailed timing in base EDID */ + found = edid_find_valid_timing(edid->monitor_details.descriptor, 4, + timing, mode_valid, mode_valid_priv); + if (!found) return -EINVAL; if (edid->version != 1 || edid->revision < 4) { -- 2.30.1 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210306195437.9740-5-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2 03/19] common: edid: check for digital display earlier
When searching for detailed timing in EDID, check for digital display earlier. There is no point parsing other parameters if this flag is not present. Reviewed-by: Andre Przywara Signed-off-by: Jernej Skrabec --- common/edid.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/common/edid.c b/common/edid.c index 553ab8fd01a1..1cb7177742e8 100644 --- a/common/edid.c +++ b/common/edid.c @@ -185,6 +185,11 @@ int edid_get_timing_validate(u8 *buf, int buf_size, return -EINVAL; } + if (!EDID1_INFO_VIDEO_INPUT_DIGITAL(*edid)) { + debug("%s: Not a digital display\n", __func__); + return -ENOSYS; + } + if (!EDID1_INFO_FEATURE_PREFERRED_TIMING_MODE(*edid)) { debug("%s: No preferred timing\n", __func__); return -ENOENT; @@ -211,10 +216,6 @@ int edid_get_timing_validate(u8 *buf, int buf_size, if (!timing_done) return -EINVAL; - if (!EDID1_INFO_VIDEO_INPUT_DIGITAL(*edid)) { - debug("%s: Not a digital display\n", __func__); - return -ENOSYS; - } if (edid->version != 1 || edid->revision < 4) { debug("%s: EDID version %d.%d does not have required info\n", __func__, edid->version, edid->revision); -- 2.30.1 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210306195437.9740-4-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2 02/19] video: sunxi: Add mode_valid callback to sunxi_dw_hdmi
Currently driver accepts all resolution which won't work on 4k screens. Add validation callback which limits acceptable resolutions to 297 MHz. Reviewed-by: Andre Przywara Signed-off-by: Jernej Skrabec --- drivers/video/sunxi/sunxi_dw_hdmi.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/video/sunxi/sunxi_dw_hdmi.c b/drivers/video/sunxi/sunxi_dw_hdmi.c index 0b8cefc311ef..e3811a2ec15f 100644 --- a/drivers/video/sunxi/sunxi_dw_hdmi.c +++ b/drivers/video/sunxi/sunxi_dw_hdmi.c @@ -305,6 +305,12 @@ static int sunxi_dw_hdmi_read_edid(struct udevice *dev, u8 *buf, int buf_size) return dw_hdmi_read_edid(>hdmi, buf, buf_size); } +static bool sunxi_dw_hdmi_mode_valid(struct udevice *dev, +const struct display_timing *timing) +{ + return timing->pixelclock.typ <= 29700; +} + static int sunxi_dw_hdmi_enable(struct udevice *dev, int panel_bpp, const struct display_timing *edid) { @@ -388,6 +394,7 @@ static int sunxi_dw_hdmi_probe(struct udevice *dev) static const struct dm_display_ops sunxi_dw_hdmi_ops = { .read_edid = sunxi_dw_hdmi_read_edid, .enable = sunxi_dw_hdmi_enable, + .mode_valid = sunxi_dw_hdmi_mode_valid, }; U_BOOT_DRIVER(sunxi_dw_hdmi) = { -- 2.30.1 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210306195437.9740-3-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2 01/19] sunxi: video: select dw-hdmi in Kconfig, not Makefile
Currently sunxi Makefile manually specifies full path to dw-hdmi common code. However, that is not needed because it can be selected in Kconfig instead. Select proper symbol in Kconfig and drop path from Makefile. Reviewed-by: Andre Przywara Signed-off-by: Jernej Skrabec --- arch/arm/mach-sunxi/Kconfig | 1 + drivers/video/sunxi/Makefile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index 0135575ca1eb..9149196b223e 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig @@ -972,6 +972,7 @@ config VIDEO_DE2 depends on SUNXI_DE2 select DM_VIDEO select DISPLAY + select VIDEO_DW_HDMI imply VIDEO_DT_SIMPLEFB default y ---help--- diff --git a/drivers/video/sunxi/Makefile b/drivers/video/sunxi/Makefile index 147e18799229..4321673312bf 100644 --- a/drivers/video/sunxi/Makefile +++ b/drivers/video/sunxi/Makefile @@ -4,4 +4,4 @@ # Wolfgang Denk, DENX Software Engineering, w...@denx.de. obj-$(CONFIG_VIDEO_SUNXI) += sunxi_display.o simplefb_common.o lcdc.o tve_common.o ../videomodes.o -obj-$(CONFIG_VIDEO_DE2) += sunxi_de2.o sunxi_dw_hdmi.o simplefb_common.o lcdc.o ../dw_hdmi.o sunxi_lcd.o +obj-$(CONFIG_VIDEO_DE2) += sunxi_de2.o sunxi_dw_hdmi.o simplefb_common.o lcdc.o sunxi_lcd.o -- 2.30.1 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210306195437.9740-2-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2 00/19] video: sunxi: rework DE2 driver
This series greatly reworks DE2 mixer and accompanying DW-HDMI platform driver. Main goal was to use as many information from device tree as possible and thus removing SoC speficic ifdefs from the code. This was largely accomplished for mixer, HDMI and HDMI PHY driver. Most of these changes are not user visible. Only improvements relevant to the user are filtering HDMI modes based on pixel clock and searching for additional detailed timings in EDID extension block. This change allows me to use 4k monitor that I have - base EDID block on this monitor holds only 4k@60 detailed timing. Other detailed timings, which are appropriate for HDMI 1.4 controller, are contained in extension block. There is plenty of work to do. TCON handling should go to dedicated driver and clock related code in TCON and DW-HDMI code should be moved to clock drivers. Testing was done only on H3. Best regards, Jernej Changes from v1: - collected tags - reword some commit messages - dropped patch 13 and 14 from v1 - 2 new patches, first add HDMI PHY driver and another drops PHY code from sunxi dw-hdmi driver and uses separate driver instead Jernej Skrabec (19): sunxi: video: select dw-hdmi in Kconfig, not Makefile video: sunxi: Add mode_valid callback to sunxi_dw_hdmi common: edid: check for digital display earlier common: edid: extract code for detailed timing search common: edid: Search for valid timing in extension block video: sunxi: Use DW-HDMI hpd function video: sunxi: Remove check for ddc-i2c-bus property video: sunxi: Remove TV probe from DE2 video: sunxi: de2: switch to public uclass functions video: sunxi: dw-hdmi: probe driver by compatible video: sunxi: dw-hdmi: read address from DT node video: sunxi: de2: switch to DT probing video: sunxi: de2: read address from DT node clk: sunxi: Add DE2 and HDMI clocks to H3 and A64 clk: sunxi: add DE2 clock driver video: sunxi: de2: switch clock setup to DM model video: dw-hdmi: modify phy init callback to include full timings video: sunxi: Add DW HDMI PHY driver video: sunxi: dw-hdmi: Use new PHY driver arch/arm/mach-sunxi/Kconfig | 3 + common/edid.c | 82 +++-- drivers/clk/sunxi/Kconfig | 5 + drivers/clk/sunxi/Makefile | 1 + drivers/clk/sunxi/clk_a64.c | 12 + drivers/clk/sunxi/clk_de2.c | 85 + drivers/clk/sunxi/clk_h3.c | 12 + drivers/video/dw_hdmi.c | 6 +- drivers/video/meson/meson_dw_hdmi.c | 5 +- drivers/video/sunxi/Makefile| 2 +- drivers/video/sunxi/sunxi_de2.c | 191 +-- drivers/video/sunxi/sunxi_dw_hdmi.c | 300 - drivers/video/sunxi/sunxi_dw_hdmi_phy.c | 423 drivers/video/sunxi/sunxi_dw_hdmi_phy.h | 24 ++ include/dw_hdmi.h | 4 +- 15 files changed, 780 insertions(+), 375 deletions(-) create mode 100644 drivers/clk/sunxi/clk_de2.c create mode 100644 drivers/video/sunxi/sunxi_dw_hdmi_phy.c create mode 100644 drivers/video/sunxi/sunxi_dw_hdmi_phy.h -- 2.30.1 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210306195437.9740-1-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH 19/19] video: sunxi: de2: switch clock setup to DM model
Now that proper DM clock and reset driver exists for Display Engine 2 and 3, remove all clock and reset related code and use appropriate framework instead. Signed-off-by: Jernej Skrabec --- arch/arm/mach-sunxi/Kconfig | 1 + drivers/video/sunxi/sunxi_de2.c | 67 +++-- 2 files changed, 23 insertions(+), 45 deletions(-) diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index 9149196b223e..34ef1f4b030f 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig @@ -970,6 +970,7 @@ config SUNXI_DE2 config VIDEO_DE2 bool "Display Engine 2 video driver" depends on SUNXI_DE2 + select CLK_SUN8I_DE2 select DM_VIDEO select DISPLAY select VIDEO_DW_HDMI diff --git a/drivers/video/sunxi/sunxi_de2.c b/drivers/video/sunxi/sunxi_de2.c index f6c8ca075aba..cee9b46b1259 100644 --- a/drivers/video/sunxi/sunxi_de2.c +++ b/drivers/video/sunxi/sunxi_de2.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -14,10 +15,10 @@ #include #include #include +#include #include #include #include -#include #include #include #include "simplefb_common.h" @@ -36,40 +37,10 @@ struct sunxi_de2_data { const char *disp_drv_name; }; -static void sunxi_de2_composer_init(void) -{ - struct sunxi_ccm_reg * const ccm = - (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; - -#ifdef CONFIG_MACH_SUN50I - u32 reg_value; - - /* set SRAM for video use (A64 only) */ - reg_value = readl(SUNXI_SRAMC_BASE + 0x04); - reg_value &= ~(0x01 << 24); - writel(reg_value, SUNXI_SRAMC_BASE + 0x04); -#endif - - clock_set_pll10(43200); - - /* Set DE parent to pll10 */ - clrsetbits_le32(>de_clk_cfg, CCM_DE2_CTRL_PLL_MASK, - CCM_DE2_CTRL_PLL10); - - /* Set ahb gating to pass */ - setbits_le32(>ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_DE); - setbits_le32(>ahb_gate1, 1 << AHB_GATE_OFFSET_DE); - - /* Clock on */ - setbits_le32(>de_clk_cfg, CCM_DE2_CTRL_GATE); -} - -static void sunxi_de2_mode_set(ulong de_mux_base, int mux, +static void sunxi_de2_mode_set(ulong de_mux_base, const struct display_timing *mode, int bpp, ulong address, bool is_composite) { - struct de_clk * const de_clk_regs = - (struct de_clk *)(SUNXI_DE2_BASE); struct de_glb * const de_glb_regs = (struct de_glb *)(de_mux_base + SUNXI_DE2_MUX_GLB_REGS); @@ -87,17 +58,6 @@ static void sunxi_de2_mode_set(ulong de_mux_base, int mux, int channel; u32 format; - /* enable clock */ -#ifdef CONFIG_MACH_SUN8I_H3 - setbits_le32(_clk_regs->rst_cfg, (mux == 0) ? 1 : 4); -#else - setbits_le32(_clk_regs->rst_cfg, BIT(mux)); -#endif - setbits_le32(_clk_regs->gate_cfg, BIT(mux)); - setbits_le32(_clk_regs->bus_cfg, BIT(mux)); - - clrbits_le32(_clk_regs->sel_cfg, 1); - writel(SUNXI_DE2_MUX_GLB_CTL_EN, _glb_regs->ctl); writel(0, _glb_regs->status); writel(1, _glb_regs->dbuff); @@ -189,6 +149,8 @@ static int sunxi_de2_init(struct udevice *dev, ulong fbbase, struct video_priv *uc_priv = dev_get_uclass_priv(dev); struct display_timing timing; struct display_plat *disp_uc_plat; + struct reset_ctl_bulk resets; + struct clk_bulk clocks; int ret; disp_uc_plat = dev_get_uclass_plat(disp); @@ -206,8 +168,23 @@ static int sunxi_de2_init(struct udevice *dev, ulong fbbase, return ret; } - sunxi_de2_composer_init(); - sunxi_de2_mode_set((ulong)dev_read_addr(dev), mux, , + ret = reset_get_bulk(dev, ); + if (ret) + return ret; + + ret = clk_get_bulk(dev, ); + if (ret) + return ret; + + ret = clk_enable_bulk(); + if (ret) + return ret; + + ret = reset_deassert_bulk(); + if (ret) + return ret; + + sunxi_de2_mode_set((ulong)dev_read_addr(dev), , 1 << l2bpp, fbbase, is_composite); ret = display_enable(disp, 1 << l2bpp, ); -- 2.30.1 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210223204631.1609597-20-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH 18/19] clk: sunxi: add DE2 clock driver
Video driver currently manages clocks and resets by directly writing to registers. This is already a bit messy because each SoC has some specifics. It's much better to implement proper clock and reset driver which takes information from device tree file. Note that this driver is not perfect yet. It still sets PLL and parent by hand. Sunxi clock framework still doesn't know how to set parents or rates. However, this is already big step in right direction. Cc: Lukasz Majewski Signed-off-by: Jernej Skrabec --- drivers/clk/sunxi/Kconfig | 5 +++ drivers/clk/sunxi/Makefile | 1 + drivers/clk/sunxi/clk_de2.c | 85 + 3 files changed, 91 insertions(+) create mode 100644 drivers/clk/sunxi/clk_de2.c diff --git a/drivers/clk/sunxi/Kconfig b/drivers/clk/sunxi/Kconfig index bf084fa7a84a..6c96affb1f87 100644 --- a/drivers/clk/sunxi/Kconfig +++ b/drivers/clk/sunxi/Kconfig @@ -44,6 +44,11 @@ config CLK_SUN8I_A83T This enables common clock driver support for platforms based on Allwinner A83T SoC. +config CLK_SUN8I_DE2 + bool "Clock driver for Allwinner Display Engine 2 and 3" + help + This enables common clock driver support for Display Engine 2 and 3. + config CLK_SUN8I_R40 bool "Clock driver for Allwinner R40" default MACH_SUN8I_R40 diff --git a/drivers/clk/sunxi/Makefile b/drivers/clk/sunxi/Makefile index 0dfc0593fb1c..620ff96ac6f5 100644 --- a/drivers/clk/sunxi/Makefile +++ b/drivers/clk/sunxi/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_CLK_SUN5I_A10S) += clk_a10s.o obj-$(CONFIG_CLK_SUN6I_A31) += clk_a31.o obj-$(CONFIG_CLK_SUN8I_A23) += clk_a23.o obj-$(CONFIG_CLK_SUN8I_A83T) += clk_a83t.o +obj-$(CONFIG_CLK_SUN8I_DE2) += clk_de2.o obj-$(CONFIG_CLK_SUN8I_R40) += clk_r40.o obj-$(CONFIG_CLK_SUN8I_V3S) += clk_v3s.o obj-$(CONFIG_CLK_SUN9I_A80) += clk_a80.o diff --git a/drivers/clk/sunxi/clk_de2.c b/drivers/clk/sunxi/clk_de2.c new file mode 100644 index ..b8c45404c1b6 --- /dev/null +++ b/drivers/clk/sunxi/clk_de2.c @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2021 Jernej Skrabec + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct ccu_clk_gate de2_gates[] = { + [CLK_MIXER0]= GATE(0x00, BIT(0)), + [CLK_MIXER1]= GATE(0x00, BIT(1)), + [CLK_WB]= GATE(0x00, BIT(2)), + + [CLK_BUS_MIXER0]= GATE(0x04, BIT(0)), + [CLK_BUS_MIXER1]= GATE(0x04, BIT(1)), + [CLK_BUS_WB]= GATE(0x04, BIT(2)), +}; + +static struct ccu_reset de2_resets[] = { + [RST_MIXER0]= RESET(0x08, BIT(0)), + [RST_MIXER1]= RESET(0x08, BIT(1)), + [RST_WB]= RESET(0x08, BIT(2)), +}; + +static const struct ccu_desc de2_ccu_desc = { + .gates = de2_gates, + .resets = de2_resets, +}; + +static int de2_clk_probe(struct udevice *dev) +{ + struct sunxi_ccm_reg * const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + u32 val; + + if (device_is_compatible(dev_get_parent(dev), +"allwinner,sun50i-a64-de2")) { + /* set SRAM for video use */ + val = readl(SUNXI_SRAMC_BASE + 0x04); + val &= ~(0x01 << 24); + writel(val, SUNXI_SRAMC_BASE + 0x04); + } + + /* clock driver doesn't know how to set rate or parent yet */ + clock_set_pll10(43200); + + /* Set DE parent to pll10 */ + clrsetbits_le32(>de_clk_cfg, CCM_DE2_CTRL_PLL_MASK, + CCM_DE2_CTRL_PLL10); + + return sunxi_clk_probe(dev); +} + +static int de2_clk_bind(struct udevice *dev) +{ + return sunxi_reset_bind(dev, ARRAY_SIZE(de2_resets)); +} + +static const struct udevice_id de2_ccu_ids[] = { + { .compatible = "allwinner,sun8i-h3-de2-clk", + .data = (ulong)_ccu_desc }, + { .compatible = "allwinner,sun50i-a64-de2-clk", + .data = (ulong)_ccu_desc }, + { .compatible = "allwinner,sun50i-h5-de2-clk", + .data = (ulong)_ccu_desc }, + { } +}; + +U_BOOT_DRIVER(clk_sun8i_de2) = { + .name = "sun8i_de2_ccu", + .id = UCLASS_CLK, + .of_match = de2_ccu_ids, + .priv_auto = sizeof(struct ccu_priv), + .ops= _clk_ops, + .probe = de2_clk_probe, + .bind = de2_clk_bind, +}; -- 2.30.1 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210223204631.1609597-19-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH 17/19] clk: sunxi: Add DE2 clocks to H3 and A64
With the next commit another clock and reset driver will be implemented which requires DE2 related clocks and resets. Add them. Cc: Lukasz Majewski Signed-off-by: Jernej Skrabec --- drivers/clk/sunxi/clk_a64.c | 6 ++ drivers/clk/sunxi/clk_h3.c | 6 ++ 2 files changed, 12 insertions(+) diff --git a/drivers/clk/sunxi/clk_a64.c b/drivers/clk/sunxi/clk_a64.c index 0553ffa4399a..c7cf88ce3436 100644 --- a/drivers/clk/sunxi/clk_a64.c +++ b/drivers/clk/sunxi/clk_a64.c @@ -26,6 +26,8 @@ static const struct ccu_clk_gate a64_gates[] = { [CLK_BUS_OHCI0] = GATE(0x060, BIT(28)), [CLK_BUS_OHCI1] = GATE(0x060, BIT(29)), + [CLK_BUS_DE]= GATE(0x064, BIT(12)), + [CLK_BUS_UART0] = GATE(0x06c, BIT(16)), [CLK_BUS_UART1] = GATE(0x06c, BIT(17)), [CLK_BUS_UART2] = GATE(0x06c, BIT(18)), @@ -41,6 +43,8 @@ static const struct ccu_clk_gate a64_gates[] = { [CLK_USB_HSIC_12M] = GATE(0x0cc, BIT(11)), [CLK_USB_OHCI0] = GATE(0x0cc, BIT(16)), [CLK_USB_OHCI1] = GATE(0x0cc, BIT(17)), + + [CLK_DE]= GATE(0x104, BIT(31)), }; static const struct ccu_reset a64_resets[] = { @@ -60,6 +64,8 @@ static const struct ccu_reset a64_resets[] = { [RST_BUS_OHCI0] = RESET(0x2c0, BIT(28)), [RST_BUS_OHCI1] = RESET(0x2c0, BIT(29)), + [RST_BUS_DE]= RESET(0x2c4, BIT(12)), + [RST_BUS_UART0] = RESET(0x2d8, BIT(16)), [RST_BUS_UART1] = RESET(0x2d8, BIT(17)), [RST_BUS_UART2] = RESET(0x2d8, BIT(18)), diff --git a/drivers/clk/sunxi/clk_h3.c b/drivers/clk/sunxi/clk_h3.c index f81633b92d5a..bf8d963d18b6 100644 --- a/drivers/clk/sunxi/clk_h3.c +++ b/drivers/clk/sunxi/clk_h3.c @@ -30,6 +30,8 @@ static struct ccu_clk_gate h3_gates[] = { [CLK_BUS_OHCI2] = GATE(0x060, BIT(30)), [CLK_BUS_OHCI3] = GATE(0x060, BIT(31)), + [CLK_BUS_DE]= GATE(0x064, BIT(12)), + [CLK_BUS_UART0] = GATE(0x06c, BIT(16)), [CLK_BUS_UART1] = GATE(0x06c, BIT(17)), [CLK_BUS_UART2] = GATE(0x06c, BIT(18)), @@ -48,6 +50,8 @@ static struct ccu_clk_gate h3_gates[] = { [CLK_USB_OHCI1] = GATE(0x0cc, BIT(17)), [CLK_USB_OHCI2] = GATE(0x0cc, BIT(18)), [CLK_USB_OHCI3] = GATE(0x0cc, BIT(19)), + + [CLK_DE]= GATE(0x104, BIT(31)), }; static struct ccu_reset h3_resets[] = { @@ -72,6 +76,8 @@ static struct ccu_reset h3_resets[] = { [RST_BUS_OHCI2] = RESET(0x2c0, BIT(30)), [RST_BUS_OHCI3] = RESET(0x2c0, BIT(31)), + [RST_BUS_DE]= RESET(0x2c4, BIT(12)), + [RST_BUS_EPHY] = RESET(0x2c8, BIT(2)), [RST_BUS_UART0] = RESET(0x2d8, BIT(16)), -- 2.30.1 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210223204631.1609597-18-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH 16/19] video: sunxi: de2: read address from DT node
Currently DE2 uses hardcoded address based on SoC for which U-Boot is built. Read it from DT instead so there is no need to specify it when support for new SoC is added. Signed-off-by: Jernej Skrabec --- drivers/video/sunxi/sunxi_de2.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/video/sunxi/sunxi_de2.c b/drivers/video/sunxi/sunxi_de2.c index 81576e45e9ef..f6c8ca075aba 100644 --- a/drivers/video/sunxi/sunxi_de2.c +++ b/drivers/video/sunxi/sunxi_de2.c @@ -64,11 +64,10 @@ static void sunxi_de2_composer_init(void) setbits_le32(>de_clk_cfg, CCM_DE2_CTRL_GATE); } -static void sunxi_de2_mode_set(int mux, const struct display_timing *mode, +static void sunxi_de2_mode_set(ulong de_mux_base, int mux, + const struct display_timing *mode, int bpp, ulong address, bool is_composite) { - ulong de_mux_base = (mux == 0) ? - SUNXI_DE2_MUX0_BASE : SUNXI_DE2_MUX1_BASE; struct de_clk * const de_clk_regs = (struct de_clk *)(SUNXI_DE2_BASE); struct de_glb * const de_glb_regs = @@ -208,7 +207,8 @@ static int sunxi_de2_init(struct udevice *dev, ulong fbbase, } sunxi_de2_composer_init(); - sunxi_de2_mode_set(mux, , 1 << l2bpp, fbbase, is_composite); + sunxi_de2_mode_set((ulong)dev_read_addr(dev), mux, , + 1 << l2bpp, fbbase, is_composite); ret = display_enable(disp, 1 << l2bpp, ); if (ret) { -- 2.30.1 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210223204631.1609597-17-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH 15/19] video: sunxi: de2: switch to DT probing
Currently DE2 driver is probed via driver info. Switch probing to device tree compatible string method. Display is now searched via driver name which has same limitation as previous method. This can be improved only when all drivers in chain are probed via device tree compatible strings. Signed-off-by: Jernej Skrabec --- drivers/video/sunxi/sunxi_de2.c | 88 +++-- 1 file changed, 52 insertions(+), 36 deletions(-) diff --git a/drivers/video/sunxi/sunxi_de2.c b/drivers/video/sunxi/sunxi_de2.c index e02d359cd259..81576e45e9ef 100644 --- a/drivers/video/sunxi/sunxi_de2.c +++ b/drivers/video/sunxi/sunxi_de2.c @@ -31,6 +31,11 @@ enum { LCD_MAX_LOG2_BPP= VIDEO_BPP32, }; +struct sunxi_de2_data { + int id; + const char *disp_drv_name; +}; + static void sunxi_de2_composer_init(void) { struct sunxi_ccm_reg * const ccm = @@ -228,51 +233,34 @@ static int sunxi_de2_init(struct udevice *dev, ulong fbbase, static int sunxi_de2_probe(struct udevice *dev) { + const struct sunxi_de2_data *data = + (const struct sunxi_de2_data *)dev_get_driver_data(dev); struct video_uc_plat *plat = dev_get_uclass_plat(dev); struct udevice *disp; - int ret; + int ret, index = 0; /* Before relocation we don't need to do anything */ if (!(gd->flags & GD_FLG_RELOC)) return 0; - ret = uclass_get_device_by_driver(UCLASS_DISPLAY, - DM_DRIVER_GET(sunxi_lcd), ); - if (!ret) { - int mux; + while (!(ret = uclass_get_device(UCLASS_DISPLAY, index++, ))) { + if (strcmp(disp->driver->name, data->disp_drv_name)) + continue; - mux = 0; + ret = sunxi_de2_init(dev, plat->base, VIDEO_BPP32, disp, +data->id, false); + if (ret) + return ret; - ret = sunxi_de2_init(dev, plat->base, VIDEO_BPP32, disp, mux, -false); - if (!ret) { - video_set_flush_dcache(dev, 1); - return 0; - } - } - - debug("%s: lcd display not found (ret=%d)\n", __func__, ret); - - ret = uclass_get_device_by_driver(UCLASS_DISPLAY, - DM_DRIVER_GET(sunxi_dw_hdmi), ); - if (!ret) { - int mux; - if (IS_ENABLED(CONFIG_MACH_SUNXI_H3_H5)) - mux = 0; - else - mux = 1; + video_set_flush_dcache(dev, 1); - ret = sunxi_de2_init(dev, plat->base, VIDEO_BPP32, disp, mux, -false); - if (!ret) { - video_set_flush_dcache(dev, 1); - return 0; - } + return 0; } - debug("%s: hdmi display not found (ret=%d)\n", __func__, ret); + debug("%s: %s not found (ret=%d)\n", __func__, + data->disp_drv_name, ret); - return -ENODEV; + return ret; } static int sunxi_de2_bind(struct udevice *dev) @@ -285,22 +273,50 @@ static int sunxi_de2_bind(struct udevice *dev) return 0; } +const struct sunxi_de2_data h3_mixer_0 = { + .id = 0, + .disp_drv_name = "sunxi_dw_hdmi", +}; + +const struct sunxi_de2_data a64_mixer_0 = { + .id = 0, + .disp_drv_name = "sunxi_lcd", +}; + +const struct sunxi_de2_data a64_mixer_1 = { + .id = 1, + .disp_drv_name = "sunxi_dw_hdmi", +}; + +static const struct udevice_id sunxi_de2_ids[] = { + { + .compatible = "allwinner,sun8i-h3-de2-mixer-0", + .data = (ulong)_mixer_0, + }, + { + .compatible = "allwinner,sun50i-a64-de2-mixer-0", + .data = (ulong)_mixer_0, + }, + { + .compatible = "allwinner,sun50i-a64-de2-mixer-1", + .data = (ulong)_mixer_1, + }, + { } +}; + static const struct video_ops sunxi_de2_ops = { }; U_BOOT_DRIVER(sunxi_de2) = { .name = "sunxi_de2", .id = UCLASS_VIDEO, + .of_match = sunxi_de2_ids, .ops= _de2_ops, .bind = sunxi_de2_bind, .probe = sunxi_de2_probe, .flags = DM_FLAG_PRE_RELOC, }; -U_BOOT_DRVINFO(sunxi_de2) = { - .name = "sunxi_de2" -}; - /* * Simplefb support. */ -- 2.30.1 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210223204631.1609597-16-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH 14/19] video: sunxi: dw-hdmi: rework PHY initialization
Now that bit meanings are somewhat known, rework PHY initialization. This is modelled after Linux driver. Signed-off-by: Jernej Skrabec --- drivers/video/sunxi/sunxi_dw_hdmi.c | 411 +++- 1 file changed, 279 insertions(+), 132 deletions(-) diff --git a/drivers/video/sunxi/sunxi_dw_hdmi.c b/drivers/video/sunxi/sunxi_dw_hdmi.c index 4cc175d714ea..c4cded569bfb 100644 --- a/drivers/video/sunxi/sunxi_dw_hdmi.c +++ b/drivers/video/sunxi/sunxi_dw_hdmi.c @@ -18,100 +18,200 @@ #include #include +#define SUN8I_HDMI_PHY_DBG_CTRL_PX_LOCKBIT(0) +#define SUN8I_HDMI_PHY_DBG_CTRL_POL_MASK GENMASK(15, 8) +#define SUN8I_HDMI_PHY_DBG_CTRL_POL_NHSYNC BIT(8) +#define SUN8I_HDMI_PHY_DBG_CTRL_POL_NVSYNC BIT(9) +#define SUN8I_HDMI_PHY_DBG_CTRL_ADDR_MASK GENMASK(23, 16) +#define SUN8I_HDMI_PHY_DBG_CTRL_ADDR(addr) (addr << 16) + +#define SUN8I_HDMI_PHY_REXT_CTRL_REXT_EN BIT(31) + +#define SUN8I_HDMI_PHY_READ_EN_MAGIC 0x54524545 + +#define SUN8I_HDMI_PHY_UNSCRAMBLE_MAGIC0x42494E47 + +#define SUN8I_HDMI_PHY_ANA_CFG1_REG_SWIBIT(31) +#define SUN8I_HDMI_PHY_ANA_CFG1_REG_PWEND BIT(30) +#define SUN8I_HDMI_PHY_ANA_CFG1_REG_PWENC BIT(29) +#define SUN8I_HDMI_PHY_ANA_CFG1_REG_CALSW BIT(28) +#define SUN8I_HDMI_PHY_ANA_CFG1_REG_SVRCAL(x) ((x) << 26) +#define SUN8I_HDMI_PHY_ANA_CFG1_REG_SVBH(x)((x) << 24) +#define SUN8I_HDMI_PHY_ANA_CFG1_AMP_OPTBIT(23) +#define SUN8I_HDMI_PHY_ANA_CFG1_EMP_OPTBIT(22) +#define SUN8I_HDMI_PHY_ANA_CFG1_AMPCK_OPT BIT(21) +#define SUN8I_HDMI_PHY_ANA_CFG1_EMPCK_OPT BIT(20) +#define SUN8I_HDMI_PHY_ANA_CFG1_ENRCAL BIT(19) +#define SUN8I_HDMI_PHY_ANA_CFG1_ENCALOGBIT(18) +#define SUN8I_HDMI_PHY_ANA_CFG1_REG_SCKTMDSBIT(17) +#define SUN8I_HDMI_PHY_ANA_CFG1_TMDSCLK_EN BIT(16) +#define SUN8I_HDMI_PHY_ANA_CFG1_TXEN_MASK GENMASK(15, 12) +#define SUN8I_HDMI_PHY_ANA_CFG1_TXEN_ALL (0xf << 12) +#define SUN8I_HDMI_PHY_ANA_CFG1_BIASEN_TMDSCLK BIT(11) +#define SUN8I_HDMI_PHY_ANA_CFG1_BIASEN_TMDS2 BIT(10) +#define SUN8I_HDMI_PHY_ANA_CFG1_BIASEN_TMDS1 BIT(9) +#define SUN8I_HDMI_PHY_ANA_CFG1_BIASEN_TMDS0 BIT(8) +#define SUN8I_HDMI_PHY_ANA_CFG1_ENP2S_TMDSCLK BIT(7) +#define SUN8I_HDMI_PHY_ANA_CFG1_ENP2S_TMDS2BIT(6) +#define SUN8I_HDMI_PHY_ANA_CFG1_ENP2S_TMDS1BIT(5) +#define SUN8I_HDMI_PHY_ANA_CFG1_ENP2S_TMDS0BIT(4) +#define SUN8I_HDMI_PHY_ANA_CFG1_CKEN BIT(3) +#define SUN8I_HDMI_PHY_ANA_CFG1_LDOEN BIT(2) +#define SUN8I_HDMI_PHY_ANA_CFG1_ENVBS BIT(1) +#define SUN8I_HDMI_PHY_ANA_CFG1_ENBI BIT(0) + +#define SUN8I_HDMI_PHY_ANA_CFG2_M_EN BIT(31) +#define SUN8I_HDMI_PHY_ANA_CFG2_PLLDBENBIT(30) +#define SUN8I_HDMI_PHY_ANA_CFG2_SENBIT(29) +#define SUN8I_HDMI_PHY_ANA_CFG2_REG_HPDPD BIT(28) +#define SUN8I_HDMI_PHY_ANA_CFG2_REG_HPDEN BIT(27) +#define SUN8I_HDMI_PHY_ANA_CFG2_REG_PLRCK BIT(26) +#define SUN8I_HDMI_PHY_ANA_CFG2_REG_PLR(x) ((x) << 23) +#define SUN8I_HDMI_PHY_ANA_CFG2_REG_DENCK BIT(22) +#define SUN8I_HDMI_PHY_ANA_CFG2_REG_DENBIT(21) +#define SUN8I_HDMI_PHY_ANA_CFG2_REG_CD(x) ((x) << 19) +#define SUN8I_HDMI_PHY_ANA_CFG2_REG_CKSS(x)((x) << 17) +#define SUN8I_HDMI_PHY_ANA_CFG2_REG_BIGSWCKBIT(16) +#define SUN8I_HDMI_PHY_ANA_CFG2_REG_BIGSW BIT(15) +#define SUN8I_HDMI_PHY_ANA_CFG2_REG_CSMPS(x) ((x) << 13) +#define SUN8I_HDMI_PHY_ANA_CFG2_REG_SLV(x) ((x) << 10) +#define SUN8I_HDMI_PHY_ANA_CFG2_REG_BOOSTCK(x) ((x) << 8) +#define SUN8I_HDMI_PHY_ANA_CFG2_REG_BOOST(x) ((x) << 6) +#define SUN8I_HDMI_PHY_ANA_CFG2_REG_RESDI(x) ((x) << 0) + +#define SUN8I_HDMI_PHY_ANA_CFG3_REG_SLOWCK(x) ((x) << 30) +#define SUN8I_HDMI_PHY_ANA_CFG3_REG_SLOW(x)((x) << 28) +#define SUN8I_HDMI_PHY_ANA_CFG3_REG_WIRE(x)((x) << 18) +#define SUN8I_HDMI_PHY_ANA_CFG3_REG_AMPCK(x) ((x) << 14) +#define SUN8I_HDMI_PHY_ANA_CFG3_REG_EMPCK(x) ((x) << 11) +#define SUN8I_HDMI_PHY_ANA_CFG3_REG_AMP(x) ((x) << 7) +#define SUN8I_HDMI_PHY_ANA_CFG3_REG_EMP(x) ((x) << 4) +#define SUN8I_HDMI_PHY_ANA_CFG3_SDAPD BIT(3) +#define SUN8I_HDMI_PHY_ANA_CFG3_SDAEN BIT(2) +#define SUN8I_HDMI_PHY_ANA_CFG3_SCLPD BIT(1) +#define SUN8I_HDMI_PHY_ANA_CFG3_SCLEN BIT(0) + +#define SUN8I_HDMI_PHY_PLL_CFG1_REG_OD1BIT(31) +#define SUN8I_HDMI_PHY_PLL_CFG1_REG_OD BIT(30) +#define SUN8I_HDMI_PHY_PLL_CFG1_LDO2_ENBIT(29) +#define SUN8I_HDMI_PHY_PLL_CFG1_LDO1_ENBIT(28) +#define SUN8I_HDMI_PHY_PLL_CFG1_HV_IS_33 BIT(27) +#define SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_MSK BIT(26) +#define SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_SHIFT 26 +#define SUN8I_HDMI_PHY_PLL_CFG1_PLLEN BIT(25) +#define SUN8I
[linux-sunxi] [PATCH 13/19] video: sunxi: dw-hdmi: move PHY config to appropriate place
Currently sunxi_dw_hdmi_enable() configures PHY timing related parameters. However, sunxi_dw_hdmi_phy_cfg() is better suited place for that. Move the code there. This also allows to easier driver expansion when controller uses different PHY than currently supported (like that in H6). Signed-off-by: Jernej Skrabec --- drivers/video/sunxi/sunxi_dw_hdmi.c | 24 +--- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/video/sunxi/sunxi_dw_hdmi.c b/drivers/video/sunxi/sunxi_dw_hdmi.c index 483d57293155..4cc175d714ea 100644 --- a/drivers/video/sunxi/sunxi_dw_hdmi.c +++ b/drivers/video/sunxi/sunxi_dw_hdmi.c @@ -114,11 +114,13 @@ static void sunxi_dw_hdmi_phy_init(struct dw_hdmi *hdmi) writel(0x42494E47, >unscramble); } -static void sunxi_dw_hdmi_phy_set(struct dw_hdmi *hdmi, uint clock, int phy_div) +static void sunxi_dw_hdmi_phy_set(struct dw_hdmi *hdmi, + const struct display_timing *edid, + int phy_div) { struct sunxi_hdmi_phy * const phy = (struct sunxi_hdmi_phy *)(hdmi->ioaddr + HDMI_PHY_OFFS); - int div = sunxi_dw_hdmi_get_divider(clock); + int div = sunxi_dw_hdmi_get_divider(edid->pixelclock.typ); u32 tmp; /* @@ -187,6 +189,14 @@ static void sunxi_dw_hdmi_phy_set(struct dw_hdmi *hdmi, uint clock, int phy_div) writel(0x0F81C405, >unk2); break; } + + if (edid->flags & DISPLAY_FLAGS_VSYNC_LOW) + setbits_le32(>pol, 0x200); + + if (edid->flags & DISPLAY_FLAGS_HSYNC_LOW) + setbits_le32(>pol, 0x100); + + setbits_le32(>ctrl, 0xf << 12); } static void sunxi_dw_hdmi_pll_set(uint clk_khz, int *phy_div) @@ -272,7 +282,7 @@ static int sunxi_dw_hdmi_phy_cfg(struct dw_hdmi *hdmi, int phy_div; sunxi_dw_hdmi_pll_set(edid->pixelclock.typ / 1000, _div); - sunxi_dw_hdmi_phy_set(hdmi, edid->pixelclock.typ, phy_div); + sunxi_dw_hdmi_phy_set(hdmi, edid, phy_div); return 0; } @@ -304,14 +314,6 @@ static int sunxi_dw_hdmi_enable(struct udevice *dev, int panel_bpp, sunxi_dw_hdmi_lcdc_init(priv->mux, edid, panel_bpp); - if (edid->flags & DISPLAY_FLAGS_VSYNC_LOW) - setbits_le32(>pol, 0x200); - - if (edid->flags & DISPLAY_FLAGS_HSYNC_LOW) - setbits_le32(>pol, 0x100); - - setbits_le32(>ctrl, 0xf << 12); - /* * This is last hdmi access before boot, so scramble addresses * again or othwerwise BSP driver won't work. Dummy read is -- 2.30.1 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210223204631.1609597-14-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH 12/19] video: dw-hdmi: modify phy init callback to include full timings
Currently PHY init callback has only pixel clock as a parameter, but other timing parameters may be needed for custom PHYs. Modify callback signature to include full timings. Cc: Neil Armstrong Signed-off-by: Jernej Skrabec --- drivers/video/dw_hdmi.c | 6 +++--- drivers/video/meson/meson_dw_hdmi.c | 5 +++-- drivers/video/sunxi/sunxi_dw_hdmi.c | 7 --- include/dw_hdmi.h | 4 ++-- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/video/dw_hdmi.c b/drivers/video/dw_hdmi.c index c4fbb1829446..8d71f713f99f 100644 --- a/drivers/video/dw_hdmi.c +++ b/drivers/video/dw_hdmi.c @@ -901,7 +901,7 @@ static const u8 pre_buf[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe9, }; -int dw_hdmi_phy_cfg(struct dw_hdmi *hdmi, uint mpixelclock) +int dw_hdmi_phy_cfg(struct dw_hdmi *hdmi, const struct display_timing *edid) { int i, ret; @@ -912,7 +912,7 @@ int dw_hdmi_phy_cfg(struct dw_hdmi *hdmi, uint mpixelclock) hdmi_phy_enable_tmds(hdmi, 0); hdmi_phy_enable_power(hdmi, 0); - ret = hdmi_phy_configure(hdmi, mpixelclock); + ret = hdmi_phy_configure(hdmi, edid->pixelclock.typ); if (ret) { debug("hdmi phy config failure %d\n", ret); return ret; @@ -988,7 +988,7 @@ int dw_hdmi_enable(struct dw_hdmi *hdmi, const struct display_timing *edid) hdmi_av_composer(hdmi, edid); - ret = hdmi->phy_set(hdmi, edid->pixelclock.typ); + ret = hdmi->phy_set(hdmi, edid); if (ret) return ret; diff --git a/drivers/video/meson/meson_dw_hdmi.c b/drivers/video/meson/meson_dw_hdmi.c index e5f281320534..7558814b3491 100644 --- a/drivers/video/meson/meson_dw_hdmi.c +++ b/drivers/video/meson/meson_dw_hdmi.c @@ -292,7 +292,8 @@ static void meson_dw_hdmi_phy_setup_mode(struct meson_dw_hdmi *priv, } } -static int meson_dw_hdmi_phy_init(struct dw_hdmi *hdmi, uint pixel_clock) +static int meson_dw_hdmi_phy_init(struct dw_hdmi *hdmi, + const struct display_timing *edid) { struct meson_dw_hdmi *priv = container_of(hdmi, struct meson_dw_hdmi, hdmi); @@ -322,7 +323,7 @@ static int meson_dw_hdmi_phy_init(struct dw_hdmi *hdmi, uint pixel_clock) dw_hdmi_top_write(hdmi, HDMITX_TOP_TMDS_CLK_PTTN_CNTL, 0x2); /* Setup PHY parameters */ - meson_dw_hdmi_phy_setup_mode(priv, pixel_clock); + meson_dw_hdmi_phy_setup_mode(priv, edid->pixelclock.typ); /* Setup PHY */ dw_hdmi_hhi_update_bits(priv, HHI_HDMI_PHY_CNTL1, diff --git a/drivers/video/sunxi/sunxi_dw_hdmi.c b/drivers/video/sunxi/sunxi_dw_hdmi.c index 0744954fa15f..483d57293155 100644 --- a/drivers/video/sunxi/sunxi_dw_hdmi.c +++ b/drivers/video/sunxi/sunxi_dw_hdmi.c @@ -266,12 +266,13 @@ static void sunxi_dw_hdmi_lcdc_init(int mux, const struct display_timing *edid, lcdc_enable(lcdc, bpp); } -static int sunxi_dw_hdmi_phy_cfg(struct dw_hdmi *hdmi, uint mpixelclock) +static int sunxi_dw_hdmi_phy_cfg(struct dw_hdmi *hdmi, +const struct display_timing *edid) { int phy_div; - sunxi_dw_hdmi_pll_set(mpixelclock / 1000, _div); - sunxi_dw_hdmi_phy_set(hdmi, mpixelclock, phy_div); + sunxi_dw_hdmi_pll_set(edid->pixelclock.typ / 1000, _div); + sunxi_dw_hdmi_phy_set(hdmi, edid->pixelclock.typ, phy_div); return 0; } diff --git a/include/dw_hdmi.h b/include/dw_hdmi.h index 8acae3839fb3..46b87916b8bb 100644 --- a/include/dw_hdmi.h +++ b/include/dw_hdmi.h @@ -544,12 +544,12 @@ struct dw_hdmi { struct hdmi_data_info hdmi_data; struct udevice *ddc_bus; - int (*phy_set)(struct dw_hdmi *hdmi, uint mpixelclock); + int (*phy_set)(struct dw_hdmi *hdmi, const struct display_timing *edid); void (*write_reg)(struct dw_hdmi *hdmi, u8 val, int offset); u8 (*read_reg)(struct dw_hdmi *hdmi, int offset); }; -int dw_hdmi_phy_cfg(struct dw_hdmi *hdmi, uint mpixelclock); +int dw_hdmi_phy_cfg(struct dw_hdmi *hdmi, const struct display_timing *edid); int dw_hdmi_phy_wait_for_hpd(struct dw_hdmi *hdmi); void dw_hdmi_phy_init(struct dw_hdmi *hdmi); -- 2.30.1 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210223204631.1609597-13-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH 11/19] video: sunxi: dw-hdmi: read address from DT node
Currently HDMI controller MMIO address is hardcoded. Change that so address is read from DT node. That will make adding support for new variants a bit easier. Signed-off-by: Jernej Skrabec --- drivers/video/sunxi/sunxi_dw_hdmi.c | 38 ++--- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/drivers/video/sunxi/sunxi_dw_hdmi.c b/drivers/video/sunxi/sunxi_dw_hdmi.c index 6f77b2a43b40..0744954fa15f 100644 --- a/drivers/video/sunxi/sunxi_dw_hdmi.c +++ b/drivers/video/sunxi/sunxi_dw_hdmi.c @@ -57,10 +57,10 @@ static int sunxi_dw_hdmi_get_divider(uint clock) return 1; } -static void sunxi_dw_hdmi_phy_init(void) +static void sunxi_dw_hdmi_phy_init(struct dw_hdmi *hdmi) { struct sunxi_hdmi_phy * const phy = - (struct sunxi_hdmi_phy *)(SUNXI_HDMI_BASE + HDMI_PHY_OFFS); + (struct sunxi_hdmi_phy *)(hdmi->ioaddr + HDMI_PHY_OFFS); unsigned long tmo; u32 tmp; @@ -114,10 +114,10 @@ static void sunxi_dw_hdmi_phy_init(void) writel(0x42494E47, >unscramble); } -static void sunxi_dw_hdmi_phy_set(uint clock, int phy_div) +static void sunxi_dw_hdmi_phy_set(struct dw_hdmi *hdmi, uint clock, int phy_div) { struct sunxi_hdmi_phy * const phy = - (struct sunxi_hdmi_phy *)(SUNXI_HDMI_BASE + HDMI_PHY_OFFS); + (struct sunxi_hdmi_phy *)(hdmi->ioaddr + HDMI_PHY_OFFS); int div = sunxi_dw_hdmi_get_divider(clock); u32 tmp; @@ -271,7 +271,7 @@ static int sunxi_dw_hdmi_phy_cfg(struct dw_hdmi *hdmi, uint mpixelclock) int phy_div; sunxi_dw_hdmi_pll_set(mpixelclock / 1000, _div); - sunxi_dw_hdmi_phy_set(mpixelclock, phy_div); + sunxi_dw_hdmi_phy_set(hdmi, mpixelclock, phy_div); return 0; } @@ -292,9 +292,9 @@ static bool sunxi_dw_hdmi_mode_valid(struct udevice *dev, static int sunxi_dw_hdmi_enable(struct udevice *dev, int panel_bpp, const struct display_timing *edid) { - struct sunxi_hdmi_phy * const phy = - (struct sunxi_hdmi_phy *)(SUNXI_HDMI_BASE + HDMI_PHY_OFFS); struct sunxi_dw_hdmi_priv *priv = dev_get_priv(dev); + struct sunxi_hdmi_phy * const phy = + (struct sunxi_hdmi_phy *)(priv->hdmi.ioaddr + HDMI_PHY_OFFS); int ret; ret = dw_hdmi_enable(>hdmi, edid); @@ -316,12 +316,26 @@ static int sunxi_dw_hdmi_enable(struct udevice *dev, int panel_bpp, * again or othwerwise BSP driver won't work. Dummy read is * needed or otherwise last write doesn't get written correctly. */ - (void)readb(SUNXI_HDMI_BASE); + (void)readb(priv->hdmi.ioaddr); writel(0, >unscramble); return 0; } +static int sunxi_dw_hdmi_of_to_plat(struct udevice *dev) +{ + struct sunxi_dw_hdmi_priv *priv = dev_get_priv(dev); + struct dw_hdmi *hdmi = >hdmi; + + hdmi->ioaddr = (ulong)dev_read_addr(dev); + hdmi->i2c_clk_high = 0xd8; + hdmi->i2c_clk_low = 0xfe; + hdmi->reg_io_width = 1; + hdmi->phy_set = sunxi_dw_hdmi_phy_cfg; + + return 0; +} + static int sunxi_dw_hdmi_probe(struct udevice *dev) { struct display_plat *uc_plat = dev_get_uclass_plat(dev); @@ -346,13 +360,8 @@ static int sunxi_dw_hdmi_probe(struct udevice *dev) /* Clock on */ setbits_le32(>hdmi_clk_cfg, CCM_HDMI_CTRL_GATE); - sunxi_dw_hdmi_phy_init(); + sunxi_dw_hdmi_phy_init(>hdmi); - priv->hdmi.ioaddr = SUNXI_HDMI_BASE; - priv->hdmi.i2c_clk_high = 0xd8; - priv->hdmi.i2c_clk_low = 0xfe; - priv->hdmi.reg_io_width = 1; - priv->hdmi.phy_set = sunxi_dw_hdmi_phy_cfg; priv->mux = uc_plat->source_id; ret = dw_hdmi_phy_wait_for_hpd(>hdmi); @@ -382,6 +391,7 @@ U_BOOT_DRIVER(sunxi_dw_hdmi) = { .id = UCLASS_DISPLAY, .of_match = sunxi_dw_hdmi_ids, .ops= _dw_hdmi_ops, + .of_to_plat = sunxi_dw_hdmi_of_to_plat, .probe = sunxi_dw_hdmi_probe, .priv_auto = sizeof(struct sunxi_dw_hdmi_priv), }; -- 2.30.1 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210223204631.1609597-12-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH 10/19] video: sunxi: dw-hdmi: probe driver by compatible
Currently sunxi dw-hdmi driver is probed unconditionally, even if there is no such device. Switch driver to probing via compatible string. This brings many benefits - driver can read DT node and allows driver to be always enabled. Signed-off-by: Jernej Skrabec --- drivers/video/sunxi/sunxi_dw_hdmi.c | 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/video/sunxi/sunxi_dw_hdmi.c b/drivers/video/sunxi/sunxi_dw_hdmi.c index 6d2bc206fc2c..6f77b2a43b40 100644 --- a/drivers/video/sunxi/sunxi_dw_hdmi.c +++ b/drivers/video/sunxi/sunxi_dw_hdmi.c @@ -372,14 +372,16 @@ static const struct dm_display_ops sunxi_dw_hdmi_ops = { .mode_valid = sunxi_dw_hdmi_mode_valid, }; +static const struct udevice_id sunxi_dw_hdmi_ids[] = { + { .compatible = "allwinner,sun8i-a83t-dw-hdmi" }, + { } +}; + U_BOOT_DRIVER(sunxi_dw_hdmi) = { .name = "sunxi_dw_hdmi", .id = UCLASS_DISPLAY, + .of_match = sunxi_dw_hdmi_ids, .ops= _dw_hdmi_ops, .probe = sunxi_dw_hdmi_probe, .priv_auto = sizeof(struct sunxi_dw_hdmi_priv), }; - -U_BOOT_DRVINFO(sunxi_dw_hdmi) = { - .name = "sunxi_dw_hdmi" -}; -- 2.30.1 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210223204631.1609597-11-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH 09/19] video: sunxi: de2: switch to public uclass functions
Currently DE2 driver uses functions which are defined in -internal header. They are not meant to be used outside of uclass framework. Switch DE2 driver to public ones. This has additional benefit that device_probe doesn't need to be called manually. Signed-off-by: Jernej Skrabec --- drivers/video/sunxi/sunxi_de2.c | 29 ++--- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/drivers/video/sunxi/sunxi_de2.c b/drivers/video/sunxi/sunxi_de2.c index 6b836a011944..e02d359cd259 100644 --- a/drivers/video/sunxi/sunxi_de2.c +++ b/drivers/video/sunxi/sunxi_de2.c @@ -19,8 +19,6 @@ #include #include #include -#include -#include #include #include "simplefb_common.h" @@ -198,13 +196,6 @@ static int sunxi_de2_init(struct udevice *dev, ulong fbbase, disp_uc_plat->source_id = mux; - ret = device_probe(disp); - if (ret) { - debug("%s: device '%s' display won't probe (ret=%d)\n", - __func__, dev->name, ret); - return ret; - } - ret = display_read_timing(disp, ); if (ret) { debug("%s: Failed to read timings\n", __func__); @@ -245,8 +236,8 @@ static int sunxi_de2_probe(struct udevice *dev) if (!(gd->flags & GD_FLG_RELOC)) return 0; - ret = uclass_find_device_by_name(UCLASS_DISPLAY, -"sunxi_lcd", ); + ret = uclass_get_device_by_driver(UCLASS_DISPLAY, + DM_DRIVER_GET(sunxi_lcd), ); if (!ret) { int mux; @@ -262,8 +253,8 @@ static int sunxi_de2_probe(struct udevice *dev) debug("%s: lcd display not found (ret=%d)\n", __func__, ret); - ret = uclass_find_device_by_name(UCLASS_DISPLAY, -"sunxi_dw_hdmi", ); + ret = uclass_get_device_by_driver(UCLASS_DISPLAY, + DM_DRIVER_GET(sunxi_dw_hdmi), ); if (!ret) { int mux; if (IS_ENABLED(CONFIG_MACH_SUNXI_H3_H5)) @@ -332,8 +323,8 @@ int sunxi_simplefb_setup(void *blob) mux = 1; /* Skip simplefb setting if DE2 / HDMI is not present */ - ret = uclass_find_device_by_name(UCLASS_VIDEO, -"sunxi_de2", ); + ret = uclass_get_device_by_driver(UCLASS_VIDEO, + DM_DRIVER_GET(sunxi_de2), ); if (ret) { debug("DE2 not present\n"); return 0; @@ -342,8 +333,8 @@ int sunxi_simplefb_setup(void *blob) return 0; } - ret = uclass_find_device_by_name(UCLASS_DISPLAY, -"sunxi_dw_hdmi", ); + ret = uclass_get_device_by_driver(UCLASS_DISPLAY, + DM_DRIVER_GET(sunxi_dw_hdmi), ); if (ret) { debug("HDMI not present\n"); } else if (device_active(hdmi)) { @@ -355,8 +346,8 @@ int sunxi_simplefb_setup(void *blob) debug("HDMI present but not probed\n"); } - ret = uclass_find_device_by_name(UCLASS_DISPLAY, -"sunxi_lcd", ); + ret = uclass_get_device_by_driver(UCLASS_DISPLAY, + DM_DRIVER_GET(sunxi_lcd), ); if (ret) debug("LCD not present\n"); else if (device_active(lcd)) -- 2.30.1 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210223204631.1609597-10-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH 08/19] video: sunxi: Remove TV probe from DE2
TV driver was never fully implemented. Remove search for it from DE2 driver. Signed-off-by: Jernej Skrabec --- drivers/video/sunxi/sunxi_de2.c | 15 +-- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/drivers/video/sunxi/sunxi_de2.c b/drivers/video/sunxi/sunxi_de2.c index a3e21aa5f13e..6b836a011944 100644 --- a/drivers/video/sunxi/sunxi_de2.c +++ b/drivers/video/sunxi/sunxi_de2.c @@ -281,20 +281,7 @@ static int sunxi_de2_probe(struct udevice *dev) debug("%s: hdmi display not found (ret=%d)\n", __func__, ret); - ret = uclass_find_device_by_name(UCLASS_DISPLAY, - "sunxi_tve", ); - if (ret) { - debug("%s: tv not found (ret=%d)\n", __func__, ret); - return ret; - } - - ret = sunxi_de2_init(dev, plat->base, VIDEO_BPP32, disp, 1, true); - if (ret) - return ret; - - video_set_flush_dcache(dev, 1); - - return 0; + return -ENODEV; } static int sunxi_de2_bind(struct udevice *dev) -- 2.30.1 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210223204631.1609597-9-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH 07/19] video: sunxi: Remove check for ddc-i2c-bus property
No Allwinner boards with DW-HDMI controller use separate I2C bus for EDID read. Remove that check. Signed-off-by: Jernej Skrabec --- drivers/video/sunxi/sunxi_dw_hdmi.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/video/sunxi/sunxi_dw_hdmi.c b/drivers/video/sunxi/sunxi_dw_hdmi.c index 37e78ff24111..6d2bc206fc2c 100644 --- a/drivers/video/sunxi/sunxi_dw_hdmi.c +++ b/drivers/video/sunxi/sunxi_dw_hdmi.c @@ -361,9 +361,6 @@ static int sunxi_dw_hdmi_probe(struct udevice *dev) return -1; } - uclass_get_device_by_phandle(UCLASS_I2C, dev, "ddc-i2c-bus", ->hdmi.ddc_bus); - dw_hdmi_init(>hdmi); return 0; -- 2.30.1 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210223204631.1609597-8-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH 06/19] video: sunxi: Use DW-HDMI hpd function
It turns out that even though A64, H3 and H5 have custom PHY, standard hot plug detection for DW-HDMI works just fine. Remove custom hpd method to reduce amount of custom code. Signed-off-by: Jernej Skrabec --- drivers/video/sunxi/sunxi_dw_hdmi.c | 34 + 1 file changed, 6 insertions(+), 28 deletions(-) diff --git a/drivers/video/sunxi/sunxi_dw_hdmi.c b/drivers/video/sunxi/sunxi_dw_hdmi.c index e3811a2ec15f..37e78ff24111 100644 --- a/drivers/video/sunxi/sunxi_dw_hdmi.c +++ b/drivers/video/sunxi/sunxi_dw_hdmi.c @@ -114,28 +114,6 @@ static void sunxi_dw_hdmi_phy_init(void) writel(0x42494E47, >unscramble); } -static int sunxi_dw_hdmi_get_plug_in_status(void) -{ - struct sunxi_hdmi_phy * const phy = - (struct sunxi_hdmi_phy *)(SUNXI_HDMI_BASE + HDMI_PHY_OFFS); - - return !!(readl(>status) & (1 << 19)); -} - -static int sunxi_dw_hdmi_wait_for_hpd(void) -{ - ulong start; - - start = get_timer(0); - do { - if (sunxi_dw_hdmi_get_plug_in_status()) - return 0; - udelay(100); - } while (get_timer(start) < 300); - - return -1; -} - static void sunxi_dw_hdmi_phy_set(uint clock, int phy_div) { struct sunxi_hdmi_phy * const phy = @@ -370,12 +348,6 @@ static int sunxi_dw_hdmi_probe(struct udevice *dev) sunxi_dw_hdmi_phy_init(); - ret = sunxi_dw_hdmi_wait_for_hpd(); - if (ret < 0) { - debug("hdmi can not get hpd signal\n"); - return -1; - } - priv->hdmi.ioaddr = SUNXI_HDMI_BASE; priv->hdmi.i2c_clk_high = 0xd8; priv->hdmi.i2c_clk_low = 0xfe; @@ -383,6 +355,12 @@ static int sunxi_dw_hdmi_probe(struct udevice *dev) priv->hdmi.phy_set = sunxi_dw_hdmi_phy_cfg; priv->mux = uc_plat->source_id; + ret = dw_hdmi_phy_wait_for_hpd(>hdmi); + if (ret < 0) { + debug("hdmi can not get hpd signal\n"); + return -1; + } + uclass_get_device_by_phandle(UCLASS_I2C, dev, "ddc-i2c-bus", >hdmi.ddc_bus); -- 2.30.1 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210223204631.1609597-7-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH 05/19] common: edid: Search for valid timing in extension block
One of my monitors have only 4k@60 timing in base EDID block which is out of range for devices with HDMI 1.4. It turns out that it has additional detailed timings in CTA-861 Extension Block and two of them are appropriate for HDMI 1.4. Add additional search for valid detailed timing in extension block. Signed-off-by: Jernej Skrabec --- common/edid.c | 18 ++ 1 file changed, 18 insertions(+) diff --git a/common/edid.c b/common/edid.c index a6c875d9c8e8..14d8836c360e 100644 --- a/common/edid.c +++ b/common/edid.c @@ -220,6 +220,24 @@ int edid_get_timing_validate(u8 *buf, int buf_size, /* Look for detailed timing in base EDID */ found = edid_find_valid_timing(edid->monitor_details.descriptor, 4, timing, mode_valid, mode_valid_priv); + + /* Look for detailed timing in CTA-861 Extension Block */ + if (!found && edid->extension_flag && buf_size >= EDID_EXT_SIZE) { + struct edid_cea861_info *info = + (struct edid_cea861_info *)(buf + sizeof(*edid)); + + if (info->extension_tag == EDID_CEA861_EXTENSION_TAG) { + int count = EDID_CEA861_DTD_COUNT(*info); + int offset = info->dtd_offset; + int size = count * sizeof(struct edid_detailed_timing); + + if (offset >= 4 && offset + size < EDID_SIZE) + found = edid_find_valid_timing( + (u8*)info + offset, count, timing, + mode_valid, mode_valid_priv); + } + } + if (!found) return -EINVAL; -- 2.30.1 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210223204631.1609597-6-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH 04/19] common: edid: extract code for detailed timing search
Code which searches for valid detailed timing entry will be used in more places. Extract it. Signed-off-by: Jernej Skrabec --- common/edid.c | 49 - 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/common/edid.c b/common/edid.c index 1cb7177742e8..a6c875d9c8e8 100644 --- a/common/edid.c +++ b/common/edid.c @@ -169,6 +169,29 @@ static bool cea_is_hdmi_vsdb_present(struct edid_cea861_info *info) return false; } +static bool edid_find_valid_timing(void *buf, int count, + struct display_timing *timing, + bool (*mode_valid)(void *priv, + const struct display_timing *timing), + void *mode_valid_priv) +{ + struct edid_detailed_timing *t = buf; + bool found = false; + int i; + + for (i = 0; i < count && !found; i++, t++) + if (EDID_DETAILED_TIMING_PIXEL_CLOCK(*t) != 0) { + decode_timing((u8 *)t, timing); + if (mode_valid) + found = mode_valid(mode_valid_priv, + timing); + else + found = true; + } + + return found; +} + int edid_get_timing_validate(u8 *buf, int buf_size, struct display_timing *timing, int *panel_bits_per_colourp, @@ -177,8 +200,7 @@ int edid_get_timing_validate(u8 *buf, int buf_size, void *mode_valid_priv) { struct edid1_info *edid = (struct edid1_info *)buf; - bool timing_done; - int i; + bool found; if (buf_size < sizeof(*edid) || edid_check_info(edid)) { debug("%s: Invalid buffer\n", __func__); @@ -195,25 +217,10 @@ int edid_get_timing_validate(u8 *buf, int buf_size, return -ENOENT; } - /* Look for detailed timing */ - timing_done = false; - for (i = 0; i < 4; i++) { - struct edid_monitor_descriptor *desc; - - desc = >monitor_details.descriptor[i]; - if (desc->zero_flag_1 != 0) { - decode_timing((u8 *)desc, timing); - if (mode_valid) - timing_done = mode_valid(mode_valid_priv, -timing); - else - timing_done = true; - - if (timing_done) - break; - } - } - if (!timing_done) + /* Look for detailed timing in base EDID */ + found = edid_find_valid_timing(edid->monitor_details.descriptor, 4, + timing, mode_valid, mode_valid_priv); + if (!found) return -EINVAL; if (edid->version != 1 || edid->revision < 4) { -- 2.30.1 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210223204631.1609597-5-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH 03/19] common: edid: check for digital display earlier
When searching for detailed timing in EDID, check for digital display earlier. There is no point parsing other parameters if this flag is not present. Signed-off-by: Jernej Skrabec --- common/edid.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/common/edid.c b/common/edid.c index 553ab8fd01a1..1cb7177742e8 100644 --- a/common/edid.c +++ b/common/edid.c @@ -185,6 +185,11 @@ int edid_get_timing_validate(u8 *buf, int buf_size, return -EINVAL; } + if (!EDID1_INFO_VIDEO_INPUT_DIGITAL(*edid)) { + debug("%s: Not a digital display\n", __func__); + return -ENOSYS; + } + if (!EDID1_INFO_FEATURE_PREFERRED_TIMING_MODE(*edid)) { debug("%s: No preferred timing\n", __func__); return -ENOENT; @@ -211,10 +216,6 @@ int edid_get_timing_validate(u8 *buf, int buf_size, if (!timing_done) return -EINVAL; - if (!EDID1_INFO_VIDEO_INPUT_DIGITAL(*edid)) { - debug("%s: Not a digital display\n", __func__); - return -ENOSYS; - } if (edid->version != 1 || edid->revision < 4) { debug("%s: EDID version %d.%d does not have required info\n", __func__, edid->version, edid->revision); -- 2.30.1 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210223204631.1609597-4-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH 02/19] video: sunxi: Add mode_valid callback to sunxi_dw_hdmi
Currently driver accepts all resolution which won't work on 4k screens. Add validation callback which limits acceptable resolutions to 297 MHz. Signed-off-by: Jernej Skrabec --- drivers/video/sunxi/sunxi_dw_hdmi.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/video/sunxi/sunxi_dw_hdmi.c b/drivers/video/sunxi/sunxi_dw_hdmi.c index 0b8cefc311ef..e3811a2ec15f 100644 --- a/drivers/video/sunxi/sunxi_dw_hdmi.c +++ b/drivers/video/sunxi/sunxi_dw_hdmi.c @@ -305,6 +305,12 @@ static int sunxi_dw_hdmi_read_edid(struct udevice *dev, u8 *buf, int buf_size) return dw_hdmi_read_edid(>hdmi, buf, buf_size); } +static bool sunxi_dw_hdmi_mode_valid(struct udevice *dev, +const struct display_timing *timing) +{ + return timing->pixelclock.typ <= 29700; +} + static int sunxi_dw_hdmi_enable(struct udevice *dev, int panel_bpp, const struct display_timing *edid) { @@ -388,6 +394,7 @@ static int sunxi_dw_hdmi_probe(struct udevice *dev) static const struct dm_display_ops sunxi_dw_hdmi_ops = { .read_edid = sunxi_dw_hdmi_read_edid, .enable = sunxi_dw_hdmi_enable, + .mode_valid = sunxi_dw_hdmi_mode_valid, }; U_BOOT_DRIVER(sunxi_dw_hdmi) = { -- 2.30.1 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210223204631.1609597-3-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH 01/19] sunxi: video: select dw-hdmi in Kconfig, not Makefile
Currently sunxi Makefile manually specifies full path to dw-hdmi common code. However, that is not needed because it can be selected in Kconfig instead. Select proper symbol in Kconfig and drop path from Makefile. Signed-off-by: Jernej Skrabec --- arch/arm/mach-sunxi/Kconfig | 1 + drivers/video/sunxi/Makefile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index 0135575ca1eb..9149196b223e 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig @@ -972,6 +972,7 @@ config VIDEO_DE2 depends on SUNXI_DE2 select DM_VIDEO select DISPLAY + select VIDEO_DW_HDMI imply VIDEO_DT_SIMPLEFB default y ---help--- diff --git a/drivers/video/sunxi/Makefile b/drivers/video/sunxi/Makefile index 147e18799229..4321673312bf 100644 --- a/drivers/video/sunxi/Makefile +++ b/drivers/video/sunxi/Makefile @@ -4,4 +4,4 @@ # Wolfgang Denk, DENX Software Engineering, w...@denx.de. obj-$(CONFIG_VIDEO_SUNXI) += sunxi_display.o simplefb_common.o lcdc.o tve_common.o ../videomodes.o -obj-$(CONFIG_VIDEO_DE2) += sunxi_de2.o sunxi_dw_hdmi.o simplefb_common.o lcdc.o ../dw_hdmi.o sunxi_lcd.o +obj-$(CONFIG_VIDEO_DE2) += sunxi_de2.o sunxi_dw_hdmi.o simplefb_common.o lcdc.o sunxi_lcd.o -- 2.30.1 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210223204631.1609597-2-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH 00/19] video: sunxi: Rework DE2 driver
This series greatly reworks DE2 mixer and accompanying DW-HDMI platform driver. Main goal was to use as many information from device tree as possible and thus removing SoC speficic ifdefs from the code. This was largely accomplished for mixer driver and mostly for HDMI driver. Most of these changes are not user visible. Only improvements relevant to the user are filtering HDMI modes based on pixel clock and searching for additional detailed timings in EDID extension block. This change allows me to use 4k monitor that I have - base EDID block on this monitor holds only 4k@60 detailed timing. Other detailed timings, which are appropriate for HDMI 1.4 controller, are contained in extension block. There is plenty of work to do. TCON handling should go to dedicated driver and clock related code in TCON and DW-HDMI code should be moved to clock drivers. Testing was done only on H3. Best regards, Jernej Jernej Skrabec (19): sunxi: video: select dw-hdmi in Kconfig, not Makefile video: sunxi: Add mode_valid callback to sunxi_dw_hdmi common: edid: check for digital display earlier common: edid: extract code for detailed timing search common: edid: Search for valid timing in extension block video: sunxi: Use DW-HDMI hpd function video: sunxi: Remove check for ddc-i2c-bus property video: sunxi: Remove TV probe from DE2 video: sunxi: de2: switch to public uclass functions video: sunxi: dw-hdmi: probe driver by compatible video: sunxi: dw-hdmi: read address from DT node video: dw-hdmi: modify phy init callback to include full timings video: sunxi: dw-hdmi: move PHY config to appropriate place video: sunxi: dw-hdmi: rework PHY initialization video: sunxi: de2: switch to DT probing video: sunxi: de2: read address from DT node clk: sunxi: Add DE2 clocks to H3 and A64 clk: sunxi: add DE2 clock driver video: sunxi: de2: switch clock setup to DM model arch/arm/mach-sunxi/Kconfig | 2 + common/edid.c | 82 +++-- drivers/clk/sunxi/Kconfig | 5 + drivers/clk/sunxi/Makefile | 1 + drivers/clk/sunxi/clk_a64.c | 6 + drivers/clk/sunxi/clk_de2.c | 85 + drivers/clk/sunxi/clk_h3.c | 6 + drivers/video/dw_hdmi.c | 6 +- drivers/video/meson/meson_dw_hdmi.c | 5 +- drivers/video/sunxi/Makefile| 2 +- drivers/video/sunxi/sunxi_de2.c | 191 +-- drivers/video/sunxi/sunxi_dw_hdmi.c | 498 ++-- include/dw_hdmi.h | 4 +- 13 files changed, 570 insertions(+), 323 deletions(-) create mode 100644 drivers/clk/sunxi/clk_de2.c -- 2.30.1 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210223204631.1609597-1-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH] sunxi: add fdtoverlay_addr_r environment variable
Commit 69076dff2284 ("cmd: pxe: add support for FDT overlays") added support for loading DT overlay files to PXE boot. However, it needs additional environment variable which points to memory location which can be used to temporary store overlay data. Add it and in the process unify alignment using spaces. Signed-off-by: Jernej Skrabec --- include/configs/sunxi-common.h | 48 ++ 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index ded5aea551d3..4814e898c6ea 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -62,7 +62,7 @@ #define SDRAM_OFFSET(x) 0x2##x #define CONFIG_SYS_SDRAM_BASE 0x2000 #define CONFIG_SYS_LOAD_ADDR 0x2200 /* default load address */ -/* Note SPL_STACK_R_ADDR is set through Kconfig, we include it here +/* Note SPL_STACK_R_ADDR is set through Kconfig, we include it here * since it needs to fit in with the other values. By also #defining it * we get warnings if the Kconfig value mismatches. */ #define CONFIG_SPL_STACK_R_ADDR0x2fe0 @@ -72,7 +72,7 @@ #define CONFIG_SYS_SDRAM_BASE 0x4000 #define CONFIG_SYS_LOAD_ADDR 0x4200 /* default load address */ /* V3s do not have enough memory to place code at 0x4a00 */ -/* Note SPL_STACK_R_ADDR is set through Kconfig, we include it here +/* Note SPL_STACK_R_ADDR is set through Kconfig, we include it here * since it needs to fit in with the other values. By also #defining it * we get warnings if the Kconfig value mismatches. */ #define CONFIG_SPL_STACK_R_ADDR0x4fe0 @@ -259,38 +259,41 @@ extern int soft_i2c_gpio_scl; * Scripts, PXE and DTBs should go afterwards, leaving the rest for the initrd. * Align the initrd to a 2MB page. */ -#define BOOTM_SIZE __stringify(0xa00) -#define KERNEL_ADDR_R __stringify(SDRAM_OFFSET(008)) -#define FDT_ADDR_R __stringify(SDRAM_OFFSET(FA0)) -#define SCRIPT_ADDR_R __stringify(SDRAM_OFFSET(FC0)) -#define PXEFILE_ADDR_R __stringify(SDRAM_OFFSET(FD0)) -#define RAMDISK_ADDR_R __stringify(SDRAM_OFFSET(FE0)) +#define BOOTM_SIZE__stringify(0xa00) +#define KERNEL_ADDR_R __stringify(SDRAM_OFFSET(008)) +#define FDT_ADDR_R__stringify(SDRAM_OFFSET(FA0)) +#define SCRIPT_ADDR_R __stringify(SDRAM_OFFSET(FC0)) +#define PXEFILE_ADDR_R__stringify(SDRAM_OFFSET(FD0)) +#define FDTOVERLAY_ADDR_R __stringify(SDRAM_OFFSET(FE0)) +#define RAMDISK_ADDR_R__stringify(SDRAM_OFFSET(FF0)) #else /* * 160M RAM (256M minimum minus 64MB heap + 32MB for u-boot, stack, fb, etc. * 32M uncompressed kernel, 16M compressed kernel, 1M fdt, - * 1M script, 1M pxe and the ramdisk at the end. + * 1M script, 1M pxe, 1M dt overlay and the ramdisk at the end. */ #ifndef CONFIG_MACH_SUN8I_V3S -#define BOOTM_SIZE __stringify(0xa00) -#define KERNEL_ADDR_R __stringify(SDRAM_OFFSET(200)) -#define FDT_ADDR_R __stringify(SDRAM_OFFSET(300)) -#define SCRIPT_ADDR_R __stringify(SDRAM_OFFSET(310)) -#define PXEFILE_ADDR_R __stringify(SDRAM_OFFSET(320)) -#define RAMDISK_ADDR_R __stringify(SDRAM_OFFSET(330)) +#define BOOTM_SIZE__stringify(0xa00) +#define KERNEL_ADDR_R __stringify(SDRAM_OFFSET(200)) +#define FDT_ADDR_R__stringify(SDRAM_OFFSET(300)) +#define SCRIPT_ADDR_R __stringify(SDRAM_OFFSET(310)) +#define PXEFILE_ADDR_R__stringify(SDRAM_OFFSET(320)) +#define FDTOVERLAY_ADDR_R __stringify(SDRAM_OFFSET(330)) +#define RAMDISK_ADDR_R__stringify(SDRAM_OFFSET(340)) #else /* * 64M RAM minus 2MB heap + 16MB for u-boot, stack, fb, etc. * 16M uncompressed kernel, 8M compressed kernel, 1M fdt, - * 1M script, 1M pxe and the ramdisk at the end. + * 1M script, 1M pxe, 1M dt overlay and the ramdisk at the end. */ -#define BOOTM_SIZE __stringify(0x2e0) -#define KERNEL_ADDR_R __stringify(SDRAM_OFFSET(100)) -#define FDT_ADDR_R __stringify(SDRAM_OFFSET(180)) -#define SCRIPT_ADDR_R __stringify(SDRAM_OFFSET(190)) -#define PXEFILE_ADDR_R __stringify(SDRAM_OFFSET(1A0)) -#define RAMDISK_ADDR_R __stringify(SDRAM_OFFSET(1B0)) +#define BOOTM_SIZE__stringify(0x2e0) +#define KERNEL_ADDR_R __stringify(SDRAM_OFFSET(100)) +#define FDT_ADDR_R__stringify(SDRAM_OFFSET(180)) +#define SCRIPT_ADDR_R __stringify(SDRAM_OFFSET(190)) +#define PXEFILE_ADDR_R__stringify(SDRAM_OFFSET(1A0)) +#define FDTOVERLAY_ADDR_R __stringify(SDRAM_OFFSET(1B0)) +#define RAMDISK_ADDR_R__stringify(SDRAM_OFFSET(1C0)) #endif #endif @@ -300,6 +303,7 @@ extern int soft_i2c_gpio_scl; "fdt_addr_r=" FDT_ADDR_R "\0" \ "scriptaddr=" SCRIPT_ADDR_R "\0" \ "pxefile_addr_r=" PXEFILE_ADDR
[linux-sunxi] [PATCH v3 5/5] drm/sun4i: dw-hdmi: Fix max. frequency for H6
It turns out that reasoning for lowering max. supported frequency is wrong. Scrambling works just fine. Several now fixed bugs prevented proper functioning, even with rates lower than 340 MHz. Issues were just more pronounced with higher frequencies. Fix that by allowing max. supported frequency in HW and fix the comment. Fixes: cd9063757a22 ("drm/sun4i: DW HDMI: Lower max. supported rate for H6") Reviewed-by: Chen-Yu Tsai Tested-by: Andre Heider Signed-off-by: Jernej Skrabec --- drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c index 23773a5e0650..bbdfd5e26ec8 100644 --- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c +++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c @@ -47,11 +47,9 @@ sun8i_dw_hdmi_mode_valid_h6(struct dw_hdmi *hdmi, void *data, { /* * Controller support maximum of 594 MHz, which correlates to -* 4K@60Hz 4:4:4 or RGB. However, for frequencies greater than -* 340 MHz scrambling has to be enabled. Because scrambling is -* not yet implemented, just limit to 340 MHz for now. +* 4K@60Hz 4:4:4 or RGB. */ - if (mode->clock > 34) + if (mode->clock > 594000) return MODE_CLOCK_HIGH; return MODE_OK; -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210209175900.7092-6-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v3 4/5] drm/sun4i: Fix H6 HDMI PHY configuration
As it turns out, vendor HDMI PHY driver for H6 has a pretty big table of predefined values for various pixel clocks. However, most of them are not useful/tested because they come from reference driver code. Vendor PHY driver is concerned with only few of those, namely 27 MHz, 74.25 MHz, 148.5 MHz, 297 MHz and 594 MHz. These are all frequencies for standard CEA modes. Fix sun50i_h6_cur_ctr and sun50i_h6_phy_config with the values only for aforementioned frequencies. Table sun50i_h6_mpll_cfg doesn't need to be changed because values are actually frequency dependant and not so much SoC dependant. See i.MX6 documentation for explanation of those values for similar PHY. Fixes: c71c9b2fee17 ("drm/sun4i: Add support for Synopsys HDMI PHY") Tested-by: Andre Heider Signed-off-by: Jernej Skrabec --- drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c | 26 +- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c index 35c2133724e2..9994edf67509 100644 --- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c +++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c @@ -104,29 +104,21 @@ static const struct dw_hdmi_mpll_config sun50i_h6_mpll_cfg[] = { static const struct dw_hdmi_curr_ctrl sun50i_h6_cur_ctr[] = { /* pixelclkbpp8bpp10 bpp12 */ - { 25175000, { 0x, 0x, 0x }, }, { 2700, { 0x0012, 0x, 0x }, }, - { 5940, { 0x0008, 0x0008, 0x0008 }, }, - { 7200, { 0x0008, 0x0008, 0x001b }, }, - { 7425, { 0x0013, 0x0013, 0x0013 }, }, - { 9000, { 0x0008, 0x001a, 0x001b }, }, - { 11880, { 0x001b, 0x001a, 0x001b }, }, - { 14400, { 0x001b, 0x001a, 0x0034 }, }, - { 18000, { 0x001b, 0x0033, 0x0034 }, }, - { 21600, { 0x0036, 0x0033, 0x0034 }, }, - { 23760, { 0x0036, 0x0033, 0x001b }, }, - { 28800, { 0x0036, 0x001b, 0x001b }, }, - { 29700, { 0x0019, 0x001b, 0x0019 }, }, - { 33000, { 0x0036, 0x001b, 0x001b }, }, - { 59400, { 0x003f, 0x001b, 0x001b }, }, + { 7425, { 0x0013, 0x001a, 0x001b }, }, + { 14850, { 0x0019, 0x0033, 0x0034 }, }, + { 29700, { 0x0019, 0x001b, 0x001b }, }, + { 59400, { 0x0010, 0x001b, 0x001b }, }, { ~0UL, { 0x, 0x, 0x }, } }; static const struct dw_hdmi_phy_config sun50i_h6_phy_config[] = { /*pixelclk symbol term vlev*/ - { 7425, 0x8009, 0x0004, 0x0232}, - { 14850, 0x8029, 0x0004, 0x0273}, - { 59400, 0x8039, 0x0004, 0x014a}, + { 2700, 0x8009, 0x0007, 0x02b0 }, + { 7425, 0x8009, 0x0006, 0x022d }, + { 14850, 0x8029, 0x0006, 0x0270 }, + { 29700, 0x8039, 0x0005, 0x01ab }, + { 59400, 0x8029, 0x, 0x008a }, { ~0UL, 0x, 0x, 0x} }; -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210209175900.7092-5-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v3 3/5] drm/sun4i: dw-hdmi: always set clock rate
As expected, HDMI controller clock should always match pixel clock. In the past, changing HDMI controller rate would seemingly worsen situation. However, that was the result of other bugs which are now fixed. Fix that by removing set_rate quirk and always set clock rate. Fixes: 40bb9d3147b2 ("drm/sun4i: Add support for H6 DW HDMI controller") Reviewed-by: Chen-Yu Tsai Tested-by: Andre Heider Signed-off-by: Jernej Skrabec --- drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c | 4 +--- drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c index 92add2cef2e7..23773a5e0650 100644 --- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c +++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c @@ -21,8 +21,7 @@ static void sun8i_dw_hdmi_encoder_mode_set(struct drm_encoder *encoder, { struct sun8i_dw_hdmi *hdmi = encoder_to_sun8i_dw_hdmi(encoder); - if (hdmi->quirks->set_rate) - clk_set_rate(hdmi->clk_tmds, mode->crtc_clock * 1000); + clk_set_rate(hdmi->clk_tmds, mode->crtc_clock * 1000); } static const struct drm_encoder_helper_funcs @@ -295,7 +294,6 @@ static int sun8i_dw_hdmi_remove(struct platform_device *pdev) static const struct sun8i_dw_hdmi_quirks sun8i_a83t_quirks = { .mode_valid = sun8i_dw_hdmi_mode_valid_a83t, - .set_rate = true, }; static const struct sun8i_dw_hdmi_quirks sun50i_h6_quirks = { diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h index d983746fa194..d4b55af0592f 100644 --- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h +++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h @@ -179,7 +179,6 @@ struct sun8i_dw_hdmi_quirks { enum drm_mode_status (*mode_valid)(struct dw_hdmi *hdmi, void *data, const struct drm_display_info *info, const struct drm_display_mode *mode); - unsigned int set_rate : 1; unsigned int use_drm_infoframe : 1; }; -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210209175900.7092-4-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v3 2/5] drm/sun4i: tcon: set sync polarity for tcon1 channel
Channel 1 has polarity bits for vsync and hsync signals but driver never sets them. It turns out that with pre-HDMI2 controllers seemingly there is no issue if polarity is not set. However, with HDMI2 controllers (H6) there often comes to de-synchronization due to phase shift. This causes flickering screen. It's safe to assume that similar issues might happen also with pre-HDMI2 controllers. Solve issue with setting vsync and hsync polarity. Note that display stacks with tcon top have polarity bits actually in tcon0 polarity register. Fixes: 9026e0d122ac ("drm: Add Allwinner A10 Display Engine support") Reviewed-by: Chen-Yu Tsai Tested-by: Andre Heider Signed-off-by: Jernej Skrabec --- drivers/gpu/drm/sun4i/sun4i_tcon.c | 25 + drivers/gpu/drm/sun4i/sun4i_tcon.h | 6 ++ 2 files changed, 31 insertions(+) diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c index 6b9af4c08cd6..9f06dec0fc61 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c @@ -672,6 +672,30 @@ static void sun4i_tcon1_mode_set(struct sun4i_tcon *tcon, SUN4I_TCON1_BASIC5_V_SYNC(vsync) | SUN4I_TCON1_BASIC5_H_SYNC(hsync)); + /* Setup the polarity of multiple signals */ + if (tcon->quirks->polarity_in_ch0) { + val = 0; + + if (mode->flags & DRM_MODE_FLAG_PHSYNC) + val |= SUN4I_TCON0_IO_POL_HSYNC_POSITIVE; + + if (mode->flags & DRM_MODE_FLAG_PVSYNC) + val |= SUN4I_TCON0_IO_POL_VSYNC_POSITIVE; + + regmap_write(tcon->regs, SUN4I_TCON0_IO_POL_REG, val); + } else { + /* according to vendor driver, this bit must be always set */ + val = SUN4I_TCON1_IO_POL_UNKNOWN; + + if (mode->flags & DRM_MODE_FLAG_PHSYNC) + val |= SUN4I_TCON1_IO_POL_HSYNC_POSITIVE; + + if (mode->flags & DRM_MODE_FLAG_PVSYNC) + val |= SUN4I_TCON1_IO_POL_VSYNC_POSITIVE; + + regmap_write(tcon->regs, SUN4I_TCON1_IO_POL_REG, val); + } + /* Map output pins to channel 1 */ regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG, SUN4I_TCON_GCTL_IOMAP_MASK, @@ -1500,6 +1524,7 @@ static const struct sun4i_tcon_quirks sun8i_a83t_tv_quirks = { static const struct sun4i_tcon_quirks sun8i_r40_tv_quirks = { .has_channel_1 = true, + .polarity_in_ch0= true, .set_mux= sun8i_r40_tcon_tv_set_mux, }; diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.h b/drivers/gpu/drm/sun4i/sun4i_tcon.h index c5ac1b02482c..e624f6977eb8 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tcon.h +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.h @@ -154,6 +154,11 @@ #define SUN4I_TCON1_BASIC5_V_SYNC(height) (((height) - 1) & 0x3ff) #define SUN4I_TCON1_IO_POL_REG 0xf0 +/* there is no documentation about this bit */ +#define SUN4I_TCON1_IO_POL_UNKNOWN BIT(26) +#define SUN4I_TCON1_IO_POL_HSYNC_POSITIVE BIT(25) +#define SUN4I_TCON1_IO_POL_VSYNC_POSITIVE BIT(24) + #define SUN4I_TCON1_IO_TRI_REG 0xf4 #define SUN4I_TCON_ECC_FIFO_REG0xf8 @@ -236,6 +241,7 @@ struct sun4i_tcon_quirks { boolneeds_de_be_mux; /* sun6i needs mux to select backend */ boolneeds_edp_reset; /* a80 edp reset needed for tcon0 access */ boolsupports_lvds; /* Does the TCON support an LVDS output? */ + boolpolarity_in_ch0; /* some tcon1 channels have polarity bits in tcon0 pol register */ u8 dclk_min_div; /* minimum divider for TCON0 DCLK */ /* callback to handle tcon muxing options */ -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210209175900.7092-3-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v3 1/5] clk: sunxi-ng: mp: fix parent rate change flag check
CLK_SET_RATE_PARENT flag is checked on parent clock instead of current one. Fix that. Fixes: 3f790433c3cb ("clk: sunxi-ng: Adjust MP clock parent rate when allowed") Reviewed-by: Chen-Yu Tsai Tested-by: Andre Heider Signed-off-by: Jernej Skrabec --- drivers/clk/sunxi-ng/ccu_mp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/sunxi-ng/ccu_mp.c b/drivers/clk/sunxi-ng/ccu_mp.c index fa4ecb915590..9d3a76604d94 100644 --- a/drivers/clk/sunxi-ng/ccu_mp.c +++ b/drivers/clk/sunxi-ng/ccu_mp.c @@ -108,7 +108,7 @@ static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux, max_m = cmp->m.max ?: 1 << cmp->m.width; max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1); - if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) { + if (!clk_hw_can_set_rate_parent(>common.hw)) { ccu_mp_find_best(*parent_rate, rate, max_m, max_p, , ); rate = *parent_rate / p / m; } else { -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210209175900.7092-2-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v3 0/5] sunxi: fix H6 HDMI related issues
Over the year I got plenty of reports of troubles with H6 HDMI signal. Sometimes monitor flickers, sometimes there was no image at all and sometimes it didn't play well with AVR. It turns out there are multiple issues. Patch 1 fixes clock issue, which didn't adjust parent rate, even if it is allowed to do so. Patch 2 adds polarity config in tcon1. This is seemingly not needed for pre-HDMI2 controllers, although BSP drivers set it accordingly every time. It turns out that HDMI2 controllers often don't work with monitors if polarity is not set correctly. Patch 3 always set clock rate for HDMI controller. Patch 4 fixes H6 HDMI PHY settings. Patch 5 fixes comment and clock rate limit (wrong reasoning). Please take a look. Best regards, Jernej Changes from v2: - use clk_hw_can_set_rate_parent() directly instead of checking flags Changes from v1: - collected Chen-Yu tags (except on replaced patch 4) - Added some comments in patch 2 - Replaced patch 4 (see commit log for explanation) Jernej Skrabec (5): clk: sunxi-ng: mp: fix parent rate change flag check drm/sun4i: tcon: set sync polarity for tcon1 channel drm/sun4i: dw-hdmi: always set clock rate drm/sun4i: Fix H6 HDMI PHY configuration drm/sun4i: dw-hdmi: Fix max. frequency for H6 drivers/clk/sunxi-ng/ccu_mp.c | 2 +- drivers/gpu/drm/sun4i/sun4i_tcon.c | 25 + drivers/gpu/drm/sun4i/sun4i_tcon.h | 6 ++ drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c | 10 +++--- drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h | 1 - drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c | 26 +- 6 files changed, 44 insertions(+), 26 deletions(-) -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210209175900.7092-1-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2 5/5] drm/sun4i: dw-hdmi: Fix max. frequency for H6
It turns out that reasoning for lowering max. supported frequency is wrong. Scrambling works just fine. Several now fixed bugs prevented proper functioning, even with rates lower than 340 MHz. Issues were just more pronounced with higher frequencies. Fix that by allowing max. supported frequency in HW and fix the comment. Fixes: cd9063757a22 ("drm/sun4i: DW HDMI: Lower max. supported rate for H6") Reviewed-by: Chen-Yu Tsai Tested-by: Andre Heider Signed-off-by: Jernej Skrabec --- drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c index 23773a5e0650..bbdfd5e26ec8 100644 --- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c +++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c @@ -47,11 +47,9 @@ sun8i_dw_hdmi_mode_valid_h6(struct dw_hdmi *hdmi, void *data, { /* * Controller support maximum of 594 MHz, which correlates to -* 4K@60Hz 4:4:4 or RGB. However, for frequencies greater than -* 340 MHz scrambling has to be enabled. Because scrambling is -* not yet implemented, just limit to 340 MHz for now. +* 4K@60Hz 4:4:4 or RGB. */ - if (mode->clock > 34) + if (mode->clock > 594000) return MODE_CLOCK_HIGH; return MODE_OK; -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210208121752.2255465-6-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2 4/5] drm/sun4i: Fix H6 HDMI PHY configuration
As it turns out, vendor HDMI PHY driver for H6 has a pretty big table of predefined values for various pixel clocks. However, most of them are not useful/tested because they come from reference driver code. Vendor PHY driver is concerned with only few of those, namely 27 MHz, 74.25 MHz, 148.5 MHz, 297 MHz and 594 MHz. These are all frequencies for standard CEA modes. Fix sun50i_h6_cur_ctr and sun50i_h6_phy_config with the values only for aforementioned frequencies. Table sun50i_h6_mpll_cfg doesn't need to be changed because values are actually frequency dependant and not so much SoC dependant. See i.MX6 documentation for explanation of those values for similar PHY. Fixes: c71c9b2fee17 ("drm/sun4i: Add support for Synopsys HDMI PHY") Tested-by: Andre Heider Signed-off-by: Jernej Skrabec --- drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c | 26 +- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c index 35c2133724e2..9994edf67509 100644 --- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c +++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c @@ -104,29 +104,21 @@ static const struct dw_hdmi_mpll_config sun50i_h6_mpll_cfg[] = { static const struct dw_hdmi_curr_ctrl sun50i_h6_cur_ctr[] = { /* pixelclkbpp8bpp10 bpp12 */ - { 25175000, { 0x, 0x, 0x }, }, { 2700, { 0x0012, 0x, 0x }, }, - { 5940, { 0x0008, 0x0008, 0x0008 }, }, - { 7200, { 0x0008, 0x0008, 0x001b }, }, - { 7425, { 0x0013, 0x0013, 0x0013 }, }, - { 9000, { 0x0008, 0x001a, 0x001b }, }, - { 11880, { 0x001b, 0x001a, 0x001b }, }, - { 14400, { 0x001b, 0x001a, 0x0034 }, }, - { 18000, { 0x001b, 0x0033, 0x0034 }, }, - { 21600, { 0x0036, 0x0033, 0x0034 }, }, - { 23760, { 0x0036, 0x0033, 0x001b }, }, - { 28800, { 0x0036, 0x001b, 0x001b }, }, - { 29700, { 0x0019, 0x001b, 0x0019 }, }, - { 33000, { 0x0036, 0x001b, 0x001b }, }, - { 59400, { 0x003f, 0x001b, 0x001b }, }, + { 7425, { 0x0013, 0x001a, 0x001b }, }, + { 14850, { 0x0019, 0x0033, 0x0034 }, }, + { 29700, { 0x0019, 0x001b, 0x001b }, }, + { 59400, { 0x0010, 0x001b, 0x001b }, }, { ~0UL, { 0x, 0x, 0x }, } }; static const struct dw_hdmi_phy_config sun50i_h6_phy_config[] = { /*pixelclk symbol term vlev*/ - { 7425, 0x8009, 0x0004, 0x0232}, - { 14850, 0x8029, 0x0004, 0x0273}, - { 59400, 0x8039, 0x0004, 0x014a}, + { 2700, 0x8009, 0x0007, 0x02b0 }, + { 7425, 0x8009, 0x0006, 0x022d }, + { 14850, 0x8029, 0x0006, 0x0270 }, + { 29700, 0x8039, 0x0005, 0x01ab }, + { 59400, 0x8029, 0x, 0x008a }, { ~0UL, 0x, 0x, 0x} }; -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210208121752.2255465-5-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2 3/5] drm/sun4i: dw-hdmi: always set clock rate
As expected, HDMI controller clock should always match pixel clock. In the past, changing HDMI controller rate would seemingly worsen situation. However, that was the result of other bugs which are now fixed. Fix that by removing set_rate quirk and always set clock rate. Fixes: 40bb9d3147b2 ("drm/sun4i: Add support for H6 DW HDMI controller") Reviewed-by: Chen-Yu Tsai Tested-by: Andre Heider Signed-off-by: Jernej Skrabec --- drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c | 4 +--- drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c index 92add2cef2e7..23773a5e0650 100644 --- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c +++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c @@ -21,8 +21,7 @@ static void sun8i_dw_hdmi_encoder_mode_set(struct drm_encoder *encoder, { struct sun8i_dw_hdmi *hdmi = encoder_to_sun8i_dw_hdmi(encoder); - if (hdmi->quirks->set_rate) - clk_set_rate(hdmi->clk_tmds, mode->crtc_clock * 1000); + clk_set_rate(hdmi->clk_tmds, mode->crtc_clock * 1000); } static const struct drm_encoder_helper_funcs @@ -295,7 +294,6 @@ static int sun8i_dw_hdmi_remove(struct platform_device *pdev) static const struct sun8i_dw_hdmi_quirks sun8i_a83t_quirks = { .mode_valid = sun8i_dw_hdmi_mode_valid_a83t, - .set_rate = true, }; static const struct sun8i_dw_hdmi_quirks sun50i_h6_quirks = { diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h index d983746fa194..d4b55af0592f 100644 --- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h +++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h @@ -179,7 +179,6 @@ struct sun8i_dw_hdmi_quirks { enum drm_mode_status (*mode_valid)(struct dw_hdmi *hdmi, void *data, const struct drm_display_info *info, const struct drm_display_mode *mode); - unsigned int set_rate : 1; unsigned int use_drm_infoframe : 1; }; -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210208121752.2255465-4-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2 2/5] drm/sun4i: tcon: set sync polarity for tcon1 channel
Channel 1 has polarity bits for vsync and hsync signals but driver never sets them. It turns out that with pre-HDMI2 controllers seemingly there is no issue if polarity is not set. However, with HDMI2 controllers (H6) there often comes to de-synchronization due to phase shift. This causes flickering screen. It's safe to assume that similar issues might happen also with pre-HDMI2 controllers. Solve issue with setting vsync and hsync polarity. Note that display stacks with tcon top have polarity bits actually in tcon0 polarity register. Fixes: 9026e0d122ac ("drm: Add Allwinner A10 Display Engine support") Reviewed-by: Chen-Yu Tsai Tested-by: Andre Heider Signed-off-by: Jernej Skrabec --- drivers/gpu/drm/sun4i/sun4i_tcon.c | 25 + drivers/gpu/drm/sun4i/sun4i_tcon.h | 6 ++ 2 files changed, 31 insertions(+) diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c index 6b9af4c08cd6..9f06dec0fc61 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c @@ -672,6 +672,30 @@ static void sun4i_tcon1_mode_set(struct sun4i_tcon *tcon, SUN4I_TCON1_BASIC5_V_SYNC(vsync) | SUN4I_TCON1_BASIC5_H_SYNC(hsync)); + /* Setup the polarity of multiple signals */ + if (tcon->quirks->polarity_in_ch0) { + val = 0; + + if (mode->flags & DRM_MODE_FLAG_PHSYNC) + val |= SUN4I_TCON0_IO_POL_HSYNC_POSITIVE; + + if (mode->flags & DRM_MODE_FLAG_PVSYNC) + val |= SUN4I_TCON0_IO_POL_VSYNC_POSITIVE; + + regmap_write(tcon->regs, SUN4I_TCON0_IO_POL_REG, val); + } else { + /* according to vendor driver, this bit must be always set */ + val = SUN4I_TCON1_IO_POL_UNKNOWN; + + if (mode->flags & DRM_MODE_FLAG_PHSYNC) + val |= SUN4I_TCON1_IO_POL_HSYNC_POSITIVE; + + if (mode->flags & DRM_MODE_FLAG_PVSYNC) + val |= SUN4I_TCON1_IO_POL_VSYNC_POSITIVE; + + regmap_write(tcon->regs, SUN4I_TCON1_IO_POL_REG, val); + } + /* Map output pins to channel 1 */ regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG, SUN4I_TCON_GCTL_IOMAP_MASK, @@ -1500,6 +1524,7 @@ static const struct sun4i_tcon_quirks sun8i_a83t_tv_quirks = { static const struct sun4i_tcon_quirks sun8i_r40_tv_quirks = { .has_channel_1 = true, + .polarity_in_ch0= true, .set_mux= sun8i_r40_tcon_tv_set_mux, }; diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.h b/drivers/gpu/drm/sun4i/sun4i_tcon.h index c5ac1b02482c..e624f6977eb8 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tcon.h +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.h @@ -154,6 +154,11 @@ #define SUN4I_TCON1_BASIC5_V_SYNC(height) (((height) - 1) & 0x3ff) #define SUN4I_TCON1_IO_POL_REG 0xf0 +/* there is no documentation about this bit */ +#define SUN4I_TCON1_IO_POL_UNKNOWN BIT(26) +#define SUN4I_TCON1_IO_POL_HSYNC_POSITIVE BIT(25) +#define SUN4I_TCON1_IO_POL_VSYNC_POSITIVE BIT(24) + #define SUN4I_TCON1_IO_TRI_REG 0xf4 #define SUN4I_TCON_ECC_FIFO_REG0xf8 @@ -236,6 +241,7 @@ struct sun4i_tcon_quirks { boolneeds_de_be_mux; /* sun6i needs mux to select backend */ boolneeds_edp_reset; /* a80 edp reset needed for tcon0 access */ boolsupports_lvds; /* Does the TCON support an LVDS output? */ + boolpolarity_in_ch0; /* some tcon1 channels have polarity bits in tcon0 pol register */ u8 dclk_min_div; /* minimum divider for TCON0 DCLK */ /* callback to handle tcon muxing options */ -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210208121752.2255465-3-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2 1/5] clk: sunxi-ng: mp: fix parent rate change flag check
CLK_SET_RATE_PARENT flag is checked on parent clock instead of current one. Fix that. Fixes: 3f790433c3cb ("clk: sunxi-ng: Adjust MP clock parent rate when allowed") Reviewed-by: Chen-Yu Tsai Tested-by: Andre Heider Signed-off-by: Jernej Skrabec --- drivers/clk/sunxi-ng/ccu_mp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/sunxi-ng/ccu_mp.c b/drivers/clk/sunxi-ng/ccu_mp.c index fa4ecb915590..5f40be6d2dfd 100644 --- a/drivers/clk/sunxi-ng/ccu_mp.c +++ b/drivers/clk/sunxi-ng/ccu_mp.c @@ -108,7 +108,7 @@ static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux, max_m = cmp->m.max ?: 1 << cmp->m.width; max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1); - if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) { + if (!(clk_hw_get_flags(>common.hw) & CLK_SET_RATE_PARENT)) { ccu_mp_find_best(*parent_rate, rate, max_m, max_p, , ); rate = *parent_rate / p / m; } else { -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210208121752.2255465-2-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2 0/5] sunxi: fix H6 HDMI related issues
Over the year I got plenty of reports of troubles with H6 HDMI signal. Sometimes monitor flickers, sometimes there was no image at all and sometimes it didn't play well with AVR. It turns out there are multiple issues. Patch 1 fixes clock issue, which didn't adjust parent rate, even if it is allowed to do so. Patch 2 adds polarity config in tcon1. This is seemingly not needed for pre-HDMI2 controllers, although BSP drivers set it accordingly every time. It turns out that HDMI2 controllers often don't work with monitors if polarity is not set correctly. Patch 3 always set clock rate for HDMI controller. Patch 4 fixes H6 HDMI PHY setting. Patch 5 fixes comment and clock rate limit (wrong reasoning). Please take a look. Best regards, Jernej Changes from v1: - collected Chen-Yu tags (except on replaced patch 4) - Added some comments in patch 2 - Replaced patch 4 (see commit log for explanation) Jernej Skrabec (5): clk: sunxi-ng: mp: fix parent rate change flag check drm/sun4i: tcon: set sync polarity for tcon1 channel drm/sun4i: dw-hdmi: always set clock rate drm/sun4i: Fix H6 HDMI PHY configuration drm/sun4i: dw-hdmi: Fix max. frequency for H6 drivers/clk/sunxi-ng/ccu_mp.c | 2 +- drivers/gpu/drm/sun4i/sun4i_tcon.c | 25 + drivers/gpu/drm/sun4i/sun4i_tcon.h | 6 ++ drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c | 10 +++--- drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h | 1 - drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c | 26 +- 6 files changed, 44 insertions(+), 26 deletions(-) -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210208121752.2255465-1-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH 5/5] drm/sun4i: dw-hdmi: Fix max. frequency for H6
It turns out that reasoning for lowering max. supported frequency is wrong. Scrambling works just fine. Several now fixed bugs prevented proper functioning, even with rates lower than 340 MHz. Issues were just more pronounced with higher frequencies. Fix that by allowing max. supported frequency in HW and fix the comment. Fixes: cd9063757a22 ("drm/sun4i: DW HDMI: Lower max. supported rate for H6") Tested-by: Andre Heider Signed-off-by: Jernej Skrabec --- drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c index 23773a5e0650..bbdfd5e26ec8 100644 --- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c +++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c @@ -47,11 +47,9 @@ sun8i_dw_hdmi_mode_valid_h6(struct dw_hdmi *hdmi, void *data, { /* * Controller support maximum of 594 MHz, which correlates to -* 4K@60Hz 4:4:4 or RGB. However, for frequencies greater than -* 340 MHz scrambling has to be enabled. Because scrambling is -* not yet implemented, just limit to 340 MHz for now. +* 4K@60Hz 4:4:4 or RGB. */ - if (mode->clock > 34) + if (mode->clock > 594000) return MODE_CLOCK_HIGH; return MODE_OK; -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210204184710.1880895-6-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH 4/5] drm/sun4i: Fix H6 HDMI PHY configuration
cpce value for 594 MHz is set differently in BSP driver. Fix that. Fixes: c71c9b2fee17 ("drm/sun4i: Add support for Synopsys HDMI PHY") Tested-by: Andre Heider Signed-off-by: Jernej Skrabec --- drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c index 35c2133724e2..89aff19ddeb4 100644 --- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c +++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c @@ -89,7 +89,7 @@ static const struct dw_hdmi_mpll_config sun50i_h6_mpll_cfg[] = { }, }, { 59400, { - { 0x1a40, 0x0003 }, + { 0x1a7c, 0x0003 }, { 0x3b4c, 0x0003 }, { 0x5a64, 0x0003 }, }, -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210204184710.1880895-5-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH 3/5] drm/sun4i: dw-hdmi: always set clock rate
As expected, HDMI controller clock should always match pixel clock. In the past, changing HDMI controller rate would seemingly worsen situation. However, that was the result of other bugs which are now fixed. Fix that by removing set_rate quirk and always set clock rate. Fixes: 40bb9d3147b2 ("drm/sun4i: Add support for H6 DW HDMI controller") Tested-by: Andre Heider Signed-off-by: Jernej Skrabec --- drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c | 4 +--- drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c index 92add2cef2e7..23773a5e0650 100644 --- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c +++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c @@ -21,8 +21,7 @@ static void sun8i_dw_hdmi_encoder_mode_set(struct drm_encoder *encoder, { struct sun8i_dw_hdmi *hdmi = encoder_to_sun8i_dw_hdmi(encoder); - if (hdmi->quirks->set_rate) - clk_set_rate(hdmi->clk_tmds, mode->crtc_clock * 1000); + clk_set_rate(hdmi->clk_tmds, mode->crtc_clock * 1000); } static const struct drm_encoder_helper_funcs @@ -295,7 +294,6 @@ static int sun8i_dw_hdmi_remove(struct platform_device *pdev) static const struct sun8i_dw_hdmi_quirks sun8i_a83t_quirks = { .mode_valid = sun8i_dw_hdmi_mode_valid_a83t, - .set_rate = true, }; static const struct sun8i_dw_hdmi_quirks sun50i_h6_quirks = { diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h index d983746fa194..d4b55af0592f 100644 --- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h +++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h @@ -179,7 +179,6 @@ struct sun8i_dw_hdmi_quirks { enum drm_mode_status (*mode_valid)(struct dw_hdmi *hdmi, void *data, const struct drm_display_info *info, const struct drm_display_mode *mode); - unsigned int set_rate : 1; unsigned int use_drm_infoframe : 1; }; -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210204184710.1880895-4-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH 2/5] drm/sun4i: tcon: set sync polarity for tcon1 channel
Channel 1 has polarity bits for vsync and hsync signals but driver never sets them. It turns out that with pre-HDMI2 controllers seemingly there is no issue if polarity is not set. However, with HDMI2 controllers (H6) there often comes to de-synchronization due to phase shift. This causes flickering screen. It's safe to assume that similar issues might happen also with pre-HDMI2 controllers. Solve issue with setting vsync and hsync polarity. Note that display stacks with tcon top have polarity bits actually in tcon0 polarity register. Fixes: 9026e0d122ac ("drm: Add Allwinner A10 Display Engine support") Tested-by: Andre Heider Signed-off-by: Jernej Skrabec --- drivers/gpu/drm/sun4i/sun4i_tcon.c | 24 drivers/gpu/drm/sun4i/sun4i_tcon.h | 5 + 2 files changed, 29 insertions(+) diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c index 6b9af4c08cd6..0d132dae58c0 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c @@ -672,6 +672,29 @@ static void sun4i_tcon1_mode_set(struct sun4i_tcon *tcon, SUN4I_TCON1_BASIC5_V_SYNC(vsync) | SUN4I_TCON1_BASIC5_H_SYNC(hsync)); + /* Setup the polarity of sync signals */ + if (tcon->quirks->polarity_in_ch0) { + val = 0; + + if (mode->flags & DRM_MODE_FLAG_PHSYNC) + val |= SUN4I_TCON0_IO_POL_HSYNC_POSITIVE; + + if (mode->flags & DRM_MODE_FLAG_PVSYNC) + val |= SUN4I_TCON0_IO_POL_VSYNC_POSITIVE; + + regmap_write(tcon->regs, SUN4I_TCON0_IO_POL_REG, val); + } else { + val = SUN4I_TCON1_IO_POL_UNKNOWN; + + if (mode->flags & DRM_MODE_FLAG_PHSYNC) + val |= SUN4I_TCON1_IO_POL_HSYNC_POSITIVE; + + if (mode->flags & DRM_MODE_FLAG_PVSYNC) + val |= SUN4I_TCON1_IO_POL_VSYNC_POSITIVE; + + regmap_write(tcon->regs, SUN4I_TCON1_IO_POL_REG, val); + } + /* Map output pins to channel 1 */ regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG, SUN4I_TCON_GCTL_IOMAP_MASK, @@ -1500,6 +1523,7 @@ static const struct sun4i_tcon_quirks sun8i_a83t_tv_quirks = { static const struct sun4i_tcon_quirks sun8i_r40_tv_quirks = { .has_channel_1 = true, + .polarity_in_ch0= true, .set_mux= sun8i_r40_tcon_tv_set_mux, }; diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.h b/drivers/gpu/drm/sun4i/sun4i_tcon.h index c5ac1b02482c..b504fb2d3de5 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tcon.h +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.h @@ -154,6 +154,10 @@ #define SUN4I_TCON1_BASIC5_V_SYNC(height) (((height) - 1) & 0x3ff) #define SUN4I_TCON1_IO_POL_REG 0xf0 +#define SUN4I_TCON1_IO_POL_UNKNOWN BIT(26) +#define SUN4I_TCON1_IO_POL_HSYNC_POSITIVE BIT(25) +#define SUN4I_TCON1_IO_POL_VSYNC_POSITIVE BIT(24) + #define SUN4I_TCON1_IO_TRI_REG 0xf4 #define SUN4I_TCON_ECC_FIFO_REG0xf8 @@ -236,6 +240,7 @@ struct sun4i_tcon_quirks { boolneeds_de_be_mux; /* sun6i needs mux to select backend */ boolneeds_edp_reset; /* a80 edp reset needed for tcon0 access */ boolsupports_lvds; /* Does the TCON support an LVDS output? */ + boolpolarity_in_ch0; /* some tcon1 channels have polarity bits in tcon0 pol register */ u8 dclk_min_div; /* minimum divider for TCON0 DCLK */ /* callback to handle tcon muxing options */ -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210204184710.1880895-3-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH 1/5] clk: sunxi-ng: mp: fix parent rate change flag check
CLK_SET_RATE_PARENT flag is checked on parent clock instead of current one. Fix that. Fixes: 3f790433c3cb ("clk: sunxi-ng: Adjust MP clock parent rate when allowed") Tested-by: Andre Heider Signed-off-by: Jernej Skrabec --- drivers/clk/sunxi-ng/ccu_mp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/sunxi-ng/ccu_mp.c b/drivers/clk/sunxi-ng/ccu_mp.c index fa4ecb915590..5f40be6d2dfd 100644 --- a/drivers/clk/sunxi-ng/ccu_mp.c +++ b/drivers/clk/sunxi-ng/ccu_mp.c @@ -108,7 +108,7 @@ static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux, max_m = cmp->m.max ?: 1 << cmp->m.width; max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1); - if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) { + if (!(clk_hw_get_flags(>common.hw) & CLK_SET_RATE_PARENT)) { ccu_mp_find_best(*parent_rate, rate, max_m, max_p, , ); rate = *parent_rate / p / m; } else { -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210204184710.1880895-2-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH 0/5] sunxi: fix H6 HDMI related issues
Over the year I got plenty of reports of troubles with H6 HDMI signal. Sometimes monitor flickers, sometimes there was no image at all and sometimes it didn't play well with AVR. It turns out there are multiple issues. Patch 1 fixes clock issue, which didn't adjust parent rate, even if it is allowed to do so. Patch 2 adds polarity config in tcon1. This is seemingly not needed for pre-HDMI2 controllers, although BSP drivers set it accordingly every time. It turns out that HDMI2 controllers often don't work with monitors if polarity is not set correctly. Patch 3 always set clock rate for HDMI controller. Patch 4 fixes cpce PHY setting for 594 MHz. Patch 5 fixes comment and clock rate limit (wrong reasoning). Please take a look. Best regards, Jernej Jernej Skrabec (5): clk: sunxi-ng: mp: fix parent rate change flag check drm/sun4i: tcon: set sync polarity for tcon1 channel drm/sun4i: dw-hdmi: always set clock rate drm/sun4i: Fix H6 HDMI PHY configuration drm/sun4i: dw-hdmi: Fix max. frequency for H6 drivers/clk/sunxi-ng/ccu_mp.c | 2 +- drivers/gpu/drm/sun4i/sun4i_tcon.c | 24 drivers/gpu/drm/sun4i/sun4i_tcon.h | 5 + drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c | 10 +++--- drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h | 1 - drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c | 2 +- 6 files changed, 34 insertions(+), 10 deletions(-) -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210204184710.1880895-1-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2] sunxi: spl: Fix H616 clock initialization
It turns out that there is a magic bit in PRCM region which seemingly makes PLLs work if it's enabled. Sadly, there is no documentation what it does exactly, so we'll just mimick BSP boot0 behaviour and enable it before any clock is set up. Fixes: b18bd53d6cde ("sunxi: introduce support for H616 clocks") Signed-off-by: Jernej Skrabec --- Changes from v1: - use if (IS_ENABLED()) instead of #ifdef #endif arch/arm/mach-sunxi/clock_sun50i_h6.c | 5 + 1 file changed, 5 insertions(+) diff --git a/arch/arm/mach-sunxi/clock_sun50i_h6.c b/arch/arm/mach-sunxi/clock_sun50i_h6.c index 06d84eb158d7..492fc4a3fca8 100644 --- a/arch/arm/mach-sunxi/clock_sun50i_h6.c +++ b/arch/arm/mach-sunxi/clock_sun50i_h6.c @@ -9,6 +9,11 @@ void clock_init_safe(void) { struct sunxi_ccm_reg *const ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + + /* this seems to enable PLLs on H616 */ + if (IS_ENABLED(CONFIG_MACH_SUN50I_H616)) + setbits_le32(SUNXI_PRCM_BASE + 0x250, 0x10); + clock_set_pll1(40800); writel(CCM_PLL6_DEFAULT, >pll6_cfg); -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210201172557.3776708-1-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH] sunxi: spl: Fix H616 clock initialization
It turns out that there is a magic bit in PRCM region which seemingly makes PLLs work if it's enabled. Sadly, there is no documentation what it does exactly, so we'll just mimick BSP boot0 behaviour and enable it before any clock is set up. Fixes: b18bd53d6cde ("sunxi: introduce support for H616 clocks") Signed-off-by: Jernej Skrabec --- arch/arm/mach-sunxi/clock_sun50i_h6.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/mach-sunxi/clock_sun50i_h6.c b/arch/arm/mach-sunxi/clock_sun50i_h6.c index 06d84eb158d7..68c8e7f2afbe 100644 --- a/arch/arm/mach-sunxi/clock_sun50i_h6.c +++ b/arch/arm/mach-sunxi/clock_sun50i_h6.c @@ -9,6 +9,12 @@ void clock_init_safe(void) { struct sunxi_ccm_reg *const ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + +#ifdef CONFIG_MACH_SUN50I_H616 + /* this seems to enable PLLs */ + setbits_le32(SUNXI_PRCM_BASE + 0x250, 0x10); +#endif + clock_set_pll1(40800); writel(CCM_PLL6_DEFAULT, >pll6_cfg); -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210131202539.3735672-1-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH] ARM: dts: sunxi: bananapi-m2-plus: Increase BT UART speed
Bluetooth module on BananaPi M2 Plus can also be used for streaming audio. However, for that case higher UART speed is required. Add a max-speed property. Signed-off-by: Jernej Skrabec --- arch/arm/boot/dts/sunxi-bananapi-m2-plus.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/sunxi-bananapi-m2-plus.dtsi b/arch/arm/boot/dts/sunxi-bananapi-m2-plus.dtsi index 8e5cb3b3fd68..7a6af54dd342 100644 --- a/arch/arm/boot/dts/sunxi-bananapi-m2-plus.dtsi +++ b/arch/arm/boot/dts/sunxi-bananapi-m2-plus.dtsi @@ -219,6 +219,7 @@ { bluetooth { compatible = "brcm,bcm43438-bt"; + max-speed = <150>; clocks = < 1>; clock-names = "lpo"; vbat-supply = <_vcc3v3>; -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210116105228.847073-1-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH] ARM: dts: sun8i: h2-plus: bananapi-m2-zero: Increase BT UART speed
Bluetooth module on BananaPi M2 Zero can also be used for streaming audio. However, for that case higher UART speed is required. Add a max-speed property. Signed-off-by: Jernej Skrabec --- arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts b/arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts index 4c6704e4c57e..240e0f363cd1 100644 --- a/arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts +++ b/arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts @@ -125,6 +125,7 @@ { bluetooth { compatible = "brcm,bcm43438-bt"; + max-speed = <150>; clocks = < 1>; clock-names = "lpo"; vbat-supply = <_vcc3v3>; -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210116103710.245617-1-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2 21/21] sunxi: Add support for OrangePi Zero2
OrangePi Zero2 is SBC based on Allwinner H616 with 1 GiB of RAM, SD card support, gigabit ethernet, micro HDMI, WIFI, Bluetooth and 1 USB 2.0 port. It also has two GPIO headers which allows further peripherals to be used. Device Tree file is taken from initial OrangePi Zero2 Linux submission and it's not yet merged. Signed-off-by: Jernej Skrabec --- arch/arm/dts/Makefile | 2 + arch/arm/dts/sun50i-h616-orangepi-zero2.dts | 240 board/sunxi/MAINTAINERS | 5 + configs/orangepi_zero2_defconfig| 15 ++ 4 files changed, 262 insertions(+) create mode 100644 arch/arm/dts/sun50i-h616-orangepi-zero2.dts create mode 100644 configs/orangepi_zero2_defconfig diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 1a62e4c0708a..ed6150dca38d 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -609,6 +609,8 @@ dtb-$(CONFIG_MACH_SUN50I_H6) += \ sun50i-h6-orangepi-lite2.dtb \ sun50i-h6-orangepi-one-plus.dtb \ sun50i-h6-pine-h64.dtb +dtb-$(CONFIG_MACH_SUN50I_H616) += \ + sun50i-h616-orangepi-zero2.dtb dtb-$(CONFIG_MACH_SUN50I) += \ sun50i-a64-amarula-relic.dtb \ sun50i-a64-bananapi-m64.dtb \ diff --git a/arch/arm/dts/sun50i-h616-orangepi-zero2.dts b/arch/arm/dts/sun50i-h616-orangepi-zero2.dts new file mode 100644 index ..2afc036059b4 --- /dev/null +++ b/arch/arm/dts/sun50i-h616-orangepi-zero2.dts @@ -0,0 +1,240 @@ +// SPDX-License-Identifier: (GPL-2.0+ or MIT) +/* + * Copyright (C) 2020 Arm Ltd. + */ + +/dts-v1/; + +#include "sun50i-h616.dtsi" + +#include +#include +#include + +/ { + model = "OrangePi Zero2"; + compatible = "xunlong,orangepi-zero2", "allwinner,sun50i-h616"; + + aliases { + ethernet0 = + serial0 = + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + leds { + compatible = "gpio-leds"; + + power { + function = LED_FUNCTION_POWER; + color = ; + gpios = < 2 12 GPIO_ACTIVE_HIGH>; /* PC12 */ + default-state = "on"; + }; + + status { + function = LED_FUNCTION_STATUS; + color = ; + gpios = < 2 13 GPIO_ACTIVE_HIGH>; /* PC13 */ + }; + }; + + reg_vcc5v: vcc5v { + /* board wide 5V supply directly from the USB-C socket */ + compatible = "regulator-fixed"; + regulator-name = "vcc-5v"; + regulator-min-microvolt = <500>; + regulator-max-microvolt = <500>; + regulator-always-on; + }; + + reg_usb1_vbus: usb1-vbus { + compatible = "regulator-fixed"; + regulator-name = "usb1-vbus"; + regulator-min-microvolt = <500>; + regulator-max-microvolt = <500>; + vin-supply = <_vcc5v>; + enable-active-high; + gpio = < 2 16 GPIO_ACTIVE_HIGH>; /* PC16 */ + status = "okay"; + }; +}; + + { + status = "okay"; +}; + + { + status = "okay"; +}; + +/* USB 2 & 3 are on headers only. */ + + { + pinctrl-names = "default"; + pinctrl-0 = <_rgmii_pins>; + phy-mode = "rgmii"; + phy-handle = <_rgmii_phy>; + phy-supply = <_dcdce>; + allwinner,rx-delay-ps = <3100>; + allwinner,tx-delay-ps = <700>; + status = "okay"; +}; + + { + ext_rgmii_phy: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; + }; +}; + + { + vmmc-supply = <_dcdce>; + cd-gpios = < 5 6 GPIO_ACTIVE_LOW>; /* PF6 */ + bus-width = <4>; + status = "okay"; +}; + + { + status = "okay"; +}; + + { + status = "okay"; +}; + +_i2c { + status = "okay"; + + axp305: pmic@36 { + compatible = "x-powers,axp305", "x-powers,axp805", +"x-powers,axp806"; + reg = <0x36>; + + x-powers,self-working-mode; + vina-supply = <_vcc5v>; + vinb-supply = <_vcc5v>; + vinc-supply = <_vcc5v>; + vind-supply = <_vcc5v>; + vine-supply = <_vcc5v>; + aldoin-supply = <_vcc5v>; + bldoin-supply = <_vcc5v>; + cldoin-supply = <_vcc5v>; + +
[linux-sunxi] [PATCH v2 20/21] clk: sunxi: Add support for H616 clocks
This commit introduces DM H616 clock driver. Reviewed-by: Andre Przywara Signed-off-by: Jernej Skrabec --- drivers/clk/sunxi/Kconfig| 7 ++ drivers/clk/sunxi/Makefile | 1 + drivers/clk/sunxi/clk_h616.c | 120 +++ 3 files changed, 128 insertions(+) create mode 100644 drivers/clk/sunxi/clk_h616.c diff --git a/drivers/clk/sunxi/Kconfig b/drivers/clk/sunxi/Kconfig index 5ff101b99305..bf084fa7a84a 100644 --- a/drivers/clk/sunxi/Kconfig +++ b/drivers/clk/sunxi/Kconfig @@ -79,6 +79,13 @@ config CLK_SUN50I_H6 This enables common clock driver support for platforms based on Allwinner H6 SoC. +config CLK_SUN50I_H616 + bool "Clock driver for Allwinner H616" + default MACH_SUN50I_H616 + help + This enables common clock driver support for platforms based + on Allwinner H616 SoC. + config CLK_SUN50I_A64 bool "Clock driver for Allwinner A64" default MACH_SUN50I diff --git a/drivers/clk/sunxi/Makefile b/drivers/clk/sunxi/Makefile index 36fb2aeb56c5..0dfc0593fb1c 100644 --- a/drivers/clk/sunxi/Makefile +++ b/drivers/clk/sunxi/Makefile @@ -16,4 +16,5 @@ obj-$(CONFIG_CLK_SUN8I_V3S) += clk_v3s.o obj-$(CONFIG_CLK_SUN9I_A80) += clk_a80.o obj-$(CONFIG_CLK_SUN8I_H3) += clk_h3.o obj-$(CONFIG_CLK_SUN50I_H6) += clk_h6.o +obj-$(CONFIG_CLK_SUN50I_H616) += clk_h616.o obj-$(CONFIG_CLK_SUN50I_A64) += clk_a64.o diff --git a/drivers/clk/sunxi/clk_h616.c b/drivers/clk/sunxi/clk_h616.c new file mode 100644 index ..e2e3a5c78c95 --- /dev/null +++ b/drivers/clk/sunxi/clk_h616.c @@ -0,0 +1,120 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2021 Jernej Skrabec + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static struct ccu_clk_gate h616_gates[] = { + [CLK_BUS_MMC0] = GATE(0x84c, BIT(0)), + [CLK_BUS_MMC1] = GATE(0x84c, BIT(1)), + [CLK_BUS_MMC2] = GATE(0x84c, BIT(2)), + + [CLK_BUS_UART0] = GATE(0x90c, BIT(0)), + [CLK_BUS_UART1] = GATE(0x90c, BIT(1)), + [CLK_BUS_UART2] = GATE(0x90c, BIT(2)), + [CLK_BUS_UART3] = GATE(0x90c, BIT(3)), + [CLK_BUS_UART4] = GATE(0x90c, BIT(4)), + [CLK_BUS_UART5] = GATE(0x90c, BIT(5)), + + [CLK_SPI0] = GATE(0x940, BIT(31)), + [CLK_SPI1] = GATE(0x944, BIT(31)), + + [CLK_BUS_SPI0] = GATE(0x96c, BIT(0)), + [CLK_BUS_SPI1] = GATE(0x96c, BIT(1)), + + [CLK_BUS_EMAC0] = GATE(0x97c, BIT(0)), + [CLK_BUS_EMAC1] = GATE(0x97c, BIT(1)), + + [CLK_USB_PHY0] = GATE(0xa70, BIT(29)), + [CLK_USB_OHCI0] = GATE(0xa70, BIT(31)), + + [CLK_USB_PHY1] = GATE(0xa74, BIT(29)), + [CLK_USB_OHCI1] = GATE(0xa74, BIT(31)), + + [CLK_USB_PHY2] = GATE(0xa78, BIT(29)), + [CLK_USB_OHCI2] = GATE(0xa78, BIT(31)), + + [CLK_USB_PHY3] = GATE(0xa7c, BIT(29)), + [CLK_USB_OHCI3] = GATE(0xa7c, BIT(31)), + + [CLK_BUS_OHCI0] = GATE(0xa8c, BIT(0)), + [CLK_BUS_OHCI1] = GATE(0xa8c, BIT(1)), + [CLK_BUS_OHCI2] = GATE(0xa8c, BIT(2)), + [CLK_BUS_OHCI3] = GATE(0xa8c, BIT(3)), + [CLK_BUS_EHCI0] = GATE(0xa8c, BIT(4)), + [CLK_BUS_EHCI1] = GATE(0xa8c, BIT(5)), + [CLK_BUS_EHCI2] = GATE(0xa8c, BIT(6)), + [CLK_BUS_EHCI3] = GATE(0xa8c, BIT(7)), + [CLK_BUS_OTG] = GATE(0xa8c, BIT(8)), +}; + +static struct ccu_reset h616_resets[] = { + [RST_BUS_MMC0] = RESET(0x84c, BIT(16)), + [RST_BUS_MMC1] = RESET(0x84c, BIT(17)), + [RST_BUS_MMC2] = RESET(0x84c, BIT(18)), + + [RST_BUS_UART0] = RESET(0x90c, BIT(16)), + [RST_BUS_UART1] = RESET(0x90c, BIT(17)), + [RST_BUS_UART2] = RESET(0x90c, BIT(18)), + [RST_BUS_UART3] = RESET(0x90c, BIT(19)), + [RST_BUS_UART4] = RESET(0x90c, BIT(20)), + [RST_BUS_UART5] = RESET(0x90c, BIT(21)), + + [RST_BUS_SPI0] = RESET(0x96c, BIT(16)), + [RST_BUS_SPI1] = RESET(0x96c, BIT(17)), + + [RST_BUS_EMAC0] = RESET(0x97c, BIT(16)), + [RST_BUS_EMAC1] = RESET(0x97c, BIT(17)), + + [RST_USB_PHY0] = RESET(0xa70, BIT(30)), + + [RST_USB_PHY1] = RESET(0xa74, BIT(30)), + + [RST_USB_PHY2] = RESET(0xa78, BIT(30)), + + [RST_USB_PHY3] = RESET(0xa7c, BIT(30)), + + [RST_BUS_OHCI0] = RESET(0xa8c, BIT(16)), + [RST_BUS_OHCI1] = RESET(0xa8c, BIT(17)), + [RST_BUS_OHCI2] = RESET(0xa8c, BIT(18)), + [RST_BUS_OHCI3] = RESET(0xa8c, BIT(19)), + [RST_BUS_EHCI0] = RESET(0xa8c, BIT(20)), + [RST_BUS_EH
[linux-sunxi] [PATCH v2 19/21] sunxi: gpio: introduce compatible for H616
H616 pinctrl is no different configuration wise than others, so just add compatible for it. Reviewed-by: Andre Przywara Signed-off-by: Jernej Skrabec --- drivers/gpio/sunxi_gpio.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c index 02c3471b5684..1985ee5d2fc9 100644 --- a/drivers/gpio/sunxi_gpio.c +++ b/drivers/gpio/sunxi_gpio.c @@ -356,6 +356,7 @@ static const struct udevice_id sunxi_gpio_ids[] = { ID("allwinner,sun9i-a80-pinctrl", a_all), ID("allwinner,sun50i-a64-pinctrl", a_all), ID("allwinner,sun50i-h6-pinctrl", a_all), + ID("allwinner,sun50i-h616-pinctrl", a_all), ID("allwinner,sun6i-a31-r-pinctrl", l_2), ID("allwinner,sun8i-a23-r-pinctrl", l_1), ID("allwinner,sun8i-a83t-r-pinctrl",l_1), -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210111201153.1800440-20-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2 18/21] arm: sunxi: add initial H616 DTSI and headers
This commit introduces H616 DTSI file and dt-bindings headers needed for device tree files. Files are taken from initial Linux H616 support submission with minor change - emac0 fallback has H6 compatible instead of A64, otherwise network doesn't work. H616 DTSI is not merged upstream yet. Signed-off-by: Jernej Skrabec --- arch/arm/dts/sun50i-h616.dtsi | 716 include/dt-bindings/clock/sun50i-h616-ccu.h | 115 include/dt-bindings/reset/sun50i-h616-ccu.h | 70 ++ 3 files changed, 901 insertions(+) create mode 100644 arch/arm/dts/sun50i-h616.dtsi create mode 100644 include/dt-bindings/clock/sun50i-h616-ccu.h create mode 100644 include/dt-bindings/reset/sun50i-h616-ccu.h diff --git a/arch/arm/dts/sun50i-h616.dtsi b/arch/arm/dts/sun50i-h616.dtsi new file mode 100644 index ..d416e9a3d3e6 --- /dev/null +++ b/arch/arm/dts/sun50i-h616.dtsi @@ -0,0 +1,716 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +// Copyright (C) 2020 Arm Ltd. +// based on the H6 dtsi, which is: +// Copyright (C) 2017 Icenowy Zheng + +#include +#include +#include +#include +#include + +/ { + interrupt-parent = <>; + #address-cells = <2>; + #size-cells = <2>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + compatible = "arm,cortex-a53"; + device_type = "cpu"; + reg = <0>; + enable-method = "psci"; + clocks = < CLK_CPUX>; + }; + + cpu1: cpu@1 { + compatible = "arm,cortex-a53"; + device_type = "cpu"; + reg = <1>; + enable-method = "psci"; + clocks = < CLK_CPUX>; + }; + + cpu2: cpu@2 { + compatible = "arm,cortex-a53"; + device_type = "cpu"; + reg = <2>; + enable-method = "psci"; + clocks = < CLK_CPUX>; + }; + + cpu3: cpu@3 { + compatible = "arm,cortex-a53"; + device_type = "cpu"; + reg = <3>; + enable-method = "psci"; + clocks = < CLK_CPUX>; + }; + }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + /* 512KiB reserved for ARM Trusted Firmware (BL31) */ + secmon_reserved: secmon@4000 { + reg = <0x0 0x4000 0x0 0x8>; + no-map; + }; + }; + + osc24M: osc24M_clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <2400>; + clock-output-names = "osc24M"; + }; + + pmu { + compatible = "arm,cortex-a53-pmu"; + interrupts = , +, +, +; + interrupt-affinity = <>, <>, <>, <>; + }; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; + + timer { + compatible = "arm,armv8-timer"; + arm,no-tick-in-suspend; + interrupts = , +, +, +; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x0 0x0 0x4000>; + + syscon: syscon@300 { + compatible = "allwinner,sun50i-h616-system-control"; + reg = <0x0300 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + sram_c: sram@28000 { + compatible = "mmio-sram"; + reg = <0x00028000 0x3>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x00028000 0x3>; + }; + }; + + ccu: clock@3001000 { + compatible = "
[linux-sunxi] [PATCH v2 17/21] net: sun8i-emac: Determine pinmux based on SoC, not EMAC type
From: Andre Przywara --- drivers/net/sun8i_emac.c | 28 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c index e0bf19e34c17..4867a8425404 100644 --- a/drivers/net/sun8i_emac.c +++ b/drivers/net/sun8i_emac.c @@ -85,7 +85,9 @@ /* IO mux settings */ #define SUN8I_IOMUX_H3 2 -#define SUN8I_IOMUX_R405 +#define SUN8I_IOMUX_R405 +#define SUN8I_IOMUX_H6 5 +#define SUN8I_IOMUX_H616 2 #define SUN8I_IOMUX4 /* H3/A64 EMAC Register's offset */ @@ -514,10 +516,10 @@ static int sun8i_emac_eth_start(struct udevice *dev) static int parse_phy_pins(struct udevice *dev) { - struct emac_eth_dev *priv = dev_get_priv(dev); int offset; const char *pin_name; int drive, pull = SUN4I_PINCTRL_NO_PULL, i; + u32 iomux; offset = fdtdec_lookup_phandle(gd->fdt_blob, dev_of_offset(dev), "pinctrl-0"); @@ -544,6 +546,21 @@ static int parse_phy_pins(struct udevice *dev) else if (fdt_get_property(gd->fdt_blob, offset, "bias-pull-down", NULL)) pull = SUN4I_PINCTRL_PULL_DOWN; + /* +* The GPIO pinmux value is an integration choice, so depends on the +* SoC, not the EMAC variant. +*/ + if (IS_ENABLED(CONFIG_MACH_SUN8I_H3)) + iomux = SUN8I_IOMUX_H3; + else if (IS_ENABLED(CONFIG_MACH_SUN8I_R40)) + iomux = SUN8I_IOMUX_R40; + else if (IS_ENABLED(CONFIG_MACH_SUN50I_H6)) + iomux = SUN8I_IOMUX_H6; + else if (IS_ENABLED(CONFIG_MACH_SUN50I_H616)) + iomux = SUN8I_IOMUX_H616; + else + iomux = SUN8I_IOMUX; + for (i = 0; ; i++) { int pin; @@ -556,12 +573,7 @@ static int parse_phy_pins(struct udevice *dev) if (pin < 0) continue; - if (priv->variant == H3_EMAC) - sunxi_gpio_set_cfgpin(pin, SUN8I_IOMUX_H3); - else if (priv->variant == R40_GMAC || priv->variant == H6_EMAC) - sunxi_gpio_set_cfgpin(pin, SUN8I_IOMUX_R40); - else - sunxi_gpio_set_cfgpin(pin, SUN8I_IOMUX); + sunxi_gpio_set_cfgpin(pin, iomux); if (drive != ~0) sunxi_gpio_set_drv(pin, drive); -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210111201153.1800440-18-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2 16/21] sunxi: Add H616 FEL support
H616 uses different address for reset. Add it. Signed-off-by: Jernej Skrabec --- arch/arm/cpu/armv8/fel_utils.S | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/arm/cpu/armv8/fel_utils.S b/arch/arm/cpu/armv8/fel_utils.S index 9510dcd9e4c1..2dbd4b365221 100644 --- a/arch/arm/cpu/armv8/fel_utils.S +++ b/arch/arm/cpu/armv8/fel_utils.S @@ -40,7 +40,10 @@ ENTRY(return_to_fel) str w2, [x1] ldr x0, =0xfa50392f // CPU hotplug magic -#ifdef CONFIG_MACH_SUN50I_H6 +#ifdef CONFIG_MACH_SUN50I_H616 + ldr x2, =(SUNXI_RTC_BASE + 0x5c0) + str w0, [x2], #0x4 +#elif CONFIG_MACH_SUN50I_H6 ldr x2, =(SUNXI_RTC_BASE + 0x1b8) // BOOT_CPU_HP_FLAG_REG str w0, [x2], #0x4 #else -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210111201153.1800440-17-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2 15/21] mmc: sunxi: Add H616 clock offset
H616 mmc clock is on same address as H6. Signed-off-by: Jernej Skrabec --- drivers/mmc/sunxi_mmc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index d632b2332ca3..8458d154afd8 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -601,7 +601,8 @@ static unsigned get_mclk_offset(void) if (IS_ENABLED(CONFIG_MACH_SUN9I_A80)) return 0x410; - if (IS_ENABLED(CONFIG_MACH_SUN50I_H6)) + if (IS_ENABLED(CONFIG_MACH_SUN50I_H6) || + IS_ENABLED(CONFIG_MACH_SUN50I_H616)) return 0x830; return 0x88; -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210111201153.1800440-16-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2 14/21] sunxi: Add support for H616 SoC
H616 is very similar to H6 so most of the infrastructure can be reused. However, two big differences are that it doesn't have functional SRAM A2 which is usually used for TF-A and it doesn't have ARISC co-processor. It also needs bigger SPL size - 48 KiB. Signed-off-by: Jernej Skrabec --- arch/arm/dts/sunxi-u-boot.dtsi | 8 arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h | 7 +++ arch/arm/mach-sunxi/Kconfig | 11 ++- arch/arm/mach-sunxi/clock_sun50i_h6.c | 2 +- arch/arm/mach-sunxi/cpu_info.c | 2 ++ drivers/power/Kconfig | 1 + include/configs/sunxi-common.h | 7 +++ 7 files changed, 36 insertions(+), 2 deletions(-) diff --git a/arch/arm/dts/sunxi-u-boot.dtsi b/arch/arm/dts/sunxi-u-boot.dtsi index c77cf7cacf0c..abe629c55e57 100644 --- a/arch/arm/dts/sunxi-u-boot.dtsi +++ b/arch/arm/dts/sunxi-u-boot.dtsi @@ -3,6 +3,8 @@ #ifdef CONFIG_MACH_SUN50I_H6 #define BL31_ADDR 0x104000 #define SCP_ADDR 0x114000 +#elif defined(CONFIG_MACH_SUN50I_H616) +#define BL31_ADDR 0x40004000 #else #define BL31_ADDR 0x44000 #define SCP_ADDR 0x5 @@ -61,6 +63,7 @@ }; }; +#ifndef CONFIG_MACH_SUN50I_H616 scp { description = "SCP firmware"; type = "firmware"; @@ -73,6 +76,7 @@ missing-msg = "scp-sunxi"; }; }; +#endif @fdt-SEQ { description = "NAME"; @@ -87,7 +91,11 @@ @config-SEQ { description = "NAME"; firmware = "atf"; +#ifdef CONFIG_MACH_SUN50I_H616 + loadables = "uboot"; +#else loadables = "scp", "uboot"; +#endif fdt = "fdt-SEQ"; }; }; diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h b/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h index 6392cb07b472..d9cf8ae04288 100644 --- a/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h +++ b/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h @@ -28,13 +28,20 @@ #define SUNXI_GIC400_BASE 0x0302 #define SUNXI_IOMMU_BASE 0x030F +#ifdef CONFIG_MACH_SUN50I_H6 #define SUNXI_DRAM_COM_BASE0x04002000 #define SUNXI_DRAM_CTL0_BASE 0x04003000 #define SUNXI_DRAM_PHY0_BASE 0x04005000 +#endif #define SUNXI_NFC_BASE 0x04011000 #define SUNXI_MMC0_BASE0x0402 #define SUNXI_MMC1_BASE0x04021000 #define SUNXI_MMC2_BASE0x04022000 +#ifdef CONFIG_MACH_SUN50I_H616 +#define SUNXI_DRAM_COM_BASE0x047FA000 +#define SUNXI_DRAM_CTL0_BASE 0x047FB000 +#define SUNXI_DRAM_PHY0_BASE 0x0480 +#endif #define SUNXI_UART0_BASE 0x0500 #define SUNXI_UART1_BASE 0x05000400 diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index a8571d180259..1415355750c4 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig @@ -190,9 +190,10 @@ config MACH_SUNXI_H3_H5 select SUPPORT_SPL # TODO: try out A80's 8GiB DRAM space +# TODO: H616 supports 4 GiB DRAM space config SUNXI_DRAM_MAX_SIZE hex - default 0xC000 if MACH_SUN50I || MACH_SUN50I_H5 || MACH_SUN50I_H6 + default 0xC000 if MACH_SUN50I || MACH_SUN50I_H5 || MACH_SUN50I_H6 || MACH_SUN50I_H616 default 0x8000 choice @@ -355,6 +356,12 @@ config MACH_SUN50I_H6 select DRAM_SUN50I_H6 select SUN50I_GEN_H6 +config MACH_SUN50I_H616 + bool "sun50i (Allwinner H616)" + select ARM64 + select DRAM_SUN50I_H616 + select SUN50I_GEN_H6 + endchoice # The sun8i SoCs share a lot, this helps to avoid a lot of "if A23 || A33" @@ -591,6 +598,7 @@ config SYS_CLK_FREQ default 100800 if MACH_SUN8I default 100800 if MACH_SUN9I default 88800 if MACH_SUN50I_H6 + default 100800 if MACH_SUN50I_H616 config SYS_CONFIG_NAME default "sun4i" if MACH_SUN4I @@ -601,6 +609,7 @@ config SYS_CONFIG_NAME default "sun9i" if MACH_SUN9I default "sun50i" if MACH_SUN50I default "sun50i" if MACH_SUN50I_H6 + default "sun50i" if MACH_SUN50I_H616 config SYS_BOARD default "sunxi" d
[linux-sunxi] [PATCH v2 13/21] net: sun8i-emac: Always clear syscon EPHY register
From: Andre Przywara At the moment we only consider the EPHY register for those SoCs were we actually have an internal PHY to configure. However even other SoCs have this register, an expect a bit to be cleared for proper operation with an external PHY. Rework sun8i_emac_set_syscon_ephy() to be called regardless of the EMAC model, and clear the H3_EPHY_SELECT bit if no internal PHY is used. This helps with the upcoming H616 support, were we need to consider two EMACs. Signed-off-by: Andre Przywara --- drivers/net/sun8i_emac.c | 31 +-- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c index 4524604126c9..e0bf19e34c17 100644 --- a/drivers/net/sun8i_emac.c +++ b/drivers/net/sun8i_emac.c @@ -297,30 +297,29 @@ static void sun8i_adjust_link(struct emac_eth_dev *priv, writel(v, priv->mac_reg + EMAC_CTL0); } -static int sun8i_emac_set_syscon_ephy(struct emac_eth_dev *priv, u32 *reg) +static u32 sun8i_emac_set_syscon_ephy(struct emac_eth_dev *priv, u32 reg) { if (priv->use_internal_phy) { /* H3 based SoC's that has an Internal 100MBit PHY * needs to be configured and powered up before use */ - *reg &= ~H3_EPHY_DEFAULT_MASK; - *reg |= H3_EPHY_DEFAULT_VALUE; - *reg |= priv->phyaddr << H3_EPHY_ADDR_SHIFT; - *reg &= ~H3_EPHY_SHUTDOWN; - *reg |= H3_EPHY_SELECT; - } else - /* This is to select External Gigabit PHY on -* the boards with H3 SoC. - */ - *reg &= ~H3_EPHY_SELECT; + reg &= ~H3_EPHY_DEFAULT_MASK; + reg |= H3_EPHY_DEFAULT_VALUE; + reg |= priv->phyaddr << H3_EPHY_ADDR_SHIFT; + reg &= ~H3_EPHY_SHUTDOWN; + return reg | H3_EPHY_SELECT; + } - return 0; + /* This is to select External Gigabit PHY on those boards with +* an internal PHY. Does not hurt on other SoCs. Linux does +* it as well. +*/ + return reg & ~H3_EPHY_SELECT; } static int sun8i_emac_set_syscon(struct sun8i_eth_pdata *pdata, struct emac_eth_dev *priv) { - int ret; u32 reg; if (priv->variant == R40_GMAC) { @@ -336,11 +335,7 @@ static int sun8i_emac_set_syscon(struct sun8i_eth_pdata *pdata, reg = readl(priv->sysctl_reg + 0x30); - if (priv->variant == H3_EMAC || priv->variant == H6_EMAC) { - ret = sun8i_emac_set_syscon_ephy(priv, ); - if (ret) - return ret; - } + reg = sun8i_emac_set_syscon_ephy(priv, reg); reg &= ~(SC_ETCS_MASK | SC_EPIT); if (priv->variant == H3_EMAC || -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210111201153.1800440-14-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2 11/21] sunxi: Add H616 DRAM support
Allwinner H616 supports many types of DRAM. Most notably it supports LPDDR4. However, all commercially available boards at this time use only DDR3, so this commit adds only DDR3 support. Controller and MBUS are very similar to H6 but PHY is completely unknown. Signed-off-by: Jernej Skrabec --- arch/arm/include/asm/arch-sunxi/dram.h|2 + .../include/asm/arch-sunxi/dram_sun50i_h616.h | 159 +++ arch/arm/mach-sunxi/Kconfig | 43 + arch/arm/mach-sunxi/Makefile |2 + arch/arm/mach-sunxi/dram_sun50i_h616.c| 1023 + arch/arm/mach-sunxi/dram_timings/Makefile |2 + .../mach-sunxi/dram_timings/h616_ddr3_1333.c | 94 ++ 7 files changed, 1325 insertions(+) create mode 100644 arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h create mode 100644 arch/arm/mach-sunxi/dram_sun50i_h616.c create mode 100644 arch/arm/mach-sunxi/dram_timings/h616_ddr3_1333.c diff --git a/arch/arm/include/asm/arch-sunxi/dram.h b/arch/arm/include/asm/arch-sunxi/dram.h index 8002b7efdc19..c3b3e1f512b2 100644 --- a/arch/arm/include/asm/arch-sunxi/dram.h +++ b/arch/arm/include/asm/arch-sunxi/dram.h @@ -29,6 +29,8 @@ #include #elif defined(CONFIG_MACH_SUN50I_H6) #include +#elif defined(CONFIG_MACH_SUN50I_H616) +#include #else #include #endif diff --git a/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h b/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h new file mode 100644 index ..134679d55205 --- /dev/null +++ b/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h @@ -0,0 +1,159 @@ +/* + * H616 dram controller register and constant defines + * + * (C) Copyright 2020 Jernej Skrabec + * + * Based on H6 one, which is: + * (C) Copyright 2017 Icenowy Zheng + * + * SPDX-License-Identifier:GPL-2.0+ + */ + +#ifndef _SUNXI_DRAM_SUN50I_H616_H +#define _SUNXI_DRAM_SUN50I_H616_H + +#include +#ifndef __ASSEMBLY__ +#include +#endif + +enum sunxi_dram_type { + SUNXI_DRAM_TYPE_DDR3 = 3, + SUNXI_DRAM_TYPE_DDR4, + SUNXI_DRAM_TYPE_LPDDR3 = 7, + SUNXI_DRAM_TYPE_LPDDR4 +}; + +/* MBUS part is largely the same as in H6, except for one special register */ +struct sunxi_mctl_com_reg { + u32 cr; /* 0x000 control register */ + u8 reserved_0x004[4]; /* 0x004 */ + u32 unk_0x008; /* 0x008 */ + u32 tmr;/* 0x00c timer register */ + u8 reserved_0x010[4]; /* 0x010 */ + u32 unk_0x014; /* 0x014 */ + u8 reserved_0x018[8]; /* 0x018 */ + u32 maer0; /* 0x020 master enable register 0 */ + u32 maer1; /* 0x024 master enable register 1 */ + u32 maer2; /* 0x028 master enable register 2 */ + u8 reserved_0x02c[468]; /* 0x02c */ + u32 bwcr; /* 0x200 bandwidth control register */ + u8 reserved_0x204[12]; /* 0x204 */ + /* +* The last master configured by BSP libdram is at 0x49x, so the +* size of this struct array is set to 41 (0x29) now. +*/ + struct { + u32 cfg0; /* 0x0 */ + u32 cfg1; /* 0x4 */ + u8 reserved_0x8[8]; /* 0x8 */ + } master[41]; /* 0x210 + index * 0x10 */ + u8 reserved_0x4a0[96]; /* 0x4a0 */ + u32 unk_0x500; /* 0x500 */ +}; +check_member(sunxi_mctl_com_reg, unk_0x500, 0x500); + +/* + * Controller registers seems to be the same or at least very similar + * to those in H6. + */ +struct sunxi_mctl_ctl_reg { + u32 mstr; /* 0x000 */ + u32 statr; /* 0x004 unused */ + u32 mstr1; /* 0x008 unused */ + u32 clken; /* 0x00c */ + u32 mrctrl0;/* 0x010 unused */ + u32 mrctrl1;/* 0x014 unused */ + u32 mrstatr;/* 0x018 unused */ + u32 mrctrl2;/* 0x01c unused */ + u32 derateen; /* 0x020 unused */ + u32 derateint; /* 0x024 unused */ + u8 reserved_0x028[8]; /* 0x028 */ + u32 pwrctl; /* 0x030 unused */ + u32 pwrtmg; /* 0x034 unused */ + u32 hwlpctl;/* 0x038 unused */ + u8 reserved_0x03c[20]; /* 0x03c */ + u32 rfshctl0; /* 0x050 unused */ + u32 rfshctl1; /* 0x054 unused */ + u8 reserved_0x058[8]; /* 0x05c */ + u32 rfshctl3; /* 0x060 */ + u32 rfshtmg;/* 0x064 */ + u8 reserved_0x068[104]; /* 0x068 */ + u32 init[8];/* 0x0d0 */ + u32 dimmctl;/* 0x0f0 unused */ + u32 rankctl;/* 0x0f4 */ + u8 reserved_0x0f8[8]; /* 0x0f8 */ + u32 dramtmg[17];/* 0x100 */ + u8 reserved_0x144[60]; /* 0x144 */ + u32 zqctl[3]; /* 0x180 */ + u32 zqstat; /* 0x18c unused */ + u32 dfitmg0;/* 0x190
[linux-sunxi] [PATCH v2 12/21] mmc: sunxi: Refactor mod clock register offset
From: Andre Przywara So far the only difference between the various Allwinner MMC controller we are concerned about is the mod clock register offset. This is actually not directly related to the MMC controller IP, but an integration choice, dependent on the SoC this appears in. To avoid becoming trapped with some compatible fallback strings, let's remove the whole struct sunxi_mmc_variant, and replace this with a SoC based choice, which we can derive from the CONFIG_MACH_SUNx_y symbols. This will later simplify H616 support. Signed-off-by: Andre Przywara Reviewed-by: Jaehoon Chung --- drivers/mmc/sunxi_mmc.c | 84 +++-- 1 file changed, 23 insertions(+), 61 deletions(-) diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index 3767a39277c1..d632b2332ca3 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -23,12 +23,6 @@ #include #include -#ifdef CONFIG_DM_MMC -struct sunxi_mmc_variant { - u16 mclk_offset; -}; -#endif - struct sunxi_mmc_plat { struct mmc_config cfg; struct mmc mmc; @@ -42,9 +36,6 @@ struct sunxi_mmc_priv { int cd_inverted;/* Inverted Card Detect */ struct sunxi_mmc *reg; struct mmc_config cfg; -#ifdef CONFIG_DM_MMC - const struct sunxi_mmc_variant *variant; -#endif }; #if !CONFIG_IS_ENABLED(DM_MMC) @@ -605,6 +596,17 @@ static const struct dm_mmc_ops sunxi_mmc_ops = { .get_cd = sunxi_mmc_getcd, }; +static unsigned get_mclk_offset(void) +{ + if (IS_ENABLED(CONFIG_MACH_SUN9I_A80)) + return 0x410; + + if (IS_ENABLED(CONFIG_MACH_SUN50I_H6)) + return 0x830; + + return 0x88; +}; + static int sunxi_mmc_probe(struct udevice *dev) { struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); @@ -633,8 +635,6 @@ static int sunxi_mmc_probe(struct udevice *dev) cfg->f_max = 5200; priv->reg = (void *)dev_read_addr(dev); - priv->variant = - (const struct sunxi_mmc_variant *)dev_get_driver_data(dev); /* We don't have a sunxi clock driver so find the clock address here */ ret = dev_read_phandle_with_args(dev, "clocks", "#clock-cells", 0, @@ -644,8 +644,7 @@ static int sunxi_mmc_probe(struct udevice *dev) ccu_reg = (u32 *)ofnode_get_addr(args.node); priv->mmc_no = ((uintptr_t)priv->reg - SUNXI_MMC0_BASE) / 0x1000; - priv->mclkreg = (void *)ccu_reg + - (priv->variant->mclk_offset + (priv->mmc_no * 4)); + priv->mclkreg = (void *)ccu_reg + get_mclk_offset() + priv->mmc_no * 4; ret = clk_get_by_name(dev, "ahb", _clk); if (!ret) @@ -687,55 +686,18 @@ static int sunxi_mmc_bind(struct udevice *dev) return mmc_bind(dev, >mmc, >cfg); } -static const struct sunxi_mmc_variant sun4i_a10_variant = { - .mclk_offset = 0x88, -}; - -static const struct sunxi_mmc_variant sun9i_a80_variant = { - .mclk_offset = 0x410, -}; - -static const struct sunxi_mmc_variant sun50i_h6_variant = { - .mclk_offset = 0x830, -}; - static const struct udevice_id sunxi_mmc_ids[] = { - { - .compatible = "allwinner,sun4i-a10-mmc", - .data = (ulong)_a10_variant, - }, - { - .compatible = "allwinner,sun5i-a13-mmc", - .data = (ulong)_a10_variant, - }, - { - .compatible = "allwinner,sun7i-a20-mmc", - .data = (ulong)_a10_variant, - }, - { - .compatible = "allwinner,sun8i-a83t-emmc", - .data = (ulong)_a10_variant, - }, - { - .compatible = "allwinner,sun9i-a80-mmc", - .data = (ulong)_a80_variant, - }, - { - .compatible = "allwinner,sun50i-a64-mmc", - .data = (ulong)_a10_variant, - }, - { - .compatible = "allwinner,sun50i-a64-emmc", - .data = (ulong)_a10_variant, - }, - { - .compatible = "allwinner,sun50i-h6-mmc", - .data = (ulong)_h6_variant, - }, - { - .compatible = "allwinner,sun50i-h6-emmc", - .data = (ulong)_h6_variant, - }, + { .compatible = "allwinner,sun4i-a10-mmc" }, + { .compatible = "allwinner,sun5i-a13-mmc" }, + { .compatible = "allwinner,sun7i-a20-mmc" }, + { .compatible = "allwinner,sun8i-a83t-emmc" }, + { .compatible = "allwinner,sun9i-a80-mmc" }, + { .compatible = "allwinner,sun50i-a64-mmc" }, + { .compatible = "allwinner,sun50i-a64-emmc" }, + { .compatible = "allwinner,sun50i-h6-mmc" }, + { .compatible = "allwinner,sun50i-h6-emmc" }, + { .compatible = "allwinner,sun50i-a100-mmc" }, + { .compatible = "allwinner,sun50i-a100-emmc" }, { /* sentinel */ } }; -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email
[linux-sunxi] [PATCH v2 10/21] sunxi: add support for R_I2C on H616
This port is needed for communication with PMIC. SPL uses it to set DRAM voltage on H616 boards. Reviewed-by: Samuel Holland Signed-off-by: Jernej Skrabec --- arch/arm/include/asm/arch-sunxi/gpio.h | 1 + board/sunxi/board.c| 4 2 files changed, 5 insertions(+) diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h index cdb7dbd5b8e5..de77bf638e21 100644 --- a/arch/arm/include/asm/arch-sunxi/gpio.h +++ b/arch/arm/include/asm/arch-sunxi/gpio.h @@ -220,6 +220,7 @@ enum sunxi_gpio_number { #define SUN8I_A23_GPL_R_TWI3 #define SUN8I_GPL_R_UART 2 #define SUN50I_GPL_R_TWI 2 +#define SUN50I_H616_GPL_R_TWI 3 #define SUN9I_GPN_R_RSB3 diff --git a/board/sunxi/board.c b/board/sunxi/board.c index 40fdd5da0477..14d31c719ece 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -196,6 +196,10 @@ void i2c_init_board(void) clock_twi_onoff(5, 1); sunxi_gpio_set_cfgpin(SUNXI_GPL(8), SUN50I_GPL_R_TWI); sunxi_gpio_set_cfgpin(SUNXI_GPL(9), SUN50I_GPL_R_TWI); +#elif CONFIG_MACH_SUN50I_H616 + clock_twi_onoff(5, 1); + sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN50I_H616_GPL_R_TWI); + sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN50I_H616_GPL_R_TWI); #else clock_twi_onoff(5, 1); sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN8I_H3_GPL_R_TWI); -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210111201153.1800440-11-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2 09/21] sunxi: add support for H616 uart0
This port is used for debug terminal on all known H616 boards. Reviewed-by: Samuel Holland Signed-off-by: Jernej Skrabec --- arch/arm/include/asm/arch-sunxi/gpio.h | 1 + arch/arm/mach-sunxi/board.c| 4 2 files changed, 5 insertions(+) diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h index f817d328f432..cdb7dbd5b8e5 100644 --- a/arch/arm/include/asm/arch-sunxi/gpio.h +++ b/arch/arm/include/asm/arch-sunxi/gpio.h @@ -206,6 +206,7 @@ enum sunxi_gpio_number { #define SUN6I_GPH_UART02 #define SUN9I_GPH_UART02 #define SUN50I_H6_GPH_UART02 +#define SUN50I_H616_GPH_UART0 2 #define SUNXI_GPI_SDC3 2 #define SUN7I_GPI_TWI3 3 diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c index 8ed9a87c1195..a883edd24107 100644 --- a/arch/arm/mach-sunxi/board.c +++ b/arch/arm/mach-sunxi/board.c @@ -116,6 +116,10 @@ static int gpio_init(void) sunxi_gpio_set_cfgpin(SUNXI_GPH(0), SUN50I_H6_GPH_UART0); sunxi_gpio_set_cfgpin(SUNXI_GPH(1), SUN50I_H6_GPH_UART0); sunxi_gpio_set_pull(SUNXI_GPH(1), SUNXI_GPIO_PULL_UP); +#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN50I_H616) + sunxi_gpio_set_cfgpin(SUNXI_GPH(0), SUN50I_H616_GPH_UART0); + sunxi_gpio_set_cfgpin(SUNXI_GPH(1), SUN50I_H616_GPH_UART0); + sunxi_gpio_set_pull(SUNXI_GPH(1), SUNXI_GPIO_PULL_UP); #elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN8I_A83T) sunxi_gpio_set_cfgpin(SUNXI_GPB(9), SUN8I_A83T_GPB_UART0); sunxi_gpio_set_cfgpin(SUNXI_GPB(10), SUN8I_A83T_GPB_UART0); -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210111201153.1800440-10-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2 04/21] i2c: mvtwsi: sunxi: update macro
While currently none of the newer Allwinner SoCs currently has I2C support implemented in U-Boot, this will change soon. mvtwsi driver is good as it is for them except one macro. Update it to be ready once I2C support lands for those SoCs. Reviewed-by: Heiko Schocher Reviewed-by: Samuel Holland Signed-off-by: Jernej Skrabec --- drivers/i2c/mvtwsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/mvtwsi.c b/drivers/i2c/mvtwsi.c index 14c594d648ba..36d0d1485277 100644 --- a/drivers/i2c/mvtwsi.c +++ b/drivers/i2c/mvtwsi.c @@ -121,7 +121,7 @@ enum mvtwsi_ctrl_register_fields { * on other platforms, it is a normal r/w bit, which is cleared by writing 0. */ -#ifdef CONFIG_SUNXI_GEN_SUN6I +#if defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6) #defineMVTWSI_CONTROL_CLEAR_IFLG 0x0008 #else #defineMVTWSI_CONTROL_CLEAR_IFLG 0x -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210111201153.1800440-5-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2 08/21] sunxi: introduce support for H616 clocks
H616 has mostly the same clocks as H6 with some small differences. Just reuse H6 clocks for H616 and handle differences with macros. Reviewed-by: Samuel Holland Signed-off-by: Jernej Skrabec --- .../include/asm/arch-sunxi/clock_sun50i_h6.h | 18 +- arch/arm/mach-sunxi/clock_sun50i_h6.c | 8 ++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h b/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h index e83e84ab6cab..62abfc4ef6bd 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h @@ -230,6 +230,7 @@ struct sunxi_ccm_reg { #define CCM_PLL1_CTRL_EN BIT(31) #define CCM_PLL1_LOCK_EN BIT(29) #define CCM_PLL1_LOCK BIT(28) +#define CCM_PLL1_OUT_ENBIT(27) #define CCM_PLL1_CLOCK_TIME_2 (2 << 24) #define CCM_PLL1_CTRL_P(p) ((p) << 16) #define CCM_PLL1_CTRL_N(n) ((n) << 8) @@ -238,6 +239,7 @@ struct sunxi_ccm_reg { #define CCM_PLL5_CTRL_EN BIT(31) #define CCM_PLL5_LOCK_EN BIT(29) #define CCM_PLL5_LOCK BIT(28) +#define CCM_PLL5_OUT_ENBIT(27) #define CCM_PLL5_CTRL_N(n) ((n) << 8) #define CCM_PLL5_CTRL_DIV1(div1) ((div1) << 0) #define CCM_PLL5_CTRL_DIV2(div0) ((div0) << 1) @@ -252,7 +254,6 @@ struct sunxi_ccm_reg { #define CCM_PLL6_CTRL_DIV1_MASK(0x1 << CCM_PLL6_CTRL_DIV1_SHIFT) #define CCM_PLL6_CTRL_DIV2_SHIFT 1 #define CCM_PLL6_CTRL_DIV2_MASK(0x1 << CCM_PLL6_CTRL_DIV2_SHIFT) -#define CCM_PLL6_DEFAULT 0xa0006300 /* cpu_axi bit field*/ #define CCM_CPU_AXI_MUX_MASK (0x3 << 24) @@ -262,6 +263,9 @@ struct sunxi_ccm_reg { #define CCM_CPU_AXI_AXI_MASK 0x3 #define CCM_CPU_AXI_DEFAULT_FACTORS0x301 +#ifdef CONFIG_MACH_SUN50I_H6 +#define CCM_PLL6_DEFAULT 0xa0006300 + /* psi_ahb1_ahb2 bit field */ #define CCM_PSI_AHB1_AHB2_DEFAULT 0x03000102 @@ -270,6 +274,18 @@ struct sunxi_ccm_reg { /* apb1 bit field */ #define CCM_APB1_DEFAULT 0x03000102 +#elif CONFIG_MACH_SUN50I_H616 +#define CCM_PLL6_DEFAULT 0xa8003100 + +/* psi_ahb1_ahb2 bit field */ +#define CCM_PSI_AHB1_AHB2_DEFAULT 0x0302 + +/* ahb3 bit field */ +#define CCM_AHB3_DEFAULT 0x0302 + +/* apb1 bit field */ +#define CCM_APB1_DEFAULT 0x03000102 +#endif /* apb2 bit field */ #define APB2_CLK_SRC_OSC24M(0x0 << 24) diff --git a/arch/arm/mach-sunxi/clock_sun50i_h6.c b/arch/arm/mach-sunxi/clock_sun50i_h6.c index 6bd466915c11..daca02019bab 100644 --- a/arch/arm/mach-sunxi/clock_sun50i_h6.c +++ b/arch/arm/mach-sunxi/clock_sun50i_h6.c @@ -68,6 +68,9 @@ void clock_set_pll1(unsigned int clk) /* clk = 24*n/p, p is ignored if clock is >288MHz */ writel(CCM_PLL1_CTRL_EN | CCM_PLL1_LOCK_EN | CCM_PLL1_CLOCK_TIME_2 | +#ifdef CONFIG_MACH_SUN50I_H616 + CCM_PLL1_OUT_EN | +#endif CCM_PLL1_CTRL_N(clk / 2400), >pll1_cfg); while (!(readl(>pll1_cfg) & CCM_PLL1_LOCK)) {} @@ -83,6 +86,7 @@ unsigned int clock_get_pll6(void) { struct sunxi_ccm_reg *const ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + int m = IS_ENABLED(CONFIG_MACH_SUN50I_H6) 4 : 2; uint32_t rval = readl(>pll6_cfg); int n = ((rval & CCM_PLL6_CTRL_N_MASK) >> CCM_PLL6_CTRL_N_SHIFT); @@ -90,8 +94,8 @@ unsigned int clock_get_pll6(void) CCM_PLL6_CTRL_DIV1_SHIFT) + 1; int div2 = ((rval & CCM_PLL6_CTRL_DIV2_MASK) >> CCM_PLL6_CTRL_DIV2_SHIFT) + 1; - /* The register defines PLL6-4X, not plain PLL6 */ - return 2400 / 4 * n / div1 / div2; + /* The register defines PLL6-2X or PLL6-4X, not plain PLL6 */ + return 2400 / m * n / div1 / div2; } int clock_twi_onoff(int port, int state) -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210111201153.1800440-9-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2 03/21] mmc: sunxi: Replace H6 ifdefs with H6 gen macro
It turns out that several SoCs share same mmc configuration as H6. In order to lower ifdef clutter replace H6 specific macro with common one. Reviewed-by: Andre Przywara Signed-off-by: Jernej Skrabec --- arch/arm/include/asm/arch-sunxi/mmc.h | 2 +- drivers/mmc/sunxi_mmc.c | 12 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/arm/include/asm/arch-sunxi/mmc.h b/arch/arm/include/asm/arch-sunxi/mmc.h index f2deafddd202..340e25b04d2a 100644 --- a/arch/arm/include/asm/arch-sunxi/mmc.h +++ b/arch/arm/include/asm/arch-sunxi/mmc.h @@ -45,7 +45,7 @@ struct sunxi_mmc { u32 chda; /* 0x90 */ u32 cbda; /* 0x94 */ u32 res2[26]; -#if defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_MACH_SUN50I_H6) +#if defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6) u32 res3[17]; u32 samp_dl; u32 res4[46]; diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index 0e03b07ce555..3767a39277c1 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -122,7 +122,7 @@ static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz) if (IS_ENABLED(CONFIG_MACH_SUN8I_A83T) && priv->mmc_no != 2) new_mode = false; -#if defined(CONFIG_MACH_SUN50I) || defined(CONFIG_MACH_SUN50I_H6) +#if defined(CONFIG_MACH_SUN50I) || defined(CONFIG_SUN50I_GEN_H6) calibrate = true; #endif @@ -133,7 +133,7 @@ static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz) #ifdef CONFIG_MACH_SUN9I pll = CCM_MMC_CTRL_PLL_PERIPH0; pll_hz = clock_get_pll4_periph0(); -#elif defined(CONFIG_MACH_SUN50I_H6) +#elif defined(CONFIG_SUN50I_GEN_H6) pll = CCM_MMC_CTRL_PLL6X2; pll_hz = clock_get_pll6() * 2; #else @@ -249,7 +249,7 @@ static int mmc_config_clock(struct sunxi_mmc_priv *priv, struct mmc *mmc) rval &= ~SUNXI_MMC_CLK_DIVIDER_MASK; writel(rval, >reg->clkcr); -#if defined(CONFIG_MACH_SUN50I) || defined(CONFIG_MACH_SUN50I_H6) +#if defined(CONFIG_MACH_SUN50I) || defined(CONFIG_SUN50I_GEN_H6) /* A64 supports calibration of delays on MMC controller and we * have to set delay of zero before starting calibration. * Allwinner BSP driver sets a delay only in the case of @@ -530,7 +530,7 @@ struct mmc *sunxi_mmc_init(int sdc_no) cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; cfg->host_caps = MMC_MODE_4BIT; -#if defined(CONFIG_MACH_SUN50I) || defined(CONFIG_MACH_SUN8I) || defined(CONFIG_MACH_SUN50I_H6) +#if defined(CONFIG_MACH_SUN50I) || defined(CONFIG_MACH_SUN8I) || defined(CONFIG_SUN50I_GEN_H6) if (sdc_no == 2) cfg->host_caps = MMC_MODE_8BIT; #endif @@ -545,7 +545,7 @@ struct mmc *sunxi_mmc_init(int sdc_no) /* config ahb clock */ debug("init mmc %d clock and io\n", sdc_no); -#if !defined(CONFIG_MACH_SUN50I_H6) +#if !defined(CONFIG_SUN50I_GEN_H6) setbits_le32(>ahb_gate0, 1 << AHB_GATE_OFFSET_MMC(sdc_no)); #ifdef CONFIG_SUNXI_GEN_SUN6I @@ -557,7 +557,7 @@ struct mmc *sunxi_mmc_init(int sdc_no) writel(SUNXI_MMC_COMMON_CLK_GATE | SUNXI_MMC_COMMON_RESET, SUNXI_MMC_COMMON_BASE + 4 * sdc_no); #endif -#else /* CONFIG_MACH_SUN50I_H6 */ +#else /* CONFIG_SUN50I_GEN_H6 */ setbits_le32(>sd_gate_reset, 1 << sdc_no); /* unassert reset */ setbits_le32(>sd_gate_reset, 1 << (RESET_SHIFT + sdc_no)); -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210111201153.1800440-4-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2 07/21] sunxi: support loading with SPL > 32KB
From: Andre Przywara H616 supports and needs bigger SPL than 32 KiB, mostly due to big DRAM driver and need for PMIC configuration, which pulls several drivers which are not needed otherwise. spl_mmc_get_uboot_raw_sector() will now compare pre-configured size with that, reported in SPL header. If size in header is bigger, it will use that value instead. In the process of function rework, also add missing function argument. Signed-off-by: Andre Przywara Signed-off-by: Jernej Skrabec --- arch/arm/mach-sunxi/board.c | 16 ++-- common/spl/Kconfig | 3 ++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c index 7a8b303f233c..8ed9a87c1195 100644 --- a/arch/arm/mach-sunxi/board.c +++ b/arch/arm/mach-sunxi/board.c @@ -277,15 +277,27 @@ uint32_t sunxi_get_boot_device(void) } #ifdef CONFIG_SPL_BUILD +static u32 sunxi_get_spl_size(void) +{ + if (!is_boot0_magic(SPL_ADDR + 4)) /* eGON.BT0 */ + return 0; + + return readl(SPL_ADDR + 0x10); +} + /* * The eGON SPL image can be located at 8KB or at 128KB into an SD card or * an eMMC device. The boot source has bit 4 set in the latter case. * By adding 120KB to the normal offset when booting from a "high" location * we can support both cases. */ -unsigned long spl_mmc_get_uboot_raw_sector(struct mmc *mmc) +unsigned long spl_mmc_get_uboot_raw_sector(struct mmc *mmc, + unsigned long raw_sect) { - unsigned long sector = CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR; + unsigned long spl_size = sunxi_get_spl_size(); + unsigned long sector; + + sector = max(raw_sect, spl_size / 512); switch (sunxi_get_boot_source()) { case SUNXI_BOOTED_FROM_MMC0_HIGH: diff --git a/common/spl/Kconfig b/common/spl/Kconfig index bed715774d81..1ef09e4ad22a 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -316,7 +316,7 @@ config SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR config SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR hex "Address on the MMC to load U-Boot from" depends on SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR - default 0x50 if ARCH_SUNXI + default 0x40 if ARCH_SUNXI default 0x75 if ARCH_DAVINCI default 0x8a if ARCH_MX6 || ARCH_MX7 default 0x100 if ARCH_UNIPHIER @@ -333,6 +333,7 @@ config SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR config SYS_MMCSD_RAW_MODE_U_BOOT_DATA_PART_OFFSET hex "U-Boot main hardware partition image offset" depends on SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR + default 0x10 if ARCH_SUNXI default 0x0 help On some platforms SPL location depends on hardware partition. The ROM -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210111201153.1800440-8-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2 02/21] sunxi: Introduce common symbol for H6 like SoCs
It turns out that there are at least 2 other SoCs which have basically the same memory map, similar clocks and other features as H6. It's very likely that we'll see more such SoCs in the future. In order to ease porting to new SoCs and lower ifdef clutter, introduce common symbol for them. Signed-off-by: Jernej Skrabec --- arch/arm/include/asm/arch-sunxi/boot0.h | 2 +- arch/arm/include/asm/arch-sunxi/clock.h | 2 +- arch/arm/include/asm/arch-sunxi/cpu.h | 2 +- arch/arm/include/asm/arch-sunxi/timer.h | 2 +- arch/arm/mach-sunxi/Kconfig | 19 +-- arch/arm/mach-sunxi/Makefile| 2 +- arch/arm/mach-sunxi/board.c | 4 ++-- arch/arm/mach-sunxi/rmr_switch.S| 2 +- common/spl/Kconfig | 4 ++-- include/configs/sun50i.h| 2 +- 10 files changed, 24 insertions(+), 17 deletions(-) diff --git a/arch/arm/include/asm/arch-sunxi/boot0.h b/arch/arm/include/asm/arch-sunxi/boot0.h index 46d0f0666c2b..e8e8e38f0556 100644 --- a/arch/arm/include/asm/arch-sunxi/boot0.h +++ b/arch/arm/include/asm/arch-sunxi/boot0.h @@ -39,7 +39,7 @@ .word 0xf57ff06f // isb sy .word 0xe320f003 // wfi .word 0xeafd // b @wfi -#ifndef CONFIG_MACH_SUN50I_H6 +#ifndef CONFIG_SUN50I_GEN_H6 .word 0x017000a0 // writeable RVBAR mapping address #else .word 0x09010040 // writeable RVBAR mapping address diff --git a/arch/arm/include/asm/arch-sunxi/clock.h b/arch/arm/include/asm/arch-sunxi/clock.h index 5994130e6b54..cbbe5c7a1e68 100644 --- a/arch/arm/include/asm/arch-sunxi/clock.h +++ b/arch/arm/include/asm/arch-sunxi/clock.h @@ -16,7 +16,7 @@ /* clock control module regs definition */ #if defined(CONFIG_MACH_SUN8I_A83T) #include -#elif defined(CONFIG_MACH_SUN50I_H6) +#elif defined(CONFIG_SUN50I_GEN_H6) #include #elif defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN8I) || \ defined(CONFIG_MACH_SUN50I) diff --git a/arch/arm/include/asm/arch-sunxi/cpu.h b/arch/arm/include/asm/arch-sunxi/cpu.h index 8b57d24e2f0c..b08f2023748c 100644 --- a/arch/arm/include/asm/arch-sunxi/cpu.h +++ b/arch/arm/include/asm/arch-sunxi/cpu.h @@ -8,7 +8,7 @@ #if defined(CONFIG_MACH_SUN9I) #include -#elif defined(CONFIG_MACH_SUN50I_H6) +#elif defined(CONFIG_SUN50I_GEN_H6) #include #else #include diff --git a/arch/arm/include/asm/arch-sunxi/timer.h b/arch/arm/include/asm/arch-sunxi/timer.h index 6f138d04b806..bb5626d893bb 100644 --- a/arch/arm/include/asm/arch-sunxi/timer.h +++ b/arch/arm/include/asm/arch-sunxi/timer.h @@ -76,7 +76,7 @@ struct sunxi_timer_reg { struct sunxi_tgp tgp[4]; u8 res5[8]; u32 cpu_cfg; -#elif defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_MACH_SUN50I_H6) +#elif defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6) u8 res3[16]; struct sunxi_wdog wdog[5]; /* We have 5 watchdogs */ #endif diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index 49ef217f08c0..bd82c0ef3ee4 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig @@ -82,7 +82,7 @@ config SUN8I_RSB config SUNXI_SRAM_ADDRESS hex default 0x1 if MACH_SUN9I || MACH_SUN50I || MACH_SUN50I_H5 - default 0x2 if MACH_SUN50I_H6 + default 0x2 if SUN50I_GEN_H6 default 0x0 ---help--- Older Allwinner SoCs have their mask boot ROM mapped just below 4GB, @@ -108,6 +108,15 @@ config SUNXI_GEN_SUN6I separate ahb reset control registers, custom pmic bus, new style watchdog, etc. +config SUN50I_GEN_H6 + bool + select FIT + select SPL_LOAD_FIT + select SUPPORT_SPL + ---help--- + Select this for sunxi SoCs which have H6 like peripherals, clocks + and memory map. + config SUNXI_DRAM_DW bool ---help--- @@ -302,11 +311,9 @@ config MACH_SUN50I_H5 config MACH_SUN50I_H6 bool "sun50i (Allwinner H6)" select ARM64 - select SUPPORT_SPL - select FIT select PHY_SUN4I_USB - select SPL_LOAD_FIT select DRAM_SUN50I_H6 + select SUN50I_GEN_H6 endchoice @@ -756,7 +763,7 @@ config VIDEO_SUNXI depends on !MACH_SUN8I_V3S depends on !MACH_SUN9I depends on !MACH_SUN50I - depends on !MACH_SUN50I_H6 + depends on !SUN50I_GEN_H6 select VIDEO imply VIDEO_DT_SIMPLEFB default y @@ -989,7 +996,7 @@ config SPL_STACK_R_ADDR default 0x4fe0 if MACH_SUN8I default 0x2fe0 if MACH_SUN9I default 0x4fe0 if MACH_SUN50I - default 0x4fe0 if MACH_SUN50I_H6 + default 0x4fe0 if SUN50I_GEN_H6 config SPL_SPI_SUNXI bool "Support for SPI Flash on Allwinner SoCs in SPL" diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile index d129f334798b..b8aca43d6630 100644 --- a/arch/arm/mach-sunxi
[linux-sunxi] [PATCH v2 01/21] sunxi: Add support for AXP305 PMIC
This PMIC can be found on H616 boards and it's very similar to AXP805 and AXP806. Reviewed-by: Andre Przywara Reviewed-by: Jaehoon Chung Signed-off-by: Jernej Skrabec --- arch/arm/mach-sunxi/pmic_bus.c | 6 +++ board/sunxi/board.c| 10 ++-- drivers/power/Kconfig | 13 +- drivers/power/Makefile | 1 + drivers/power/axp305.c | 83 ++ include/axp305.h | 17 +++ include/axp_pmic.h | 3 ++ 7 files changed, 129 insertions(+), 4 deletions(-) create mode 100644 drivers/power/axp305.c create mode 100644 include/axp305.h diff --git a/arch/arm/mach-sunxi/pmic_bus.c b/arch/arm/mach-sunxi/pmic_bus.c index dea42de833f1..0394ce856448 100644 --- a/arch/arm/mach-sunxi/pmic_bus.c +++ b/arch/arm/mach-sunxi/pmic_bus.c @@ -18,6 +18,8 @@ #define AXP209_I2C_ADDR0x34 +#define AXP305_I2C_ADDR0x36 + #define AXP221_CHIP_ADDR 0x68 #define AXP221_CTRL_ADDR 0x3e #define AXP221_INIT_DATA 0x3e @@ -64,6 +66,8 @@ int pmic_bus_read(u8 reg, u8 *data) return i2c_read(AXP152_I2C_ADDR, reg, 1, data, 1); #elif defined CONFIG_AXP209_POWER return i2c_read(AXP209_I2C_ADDR, reg, 1, data, 1); +#elif defined CONFIG_AXP305_POWER + return i2c_read(AXP305_I2C_ADDR, reg, 1, data, 1); #elif defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || defined CONFIG_AXP818_POWER # ifdef CONFIG_MACH_SUN6I return p2wi_read(reg, data); @@ -81,6 +85,8 @@ int pmic_bus_write(u8 reg, u8 data) return i2c_write(AXP152_I2C_ADDR, reg, 1, , 1); #elif defined CONFIG_AXP209_POWER return i2c_write(AXP209_I2C_ADDR, reg, 1, , 1); +#elif defined CONFIG_AXP305_POWER + return i2c_write(AXP305_I2C_ADDR, reg, 1, , 1); #elif defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || defined CONFIG_AXP818_POWER # ifdef CONFIG_MACH_SUN6I return p2wi_write(reg, data); diff --git a/board/sunxi/board.c b/board/sunxi/board.c index 77e464718846..40fdd5da0477 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -634,16 +634,18 @@ void sunxi_board_init(void) #endif #if defined CONFIG_AXP152_POWER || defined CONFIG_AXP209_POWER || \ - defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || \ - defined CONFIG_AXP818_POWER + defined CONFIG_AXP221_POWER || defined CONFIG_AXP305_POWER || \ + defined CONFIG_AXP809_POWER || defined CONFIG_AXP818_POWER power_failed = axp_init(); #if defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || \ defined CONFIG_AXP818_POWER power_failed |= axp_set_dcdc1(CONFIG_AXP_DCDC1_VOLT); #endif +#if !defined(CONFIG_AXP305_POWER) power_failed |= axp_set_dcdc2(CONFIG_AXP_DCDC2_VOLT); power_failed |= axp_set_dcdc3(CONFIG_AXP_DCDC3_VOLT); +#endif #if !defined(CONFIG_AXP209_POWER) && !defined(CONFIG_AXP818_POWER) power_failed |= axp_set_dcdc4(CONFIG_AXP_DCDC4_VOLT); #endif @@ -656,8 +658,10 @@ void sunxi_board_init(void) defined CONFIG_AXP818_POWER power_failed |= axp_set_aldo1(CONFIG_AXP_ALDO1_VOLT); #endif +#if !defined(CONFIG_AXP305_POWER) power_failed |= axp_set_aldo2(CONFIG_AXP_ALDO2_VOLT); -#if !defined(CONFIG_AXP152_POWER) +#endif +#if !defined(CONFIG_AXP152_POWER) && !defined(CONFIG_AXP305_POWER) power_failed |= axp_set_aldo3(CONFIG_AXP_ALDO3_VOLT); #endif #ifdef CONFIG_AXP209_POWER diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 02050f6f3569..d17cf2d9112a 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -48,6 +48,15 @@ config AXP221_POWER Select this to enable support for the axp221/axp223 pmic found on most A23 and A31 boards. +config AXP305_POWER + bool "axp305 pmic support" + depends on MACH_SUN50I_H616 + select AXP_PMIC_BUS + select CMD_POWEROFF + ---help--- + Select this to enable support for the axp305 pmic found on most + H616 boards. + config AXP809_POWER bool "axp809 pmic support" depends on MACH_SUN9I @@ -127,11 +136,12 @@ config AXP_DCDC3_VOLT config AXP_DCDC4_VOLT int "axp pmic dcdc4 voltage" - depends on AXP152_POWER || AXP221_POWER || AXP809_POWER || AXP818_POWER + depends on AXP152_POWER || AXP221_POWER || AXP809_POWER || AXP818_POWER || AXP305_POWER default 1250 if AXP152_POWER default 1200 if MACH_SUN6I default 0 if MACH_SUN8I default 900 if MACH_SUN9I + default 1500 if AXP305_POWER ---help--- Set the voltage (mV) to program the axp pmic dcdc4 at, set to 0 to disable dcdc4. @@ -140,6 +150,7 @@ config AXP_DCDC4_VOLT On A23 / A33 boards dcdc4 is unused and should be disabled. On A80 boards dcdc4 powers VDD-SYS, HDMI, USB OTG and should be 0.9V. On A83T boards dcdc4 is
[linux-sunxi] [PATCH v2 06/21] sunxi: Add support for I2C on H6 like SoCs
I2C support, especially R_I2C port, will be needed in future. Upcoming support for H616 will need R_I2C to adjust DRAM voltage. Reviewed-by: Samuel Holland Signed-off-by: Jernej Skrabec --- .../include/asm/arch-sunxi/clock_sun50i_h6.h | 1 + arch/arm/mach-sunxi/Kconfig | 2 +- arch/arm/mach-sunxi/clock_sun50i_h6.c | 29 +++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h b/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h index 426069fc69a4..e83e84ab6cab 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h @@ -297,6 +297,7 @@ struct sunxi_ccm_reg { /* Module gate/reset shift*/ #define RESET_SHIFT(16) +#define GATE_SHIFT (0) /* DRAM clock bit field */ #define DRAM_MOD_RESET BIT(30) diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index bd82c0ef3ee4..b23ed695cd1c 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig @@ -730,7 +730,7 @@ config I2C3_ENABLE See I2C0_ENABLE help text. endif -if SUNXI_GEN_SUN6I +if SUNXI_GEN_SUN6I || SUN50I_GEN_H6 config R_I2C_ENABLE bool "Enable the PRCM I2C/TWI controller" # This is used for the pmic on H3 diff --git a/arch/arm/mach-sunxi/clock_sun50i_h6.c b/arch/arm/mach-sunxi/clock_sun50i_h6.c index ba8a26eb0d36..6bd466915c11 100644 --- a/arch/arm/mach-sunxi/clock_sun50i_h6.c +++ b/arch/arm/mach-sunxi/clock_sun50i_h6.c @@ -2,6 +2,7 @@ #include #include #include +#include #ifdef CONFIG_SPL_BUILD void clock_init_safe(void) @@ -92,3 +93,31 @@ unsigned int clock_get_pll6(void) /* The register defines PLL6-4X, not plain PLL6 */ return 2400 / 4 * n / div1 / div2; } + +int clock_twi_onoff(int port, int state) +{ + struct sunxi_ccm_reg *const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + struct sunxi_prcm_reg *const prcm = + (struct sunxi_prcm_reg *)SUNXI_PRCM_BASE; + u32 value, *ptr; + int shift; + + value = BIT(GATE_SHIFT) | BIT (RESET_SHIFT); + + if (port == 5) { + shift = 0; + ptr = >twi_gate_reset; + } else { + shift = port; + ptr = >twi_gate_reset; + } + + /* set the apb clock gate and reset for twi */ + if (state) + setbits_le32(ptr, value << shift); + else + clrbits_le32(ptr, value << shift); + + return 0; +} -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210111201153.1800440-7-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v2 05/21] sunxi: prcm: Add memory map for H6 like SoCs
There was no need to have prcm definitions for H6 and similar SoCs till now. However, support R_I2C will be needed soon in SPL. Move old definitions to prcm_sun6i.h and add new ones in prcm_sun50i.h. One of those files will be selected in common prcm.h based on defined macros. This commit doesn't do any functional change. Signed-off-by: Jernej Skrabec --- arch/arm/include/asm/arch-sunxi/prcm.h| 249 +- arch/arm/include/asm/arch-sunxi/prcm_sun50i.h | 47 arch/arm/include/asm/arch-sunxi/prcm_sun6i.h | 247 + 3 files changed, 304 insertions(+), 239 deletions(-) create mode 100644 arch/arm/include/asm/arch-sunxi/prcm_sun50i.h create mode 100644 arch/arm/include/asm/arch-sunxi/prcm_sun6i.h diff --git a/arch/arm/include/asm/arch-sunxi/prcm.h b/arch/arm/include/asm/arch-sunxi/prcm.h index 767d1ff98d74..5106076f5e91 100644 --- a/arch/arm/include/asm/arch-sunxi/prcm.h +++ b/arch/arm/include/asm/arch-sunxi/prcm.h @@ -1,247 +1,18 @@ /* SPDX-License-Identifier: GPL-2.0+ */ /* - * Sunxi A31 Power Management Unit register definition. + * (C) Copyright 2020 Jernej Skrabec * - * (C) Copyright 2013 Oliver Schinagl - * http://linux-sunxi.org - * Allwinner Technology Co., Ltd. - * Berg Xing - * Tom Cubie + * Sunxi platform prcm register definition. */ #ifndef _SUNXI_PRCM_H #define _SUNXI_PRCM_H -#define __PRCM_CPUS_CFG_PRE(n) (((n) & 0x3) << 4) -#define PRCM_CPUS_CFG_PRE_MASK __PRCM_CPUS_CFG_PRE(0x3) -#define __PRCM_CPUS_CFG_PRE_DIV(n) (((n) >> 1) - 1) -#define PRCM_CPUS_CFG_PRE_DIV(n) \ - __PRCM_CPUS_CFG_PRE(__PRCM_CPUS_CFG_CLK_PRE(n)) -#define __PRCM_CPUS_CFG_POST(n) (((n) & 0x1f) << 8) -#define PRCM_CPUS_CFG_POST_MASK __PRCM_CPUS_CFG_POST(0x1f) -#define __PRCM_CPUS_CFG_POST_DIV(n) ((n) - 1) -#define PRCM_CPUS_CFG_POST_DIV(n) \ - __PRCM_CPUS_CFG_POST_DIV(__PRCM_CPUS_CFG_POST_DIV(n)) -#define __PRCM_CPUS_CFG_CLK_SRC(n) (((n) & 0x3) << 16) -#define PRCM_CPUS_CFG_CLK_SRC_MASK __PRCM_CPUS_CFG_CLK_SRC(0x3) -#define __PRCM_CPUS_CFG_CLK_SRC_LOSC 0x0 -#define __PRCM_CPUS_CFG_CLK_SRC_HOSC 0x1 -#define __PRCM_CPUS_CFG_CLK_SRC_PLL6 0x2 -#define __PRCM_CPUS_CFG_CLK_SRC_PDIV 0x3 -#define PRCM_CPUS_CFG_CLK_SRC_LOSC \ - __PRCM_CPUS_CFG_CLK_SRC(__PRCM_CPUS_CFG_CLK_SRC_LOSC) -#define PRCM_CPUS_CFG_CLK_SRC_HOSC \ - __PRCM_CPUS_CFG_CLK_SRC(__PRCM_CPUS_CFG_CLK_SRC_HOSC) -#define PRCM_CPUS_CFG_CLK_SRC_PLL6 \ - __PRCM_CPUS_CFG_CLK_SRC(__PRCM_CPUS_CFG_CLK_SRC_PLL6) -#define PRCM_CPUS_CFG_CLK_SRC_PDIV \ - __PRCM_CPUS_CFG_CLK_SRC(__PRCM_CPUS_CFG_CLK_SRC_PDIV) - -#define __PRCM_APB0_RATIO(n) (((n) & 0x3) << 0) -#define PRCM_APB0_RATIO_DIV_MASK __PRCM_APB0_RATIO_DIV(0x3) -#define __PRCM_APB0_RATIO_DIV(n) (((n) >> 1) - 1) -#define PRCM_APB0_RATIO_DIV(n) \ - __PRCM_APB0_RATIO(__PRCM_APB0_RATIO_DIV(n)) - -#define PRCM_CPU_CFG_NEON_CLK_EN (0x1 << 0) -#define PRCM_CPU_CFG_CPU_CLK_EN (0x1 << 1) - -#define PRCM_APB0_GATE_PIO (0x1 << 0) -#define PRCM_APB0_GATE_IR (0x1 << 1) -#define PRCM_APB0_GATE_TIMER01 (0x1 << 2) -#define PRCM_APB0_GATE_P2WI (0x1 << 3) /* sun6i */ -#define PRCM_APB0_GATE_RSB (0x1 << 3) /* sun8i */ -#define PRCM_APB0_GATE_UART (0x1 << 4) -#define PRCM_APB0_GATE_1WIRE (0x1 << 5) -#define PRCM_APB0_GATE_I2C (0x1 << 6) - -#define PRCM_APB0_RESET_PIO (0x1 << 0) -#define PRCM_APB0_RESET_IR (0x1 << 1) -#define PRCM_APB0_RESET_TIMER01 (0x1 << 2) -#define PRCM_APB0_RESET_P2WI (0x1 << 3) -#define PRCM_APB0_RESET_UART (0x1 << 4) -#define PRCM_APB0_RESET_1WIRE (0x1 << 5) -#define PRCM_APB0_RESET_I2C (0x1 << 6) - -#define PRCM_PLL_CTRL_PLL_BIAS (0x1 << 0) -#define PRCM_PLL_CTRL_HOSC_GAIN_ENH (0x1 << 1) -#define __PRCM_PLL_CTRL_USB_CLK_SRC(n) (((n) & 0x3) << 4) -#define PRCM_PLL_CTRL_USB_CLK_SRC_MASK \ - __PRCM_PLL_CTRL_USB_CLK_SRC(0x3) -#define __PRCM_PLL_CTRL_USB_CLK_0 0x0 -#define __PRCM_PLL_CTRL_USB_CLK_1 0x1 -#define __PRCM_PLL_CTRL_USB_CLK_2 0x2 -#define __PRCM_PLL_CTRL_USB_CLK_3 0x3 -#define PRCM_PLL_CTRL_USB_CLK_0 \ - __PRCM_PLL_CTRL_USB_CLK_SRC(__PRCM_PLL_CTRL_USB_CLK_0) -#define PRCM_PLL_CTRL_USB_CLK_1 \ - __PRCM_PLL_CTRL_USB_CLK_SRC(__PRCM_PLL_CTRL_USB_CLK_1) -#define PRCM_PLL_CTRL_USB_CLK_2 \ - __PRCM_PLL_CTRL_USB_CLK_SRC(__PRCM_PLL_CTRL_USB_CLK_2) -#define PRCM_PLL_CTRL_USB_CLK_3 \ - __PRCM_PLL_CTRL_USB_CLK_SRC(__PRCM_PLL_CTRL_USB_CLK_3) -#define __PRCM_PLL_CTRL_INT_PLL_IN_SEL(n) (((n) & 0x3) << 12) -#define PRCM_PLL_CTRL_INT_PLL_IN_SEL_MASK \ - __PRCM_PLL_CTRL_INT_PLL_IN_SEL(0x3) -#define PRCM_PLL_CTRL_INT_PLL_IN_SEL(n) \ - __PRCM_PLL_CTRL_INT_PLL_IN_SEL(n) -#define __PRCM_PLL_CTRL_HOSC_CLK_SEL(n) (((n) & 0x3) << 20) -#define PRCM_PLL_CTRL_HOSC_CLK_SEL_MASK \ - __PRCM_PLL_CTRL_HOSC_CLK_SEL(0x3) -#define __PRCM_PLL_CTRL_HOSC_CLK_0 0x0 -#define __PRCM_PLL_CTRL_HOSC_CLK
[linux-sunxi] [PATCH v2 00/21] sunxi: Introduce H616 support
This series introduces H616 support. Later patches add also OrangePi Zero2 support but since H616 DT is not merged into Linux yet, I don't expect them to land yet. Most patches are ready to land, except those which depends on non-upstreamed DT yet. This series is based on u-boot-sunxi repo. Please take a look. Best regards, Jernej Changes from v1: - collected tags - replaced AXP805 magic value with macro - fixed H6 build (missing symbols after refactoring) - removed premature SPI boot support - add missing peripherals to prcm map - reworked mmc sector calculation - fixed comment in clock function - used IS_ENABLED ternary instead of #if #else #endif - renamed DRAM struct field to more meaningful name - fixed missing space in Kconfig for DRAM symbol - removed unused macro from sunxi-u-boot.dtsi - removed padding definition for H616 - added FEL support for H616 - picked patches 1-2 from https://patchwork.ozlabs.org/project/uboot/list/?series=223600 - added mmc support for H616 Andre Przywara (4): sunxi: support loading with SPL > 32KB mmc: sunxi: Refactor mod clock register offset net: sun8i-emac: Always clear syscon EPHY register net: sun8i-emac: Determine pinmux based on SoC, not EMAC type Jernej Skrabec (17): sunxi: Add support for AXP305 PMIC sunxi: Introduce common symbol for H6 like SoCs mmc: sunxi: Replace H6 ifdefs with H6 gen macro i2c: mvtwsi: sunxi: update macro sunxi: prcm: Add memory map for H6 like SoCs sunxi: Add support for I2C on H6 like SoCs sunxi: introduce support for H616 clocks sunxi: add support for H616 uart0 sunxi: add support for R_I2C on H616 sunxi: Add H616 DRAM support sunxi: Add support for H616 SoC mmc: sunxi: Add H616 clock offset sunxi: Add H616 FEL support arm: sunxi: add initial H616 DTSI and headers sunxi: gpio: introduce compatible for H616 clk: sunxi: Add support for H616 clocks sunxi: Add support for OrangePi Zero2 arch/arm/cpu/armv8/fel_utils.S|5 +- arch/arm/dts/Makefile |2 + arch/arm/dts/sun50i-h616-orangepi-zero2.dts | 240 arch/arm/dts/sun50i-h616.dtsi | 716 arch/arm/dts/sunxi-u-boot.dtsi|8 + arch/arm/include/asm/arch-sunxi/boot0.h |2 +- arch/arm/include/asm/arch-sunxi/clock.h |2 +- .../include/asm/arch-sunxi/clock_sun50i_h6.h | 19 +- arch/arm/include/asm/arch-sunxi/cpu.h |2 +- .../include/asm/arch-sunxi/cpu_sun50i_h6.h|7 + arch/arm/include/asm/arch-sunxi/dram.h|2 + .../include/asm/arch-sunxi/dram_sun50i_h616.h | 159 +++ arch/arm/include/asm/arch-sunxi/gpio.h|2 + arch/arm/include/asm/arch-sunxi/mmc.h |2 +- arch/arm/include/asm/arch-sunxi/prcm.h| 249 +--- arch/arm/include/asm/arch-sunxi/prcm_sun50i.h | 47 + arch/arm/include/asm/arch-sunxi/prcm_sun6i.h | 247 arch/arm/include/asm/arch-sunxi/timer.h |2 +- arch/arm/mach-sunxi/Kconfig | 75 +- arch/arm/mach-sunxi/Makefile |4 +- arch/arm/mach-sunxi/board.c | 24 +- arch/arm/mach-sunxi/clock_sun50i_h6.c | 37 +- arch/arm/mach-sunxi/cpu_info.c|2 + arch/arm/mach-sunxi/dram_sun50i_h616.c| 1023 + arch/arm/mach-sunxi/dram_timings/Makefile |2 + .../mach-sunxi/dram_timings/h616_ddr3_1333.c | 94 ++ arch/arm/mach-sunxi/pmic_bus.c|6 + arch/arm/mach-sunxi/rmr_switch.S |2 +- board/sunxi/MAINTAINERS |5 + board/sunxi/board.c | 14 +- common/spl/Kconfig|7 +- configs/orangepi_zero2_defconfig | 15 + drivers/clk/sunxi/Kconfig |7 + drivers/clk/sunxi/Makefile|1 + drivers/clk/sunxi/clk_h616.c | 120 ++ drivers/gpio/sunxi_gpio.c |1 + drivers/i2c/mvtwsi.c |2 +- drivers/mmc/sunxi_mmc.c | 97 +- drivers/net/sun8i_emac.c | 59 +- drivers/power/Kconfig | 14 +- drivers/power/Makefile|1 + drivers/power/axp305.c| 83 ++ include/axp305.h | 17 + include/axp_pmic.h|3 + include/configs/sun50i.h |2 +- include/configs/sunxi-common.h|7 + include/dt-bindings/clock/sun50i-h616-ccu.h | 115 ++ include/dt-bindings/reset/sun50i-h616-ccu.h | 70 ++ 48 files changed, 3258 insertions(+), 364 deletions(-) create mode 100644 arch/arm/dts/sun50i-h616-orangepi-zero2.dts create mode 100644 arch/arm/dts/sun50i-h616.dtsi create mode 100644 arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h create mode 100644 arch/arm/include/asm/arch-sunxi/prcm_sun50
[linux-sunxi] [PATCH] arm64: dts: allwinner: h6: PineH64 model B: Add bluetooth
PineH64 model B has wifi+bt combo module. Wifi is already supported, so lets add also bluetooth node. Signed-off-by: Jernej Skrabec --- .../dts/allwinner/sun50i-h6-pine-h64-model-b.dts | 15 +++ 1 file changed, 15 insertions(+) diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64-model-b.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64-model-b.dts index 7fea1e4e2d49..645bd8761eb5 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64-model-b.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64-model-b.dts @@ -34,3 +34,18 @@ { non-removable; status = "okay"; }; + + { + pinctrl-names = "default"; + pinctrl-0 = <_pins>, <_rts_cts_pins>; + uart-has-rtscts; + status = "okay"; + + bluetooth { + compatible = "realtek,rtl8723bs-bt"; + device-wakeup-gpios = <_pio 1 2 GPIO_ACTIVE_HIGH>; /* PM2 */ + host-wakeup-gpios = <_pio 1 1 GPIO_ACTIVE_HIGH>; /* PM1 */ + enable-gpios = <_pio 1 4 GPIO_ACTIVE_HIGH>; /* PM4 */ + max-speed = <150>; + }; +}; -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210110211606.3733056-1-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH 2/3] drm/sun4i: de2/de3: Remove redundant CSC matrices
YUV to RGB matrices are almost identical to YVU to RGB matrices. They only have second and third column reversed. Do that reversion in code in order to lower amount of static data and redundancy. Signed-off-by: Jernej Skrabec --- drivers/gpu/drm/sun4i/sun8i_csc.c | 99 +++ 1 file changed, 34 insertions(+), 65 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c b/drivers/gpu/drm/sun4i/sun8i_csc.c index 5c6ad643dae2..1d10714e417e 100644 --- a/drivers/gpu/drm/sun4i/sun8i_csc.c +++ b/drivers/gpu/drm/sun4i/sun8i_csc.c @@ -46,33 +46,6 @@ static const u32 yuv2rgb[2][2][12] = { }, }; -static const u32 yvu2rgb[2][2][12] = { - [DRM_COLOR_YCBCR_LIMITED_RANGE] = { - [DRM_COLOR_YCBCR_BT601] = { - 0x04A8, 0x0662, 0x, 0xFFFC8451, - 0x04A8, 0xFCC0, 0xFE6F, 0x00021E4D, - 0x04A8, 0x, 0x0811, 0xFFFBACA9, - }, - [DRM_COLOR_YCBCR_BT709] = { - 0x04A8, 0x072B, 0x, 0xFFFC1F99, - 0x04A8, 0xFDDF, 0xFF26, 0x00013383, - 0x04A8, 0x, 0x0873, 0xFFFB7BEF, - } - }, - [DRM_COLOR_YCBCR_FULL_RANGE] = { - [DRM_COLOR_YCBCR_BT601] = { - 0x0400, 0x059B, 0x, 0xFFFD322E, - 0x0400, 0xFD25, 0xFEA0, 0x00021DD5, - 0x0400, 0x, 0x0716, 0xFFFC74BD, - }, - [DRM_COLOR_YCBCR_BT709] = { - 0x0400, 0x064C, 0x, 0xFFFCD9B4, - 0x0400, 0xFE21, 0xFF41, 0x00014F96, - 0x0400, 0x, 0x076C, 0xFFFC49EF, - } - }, -}; - /* * DE3 has a bit different CSC units. Factors are in two's complement format. * First three factors in a row are multiplication factors which have 17 bits @@ -123,33 +96,6 @@ static const u32 yuv2rgb_de3[2][2][12] = { }, }; -static const u32 yvu2rgb_de3[2][2][12] = { - [DRM_COLOR_YCBCR_LIMITED_RANGE] = { - [DRM_COLOR_YCBCR_BT601] = { - 0x0002542A, 0x0003312A, 0x, 0xFFC0, - 0x0002542A, 0xFFFE5FC3, 0x376B, 0xFE00, - 0x0002542A, 0x, 0x000408D2, 0xFE00, - }, - [DRM_COLOR_YCBCR_BT709] = { - 0x0002542A, 0x000395E2, 0x, 0xFFC0, - 0x0002542A, 0xFFFEEF27, 0x92D2, 0xFE00, - 0x0002542A, 0x, 0x0004398C, 0xFE00, - } - }, - [DRM_COLOR_YCBCR_FULL_RANGE] = { - [DRM_COLOR_YCBCR_BT601] = { - 0x0002, 0x0002CDD2, 0x, 0x, - 0x0002, 0xFFFE925D, 0x4FCE, 0xFE00, - 0x0002, 0x, 0x00038B43, 0xFE00, - }, - [DRM_COLOR_YCBCR_BT709] = { - 0x0002, 0x0003264C, 0x, 0x, - 0x0002, 0x1053, 0xA018, 0xFE00, - 0x0002, 0x, 0x0003B611, 0xFE00, - } - }, -}; - static void sun8i_csc_set_coefficients(struct regmap *map, u32 base, enum sun8i_csc_mode mode, enum drm_color_encoding encoding, @@ -157,21 +103,30 @@ static void sun8i_csc_set_coefficients(struct regmap *map, u32 base, { const u32 *table; u32 base_reg; + int i; + + table = yuv2rgb[range][encoding]; switch (mode) { case SUN8I_CSC_MODE_YUV2RGB: - table = yuv2rgb[range][encoding]; + base_reg = SUN8I_CSC_COEFF(base, 0); + regmap_bulk_write(map, base_reg, table, 12); break; case SUN8I_CSC_MODE_YVU2RGB: - table = yvu2rgb[range][encoding]; + for (i = 0; i < 12; i++) { + if ((i & 3) == 1) + base_reg = SUN8I_CSC_COEFF(base, i + 1); + else if ((i & 3) == 2) + base_reg = SUN8I_CSC_COEFF(base, i - 1); + else + base_reg = SUN8I_CSC_COEFF(base, i); + regmap_write(map, base_reg, table[i]); + } break; default: DRM_WARN("Wrong CSC mode specified.\n"); return; } - - base_reg = SUN8I_CSC_COEFF(base, 0); - regmap_bulk_write(map, base_reg, table, 12); } static void sun8i_de3_ccsc_set_coefficients(struct regmap *map, int layer, @@ -180,22 +135,36 @@ static void sun8i_de3_
[linux-sunxi] [PATCH 3/3] drm/sun4i: Add support for BT2020 to DE3
DE3 supports 10-bit formats, so it's only naturally to also support BT2020 encoding. Add support for it. Signed-off-by: Jernej Skrabec --- drivers/gpu/drm/sun4i/sun8i_csc.c | 12 +++- drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 2 ++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c b/drivers/gpu/drm/sun4i/sun8i_csc.c index 1d10714e417e..9bd62de0c288 100644 --- a/drivers/gpu/drm/sun4i/sun8i_csc.c +++ b/drivers/gpu/drm/sun4i/sun8i_csc.c @@ -69,7 +69,7 @@ static const u32 yuv2rgb[2][2][12] = { * c20 c21 c22 [d2 const2] */ -static const u32 yuv2rgb_de3[2][2][12] = { +static const u32 yuv2rgb_de3[2][3][12] = { [DRM_COLOR_YCBCR_LIMITED_RANGE] = { [DRM_COLOR_YCBCR_BT601] = { 0x0002542A, 0x, 0x0003312A, 0xFFC0, @@ -80,6 +80,11 @@ static const u32 yuv2rgb_de3[2][2][12] = { 0x0002542A, 0x, 0x000395E2, 0xFFC0, 0x0002542A, 0x92D2, 0xFFFEEF27, 0xFE00, 0x0002542A, 0x0004398C, 0x, 0xFE00, + }, + [DRM_COLOR_YCBCR_BT2020] = { + 0x0002542A, 0x, 0x00035B7B, 0xFFC0, + 0x0002542A, 0xA017, 0xFFFEB2FC, 0xFE00, + 0x0002542A, 0x00044896, 0x, 0xFE00, } }, [DRM_COLOR_YCBCR_FULL_RANGE] = { @@ -92,6 +97,11 @@ static const u32 yuv2rgb_de3[2][2][12] = { 0x0002, 0x, 0x0003264C, 0x, 0x0002, 0xA018, 0x1053, 0xFE00, 0x0002, 0x0003B611, 0x, 0xFE00, + }, + [DRM_COLOR_YCBCR_BT2020] = { + 0x0002, 0x, 0x0002F2FE, 0x, + 0x0002, 0xABC0, 0xFFFEDB78, 0xFE00, + 0x0002, 0x0003C346, 0x, 0xFE00, } }, }; diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c index 76393fc976fe..8cc294a9969d 100644 --- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c +++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c @@ -543,6 +543,8 @@ struct sun8i_vi_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) + supported_encodings |= BIT(DRM_COLOR_YCBCR_BT2020); supported_ranges = BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) | BIT(DRM_COLOR_YCBCR_FULL_RANGE); -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210110201947.3611649-4-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH 1/3] drm/sun4i: csc: Rework DE3 CSC macros
Rework DE3 CSC macros to take just one coordinate instead of two. This will make its usage easier in subsequent commit. Signed-off-by: Jernej Skrabec --- drivers/gpu/drm/sun4i/sun8i_csc.c | 2 +- drivers/gpu/drm/sun4i/sun8i_mixer.h | 6 ++ 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c b/drivers/gpu/drm/sun4i/sun8i_csc.c index 781955dd4995..5c6ad643dae2 100644 --- a/drivers/gpu/drm/sun4i/sun8i_csc.c +++ b/drivers/gpu/drm/sun4i/sun8i_csc.c @@ -194,7 +194,7 @@ static void sun8i_de3_ccsc_set_coefficients(struct regmap *map, int layer, return; } - base_reg = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE, layer, 0, 0); + base_reg = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE, layer, 0); regmap_bulk_write(map, base_reg, table, 12); } diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h index 7576b523fdbb..145833a9d82d 100644 --- a/drivers/gpu/drm/sun4i/sun8i_mixer.h +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h @@ -50,10 +50,8 @@ #define SUN8I_MIXER_BLEND_CK_MIN(base, x) ((base) + 0xe0 + 0x04 * (x)) #define SUN8I_MIXER_BLEND_OUTCTL(base) ((base) + 0xfc) #define SUN50I_MIXER_BLEND_CSC_CTL(base) ((base) + 0x100) -#define SUN50I_MIXER_BLEND_CSC_COEFF(base, layer, x, y) \ - ((base) + 0x110 + (layer) * 0x30 + (x) * 0x10 + 4 * (y)) -#define SUN50I_MIXER_BLEND_CSC_CONST(base, layer, i) \ - ((base) + 0x110 + (layer) * 0x30 + (i) * 0x10 + 0x0c) +#define SUN50I_MIXER_BLEND_CSC_COEFF(base, layer, x) \ + ((base) + 0x110 + (layer) * 0x30 + (x) * 4) #define SUN8I_MIXER_BLEND_PIPE_CTL_EN_MSK GENMASK(12, 8) #define SUN8I_MIXER_BLEND_PIPE_CTL_EN(pipe)BIT(8 + pipe) -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210110201947.3611649-2-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH 0/3] drm/sun4i: de2/de3: CSC improvements
This short series reworks CSC handling to remove duplicated constants (patch 1 and 2) and adds BT2020 encoding to DE3 (patch 3). Please take a look. Best regards, Jernej Jernej Skrabec (3): drm/sun4i: csc: Rework DE3 CSC macros drm/sun4i: de2/de3: Remove redundant CSC matrices drm/sun4i: Add support for BT2020 to DE3 drivers/gpu/drm/sun4i/sun8i_csc.c | 109 ++--- drivers/gpu/drm/sun4i/sun8i_mixer.h| 6 +- drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 2 + 3 files changed, 48 insertions(+), 69 deletions(-) -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210110201947.3611649-1-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v6 3/3] arm64: dts: sun50i: Add support for Orange Pi 3
From: Andre Heider dts file is taken from Linux 5.11-rc1 tag. The Bluetooth controller of this device ships with a default address, use the new CONFIG_FIXUP_BDADDR option to fix it up. akonadi:?collection=30=INBOX Acked-by: Maxime Ripard Signed-off-by: Andre Heider [Updated OrangePi 3 DT, rebase and config update] Signed-off-by: Jernej Skrabec --- arch/arm/dts/Makefile | 1 + arch/arm/dts/sun50i-h6-orangepi-3.dts | 345 ++ board/sunxi/MAINTAINERS | 5 + configs/orangepi_3_defconfig | 12 + 4 files changed, 363 insertions(+) create mode 100644 arch/arm/dts/sun50i-h6-orangepi-3.dts create mode 100644 configs/orangepi_3_defconfig diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index e00aed1ec207..607571d04b25 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -605,6 +605,7 @@ dtb-$(CONFIG_MACH_SUN50I_H5) += \ sun50i-h5-orangepi-zero-plus2.dtb dtb-$(CONFIG_MACH_SUN50I_H6) += \ sun50i-h6-beelink-gs1.dtb \ + sun50i-h6-orangepi-3.dtb \ sun50i-h6-orangepi-lite2.dtb \ sun50i-h6-orangepi-one-plus.dtb \ sun50i-h6-pine-h64.dtb \ diff --git a/arch/arm/dts/sun50i-h6-orangepi-3.dts b/arch/arm/dts/sun50i-h6-orangepi-3.dts new file mode 100644 index ..15c9dd8c4479 --- /dev/null +++ b/arch/arm/dts/sun50i-h6-orangepi-3.dts @@ -0,0 +1,345 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +// Copyright (C) 2019 Ondřej Jirman + +/dts-v1/; + +#include "sun50i-h6.dtsi" +#include "sun50i-h6-cpu-opp.dtsi" + +#include + +/ { + model = "OrangePi 3"; + compatible = "xunlong,orangepi-3", "allwinner,sun50i-h6"; + + aliases { + serial0 = + serial1 = + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + connector { + compatible = "hdmi-connector"; + ddc-en-gpios = < 7 2 GPIO_ACTIVE_HIGH>; /* PH2 */ + type = "a"; + + port { + hdmi_con_in: endpoint { + remote-endpoint = <_out_con>; + }; + }; + }; + + ext_osc32k: ext_osc32k_clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <32768>; + clock-output-names = "ext_osc32k"; + }; + + leds { + compatible = "gpio-leds"; + + power { + label = "orangepi:red:power"; + gpios = <_pio 0 4 GPIO_ACTIVE_HIGH>; /* PL4 */ + default-state = "on"; + }; + + status { + label = "orangepi:green:status"; + gpios = <_pio 0 7 GPIO_ACTIVE_HIGH>; /* PL7 */ + }; + }; + + reg_vcc5v: vcc5v { + /* board wide 5V supply directly from the DC jack */ + compatible = "regulator-fixed"; + regulator-name = "vcc-5v"; + regulator-min-microvolt = <500>; + regulator-max-microvolt = <500>; + regulator-always-on; + }; + + reg_vcc33_wifi: vcc33-wifi { + /* Always on 3.3V regulator for WiFi and BT */ + compatible = "regulator-fixed"; + regulator-name = "vcc33-wifi"; + regulator-min-microvolt = <330>; + regulator-max-microvolt = <330>; + regulator-always-on; + vin-supply = <_vcc5v>; + }; + + reg_vcc_wifi_io: vcc-wifi-io { + /* Always on 1.8V/300mA regulator for WiFi and BT IO */ + compatible = "regulator-fixed"; + regulator-name = "vcc-wifi-io"; + regulator-min-microvolt = <180>; + regulator-max-microvolt = <180>; + regulator-always-on; + vin-supply = <_vcc33_wifi>; + }; + + wifi_pwrseq: wifi-pwrseq { + compatible = "mmc-pwrseq-simple"; + clocks = < 1>; + clock-names = "ext_clock"; + reset-gpios = <_pio 1 3 GPIO_ACTIVE_LOW>; /* PM3 */ + post-power-on-delay-ms = <200>; + }; +}; + + { + cpu-supply = <_dcdca>; +}; + + { + status = "okay"; +}; + + { + status = "okay"; +}; + + { + status = "okay"; +}; + + { + status = "okay"; +}; + + { + mali-supply = <_dcdcc>; + status = "okay"; +}; + + { + status = "okay&q
[linux-sunxi] [PATCH v6 2/3] arm: sunxi: add a config option to fixup a Bluetooth address
From: Andre Heider Some Bluetooth controllers, like the BCM4345C5 of the Orange Pi 3, ship with the controller default address. Add a config option to fix it up so it can function properly. Signed-off-by: Andre Heider Tested-by: Ondrej Jirman Acked-by: Maxime Ripard [rebased] Signed-off-by: Jernej Skrabec --- arch/arm/mach-sunxi/Kconfig | 11 +++ board/sunxi/board.c | 34 ++ 2 files changed, 45 insertions(+) diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index 49ef217f08c0..11e644519271 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig @@ -1016,4 +1016,15 @@ config PINEPHONE_DT_SELECTION Enable this option to automatically select the device tree for the correct PinePhone hardware revision during boot. +config BLUETOOTH_DT_DEVICE_FIXUP + string "Fixup the Bluetooth controller address" + default "" + help + This option specifies the DT compatible name of the Bluetooth + controller for which to set the "local-bd-address" property. + Set this option if your device ships with the Bluetooth controller + default address. + The used address is "bdaddr" if set, and "ethaddr" with the LSB + flipped elsewise. + endif diff --git a/board/sunxi/board.c b/board/sunxi/board.c index 4a29e351141b..ed658fced3c7 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -908,6 +908,38 @@ int misc_init_r(void) return 0; } +static void bluetooth_dt_fixup(void *blob) +{ + /* Some devices ship with a Bluetooth controller default address. +* Set a valid address through the device tree. +*/ + uchar tmp[ETH_ALEN], bdaddr[ETH_ALEN]; + unsigned int sid[4]; + int i; + + if (!CONFIG_BLUETOOTH_DT_DEVICE_FIXUP[0]) + return; + + if (eth_env_get_enetaddr("bdaddr", tmp)) { + /* Convert between the binary formats of the corresponding stacks */ + for (i = 0; i < ETH_ALEN; ++i) + bdaddr[i] = tmp[ETH_ALEN - i - 1]; + } else { + if (!get_unique_sid(sid)) + return; + + bdaddr[0] = ((sid[3] >> 0) & 0xff) ^ 1; + bdaddr[1] = (sid[3] >> 8) & 0xff; + bdaddr[2] = (sid[3] >> 16) & 0xff; + bdaddr[3] = (sid[3] >> 24) & 0xff; + bdaddr[4] = (sid[0] >> 0) & 0xff; + bdaddr[5] = 0x02; + } + + do_fixup_by_compat(blob, CONFIG_BLUETOOTH_DT_DEVICE_FIXUP, + "local-bd-address", bdaddr, ETH_ALEN, 1); +} + int ft_board_setup(void *blob, struct bd_info *bd) { int __maybe_unused r; @@ -918,6 +950,8 @@ int ft_board_setup(void *blob, struct bd_info *bd) */ setup_environment(blob); + bluetooth_dt_fixup(blob); + #ifdef CONFIG_VIDEO_DT_SIMPLEFB r = sunxi_simplefb_setup(blob); if (r) -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210110192939.3138193-3-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v6 1/3] sunxi: board: extract creating a unique sid into a helper function
From: Andre Heider Refactor setup_environment() so we can use the created sid for a Bluetooth address too. Acked-by: Maxime Ripard Reviewed-by: Andre Przywara Signed-off-by: Andre Heider [rebased] Signed-off-by: Jernej Skrabec --- board/sunxi/board.c | 121 1 file changed, 66 insertions(+), 55 deletions(-) diff --git a/board/sunxi/board.c b/board/sunxi/board.c index 708a27ed78e9..4a29e351141b 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -789,6 +789,38 @@ static void parse_spl_header(const uint32_t spl_addr) env_set_hex("fel_scriptaddr", spl->fel_script_address); } +static bool get_unique_sid(unsigned int *sid) +{ + if (sunxi_get_sid(sid) != 0) + return false; + + if (!sid[0]) + return false; + + /* +* The single words 1 - 3 of the SID have quite a few bits +* which are the same on many models, so we take a crc32 +* of all 3 words, to get a more unique value. +* +* Note we only do this on newer SoCs as we cannot change +* the algorithm on older SoCs since those have been using +* fixed mac-addresses based on only using word 3 for a +* long time and changing a fixed mac-address with an +* u-boot update is not good. +*/ +#if !defined(CONFIG_MACH_SUN4I) && !defined(CONFIG_MACH_SUN5I) && \ +!defined(CONFIG_MACH_SUN6I) && !defined(CONFIG_MACH_SUN7I) && \ +!defined(CONFIG_MACH_SUN8I_A23) && !defined(CONFIG_MACH_SUN8I_A33) + sid[3] = crc32(0, (unsigned char *)[1], 12); +#endif + + /* Ensure the NIC specific bytes of the mac are not all 0 */ + if ((sid[3] & 0xff) == 0) + sid[3] |= 0x80; + + return true; +} + /* * Note this function gets called multiple times. * It must not make any changes to env variables which already exist. @@ -799,61 +831,40 @@ static void setup_environment(const void *fdt) unsigned int sid[4]; uint8_t mac_addr[6]; char ethaddr[16]; - int i, ret; - - ret = sunxi_get_sid(sid); - if (ret == 0 && sid[0] != 0) { - /* -* The single words 1 - 3 of the SID have quite a few bits -* which are the same on many models, so we take a crc32 -* of all 3 words, to get a more unique value. -* -* Note we only do this on newer SoCs as we cannot change -* the algorithm on older SoCs since those have been using -* fixed mac-addresses based on only using word 3 for a -* long time and changing a fixed mac-address with an -* u-boot update is not good. -*/ -#if !defined(CONFIG_MACH_SUN4I) && !defined(CONFIG_MACH_SUN5I) && \ -!defined(CONFIG_MACH_SUN6I) && !defined(CONFIG_MACH_SUN7I) && \ -!defined(CONFIG_MACH_SUN8I_A23) && !defined(CONFIG_MACH_SUN8I_A33) - sid[3] = crc32(0, (unsigned char *)[1], 12); -#endif - - /* Ensure the NIC specific bytes of the mac are not all 0 */ - if ((sid[3] & 0xff) == 0) - sid[3] |= 0x80; - - for (i = 0; i < 4; i++) { - sprintf(ethaddr, "ethernet%d", i); - if (!fdt_get_alias(fdt, ethaddr)) - continue; - - if (i == 0) - strcpy(ethaddr, "ethaddr"); - else - sprintf(ethaddr, "eth%daddr", i); - - if (env_get(ethaddr)) - continue; - - /* Non OUI / registered MAC address */ - mac_addr[0] = (i << 4) | 0x02; - mac_addr[1] = (sid[0] >> 0) & 0xff; - mac_addr[2] = (sid[3] >> 24) & 0xff; - mac_addr[3] = (sid[3] >> 16) & 0xff; - mac_addr[4] = (sid[3] >> 8) & 0xff; - mac_addr[5] = (sid[3] >> 0) & 0xff; - - eth_env_set_enetaddr(ethaddr, mac_addr); - } - - if (!env_get("serial#")) { - snprintf(serial_string, sizeof(serial_string), - "%08x%08x", sid[0], sid[3]); - - env_set("serial#", serial_string); - } + int i; + + if (!get_unique_sid(sid)) + return; + + for (i = 0; i < 4; i++) { + sprintf(ethaddr, "ethernet%d", i); + if (!fdt_get_alias(fdt, ethaddr)) + continue; + + if (i == 0) +
[linux-sunxi] [PATCH v6 0/3] sunxi: Add support for OrangePi 3
This series introduces OrangePi 3 support. Previous cover letter: This is just refreshed v4 from here: https://patchwork.ozlabs.org/project/uboot/list/?series=156657=* Patches are only rebased, DT updated and defconfig regenerated, so I kept old tags. Only difference with old version is that this one does not sync H6 DT files. Becasue of that, this series should be applied on top of: https://patchwork.ozlabs.org/project/uboot/list/?series=222516 Please take a look. Best regards, Jernej Changes from v5: - Added tags - Renamed FIXUP_BDADDR -> BLUETOOTH_DT_DEVICE_FIXUP - Renamed fixup_bd_address() -> bluetooth_dt_fixup() - Removed CONFIG_PSCI_RESET from defconfig Andre Heider (3): sunxi: board: extract creating a unique sid into a helper function arm: sunxi: add a config option to fixup a Bluetooth address arm64: dts: sun50i: Add support for Orange Pi 3 arch/arm/dts/Makefile | 1 + arch/arm/dts/sun50i-h6-orangepi-3.dts | 345 ++ arch/arm/mach-sunxi/Kconfig | 11 + board/sunxi/MAINTAINERS | 5 + board/sunxi/board.c | 155 configs/orangepi_3_defconfig | 12 + 6 files changed, 474 insertions(+), 55 deletions(-) create mode 100644 arch/arm/dts/sun50i-h6-orangepi-3.dts create mode 100644 configs/orangepi_3_defconfig -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210110192939.3138193-1-jernej.skrabec%40siol.net.
[linux-sunxi] [PATCH v3] drm/sun4i: de2: Reimplement plane z position setting logic
From: Roman Stratiienko To set blending channel order register software needs to know state and position of each channel, which impossible at plane commit stage. Move this procedure to atomic_flush stage, where all necessary information is available. Fixes: f88c5ee77496 ("drm/sun4i: Implement zpos for DE2") Fixes: d8b3f454dab4 ("drm/sun4i: sun8i: Avoid clearing blending order at each atomic commit") Signed-off-by: Roman Stratiienko [rebased, addressed comments] Signed-off-by: Jernej Skrabec --- drivers/gpu/drm/sun4i/sun8i_mixer.c| 57 +- drivers/gpu/drm/sun4i/sun8i_mixer.h| 5 +++ drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 42 +++ drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 42 +++ 4 files changed, 64 insertions(+), 82 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c index 5b42cf25cc86..d2153b10b08d 100644 --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c @@ -250,6 +250,50 @@ int sun8i_mixer_drm_format_to_hw(u32 format, u32 *hw_format) static void sun8i_mixer_commit(struct sunxi_engine *engine) { + struct sun8i_mixer *mixer = engine_to_sun8i_mixer(engine); + int channel_by_zpos[SUN8I_MIXER_MAX_CHANNELS]; + u32 base = sun8i_blender_base(mixer); + u32 route = 0, pipe_ctl = 0; + unsigned int channel_count; + int i, j; + + channel_count = mixer->cfg->vi_num + mixer->cfg->ui_num; + + DRM_DEBUG_DRIVER("Update blender routing\n"); + + for (i = 0; i < SUN8I_MIXER_MAX_CHANNELS; i++) + channel_by_zpos[i] = -1; + + for (i = 0; i < channel_count; i++) { + int zpos = mixer->channel_zpos[i]; + + if (zpos >= 0 && zpos < channel_count) + channel_by_zpos[zpos] = i; + } + + j = 0; + for (i = 0; i < channel_count; i++) { + int ch = channel_by_zpos[i]; + + if (ch >= 0) { + pipe_ctl |= SUN8I_MIXER_BLEND_PIPE_CTL_EN(j); + route |= ch << SUN8I_MIXER_BLEND_ROUTE_PIPE_SHIFT(j); + j++; + } + } + + /* +* Set fill color of bottom plane to black. Generally not needed +* except when VI plane is at bottom (zpos = 0) and enabled. +*/ + pipe_ctl |= SUN8I_MIXER_BLEND_PIPE_CTL_FC_EN(0); + + regmap_write(mixer->engine.regs, +SUN8I_MIXER_BLEND_PIPE_CTL(base), pipe_ctl); + + regmap_write(mixer->engine.regs, +SUN8I_MIXER_BLEND_ROUTE(base), route); + DRM_DEBUG_DRIVER("Committing changes\n"); regmap_write(engine->regs, SUN8I_MIXER_GLOBAL_DBUFF, @@ -479,23 +523,16 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master, 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++) + for (i = 0; i < plane_cnt; i++) { + mixer->channel_zpos[i] = -1; 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); + } return 0; diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h index 7576b523fdbb..7b378d6e4dd9 100644 --- a/drivers/gpu/drm/sun4i/sun8i_mixer.h +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h @@ -12,6 +12,8 @@ #include "sunxi_engine.h" +#define SUN8I_MIXER_MAX_CHANNELS 5 + #define SUN8I_MIXER_SIZE(w, h) (((h) - 1) << 16 | ((w) - 1)) #define SUN8I_MIXER_COORD(x, y)((y) << 16 | (x)) @@ -179,6 +181,9 @@ struct sun8i_mixer { struct clk *bus_clk; struct clk *mod_clk; + + /* -1 means that layer is disabled */ + int channel_zpos[SUN8I_MIXER_MAX_CHANNELS]; }; static inline struct sun8i_mixer * diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c index 816ad4ce8996..9f82
[linux-sunxi] [PATCH] arm64: dts: allwinner: h5: Add deinterlace node
Deinterlace core is completely compatible to H3. Add a node for it. Signed-off-by: Jernej Skrabec --- Note: I didn't add H5 fallback, since the only reason why this node is not in common H3/H5 dtsi is that it's located on different addresses. If anyone feel fallback compatible is needed, I'll add it in next revision. arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi | 13 + 1 file changed, 13 insertions(+) diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi index 10489e508695..578a63dedf46 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi @@ -121,6 +121,19 @@ crypto: crypto@1c15000 { resets = < RST_BUS_CE>; }; + deinterlace: deinterlace@1e0 { + compatible = "allwinner,sun8i-h3-deinterlace"; + reg = <0x01e0 0x2>; + clocks = < CLK_BUS_DEINTERLACE>, +< CLK_DEINTERLACE>, +< CLK_DRAM_DEINTERLACE>; + clock-names = "bus", "mod", "ram"; + resets = < RST_BUS_DEINTERLACE>; + interrupts = ; + interconnects = < 9>; + interconnect-names = "dma-mem"; + }; + mali: gpu@1e8 { compatible = "allwinner,sun50i-h5-mali", "arm,mali-450"; reg = <0x01e8 0x3>; -- 2.30.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210106182523.1325796-1-jernej.skrabec%40siol.net.