1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2015 Thomas Chou <thomas@wytron.com.tw> 4 */ 5 6 #include <common.h> 7 #include <console.h> 8 #include <dm.h> 9 #include <errno.h> 10 #include <fdt_support.h> 11 #include <flash.h> 12 #include <mtd.h> 13 #include <asm/io.h> 14 15 DECLARE_GLOBAL_DATA_PTR; 16 17 /* The STATUS register */ 18 #define QUADSPI_SR_BP0 BIT(2) 19 #define QUADSPI_SR_BP1 BIT(3) 20 #define QUADSPI_SR_BP2 BIT(4) 21 #define QUADSPI_SR_BP2_0 GENMASK(4, 2) 22 #define QUADSPI_SR_BP3 BIT(6) 23 #define QUADSPI_SR_TB BIT(5) 24 25 /* 26 * The QUADSPI_MEM_OP register is used to do memory protect and erase operations 27 */ 28 #define QUADSPI_MEM_OP_BULK_ERASE 0x00000001 29 #define QUADSPI_MEM_OP_SECTOR_ERASE 0x00000002 30 #define QUADSPI_MEM_OP_SECTOR_PROTECT 0x00000003 31 32 /* 33 * The QUADSPI_ISR register is used to determine whether an invalid write or 34 * erase operation trigerred an interrupt 35 */ 36 #define QUADSPI_ISR_ILLEGAL_ERASE BIT(0) 37 #define QUADSPI_ISR_ILLEGAL_WRITE BIT(1) 38 39 struct altera_qspi_regs { 40 u32 rd_status; 41 u32 rd_sid; 42 u32 rd_rdid; 43 u32 mem_op; 44 u32 isr; 45 u32 imr; 46 u32 chip_select; 47 }; 48 49 struct altera_qspi_platdata { 50 struct altera_qspi_regs *regs; 51 void *base; 52 unsigned long size; 53 }; 54 55 static uint flash_verbose; 56 flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* FLASH chips info */ 57 58 static void altera_qspi_get_locked_range(struct mtd_info *mtd, loff_t *ofs, 59 uint64_t *len); 60 61 void flash_print_info(flash_info_t *info) 62 { 63 struct mtd_info *mtd = info->mtd; 64 loff_t ofs; 65 u64 len; 66 67 printf("Altera QSPI flash Size: %ld MB in %d Sectors\n", 68 info->size >> 20, info->sector_count); 69 altera_qspi_get_locked_range(mtd, &ofs, &len); 70 printf(" %08lX +%lX", info->start[0], info->size); 71 if (len) { 72 printf(", protected %08llX +%llX", 73 info->start[0] + ofs, len); 74 } 75 putc('\n'); 76 } 77 78 void flash_set_verbose(uint v) 79 { 80 flash_verbose = v; 81 } 82 83 int flash_erase(flash_info_t *info, int s_first, int s_last) 84 { 85 struct mtd_info *mtd = info->mtd; 86 struct erase_info instr; 87 int ret; 88 89 memset(&instr, 0, sizeof(instr)); 90 instr.mtd = mtd; 91 instr.addr = mtd->erasesize * s_first; 92 instr.len = mtd->erasesize * (s_last + 1 - s_first); 93 flash_set_verbose(1); 94 ret = mtd_erase(mtd, &instr); 95 flash_set_verbose(0); 96 if (ret) 97 return ERR_PROTECTED; 98 99 puts(" done\n"); 100 return 0; 101 } 102 103 int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt) 104 { 105 struct mtd_info *mtd = info->mtd; 106 struct udevice *dev = mtd->dev; 107 struct altera_qspi_platdata *pdata = dev_get_platdata(dev); 108 ulong base = (ulong)pdata->base; 109 loff_t to = addr - base; 110 size_t retlen; 111 int ret; 112 113 ret = mtd_write(mtd, to, cnt, &retlen, src); 114 if (ret) 115 return ERR_PROTECTED; 116 117 return 0; 118 } 119 120 unsigned long flash_init(void) 121 { 122 struct udevice *dev; 123 124 /* probe every MTD device */ 125 for (uclass_first_device(UCLASS_MTD, &dev); 126 dev; 127 uclass_next_device(&dev)) { 128 } 129 130 return flash_info[0].size; 131 } 132 133 static int altera_qspi_erase(struct mtd_info *mtd, struct erase_info *instr) 134 { 135 struct udevice *dev = mtd->dev; 136 struct altera_qspi_platdata *pdata = dev_get_platdata(dev); 137 struct altera_qspi_regs *regs = pdata->regs; 138 size_t addr = instr->addr; 139 size_t len = instr->len; 140 size_t end = addr + len; 141 u32 sect; 142 u32 stat; 143 u32 *flash, *last; 144 145 instr->state = MTD_ERASING; 146 addr &= ~(mtd->erasesize - 1); /* get lower aligned address */ 147 while (addr < end) { 148 if (ctrlc()) { 149 if (flash_verbose) 150 putc('\n'); 151 instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN; 152 instr->state = MTD_ERASE_FAILED; 153 mtd_erase_callback(instr); 154 return -EIO; 155 } 156 flash = pdata->base + addr; 157 last = pdata->base + addr + mtd->erasesize; 158 /* skip erase if sector is blank */ 159 while (flash < last) { 160 if (readl(flash) != 0xffffffff) 161 break; 162 flash++; 163 } 164 if (flash < last) { 165 sect = addr / mtd->erasesize; 166 sect <<= 8; 167 sect |= QUADSPI_MEM_OP_SECTOR_ERASE; 168 debug("erase %08x\n", sect); 169 writel(sect, ®s->mem_op); 170 stat = readl(®s->isr); 171 if (stat & QUADSPI_ISR_ILLEGAL_ERASE) { 172 /* erase failed, sector might be protected */ 173 debug("erase %08x fail %x\n", sect, stat); 174 writel(stat, ®s->isr); /* clear isr */ 175 instr->fail_addr = addr; 176 instr->state = MTD_ERASE_FAILED; 177 mtd_erase_callback(instr); 178 return -EIO; 179 } 180 if (flash_verbose) 181 putc('.'); 182 } else { 183 if (flash_verbose) 184 putc(','); 185 } 186 addr += mtd->erasesize; 187 } 188 instr->state = MTD_ERASE_DONE; 189 mtd_erase_callback(instr); 190 191 return 0; 192 } 193 194 static int altera_qspi_read(struct mtd_info *mtd, loff_t from, size_t len, 195 size_t *retlen, u_char *buf) 196 { 197 struct udevice *dev = mtd->dev; 198 struct altera_qspi_platdata *pdata = dev_get_platdata(dev); 199 200 memcpy_fromio(buf, pdata->base + from, len); 201 *retlen = len; 202 203 return 0; 204 } 205 206 static int altera_qspi_write(struct mtd_info *mtd, loff_t to, size_t len, 207 size_t *retlen, const u_char *buf) 208 { 209 struct udevice *dev = mtd->dev; 210 struct altera_qspi_platdata *pdata = dev_get_platdata(dev); 211 struct altera_qspi_regs *regs = pdata->regs; 212 u32 stat; 213 214 memcpy_toio(pdata->base + to, buf, len); 215 /* check whether write triggered a illegal write interrupt */ 216 stat = readl(®s->isr); 217 if (stat & QUADSPI_ISR_ILLEGAL_WRITE) { 218 /* write failed, sector might be protected */ 219 debug("write fail %x\n", stat); 220 writel(stat, ®s->isr); /* clear isr */ 221 return -EIO; 222 } 223 *retlen = len; 224 225 return 0; 226 } 227 228 static void altera_qspi_sync(struct mtd_info *mtd) 229 { 230 } 231 232 static void altera_qspi_get_locked_range(struct mtd_info *mtd, loff_t *ofs, 233 uint64_t *len) 234 { 235 struct udevice *dev = mtd->dev; 236 struct altera_qspi_platdata *pdata = dev_get_platdata(dev); 237 struct altera_qspi_regs *regs = pdata->regs; 238 int shift0 = ffs(QUADSPI_SR_BP2_0) - 1; 239 int shift3 = ffs(QUADSPI_SR_BP3) - 1 - 3; 240 u32 stat = readl(®s->rd_status); 241 unsigned pow = ((stat & QUADSPI_SR_BP2_0) >> shift0) | 242 ((stat & QUADSPI_SR_BP3) >> shift3); 243 244 *ofs = 0; 245 *len = 0; 246 if (pow) { 247 *len = mtd->erasesize << (pow - 1); 248 if (*len > mtd->size) 249 *len = mtd->size; 250 if (!(stat & QUADSPI_SR_TB)) 251 *ofs = mtd->size - *len; 252 } 253 } 254 255 static int altera_qspi_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) 256 { 257 struct udevice *dev = mtd->dev; 258 struct altera_qspi_platdata *pdata = dev_get_platdata(dev); 259 struct altera_qspi_regs *regs = pdata->regs; 260 u32 sector_start, sector_end; 261 u32 num_sectors; 262 u32 mem_op; 263 u32 sr_bp; 264 u32 sr_tb; 265 266 num_sectors = mtd->size / mtd->erasesize; 267 sector_start = ofs / mtd->erasesize; 268 sector_end = (ofs + len) / mtd->erasesize; 269 270 if (sector_start >= num_sectors / 2) { 271 sr_bp = fls(num_sectors - 1 - sector_start) + 1; 272 sr_tb = 0; 273 } else if (sector_end < num_sectors / 2) { 274 sr_bp = fls(sector_end) + 1; 275 sr_tb = 1; 276 } else { 277 sr_bp = 15; 278 sr_tb = 0; 279 } 280 281 mem_op = (sr_tb << 12) | (sr_bp << 8); 282 mem_op |= QUADSPI_MEM_OP_SECTOR_PROTECT; 283 debug("lock %08x\n", mem_op); 284 writel(mem_op, ®s->mem_op); 285 286 return 0; 287 } 288 289 static int altera_qspi_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) 290 { 291 struct udevice *dev = mtd->dev; 292 struct altera_qspi_platdata *pdata = dev_get_platdata(dev); 293 struct altera_qspi_regs *regs = pdata->regs; 294 u32 mem_op; 295 296 mem_op = QUADSPI_MEM_OP_SECTOR_PROTECT; 297 debug("unlock %08x\n", mem_op); 298 writel(mem_op, ®s->mem_op); 299 300 return 0; 301 } 302 303 static int altera_qspi_probe(struct udevice *dev) 304 { 305 struct altera_qspi_platdata *pdata = dev_get_platdata(dev); 306 struct altera_qspi_regs *regs = pdata->regs; 307 unsigned long base = (unsigned long)pdata->base; 308 struct mtd_info *mtd; 309 flash_info_t *flash = &flash_info[0]; 310 u32 rdid; 311 int i; 312 313 rdid = readl(®s->rd_rdid); 314 debug("rdid %x\n", rdid); 315 316 mtd = dev_get_uclass_priv(dev); 317 mtd->dev = dev; 318 mtd->name = "nor0"; 319 mtd->type = MTD_NORFLASH; 320 mtd->flags = MTD_CAP_NORFLASH; 321 mtd->size = 1 << ((rdid & 0xff) - 6); 322 mtd->writesize = 1; 323 mtd->writebufsize = mtd->writesize; 324 mtd->_erase = altera_qspi_erase; 325 mtd->_read = altera_qspi_read; 326 mtd->_write = altera_qspi_write; 327 mtd->_sync = altera_qspi_sync; 328 mtd->_lock = altera_qspi_lock; 329 mtd->_unlock = altera_qspi_unlock; 330 mtd->numeraseregions = 0; 331 mtd->erasesize = 0x10000; 332 if (add_mtd_device(mtd)) 333 return -ENOMEM; 334 335 flash->mtd = mtd; 336 flash->size = mtd->size; 337 flash->sector_count = mtd->size / mtd->erasesize; 338 flash->flash_id = rdid; 339 flash->start[0] = base; 340 for (i = 1; i < flash->sector_count; i++) 341 flash->start[i] = flash->start[i - 1] + mtd->erasesize; 342 gd->bd->bi_flashstart = base; 343 344 return 0; 345 } 346 347 static int altera_qspi_ofdata_to_platdata(struct udevice *dev) 348 { 349 struct altera_qspi_platdata *pdata = dev_get_platdata(dev); 350 void *blob = (void *)gd->fdt_blob; 351 int node = dev_of_offset(dev); 352 const char *list, *end; 353 const fdt32_t *cell; 354 void *base; 355 unsigned long addr, size; 356 int parent, addrc, sizec; 357 int len, idx; 358 359 /* 360 * decode regs. there are multiple reg tuples, and they need to 361 * match with reg-names. 362 */ 363 parent = fdt_parent_offset(blob, node); 364 fdt_support_default_count_cells(blob, parent, &addrc, &sizec); 365 list = fdt_getprop(blob, node, "reg-names", &len); 366 if (!list) 367 return -ENOENT; 368 end = list + len; 369 cell = fdt_getprop(blob, node, "reg", &len); 370 if (!cell) 371 return -ENOENT; 372 idx = 0; 373 while (list < end) { 374 addr = fdt_translate_address((void *)blob, 375 node, cell + idx); 376 size = fdt_addr_to_cpu(cell[idx + addrc]); 377 base = map_physmem(addr, size, MAP_NOCACHE); 378 len = strlen(list); 379 if (strcmp(list, "avl_csr") == 0) { 380 pdata->regs = base; 381 } else if (strcmp(list, "avl_mem") == 0) { 382 pdata->base = base; 383 pdata->size = size; 384 } 385 idx += addrc + sizec; 386 list += (len + 1); 387 } 388 389 return 0; 390 } 391 392 static const struct udevice_id altera_qspi_ids[] = { 393 { .compatible = "altr,quadspi-1.0" }, 394 {} 395 }; 396 397 U_BOOT_DRIVER(altera_qspi) = { 398 .name = "altera_qspi", 399 .id = UCLASS_MTD, 400 .of_match = altera_qspi_ids, 401 .ofdata_to_platdata = altera_qspi_ofdata_to_platdata, 402 .platdata_auto_alloc_size = sizeof(struct altera_qspi_platdata), 403 .probe = altera_qspi_probe, 404 }; 405