[U-Boot] [PATCH] sunxi: Add H6 SPI SPL support
Marek Kraus
gamelaster at outlook.com
Mon Apr 8 22:12:09 UTC 2019
Add H6 SPI addresses and masks
(since H6 memory map is totally different).
Tested on Pine H64 rev B with Winbond W25Q128FW,
Signed-off-by: Marek Kraus <gamelaster at outlook.com>
---
arch/arm/mach-sunxi/Kconfig | 2 +-
arch/arm/mach-sunxi/spl_spi_sunxi.c | 123 ++++++++++++++++++++++++++++--------
configs/pine_h64_defconfig | 1 +
3 files changed, 98 insertions(+), 28 deletions(-)
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index 74e234cded..81b5948454 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -972,7 +972,7 @@ config SPL_STACK_R_ADDR
config SPL_SPI_SUNXI
bool "Support for SPI Flash on Allwinner SoCs in SPL"
- depends on MACH_SUN4I || MACH_SUN5I || MACH_SUN7I || MACH_SUNXI_H3_H5 || MACH_SUN50I
+ depends on MACH_SUN4I || MACH_SUN5I || MACH_SUN7I || MACH_SUNXI_H3_H5 || MACH_SUN50I || MACH_SUN50I_H6
help
Enable support for SPI Flash. This option allows SPL to read from
sunxi SPI Flash. It uses the same method as the boot ROM, so does
diff --git a/arch/arm/mach-sunxi/spl_spi_sunxi.c b/arch/arm/mach-sunxi/spl_spi_sunxi.c
index 043d9f6ead..cdf6d53ec5 100644
--- a/arch/arm/mach-sunxi/spl_spi_sunxi.c
+++ b/arch/arm/mach-sunxi/spl_spi_sunxi.c
@@ -28,7 +28,7 @@
* A10/A13/A20 (sun4i variant) and everything else (sun6i variant).
* Both of them are supported.
*
- * The pin mixing part is SoC specific and only A10/A13/A20/H3/A64 are
+ * The pin mixing part is SoC specific and only A10/A13/A20/H3/A64/H6 are
* supported at the moment.
*/
@@ -70,6 +70,25 @@
#define SUN6I_TCR_XCH BIT(31)
/*****************************************************************************/
+/* SUN50I_H6 variant of the SPI controller */
+/*****************************************************************************/
+
+#define SUN50I_H6_SPI0_CCTL (0x05010000 + 0x24)
+#define SUN50I_H6_SPI0_GCR (0x05010000 + 0x04)
+#define SUN50I_H6_SPI0_TCR (0x05010000 + 0x08)
+#define SUN50I_H6_SPI0_FIFO_STA (0x05010000 + 0x1C)
+#define SUN50I_H6_SPI0_MBC (0x05010000 + 0x30)
+#define SUN50I_H6_SPI0_MTC (0x05010000 + 0x34)
+#define SUN50I_H6_SPI0_BCC (0x05010000 + 0x38)
+#define SUN50I_H6_SPI0_TXD (0x05010000 + 0x200)
+#define SUN50I_H6_SPI0_RXD (0x05010000 + 0x300)
+
+#define SUN50I_H6_SPI_GATING_REG (0x03001000 + 0x96C)
+#define SUN50I_H6_SPI0_RST BIT(16)
+#define SUN50I_H6_SPI0_GATING_CLK BIT(0)
+#define SUN50I_H6_CCU_SPI0_CLK (0x03001000 + 0x940)
+
+/*****************************************************************************/
#define CCM_AHB_GATING0 (0x01C20000 + 0x60)
#define CCM_SPI0_CLK (0x01C20000 + 0xA0)
@@ -85,19 +104,29 @@
/*
* Allwinner A10/A20 SoCs were using pins PC0,PC1,PC2,PC23 for booting
- * from SPI Flash, everything else is using pins PC0,PC1,PC2,PC3.
+ * from SPI Flash, H6 using PC0,PC2,PC3,PC5 , everything else is using
+ * pins PC0,PC1,PC2,PC3.
*/
static void spi0_pinmux_setup(unsigned int pin_function)
{
unsigned int pin;
- for (pin = SUNXI_GPC(0); pin <= SUNXI_GPC(2); pin++)
- sunxi_gpio_set_cfgpin(pin, pin_function);
- if (IS_ENABLED(CONFIG_MACH_SUN4I) || IS_ENABLED(CONFIG_MACH_SUN7I))
- sunxi_gpio_set_cfgpin(SUNXI_GPC(23), pin_function);
- else
+ if (IS_ENABLED(CONFIG_MACH_SUN50I_H6)) {
+ sunxi_gpio_set_cfgpin(SUNXI_GPC(0), pin_function);
+ sunxi_gpio_set_cfgpin(SUNXI_GPC(2), pin_function);
sunxi_gpio_set_cfgpin(SUNXI_GPC(3), pin_function);
+ sunxi_gpio_set_cfgpin(SUNXI_GPC(5), pin_function);
+ } else {
+ for (pin = SUNXI_GPC(0); pin <= SUNXI_GPC(2); pin++)
+ sunxi_gpio_set_cfgpin(pin, pin_function);
+
+ if (IS_ENABLED(CONFIG_MACH_SUN4I) ||
+ IS_ENABLED(CONFIG_MACH_SUN7I))
+ sunxi_gpio_set_cfgpin(SUNXI_GPC(23), pin_function);
+ else
+ sunxi_gpio_set_cfgpin(SUNXI_GPC(3), pin_function);
+ }
}
/*
@@ -106,26 +135,43 @@ static void spi0_pinmux_setup(unsigned int pin_function)
static void spi0_enable_clock(void)
{
/* Deassert SPI0 reset on SUN6I */
- if (IS_ENABLED(CONFIG_SUNXI_GEN_SUN6I))
+ if (IS_ENABLED(CONFIG_MACH_SUN50I_H6))
+ setbits_le32(SUN50I_H6_SPI_GATING_REG,
+ SUN50I_H6_SPI0_RST);
+ else if (IS_ENABLED(CONFIG_SUNXI_GEN_SUN6I))
setbits_le32(SUN6I_BUS_SOFT_RST_REG0,
(1 << AHB_RESET_SPI0_SHIFT));
/* Open the SPI0 gate */
- setbits_le32(CCM_AHB_GATING0, (1 << AHB_GATE_OFFSET_SPI0));
+ if (IS_ENABLED(CONFIG_MACH_SUN50I_H6))
+ setbits_le32(SUN50I_H6_SPI_GATING_REG,
+ SUN50I_H6_SPI0_GATING_CLK);
+ else
+ setbits_le32(CCM_AHB_GATING0, (1 << AHB_GATE_OFFSET_SPI0));
/* Divide by 4 */
- writel(SPI0_CLK_DIV_BY_4, IS_ENABLED(CONFIG_SUNXI_GEN_SUN6I) ?
- SUN6I_SPI0_CCTL : SUN4I_SPI0_CCTL);
+ if (IS_ENABLED(CONFIG_MACH_SUN50I_H6))
+ writel(SPI0_CLK_DIV_BY_4, SUN50I_H6_SPI0_CCTL);
+ else
+ writel(SPI0_CLK_DIV_BY_4, IS_ENABLED(CONFIG_SUNXI_GEN_SUN6I) ?
+ SUN6I_SPI0_CCTL : SUN4I_SPI0_CCTL);
+
/* 24MHz from OSC24M */
- writel((1 << 31), CCM_SPI0_CLK);
+ writel((1 << 31), IS_ENABLED(CONFIG_MACH_SUN50I_H6) ?
+ SUN50I_H6_CCU_SPI0_CLK : CCM_SPI0_CLK);
- if (IS_ENABLED(CONFIG_SUNXI_GEN_SUN6I)) {
+ if (IS_ENABLED(CONFIG_SUNXI_GEN_SUN6I) ||
+ IS_ENABLED(CONFIG_MACH_SUN50I_H6)) {
/* Enable SPI in the master mode and do a soft reset */
- setbits_le32(SUN6I_SPI0_GCR, SUN6I_CTL_MASTER |
- SUN6I_CTL_ENABLE |
- SUN6I_CTL_SRST);
+ setbits_le32(IS_ENABLED(CONFIG_MACH_SUN50I_H6) ?
+ SUN50I_H6_SPI0_GCR : SUN6I_SPI0_GCR,
+ SUN6I_CTL_MASTER |
+ SUN6I_CTL_ENABLE |
+ SUN6I_CTL_SRST);
+
/* Wait for completion */
- while (readl(SUN6I_SPI0_GCR) & SUN6I_CTL_SRST)
+ while (readl(IS_ENABLED(CONFIG_MACH_SUN50I_H6) ?
+ SUN50I_H6_SPI0_GCR : SUN6I_SPI0_GCR) & SUN6I_CTL_SRST)
;
} else {
/* Enable SPI in the master mode and reset FIFO */
@@ -139,22 +185,33 @@ static void spi0_enable_clock(void)
static void spi0_disable_clock(void)
{
/* Disable the SPI0 controller */
- if (IS_ENABLED(CONFIG_SUNXI_GEN_SUN6I))
- clrbits_le32(SUN6I_SPI0_GCR, SUN6I_CTL_MASTER |
- SUN6I_CTL_ENABLE);
+ if (IS_ENABLED(CONFIG_SUNXI_GEN_SUN6I) ||
+ IS_ENABLED(CONFIG_MACH_SUN50I_H6))
+ clrbits_le32(IS_ENABLED(CONFIG_MACH_SUN50I_H6) ?
+ SUN50I_H6_SPI0_GCR : SUN6I_SPI0_GCR,
+ SUN6I_CTL_MASTER |
+ SUN6I_CTL_ENABLE);
else
clrbits_le32(SUN4I_SPI0_CTL, SUN4I_CTL_MASTER |
SUN4I_CTL_ENABLE);
/* Disable the SPI0 clock */
- writel(0, CCM_SPI0_CLK);
+ writel(0, IS_ENABLED(CONFIG_MACH_SUN50I_H6) ?
+ SUN50I_H6_CCU_SPI0_CLK : CCM_SPI0_CLK);
/* Close the SPI0 gate */
- clrbits_le32(CCM_AHB_GATING0, (1 << AHB_GATE_OFFSET_SPI0));
+ if (IS_ENABLED(CONFIG_MACH_SUN50I_H6))
+ clrbits_le32(SUN50I_H6_SPI_GATING_REG,
+ SUN50I_H6_SPI0_GATING_CLK);
+ else
+ clrbits_le32(CCM_AHB_GATING0, (1 << AHB_GATE_OFFSET_SPI0));
/* Assert SPI0 reset on SUN6I */
- if (IS_ENABLED(CONFIG_SUNXI_GEN_SUN6I))
- clrbits_le32(SUN6I_BUS_SOFT_RST_REG0,
+ if (IS_ENABLED(CONFIG_MACH_SUN50I_H6))
+ setbits_le32(SUN50I_H6_SPI_GATING_REG,
+ SUN50I_H6_SPI0_RST);
+ else if (IS_ENABLED(CONFIG_SUNXI_GEN_SUN6I))
+ setbits_le32(SUN6I_BUS_SOFT_RST_REG0,
(1 << AHB_RESET_SPI0_SHIFT));
}
@@ -162,7 +219,7 @@ static void spi0_init(void)
{
unsigned int pin_function = SUNXI_GPC_SPI0;
- if (IS_ENABLED(CONFIG_MACH_SUN50I))
+ if (IS_ENABLED(CONFIG_MACH_SUN50I) || IS_ENABLED(CONFIG_MACH_SUN50I_H6))
pin_function = SUN50I_GPC_SPI0;
spi0_pinmux_setup(pin_function);
@@ -173,7 +230,9 @@ static void spi0_deinit(void)
{
/* New SoCs can disable pins, older could only set them as input */
unsigned int pin_function = SUNXI_GPIO_INPUT;
- if (IS_ENABLED(CONFIG_SUNXI_GEN_SUN6I))
+
+ if (IS_ENABLED(CONFIG_SUNXI_GEN_SUN6I) ||
+ IS_ENABLED(CONFIG_MACH_SUN50I_H6))
pin_function = SUNXI_GPIO_DISABLE;
spi0_disable_clock();
@@ -233,7 +292,17 @@ static void spi0_read_data(void *buf, u32 addr, u32 len)
if (chunk_len > SPI_READ_MAX_SIZE)
chunk_len = SPI_READ_MAX_SIZE;
- if (IS_ENABLED(CONFIG_SUNXI_GEN_SUN6I)) {
+ if (IS_ENABLED(CONFIG_MACH_SUN50I_H6)) {
+ sunxi_spi0_read_data(buf8, addr, chunk_len,
+ SUN50I_H6_SPI0_TCR,
+ SUN6I_TCR_XCH,
+ SUN50I_H6_SPI0_FIFO_STA,
+ SUN50I_H6_SPI0_TXD,
+ SUN50I_H6_SPI0_RXD,
+ SUN50I_H6_SPI0_MBC,
+ SUN50I_H6_SPI0_MTC,
+ SUN50I_H6_SPI0_BCC);
+ } else if (IS_ENABLED(CONFIG_SUNXI_GEN_SUN6I)) {
sunxi_spi0_read_data(buf8, addr, chunk_len,
SUN6I_SPI0_TCR,
SUN6I_TCR_XCH,
diff --git a/configs/pine_h64_defconfig b/configs/pine_h64_defconfig
index e34f4fd1e4..baddc33abb 100644
--- a/configs/pine_h64_defconfig
+++ b/configs/pine_h64_defconfig
@@ -6,6 +6,7 @@ CONFIG_MMC0_CD_PIN="PF6"
CONFIG_MMC_SUNXI_SLOT_EXTRA=2
# CONFIG_PSCI_RESET is not set
CONFIG_NR_DRAM_BANKS=1
+CONFIG_SPL_SPI_SUNXI=y
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_SPL_DOS_PARTITION is not set
--
2.11.0
More information about the U-Boot
mailing list