Add X96Q LPDDR3 v1.3 custom U-Boot build and eMMC flash tooling.
Armbian-compatible U-Boot v2025.01 with eMMC, DTB, and flash fixes for the X96Q TV box. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
|
||||
index 8065161e6..b92c0402c 100644
|
||||
--- a/arch/arm/mach-sunxi/Kconfig
|
||||
+++ b/arch/arm/mach-sunxi/Kconfig
|
||||
@@ -1130,6 +1130,12 @@ config BLUETOOTH_DT_DEVICE_FIXUP
|
||||
The used address is "bdaddr" if set, and "ethaddr" with the LSB
|
||||
flipped elsewise.
|
||||
|
||||
+config X96Q_BINARY_BUILD
|
||||
+ bool "Print 'binary build' easter egg on UART in SPL"
|
||||
+ default n
|
||||
+ help
|
||||
+ Print a short banner on the serial console early in SPL boot.
|
||||
+
|
||||
source "board/sunxi/Kconfig"
|
||||
|
||||
endif
|
||||
diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
|
||||
index 701899ee4..7b6e9ee9c 100644
|
||||
--- a/arch/arm/mach-sunxi/board.c
|
||||
+++ b/arch/arm/mach-sunxi/board.c
|
||||
@@ -470,6 +470,9 @@ void board_init_f(ulong dummy)
|
||||
|
||||
spl_init();
|
||||
preloader_console_init();
|
||||
+#ifdef CONFIG_X96Q_BINARY_BUILD
|
||||
+ puts("*** binary build ***\n");
|
||||
+#endif
|
||||
|
||||
#if CONFIG_IS_ENABLED(I2C) && CONFIG_IS_ENABLED(SYS_I2C_LEGACY)
|
||||
/* Needed early by sunxi_board_init if PMU is enabled */
|
||||
@@ -0,0 +1,15 @@
|
||||
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
|
||||
--- a/board/sunxi/board.c
|
||||
+++ b/board/sunxi/board.c
|
||||
@@ -826,6 +826,10 @@ int misc_init_r(void)
|
||||
char *prefix = IS_ENABLED(CONFIG_ARM64) ? "allwinner/" : "";
|
||||
char str[64];
|
||||
|
||||
snprintf(str, sizeof(str), "%s%s.dtb", prefix, spl_dt_name);
|
||||
+#ifdef CONFIG_X96Q_BINARY_BUILD
|
||||
+ /* Armbian ships sun50i-h313-x96q-lpddr3.dtb, not the v1.3 suffix */
|
||||
+ snprintf(str, sizeof(str), "%ssun50i-h313-x96q-lpddr3.dtb", prefix);
|
||||
+#endif
|
||||
env_set("fdtfile", str);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
commit 3e78f8f407a0a0e7b50aa7eaa6f2f579f35e9837
|
||||
Author: Jernej Skrabec <jernej.skrabec@gmail.com>
|
||||
Date: Sun Mar 9 07:12:41 2025 +0100
|
||||
|
||||
sunxi: mmc: Improve reset procedure
|
||||
|
||||
Cards should always be reset and threshold set. This fixes eMMC on H616.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
|
||||
[Andre: use macro-defined offsets to fix build on older SoCs]
|
||||
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
|
||||
|
||||
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
|
||||
index 8f72d758e..951e6acd3 100644
|
||||
--- a/drivers/mmc/sunxi_mmc.c
|
||||
+++ b/drivers/mmc/sunxi_mmc.c
|
||||
@@ -449,6 +449,26 @@ out:
|
||||
return error;
|
||||
}
|
||||
|
||||
+static void sunxi_mmc_reset(void *regs)
|
||||
+{
|
||||
+ /* Reset controller */
|
||||
+ writel(SUNXI_MMC_GCTRL_RESET, regs + SUNXI_MMC_GCTRL);
|
||||
+ udelay(1000);
|
||||
+
|
||||
+ if (IS_ENABLED(CONFIG_SUN50I_GEN_H6) || IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2)) {
|
||||
+ /* Reset card */
|
||||
+ writel(SUNXI_MMC_HWRST_ASSERT, regs + SUNXI_MMC_HWRST);
|
||||
+ udelay(10);
|
||||
+ writel(SUNXI_MMC_HWRST_DEASSERT, regs + SUNXI_MMC_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 + SUNXI_MMC_THLDC);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/* non-DM code here is used by the (ARM) SPL only */
|
||||
|
||||
#if !CONFIG_IS_ENABLED(DM_MMC)
|
||||
@@ -496,9 +516,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;
|
||||
}
|
||||
@@ -691,9 +709,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 f4ae5a790..718651603 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
|
||||
@@ -57,6 +60,7 @@ struct sunxi_mmc {
|
||||
#define SUNXI_MMC_CLK_ENABLE (0x1 << 16)
|
||||
#define SUNXI_MMC_CLK_DIVIDER_MASK (0xff)
|
||||
|
||||
+#define SUNXI_MMC_GCTRL 0x000
|
||||
#define SUNXI_MMC_GCTRL_SOFT_RESET (0x1 << 0)
|
||||
#define SUNXI_MMC_GCTRL_FIFO_RESET (0x1 << 1)
|
||||
#define SUNXI_MMC_GCTRL_DMA_RESET (0x1 << 2)
|
||||
@@ -123,6 +127,10 @@ struct sunxi_mmc {
|
||||
|
||||
#define SUNXI_MMC_NTSR_MODE_SEL_NEW (0x1 << 31)
|
||||
|
||||
+#define SUNXI_MMC_HWRST 0x078
|
||||
+#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 +141,12 @@ struct sunxi_mmc {
|
||||
#define SUNXI_MMC_COMMON_CLK_GATE (1 << 16)
|
||||
#define SUNXI_MMC_COMMON_RESET (1 << 18)
|
||||
|
||||
+#define SUNXI_MMC_THLDC 0x100
|
||||
+#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 */
|
||||
Reference in New Issue
Block a user