source: trunk/spi25.c

Last change on this file was 1672, checked in by stefanct, 3 weeks ago

Update spi_get_erasefn_from_opcode().

We forgot to add a few SPI erase functions to the helper function that is
used for SFDP. Also, sort the declarations in the header.

Signed-off-by: Stefan Tauner <stefan.tauner@…>
Acked-by: Stefan Tauner <stefan.tauner@…>

File size: 27.1 KB
Line 
1/*
2 * This file is part of the flashrom project.
3 *
4 * Copyright (C) 2007, 2008, 2009, 2010 Carl-Daniel Hailfinger
5 * Copyright (C) 2008 coresystems GmbH
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
19 */
20
21/*
22 * Contains the common SPI chip driver functions
23 */
24
25#include <string.h>
26#include "flash.h"
27#include "flashchips.h"
28#include "chipdrivers.h"
29#include "programmer.h"
30#include "spi.h"
31
32static int spi_rdid(struct flashctx *flash, unsigned char *readarr, int bytes)
33{
34        static const unsigned char cmd[JEDEC_RDID_OUTSIZE] = { JEDEC_RDID };
35        int ret;
36        int i;
37
38        ret = spi_send_command(flash, sizeof(cmd), bytes, cmd, readarr);
39        if (ret)
40                return ret;
41        msg_cspew("RDID returned");
42        for (i = 0; i < bytes; i++)
43                msg_cspew(" 0x%02x", readarr[i]);
44        msg_cspew(". ");
45        return 0;
46}
47
48static int spi_rems(struct flashctx *flash, unsigned char *readarr)
49{
50        unsigned char cmd[JEDEC_REMS_OUTSIZE] = { JEDEC_REMS, 0, 0, 0 };
51        uint32_t readaddr;
52        int ret;
53
54        ret = spi_send_command(flash, sizeof(cmd), JEDEC_REMS_INSIZE, cmd,
55                               readarr);
56        if (ret == SPI_INVALID_ADDRESS) {
57                /* Find the lowest even address allowed for reads. */
58                readaddr = (spi_get_valid_read_addr(flash) + 1) & ~1;
59                cmd[1] = (readaddr >> 16) & 0xff,
60                cmd[2] = (readaddr >> 8) & 0xff,
61                cmd[3] = (readaddr >> 0) & 0xff,
62                ret = spi_send_command(flash, sizeof(cmd), JEDEC_REMS_INSIZE,
63                                       cmd, readarr);
64        }
65        if (ret)
66                return ret;
67        msg_cspew("REMS returned 0x%02x 0x%02x. ", readarr[0], readarr[1]);
68        return 0;
69}
70
71static int spi_res(struct flashctx *flash, unsigned char *readarr, int bytes)
72{
73        unsigned char cmd[JEDEC_RES_OUTSIZE] = { JEDEC_RES, 0, 0, 0 };
74        uint32_t readaddr;
75        int ret;
76        int i;
77
78        ret = spi_send_command(flash, sizeof(cmd), bytes, cmd, readarr);
79        if (ret == SPI_INVALID_ADDRESS) {
80                /* Find the lowest even address allowed for reads. */
81                readaddr = (spi_get_valid_read_addr(flash) + 1) & ~1;
82                cmd[1] = (readaddr >> 16) & 0xff,
83                cmd[2] = (readaddr >> 8) & 0xff,
84                cmd[3] = (readaddr >> 0) & 0xff,
85                ret = spi_send_command(flash, sizeof(cmd), bytes, cmd, readarr);
86        }
87        if (ret)
88                return ret;
89        msg_cspew("RES returned");
90        for (i = 0; i < bytes; i++)
91                msg_cspew(" 0x%02x", readarr[i]);
92        msg_cspew(". ");
93        return 0;
94}
95
96int spi_write_enable(struct flashctx *flash)
97{
98        static const unsigned char cmd[JEDEC_WREN_OUTSIZE] = { JEDEC_WREN };
99        int result;
100
101        /* Send WREN (Write Enable) */
102        result = spi_send_command(flash, sizeof(cmd), 0, cmd, NULL);
103
104        if (result)
105                msg_cerr("%s failed\n", __func__);
106
107        return result;
108}
109
110int spi_write_disable(struct flashctx *flash)
111{
112        static const unsigned char cmd[JEDEC_WRDI_OUTSIZE] = { JEDEC_WRDI };
113
114        /* Send WRDI (Write Disable) */
115        return spi_send_command(flash, sizeof(cmd), 0, cmd, NULL);
116}
117
118static int probe_spi_rdid_generic(struct flashctx *flash, int bytes)
119{
120        const struct flashchip *chip = flash->chip;
121        unsigned char readarr[4];
122        uint32_t id1;
123        uint32_t id2;
124
125        if (spi_rdid(flash, readarr, bytes)) {
126                return 0;
127        }
128
129        if (!oddparity(readarr[0]))
130                msg_cdbg("RDID byte 0 parity violation. ");
131
132        /* Check if this is a continuation vendor ID.
133         * FIXME: Handle continuation device IDs.
134         */
135        if (readarr[0] == 0x7f) {
136                if (!oddparity(readarr[1]))
137                        msg_cdbg("RDID byte 1 parity violation. ");
138                id1 = (readarr[0] << 8) | readarr[1];
139                id2 = readarr[2];
140                if (bytes > 3) {
141                        id2 <<= 8;
142                        id2 |= readarr[3];
143                }
144        } else {
145                id1 = readarr[0];
146                id2 = (readarr[1] << 8) | readarr[2];
147        }
148
149        msg_cdbg("%s: id1 0x%02x, id2 0x%02x\n", __func__, id1, id2);
150
151        if (id1 == chip->manufacture_id && id2 == chip->model_id)
152                return 1;
153
154        /* Test if this is a pure vendor match. */
155        if (id1 == chip->manufacture_id && GENERIC_DEVICE_ID == chip->model_id)
156                return 1;
157
158        /* Test if there is any vendor ID. */
159        if (GENERIC_MANUF_ID == chip->manufacture_id && id1 != 0xff)
160                return 1;
161
162        return 0;
163}
164
165int probe_spi_rdid(struct flashctx *flash)
166{
167        return probe_spi_rdid_generic(flash, 3);
168}
169
170int probe_spi_rdid4(struct flashctx *flash)
171{
172        /* Some SPI controllers do not support commands with writecnt=1 and
173         * readcnt=4.
174         */
175        switch (flash->pgm->spi.type) {
176#if CONFIG_INTERNAL == 1
177#if defined(__i386__) || defined(__x86_64__)
178        case SPI_CONTROLLER_IT87XX:
179        case SPI_CONTROLLER_WBSIO:
180                msg_cinfo("4 byte RDID not supported on this SPI controller\n");
181                return 0;
182                break;
183#endif
184#endif
185        default:
186                return probe_spi_rdid_generic(flash, 4);
187        }
188
189        return 0;
190}
191
192int probe_spi_rems(struct flashctx *flash)
193{
194        const struct flashchip *chip = flash->chip;
195        unsigned char readarr[JEDEC_REMS_INSIZE];
196        uint32_t id1, id2;
197
198        if (spi_rems(flash, readarr)) {
199                return 0;
200        }
201
202        id1 = readarr[0];
203        id2 = readarr[1];
204
205        msg_cdbg("%s: id1 0x%x, id2 0x%x\n", __func__, id1, id2);
206
207        if (id1 == chip->manufacture_id && id2 == chip->model_id)
208                return 1;
209
210        /* Test if this is a pure vendor match. */
211        if (id1 == chip->manufacture_id && GENERIC_DEVICE_ID == chip->model_id)
212                return 1;
213
214        /* Test if there is any vendor ID. */
215        if (GENERIC_MANUF_ID == chip->manufacture_id && id1 != 0xff)
216                return 1;
217
218        return 0;
219}
220
221int probe_spi_res1(struct flashctx *flash)
222{
223        static const unsigned char allff[] = {0xff, 0xff, 0xff};
224        static const unsigned char all00[] = {0x00, 0x00, 0x00};
225        unsigned char readarr[3];
226        uint32_t id2;
227
228        /* We only want one-byte RES if RDID and REMS are unusable. */
229
230        /* Check if RDID is usable and does not return 0xff 0xff 0xff or
231         * 0x00 0x00 0x00. In that case, RES is pointless.
232         */
233        if (!spi_rdid(flash, readarr, 3) && memcmp(readarr, allff, 3) &&
234            memcmp(readarr, all00, 3)) {
235                msg_cdbg("Ignoring RES in favour of RDID.\n");
236                return 0;
237        }
238        /* Check if REMS is usable and does not return 0xff 0xff or
239         * 0x00 0x00. In that case, RES is pointless.
240         */
241        if (!spi_rems(flash, readarr) &&
242            memcmp(readarr, allff, JEDEC_REMS_INSIZE) &&
243            memcmp(readarr, all00, JEDEC_REMS_INSIZE)) {
244                msg_cdbg("Ignoring RES in favour of REMS.\n");
245                return 0;
246        }
247
248        if (spi_res(flash, readarr, 1)) {
249                return 0;
250        }
251
252        id2 = readarr[0];
253
254        msg_cdbg("%s: id 0x%x\n", __func__, id2);
255
256        if (id2 != flash->chip->model_id)
257                return 0;
258
259        return 1;
260}
261
262int probe_spi_res2(struct flashctx *flash)
263{
264        unsigned char readarr[2];
265        uint32_t id1, id2;
266
267        if (spi_res(flash, readarr, 2)) {
268                return 0;
269        }
270
271        id1 = readarr[0];
272        id2 = readarr[1];
273
274        msg_cdbg("%s: id1 0x%x, id2 0x%x\n", __func__, id1, id2);
275
276        if (id1 != flash->chip->manufacture_id || id2 != flash->chip->model_id)
277                return 0;
278
279        return 1;
280}
281
282int probe_spi_res3(struct flashctx *flash)
283{
284        unsigned char readarr[3];
285        uint32_t id1, id2;
286
287        if (spi_res(flash, readarr, 3)) {
288                return 0;
289        }
290
291        id1 = (readarr[0] << 8) | readarr[1];
292        id2 = readarr[2];
293
294        msg_cdbg("%s: id1 0x%x, id2 0x%x\n", __func__, id1, id2);
295
296        if (id1 != flash->chip->manufacture_id || id2 != flash->chip->model_id)
297                return 0;
298
299        return 1;
300}
301
302/* Only used for some Atmel chips. */
303int probe_spi_at25f(struct flashctx *flash)
304{
305        static const unsigned char cmd[AT25F_RDID_OUTSIZE] = { AT25F_RDID };
306        unsigned char readarr[AT25F_RDID_INSIZE];
307        uint32_t id1;
308        uint32_t id2;
309
310        if (spi_send_command(flash, sizeof(cmd), sizeof(readarr), cmd, readarr))
311                return 0;
312
313        id1 = readarr[0];
314        id2 = readarr[1];
315
316        msg_cdbg("%s: id1 0x%02x, id2 0x%02x\n", __func__, id1, id2);
317
318        if (id1 == flash->chip->manufacture_id && id2 == flash->chip->model_id)
319                return 1;
320
321        return 0;
322}
323
324int spi_chip_erase_60(struct flashctx *flash)
325{
326        int result;
327        struct spi_command cmds[] = {
328        {
329                .writecnt       = JEDEC_WREN_OUTSIZE,
330                .writearr       = (const unsigned char[]){ JEDEC_WREN },
331                .readcnt        = 0,
332                .readarr        = NULL,
333        }, {
334                .writecnt       = JEDEC_CE_60_OUTSIZE,
335                .writearr       = (const unsigned char[]){ JEDEC_CE_60 },
336                .readcnt        = 0,
337                .readarr        = NULL,
338        }, {
339                .writecnt       = 0,
340                .writearr       = NULL,
341                .readcnt        = 0,
342                .readarr        = NULL,
343        }};
344       
345        result = spi_send_multicommand(flash, cmds);
346        if (result) {
347                msg_cerr("%s failed during command execution\n",
348                        __func__);
349                return result;
350        }
351        /* Wait until the Write-In-Progress bit is cleared.
352         * This usually takes 1-85 s, so wait in 1 s steps.
353         */
354        /* FIXME: We assume spi_read_status_register will never fail. */
355        while (spi_read_status_register(flash) & SPI_SR_WIP)
356                programmer_delay(1000 * 1000);
357        /* FIXME: Check the status register for errors. */
358        return 0;
359}
360
361int spi_chip_erase_62(struct flashctx *flash)
362{
363        int result;
364        struct spi_command cmds[] = {
365        {
366                .writecnt       = JEDEC_WREN_OUTSIZE,
367                .writearr       = (const unsigned char[]){ JEDEC_WREN },
368                .readcnt        = 0,
369                .readarr        = NULL,
370        }, {
371                .writecnt       = JEDEC_CE_62_OUTSIZE,
372                .writearr       = (const unsigned char[]){ JEDEC_CE_62 },
373                .readcnt        = 0,
374                .readarr        = NULL,
375        }, {
376                .writecnt       = 0,
377                .writearr       = NULL,
378                .readcnt        = 0,
379                .readarr        = NULL,
380        }};
381       
382        result = spi_send_multicommand(flash, cmds);
383        if (result) {
384                msg_cerr("%s failed during command execution\n",
385                        __func__);
386                return result;
387        }
388        /* Wait until the Write-In-Progress bit is cleared.
389         * This usually takes 2-5 s, so wait in 100 ms steps.
390         */
391        /* FIXME: We assume spi_read_status_register will never fail. */
392        while (spi_read_status_register(flash) & SPI_SR_WIP)
393                programmer_delay(100 * 1000);
394        /* FIXME: Check the status register for errors. */
395        return 0;
396}
397
398int spi_chip_erase_c7(struct flashctx *flash)
399{
400        int result;
401        struct spi_command cmds[] = {
402        {
403                .writecnt       = JEDEC_WREN_OUTSIZE,
404                .writearr       = (const unsigned char[]){ JEDEC_WREN },
405                .readcnt        = 0,
406                .readarr        = NULL,
407        }, {
408                .writecnt       = JEDEC_CE_C7_OUTSIZE,
409                .writearr       = (const unsigned char[]){ JEDEC_CE_C7 },
410                .readcnt        = 0,
411                .readarr        = NULL,
412        }, {
413                .writecnt       = 0,
414                .writearr       = NULL,
415                .readcnt        = 0,
416                .readarr        = NULL,
417        }};
418
419        result = spi_send_multicommand(flash, cmds);
420        if (result) {
421                msg_cerr("%s failed during command execution\n", __func__);
422                return result;
423        }
424        /* Wait until the Write-In-Progress bit is cleared.
425         * This usually takes 1-85 s, so wait in 1 s steps.
426         */
427        /* FIXME: We assume spi_read_status_register will never fail. */
428        while (spi_read_status_register(flash) & SPI_SR_WIP)
429                programmer_delay(1000 * 1000);
430        /* FIXME: Check the status register for errors. */
431        return 0;
432}
433
434int spi_block_erase_52(struct flashctx *flash, unsigned int addr,
435                       unsigned int blocklen)
436{
437        int result;
438        struct spi_command cmds[] = {
439        {
440                .writecnt       = JEDEC_WREN_OUTSIZE,
441                .writearr       = (const unsigned char[]){ JEDEC_WREN },
442                .readcnt        = 0,
443                .readarr        = NULL,
444        }, {
445                .writecnt       = JEDEC_BE_52_OUTSIZE,
446                .writearr       = (const unsigned char[]){
447                                        JEDEC_BE_52,
448                                        (addr >> 16) & 0xff,
449                                        (addr >> 8) & 0xff,
450                                        (addr & 0xff)
451                                },
452                .readcnt        = 0,
453                .readarr        = NULL,
454        }, {
455                .writecnt       = 0,
456                .writearr       = NULL,
457                .readcnt        = 0,
458                .readarr        = NULL,
459        }};
460
461        result = spi_send_multicommand(flash, cmds);
462        if (result) {
463                msg_cerr("%s failed during command execution at address 0x%x\n",
464                        __func__, addr);
465                return result;
466        }
467        /* Wait until the Write-In-Progress bit is cleared.
468         * This usually takes 100-4000 ms, so wait in 100 ms steps.
469         */
470        while (spi_read_status_register(flash) & SPI_SR_WIP)
471                programmer_delay(100 * 1000);
472        /* FIXME: Check the status register for errors. */
473        return 0;
474}
475
476/* Block size is usually
477 * 64k for Macronix
478 * 32k for SST
479 * 4-32k non-uniform for EON
480 */
481int spi_block_erase_d8(struct flashctx *flash, unsigned int addr,
482                       unsigned int blocklen)
483{
484        int result;
485        struct spi_command cmds[] = {
486        {
487                .writecnt       = JEDEC_WREN_OUTSIZE,
488                .writearr       = (const unsigned char[]){ JEDEC_WREN },
489                .readcnt        = 0,
490                .readarr        = NULL,
491        }, {
492                .writecnt       = JEDEC_BE_D8_OUTSIZE,
493                .writearr       = (const unsigned char[]){
494                                        JEDEC_BE_D8,
495                                        (addr >> 16) & 0xff,
496                                        (addr >> 8) & 0xff,
497                                        (addr & 0xff)
498                                },
499                .readcnt        = 0,
500                .readarr        = NULL,
501        }, {
502                .writecnt       = 0,
503                .writearr       = NULL,
504                .readcnt        = 0,
505                .readarr        = NULL,
506        }};
507
508        result = spi_send_multicommand(flash, cmds);
509        if (result) {
510                msg_cerr("%s failed during command execution at address 0x%x\n",
511                        __func__, addr);
512                return result;
513        }
514        /* Wait until the Write-In-Progress bit is cleared.
515         * This usually takes 100-4000 ms, so wait in 100 ms steps.
516         */
517        while (spi_read_status_register(flash) & SPI_SR_WIP)
518                programmer_delay(100 * 1000);
519        /* FIXME: Check the status register for errors. */
520        return 0;
521}
522
523/* Block size is usually
524 * 4k for PMC
525 */
526int spi_block_erase_d7(struct flashctx *flash, unsigned int addr,
527                       unsigned int blocklen)
528{
529        int result;
530        struct spi_command cmds[] = {
531        {
532                .writecnt       = JEDEC_WREN_OUTSIZE,
533                .writearr       = (const unsigned char[]){ JEDEC_WREN },
534                .readcnt        = 0,
535                .readarr        = NULL,
536        }, {
537                .writecnt       = JEDEC_BE_D7_OUTSIZE,
538                .writearr       = (const unsigned char[]){
539                                        JEDEC_BE_D7,
540                                        (addr >> 16) & 0xff,
541                                        (addr >> 8) & 0xff,
542                                        (addr & 0xff)
543                                },
544                .readcnt        = 0,
545                .readarr        = NULL,
546        }, {
547                .writecnt       = 0,
548                .writearr       = NULL,
549                .readcnt        = 0,
550                .readarr        = NULL,
551        }};
552
553        result = spi_send_multicommand(flash, cmds);
554        if (result) {
555                msg_cerr("%s failed during command execution at address 0x%x\n",
556                        __func__, addr);
557                return result;
558        }
559        /* Wait until the Write-In-Progress bit is cleared.
560         * This usually takes 100-4000 ms, so wait in 100 ms steps.
561         */
562        while (spi_read_status_register(flash) & SPI_SR_WIP)
563                programmer_delay(100 * 1000);
564        /* FIXME: Check the status register for errors. */
565        return 0;
566}
567
568/* Sector size is usually 4k, though Macronix eliteflash has 64k */
569int spi_block_erase_20(struct flashctx *flash, unsigned int addr,
570                       unsigned int blocklen)
571{
572        int result;
573        struct spi_command cmds[] = {
574        {
575                .writecnt       = JEDEC_WREN_OUTSIZE,
576                .writearr       = (const unsigned char[]){ JEDEC_WREN },
577                .readcnt        = 0,
578                .readarr        = NULL,
579        }, {
580                .writecnt       = JEDEC_SE_OUTSIZE,
581                .writearr       = (const unsigned char[]){
582                                        JEDEC_SE,
583                                        (addr >> 16) & 0xff,
584                                        (addr >> 8) & 0xff,
585                                        (addr & 0xff)
586                                },
587                .readcnt        = 0,
588                .readarr        = NULL,
589        }, {
590                .writecnt       = 0,
591                .writearr       = NULL,
592                .readcnt        = 0,
593                .readarr        = NULL,
594        }};
595
596        result = spi_send_multicommand(flash, cmds);
597        if (result) {
598                msg_cerr("%s failed during command execution at address 0x%x\n",
599                        __func__, addr);
600                return result;
601        }
602        /* Wait until the Write-In-Progress bit is cleared.
603         * This usually takes 15-800 ms, so wait in 10 ms steps.
604         */
605        while (spi_read_status_register(flash) & SPI_SR_WIP)
606                programmer_delay(10 * 1000);
607        /* FIXME: Check the status register for errors. */
608        return 0;
609}
610
611int spi_block_erase_50(struct flashctx *flash, unsigned int addr, unsigned int blocklen)
612{
613        int result;
614        struct spi_command cmds[] = {
615        {
616/*              .writecnt       = JEDEC_WREN_OUTSIZE,
617                .writearr       = (const unsigned char[]){ JEDEC_WREN },
618                .readcnt        = 0,
619                .readarr        = NULL,
620        }, { */
621                .writecnt       = JEDEC_BE_50_OUTSIZE,
622                .writearr       = (const unsigned char[]){
623                                        JEDEC_BE_50,
624                                        (addr >> 16) & 0xff,
625                                        (addr >> 8) & 0xff,
626                                        (addr & 0xff)
627                                },
628                .readcnt        = 0,
629                .readarr        = NULL,
630        }, {
631                .writecnt       = 0,
632                .writearr       = NULL,
633                .readcnt        = 0,
634                .readarr        = NULL,
635        }};
636
637        result = spi_send_multicommand(flash, cmds);
638        if (result) {
639                msg_cerr("%s failed during command execution at address 0x%x\n", __func__, addr);
640                return result;
641        }
642        /* Wait until the Write-In-Progress bit is cleared.
643         * This usually takes 10 ms, so wait in 1 ms steps.
644         */
645        while (spi_read_status_register(flash) & SPI_SR_WIP)
646                programmer_delay(1 * 1000);
647        /* FIXME: Check the status register for errors. */
648        return 0;
649}
650
651int spi_block_erase_81(struct flashctx *flash, unsigned int addr, unsigned int blocklen)
652{
653        int result;
654        struct spi_command cmds[] = {
655        {
656/*              .writecnt       = JEDEC_WREN_OUTSIZE,
657                .writearr       = (const unsigned char[]){ JEDEC_WREN },
658                .readcnt        = 0,
659                .readarr        = NULL,
660        }, { */
661                .writecnt       = JEDEC_BE_81_OUTSIZE,
662                .writearr       = (const unsigned char[]){
663                                        JEDEC_BE_81,
664                                        (addr >> 16) & 0xff,
665                                        (addr >> 8) & 0xff,
666                                        (addr & 0xff)
667                                },
668                .readcnt        = 0,
669                .readarr        = NULL,
670        }, {
671                .writecnt       = 0,
672                .writearr       = NULL,
673                .readcnt        = 0,
674                .readarr        = NULL,
675        }};
676
677        result = spi_send_multicommand(flash, cmds);
678        if (result) {
679                msg_cerr("%s failed during command execution at address 0x%x\n", __func__, addr);
680                return result;
681        }
682        /* Wait until the Write-In-Progress bit is cleared.
683         * This usually takes 8 ms, so wait in 1 ms steps.
684         */
685        while (spi_read_status_register(flash) & SPI_SR_WIP)
686                programmer_delay(1 * 1000);
687        /* FIXME: Check the status register for errors. */
688        return 0;
689}
690
691int spi_block_erase_60(struct flashctx *flash, unsigned int addr,
692                       unsigned int blocklen)
693{
694        if ((addr != 0) || (blocklen != flash->chip->total_size * 1024)) {
695                msg_cerr("%s called with incorrect arguments\n",
696                        __func__);
697                return -1;
698        }
699        return spi_chip_erase_60(flash);
700}
701
702int spi_block_erase_62(struct flashctx *flash, unsigned int addr, unsigned int blocklen)
703{
704        if ((addr != 0) || (blocklen != flash->chip->total_size * 1024)) {
705                msg_cerr("%s called with incorrect arguments\n",
706                        __func__);
707                return -1;
708        }
709        return spi_chip_erase_62(flash);
710}
711
712int spi_block_erase_c7(struct flashctx *flash, unsigned int addr,
713                       unsigned int blocklen)
714{
715        if ((addr != 0) || (blocklen != flash->chip->total_size * 1024)) {
716                msg_cerr("%s called with incorrect arguments\n",
717                        __func__);
718                return -1;
719        }
720        return spi_chip_erase_c7(flash);
721}
722
723erasefunc_t *spi_get_erasefn_from_opcode(uint8_t opcode)
724{
725        switch(opcode){
726        case 0xff:
727        case 0x00:
728                /* Not specified, assuming "not supported". */
729                return NULL;
730        case 0x20:
731                return &spi_block_erase_20;
732        case 0x50:
733                return &spi_block_erase_50;
734        case 0x52:
735                return &spi_block_erase_52;
736        case 0x60:
737                return &spi_block_erase_60;
738        case 0x62:
739                return &spi_block_erase_62;
740        case 0x81:
741                return &spi_block_erase_81;
742        case 0xc7:
743                return &spi_block_erase_c7;
744        case 0xd7:
745                return &spi_block_erase_d7;
746        case 0xd8:
747                return &spi_block_erase_d8;
748        default:
749                msg_cinfo("%s: unknown erase opcode (0x%02x). Please report "
750                          "this at flashrom@flashrom.org\n", __func__, opcode);
751                return NULL;
752        }
753}
754
755int spi_byte_program(struct flashctx *flash, unsigned int addr,
756                     uint8_t databyte)
757{
758        int result;
759        struct spi_command cmds[] = {
760        {
761                .writecnt       = JEDEC_WREN_OUTSIZE,
762                .writearr       = (const unsigned char[]){ JEDEC_WREN },
763                .readcnt        = 0,
764                .readarr        = NULL,
765        }, {
766                .writecnt       = JEDEC_BYTE_PROGRAM_OUTSIZE,
767                .writearr       = (const unsigned char[]){
768                                        JEDEC_BYTE_PROGRAM,
769                                        (addr >> 16) & 0xff,
770                                        (addr >> 8) & 0xff,
771                                        (addr & 0xff),
772                                        databyte
773                                },
774                .readcnt        = 0,
775                .readarr        = NULL,
776        }, {
777                .writecnt       = 0,
778                .writearr       = NULL,
779                .readcnt        = 0,
780                .readarr        = NULL,
781        }};
782
783        result = spi_send_multicommand(flash, cmds);
784        if (result) {
785                msg_cerr("%s failed during command execution at address 0x%x\n",
786                        __func__, addr);
787        }
788        return result;
789}
790
791int spi_nbyte_program(struct flashctx *flash, unsigned int addr, uint8_t *bytes,
792                      unsigned int len)
793{
794        int result;
795        /* FIXME: Switch to malloc based on len unless that kills speed. */
796        unsigned char cmd[JEDEC_BYTE_PROGRAM_OUTSIZE - 1 + 256] = {
797                JEDEC_BYTE_PROGRAM,
798                (addr >> 16) & 0xff,
799                (addr >> 8) & 0xff,
800                (addr >> 0) & 0xff,
801        };
802        struct spi_command cmds[] = {
803        {
804                .writecnt       = JEDEC_WREN_OUTSIZE,
805                .writearr       = (const unsigned char[]){ JEDEC_WREN },
806                .readcnt        = 0,
807                .readarr        = NULL,
808        }, {
809                .writecnt       = JEDEC_BYTE_PROGRAM_OUTSIZE - 1 + len,
810                .writearr       = cmd,
811                .readcnt        = 0,
812                .readarr        = NULL,
813        }, {
814                .writecnt       = 0,
815                .writearr       = NULL,
816                .readcnt        = 0,
817                .readarr        = NULL,
818        }};
819
820        if (!len) {
821                msg_cerr("%s called for zero-length write\n", __func__);
822                return 1;
823        }
824        if (len > 256) {
825                msg_cerr("%s called for too long a write\n", __func__);
826                return 1;
827        }
828
829        memcpy(&cmd[4], bytes, len);
830
831        result = spi_send_multicommand(flash, cmds);
832        if (result) {
833                msg_cerr("%s failed during command execution at address 0x%x\n",
834                        __func__, addr);
835        }
836        return result;
837}
838
839int spi_nbyte_read(struct flashctx *flash, unsigned int address, uint8_t *bytes,
840                   unsigned int len)
841{
842        const unsigned char cmd[JEDEC_READ_OUTSIZE] = {
843                JEDEC_READ,
844                (address >> 16) & 0xff,
845                (address >> 8) & 0xff,
846                (address >> 0) & 0xff,
847        };
848
849        /* Send Read */
850        return spi_send_command(flash, sizeof(cmd), len, cmd, bytes);
851}
852
853/*
854 * Read a part of the flash chip.
855 * FIXME: Use the chunk code from Michael Karcher instead.
856 * Each page is read separately in chunks with a maximum size of chunksize.
857 */
858int spi_read_chunked(struct flashctx *flash, uint8_t *buf, unsigned int start,
859                     unsigned int len, unsigned int chunksize)
860{
861        int rc = 0;
862        unsigned int i, j, starthere, lenhere, toread;
863        unsigned int page_size = flash->chip->page_size;
864
865        /* Warning: This loop has a very unusual condition and body.
866         * The loop needs to go through each page with at least one affected
867         * byte. The lowest page number is (start / page_size) since that
868         * division rounds down. The highest page number we want is the page
869         * where the last byte of the range lives. That last byte has the
870         * address (start + len - 1), thus the highest page number is
871         * (start + len - 1) / page_size. Since we want to include that last
872         * page as well, the loop condition uses <=.
873         */
874        for (i = start / page_size; i <= (start + len - 1) / page_size; i++) {
875                /* Byte position of the first byte in the range in this page. */
876                /* starthere is an offset to the base address of the chip. */
877                starthere = max(start, i * page_size);
878                /* Length of bytes in the range in this page. */
879                lenhere = min(start + len, (i + 1) * page_size) - starthere;
880                for (j = 0; j < lenhere; j += chunksize) {
881                        toread = min(chunksize, lenhere - j);
882                        rc = spi_nbyte_read(flash, starthere + j, buf + starthere - start + j, toread);
883                        if (rc)
884                                break;
885                }
886                if (rc)
887                        break;
888        }
889
890        return rc;
891}
892
893/*
894 * Write a part of the flash chip.
895 * FIXME: Use the chunk code from Michael Karcher instead.
896 * Each page is written separately in chunks with a maximum size of chunksize.
897 */
898int spi_write_chunked(struct flashctx *flash, uint8_t *buf, unsigned int start,
899                      unsigned int len, unsigned int chunksize)
900{
901        int rc = 0;
902        unsigned int i, j, starthere, lenhere, towrite;
903        /* FIXME: page_size is the wrong variable. We need max_writechunk_size
904         * in struct flashctx to do this properly. All chips using
905         * spi_chip_write_256 have page_size set to max_writechunk_size, so
906         * we're OK for now.
907         */
908        unsigned int page_size = flash->chip->page_size;
909
910        /* Warning: This loop has a very unusual condition and body.
911         * The loop needs to go through each page with at least one affected
912         * byte. The lowest page number is (start / page_size) since that
913         * division rounds down. The highest page number we want is the page
914         * where the last byte of the range lives. That last byte has the
915         * address (start + len - 1), thus the highest page number is
916         * (start + len - 1) / page_size. Since we want to include that last
917         * page as well, the loop condition uses <=.
918         */
919        for (i = start / page_size; i <= (start + len - 1) / page_size; i++) {
920                /* Byte position of the first byte in the range in this page. */
921                /* starthere is an offset to the base address of the chip. */
922                starthere = max(start, i * page_size);
923                /* Length of bytes in the range in this page. */
924                lenhere = min(start + len, (i + 1) * page_size) - starthere;
925                for (j = 0; j < lenhere; j += chunksize) {
926                        towrite = min(chunksize, lenhere - j);
927                        rc = spi_nbyte_program(flash, starthere + j, buf + starthere - start + j, towrite);
928                        if (rc)
929                                break;
930                        while (spi_read_status_register(flash) & SPI_SR_WIP)
931                                programmer_delay(10);
932                }
933                if (rc)
934                        break;
935        }
936
937        return rc;
938}
939
940/*
941 * Program chip using byte programming. (SLOW!)
942 * This is for chips which can only handle one byte writes
943 * and for chips where memory mapped programming is impossible
944 * (e.g. due to size constraints in IT87* for over 512 kB)
945 */
946/* real chunksize is 1, logical chunksize is 1 */
947int spi_chip_write_1(struct flashctx *flash, uint8_t *buf, unsigned int start,
948                     unsigned int len)
949{
950        unsigned int i;
951        int result = 0;
952
953        for (i = start; i < start + len; i++) {
954                result = spi_byte_program(flash, i, buf[i - start]);
955                if (result)
956                        return 1;
957                while (spi_read_status_register(flash) & SPI_SR_WIP)
958                        programmer_delay(10);
959        }
960
961        return 0;
962}
963
964int default_spi_write_aai(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len)
965{
966        uint32_t pos = start;
967        int result;
968        unsigned char cmd[JEDEC_AAI_WORD_PROGRAM_CONT_OUTSIZE] = {
969                JEDEC_AAI_WORD_PROGRAM,
970        };
971        struct spi_command cmds[] = {
972        {
973                .writecnt       = JEDEC_WREN_OUTSIZE,
974                .writearr       = (const unsigned char[]){ JEDEC_WREN },
975                .readcnt        = 0,
976                .readarr        = NULL,
977        }, {
978                .writecnt       = JEDEC_AAI_WORD_PROGRAM_OUTSIZE,
979                .writearr       = (const unsigned char[]){
980                                        JEDEC_AAI_WORD_PROGRAM,
981                                        (start >> 16) & 0xff,
982                                        (start >> 8) & 0xff,
983                                        (start & 0xff),
984                                        buf[0],
985                                        buf[1]
986                                },
987                .readcnt        = 0,
988                .readarr        = NULL,
989        }, {
990                .writecnt       = 0,
991                .writearr       = NULL,
992                .readcnt        = 0,
993                .readarr        = NULL,
994        }};
995
996        switch (flash->pgm->spi.type) {
997#if CONFIG_INTERNAL == 1
998#if defined(__i386__) || defined(__x86_64__)
999        case SPI_CONTROLLER_IT87XX:
1000        case SPI_CONTROLLER_WBSIO:
1001                msg_perr("%s: impossible with this SPI controller,"
1002                                " degrading to byte program\n", __func__);
1003                return spi_chip_write_1(flash, buf, start, len);
1004#endif
1005#endif
1006        default:
1007                break;
1008        }
1009
1010        /* The even start address and even length requirements can be either
1011         * honored outside this function, or we can call spi_byte_program
1012         * for the first and/or last byte and use AAI for the rest.
1013         * FIXME: Move this to generic code.
1014         */
1015        /* The data sheet requires a start address with the low bit cleared. */
1016        if (start % 2) {
1017                msg_cerr("%s: start address not even! Please report a bug at "
1018                         "flashrom@flashrom.org\n", __func__);
1019                if (spi_chip_write_1(flash, buf, start, start % 2))
1020                        return SPI_GENERIC_ERROR;
1021                pos += start % 2;
1022                cmds[1].writearr = (const unsigned char[]){
1023                                        JEDEC_AAI_WORD_PROGRAM,
1024                                        (pos >> 16) & 0xff,
1025                                        (pos >> 8) & 0xff,
1026                                        (pos & 0xff),
1027                                        buf[pos - start],
1028                                        buf[pos - start + 1]
1029                                };
1030                /* Do not return an error for now. */
1031                //return SPI_GENERIC_ERROR;
1032        }
1033        /* The data sheet requires total AAI write length to be even. */
1034        if (len % 2) {
1035                msg_cerr("%s: total write length not even! Please report a "
1036                         "bug at flashrom@flashrom.org\n", __func__);
1037                /* Do not return an error for now. */
1038                //return SPI_GENERIC_ERROR;
1039        }
1040
1041
1042        result = spi_send_multicommand(flash, cmds);
1043        if (result) {
1044                msg_cerr("%s failed during start command execution\n",
1045                         __func__);
1046                /* FIXME: Should we send WRDI here as well to make sure the chip
1047                 * is not in AAI mode?
1048                 */
1049                return result;
1050        }
1051        while (spi_read_status_register(flash) & SPI_SR_WIP)
1052                programmer_delay(10);
1053
1054        /* We already wrote 2 bytes in the multicommand step. */
1055        pos += 2;
1056
1057        /* Are there at least two more bytes to write? */
1058        while (pos < start + len - 1) {
1059                cmd[1] = buf[pos++ - start];
1060                cmd[2] = buf[pos++ - start];
1061                spi_send_command(flash, JEDEC_AAI_WORD_PROGRAM_CONT_OUTSIZE, 0,
1062                                 cmd, NULL);
1063                while (spi_read_status_register(flash) & SPI_SR_WIP)
1064                        programmer_delay(10);
1065        }
1066
1067        /* Use WRDI to exit AAI mode. This needs to be done before issuing any
1068         * other non-AAI command.
1069         */
1070        spi_write_disable(flash);
1071
1072        /* Write remaining byte (if any). */
1073        if (pos < start + len) {
1074                if (spi_chip_write_1(flash, buf + pos - start, pos, pos % 2))
1075                        return SPI_GENERIC_ERROR;
1076                pos += pos % 2;
1077        }
1078
1079        return 0;
1080}
Note: See TracBrowser for help on using the repository browser.