Skip to content

Commit c65c3b1

Browse files
committed
spi: use pins and pinmux data from soc_info
The bootable SPI flash is always connected to PortC pins, though the exact pin numbers within PortC and their pinmux differs between the SoCs. We always need four pins (MOSI, MISO, CLK, CS), so pack their pin numbers into one 32-bit word and store that in our soc table. Also store the required pinmux (which is always the same for all four pins) in the table. Then use this information in the SPI flash code to extract the pins again and configure them accordingly. This does away with the fragile switch/case construct we used to configure the pins so far. Signed-off-by: Andre Przywara <osp@andrep.de>
1 parent ef7839a commit c65c3b1

3 files changed

Lines changed: 51 additions & 53 deletions

File tree

fel-spiflash.c

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

90-
#define SUNIV_GPC_SPI0 (2)
91-
#define SUNXI_GPC_SPI0 (3)
92-
#define SUN50I_GPC_SPI0 (4)
93-
9490
#define SUN4I_CTL_ENABLE (1 << 0)
9591
#define SUN4I_CTL_MASTER (1 << 1)
9692
#define SUN4I_CTL_TF_RST (1 << 8)
@@ -163,6 +159,14 @@ static bool spi_is_sun6i(feldev_handle *dev)
163159
}
164160
}
165161

162+
/* Extract a pin number from the packed representation (one byte per pin) */
163+
static uint8_t spi_pin(soc_info_t *soc_info, int pin)
164+
{
165+
int shift = (pin - 1) * 8;
166+
167+
return (soc_info->spi_pins >> shift) & 0xff;
168+
}
169+
166170
/*
167171
* Init the SPI0 controller and setup pins muxing.
168172
*/
@@ -178,60 +182,18 @@ static bool spi0_init(feldev_handle *dev)
178182
return false;
179183
}
180184

