diff --git a/fel-spiflash.c b/fel-spiflash.c index 95cab875c..f68593211 100644 --- a/fel-spiflash.c +++ b/fel-spiflash.c @@ -75,22 +75,18 @@ void fel_writel(feldev_handle *dev, uint32_t addr, uint32_t val); #define PB (1) #define PC (2) -#define CCM_SPI0_CLK (0x01C20000 + 0xA0) -#define CCM_AHB_GATING0 (0x01C20000 + 0x60) +#define CCM_SPI0_CLK_OFF 0xa0 +#define CCM_AHB_GATING0_OFF 0x60 #define CCM_AHB_GATE_SPI0 (1 << 20) -#define SUN6I_BUS_SOFT_RST_REG0 (0x01C20000 + 0x2C0) +#define SUN6I_BUS_SOFT_RST_REG0_OFF 0x2c0 #define SUN6I_SPI0_RST (1 << 20) -#define SUNIV_PLL6_CTL (0x01c20000 + 0x28) -#define SUNIV_AHB_APB_CFG (0x01c20000 + 0x54) +#define SUNIV_PLL6_CTL_OFF 0x28 +#define SUNIV_AHB_APB_CFG_OFF 0x54 -#define H6_CCM_SPI0_CLK (0x03001000 + 0x940) -#define H6_CCM_SPI_BGR (0x03001000 + 0x96C) +#define H6_CCM_SPI0_CLK_OFF 0x940 +#define H6_CCM_SPI_BGR_OFF 0x96c #define H6_CCM_SPI0_GATE_RESET (1 << 0 | 1 << 16) -#define SUNIV_GPC_SPI0 (2) -#define SUNXI_GPC_SPI0 (3) -#define SUN50I_GPC_SPI0 (4) - #define SUN4I_CTL_ENABLE (1 << 0) #define SUN4I_CTL_MASTER (1 << 1) #define SUN4I_CTL_TF_RST (1 << 8) @@ -122,38 +118,9 @@ void fel_writel(feldev_handle *dev, uint32_t addr, uint32_t val); #define CCM_SPI0_CLK_DIV_BY_6 (0x1002) #define CCM_SPI0_CLK_DIV_BY_32 (0x100f) -static uint32_t gpio_base(feldev_handle *dev) -{ - soc_info_t *soc_info = dev->soc_info; - switch (soc_info->soc_id) { - case 0x1816: /* V536 */ - case 0x1817: /* V831 */ - case 0x1728: /* H6 */ - case 0x1823: /* H616 */ - return 0x0300B000; - default: - return 0x01C20800; - } -} - 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 */ - case 0x1663: /* F1C100s */ - case 0x1701: /* R40 */ - return 0x01C05000; - case 0x1816: /* V536 */ - case 0x1817: /* V831 */ - case 0x1728: /* H6 */ - case 0x1823: /* H616 */ - return 0x05010000; - default: - return 0x01C68000; - } + return dev->soc_info->spi_base; } /* @@ -162,13 +129,21 @@ static uint32_t spi_base(feldev_handle *dev) static void gpio_set_cfgpin(feldev_handle *dev, int port_num, int pin_num, int val) { - 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); - x &= ~(0x7 << (pin_idx * 4)); - x |= val << (pin_idx * 4); - writel(x, cfg_reg); + uint32_t cfg_reg; + uint32_t pin_idx = pin_num % 8; + uint32_t reg; + + cfg_reg = dev->soc_info->gpio_base; + if (dev->soc_info->flags & GPIO_NCAT2) + cfg_reg += port_num * 0x30; + else + cfg_reg += port_num * 0x24; + cfg_reg += 4 * (pin_num / 8); + + reg = readl(cfg_reg); + reg &= ~(0xf << (pin_idx * 4)); + reg |= val << (pin_idx * 4); + writel(reg, cfg_reg); } static bool spi_is_sun6i(feldev_handle *dev) @@ -184,18 +159,12 @@ static bool spi_is_sun6i(feldev_handle *dev) } } -static bool soc_is_h6_style(feldev_handle *dev) +/* Extract a pin number from the packed representation (one byte per pin) */ +static uint8_t spi_pin(soc_info_t *soc_info, int pin) { - soc_info_t *soc_info = dev->soc_info; - switch (soc_info->soc_id) { - case 0x1816: /* V536 */ - case 0x1817: /* V831 */ - case 0x1728: /* H6 */ - case 0x1823: /* H616 */ - return true; - default: - return false; - } + int shift = (pin - 1) * 8; + + return (soc_info->spi_pins >> shift) & 0xff; } /* @@ -205,81 +174,42 @@ static bool spi0_init(feldev_handle *dev) { uint32_t reg_val; soc_info_t *soc_info = dev->soc_info; + uint32_t ccu_base; + if (!soc_info) { printf("Unable to fetch device information. " "Possibly unknown device.\n"); return false; } - /* Setup SPI0 pins muxing */ - switch (soc_info->soc_id) { - case 0x1663: /* Allwinner F1C100s/F1C600/R6/F1C100A/F1C500 */ - gpio_set_cfgpin(dev, PC, 0, SUNIV_GPC_SPI0); - gpio_set_cfgpin(dev, PC, 1, SUNIV_GPC_SPI0); - gpio_set_cfgpin(dev, PC, 2, SUNIV_GPC_SPI0); - gpio_set_cfgpin(dev, PC, 3, SUNIV_GPC_SPI0); - break; - case 0x1625: /* Allwinner A13 */ - case 0x1680: /* Allwinner H3 */ - case 0x1681: /* Allwinner V3s */ - case 0x1718: /* Allwinner H5 */ - gpio_set_cfgpin(dev, PC, 0, SUNXI_GPC_SPI0); - gpio_set_cfgpin(dev, PC, 1, SUNXI_GPC_SPI0); - gpio_set_cfgpin(dev, PC, 2, SUNXI_GPC_SPI0); - gpio_set_cfgpin(dev, PC, 3, SUNXI_GPC_SPI0); - break; - case 0x1623: /* Allwinner A10 */ - case 0x1651: /* Allwinner A20 */ - case 0x1701: /* Allwinner R40 */ - gpio_set_cfgpin(dev, PC, 0, SUNXI_GPC_SPI0); - gpio_set_cfgpin(dev, PC, 1, SUNXI_GPC_SPI0); - gpio_set_cfgpin(dev, PC, 2, SUNXI_GPC_SPI0); - gpio_set_cfgpin(dev, PC, 23, SUNXI_GPC_SPI0); - break; - case 0x1689: /* Allwinner A64 */ - 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; - case 0x1816: /* Allwinner V536 */ - case 0x1817: /* Allwinner V831 */ - gpio_set_cfgpin(dev, PC, 1, SUN50I_GPC_SPI0); /* SPI0-CS */ - /* fall-through */ - case 0x1728: /* Allwinner H6 */ - gpio_set_cfgpin(dev, PC, 0, SUN50I_GPC_SPI0); - gpio_set_cfgpin(dev, PC, 2, SUN50I_GPC_SPI0); - gpio_set_cfgpin(dev, PC, 3, SUN50I_GPC_SPI0); - /* PC5 is SPI0-CS on the H6, and SPI0-HOLD on the V831 */ - gpio_set_cfgpin(dev, PC, 5, SUN50I_GPC_SPI0); - break; - case 0x1823: /* Allwinner H616 */ - gpio_set_cfgpin(dev, PC, 0, SUN50I_GPC_SPI0); /* SPI0_CLK */ - gpio_set_cfgpin(dev, PC, 2, SUN50I_GPC_SPI0); /* SPI0_MOSI */ - gpio_set_cfgpin(dev, PC, 3, SUN50I_GPC_SPI0); /* SPI0_CS0 */ - gpio_set_cfgpin(dev, PC, 4, SUN50I_GPC_SPI0); /* SPI0_MISO */ - break; - default: /* Unknown/Unsupported SoC */ + if (!soc_info->spi_base) { printf("SPI support not implemented yet for %x (%s)!\n", soc_info->soc_id, soc_info->name); return false; } - if (soc_is_h6_style(dev)) { - reg_val = readl(H6_CCM_SPI_BGR); + /* Setup SPI0 pins muxing */ + gpio_set_cfgpin(dev, PC, spi_pin(soc_info, 1), soc_info->spi_pinmux); + gpio_set_cfgpin(dev, PC, spi_pin(soc_info, 2), soc_info->spi_pinmux); + gpio_set_cfgpin(dev, PC, spi_pin(soc_info, 3), soc_info->spi_pinmux); + gpio_set_cfgpin(dev, PC, spi_pin(soc_info, 4), soc_info->spi_pinmux); + + ccu_base = dev->soc_info->ccu_base; + if (dev->soc_info->flags & H6_STYLE_CLOCKS) { + reg_val = readl(ccu_base + H6_CCM_SPI_BGR_OFF); reg_val |= H6_CCM_SPI0_GATE_RESET; - writel(reg_val, H6_CCM_SPI_BGR); + writel(reg_val, ccu_base + H6_CCM_SPI_BGR_OFF); } else { if (spi_is_sun6i(dev)) { /* Deassert SPI0 reset */ - reg_val = readl(SUN6I_BUS_SOFT_RST_REG0); + reg_val = readl(ccu_base + SUN6I_BUS_SOFT_RST_REG0_OFF); reg_val |= SUN6I_SPI0_RST; - writel(reg_val, SUN6I_BUS_SOFT_RST_REG0); + writel(reg_val, ccu_base + SUN6I_BUS_SOFT_RST_REG0_OFF); } - reg_val = readl(CCM_AHB_GATING0); + reg_val = readl(ccu_base + CCM_AHB_GATING0_OFF); reg_val |= CCM_AHB_GATE_SPI0; - writel(reg_val, CCM_AHB_GATING0); + writel(reg_val, ccu_base + CCM_AHB_GATING0_OFF); } if (soc_info->soc_id == 0x1663) { /* suniv F1C100s */ @@ -291,9 +221,9 @@ static bool spi0_init(feldev_handle *dev) */ /* Set PLL6 to 600MHz */ - writel(0x80041801, SUNIV_PLL6_CTL); + writel(0x80041801, ccu_base + SUNIV_PLL6_CTL_OFF); /* PLL6:AHB:APB = 6:2:1 */ - writel(0x00003180, SUNIV_AHB_APB_CFG); + writel(0x00003180, ccu_base + SUNIV_AHB_APB_CFG_OFF); /* divide by 32 */ writel(CCM_SPI0_CLK_DIV_BY_32, SUN6I_SPI0_CCTL); } else { @@ -301,8 +231,10 @@ static bool spi0_init(feldev_handle *dev) writel(CCM_SPI0_CLK_DIV_BY_4, spi_is_sun6i(dev) ? SUN6I_SPI0_CCTL : SUN4I_SPI0_CCTL); /* Choose 24MHz from OSC24M and enable clock */ - writel(1U << 31, - soc_is_h6_style(dev) ? H6_CCM_SPI0_CLK : CCM_SPI0_CLK); + if (dev->soc_info->flags & H6_STYLE_CLOCKS) + writel(1U << 31, ccu_base + H6_CCM_SPI0_CLK_OFF); + else + writel(1U << 31, ccu_base + CCM_SPI0_CLK_OFF); } if (spi_is_sun6i(dev)) { diff --git a/fel.c b/fel.c index 79a7c24d0..b112506a6 100644 --- a/fel.c +++ b/fel.c @@ -426,7 +426,7 @@ void aw_fel_print_sid(feldev_handle *dev, bool force_workaround) return; } - if (soc_info->sid_fix || force_workaround) { + if (soc_info->flags & NEEDS_SID_FIX || force_workaround) { pr_info("Read SID key via registers, base = 0x%08X\n", soc_info->sid_base); } else { @@ -788,7 +788,7 @@ uint32_t aw_fel_write_and_execute_spl(feldev_handle *dev, uint8_t *buf, size_t l if (spl_checksum != 0) pr_fatal("SPL: checksum check failed\n"); - if (soc_info->needs_l2en) { + if (soc_info->flags & NEEDS_L2EN) { pr_info("Enabling the L2 cache\n"); aw_enable_l2_cache(dev, soc_info); } diff --git a/fel_lib.c b/fel_lib.c index b667dd16c..38a07c3f0 100644 --- a/fel_lib.c +++ b/fel_lib.c @@ -252,7 +252,8 @@ static void aw_disable_icache(feldev_handle *dev) void aw_fel_write(feldev_handle *dev, const void *buf, uint32_t offset, size_t len) { - if (dev->soc_info->icache_fix && !dev->usb->icache_hacked) { + if (dev->soc_info->flags & NEEDS_ICACHE_FIX && + !dev->usb->icache_hacked) { aw_disable_icache(dev); dev->usb->icache_hacked = true; } @@ -617,7 +618,7 @@ int fel_read_sid(feldev_handle *dev, uint32_t *result, if ((offset & 3) || (length & 3)) /* needs to be 32-bit aligned */ return -3; - if (soc->sid_fix || force_workaround) + if (soc->flags & NEEDS_SID_FIX || force_workaround) /* Work around SID issues by using ARM thunk code */ fel_get_sid_registers(dev, result, offset, length); else diff --git a/soc_info.c b/soc_info.c index 4cb6bcc44..0fb2f2884 100644 --- a/soc_info.c +++ b/soc_info.c @@ -324,6 +324,10 @@ static const sid_section generic_2k_sid_maps[] = { SID_SECTION(NULL, 0, 0), }; +/* Pack four pin numbers into one uint32_t, using one byte per pin */ +#define SPI_PINS(p1, p2, p3, p4) \ + ((p1) << 0 | (p2) << 8 | (p3) << 16 | (p4) << 24) + soc_info_t soc_info_table[] = { { .soc_id = 0x1623, /* Allwinner A10 */ @@ -332,9 +336,14 @@ soc_info_t soc_info_table[] = { .thunk_addr = 0xA200, .thunk_size = 0x200, .swap_buffers = a10_a13_a20_sram_swap_buffers, .sram_size = 48 * 1024, - .needs_l2en = true, .sid_base = 0x01C23800, .watchdog = &wd_a10_compat, + .gpio_base = SUNXI_PIO_BASE, + .ccu_base = AW_CCM_BASE, + .spi_base = SUN4I_SPI_BASE, + .spi_pins = SPI_PINS(0, 1, 2, 23), + .spi_pinmux = SUNXI_GPC_SPI0, + .flags = NEEDS_L2EN, },{ .soc_id = 0x1625, /* Allwinner A10s, A13, R8 */ .name = "A13", @@ -342,9 +351,14 @@ soc_info_t soc_info_table[] = { .thunk_addr = 0xA200, .thunk_size = 0x200, .swap_buffers = a10_a13_a20_sram_swap_buffers, .sram_size = 48 * 1024, - .needs_l2en = true, .sid_base = 0x01C23800, .watchdog = &wd_a10_compat, + .gpio_base = SUNXI_PIO_BASE, + .ccu_base = AW_CCM_BASE, + .spi_base = SUN4I_SPI_BASE, + .spi_pins = SPI_PINS(0, 1, 2, 3), + .spi_pinmux = SUNXI_GPC_SPI0, + .flags = NEEDS_L2EN, },{ .soc_id = 0x1651, /* Allwinner A20 */ .name = "A20", @@ -355,6 +369,11 @@ soc_info_t soc_info_table[] = { .sid_base = 0x01C23800, .sid_sections = generic_2k_sid_maps, .watchdog = &wd_a10_compat, + .gpio_base = SUNXI_PIO_BASE, + .ccu_base = AW_CCM_BASE, + .spi_base = SUN4I_SPI_BASE, + .spi_pins = SPI_PINS(0, 1, 2, 23), + .spi_pinmux = SUNXI_GPC_SPI0, },{ .soc_id = 0x1650, /* Allwinner A23 */ .name = "A23", @@ -365,6 +384,8 @@ soc_info_t soc_info_table[] = { .sid_base = 0x01C23800, .sid_sections = generic_2k_sid_maps, .watchdog = &wd_h3_compat, + .gpio_base = SUNXI_PIO_BASE, + .ccu_base = AW_CCM_BASE, },{ .soc_id = 0x1633, /* Allwinner A31 */ .name = "A31", @@ -373,6 +394,8 @@ soc_info_t soc_info_table[] = { .swap_buffers = a31_sram_swap_buffers, .sram_size = 32 * 1024, .watchdog = &wd_h3_compat, + .gpio_base = SUNXI_PIO_BASE, + .ccu_base = AW_CCM_BASE, },{ .soc_id = 0x1667, /* Allwinner A33, R16 */ .name = "A33", @@ -383,6 +406,8 @@ soc_info_t soc_info_table[] = { .sid_base = 0x01C23800, .sid_sections = generic_2k_sid_maps, .watchdog = &wd_h3_compat, + .gpio_base = SUNXI_PIO_BASE, + .ccu_base = AW_CCM_BASE, },{ .soc_id = 0x1689, /* Allwinner A64 */ .name = "A64", @@ -398,6 +423,11 @@ soc_info_t soc_info_table[] = { /* Check L.NOP in the OpenRISC reset vector */ .needs_smc_workaround_if_zero_word_at_addr = 0x40004, .watchdog = &wd_h3_compat, + .gpio_base = SUNXI_PIO_BASE, + .ccu_base = AW_CCM_BASE, + .spi_base = SUN6I_SPI_BASE, + .spi_pins = SPI_PINS(0, 1, 2, 3), + .spi_pinmux = SUN50I_GPC_SPI0, },{ .soc_id = 0x1639, /* Allwinner A80 */ .name = "A80", @@ -410,6 +440,8 @@ soc_info_t soc_info_table[] = { .sid_offset = 0x200, .sid_sections = generic_2k_sid_maps, .watchdog = &wd_a80, + .gpio_base = A80_PIO_BASE, + .ccu_base = A80_CCM_BASE, },{ .soc_id = 0x1663, /* Allwinner F1C100s (all new sun3i?) */ .name = "F1C100s", @@ -419,6 +451,11 @@ soc_info_t soc_info_table[] = { .sram_size = 32 * 1024, /* No SID */ .watchdog = &wd_h3_compat, + .gpio_base = SUNXI_PIO_BASE, + .ccu_base = AW_CCM_BASE, + .spi_base = SUN4I_SPI_BASE, + .spi_pins = SPI_PINS(0, 1, 2, 3), + .spi_pinmux = SUNIV_GPC_SPI0, },{ .soc_id = 0x1673, /* Allwinner A83T */ .name = "A83T", @@ -431,6 +468,8 @@ soc_info_t soc_info_table[] = { .sid_offset = 0x200, .sid_sections = generic_2k_sid_maps, .watchdog = &wd_h3_compat, + .gpio_base = SUNXI_PIO_BASE, + .ccu_base = AW_CCM_BASE, },{ .soc_id = 0x1680, /* Allwinner H3, H2+ */ .name = "H3", @@ -441,11 +480,16 @@ soc_info_t soc_info_table[] = { .sram_size = 108 * 1024, .sid_base = 0x01C14000, .sid_offset = 0x200, - .sid_fix = true, .sid_sections = h3_sid_maps, /* Check L.NOP in the OpenRISC reset vector */ .needs_smc_workaround_if_zero_word_at_addr = 0x40004, .watchdog = &wd_h3_compat, + .gpio_base = SUNXI_PIO_BASE, + .ccu_base = AW_CCM_BASE, + .spi_base = SUN6I_SPI_BASE, + .spi_pins = SPI_PINS(0, 1, 2, 3), + .spi_pinmux = SUNXI_GPC_SPI0, + .flags = NEEDS_SID_FIX, },{ .soc_id = 0x1681, /* Allwinner V3s */ .name = "V3s", @@ -457,6 +501,11 @@ soc_info_t soc_info_table[] = { .sid_base = 0x01C23800, .sid_sections = generic_2k_sid_maps, .watchdog = &wd_h3_compat, + .gpio_base = SUNXI_PIO_BASE, + .ccu_base = AW_CCM_BASE, + .spi_base = SUN6I_SPI_BASE, + .spi_pins = SPI_PINS(0, 1, 2, 3), + .spi_pinmux = SUNXI_GPC_SPI0, },{ .soc_id = 0x1708, /* Allwinner T7 */ .name = "T7", @@ -469,6 +518,9 @@ soc_info_t soc_info_table[] = { .sid_offset = 0x200, .sid_sections = t7_sid_maps, .watchdog = &wd_h6_compat, + .gpio_base = H6_PIO_BASE, + .ccu_base = H6_CCM_BASE, + .flags = H6_STYLE_CLOCKS, },{ .soc_id = 0x1718, /* Allwinner H5 */ .name = "H5", @@ -484,6 +536,11 @@ soc_info_t soc_info_table[] = { /* Check L.NOP in the OpenRISC reset vector */ .needs_smc_workaround_if_zero_word_at_addr = 0x40004, .watchdog = &wd_h3_compat, + .gpio_base = SUNXI_PIO_BASE, + .ccu_base = AW_CCM_BASE, + .spi_base = SUN6I_SPI_BASE, + .spi_pins = SPI_PINS(0, 1, 2, 3), + .spi_pinmux = SUNXI_GPC_SPI0, },{ .soc_id = 0x1701, /* Allwinner R40 */ .name = "R40", @@ -495,6 +552,11 @@ soc_info_t soc_info_table[] = { .sid_offset = 0x200, .sid_sections = r40_sid_maps, .watchdog = &wd_a10_compat, + .gpio_base = SUNXI_PIO_BASE, + .ccu_base = AW_CCM_BASE, + .spi_base = SUN4I_SPI_BASE, + .spi_pins = SPI_PINS(0, 1, 2, 23), + .spi_pinmux = SUNXI_GPC_SPI0, },{ .soc_id = 0x1719, /* Allwinner A63 */ .name = "A63", @@ -508,6 +570,9 @@ soc_info_t soc_info_table[] = { .sid_sections = generic_2k_sid_maps, .rvbar_reg = 0x09010040, .watchdog = &wd_h6_compat, + .gpio_base = H6_PIO_BASE, + .ccu_base = H6_CCM_BASE, + .flags = H6_STYLE_CLOCKS, },{ .soc_id = 0x1728, /* Allwinner H6 */ .name = "H6", @@ -523,6 +588,12 @@ soc_info_t soc_info_table[] = { /* Check L.NOP in the OpenRISC reset vector */ .needs_smc_workaround_if_zero_word_at_addr = 0x100004, .watchdog = &wd_h6_compat, + .gpio_base = H6_PIO_BASE, + .ccu_base = H6_CCM_BASE, + .spi_base = H6_SPI_BASE, + .spi_pins = SPI_PINS(0, 2, 3, 5), + .spi_pinmux = SUN50I_GPC_SPI0, + .flags = H6_STYLE_CLOCKS, },{ .soc_id = 0x1816, /* Allwinner V536 */ .name = "V536", @@ -535,6 +606,12 @@ soc_info_t soc_info_table[] = { .sid_offset = 0x200, .sid_sections = generic_2k_sid_maps, .watchdog = &wd_h6_compat, + .gpio_base = H6_PIO_BASE, + .ccu_base = H6_CCM_BASE, + .spi_base = H6_SPI_BASE, + .spi_pins = SPI_PINS(0, 1, 2, 3), + .spi_pinmux = SUN50I_GPC_SPI0, + .flags = H6_STYLE_CLOCKS, },{ .soc_id = 0x1817, /* Allwinner V831 */ .name = "V831", @@ -547,6 +624,12 @@ soc_info_t soc_info_table[] = { .sid_offset = 0x200, .sid_sections = generic_2k_sid_maps, .watchdog = &wd_h6_compat, + .gpio_base = H6_PIO_BASE, + .ccu_base = H6_CCM_BASE, + .spi_base = H6_SPI_BASE, + .spi_pins = SPI_PINS(0, 1, 2, 3), + .spi_pinmux = SUN50I_GPC_SPI0, + .flags = H6_STYLE_CLOCKS, },{ .soc_id = 0x1823, /* Allwinner H616 */ .name = "H616", @@ -562,6 +645,12 @@ soc_info_t soc_info_table[] = { .rvbar_reg_alt= 0x08100040, .ver_reg = 0x03000024, .watchdog = &wd_h6_compat, + .gpio_base = H6_PIO_BASE, + .ccu_base = H6_CCM_BASE, + .spi_base = H6_SPI_BASE, + .spi_pins = SPI_PINS(0, 2, 3, 4), + .spi_pinmux = SUN50I_GPC_SPI0, + .flags = H6_STYLE_CLOCKS, },{ .soc_id = 0x1851, /* Allwinner R329 */ .name = "R329", @@ -576,6 +665,9 @@ soc_info_t soc_info_table[] = { .sid_sections = generic_2k_sid_maps, .rvbar_reg = 0x08100040, .watchdog = &wd_h6_compat, + .gpio_base = R329_PIO_BASE, + .ccu_base = R329_CCM_BASE, + .flags = FLAGS_NCAT2, },{ .soc_id = 0x1886, /* Allwinner V853 */ .name = "V853", @@ -587,8 +679,10 @@ soc_info_t soc_info_table[] = { .sid_base = 0x03006000, .sid_offset = 0x200, .sid_sections = generic_2k_sid_maps, - .icache_fix = true, .watchdog = &wd_v853_compat, + .gpio_base = V853_PIO_BASE, + .ccu_base = R329_CCM_BASE, + .flags = NEEDS_ICACHE_FIX | FLAGS_NCAT2, },{ .soc_id = 0x1859, /* Allwinner D1/D1s/R528/T113-S3 */ .name = "R528", @@ -600,8 +694,10 @@ soc_info_t soc_info_table[] = { .sid_base = 0x03006000, .sid_offset = 0x200, .sid_sections = generic_2k_sid_maps, - .icache_fix = true, .watchdog = &wd_v853_compat, + .gpio_base = V853_PIO_BASE, + .ccu_base = R329_CCM_BASE, + .flags = NEEDS_ICACHE_FIX | FLAGS_NCAT2, },{ .soc_id = 0x1721, /* Allwinner V5 */ .name = "V5", @@ -614,6 +710,9 @@ soc_info_t soc_info_table[] = { .sid_offset = 0x200, .sid_sections = generic_2k_sid_maps, .watchdog = &wd_h6_compat, + .gpio_base = H6_PIO_BASE, + .ccu_base = H6_CCM_BASE, + .flags = H6_STYLE_CLOCKS, },{ .soc_id = 0x1890, /* Allwinner A523 */ .name = "A523", @@ -626,8 +725,10 @@ soc_info_t soc_info_table[] = { .sid_offset = 0x200, .sid_sections = generic_2k_sid_maps, .rvbar_reg = 0x08000040, - .icache_fix = true, .watchdog = &wd_a523_compat, + .gpio_base = V853_PIO_BASE, + .ccu_base = R329_CCM_BASE, + .flags = NEEDS_ICACHE_FIX | FLAGS_NCAT2, },{ .soc_id = 0x1855, /* Allwinner A133 */ .name = "A133", @@ -642,6 +743,9 @@ soc_info_t soc_info_table[] = { .rvbar_reg = 0x08100040, .needs_smc_workaround_if_zero_word_at_addr = 0x100004, .watchdog = &wd_h6_compat, + .gpio_base = H6_PIO_BASE, + .ccu_base = H6_CCM_BASE, + .flags = H6_STYLE_CLOCKS, },{ .swap_buffers = NULL /* End of the table */ } diff --git a/soc_info.h b/soc_info.h index 508f29dab..497c5cda5 100644 --- a/soc_info.h +++ b/soc_info.h @@ -76,6 +76,35 @@ typedef struct { .size_bits = _size_bits, \ } +#define BIT(x) (1U << (x)) + +enum soc_flags { + NEEDS_L2EN = BIT(0), + NEEDS_SID_FIX = BIT(1), + NEEDS_ICACHE_FIX = BIT(2), + H6_STYLE_CLOCKS = BIT(3), + GPIO_NCAT2 = BIT(4), +}; + +#define FLAGS_NCAT2 (GPIO_NCAT2 | H6_STYLE_CLOCKS) + +#define AW_CCM_BASE 0x01c20000 +#define SUNXI_PIO_BASE 0x01c20800 +#define A80_CCM_BASE 0x06000000 +#define A80_PIO_BASE 0x06000800 +#define H6_PIO_BASE 0x0300b000 +#define H6_CCM_BASE 0x03001000 +#define V853_PIO_BASE 0x02000000 +#define R329_PIO_BASE 0x02000400 +#define R329_CCM_BASE 0x02001000 +#define SUN4I_SPI_BASE 0x01c05000 +#define SUN6I_SPI_BASE 0x01c68000 +#define H6_SPI_BASE 0x05010000 + +#define SUNIV_GPC_SPI0 2 +#define SUNXI_GPC_SPI0 3 +#define SUN50I_GPC_SPI0 4 + /* * Each SoC variant may have its own list of memory buffers to be exchanged * and the information about the placement of the thunk code, which handles @@ -121,7 +150,6 @@ typedef struct { uint32_t scratch_addr; /* A safe place to upload & run code */ uint32_t thunk_addr; /* Address of the thunk code */ uint32_t thunk_size; /* Maximal size of the thunk code */ - bool needs_l2en; /* Set the L2EN bit */ uint32_t mmu_tt_addr; /* MMU translation table address */ uint32_t sid_base; /* base address for SID registers */ uint32_t sid_offset; /* offset for SID_KEY[0-3], "root key" */ @@ -130,13 +158,17 @@ typedef struct { uint32_t rvbar_reg_alt;/* alternative MMIO address of RVBARADDR0_L register */ uint32_t ver_reg; /* MMIO address of "Version Register" */ const watchdog_info *watchdog; /* Used for reset */ - bool sid_fix; /* Use SID workaround (read via register) */ /* Use I$ workaround (disable I$ before first write to prevent stale thunk */ - bool icache_fix; /* Use SMC workaround (enter secure mode) if can't read from this address */ uint32_t needs_smc_workaround_if_zero_word_at_addr; uint32_t sram_size; /* Usable contiguous SRAM at spl_addr */ sram_swap_buffers *swap_buffers; + uint32_t gpio_base; + uint32_t ccu_base; + uint32_t spi_base; + uint32_t spi_pins; /* PC offset for 4 pins, 1 byte each */ + uint8_t spi_pinmux; + uint32_t flags; } soc_info_t;