[U-Boot] [PATCH 1/2] altera_qspi: add lock unlock ops
Thomas Chou
thomas at wytron.com.tw
Sun Nov 29 12:38:22 CET 2015
Add lock() and unlock() mtd ops to altera_qspi.
Signed-off-by: Thomas Chou <thomas at 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
More information about the U-Boot
mailing list