All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/7] sunxi: add the Allwinner B288 and the PocketBook Verse
@ 2026-10-16  9:16 Pablo Mazzini
  2026-10-16  9:16 ` [PATCH 1/7] sunxi: add support for the Allwinner B288 Pablo Mazzini
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Pablo Mazzini @ 2026-10-16  9:16 UTC (permalink / raw)
  To: Andre Przywara, u-boot; +Cc: Tom Rini, linux-sunxi

The Allwinner B288 (sun8iw10p1) is a dual Cortex-A7 SoC used in e-book
readers. This series adds SPL and U-Boot support for it, and one board:
the PocketBook Verse (PB629).

The DT is still under review for Linux. Until it reaches
dts/upstream, the last patch carries a copy in arch/arm/dts.

Tested on a PB629.

Pablo Mazzini (7):
  sunxi: add support for the Allwinner B288
  sunxi: dram: support the Allwinner B288
  dt-bindings: clock: add the Allwinner B288 CCU
  clk: sunxi: add the Allwinner B288 gates and resets
  pinctrl: sunxi: add the Allwinner B288 PIO
  mmc: sunxi: B288 mmc0/mmc1 run off PLL_PERIPH0 2x
  sunxi: add the PocketBook Verse

 arch/arm/cpu/armv7/sunxi/psci.c              |   9 +-
 arch/arm/dts/Makefile                        |   2 +
 arch/arm/dts/sun8i-b288-pocketbook-verse.dts | 114 ++++++++
 arch/arm/dts/sun8i-b288.dtsi                 | 292 +++++++++++++++++++
 arch/arm/include/asm/arch-sunxi/cpu.h        |   1 +
 arch/arm/include/asm/arch-sunxi/cpu_sun4i.h  |  16 +-
 arch/arm/mach-sunxi/Kconfig                  |  14 +
 arch/arm/mach-sunxi/board.c                  |   4 +
 arch/arm/mach-sunxi/clock_sun6i.c            |   1 +
 arch/arm/mach-sunxi/cpu_info.c               |   2 +
 arch/arm/mach-sunxi/dram_sunxi_dw.c          |  97 +++++-
 board/sunxi/MAINTAINERS                      |   6 +
 configs/pocketbook_verse_defconfig           |  10 +
 drivers/clk/sunxi/Kconfig                    |   7 +
 drivers/clk/sunxi/Makefile                   |   1 +
 drivers/clk/sunxi/clk_b288.c                 | 101 +++++++
 drivers/clk/sunxi/clk_sunxi.c                |   5 +
 drivers/mmc/sunxi_mmc.c                      |   7 +
 drivers/pinctrl/sunxi/Kconfig                |   5 +
 drivers/pinctrl/sunxi/pinctrl-sunxi.c        |  22 ++
 include/dt-bindings/clock/sun8i-b288-ccu.h   |  82 ++++++
 include/dt-bindings/reset/sun8i-b288-ccu.h   |  45 +++
 include/sunxi_gpio.h                         |   1 +
 23 files changed, 827 insertions(+), 17 deletions(-)
 create mode 100644 arch/arm/dts/sun8i-b288-pocketbook-verse.dts
 create mode 100644 arch/arm/dts/sun8i-b288.dtsi
 create mode 100644 configs/pocketbook_verse_defconfig
 create mode 100644 drivers/clk/sunxi/clk_b288.c
 create mode 100644 include/dt-bindings/clock/sun8i-b288-ccu.h
 create mode 100644 include/dt-bindings/reset/sun8i-b288-ccu.h


base-commit: 65a7532545336e4b73e049a69436e255da7df961
-- 
2.52.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/7] sunxi: add support for the Allwinner B288
  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
  2026-10-16  9:16 ` [PATCH 2/7] sunxi: dram: support " Pablo Mazzini
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Pablo Mazzini @ 2026-10-16  9:16 UTC (permalink / raw)
  To: Andre Przywara, u-boot; +Cc: Tom Rini, linux-sunxi, Ilias Apalodimas

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


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/7] sunxi: dram: support the Allwinner B288
  2026-10-16  9:16 [PATCH 0/7] sunxi: add the Allwinner B288 and the PocketBook Verse Pablo Mazzini
  2026-10-16  9:16 ` [PATCH 1/7] sunxi: add support for the Allwinner B288 Pablo Mazzini
@ 2026-10-16  9:16 ` Pablo Mazzini
  2026-10-16  9:16 ` [PATCH 3/7] dt-bindings: clock: add the Allwinner B288 CCU Pablo Mazzini
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Pablo Mazzini @ 2026-10-16  9:16 UTC (permalink / raw)
  To: Andre Przywara, u-boot; +Cc: Tom Rini, linux-sunxi, Ilias Apalodimas

The B288 has the DW controller and PHY of the H3, set up as on the H5.
Gate training finds its ranks and bus width, as in the vendor code.

Signed-off-by: Pablo Mazzini <pmazzini@gmail.com>
---
 arch/arm/mach-sunxi/Kconfig         |  1 +
 arch/arm/mach-sunxi/dram_sunxi_dw.c | 97 +++++++++++++++++++++++++----
 2 files changed, 86 insertions(+), 12 deletions(-)

diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index ed2402f71f2..0326c7a976b 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -788,6 +788,7 @@ config DRAM_ODT_EN
 	depends on !MACH_SUN50I_H616
 	depends on !MACH_SUN55I_A523
 	default y if MACH_SUN8I_A23
+	default y if MACH_SUN8I_B288
 	default y if MACH_SUNXI_H3_H5
 	default y if MACH_SUN8I_R40
 	default y if MACH_SUN50I
diff --git a/arch/arm/mach-sunxi/dram_sunxi_dw.c b/arch/arm/mach-sunxi/dram_sunxi_dw.c
index 4ed295909ce..ee96186abc6 100644
--- a/arch/arm/mach-sunxi/dram_sunxi_dw.c
+++ b/arch/arm/mach-sunxi/dram_sunxi_dw.c
@@ -21,6 +21,10 @@ static void mctl_phy_init(u32 val)
 	struct sunxi_mctl_ctl_reg * const mctl_ctl =
 			(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
 
+	/* the B288 latches the configuration before triggering */
+	if (IS_ENABLED(CONFIG_MACH_SUN8I_B288))
+		writel(val, &mctl_ctl->pir);
+
 	writel(val | PIR_INIT, &mctl_ctl->pir);
 	mctl_await_completion(&mctl_ctl->pgsr[0], PGSR_INIT_DONE, 0x1);
 }
@@ -48,6 +52,11 @@ static void mctl_set_bit_delays(struct dram_para *para)
 	for (i = 0; i < 4; i++)
 		writel(0x6 << 24, &mctl_ctl->dx[i].sdlr);
 #endif
+	if (IS_ENABLED(CONFIG_MACH_SUN8I_B288)) {
+		/* boot0 uses 8 on DX0/DX1 and 6 on DX2/DX3 */
+		for (i = 0; i < 4; i++)
+			writel((i < 2 ? 0x8 : 0x6) << 24, &mctl_ctl->dx[i].sdlr);
+	}
 
 	setbits_le32(&mctl_ctl->pgcr[0], 1 << 26);
 }
@@ -248,9 +257,24 @@ static void mctl_set_master_priority_r40(void)
 	MBUS_CONF(UNKNOWN3, true,    HIGH, 0, 1280,  144,   64);
 }
 
+/*
+ * The B288 boot0 only sets the MBUS window timer: it leaves the per-port
+ * table, bwcr and mapr alone, so no master is bandwidth limited.
+ */
+static void mctl_set_master_priority_b288(void)
+{
+	struct sunxi_mctl_com_reg * const mctl_com =
+			(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
+
+	clrsetbits_le32(&mctl_com->tmr, 0xfff, 399);
+}
+
 static void mctl_set_master_priority(uint16_t socid)
 {
 	switch (socid) {
+	case SOCID_B288:
+		mctl_set_master_priority_b288();
+		return;
 	case SOCID_H3:
 		mctl_set_master_priority_h3();
 		return;
@@ -430,14 +454,15 @@ static void mctl_sys_init(uint16_t socid, struct dram_para *para)
 	clrbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MCTL);
 	clrbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MCTL);
 	clrbits_le32(&ccm->pll5_cfg, CCM_PLL5_CTRL_EN);
-	if (socid == SOCID_A64 || socid == SOCID_R40)
+	if (socid == SOCID_A64 || socid == SOCID_R40 || socid == SOCID_B288)
 		clrbits_le32(&ccm->pll11_cfg, CCM_PLL11_CTRL_EN);
 	udelay(10);
 
 	clrbits_le32(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_RST);
 	udelay(1000);
 
-	if (socid == SOCID_A64 || socid == SOCID_R40) {
+	if (socid == SOCID_A64 || socid == SOCID_R40 || socid == SOCID_B288) {
+		/* The B288 feeds the controller from PLL_DDR1 (pll11), too */
 		clock_set_pll11(CONFIG_DRAM_CLK * 2 * 1000000, false);
 		clrsetbits_le32(&ccm->dram_clk_cfg,
 				CCM_DRAMCLK_CFG_DIV_MASK |
@@ -464,7 +489,8 @@ static void mctl_sys_init(uint16_t socid, struct dram_para *para)
 	setbits_le32(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_RST);
 	udelay(10);
 
-	writel(socid == SOCID_H5 ? 0x8000 : 0xc00e, &mctl_ctl->clken);
+	writel((socid == SOCID_H5 || socid == SOCID_B288) ? 0x8000 : 0xc00e,
+	       &mctl_ctl->clken);
 	udelay(500);
 }
 
@@ -473,6 +499,14 @@ static void mctl_sys_init(uint16_t socid, struct dram_para *para)
 #define DX_GCR_ODT_ALWAYS_ON	(0x1 << 4)
 #define DX_GCR_ODT_OFF		(0x2 << 4)
 
+static void mctl_set_odtmap(struct dram_para *para)
+{
+	struct sunxi_mctl_ctl_reg * const mctl_ctl =
+			(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
+
+	writel(para->dual_rank ? 0x00000303 : 0x00000201, &mctl_ctl->odtmap);
+}
+
 static int mctl_channel_init(uint16_t socid, struct dram_para *para)
 {
 	struct sunxi_mctl_com_reg * const mctl_com =
@@ -488,7 +522,7 @@ static int mctl_channel_init(uint16_t socid, struct dram_para *para)
 
 	/* setting VTC, default disable all VT */
 	clrbits_le32(&mctl_ctl->pgcr[0], (1 << 30) | 0x3f);
-	if (socid == SOCID_H5)
+	if (socid == SOCID_H5 || socid == SOCID_B288)
 		setbits_le32(&mctl_ctl->pgcr[1], (1 << 24) | (1 << 26));
 	else
 		clrsetbits_le32(&mctl_ctl->pgcr[1], 1 << 24, 1 << 26);
@@ -515,8 +549,9 @@ static int mctl_channel_init(uint16_t socid, struct dram_para *para)
 	}
 
 	/* AC PDR should always ON */
-	clrsetbits_le32(&mctl_ctl->aciocr, socid == SOCID_H5 ? (0x1 << 11) : 0,
-			0x1 << 1);
+	clrsetbits_le32(&mctl_ctl->aciocr,
+			(socid == SOCID_H5 || socid == SOCID_B288) ?
+			(0x1 << 11) : 0, 0x1 << 1);
 
 	/* set DQS auto gating PD mode */
 	setbits_le32(&mctl_ctl->pgcr[2], 0x3 << 6);
@@ -535,7 +570,8 @@ static int mctl_channel_init(uint16_t socid, struct dram_para *para)
 		/* dphy & aphy phase select 270 degree */
 		clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8),
 				(0x1 << 10) | (0x1 << 8));
-	} else if (socid == SOCID_A64 || socid == SOCID_H5) {
+	} else if (socid == SOCID_A64 || socid == SOCID_H5 ||
+		   socid == SOCID_B288) {
 		/* dphy & aphy phase select ? */
 		clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8),
 				(0x0 << 10) | (0x3 << 8));
@@ -572,6 +608,19 @@ static int mctl_channel_init(uint16_t socid, struct dram_para *para)
 
 		mctl_phy_init(PIR_PLLINIT | PIR_DCAL | PIR_PHYRST |
 			      PIR_DRAMRST | PIR_DRAMINIT | PIR_QSGATE);
+	} else if (socid == SOCID_B288) {
+		/* A 24-bit zqcr value, as on the A64; the H3 quirk hangs */
+		clrsetbits_le32(&mctl_ctl->zqcr, 0xffffff, CONFIG_DRAM_ZQ);
+		mctl_set_odtmap(para);
+
+		/* DQS gating mode 1: gate training finds the ranks and lanes */
+		clrbits_le32(&mctl_ctl->pgcr[2], 0x3 << 6);
+		clrbits_le32(&mctl_ctl->dqsgmr, 0x107);
+		/* the vendor's training configuration */
+		clrsetbits_le32(&mctl_ctl->dtcr, 0xffffff, 0x3087);
+		mctl_phy_init(PIR_ZCAL | PIR_PLLINIT | PIR_PHYRST);
+		mctl_phy_init(PIR_DCAL | PIR_DRAMRST | PIR_DRAMINIT |
+			      PIR_QSGATE);
 	} else if (socid == SOCID_H3) {
 		mctl_h3_zq_calibration_quirk(para);
 
@@ -636,7 +685,7 @@ static int mctl_channel_init(uint16_t socid, struct dram_para *para)
 	udelay(10);
 
 	/* set PGCR3, CKE polarity */
-	if (socid == SOCID_H3 || socid == SOCID_V3S)
+	if (socid == SOCID_H3 || socid == SOCID_V3S || socid == SOCID_B288)
 		writel(0x00aa0060, &mctl_ctl->pgcr[3]);
 	else if (socid == SOCID_A64 || socid == SOCID_H5 || socid == SOCID_R40)
 		writel(0xc0aa0060, &mctl_ctl->pgcr[3]);
@@ -822,6 +871,23 @@ static void mctl_auto_detect_dram_size(uint16_t socid, struct dram_para *para)
 	   3,  3,  3,  3,  3,  3,  3,  3,			\
 	   3,  3,  3,  3,  2,  0,  0      }
 
+/* As programmed by the B288 boot0 */
+#define SUN8I_B288_DX_READ_DELAYS				\
+	{{ 16, 17, 18, 19, 18, 19, 19, 19, 16,  0,  0 },	\
+	 { 26, 26, 26, 25, 25, 25, 25, 25, 20,  0,  0 },	\
+	 { 20, 22, 24, 22, 26, 25, 25, 25, 20,  0,  0 },	\
+	 { 21, 21, 21, 20, 20, 19, 19, 19, 18,  0,  0 }}
+#define SUN8I_B288_DX_WRITE_DELAYS				\
+	{{  0,  1,  3,  3,  3,  3,  3,  4,  3, 11,  0 },	\
+	 {  3,  3,  4,  4,  3,  3,  3,  3,  3, 11,  0 },	\
+	 {  0,  3,  3,  1,  6,  6,  5,  6,  3,  9,  0 },	\
+	 {  5,  5,  6,  6,  4,  5,  3,  3,  3,  9,  0 }}
+#define SUN8I_B288_AC_DELAYS					\
+	{  0,  0,  8,  3,  0,  0,  0,  0,			\
+	   0,  0,  0,  0,  0,  0,  0,  0,			\
+	   0,  0,  0,  0,  0,  0,  0,  0,			\
+	   0,  0,  0,  0,  3,  0,  0      }
+
 unsigned long sunxi_dram_init(void)
 {
 	struct sunxi_mctl_com_reg * const mctl_com =
@@ -851,6 +917,10 @@ unsigned long sunxi_dram_init(void)
 		.dx_read_delays  = SUN8I_H3_DX_READ_DELAYS,
 		.dx_write_delays = SUN8I_H3_DX_WRITE_DELAYS,
 		.ac_delays	 = SUN8I_H3_AC_DELAYS,
+#elif defined(CONFIG_MACH_SUN8I_B288)
+		.dx_read_delays  = SUN8I_B288_DX_READ_DELAYS,
+		.dx_write_delays = SUN8I_B288_DX_WRITE_DELAYS,
+		.ac_delays	 = SUN8I_B288_AC_DELAYS,
 #elif defined(CONFIG_MACH_SUN8I_V3S)
 		.dx_read_delays  = SUN8I_V3S_DX_READ_DELAYS,
 		.dx_write_delays = SUN8I_V3S_DX_WRITE_DELAYS,
@@ -878,6 +948,8 @@ unsigned long sunxi_dram_init(void)
 	uint16_t socid = SOCID_H3;
 #elif defined(CONFIG_MACH_SUN8I_R40)
 	uint16_t socid = SOCID_R40;
+#elif defined(CONFIG_MACH_SUN8I_B288)
+	uint16_t socid = SOCID_B288;
 #elif defined(CONFIG_MACH_SUN8I_V3S)
 	uint16_t socid = SOCID_V3S;
 #elif defined(CONFIG_MACH_SUN50I)
@@ -890,12 +962,13 @@ unsigned long sunxi_dram_init(void)
 	if (mctl_channel_init(socid, &para))
 		return 0;
 
-	if (para.dual_rank)
-		writel(0x00000303, &mctl_ctl->odtmap);
-	else
-		writel(0x00000201, &mctl_ctl->odtmap);
+	mctl_set_odtmap(&para);
 	udelay(1);
 
+	/* the B288 trains with static DX clocks; dynamic from now on */
+	if (socid == SOCID_B288)
+		clrbits_le32(&mctl_ctl->pgcr[0], (0x3 << 14) | (0x3 << 12));
+
 	/* odt delay */
 	if (socid == SOCID_H3)
 		writel(0x0c000400, &mctl_ctl->odtcfg);
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 3/7] dt-bindings: clock: add the Allwinner B288 CCU
  2026-10-16  9:16 [PATCH 0/7] sunxi: add the Allwinner B288 and the PocketBook Verse Pablo Mazzini
  2026-10-16  9:16 ` [PATCH 1/7] sunxi: add support for the Allwinner B288 Pablo Mazzini
  2026-10-16  9:16 ` [PATCH 2/7] sunxi: dram: support " Pablo Mazzini
@ 2026-10-16  9:16 ` Pablo Mazzini
  2026-10-16  9:16 ` [PATCH 4/7] clk: sunxi: add the Allwinner B288 gates and resets Pablo Mazzini
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Pablo Mazzini @ 2026-10-16  9:16 UTC (permalink / raw)
  To: Andre Przywara, u-boot; +Cc: Tom Rini, linux-sunxi

The clock and reset indices of the B288 CCU, as under review for Linux.

Signed-off-by: Pablo Mazzini <pmazzini@gmail.com>
---
 include/dt-bindings/clock/sun8i-b288-ccu.h | 82 ++++++++++++++++++++++
 include/dt-bindings/reset/sun8i-b288-ccu.h | 45 ++++++++++++
 2 files changed, 127 insertions(+)
 create mode 100644 include/dt-bindings/clock/sun8i-b288-ccu.h
 create mode 100644 include/dt-bindings/reset/sun8i-b288-ccu.h

diff --git a/include/dt-bindings/clock/sun8i-b288-ccu.h b/include/dt-bindings/clock/sun8i-b288-ccu.h
new file mode 100644
index 00000000000..c9b9eaf979a
--- /dev/null
+++ b/include/dt-bindings/clock/sun8i-b288-ccu.h
@@ -0,0 +1,82 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+#ifndef _DT_BINDINGS_CLK_SUN8I_B288_H_
+#define _DT_BINDINGS_CLK_SUN8I_B288_H_
+
+#define CLK_PLL_CPUX	0
+#define CLK_PLL_AUDIO_BASE	1
+#define CLK_PLL_VIDEO0	2
+#define CLK_PLL_DDR0	3
+#define CLK_PLL_PERIPH0	4
+#define CLK_PLL_VIDEO1	5
+#define CLK_PLL_24M	6
+#define CLK_PLL_PERIPH1	7
+#define CLK_PLL_DE	8
+#define CLK_PLL_DDR1	9
+
+#define CLK_PLL_PERIPH0_2X	10
+#define CLK_PLL_PERIPH1_2X	11
+#define CLK_CPUX	12
+#define CLK_AXI	13
+#define CLK_CPUAPB	14
+#define CLK_AHB1	15
+#define CLK_APB1	16
+#define CLK_APB2	17
+
+#define CLK_NAND	18
+#define CLK_MMC0	19
+#define CLK_MMC1	20
+#define CLK_MMC2	21
+#define CLK_MMC3	22
+#define CLK_SPI0	23
+#define CLK_SPI1	24
+#define CLK_SPI2	25
+#define CLK_DRAM	26
+#define CLK_DE	27
+#define CLK_EE	28
+#define CLK_EDMA	29
+#define CLK_TCON0	30
+#define CLK_MBUS	31
+
+#define CLK_BUS_THS	32
+#define CLK_BUS_NAND	33
+#define CLK_BUS_SDMMC0_BUS	34
+#define CLK_BUS_SDMMC1_BUS	35
+#define CLK_BUS_SDMMC2_BUS	36
+#define CLK_BUS_SDMMC3_BUS	37
+#define CLK_BUS_SPI0	38
+#define CLK_BUS_SPI1	39
+#define CLK_BUS_SPI2	40
+#define CLK_BUS_I2S0	41
+#define CLK_BUS_I2S1	42
+#define CLK_BUS_SPDIF	43
+#define CLK_BUS_DSD	44
+#define CLK_BUS_DMIC	45
+#define CLK_BUS_USBOHCI0	46
+#define CLK_BUS_USBEHCI0	47
+#define CLK_BUS_USBOTG	48
+#define CLK_BUS_DE	49
+#define CLK_BUS_EE	50
+#define CLK_BUS_TCON0	51
+#define CLK_BUS_CSI	52
+#define CLK_BUS_ADDA	53
+#define CLK_BUS_SDRAM	54
+#define CLK_BUS_PSRAM	55
+#define CLK_BUS_DMA	56
+#define CLK_BUS_UART0	57
+#define CLK_BUS_UART1	58
+#define CLK_BUS_UART2	59
+#define CLK_BUS_UART3	60
+#define CLK_BUS_UART4	61
+#define CLK_BUS_UART5	62
+#define CLK_BUS_TWI0	63
+#define CLK_BUS_TWI1	64
+#define CLK_BUS_TWI2	65
+#define CLK_BUS_PIO	66
+#define CLK_BUS_GPADC	67
+#define CLK_BUS_KEYADC	68
+#define CLK_MMC0_SAMPLE	69
+#define CLK_MMC0_OUTPUT	70
+#define CLK_MMC1_SAMPLE	71
+#define CLK_MMC1_OUTPUT	72
+
+#endif
diff --git a/include/dt-bindings/reset/sun8i-b288-ccu.h b/include/dt-bindings/reset/sun8i-b288-ccu.h
new file mode 100644
index 00000000000..67514565454
--- /dev/null
+++ b/include/dt-bindings/reset/sun8i-b288-ccu.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+#ifndef _DT_BINDINGS_RST_SUN8I_B288_H_
+#define _DT_BINDINGS_RST_SUN8I_B288_H_
+
+#define RST_BUS_THS	0
+#define RST_BUS_NAND	1
+#define RST_BUS_MMC0	2
+#define RST_BUS_MMC1	3
+#define RST_BUS_MMC2	4
+#define RST_BUS_MMC3	5
+#define RST_BUS_SPI0	6
+#define RST_BUS_SPI1	7
+#define RST_BUS_SPI2	8
+#define RST_BUS_I2S0	9
+#define RST_BUS_I2S1	10
+#define RST_BUS_SPDIF	11
+#define RST_BUS_DSD	12
+#define RST_BUS_DMIC	13
+#define RST_USBPHY0	14
+#define RST_BUS_OHCI0	15
+#define RST_BUS_EHCI0	16
+#define RST_BUS_OTG	17
+#define RST_BUS_DE	18
+#define RST_BUS_EE	19
+#define RST_BUS_TCON0	20
+#define RST_BUS_CSI	21
+#define RST_BUS_ADDA	22
+#define RST_BUS_WLAN	23
+#define RST_MBUS	24
+#define RST_BUS_DRAM	25
+#define RST_BUS_PSRAM	26
+#define RST_BUS_DMA	27
+#define RST_BUS_UART0	28
+#define RST_BUS_UART1	29
+#define RST_BUS_UART2	30
+#define RST_BUS_UART3	31
+#define RST_BUS_UART4	32
+#define RST_BUS_UART5	33
+#define RST_BUS_I2C0	34
+#define RST_BUS_I2C1	35
+#define RST_BUS_I2C2	36
+#define RST_BUS_GPADC	37
+#define RST_BUS_KEYADC	38
+
+#endif
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 4/7] clk: sunxi: add the Allwinner B288 gates and resets
  2026-10-16  9:16 [PATCH 0/7] sunxi: add the Allwinner B288 and the PocketBook Verse Pablo Mazzini
                   ` (2 preceding siblings ...)
  2026-10-16  9:16 ` [PATCH 3/7] dt-bindings: clock: add the Allwinner B288 CCU Pablo Mazzini
@ 2026-10-16  9:16 ` Pablo Mazzini
  2026-10-16  9:16 ` [PATCH 5/7] pinctrl: sunxi: add the Allwinner B288 PIO Pablo Mazzini
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Pablo Mazzini @ 2026-10-16  9:16 UTC (permalink / raw)
  To: Andre Przywara, u-boot; +Cc: Tom Rini, linux-sunxi, Lukasz Majewski

The bus clock gates and resets, as in the Linux CCU driver.

Signed-off-by: Pablo Mazzini <pmazzini@gmail.com>
---
 drivers/clk/sunxi/Kconfig     |   7 +++
 drivers/clk/sunxi/Makefile    |   1 +
 drivers/clk/sunxi/clk_b288.c  | 101 ++++++++++++++++++++++++++++++++++
 drivers/clk/sunxi/clk_sunxi.c |   5 ++
 4 files changed, 114 insertions(+)
 create mode 100644 drivers/clk/sunxi/clk_b288.c

diff --git a/drivers/clk/sunxi/Kconfig b/drivers/clk/sunxi/Kconfig
index 1c1cc82719c..e4fe6f63626 100644
--- a/drivers/clk/sunxi/Kconfig
+++ b/drivers/clk/sunxi/Kconfig
@@ -52,6 +52,13 @@ config CLK_SUN8I_A23
 	  This enables common clock driver support for platforms based
 	  on Allwinner A23/A33 SoC.
 
+config CLK_SUN8I_B288
+	bool "Clock driver for Allwinner B288"
+	default MACH_SUN8I_B288
+	help
+	  This enables common clock driver support for platforms based
+	  on Allwinner B288 SoC.
+
 config CLK_SUN8I_A83T
 	bool "Clock driver for Allwinner A83T"
 	default MACH_SUN8I_A83T
diff --git a/drivers/clk/sunxi/Makefile b/drivers/clk/sunxi/Makefile
index 93b542cebcd..4f278ff551a 100644
--- a/drivers/clk/sunxi/Makefile
+++ b/drivers/clk/sunxi/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_CLK_SUN6I_A31) += clk_a31.o
 obj-$(CONFIG_CLK_SUN6I_A31_R) += clk_a31_r.o
 obj-$(CONFIG_CLK_SUN8I_A23) += clk_a23.o
 obj-$(CONFIG_CLK_SUN8I_A83T) += clk_a83t.o
+obj-$(CONFIG_CLK_SUN8I_B288) += clk_b288.o
 obj-$(CONFIG_CLK_SUN8I_R40) += clk_r40.o
 obj-$(CONFIG_CLK_SUN8I_V3S) += clk_v3s.o
 obj-$(CONFIG_CLK_SUN9I_A80) += clk_a80.o
diff --git a/drivers/clk/sunxi/clk_b288.c b/drivers/clk/sunxi/clk_b288.c
new file mode 100644
index 00000000000..505fa27f83a
--- /dev/null
+++ b/drivers/clk/sunxi/clk_b288.c
@@ -0,0 +1,101 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Allwinner B288 (sun8iw10p1) CCU gates and resets
+ */
+
+#include <clk-uclass.h>
+#include <dm.h>
+#include <errno.h>
+#include <clk/sunxi.h>
+#include <dt-bindings/clock/sun8i-b288-ccu.h>
+#include <dt-bindings/reset/sun8i-b288-ccu.h>
+#include <linux/bitops.h>
+
+static const struct ccu_clk_gate b288_gates[] = {
+	[CLK_BUS_DMA]		= GATE(0x060, BIT(6)),
+	[CLK_BUS_SDMMC0_BUS]	= GATE(0x060, BIT(8)),
+	[CLK_BUS_SDMMC1_BUS]	= GATE(0x060, BIT(9)),
+	[CLK_BUS_SDMMC2_BUS]	= GATE(0x060, BIT(10)),
+	[CLK_BUS_SDMMC3_BUS]	= GATE(0x060, BIT(11)),
+	[CLK_BUS_NAND]		= GATE(0x060, BIT(13)),
+	[CLK_BUS_SDRAM]		= GATE(0x060, BIT(14)),
+	[CLK_BUS_PSRAM]		= GATE(0x060, BIT(15)),
+	[CLK_BUS_SPI0]		= GATE(0x060, BIT(20)),
+	[CLK_BUS_SPI1]		= GATE(0x060, BIT(21)),
+	[CLK_BUS_SPI2]		= GATE(0x060, BIT(22)),
+	[CLK_BUS_USBOTG]	= GATE(0x060, BIT(24)),
+	[CLK_BUS_USBEHCI0]	= GATE(0x060, BIT(26)),
+	[CLK_BUS_USBOHCI0]	= GATE(0x060, BIT(29)),
+	[CLK_BUS_TCON0]		= GATE(0x064, BIT(4)),
+	[CLK_BUS_CSI]		= GATE(0x064, BIT(8)),
+	[CLK_BUS_DE]		= GATE(0x064, BIT(12)),
+	[CLK_BUS_EE]		= GATE(0x064, BIT(13)),
+	[CLK_BUS_ADDA]		= GATE(0x068, BIT(0)),
+	[CLK_BUS_SPDIF]		= GATE(0x068, BIT(1)),
+	[CLK_BUS_DSD]		= GATE(0x068, BIT(2)),
+	[CLK_BUS_DMIC]		= GATE(0x068, BIT(3)),
+	[CLK_BUS_PIO]		= GATE(0x068, BIT(5)),
+	[CLK_BUS_THS]		= GATE(0x068, BIT(8)),
+	[CLK_BUS_KEYADC]	= GATE(0x068, BIT(9)),
+	[CLK_BUS_GPADC]		= GATE(0x068, BIT(10)),
+	[CLK_BUS_I2S0]		= GATE(0x068, BIT(12)),
+	[CLK_BUS_I2S1]		= GATE(0x068, BIT(13)),
+	[CLK_BUS_TWI0]		= GATE(0x06c, BIT(0)),
+	[CLK_BUS_TWI1]		= GATE(0x06c, BIT(1)),
+	[CLK_BUS_TWI2]		= GATE(0x06c, BIT(2)),
+	[CLK_BUS_UART0]		= GATE(0x06c, BIT(16)),
+	[CLK_BUS_UART1]		= GATE(0x06c, BIT(17)),
+	[CLK_BUS_UART2]		= GATE(0x06c, BIT(18)),
+	[CLK_BUS_UART3]		= GATE(0x06c, BIT(19)),
+	[CLK_BUS_UART4]		= GATE(0x06c, BIT(20)),
+	[CLK_BUS_UART5]		= GATE(0x06c, BIT(21)),
+};
+
+static const struct ccu_reset b288_resets[] = {
+	[RST_USBPHY0]		= RESET(0x0cc, BIT(0)),
+	[RST_MBUS]		= RESET(0x0fc, BIT(31)),
+	[RST_BUS_DMA]		= RESET(0x2c0, BIT(6)),
+	[RST_BUS_MMC0]		= RESET(0x2c0, BIT(8)),
+	[RST_BUS_MMC1]		= RESET(0x2c0, BIT(9)),
+	[RST_BUS_MMC2]		= RESET(0x2c0, BIT(10)),
+	[RST_BUS_MMC3]		= RESET(0x2c0, BIT(11)),
+	[RST_BUS_NAND]		= RESET(0x2c0, BIT(13)),
+	[RST_BUS_DRAM]		= RESET(0x2c0, BIT(14)),
+	[RST_BUS_PSRAM]		= RESET(0x2c0, BIT(15)),
+	[RST_BUS_SPI0]		= RESET(0x2c0, BIT(20)),
+	[RST_BUS_SPI1]		= RESET(0x2c0, BIT(21)),
+	[RST_BUS_SPI2]		= RESET(0x2c0, BIT(22)),
+	[RST_BUS_OTG]		= RESET(0x2c0, BIT(24)),
+	[RST_BUS_EHCI0]		= RESET(0x2c0, BIT(26)),
+	[RST_BUS_OHCI0]		= RESET(0x2c0, BIT(29)),
+	[RST_BUS_WLAN]		= RESET(0x2c4, BIT(1)),
+	[RST_BUS_TCON0]		= RESET(0x2c4, BIT(4)),
+	[RST_BUS_CSI]		= RESET(0x2c4, BIT(8)),
+	[RST_BUS_DE]		= RESET(0x2c4, BIT(12)),
+	[RST_BUS_EE]		= RESET(0x2c4, BIT(13)),
+	[RST_BUS_ADDA]		= RESET(0x2d0, BIT(0)),
+	[RST_BUS_SPDIF]		= RESET(0x2d0, BIT(1)),
+	[RST_BUS_DSD]		= RESET(0x2d0, BIT(2)),
+	[RST_BUS_DMIC]		= RESET(0x2d0, BIT(3)),
+	[RST_BUS_THS]		= RESET(0x2d0, BIT(8)),
+	[RST_BUS_KEYADC]	= RESET(0x2d0, BIT(9)),
+	[RST_BUS_GPADC]		= RESET(0x2d0, BIT(10)),
+	[RST_BUS_I2S0]		= RESET(0x2d0, BIT(12)),
+	[RST_BUS_I2S1]		= RESET(0x2d0, BIT(13)),
+	[RST_BUS_I2C0]		= RESET(0x2d8, BIT(0)),
+	[RST_BUS_I2C1]		= RESET(0x2d8, BIT(1)),
+	[RST_BUS_I2C2]		= RESET(0x2d8, BIT(2)),
+	[RST_BUS_UART0]		= RESET(0x2d8, BIT(16)),
+	[RST_BUS_UART1]		= RESET(0x2d8, BIT(17)),
+	[RST_BUS_UART2]		= RESET(0x2d8, BIT(18)),
+	[RST_BUS_UART3]		= RESET(0x2d8, BIT(19)),
+	[RST_BUS_UART4]		= RESET(0x2d8, BIT(20)),
+	[RST_BUS_UART5]		= RESET(0x2d8, BIT(21)),
+};
+
+const struct ccu_desc b288_ccu_desc = {
+	.gates = b288_gates,
+	.resets = b288_resets,
+	.num_gates = ARRAY_SIZE(b288_gates),
+	.num_resets = ARRAY_SIZE(b288_resets),
+};
diff --git a/drivers/clk/sunxi/clk_sunxi.c b/drivers/clk/sunxi/clk_sunxi.c
index 046d5d1605a..5f40f30fe89 100644
--- a/drivers/clk/sunxi/clk_sunxi.c
+++ b/drivers/clk/sunxi/clk_sunxi.c
@@ -117,6 +117,7 @@ extern const struct ccu_desc a64_ccu_desc;
 extern const struct ccu_desc a80_ccu_desc;
 extern const struct ccu_desc a80_mmc_clk_desc;
 extern const struct ccu_desc a83t_ccu_desc;
+extern const struct ccu_desc b288_ccu_desc;
 extern const struct ccu_desc d1_ccu_desc;
 extern const struct ccu_desc f1c100s_ccu_desc;
 extern const struct ccu_desc h3_ccu_desc;
@@ -154,6 +155,10 @@ static const struct udevice_id sunxi_clk_ids[] = {
 	{ .compatible = "allwinner,sun8i-a33-ccu",
 	  .data = (ulong)&a23_ccu_desc },
 #endif
+#ifdef CONFIG_CLK_SUN8I_B288
+	{ .compatible = "allwinner,sun8i-b288-ccu",
+	  .data = (ulong)&b288_ccu_desc },
+#endif
 #ifdef CONFIG_CLK_SUN8I_A83T
 	{ .compatible = "allwinner,sun8i-a83t-ccu",
 	  .data = (ulong)&a83t_ccu_desc },
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 5/7] pinctrl: sunxi: add the Allwinner B288 PIO
  2026-10-16  9:16 [PATCH 0/7] sunxi: add the Allwinner B288 and the PocketBook Verse Pablo Mazzini
                   ` (3 preceding siblings ...)
  2026-10-16  9:16 ` [PATCH 4/7] clk: sunxi: add the Allwinner B288 gates and resets Pablo Mazzini
@ 2026-10-16  9:16 ` 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
  6 siblings, 0 replies; 8+ messages in thread
