diff options
Diffstat (limited to 'drivers/spi/spi-nxp-fspi.c')
-rw-r--r-- | drivers/spi/spi-nxp-fspi.c | 1105 |
1 files changed, 1105 insertions, 0 deletions
diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c new file mode 100644 index 000000000000..75c6448f5015 --- /dev/null +++ b/drivers/spi/spi-nxp-fspi.c | |||
@@ -0,0 +1,1105 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0+ | ||
2 | |||
3 | /* | ||
4 | * NXP FlexSPI(FSPI) controller driver. | ||
5 | * | ||
6 | * Copyright 2019 NXP. | ||
7 | * | ||
8 | * FlexSPI is a flexsible SPI host controller which supports two SPI | ||
9 | * channels and up to 4 external devices. Each channel supports | ||
10 | * Single/Dual/Quad/Octal mode data transfer (1/2/4/8 bidirectional | ||
11 | * data lines). | ||
12 | * | ||
13 | * FlexSPI controller is driven by the LUT(Look-up Table) registers | ||
14 | * LUT registers are a look-up-table for sequences of instructions. | ||
15 | * A valid sequence consists of four LUT registers. | ||
16 | * Maximum 32 LUT sequences can be programmed simultaneously. | ||
17 | * | ||
18 | * LUTs are being created at run-time based on the commands passed | ||
19 | * from the spi-mem framework, thus using single LUT index. | ||
20 | * | ||
21 | * Software triggered Flash read/write access by IP Bus. | ||
22 | * | ||
23 | * Memory mapped read access by AHB Bus. | ||
24 | * | ||
25 | * Based on SPI MEM interface and spi-fsl-qspi.c driver. | ||
26 | * | ||
27 | * Author: | ||
28 | * Yogesh Narayan Gaur <yogeshnarayan.gaur@nxp.com> | ||
29 | * Boris Brezillion <bbrezillon@kernel.org> | ||
30 | * Frieder Schrempf <frieder.schrempf@kontron.de> | ||
31 | */ | ||
32 | |||
33 | #include <linux/bitops.h> | ||
34 | #include <linux/clk.h> | ||
35 | #include <linux/completion.h> | ||
36 | #include <linux/delay.h> | ||
37 | #include <linux/err.h> | ||
38 | #include <linux/errno.h> | ||
39 | #include <linux/interrupt.h> | ||
40 | #include <linux/io.h> | ||
41 | #include <linux/iopoll.h> | ||
42 | #include <linux/jiffies.h> | ||
43 | #include <linux/kernel.h> | ||
44 | #include <linux/module.h> | ||
45 | #include <linux/mutex.h> | ||
46 | #include <linux/of.h> | ||
47 | #include <linux/of_device.h> | ||
48 | #include <linux/platform_device.h> | ||
49 | #include <linux/pm_qos.h> | ||
50 | #include <linux/sizes.h> | ||
51 | |||
52 | #include <linux/spi/spi.h> | ||
53 | #include <linux/spi/spi-mem.h> | ||
54 | |||
55 | /* | ||
56 | * The driver only uses one single LUT entry, that is updated on | ||
57 | * each call of exec_op(). Index 0 is preset at boot with a basic | ||
58 | * read operation, so let's use the last entry (31). | ||
59 | */ | ||
60 | #define SEQID_LUT 31 | ||
61 | |||
62 | /* Registers used by the driver */ | ||
63 | #define FSPI_MCR0 0x00 | ||
64 | #define FSPI_MCR0_AHB_TIMEOUT(x) ((x) << 24) | ||
65 | #define FSPI_MCR0_IP_TIMEOUT(x) ((x) << 16) | ||
66 | #define FSPI_MCR0_LEARN_EN BIT(15) | ||
67 | #define FSPI_MCR0_SCRFRUN_EN BIT(14) | ||
68 | #define FSPI_MCR0_OCTCOMB_EN BIT(13) | ||
69 | #define FSPI_MCR0_DOZE_EN BIT(12) | ||
70 | #define FSPI_MCR0_HSEN BIT(11) | ||
71 | #define FSPI_MCR0_SERCLKDIV BIT(8) | ||
72 | #define FSPI_MCR0_ATDF_EN BIT(7) | ||
73 | #define FSPI_MCR0_ARDF_EN BIT(6) | ||
74 | #define FSPI_MCR0_RXCLKSRC(x) ((x) << 4) | ||
75 | #define FSPI_MCR0_END_CFG(x) ((x) << 2) | ||
76 | #define FSPI_MCR0_MDIS BIT(1) | ||
77 | #define FSPI_MCR0_SWRST BIT(0) | ||
78 | |||
79 | #define FSPI_MCR1 0x04 | ||
80 | #define FSPI_MCR1_SEQ_TIMEOUT(x) ((x) << 16) | ||
81 | #define FSPI_MCR1_AHB_TIMEOUT(x) (x) | ||
82 | |||
83 | #define FSPI_MCR2 0x08 | ||
84 | #define FSPI_MCR2_IDLE_WAIT(x) ((x) << 24) | ||
85 | #define FSPI_MCR2_SAMEDEVICEEN BIT(15) | ||
86 | #define FSPI_MCR2_CLRLRPHS BIT(14) | ||
87 | #define FSPI_MCR2_ABRDATSZ BIT(8) | ||
88 | #define FSPI_MCR2_ABRLEARN BIT(7) | ||
89 | #define FSPI_MCR2_ABR_READ BIT(6) | ||
90 | #define FSPI_MCR2_ABRWRITE BIT(5) | ||
91 | #define FSPI_MCR2_ABRDUMMY BIT(4) | ||
92 | #define FSPI_MCR2_ABR_MODE BIT(3) | ||
93 | #define FSPI_MCR2_ABRCADDR BIT(2) | ||
94 | #define FSPI_MCR2_ABRRADDR BIT(1) | ||
95 | #define FSPI_MCR2_ABR_CMD BIT(0) | ||
96 | |||
97 | #define FSPI_AHBCR 0x0c | ||
98 | #define FSPI_AHBCR_RDADDROPT BIT(6) | ||
99 | #define FSPI_AHBCR_PREF_EN BIT(5) | ||
100 | #define FSPI_AHBCR_BUFF_EN BIT(4) | ||
101 | #define FSPI_AHBCR_CACH_EN BIT(3) | ||
102 | #define FSPI_AHBCR_CLRTXBUF BIT(2) | ||
103 | #define FSPI_AHBCR_CLRRXBUF BIT(1) | ||
104 | #define FSPI_AHBCR_PAR_EN BIT(0) | ||
105 | |||
106 | #define FSPI_INTEN 0x10 | ||
107 | #define FSPI_INTEN_SCLKSBWR BIT(9) | ||
108 | #define FSPI_INTEN_SCLKSBRD BIT(8) | ||
109 | #define FSPI_INTEN_DATALRNFL BIT(7) | ||
110 | #define FSPI_INTEN_IPTXWE BIT(6) | ||
111 | #define FSPI_INTEN_IPRXWA BIT(5) | ||
112 | #define FSPI_INTEN_AHBCMDERR BIT(4) | ||
113 | #define FSPI_INTEN_IPCMDERR BIT(3) | ||
114 | #define FSPI_INTEN_AHBCMDGE BIT(2) | ||
115 | #define FSPI_INTEN_IPCMDGE BIT(1) | ||
116 | #define FSPI_INTEN_IPCMDDONE BIT(0) | ||
117 | |||
118 | #define FSPI_INTR 0x14 | ||
119 | #define FSPI_INTR_SCLKSBWR BIT(9) | ||
120 | #define FSPI_INTR_SCLKSBRD BIT(8) | ||
121 | #define FSPI_INTR_DATALRNFL BIT(7) | ||
122 | #define FSPI_INTR_IPTXWE BIT(6) | ||
123 | #define FSPI_INTR_IPRXWA BIT(5) | ||
124 | #define FSPI_INTR_AHBCMDERR BIT(4) | ||
125 | #define FSPI_INTR_IPCMDERR BIT(3) | ||
126 | #define FSPI_INTR_AHBCMDGE BIT(2) | ||
127 | #define FSPI_INTR_IPCMDGE BIT(1) | ||
128 | #define FSPI_INTR_IPCMDDONE BIT(0) | ||
129 | |||
130 | #define FSPI_LUTKEY 0x18 | ||
131 | #define FSPI_LUTKEY_VALUE 0x5AF05AF0 | ||
132 | |||
133 | #define FSPI_LCKCR 0x1C | ||
134 | |||
135 | #define FSPI_LCKER_LOCK 0x1 | ||
136 | #define FSPI_LCKER_UNLOCK 0x2 | ||
137 | |||
138 | #define FSPI_BUFXCR_INVALID_MSTRID 0xE | ||
139 | #define FSPI_AHBRX_BUF0CR0 0x20 | ||
140 | #define FSPI_AHBRX_BUF1CR0 0x24 | ||
141 | #define FSPI_AHBRX_BUF2CR0 0x28 | ||
142 | #define FSPI_AHBRX_BUF3CR0 0x2C | ||
143 | #define FSPI_AHBRX_BUF4CR0 0x30 | ||
144 | #define FSPI_AHBRX_BUF5CR0 0x34 | ||
145 | #define FSPI_AHBRX_BUF6CR0 0x38 | ||
146 | #define FSPI_AHBRX_BUF7CR0 0x3C | ||
147 | #define FSPI_AHBRXBUF0CR7_PREF BIT(31) | ||
148 | |||
149 | #define FSPI_AHBRX_BUF0CR1 0x40 | ||
150 | #define FSPI_AHBRX_BUF1CR1 0x44 | ||
151 | #define FSPI_AHBRX_BUF2CR1 0x48 | ||
152 | #define FSPI_AHBRX_BUF3CR1 0x4C | ||
153 | #define FSPI_AHBRX_BUF4CR1 0x50 | ||
154 | #define FSPI_AHBRX_BUF5CR1 0x54 | ||
155 | #define FSPI_AHBRX_BUF6CR1 0x58 | ||
156 | #define FSPI_AHBRX_BUF7CR1 0x5C | ||
157 | |||
158 | #define FSPI_FLSHA1CR0 0x60 | ||
159 | #define FSPI_FLSHA2CR0 0x64 | ||
160 | #define FSPI_FLSHB1CR0 0x68 | ||
161 | #define FSPI_FLSHB2CR0 0x6C | ||
162 | #define FSPI_FLSHXCR0_SZ_KB 10 | ||
163 | #define FSPI_FLSHXCR0_SZ(x) ((x) >> FSPI_FLSHXCR0_SZ_KB) | ||
164 | |||
165 | #define FSPI_FLSHA1CR1 0x70 | ||
166 | #define FSPI_FLSHA2CR1 0x74 | ||
167 | #define FSPI_FLSHB1CR1 0x78 | ||
168 | #define FSPI_FLSHB2CR1 0x7C | ||
169 | #define FSPI_FLSHXCR1_CSINTR(x) ((x) << 16) | ||
170 | #define FSPI_FLSHXCR1_CAS(x) ((x) << 11) | ||
171 | #define FSPI_FLSHXCR1_WA BIT(10) | ||
172 | #define FSPI_FLSHXCR1_TCSH(x) ((x) << 5) | ||
173 | #define FSPI_FLSHXCR1_TCSS(x) (x) | ||
174 | |||
175 | #define FSPI_FLSHA1CR2 0x80 | ||
176 | #define FSPI_FLSHA2CR2 0x84 | ||
177 | #define FSPI_FLSHB1CR2 0x88 | ||
178 | #define FSPI_FLSHB2CR2 0x8C | ||
179 | #define FSPI_FLSHXCR2_CLRINSP BIT(24) | ||
180 | #define FSPI_FLSHXCR2_AWRWAIT BIT(16) | ||
181 | #define FSPI_FLSHXCR2_AWRSEQN_SHIFT 13 | ||
182 | #define FSPI_FLSHXCR2_AWRSEQI_SHIFT 8 | ||
183 | #define FSPI_FLSHXCR2_ARDSEQN_SHIFT 5 | ||
184 | #define FSPI_FLSHXCR2_ARDSEQI_SHIFT 0 | ||
185 | |||
186 | #define FSPI_IPCR0 0xA0 | ||
187 | |||
188 | #define FSPI_IPCR1 0xA4 | ||
189 | #define FSPI_IPCR1_IPAREN BIT(31) | ||
190 | #define FSPI_IPCR1_SEQNUM_SHIFT 24 | ||
191 | #define FSPI_IPCR1_SEQID_SHIFT 16 | ||
192 | #define FSPI_IPCR1_IDATSZ(x) (x) | ||
193 | |||
194 | #define FSPI_IPCMD 0xB0 | ||
195 | #define FSPI_IPCMD_TRG BIT(0) | ||
196 | |||
197 | #define FSPI_DLPR 0xB4 | ||
198 | |||
199 | #define FSPI_IPRXFCR 0xB8 | ||
200 | #define FSPI_IPRXFCR_CLR BIT(0) | ||
201 | #define FSPI_IPRXFCR_DMA_EN BIT(1) | ||
202 | #define FSPI_IPRXFCR_WMRK(x) ((x) << 2) | ||
203 | |||
204 | #define FSPI_IPTXFCR 0xBC | ||
205 | #define FSPI_IPTXFCR_CLR BIT(0) | ||
206 | #define FSPI_IPTXFCR_DMA_EN BIT(1) | ||
207 | #define FSPI_IPTXFCR_WMRK(x) ((x) << 2) | ||
208 | |||
209 | #define FSPI_DLLACR 0xC0 | ||
210 | #define FSPI_DLLACR_OVRDEN BIT(8) | ||
211 | |||
212 | #define FSPI_DLLBCR 0xC4 | ||
213 | #define FSPI_DLLBCR_OVRDEN BIT(8) | ||
214 | |||
215 | #define FSPI_STS0 0xE0 | ||
216 | #define FSPI_STS0_DLPHB(x) ((x) << 8) | ||
217 | #define FSPI_STS0_DLPHA(x) ((x) << 4) | ||
218 | #define FSPI_STS0_CMD_SRC(x) ((x) << 2) | ||
219 | #define FSPI_STS0_ARB_IDLE BIT(1) | ||
220 | #define FSPI_STS0_SEQ_IDLE BIT(0) | ||
221 | |||
222 | #define FSPI_STS1 0xE4 | ||
223 | #define FSPI_STS1_IP_ERRCD(x) ((x) << 24) | ||
224 | #define FSPI_STS1_IP_ERRID(x) ((x) << 16) | ||
225 | #define FSPI_STS1_AHB_ERRCD(x) ((x) << 8) | ||
226 | #define FSPI_STS1_AHB_ERRID(x) (x) | ||
227 | |||
228 | #define FSPI_AHBSPNST 0xEC | ||
229 | #define FSPI_AHBSPNST_DATLFT(x) ((x) << 16) | ||
230 | #define FSPI_AHBSPNST_BUFID(x) ((x) << 1) | ||
231 | #define FSPI_AHBSPNST_ACTIVE BIT(0) | ||
232 | |||
233 | #define FSPI_IPRXFSTS 0xF0 | ||
234 | #define FSPI_IPRXFSTS_RDCNTR(x) ((x) << 16) | ||
235 | #define FSPI_IPRXFSTS_FILL(x) (x) | ||
236 | |||
237 | #define FSPI_IPTXFSTS 0xF4 | ||
238 | #define FSPI_IPTXFSTS_WRCNTR(x) ((x) << 16) | ||
239 | #define FSPI_IPTXFSTS_FILL(x) (x) | ||
240 | |||
241 | #define FSPI_RFDR 0x100 | ||
242 | #define FSPI_TFDR 0x180 | ||
243 | |||
244 | #define FSPI_LUT_BASE 0x200 | ||
245 | #define FSPI_LUT_OFFSET (SEQID_LUT * 4 * 4) | ||
246 | #define FSPI_LUT_REG(idx) \ | ||
247 | (FSPI_LUT_BASE + FSPI_LUT_OFFSET + (idx) * 4) | ||
248 | |||
249 | /* register map end */ | ||
250 | |||
251 | /* Instruction set for the LUT register. */ | ||
252 | #define LUT_STOP 0x00 | ||
253 | #define LUT_CMD 0x01 | ||
254 | #define LUT_ADDR 0x02 | ||
255 | #define LUT_CADDR_SDR 0x03 | ||
256 | #define LUT_MODE 0x04 | ||
257 | #define LUT_MODE2 0x05 | ||
258 | #define LUT_MODE4 0x06 | ||
259 | #define LUT_MODE8 0x07 | ||
260 | #define LUT_NXP_WRITE 0x08 | ||
261 | #define LUT_NXP_READ 0x09 | ||
262 | #define LUT_LEARN_SDR 0x0A | ||
263 | #define LUT_DATSZ_SDR 0x0B | ||
264 | #define LUT_DUMMY 0x0C | ||
265 | #define LUT_DUMMY_RWDS_SDR 0x0D | ||
266 | #define LUT_JMP_ON_CS 0x1F | ||
267 | #define LUT_CMD_DDR 0x21 | ||
268 | #define LUT_ADDR_DDR 0x22 | ||
269 | #define LUT_CADDR_DDR 0x23 | ||
270 | #define LUT_MODE_DDR 0x24 | ||
271 | #define LUT_MODE2_DDR 0x25 | ||
272 | #define LUT_MODE4_DDR 0x26 | ||
273 | #define LUT_MODE8_DDR 0x27 | ||
274 | #define LUT_WRITE_DDR 0x28 | ||
275 | #define LUT_READ_DDR 0x29 | ||
276 | #define LUT_LEARN_DDR 0x2A | ||
277 | #define LUT_DATSZ_DDR 0x2B | ||
278 | #define LUT_DUMMY_DDR 0x2C | ||
279 | #define LUT_DUMMY_RWDS_DDR 0x2D | ||
280 | |||
281 | /* | ||
282 | * Calculate number of required PAD bits for LUT register. | ||
283 | * | ||
284 | * The pad stands for the number of IO lines [0:7]. | ||
285 | * For example, the octal read needs eight IO lines, | ||
286 | * so you should use LUT_PAD(8). This macro | ||
287 | * returns 3 i.e. use eight (2^3) IP lines for read. | ||
288 | */ | ||
289 | #define LUT_PAD(x) (fls(x) - 1) | ||
290 | |||
291 | /* | ||
292 | * Macro for constructing the LUT entries with the following | ||
293 | * register layout: | ||
294 | * | ||
295 | * --------------------------------------------------- | ||
296 | * | INSTR1 | PAD1 | OPRND1 | INSTR0 | PAD0 | OPRND0 | | ||
297 | * --------------------------------------------------- | ||
298 | */ | ||
299 | #define PAD_SHIFT 8 | ||
300 | #define INSTR_SHIFT 10 | ||
301 | #define OPRND_SHIFT 16 | ||
302 | |||
303 | /* Macros for constructing the LUT register. */ | ||
304 | #define LUT_DEF(idx, ins, pad, opr) \ | ||
305 | ((((ins) << INSTR_SHIFT) | ((pad) << PAD_SHIFT) | \ | ||
306 | (opr)) << (((idx) % 2) * OPRND_SHIFT)) | ||
307 | |||
308 | #define POLL_TOUT 5000 | ||
309 | #define NXP_FSPI_MAX_CHIPSELECT 4 | ||
310 | |||
311 | struct nxp_fspi_devtype_data { | ||
312 | unsigned int rxfifo; | ||
313 | unsigned int txfifo; | ||
314 | unsigned int ahb_buf_size; | ||
315 | unsigned int quirks; | ||
316 | bool little_endian; | ||
317 | }; | ||
318 | |||
319 | static const struct nxp_fspi_devtype_data lx2160a_data = { | ||
320 | .rxfifo = SZ_512, /* (64 * 64 bits) */ | ||
321 | .txfifo = SZ_1K, /* (128 * 64 bits) */ | ||
322 | .ahb_buf_size = SZ_2K, /* (256 * 64 bits) */ | ||
323 | .quirks = 0, | ||
324 | .little_endian = true, /* little-endian */ | ||
325 | }; | ||
326 | |||
327 | struct nxp_fspi { | ||
328 | void __iomem *iobase; | ||
329 | void __iomem *ahb_addr; | ||
330 | u32 memmap_phy; | ||
331 | u32 memmap_phy_size; | ||
332 | struct clk *clk, *clk_en; | ||
333 | struct device *dev; | ||
334 | struct completion c; | ||
335 | const struct nxp_fspi_devtype_data *devtype_data; | ||
336 | struct mutex lock; | ||
337 | struct pm_qos_request pm_qos_req; | ||
338 | int selected; | ||
339 | }; | ||
340 | |||
341 | /* | ||
342 | * R/W functions for big- or little-endian registers: | ||
343 | * The FSPI controller's endianness is independent of | ||
344 | * the CPU core's endianness. So far, although the CPU | ||
345 | * core is little-endian the FSPI controller can use | ||
346 | * big-endian or little-endian. | ||
347 | */ | ||
348 | static void fspi_writel(struct nxp_fspi *f, u32 val, void __iomem *addr) | ||
349 | { | ||
350 | if (f->devtype_data->little_endian) | ||
351 | iowrite32(val, addr); | ||
352 | else | ||
353 | iowrite32be(val, addr); | ||
354 | } | ||
355 | |||
356 | static u32 fspi_readl(struct nxp_fspi *f, void __iomem *addr) | ||
357 | { | ||
358 | if (f->devtype_data->little_endian) | ||
359 | return ioread32(addr); | ||
360 | else | ||
361 | return ioread32be(addr); | ||
362 | } | ||
363 | |||
364 | static irqreturn_t nxp_fspi_irq_handler(int irq, void *dev_id) | ||
365 | { | ||
366 | struct nxp_fspi *f = dev_id; | ||
367 | u32 reg; | ||
368 | |||
369 | /* clear interrupt */ | ||
370 | reg = fspi_readl(f, f->iobase + FSPI_INTR); | ||
371 | fspi_writel(f, FSPI_INTR_IPCMDDONE, f->iobase + FSPI_INTR); | ||
372 | |||
373 | if (reg & FSPI_INTR_IPCMDDONE) | ||
374 | complete(&f->c); | ||
375 | |||
376 | return IRQ_HANDLED; | ||
377 | } | ||
378 | |||
379 | static int nxp_fspi_check_buswidth(struct nxp_fspi *f, u8 width) | ||
380 | { | ||
381 | switch (width) { | ||
382 | case 1: | ||
383 | case 2: | ||
384 | case 4: | ||
385 | case 8: | ||
386 | return 0; | ||
387 | } | ||
388 | |||
389 | return -ENOTSUPP; | ||
390 | } | ||
391 | |||
392 | static bool nxp_fspi_supports_op(struct spi_mem *mem, | ||
393 | const struct spi_mem_op *op) | ||
394 | { | ||
395 | struct nxp_fspi *f = spi_controller_get_devdata(mem->spi->master); | ||
396 | int ret; | ||
397 | |||
398 | ret = nxp_fspi_check_buswidth(f, op->cmd.buswidth); | ||
399 | |||
400 | if (op->addr.nbytes) | ||
401 | ret |= nxp_fspi_check_buswidth(f, op->addr.buswidth); | ||
402 | |||
403 | if (op->dummy.nbytes) | ||
404 | ret |= nxp_fspi_check_buswidth(f, op->dummy.buswidth); | ||
405 | |||
406 | if (op->data.nbytes) | ||
407 | ret |= nxp_fspi_check_buswidth(f, op->data.buswidth); | ||
408 | |||
409 | if (ret) | ||
410 | return false; | ||
411 | |||
412 | /* | ||
413 | * The number of address bytes should be equal to or less than 4 bytes. | ||
414 | */ | ||
415 | if (op->addr.nbytes > 4) | ||
416 | return false; | ||
417 | |||
418 | /* | ||
419 | * If requested address value is greater than controller assigned | ||
420 | * memory mapped space, return error as it didn't fit in the range | ||
421 | * of assigned address space. | ||
422 | */ | ||
423 | if (op->addr.val >= f->memmap_phy_size) | ||
424 | return false; | ||
425 | |||
426 | /* Max 64 dummy clock cycles supported */ | ||
427 | if (op->dummy.buswidth && | ||
428 | (op->dummy.nbytes * 8 / op->dummy.buswidth > 64)) | ||
429 | return false; | ||
430 | |||
431 | /* Max data length, check controller limits and alignment */ | ||
432 | if (op->data.dir == SPI_MEM_DATA_IN && | ||
433 | (op->data.nbytes > f->devtype_data->ahb_buf_size || | ||
434 | (op->data.nbytes > f->devtype_data->rxfifo - 4 && | ||
435 | !IS_ALIGNED(op->data.nbytes, 8)))) | ||
436 | return false; | ||
437 | |||
438 | if (op->data.dir == SPI_MEM_DATA_OUT && | ||
439 | op->data.nbytes > f->devtype_data->txfifo) | ||
440 | return false; | ||
441 | |||
442 | return true; | ||
443 | } | ||
444 | |||
445 | /* Instead of busy looping invoke readl_poll_timeout functionality. */ | ||
446 | static int fspi_readl_poll_tout(struct nxp_fspi *f, void __iomem *base, | ||
447 | u32 mask, u32 delay_us, | ||
448 | u32 timeout_us, bool c) | ||
449 | { | ||
450 | u32 reg; | ||
451 | |||
452 | if (!f->devtype_data->little_endian) | ||
453 | mask = (u32)cpu_to_be32(mask); | ||
454 | |||
455 | if (c) | ||
456 | return readl_poll_timeout(base, reg, (reg & mask), | ||
457 | delay_us, timeout_us); | ||
458 | else | ||
459 | return readl_poll_timeout(base, reg, !(reg & mask), | ||
460 | delay_us, timeout_us); | ||
461 | } | ||
462 | |||
463 | /* | ||
464 | * If the slave device content being changed by Write/Erase, need to | ||
465 | * invalidate the AHB buffer. This can be achieved by doing the reset | ||
466 | * of controller after setting MCR0[SWRESET] bit. | ||
467 | */ | ||
468 | static inline void nxp_fspi_invalid(struct nxp_fspi *f) | ||
469 | { | ||
470 | u32 reg; | ||
471 | int ret; | ||
472 | |||
473 | reg = fspi_readl(f, f->iobase + FSPI_MCR0); | ||
474 | fspi_writel(f, reg | FSPI_MCR0_SWRST, f->iobase + FSPI_MCR0); | ||
475 | |||
476 | /* w1c register, wait unit clear */ | ||
477 | ret = fspi_readl_poll_tout(f, f->iobase + FSPI_MCR0, | ||
478 | FSPI_MCR0_SWRST, 0, POLL_TOUT, false); | ||
479 | WARN_ON(ret); | ||
480 | } | ||
481 | |||
482 | static void nxp_fspi_prepare_lut(struct nxp_fspi *f, | ||
483 | const struct spi_mem_op *op) | ||
484 | { | ||
485 | void __iomem *base = f->iobase; | ||
486 | u32 lutval[4] = {}; | ||
487 | int lutidx = 1, i; | ||
488 | |||
489 | /* cmd */ | ||
490 | lutval[0] |= LUT_DEF(0, LUT_CMD, LUT_PAD(op->cmd.buswidth), | ||
491 | op->cmd.opcode); | ||
492 | |||
493 | /* addr bytes */ | ||
494 | if (op->addr.nbytes) { | ||
495 | lutval[lutidx / 2] |= LUT_DEF(lutidx, LUT_ADDR, | ||
496 | LUT_PAD(op->addr.buswidth), | ||
497 | op->addr.nbytes * 8); | ||
498 | lutidx++; | ||
499 | } | ||
500 | |||
501 | /* dummy bytes, if needed */ | ||
502 | if (op->dummy.nbytes) { | ||
503 | lutval[lutidx / 2] |= LUT_DEF(lutidx, LUT_DUMMY, | ||
504 | /* | ||
505 | * Due to FlexSPI controller limitation number of PAD for dummy | ||
506 | * buswidth needs to be programmed as equal to data buswidth. | ||
507 | */ | ||
508 | LUT_PAD(op->data.buswidth), | ||
509 | op->dummy.nbytes * 8 / | ||
510 | op->dummy.buswidth); | ||
511 | lutidx++; | ||
512 | } | ||
513 | |||
514 | /* read/write data bytes */ | ||
515 | if (op->data.nbytes) { | ||
516 | lutval[lutidx / 2] |= LUT_DEF(lutidx, | ||
517 | op->data.dir == SPI_MEM_DATA_IN ? | ||
518 | LUT_NXP_READ : LUT_NXP_WRITE, | ||
519 | LUT_PAD(op->data.buswidth), | ||
520 | 0); | ||
521 | lutidx++; | ||
522 | } | ||
523 | |||
524 | /* stop condition. */ | ||
525 | lutval[lutidx / 2] |= LUT_DEF(lutidx, LUT_STOP, 0, 0); | ||
526 | |||
527 | /* unlock LUT */ | ||
528 | fspi_writel(f, FSPI_LUTKEY_VALUE, f->iobase + FSPI_LUTKEY); | ||
529 | fspi_writel(f, FSPI_LCKER_UNLOCK, f->iobase + FSPI_LCKCR); | ||
530 | |||
531 | /* fill LUT */ | ||
532 | for (i = 0; i < ARRAY_SIZE(lutval); i++) | ||
533 | fspi_writel(f, lutval[i], base + FSPI_LUT_REG(i)); | ||
534 | |||
535 | dev_dbg(f->dev, "CMD[%x] lutval[0:%x \t 1:%x \t 2:%x \t 3:%x]\n", | ||
536 | op->cmd.opcode, lutval[0], lutval[1], lutval[2], lutval[3]); | ||
537 | |||
538 | /* lock LUT */ | ||
539 | fspi_writel(f, FSPI_LUTKEY_VALUE, f->iobase + FSPI_LUTKEY); | ||
540 | fspi_writel(f, FSPI_LCKER_LOCK, f->iobase + FSPI_LCKCR); | ||
541 | } | ||
542 | |||
543 | static int nxp_fspi_clk_prep_enable(struct nxp_fspi *f) | ||
544 | { | ||
545 | int ret; | ||
546 | |||
547 | ret = clk_prepare_enable(f->clk_en); | ||
548 | if (ret) | ||
549 | return ret; | ||
550 | |||
551 | ret = clk_prepare_enable(f->clk); | ||
552 | if (ret) { | ||
553 | clk_disable_unprepare(f->clk_en); | ||
554 | return ret; | ||
555 | } | ||
556 | |||
557 | return 0; | ||
558 | } | ||
559 | |||
560 | static void nxp_fspi_clk_disable_unprep(struct nxp_fspi *f) | ||
561 | { | ||
562 | clk_disable_unprepare(f->clk); | ||
563 | clk_disable_unprepare(f->clk_en); | ||
564 | } | ||
565 | |||
566 | /* | ||
567 | * In FlexSPI controller, flash access is based on value of FSPI_FLSHXXCR0 | ||
568 | * register and start base address of the slave device. | ||
569 | * | ||
570 | * (Higher address) | ||
571 | * -------- <-- FLSHB2CR0 | ||
572 | * | B2 | | ||
573 | * | | | ||
574 | * B2 start address --> -------- <-- FLSHB1CR0 | ||
575 | * | B1 | | ||
576 | * | | | ||
577 | * B1 start address --> -------- <-- FLSHA2CR0 | ||
578 | * | A2 | | ||
579 | * | | | ||
580 | * A2 start address --> -------- <-- FLSHA1CR0 | ||
581 | * | A1 | | ||
582 | * | | | ||
583 | * A1 start address --> -------- (Lower address) | ||
584 | * | ||
585 | * | ||
586 | * Start base address defines the starting address range for given CS and | ||
587 | * FSPI_FLSHXXCR0 defines the size of the slave device connected at given CS. | ||
588 | * | ||
589 | * But, different targets are having different combinations of number of CS, | ||
590 | * some targets only have single CS or two CS covering controller's full | ||
591 | * memory mapped space area. | ||
592 | * Thus, implementation is being done as independent of the size and number | ||
593 | * of the connected slave device. | ||
594 | * Assign controller memory mapped space size as the size to the connected | ||
595 | * slave device. | ||
596 | * Mark FLSHxxCR0 as zero initially and then assign value only to the selected | ||
597 | * chip-select Flash configuration register. | ||
598 | * | ||
599 | * For e.g. to access CS2 (B1), FLSHB1CR0 register would be equal to the | ||
600 | * memory mapped size of the controller. | ||
601 | * Value for rest of the CS FLSHxxCR0 register would be zero. | ||
602 | * | ||
603 | */ | ||
604 | static void nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi) | ||
605 | { | ||
606 | unsigned long rate = spi->max_speed_hz; | ||
607 | int ret; | ||
608 | uint64_t size_kb; | ||
609 | |||
610 | /* | ||
611 | * Return, if previously selected slave device is same as current | ||
612 | * requested slave device. | ||
613 | */ | ||
614 | if (f->selected == spi->chip_select) | ||
615 | return; | ||
616 | |||
617 | /* Reset FLSHxxCR0 registers */ | ||
618 | fspi_writel(f, 0, f->iobase + FSPI_FLSHA1CR0); | ||
619 | fspi_writel(f, 0, f->iobase + FSPI_FLSHA2CR0); | ||
620 | fspi_writel(f, 0, f->iobase + FSPI_FLSHB1CR0); | ||
621 | fspi_writel(f, 0, f->iobase + FSPI_FLSHB2CR0); | ||
622 | |||
623 | /* Assign controller memory mapped space as size, KBytes, of flash. */ | ||
624 | size_kb = FSPI_FLSHXCR0_SZ(f->memmap_phy_size); | ||
625 | |||
626 | fspi_writel(f, size_kb, f->iobase + FSPI_FLSHA1CR0 + | ||
627 | 4 * spi->chip_select); | ||
628 | |||
629 | dev_dbg(f->dev, "Slave device [CS:%x] selected\n", spi->chip_select); | ||
630 | |||
631 | nxp_fspi_clk_disable_unprep(f); | ||
632 | |||
633 | ret = clk_set_rate(f->clk, rate); | ||
634 | if (ret) | ||
635 | return; | ||
636 | |||
637 | ret = nxp_fspi_clk_prep_enable(f); | ||
638 | if (ret) | ||
639 | return; | ||
640 | |||
641 | f->selected = spi->chip_select; | ||
642 | } | ||
643 | |||
644 | static void nxp_fspi_read_ahb(struct nxp_fspi *f, const struct spi_mem_op *op) | ||
645 | { | ||
646 | u32 len = op->data.nbytes; | ||
647 | |||
648 | /* Read out the data directly from the AHB buffer. */ | ||
649 | memcpy_fromio(op->data.buf.in, (f->ahb_addr + op->addr.val), len); | ||
650 | } | ||
651 | |||
652 | static void nxp_fspi_fill_txfifo(struct nxp_fspi *f, | ||
653 | const struct spi_mem_op *op) | ||
654 | { | ||
655 | void __iomem *base = f->iobase; | ||
656 | int i, ret; | ||
657 | u8 *buf = (u8 *) op->data.buf.out; | ||
658 | |||
659 | /* clear the TX FIFO. */ | ||
660 | fspi_writel(f, FSPI_IPTXFCR_CLR, base + FSPI_IPTXFCR); | ||
661 | |||
662 | /* | ||
663 | * Default value of water mark level is 8 bytes, hence in single | ||
664 | * write request controller can write max 8 bytes of data. | ||
665 | */ | ||
666 | |||
667 | for (i = 0; i < ALIGN_DOWN(op->data.nbytes, 8); i += 8) { | ||
668 | /* Wait for TXFIFO empty */ | ||
669 | ret = fspi_readl_poll_tout(f, f->iobase + FSPI_INTR, | ||
670 | FSPI_INTR_IPTXWE, 0, | ||
671 | POLL_TOUT, true); | ||
672 | WARN_ON(ret); | ||
673 | |||
674 | fspi_writel(f, *(u32 *) (buf + i), base + FSPI_TFDR); | ||
675 | fspi_writel(f, *(u32 *) (buf + i + 4), base + FSPI_TFDR + 4); | ||
676 | fspi_writel(f, FSPI_INTR_IPTXWE, base + FSPI_INTR); | ||
677 | } | ||
678 | |||
679 | if (i < op->data.nbytes) { | ||
680 | u32 data = 0; | ||
681 | int j; | ||
682 | /* Wait for TXFIFO empty */ | ||
683 | ret = fspi_readl_poll_tout(f, f->iobase + FSPI_INTR, | ||
684 | FSPI_INTR_IPTXWE, 0, | ||
685 | POLL_TOUT, true); | ||
686 | WARN_ON(ret); | ||
687 | |||
688 | for (j = 0; j < ALIGN(op->data.nbytes - i, 4); j += 4) { | ||
689 | memcpy(&data, buf + i + j, 4); | ||
690 | fspi_writel(f, data, base + FSPI_TFDR + j); | ||
691 | } | ||
692 | fspi_writel(f, FSPI_INTR_IPTXWE, base + FSPI_INTR); | ||
693 | } | ||
694 | } | ||
695 | |||
696 | static void nxp_fspi_read_rxfifo(struct nxp_fspi *f, | ||
697 | const struct spi_mem_op *op) | ||
698 | { | ||
699 | void __iomem *base = f->iobase; | ||
700 | int i, ret; | ||
701 | int len = op->data.nbytes; | ||
702 | u8 *buf = (u8 *) op->data.buf.in; | ||
703 | |||
704 | /* | ||
705 | * Default value of water mark level is 8 bytes, hence in single | ||
706 | * read request controller can read max 8 bytes of data. | ||
707 | */ | ||
708 | for (i = 0; i < ALIGN_DOWN(len, 8); i += 8) { | ||
709 | /* Wait for RXFIFO available */ | ||
710 | ret = fspi_readl_poll_tout(f, f->iobase + FSPI_INTR, | ||
711 | FSPI_INTR_IPRXWA, 0, | ||
712 | POLL_TOUT, true); | ||
713 | WARN_ON(ret); | ||
714 | |||
715 | *(u32 *)(buf + i) = fspi_readl(f, base + FSPI_RFDR); | ||
716 | *(u32 *)(buf + i + 4) = fspi_readl(f, base + FSPI_RFDR + 4); | ||
717 | /* move the FIFO pointer */ | ||
718 | fspi_writel(f, FSPI_INTR_IPRXWA, base + FSPI_INTR); | ||
719 | } | ||
720 | |||
721 | if (i < len) { | ||
722 | u32 tmp; | ||
723 | int size, j; | ||
724 | |||
725 | buf = op->data.buf.in + i; | ||
726 | /* Wait for RXFIFO available */ | ||
727 | ret = fspi_readl_poll_tout(f, f->iobase + FSPI_INTR, | ||
728 | FSPI_INTR_IPRXWA, 0, | ||
729 | POLL_TOUT, true); | ||
730 | WARN_ON(ret); | ||
731 | |||
732 | len = op->data.nbytes - i; | ||
733 | for (j = 0; j < op->data.nbytes - i; j += 4) { | ||
734 | tmp = fspi_readl(f, base + FSPI_RFDR + j); | ||
735 | size = min(len, 4); | ||
736 | memcpy(buf + j, &tmp, size); | ||
737 | len -= size; | ||
738 | } | ||
739 | } | ||
740 | |||
741 | /* invalid the RXFIFO */ | ||
742 | fspi_writel(f, FSPI_IPRXFCR_CLR, base + FSPI_IPRXFCR); | ||
743 | /* move the FIFO pointer */ | ||
744 | fspi_writel(f, FSPI_INTR_IPRXWA, base + FSPI_INTR); | ||
745 | } | ||
746 | |||
747 | static int nxp_fspi_do_op(struct nxp_fspi *f, const struct spi_mem_op *op) | ||
748 | { | ||
749 | void __iomem *base = f->iobase; | ||
750 | int seqnum = 0; | ||
751 | int err = 0; | ||
752 | u32 reg; | ||
753 | |||
754 | reg = fspi_readl(f, base + FSPI_IPRXFCR); | ||
755 | /* invalid RXFIFO first */ | ||
756 | reg &= ~FSPI_IPRXFCR_DMA_EN; | ||
757 | reg = reg | FSPI_IPRXFCR_CLR; | ||
758 | fspi_writel(f, reg, base + FSPI_IPRXFCR); | ||
759 | |||
760 | init_completion(&f->c); | ||
761 | |||
762 | fspi_writel(f, op->addr.val, base + FSPI_IPCR0); | ||
763 | /* | ||
764 | * Always start the sequence at the same index since we update | ||
765 | * the LUT at each exec_op() call. And also specify the DATA | ||
766 | * length, since it's has not been specified in the LUT. | ||
767 | */ | ||
768 | fspi_writel(f, op->data.nbytes | | ||
769 | (SEQID_LUT << FSPI_IPCR1_SEQID_SHIFT) | | ||
770 | (seqnum << FSPI_IPCR1_SEQNUM_SHIFT), | ||
771 | base + FSPI_IPCR1); | ||
772 | |||
773 | /* Trigger the LUT now. */ | ||
774 | fspi_writel(f, FSPI_IPCMD_TRG, base + FSPI_IPCMD); | ||
775 | |||
776 | /* Wait for the interrupt. */ | ||
777 | if (!wait_for_completion_timeout(&f->c, msecs_to_jiffies(1000))) | ||
778 | err = -ETIMEDOUT; | ||
779 | |||
780 | /* Invoke IP data read, if request is of data read. */ | ||
781 | if (!err && op->data.nbytes && op->data.dir == SPI_MEM_DATA_IN) | ||
782 | nxp_fspi_read_rxfifo(f, op); | ||
783 | |||
784 | return err; | ||
785 | } | ||
786 | |||
787 | static int nxp_fspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) | ||
788 | { | ||
789 | struct nxp_fspi *f = spi_controller_get_devdata(mem->spi->master); | ||
790 | int err = 0; | ||
791 | |||
792 | mutex_lock(&f->lock); | ||
793 | |||
794 | /* Wait for controller being ready. */ | ||
795 | err = fspi_readl_poll_tout(f, f->iobase + FSPI_STS0, | ||
796 | FSPI_STS0_ARB_IDLE, 1, POLL_TOUT, true); | ||
797 | WARN_ON(err); | ||
798 | |||
799 | nxp_fspi_select_mem(f, mem->spi); | ||
800 | |||
801 | nxp_fspi_prepare_lut(f, op); | ||
802 | /* | ||
803 | * If we have large chunks of data, we read them through the AHB bus | ||
804 | * by accessing the mapped memory. In all other cases we use | ||
805 | * IP commands to access the flash. | ||
806 | */ | ||
807 | if (op->data.nbytes > (f->devtype_data->rxfifo - 4) && | ||
808 | op->data.dir == SPI_MEM_DATA_IN) { | ||
809 | nxp_fspi_read_ahb(f, op); | ||
810 | } else { | ||
811 | if (op->data.nbytes && op->data.dir == SPI_MEM_DATA_OUT) | ||
812 | nxp_fspi_fill_txfifo(f, op); | ||
813 | |||
814 | err = nxp_fspi_do_op(f, op); | ||
815 | } | ||
816 | |||
817 | /* Invalidate the data in the AHB buffer. */ | ||
818 | nxp_fspi_invalid(f); | ||
819 | |||
820 | mutex_unlock(&f->lock); | ||
821 | |||
822 | return err; | ||
823 | } | ||
824 | |||
825 | static int nxp_fspi_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op) | ||
826 | { | ||
827 | struct nxp_fspi *f = spi_controller_get_devdata(mem->spi->master); | ||
828 | |||
829 | if (op->data.dir == SPI_MEM_DATA_OUT) { | ||
830 | if (op->data.nbytes > f->devtype_data->txfifo) | ||
831 | op->data.nbytes = f->devtype_data->txfifo; | ||
832 | } else { | ||
833 | if (op->data.nbytes > f->devtype_data->ahb_buf_size) | ||
834 | op->data.nbytes = f->devtype_data->ahb_buf_size; | ||
835 | else if (op->data.nbytes > (f->devtype_data->rxfifo - 4)) | ||
836 | op->data.nbytes = ALIGN_DOWN(op->data.nbytes, 8); | ||
837 | } | ||
838 | |||
839 | return 0; | ||
840 | } | ||
841 | |||
842 | static int nxp_fspi_default_setup(struct nxp_fspi *f) | ||
843 | { | ||
844 | void __iomem *base = f->iobase; | ||
845 | int ret, i; | ||
846 | u32 reg; | ||
847 | |||
848 | /* disable and unprepare clock to avoid glitch pass to controller */ | ||
849 | nxp_fspi_clk_disable_unprep(f); | ||
850 | |||
851 | /* the default frequency, we will change it later if necessary. */ | ||
852 | ret = clk_set_rate(f->clk, 20000000); | ||
853 | if (ret) | ||
854 | return ret; | ||
855 | |||
856 | ret = nxp_fspi_clk_prep_enable(f); | ||
857 | if (ret) | ||
858 | return ret; | ||
859 | |||
860 | /* Reset the module */ | ||
861 | /* w1c register, wait unit clear */ | ||
862 | ret = fspi_readl_poll_tout(f, f->iobase + FSPI_MCR0, | ||
863 | FSPI_MCR0_SWRST, 0, POLL_TOUT, false); | ||
864 | WARN_ON(ret); | ||
865 | |||
866 | /* Disable the module */ | ||
867 | fspi_writel(f, FSPI_MCR0_MDIS, base + FSPI_MCR0); | ||
868 | |||
869 | /* Reset the DLL register to default value */ | ||
870 | fspi_writel(f, FSPI_DLLACR_OVRDEN, base + FSPI_DLLACR); | ||
871 | fspi_writel(f, FSPI_DLLBCR_OVRDEN, base + FSPI_DLLBCR); | ||
872 | |||
873 | /* enable module */ | ||
874 | fspi_writel(f, FSPI_MCR0_AHB_TIMEOUT(0xFF) | FSPI_MCR0_IP_TIMEOUT(0xFF), | ||
875 | base + FSPI_MCR0); | ||
876 | |||
877 | /* | ||
878 | * Disable same device enable bit and configure all slave devices | ||
879 | * independently. | ||
880 | */ | ||
881 | reg = fspi_readl(f, f->iobase + FSPI_MCR2); | ||
882 | reg = reg & ~(FSPI_MCR2_SAMEDEVICEEN); | ||
883 | fspi_writel(f, reg, base + FSPI_MCR2); | ||
884 | |||
885 | /* AHB configuration for access buffer 0~7. */ | ||
886 | for (i = 0; i < 7; i++) | ||
887 | fspi_writel(f, 0, base + FSPI_AHBRX_BUF0CR0 + 4 * i); | ||
888 | |||
889 | /* | ||
890 | * Set ADATSZ with the maximum AHB buffer size to improve the read | ||
891 | * performance. | ||
892 | */ | ||
893 | fspi_writel(f, (f->devtype_data->ahb_buf_size / 8 | | ||
894 | FSPI_AHBRXBUF0CR7_PREF), base + FSPI_AHBRX_BUF7CR0); | ||
895 | |||
896 | /* prefetch and no start address alignment limitation */ | ||
897 | fspi_writel(f, FSPI_AHBCR_PREF_EN | FSPI_AHBCR_RDADDROPT, | ||
898 | base + FSPI_AHBCR); | ||
899 | |||
900 | /* AHB Read - Set lut sequence ID for all CS. */ | ||
901 | fspi_writel(f, SEQID_LUT, base + FSPI_FLSHA1CR2); | ||
902 | fspi_writel(f, SEQID_LUT, base + FSPI_FLSHA2CR2); | ||
903 | fspi_writel(f, SEQID_LUT, base + FSPI_FLSHB1CR2); | ||
904 | fspi_writel(f, SEQID_LUT, base + FSPI_FLSHB2CR2); | ||
905 | |||
906 | f->selected = -1; | ||
907 | |||
908 | /* enable the interrupt */ | ||
909 | fspi_writel(f, FSPI_INTEN_IPCMDDONE, base + FSPI_INTEN); | ||
910 | |||
911 | return 0; | ||
912 | } | ||
913 | |||
914 | static const char *nxp_fspi_get_name(struct spi_mem *mem) | ||
915 | { | ||
916 | struct nxp_fspi *f = spi_controller_get_devdata(mem->spi->master); | ||
917 | struct device *dev = &mem->spi->dev; | ||
918 | const char *name; | ||
919 | |||
920 | // Set custom name derived from the platform_device of the controller. | ||
921 | if (of_get_available_child_count(f->dev->of_node) == 1) | ||
922 | return dev_name(f->dev); | ||
923 | |||
924 | name = devm_kasprintf(dev, GFP_KERNEL, | ||
925 | "%s-%d", dev_name(f->dev), | ||
926 | mem->spi->chip_select); | ||
927 | |||
928 | if (!name) { | ||
929 | dev_err(dev, "failed to get memory for custom flash name\n"); | ||
930 | return ERR_PTR(-ENOMEM); | ||
931 | } | ||
932 | |||
933 | return name; | ||
934 | } | ||
935 | |||
936 | static const struct spi_controller_mem_ops nxp_fspi_mem_ops = { | ||
937 | .adjust_op_size = nxp_fspi_adjust_op_size, | ||
938 | .supports_op = nxp_fspi_supports_op, | ||
939 | .exec_op = nxp_fspi_exec_op, | ||
940 | .get_name = nxp_fspi_get_name, | ||
941 | }; | ||
942 | |||
943 | static int nxp_fspi_probe(struct platform_device *pdev) | ||
944 | { | ||
945 | struct spi_controller *ctlr; | ||
946 | struct device *dev = &pdev->dev; | ||
947 | struct device_node *np = dev->of_node; | ||
948 | struct resource *res; | ||
949 | struct nxp_fspi *f; | ||
950 | int ret; | ||
951 | |||
952 | ctlr = spi_alloc_master(&pdev->dev, sizeof(*f)); | ||
953 | if (!ctlr) | ||
954 | return -ENOMEM; | ||
955 | |||
956 | ctlr->mode_bits = SPI_RX_DUAL | SPI_RX_QUAD | | ||
957 | SPI_TX_DUAL | SPI_TX_QUAD; | ||
958 | |||
959 | f = spi_controller_get_devdata(ctlr); | ||
960 | f->dev = dev; | ||
961 | f->devtype_data = of_device_get_match_data(dev); | ||
962 | if (!f->devtype_data) { | ||
963 | ret = -ENODEV; | ||
964 | goto err_put_ctrl; | ||
965 | } | ||
966 | |||
967 | platform_set_drvdata(pdev, f); | ||
968 | |||
969 | /* find the resources - configuration register address space */ | ||
970 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fspi_base"); | ||
971 | f->iobase = devm_ioremap_resource(dev, res); | ||
972 | if (IS_ERR(f->iobase)) { | ||
973 | ret = PTR_ERR(f->iobase); | ||
974 | goto err_put_ctrl; | ||
975 | } | ||
976 | |||
977 | /* find the resources - controller memory mapped space */ | ||
978 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fspi_mmap"); | ||
979 | f->ahb_addr = devm_ioremap_resource(dev, res); | ||
980 | if (IS_ERR(f->ahb_addr)) { | ||
981 | ret = PTR_ERR(f->ahb_addr); | ||
982 | goto err_put_ctrl; | ||
983 | } | ||
984 | |||
985 | /* assign memory mapped starting address and mapped size. */ | ||
986 | f->memmap_phy = res->start; | ||
987 | f->memmap_phy_size = resource_size(res); | ||
988 | |||
989 | /* find the clocks */ | ||
990 | f->clk_en = devm_clk_get(dev, "fspi_en"); | ||
991 | if (IS_ERR(f->clk_en)) { | ||
992 | ret = PTR_ERR(f->clk_en); | ||
993 | goto err_put_ctrl; | ||
994 | } | ||
995 | |||
996 | f->clk = devm_clk_get(dev, "fspi"); | ||
997 | if (IS_ERR(f->clk)) { | ||
998 | ret = PTR_ERR(f->clk); | ||
999 | goto err_put_ctrl; | ||
1000 | } | ||
1001 | |||
1002 | ret = nxp_fspi_clk_prep_enable(f); | ||
1003 | if (ret) { | ||
1004 | dev_err(dev, "can not enable the clock\n"); | ||
1005 | goto err_put_ctrl; | ||
1006 | } | ||
1007 | |||
1008 | /* find the irq */ | ||
1009 | ret = platform_get_irq(pdev, 0); | ||
1010 | if (ret < 0) { | ||
1011 | dev_err(dev, "failed to get the irq: %d\n", ret); | ||
1012 | goto err_disable_clk; | ||
1013 | } | ||
1014 | |||
1015 | ret = devm_request_irq(dev, ret, | ||
1016 | nxp_fspi_irq_handler, 0, pdev->name, f); | ||
1017 | if (ret) { | ||
1018 | dev_err(dev, "failed to request irq: %d\n", ret); | ||
1019 | goto err_disable_clk; | ||
1020 | } | ||
1021 | |||
1022 | mutex_init(&f->lock); | ||
1023 | |||
1024 | ctlr->bus_num = -1; | ||
1025 | ctlr->num_chipselect = NXP_FSPI_MAX_CHIPSELECT; | ||
1026 | ctlr->mem_ops = &nxp_fspi_mem_ops; | ||
1027 | |||
1028 | nxp_fspi_default_setup(f); | ||
1029 | |||
1030 | ctlr->dev.of_node = np; | ||
1031 | |||
1032 | ret = spi_register_controller(ctlr); | ||
1033 | if (ret) | ||
1034 | goto err_destroy_mutex; | ||
1035 | |||
1036 | return 0; | ||
1037 | |||
1038 | err_destroy_mutex: | ||
1039 | mutex_destroy(&f->lock); | ||
1040 | |||
1041 | err_disable_clk: | ||
1042 | nxp_fspi_clk_disable_unprep(f); | ||
1043 | |||
1044 | err_put_ctrl: | ||
1045 | spi_controller_put(ctlr); | ||
1046 | |||
1047 | dev_err(dev, "NXP FSPI probe failed\n"); | ||
1048 | return ret; | ||
1049 | } | ||
1050 | |||
1051 | static int nxp_fspi_remove(struct platform_device *pdev) | ||
1052 | { | ||
1053 | struct nxp_fspi *f = platform_get_drvdata(pdev); | ||
1054 | |||
1055 | /* disable the hardware */ | ||
1056 | fspi_writel(f, FSPI_MCR0_MDIS, f->iobase + FSPI_MCR0); | ||
1057 | |||
1058 | nxp_fspi_clk_disable_unprep(f); | ||
1059 | |||
1060 | mutex_destroy(&f->lock); | ||
1061 | |||
1062 | return 0; | ||
1063 | } | ||
1064 | |||
1065 | static int nxp_fspi_suspend(struct device *dev) | ||
1066 | { | ||
1067 | return 0; | ||
1068 | } | ||
1069 | |||
1070 | static int nxp_fspi_resume(struct device *dev) | ||
1071 | { | ||
1072 | struct nxp_fspi *f = dev_get_drvdata(dev); | ||
1073 | |||
1074 | nxp_fspi_default_setup(f); | ||
1075 | |||
1076 | return 0; | ||
1077 | } | ||
1078 | |||
1079 | static const struct of_device_id nxp_fspi_dt_ids[] = { | ||
1080 | { .compatible = "nxp,lx2160a-fspi", .data = (void *)&lx2160a_data, }, | ||
1081 | { /* sentinel */ } | ||
1082 | }; | ||
1083 | MODULE_DEVICE_TABLE(of, nxp_fspi_dt_ids); | ||
1084 | |||
1085 | static const struct dev_pm_ops nxp_fspi_pm_ops = { | ||
1086 | .suspend = nxp_fspi_suspend, | ||
1087 | .resume = nxp_fspi_resume, | ||
1088 | }; | ||
1089 | |||
1090 | static struct platform_driver nxp_fspi_driver = { | ||
1091 | .driver = { | ||
1092 | .name = "nxp-fspi", | ||
1093 | .of_match_table = nxp_fspi_dt_ids, | ||
1094 | .pm = &nxp_fspi_pm_ops, | ||
1095 | }, | ||
1096 | .probe = nxp_fspi_probe, | ||
1097 | .remove = nxp_fspi_remove, | ||
1098 | }; | ||
1099 | module_platform_driver(nxp_fspi_driver); | ||
1100 | |||
1101 | MODULE_DESCRIPTION("NXP FSPI Controller Driver"); | ||
1102 | MODULE_AUTHOR("NXP Semiconductor"); | ||
1103 | MODULE_AUTHOR("Yogesh Narayan Gaur <yogeshnarayan.gaur@nxp.com>"); | ||
1104 | MODULE_AUTHOR("Boris Brezillion <bbrezillon@kernel.org>"); | ||
1105 | MODULE_AUTHOR("Frieder Schrempf <frieder.schrempf@kontron.de>"); | ||