[U-Boot] [PATCH 1/2] altera_qspi: add lock unlock ops

Add lock() and unlock() mtd ops to altera_qspi.
Signed-off-by: Thomas Chou thomas@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))

Fix erase and write error code, which should be "protected".
Signed-off-by: Thomas Chou thomas@wytron.com.tw --- drivers/mtd/altera_qspi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/mtd/altera_qspi.c b/drivers/mtd/altera_qspi.c index 89f04a4..cf45e73 100644 --- a/drivers/mtd/altera_qspi.c +++ b/drivers/mtd/altera_qspi.c @@ -77,7 +77,7 @@ int flash_erase(flash_info_t *info, int s_first, int s_last) instr.len = mtd->erasesize * (s_last + 1 - s_first); ret = mtd_erase(mtd, &instr); if (ret) - return ERR_NOT_ERASED; + return ERR_PROTECTED;
return 0; } @@ -94,7 +94,7 @@ int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
ret = mtd_write(mtd, to, cnt, &retlen, src); if (ret) - return ERR_NOT_ERASED; + return ERR_PROTECTED;
return 0; }

On Sunday, November 29, 2015 at 12:38:23 PM, Thomas Chou wrote:
Fix erase and write error code, which should be "protected".
Can you elaborate on why do you think this change is correct please ? That reasoning should be part of the patch description.
Signed-off-by: Thomas Chou thomas@wytron.com.tw
drivers/mtd/altera_qspi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/mtd/altera_qspi.c b/drivers/mtd/altera_qspi.c index 89f04a4..cf45e73 100644 --- a/drivers/mtd/altera_qspi.c +++ b/drivers/mtd/altera_qspi.c @@ -77,7 +77,7 @@ int flash_erase(flash_info_t *info, int s_first, int s_last) instr.len = mtd->erasesize * (s_last + 1 - s_first); ret = mtd_erase(mtd, &instr); if (ret)
return ERR_NOT_ERASED;
return ERR_PROTECTED;
return 0;
} @@ -94,7 +94,7 @@ int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
ret = mtd_write(mtd, to, cnt, &retlen, src); if (ret)
return ERR_NOT_ERASED;
return ERR_PROTECTED;
return 0;
}
Best regards, Marek Vasut

On Sun, 2015-11-29 at 19:38 +0800, Thomas Chou wrote:
Fix erase and write error code, which should be "protected".
Signed-off-by: Thomas Chou thomas@wytron.com.tw
drivers/mtd/altera_qspi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
Acked-by: Chin Liang See clsee@altera.com
Thanks Chin Liang

On Sunday, November 29, 2015 at 12:38:22 PM, Thomas Chou wrote:
Add lock() and unlock() mtd ops to altera_qspi.
Signed-off-by: Thomas Chou thomas@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;
u64 please.
- 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);
Do you really need the typecasts here ? %llx should do it for the len and dropping the l should do it for ofs I think.
- }
- 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;
What are all these magic numbers ?
- }
+}
+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;
u64
- u32 mem_op;
- u32 sr_bp;
- u32 sr_tb;
All were just minor nits, thanks!
Best regards, Marek Vasut

On Sun, 2015-11-29 at 19:38 +0800, Thomas Chou wrote:
Add lock() and unlock() mtd ops to altera_qspi.
Signed-off-by: Thomas Chou thomas@wytron.com.tw
drivers/mtd/altera_qspi.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+)
Acked-by: Chin Liang See clsee@altera.com
As agreed with Marek, it would be great that some of the magic number can be converted as defines. FYI, I am opening both Quad SPI controller spec and EPCQ spec to review this :)
Thanks Chin Liang

