BananaPi BPI-M4-Zero: `Update u-boot to v2025.01`

Signed-off-by: Patrick Yavitz <pyavitz@gmail.com>
This commit is contained in:
Patrick Yavitz 2025-06-29 20:41:06 -04:00 committed by Igor
parent 8677a9af21
commit f349c76904
8 changed files with 899 additions and 2 deletions

View File

@ -10,8 +10,8 @@ KERNEL_TARGET="current,edge"
KERNEL_TEST_TARGET="current"
MODULES_BLACKLIST="rtw88_8821c rtw88_8821cu"
FORCE_BOOTSCRIPT_UPDATE="yes"
BOOTBRANCH_BOARD="tag:v2024.04"
BOOTPATCHDIR="v2024.04"
BOOTBRANCH_BOARD="tag:v2025.01"
BOOTPATCHDIR="v2025.01"
PACKAGE_LIST_BOARD="rfkill bluetooth bluez bluez-tools"
function post_family_tweaks_bsp__bananapi_firmware() {

View File

@ -0,0 +1,385 @@
From 60419770c7390799776d0063b02285758723988e Mon Sep 17 00:00:00 2001
From: Patrick Yavitz <pyavitz@gmail.com>
Date: Sat, 4 Jan 2025 08:27:46 -0500
Subject: [PATCH] Add board BananaPi BPI-M4-Zero
sun50i-h618-bananapi-m4-zero.dts
sun50i-h618-bananapi-m4.dtsi
bananapi_m4zero_defconfig
Signed-off-by: Patrick Yavitz <pyavitz@gmail.com>
---
configs/bananapi_m4zero_defconfig | 30 +++
.../src/arm64/allwinner/sun50i-h616.dtsi | 18 ++
.../sun50i-h618-bananapi-m4-zero.dts | 77 +++++++
.../allwinner/sun50i-h618-bananapi-m4.dtsi | 208 ++++++++++++++++++
4 files changed, 333 insertions(+)
create mode 100644 configs/bananapi_m4zero_defconfig
create mode 100644 dts/upstream/src/arm64/allwinner/sun50i-h618-bananapi-m4-zero.dts
create mode 100644 dts/upstream/src/arm64/allwinner/sun50i-h618-bananapi-m4.dtsi
diff --git a/configs/bananapi_m4zero_defconfig b/configs/bananapi_m4zero_defconfig
new file mode 100644
index 00000000000..51f01e37edc
--- /dev/null
+++ b/configs/bananapi_m4zero_defconfig
@@ -0,0 +1,30 @@
+CONFIG_OF_UPSTREAM=y
+CONFIG_ARM=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_DEFAULT_DEVICE_TREE="allwinner/sun50i-h618-bananapi-m4-zero"
+CONFIG_SPL=y
+CONFIG_DRAM_SUN50I_H616_DX_ODT=0x07070707
+CONFIG_DRAM_SUN50I_H616_DX_DRI=0x0e0e0e0e
+CONFIG_DRAM_SUN50I_H616_CA_DRI=0x0e0e
+CONFIG_DRAM_SUN50I_H616_ODT_EN=0xaaaaeeee
+CONFIG_DRAM_SUN50I_H616_TPR6=0x48808080
+CONFIG_DRAM_SUN50I_H616_TPR10=0x402f6663
+CONFIG_DRAM_SUN50I_H616_TPR11=0x26262524
+CONFIG_DRAM_SUN50I_H616_TPR12=0x100f100f
+CONFIG_MACH_SUN50I_H616=y
+CONFIG_SUNXI_DRAM_H616_LPDDR4=y
+CONFIG_DRAM_CLK=792
+CONFIG_MMC_SUNXI_SLOT_EXTRA=2
+CONFIG_R_I2C_ENABLE=y
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_SPL_I2C=y
+CONFIG_SPL_SYS_I2C_LEGACY=y
+CONFIG_SYS_I2C_MVTWSI=y
+CONFIG_SYS_I2C_SLAVE=0x7f
+CONFIG_SYS_I2C_SPEED=400000
+CONFIG_SUN8I_EMAC=y
+CONFIG_SUPPORT_EMMC_BOOT=y
+CONFIG_AXP313_POWER=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_MUSB_GADGET=y
diff --git a/dts/upstream/src/arm64/allwinner/sun50i-h616.dtsi b/dts/upstream/src/arm64/allwinner/sun50i-h616.dtsi
index e88c1fbac6a..9a23d4bd05b 100644
--- a/dts/upstream/src/arm64/allwinner/sun50i-h616.dtsi
+++ b/dts/upstream/src/arm64/allwinner/sun50i-h616.dtsi
@@ -335,6 +335,24 @@
function = "uart1";
};
+ /omit-if-no-ref/
+ uart4_pi_pins: uart4-pi-pins {
+ pins = "PI13", "PI14";
+ function = "uart4";
+ };
+
+ /omit-if-no-ref/
+ uart4_pi_rts_cts_pins: uart4-pi-rts-cts-pins {
+ pins = "PI15", "PI16";
+ function = "uart4";
+ };
+
+ /omit-if-no-ref/
+ uart5_ph_pins: uart5-ph-pins {
+ pins = "PH2", "PH3";
+ function = "uart5";
+ };
+
/omit-if-no-ref/
x32clk_fanout_pin: x32clk-fanout-pin {
pins = "PG10";
diff --git a/dts/upstream/src/arm64/allwinner/sun50i-h618-bananapi-m4-zero.dts b/dts/upstream/src/arm64/allwinner/sun50i-h618-bananapi-m4-zero.dts
new file mode 100644
index 00000000000..dde03092cf0
--- /dev/null
+++ b/dts/upstream/src/arm64/allwinner/sun50i-h618-bananapi-m4-zero.dts
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2024 Patrick Yavitz <pyavitz@gmail.com>
+ */
+
+/dts-v1/;
+
+#include "sun50i-h618-bananapi-m4.dtsi"
+
+/ {
+ model = "BananaPi BPI-M4-Zero";
+ compatible = "sinovoip,bpi-m4-zero", "allwinner,sun50i-h618";
+
+ aliases {
+ serial5 = &uart5;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-0 {
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_STATUS;
+ gpios = <&pio 2 12 GPIO_ACTIVE_HIGH>; /* PC12 */
+ linux,default-trigger = "heartbeat";
+ };
+ };
+};
+
+/* Connected to an on-board RTL8821CU USB WiFi chip. */
+&ehci1 {
+ status = "disabled";
+};
+
+&ehci3 {
+ status = "okay";
+};
+
+&emac0 {
+ status = "disabled";
+};
+
+/* SDIO */
+&mmc1 {
+ status = "disabled";
+ bus-width = <4>;
+ max-frequency = <100000000>;
+
+ non-removable;
+ disable-wp;
+
+ /* WiFi firmware requires power to be kept while in suspend */
+ keep-power-in-suspend;
+
+ mmc-pwrseq = <&wifi_pwrseq>;
+
+ cd-gpios = <&pio 6 15 GPIO_ACTIVE_HIGH>; /* PG15 */
+ vmmc-supply = <&reg_vcc3v3>;
+
+ sdio: wifi@1 {
+ reg = <1>;
+ compatible = "brcm,bcm4329-fmac";
+ };
+};
+
+&ohci3 {
+ status = "okay";
+};
+
+&usbotg {
+ status = "okay";
+ dr_mode = "peripheral";
+};
+
+&usbphy {
+ status = "okay";
+};
diff --git a/dts/upstream/src/arm64/allwinner/sun50i-h618-bananapi-m4.dtsi b/dts/upstream/src/arm64/allwinner/sun50i-h618-bananapi-m4.dtsi
new file mode 100644
index 00000000000..2e8567d01f3
--- /dev/null
+++ b/dts/upstream/src/arm64/allwinner/sun50i-h618-bananapi-m4.dtsi
@@ -0,0 +1,208 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2024 Patrick Yavitz <pyavitz@gmail.com>
+ */
+
+/dts-v1/;
+
+#include "sun50i-h616.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ aliases {
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ reg_usb_vbus: regulator-usb-vbus {
+ /* Separate discrete regulator for the USB ports */
+ compatible = "regulator-fixed";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-name = "usb-vbus";
+ vin-supply = <&reg_vcc5v>;
+ };
+
+ reg_vcc5v: regulator-vcc5v {
+ /* Board wide 5V supply directly from the USB-C socket */
+ compatible = "regulator-fixed";
+ regulator-always-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-name = "vcc-5v";
+ };
+
+ reg_vcc3v3: regulator-vcc3v3 {
+ compatible = "regulator-fixed";
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-3v3";
+ vin-supply = <&reg_vcc5v>;
+ };
+
+ reg_vcc1v8: regulator-vcc1v8 {
+ compatible = "regulator-fixed";
+ regulator-always-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc-1v8";
+ vin-supply = <&reg_vcc3v3>;
+ };
+
+ wifi_pwrseq: wifi-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ clocks = <&rtc CLK_OSC32K_FANOUT>;
+ clock-names = "ext_clock";
+ pinctrl-0 = <&x32clk_fanout_pin>;
+ pinctrl-names = "default";
+ post-power-on-delay-ms = <200>;
+ reset-gpios = <&pio 6 18 GPIO_ACTIVE_LOW>; /* PG18 */
+ };
+};
+
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+};
+
+&emac0 {
+ status = "okay";
+ pinctrl-0 = <&ext_rgmii_pins>;
+ pinctrl-names = "default";
+ phy-mode = "rgmii";
+ phy-handle = <&ext_rgmii_phy>;
+ phy-supply = <&reg_dldo1>;
+ allwinner,rx-delay-ps = <3100>;
+ allwinner,tx-delay-ps = <700>;
+};
+
+&ir {
+ status = "disabled";
+ pinctrl-0 = <&ir_rx_pin>;
+ pinctrl-names = "default";
+};
+
+&mdio0 {
+ ext_rgmii_phy: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ };
+};
+
+/* SD card */
+&mmc0 {
+ status = "okay";
+ bus-width = <4>;
+ max-frequency = <50000000>;
+
+ disable-wp;
+
+ cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */
+ vmmc-supply = <&reg_vcc3v3>;
+};
+
+/* eMMC */
+&mmc2 {
+ status = "okay";
+ bus-width = <8>;
+ cap-mmc-hw-reset;
+ mmc-hs200-1_8v;
+
+ non-removable;
+ disable-wp;
+
+ vmmc-supply = <&reg_vcc3v3>;
+ vqmmc-supply = <&reg_vcc1v8>;
+};
+
+&pio {
+ vcc-pc-supply = <&reg_aldo1>;
+ vcc-pf-supply = <&reg_dldo1>;
+ vcc-pg-supply = <&reg_dldo1>;
+ vcc-ph-supply = <&reg_dldo1>;
+ vcc-pi-supply = <&reg_dldo1>;
+};
+
+&r_i2c {
+ status = "okay";
+
+ axp313: pmic@36 {
+ compatible = "x-powers,axp313a";
+ reg = <0x36>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ interrupt-parent = <&pio>;
+
+ vin1-supply = <&reg_vcc5v>;
+ vin2-supply = <&reg_vcc5v>;
+ vin3-supply = <&reg_vcc5v>;
+
+ regulators {
+ reg_aldo1: aldo1 {
+ regulator-always-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc-1v8-pll";
+ };
+
+ reg_dldo1: dldo1 {
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-3v3-io";
+ };
+
+ reg_dcdc1: dcdc1 {
+ regulator-always-on;
+ regulator-min-microvolt = <810000>;
+ regulator-max-microvolt = <990000>;
+ regulator-name = "vdd-gpu-sys";
+ };
+
+ reg_dcdc2: dcdc2 {
+ regulator-always-on;
+ regulator-min-microvolt = <810000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-name = "vdd-cpu";
+ };
+
+ reg_dcdc3: dcdc3 {
+ regulator-always-on;
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-name = "vdd-dram";
+ };
+ };
+ };
+};
+
+&uart0 {
+ status = "okay";
+ pinctrl-0 = <&uart0_ph_pins>;
+ pinctrl-names = "default";
+};
+
+&uart1 {
+ status = "disabled";
+ pinctrl-0 = <&uart1_pins>;
+ pinctrl-names = "default";
+};
+
+&uart4 {
+ status = "disabled";
+ pinctrl-0 = <&uart4_pi_pins>;
+ pinctrl-names = "default";
+};
+
+&uart5 {
+ status = "okay";
+ pinctrl-0 = <&uart5_ph_pins>;
+ pinctrl-names = "default";
+};
--
2.39.5

