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