Add lock() and unlock() mtd ops to altera_qspi.
Signed-off-by: Thomas Chou thomas@wytron.com.tw --- v2 change uint64_t to u64 as suggested by Marek. add macros for status register. limit get_locked_range to mtd->size.
drivers/mtd/altera_qspi.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+)
diff --git a/drivers/mtd/altera_qspi.c b/drivers/mtd/altera_qspi.c index 50c6e0e..61a6a5e 100644 --- a/drivers/mtd/altera_qspi.c +++ b/drivers/mtd/altera_qspi.c @@ -14,6 +14,14 @@
DECLARE_GLOBAL_DATA_PTR;
+/* The STATUS register */ +#define QUADSPI_SR_BP0 BIT(2) +#define QUADSPI_SR_BP1 BIT(3) +#define QUADSPI_SR_BP2 BIT(4) +#define QUADSPI_SR_BP2_0 GENMASK(4, 2) +#define QUADSPI_SR_BP3 BIT(6) +#define QUADSPI_SR_TB BIT(5) + /* * The QUADSPI_MEM_OP register is used to do memory protect and erase operations */ @@ -46,10 +54,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; + u64 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 %08llX +%llX", + info->start[0] + ofs, len); + } + putc('\n'); }
int flash_erase(flash_info_t *info, int s_first, int s_last) @@ -171,6 +193,77 @@ 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; + int shift0 = ffs(QUADSPI_SR_BP2_0) - 1; + int shift3 = ffs(QUADSPI_SR_BP3) - 1 - 3; + u32 stat = readl(®s->rd_status); + unsigned pow = ((stat & QUADSPI_SR_BP2_0) >> shift0) | + ((stat & QUADSPI_SR_BP3) >> shift3); + + *ofs = 0; + *len = 0; + if (pow) { + *len = mtd->erasesize << (pow - 1); + if (*len > mtd->size) + *len = mtd->size; + if (!(stat & QUADSPI_SR_TB)) + *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; + u32 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 +289,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))

Fix erase and write error code, which should be "protected".
From the "Embedded Peripherals IP User Guide" of Altera,
The "Illegal write" flag indicates that a write instruction is targeting a protected sector on the flash memory. This bit is set to indicate that the IP has cancelled a write instruction.
The "Illegal erase" flag indicates that an erase instruction has been set to a protected sector on the flash memory. This bit is set to indicate that the IP has cancelled the erase instruction.
Signed-off-by: Thomas Chou thomas@wytron.com.tw --- v2 add description as suggested by Marek.
drivers/mtd/altera_qspi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/mtd/altera_qspi.c b/drivers/mtd/altera_qspi.c index 61a6a5e..617bf5d 100644 --- a/drivers/mtd/altera_qspi.c +++ b/drivers/mtd/altera_qspi.c @@ -85,7 +85,7 @@ int flash_erase(flash_info_t *info, int s_first, int s_last) instr.len = mtd->erasesize * (s_last + 1 - s_first); ret = mtd_erase(mtd, &instr); if (ret) - return ERR_NOT_ERASED; + return ERR_PROTECTED;
return 0; } @@ -102,7 +102,7 @@ int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
ret = mtd_write(mtd, to, cnt, &retlen, src); if (ret) - return ERR_NOT_ERASED; + return ERR_PROTECTED;
return 0; }

On Tuesday, December 01, 2015 at 10:07:56 AM, Thomas Chou wrote:
Fix erase and write error code, which should be "protected".
From the "Embedded Peripherals IP User Guide" of Altera,
The "Illegal write" flag indicates that a write instruction is targeting a protected sector on the flash memory. This bit is set to indicate that the IP has cancelled a write instruction.
The "Illegal erase" flag indicates that an erase instruction has been set to a protected sector on the flash memory. This bit is set to indicate that the IP has cancelled the erase instruction.
Signed-off-by: Thomas Chou thomas@wytron.com.tw
Reviewed-by: Marek Vasut marex@denx.de
Best regards, Marek Vasut

On 2015年12月01日 17:07, Thomas Chou wrote:
Fix erase and write error code, which should be "protected".
From the "Embedded Peripherals IP User Guide" of Altera,
The "Illegal write" flag indicates that a write instruction is targeting a protected sector on the flash memory. This bit is set to indicate that the IP has cancelled a write instruction.
The "Illegal erase" flag indicates that an erase instruction has been set to a protected sector on the flash memory. This bit is set to indicate that the IP has cancelled the erase instruction.
Signed-off-by: Thomas Chou thomas@wytron.com.tw
v2 add description as suggested by Marek.
drivers/mtd/altera_qspi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
Applied to u-boot-nios.

On Tuesday, December 01, 2015 at 10:07:55 AM, Thomas Chou wrote:
Add lock() and unlock() mtd ops to altera_qspi.
Signed-off-by: Thomas Chou thomas@wytron.com.tw
Reviewed-by: Marek Vasut marex@denx.de
Best regards, Marek Vasut

On 2015年12月01日 17:07, Thomas Chou wrote:
Add lock() and unlock() mtd ops to altera_qspi.
Signed-off-by: Thomas Chou thomas@wytron.com.tw
v2 change uint64_t to u64 as suggested by Marek. add macros for status register. limit get_locked_range to mtd->size.
drivers/mtd/altera_qspi.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+)
Applied to u-boot-nios.
participants (3)
-
Chin Liang See
-
Marek Vasut
-
Thomas Chou