1 /***************************************************************************
2 * Copyright (C) 2019 by Andreas Bolsch <andreas.bolsch@mni.thm.de *
3 * This program is free software; you can redistribute it and/or modify *
4 * it under the terms of the GNU General Public License as published by *
5 * the Free Software Foundation; either version 2 of the License, or *
6 * (at your option) any later version. *
8 * This program is distributed in the hope that it will be useful, *
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
11 * GNU General Public License for more details. *
13 * You should have received a copy of the GNU General Public License *
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
15 ***************************************************************************/
25 #define SFDP_MAGIC 0x50444653
26 #define SFDP_ACCESS_PROT 0xFF
27 #define SFDP_BASIC_FLASH 0xFF00
28 #define SFDP_4BYTE_ADDR 0xFF84
30 static const char *sfdp_name = "sfdp";
42 struct sfdp_basic_flash_param {
43 uint32_t fast_addr; /* 01: fast read and 3/4 address bytes */
44 uint32_t density; /* 02: memory density */
45 uint32_t fast_1x4; /* 03: 1-1-4 and 1-4-4 fast read */
46 uint32_t fast_1x2; /* 04: 1-2-2 and 1-1-2 fast read */
47 uint32_t fast_444; /* 05: 4-4-4 and 2-2-2 fast read */
48 uint32_t read_222; /* 06: 2-2-2 fast read instr and dummy */
49 uint32_t read_444; /* 07: 4-4-4 fast read instr and dummy */
50 uint32_t erase_t12; /* 08: erase types 1, 2 */
51 uint32_t erase_t34; /* 09: erase types 3, 4 */
52 uint32_t erase_time; /* 10: erase times for types 1 - 4 */
53 uint32_t chip_byte; /* 11: chip erase time, byte prog time, page prog */
54 uint32_t susp_time; /* 12: suspend and resume times */
55 uint32_t susp_instr; /* 13: suspend and resume instr */
56 uint32_t pwrd_instr; /* 14: powerdown instr */
57 uint32_t quad_req; /* 15: quad enable requirements */
58 uint32_t addr_reset; /* 16: 3-/4-byte addressing and reset */
59 uint32_t read_1x8; /* 17: 1-1-8 and 1-8-8 fast read instr and dummy */
60 uint32_t dtr_drive; /* 18: dtr modes and drive strength */
61 uint32_t octal_req; /* 19: octal enable requirements */
62 uint32_t speed_888; /* 20: speed in 8-8-8 modes */
65 struct sfdp_4byte_addr_param {
66 uint32_t flags; /* 01: various flags */
67 uint32_t erase_t1234; /* 02: erase commands */
70 /* Try to get parameters from flash via SFDP */
71 int spi_sfdp(struct flash_bank *bank, struct flash_device *dev,
72 read_sfdp_block_t read_sfdp_block)
74 struct sfdp_hdr header;
75 struct sfdp_phdr *pheaders = NULL;
76 uint32_t *ptable = NULL;
77 unsigned int j, k, nph;
78 int retval, erase_type = 0;
80 memset(dev, 0, sizeof(struct flash_device));
82 /* retrieve SFDP header */
83 memset(&header, 0, sizeof(header));
84 retval = read_sfdp_block(bank, 0x0, sizeof(header) >> 2, (uint32_t *)&header);
85 if (retval != ERROR_OK)
87 LOG_DEBUG("header 0x%08" PRIx32 " 0x%08" PRIx32, header.signature, header.revision);
88 if (header.signature != SFDP_MAGIC) {
89 LOG_INFO("no SDFP found");
90 return ERROR_FLASH_BANK_NOT_PROBED;
92 if (((header.revision >> 24) & 0xFF) != SFDP_ACCESS_PROT) {
93 LOG_ERROR("access protocol 0x%02x not implemented",
94 (header.revision >> 24) & 0xFFU);
95 return ERROR_FLASH_BANK_NOT_PROBED;
98 /* retrieve table of parameter headers */
99 nph = ((header.revision >> 16) & 0xFF) + 1;
100 LOG_DEBUG("parameter headers: %d", nph);
101 pheaders = malloc(sizeof(struct sfdp_phdr) * nph);
102 if (pheaders == NULL) {
103 LOG_ERROR("not enough memory");
106 memset(pheaders, 0, sizeof(struct sfdp_phdr) * nph);
107 retval = read_sfdp_block(bank, sizeof(header),
108 (sizeof(struct sfdp_phdr) >> 2) * nph, (uint32_t *)pheaders);
109 if (retval != ERROR_OK)
112 for (k = 0; k < nph; k++) {
113 uint8_t words = (pheaders[k].revision >> 24) & 0xFF;
114 uint16_t id = (((pheaders[k].ptr) >> 16) & 0xFF00) | (pheaders[k].revision & 0xFF);
115 uint32_t ptr = pheaders[k].ptr & 0xFFFFFF;
117 LOG_DEBUG("pheader %d len=0x%02" PRIx8 " id=0x%04" PRIx16
118 " ptr=0x%06" PRIx32, k, words, id, ptr);
120 /* retrieve parameter table */
121 ptable = malloc(words << 2);
122 if (ptable == NULL) {
123 LOG_ERROR("not enough memory");
127 retval = read_sfdp_block(bank, ptr, words, ptable);
128 if (retval != ERROR_OK)
131 for (j = 0; j < words; j++)
132 LOG_DEBUG("word %02d 0x%08X", j + 1, ptable[j]);
134 if (id == SFDP_BASIC_FLASH) {
135 struct sfdp_basic_flash_param *table = (struct sfdp_basic_flash_param *)ptable;
139 LOG_ERROR("id=0x%04" PRIx16 " invalid length %d", id, words);
140 retval = ERROR_FLASH_BANK_NOT_PROBED;
144 LOG_DEBUG("basic flash parameter table");
145 /* dummy device name */
146 dev->name = sfdp_name;
148 /* default instructions */
149 dev->read_cmd = SPIFLASH_READ;
150 dev->pprog_cmd = SPIFLASH_PAGE_PROGRAM;
151 dev->chip_erase_cmd = SPIFLASH_MASS_ERASE;
153 /* get device size */
154 if (table->density & (1UL << 31))
155 dev->size_in_bytes = 1UL << ((table->density & ~(1UL << 31)) - 3);
157 dev->size_in_bytes = (table->density + 1) >> 3;
159 /* 2-2-2 read instruction, not used */
160 if (table->fast_444 & (1UL << 0))
161 dev->qread_cmd = (table->read_222 >> 24) & 0xFF;
163 /* 4-4-4 read instruction */
164 if (table->fast_444 & (1UL << 4))
165 dev->qread_cmd = (table->read_444 >> 24) & 0xFF;
167 /* find the largest erase block size and instruction */
168 erase = (table->erase_t12 >> 0) & 0xFFFF;
170 if (((table->erase_t12 >> 16) & 0xFF) > (erase & 0xFF)) {
171 erase = (table->erase_t12 >> 16) & 0xFFFF;
174 if (((table->erase_t34 >> 0) & 0xFF) > (erase & 0xFF)) {
175 erase = (table->erase_t34 >> 0) & 0xFFFF;
178 if (((table->erase_t34 >> 16) & 0xFF) > (erase & 0xFF)) {
179 erase = (table->erase_t34 >> 16) & 0xFFFF;
182 dev->erase_cmd = (erase >> 8) & 0xFF;
183 dev->sectorsize = 1UL << (erase & 0xFF);
185 if ((offsetof(struct sfdp_basic_flash_param, chip_byte) >> 2) < words) {
186 /* get Program Page Size, if chip_byte present, that's optional */
187 dev->pagesize = 1UL << ((table->chip_byte >> 4) & 0x0F);
189 /* no explicit page size specified ... */
190 if (table->fast_addr & (1UL << 2)) {
191 /* Write Granularity = 1, use 64 bytes */
192 dev->pagesize = 1UL << 6;
194 /* Write Granularity = 0, use 16 bytes */
195 dev->pagesize = 1UL << 4;
199 if (dev->size_in_bytes > (1UL << 24)) {
200 if (((table->fast_addr >> 17) & 0x3) == 0x0)
201 LOG_ERROR("device needs paging - not implemented");
203 /* 4-byte addresses needed if more than 16 MBytes */
204 if (((offsetof(struct sfdp_basic_flash_param, addr_reset) >> 2) < words) &&
205 (table->addr_reset & (1UL << 29))) {
206 /* dedicated 4-byte-address instructions, hopefully these ...
207 * this entry is unfortunately optional as well
208 * a subsequent 4-byte address table may overwrite this */
209 dev->read_cmd = 0x13;
210 dev->pprog_cmd = 0x12;
211 dev->erase_cmd = 0xDC;
212 if (dev->qread_cmd != 0)
213 dev->qread_cmd = 0xEC;
214 } else if (((table->fast_addr >> 17) & 0x3) == 0x1)
215 LOG_INFO("device has to be switched to 4-byte addresses");
217 } else if (id == SFDP_4BYTE_ADDR) {
218 struct sfdp_4byte_addr_param *table = (struct sfdp_4byte_addr_param *)ptable;
220 if (words >= (offsetof(struct sfdp_4byte_addr_param, erase_t1234)
221 + sizeof(table->erase_t1234)) >> 2) {
222 LOG_INFO("4-byte address parameter table");
224 /* read and page program instructions */
225 if (table->flags & (1UL << 0))
226 dev->read_cmd = 0x13;
227 if (table->flags & (1UL << 5))
228 dev->qread_cmd = 0xEC;
229 if (table->flags & (1UL << 6))
230 dev->pprog_cmd = 0x12;
232 /* erase instructions */
233 if ((erase_type == 1) && (table->flags & (1UL << 9)))
234 dev->erase_cmd = (table->erase_t1234 >> 0) & 0xFF;
235 else if ((erase_type == 2) && (table->flags & (1UL << 10)))
236 dev->erase_cmd = (table->erase_t1234 >> 8) & 0xFF;
237 else if ((erase_type == 3) && (table->flags & (1UL << 11)))
238 dev->erase_cmd = (table->erase_t1234 >> 16) & 0xFF;
239 else if ((erase_type == 4) && (table->flags & (1UL << 12)))
240 dev->erase_cmd = (table->erase_t1234 >> 24) & 0xFF;
242 LOG_ERROR("parameter table id=0x%04" PRIx16 " invalid length %d", id, words);
244 LOG_DEBUG("unimplemented parameter table id=0x%04" PRIx16, id);
250 if (erase_type != 0) {
251 LOG_INFO("valid SFDP detected");
254 LOG_ERROR("incomplete/invalid SFDP");
255 retval = ERROR_FLASH_BANK_NOT_PROBED;