The B288 is a dual Cortex-A7 SoC of the sun8i family, used in e-readers.
Its memory map follows the H3, but the RTC, CPUCFG and SID sit where the
A20 has them, and there is no SRAM A2.
Signed-off-by: Pablo Mazzini <pmazzini@gmail.com>
---
arch/arm/cpu/armv7/sunxi/psci.c | 9 +++++++--
arch/arm/include/asm/arch-sunxi/cpu.h | 1 +
arch/arm/include/asm/arch-sunxi/cpu_sun4i.h | 16 +++++++++++++---
arch/arm/mach-sunxi/Kconfig | 13 +++++++++++++
arch/arm/mach-sunxi/board.c | 4 ++++
arch/arm/mach-sunxi/clock_sun6i.c | 1 +
arch/arm/mach-sunxi/cpu_info.c | 2 ++
include/sunxi_gpio.h | 1 +
8 files changed, 42 insertions(+), 5 deletions(-)
@@ -53,6 +53,7 @@
* CPU state, rather than the older CPUCFG system.
*/
#define SUN8I_R528_SOFT_ENTRY (0x1c8)
+#define SUN8I_B288_SOFT_ENTRY (0x1e4)
#define SUN8I_R528_C0_RST_CTRL (0x0000)
#define SUN8I_R528_C0_CTRL_REG0 (0x0010)
#define SUN8I_R528_C0_CPU_STATUS (0x0080)
@@ -126,6 +127,9 @@ static void __secure sunxi_cpu_set_entry(int __always_unused cpu, void *entry)
} else if (IS_ENABLED(CONFIG_MACH_SUN8I_R528)) {
writel((u32)entry,
SUNXI_R_CPUCFG_BASE + SUN8I_R528_SOFT_ENTRY);
+ } else if (IS_ENABLED(CONFIG_MACH_SUN8I_B288)) {
+ /* the B288 BROM takes the secondary entry from the RTC */
+ writel((u32)entry, SUNXI_RTC_BASE + SUN8I_B288_SOFT_ENTRY);
} else {
writel((u32)entry, SUNXI_CPUCFG_BASE + SUNXI_PRIV0);
}
@@ -144,8 +148,9 @@ static void __secure sunxi_cpu_set_power(int cpu, bool on)
} else if (IS_ENABLED(CONFIG_MACH_SUN8I_R40)) {
clamp = (void *)SUNXI_CPUCFG_BASE + SUN8I_R40_PWR_CLAMP(cpu);
pwroff = (void *)SUNXI_CPUCFG_BASE + SUN8I_R40_PWROFF;
- } else if (IS_ENABLED(CONFIG_MACH_SUN8I_R528)) {
- /* R528 leaves both cores powered up, manages them via reset */
+ } else if (IS_ENABLED(CONFIG_MACH_SUN8I_R528) ||
+ IS_ENABLED(CONFIG_MACH_SUN8I_B288)) {
+ /* Both leave the cores powered and manage them via reset */
return;
} else {
if (IS_ENABLED(CONFIG_MACH_SUN6I) ||
@@ -21,5 +21,6 @@
#define SOCID_V3S 0x1681
#define SOCID_H5 0x1718
#define SOCID_R40 0x1701
+#define SOCID_B288 0x1699
#endif /* _SUNXI_CPU_H */
@@ -13,7 +13,8 @@
#if defined(CONFIG_SUNXI_GEN_SUN6I) && \
!defined(CONFIG_MACH_SUN8I_R40) && \
- !defined(CONFIG_MACH_SUN8I_V3S)
+ !defined(CONFIG_MACH_SUN8I_V3S) && \
+ !defined(CONFIG_MACH_SUN8I_B288)
#define SUNXI_SRAM_A2_BASE 0x00040000
#ifdef CONFIG_MACH_SUN8I_H3
#define SUNXI_SRAM_A2_SIZE (48 * 1024) /* 16+32 kiB */
@@ -77,6 +78,9 @@ defined(CONFIG_MACH_SUN50I)
/* SID address space starts at 0x01c1400, but e-fuse is at offset 0x200 */
#define SUNXI_SIDC_BASE 0x01c14000
#define SUNXI_SID_BASE 0x01c14200
+#elif defined(CONFIG_MACH_SUN8I_B288)
+/* The H3's SID address, but with the e-fuse at offset 0, as on the A10 */
+#define SUNXI_SID_BASE 0x01c14000
#else
#define SUNXI_SID_BASE 0x01c23800
#endif
@@ -86,7 +90,8 @@ defined(CONFIG_MACH_SUN50I)
#define SUNXI_TP_BASE 0x01c25000
#define SUNXI_PMU_BASE 0x01c25400
-#if defined CONFIG_MACH_SUN7I || defined CONFIG_MACH_SUN8I_R40
+#if defined CONFIG_MACH_SUN7I || defined CONFIG_MACH_SUN8I_R40 || \
+ defined CONFIG_MACH_SUN8I_B288
#define SUNXI_CPUCFG_BASE 0x01c25c00
#endif
@@ -144,12 +149,17 @@ defined(CONFIG_MACH_SUN50I)
#define SUNXI_HDMI_BASE 0x01ee0000
#endif
+#ifdef CONFIG_MACH_SUN8I_B288
+#define SUNXI_RTC_BASE 0x01c20400
+#else
#define SUNXI_RTC_BASE 0x01f00000
+#endif
#define SUNXI_PRCM_BASE 0x01f01400
#if defined CONFIG_SUNXI_GEN_SUN6I && \
!defined CONFIG_MACH_SUN8I_A83T && \
- !defined CONFIG_MACH_SUN8I_R40
+ !defined CONFIG_MACH_SUN8I_R40 && \
+ !defined CONFIG_MACH_SUN8I_B288
#define SUNXI_CPUCFG_BASE 0x01f01c00
#endif
@@ -490,6 +490,18 @@ config MACH_SUN8I_R528
select DRAM_SUN20I_D1
imply OF_UPSTREAM
+config MACH_SUN8I_B288
+ bool "sun8i (Allwinner B288)"
+ select CPU_V7A
+ select CPU_V7_HAS_NONSEC
+ select CPU_V7_HAS_VIRT
+ select ARCH_SUPPORT_PSCI
+ select SUNXI_GEN_SUN6I
+ select SUNXI_DRAM_DW
+ select SUNXI_DRAM_DW_32BIT
+ select SUPPORT_SPL
+ imply OF_UPSTREAM
+
config MACH_SUN8I_V3S
bool "sun8i (Allwinner V3/V3s/S3/S3L)"
select CPU_V7A
@@ -579,6 +591,7 @@ config MACH_SUN8I
default y if MACH_SUNXI_H3_H5
default y if MACH_SUN8I_R40
default y if MACH_SUN8I_V3S
+ default y if MACH_SUN8I_B288
config RESERVE_ALLWINNER_BOOT0_HEADER
bool "reserve space for Allwinner boot0 header"
@@ -153,6 +153,10 @@ static int gpio_init(void)
sunxi_gpio_set_cfgpin(SUNXI_GPB(8), SUN8I_V3S_GPB_UART0);
sunxi_gpio_set_cfgpin(SUNXI_GPB(9), SUN8I_V3S_GPB_UART0);
sunxi_gpio_set_pull(SUNXI_GPB(9), SUNXI_GPIO_PULL_UP);
+#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN8I_B288)
+ sunxi_gpio_set_cfgpin(SUNXI_GPB(4), SUN8I_B288_GPB_UART0);
+ sunxi_gpio_set_cfgpin(SUNXI_GPB(5), SUN8I_B288_GPB_UART0);
+ sunxi_gpio_set_pull(SUNXI_GPB(5), SUNXI_GPIO_PULL_UP);
#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN9I)
sunxi_gpio_set_cfgpin(SUNXI_GPH(12), SUN9I_GPH_UART0);
sunxi_gpio_set_cfgpin(SUNXI_GPH(13), SUN9I_GPH_UART0);
@@ -305,6 +305,7 @@ void clock_set_pll10(unsigned int clk)
#if defined(CONFIG_MACH_SUN8I_A33) || \
defined(CONFIG_MACH_SUN8I_R40) || \
+ defined(CONFIG_MACH_SUN8I_B288) || \
defined(CONFIG_MACH_SUN50I)
void clock_set_pll11(unsigned int clk, bool sigma_delta_enable)
{
@@ -86,6 +86,8 @@ int print_cpuinfo(void)
printf("CPU: Allwinner A33 (SUN8I %04x)\n", sunxi_get_sram_id());
#elif defined CONFIG_MACH_SUN8I_A83T
printf("CPU: Allwinner A83T (SUN8I %04x)\n", sunxi_get_sram_id());
+#elif defined CONFIG_MACH_SUN8I_B288
+ printf("CPU: Allwinner B288 (SUN8I %04x)\n", sunxi_get_sram_id());
#elif defined CONFIG_MACH_SUN8I_H3
printf("CPU: Allwinner H3 (SUN8I %04x)\n", sunxi_get_sram_id());
#elif defined CONFIG_MACH_SUN8I_R40
@@ -116,6 +116,7 @@ enum sunxi_gpio_number {
#define SUN8I_A33_GPB_UART0 3
#define SUN8I_A83T_GPB_UART0 2
#define SUN8I_V3S_GPB_UART0 3
+#define SUN8I_B288_GPB_UART0 2
#define SUN50I_GPB_UART0 4
#define SUNXI_GPC_NAND 2