Add more stock U-Boot images
[oweals/u-boot_mod.git] / u-boot / common / flash.c
1 /*
2  * Copyright (C) 2015 Piotr Dymacz <piotr@dymacz.pl>
3  * Copyright (C) 2005 Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
4  *
5  * SPDX-License-Identifier:GPL-2.0
6  */
7
8 #include <common.h>
9 #include <flash.h>
10
11 #ifndef CFG_NO_FLASH
12
13 /* Info for FLASH chips */
14 flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
15
16 /* List of supported and known SPI NOR FLASH chips */
17 static char VENDOR_ATMEL[]      = "Atmel";
18 static char VENDOR_EON[]        = "EON";
19 static char VENDOR_GIGADEVICE[] = "GigaDevice";
20 static char VENDOR_MACRONIX[]   = "Macronix";
21 static char VENDOR_MICRON[]     = "Micron";
22 static char VENDOR_SPANSION[]   = "Spansion";
23 static char VENDOR_WINBOND[]    = "Winbond";
24
25 const spi_nor_ids_info_t spi_nor_ids[] = {
26         /* 4 MiB */
27         { "AT25DF321", 0x1F4700, SIZE_4MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
28         { "EN25Q32",   0x1C3016, SIZE_4MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
29         { "EN25F32",   0x1C3116, SIZE_4MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
30         { "GD25Q32",   0xC84016, SIZE_4MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
31         { "MX25L320",  0xC22016, SIZE_4MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
32         { "M25P32",    0x202016, SIZE_4MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
33         { "S25FL032P", 0x010215, SIZE_4MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
34         { "W25Q32",    0xEF4016, SIZE_4MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
35
36         /* 8 MiB */
37         { "AT25DF641", 0x1F4800, SIZE_8MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
38         { "EN25Q64",   0x1C3017, SIZE_8MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
39         { "GD25Q64",   0xC84017, SIZE_8MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
40         { "MX25L64",   0xC22017, SIZE_8MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
41         { "MX25L64",   0xC22617, SIZE_8MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
42         { "M25P64",    0x202017, SIZE_8MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
43         { "S25FL064P", 0x010216, SIZE_8MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
44         { "W25Q64",    0xEF4017, SIZE_8MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
45
46         /* 16 MiB */
47         { "GD25Q128",  0xC84018, SIZE_16MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
48         { "MX25L128",  0xC22018, SIZE_16MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
49         { "MX25L128",  0xC22618, SIZE_16MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
50         { "N25Q128",   0x20BA18, SIZE_16MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
51         { "S25FL127S", 0x012018, SIZE_16MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
52         { "W25Q128",   0xEF4018, SIZE_16MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
53         { "W25Q128FW", 0xEF6018, SIZE_16MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
54 };
55
56 const u32 spi_nor_ids_count = sizeof(spi_nor_ids) / sizeof(spi_nor_ids_info_t);
57
58 const char *flash_manuf_name(u32 jedec_id)
59 {
60         switch (jedec_id >> 16) {
61         case FLASH_VENDOR_JEDEC_ATMEL:
62                 return VENDOR_ATMEL;
63                 break;
64         case FLASH_VENDOR_JEDEC_EON:
65                 return VENDOR_EON;
66                 break;
67         case FLASH_VENDOR_JEDEC_GIGADEVICE:
68                 return VENDOR_GIGADEVICE;
69                 break;
70         case FLASH_VENDOR_JEDEC_MACRONIX:
71                 return VENDOR_MACRONIX;
72                 break;
73         case FLASH_VENDOR_JEDEC_MICRON:
74                 return VENDOR_MICRON;
75                 break;
76         case FLASH_VENDOR_JEDEC_SPANSION:
77                 return VENDOR_SPANSION;
78                 break;
79         case FLASH_VENDOR_JEDEC_WINBOND:
80                 return VENDOR_WINBOND;
81                 break;
82         default:
83                 return "Unknown";
84                 break;
85         }
86 }
87
88 flash_info_t *addr2info(ulong addr)
89 {
90         flash_info_t *info;
91         int i;
92
93         for (i = 0, info = &flash_info[0]; i < CFG_MAX_FLASH_BANKS; ++i, ++info) {
94                 /*
95                  * WARNING - The '- 1' is needed if the flash
96                  * is at the end of the address space, since
97                  * info->start[0] + info->size wraps back to 0.
98                  * Please don't change this unless you understand this.
99                  */
100                 if (info->flash_id != FLASH_UNKNOWN
101                         && addr >= info->start[0]
102                         && addr <= info->start[0] + info->size - 1) {
103                         return info;
104                 }
105         }
106
107         return NULL;
108 }
109
110 /*
111  * Copy memory to flash.
112  * Make sure all target addresses are within Flash bounds,
113  * and no protected sectors are hit.
114  * Returns:
115  * ERR_OK          0 - OK
116  * ERR_TIMOUT      1 - write timeout
117  * ERR_NOT_ERASED  2 - Flash not erased
118  * ERR_PROTECTED   4 - target range includes protected sectors
119  * ERR_INVAL       8 - target address not in Flash memory
120  * ERR_ALIGN       16 - target address not aligned on boundary
121  *                      (only some targets require alignment)
122  */
123 int flash_write(char *src, ulong addr, ulong cnt)
124 {
125         int i;
126         ulong end = addr + cnt - 1;
127         flash_info_t *info_first = addr2info(addr);
128         flash_info_t *info_last = addr2info(end);
129         flash_info_t *info;
130
131         if (cnt == 0)
132                 return ERR_OK;
133
134         if (!info_first || !info_last)
135                 return ERR_INVAL;
136
137         /* Finally write data to flash */
138         for (info = info_first; info <= info_last && cnt > 0; ++info) {
139                 ulong len = info->start[0] + info->size - addr;
140
141                 if (len > cnt)
142                         len = cnt;
143
144                 if ((i = write_buff(info, (uchar *)src, addr, len)) != 0)
145                         return i;
146
147                 cnt  -= len;
148                 addr += len;
149                 src  += len;
150         }
151
152         return ERR_OK;
153 }
154
155 void flash_perror(int err)
156 {
157         switch (err) {
158         case ERR_OK:
159                 break;
160         case ERR_TIMOUT:
161                 printf_err("timeout writing to FLASH\n");
162                 break;
163         case ERR_NOT_ERASED:
164                 printf_err("FLASH not erased\n");
165                 break;
166         case ERR_INVAL:
167                 printf_err("outside available FLASH\n");
168                 break;
169         case ERR_ALIGN:
170                 printf_err("start and/or end address not on sector boundary\n");
171                 break;
172         case ERR_UNKNOWN_FLASH_VENDOR:
173                 printf_err("unknown vendor of FLASH\n");
174                 break;
175         case ERR_UNKNOWN_FLASH_TYPE:
176                 printf_err("unknown type of FLASH\n");
177                 break;
178         case ERR_PROG_ERROR:
179                 printf_err("general FLASH programming error\n");
180                 break;
181         default:
182                 printf_err("%s[%d] FIXME: rc=%d\n", __FILE__, __LINE__, err);
183                 break;
184         }
185 }
186 #endif /* !CFG_NO_FLASH */