From 17d6eceab5c005ad6780ad22ae8e7b5c1c9ac0d7 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Tue, 23 Mar 2021 21:27:31 +0100 Subject: [PATCH 1/9] 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 Signed-off-by: Andre Przywara --- 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 33a4d7b637..d81c0f43e1 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 0x20000000 #define CONFIG_SYS_LOAD_ADDR 0x22000000 /* 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_ADDR 0x2fe00000 @@ -72,7 +72,7 @@ #define CONFIG_SYS_SDRAM_BASE 0x40000000 #define CONFIG_SYS_LOAD_ADDR 0x42000000 /* default load address */ /* V3s do not have enough memory to place code at 0x4a000000 */ -/* 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_ADDR 0x4fe00000 @@ -240,40 +240,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(0xa000000) -#define KERNEL_ADDR_R __stringify(SDRAM_OFFSET(0080000)) -#define FDT_ADDR_R __stringify(SDRAM_OFFSET(FA00000)) -#define SCRIPT_ADDR_R __stringify(SDRAM_OFFSET(FC00000)) -#define PXEFILE_ADDR_R __stringify(SDRAM_OFFSET(FD00000)) -#define RAMDISK_ADDR_R __stringify(SDRAM_OFFSET(FE00000)) +#define BOOTM_SIZE __stringify(0xa000000) +#define KERNEL_ADDR_R __stringify(SDRAM_OFFSET(0080000)) +#define FDT_ADDR_R __stringify(SDRAM_OFFSET(FA00000)) +#define SCRIPT_ADDR_R __stringify(SDRAM_OFFSET(FC00000)) +#define PXEFILE_ADDR_R __stringify(SDRAM_OFFSET(FD00000)) +#define FDTOVERLAY_ADDR_R __stringify(SDRAM_OFFSET(FE00000)) +#define RAMDISK_ADDR_R __stringify(SDRAM_OFFSET(FF00000)) #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(0xa000000) -#define KERNEL_ADDR_R __stringify(SDRAM_OFFSET(2000000)) -#define FDT_ADDR_R __stringify(SDRAM_OFFSET(3000000)) -#define SCRIPT_ADDR_R __stringify(SDRAM_OFFSET(3100000)) -#define PXEFILE_ADDR_R __stringify(SDRAM_OFFSET(3200000)) -#define RAMDISK_ADDR_R __stringify(SDRAM_OFFSET(3300000)) +#define BOOTM_SIZE __stringify(0xa000000) +#define KERNEL_ADDR_R __stringify(SDRAM_OFFSET(2000000)) +#define FDT_ADDR_R __stringify(SDRAM_OFFSET(3000000)) +#define SCRIPT_ADDR_R __stringify(SDRAM_OFFSET(3100000)) +#define PXEFILE_ADDR_R __stringify(SDRAM_OFFSET(3200000)) +#define FDTOVERLAY_ADDR_R __stringify(SDRAM_OFFSET(3300000)) +#define RAMDISK_ADDR_R __stringify(SDRAM_OFFSET(3400000)) #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(0x2e00000) -#define KERNEL_ADDR_R __stringify(SDRAM_OFFSET(1000000)) -#define FDT_ADDR_R __stringify(SDRAM_OFFSET(1800000)) -#define SCRIPT_ADDR_R __stringify(SDRAM_OFFSET(1900000)) -#define PXEFILE_ADDR_R __stringify(SDRAM_OFFSET(1A00000)) -#define RAMDISK_ADDR_R __stringify(SDRAM_OFFSET(1B00000)) +#define BOOTM_SIZE __stringify(0x2e00000) +#define KERNEL_ADDR_R __stringify(SDRAM_OFFSET(1000000)) +#define FDT_ADDR_R __stringify(SDRAM_OFFSET(1800000)) +#define SCRIPT_ADDR_R __stringify(SDRAM_OFFSET(1900000)) +#define PXEFILE_ADDR_R __stringify(SDRAM_OFFSET(1A00000)) +#define FDTOVERLAY_ADDR_R __stringify(SDRAM_OFFSET(1B00000)) +#define RAMDISK_ADDR_R __stringify(SDRAM_OFFSET(1C00000)) #endif #endif @@ -283,6 +285,7 @@ extern int soft_i2c_gpio_scl; "fdt_addr_r=" FDT_ADDR_R "\0" \ "scriptaddr=" SCRIPT_ADDR_R "\0" \ "pxefile_addr_r=" PXEFILE_ADDR_R "\0" \ + "fdtoverlay_addr_r=" FDTOVERLAY_ADDR_R "\0" \ "ramdisk_addr_r=" RAMDISK_ADDR_R "\0" #define DFU_ALT_INFO_RAM \ From e9dfd8e96031317a837e659ac2aa1a59278c2ce6 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Fri, 26 Feb 2021 00:13:24 +0800 Subject: [PATCH 2/9] sunxi: support asymmetric dual rank DRAM on A64/R40 Previously we have known that R40 has a configuration register for its rank 1, which allows different configuration than rank 0. Reverse engineering of newest libdram of A64 from Allwinner shows that A64 has this register too. It's bit 0 (which enables dual rank in rank 0 configuration register) means a dedicated rank size setup is used for rank 1. Now, Pine64 scheduled to use a 3GiB LPDDR3 DRAM chip (which has 2GiB rank 0 and 1GiB rank 1) on PinePhone, that makes asymmetric dual rank DRAM support necessary. Add this support. The code could support both A64 and R40, but because dual rank detection is broken on R40 now, we cannot really use it on R40 currently. Signed-off-by: Icenowy Zheng Reviewed-by: Andre Przywara Tested-by: Peter Robinson Signed-off-by: Andre Przywara --- .../include/asm/arch-sunxi/dram_sunxi_dw.h | 11 ++- arch/arm/mach-sunxi/dram_sunxi_dw.c | 94 +++++++++++++++---- 2 files changed, 82 insertions(+), 23 deletions(-) diff --git a/arch/arm/include/asm/arch-sunxi/dram_sunxi_dw.h b/arch/arm/include/asm/arch-sunxi/dram_sunxi_dw.h index a5a7ebde44..e843c14202 100644 --- a/arch/arm/include/asm/arch-sunxi/dram_sunxi_dw.h +++ b/arch/arm/include/asm/arch-sunxi/dram_sunxi_dw.h @@ -215,12 +215,17 @@ struct sunxi_mctl_ctl_reg { #define NR_OF_BYTE_LANES (32 / BITS_PER_BYTE) /* The eight data lines (DQn) plus DM, DQS and DQSN */ #define LINES_PER_BYTE_LANE (BITS_PER_BYTE + 3) -struct dram_para { + +struct rank_para { u16 page_size; - u8 bus_full_width; - u8 dual_rank; u8 row_bits; u8 bank_bits; +}; + +struct dram_para { + u8 dual_rank; + u8 bus_full_width; + struct rank_para ranks[2]; const u8 dx_read_delays[NR_OF_BYTE_LANES][LINES_PER_BYTE_LANE]; const u8 dx_write_delays[NR_OF_BYTE_LANES][LINES_PER_BYTE_LANE]; const u8 ac_delays[31]; diff --git a/arch/arm/mach-sunxi/dram_sunxi_dw.c b/arch/arm/mach-sunxi/dram_sunxi_dw.c index d0600011ff..2b9d631d49 100644 --- a/arch/arm/mach-sunxi/dram_sunxi_dw.c +++ b/arch/arm/mach-sunxi/dram_sunxi_dw.c @@ -399,11 +399,19 @@ static void mctl_set_cr(uint16_t socid, struct dram_para *para) #else #error Unsupported DRAM type! #endif - (para->bank_bits == 3 ? MCTL_CR_EIGHT_BANKS : MCTL_CR_FOUR_BANKS) | + (para->ranks[0].bank_bits == 3 ? MCTL_CR_EIGHT_BANKS : MCTL_CR_FOUR_BANKS) | MCTL_CR_BUS_FULL_WIDTH(para->bus_full_width) | (para->dual_rank ? MCTL_CR_DUAL_RANK : MCTL_CR_SINGLE_RANK) | - MCTL_CR_PAGE_SIZE(para->page_size) | - MCTL_CR_ROW_BITS(para->row_bits), &mctl_com->cr); + MCTL_CR_PAGE_SIZE(para->ranks[0].page_size) | + MCTL_CR_ROW_BITS(para->ranks[0].row_bits), &mctl_com->cr); + + if (para->dual_rank && (socid == SOCID_A64 || socid == SOCID_R40)) { + writel((para->ranks[1].bank_bits == 3 ? MCTL_CR_EIGHT_BANKS : MCTL_CR_FOUR_BANKS) | + MCTL_CR_BUS_FULL_WIDTH(para->bus_full_width) | + MCTL_CR_DUAL_RANK | + MCTL_CR_PAGE_SIZE(para->ranks[1].page_size) | + MCTL_CR_ROW_BITS(para->ranks[1].row_bits), &mctl_com->cr_r1); + } if (socid == SOCID_R40) { if (para->dual_rank) @@ -646,35 +654,63 @@ static int mctl_channel_init(uint16_t socid, struct dram_para *para) return 0; } -static void mctl_auto_detect_dram_size(uint16_t socid, struct dram_para *para) +/* + * Test if memory at offset offset matches memory at a certain base + */ +static bool mctl_mem_matches_base(u32 offset, ulong base) +{ + /* Try to write different values to RAM at two addresses */ + writel(0, base); + writel(0xaa55aa55, base + offset); + dsb(); + /* Check if the same value is actually observed when reading back */ + return readl(base) == + readl(base + offset); +} + +static void mctl_auto_detect_dram_size_rank(uint16_t socid, struct dram_para *para, ulong base, struct rank_para *rank) { /* detect row address bits */ - para->page_size = 512; - para->row_bits = 16; - para->bank_bits = 2; + rank->page_size = 512; + rank->row_bits = 16; + rank->bank_bits = 2; mctl_set_cr(socid, para); - for (para->row_bits = 11; para->row_bits < 16; para->row_bits++) - if (mctl_mem_matches((1 << (para->row_bits + para->bank_bits)) * para->page_size)) + for (rank->row_bits = 11; rank->row_bits < 16; rank->row_bits++) + if (mctl_mem_matches_base((1 << (rank->row_bits + rank->bank_bits)) * rank->page_size, base)) break; /* detect bank address bits */ - para->bank_bits = 3; + rank->bank_bits = 3; mctl_set_cr(socid, para); - for (para->bank_bits = 2; para->bank_bits < 3; para->bank_bits++) - if (mctl_mem_matches((1 << para->bank_bits) * para->page_size)) + for (rank->bank_bits = 2; rank->bank_bits < 3; rank->bank_bits++) + if (mctl_mem_matches_base((1 << rank->bank_bits) * rank->page_size, base)) break; /* detect page size */ - para->page_size = 8192; + rank->page_size = 8192; mctl_set_cr(socid, para); - for (para->page_size = 512; para->page_size < 8192; para->page_size *= 2) - if (mctl_mem_matches(para->page_size)) + for (rank->page_size = 512; rank->page_size < 8192; rank->page_size *= 2) + if (mctl_mem_matches_base(rank->page_size, base)) break; } +static unsigned long mctl_calc_rank_size(struct rank_para *rank) +{ + return (1UL << (rank->row_bits + rank->bank_bits)) * rank->page_size; +} + +static void mctl_auto_detect_dram_size(uint16_t socid, struct dram_para *para) +{ + mctl_auto_detect_dram_size_rank(socid, para, (ulong)CONFIG_SYS_SDRAM_BASE, ¶->ranks[0]); + + if ((socid == SOCID_A64 || socid == SOCID_R40) && para->dual_rank) { + mctl_auto_detect_dram_size_rank(socid, para, (ulong)CONFIG_SYS_SDRAM_BASE + mctl_calc_rank_size(¶->ranks[0]), ¶->ranks[1]); + } +} + /* * The actual values used here are taken from Allwinner provided boot0 * binaries, though they are probably board specific, so would likely benefit @@ -769,12 +805,23 @@ unsigned long sunxi_dram_init(void) struct sunxi_mctl_ctl_reg * const mctl_ctl = (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE; + unsigned long size; + struct dram_para para = { .dual_rank = 1, .bus_full_width = 1, - .row_bits = 15, - .bank_bits = 3, - .page_size = 4096, + .ranks = { + { + .row_bits = 15, + .bank_bits = 3, + .page_size = 4096, + }, + { + .row_bits = 15, + .bank_bits = 3, + .page_size = 4096, + } + }, #if defined(CONFIG_MACH_SUN8I_H3) .dx_read_delays = SUN8I_H3_DX_READ_DELAYS, @@ -846,6 +893,13 @@ unsigned long sunxi_dram_init(void) mctl_auto_detect_dram_size(socid, ¶); mctl_set_cr(socid, ¶); - return (1UL << (para.row_bits + para.bank_bits)) * para.page_size * - (para.dual_rank ? 2 : 1); + size = mctl_calc_rank_size(¶.ranks[0]); + if (socid == SOCID_A64 || socid == SOCID_R40) { + if (para.dual_rank) + size += mctl_calc_rank_size(¶.ranks[1]); + } else if (para.dual_rank) { + size *= 2; + } + + return size; } From a5ff6f5c72ae26f218f8fa2739a368fcdefca093 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Fri, 26 Feb 2021 00:13:25 +0800 Subject: [PATCH 3/9] sunxi: enable dual rank memory on R40 Previously we do not have proper dual rank memory detection on R40 (because we omitted PIR_QSGATE, which does not work on R40 with our configuration), and dual rank memory is just simply disabled as early R40 boards available (Banana Pi M2 Ultra and Berry) have single rank memory. As a board with dual rank memory (Forlinx OKA40i-C) is now known to us, we need to have a way to do memory rank detection to support that board. Add some routine to detect memory rank by trying to access the memory in rank 1 and check for error status of the memory controller, and then enable dual rank memory on R40. Similar routine can be used to detect half DQ width (which is also detected by PIR_QSGATE on other SoCs), but it's left unimplemented because there's no known R40 board with half DQ width now. Signed-off-by: Icenowy Zheng Reviewed-by: Andre Przywara [Andre: Move R40 detect code call into sunxi_dram_init()] Signed-off-by: Andre Przywara --- arch/arm/mach-sunxi/dram_sunxi_dw.c | 55 +++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-sunxi/dram_sunxi_dw.c b/arch/arm/mach-sunxi/dram_sunxi_dw.c index 2b9d631d49..9107b114df 100644 --- a/arch/arm/mach-sunxi/dram_sunxi_dw.c +++ b/arch/arm/mach-sunxi/dram_sunxi_dw.c @@ -414,11 +414,9 @@ static void mctl_set_cr(uint16_t socid, struct dram_para *para) } if (socid == SOCID_R40) { - if (para->dual_rank) - panic("Dual rank memory not supported\n"); - /* Mux pin to A15 address line for single rank memory. */ - setbits_le32(&mctl_com->cr_r1, MCTL_CR_R1_MUX_A15); + if (!para->dual_rank) + setbits_le32(&mctl_com->cr_r1, MCTL_CR_R1_MUX_A15); } } @@ -702,6 +700,48 @@ static unsigned long mctl_calc_rank_size(struct rank_para *rank) return (1UL << (rank->row_bits + rank->bank_bits)) * rank->page_size; } +/* + * Because we cannot do mctl_phy_init(PIR_QSGATE) on R40 now (which leads + * to failure), it's needed to detect the rank count of R40 in another way. + * + * The code here is modelled after time_out_detect() in BSP, which tries to + * access the memory and check for error code. + * + * TODO: auto detect half DQ width here + */ +static void mctl_r40_detect_rank_count(struct dram_para *para) +{ + ulong rank1_base = (ulong) CONFIG_SYS_SDRAM_BASE + + mctl_calc_rank_size(¶->ranks[0]); + struct sunxi_mctl_ctl_reg * const mctl_ctl = + (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE; + + /* Enable read time out */ + setbits_le32(&mctl_ctl->pgcr[0], 0x1 << 25); + + (void) readl((void *) rank1_base); + udelay(10); + + if (readl(&mctl_ctl->pgsr[0]) & (0x1 << 13)) { + clrsetbits_le32(&mctl_ctl->dtcr, 0xf << 24, 0x1 << 24); + para->dual_rank = 0; + } + + /* Reset PHY FIFO to clear it */ + clrbits_le32(&mctl_ctl->pgcr[0], 0x1 << 26); + udelay(100); + setbits_le32(&mctl_ctl->pgcr[0], 0x1 << 26); + + /* Clear error status */ + setbits_le32(&mctl_ctl->pgcr[0], 0x1 << 24); + + /* Clear time out flag */ + clrbits_le32(&mctl_ctl->pgsr[0], 0x1 << 13); + + /* Disable read time out */ + clrbits_le32(&mctl_ctl->pgcr[0], 0x1 << 25); +} + static void mctl_auto_detect_dram_size(uint16_t socid, struct dram_para *para) { mctl_auto_detect_dram_size_rank(socid, para, (ulong)CONFIG_SYS_SDRAM_BASE, ¶->ranks[0]); @@ -854,8 +894,6 @@ unsigned long sunxi_dram_init(void) uint16_t socid = SOCID_H3; #elif defined(CONFIG_MACH_SUN8I_R40) uint16_t socid = SOCID_R40; - /* Currently we cannot support R40 with dual rank memory */ - para.dual_rank = 0; #elif defined(CONFIG_MACH_SUN8I_V3S) uint16_t socid = SOCID_V3S; #elif defined(CONFIG_MACH_SUN50I) @@ -890,6 +928,11 @@ unsigned long sunxi_dram_init(void) setbits_le32(&mctl_com->cccr, 1 << 31); udelay(10); + if (socid == SOCID_R40) { + mctl_r40_detect_rank_count(¶); + mctl_set_cr(SOCID_R40, ¶); + } + mctl_auto_detect_dram_size(socid, ¶); mctl_set_cr(socid, ¶); From 9078b67f3c968cbc3142432decc93a51780b4642 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sun, 7 Feb 2021 23:57:19 -0600 Subject: [PATCH 4/9] clk: sunxi: Add a dummy clock driver for the RTC The 32kHz clock ("LOSC") on sunxi SoCs is provided by the RTC. It is used, among other things, by the XHCI controller in the H6. To be able to call clk_get_bulk() on the XHCI controller, some device needs to provide all referenced clocks. Since LOSC is a fixed-rate always-on clock, implementation is trivial. Signed-off-by: Samuel Holland Reviewed-by: Andre Przywara Signed-off-by: Andre Przywara --- drivers/clk/sunxi/Makefile | 2 ++ drivers/clk/sunxi/clk_sun6i_rtc.c | 35 +++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 drivers/clk/sunxi/clk_sun6i_rtc.c diff --git a/drivers/clk/sunxi/Makefile b/drivers/clk/sunxi/Makefile index 0dfc0593fb..4f9282a8b9 100644 --- a/drivers/clk/sunxi/Makefile +++ b/drivers/clk/sunxi/Makefile @@ -6,6 +6,8 @@ obj-$(CONFIG_CLK_SUNXI) += clk_sunxi.o +obj-$(CONFIG_CLK_SUNXI) += clk_sun6i_rtc.o + obj-$(CONFIG_CLK_SUN4I_A10) += clk_a10.o obj-$(CONFIG_CLK_SUN5I_A10S) += clk_a10s.o obj-$(CONFIG_CLK_SUN6I_A31) += clk_a31.o diff --git a/drivers/clk/sunxi/clk_sun6i_rtc.c b/drivers/clk/sunxi/clk_sun6i_rtc.c new file mode 100644 index 0000000000..0c280d221b --- /dev/null +++ b/drivers/clk/sunxi/clk_sun6i_rtc.c @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2018 Amarula Solutions. + * Copyright (C) 2020 Samuel Holland + */ + +#include +#include + +static int clk_sun6i_rtc_enable(struct clk *clk) +{ + return 0; +} + +static const struct clk_ops clk_sun6i_rtc_ops = { + .enable = clk_sun6i_rtc_enable, +}; + +static const struct udevice_id sun6i_rtc_ids[] = { + { .compatible = "allwinner,sun6i-a31-rtc" }, + { .compatible = "allwinner,sun8i-a23-rtc" }, + { .compatible = "allwinner,sun8i-h3-rtc" }, + { .compatible = "allwinner,sun8i-r40-rtc" }, + { .compatible = "allwinner,sun8i-v3-rtc" }, + { .compatible = "allwinner,sun50i-h5-rtc" }, + { .compatible = "allwinner,sun50i-h6-rtc" }, + { } +}; + +U_BOOT_DRIVER(clk_sun6i_rtc) = { + .name = "clk_sun6i_rtc", + .id = UCLASS_CLK, + .of_match = sun6i_rtc_ids, + .ops = &clk_sun6i_rtc_ops, +}; From fa7eabf650ae8ad904b1258f1dd6bcc02922bafe Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sun, 7 Feb 2021 23:57:20 -0600 Subject: [PATCH 5/9] clk: sunxi: h6: Add XHCI clocks The XHCI controller has its own clock and reset. Add them. Signed-off-by: Samuel Holland Reviewed-by: Andre Przywara Signed-off-by: Andre Przywara --- drivers/clk/sunxi/clk_h6.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/sunxi/clk_h6.c b/drivers/clk/sunxi/clk_h6.c index ac8656fe89..df93d96b3b 100644 --- a/drivers/clk/sunxi/clk_h6.c +++ b/drivers/clk/sunxi/clk_h6.c @@ -43,6 +43,7 @@ static struct ccu_clk_gate h6_gates[] = { [CLK_BUS_OHCI0] = GATE(0xa8c, BIT(0)), [CLK_BUS_OHCI3] = GATE(0xa8c, BIT(3)), [CLK_BUS_EHCI0] = GATE(0xa8c, BIT(4)), + [CLK_BUS_XHCI] = GATE(0xa8c, BIT(5)), [CLK_BUS_EHCI3] = GATE(0xa8c, BIT(7)), [CLK_BUS_OTG] = GATE(0xa8c, BIT(8)), }; @@ -71,6 +72,7 @@ static struct ccu_reset h6_resets[] = { [RST_BUS_OHCI0] = RESET(0xa8c, BIT(16)), [RST_BUS_OHCI3] = RESET(0xa8c, BIT(19)), [RST_BUS_EHCI0] = RESET(0xa8c, BIT(20)), + [RST_BUS_XHCI] = RESET(0xa8c, BIT(21)), [RST_BUS_EHCI3] = RESET(0xa8c, BIT(23)), [RST_BUS_OTG] = RESET(0xa8c, BIT(24)), }; From ed4bc13f3d3e1450a9c0bb31cbd4df658685b516 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Mon, 8 Feb 2021 00:03:16 -0600 Subject: [PATCH 6/9] sunxi: binman: Respect the default FIT configuration binman can fill in the default FIT configuration index as selected by the "default-dt" argument, which is set to CONFIG_DEFAULT_DEVICE_TREE. Let's respect the user's configuration by taking advantage of this feature, instead of always defaulting to the first device tree in CONFIG_OF_LIST. Signed-off-by: Samuel Holland Reviewed-by: Simon Glass Signed-off-by: Andre Przywara --- arch/arm/dts/sunxi-u-boot.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/dts/sunxi-u-boot.dtsi b/arch/arm/dts/sunxi-u-boot.dtsi index cd096bf2a0..f822588898 100644 --- a/arch/arm/dts/sunxi-u-boot.dtsi +++ b/arch/arm/dts/sunxi-u-boot.dtsi @@ -86,7 +86,7 @@ }; configurations { - default = "config-1"; + default = "@config-DEFAULT-SEQ"; @config-SEQ { description = "NAME"; From 925cd8d77eedfc5a05d7a9559da4e30b9277920a Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Mon, 8 Feb 2021 00:03:17 -0600 Subject: [PATCH 7/9] sunxi: binman: Do not hardcode U-Boot load address The FIT description has access to the configuration variables. Use the appropriate variable instead of hardcoding the address. Signed-off-by: Samuel Holland Reviewed-by: Simon Glass Signed-off-by: Andre Przywara --- arch/arm/dts/sunxi-u-boot.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/dts/sunxi-u-boot.dtsi b/arch/arm/dts/sunxi-u-boot.dtsi index f822588898..a4227a3c22 100644 --- a/arch/arm/dts/sunxi-u-boot.dtsi +++ b/arch/arm/dts/sunxi-u-boot.dtsi @@ -42,7 +42,7 @@ os = "u-boot"; arch = "arm64"; compression = "none"; - load = <0x4a000000>; + load = ; u-boot-nodtb { }; From 747c2421c69d516af0f330cecf595fe4480854a3 Mon Sep 17 00:00:00 2001 From: Arnaud Ferraris Date: Sat, 20 Feb 2021 13:14:15 +0100 Subject: [PATCH 8/9] sunxi: arm64: Add addresses for compressed kernel load The "booti" command to load arm64 Linux kernels supports automatic decompression of zipped kernel images, but relies on some environment variables to point to usable buffer RAM. Add those variables and let them point to some default values, that should cover most use-cases. Signed-off-by: Andre Przywara --- include/configs/sunxi-common.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index d81c0f43e1..9e37e99684 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -243,6 +243,8 @@ extern int soft_i2c_gpio_scl; */ #define BOOTM_SIZE __stringify(0xa000000) #define KERNEL_ADDR_R __stringify(SDRAM_OFFSET(0080000)) +#define KERNEL_COMP_ADDR_R __stringify(SDRAM_OFFSET(4000000)) +#define KERNEL_COMP_SIZE __stringify(0xb000000) #define FDT_ADDR_R __stringify(SDRAM_OFFSET(FA00000)) #define SCRIPT_ADDR_R __stringify(SDRAM_OFFSET(FC00000)) #define PXEFILE_ADDR_R __stringify(SDRAM_OFFSET(FD00000)) @@ -288,6 +290,18 @@ extern int soft_i2c_gpio_scl; "fdtoverlay_addr_r=" FDTOVERLAY_ADDR_R "\0" \ "ramdisk_addr_r=" RAMDISK_ADDR_R "\0" +#ifdef CONFIG_ARM64 + +#define MEM_LAYOUT_ENV_EXTRA_SETTINGS \ + "kernel_comp_addr_r=" KERNEL_COMP_ADDR_R "\0" \ + "kernel_comp_size=" KERNEL_COMP_SIZE "\0" + +#else + +#define MEM_LAYOUT_ENV_EXTRA_SETTINGS "" + +#endif + #define DFU_ALT_INFO_RAM \ "dfu_alt_info_ram=" \ "kernel ram " KERNEL_ADDR_R " 0x1000000;" \ @@ -438,6 +452,7 @@ extern int soft_i2c_gpio_scl; #define CONFIG_EXTRA_ENV_SETTINGS \ CONSOLE_ENV_SETTINGS \ MEM_LAYOUT_ENV_SETTINGS \ + MEM_LAYOUT_ENV_EXTRA_SETTINGS \ DFU_ALT_INFO_RAM \ "fdtfile=" FDTFILE "\0" \ "console=ttyS0,115200\0" \ From 599177ed5139dbab112d0c9603e18382d0c642ba Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Sat, 6 Mar 2021 20:54:19 +0100 Subject: [PATCH 9/9] 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 Reviewed-by: Andre Przywara Signed-off-by: Andre Przywara --- 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 a29d11505a..8e9012dbbf 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig @@ -973,6 +973,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 147e187992..4321673312 100644 --- a/drivers/video/sunxi/Makefile +++ b/drivers/video/sunxi/Makefile @@ -4,4 +4,4 @@ # Wolfgang Denk, DENX Software Engineering, wd@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