sf: probe: Add new spi_flash_probe support
[oweals/u-boot.git] / drivers / mtd / spi / spi_flash_probe.c
1 /*
2  * SPI flash probing
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  * Licensed under the GPL-2 or later.
9  */
10
11 #include <common.h>
12 #include <fdtdec.h>
13 #include <malloc.h>
14 #include <spi.h>
15 #include <spi_flash.h>
16
17 #include "spi_flash_internal.h"
18
19 DECLARE_GLOBAL_DATA_PTR;
20
21 /*
22  * struct spi_flash_params - SPI/QSPI flash device params structure
23  *
24  * @name:               Device name ([MANUFLETTER][DEVTYPE][DENSITY][EXTRAINFO])
25  * @jedec:              Device jedec ID (0x[1byte_manuf_id][2byte_dev_id])
26  * @ext_jedec:          Device ext_jedec ID
27  * @sector_size:        Sector size of this device
28  * @nr_sectors: No.of sectors on this device
29  */
30 struct spi_flash_params {
31         const char *name;
32         u32 jedec;
33         u16 ext_jedec;
34         u32 sector_size;
35         u32 nr_sectors;
36 };
37
38 static const struct spi_flash_params spi_flash_params_table[] = {
39 #ifdef CONFIG_SPI_FLASH_STMICRO         /* STMICRO */
40         {"N25Q32",              0x20ba16, 0x0,     64 * 1024,     64},
41         {"N25Q32A",             0x20bb16, 0x0,     64 * 1024,     64},
42         {"N25Q64",              0x20ba17, 0x0,     64 * 1024,    128},
43         {"N25Q64A",             0x20bb17, 0x0,     64 * 1024,    128},
44         {"N25Q128",             0x20ba18, 0x0,     64 * 1024,    256},
45         {"N25Q128A",            0x20bb18, 0x0,     64 * 1024,    256},
46         {"N25Q256",             0x20ba19, 0x0,     64 * 1024,    512},
47         {"N25Q256A",            0x20bb19, 0x0,     64 * 1024,    512},
48         {"N25Q512",             0x20ba20, 0x0,     64 * 1024,   1024},
49         {"N25Q512A",            0x20bb20, 0x0,     64 * 1024,   1024},
50         {"N25Q1024",            0x20ba21, 0x0,     64 * 1024,   2048},
51         {"N25Q1024A",           0x20bb21, 0x0,     64 * 1024,   2048},
52 #endif
53         /*
54          * TODO:
55          * ATMEL
56          * EON
57          * GIGADEVICE
58          * MACRONIX
59          * RAMTRON
60          * SPANSION
61          * SST
62          * STMICRO (M25*)
63          * WINBOND
64          */
65 };
66
67 struct spi_flash *spi_flash_validate_ids(struct spi_slave *spi, u8 *idcode)
68 {
69         const struct spi_flash_params *params;
70         struct spi_flash *flash;
71         int i;
72         u16 jedec = idcode[1] << 8 | idcode[2];
73
74         /* Get the flash id (jedec = manuf_id + dev_id) */
75         for (i = 0; i < ARRAY_SIZE(spi_flash_params_table); i++) {
76                 params = &spi_flash_params_table[i];
77                 if ((params->jedec >> 16) == idcode[0]) {
78                         if ((params->jedec & 0xFFFF) == jedec)
79                                 break;
80                 }
81         }
82
83         if (i == ARRAY_SIZE(spi_flash_params_table)) {
84                 printf("SF: Unsupported flash ID: manuf %02x, jedec %04x\n",
85                        idcode[0], jedec);
86                 return NULL;
87         }
88
89         flash = malloc(sizeof(*flash));
90         if (!flash) {
91                 debug("SF: Failed to allocate spi_flash\n");
92                 return NULL;
93         }
94         memset(flash, '\0', sizeof(*flash));
95
96         flash->spi = spi;
97         flash->name = params->name;
98         flash->poll_cmd = CMD_READ_STATUS;
99
100         /* Assign spi_flash ops */
101         flash->write = spi_flash_cmd_write_multi;
102         flash->erase = spi_flash_cmd_erase;
103         flash->read = spi_flash_cmd_read_fast;
104
105         /* Compute the flash size */
106         flash->page_size = 256;
107         flash->sector_size = params->sector_size;
108         flash->size = flash->sector_size * params->nr_sectors;
109
110         return flash;
111 }
112
113 #ifdef CONFIG_SPI_FLASH_BAR
114 int spi_flash_bank_config(struct spi_flash *flash, u8 idcode0)
115 {
116         u8 cmd;
117         u8 curr_bank = 0;
118
119         /* discover bank cmds */
120         switch (idcode0) {
121         case SPI_FLASH_SPANSION_IDCODE0:
122                 flash->bank_read_cmd = CMD_BANKADDR_BRRD;
123                 flash->bank_write_cmd = CMD_BANKADDR_BRWR;
124                 break;
125         case SPI_FLASH_STMICRO_IDCODE0:
126         case SPI_FLASH_WINBOND_IDCODE0:
127                 flash->bank_read_cmd = CMD_EXTNADDR_RDEAR;
128                 flash->bank_write_cmd = CMD_EXTNADDR_WREAR;
129                 break;
130         default:
131                 printf("SF: Unsupported bank commands %02x\n", idcode0);
132                 return -1;
133         }
134
135         /* read the bank reg - on which bank the flash is in currently */
136         cmd = flash->bank_read_cmd;
137         if (flash->size > SPI_FLASH_16MB_BOUN) {
138                 if (spi_flash_read_common(flash, &cmd, 1, &curr_bank, 1)) {
139                         debug("SF: fail to read bank addr register\n");
140                         return -1;
141                 }
142                 flash->bank_curr = curr_bank;
143         } else {
144                 flash->bank_curr = curr_bank;
145         }
146
147         return 0;
148 }
149 #endif
150
151 #ifdef CONFIG_OF_CONTROL
152 int spi_flash_decode_fdt(const void *blob, struct spi_flash *flash)
153 {
154         fdt_addr_t addr;
155         fdt_size_t size;
156         int node;
157
158         /* If there is no node, do nothing */
159         node = fdtdec_next_compatible(blob, 0, COMPAT_GENERIC_SPI_FLASH);
160         if (node < 0)
161                 return 0;
162
163         addr = fdtdec_get_addr_size(blob, node, "memory-map", &size);
164         if (addr == FDT_ADDR_T_NONE) {
165                 debug("%s: Cannot decode address\n", __func__);
166                 return 0;
167         }
168
169         if (flash->size != size) {
170                 debug("%s: Memory map must cover entire device\n", __func__);
171                 return -1;
172         }
173         flash->memory_map = (void *)addr;
174
175         return 0;
176 }
177 #endif /* CONFIG_OF_CONTROL */
178
179 struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
180                 unsigned int max_hz, unsigned int spi_mode)
181 {
182         struct spi_slave *spi;
183         struct spi_flash *flash = NULL;
184         u8 idcode[5], *idp;
185         int ret;
186
187         /* Setup spi_slave */
188         spi = spi_setup_slave(bus, cs, max_hz, spi_mode);
189         if (!spi) {
190                 printf("SF: Failed to set up slave\n");
191                 return NULL;
192         }
193
194         /* Claim spi bus */
195         ret = spi_claim_bus(spi);
196         if (ret) {
197                 debug("SF: Failed to claim SPI bus: %d\n", ret);
198                 goto err_claim_bus;
199         }
200
201         /* Read the ID codes */
202         ret = spi_flash_cmd(spi, CMD_READ_ID, idcode, sizeof(idcode));
203         if (ret) {
204                 printf("SF: Failed to get idcodes\n");
205                 goto err_read_id;
206         }
207
208 #ifdef DEBUG
209         printf("SF: Got idcodes\n");
210         print_buffer(0, idcode, 1, sizeof(idcode), 0);
211 #endif
212
213         /* Validate ID's from flash dev table */
214         idp = idcode;
215         flash = spi_flash_validate_ids(spi, idp);
216         if (!flash)
217                 goto err_read_id;
218
219 #ifdef CONFIG_SPI_FLASH_BAR
220         /* Configure the BAR - discover bank cmds and read current bank  */
221         ret = spi_flash_bank_config(flash, *idp);
222         if (ret < 0)
223                 goto err_read_id;
224 #endif
225
226 #ifdef CONFIG_OF_CONTROL
227         if (spi_flash_decode_fdt(gd->fdt_blob, flash)) {
228                 debug("SF: FDT decode error\n");
229                 goto err_read_id;
230         }
231 #endif
232 #ifndef CONFIG_SPL_BUILD
233         printf("SF: Detected %s with page size ", flash->name);
234         print_size(flash->sector_size, ", total ");
235         print_size(flash->size, "");
236         if (flash->memory_map)
237                 printf(", mapped at %p", flash->memory_map);
238         puts("\n");
239 #endif
240 #ifndef CONFIG_SPI_FLASH_BAR
241         if (flash->size > SPI_FLASH_16MB_BOUN) {
242                 puts("SF: Warning - Only lower 16MiB accessible,");
243                 puts(" Full access #define CONFIG_SPI_FLASH_BAR\n");
244         }
245 #endif
246
247         /* Release spi bus */
248         spi_release_bus(spi);
249
250         return flash;
251
252 err_read_id:
253         spi_release_bus(spi);
254 err_claim_bus:
255         spi_free_slave(spi);
256         return NULL;
257 }
258
259 void spi_flash_free(struct spi_flash *flash)
260 {
261         spi_free_slave(flash->spi);
262         free(flash);
263 }