1 /* 2 * Copyright (c) 2019-2020, Broadcom 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <stdbool.h> 8 #include <stddef.h> 9 #include <stdint.h> 10 11 #include <common/debug.h> 12 #include <drivers/delay_timer.h> 13 #include <errno.h> 14 15 #include <sf.h> 16 #include <spi.h> 17 18 #define SPI_FLASH_CMD_LEN 4 19 #define QSPI_WAIT_TIMEOUT_US 200000U /* usec */ 20 21 #define FINFO(jedec_id, ext_id, _sector_size, _n_sectors, _page_size, _flags) \ 22 .id = { \ 23 ((jedec_id) >> 16) & 0xff, \ 24 ((jedec_id) >> 8) & 0xff, \ 25 (jedec_id) & 0xff, \ 26 ((ext_id) >> 8) & 0xff, \ 27 (ext_id) & 0xff, \ 28 }, \ 29 .id_len = (!(jedec_id) ? 0 : (3 + ((ext_id) ? 2 : 0))), \ 30 .sector_size = (_sector_size), \ 31 .n_sectors = (_n_sectors), \ 32 .page_size = _page_size, \ 33 .flags = (_flags), 34 35 /* SPI/QSPI flash device params structure */ 36 const struct spi_flash_info spi_flash_ids[] = { 37 {"W25Q64CV", FINFO(0xef4017, 0x0, 64 * 1024, 128, 256, WR_QPP | SECT_4K)}, 38 {"W25Q64DW", FINFO(0xef6017, 0x0, 64 * 1024, 128, 256, WR_QPP | SECT_4K)}, 39 {"W25Q32", FINFO(0xef4016, 0x0, 64 * 1024, 64, 256, SECT_4K)}, 40 {"MX25l3205D", FINFO(0xc22016, 0x0, 64 * 1024, 64, 256, SECT_4K)}, 41 }; 42 43 static void spi_flash_addr(uint32_t addr, uint8_t *cmd) 44 { 45 /* 46 * cmd[0] holds a SPI Flash command, stored earlier 47 * cmd[1/2/3] holds 24bit flash address 48 */ 49 cmd[1] = addr >> 16; 50 cmd[2] = addr >> 8; 51 cmd[3] = addr >> 0; 52 } 53 54 static const struct spi_flash_info *spi_flash_read_id(void) 55 { 56 const struct spi_flash_info *info; 57 uint8_t id[SPI_FLASH_MAX_ID_LEN]; 58 int ret; 59 60 ret = spi_flash_cmd(CMD_READ_ID, id, SPI_FLASH_MAX_ID_LEN); 61 if (ret < 0) { 62 ERROR("SF: Error %d reading JEDEC ID\n", ret); 63 return NULL; 64 } 65 66 for (info = spi_flash_ids; info->name != NULL; info++) { 67 if (info->id_len) { 68 if (!memcmp(info->id, id, info->id_len)) 69 return info; 70 } 71 } 72 73 printf("SF: unrecognized JEDEC id bytes: %02x, %02x, %02x\n", 74 id[0], id[1], id[2]); 75 return NULL; 76 } 77 78 /* Enable writing on the SPI flash */ 79 static inline int spi_flash_cmd_write_enable(struct spi_flash *flash) 80 { 81 return spi_flash_cmd(CMD_WRITE_ENABLE, NULL, 0); 82 } 83 84 static int spi_flash_cmd_wait(struct spi_flash *flash) 85 { 86 uint8_t cmd; 87 uint32_t i; 88 uint8_t status; 89 int ret; 90 91 i = 0; 92 while (1) { 93 cmd = CMD_RDSR; 94 ret = spi_flash_cmd_read(&cmd, 1, &status, 1); 95 if (ret < 0) { 96 ERROR("SF: cmd wait failed\n"); 97 break; 98 } 99 if (!(status & STATUS_WIP)) 100 break; 101 102 i++; 103 if (i >= QSPI_WAIT_TIMEOUT_US) { 104 ERROR("SF: cmd wait timeout\n"); 105 ret = -1; 106 break; 107 } 108 udelay(1); 109 } 110 111 return ret; 112 } 113 114 static int spi_flash_write_common(struct spi_flash *flash, const uint8_t *cmd, 115 size_t cmd_len, const void *buf, 116 size_t buf_len) 117 { 118 int ret; 119 120 ret = spi_flash_cmd_write_enable(flash); 121 if (ret < 0) { 122 ERROR("SF: enabling write failed\n"); 123 return ret; 124 } 125 126 ret = spi_flash_cmd_write(cmd, cmd_len, buf, buf_len); 127 if (ret < 0) { 128 ERROR("SF: write cmd failed\n"); 129 return ret; 130 } 131 132 ret = spi_flash_cmd_wait(flash); 133 if (ret < 0) { 134 ERROR("SF: write timed out\n"); 135 return ret; 136 } 137 138 return ret; 139 } 140 141 static int spi_flash_read_common(const uint8_t *cmd, size_t cmd_len, 142 void *data, size_t data_len) 143 { 144 int ret; 145 146 ret = spi_flash_cmd_read(cmd, cmd_len, data, data_len); 147 if (ret < 0) { 148 ERROR("SF: read cmd failed\n"); 149 return ret; 150 } 151 152 return ret; 153 } 154 155 int spi_flash_read(struct spi_flash *flash, uint32_t offset, 156 uint32_t len, void *data) 157 { 158 uint32_t read_len = 0, read_addr; 159 uint8_t cmd[SPI_FLASH_CMD_LEN]; 160 int ret; 161 162 ret = spi_claim_bus(); 163 if (ret) { 164 ERROR("SF: unable to claim SPI bus\n"); 165 return ret; 166 } 167 168 cmd[0] = CMD_READ_NORMAL; 169 while (len) { 170 read_addr = offset; 171 read_len = MIN(flash->page_size, (len - read_len)); 172 spi_flash_addr(read_addr, cmd); 173 174 ret = spi_flash_read_common(cmd, sizeof(cmd), data, read_len); 175 if (ret < 0) { 176 ERROR("SF: read failed\n"); 177 break; 178 } 179 180 offset += read_len; 181 len -= read_len; 182 data += read_len; 183 } 184 SPI_DEBUG("SF read done\n"); 185 186 spi_release_bus(); 187 return ret; 188 } 189 190 int spi_flash_write(struct spi_flash *flash, uint32_t offset, 191 uint32_t len, void *buf) 192 { 193 unsigned long byte_addr, page_size; 194 uint8_t cmd[SPI_FLASH_CMD_LEN]; 195 uint32_t chunk_len, actual; 196 uint32_t write_addr; 197 int ret; 198 199 ret = spi_claim_bus(); 200 if (ret) { 201 ERROR("SF: unable to claim SPI bus\n"); 202 return ret; 203 } 204 205 page_size = flash->page_size; 206 207 cmd[0] = flash->write_cmd; 208 for (actual = 0; actual < len; actual += chunk_len) { 209 write_addr = offset; 210 byte_addr = offset % page_size; 211 chunk_len = MIN(len - actual, 212 (uint32_t)(page_size - byte_addr)); 213 spi_flash_addr(write_addr, cmd); 214 215 SPI_DEBUG("SF:0x%p=>cmd:{0x%02x 0x%02x%02x%02x} chunk_len:%d\n", 216 buf + actual, cmd[0], cmd[1], 217 cmd[2], cmd[3], chunk_len); 218 219 ret = spi_flash_write_common(flash, cmd, sizeof(cmd), 220 buf + actual, chunk_len); 221 if (ret < 0) { 222 ERROR("SF: write cmd failed\n"); 223 break; 224 } 225 226 offset += chunk_len; 227 } 228 SPI_DEBUG("SF write done\n"); 229 230 spi_release_bus(); 231 return ret; 232 } 233 234 int spi_flash_erase(struct spi_flash *flash, uint32_t offset, uint32_t len) 235 { 236 uint8_t cmd[SPI_FLASH_CMD_LEN]; 237 uint32_t erase_size, erase_addr; 238 int ret; 239 240 erase_size = flash->erase_size; 241 242 if (offset % erase_size || len % erase_size) { 243 ERROR("SF: Erase offset/length not multiple of erase size\n"); 244 return -1; 245 } 246 247 ret = spi_claim_bus(); 248 if (ret) { 249 ERROR("SF: unable to claim SPI bus\n"); 250 return ret; 251 } 252 253 cmd[0] = flash->erase_cmd; 254 while (len) { 255 erase_addr = offset; 256 spi_flash_addr(erase_addr, cmd); 257 258 SPI_DEBUG("SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1], 259 cmd[2], cmd[3], erase_addr); 260 261 ret = spi_flash_write_common(flash, cmd, sizeof(cmd), NULL, 0); 262 if (ret < 0) { 263 ERROR("SF: erase failed\n"); 264 break; 265 } 266 267 offset += erase_size; 268 len -= erase_size; 269 } 270 SPI_DEBUG("sf erase done\n"); 271 272 spi_release_bus(); 273 return ret; 274 } 275 276 int spi_flash_probe(struct spi_flash *flash) 277 { 278 const struct spi_flash_info *info = NULL; 279 int ret; 280 281 ret = spi_claim_bus(); 282 if (ret) { 283 ERROR("SF: Unable to claim SPI bus\n"); 284 ERROR("SF: probe failed\n"); 285 return ret; 286 } 287 288 info = spi_flash_read_id(); 289 if (!info) 290 goto probe_fail; 291 292 INFO("Flash Name: %s sectors %x, sec size %x\n", 293 info->name, info->n_sectors, 294 info->sector_size); 295 flash->size = info->n_sectors * info->sector_size; 296 flash->sector_size = info->sector_size; 297 flash->page_size = info->page_size; 298 flash->flags = info->flags; 299 300 flash->read_cmd = CMD_READ_NORMAL; 301 flash->write_cmd = CMD_PAGE_PROGRAM; 302 flash->erase_cmd = CMD_ERASE_64K; 303 flash->erase_size = ERASE_SIZE_64K; 304 305 probe_fail: 306 spi_release_bus(); 307 return ret; 308 } 309