From: Pablo Mazzini @ 2026-10-16  9:16 UTC (permalink / raw)
  To: Andre Przywara, u-boot; +Cc: Tom Rini, linux-sunxi

The pin functions used by the PocketBook Verse.

Signed-off-by: Pablo Mazzini <pmazzini@gmail.com>
---
 drivers/pinctrl/sunxi/Kconfig         |  5 +++++
 drivers/pinctrl/sunxi/pinctrl-sunxi.c | 22 ++++++++++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig
index 54314992299..748a4140fbd 100644
--- a/drivers/pinctrl/sunxi/Kconfig
+++ b/drivers/pinctrl/sunxi/Kconfig
@@ -54,6 +54,11 @@ config PINCTRL_SUN8I_A33
 	default MACH_SUN8I_A33
 	select PINCTRL_SUNXI
 
+config PINCTRL_SUN8I_B288
+	bool "Support for the Allwinner B288 PIO"
+	default MACH_SUN8I_B288
+	select PINCTRL_SUNXI
+
 config PINCTRL_SUN8I_A83T
 	bool "Support for the Allwinner A83T PIO"
 	default MACH_SUN8I_A83T
diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
index ab4e88c9918..29219c11b93 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
@@ -448,6 +448,22 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a33_pinctrl_desc = {
 	.num_banks	= 8,
 };
 
