aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/dts/Makefile1
-rw-r--r--arch/arm/include/asm/arch-sunxi/dram.h1
-rw-r--r--arch/arm/mach-sunxi/clock_sun4i.c2
-rw-r--r--arch/arm/mach-sunxi/dram_helpers.c32
-rw-r--r--arch/arm/mach-sunxi/dram_sunxi_dw.c13
-rw-r--r--board/sunxi/MAINTAINERS5
-rw-r--r--configs/A20-OLinuXino_MICRO-eMMC_defconfig1
-rw-r--r--configs/A20-OLinuXino_MICRO_defconfig1
-rw-r--r--configs/orangepi_zero2w_defconfig30
-rw-r--r--drivers/spi/spi-sunxi.c34
10 files changed, 100 insertions, 20 deletions
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index d972503..b102ffb 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -839,6 +839,7 @@ dtb-$(CONFIG_MACH_SUN50I_H6) += \
sun50i-h6-tanix-tx6-mini.dtb
dtb-$(CONFIG_MACH_SUN50I_H616) += \
sun50i-h616-orangepi-zero2.dtb \
+ sun50i-h618-orangepi-zero2w.dtb \
sun50i-h618-orangepi-zero3.dtb \
sun50i-h618-transpeed-8k618-t.dtb \
sun50i-h616-x96-mate.dtb
diff --git a/arch/arm/include/asm/arch-sunxi/dram.h b/arch/arm/include/asm/arch-sunxi/dram.h
index 682daae..9d21b49 100644
--- a/arch/arm/include/asm/arch-sunxi/dram.h
+++ b/arch/arm/include/asm/arch-sunxi/dram.h
@@ -40,5 +40,6 @@
unsigned long sunxi_dram_init(void);
void mctl_await_completion(u32 *reg, u32 mask, u32 val);
bool mctl_mem_matches(u32 offset);
+bool mctl_mem_matches_base(u32 offset, ulong base);
#endif /* _SUNXI_DRAM_H */
diff --git a/arch/arm/mach-sunxi/clock_sun4i.c b/arch/arm/mach-sunxi/clock_sun4i.c
index 8f1d1b6..ac3b7a8 100644
--- a/arch/arm/mach-sunxi/clock_sun4i.c
+++ b/arch/arm/mach-sunxi/clock_sun4i.c
@@ -25,6 +25,7 @@ void clock_init_safe(void)
APB0_DIV_1 << APB0_DIV_SHIFT |
CPU_CLK_SRC_OSC24M << CPU_CLK_SRC_SHIFT,
&ccm->cpu_ahb_apb0_cfg);
+ sdelay(20);
writel(PLL1_CFG_DEFAULT, &ccm->pll1_cfg);
sdelay(200);
writel(AXI_DIV_1 << AXI_DIV_SHIFT |
@@ -32,6 +33,7 @@ void clock_init_safe(void)
APB0_DIV_1 << APB0_DIV_SHIFT |
CPU_CLK_SRC_PLL1 << CPU_CLK_SRC_SHIFT,
&ccm->cpu_ahb_apb0_cfg);
+ sdelay(20);
#ifdef CONFIG_MACH_SUN7I
setbits_le32(&ccm->ahb_gate0, 0x1 << AHB_GATE_OFFSET_DMA);
#endif
diff --git a/arch/arm/mach-sunxi/dram_helpers.c b/arch/arm/mach-sunxi/dram_helpers.c
index 4a867df..83dbe4c 100644
--- a/arch/arm/mach-sunxi/dram_helpers.c
+++ b/arch/arm/mach-sunxi/dram_helpers.c
@@ -26,19 +26,39 @@ void mctl_await_completion(u32 *reg, u32 mask, u32 val)
}
/*
- * Test if memory at offset offset matches memory at begin of DRAM
+ * Test if memory at offset matches memory at a certain base
*
* Note: dsb() is not available on ARMv5 in Thumb mode
*/
#ifndef CONFIG_MACH_SUNIV
-bool mctl_mem_matches(u32 offset)
+bool mctl_mem_matches_base(u32 offset, ulong base)
{
+ u32 val_base;
+ u32 val_offset;
+ bool ret;
+
+ /* Save original values */
+ val_base = readl(base);
+ val_offset = readl(base + offset);
+
/* Try to write different values to RAM at two addresses */
- writel(0, CFG_SYS_SDRAM_BASE);
- writel(0xaa55aa55, (ulong)CFG_SYS_SDRAM_BASE + offset);
+ writel(0, base);
+ writel(0xaa55aa55, base + offset);
dsb();
/* Check if the same value is actually observed when reading back */
- return readl(CFG_SYS_SDRAM_BASE) ==
- readl((ulong)CFG_SYS_SDRAM_BASE + offset);
+ ret = readl(base) == readl(base + offset);
+
+ /* Restore original values */
+ writel(val_base, base);
+ writel(val_offset, base + offset);
+ return ret;
+}
+
+/*
+ * Test if memory at offset matches memory at begin of DRAM
+ */
+bool mctl_mem_matches(u32 offset)
+{
+ return mctl_mem_matches_base(offset, CFG_SYS_SDRAM_BASE);
}
#endif
diff --git a/arch/arm/mach-sunxi/dram_sunxi_dw.c b/arch/arm/mach-sunxi/dram_sunxi_dw.c
index 3bfcc63..e064ef3 100644
--- a/arch/arm/mach-sunxi/dram_sunxi_dw.c
+++ b/arch/arm/mach-sunxi/dram_sunxi_dw.c
@@ -650,19 +650,6 @@ static int mctl_channel_init(uint16_t socid, struct dram_para *para)
return 0;
}
-/*
- * Test if memory at offset offset matches memory at a certain base
- */
-static bool mctl_mem_matches_base(u32 offset, ulong base)
-{
- /* Try to write different values to RAM at two addresses */
- writel(0, base);
- writel(0xaa55aa55, base + offset);
- dsb();
- /* Check if the same value is actually observed when reading back */
- return readl(base) ==
- readl(base + offset);
-}
static void mctl_auto_detect_dram_size_rank(uint16_t socid, struct dram_para *para, ulong base, struct rank_para *rank)
{
diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS
index a2da6a4..4bcd9b9 100644
--- a/board/sunxi/MAINTAINERS
+++ b/board/sunxi/MAINTAINERS
@@ -460,6 +460,11 @@ M: Jernej Skrabec <jernej.skrabec@siol.net>
S: Maintained
F: configs/orangepi_zero2_defconfig
+ORANGEPI ZERO 2W BOARD
+M: Andre Przywara <andre.przywara@arm.com>
+S: Maintained
+F: configs/orangepi_zero2w_defconfig
+
ORANGEPI ZERO 3 BOARD
M: Andre Przywara <andre.przywara@arm.com>
S: Maintained
diff --git a/configs/A20-OLinuXino_MICRO-eMMC_defconfig b/configs/A20-OLinuXino_MICRO-eMMC_defconfig
index ca5869f..2f26b0c 100644
--- a/configs/A20-OLinuXino_MICRO-eMMC_defconfig
+++ b/configs/A20-OLinuXino_MICRO-eMMC_defconfig
@@ -20,6 +20,7 @@ CONFIG_ETH_DESIGNWARE=y
CONFIG_MII=y
CONFIG_SUN7I_GMAC=y
CONFIG_SUN7I_GMAC_FORCE_TXERR=y
+CONFIG_AXP_ALDO3_INRUSH_QUIRK=y
CONFIG_AXP_ALDO3_VOLT=2800
CONFIG_AXP_ALDO4_VOLT=2800
CONFIG_SCSI=y
diff --git a/configs/A20-OLinuXino_MICRO_defconfig b/configs/A20-OLinuXino_MICRO_defconfig
index db4270f..673ab85 100644
--- a/configs/A20-OLinuXino_MICRO_defconfig
+++ b/configs/A20-OLinuXino_MICRO_defconfig
@@ -20,6 +20,7 @@ CONFIG_ETH_DESIGNWARE=y
CONFIG_MII=y
CONFIG_SUN7I_GMAC=y
CONFIG_SUN7I_GMAC_FORCE_TXERR=y
+CONFIG_AXP_ALDO3_INRUSH_QUIRK=y
CONFIG_AXP_ALDO3_VOLT=2800
CONFIG_AXP_ALDO4_VOLT=2800
CONFIG_SCSI=y
diff --git a/configs/orangepi_zero2w_defconfig b/configs/orangepi_zero2w_defconfig
new file mode 100644
index 0000000..5734d9d
--- /dev/null
+++ b/configs/orangepi_zero2w_defconfig
@@ -0,0 +1,30 @@
+CONFIG_ARM=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_DEFAULT_DEVICE_TREE="sun50i-h618-orangepi-zero2w"
+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_R_I2C_ENABLE=y
+CONFIG_SPL_SPI_SUNXI=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_MTD=y
+CONFIG_SPI_FLASH_ZBIT=y
+CONFIG_AXP313_POWER=y
+CONFIG_SPI=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_MUSB_GADGET=y
diff --git a/drivers/spi/spi-sunxi.c b/drivers/spi/spi-sunxi.c
index c56d82d..9ec6b35 100644
--- a/drivers/spi/spi-sunxi.c
+++ b/drivers/spi/spi-sunxi.c
@@ -117,6 +117,8 @@ enum sun4i_spi_bits {
SPI_TCR_XCH,
SPI_TCR_CS_MANUAL,
SPI_TCR_CS_LEVEL,
+ SPI_TCR_SDC,
+ SPI_TCR_SDM,
SPI_FCR_TF_RST,
SPI_FCR_RF_RST,
SPI_FSR_RF_CNT_MASK,
@@ -128,6 +130,7 @@ struct sun4i_spi_variant {
u32 fifo_depth;
bool has_soft_reset;
bool has_burst_ctl;
+ bool has_clk_ctl;
};
struct sun4i_spi_plat {
@@ -302,7 +305,19 @@ static int sun4i_spi_claim_bus(struct udevice *dev)
setbits_le32(SPI_REG(priv, SPI_TCR), SPI_BIT(priv, SPI_TCR_CS_MANUAL) |
SPI_BIT(priv, SPI_TCR_CS_ACTIVE_LOW));
- sun4i_spi_set_speed_mode(dev->parent);
+ if (priv->variant->has_clk_ctl) {
+ sun4i_spi_set_speed_mode(dev->parent);
+ } else {
+ /*
+ * At this moment there is no ability to change input clock.
+ * Therefore, we can only use default HOSC@24MHz clock and
+ * set SPI sampling mode to normal
+ */
+ clrsetbits_le32(SPI_REG(priv, SPI_TCR),
+ SPI_BIT(priv, SPI_TCR_SDC) |
+ SPI_BIT(priv, SPI_TCR_SDM),
+ SPI_BIT(priv, SPI_TCR_SDM));
+ }
return 0;
}
@@ -516,6 +531,8 @@ static const u32 sun6i_spi_bits[] = {
[SPI_TCR_CS_MASK] = 0x30,
[SPI_TCR_CS_MANUAL] = BIT(6),
[SPI_TCR_CS_LEVEL] = BIT(7),
+ [SPI_TCR_SDC] = BIT(11),
+ [SPI_TCR_SDM] = BIT(13),
[SPI_TCR_XCH] = BIT(31),
[SPI_FCR_RF_RST] = BIT(15),
[SPI_FCR_TF_RST] = BIT(31),
@@ -526,6 +543,7 @@ static const struct sun4i_spi_variant sun4i_a10_spi_variant = {
.regs = sun4i_spi_regs,
.bits = sun4i_spi_bits,
.fifo_depth = 64,
+ .has_clk_ctl = true,
};
static const struct sun4i_spi_variant sun6i_a31_spi_variant = {
@@ -534,6 +552,7 @@ static const struct sun4i_spi_variant sun6i_a31_spi_variant = {
.fifo_depth = 128,
.has_soft_reset = true,
.has_burst_ctl = true,
+ .has_clk_ctl = true,
};
static const struct sun4i_spi_variant sun8i_h3_spi_variant = {
@@ -542,6 +561,15 @@ static const struct sun4i_spi_variant sun8i_h3_spi_variant = {
.fifo_depth = 64,
.has_soft_reset = true,
.has_burst_ctl = true,
+ .has_clk_ctl = true,
+};
+
+static const struct sun4i_spi_variant sun50i_r329_spi_variant = {
+ .regs = sun6i_spi_regs,
+ .bits = sun6i_spi_bits,
+ .fifo_depth = 64,
+ .has_soft_reset = true,
+ .has_burst_ctl = true,
};
static const struct udevice_id sun4i_spi_ids[] = {
@@ -557,6 +585,10 @@ static const struct udevice_id sun4i_spi_ids[] = {
.compatible = "allwinner,sun8i-h3-spi",
.data = (ulong)&sun8i_h3_spi_variant,
},
+ {
+ .compatible = "allwinner,sun50i-r329-spi",
+ .data = (ulong)&sun50i_r329_spi_variant,
+ },
{ /* sentinel */ }
};