View File

@ -0,0 +1,116 @@
From 110909494f8eeae7470321399978c25d9e3af554 Mon Sep 17 00:00:00 2001
From: Jernej Skrabec <jernej.skrabec@gmail.com>
Subject: [PATCH] sunxi: mmc: Improve reset procedure
Date: Sun, 9 Mar 2025 07:12:41 +0100
Cards should always be reset and threshold set. This fixes eMMC on H616.
Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
---
drivers/mmc/sunxi_mmc.c | 28 ++++++++++++++++++++++------
drivers/mmc/sunxi_mmc.h | 15 +++++++++++++--
2 files changed, 35 insertions(+), 8 deletions(-)
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
index 0b56d1405bee..335def4b9738 100644
--- a/drivers/mmc/sunxi_mmc.c
+++ b/drivers/mmc/sunxi_mmc.c
@@ -442,6 +442,26 @@ out:
return error;
}
+static void sunxi_mmc_reset(struct sunxi_mmc *regs)
+{
+ /* Reset controller */
+ writel(SUNXI_MMC_GCTRL_RESET, &regs->gctrl);
+ udelay(1000);
+
+ if (IS_ENABLED(CONFIG_SUN50I_GEN_H6) || IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2)) {
+ /* Reset card */
+ writel(SUNXI_MMC_HWRST_ASSERT, &regs->hwrst);
+ udelay(10);
+ writel(SUNXI_MMC_HWRST_DEASSERT, &regs->hwrst);
+ udelay(300);
+
+ /* Setup FIFO R/W threshold. Needed on H616. */
+ writel(SUNXI_MMC_THLDC_READ_THLD(512) |
+ SUNXI_MMC_THLDC_WRITE_EN |
+ SUNXI_MMC_THLDC_READ_EN, &regs->thldc);
+ }
+}
+
/* non-DM code here is used by the (ARM) SPL only */
#if !CONFIG_IS_ENABLED(DM_MMC)
@@ -489,9 +509,7 @@ static int sunxi_mmc_core_init(struct mmc *mmc)
{
struct sunxi_mmc_priv *priv = mmc->priv;
- /* Reset controller */
- writel(SUNXI_MMC_GCTRL_RESET, &priv->reg->gctrl);
- udelay(1000);
+ sunxi_mmc_reset(priv->reg);
return 0;
}
@@ -684,9 +702,7 @@ static int sunxi_mmc_probe(struct udevice *dev)
upriv->mmc = &plat->mmc;
- /* Reset controller */
- writel(SUNXI_MMC_GCTRL_RESET, &priv->reg->gctrl);
- udelay(1000);
+ sunxi_mmc_reset(priv->reg);
return 0;
}
diff --git a/drivers/mmc/sunxi_mmc.h b/drivers/mmc/sunxi_mmc.h
index f4ae5a790c87..9d55904c213c 100644
--- a/drivers/mmc/sunxi_mmc.h
+++ b/drivers/mmc/sunxi_mmc.h
@@ -37,7 +37,9 @@ struct sunxi_mmc {
u32 res0; /* 0x54 reserved */
u32 a12a; /* 0x58 Auto command 12 argument */
u32 ntsr; /* 0x5c New timing set register */
- u32 res1[8];
+ u32 res1[6];
+ u32 hwrst; /* 0x78 Hardware Reset */
+ u32 res5;
u32 dmac; /* 0x80 internal DMA control */
u32 dlba; /* 0x84 internal DMA descr list base address */
u32 idst; /* 0x88 internal DMA status */
@@ -46,7 +48,8 @@ struct sunxi_mmc {
u32 cbda; /* 0x94 */
u32 res2[26];
#if defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2)
- u32 res3[17];
+ u32 thldc; /* 0x100 Threshold control */
+ u32 res3[16];
u32 samp_dl;
u32 res4[46];
#endif
@@ -123,6 +126,9 @@ struct sunxi_mmc {
#define SUNXI_MMC_NTSR_MODE_SEL_NEW (0x1 << 31)
+#define SUNXI_MMC_HWRST_ASSERT (0x0 << 0)
+#define SUNXI_MMC_HWRST_DEASSERT (0x1 << 0)
+
#define SUNXI_MMC_IDMAC_RESET (0x1 << 0)
#define SUNXI_MMC_IDMAC_FIXBURST (0x1 << 1)
#define SUNXI_MMC_IDMAC_ENABLE (0x1 << 7)
@@ -133,6 +139,11 @@ struct sunxi_mmc {
#define SUNXI_MMC_COMMON_CLK_GATE (1 << 16)
#define SUNXI_MMC_COMMON_RESET (1 << 18)
+#define SUNXI_MMC_THLDC_READ_EN (0x1 << 0)
+#define SUNXI_MMC_THLDC_BSY_CLR_INT_EN (0x1 << 1)
+#define SUNXI_MMC_THLDC_WRITE_EN (0x1 << 2)
+#define SUNXI_MMC_THLDC_READ_THLD(x) (((x) & 0xfff) << 16)
+
#define SUNXI_MMC_CAL_DL_SW_EN (0x1 << 7)
#endif /* _SUNXI_MMC_H */
--
2.48.1

View File

@ -0,0 +1,198 @@
From 110909494f8eeae7470321399978c25d9e3af554 Mon Sep 17 00:00:00 2001
From: Jernej Skrabec <jernej.skrabec@gmail.com>
Subject: [PATCH 1/2] sunxi: h616: dram: Rework size detection
Date: Sun, 9 Mar 2025 07:31:42 +0100
Since there is quite a few possible DRAM configurations in terms of bus
width, rank and rows and columns count, size detection algorithm must be
very careful not to test combination which would be bigger than H616 is
actually capable of handling.
Ideally, we should always detect memory aliasing, even for 4 GB memory
size, which is the maximum amount of memory that H616 is capable of
handling. For this reason, we have to configure minimum amount of
supported rows when testing for columns and vice versa. This way test
code will never step out of 4 GB boundary.
While at it, check for 17 rows maximum. This aligns code with BSP DRAM
driver. There is probably no such configuration which would make sense
with 4 GB memory.
Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
---
arch/arm/mach-sunxi/dram_sun50i_h616.c | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c b/arch/arm/mach-sunxi/dram_sun50i_h616.c
index b3554cc64bf5..6f84e59e39cd 100644
--- a/arch/arm/mach-sunxi/dram_sun50i_h616.c
+++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c
@@ -1363,7 +1363,7 @@ static void mctl_auto_detect_rank_width(const struct dram_para *para,
static void mctl_auto_detect_dram_size(const struct dram_para *para,
struct dram_config *config)
{
- unsigned int shift;
+ unsigned int shift, cols, rows;
/* max. config for columns, but not rows */
config->cols = 11;
@@ -1373,23 +1373,27 @@ static void mctl_auto_detect_dram_size(const struct dram_para *para,
shift = config->bus_full_width + 1;
/* detect column address bits */
- for (config->cols = 8; config->cols < 11; config->cols++) {
- if (mctl_mem_matches(1ULL << (config->cols + shift)))
+ for (cols = 8; cols < 11; cols++) {
+ if (mctl_mem_matches(1ULL << (cols + shift)))
break;
}
- debug("detected %u columns\n", config->cols);
+ debug("detected %u columns\n", cols);
/* reconfigure to make sure that all active rows are accessible */
- config->rows = 18;
+ config->cols = 8;
+ config->rows = 17;
mctl_core_init(para, config);
/* detect row address bits */
shift = config->bus_full_width + 4 + config->cols;
- for (config->rows = 13; config->rows < 18; config->rows++) {
- if (mctl_mem_matches(1ULL << (config->rows + shift)))
+ for (rows = 13; rows < 17; rows++) {
+ if (mctl_mem_matches(1ULL << (rows + shift)))
break;
}
- debug("detected %u rows\n", config->rows);
+ debug("detected %u rows\n", rows);
+
+ config->cols = cols;
+ config->rows = rows;
}
static unsigned long mctl_calc_size(const struct dram_config *config)
--
2.48.1
From 110909494f8eeae7470321399978c25d9e3af554 Mon Sep 17 00:00:00 2001
From: Jernej Skrabec <jernej.skrabec@gmail.com>
Subject: [PATCH 2/2] sunxi: H616: dram: Improve address wrapping detection
Date: Sun, 9 Mar 2025 07:31:43 +0100
It turns out that checking just one write is not enough. Due to
unexplained reasons scan procedure detected double the size. By making
16 dword writes and comparisons that never happens.
New procedure is also inverted. Instead of writing two different values
to base address and some offset and then reading both and comparing
values, simplify this by writing pattern at the base address and then
search for this pattern at some offset.
Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
---
arch/arm/mach-sunxi/dram_sun50i_h616.c | 58 +++++++++++++++++++++++++-
1 file changed, 56 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c b/arch/arm/mach-sunxi/dram_sun50i_h616.c
index 6f84e59e39cd..1e21f5dd451f 100644
--- a/arch/arm/mach-sunxi/dram_sun50i_h616.c
+++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c
@@ -1360,38 +1360,92 @@ static void mctl_auto_detect_rank_width(const struct dram_para *para,
panic("This DRAM setup is currently not supported.\n");
}
+static void mctl_write_pattern(void)
+{
+ unsigned int i;
+ u32 *ptr, val;
+
+ ptr = (u32 *)CFG_SYS_SDRAM_BASE;
+ for (i = 0; i < 16; ptr++, i++) {
+ if (i & 1)
+ val = ~(ulong)ptr;
+ else
+ val = (ulong)ptr;
+ writel(val, ptr);
+ }
+}
+
+static bool mctl_check_pattern(ulong offset)
+{
+ unsigned int i;
+ u32 *ptr, val;
+
+ ptr = (u32 *)CFG_SYS_SDRAM_BASE;
+ for (i = 0; i < 16; ptr++, i++) {
+ if (i & 1)
+ val = ~(ulong)ptr;
+ else
+ val = (ulong)ptr;
+ if (val != *(ptr + offset / 4))
+ return false;
+ }
+
+ return true;
+}
+
static void mctl_auto_detect_dram_size(const struct dram_para *para,
struct dram_config *config)
{
unsigned int shift, cols, rows;
+ u32 buffer[16];
/* max. config for columns, but not rows */
config->cols = 11;
config->rows = 13;
mctl_core_init(para, config);
+ /*
+ * Store content so it can be restored later. This is important
+ * if controller was already initialized and holds any data
+ * which is important for restoring system.
+ */
+ memcpy(buffer, (u32 *)CFG_SYS_SDRAM_BASE, sizeof(buffer));
+
+ mctl_write_pattern();
+
shift = config->bus_full_width + 1;
/* detect column address bits */
for (cols = 8; cols < 11; cols++) {
- if (mctl_mem_matches(1ULL << (cols + shift)))
+ if (mctl_check_pattern(1ULL << (cols + shift)))
break;
}
debug("detected %u columns\n", cols);
+ /* restore data */
+ memcpy((u32 *)CFG_SYS_SDRAM_BASE, buffer, sizeof(buffer));
+
/* reconfigure to make sure that all active rows are accessible */
config->cols = 8;
config->rows = 17;
mctl_core_init(para, config);
+ /* store data again as it might be moved */
+ memcpy(buffer, (u32 *)CFG_SYS_SDRAM_BASE, sizeof(buffer));
+
+ mctl_write_pattern();
+
/* detect row address bits */
shift = config->bus_full_width + 4 + config->cols;
for (rows = 13; rows < 17; rows++) {
- if (mctl_mem_matches(1ULL << (rows + shift)))
+ if (mctl_check_pattern(1ULL << (rows + shift)))
break;
}
debug("detected %u rows\n", rows);
+ /* restore data again */
+ memcpy((u32 *)CFG_SYS_SDRAM_BASE, buffer, sizeof(buffer));
+
config->cols = cols;
config->rows = rows;
}
--
2.48.1

View File

@ -0,0 +1,26 @@
From e297186797d90041e3f554d5759878e9fd72ed8e Mon Sep 17 00:00:00 2001
From: Jernej Skrabec <jernej.skrabec@gmail.com>
Date: Wed, 28 Feb 2024 14:15:33 -0500
Subject: [PATCH] HACK: sunxi: h616 gpu enable
Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
---
arch/arm/mach-sunxi/clock_sun50i_h6.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm/mach-sunxi/clock_sun50i_h6.c b/arch/arm/mach-sunxi/clock_sun50i_h6.c
index bea91c78bc..7f60b8c79f 100644
--- a/arch/arm/mach-sunxi/clock_sun50i_h6.c
+++ b/arch/arm/mach-sunxi/clock_sun50i_h6.c
@@ -16,6 +16,8 @@ void clock_init_safe(void)
/* this seems to enable PLLs on H616 */
setbits_le32(&prcm->sys_pwroff_gating, 0x10);
setbits_le32(&prcm->res_cal_ctrl, 2);
+ /* enable GPU */
+ writel(0, 0x7010254);
}
if (IS_ENABLED(CONFIG_MACH_SUN50I_H616) ||
--
2.39.2

View File

@ -0,0 +1,33 @@
From ad10cf66b98acbdc21f431e262633e18b2e93c70 Mon Sep 17 00:00:00 2001
From: Kali Prasad <kprasadvnsi@protonmail.com>
Date: Sun, 24 Nov 2024 07:51:12 -0500
Subject: [PATCH] sunxi: h616 ths workaround
Signed-off-by: Kali Prasad <kprasadvnsi@protonmail.com>
---
board/sunxi/board.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index 961cdcde74..af2b372a56 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -225,6 +225,15 @@ int board_init(void)
if (ret)
return ret;
+#if CONFIG_MACH_SUN50I_H616
+ /*
+ * The bit[16] of register reg[0x03000000] must be zero for the THS
+ * driver to work properly in the kernel. The BSP u-boot is putting
+ * the whole register to zero so we are doing the same.
+ */
+ writel(0x0, SUNXI_SRAMC_BASE);
+#endif
+
eth_init_board();
return 0;
--
2.39.5

View File

@ -0,0 +1,33 @@
From 110909494f8eeae7470321399978c25d9e3af554 Mon Sep 17 00:00:00 2001
From: Patrick Yavitz <pyavitz@gmail.com>
Date: Mon, 13 May 2024 17:45:57 -0400
Subject: [PATCH] mach-sunxi: dram_helpers: add delay to steady dram detection
Signed-off-by: Patrick Yavitz <pyavitz@gmail.com>
---
arch/arm/mach-sunxi/dram_helpers.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm/mach-sunxi/dram_helpers.c b/arch/arm/mach-sunxi/dram_helpers.c
index 83dbe4ca98..df7845502d 100644
--- a/arch/arm/mach-sunxi/dram_helpers.c
+++ b/arch/arm/mach-sunxi/dram_helpers.c
@@ -11,6 +11,7 @@
#include <asm/barriers.h>
#include <asm/io.h>
#include <asm/arch/dram.h>
+#include <linux/delay.h>
/*
* Wait up to 1s for value to be set in given part of reg.
@@ -45,6 +46,7 @@ bool mctl_mem_matches_base(u32 offset, ulong base)
writel(0, base);
writel(0xaa55aa55, base + offset);
dsb();
+ udelay(150);
/* Check if the same value is actually observed when reading back */
ret = readl(base) == readl(base + offset);
--
2.39.2

View File

@ -0,0 +1,106 @@
From 110909494f8eeae7470321399978c25d9e3af554 Mon Sep 17 00:00:00 2001
From: Andre Przywara <andre.przywara@arm.com>
Subject: [PATCH] sunxi: pmic_bus: Move SPL I2C addresses into Kconfig
Date: Tue, 18 Mar 2025 00:39:43 +0000
Some of the X-Power AXP PMICs can be ordered with an alternative I2C
address, for instance an AXP717 could be shipped with address 0x34 or
with address 0x35. Similarly the AXP803 lists two possible addresses.
For DM (DT) based drivers this is no problem, but the Allwinner SPL
code relies on exactly one hardcoded address per PMIC so far.
Add a Kconfig variable that holds the I2C address used by the PMIC
accessed in the SPL, and provide the (mostly only one) supported address
as its default, for the PMICs we use. Boards using the other address
can easily set this in their defconfig.
This effectively moves the hardcoding from C code to Kconfig.
That enables to use the AXP717 on some boards with the new Allwinner
A523 chip, which use the other I2C address there.
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
---
arch/arm/mach-sunxi/pmic_bus.c | 27 ++-------------------------
drivers/power/Kconfig | 10 ++++++++++
2 files changed, 12 insertions(+), 25 deletions(-)
diff --git a/arch/arm/mach-sunxi/pmic_bus.c b/arch/arm/mach-sunxi/pmic_bus.c
index 8e19324c8ac..c77dc538456 100644
--- a/arch/arm/mach-sunxi/pmic_bus.c
+++ b/arch/arm/mach-sunxi/pmic_bus.c
@@ -16,33 +16,10 @@
#include <power/pmic.h>
#include <asm/arch/pmic_bus.h>
-#define AXP152_I2C_ADDR 0x30
-
-#define AXP209_I2C_ADDR 0x34
-#define AXP717_I2C_ADDR 0x34
-
-#define AXP305_I2C_ADDR 0x36
-#define AXP313_I2C_ADDR 0x36
-
#define AXP221_CHIP_ADDR 0x68
#if CONFIG_IS_ENABLED(PMIC_AXP)
static struct udevice *pmic;
-#else
-static int pmic_i2c_address(void)
-{
- if (IS_ENABLED(CONFIG_AXP152_POWER))
- return AXP152_I2C_ADDR;
- if (IS_ENABLED(CONFIG_AXP305_POWER))
- return AXP305_I2C_ADDR;
- if (IS_ENABLED(CONFIG_AXP313_POWER))
- return AXP313_I2C_ADDR;
- if (IS_ENABLED(CONFIG_AXP717_POWER))
- return AXP717_I2C_ADDR;
-
- /* Other AXP2xx and AXP8xx variants */
- return AXP209_I2C_ADDR;
-}
#endif
int pmic_bus_init(void)
@@ -88,7 +65,7 @@ int pmic_bus_read(u8 reg, u8 *data)
if (IS_ENABLED(CONFIG_SYS_I2C_SUN8I_RSB))
return rsb_read(AXP_PMIC_PRI_RUNTIME_ADDR, reg, data);
- return i2c_read(pmic_i2c_address(), reg, 1, data, 1);
+ return i2c_read(CONFIG_AXP_I2C_ADDRESS, reg, 1, data, 1);
#endif
}
@@ -102,7 +79,7 @@ int pmic_bus_write(u8 reg, u8 data)
if (IS_ENABLED(CONFIG_SYS_I2C_SUN8I_RSB))
return rsb_write(AXP_PMIC_PRI_RUNTIME_ADDR, reg, data);
- return i2c_write(pmic_i2c_address(), reg, 1, &data, 1);
+ return i2c_write(CONFIG_AXP_I2C_ADDRESS, reg, 1, &data, 1);
#endif
}
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 5c73bc75a15..eed65058e66 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -148,6 +148,16 @@ config SY8106A_POWER
endchoice
+config AXP_I2C_ADDRESS
+ hex "AXP PMIC I2C address"
+ depends on ARCH_SUNXI && !SUNXI_NO_PMIC
+ default 0x36 if AXP305_POWER
+ default 0x36 if AXP313_POWER
+ default 0x30 if AXP152_POWER
+ default 0x34
+ ---help---
+ I2C address of the AXP PMIC, used for the SPL only.
+
config AXP_DCDC1_VOLT
int "axp pmic dcdc1 voltage"
depends on AXP221_POWER || AXP809_POWER || AXP818_POWER || AXP803_POWER
--
2.46.3