Skip to content

Commit c53f0c4

Browse files
committed
feat: fixes A523 SPI support
1 parent 7540cb2 commit c53f0c4

2 files changed

Lines changed: 49 additions & 6 deletions

File tree

fel-spiflash.c

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ void fel_writel(feldev_handle *dev, uint32_t addr, uint32_t val);
8787
#define H6_CCM_SPI_BGR (0x03001000 + 0x96C)
8888
#define H6_CCM_SPI0_GATE_RESET (1 << 0 | 1 << 16)
8989

90+
#define SUN55I_CCM_SPI0_CLK (0x02001000 + 0x940)
91+
#define SUN55I_CCM_SPI_BGR (0x02001000 + 0x96C)
92+
#define SUN55I_CCM_SPI0_GATE_RESET (1 << 0 | 1 << 16)
93+
9094
#define SUNIV_GPC_SPI0 (2)
9195
#define SUNXI_GPC_SPI0 (3)
9296
#define SUN50I_GPC_SPI0 (4)
@@ -131,6 +135,8 @@ static uint32_t gpio_base(feldev_handle *dev)
131135
case 0x1728: /* H6 */
132136
case 0x1823: /* H616 */
133137
return 0x0300B000;
138+
case 0x1890: /* A523 */
139+
return 0x02000000;
134140
default:
135141
return 0x01C20800;
136142
}
@@ -151,22 +157,36 @@ static uint32_t spi_base(feldev_handle *dev)
151157
case 0x1728: /* H6 */
152158
case 0x1823: /* H616 */
153159
return 0x05010000;
160+
case 0x1890: /* A523 */
161+
return 0x04025000;
154162
default:
155163
return 0x01C68000;
156164
}
157165
}
158166

167+
static uint32_t gpio_port_stride(feldev_handle *dev)
168+
{
169+
soc_info_t *soc_info = dev->soc_info;
170+
switch (soc_info->soc_id) {
171+
case 0x1890: /* A523 */
172+
return 0x30;
173+
default:
174+
return 0x24;
175+
}
176+
}
177+
159178
/*
160-
* Configure pin function on a GPIO port
179+
* Configure pin function on a GPIO port.
180+
* Mux fields are 4 bits wide on all sunxi SoCs (pin_idx * 4 bit offset).
161181
*/
162182
static void gpio_set_cfgpin(feldev_handle *dev, int port_num, int pin_num,
163183
int val)
164184
{
165-
uint32_t port_base = gpio_base(dev) + port_num * 0x24;
185+
uint32_t port_base = gpio_base(dev) + port_num * gpio_port_stride(dev);
166186
uint32_t cfg_reg = port_base + 4 * (pin_num / 8);
167187
uint32_t pin_idx = pin_num % 8;
168188
uint32_t x = readl(cfg_reg);
169-
x &= ~(0x7 << (pin_idx * 4));
189+
x &= ~(0xf << (pin_idx * 4));
170190
x |= val << (pin_idx * 4);
171191
writel(x, cfg_reg);
172192
}
@@ -198,6 +218,17 @@ static bool soc_is_h6_style(feldev_handle *dev)
198218
}
199219
}
200220

221+
static bool soc_is_a523_style(feldev_handle *dev)
222+
{
223+
soc_info_t *soc_info = dev->soc_info;
224+
switch (soc_info->soc_id) {
225+
case 0x1890: /* A523 */
226+
return true;
227+
default:
228+
return false;
229+
}
230+
}
231+
201232
/*
202233
* Init the SPI0 controller and setup pins muxing.
203234
*/
@@ -259,13 +290,23 @@ static bool spi0_init(feldev_handle *dev)
259290
gpio_set_cfgpin(dev, PC, 3, SUN50I_GPC_SPI0); /* SPI0_CS0 */
260291
gpio_set_cfgpin(dev, PC, 4, SUN50I_GPC_SPI0); /* SPI0_MISO */
261292
break;
293+
case 0x1890: /* Allwinner A523 */
294+
gpio_set_cfgpin(dev, PC, 12, SUN50I_GPC_SPI0); /* SPI0_CLK */
295+
gpio_set_cfgpin(dev, PC, 2, SUN50I_GPC_SPI0); /* SPI0_MOSI */
296+
gpio_set_cfgpin(dev, PC, 3, SUN50I_GPC_SPI0); /* SPI0_CS0 */
297+
gpio_set_cfgpin(dev, PC, 4, SUN50I_GPC_SPI0); /* SPI0_MISO */
298+
break;
262299
default: /* Unknown/Unsupported SoC */
263300
printf("SPI support not implemented yet for %x (%s)!\n",
264301
soc_info->soc_id, soc_info->name);
265302
return false;
266303
}
267304

268-
if (soc_is_h6_style(dev)) {
305+
if (soc_is_a523_style(dev)) {
306+
reg_val = readl(SUN55I_CCM_SPI_BGR);
307+
reg_val |= SUN55I_CCM_SPI0_GATE_RESET;
308+
writel(reg_val, SUN55I_CCM_SPI_BGR);
309+
} else if (soc_is_h6_style(dev)) {
269310
reg_val = readl(H6_CCM_SPI_BGR);
270311
reg_val |= H6_CCM_SPI0_GATE_RESET;
271312
writel(reg_val, H6_CCM_SPI_BGR);
@@ -302,7 +343,8 @@ static bool spi0_init(feldev_handle *dev)
302343
spi_is_sun6i(dev) ? SUN6I_SPI0_CCTL : SUN4I_SPI0_CCTL);
303344
/* Choose 24MHz from OSC24M and enable clock */
304345
writel(1U << 31,
305-
soc_is_h6_style(dev) ? H6_CCM_SPI0_CLK : CCM_SPI0_CLK);
346+
soc_is_a523_style(dev) ? SUN55I_CCM_SPI0_CLK :
347+
soc_is_h6_style(dev) ? H6_CCM_SPI0_CLK : CCM_SPI0_CLK);
306348
}
307349

308350
if (spi_is_sun6i(dev)) {

soc_info.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,8 @@ soc_info_t soc_info_table[] = {
618618
.soc_id = 0x1890, /* Allwinner A523 */
619619
.name = "A523",
620620
.spl_addr = 0x44000,
621-
.scratch_addr = 0x45000,
621+
.scratch_addr = 0x44200, /* 0x44000+0x200: backup region is only 512 B; larger values
622+
* cause the BROM's FEL_READ to corrupt subsequent USB ops */
622623
.thunk_addr = 0x40000, .thunk_size = 0x200,
623624
.swap_buffers = a523_sram_swap_buffers,
624625
.sram_size = 96 * 1024,

0 commit comments

Comments
 (0)