]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/mtd/spi/sf_ops.c
karo: fdt: fix panel-dpi support
[karo-tx-uboot.git] / drivers / mtd / spi / sf_ops.c
1 /*
2  * SPI flash operations
3  *
4  * Copyright (C) 2008 Atmel Corporation
5  * Copyright (C) 2010 Reinhard Meyer, EMK Elektronik
6  * Copyright (C) 2013 Jagannadha Sutradharudu Teki, Xilinx Inc.
7  *
8  * SPDX-License-Identifier:     GPL-2.0+
9  */
10
11 #include <common.h>
12 #include <errno.h>
13 #include <malloc.h>
14 #include <spi.h>
15 #include <spi_flash.h>
16 #include <watchdog.h>
17 #include <linux/compiler.h>
18
19 #include "sf_internal.h"
20
21 static void spi_flash_addr(u32 addr, u8 *cmd)
22 {
23         /* cmd[0] is actual command */
24         cmd[1] = addr >> 16;
25         cmd[2] = addr >> 8;
26         cmd[3] = addr >> 0;
27 }
28
29 int spi_flash_cmd_read_status(struct spi_flash *flash, u8 *rs)
30 {
31         int ret;
32         u8 cmd;
33
34         cmd = CMD_READ_STATUS;
35         ret = spi_flash_read_common(flash, &cmd, 1, rs, 1);
36         if (ret < 0) {
37                 debug("SF: fail to read status register\n");
38                 return ret;
39         }
40
41         return 0;
42 }
43
44 int spi_flash_cmd_write_status(struct spi_flash *flash, u8 ws)
45 {
46         u8 cmd;
47         int ret;
48
49         cmd = CMD_WRITE_STATUS;
50         ret = spi_flash_write_common(flash, &cmd, 1, &ws, 1);
51         if (ret < 0) {
52                 debug("SF: fail to write status register\n");
53                 return ret;
54         }
55
56         return 0;
57 }
58
59 #if defined(CONFIG_SPI_FLASH_SPANSION) || defined(CONFIG_SPI_FLASH_WINBOND)
60 int spi_flash_cmd_read_config(struct spi_flash *flash, u8 *rc)
61 {
62         int ret;
63         u8 cmd;
64
65         cmd = CMD_READ_CONFIG;
66         ret = spi_flash_read_common(flash, &cmd, 1, rc, 1);
67         if (ret < 0) {
68                 debug("SF: fail to read config register\n");
69                 return ret;
70         }
71
72         return 0;
73 }
74
75 int spi_flash_cmd_write_config(struct spi_flash *flash, u8 wc)
76 {
77         u8 data[2];
78         u8 cmd;
79         int ret;
80
81         ret = spi_flash_cmd_read_status(flash, &data[0]);
82         if (ret < 0)
83                 return ret;
84
85         cmd = CMD_WRITE_STATUS;
86         data[1] = wc;
87         ret = spi_flash_write_common(flash, &cmd, 1, &data, 2);
88         if (ret) {
89                 debug("SF: fail to write config register\n");
90                 return ret;
91         }
92
93         return 0;
94 }
95 #endif
96
97 #ifdef CONFIG_SPI_FLASH_BAR
98 static int spi_flash_cmd_bankaddr_write(struct spi_flash *flash, u8 bank_sel)
99 {
100         u8 cmd;
101         int ret;
102
103         if (flash->bank_curr == bank_sel) {
104                 debug("SF: not require to enable bank%d\n", bank_sel);
105                 return 0;
106         }
107
108         cmd = flash->bank_write_cmd;
109         ret = spi_flash_write_common(flash, &cmd, 1, &bank_sel, 1);
110         if (ret < 0) {
111                 debug("SF: fail to write bank register\n");
112                 return ret;
113         }
114         flash->bank_curr = bank_sel;
115
116         return 0;
117 }
118
119 static int spi_flash_bank(struct spi_flash *flash, u32 offset)
120 {
121         u8 bank_sel;
122         int ret;
123
124         bank_sel = offset / (SPI_FLASH_16MB_BOUN << flash->shift);
125
126         ret = spi_flash_cmd_bankaddr_write(flash, bank_sel);
127         if (ret) {
128                 debug("SF: fail to set bank%d\n", bank_sel);
129                 return ret;
130         }
131
132         return bank_sel;
133 }
134 #endif
135
136 #ifdef CONFIG_SF_DUAL_FLASH
137 static void spi_flash_dual_flash(struct spi_flash *flash, u32 *addr)
138 {
139         switch (flash->dual_flash) {
140         case SF_DUAL_STACKED_FLASH:
141                 if (*addr >= (flash->size >> 1)) {
142                         *addr -= flash->size >> 1;
143                         flash->spi->flags |= SPI_XFER_U_PAGE;
144                 } else {
145                         flash->spi->flags &= ~SPI_XFER_U_PAGE;
146                 }
147                 break;
148         case SF_DUAL_PARALLEL_FLASH:
149                 *addr >>= flash->shift;
150                 break;
151         default:
152                 debug("SF: Unsupported dual_flash=%d\n", flash->dual_flash);
153                 break;
154         }
155 }
156 #endif
157
158 static int spi_flash_poll_status(struct spi_slave *spi, unsigned long timeout,
159                                  u8 cmd, u8 poll_bit)
160 {
161         unsigned long timebase;
162         unsigned long flags = SPI_XFER_BEGIN;
163         int ret;
164         u8 status;
165         u8 check_status = 0x0;
166
167         if (cmd == CMD_FLAG_STATUS)
168                 check_status = poll_bit;
169
170 #ifdef CONFIG_SF_DUAL_FLASH
171         if (spi->flags & SPI_XFER_U_PAGE)
172                 flags |= SPI_XFER_U_PAGE;
173 #endif
174         ret = spi_xfer(spi, 8, &cmd, NULL, flags);
175         if (ret) {
176                 debug("SF: fail to read %s status register\n",
177                       cmd == CMD_READ_STATUS ? "read" : "flag");
178                 return ret;
179         }
180
181         timebase = get_timer(0);
182         do {
183                 WATCHDOG_RESET();
184
185                 ret = spi_xfer(spi, 8, NULL, &status, 0);
186                 if (ret)
187                         return -1;
188
189                 if ((status & poll_bit) == check_status)
190                         break;
191
192         } while (get_timer(timebase) < timeout);
193
194         spi_xfer(spi, 0, NULL, NULL, SPI_XFER_END);
195
196         if ((status & poll_bit) == check_status)
197                 return 0;
198
199         /* Timed out */
200         debug("SF: time out!\n");
201         return -1;
202 }
203
204 int spi_flash_cmd_wait_ready(struct spi_flash *flash, unsigned long timeout)
205 {
206         struct spi_slave *spi = flash->spi;
207         int ret;
208         u8 poll_bit = STATUS_WIP;
209         u8 cmd = CMD_READ_STATUS;
210
211         ret = spi_flash_poll_status(spi, timeout, cmd, poll_bit);
212         if (ret < 0)
213                 return ret;
214
215         if (flash->poll_cmd == CMD_FLAG_STATUS) {
216                 poll_bit = STATUS_PEC;
217                 cmd = CMD_FLAG_STATUS;
218                 ret = spi_flash_poll_status(spi, timeout, cmd, poll_bit);
219                 if (ret < 0)
220                         return ret;
221         }
222
223         return 0;
224 }
225
226 int spi_flash_write_common(struct spi_flash *flash, const u8 *cmd,
227                 size_t cmd_len, const void *buf, size_t buf_len)
228 {
229         struct spi_slave *spi = flash->spi;
230         unsigned long timeout = SPI_FLASH_PROG_TIMEOUT;
231         int ret;
232
233         if (buf == NULL)
234                 timeout = SPI_FLASH_PAGE_ERASE_TIMEOUT;
235
236         ret = spi_claim_bus(flash->spi);
237         if (ret) {
238                 debug("SF: unable to claim SPI bus\n");
239                 return ret;
240         }
241
242         ret = spi_flash_cmd_write_enable(flash);
243         if (ret < 0) {
244                 debug("SF: enabling write failed\n");
245                 return ret;
246         }
247
248         ret = spi_flash_cmd_write(spi, cmd, cmd_len, buf, buf_len);
249         if (ret < 0) {
250                 debug("SF: write cmd failed\n");
251                 return ret;
252         }
253
254         ret = spi_flash_cmd_wait_ready(flash, timeout);
255         if (ret < 0) {
256                 debug("SF: write %s timed out\n",
257                       timeout == SPI_FLASH_PROG_TIMEOUT ?
258                         "program" : "page erase");
259                 return ret;
260         }
261
262         spi_release_bus(spi);
263
264         return ret;
265 }
266
267 int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len)
268 {
269         u32 erase_size, erase_addr;
270         u8 cmd[SPI_FLASH_CMD_LEN];
271         int ret = -1;
272
273         erase_size = flash->erase_size;
274         if (offset % erase_size || len % erase_size) {
275                 debug("SF: Erase offset/length not multiple of erase size\n");
276                 return -1;
277         }
278
279         cmd[0] = flash->erase_cmd;
280         while (len) {
281                 erase_addr = offset;
282
283 #ifdef CONFIG_SF_DUAL_FLASH
284                 if (flash->dual_flash > SF_SINGLE_FLASH)
285                         spi_flash_dual_flash(flash, &erase_addr);
286 #endif
287 #ifdef CONFIG_SPI_FLASH_BAR
288                 ret = spi_flash_bank(flash, erase_addr);
289                 if (ret < 0)
290                         return ret;
291 #endif
292                 spi_flash_addr(erase_addr, cmd);
293
294                 debug("SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1],
295                       cmd[2], cmd[3], erase_addr);
296
297                 ret = spi_flash_write_common(flash, cmd, sizeof(cmd), NULL, 0);
298                 if (ret < 0) {
299                         debug("SF: erase failed\n");
300                         break;
301                 }
302
303                 offset += erase_size;
304                 len -= erase_size;
305         }
306
307         return ret;
308 }
309
310 int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset,
311                 size_t len, const void *buf)
312 {
313         unsigned long byte_addr, page_size;
314         u32 write_addr;
315         size_t chunk_len, actual;
316         u8 cmd[SPI_FLASH_CMD_LEN];
317         int ret = -1;
318
319         page_size = flash->page_size;
320
321         cmd[0] = flash->write_cmd;
322         for (actual = 0; actual < len; actual += chunk_len) {
323                 write_addr = offset;
324
325 #ifdef CONFIG_SF_DUAL_FLASH
326                 if (flash->dual_flash > SF_SINGLE_FLASH)
327                         spi_flash_dual_flash(flash, &write_addr);
328 #endif
329 #ifdef CONFIG_SPI_FLASH_BAR
330                 ret = spi_flash_bank(flash, write_addr);
331                 if (ret < 0)
332                         return ret;
333 #endif
334                 byte_addr = offset % page_size;
335                 chunk_len = min(len - actual, (size_t)(page_size - byte_addr));
336
337                 if (flash->spi->max_write_size)
338                         chunk_len = min(chunk_len,
339                                         (size_t)flash->spi->max_write_size);
340
341                 spi_flash_addr(write_addr, cmd);
342
343                 debug("SF: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %zu\n",
344                       buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
345
346                 ret = spi_flash_write_common(flash, cmd, sizeof(cmd),
347                                         buf + actual, chunk_len);
348                 if (ret < 0) {
349                         debug("SF: write failed\n");
350                         break;
351                 }
352
353                 offset += chunk_len;
354         }
355
356         return ret;
357 }
358
359 int spi_flash_read_common(struct spi_flash *flash, const u8 *cmd,
360                 size_t cmd_len, void *data, size_t data_len)
361 {
362         struct spi_slave *spi = flash->spi;
363         int ret;
364
365         ret = spi_claim_bus(flash->spi);
366         if (ret) {
367                 debug("SF: unable to claim SPI bus\n");
368                 return ret;
369         }
370
371         ret = spi_flash_cmd_read(spi, cmd, cmd_len, data, data_len);
372         if (ret < 0) {
373                 debug("SF: read cmd failed\n");
374                 return ret;
375         }
376
377         spi_release_bus(spi);
378
379         return ret;
380 }
381
382 void __weak spi_flash_copy_mmap(void *data, void *offset, size_t len)
383 {
384         memcpy(data, offset, len);
385 }
386
387 int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset,
388                 size_t len, void *data)
389 {
390         u8 *cmd, cmdsz;
391         u32 remain_len, read_len, read_addr;
392         int bank_sel = 0;
393         int ret = -1;
394
395         /* Handle memory-mapped SPI */
396         if (flash->memory_map) {
397                 ret = spi_claim_bus(flash->spi);
398                 if (ret) {
399                         debug("SF: unable to claim SPI bus\n");
400                         return ret;
401                 }
402                 spi_xfer(flash->spi, 0, NULL, NULL, SPI_XFER_MMAP);
403                 spi_flash_copy_mmap(data, flash->memory_map + offset, len);
404                 spi_xfer(flash->spi, 0, NULL, NULL, SPI_XFER_MMAP_END);
405                 spi_release_bus(flash->spi);
406                 return 0;
407         }
408
409         cmdsz = SPI_FLASH_CMD_LEN + flash->dummy_byte;
410         cmd = calloc(1, cmdsz);
411         if (!cmd) {
412                 debug("SF: Failed to allocate cmd\n");
413                 return -ENOMEM;
414         }
415
416         cmd[0] = flash->read_cmd;
417         while (len) {
418                 read_addr = offset;
419
420 #ifdef CONFIG_SF_DUAL_FLASH
421                 if (flash->dual_flash > SF_SINGLE_FLASH)
422                         spi_flash_dual_flash(flash, &read_addr);
423 #endif
424 #ifdef CONFIG_SPI_FLASH_BAR
425                 bank_sel = spi_flash_bank(flash, read_addr);
426                 if (bank_sel < 0)
427                         return ret;
428 #endif
429                 remain_len = ((SPI_FLASH_16MB_BOUN << flash->shift) *
430                                 (bank_sel + 1)) - offset;
431                 if (len < remain_len)
432                         read_len = len;
433                 else
434                         read_len = remain_len;
435
436                 spi_flash_addr(read_addr, cmd);
437
438                 ret = spi_flash_read_common(flash, cmd, cmdsz, data, read_len);
439                 if (ret < 0) {
440                         debug("SF: read failed\n");
441                         break;
442                 }
443
444                 offset += read_len;
445                 len -= read_len;
446                 data += read_len;
447         }
448
449         free(cmd);
450         return ret;
451 }
452
453 #ifdef CONFIG_SPI_FLASH_SST
454 static int sst_byte_write(struct spi_flash *flash, u32 offset, const void *buf)
455 {
456         int ret;
457         u8 cmd[4] = {
458                 CMD_SST_BP,
459                 offset >> 16,
460                 offset >> 8,
461                 offset,
462         };
463
464         debug("BP[%02x]: 0x%p => cmd = { 0x%02x 0x%06x }\n",
465               spi_w8r8(flash->spi, CMD_READ_STATUS), buf, cmd[0], offset);
466
467         ret = spi_flash_cmd_write_enable(flash);
468         if (ret)
469                 return ret;
470
471         ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd), buf, 1);
472         if (ret)
473                 return ret;
474
475         return spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
476 }
477
478 int sst_write_wp(struct spi_flash *flash, u32 offset, size_t len,
479                 const void *buf)
480 {
481         size_t actual, cmd_len;
482         int ret;
483         u8 cmd[4];
484
485         ret = spi_claim_bus(flash->spi);
486         if (ret) {
487                 debug("SF: Unable to claim SPI bus\n");
488                 return ret;
489         }
490
491         /* If the data is not word aligned, write out leading single byte */
492         actual = offset % 2;
493         if (actual) {
494                 ret = sst_byte_write(flash, offset, buf);
495                 if (ret)
496                         goto done;
497         }
498         offset += actual;
499
500         ret = spi_flash_cmd_write_enable(flash);
501         if (ret)
502                 goto done;
503
504         cmd_len = 4;
505         cmd[0] = CMD_SST_AAI_WP;
506         cmd[1] = offset >> 16;
507         cmd[2] = offset >> 8;
508         cmd[3] = offset;
509
510         for (; actual < len - 1; actual += 2) {
511                 debug("WP[%02x]: 0x%p => cmd = { 0x%02x 0x%06x }\n",
512                       spi_w8r8(flash->spi, CMD_READ_STATUS), buf + actual,
513                       cmd[0], offset);
514
515                 ret = spi_flash_cmd_write(flash->spi, cmd, cmd_len,
516                                         buf + actual, 2);
517                 if (ret) {
518                         debug("SF: sst word program failed\n");
519                         break;
520                 }
521
522                 ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
523                 if (ret)
524                         break;
525
526                 cmd_len = 1;
527                 offset += 2;
528         }
529
530         if (!ret)
531                 ret = spi_flash_cmd_write_disable(flash);
532
533         /* If there is a single trailing byte, write it out */
534         if (!ret && actual != len)
535                 ret = sst_byte_write(flash, offset, buf + actual);
536
537  done:
538         debug("SF: sst: program %s %zu bytes @ 0x%zx\n",
539               ret ? "failure" : "success", len, offset - actual);
540
541         spi_release_bus(flash->spi);
542         return ret;
543 }
544
545 int sst_write_bp(struct spi_flash *flash, u32 offset, size_t len,
546                 const void *buf)
547 {
548         size_t actual;
549         int ret;
550
551         ret = spi_claim_bus(flash->spi);
552         if (ret) {
553                 debug("SF: Unable to claim SPI bus\n");
554                 return ret;
555         }
556
557         for (actual = 0; actual < len; actual++) {
558                 ret = sst_byte_write(flash, offset, buf + actual);
559                 if (ret) {
560                         debug("SF: sst byte program failed\n");
561                         break;
562                 }
563                 offset++;
564         }
565
566         if (!ret)
567                 ret = spi_flash_cmd_write_disable(flash);
568
569         debug("SF: sst: program %s %zu bytes @ 0x%zx\n",
570               ret ? "failure" : "success", len, offset - actual);
571
572         spi_release_bus(flash->spi);
573         return ret;
574 }
575 #endif