From: Pablo Mazzini <pmazzini@gmail.com>
To: Andre Przywara <andre.przywara@arm.com>, u-boot@lists.u-boot-project.org
Cc: Tom Rini <trini@konsulko.com>,
linux-sunxi@lists.linux.dev,
Ilias Apalodimas <ilias.apalodimas@linaro.org>
Subject: [PATCH 1/7] sunxi: add support for the Allwinner B288
Date: Fri, 16 Oct 2026 10:16:02 +0100 [thread overview]
Message-ID: <20261016091608.121842-2-pmazzini@gmail.com> (raw)
In-Reply-To: <20261016091608.121842-1-pmazzini@gmail.com>
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(-)
diff --git a/arch/arm/cpu/armv7/sunxi/psci.c b/arch/arm/cpu/armv7/sunxi/psci.c
index 4c30f3294b7..18a93546f16 100644
--- a/arch/arm/cpu/armv7/sunxi/psci.c
+++ b/arch/arm/cpu/armv7/sunxi/psci.c
@@ -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) ||
diff --git a/arch/arm/include/asm/arch-sunxi/cpu.h b/arch/arm/include/asm/arch-sunxi/cpu.h
index 768c6572d6b..7515d98959d 100644
--- a/arch/arm/include/asm/arch-sunxi/cpu.h
+++ b/arch/arm/include/asm/arch-sunxi/cpu.h
@@ -21,5 +21,6 @@
#define SOCID_V3S 0x1681
#define SOCID_H5 0x1718
#define SOCID_R40 0x1701
+#define SOCID_B288 0x1699
#endif /* _SUNXI_CPU_H */
diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
index f023a4cfd93..559544daf58 100644
--- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
+++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.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
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index b0c5d3cd903..ed2402f71f2 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -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"
diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
index 432b1c10f92..c2b01896da9 100644
--- a/arch/arm/mach-sunxi/board.c
+++ b/arch/arm/mach-sunxi/board.c
@@ -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);
diff --git a/arch/arm/mach-sunxi/clock_sun6i.c b/arch/arm/mach-sunxi/clock_sun6i.c
index 657736c7ac2..d8e549a0adb 100644
--- a/arch/arm/mach-sunxi/clock_sun6i.c
+++ b/arch/arm/mach-sunxi/clock_sun6i.c
@@ -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)
{
diff --git a/arch/arm/mach-sunxi/cpu_info.c b/arch/arm/mach-sunxi/cpu_info.c
index c3a51d9956e..7c04105ad6d 100644
--- a/arch/arm/mach-sunxi/cpu_info.c
+++ b/arch/arm/mach-sunxi/cpu_info.c
@@ -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
diff --git a/include/sunxi_gpio.h b/include/sunxi_gpio.h
index 12b54c8dda4..ad2bd0470f8 100644
--- a/include/sunxi_gpio.h
+++ b/include/sunxi_gpio.h
@@ -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
--
2.52.0
next prev parent reply other threads:[~2026-10-16 9:17 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-16 9:16 [PATCH 0/7] sunxi: add the Allwinner B288 and the PocketBook Verse Pablo Mazzini
2026-10-16 9:16 ` Pablo Mazzini [this message]
2026-10-16 9:16 ` [PATCH 2/7] sunxi: dram: support the Allwinner B288 Pablo Mazzini
2026-10-16 9:16 ` [PATCH 3/7] dt-bindings: clock: add the Allwinner B288 CCU Pablo Mazzini
2026-10-16 9:16 ` [PATCH 4/7] clk: sunxi: add the Allwinner B288 gates and resets Pablo Mazzini
2026-10-16 9:16 ` [PATCH 5/7] pinctrl: sunxi: add the Allwinner B288 PIO Pablo Mazzini
2026-10-16 9:16 ` [PATCH 6/7] mmc: sunxi: B288 mmc0/mmc1 run off PLL_PERIPH0 2x Pablo Mazzini
2026-10-16 9:16 ` [PATCH 7/7] sunxi: add the PocketBook Verse Pablo Mazzini
2026-10-16 17:28 ` [PATCH 0/7] sunxi: add the Allwinner B288 and " Andre Przywara
2026-10-16 18:38 ` Pablo Mazzini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261016091608.121842-2-pmazzini@gmail.com \
--to=pmazzini@gmail.com \
--cc=andre.przywara@arm.com \
--cc=ilias.apalodimas@linaro.org \
--cc=linux-sunxi@lists.linux.dev \
--cc=trini@konsulko.com \
--cc=u-boot@lists.u-boot-project.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox