From 83d5e3c9e912ddd96076a6fccaa2dbf130fc5930 Mon Sep 17 00:00:00 2001 From: Maksim Kiselev Date: Sat, 11 Nov 2023 16:33:07 +0300 Subject: sunxi: SPL SPI: Add SPI boot support for the Allwinner R528/T113 SoCs R528/T113 SoCs uses the same SPI IP as the H6, also have the same clocks and reset bits layout, but the CCU base is different. Another difference is that the new SoCs do not have a clock divider inside. Instead of this we should configure sample mode depending on input clock rate. The pin assignment is also different: the H6 uses PC0, the R528/T113 PC4 instead. This makes for a change in spi0_pinmux_setup() routine. This patch extends the H6/H616 #ifdef guards to also cover the R528/T113, using the shared CONFIG_SUNXI_GEN_NCAT2 and CONFIG_MACH_SUN8I_R528 symbols. Also use CONFIG_SUNXI_GEN_NCAT2 symbol for the Kconfig dependency. Signed-off-by: Maksim Kiselev Tested-by: Sam Edwards --- arch/arm/mach-sunxi/Kconfig | 2 +- arch/arm/mach-sunxi/spl_spi_sunxi.c | 78 +++++++++++++++++++++++++++---------- 2 files changed, 58 insertions(+), 22 deletions(-) diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index fe89aec6b9a..ddf9414b08e 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig @@ -1078,7 +1078,7 @@ config SPL_STACK_R_ADDR config SPL_SPI_SUNXI bool "Support for SPI Flash on Allwinner SoCs in SPL" - depends on MACH_SUN4I || MACH_SUN5I || MACH_SUN7I || MACH_SUNXI_H3_H5 || MACH_SUN50I || MACH_SUN8I_R40 || SUN50I_GEN_H6 || MACH_SUNIV + depends on MACH_SUN4I || MACH_SUN5I || MACH_SUN7I || MACH_SUNXI_H3_H5 || MACH_SUN50I || MACH_SUN8I_R40 || SUN50I_GEN_H6 || MACH_SUNIV || SUNXI_GEN_NCAT2 help Enable support for SPI Flash. This option allows SPL to read from sunxi SPI Flash. It uses the same method as the boot ROM, so does diff --git a/arch/arm/mach-sunxi/spl_spi_sunxi.c b/arch/arm/mach-sunxi/spl_spi_sunxi.c index 72faa7171c1..7acb44f52ae 100644 --- a/arch/arm/mach-sunxi/spl_spi_sunxi.c +++ b/arch/arm/mach-sunxi/spl_spi_sunxi.c @@ -72,18 +72,27 @@ #define SUN6I_CTL_ENABLE BIT(0) #define SUN6I_CTL_MASTER BIT(1) #define SUN6I_CTL_SRST BIT(31) +#define SUN6I_TCR_SDM BIT(13) #define SUN6I_TCR_XCH BIT(31) /*****************************************************************************/ -#define CCM_AHB_GATING0 (0x01C20000 + 0x60) -#define CCM_H6_SPI_BGR_REG (0x03001000 + 0x96c) -#ifdef CONFIG_SUN50I_GEN_H6 -#define CCM_SPI0_CLK (0x03001000 + 0x940) +#if IS_ENABLED(CONFIG_SUN50I_GEN_H6) +#define CCM_BASE 0x03001000 +#elif IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2) +#define CCM_BASE 0x02001000 #else -#define CCM_SPI0_CLK (0x01C20000 + 0xA0) +#define CCM_BASE 0x01C20000 #endif -#define SUN6I_BUS_SOFT_RST_REG0 (0x01C20000 + 0x2C0) + +#define CCM_AHB_GATING0 (CCM_BASE + 0x60) +#define CCM_H6_SPI_BGR_REG (CCM_BASE + 0x96c) +#if IS_ENABLED(CONFIG_SUN50I_GEN_H6) || IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2) +#define CCM_SPI0_CLK (CCM_BASE + 0x940) +#else +#define CCM_SPI0_CLK (CCM_BASE + 0xA0) +#endif +#define SUN6I_BUS_SOFT_RST_REG0 (CCM_BASE + 0x2C0) #define AHB_RESET_SPI0_SHIFT 20 #define AHB_GATE_OFFSET_SPI0 20 @@ -101,17 +110,22 @@ */ static void spi0_pinmux_setup(unsigned int pin_function) { - /* All chips use PC0 and PC2. */ - sunxi_gpio_set_cfgpin(SUNXI_GPC(0), pin_function); + /* All chips use PC2. And all chips use PC0, except R528/T113 */ + if (!IS_ENABLED(CONFIG_MACH_SUN8I_R528)) + sunxi_gpio_set_cfgpin(SUNXI_GPC(0), pin_function); + sunxi_gpio_set_cfgpin(SUNXI_GPC(2), pin_function); - /* All chips except H6 and H616 use PC1. */ - if (!IS_ENABLED(CONFIG_SUN50I_GEN_H6)) + /* All chips except H6/H616/R528/T113 use PC1. */ + if (!IS_ENABLED(CONFIG_SUN50I_GEN_H6) && + !IS_ENABLED(CONFIG_MACH_SUN8I_R528)) sunxi_gpio_set_cfgpin(SUNXI_GPC(1), pin_function); - if (IS_ENABLED(CONFIG_MACH_SUN50I_H6)) + if (IS_ENABLED(CONFIG_MACH_SUN50I_H6) || + IS_ENABLED(CONFIG_MACH_SUN8I_R528)) sunxi_gpio_set_cfgpin(SUNXI_GPC(5), pin_function); - if (IS_ENABLED(CONFIG_MACH_SUN50I_H616)) + if (IS_ENABLED(CONFIG_MACH_SUN50I_H616) || + IS_ENABLED(CONFIG_MACH_SUN8I_R528)) sunxi_gpio_set_cfgpin(SUNXI_GPC(4), pin_function); /* Older generations use PC23 for CS, newer ones use PC3. */ @@ -125,7 +139,8 @@ static void spi0_pinmux_setup(unsigned int pin_function) static bool is_sun6i_gen_spi(void) { return IS_ENABLED(CONFIG_SUNXI_GEN_SUN6I) || - IS_ENABLED(CONFIG_SUN50I_GEN_H6); + IS_ENABLED(CONFIG_SUN50I_GEN_H6) || + IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2); } static uintptr_t spi0_base_address(void) @@ -136,6 +151,9 @@ static uintptr_t spi0_base_address(void) if (IS_ENABLED(CONFIG_SUN50I_GEN_H6)) return 0x05010000; + if (IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2)) + return 0x04025000; + if (!is_sun6i_gen_spi() || IS_ENABLED(CONFIG_MACH_SUNIV)) return 0x01C05000; @@ -151,23 +169,30 @@ static void spi0_enable_clock(void) uintptr_t base = spi0_base_address(); /* Deassert SPI0 reset on SUN6I */ - if (IS_ENABLED(CONFIG_SUN50I_GEN_H6)) + if (IS_ENABLED(CONFIG_SUN50I_GEN_H6) || + IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2)) setbits_le32(CCM_H6_SPI_BGR_REG, (1U << 16) | 0x1); else if (is_sun6i_gen_spi()) setbits_le32(SUN6I_BUS_SOFT_RST_REG0, (1 << AHB_RESET_SPI0_SHIFT)); /* Open the SPI0 gate */ - if (!IS_ENABLED(CONFIG_SUN50I_GEN_H6)) + if (!IS_ENABLED(CONFIG_SUN50I_GEN_H6) && + !IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2)) setbits_le32(CCM_AHB_GATING0, (1 << AHB_GATE_OFFSET_SPI0)); if (IS_ENABLED(CONFIG_MACH_SUNIV)) { /* Divide by 32, clock source is AHB clock 200MHz */ writel(SPI0_CLK_DIV_BY_32, base + SUN6I_SPI0_CCTL); } else { - /* Divide by 4 */ - writel(SPI0_CLK_DIV_BY_4, base + (is_sun6i_gen_spi() ? - SUN6I_SPI0_CCTL : SUN4I_SPI0_CCTL)); + /* New SoCs do not have a clock divider inside */ + if (!IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2)) { + /* Divide by 4 */ + writel(SPI0_CLK_DIV_BY_4, + base + (is_sun6i_gen_spi() ? SUN6I_SPI0_CCTL : + SUN4I_SPI0_CCTL)); + } + /* 24MHz from OSC24M */ writel((1 << 31), CCM_SPI0_CLK); } @@ -179,6 +204,14 @@ static void spi0_enable_clock(void) /* Wait for completion */ while (readl(base + SUN6I_SPI0_GCR) & SUN6I_CTL_SRST) ; + + /* + * For new SoCs we should configure sample mode depending on + * input clock. As 24MHz from OSC24M is used, we could use + * normal sample mode by setting SDM bit in the TCR register + */ + if (IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2)) + setbits_le32(base + SUN6I_SPI0_TCR, SUN6I_TCR_SDM); } else { /* Enable SPI in the master mode and reset FIFO */ setbits_le32(base + SUN4I_SPI0_CTL, SUN4I_CTL_MASTER | @@ -205,11 +238,13 @@ static void spi0_disable_clock(void) writel(0, CCM_SPI0_CLK); /* Close the SPI0 gate */ - if (!IS_ENABLED(CONFIG_SUN50I_GEN_H6)) + if (!IS_ENABLED(CONFIG_SUN50I_GEN_H6) && + !IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2)) clrbits_le32(CCM_AHB_GATING0, (1 << AHB_GATE_OFFSET_SPI0)); /* Assert SPI0 reset on SUN6I */ - if (IS_ENABLED(CONFIG_SUN50I_GEN_H6)) + if (IS_ENABLED(CONFIG_SUN50I_GEN_H6) || + IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2)) clrbits_le32(CCM_H6_SPI_BGR_REG, (1U << 16) | 0x1); else if (is_sun6i_gen_spi()) clrbits_le32(SUN6I_BUS_SOFT_RST_REG0, @@ -223,7 +258,8 @@ static void spi0_init(void) if (IS_ENABLED(CONFIG_MACH_SUN50I) || IS_ENABLED(CONFIG_SUN50I_GEN_H6)) pin_function = SUN50I_GPC_SPI0; - else if (IS_ENABLED(CONFIG_MACH_SUNIV)) + else if (IS_ENABLED(CONFIG_MACH_SUNIV) || + IS_ENABLED(CONFIG_MACH_SUN8I_R528)) pin_function = SUNIV_GPC_SPI0; spi0_pinmux_setup(pin_function); -- cgit v1.3.1 From 6f68b9ce6cd180e5dc8d469a82db0cb48cc8d0ef Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Fri, 13 Oct 2023 23:12:14 +0100 Subject: usb: musb-new: add Allwinner F1C100s support The Allwinner F1C100s SoC has a MUSB controller like the one in the A33, but needs an SRAM region to be claimed like the A10. We do the latter anyway, even on chips that don't need it, so there is no real difference in our compatible string matching. Add a mapping between the config struct used in the Linux to our requirements here on the way. Signed-off-by: Andre Przywara --- drivers/usb/musb-new/sunxi.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/usb/musb-new/sunxi.c b/drivers/usb/musb-new/sunxi.c index 91f082fe05e..778b01b22ea 100644 --- a/drivers/usb/musb-new/sunxi.c +++ b/drivers/usb/musb-new/sunxi.c @@ -506,6 +506,16 @@ static int musb_usb_remove(struct udevice *dev) return 0; } +/* + * The Linux driver has a config struct, its fields mapping to this driver + * like this: + * .hdrc_config: + * sunxi_musb_hdrc_config_5eps => musb_config + * sunxi_musb_hdrc_config_4eps => musb_config_h3 + * .has_sram: always enabled, ideally no-op on SoCs not using it + * .has_reset: automatically detected from DT + * .no_configdata: handled via Kconfig's CONFIG_USB_MUSB_FIXED_CONFIGDATA + */ static const struct sunxi_musb_config sun4i_a10_cfg = { .config = &musb_config, }; @@ -518,6 +528,10 @@ static const struct sunxi_musb_config sun8i_h3_cfg = { .config = &musb_config_h3, }; +static const struct sunxi_musb_config suniv_f1c100s_cfg = { + .config = &musb_config, +}; + static const struct udevice_id sunxi_musb_ids[] = { { .compatible = "allwinner,sun4i-a10-musb", .data = (ulong)&sun4i_a10_cfg }, @@ -527,6 +541,8 @@ static const struct udevice_id sunxi_musb_ids[] = { .data = (ulong)&sun6i_a31_cfg }, { .compatible = "allwinner,sun8i-h3-musb", .data = (ulong)&sun8i_h3_cfg }, + { .compatible = "allwinner,suniv-f1c100s-musb", + .data = (ulong)&suniv_f1c100s_cfg }, { } }; -- cgit v1.3.1 From 02780a1c2675916bea8dbfb594bba7936ff538d5 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 7 Dec 2023 15:09:51 +0000 Subject: sunxi: move #ifdef guards around tzpc_init() to header file Some later 32-bit SoCs require some setup of the Secure Peripherals Controller, which is handled in tzpc_init(). At the moment this is guarded in board.c by some #ifdefs selecting the SoCs that need it. Move those #ifdef guards into the header file, providing an empty stub function for all other SoCs, so that the #ifdefs can be removed from the .c file, to improve readability. Signed-off-by: Andre Przywara --- arch/arm/include/asm/arch-sunxi/tzpc.h | 6 ++++++ arch/arm/mach-sunxi/board.c | 2 -- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/arm/include/asm/arch-sunxi/tzpc.h b/arch/arm/include/asm/arch-sunxi/tzpc.h index 7a6fcaebdb5..92696088a39 100644 --- a/arch/arm/include/asm/arch-sunxi/tzpc.h +++ b/arch/arm/include/asm/arch-sunxi/tzpc.h @@ -28,6 +28,12 @@ struct sunxi_tzpc { #define SUN8I_H3_TZPC_DECPORT1_ALL 0xff #define SUN8I_H3_TZPC_DECPORT2_ALL 0x7f +#if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I_H3 void tzpc_init(void); +#else +static inline void tzpc_init(void) +{ +} +#endif #endif /* _SUNXI_TZPC_H */ diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c index f4dbb2a740b..0140b07d32a 100644 --- a/arch/arm/mach-sunxi/board.c +++ b/arch/arm/mach-sunxi/board.c @@ -458,10 +458,8 @@ void board_init_f(ulong dummy) { sunxi_sram_init(); -#if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I_H3 /* Enable non-secure access to some peripherals */ tzpc_init(); -#endif clock_init(); timer_init(); -- cgit v1.3.1 From 1a6828d0c54da2267cfc2a8abe7c51226f1cb80f Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Tue, 2 Jan 2024 15:02:51 +0000 Subject: sunxi: remove unneeded i2c_init_board() call for U-Boot proper The driver used for the Allwinner I2C IP is using proper DT and DM enablement for a while: we enable the clock gate and de-assert the reset line in the driver's probe() routine, and the pinmux setup is taken care of by the DM framework. This means the explicit call to the i2c_init_board() routine is not needed for U-Boot proper. As the board_init() function in board.c is only called for U-Boot proper, we can remove the call, something that the comment there hinted at already. Fix the comment for the board_init() function on the way: we were not really doing board specific setup there. The fact that this function is called from U-Boot proper only is probably more helpful for reasoning about this code. Signed-off-by: Andre Przywara --- board/sunxi/board.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/board/sunxi/board.c b/board/sunxi/board.c index 8c12c8deade..1313b01dcea 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -186,7 +186,7 @@ enum env_location env_get_location(enum env_operation op, int prio) return ENVL_UNKNOWN; } -/* add board specific code here */ +/* called only from U-Boot proper */ int board_init(void) { __maybe_unused int id_pfr1, ret; @@ -226,13 +226,6 @@ int board_init(void) if (ret) return ret; -#if CONFIG_IS_ENABLED(DM_I2C) - /* - * Temporary workaround for enabling I2C clocks until proper sunxi DM - * clk, reset and pinctrl drivers land. - */ - i2c_init_board(); -#endif eth_init_board(); return 0; -- cgit v1.3.1 From 8cb3c49454ef6d72a20bb9c96f7ae841591ed33c Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 7 Dec 2023 16:06:04 +0000 Subject: sunxi: compile clock.c for SPL only With the clock_twi_onoff() function now being called only from the SPL, the whole clock.c file in arch/arm/mach-sunxi is needed by SPL code only. Remove the redundant #ifdef from the clock_init() function, actually this function was already only called from the SPL. Then adjust the Makefile to compile clock.c only with CONFIG_SPL_BUILD defined. This avoids unnecessary code in U-Boot proper and allows further refactoring and code-split between the SPL and U-Boot proper. Signed-off-by: Andre Przywara --- arch/arm/mach-sunxi/Makefile | 2 +- arch/arm/mach-sunxi/clock.c | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile index 1d4c70ec352..3f83c0280ef 100644 --- a/arch/arm/mach-sunxi/Makefile +++ b/arch/arm/mach-sunxi/Makefile @@ -7,7 +7,6 @@ # Wolfgang Denk, DENX Software Engineering, wd@denx.de. obj-y += board.o -obj-y += clock.o obj-y += cpu_info.o obj-y += dram_helpers.o obj-$(CONFIG_SUN6I_PRCM) += prcm.o @@ -31,6 +30,7 @@ obj-y += timer.o endif ifdef CONFIG_SPL_BUILD +obj-y += clock.o obj-$(CONFIG_MACH_SUNIV) += dram_suniv.o obj-$(CONFIG_DRAM_SUN4I) += dram_sun4i.o obj-$(CONFIG_DRAM_SUN6I) += dram_sun6i.o diff --git a/arch/arm/mach-sunxi/clock.c b/arch/arm/mach-sunxi/clock.c index b6c68c94f67..5e9fa0d0748 100644 --- a/arch/arm/mach-sunxi/clock.c +++ b/arch/arm/mach-sunxi/clock.c @@ -23,10 +23,8 @@ __weak void gtbus_init(void) int clock_init(void) { -#ifdef CONFIG_SPL_BUILD clock_init_safe(); gtbus_init(); -#endif clock_init_uart(); clock_init_sec(); -- cgit v1.3.1 From a2b2a47a16489e96e251fe2b0fab2ac9798be02f Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 7 Dec 2023 16:06:51 +0000 Subject: sunxi: sun4i: make more clock functions SPL only In clock_sun4i.c, responsible for (mostly early) clock setup on early generation Allwinner SoCs, many functions are only needed by the SPL, and are thus already guarded by CONFIG_SPL_BUILD. Over the years drivers like for the UART or I2C were converted to DM, so they care about clock setup themselves now, by using a proper DM clock driver. This means those devices need the clock setup functions here for the SPL only. Include those functions into the existing CONFIG_SPL_BUILD guards, so they are compiled for the SPL only. This avoids unnecessary code in U-Boot proper and helps further refactoring. Add some comments on the way to help understanding of the file. Signed-off-by: Andre Przywara --- arch/arm/mach-sunxi/clock_sun4i.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-sunxi/clock_sun4i.c b/arch/arm/mach-sunxi/clock_sun4i.c index ac3b7a801f4..6458d066f7e 100644 --- a/arch/arm/mach-sunxi/clock_sun4i.c +++ b/arch/arm/mach-sunxi/clock_sun4i.c @@ -43,7 +43,6 @@ void clock_init_safe(void) setbits_le32(&ccm->pll6_cfg, 0x1 << CCM_PLL6_CTRL_SATA_EN_SHIFT); #endif } -#endif void clock_init_uart(void) { @@ -77,7 +76,6 @@ int clock_twi_onoff(int port, int state) return 0; } -#ifdef CONFIG_SPL_BUILD #define PLL1_CFG(N, K, M, P) ( 1 << CCM_PLL1_CFG_ENABLE_SHIFT | \ 0 << CCM_PLL1_CFG_VCO_RST_SHIFT | \ 8 << CCM_PLL1_CFG_VCO_BIAS_SHIFT | \ @@ -177,8 +175,9 @@ void clock_set_pll1(unsigned int hz) &ccm->cpu_ahb_apb0_cfg); sdelay(20); } -#endif +#endif /* CONFIG_SPL_BUILD */ +/* video, DRAM, PLL_PERIPH clocks */ void clock_set_pll3(unsigned int clk) { struct sunxi_ccm_reg * const ccm = -- cgit v1.3.1 From 58bf08999962f27d8dbdd3ae3171b2ab59358b9c Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 7 Dec 2023 16:06:51 +0000 Subject: sunxi: sun6i: make more clock functions SPL only In clock_sun6i.c, responsible for (mostly early) clock setup on older generation Allwinner SoCs, many functions are only needed by the SPL, and are thus already guarded by CONFIG_SPL_BUILD. Over the years drivers like for the UART or I2C were converted to DM, so they care about clock setup themselves now, by using a proper DM clock driver. This means those devices need the clock setup functions here for the SPL only. Include those functions into the existing CONFIG_SPL_BUILD guards, so they are compiled for the SPL only. This avoids unnecessary code in U-Boot proper and helps further refactoring. Add some comments on the way to help understanding of the file. Signed-off-by: Andre Przywara --- arch/arm/mach-sunxi/clock_sun6i.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/arm/mach-sunxi/clock_sun6i.c b/arch/arm/mach-sunxi/clock_sun6i.c index aad9df282ec..59f7e15ffe8 100644 --- a/arch/arm/mach-sunxi/clock_sun6i.c +++ b/arch/arm/mach-sunxi/clock_sun6i.c @@ -62,7 +62,6 @@ void clock_init_safe(void) setbits_le32(&ccm->sata_clk_cfg, CCM_SATA_CTRL_ENABLE); #endif } -#endif /* CONFIG_SPL_BUILD */ void clock_init_sec(void) { @@ -124,7 +123,6 @@ void clock_init_uart(void) #endif } -#ifdef CONFIG_SPL_BUILD void clock_set_pll1(unsigned int clk) { struct sunxi_ccm_reg * const ccm = @@ -173,6 +171,7 @@ void clock_set_pll1(unsigned int clk) } #endif /* CONFIG_SPL_BUILD */ +/* video, DRAM, PLL_PERIPH clocks */ void clock_set_pll3(unsigned int clk) { struct sunxi_ccm_reg * const ccm = -- cgit v1.3.1 From c209a7163a37196486d44c0529544953ac4e4db2 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 7 Dec 2023 16:07:05 +0000 Subject: sunxi: sun50i_h6: make more clock functions SPL only In clock_sun50i_h6.c, responsible for (mostly early) clock setup on newer generation Allwinner SoCs, many functions are only needed by the SPL, and are thus already guarded by CONFIG_SPL_BUILD. Over the years drivers like for the UART or I2C were converted to DM, so they care about clock setup themselves now, by using a proper DM clock driver. This means those devices need the clock setup functions here for the SPL only. Include those functions into the existing CONFIG_SPL_BUILD guards, so they are compiled for the SPL only. By moving the clock_get_pll6() function to the end of the file, all SPL-only clocks can be contained within one #ifdef guard. This avoids unnecessary code in U-Boot proper and helps further refactoring. Add some comments on the way to help understanding of the file. Signed-off-by: Andre Przywara --- arch/arm/mach-sunxi/clock_sun50i_h6.c | 57 +++++++++++++++++------------------ 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/arch/arm/mach-sunxi/clock_sun50i_h6.c b/arch/arm/mach-sunxi/clock_sun50i_h6.c index dac3663e1be..cc2ee336416 100644 --- a/arch/arm/mach-sunxi/clock_sun50i_h6.c +++ b/arch/arm/mach-sunxi/clock_sun50i_h6.c @@ -51,7 +51,6 @@ void clock_init_safe(void) */ writel(MBUS_CLK_SRC_PLL6X2 | MBUS_CLK_M(3), &ccm->mbus_cfg); } -#endif void clock_init_uart(void) { @@ -73,7 +72,6 @@ void clock_init_uart(void) 1 << (RESET_SHIFT + CONFIG_CONS_INDEX - 1)); } -#ifdef CONFIG_SPL_BUILD void clock_set_pll1(unsigned int clk) { struct sunxi_ccm_reg * const ccm = @@ -105,33 +103,6 @@ void clock_set_pll1(unsigned int clk) val |= CCM_CPU_AXI_MUX_PLL_CPUX; writel(val, &ccm->cpu_axi_cfg); } -#endif - -unsigned int clock_get_pll6(void) -{ - struct sunxi_ccm_reg *const ccm = - (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; - uint32_t rval = readl(&ccm->pll6_cfg); - int n = ((rval & CCM_PLL6_CTRL_N_MASK) >> CCM_PLL6_CTRL_N_SHIFT) + 1; - int div2 = ((rval & CCM_PLL6_CTRL_DIV2_MASK) >> - CCM_PLL6_CTRL_DIV2_SHIFT) + 1; - int div1, m; - - if (IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2)) { - div1 = ((rval & CCM_PLL6_CTRL_P0_MASK) >> - CCM_PLL6_CTRL_P0_SHIFT) + 1; - m = 1; - } else { - div1 = ((rval & CCM_PLL6_CTRL_DIV1_MASK) >> - CCM_PLL6_CTRL_DIV1_SHIFT) + 1; - if (IS_ENABLED(CONFIG_MACH_SUN50I_H6)) - m = 4; - else - m = 2; - } - - return 24000000U * n / m / div1 / div2; -} int clock_twi_onoff(int port, int state) { @@ -160,3 +131,31 @@ int clock_twi_onoff(int port, int state) return 0; } +#endif /* CONFIG_SPL_BUILD */ + +/* PLL_PERIPH0 clock, used by the MMC driver */ +unsigned int clock_get_pll6(void) +{ + struct sunxi_ccm_reg *const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + uint32_t rval = readl(&ccm->pll6_cfg); + int n = ((rval & CCM_PLL6_CTRL_N_MASK) >> CCM_PLL6_CTRL_N_SHIFT) + 1; + int div2 = ((rval & CCM_PLL6_CTRL_DIV2_MASK) >> + CCM_PLL6_CTRL_DIV2_SHIFT) + 1; + int div1, m; + + if (IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2)) { + div1 = ((rval & CCM_PLL6_CTRL_P0_MASK) >> + CCM_PLL6_CTRL_P0_SHIFT) + 1; + m = 1; + } else { + div1 = ((rval & CCM_PLL6_CTRL_DIV1_MASK) >> + CCM_PLL6_CTRL_DIV1_SHIFT) + 1; + if (IS_ENABLED(CONFIG_MACH_SUN50I_H6)) + m = 4; + else + m = 2; + } + + return 24000000U * n / m / div1 / div2; +} -- cgit v1.3.1 From 25f07d2cc3c81763b2bf112a7edd24049554370d Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 7 Dec 2023 15:42:47 +0000 Subject: sunxi: sun8i_a83t: make more clock functions SPL only In clock_sun8i_a83t.c, responsible for (mostly early) clock setup on the Allwinner A83T SoC, many functions are only needed by the SPL, and are thus already guarded by CONFIG_SPL_BUILD. Over the years drivers like for the UART or I2C were converted to DM, so they care about clock setup themselves now, by using a proper DM clock driver. This means those devices need the clock setup functions here for the SPL only. Include those functions into the existing CONFIG_SPL_BUILD guards, so they are compiled for the SPL only. This avoids unnecessary code in U-Boot proper and helps further refactoring. Add some comments on the way to help understanding of the file. Signed-off-by: Andre Przywara --- arch/arm/mach-sunxi/clock_sun8i_a83t.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-sunxi/clock_sun8i_a83t.c b/arch/arm/mach-sunxi/clock_sun8i_a83t.c index 198fe9dbd73..9eeba084f95 100644 --- a/arch/arm/mach-sunxi/clock_sun8i_a83t.c +++ b/arch/arm/mach-sunxi/clock_sun8i_a83t.c @@ -46,7 +46,6 @@ void clock_init_safe(void) /* timestamp */ writel(1, 0x01720000); } -#endif void clock_init_uart(void) { @@ -70,7 +69,6 @@ void clock_init_uart(void) CONFIG_CONS_INDEX - 1)); } -#ifdef CONFIG_SPL_BUILD void clock_set_pll1(unsigned int clk) { struct sunxi_ccm_reg * const ccm = @@ -102,8 +100,9 @@ void clock_set_pll1(unsigned int clk) CPU_CLK_SRC_PLL1 << C1_CPUX_CLK_SRC_SHIFT, &ccm->cpu_axi_cfg); } -#endif +#endif /* CONFIG_SPL_BUILD */ +/* DRAM and PLL_PERIPH0 clock (used by the MMC driver) */ void clock_set_pll5(unsigned int clk) { struct sunxi_ccm_reg * const ccm = -- cgit v1.3.1 From 192c5c9e51c1ef100c3d027d253ffad26ff75a68 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 7 Dec 2023 15:43:21 +0000 Subject: sunxi: sun9i: make more clock functions SPL only In clock_sun9i.c, responsible for (mostly early) clock setup on the Allwinner A80 SoC, many functions are only needed by the SPL, and are thus already guarded by CONFIG_SPL_BUILD. Over the years drivers like for the UART or I2C were converted to DM, and they care about clock setup themselves now, by using a proper DM clock driver. This means those devices need the clock setup functions here for the SPL only. Move some functions around, to group all SPL-only function within one #ifdef guard. Some functions were exported, but never used outside of this file, so remove their prototypes from the header file and mark them as static. This avoids unnecessary code in U-Boot proper and helps further refactoring. Add some comments on the way to help understanding of the file. Signed-off-by: Andre Przywara --- arch/arm/include/asm/arch-sunxi/clock_sun9i.h | 3 - arch/arm/mach-sunxi/clock_sun9i.c | 97 +++++++++++++-------------- 2 files changed, 48 insertions(+), 52 deletions(-) diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun9i.h b/arch/arm/include/asm/arch-sunxi/clock_sun9i.h index fe6b8ba2732..0264bfe1c50 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun9i.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun9i.h @@ -220,10 +220,7 @@ struct sunxi_ccm_reg { #ifndef __ASSEMBLY__ void clock_set_pll1(unsigned int clk); -void clock_set_pll2(unsigned int clk); -void clock_set_pll4(unsigned int clk); void clock_set_pll6(unsigned int clk); -void clock_set_pll12(unsigned int clk); unsigned int clock_get_pll4_periph0(void); #endif diff --git a/arch/arm/mach-sunxi/clock_sun9i.c b/arch/arm/mach-sunxi/clock_sun9i.c index edaff9a28ce..5913e40cb65 100644 --- a/arch/arm/mach-sunxi/clock_sun9i.c +++ b/arch/arm/mach-sunxi/clock_sun9i.c @@ -17,6 +17,52 @@ #ifdef CONFIG_SPL_BUILD +static void clock_set_pll2(unsigned int clk) +{ + struct sunxi_ccm_reg * const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + const int p = 0; + + /* Switch cluster 1 to 24MHz clock while changing PLL2 */ + clrsetbits_le32(&ccm->cpu_clk_source, C1_CPUX_CLK_SRC_MASK, + C1_CPUX_CLK_SRC_OSC24M); + + writel(CCM_PLL2_CTRL_EN | CCM_PLL2_CTRL_P(p) | + CCM_PLL2_CLOCK_TIME_2 | CCM_PLL2_CTRL_N(clk / 24000000), + &ccm->pll2_c1_cfg); + + sdelay(2000); + + /* Switch cluster 1 back to PLL2 */ + clrsetbits_le32(&ccm->cpu_clk_source, C1_CPUX_CLK_SRC_MASK, + C1_CPUX_CLK_SRC_PLL2); +} + +static void clock_set_pll4(unsigned int clk) +{ + struct sunxi_ccm_reg * const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + + writel(CCM_PLL4_CTRL_EN | CCM_PLL4_CTRL_N(clk / 24000000), + &ccm->pll4_periph0_cfg); + + sdelay(2000); +} + +static void clock_set_pll12(unsigned int clk) +{ + struct sunxi_ccm_reg * const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + + if (readl(&ccm->pll12_periph1_cfg) & CCM_PLL12_CTRL_EN) + return; + + writel(CCM_PLL12_CTRL_EN | CCM_PLL12_CTRL_N(clk / 24000000), + &ccm->pll12_periph1_cfg); + + sdelay(2000); +} + void clock_init_safe(void) { struct sunxi_ccm_reg * const ccm = @@ -63,7 +109,6 @@ void clock_init_safe(void) /* set enable-bit in TSTAMP_CTRL_REG */ writel(1, 0x01720000); } -#endif void clock_init_uart(void) { @@ -80,7 +125,6 @@ void clock_init_uart(void) CONFIG_CONS_INDEX - 1)); } -#ifdef CONFIG_SPL_BUILD void clock_set_pll1(unsigned int clk) { struct sunxi_ccm_reg * const ccm = @@ -108,27 +152,6 @@ void clock_set_pll1(unsigned int clk) C0_CPUX_CLK_SRC_PLL1); } -void clock_set_pll2(unsigned int clk) -{ - struct sunxi_ccm_reg * const ccm = - (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; - const int p = 0; - - /* Switch cluster 1 to 24MHz clock while changing PLL2 */ - clrsetbits_le32(&ccm->cpu_clk_source, C1_CPUX_CLK_SRC_MASK, - C1_CPUX_CLK_SRC_OSC24M); - - writel(CCM_PLL2_CTRL_EN | CCM_PLL2_CTRL_P(p) | - CCM_PLL2_CLOCK_TIME_2 | CCM_PLL2_CTRL_N(clk / 24000000), - &ccm->pll2_c1_cfg); - - sdelay(2000); - - /* Switch cluster 1 back to PLL2 */ - clrsetbits_le32(&ccm->cpu_clk_source, C1_CPUX_CLK_SRC_MASK, - C1_CPUX_CLK_SRC_PLL2); -} - void clock_set_pll6(unsigned int clk) { struct sunxi_ccm_reg * const ccm = @@ -143,32 +166,6 @@ void clock_set_pll6(unsigned int clk) sdelay(2000); } -void clock_set_pll12(unsigned int clk) -{ - struct sunxi_ccm_reg * const ccm = - (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; - - if (readl(&ccm->pll12_periph1_cfg) & CCM_PLL12_CTRL_EN) - return; - - writel(CCM_PLL12_CTRL_EN | CCM_PLL12_CTRL_N(clk / 24000000), - &ccm->pll12_periph1_cfg); - - sdelay(2000); -} - - -void clock_set_pll4(unsigned int clk) -{ - struct sunxi_ccm_reg * const ccm = - (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; - - writel(CCM_PLL4_CTRL_EN | CCM_PLL4_CTRL_N(clk / 24000000), - &ccm->pll4_periph0_cfg); - - sdelay(2000); -} -#endif int clock_twi_onoff(int port, int state) { @@ -193,7 +190,9 @@ int clock_twi_onoff(int port, int state) return 0; } +#endif /* CONFIG_SPL_BUILD */ +/* PLL_PERIPH0 clock (used by the MMC driver) */ unsigned int clock_get_pll4_periph0(void) { struct sunxi_ccm_reg *const ccm = -- cgit v1.3.1