mach-sunxi: Add support for SUNIV architecture
Add support for the suniv architecture, which is newer ARM9 SoCs by Allwinner. The design of it seems to be a mixture of sun3i, sun4i and sun6i. Signed-off-by: Icenowy Zheng <icenowy@aosc.io> Signed-off-by: Jesse Taube <Mr.Bossman075@gmail.com> Reviewed-by: Andre Przywara <andre.przywara@arm.com> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
This commit is contained in:
parent
2c699fe0d3
commit
cfe673cda7
@ -1,6 +1,7 @@
|
||||
if ARCH_SUNXI
|
||||
|
||||
config SPL_LDSCRIPT
|
||||
default "arch/arm/cpu/arm926ejs/sunxi/u-boot-spl.lds" if MACH_SUNIV
|
||||
default "arch/arm/cpu/armv7/sunxi/u-boot-spl.lds" if !ARM64
|
||||
|
||||
config IDENT_STRING
|
||||
@ -183,6 +184,12 @@ choice
|
||||
prompt "Sunxi SoC Variant"
|
||||
optional
|
||||
|
||||
config MACH_SUNIV
|
||||
bool "suniv (Allwinner F1C100s/F1C200s/F1C600/R6)"
|
||||
select CPU_ARM926EJS
|
||||
select SUNXI_GEN_SUN6I
|
||||
select SUPPORT_SPL
|
||||
|
||||
config MACH_SUN4I
|
||||
bool "sun4i (Allwinner A10)"
|
||||
select CPU_V7A
|
||||
@ -589,6 +596,7 @@ config DRAM_ODT_CORRECTION
|
||||
endif
|
||||
|
||||
config SYS_CLK_FREQ
|
||||
default 408000000 if MACH_SUNIV
|
||||
default 1008000000 if MACH_SUN4I
|
||||
default 1008000000 if MACH_SUN5I
|
||||
default 1008000000 if MACH_SUN6I
|
||||
@ -600,6 +608,7 @@ config SYS_CLK_FREQ
|
||||
default 1008000000 if MACH_SUN50I_H616
|
||||
|
||||
config SYS_CONFIG_NAME
|
||||
default "suniv" if MACH_SUNIV
|
||||
default "sun4i" if MACH_SUN4I
|
||||
default "sun5i" if MACH_SUN5I
|
||||
default "sun6i" if MACH_SUN6I
|
||||
@ -817,7 +826,7 @@ config VIDEO_SUNXI
|
||||
|
||||
config VIDEO_HDMI
|
||||
bool "HDMI output support"
|
||||
depends on VIDEO_SUNXI && !MACH_SUN8I
|
||||
depends on VIDEO_SUNXI && !MACH_SUN8I && !MACH_SUNIV
|
||||
default y
|
||||
---help---
|
||||
Say Y here to add support for outputting video over HDMI.
|
||||
@ -1017,6 +1026,7 @@ config GMAC_TX_DELAY
|
||||
Set the GMAC Transmit Clock Delay Chain value.
|
||||
|
||||
config SPL_STACK_R_ADDR
|
||||
default 0x81e00000 if MACH_SUNIV
|
||||
default 0x4fe00000 if MACH_SUN4I
|
||||
default 0x4fe00000 if MACH_SUN5I
|
||||
default 0x4fe00000 if MACH_SUN6I
|
||||
|
@ -87,7 +87,8 @@ static int gpio_init(void)
|
||||
sunxi_gpio_set_cfgpin(SUNXI_GPB(22), SUNXI_GPIO_INPUT);
|
||||
sunxi_gpio_set_cfgpin(SUNXI_GPB(23), SUNXI_GPIO_INPUT);
|
||||
#endif
|
||||
#if defined(CONFIG_MACH_SUN8I) && !defined(CONFIG_MACH_SUN8I_R40)
|
||||
#if (defined(CONFIG_MACH_SUN8I) && !defined(CONFIG_MACH_SUN8I_R40)) || \
|
||||
defined(CONFIG_MACH_SUNIV)
|
||||
sunxi_gpio_set_cfgpin(SUNXI_GPF(2), SUN8I_GPF_UART0);
|
||||
sunxi_gpio_set_cfgpin(SUNXI_GPF(4), SUN8I_GPF_UART0);
|
||||
#else
|
||||
@ -95,6 +96,10 @@ static int gpio_init(void)
|
||||
sunxi_gpio_set_cfgpin(SUNXI_GPF(4), SUNXI_GPF_UART0);
|
||||
#endif
|
||||
sunxi_gpio_set_pull(SUNXI_GPF(4), 1);
|
||||
#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUNIV)
|
||||
sunxi_gpio_set_cfgpin(SUNXI_GPE(0), SUNIV_GPE_UART0);
|
||||
sunxi_gpio_set_cfgpin(SUNXI_GPE(1), SUNIV_GPE_UART0);
|
||||
sunxi_gpio_set_pull(SUNXI_GPE(1), SUNXI_GPIO_PULL_UP);
|
||||
#elif CONFIG_CONS_INDEX == 1 && (defined(CONFIG_MACH_SUN4I) || \
|
||||
defined(CONFIG_MACH_SUN7I) || \
|
||||
defined(CONFIG_MACH_SUN8I_R40))
|
||||
@ -271,10 +276,36 @@ unsigned long spl_mmc_get_uboot_raw_sector(struct mmc *mmc,
|
||||
return sector;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MACH_SUNIV
|
||||
/*
|
||||
* The suniv BROM does not pass the boot media type to SPL, so we try with the
|
||||
* boot sequence in BROM: mmc0->spinor->fail.
|
||||
* TODO: This has the slight chance of being wrong (invalid SPL signature,
|
||||
* but valid U-Boot legacy image on the SD card), but this should be rare.
|
||||
* It looks like we can deduce from some BROM state upon entering the SPL
|
||||
* (registers, SP, or stack itself) where the BROM was coming from and use
|
||||
* that here.
|
||||
*/
|
||||
void board_boot_order(u32 *spl_boot_list)
|
||||
{
|
||||
/*
|
||||
* See the comments above in sunxi_get_boot_device() for information
|
||||
* about FEL boot.
|
||||
*/
|
||||
if (!is_boot0_magic(SPL_ADDR + 4)) {
|
||||
spl_boot_list[0] = BOOT_DEVICE_BOARD;
|
||||
return;
|
||||
}
|
||||
|
||||
spl_boot_list[0] = BOOT_DEVICE_MMC1;
|
||||
spl_boot_list[1] = BOOT_DEVICE_SPI;
|
||||
}
|
||||
#else
|
||||
u32 spl_boot_device(void)
|
||||
{
|
||||
return sunxi_get_boot_device();
|
||||
}
|
||||
#endif
|
||||
|
||||
__weak void sunxi_sram_init(void)
|
||||
{
|
||||
|
@ -35,7 +35,8 @@ int clock_init(void)
|
||||
}
|
||||
|
||||
/* These functions are shared between various SoCs so put them here. */
|
||||
#if defined CONFIG_SUNXI_GEN_SUN6I && !defined CONFIG_MACH_SUN9I
|
||||
#if defined CONFIG_SUNXI_GEN_SUN6I && !defined CONFIG_MACH_SUN9I && \
|
||||
!defined CONFIG_MACH_SUNIV
|
||||
int clock_twi_onoff(int port, int state)
|
||||
{
|
||||
struct sunxi_ccm_reg *const ccm =
|
||||
|
@ -23,7 +23,8 @@ void clock_init_safe(void)
|
||||
struct sunxi_ccm_reg * const ccm =
|
||||
(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
|
||||
|
||||
#if !defined(CONFIG_MACH_SUNXI_H3_H5) && !defined(CONFIG_MACH_SUN50I)
|
||||
#if !defined(CONFIG_MACH_SUNXI_H3_H5) && !defined(CONFIG_MACH_SUN50I) && \
|
||||
!defined(CONFIG_MACH_SUNIV)
|
||||
struct sunxi_prcm_reg * const prcm =
|
||||
(struct sunxi_prcm_reg *)SUNXI_PRCM_BASE;
|
||||
|
||||
@ -49,9 +50,11 @@ void clock_init_safe(void)
|
||||
|
||||
writel(AHB1_ABP1_DIV_DEFAULT, &ccm->ahb1_apb1_div);
|
||||
|
||||
writel(MBUS_CLK_DEFAULT, &ccm->mbus0_clk_cfg);
|
||||
if (IS_ENABLED(CONFIG_MACH_SUN6I))
|
||||
writel(MBUS_CLK_DEFAULT, &ccm->mbus1_clk_cfg);
|
||||
if (!IS_ENABLED(CONFIG_MACH_SUNIV)) {
|
||||
writel(MBUS_CLK_DEFAULT, &ccm->mbus0_clk_cfg);
|
||||
if (IS_ENABLED(CONFIG_MACH_SUN6I))
|
||||
writel(MBUS_CLK_DEFAULT, &ccm->mbus1_clk_cfg);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_MACH_SUN8I_R40) && defined(CONFIG_SUNXI_AHCI)
|
||||
setbits_le32(&ccm->sata_pll_cfg, CCM_SATA_PLL_DEFAULT);
|
||||
@ -87,22 +90,36 @@ void clock_init_uart(void)
|
||||
struct sunxi_ccm_reg *const ccm =
|
||||
(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
|
||||
|
||||
/* uart clock source is apb2 */
|
||||
writel(APB2_CLK_SRC_OSC24M|
|
||||
APB2_CLK_RATE_N_1|
|
||||
APB2_CLK_RATE_M(1),
|
||||
&ccm->apb2_div);
|
||||
#ifdef CONFIG_MACH_SUNIV
|
||||
/* suniv doesn't have apb2, UART clock source is always apb1 */
|
||||
|
||||
/* open the clock for uart */
|
||||
setbits_le32(&ccm->apb2_gate,
|
||||
CLK_GATE_OPEN << (APB2_GATE_UART_SHIFT +
|
||||
CONFIG_CONS_INDEX - 1));
|
||||
/* open the clock for uart */
|
||||
setbits_le32(&ccm->apb1_gate,
|
||||
CLK_GATE_OPEN << (APB1_GATE_UART_SHIFT +
|
||||
CONFIG_CONS_INDEX - 1));
|
||||
|
||||
/* deassert uart reset */
|
||||
setbits_le32(&ccm->apb2_reset_cfg,
|
||||
1 << (APB2_RESET_UART_SHIFT +
|
||||
CONFIG_CONS_INDEX - 1));
|
||||
/* deassert uart reset */
|
||||
setbits_le32(&ccm->apb1_reset_cfg,
|
||||
1 << (APB1_RESET_UART_SHIFT +
|
||||
CONFIG_CONS_INDEX - 1));
|
||||
#else
|
||||
/* uart clock source is apb2 */
|
||||
writel(APB2_CLK_SRC_OSC24M|
|
||||
APB2_CLK_RATE_N_1|
|
||||
APB2_CLK_RATE_M(1),
|
||||
&ccm->apb2_div);
|
||||
|
||||
/* open the clock for uart */
|
||||
setbits_le32(&ccm->apb2_gate,
|
||||
CLK_GATE_OPEN << (APB2_GATE_UART_SHIFT +
|
||||
CONFIG_CONS_INDEX - 1));
|
||||
|
||||
/* deassert uart reset */
|
||||
setbits_le32(&ccm->apb2_reset_cfg,
|
||||
1 << (APB2_RESET_UART_SHIFT +
|
||||
CONFIG_CONS_INDEX - 1));
|
||||
#endif /* !CONFIG_MACH_SUNIV */
|
||||
#else /* CONFIG_CONS_INDEX >= 5 */
|
||||
/* enable R_PIO and R_UART clocks, and de-assert resets */
|
||||
prcm_apb0_enable(PRCM_APB0_GATE_PIO | PRCM_APB0_GATE_UART);
|
||||
#endif
|
||||
@ -125,10 +142,15 @@ void clock_set_pll1(unsigned int clk)
|
||||
}
|
||||
|
||||
/* Switch to 24MHz clock while changing PLL1 */
|
||||
writel(AXI_DIV_3 << AXI_DIV_SHIFT |
|
||||
ATB_DIV_2 << ATB_DIV_SHIFT |
|
||||
CPU_CLK_SRC_OSC24M << CPU_CLK_SRC_SHIFT,
|
||||
&ccm->cpu_axi_cfg);
|
||||
if (IS_ENABLED(CONFIG_MACH_SUNIV)) {
|
||||
writel(CPU_CLK_SRC_OSC24M << CPU_CLK_SRC_SHIFT,
|
||||
&ccm->cpu_axi_cfg);
|
||||
} else {
|
||||
writel(AXI_DIV_3 << AXI_DIV_SHIFT |
|
||||
ATB_DIV_2 << ATB_DIV_SHIFT |
|
||||
CPU_CLK_SRC_OSC24M << CPU_CLK_SRC_SHIFT,
|
||||
&ccm->cpu_axi_cfg);
|
||||
}
|
||||
|
||||
/*
|
||||
* sun6i: PLL1 rate = ((24000000 * n * k) >> 0) / m (p is ignored)
|
||||
@ -140,10 +162,15 @@ void clock_set_pll1(unsigned int clk)
|
||||
sdelay(200);
|
||||
|
||||
/* Switch CPU to PLL1 */
|
||||
writel(AXI_DIV_3 << AXI_DIV_SHIFT |
|
||||
ATB_DIV_2 << ATB_DIV_SHIFT |
|
||||
CPU_CLK_SRC_PLL1 << CPU_CLK_SRC_SHIFT,
|
||||
&ccm->cpu_axi_cfg);
|
||||
if (IS_ENABLED(CONFIG_MACH_SUNIV)) {
|
||||
writel(CPU_CLK_SRC_PLL1 << CPU_CLK_SRC_SHIFT,
|
||||
&ccm->cpu_axi_cfg);
|
||||
} else {
|
||||
writel(AXI_DIV_3 << AXI_DIV_SHIFT |
|
||||
ATB_DIV_2 << ATB_DIV_SHIFT |
|
||||
CPU_CLK_SRC_PLL1 << CPU_CLK_SRC_SHIFT,
|
||||
&ccm->cpu_axi_cfg);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -317,7 +344,10 @@ unsigned int clock_get_pll6(void)
|
||||
uint32_t rval = readl(&ccm->pll6_cfg);
|
||||
int n = ((rval & CCM_PLL6_CTRL_N_MASK) >> CCM_PLL6_CTRL_N_SHIFT) + 1;
|
||||
int k = ((rval & CCM_PLL6_CTRL_K_MASK) >> CCM_PLL6_CTRL_K_SHIFT) + 1;
|
||||
return 24000000 * n * k / 2;
|
||||
if (IS_ENABLED(CONFIG_MACH_SUNIV))
|
||||
return 24000000 * n * k;
|
||||
else
|
||||
return 24000000 * n * k / 2;
|
||||
}
|
||||
|
||||
unsigned int clock_get_mipi_pll(void)
|
||||
|
@ -57,6 +57,8 @@ int print_cpuinfo(void)
|
||||
{
|
||||
#ifdef CONFIG_MACH_SUN4I
|
||||
puts("CPU: Allwinner A10 (SUN4I)\n");
|
||||
#elif defined CONFIG_MACH_SUNIV
|
||||
puts("CPU: Allwinner F Series (SUNIV)\n");
|
||||
#elif defined CONFIG_MACH_SUN5I
|
||||
u32 val = readl(SUNXI_SID_BASE + 0x08);
|
||||
switch ((val >> 12) & 0xf) {
|
||||
|
Loading…
Reference in New Issue
Block a user