1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Rockchip Serial Flash Controller Driver |
4 | * |
5 | * Copyright (c) 2017-2021, Rockchip Inc. |
6 | * Author: Shawn Lin <shawn.lin@rock-chips.com> |
7 | * Chris Morgan <macroalpha82@gmail.com> |
8 | * Jon Lin <Jon.lin@rock-chips.com> |
9 | */ |
10 | |
11 | #include <linux/bitops.h> |
12 | #include <linux/clk.h> |
13 | #include <linux/completion.h> |
14 | #include <linux/dma-mapping.h> |
15 | #include <linux/iopoll.h> |
16 | #include <linux/mm.h> |
17 | #include <linux/module.h> |
18 | #include <linux/of.h> |
19 | #include <linux/platform_device.h> |
20 | #include <linux/slab.h> |
21 | #include <linux/interrupt.h> |
22 | #include <linux/spi/spi-mem.h> |
23 | |
24 | /* System control */ |
25 | #define SFC_CTRL 0x0 |
26 | #define SFC_CTRL_PHASE_SEL_NEGETIVE BIT(1) |
27 | #define SFC_CTRL_CMD_BITS_SHIFT 8 |
28 | #define SFC_CTRL_ADDR_BITS_SHIFT 10 |
29 | #define SFC_CTRL_DATA_BITS_SHIFT 12 |
30 | |
31 | /* Interrupt mask */ |
32 | #define SFC_IMR 0x4 |
33 | #define SFC_IMR_RX_FULL BIT(0) |
34 | #define SFC_IMR_RX_UFLOW BIT(1) |
35 | #define SFC_IMR_TX_OFLOW BIT(2) |
36 | #define SFC_IMR_TX_EMPTY BIT(3) |
37 | #define SFC_IMR_TRAN_FINISH BIT(4) |
38 | #define SFC_IMR_BUS_ERR BIT(5) |
39 | #define SFC_IMR_NSPI_ERR BIT(6) |
40 | #define SFC_IMR_DMA BIT(7) |
41 | |
42 | /* Interrupt clear */ |
43 | #define SFC_ICLR 0x8 |
44 | #define SFC_ICLR_RX_FULL BIT(0) |
45 | #define SFC_ICLR_RX_UFLOW BIT(1) |
46 | #define SFC_ICLR_TX_OFLOW BIT(2) |
47 | #define SFC_ICLR_TX_EMPTY BIT(3) |
48 | #define SFC_ICLR_TRAN_FINISH BIT(4) |
49 | #define SFC_ICLR_BUS_ERR BIT(5) |
50 | #define SFC_ICLR_NSPI_ERR BIT(6) |
51 | #define SFC_ICLR_DMA BIT(7) |
52 | |
53 | /* FIFO threshold level */ |
54 | #define SFC_FTLR 0xc |
55 | #define SFC_FTLR_TX_SHIFT 0 |
56 | #define SFC_FTLR_TX_MASK 0x1f |
57 | #define SFC_FTLR_RX_SHIFT 8 |
58 | #define SFC_FTLR_RX_MASK 0x1f |
59 | |
60 | /* Reset FSM and FIFO */ |
61 | #define SFC_RCVR 0x10 |
62 | #define SFC_RCVR_RESET BIT(0) |
63 | |
64 | /* Enhanced mode */ |
65 | #define SFC_AX 0x14 |
66 | |
67 | /* Address Bit number */ |
68 | #define SFC_ABIT 0x18 |
69 | |
70 | /* Interrupt status */ |
71 | #define SFC_ISR 0x1c |
72 | #define SFC_ISR_RX_FULL_SHIFT BIT(0) |
73 | #define SFC_ISR_RX_UFLOW_SHIFT BIT(1) |
74 | #define SFC_ISR_TX_OFLOW_SHIFT BIT(2) |
75 | #define SFC_ISR_TX_EMPTY_SHIFT BIT(3) |
76 | #define SFC_ISR_TX_FINISH_SHIFT BIT(4) |
77 | #define SFC_ISR_BUS_ERR_SHIFT BIT(5) |
78 | #define SFC_ISR_NSPI_ERR_SHIFT BIT(6) |
79 | #define SFC_ISR_DMA_SHIFT BIT(7) |
80 | |
81 | /* FIFO status */ |
82 | #define SFC_FSR 0x20 |
83 | #define SFC_FSR_TX_IS_FULL BIT(0) |
84 | #define SFC_FSR_TX_IS_EMPTY BIT(1) |
85 | #define SFC_FSR_RX_IS_EMPTY BIT(2) |
86 | #define SFC_FSR_RX_IS_FULL BIT(3) |
87 | #define SFC_FSR_TXLV_MASK GENMASK(12, 8) |
88 | #define SFC_FSR_TXLV_SHIFT 8 |
89 | #define SFC_FSR_RXLV_MASK GENMASK(20, 16) |
90 | #define SFC_FSR_RXLV_SHIFT 16 |
91 | |
92 | /* FSM status */ |
93 | #define SFC_SR 0x24 |
94 | #define SFC_SR_IS_IDLE 0x0 |
95 | #define SFC_SR_IS_BUSY 0x1 |
96 | |
97 | /* Raw interrupt status */ |
98 | #define SFC_RISR 0x28 |
99 | #define SFC_RISR_RX_FULL BIT(0) |
100 | #define SFC_RISR_RX_UNDERFLOW BIT(1) |
101 | #define SFC_RISR_TX_OVERFLOW BIT(2) |
102 | #define SFC_RISR_TX_EMPTY BIT(3) |
103 | #define SFC_RISR_TRAN_FINISH BIT(4) |
104 | #define SFC_RISR_BUS_ERR BIT(5) |
105 | #define SFC_RISR_NSPI_ERR BIT(6) |
106 | #define SFC_RISR_DMA BIT(7) |
107 | |
108 | /* Version */ |
109 | #define SFC_VER 0x2C |
110 | #define SFC_VER_3 0x3 |
111 | #define SFC_VER_4 0x4 |
112 | #define SFC_VER_5 0x5 |
113 | |
114 | /* Delay line controller resiter */ |
115 | #define SFC_DLL_CTRL0 0x3C |
116 | #define SFC_DLL_CTRL0_SCLK_SMP_DLL BIT(15) |
117 | #define SFC_DLL_CTRL0_DLL_MAX_VER4 0xFFU |
118 | #define SFC_DLL_CTRL0_DLL_MAX_VER5 0x1FFU |
119 | |
120 | /* Master trigger */ |
121 | #define SFC_DMA_TRIGGER 0x80 |
122 | #define SFC_DMA_TRIGGER_START 1 |
123 | |
124 | /* Src or Dst addr for master */ |
125 | #define SFC_DMA_ADDR 0x84 |
126 | |
127 | /* Length control register extension 32GB */ |
128 | #define SFC_LEN_CTRL 0x88 |
129 | #define SFC_LEN_CTRL_TRB_SEL 1 |
130 | #define SFC_LEN_EXT 0x8C |
131 | |
132 | /* Command */ |
133 | #define SFC_CMD 0x100 |
134 | #define SFC_CMD_IDX_SHIFT 0 |
135 | #define SFC_CMD_DUMMY_SHIFT 8 |
136 | #define SFC_CMD_DIR_SHIFT 12 |
137 | #define SFC_CMD_DIR_RD 0 |
138 | #define SFC_CMD_DIR_WR 1 |
139 | #define SFC_CMD_ADDR_SHIFT 14 |
140 | #define SFC_CMD_ADDR_0BITS 0 |
141 | #define SFC_CMD_ADDR_24BITS 1 |
142 | #define SFC_CMD_ADDR_32BITS 2 |
143 | #define SFC_CMD_ADDR_XBITS 3 |
144 | #define SFC_CMD_TRAN_BYTES_SHIFT 16 |
145 | #define SFC_CMD_CS_SHIFT 30 |
146 | |
147 | /* Address */ |
148 | #define SFC_ADDR 0x104 |
149 | |
150 | /* Data */ |
151 | #define SFC_DATA 0x108 |
152 | |
153 | /* The controller and documentation reports that it supports up to 4 CS |
154 | * devices (0-3), however I have only been able to test a single CS (CS 0) |
155 | * due to the configuration of my device. |
156 | */ |
157 | #define SFC_MAX_CHIPSELECT_NUM 4 |
158 | |
159 | /* The SFC can transfer max 16KB - 1 at one time |
160 | * we set it to 15.5KB here for alignment. |
161 | */ |
162 | #define SFC_MAX_IOSIZE_VER3 (512 * 31) |
163 | |
164 | /* DMA is only enabled for large data transmission */ |
165 | #define SFC_DMA_TRANS_THRETHOLD (0x40) |
166 | |
167 | /* Maximum clock values from datasheet suggest keeping clock value under |
168 | * 150MHz. No minimum or average value is suggested. |
169 | */ |
170 | #define SFC_MAX_SPEED (150 * 1000 * 1000) |
171 | |
172 | struct rockchip_sfc { |
173 | struct device *dev; |
174 | void __iomem *regbase; |
175 | struct clk *hclk; |
176 | struct clk *clk; |
177 | u32 frequency; |
178 | /* virtual mapped addr for dma_buffer */ |
179 | void *buffer; |
180 | dma_addr_t dma_buffer; |
181 | struct completion cp; |
182 | bool use_dma; |
183 | u32 max_iosize; |
184 | u16 version; |
185 | }; |
186 | |
187 | static int rockchip_sfc_reset(struct rockchip_sfc *sfc) |
188 | { |
189 | int err; |
190 | u32 status; |
191 | |
192 | writel_relaxed(SFC_RCVR_RESET, sfc->regbase + SFC_RCVR); |
193 | |
194 | err = readl_poll_timeout(sfc->regbase + SFC_RCVR, status, |
195 | !(status & SFC_RCVR_RESET), 20, |
196 | jiffies_to_usecs(HZ)); |
197 | if (err) |
198 | dev_err(sfc->dev, "SFC reset never finished\n" ); |
199 | |
200 | /* Still need to clear the masked interrupt from RISR */ |
201 | writel_relaxed(0xFFFFFFFF, sfc->regbase + SFC_ICLR); |
202 | |
203 | dev_dbg(sfc->dev, "reset\n" ); |
204 | |
205 | return err; |
206 | } |
207 | |
208 | static u16 rockchip_sfc_get_version(struct rockchip_sfc *sfc) |
209 | { |
210 | return (u16)(readl(addr: sfc->regbase + SFC_VER) & 0xffff); |
211 | } |
212 | |
213 | static u32 rockchip_sfc_get_max_iosize(struct rockchip_sfc *sfc) |
214 | { |
215 | return SFC_MAX_IOSIZE_VER3; |
216 | } |
217 | |
218 | static void rockchip_sfc_irq_unmask(struct rockchip_sfc *sfc, u32 mask) |
219 | { |
220 | u32 reg; |
221 | |
222 | /* Enable transfer complete interrupt */ |
223 | reg = readl(addr: sfc->regbase + SFC_IMR); |
224 | reg &= ~mask; |
225 | writel(val: reg, addr: sfc->regbase + SFC_IMR); |
226 | } |
227 | |
228 | static void rockchip_sfc_irq_mask(struct rockchip_sfc *sfc, u32 mask) |
229 | { |
230 | u32 reg; |
231 | |
232 | /* Disable transfer finish interrupt */ |
233 | reg = readl(addr: sfc->regbase + SFC_IMR); |
234 | reg |= mask; |
235 | writel(val: reg, addr: sfc->regbase + SFC_IMR); |
236 | } |
237 | |
238 | static int rockchip_sfc_init(struct rockchip_sfc *sfc) |
239 | { |
240 | writel(val: 0, addr: sfc->regbase + SFC_CTRL); |
241 | writel(val: 0xFFFFFFFF, addr: sfc->regbase + SFC_ICLR); |
242 | rockchip_sfc_irq_mask(sfc, mask: 0xFFFFFFFF); |
243 | if (rockchip_sfc_get_version(sfc) >= SFC_VER_4) |
244 | writel(SFC_LEN_CTRL_TRB_SEL, addr: sfc->regbase + SFC_LEN_CTRL); |
245 | |
246 | return 0; |
247 | } |
248 | |
249 | static int rockchip_sfc_wait_txfifo_ready(struct rockchip_sfc *sfc, u32 timeout_us) |
250 | { |
251 | int ret = 0; |
252 | u32 status; |
253 | |
254 | ret = readl_poll_timeout(sfc->regbase + SFC_FSR, status, |
255 | status & SFC_FSR_TXLV_MASK, 0, |
256 | timeout_us); |
257 | if (ret) { |
258 | dev_dbg(sfc->dev, "sfc wait tx fifo timeout\n" ); |
259 | |
260 | return -ETIMEDOUT; |
261 | } |
262 | |
263 | return (status & SFC_FSR_TXLV_MASK) >> SFC_FSR_TXLV_SHIFT; |
264 | } |
265 | |
266 | static int rockchip_sfc_wait_rxfifo_ready(struct rockchip_sfc *sfc, u32 timeout_us) |
267 | { |
268 | int ret = 0; |
269 | u32 status; |
270 | |
271 | ret = readl_poll_timeout(sfc->regbase + SFC_FSR, status, |
272 | status & SFC_FSR_RXLV_MASK, 0, |
273 | timeout_us); |
274 | if (ret) { |
275 | dev_dbg(sfc->dev, "sfc wait rx fifo timeout\n" ); |
276 | |
277 | return -ETIMEDOUT; |
278 | } |
279 | |
280 | return (status & SFC_FSR_RXLV_MASK) >> SFC_FSR_RXLV_SHIFT; |
281 | } |
282 | |
283 | static void rockchip_sfc_adjust_op_work(struct spi_mem_op *op) |
284 | { |
285 | if (unlikely(op->dummy.nbytes && !op->addr.nbytes)) { |
286 | /* |
287 | * SFC not support output DUMMY cycles right after CMD cycles, so |
288 | * treat it as ADDR cycles. |
289 | */ |
290 | op->addr.nbytes = op->dummy.nbytes; |
291 | op->addr.buswidth = op->dummy.buswidth; |
292 | op->addr.val = 0xFFFFFFFFF; |
293 | |
294 | op->dummy.nbytes = 0; |
295 | } |
296 | } |
297 | |
298 | static int rockchip_sfc_xfer_setup(struct rockchip_sfc *sfc, |
299 | struct spi_mem *mem, |
300 | const struct spi_mem_op *op, |
301 | u32 len) |
302 | { |
303 | u32 ctrl = 0, cmd = 0; |
304 | |
305 | /* set CMD */ |
306 | cmd = op->cmd.opcode; |
307 | ctrl |= ((op->cmd.buswidth >> 1) << SFC_CTRL_CMD_BITS_SHIFT); |
308 | |
309 | /* set ADDR */ |
310 | if (op->addr.nbytes) { |
311 | if (op->addr.nbytes == 4) { |
312 | cmd |= SFC_CMD_ADDR_32BITS << SFC_CMD_ADDR_SHIFT; |
313 | } else if (op->addr.nbytes == 3) { |
314 | cmd |= SFC_CMD_ADDR_24BITS << SFC_CMD_ADDR_SHIFT; |
315 | } else { |
316 | cmd |= SFC_CMD_ADDR_XBITS << SFC_CMD_ADDR_SHIFT; |
317 | writel(val: op->addr.nbytes * 8 - 1, addr: sfc->regbase + SFC_ABIT); |
318 | } |
319 | |
320 | ctrl |= ((op->addr.buswidth >> 1) << SFC_CTRL_ADDR_BITS_SHIFT); |
321 | } |
322 | |
323 | /* set DUMMY */ |
324 | if (op->dummy.nbytes) { |
325 | if (op->dummy.buswidth == 4) |
326 | cmd |= op->dummy.nbytes * 2 << SFC_CMD_DUMMY_SHIFT; |
327 | else if (op->dummy.buswidth == 2) |
328 | cmd |= op->dummy.nbytes * 4 << SFC_CMD_DUMMY_SHIFT; |
329 | else |
330 | cmd |= op->dummy.nbytes * 8 << SFC_CMD_DUMMY_SHIFT; |
331 | } |
332 | |
333 | /* set DATA */ |
334 | if (sfc->version >= SFC_VER_4) /* Clear it if no data to transfer */ |
335 | writel(val: len, addr: sfc->regbase + SFC_LEN_EXT); |
336 | else |
337 | cmd |= len << SFC_CMD_TRAN_BYTES_SHIFT; |
338 | if (len) { |
339 | if (op->data.dir == SPI_MEM_DATA_OUT) |
340 | cmd |= SFC_CMD_DIR_WR << SFC_CMD_DIR_SHIFT; |
341 | |
342 | ctrl |= ((op->data.buswidth >> 1) << SFC_CTRL_DATA_BITS_SHIFT); |
343 | } |
344 | if (!len && op->addr.nbytes) |
345 | cmd |= SFC_CMD_DIR_WR << SFC_CMD_DIR_SHIFT; |
346 | |
347 | /* set the Controller */ |
348 | ctrl |= SFC_CTRL_PHASE_SEL_NEGETIVE; |
349 | cmd |= spi_get_chipselect(spi: mem->spi, idx: 0) << SFC_CMD_CS_SHIFT; |
350 | |
351 | dev_dbg(sfc->dev, "sfc addr.nbytes=%x(x%d) dummy.nbytes=%x(x%d)\n" , |
352 | op->addr.nbytes, op->addr.buswidth, |
353 | op->dummy.nbytes, op->dummy.buswidth); |
354 | dev_dbg(sfc->dev, "sfc ctrl=%x cmd=%x addr=%llx len=%x\n" , |
355 | ctrl, cmd, op->addr.val, len); |
356 | |
357 | writel(val: ctrl, addr: sfc->regbase + SFC_CTRL); |
358 | writel(val: cmd, addr: sfc->regbase + SFC_CMD); |
359 | if (op->addr.nbytes) |
360 | writel(val: op->addr.val, addr: sfc->regbase + SFC_ADDR); |
361 | |
362 | return 0; |
363 | } |
364 | |
365 | static int rockchip_sfc_write_fifo(struct rockchip_sfc *sfc, const u8 *buf, int len) |
366 | { |
367 | u8 bytes = len & 0x3; |
368 | u32 dwords; |
369 | int tx_level; |
370 | u32 write_words; |
371 | u32 tmp = 0; |
372 | |
373 | dwords = len >> 2; |
374 | while (dwords) { |
375 | tx_level = rockchip_sfc_wait_txfifo_ready(sfc, timeout_us: 1000); |
376 | if (tx_level < 0) |
377 | return tx_level; |
378 | write_words = min_t(u32, tx_level, dwords); |
379 | iowrite32_rep(port: sfc->regbase + SFC_DATA, buf, count: write_words); |
380 | buf += write_words << 2; |
381 | dwords -= write_words; |
382 | } |
383 | |
384 | /* write the rest non word aligned bytes */ |
385 | if (bytes) { |
386 | tx_level = rockchip_sfc_wait_txfifo_ready(sfc, timeout_us: 1000); |
387 | if (tx_level < 0) |
388 | return tx_level; |
389 | memcpy(&tmp, buf, bytes); |
390 | writel(val: tmp, addr: sfc->regbase + SFC_DATA); |
391 | } |
392 | |
393 | return len; |
394 | } |
395 | |
396 | static int rockchip_sfc_read_fifo(struct rockchip_sfc *sfc, u8 *buf, int len) |
397 | { |
398 | u8 bytes = len & 0x3; |
399 | u32 dwords; |
400 | u8 read_words; |
401 | int rx_level; |
402 | int tmp; |
403 | |
404 | /* word aligned access only */ |
405 | dwords = len >> 2; |
406 | while (dwords) { |
407 | rx_level = rockchip_sfc_wait_rxfifo_ready(sfc, timeout_us: 1000); |
408 | if (rx_level < 0) |
409 | return rx_level; |
410 | read_words = min_t(u32, rx_level, dwords); |
411 | ioread32_rep(port: sfc->regbase + SFC_DATA, buf, count: read_words); |
412 | buf += read_words << 2; |
413 | dwords -= read_words; |
414 | } |
415 | |
416 | /* read the rest non word aligned bytes */ |
417 | if (bytes) { |
418 | rx_level = rockchip_sfc_wait_rxfifo_ready(sfc, timeout_us: 1000); |
419 | if (rx_level < 0) |
420 | return rx_level; |
421 | tmp = readl(addr: sfc->regbase + SFC_DATA); |
422 | memcpy(buf, &tmp, bytes); |
423 | } |
424 | |
425 | return len; |
426 | } |
427 | |
428 | static int rockchip_sfc_fifo_transfer_dma(struct rockchip_sfc *sfc, dma_addr_t dma_buf, size_t len) |
429 | { |
430 | writel(val: 0xFFFFFFFF, addr: sfc->regbase + SFC_ICLR); |
431 | writel(val: (u32)dma_buf, addr: sfc->regbase + SFC_DMA_ADDR); |
432 | writel(SFC_DMA_TRIGGER_START, addr: sfc->regbase + SFC_DMA_TRIGGER); |
433 | |
434 | return len; |
435 | } |
436 | |
437 | static int rockchip_sfc_xfer_data_poll(struct rockchip_sfc *sfc, |
438 | const struct spi_mem_op *op, u32 len) |
439 | { |
440 | dev_dbg(sfc->dev, "sfc xfer_poll len=%x\n" , len); |
441 | |
442 | if (op->data.dir == SPI_MEM_DATA_OUT) |
443 | return rockchip_sfc_write_fifo(sfc, buf: op->data.buf.out, len); |
444 | else |
445 | return rockchip_sfc_read_fifo(sfc, buf: op->data.buf.in, len); |
446 | } |
447 | |
448 | static int rockchip_sfc_xfer_data_dma(struct rockchip_sfc *sfc, |
449 | const struct spi_mem_op *op, u32 len) |
450 | { |
451 | int ret; |
452 | |
453 | dev_dbg(sfc->dev, "sfc xfer_dma len=%x\n" , len); |
454 | |
455 | if (op->data.dir == SPI_MEM_DATA_OUT) |
456 | memcpy(sfc->buffer, op->data.buf.out, len); |
457 | |
458 | ret = rockchip_sfc_fifo_transfer_dma(sfc, dma_buf: sfc->dma_buffer, len); |
459 | if (!wait_for_completion_timeout(x: &sfc->cp, timeout: msecs_to_jiffies(m: 2000))) { |
460 | dev_err(sfc->dev, "DMA wait for transfer finish timeout\n" ); |
461 | ret = -ETIMEDOUT; |
462 | } |
463 | rockchip_sfc_irq_mask(sfc, SFC_IMR_DMA); |
464 | if (op->data.dir == SPI_MEM_DATA_IN) |
465 | memcpy(op->data.buf.in, sfc->buffer, len); |
466 | |
467 | return ret; |
468 | } |
469 | |
470 | static int rockchip_sfc_xfer_done(struct rockchip_sfc *sfc, u32 timeout_us) |
471 | { |
472 | int ret = 0; |
473 | u32 status; |
474 | |
475 | ret = readl_poll_timeout(sfc->regbase + SFC_SR, status, |
476 | !(status & SFC_SR_IS_BUSY), |
477 | 20, timeout_us); |
478 | if (ret) { |
479 | dev_err(sfc->dev, "wait sfc idle timeout\n" ); |
480 | rockchip_sfc_reset(sfc); |
481 | |
482 | ret = -EIO; |
483 | } |
484 | |
485 | return ret; |
486 | } |
487 | |
488 | static int rockchip_sfc_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op) |
489 | { |
490 | struct rockchip_sfc *sfc = spi_controller_get_devdata(ctlr: mem->spi->controller); |
491 | u32 len = op->data.nbytes; |
492 | int ret; |
493 | |
494 | if (unlikely(mem->spi->max_speed_hz != sfc->frequency)) { |
495 | ret = clk_set_rate(clk: sfc->clk, rate: mem->spi->max_speed_hz); |
496 | if (ret) |
497 | return ret; |
498 | sfc->frequency = mem->spi->max_speed_hz; |
499 | dev_dbg(sfc->dev, "set_freq=%dHz real_freq=%ldHz\n" , |
500 | sfc->frequency, clk_get_rate(sfc->clk)); |
501 | } |
502 | |
503 | rockchip_sfc_adjust_op_work(op: (struct spi_mem_op *)op); |
504 | rockchip_sfc_xfer_setup(sfc, mem, op, len); |
505 | if (len) { |
506 | if (likely(sfc->use_dma) && len >= SFC_DMA_TRANS_THRETHOLD) { |
507 | init_completion(x: &sfc->cp); |
508 | rockchip_sfc_irq_unmask(sfc, SFC_IMR_DMA); |
509 | ret = rockchip_sfc_xfer_data_dma(sfc, op, len); |
510 | } else { |
511 | ret = rockchip_sfc_xfer_data_poll(sfc, op, len); |
512 | } |
513 | |
514 | if (ret != len) { |
515 | dev_err(sfc->dev, "xfer data failed ret %d dir %d\n" , ret, op->data.dir); |
516 | |
517 | return -EIO; |
518 | } |
519 | } |
520 | |
521 | return rockchip_sfc_xfer_done(sfc, timeout_us: 100000); |
522 | } |
523 | |
524 | static int rockchip_sfc_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op) |
525 | { |
526 | struct rockchip_sfc *sfc = spi_controller_get_devdata(ctlr: mem->spi->controller); |
527 | |
528 | op->data.nbytes = min(op->data.nbytes, sfc->max_iosize); |
529 | |
530 | return 0; |
531 | } |
532 | |
533 | static const struct spi_controller_mem_ops rockchip_sfc_mem_ops = { |
534 | .exec_op = rockchip_sfc_exec_mem_op, |
535 | .adjust_op_size = rockchip_sfc_adjust_op_size, |
536 | }; |
537 | |
538 | static irqreturn_t rockchip_sfc_irq_handler(int irq, void *dev_id) |
539 | { |
540 | struct rockchip_sfc *sfc = dev_id; |
541 | u32 reg; |
542 | |
543 | reg = readl(addr: sfc->regbase + SFC_RISR); |
544 | |
545 | /* Clear interrupt */ |
546 | writel_relaxed(reg, sfc->regbase + SFC_ICLR); |
547 | |
548 | if (reg & SFC_RISR_DMA) { |
549 | complete(&sfc->cp); |
550 | |
551 | return IRQ_HANDLED; |
552 | } |
553 | |
554 | return IRQ_NONE; |
555 | } |
556 | |
557 | static int rockchip_sfc_probe(struct platform_device *pdev) |
558 | { |
559 | struct device *dev = &pdev->dev; |
560 | struct spi_controller *host; |
561 | struct rockchip_sfc *sfc; |
562 | int ret; |
563 | |
564 | host = devm_spi_alloc_host(dev: &pdev->dev, size: sizeof(*sfc)); |
565 | if (!host) |
566 | return -ENOMEM; |
567 | |
568 | host->flags = SPI_CONTROLLER_HALF_DUPLEX; |
569 | host->mem_ops = &rockchip_sfc_mem_ops; |
570 | host->dev.of_node = pdev->dev.of_node; |
571 | host->mode_bits = SPI_TX_QUAD | SPI_TX_DUAL | SPI_RX_QUAD | SPI_RX_DUAL; |
572 | host->max_speed_hz = SFC_MAX_SPEED; |
573 | host->num_chipselect = SFC_MAX_CHIPSELECT_NUM; |
574 | |
575 | sfc = spi_controller_get_devdata(ctlr: host); |
576 | sfc->dev = dev; |
577 | |
578 | sfc->regbase = devm_platform_ioremap_resource(pdev, index: 0); |
579 | if (IS_ERR(ptr: sfc->regbase)) |
580 | return PTR_ERR(ptr: sfc->regbase); |
581 | |
582 | sfc->clk = devm_clk_get(dev: &pdev->dev, id: "clk_sfc" ); |
583 | if (IS_ERR(ptr: sfc->clk)) { |
584 | dev_err(&pdev->dev, "Failed to get sfc interface clk\n" ); |
585 | return PTR_ERR(ptr: sfc->clk); |
586 | } |
587 | |
588 | sfc->hclk = devm_clk_get(dev: &pdev->dev, id: "hclk_sfc" ); |
589 | if (IS_ERR(ptr: sfc->hclk)) { |
590 | dev_err(&pdev->dev, "Failed to get sfc ahb clk\n" ); |
591 | return PTR_ERR(ptr: sfc->hclk); |
592 | } |
593 | |
594 | sfc->use_dma = !of_property_read_bool(np: sfc->dev->of_node, |
595 | propname: "rockchip,sfc-no-dma" ); |
596 | |
597 | if (sfc->use_dma) { |
598 | ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); |
599 | if (ret) { |
600 | dev_warn(dev, "Unable to set dma mask\n" ); |
601 | return ret; |
602 | } |
603 | |
604 | sfc->buffer = dmam_alloc_coherent(dev, SFC_MAX_IOSIZE_VER3, |
605 | dma_handle: &sfc->dma_buffer, |
606 | GFP_KERNEL); |
607 | if (!sfc->buffer) |
608 | return -ENOMEM; |
609 | } |
610 | |
611 | ret = clk_prepare_enable(clk: sfc->hclk); |
612 | if (ret) { |
613 | dev_err(&pdev->dev, "Failed to enable ahb clk\n" ); |
614 | goto err_hclk; |
615 | } |
616 | |
617 | ret = clk_prepare_enable(clk: sfc->clk); |
618 | if (ret) { |
619 | dev_err(&pdev->dev, "Failed to enable interface clk\n" ); |
620 | goto err_clk; |
621 | } |
622 | |
623 | /* Find the irq */ |
624 | ret = platform_get_irq(pdev, 0); |
625 | if (ret < 0) |
626 | goto err_irq; |
627 | |
628 | ret = devm_request_irq(dev, irq: ret, handler: rockchip_sfc_irq_handler, |
629 | irqflags: 0, devname: pdev->name, dev_id: sfc); |
630 | if (ret) { |
631 | dev_err(dev, "Failed to request irq\n" ); |
632 | |
633 | goto err_irq; |
634 | } |
635 | |
636 | ret = rockchip_sfc_init(sfc); |
637 | if (ret) |
638 | goto err_irq; |
639 | |
640 | sfc->max_iosize = rockchip_sfc_get_max_iosize(sfc); |
641 | sfc->version = rockchip_sfc_get_version(sfc); |
642 | |
643 | ret = spi_register_controller(ctlr: host); |
644 | if (ret) |
645 | goto err_irq; |
646 | |
647 | return 0; |
648 | |
649 | err_irq: |
650 | clk_disable_unprepare(clk: sfc->clk); |
651 | err_clk: |
652 | clk_disable_unprepare(clk: sfc->hclk); |
653 | err_hclk: |
654 | return ret; |
655 | } |
656 | |
657 | static void rockchip_sfc_remove(struct platform_device *pdev) |
658 | { |
659 | struct spi_controller *host = platform_get_drvdata(pdev); |
660 | struct rockchip_sfc *sfc = platform_get_drvdata(pdev); |
661 | |
662 | spi_unregister_controller(ctlr: host); |
663 | |
664 | clk_disable_unprepare(clk: sfc->clk); |
665 | clk_disable_unprepare(clk: sfc->hclk); |
666 | } |
667 | |
668 | static const struct of_device_id rockchip_sfc_dt_ids[] = { |
669 | { .compatible = "rockchip,sfc" }, |
670 | { /* sentinel */ } |
671 | }; |
672 | MODULE_DEVICE_TABLE(of, rockchip_sfc_dt_ids); |
673 | |
674 | static struct platform_driver rockchip_sfc_driver = { |
675 | .driver = { |
676 | .name = "rockchip-sfc" , |
677 | .of_match_table = rockchip_sfc_dt_ids, |
678 | }, |
679 | .probe = rockchip_sfc_probe, |
680 | .remove_new = rockchip_sfc_remove, |
681 | }; |
682 | module_platform_driver(rockchip_sfc_driver); |
683 | |
684 | MODULE_LICENSE("GPL v2" ); |
685 | MODULE_DESCRIPTION("Rockchip Serial Flash Controller Driver" ); |
686 | MODULE_AUTHOR("Shawn Lin <shawn.lin@rock-chips.com>" ); |
687 | MODULE_AUTHOR("Chris Morgan <macromorgan@hotmail.com>" ); |
688 | MODULE_AUTHOR("Jon Lin <Jon.lin@rock-chips.com>" ); |
689 | |