+static const struct sunxi_pinctrl_function sun8i_b288_pinctrl_functions[] = {
+	{ "gpio_in",	0 },
+	{ "gpio_out",	1 },
+	{ "i2c0",	2 },	/* PB6-PB7 */
+	{ "mmc0",	2 },	/* PF0-PF5 */
+	{ "mmc3",	5 },	/* PC1, PC4-PC14 */
+	{ "uart0",	2 },	/* PB4-PB5 */
+};
+
+static const struct sunxi_pinctrl_desc __maybe_unused sun8i_b288_pinctrl_desc = {
+	.functions	= sun8i_b288_pinctrl_functions,
+	.num_functions	= ARRAY_SIZE(sun8i_b288_pinctrl_functions),
+	.first_bank	= SUNXI_GPIO_A,
+	.num_banks	= 7,
+};
+
 static const struct sunxi_pinctrl_function sun8i_a83t_pinctrl_functions[] = {
 	{ "gmac",	4 },	/* PD2-PD23 */
 	{ "gpio_in",	0 },
@@ -912,6 +928,12 @@ static const struct udevice_id sunxi_pinctrl_ids[] = {
 		.data = (ulong)&sun8i_a33_pinctrl_desc,
 	},
 #endif
+#ifdef CONFIG_PINCTRL_SUN8I_B288
+	{
+		.compatible = "allwinner,sun8i-b288-pinctrl",
+		.data = (ulong)&sun8i_b288_pinctrl_desc,
+	},
+#endif
 #ifdef CONFIG_PINCTRL_SUN8I_A83T
 	{
 		.compatible = "allwinner,sun8i-a83t-pinctrl",
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 6/7] mmc: sunxi: B288 mmc0/mmc1 run off PLL_PERIPH0 2x
  2026-10-16  9:16 [PATCH 0/7] sunxi: add the Allwinner B288 and the PocketBook Verse Pablo Mazzini
                   ` (4 preceding siblings ...)
  2026-10-16  9:16 ` [PATCH 5/7] pinctrl: sunxi: add the Allwinner B288 PIO Pablo Mazzini
@ 2026-10-16  9:16 ` Pablo Mazzini
  2026-10-16  9:16 ` [PATCH 7/7] sunxi: add the PocketBook Verse Pablo Mazzini
  6 siblings, 0 replies; 8+ messages in thread
From: Pablo Mazzini @ 2026-10-16  9:16 UTC (permalink / raw)
  To: Andre Przywara, u-boot
  Cc: Tom Rini, linux-sunxi, Peng Fan, Tanmay Kathpalia, Jaehoon Chung

Their mux input 1 is PLL_PERIPH0 2x, and unlike mmc2/mmc3 they do not
halve it.

Signed-off-by: Pablo Mazzini <pmazzini@gmail.com>
---
 drivers/mmc/sunxi_mmc.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
index 84f4e4c2198..7329ca3e24e 100644
--- a/drivers/mmc/sunxi_mmc.c
+++ b/drivers/mmc/sunxi_mmc.c
@@ -100,6 +100,13 @@ static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz)
 		if (IS_ENABLED(CONFIG_MACH_SUN8I_R528))
 			pll_hz /= 2;
 
