Add lock() and unlock() mtd ops to altera_qspi. Signed-off-by: Thomas Chou <tho...@wytron.com.tw> --- drivers/mtd/altera_qspi.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+)
diff --git a/drivers/mtd/altera_qspi.c b/drivers/mtd/altera_qspi.c index 50c6e0e..89f04a4 100644 --- a/drivers/mtd/altera_qspi.c +++ b/drivers/mtd/altera_qspi.c @@ -46,10 +46,24 @@ struct altera_qspi_platdata { flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* FLASH chips info */ +static void altera_qspi_get_locked_range(struct mtd_info *mtd, loff_t *ofs, + uint64_t *len); + void flash_print_info(flash_info_t *info) { + struct mtd_info *mtd = info->mtd; + loff_t ofs; + uint64_t len; + printf("Altera QSPI flash Size: %ld MB in %d Sectors\n", info->size >> 20, info->sector_count); + altera_qspi_get_locked_range(mtd, &ofs, &len); + printf(" %08lX +%lX", info->start[0], info->size); + if (len) { + printf(", protected %08lX +%lX", + info->start[0] + (ulong)ofs, (ulong)len); + } + putc('\n'); } int flash_erase(flash_info_t *info, int s_first, int s_last) @@ -171,6 +185,72 @@ static void altera_qspi_sync(struct mtd_info *mtd) { } +static void altera_qspi_get_locked_range(struct mtd_info *mtd, loff_t *ofs, + uint64_t *len) +{ + struct udevice *dev = mtd->dev; + struct altera_qspi_platdata *pdata = dev_get_platdata(dev); + struct altera_qspi_regs *regs = pdata->regs; + u32 stat = readl(®s->rd_status); + unsigned pow = ((stat >> 2) & 0x7) | ((stat >> 3) & 0x8); + + *ofs = 0; + *len = 0; + if (pow) { + *len = mtd->erasesize << (pow - 1); + if (!(stat & 0x20)) + *ofs = mtd->size - *len; + } +} + +static int altera_qspi_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) +{ + struct udevice *dev = mtd->dev; + struct altera_qspi_platdata *pdata = dev_get_platdata(dev); + struct altera_qspi_regs *regs = pdata->regs; + u32 sector_start, sector_end; + uint64_t num_sectors; + u32 mem_op; + u32 sr_bp; + u32 sr_tb; + + num_sectors = mtd->size / mtd->erasesize; + sector_start = ofs / mtd->erasesize; + sector_end = (ofs + len) / mtd->erasesize; + + if (sector_start >= num_sectors / 2) { + sr_bp = fls(num_sectors - 1 - sector_start) + 1; + sr_tb = 0; + } else if (sector_end < num_sectors / 2) { + sr_bp = fls(sector_end) + 1; + sr_tb = 1; + } else { + sr_bp = 15; + sr_tb = 0; + } + + mem_op = (sr_tb << 12) | (sr_bp << 8); + mem_op |= QUADSPI_MEM_OP_SECTOR_PROTECT; + debug("lock %08x\n", mem_op); + writel(mem_op, ®s->mem_op); + + return 0; +} + +static int altera_qspi_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) +{ + struct udevice *dev = mtd->dev; + struct altera_qspi_platdata *pdata = dev_get_platdata(dev); + struct altera_qspi_regs *regs = pdata->regs; + u32 mem_op; + + mem_op = QUADSPI_MEM_OP_SECTOR_PROTECT; + debug("unlock %08x\n", mem_op); + writel(mem_op, ®s->mem_op); + + return 0; +} + static int altera_qspi_probe(struct udevice *dev) { struct altera_qspi_platdata *pdata = dev_get_platdata(dev); @@ -196,6 +276,8 @@ static int altera_qspi_probe(struct udevice *dev) mtd->_read = altera_qspi_read; mtd->_write = altera_qspi_write; mtd->_sync = altera_qspi_sync; + mtd->_lock = altera_qspi_lock; + mtd->_unlock = altera_qspi_unlock; mtd->numeraseregions = 0; mtd->erasesize = 0x10000; if (add_mtd_device(mtd)) -- 2.5.0 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot