coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
qspi.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <spi-generic.h>
4 #include <spi_flash.h>
5 #include <arch/cache.h>
6 #include <device/mmio.h>
7 #include <soc/addressmap.h>
8 #include <soc/qspi_common.h>
9 #include <soc/gpio.h>
10 #include <soc/clock.h>
11 #include <symbols.h>
12 #include <assert.h>
13 #include <gpio.h>
14 #include <string.h>
15 
16 #define CACHE_LINE_SIZE 64
17 
18 static int curr_desc_idx = -1;
19 
20 struct cmd_desc {
29  //------------------------//
34 };
35 
36 enum qspi_mode {
37  SDR_1BIT = 1,
38  SDR_2BIT = 2,
39  SDR_4BIT = 3,
40  DDR_1BIT = 5,
41  DDR_2BIT = 6,
42  DDR_4BIT = 7,
43 };
44 
45 enum cs_state {
47  CS_ASSERT
48 };
49 
50 struct xfer_cfg {
51  enum qspi_mode mode;
52 };
53 
57 };
58 
59 struct {
60  struct cmd_desc descriptors[3];
62 } *dma = (void *)_dma_coherent;
63 
64 static void dma_transfer_chain(struct cmd_desc *chain)
65 {
66  uint32_t mstr_int_status;
67 
68  write32(&qcom_qspi->mstr_int_sts, 0xFFFFFFFF);
70 
71  while (1) {
72  mstr_int_status = read32(&qcom_qspi->mstr_int_sts);
73  if (mstr_int_status & DMA_CHAIN_DONE)
74  break;
75  }
76 }
77 
78 static void flush_chain(void)
79 {
80  struct cmd_desc *desc = &dma->descriptors[0];
81  uint8_t *src;
82  uint8_t *dst;
83 
84  dma_transfer_chain(desc);
85 
86  while (desc) {
87  if (desc->direction == MASTER_READ) {
88  if (desc->bounce_length == 0)
90  (void *)(uintptr_t) desc->data_address,
91  desc->length);
92  else {
93  src = (void *)(uintptr_t) desc->bounce_src;
94  dst = (void *)(uintptr_t) desc->bounce_dst;
95  memcpy(dst, src, desc->bounce_length);
96  }
97  }
98  desc = (void *)(uintptr_t) desc->next_descriptor;
99  }
100  curr_desc_idx = -1;
101 }
102 
103 static struct cmd_desc *allocate_descriptor(void)
104 {
105  struct cmd_desc *current;
106  struct cmd_desc *next;
107  uint8_t index;
108 
109  current = (curr_desc_idx == -1) ?
110  NULL : &dma->descriptors[curr_desc_idx];
111 
112  index = ++curr_desc_idx;
113  next = &dma->descriptors[index];
114 
115  next->data_address = (uint32_t) (uintptr_t) dma->buffers[index];
116 
117  next->next_descriptor = 0;
118  next->direction = MASTER_READ;
119  next->multi_io_mode = 0;
120  next->reserved1 = 0;
121  /*
122  * QSPI controller doesn't support transfer starts with read segment.
123  * So to support read transfers that are not preceded by write, set
124  * transfer fragment bit = 1
125  */
126  next->fragment = 1;
127  next->reserved2 = 0;
128  next->length = 0;
129  next->bounce_src = 0;
130  next->bounce_dst = 0;
131  next->bounce_length = 0;
132 
133  if (current)
134  current->next_descriptor = (uint32_t)(uintptr_t) next;
135 
136  return next;
137 }
138 
139 static void cs_change(enum cs_state state)
140 {
142 }
143 
144 static void configure_gpios(void)
145 {
146  gpio_output(QSPI_CS, 1);
147 
150 
153 
156 }
157 
158 static void queue_bounce_data(uint8_t *data, uint32_t data_bytes,
159  enum qspi_mode data_mode, bool write)
160 {
161  struct cmd_desc *desc;
162  uint8_t *ptr;
163 
164  desc = allocate_descriptor();
165  desc->direction = write;
166  desc->multi_io_mode = data_mode;
167  ptr = (void *)(uintptr_t) desc->data_address;
168 
169  if (write) {
170  memcpy(ptr, data, data_bytes);
171  } else {
172  desc->bounce_src = (uint32_t)(uintptr_t) ptr;
173  desc->bounce_dst = (uint32_t)(uintptr_t) data;
174  desc->bounce_length = data_bytes;
175  }
176 
177  desc->length = data_bytes;
178 }
179 
180 static void queue_direct_data(uint8_t *data, uint32_t data_bytes,
181  enum qspi_mode data_mode, bool write)
182 {
183  struct cmd_desc *desc;
184 
185  desc = allocate_descriptor();
186  desc->direction = write;
187  desc->multi_io_mode = data_mode;
188  desc->data_address = (uint32_t)(uintptr_t) data;
189  desc->length = data_bytes;
190 
191  if (write)
192  dcache_clean_by_mva(data, data_bytes);
193  else
194  dcache_invalidate_by_mva(data, data_bytes);
195 }
196 
197 static void queue_data(uint8_t *data, uint32_t data_bytes,
198  enum qspi_mode data_mode, bool write)
199 {
200  uint8_t *aligned_ptr;
201  uint8_t *epilog_ptr;
202  uint32_t prolog_bytes, aligned_bytes, epilog_bytes;
203 
204  if (data_bytes == 0)
205  return;
206 
207  aligned_ptr =
209 
210  prolog_bytes = MIN(data_bytes, aligned_ptr - data);
211  aligned_bytes = ALIGN_DOWN(data_bytes - prolog_bytes, CACHE_LINE_SIZE);
212  epilog_bytes = data_bytes - prolog_bytes - aligned_bytes;
213 
214  epilog_ptr = data + prolog_bytes + aligned_bytes;
215 
216  if (prolog_bytes)
217  queue_bounce_data(data, prolog_bytes, data_mode, write);
218  if (aligned_bytes)
219  queue_direct_data(aligned_ptr, aligned_bytes, data_mode, write);
220  if (epilog_bytes)
221  queue_bounce_data(epilog_ptr, epilog_bytes, data_mode, write);
222 }
223 
224 static void reg_init(void)
225 {
227  uint32_t tx_data_oe_delay, tx_data_delay;
228  uint32_t mstr_config;
229 
230  spi_mode = 0;
231 
232  tx_data_oe_delay = 0;
233  tx_data_delay = 0;
234 
235  mstr_config = (tx_data_oe_delay << TX_DATA_OE_DELAY_SHIFT) |
236  (tx_data_delay << TX_DATA_DELAY_SHIFT) | (SBL_EN) |
237  (spi_mode << SPI_MODE_SHIFT) |
238  (PIN_HOLDN) |
239  (FB_CLK_EN) |
240  (DMA_ENABLE) |
241  (FULL_CYCLE_MODE);
242 
243  write32(&qcom_qspi->mstr_cfg, mstr_config);
244  write32(&qcom_qspi->ahb_mstr_cfg, 0xA42);
245  write32(&qcom_qspi->mstr_int_en, 0x0);
246  write32(&qcom_qspi->mstr_int_sts, 0xFFFFFFFF);
247  write32(&qcom_qspi->rd_fifo_cfg, 0x0);
249 }
250 
252 {
254  clock_configure_qspi(hz * 4);
255  configure_gpios();
256  reg_init();
257 }
258 
259 int qspi_claim_bus(const struct spi_slave *slave)
260 {
262  return 0;
263 }
264 
265 void qspi_release_bus(const struct spi_slave *slave)
266 {
268 }
269 
270 static int xfer(enum qspi_mode mode, const void *dout, size_t out_bytes,
271  void *din, size_t in_bytes)
272 {
273  if ((out_bytes && !dout) || (in_bytes && !din) ||
274  (in_bytes && out_bytes)) {
275  return -1;
276  }
277 
278  queue_data((uint8_t *) (out_bytes ? dout : din),
279  in_bytes | out_bytes, mode, !!out_bytes);
280 
281  flush_chain();
282 
283  return 0;
284 }
285 
286 int qspi_xfer(const struct spi_slave *slave, const void *dout,
287  size_t out_bytes, void *din, size_t in_bytes)
288 {
289  return xfer(SDR_1BIT, dout, out_bytes, din, in_bytes);
290 }
291 
292 int qspi_xfer_dual(const struct spi_slave *slave, const void *dout,
293  size_t out_bytes, void *din, size_t in_bytes)
294 {
295  return xfer(SDR_2BIT, dout, out_bytes, din, in_bytes);
296 }
#define GPIO_OUTPUT
Definition: gpio_ftns.h:23
void dcache_clean_by_mva(void const *addr, size_t len)
Definition: cache.c:37
unsigned int dcache_line_bytes(void)
Definition: cache.c:26
static void write32(void *addr, uint32_t val)
Definition: mmio.h:40
static uint32_t read32(const void *addr)
Definition: mmio.h:22
void * memcpy(void *dest, const void *src, size_t n)
Definition: memcpy.c:7
#define assert(statement)
Definition: assert.h:74
#define MIN(a, b)
Definition: helpers.h:37
#define ALIGN_DOWN(x, a)
Definition: helpers.h:18
#define ALIGN_UP(x, a)
Definition: helpers.h:17
void gpio_output(gpio_t gpio, int value)
Definition: gpio.c:194
void gpio_set(gpio_t gpio, int value)
Definition: gpio.c:174
spi_mode
Definition: cdp.h:43
state
Definition: raminit.c:1787
struct cmd_desc descriptors[3]
Definition: qspi.c:60
bus_xfer_direction
Definition: qspi.c:54
@ MASTER_WRITE
Definition: qspi.c:56
@ MASTER_READ
Definition: qspi.c:55
static int xfer(enum qspi_mode mode, const void *dout, size_t out_bytes, void *din, size_t in_bytes)
Definition: qspi.c:270
qspi_mode
Definition: qspi.c:36
@ SDR_2BIT
Definition: qspi.c:38
@ SDR_4BIT
Definition: qspi.c:39
@ DDR_2BIT
Definition: qspi.c:41
@ SDR_1BIT
Definition: qspi.c:37
@ DDR_4BIT
Definition: qspi.c:42
@ DDR_1BIT
Definition: qspi.c:40
static void queue_bounce_data(uint8_t *data, uint32_t data_bytes, enum qspi_mode data_mode, bool write)
Definition: qspi.c:158
static void cs_change(enum cs_state state)
Definition: qspi.c:139
static void reg_init(void)
Definition: qspi.c:224
void quadspi_init(uint32_t hz)
Definition: qspi.c:251
static struct cmd_desc * allocate_descriptor(void)
Definition: qspi.c:103
static void configure_gpios(void)
Definition: qspi.c:144
static int curr_desc_idx
Definition: qspi.c:18
int qspi_claim_bus(const struct spi_slave *slave)
Definition: qspi.c:259
uint8_t buffers[3][CACHE_LINE_SIZE]
Definition: qspi.c:61
int qspi_xfer_dual(const struct spi_slave *slave, const void *dout, size_t out_bytes, void *din, size_t in_bytes)
Definition: qspi.c:292
static void queue_direct_data(uint8_t *data, uint32_t data_bytes, enum qspi_mode data_mode, bool write)
Definition: qspi.c:180
static void queue_data(uint8_t *data, uint32_t data_bytes, enum qspi_mode data_mode, bool write)
Definition: qspi.c:197
cs_state
Definition: qspi.c:45
@ CS_DEASSERT
Definition: qspi.c:46
@ CS_ASSERT
Definition: qspi.c:47
static void dma_transfer_chain(struct cmd_desc *chain)
Definition: qspi.c:64
struct @1399 * dma
static void flush_chain(void)
Definition: qspi.c:78
void qspi_release_bus(const struct spi_slave *slave)
Definition: qspi.c:265
int qspi_xfer(const struct spi_slave *slave, const void *dout, size_t out_bytes, void *din, size_t in_bytes)
Definition: qspi.c:286
#define CACHE_LINE_SIZE
Definition: qspi.c:16
#define DMA_CHAIN_DONE
Definition: qspi_common.h:59
#define FULL_CYCLE_MODE
Definition: qspi_common.h:55
#define TX_DATA_OE_DELAY_SHIFT
Definition: qspi_common.h:36
#define FB_CLK_EN
Definition: qspi_common.h:54
static struct qcom_qspi_regs *const qcom_qspi
Definition: qspi_common.h:32
#define RESET_FIFO
Definition: qspi_common.h:96
#define PIN_HOLDN
Definition: qspi_common.h:53
#define SBL_EN
Definition: qspi_common.h:46
#define SPI_MODE_SHIFT
Definition: qspi_common.h:48
#define TX_DATA_DELAY_SHIFT
Definition: qspi_common.h:42
#define DMA_ENABLE
Definition: qspi_common.h:51
@ GPIO_8MA
Definition: gpio_common.h:73
@ GPIO_NO_PULL
Definition: gpio_common.h:62
void gpio_configure(gpio_t gpio, uint32_t func, uint32_t pull, uint32_t drive_str, uint32_t enable)
Definition: gpio.c:7
int clock_configure_qspi(uint32_t hz)
Definition: clock.c:117
#define QSPI_DATA_1
Definition: addressmap.h:52
#define GPIO_FUNC_QSPI_DATA_0
Definition: addressmap.h:55
#define GPIO_FUNC_QSPI_CLK
Definition: addressmap.h:57
#define QSPI_CS
Definition: addressmap.h:53
#define GPIO_FUNC_QSPI_DATA_1
Definition: addressmap.h:56
#define QSPI_DATA_0
Definition: addressmap.h:51
#define QSPI_CLK
Definition: addressmap.h:50
static struct spi_slave slave
Definition: spiconsole.c:7
#define NULL
Definition: stddef.h:19
unsigned int uint32_t
Definition: stdint.h:14
unsigned long uintptr_t
Definition: stdint.h:21
unsigned long long uint64_t
Definition: stdint.h:17
unsigned char uint8_t
Definition: stdint.h:8
#define dcache_invalidate_by_mva(addr, len)
Definition: storage.h:17
Definition: qspi.c:20
uint32_t next_descriptor
Definition: qspi.c:22
uint32_t reserved2
Definition: qspi.c:27
uint32_t bounce_length
Definition: qspi.c:32
uint32_t bounce_dst
Definition: qspi.c:31
uint64_t padding[5]
Definition: qspi.c:33
uint32_t length
Definition: qspi.c:28
uint32_t multi_io_mode
Definition: qspi.c:24
uint32_t bounce_src
Definition: qspi.c:30
uint32_t fragment
Definition: qspi.c:26
uint32_t reserved1
Definition: qspi.c:25
uint32_t data_address
Definition: qspi.c:21
uint32_t direction
Definition: qspi.c:23
u32 next_dma_desc_addr
Definition: qspi_common.h:24
Definition: qspi.c:50
enum qspi_mode mode
Definition: qspi.c:51