blob: 61490c9d0198f5d5b91a8b8a9f97909f174efe1e [file] [log] [blame]
Alison Wang6b57ff62014-05-06 09:13:01 +08001/*
2 * Copyright 2013-2014 Freescale Semiconductor, Inc.
3 *
4 * Freescale Quad Serial Peripheral Interface (QSPI) driver
5 *
6 * SPDX-License-Identifier: GPL-2.0+
7 */
8
9#include <common.h>
10#include <malloc.h>
11#include <spi.h>
12#include <asm/io.h>
13#include <linux/sizes.h>
14#include "fsl_qspi.h"
15
16#define RX_BUFFER_SIZE 0x80
17#define TX_BUFFER_SIZE 0x40
18
19#define OFFSET_BITS_MASK 0x00ffffff
20
21#define FLASH_STATUS_WEL 0x02
22
23/* SEQID */
24#define SEQID_WREN 1
25#define SEQID_FAST_READ 2
26#define SEQID_RDSR 3
27#define SEQID_SE 4
28#define SEQID_CHIP_ERASE 5
29#define SEQID_PP 6
30#define SEQID_RDID 7
31
Peng Fan53e3db72014-12-31 11:01:36 +080032/* QSPI CMD */
33#define QSPI_CMD_PP 0x02 /* Page program (up to 256 bytes) */
34#define QSPI_CMD_RDSR 0x05 /* Read status register */
35#define QSPI_CMD_WREN 0x06 /* Write enable */
36#define QSPI_CMD_FAST_READ 0x0b /* Read data bytes (high frequency) */
37#define QSPI_CMD_CHIP_ERASE 0xc7 /* Erase whole flash chip */
38#define QSPI_CMD_SE 0xd8 /* Sector erase (usually 64KiB) */
39#define QSPI_CMD_RDID 0x9f /* Read JEDEC ID */
Alison Wang6b57ff62014-05-06 09:13:01 +080040
Peng Fan53e3db72014-12-31 11:01:36 +080041/* 4-byte address QSPI CMD - used on Spansion and some Macronix flashes */
42#define QSPI_CMD_FAST_READ_4B 0x0c /* Read data bytes (high frequency) */
43#define QSPI_CMD_PP_4B 0x12 /* Page program (up to 256 bytes) */
44#define QSPI_CMD_SE_4B 0xdc /* Sector erase (usually 64KiB) */
Alison Wang6b57ff62014-05-06 09:13:01 +080045
46#ifdef CONFIG_SYS_FSL_QSPI_LE
47#define qspi_read32 in_le32
48#define qspi_write32 out_le32
49#elif defined(CONFIG_SYS_FSL_QSPI_BE)
50#define qspi_read32 in_be32
51#define qspi_write32 out_be32
52#endif
53
54static unsigned long spi_bases[] = {
55 QSPI0_BASE_ADDR,
56};
57
58static unsigned long amba_bases[] = {
59 QSPI0_AMBA_BASE,
60};
61
62struct fsl_qspi {
63 struct spi_slave slave;
64 unsigned long reg_base;
65 unsigned long amba_base;
66 u32 sf_addr;
67 u8 cur_seqid;
68};
69
70/* QSPI support swapping the flash read/write data
71 * in hardware for LS102xA, but not for VF610 */
72static inline u32 qspi_endian_xchg(u32 data)
73{
74#ifdef CONFIG_VF610
75 return swab32(data);
76#else
77 return data;
78#endif
79}
80
81static inline struct fsl_qspi *to_qspi_spi(struct spi_slave *slave)
82{
83 return container_of(slave, struct fsl_qspi, slave);
84}
85
86static void qspi_set_lut(struct fsl_qspi *qspi)
87{
88 struct fsl_qspi_regs *regs = (struct fsl_qspi_regs *)qspi->reg_base;
89 u32 lut_base;
90
91 /* Unlock the LUT */
92 qspi_write32(&regs->lutkey, LUT_KEY_VALUE);
93 qspi_write32(&regs->lckcr, QSPI_LCKCR_UNLOCK);
94
95 /* Write Enable */
96 lut_base = SEQID_WREN * 4;
Peng Fan53e3db72014-12-31 11:01:36 +080097 qspi_write32(&regs->lut[lut_base], OPRND0(QSPI_CMD_WREN) |
Alison Wang6b57ff62014-05-06 09:13:01 +080098 PAD0(LUT_PAD1) | INSTR0(LUT_CMD));
99 qspi_write32(&regs->lut[lut_base + 1], 0);
100 qspi_write32(&regs->lut[lut_base + 2], 0);
101 qspi_write32(&regs->lut[lut_base + 3], 0);
102
103 /* Fast Read */
104 lut_base = SEQID_FAST_READ * 4;
105 if (FSL_QSPI_FLASH_SIZE <= SZ_16M)
Peng Fan53e3db72014-12-31 11:01:36 +0800106 qspi_write32(&regs->lut[lut_base], OPRND0(QSPI_CMD_FAST_READ) |
Alison Wang6b57ff62014-05-06 09:13:01 +0800107 PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) |
108 PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
109 else
Peng Fan53e3db72014-12-31 11:01:36 +0800110 qspi_write32(&regs->lut[lut_base],
111 OPRND0(QSPI_CMD_FAST_READ_4B) |
112 PAD0(LUT_PAD1) | INSTR0(LUT_CMD) |
113 OPRND1(ADDR32BIT) | PAD1(LUT_PAD1) |
114 INSTR1(LUT_ADDR));
Alison Wang6b57ff62014-05-06 09:13:01 +0800115 qspi_write32(&regs->lut[lut_base + 1], OPRND0(8) | PAD0(LUT_PAD1) |
116 INSTR0(LUT_DUMMY) | OPRND1(RX_BUFFER_SIZE) | PAD1(LUT_PAD1) |
117 INSTR1(LUT_READ));
118 qspi_write32(&regs->lut[lut_base + 2], 0);
119 qspi_write32(&regs->lut[lut_base + 3], 0);
120
121 /* Read Status */
122 lut_base = SEQID_RDSR * 4;
Peng Fan53e3db72014-12-31 11:01:36 +0800123 qspi_write32(&regs->lut[lut_base], OPRND0(QSPI_CMD_RDSR) |
Alison Wang6b57ff62014-05-06 09:13:01 +0800124 PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(1) |
125 PAD1(LUT_PAD1) | INSTR1(LUT_READ));
126 qspi_write32(&regs->lut[lut_base + 1], 0);
127 qspi_write32(&regs->lut[lut_base + 2], 0);
128 qspi_write32(&regs->lut[lut_base + 3], 0);
129
130 /* Erase a sector */
131 lut_base = SEQID_SE * 4;
132 if (FSL_QSPI_FLASH_SIZE <= SZ_16M)
Peng Fan53e3db72014-12-31 11:01:36 +0800133 qspi_write32(&regs->lut[lut_base], OPRND0(QSPI_CMD_SE) |
Alison Wang6b57ff62014-05-06 09:13:01 +0800134 PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) |
135 PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
136 else
Peng Fan53e3db72014-12-31 11:01:36 +0800137 qspi_write32(&regs->lut[lut_base], OPRND0(QSPI_CMD_SE_4B) |
Alison Wang6b57ff62014-05-06 09:13:01 +0800138 PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR32BIT) |
139 PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
140 qspi_write32(&regs->lut[lut_base + 1], 0);
141 qspi_write32(&regs->lut[lut_base + 2], 0);
142 qspi_write32(&regs->lut[lut_base + 3], 0);
143
144 /* Erase the whole chip */
145 lut_base = SEQID_CHIP_ERASE * 4;
Peng Fan53e3db72014-12-31 11:01:36 +0800146 qspi_write32(&regs->lut[lut_base], OPRND0(QSPI_CMD_CHIP_ERASE) |
Alison Wang6b57ff62014-05-06 09:13:01 +0800147 PAD0(LUT_PAD1) | INSTR0(LUT_CMD));
148 qspi_write32(&regs->lut[lut_base + 1], 0);
149 qspi_write32(&regs->lut[lut_base + 2], 0);
150 qspi_write32(&regs->lut[lut_base + 3], 0);
151
152 /* Page Program */
153 lut_base = SEQID_PP * 4;
154 if (FSL_QSPI_FLASH_SIZE <= SZ_16M)
Peng Fan53e3db72014-12-31 11:01:36 +0800155 qspi_write32(&regs->lut[lut_base], OPRND0(QSPI_CMD_PP) |
Alison Wang6b57ff62014-05-06 09:13:01 +0800156 PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) |
157 PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
158 else
Peng Fan53e3db72014-12-31 11:01:36 +0800159 qspi_write32(&regs->lut[lut_base], OPRND0(QSPI_CMD_PP_4B) |
Alison Wang6b57ff62014-05-06 09:13:01 +0800160 PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR32BIT) |
161 PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
162 qspi_write32(&regs->lut[lut_base + 1], OPRND0(TX_BUFFER_SIZE) |
163 PAD0(LUT_PAD1) | INSTR0(LUT_WRITE));
164 qspi_write32(&regs->lut[lut_base + 2], 0);
165 qspi_write32(&regs->lut[lut_base + 3], 0);
166
167 /* READ ID */
168 lut_base = SEQID_RDID * 4;
Peng Fan53e3db72014-12-31 11:01:36 +0800169 qspi_write32(&regs->lut[lut_base], OPRND0(QSPI_CMD_RDID) |
Alison Wang6b57ff62014-05-06 09:13:01 +0800170 PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(8) |
171 PAD1(LUT_PAD1) | INSTR1(LUT_READ));
172 qspi_write32(&regs->lut[lut_base + 1], 0);
173 qspi_write32(&regs->lut[lut_base + 2], 0);
174 qspi_write32(&regs->lut[lut_base + 3], 0);
175
176 /* Lock the LUT */
177 qspi_write32(&regs->lutkey, LUT_KEY_VALUE);
178 qspi_write32(&regs->lckcr, QSPI_LCKCR_LOCK);
179}
180
181void spi_init()
182{
183 /* do nothing */
184}
185
186struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
187 unsigned int max_hz, unsigned int mode)
188{
189 struct fsl_qspi *qspi;
190 struct fsl_qspi_regs *regs;
191 u32 reg_val, smpr_val;
192 u32 total_size, seq_id;
193
194 if (bus >= ARRAY_SIZE(spi_bases))
195 return NULL;
196
197 qspi = spi_alloc_slave(struct fsl_qspi, bus, cs);
198 if (!qspi)
199 return NULL;
200
201 qspi->reg_base = spi_bases[bus];
202 qspi->amba_base = amba_bases[bus];
203
204 qspi->slave.max_write_size = TX_BUFFER_SIZE;
205
206 regs = (struct fsl_qspi_regs *)qspi->reg_base;
207 qspi_write32(&regs->mcr, QSPI_MCR_RESERVED_MASK | QSPI_MCR_MDIS_MASK);
208
209 smpr_val = qspi_read32(&regs->smpr);
210 qspi_write32(&regs->smpr, smpr_val & ~(QSPI_SMPR_FSDLY_MASK |
211 QSPI_SMPR_FSPHS_MASK | QSPI_SMPR_HSENA_MASK));
212 qspi_write32(&regs->mcr, QSPI_MCR_RESERVED_MASK);
213
214 total_size = FSL_QSPI_FLASH_SIZE * FSL_QSPI_FLASH_NUM;
215 qspi_write32(&regs->sfa1ad, FSL_QSPI_FLASH_SIZE | qspi->amba_base);
216 qspi_write32(&regs->sfa2ad, FSL_QSPI_FLASH_SIZE | qspi->amba_base);
217 qspi_write32(&regs->sfb1ad, total_size | qspi->amba_base);
218 qspi_write32(&regs->sfb2ad, total_size | qspi->amba_base);
219
220 qspi_set_lut(qspi);
221
222 smpr_val = qspi_read32(&regs->smpr);
223 smpr_val &= ~QSPI_SMPR_DDRSMP_MASK;
224 qspi_write32(&regs->smpr, smpr_val);
225 qspi_write32(&regs->mcr, QSPI_MCR_RESERVED_MASK);
226
227 seq_id = 0;
228 reg_val = qspi_read32(&regs->bfgencr);
229 reg_val &= ~QSPI_BFGENCR_SEQID_MASK;
230 reg_val |= (seq_id << QSPI_BFGENCR_SEQID_SHIFT);
231 reg_val &= ~QSPI_BFGENCR_PAR_EN_MASK;
232 qspi_write32(&regs->bfgencr, reg_val);
233
234 return &qspi->slave;
235}
236
237void spi_free_slave(struct spi_slave *slave)
238{
239 struct fsl_qspi *qspi = to_qspi_spi(slave);
240
241 free(qspi);
242}
243
244int spi_claim_bus(struct spi_slave *slave)
245{
246 return 0;
247}
248
249static void qspi_op_rdid(struct fsl_qspi *qspi, u32 *rxbuf, u32 len)
250{
251 struct fsl_qspi_regs *regs = (struct fsl_qspi_regs *)qspi->reg_base;
252 u32 mcr_reg, rbsr_reg, data;
253 int i, size;
254
255 mcr_reg = qspi_read32(&regs->mcr);
256 qspi_write32(&regs->mcr, QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK |
257 QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE);
258 qspi_write32(&regs->rbct, QSPI_RBCT_RXBRD_USEIPS);
259
260 qspi_write32(&regs->sfar, qspi->amba_base);
261
262 qspi_write32(&regs->ipcr, (SEQID_RDID << QSPI_IPCR_SEQID_SHIFT) | 0);
263 while (qspi_read32(&regs->sr) & QSPI_SR_BUSY_MASK)
264 ;
265
266 i = 0;
267 size = len;
268 while ((RX_BUFFER_SIZE >= size) && (size > 0)) {
269 rbsr_reg = qspi_read32(&regs->rbsr);
270 if (rbsr_reg & QSPI_RBSR_RDBFL_MASK) {
271 data = qspi_read32(&regs->rbdr[i]);
272 data = qspi_endian_xchg(data);
273 memcpy(rxbuf, &data, 4);
274 rxbuf++;
275 size -= 4;
276 i++;
277 }
278 }
279
280 qspi_write32(&regs->mcr, mcr_reg);
281}
282
283static void qspi_op_read(struct fsl_qspi *qspi, u32 *rxbuf, u32 len)
284{
285 struct fsl_qspi_regs *regs = (struct fsl_qspi_regs *)qspi->reg_base;
286 u32 mcr_reg, data;
287 int i, size;
288 u32 to_or_from;
289
290 mcr_reg = qspi_read32(&regs->mcr);
291 qspi_write32(&regs->mcr, QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK |
292 QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE);
293 qspi_write32(&regs->rbct, QSPI_RBCT_RXBRD_USEIPS);
294
295 to_or_from = qspi->sf_addr + qspi->amba_base;
296
297 while (len > 0) {
298 qspi_write32(&regs->sfar, to_or_from);
299
300 size = (len > RX_BUFFER_SIZE) ?
301 RX_BUFFER_SIZE : len;
302
303 qspi_write32(&regs->ipcr,
304 (SEQID_FAST_READ << QSPI_IPCR_SEQID_SHIFT) | size);
305 while (qspi_read32(&regs->sr) & QSPI_SR_BUSY_MASK)
306 ;
307
308 to_or_from += size;
309 len -= size;
310
311 i = 0;
312 while ((RX_BUFFER_SIZE >= size) && (size > 0)) {
313 data = qspi_read32(&regs->rbdr[i]);
314 data = qspi_endian_xchg(data);
315 memcpy(rxbuf, &data, 4);
316 rxbuf++;
317 size -= 4;
318 i++;
319 }
320 qspi_write32(&regs->mcr, qspi_read32(&regs->mcr) |
321 QSPI_MCR_CLR_RXF_MASK);
322 }
323
324 qspi_write32(&regs->mcr, mcr_reg);
325}
326
327static void qspi_op_pp(struct fsl_qspi *qspi, u32 *txbuf, u32 len)
328{
329 struct fsl_qspi_regs *regs = (struct fsl_qspi_regs *)qspi->reg_base;
330 u32 mcr_reg, data, reg, status_reg;
331 int i, size, tx_size;
332 u32 to_or_from = 0;
333
334 mcr_reg = qspi_read32(&regs->mcr);
335 qspi_write32(&regs->mcr, QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK |
336 QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE);
337 qspi_write32(&regs->rbct, QSPI_RBCT_RXBRD_USEIPS);
338
339 status_reg = 0;
340 while ((status_reg & FLASH_STATUS_WEL) != FLASH_STATUS_WEL) {
341 qspi_write32(&regs->ipcr,
342 (SEQID_WREN << QSPI_IPCR_SEQID_SHIFT) | 0);
343 while (qspi_read32(&regs->sr) & QSPI_SR_BUSY_MASK)
344 ;
345
346 qspi_write32(&regs->ipcr,
347 (SEQID_RDSR << QSPI_IPCR_SEQID_SHIFT) | 1);
348 while (qspi_read32(&regs->sr) & QSPI_SR_BUSY_MASK)
349 ;
350
351 reg = qspi_read32(&regs->rbsr);
352 if (reg & QSPI_RBSR_RDBFL_MASK) {
353 status_reg = qspi_read32(&regs->rbdr[0]);
354 status_reg = qspi_endian_xchg(status_reg);
355 }
356 qspi_write32(&regs->mcr,
357 qspi_read32(&regs->mcr) | QSPI_MCR_CLR_RXF_MASK);
358 }
359
360 to_or_from = qspi->sf_addr + qspi->amba_base;
361 qspi_write32(&regs->sfar, to_or_from);
362
363 tx_size = (len > TX_BUFFER_SIZE) ?
364 TX_BUFFER_SIZE : len;
365
366 size = (tx_size + 3) / 4;
367
368 for (i = 0; i < size; i++) {
369 data = qspi_endian_xchg(*txbuf);
370 qspi_write32(&regs->tbdr, data);
371 txbuf++;
372 }
373
374 qspi_write32(&regs->ipcr,
375 (SEQID_PP << QSPI_IPCR_SEQID_SHIFT) | tx_size);
376 while (qspi_read32(&regs->sr) & QSPI_SR_BUSY_MASK)
377 ;
378
379 qspi_write32(&regs->mcr, mcr_reg);
380}
381
382static void qspi_op_rdsr(struct fsl_qspi *qspi, u32 *rxbuf)
383{
384 struct fsl_qspi_regs *regs = (struct fsl_qspi_regs *)qspi->reg_base;
385 u32 mcr_reg, reg, data;
386
387 mcr_reg = qspi_read32(&regs->mcr);
388 qspi_write32(&regs->mcr, QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK |
389 QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE);
390 qspi_write32(&regs->rbct, QSPI_RBCT_RXBRD_USEIPS);
391
392 qspi_write32(&regs->sfar, qspi->amba_base);
393
394 qspi_write32(&regs->ipcr,
395 (SEQID_RDSR << QSPI_IPCR_SEQID_SHIFT) | 0);
396 while (qspi_read32(&regs->sr) & QSPI_SR_BUSY_MASK)
397 ;
398
399 while (1) {
400 reg = qspi_read32(&regs->rbsr);
401 if (reg & QSPI_RBSR_RDBFL_MASK) {
402 data = qspi_read32(&regs->rbdr[0]);
403 data = qspi_endian_xchg(data);
404 memcpy(rxbuf, &data, 4);
405 qspi_write32(&regs->mcr, qspi_read32(&regs->mcr) |
406 QSPI_MCR_CLR_RXF_MASK);
407 break;
408 }
409 }
410
411 qspi_write32(&regs->mcr, mcr_reg);
412}
413
414static void qspi_op_se(struct fsl_qspi *qspi)
415{
416 struct fsl_qspi_regs *regs = (struct fsl_qspi_regs *)qspi->reg_base;
417 u32 mcr_reg;
418 u32 to_or_from = 0;
419
420 mcr_reg = qspi_read32(&regs->mcr);
421 qspi_write32(&regs->mcr, QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK |
422 QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE);
423 qspi_write32(&regs->rbct, QSPI_RBCT_RXBRD_USEIPS);
424
425 to_or_from = qspi->sf_addr + qspi->amba_base;
426 qspi_write32(&regs->sfar, to_or_from);
427
428 qspi_write32(&regs->ipcr,
429 (SEQID_WREN << QSPI_IPCR_SEQID_SHIFT) | 0);
430 while (qspi_read32(&regs->sr) & QSPI_SR_BUSY_MASK)
431 ;
432
433 qspi_write32(&regs->ipcr,
434 (SEQID_SE << QSPI_IPCR_SEQID_SHIFT) | 0);
435 while (qspi_read32(&regs->sr) & QSPI_SR_BUSY_MASK)
436 ;
437
438 qspi_write32(&regs->mcr, mcr_reg);
439}
440
441int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
442 const void *dout, void *din, unsigned long flags)
443{
444 struct fsl_qspi *qspi = to_qspi_spi(slave);
445 u32 bytes = DIV_ROUND_UP(bitlen, 8);
446 static u32 pp_sfaddr;
447 u32 txbuf;
448
449 if (dout) {
450 memcpy(&txbuf, dout, 4);
451 qspi->cur_seqid = *(u8 *)dout;
452
453 if (flags == SPI_XFER_END) {
454 qspi->sf_addr = pp_sfaddr;
455 qspi_op_pp(qspi, (u32 *)dout, bytes);
456 return 0;
457 }
458
Peng Fan53e3db72014-12-31 11:01:36 +0800459 if (qspi->cur_seqid == QSPI_CMD_FAST_READ) {
Alison Wang6b57ff62014-05-06 09:13:01 +0800460 qspi->sf_addr = swab32(txbuf) & OFFSET_BITS_MASK;
Peng Fan53e3db72014-12-31 11:01:36 +0800461 } else if (qspi->cur_seqid == QSPI_CMD_SE) {
Alison Wang6b57ff62014-05-06 09:13:01 +0800462 qspi->sf_addr = swab32(txbuf) & OFFSET_BITS_MASK;
463 qspi_op_se(qspi);
Peng Fan53e3db72014-12-31 11:01:36 +0800464 } else if (qspi->cur_seqid == QSPI_CMD_PP) {
Alison Wang6b57ff62014-05-06 09:13:01 +0800465 pp_sfaddr = swab32(txbuf) & OFFSET_BITS_MASK;
466 }
467 }
468
469 if (din) {
Peng Fan53e3db72014-12-31 11:01:36 +0800470 if (qspi->cur_seqid == QSPI_CMD_FAST_READ)
Alison Wang6b57ff62014-05-06 09:13:01 +0800471 qspi_op_read(qspi, din, bytes);
Peng Fan53e3db72014-12-31 11:01:36 +0800472 else if (qspi->cur_seqid == QSPI_CMD_RDID)
Alison Wang6b57ff62014-05-06 09:13:01 +0800473 qspi_op_rdid(qspi, din, bytes);
Peng Fan53e3db72014-12-31 11:01:36 +0800474 else if (qspi->cur_seqid == QSPI_CMD_RDSR)
Alison Wang6b57ff62014-05-06 09:13:01 +0800475 qspi_op_rdsr(qspi, din);
476 }
477
478 return 0;
479}
480
481void spi_release_bus(struct spi_slave *slave)
482{
483 /* Nothing to do */
484}