Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/linux-sunxi/sunxi-tools.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChen-Yu Tsai <wens@csie.org>2020-09-29 12:39:49 +0300
committerGitHub <noreply@github.com>2020-09-29 12:39:49 +0300
commit7cc37c883b35789f6d3a3335263550ae31fa3b38 (patch)
tree6599658bc467fb7e2d4dc016d16ba79bdc741119 /fel-spiflash.c
parente334ccf5b2aee5c450570bb6e7d06ea7c634027d (diff)
parenteac43cf7e9ea23988bf4acb10e0e140883395300 (diff)
Merge pull request #140 from Icenowy/v831
V831 SoC support
Diffstat (limited to 'fel-spiflash.c')
-rw-r--r--fel-spiflash.c114
1 files changed, 87 insertions, 27 deletions
diff --git a/fel-spiflash.c b/fel-spiflash.c
index 5a22581..467c504 100644
--- a/fel-spiflash.c
+++ b/fel-spiflash.c
@@ -81,6 +81,10 @@ void fel_writel(feldev_handle *dev, uint32_t addr, uint32_t val);
#define SUN6I_BUS_SOFT_RST_REG0 (0x01C20000 + 0x2C0)
#define SUN6I_SPI0_RST (1 << 20)
+#define H6_CCM_SPI0_CLK (0x03001000 + 0x940)
+#define H6_CCM_SPI_BGR (0x03001000 + 0x96C)
+#define H6_CCM_SPI0_GATE_RESET (1 << 0 | 1 << 16)
+
#define SUNXI_GPC_SPI0 (3)
#define SUN50I_GPC_SPI0 (4)
@@ -92,35 +96,61 @@ void fel_writel(feldev_handle *dev, uint32_t addr, uint32_t val);
#define SUN6I_TCR_XCH (1 << 31)
-#define SUN4I_SPI0_CCTL (0x01C05000 + 0x1C)
-#define SUN4I_SPI0_CTL (0x01C05000 + 0x08)
-#define SUN4I_SPI0_RX (0x01C05000 + 0x00)
-#define SUN4I_SPI0_TX (0x01C05000 + 0x04)
-#define SUN4I_SPI0_FIFO_STA (0x01C05000 + 0x28)
-#define SUN4I_SPI0_BC (0x01C05000 + 0x20)
-#define SUN4I_SPI0_TC (0x01C05000 + 0x24)
-
-#define SUN6I_SPI0_CCTL (0x01C68000 + 0x24)
-#define SUN6I_SPI0_GCR (0x01C68000 + 0x04)
-#define SUN6I_SPI0_TCR (0x01C68000 + 0x08)
-#define SUN6I_SPI0_FIFO_STA (0x01C68000 + 0x1C)
-#define SUN6I_SPI0_MBC (0x01C68000 + 0x30)
-#define SUN6I_SPI0_MTC (0x01C68000 + 0x34)
-#define SUN6I_SPI0_BCC (0x01C68000 + 0x38)
-#define SUN6I_SPI0_TXD (0x01C68000 + 0x200)
-#define SUN6I_SPI0_RXD (0x01C68000 + 0x300)
+#define SUN4I_SPI0_CCTL (spi_base(dev) + 0x1C)
+#define SUN4I_SPI0_CTL (spi_base(dev) + 0x08)
+#define SUN4I_SPI0_RX (spi_base(dev) + 0x00)
+#define SUN4I_SPI0_TX (spi_base(dev) + 0x04)
+#define SUN4I_SPI0_FIFO_STA (spi_base(dev) + 0x28)
+#define SUN4I_SPI0_BC (spi_base(dev) + 0x20)
+#define SUN4I_SPI0_TC (spi_base(dev) + 0x24)
+
+#define SUN6I_SPI0_CCTL (spi_base(dev) + 0x24)
+#define SUN6I_SPI0_GCR (spi_base(dev) + 0x04)
+#define SUN6I_SPI0_TCR (spi_base(dev) + 0x08)
+#define SUN6I_SPI0_FIFO_STA (spi_base(dev) + 0x1C)
+#define SUN6I_SPI0_MBC (spi_base(dev) + 0x30)
+#define SUN6I_SPI0_MTC (spi_base(dev) + 0x34)
+#define SUN6I_SPI0_BCC (spi_base(dev) + 0x38)
+#define SUN6I_SPI0_TXD (spi_base(dev) + 0x200)
+#define SUN6I_SPI0_RXD (spi_base(dev) + 0x300)
#define CCM_SPI0_CLK_DIV_BY_2 (0x1000)
#define CCM_SPI0_CLK_DIV_BY_4 (0x1001)
#define CCM_SPI0_CLK_DIV_BY_6 (0x1002)
+static uint32_t gpio_base(feldev_handle *dev)
+{
+ soc_info_t *soc_info = dev->soc_info;
+ switch (soc_info->soc_id) {
+ case 0x1817: /* V831 */
+ return 0x0300B000;
+ default:
+ return 0x01C28000;
+ }
+}
+
+static uint32_t spi_base(feldev_handle *dev)
+{
+ soc_info_t *soc_info = dev->soc_info;
+ switch (soc_info->soc_id) {
+ case 0x1623: /* A10 */
+ case 0x1625: /* A13 */
+ case 0x1651: /* A20 */
+ return 0x01C05000;
+ case 0x1817: /* V831 */
+ return 0x05010000;
+ default:
+ return 0x01C68000;
+ }
+}
+
/*
* Configure pin function on a GPIO port
*/
static void gpio_set_cfgpin(feldev_handle *dev, int port_num, int pin_num,
int val)
{
- uint32_t port_base = 0x01C20800 + port_num * 0x24;
+ uint32_t port_base = gpio_base(dev) + port_num * 0x24;
uint32_t cfg_reg = port_base + 4 * (pin_num / 8);
uint32_t pin_idx = pin_num % 8;
uint32_t x = readl(cfg_reg);
@@ -142,6 +172,17 @@ static bool spi_is_sun6i(feldev_handle *dev)
}
}
+static bool soc_is_h6_style(feldev_handle *dev)
+{
+ soc_info_t *soc_info = dev->soc_info;
+ switch (soc_info->soc_id) {
+ case 0x1817: /* V831 */
+ return true;
+ default:
+ return false;
+ }
+}
+
/*
* Init the SPI0 controller and setup pins muxing.
*/
@@ -179,27 +220,46 @@ static bool spi0_init(feldev_handle *dev)
gpio_set_cfgpin(dev, PC, 2, SUN50I_GPC_SPI0);
gpio_set_cfgpin(dev, PC, 3, SUN50I_GPC_SPI0);
break;
+ case 0x1817: /* Allwinner V831 */
+ gpio_set_cfgpin(dev, PC, 0, SUN50I_GPC_SPI0);
+ gpio_set_cfgpin(dev, PC, 1, SUN50I_GPC_SPI0);
+ gpio_set_cfgpin(dev, PC, 2, SUN50I_GPC_SPI0);
+ gpio_set_cfgpin(dev, PC, 3, SUN50I_GPC_SPI0);
+ break;
default: /* Unknown/Unsupported SoC */
printf("SPI support not implemented yet for %x (%s)!\n",
soc_info->soc_id, soc_info->name);
return false;
}
- reg_val = readl(CCM_AHB_GATING0);
- reg_val |= CCM_AHB_GATE_SPI0;
- writel(reg_val, CCM_AHB_GATING0);
+ if (soc_is_h6_style(dev)) {
+ reg_val = readl(H6_CCM_SPI_BGR);
+ reg_val |= H6_CCM_SPI0_GATE_RESET;
+ writel(reg_val, H6_CCM_SPI_BGR);
+
+ /* 24MHz from OSC24M */
+ writel((1 << 31), H6_CCM_SPI0_CLK);
+ } else {
+ reg_val = readl(CCM_AHB_GATING0);
+ reg_val |= CCM_AHB_GATE_SPI0;
+ writel(reg_val, CCM_AHB_GATING0);
+
+ if (spi_is_sun6i(dev)) {
+ /* Deassert SPI0 reset */
+ reg_val = readl(SUN6I_BUS_SOFT_RST_REG0);
+ reg_val |= SUN6I_SPI0_RST;
+ writel(reg_val, SUN6I_BUS_SOFT_RST_REG0);
+ }
+
+ /* 24MHz from OSC24M */
+ writel((1 << 31), CCM_SPI0_CLK);
+ }
- /* 24MHz from OSC24M */
- writel((1 << 31), CCM_SPI0_CLK);
/* divide by 4 */
writel(CCM_SPI0_CLK_DIV_BY_4, spi_is_sun6i(dev) ? SUN6I_SPI0_CCTL :
SUN4I_SPI0_CCTL);
if (spi_is_sun6i(dev)) {
- /* Deassert SPI0 reset */
- reg_val = readl(SUN6I_BUS_SOFT_RST_REG0);
- reg_val |= SUN6I_SPI0_RST;
- writel(reg_val, SUN6I_BUS_SOFT_RST_REG0);
/* Enable SPI in the master mode and do a soft reset */
reg_val = readl(SUN6I_SPI0_GCR);
reg_val |= (1 << 31) | 3;