Use CONFIG_TPLINK_IMAGE_HEADER define to select TP-Link img header, plus minor change...
[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_MACRONIX[] = "Macronix";
20 static char VENDOR_MICRON[]   = "Micron";
21 static char VENDOR_SPANSION[] = "Spansion";
22 static char VENDOR_WINBOND[]  = "Winbond";
23
24 const spi_nor_ids_info_t spi_nor_ids[] = {
25         /* 4 MiB */
26         { "AT25DF321", 0x1F4700, SIZE_4MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
27         { "EN25Q32",   0x1C3016, SIZE_4MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
28         { "EN25F32",   0x1C3116, SIZE_4MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
29         { "MX25L320",  0xC22016, SIZE_4MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
30         { "M25P32",    0x202016, SIZE_4MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
31         { "S25FL032P", 0x010215, SIZE_4MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
32         { "W25Q32",    0xEF4016, SIZE_4MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
33
34         /* 8 MiB */
35         { "AT25DF641", 0x1F4800, SIZE_8MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
36         { "EN25Q64",   0x1C3017, SIZE_8MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
37         { "MX25L64",   0xC22017, SIZE_8MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
38         { "MX25L64",   0xC22617, SIZE_8MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
39         { "M25P64",    0x202017, SIZE_8MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
40         { "S25FL064P", 0x010216, SIZE_8MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
41         { "W25Q64",    0xEF4017, SIZE_8MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
42
43         /* 16 MiB */
44         { "MX25L128",  0xC22018, SIZE_16MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
45         { "MX25L128",  0xC22618, SIZE_16MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
46         { "N25Q128",   0x20BA18, SIZE_16MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
47         { "S25FL127S", 0x012018, SIZE_16MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
48         { "W25Q128",   0xEF4018, SIZE_16MiB, SIZE_64KiB, 256, SPI_FLASH_CMD_ES_64KB },
49 };
50
51 const u32 spi_nor_ids_count = sizeof(spi_nor_ids) / sizeof(spi_nor_ids_info_t);
52
53 const char *flash_manuf_name(u32 jedec_id)
54 {
55         switch (jedec_id >> 16) {
56         case FLASH_VENDOR_JEDEC_ATMEL:
57                 return VENDOR_ATMEL;
58                 break;
59         case FLASH_VENDOR_JEDEC_EON:
60                 return VENDOR_EON;
61                 break;
62         case FLASH_VENDOR_JEDEC_MACRONIX:
63                 return VENDOR_MACRONIX;
64                 break;
65         case FLASH_VENDOR_JEDEC_MICRON:
66                 return VENDOR_MICRON;
67                 break;
68         case FLASH_VENDOR_JEDEC_SPANSION:
69                 return VENDOR_SPANSION;
70                 break;
71         case FLASH_VENDOR_JEDEC_WINBOND:
72                 return VENDOR_WINBOND;
73                 break;
74         default:
75                 return "Unknown";
76                 break;
77         }
78 }
79
80 flash_info_t *addr2info(ulong addr)
81 {
82         flash_info_t *info;
83         int i;
84
85         for (i = 0, info = &flash_info[0]; i < CFG_MAX_FLASH_BANKS; ++i, ++info) {
86                 /*
87                  * WARNING - The '- 1' is needed if the flash
88                  * is at the end of the address space, since
89                  * info->start[0] + info->size wraps back to 0.
90                  * Please don't change this unless you understand this.
91                  */
92                 if (info->flash_id != FLASH_UNKNOWN
93                         && addr >= info->start[0]
94                         && addr <= info->start[0] + info->size - 1) {
95                         return info;
96                 }
97         }
98
99         return NULL;
100 }
101
102 /*
103  * Copy memory to flash.
104  * Make sure all target addresses are within Flash bounds,
105  * and no protected sectors are hit.
106  * Returns:
107  * ERR_OK          0 - OK
108  * ERR_TIMOUT      1 - write timeout
109  * ERR_NOT_ERASED  2 - Flash not erased
110  * ERR_PROTECTED   4 - target range includes protected sectors
111  * ERR_INVAL       8 - target address not in Flash memory
112  * ERR_ALIGN       16 - target address not aligned on boundary
113  *                      (only some targets require alignment)
114  */
115 int flash_write(char *src, ulong addr, ulong cnt)
116 {
117         int i;
118         ulong end = addr + cnt - 1;
119         flash_info_t *info_first = addr2info(addr);
120         flash_info_t *info_last = addr2info(end);
121         flash_info_t *info;
122
123         if (cnt == 0)
124                 return ERR_OK;
125
126         if (!info_first || !info_last)
127                 return ERR_INVAL;
128
129         /* Finally write data to flash */
130         for (info = info_first; info <= info_last && cnt > 0; ++info) {
131                 ulong len = info->start[0] + info->size - addr;
132
133                 if (len > cnt)
134                         len = cnt;
135
136                 if ((i = write_buff(info, (uchar *)src, addr, len)) != 0)
137                         return i;
138
139                 cnt  -= len;
140                 addr += len;
141                 src  += len;
142         }
143
144         return ERR_OK;
145 }
146
147 void flash_perror(int err)
148 {
149         switch (err) {
150         case ERR_OK:
151                 break;
152         case ERR_TIMOUT:
153                 puts("## Error: timeout writing to FLASH\n");
154                 break;
155         case ERR_NOT_ERASED:
156                 puts("## Error: FLASH not erased\n");
157                 break;
158         case ERR_INVAL:
159                 puts("## Error: outside available FLASH\n");
160                 break;
161         case ERR_ALIGN:
162                 puts("## Error: start and/or end address not on sector boundary\n");
163                 break;
164         case ERR_UNKNOWN_FLASH_VENDOR:
165                 puts("## Error: unknown vendor of FLASH\n");
166                 break;
167         case ERR_UNKNOWN_FLASH_TYPE:
168                 puts("## Error: unknown type of FLASH\n");
169                 break;
170         case ERR_PROG_ERROR:
171                 puts("## Error: general FLASH programming error\n");
172                 break;
173         default:
174                 printf("## Error: %s[%d] FIXME: rc=%d\n", __FILE__, __LINE__, err);
175                 break;
176         }
177 }
178 #endif /* !CFG_NO_FLASH */