mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-24 13:43:28 +00:00
sunxi: introduce NCAT2 generation model
Allwinner seems to typically stick to a common MMIO memory map for several SoCs, but from time to time does some breaking changes, which also introduce new generations of some peripherals. The last time this happened with the H6, which apart from re-organising the base addresses also changed the clock controller significantly. We added a CONFIG_SUN50I_GEN_H6 symbol back then to mark SoCs sharing those traits. Now the Allwinner D1 changes the memory map again, and also extends the pincontroller, among other peripherals. To mark this generation of SoCs, add a CONFIG_SUNXI_GEN_NCAT2 symbol, this name is reportedly used in the Allwinner BSP code, and prevents us from inventing our own name. Add this new symbol to some guards that were already checking for the H6 generation, since many features are shared between the two (like the renovated clock controller). This paves the way to introduce a first user of this generation. Signed-off-by: Andre Przywara <andre.przywara@arm.com> Tested-by: Samuel Holland <samuel@sholland.org>
This commit is contained in:
parent
452369cd0c
commit
4a9e89a3e3
14 changed files with 90 additions and 20 deletions
|
@ -16,7 +16,7 @@
|
||||||
/* clock control module regs definition */
|
/* clock control module regs definition */
|
||||||
#if defined(CONFIG_MACH_SUN8I_A83T)
|
#if defined(CONFIG_MACH_SUN8I_A83T)
|
||||||
#include <asm/arch/clock_sun8i_a83t.h>
|
#include <asm/arch/clock_sun8i_a83t.h>
|
||||||
#elif defined(CONFIG_SUN50I_GEN_H6)
|
#elif defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2)
|
||||||
#include <asm/arch/clock_sun50i_h6.h>
|
#include <asm/arch/clock_sun50i_h6.h>
|
||||||
#elif defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN8I) || \
|
#elif defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN8I) || \
|
||||||
defined(CONFIG_MACH_SUN50I) || defined(CONFIG_MACH_SUNIV)
|
defined(CONFIG_MACH_SUN50I) || defined(CONFIG_MACH_SUNIV)
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
#include <asm/arch/cpu_sun9i.h>
|
#include <asm/arch/cpu_sun9i.h>
|
||||||
#elif defined(CONFIG_SUN50I_GEN_H6)
|
#elif defined(CONFIG_SUN50I_GEN_H6)
|
||||||
#include <asm/arch/cpu_sun50i_h6.h>
|
#include <asm/arch/cpu_sun50i_h6.h>
|
||||||
|
#elif defined(CONFIG_SUNXI_GEN_NCAT2)
|
||||||
|
#include <asm/arch/cpu_sunxi_ncat2.h>
|
||||||
#else
|
#else
|
||||||
#include <asm/arch/cpu_sun4i.h>
|
#include <asm/arch/cpu_sun4i.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
43
arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h
Normal file
43
arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* (C) Copyright 2022 Arm Limited
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0+
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _SUNXI_CPU_SUNXI_NCAT2_H
|
||||||
|
#define _SUNXI_CPU_SUNXI_NCAT2_H
|
||||||
|
|
||||||
|
#define SUNXI_CCM_BASE 0x02001000
|
||||||
|
#define SUNXI_TIMER_BASE 0x02050000
|
||||||
|
|
||||||
|
#define SUNXI_UART0_BASE 0x02500000
|
||||||
|
#define SUNXI_UART1_BASE 0x02500400
|
||||||
|
#define SUNXI_UART2_BASE 0x02500800
|
||||||
|
#define SUNXI_UART3_BASE 0x02500C00
|
||||||
|
#define SUNXI_TWI0_BASE 0x02502000
|
||||||
|
#define SUNXI_TWI1_BASE 0x02502400
|
||||||
|
#define SUNXI_TWI2_BASE 0x02502800
|
||||||
|
#define SUNXI_TWI3_BASE 0x02502C00
|
||||||
|
|
||||||
|
#define SUNXI_SRAMC_BASE 0x03000000
|
||||||
|
/* SID address space starts at 0x03006000, but e-fuse is at offset 0x200 */
|
||||||
|
#define SUNXI_SIDC_BASE 0x03006000
|
||||||
|
#define SUNXI_SID_BASE 0x03006200
|
||||||
|
#define SUNXI_GIC400_BASE 0x03020000
|
||||||
|
|
||||||
|
#define SUNXI_MMC0_BASE 0x04020000
|
||||||
|
#define SUNXI_MMC1_BASE 0x04021000
|
||||||
|
#define SUNXI_MMC2_BASE 0x04022000
|
||||||
|
|
||||||
|
#define SUNXI_R_CPUCFG_BASE 0x07000400
|
||||||
|
#define SUNXI_PRCM_BASE 0x07010000
|
||||||
|
|
||||||
|
#define SUNXI_CPUCFG_BASE 0x09010000
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLY__
|
||||||
|
void sunxi_board_init(void);
|
||||||
|
void sunxi_reset(void);
|
||||||
|
int sunxi_get_sid(unsigned int *sid);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _SUNXI_CPU_SUNXI_NCAT2_H */
|
|
@ -45,7 +45,7 @@ struct sunxi_mmc {
|
||||||
u32 chda; /* 0x90 */
|
u32 chda; /* 0x90 */
|
||||||
u32 cbda; /* 0x94 */
|
u32 cbda; /* 0x94 */
|
||||||
u32 res2[26];
|
u32 res2[26];
|
||||||
#if defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6)
|
#if defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2)
|
||||||
u32 res3[17];
|
u32 res3[17];
|
||||||
u32 samp_dl;
|
u32 samp_dl;
|
||||||
u32 res4[46];
|
u32 res4[46];
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#define _SUNXI_PRCM_H
|
#define _SUNXI_PRCM_H
|
||||||
|
|
||||||
/* prcm regs definition */
|
/* prcm regs definition */
|
||||||
#if defined(CONFIG_SUN50I_GEN_H6)
|
#if defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2)
|
||||||
#include <asm/arch/prcm_sun50i.h>
|
#include <asm/arch/prcm_sun50i.h>
|
||||||
#else
|
#else
|
||||||
#include <asm/arch/prcm_sun6i.h>
|
#include <asm/arch/prcm_sun6i.h>
|
||||||
|
|
|
@ -76,7 +76,7 @@ struct sunxi_timer_reg {
|
||||||
struct sunxi_tgp tgp[4];
|
struct sunxi_tgp tgp[4];
|
||||||
u8 res5[8];
|
u8 res5[8];
|
||||||
u32 cpu_cfg;
|
u32 cpu_cfg;
|
||||||
#elif defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6)
|
#elif defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2)
|
||||||
u8 res3[16];
|
u8 res3[16];
|
||||||
struct sunxi_wdog wdog[5]; /* We have 5 watchdogs */
|
struct sunxi_wdog wdog[5]; /* We have 5 watchdogs */
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -121,7 +121,7 @@ config AXP_PMIC_BUS
|
||||||
config SUNXI_SRAM_ADDRESS
|
config SUNXI_SRAM_ADDRESS
|
||||||
hex
|
hex
|
||||||
default 0x10000 if MACH_SUN9I || MACH_SUN50I || MACH_SUN50I_H5
|
default 0x10000 if MACH_SUN9I || MACH_SUN50I || MACH_SUN50I_H5
|
||||||
default 0x20000 if SUN50I_GEN_H6
|
default 0x20000 if SUN50I_GEN_H6 || SUNXI_GEN_NCAT2
|
||||||
default 0x0
|
default 0x0
|
||||||
---help---
|
---help---
|
||||||
Older Allwinner SoCs have their mask boot ROM mapped just below 4GB,
|
Older Allwinner SoCs have their mask boot ROM mapped just below 4GB,
|
||||||
|
@ -183,6 +183,14 @@ config SUN50I_GEN_H6
|
||||||
Select this for sunxi SoCs which have H6 like peripherals, clocks
|
Select this for sunxi SoCs which have H6 like peripherals, clocks
|
||||||
and memory map.
|
and memory map.
|
||||||
|
|
||||||
|
config SUNXI_GEN_NCAT2
|
||||||
|
bool
|
||||||
|
select MMC_SUNXI_HAS_NEW_MODE
|
||||||
|
select SUPPORT_SPL
|
||||||
|
---help---
|
||||||
|
Select this for sunxi SoCs which have D1 like peripherals, clocks
|
||||||
|
and memory map.
|
||||||
|
|
||||||
config SUNXI_DRAM_DW
|
config SUNXI_DRAM_DW
|
||||||
bool
|
bool
|
||||||
---help---
|
---help---
|
||||||
|
@ -804,6 +812,7 @@ config VIDEO_SUNXI
|
||||||
depends on !MACH_SUN9I
|
depends on !MACH_SUN9I
|
||||||
depends on !MACH_SUN50I
|
depends on !MACH_SUN50I
|
||||||
depends on !SUN50I_GEN_H6
|
depends on !SUN50I_GEN_H6
|
||||||
|
depends on !SUNXI_GEN_NCAT2
|
||||||
select VIDEO
|
select VIDEO
|
||||||
select DISPLAY
|
select DISPLAY
|
||||||
imply VIDEO_DT_SIMPLEFB
|
imply VIDEO_DT_SIMPLEFB
|
||||||
|
@ -1017,6 +1026,7 @@ config SPL_STACK_R_ADDR
|
||||||
default 0x2fe00000 if MACH_SUN9I
|
default 0x2fe00000 if MACH_SUN9I
|
||||||
default 0x4fe00000 if MACH_SUN50I
|
default 0x4fe00000 if MACH_SUN50I
|
||||||
default 0x4fe00000 if SUN50I_GEN_H6
|
default 0x4fe00000 if SUN50I_GEN_H6
|
||||||
|
default 0x4fe00000 if SUNXI_GEN_NCAT2
|
||||||
|
|
||||||
config SPL_SPI_SUNXI
|
config SPL_SPI_SUNXI
|
||||||
bool "Support for SPI Flash on Allwinner SoCs in SPL"
|
bool "Support for SPI Flash on Allwinner SoCs in SPL"
|
||||||
|
|
|
@ -25,6 +25,7 @@ obj-$(CONFIG_MACH_SUN8I) += clock_sun6i.o
|
||||||
endif
|
endif
|
||||||
obj-$(CONFIG_MACH_SUN9I) += clock_sun9i.o gtbus_sun9i.o
|
obj-$(CONFIG_MACH_SUN9I) += clock_sun9i.o gtbus_sun9i.o
|
||||||
obj-$(CONFIG_SUN50I_GEN_H6) += clock_sun50i_h6.o
|
obj-$(CONFIG_SUN50I_GEN_H6) += clock_sun50i_h6.o
|
||||||
|
obj-$(CONFIG_SUNXI_GEN_NCAT2) += clock_sun50i_h6.o
|
||||||
ifndef CONFIG_ARM64
|
ifndef CONFIG_ARM64
|
||||||
obj-y += timer.o
|
obj-y += timer.o
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -176,13 +176,19 @@ static int gpio_init(void)
|
||||||
#error Unsupported console port number. Please fix pin mux settings in board.c
|
#error Unsupported console port number. Please fix pin mux settings in board.c
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SUN50I_GEN_H6
|
/*
|
||||||
/* Update PIO power bias configuration by copy hardware detected value */
|
* Update PIO power bias configuration by copying the hardware
|
||||||
|
* detected value.
|
||||||
|
*/
|
||||||
|
if (IS_ENABLED(CONFIG_SUN50I_GEN_H6) ||
|
||||||
|
IS_ENABLED(CONFIG_SUN50I_GEN_NCAT2)) {
|
||||||
val = readl(SUNXI_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_VAL);
|
val = readl(SUNXI_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_VAL);
|
||||||
writel(val, SUNXI_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_SEL);
|
writel(val, SUNXI_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_SEL);
|
||||||
|
}
|
||||||
|
if (IS_ENABLED(CONFIG_SUN50I_GEN_H6)) {
|
||||||
val = readl(SUNXI_R_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_VAL);
|
val = readl(SUNXI_R_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_VAL);
|
||||||
writel(val, SUNXI_R_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_SEL);
|
writel(val, SUNXI_R_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_SEL);
|
||||||
#endif
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -481,7 +487,7 @@ void reset_cpu(void)
|
||||||
/* sun5i sometimes gets stuck without this */
|
/* sun5i sometimes gets stuck without this */
|
||||||
writel(WDT_MODE_RESET_EN | WDT_MODE_EN, &wdog->mode);
|
writel(WDT_MODE_RESET_EN | WDT_MODE_EN, &wdog->mode);
|
||||||
}
|
}
|
||||||
#elif defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6)
|
#elif defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2)
|
||||||
#if defined(CONFIG_MACH_SUN50I_H6)
|
#if defined(CONFIG_MACH_SUN50I_H6)
|
||||||
/* WDOG is broken for some H6 rev. use the R_WDOG instead */
|
/* WDOG is broken for some H6 rev. use the R_WDOG instead */
|
||||||
static const struct sunxi_wdog *wdog =
|
static const struct sunxi_wdog *wdog =
|
||||||
|
|
|
@ -18,8 +18,11 @@ void clock_init_safe(void)
|
||||||
setbits_le32(&prcm->res_cal_ctrl, 2);
|
setbits_le32(&prcm->res_cal_ctrl, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_MACH_SUN50I_H616) ||
|
||||||
|
IS_ENABLED(CONFIG_MACH_SUN50I_H6)) {
|
||||||
clrbits_le32(&prcm->res_cal_ctrl, 1);
|
clrbits_le32(&prcm->res_cal_ctrl, 1);
|
||||||
setbits_le32(&prcm->res_cal_ctrl, 1);
|
setbits_le32(&prcm->res_cal_ctrl, 1);
|
||||||
|
}
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_MACH_SUN50I_H6)) {
|
if (IS_ENABLED(CONFIG_MACH_SUN50I_H6)) {
|
||||||
/* set key field for ldo enable */
|
/* set key field for ldo enable */
|
||||||
|
|
|
@ -265,7 +265,7 @@ config SPL_TEXT_BASE
|
||||||
default 0x402F0400 if AM33XX
|
default 0x402F0400 if AM33XX
|
||||||
default 0x40301350 if OMAP54XX
|
default 0x40301350 if OMAP54XX
|
||||||
default 0x10060 if MACH_SUN50I || MACH_SUN50I_H5 || MACH_SUN9I
|
default 0x10060 if MACH_SUN50I || MACH_SUN50I_H5 || MACH_SUN9I
|
||||||
default 0x20060 if SUN50I_GEN_H6
|
default 0x20060 if SUN50I_GEN_H6 || SUNXI_GEN_NCAT2
|
||||||
default 0x00060 if ARCH_SUNXI
|
default 0x00060 if ARCH_SUNXI
|
||||||
default 0xfffc0000 if ARCH_ZYNQMP
|
default 0xfffc0000 if ARCH_ZYNQMP
|
||||||
default 0x0
|
default 0x0
|
||||||
|
|
|
@ -124,7 +124,8 @@ enum mvtwsi_ctrl_register_fields {
|
||||||
* on other platforms, it is a normal r/w bit, which is cleared by writing 0.
|
* on other platforms, it is a normal r/w bit, which is cleared by writing 0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6)
|
#if defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6) || \
|
||||||
|
defined(CONFIG_SUNXI_GEN_NCAT2)
|
||||||
#define MVTWSI_CONTROL_CLEAR_IFLG 0x00000008
|
#define MVTWSI_CONTROL_CLEAR_IFLG 0x00000008
|
||||||
#else
|
#else
|
||||||
#define MVTWSI_CONTROL_CLEAR_IFLG 0x00000000
|
#define MVTWSI_CONTROL_CLEAR_IFLG 0x00000000
|
||||||
|
|
|
@ -57,6 +57,7 @@ static bool sunxi_mmc_can_calibrate(void)
|
||||||
return IS_ENABLED(CONFIG_MACH_SUN50I) ||
|
return IS_ENABLED(CONFIG_MACH_SUN50I) ||
|
||||||
IS_ENABLED(CONFIG_MACH_SUN50I_H5) ||
|
IS_ENABLED(CONFIG_MACH_SUN50I_H5) ||
|
||||||
IS_ENABLED(CONFIG_SUN50I_GEN_H6) ||
|
IS_ENABLED(CONFIG_SUN50I_GEN_H6) ||
|
||||||
|
IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2) ||
|
||||||
IS_ENABLED(CONFIG_MACH_SUN8I_R40);
|
IS_ENABLED(CONFIG_MACH_SUN8I_R40);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,7 +192,7 @@ static int mmc_config_clock(struct sunxi_mmc_priv *priv, struct mmc *mmc)
|
||||||
rval &= ~SUNXI_MMC_CLK_DIVIDER_MASK;
|
rval &= ~SUNXI_MMC_CLK_DIVIDER_MASK;
|
||||||
writel(rval, &priv->reg->clkcr);
|
writel(rval, &priv->reg->clkcr);
|
||||||
|
|
||||||
#if defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6)
|
#if defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2)
|
||||||
/* A64 supports calibration of delays on MMC controller and we
|
/* A64 supports calibration of delays on MMC controller and we
|
||||||
* have to set delay of zero before starting calibration.
|
* have to set delay of zero before starting calibration.
|
||||||
* Allwinner BSP driver sets a delay only in the case of
|
* Allwinner BSP driver sets a delay only in the case of
|
||||||
|
@ -544,7 +545,7 @@ struct mmc *sunxi_mmc_init(int sdc_no)
|
||||||
|
|
||||||
/* config ahb clock */
|
/* config ahb clock */
|
||||||
debug("init mmc %d clock and io\n", sdc_no);
|
debug("init mmc %d clock and io\n", sdc_no);
|
||||||
#if !defined(CONFIG_SUN50I_GEN_H6)
|
#if !defined(CONFIG_SUN50I_GEN_H6) && !defined(CONFIG_SUNXI_GEN_NCAT2)
|
||||||
setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MMC(sdc_no));
|
setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MMC(sdc_no));
|
||||||
|
|
||||||
#ifdef CONFIG_SUNXI_GEN_SUN6I
|
#ifdef CONFIG_SUNXI_GEN_SUN6I
|
||||||
|
@ -619,7 +620,7 @@ static unsigned get_mclk_offset(void)
|
||||||
if (IS_ENABLED(CONFIG_MACH_SUN9I_A80))
|
if (IS_ENABLED(CONFIG_MACH_SUN9I_A80))
|
||||||
return 0x410;
|
return 0x410;
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_SUN50I_GEN_H6))
|
if (IS_ENABLED(CONFIG_SUN50I_GEN_H6) || IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2))
|
||||||
return 0x830;
|
return 0x830;
|
||||||
|
|
||||||
return 0x88;
|
return 0x88;
|
||||||
|
|
|
@ -19,6 +19,9 @@
|
||||||
#elif defined(CONFIG_SUN50I_GEN_H6)
|
#elif defined(CONFIG_SUN50I_GEN_H6)
|
||||||
#define SUNXI_PIO_BASE 0x0300b000
|
#define SUNXI_PIO_BASE 0x0300b000
|
||||||
#define SUNXI_R_PIO_BASE 0x07022000
|
#define SUNXI_R_PIO_BASE 0x07022000
|
||||||
|
#elif defined(CONFIG_SUNXI_GEN_NCAT2)
|
||||||
|
#define SUNXI_PIO_BASE 0x02000000
|
||||||
|
#define SUNXI_R_PIO_BASE 0x07022000
|
||||||
#else
|
#else
|
||||||
#define SUNXI_PIO_BASE 0x01c20800
|
#define SUNXI_PIO_BASE 0x01c20800
|
||||||
#define SUNXI_R_PIO_BASE 0x01f02c00
|
#define SUNXI_R_PIO_BASE 0x01f02c00
|
||||||
|
|
Loading…
Reference in a new issue