181-
/* Setup SPI0 pins muxing */
182-
switch (soc_info->soc_id) {
183-
case 0x1663: /* Allwinner F1C100s/F1C600/R6/F1C100A/F1C500 */
184-
gpio_set_cfgpin(dev, PC, 0, SUNIV_GPC_SPI0);
185-
gpio_set_cfgpin(dev, PC, 1, SUNIV_GPC_SPI0);
186-
gpio_set_cfgpin(dev, PC, 2, SUNIV_GPC_SPI0);
187-
gpio_set_cfgpin(dev, PC, 3, SUNIV_GPC_SPI0);
188-
break;
189-
case 0x1625: /* Allwinner A13 */
190-
case 0x1680: /* Allwinner H3 */
191-
case 0x1681: /* Allwinner V3s */
192-
case 0x1718: /* Allwinner H5 */
193-
gpio_set_cfgpin(dev, PC, 0, SUNXI_GPC_SPI0);
194-
gpio_set_cfgpin(dev, PC, 1, SUNXI_GPC_SPI0);
195-
gpio_set_cfgpin(dev, PC, 2, SUNXI_GPC_SPI0);
196-
gpio_set_cfgpin(dev, PC, 3, SUNXI_GPC_SPI0);
197-
break;
198-
case 0x1623: /* Allwinner A10 */
199-
case 0x1651: /* Allwinner A20 */
200-
case 0x1701: /* Allwinner R40 */
201-
gpio_set_cfgpin(dev, PC, 0, SUNXI_GPC_SPI0);
202-
gpio_set_cfgpin(dev, PC, 1, SUNXI_GPC_SPI0);
203-
gpio_set_cfgpin(dev, PC, 2, SUNXI_GPC_SPI0);
204-
gpio_set_cfgpin(dev, PC, 23, SUNXI_GPC_SPI0);
205-
break;
206-
case 0x1689: /* Allwinner A64 */
207-
gpio_set_cfgpin(dev, PC, 0, SUN50I_GPC_SPI0);
208-
gpio_set_cfgpin(dev, PC, 1, SUN50I_GPC_SPI0);
209-
gpio_set_cfgpin(dev, PC, 2, SUN50I_GPC_SPI0);
210-
gpio_set_cfgpin(dev, PC, 3, SUN50I_GPC_SPI0);
211-
break;
212-
case 0x1816: /* Allwinner V536 */
213-
case 0x1817: /* Allwinner V831 */
214-
gpio_set_cfgpin(dev, PC, 1, SUN50I_GPC_SPI0); /* SPI0-CS */
215-
/* fall-through */
216-
case 0x1728: /* Allwinner H6 */
217-
gpio_set_cfgpin(dev, PC, 0, SUN50I_GPC_SPI0);
218-
gpio_set_cfgpin(dev, PC, 2, SUN50I_GPC_SPI0);
219-
gpio_set_cfgpin(dev, PC, 3, SUN50I_GPC_SPI0);
220-
/* PC5 is SPI0-CS on the H6, and SPI0-HOLD on the V831 */
221-
gpio_set_cfgpin(dev, PC, 5, SUN50I_GPC_SPI0);
222-
break;
223-
case 0x1823: /* Allwinner H616 */
224-
gpio_set_cfgpin(dev, PC, 0, SUN50I_GPC_SPI0); /* SPI0_CLK */
225-
gpio_set_cfgpin(dev, PC, 2, SUN50I_GPC_SPI0); /* SPI0_MOSI */
226-
gpio_set_cfgpin(dev, PC, 3, SUN50I_GPC_SPI0); /* SPI0_CS0 */
227-
gpio_set_cfgpin(dev, PC, 4, SUN50I_GPC_SPI0); /* SPI0_MISO */
228-
break;
229-
default: /* Unknown/Unsupported SoC */
185+
if (!soc_info->spi_base) {
230186
printf("SPI support not implemented yet for %x (%s)!\n",
231187
soc_info->soc_id, soc_info->name);
232188
return false;
233189
}
234190

191+
/* Setup SPI0 pins muxing */
192+
gpio_set_cfgpin(dev, PC, spi_pin(soc_info, 1), soc_info->spi_pinmux);
193+
gpio_set_cfgpin(dev, PC, spi_pin(soc_info, 2), soc_info->spi_pinmux);
194+
gpio_set_cfgpin(dev, PC, spi_pin(soc_info, 3), soc_info->spi_pinmux);
195+
gpio_set_cfgpin(dev, PC, spi_pin(soc_info, 4), soc_info->spi_pinmux);
196+
235197
ccu_base = dev->soc_info->ccu_base;
236198
if (dev->soc_info->flags & H6_STYLE_CLOCKS) {
237199
reg_val = readl(ccu_base + H6_CCM_SPI_BGR_OFF);

soc_info.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,10 @@ static const sid_section generic_2k_sid_maps[] = {
324324
SID_SECTION(NULL, 0, 0),
325325
};
326326

327+
/* Pack four pin numbers into one uint32_t, using one byte per pin */
328+
#define SPI_PINS(p1, p2, p3, p4) \
329+
((p1) << 0 | (p2) << 8 | (p3) << 16 | (p4) << 24)
330+
327331
soc_info_t soc_info_table[] = {
328332
{
329333
.soc_id = 0x1623, /* Allwinner A10 */
@@ -337,6 +341,8 @@ soc_info_t soc_info_table[] = {
337341
.gpio_base = SUNXI_PIO_BASE,
338342
.ccu_base = AW_CCM_BASE,
339343
.spi_base = SUN4I_SPI_BASE,
344+
.spi_pins = SPI_PINS(0, 1, 2, 23),
345+
.spi_pinmux = SUNXI_GPC_SPI0,
340346
.flags = NEEDS_L2EN,
341347
},{
342348
.soc_id = 0x1625, /* Allwinner A10s, A13, R8 */
@@ -350,6 +356,8 @@ soc_info_t soc_info_table[] = {
350356
.gpio_base = SUNXI_PIO_BASE,
351357
.ccu_base = AW_CCM_BASE,
352358
.spi_base = SUN4I_SPI_BASE,
359+
.spi_pins = SPI_PINS(0, 1, 2, 3),
360+
.spi_pinmux = SUNXI_GPC_SPI0,
353361
.flags = NEEDS_L2EN,
354362
},{
355363
.soc_id = 0x1651, /* Allwinner A20 */
@@ -364,6 +372,8 @@ soc_info_t soc_info_table[] = {
364372
.gpio_base = SUNXI_PIO_BASE,
365373
.ccu_base = AW_CCM_BASE,
366374
.spi_base = SUN4I_SPI_BASE,
375+
.spi_pins = SPI_PINS(0, 1, 2, 23),
376+
.spi_pinmux = SUNXI_GPC_SPI0,
367377
},{
368378
.soc_id = 0x1650, /* Allwinner A23 */
369379
.name = "A23",
@@ -416,6 +426,8 @@ soc_info_t soc_info_table[] = {
416426
.gpio_base = SUNXI_PIO_BASE,
417427
.ccu_base = AW_CCM_BASE,
418428
.spi_base = SUN6I_SPI_BASE,
429+
.spi_pins = SPI_PINS(0, 1, 2, 3),
430+
.spi_pinmux = SUN50I_GPC_SPI0,
419431
},{
420432
.soc_id = 0x1639, /* Allwinner A80 */
421433
.name = "A80",
@@ -442,6 +454,8 @@ soc_info_t soc_info_table[] = {
442454
.gpio_base = SUNXI_PIO_BASE,
443455
.ccu_base = AW_CCM_BASE,
444456
.spi_base = SUN4I_SPI_BASE,
457+
.spi_pins = SPI_PINS(0, 1, 2, 3),
458+
.spi_pinmux = SUNIV_GPC_SPI0,
445459
},{
446460
.soc_id = 0x1673, /* Allwinner A83T */
447461
.name = "A83T",
@@ -473,6 +487,8 @@ soc_info_t soc_info_table[] = {
473487
.gpio_base = SUNXI_PIO_BASE,
474488
.ccu_base = AW_CCM_BASE,
475489
.spi_base = SUN6I_SPI_BASE,
490+
.spi_pins = SPI_PINS(0, 1, 2, 3),
491+
.spi_pinmux = SUNXI_GPC_SPI0,
476492
.flags = NEEDS_SID_FIX,
477493
},{
478494
.soc_id = 0x1681, /* Allwinner V3s */
@@ -488,6 +504,8 @@ soc_info_t soc_info_table[] = {
488504
.gpio_base = SUNXI_PIO_BASE,
489505
.ccu_base = AW_CCM_BASE,
490506
.spi_base = SUN6I_SPI_BASE,
507+
.spi_pins = SPI_PINS(0, 1, 2, 3),
508+
.spi_pinmux = SUNXI_GPC_SPI0,
491509
},{
492510
.soc_id = 0x1708, /* Allwinner T7 */
493511
.name = "T7",
@@ -521,6 +539,8 @@ soc_info_t soc_info_table[] = {
521539
.gpio_base = SUNXI_PIO_BASE,
522540
.ccu_base = AW_CCM_BASE,
523541
.spi_base = SUN6I_SPI_BASE,
542+
.spi_pins = SPI_PINS(0, 1, 2, 3),
543+
.spi_pinmux = SUNXI_GPC_SPI0,
524544
},{
525545
.soc_id = 0x1701, /* Allwinner R40 */
526546
.name = "R40",
@@ -535,6 +555,8 @@ soc_info_t soc_info_table[] = {
535555
.gpio_base = SUNXI_PIO_BASE,
536556
.ccu_base = AW_CCM_BASE,
537557
.spi_base = SUN4I_SPI_BASE,
558+
.spi_pins = SPI_PINS(0, 1, 2, 23),
559+
.spi_pinmux = SUNXI_GPC_SPI0,
538560
},{
539561
.soc_id = 0x1719, /* Allwinner A63 */
540562
.name = "A63",
@@ -569,6 +591,8 @@ soc_info_t soc_info_table[] = {
569591
.gpio_base = H6_PIO_BASE,
570592
.ccu_base = H6_CCM_BASE,
571593
.spi_base = H6_SPI_BASE,
594+
.spi_pins = SPI_PINS(0, 2, 3, 5),
595+
.spi_pinmux = SUN50I_GPC_SPI0,
572596
.flags = H6_STYLE_CLOCKS,
573597
},{
574598
.soc_id = 0x1816, /* Allwinner V536 */
@@ -585,6 +609,8 @@ soc_info_t soc_info_table[] = {
585609
.gpio_base = H6_PIO_BASE,
586610
.ccu_base = H6_CCM_BASE,
587611
.spi_base = H6_SPI_BASE,
612+
.spi_pins = SPI_PINS(0, 1, 2, 3),
613+
.spi_pinmux = SUN50I_GPC_SPI0,
588614
.flags = H6_STYLE_CLOCKS,
589615
},{
590616
.soc_id = 0x1817, /* Allwinner V831 */
@@ -601,6 +627,8 @@ soc_info_t soc_info_table[] = {
601627
.gpio_base = H6_PIO_BASE,
602628
.ccu_base = H6_CCM_BASE,
603629
.spi_base = H6_SPI_BASE,
630+
.spi_pins = SPI_PINS(0, 1, 2, 3),
631+
.spi_pinmux = SUN50I_GPC_SPI0,
604632
.flags = H6_STYLE_CLOCKS,
605633
},{
606634
.soc_id = 0x1823, /* Allwinner H616 */
@@ -620,6 +648,8 @@ soc_info_t soc_info_table[] = {
620648
.gpio_base = H6_PIO_BASE,
621649
.ccu_base = H6_CCM_BASE,
622650
.spi_base = H6_SPI_BASE,
651+
.spi_pins = SPI_PINS(0, 2, 3, 4),
652+
.spi_pinmux = SUN50I_GPC_SPI0,
623653
.flags = H6_STYLE_CLOCKS,
624654
},{
625655
.soc_id = 0x1851, /* Allwinner R329 */

soc_info.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,10 @@ enum soc_flags {
101101
#define SUN6I_SPI_BASE 0x01c68000
102102
#define H6_SPI_BASE 0x05010000
103103

104+
#define SUNIV_GPC_SPI0 2
105+
#define SUNXI_GPC_SPI0 3
106+
#define SUN50I_GPC_SPI0 4
107+
104108
/*
105109
* Each SoC variant may have its own list of memory buffers to be exchanged
106110
* and the information about the placement of the thunk code, which handles
@@ -162,6 +166,8 @@ typedef struct {
162166
uint32_t gpio_base;
163167
uint32_t ccu_base;
164168
uint32_t spi_base;
169+
uint32_t spi_pins; /* PC offset for 4 pins, 1 byte each */
170+
uint8_t spi_pinmux;
165171
uint32_t flags;
166172
} soc_info_t;
167173

0 commit comments

Comments
 (0)