coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
spi.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 /*
4  * This file is created based on MT8186 Functional Specification
5  * Chapter number: 5.6, 5.8
6  */
7 
8 #include <assert.h>
9 #include <console/console.h>
10 #include <device/mmio.h>
11 #include <spi_flash.h>
12 #include <soc/addressmap.h>
14 #include <soc/gpio.h>
15 #include <soc/spi.h>
16 
18  {
19  .regs = (void *)SPI0_BASE,
20  .cs_gpio = GPIO(SPI0_CSB),
21  },
22  {
23  .regs = (void *)SPI1_BASE,
24  .cs_gpio = GPIO(SPI1_CSB),
25  },
26  {
27  .regs = (void *)SPI2_BASE,
28  .cs_gpio = GPIO(SPI2_CSB),
29  },
30  {
31  .regs = (void *)SPI3_BASE,
32  .cs_gpio = GPIO(SPI3_CSB),
33  },
34  {
35  .regs = (void *)SPI4_BASE,
36  .cs_gpio = GPIO(EINT11),
37  },
38  {
39  .regs = (void *)SPI5_BASE,
40  .cs_gpio = GPIO(SPI5_CSB),
41  }
42 };
43 
44 struct pad_func {
45  gpio_t gpio;
47  enum pull_select select;
48 };
49 
50 #define PAD_FUNC(name, func) {GPIO(name), PAD_##name##_FUNC_##func, GPIO_PULL_DOWN}
51 #define PAD_FUNC_SEL(name, func, sel) {GPIO(name), PAD_##name##_FUNC_##func, sel}
52 #define PAD_FUNC_GPIO(name) {GPIO(name), 0, GPIO_PULL_DOWN}
53 
54 static const struct pad_func pad0_funcs[SPI_BUS_NUMBER][4] = {
55  {
56  PAD_FUNC(SPI0_MI, SPI0_MI_A),
57  PAD_FUNC_GPIO(SPI0_CSB),
58  PAD_FUNC(SPI0_MO, SPI0_MO_A),
59  PAD_FUNC(SPI0_CLK, SPI0_CLK_A),
60  },
61  {
62  PAD_FUNC(SPI1_MI, SPI1_MI_A),
63  PAD_FUNC_GPIO(SPI1_CSB),
64  PAD_FUNC(SPI1_MO, SPI1_MO_A),
65  PAD_FUNC(SPI1_CLK, SPI1_CLK_A),
66  },
67  {
68  PAD_FUNC(SPI2_MI, SPI2_MI_A),
69  PAD_FUNC_GPIO(SPI2_CSB),
70  PAD_FUNC(SPI2_MO, SPI2_MO_A),
71  PAD_FUNC(SPI2_CK, SPI2_CLK_A),
72  },
73  {
74  PAD_FUNC(SPI3_MI, SPI3_MI),
75  PAD_FUNC_GPIO(SPI3_CSB),
76  PAD_FUNC(SPI3_MO, SPI3_MO),
77  PAD_FUNC(SPI3_CLK, SPI3_CLK),
78  },
79  {
80  PAD_FUNC(EINT13, SPI4_MI_A),
81  PAD_FUNC_GPIO(EINT11),
82  PAD_FUNC(EINT12, SPI4_MO_A),
83  PAD_FUNC(EINT10, SPI4_CLK_A),
84  },
85  {
86  PAD_FUNC(SPI5_MI, SPI5_MI),
87  PAD_FUNC_GPIO(SPI5_CSB),
88  PAD_FUNC(SPI5_MO, SPI5_MO),
89  PAD_FUNC(SPI5_CLK, SPI5_CLK),
90  },
91 };
92 
93 static const struct pad_func pad1_funcs[SPI_BUS_NUMBER][4] = {
94  {
95  PAD_FUNC(EINT3, SPI0_MI_B),
96  PAD_FUNC_GPIO(EINT1),
97  PAD_FUNC(EINT2, SPI0_MO_B),
98  PAD_FUNC(EINT0, SPI0_CLK_B),
99  },
100  {
101  PAD_FUNC(EINT9, SPI1_MI_B),
102  PAD_FUNC_GPIO(EINT7),
103  PAD_FUNC(EINT8, SPI1_MO_B),
104  PAD_FUNC(EINT6, SPI1_CLK_B),
105  },
106  {
107  PAD_FUNC(CAM_PDN1, SPI2_MI_B),
108  PAD_FUNC_GPIO(CAM_PDN0),
109  PAD_FUNC(CAM_RST0, SPI2_MO_B),
110  PAD_FUNC(EINT18, SPI2_CLK_B),
111  },
112  {
113  },
114  {
115  PAD_FUNC(I2S2_DI, SPI4_MI_B),
116  PAD_FUNC_GPIO(I2S2_BCK),
117  PAD_FUNC(I2S2_LRCK, SPI4_MO_B),
118  PAD_FUNC(I2S2_MCK, SPI4_CLK_B),
119  },
120  {
121  },
122 };
123 
124 static const struct pad_func nor_pinmux[SPI_NOR_GPIO_SET_NUM][4] = {
125  /* GPIO 36 ~ 39 */
126  [SPI_NOR_GPIO_SET0] = {
127  PAD_FUNC_SEL(SPI0_CLK, SPINOR_CK, GPIO_PULL_DOWN),
128  PAD_FUNC_SEL(SPI0_CSB, SPINOR_CS, GPIO_PULL_UP),
129  PAD_FUNC_SEL(SPI0_MO, SPINOR_IO0, GPIO_PULL_DOWN),
130  PAD_FUNC_SEL(SPI0_MI, SPINOR_IO1, GPIO_PULL_DOWN),
131  },
132  /* GPIO 61 ~ 64 */
133  [SPI_NOR_GPIO_SET1] = {
134  PAD_FUNC_SEL(TDM_RX_BCK, SPINOR_CK, GPIO_PULL_DOWN),
135  PAD_FUNC_SEL(TDM_RX_MCLK, SPINOR_CS, GPIO_PULL_UP),
136  PAD_FUNC_SEL(TDM_RX_DATA0, SPINOR_IO0, GPIO_PULL_DOWN),
137  PAD_FUNC_SEL(TDM_RX_DATA1, SPINOR_IO1, GPIO_PULL_DOWN),
138  },
139 };
140 
142 {
143  const struct pad_func *ptr = NULL;
144 
146 
147  ptr = nor_pinmux[gpio_set];
148  for (size_t i = 0; i < ARRAY_SIZE(nor_pinmux[gpio_set]); i++) {
149  gpio_set_pull(ptr[i].gpio, GPIO_PULL_ENABLE, ptr[i].select);
150  gpio_set_mode(ptr[i].gpio, ptr[i].func);
151 
152  if (gpio_set_driving(ptr[i].gpio, GPIO_DRV_8_MA) < 0)
154  "%s: failed to set pin drive to 8 mA for %d\n",
155  __func__, ptr[i].gpio.id);
156  else
157  printk(BIOS_DEBUG, "%s: got pin drive: %#x\n", __func__,
158  gpio_get_driving(ptr[i].gpio));
159  }
160 }
161 
162 void mtk_spi_set_gpio_pinmux(unsigned int bus, enum spi_pad_mask pad_select)
163 {
165  const struct pad_func *ptr;
166 
167  if (pad_select == SPI_PAD0_MASK) {
168  ptr = pad0_funcs[bus];
169  } else {
170  assert((bus == 0 || bus == 1 || bus == 2 || bus == 4) &&
171  pad_select == SPI_PAD1_MASK);
172  ptr = pad1_funcs[bus];
173  }
174  for (int i = 0; i < 4; i++)
175  gpio_set_mode(ptr[i].gpio, ptr[i].func);
176 }
177 
178 static const struct spi_ctrlr spi_flash_ctrlr = {
179  .max_xfer_size = 65535,
180  .flash_probe = mtk_spi_flash_probe,
181 };
182 
183 const struct spi_ctrlr_buses spi_ctrlr_bus_map[] = {
184  {
185  .ctrlr = &spi_ctrlr,
186  .bus_start = 0,
187  .bus_end = SPI_BUS_NUMBER - 1,
188  },
189  {
190  .ctrlr = &spi_flash_ctrlr,
191  .bus_start = CONFIG_BOOT_DEVICE_SPI_FLASH_BUS,
192  .bus_end = CONFIG_BOOT_DEVICE_SPI_FLASH_BUS,
193  },
194 };
195 
#define assert(statement)
Definition: assert.h:74
#define ARRAY_SIZE(a)
Definition: helpers.h:12
#define SPI0_CLK
#define printk(level,...)
Definition: stdlib.h:16
@ GPIO
Definition: chip.h:84
int mtk_spi_flash_probe(const struct spi_slave *spi, struct spi_flash *flash)
void gpio_set(gpio_t gpio, int value)
Definition: gpio.c:174
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define BIOS_WARNING
BIOS_WARNING - Bad configuration.
Definition: loglevel.h:86
int gpio_set_driving(gpio_t gpio, uint8_t drv)
Definition: gpio.c:324
@ GPIO_PULL_ENABLE
Definition: gpio_common.h:13
int gpio_get_driving(gpio_t gpio)
Definition: gpio.c:354
pull_select
Definition: gpio_common.h:16
void gpio_set_pull(gpio_t gpio, enum pull_enable enable, enum pull_select select)
Definition: gpio.c:17
const struct spi_ctrlr_buses spi_ctrlr_bus_map[]
Definition: spi.c:401
const size_t spi_ctrlr_bus_map_count
Definition: spi.c:408
void gpio_set_mode(gpio_t gpio, int mode)
Definition: gpio.c:45
const struct spi_ctrlr spi_ctrlr
Definition: spi.c:261
#define SPI_BUS_NUMBER
Definition: spi.h:8
struct mtk_spi_bus spi_bus[SPI_BUS_NUMBER]
Definition: spi.c:11
void mtk_spi_set_gpio_pinmux(unsigned int bus, enum spi_pad_mask pad_select)
Definition: spi.c:18
@ GPIO_DRV_8_MA
Definition: gpio.h:27
@ SPI_NOR_GPIO_SET0
Definition: spi.h:29
@ SPI_NOR_GPIO_SET_NUM
Definition: spi.h:31
@ SPI_NOR_GPIO_SET1
Definition: spi.h:30
static const struct pad_func nor_pinmux[SPI_NOR_GPIO_SET_NUM][4]
Definition: spi.c:124
#define PAD_FUNC_SEL(name, func, sel)
Definition: spi.c:51
static const struct pad_func pad1_funcs[SPI_BUS_NUMBER][4]
Definition: spi.c:93
static const struct spi_ctrlr spi_flash_ctrlr
Definition: spi.c:178
static const struct pad_func pad0_funcs[SPI_BUS_NUMBER][4]
Definition: spi.c:54
#define PAD_FUNC(name, func)
Definition: spi.c:50
#define PAD_FUNC_GPIO(name)
Definition: spi.c:52
void mtk_snfc_init(int gpio_set)
Definition: spi.c:141
#define GPIO_PULL_UP
Definition: gpio.h:24
#define GPIO_PULL_DOWN
Definition: gpio.h:23
#define SPI1_BASE
Definition: addressmap.h:14
#define SPI2_BASE
Definition: addressmap.h:15
#define SPI0_BASE
Definition: addressmap.h:13
#define SPI5_BASE
Definition: addressmap.h:43
#define SPI4_BASE
Definition: addressmap.h:42
#define SPI3_BASE
Definition: addressmap.h:41
spi_pad_mask
Definition: spi_common.h:45
@ SPI_PAD1_MASK
Definition: spi_common.h:47
@ SPI_PAD0_MASK
Definition: spi_common.h:46
#define NULL
Definition: stddef.h:19
uint8_t u8
Definition: stdint.h:45
Definition: device.h:76
Definition: pinmux.c:36
gpio_t cs_gpio
Definition: spi_common.h:77
struct mtk_spi_regs * regs
Definition: spi_common.h:74
enum pull_select select
Definition: spi.c:47
gpio_t gpio
Definition: i2c.c:57
u8 func
Definition: bootblock.c:15
const struct spi_ctrlr * ctrlr
Definition: spi-generic.h:175
uint32_t max_xfer_size
Definition: spi-generic.h:158