+		/*
+		 * The B288's mux input 1 is PLL_PERIPH0 2x, and only the
+		 * mmc2/mmc3 controllers halve it.
+		 */
+		if (IS_ENABLED(CONFIG_MACH_SUN8I_B288) && priv->mmc_no < 2)
+			pll_hz *= 2;
+
 		/*
 		 * The A523/T527 uses PERIPH0_400M as the MMC0/1 input clock,
 		 * and PERIPH0_800M for MMC2. There is also the hidden divider
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 7/7] sunxi: add the PocketBook Verse
  2026-10-16  9:16 [PATCH 0/7] sunxi: add the Allwinner B288 and the PocketBook Verse Pablo Mazzini
                   ` (5 preceding siblings ...)
  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 ` Pablo Mazzini
  6 siblings, 0 replies; 8+ messages in thread
From: Pablo Mazzini @ 2026-10-16  9:16 UTC (permalink / raw)
  To: Andre Przywara, u-boot; +Cc: Tom Rini, linux-sunxi, Ilias Apalodimas

An Allwinner B288 e-reader. The DT is a copy of the one under review for
Linux, until it can come from dts/upstream.

Signed-off-by: Pablo Mazzini <pmazzini@gmail.com>
---
 arch/arm/dts/Makefile                        |   2 +
 arch/arm/dts/sun8i-b288-pocketbook-verse.dts | 114 ++++++++
 arch/arm/dts/sun8i-b288.dtsi                 | 292 +++++++++++++++++++
 board/sunxi/MAINTAINERS                      |   6 +
 configs/pocketbook_verse_defconfig           |  10 +
 5 files changed, 424 insertions(+)
 create mode 100644 arch/arm/dts/sun8i-b288-pocketbook-verse.dts
 create mode 100644 arch/arm/dts/sun8i-b288.dtsi
 create mode 100644 configs/pocketbook_verse_defconfig

diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 099e3f082b6..039fbab2a90 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -586,6 +586,8 @@ dtb-$(CONFIG_MACH_SUN8I_A83T) += \
 	sun8i-a83t-bananapi-m3.dtb \
 	sun8i-a83t-cubietruck-plus.dtb \
 	sun8i-a83t-tbs-a711.dtb
+dtb-$(CONFIG_MACH_SUN8I_B288) += \
+	sun8i-b288-pocketbook-verse.dtb
 dtb-$(CONFIG_MACH_SUN8I_H3) += \
 	sun8i-h2-plus-bananapi-m2-zero.dtb \
 	sun8i-h2-plus-libretech-all-h3-cc.dtb \
diff --git a/arch/arm/dts/sun8i-b288-pocketbook-verse.dts b/arch/arm/dts/sun8i-b288-pocketbook-verse.dts
new file mode 100644
index 00000000000..a60cbb63801
--- /dev/null
+++ b/arch/arm/dts/sun8i-b288-pocketbook-verse.dts
@@ -0,0 +1,114 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * PocketBook Verse (PB629), an Allwinner B288 based e-reader.
+ */
+
+/dts-v1/;
+#include "sun8i-b288.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	model = "PocketBook Verse";
+	compatible = "pocketbook,verse", "allwinner,sun8i-b288";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_pb_pins>;
+	status = "okay";
+};
+
+&mmc0 {
+	vmmc-supply = <&reg_dldo2>;
+	bus-width = <4>;
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;	/* PF6 */
+	disable-wp;
+	status = "okay";
+};
+
+&mmc3 {
+	vmmc-supply = <&reg_dcdc1>;
+	vqmmc-supply = <&reg_dldo1>;
+	bus-width = <8>;
+	non-removable;
+	cap-mmc-hw-reset;
+	mmc-ddr-1_8v;
+	mmc-hs200-1_8v;
+	status = "okay";
+};
+
+&pio {
+	vcc-pc-supply = <&reg_dldo1>;
+	vcc-pd-supply = <&reg_dldo1>;
+};
+
+&i2c0 {
+	status = "okay";
+
+	axp22x: pmic@34 {
+		/* labelled AXP227 */
+		compatible = "x-powers,axp221";
+		reg = <0x34>;
+		interrupt-parent = <&nmi_intc>;
+		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+	};
+};
+
+#include "axp22x.dtsi"
+
+&reg_dcdc1 {
+	regulator-always-on;
+	regulator-min-microvolt = <3000000>;
+	regulator-max-microvolt = <3000000>;
+	regulator-name = "vcc-io";
+};
+
+&reg_dcdc2 {
+	regulator-always-on;
+	regulator-min-microvolt = <1260000>;
+	regulator-max-microvolt = <1260000>;
+	regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc4 {
+	regulator-always-on;
+	regulator-min-microvolt = <1100000>;
+	regulator-max-microvolt = <1100000>;
+	regulator-name = "vdd-sys";
+};
+
+&reg_dcdc5 {
+	regulator-always-on;
+	regulator-min-microvolt = <1350000>;
+	regulator-max-microvolt = <1350000>;
+	regulator-name = "vcc-dram";
+};
+
+&reg_aldo3 {
+	regulator-always-on;
+	regulator-min-microvolt = <3000000>;
+	regulator-max-microvolt = <3000000>;
+	regulator-name = "avcc";
+};
+
+&reg_dldo1 {
+	regulator-min-microvolt = <1800000>;
+	regulator-max-microvolt = <1800000>;
+	regulator-name = "vcc-pc";
+};
+
+&reg_dldo2 {
+	/* microSD slot */
+	regulator-min-microvolt = <3300000>;
+	regulator-max-microvolt = <3300000>;
+	regulator-name = "vcc-sdcv";
+};
diff --git a/arch/arm/dts/sun8i-b288.dtsi b/arch/arm/dts/sun8i-b288.dtsi
new file mode 100644
index 00000000000..53832ea9dc0
--- /dev/null
+++ b/arch/arm/dts/sun8i-b288.dtsi
@@ -0,0 +1,292 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Allwinner B288 (sun8iw10p1) SoC
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/sun6i-rtc.h>
+#include <dt-bindings/clock/sun8i-b288-ccu.h>
+#include <dt-bindings/reset/sun8i-b288-ccu.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	interrupt-parent = <&gic>;
+
+	osc24M: osc24M-clk {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <24000000>;
+		clock-output-names = "osc24M";
+	};
+
+	osc32k: osc32k-clk {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <32768>;
+		clock-output-names = "ext-osc32k";
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: cpu@0 {
+			compatible = "arm,cortex-a7";
+			device_type = "cpu";
+			reg = <0>;
+			clocks = <&ccu CLK_CPUX>;
+			clock-names = "cpu";
+		};
+
+		cpu1: cpu@1 {
+			compatible = "arm,cortex-a7";
+			device_type = "cpu";
+			reg = <1>;
+			clocks = <&ccu CLK_CPUX>;
+			clock-names = "cpu";
+		};
+	};
+
+	timer {
+		compatible = "arm,armv7-timer";
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		nmi_intc: interrupt-controller@1c000d0 {
+			compatible = "allwinner,sun8i-b288-nmi",
+				     "allwinner,sun9i-a80-nmi";
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			reg = <0x01c000d0 0x0c>;
+			interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		/*
+		 * mmc0 is a v4p1x controller, so it runs in the old timing
+		 * mode and needs the sample and output phase clocks.
+		 */
+		mmc0: mmc@1c0f000 {
+			compatible = "allwinner,sun8i-b288-mmc",
+				     "allwinner,sun7i-a20-mmc";
+			reg = <0x01c0f000 0x1000>;
+			clocks = <&ccu CLK_BUS_SDMMC0_BUS>,
+				 <&ccu CLK_MMC0>,
+				 <&ccu CLK_MMC0_OUTPUT>,
+				 <&ccu CLK_MMC0_SAMPLE>;
+			clock-names = "ahb", "mmc", "output", "sample";
+			resets = <&ccu RST_BUS_MMC0>;
+			reset-names = "ahb";
+			interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&mmc0_pins>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		mmc3: mmc@1c12000 {
+			compatible = "allwinner,sun8i-b288-emmc",
+				     "allwinner,sun50i-a64-emmc";
+			reg = <0x01c12000 0x1000>;
+			clocks = <&ccu CLK_BUS_SDMMC3_BUS>, <&ccu CLK_MMC3>;
+			clock-names = "ahb", "mmc";
+			resets = <&ccu RST_BUS_MMC3>;
+			reset-names = "ahb";
+			interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&mmc3_pins>;
+			max-frequency = <150000000>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		/* mmc2 @0x01c11000 is an unsupported SDHCI-style controller. */
+
+		ccu: clock-controller@1c20000 {
+			compatible = "allwinner,sun8i-b288-ccu";
+			reg = <0x01c20000 0x400>;
+			clocks = <&osc24M>, <&rtc CLK_OSC32K>;
+			clock-names = "hosc", "losc";
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+		};
+
+		rtc: rtc@1c20400 {
+			compatible = "allwinner,sun8i-b288-rtc";
+			reg = <0x01c20400 0x400>;
+			interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+			clock-output-names = "osc32k", "osc32k-out";
+			clocks = <&osc32k>;
+			#clock-cells = <1>;
+		};
+
+		pio: pinctrl@1c20800 {
+			compatible = "allwinner,sun8i-b288-pinctrl";
+			reg = <0x01c20800 0x400>;
+			interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_PIO>, <&osc24M>, <&rtc CLK_OSC32K>;
+			clock-names = "apb", "hosc", "losc";
+			gpio-controller;
+			#gpio-cells = <3>;
+			interrupt-controller;
+			#interrupt-cells = <3>;
+
+			mmc0_pins: mmc0-pins {
+				pins = "PF0", "PF1", "PF2",
+				       "PF3", "PF4", "PF5";
+				function = "mmc0";
+				allwinner,pinmux = <2>;
+				drive-strength = <30>;
+				bias-pull-up;
+			};
+
+			i2c0_pins: i2c0-pins {
+				pins = "PB6", "PB7";
+				function = "i2c0";
+				allwinner,pinmux = <2>;
+			};
+
+			mmc3_pins: mmc3-pins {
+				pins = "PC1", "PC4", "PC5", "PC6",
+				       "PC7", "PC8", "PC9", "PC10",
+				       "PC11", "PC12", "PC13", "PC14";
+				function = "mmc3";
+				allwinner,pinmux = <5>;
+				drive-strength = <40>;
+				bias-pull-up;
+			};
+
+			uart0_pb_pins: uart0-pb-pins {
+				pins = "PB4", "PB5";
+				function = "uart0";
+				allwinner,pinmux = <2>;
+			};
+		};
+
+		wdt: watchdog@1c20ca0 {
+			compatible = "allwinner,sun8i-b288-wdt",
+				     "allwinner,sun6i-a31-wdt";
+			reg = <0x01c20ca0 0x20>;
+			interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&osc24M>;
+		};
+
+		uart0: serial@1c28000 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x01c28000 0x400>;
+			interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&ccu CLK_BUS_UART0>;
+			resets = <&ccu RST_BUS_UART0>;
+			status = "disabled";
+		};
+
+		uart1: serial@1c28400 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x01c28400 0x400>;
+			interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&ccu CLK_BUS_UART1>;
+			resets = <&ccu RST_BUS_UART1>;
+			status = "disabled";
+		};
+
+		uart2: serial@1c28800 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x01c28800 0x400>;
+			interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&ccu CLK_BUS_UART2>;
+			resets = <&ccu RST_BUS_UART2>;
+			status = "disabled";
+		};
+
+		uart3: serial@1c28c00 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x01c28c00 0x400>;
+			interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&ccu CLK_BUS_UART3>;
+			resets = <&ccu RST_BUS_UART3>;
+			status = "disabled";
+		};
+
+		uart4: serial@1c29000 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x01c29000 0x400>;
+			interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&ccu CLK_BUS_UART4>;
+			resets = <&ccu RST_BUS_UART4>;
+			status = "disabled";
+		};
+
+		i2c0: i2c@1c2ac00 {
+			compatible = "allwinner,sun8i-b288-i2c",
+				     "allwinner,sun6i-a31-i2c";
+			reg = <0x01c2ac00 0x400>;
+			interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_TWI0>;
+			resets = <&ccu RST_BUS_I2C0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c0_pins>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		i2c1: i2c@1c2b000 {
+			compatible = "allwinner,sun8i-b288-i2c",
+				     "allwinner,sun6i-a31-i2c";
+			reg = <0x01c2b000 0x400>;
+			interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_TWI1>;
+			resets = <&ccu RST_BUS_I2C1>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		i2c2: i2c@1c2b400 {
+			compatible = "allwinner,sun8i-b288-i2c",
+				     "allwinner,sun6i-a31-i2c";
+			reg = <0x01c2b400 0x400>;
+			interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_TWI2>;
+			resets = <&ccu RST_BUS_I2C2>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		gic: interrupt-controller@1c81000 {
+			compatible = "arm,gic-400";
+			reg = <0x01c81000 0x1000>,
+			      <0x01c82000 0x2000>,
+			      <0x01c84000 0x2000>,
+			      <0x01c86000 0x2000>;
+			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
+			interrupt-controller;
+			#interrupt-cells = <3>;
+		};
+	};
+};
diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS
index df745f14649..53fd2666f21 100644
--- a/board/sunxi/MAINTAINERS
+++ b/board/sunxi/MAINTAINERS
@@ -539,6 +539,12 @@ M:	Arnaud Ferraris <arnaud.ferraris@collabora.com>
 S:	Maintained
 F:	configs/pinetab_defconfig
 
+POCKETBOOK VERSE BOARD
+M:	Pablo Mazzini <pmazzini@gmail.com>
+S:	Maintained
+F:	arch/arm/dts/sun8i-b288*
+F:	configs/pocketbook_verse_defconfig
+
 R16 EVB PARROT BOARD
 M:	Quentin Schulz <quentin.schulz@free-electrons.com>
 S:	Maintained
diff --git a/configs/pocketbook_verse_defconfig b/configs/pocketbook_verse_defconfig
new file mode 100644
index 00000000000..df86ab4b786
--- /dev/null
+++ b/configs/pocketbook_verse_defconfig
@@ -0,0 +1,10 @@
+CONFIG_ARM=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_DEFAULT_DEVICE_TREE="sun8i-b288-pocketbook-verse"
+CONFIG_DRAM_CLK=672
+CONFIG_SPL=y
+CONFIG_MACH_SUN8I_B288=y
+CONFIG_DRAM_ZQ=3881977
+# CONFIG_HAS_ARMV7_SECURE_BASE is not set
+# CONFIG_OF_UPSTREAM is not set
+CONFIG_NO_NET=y
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-10-16  9:17 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-16  9:16 [PATCH 0/7] sunxi: add the Allwinner B288 and the PocketBook Verse Pablo Mazzini
2026-10-16  9:16 ` [PATCH 1/7] sunxi: add support for the Allwinner B288 Pablo Mazzini
2026-10-16  9:16 ` [PATCH 2/7] sunxi: dram: support " 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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.