History

mtd: cfi_cmdset_0002: Add support for polling status register

HyperFlash devices are compliant with CFI AMD/Fujitsu Extended Command Set (0x0002) for flash operations, therefore drivers/mtd/chips/cfi_cmdset_0002.c can be used as is. But these devices do not support DQ polling method of determining chip ready/good status. These flashes provide Status Register whose bits can be polled to know status of flash operation. Cypress HyperFlash datasheet here[1], talks about CFI Amd/Fujitsu Extended Query version 1.5. Bit 0 of "Software Features supported" field of CFI Primary Vendor-Specific Extended Query table indicates presence/absence of status register and Bit 1 indicates whether or not DQ polling is supported. Using these bits, its possible to determine whether flash supports DQ polling or need to use Status Register. Add support for polling Status Register to know device ready/status of erase/write operations when DQ polling is not supported. Print error messages on erase/program failure by looking at related Status Register bits. [1] https://www.cypress.com/file/213346/download

Vignesh Raghavendra committed 7 years ago

Commit 4844ef81 parent 99a125f2 files · +120 −17Browse files

Unified · Split

2 files
  1. drivers/mtd/chips/cfi_cmdset_0002.c +113 −17
  2. include/linux/mtd/cfi.h +7 −0
drivers/mtd/chips/cfi_cmdset_0002.c+113−17
@@ -49,6 +49,16 @@ · 48 unmodified lines
49#define SST49LF008A 0x005a49#define SST49LF008A 0x005a
50#define AT49BV6416 0x00d650#define AT49BV6416 0x00d6
51 51
52/*
53 * Status Register bit description. Used by flash devices that don't
54 * support DQ polling (e.g. HyperFlash)
55 */
56#define CFI_SR_DRB BIT(7)
57#define CFI_SR_ESB BIT(5)
58#define CFI_SR_PSB BIT(4)
59#define CFI_SR_WBASB BIT(3)
60#define CFI_SR_SLSB BIT(1)
61
52static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);62static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
53static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);63static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
54static int cfi_amdstd_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);64static int cfi_amdstd_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
@@ -97,6 +107,50 @@ static struct mtd_chip_driver cfi_amdstd_chipdrv = { · 42 unmodified lines
97 .module = THIS_MODULE107 .module = THIS_MODULE
98};108};
99 109
110/*
111 * Use status register to poll for Erase/write completion when DQ is not
112 * supported. This is indicated by Bit[1:0] of SoftwareFeatures field in
113 * CFI Primary Vendor-Specific Extended Query table 1.5
114 */
115static int cfi_use_status_reg(struct cfi_private *cfi)
116{
117 struct cfi_pri_amdstd *extp = cfi->cmdset_priv;
118 u8 poll_mask = CFI_POLL_STATUS_REG | CFI_POLL_DQ;
119
120 return extp->MinorVersion >= '5' &&
121 (extp->SoftwareFeatures & poll_mask) == CFI_POLL_STATUS_REG;
122}
123
124static void cfi_check_err_status(struct map_info *map, struct flchip *chip,
125 unsigned long adr)
126{
127 struct cfi_private *cfi = map->fldrv_priv;
128 map_word status;
129
130 if (!cfi_use_status_reg(cfi))
131 return;
132
133 cfi_send_gen_cmd(0x70, cfi->addr_unlock1, chip->start, map, cfi,
134 cfi->device_type, NULL);
135 status = map_read(map, adr);
136
137 if (map_word_bitsset(map, status, CMD(0x3a))) {
138 unsigned long chipstatus = MERGESTATUS(status);
139
140 if (chipstatus & CFI_SR_ESB)
141 pr_err("%s erase operation failed, status %lx\n",
142 map->name, chipstatus);
143 if (chipstatus & CFI_SR_PSB)
144 pr_err("%s program operation failed, status %lx\n",
145 map->name, chipstatus);
146 if (chipstatus & CFI_SR_WBASB)
147 pr_err("%s buffer program command aborted, status %lx\n",
148 map->name, chipstatus);
149 if (chipstatus & CFI_SR_SLSB)
150 pr_err("%s sector write protected, status %lx\n",
151 map->name, chipstatus);
152 }
153}
100 154
101/* #define DEBUG_CFI_FEATURES */155/* #define DEBUG_CFI_FEATURES */
102 156
@@ -742,10 +796,25 @@ static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd) · 639 unmodified lines
742 * correctly and is therefore not done (particularly with interleaved chips796 * correctly and is therefore not done (particularly with interleaved chips
743 * as each chip must be checked independently of the others).797 * as each chip must be checked independently of the others).
744 */798 */
745static int __xipram chip_ready(struct map_info *map, unsigned long addr)799static int __xipram chip_ready(struct map_info *map, struct flchip *chip,
800 unsigned long addr)
746{801{
802 struct cfi_private *cfi = map->fldrv_priv;
747 map_word d, t;803 map_word d, t;
748 804
805 if (cfi_use_status_reg(cfi)) {
806 map_word ready = CMD(CFI_SR_DRB);
807 /*
808 * For chips that support status register, check device
809 * ready bit
810 */
811 cfi_send_gen_cmd(0x70, cfi->addr_unlock1, chip->start, map, cfi,
812 cfi->device_type, NULL);
813 d = map_read(map, addr);
814
815 return map_word_andequal(map, d, ready, ready);
816 }
817
749 d = map_read(map, addr);818 d = map_read(map, addr);
750 t = map_read(map, addr);819 t = map_read(map, addr);
751 820
@@ -767,10 +836,30 @@ static int __xipram chip_ready(struct map_info *map, unsigned long addr) · 15 unmodified lines
767 * as each chip must be checked independently of the others).836 * as each chip must be checked independently of the others).
768 *837 *
769 */838 */
770static int __xipram chip_good(struct map_info *map, unsigned long addr, map_word expected)839static int __xipram chip_good(struct map_info *map, struct flchip *chip,
840 unsigned long addr, map_word expected)
771{841{
842 struct cfi_private *cfi = map->fldrv_priv;
772 map_word oldd, curd;843 map_word oldd, curd;
773 844
845 if (cfi_use_status_reg(cfi)) {
846 map_word ready = CMD(CFI_SR_DRB);
847 map_word err = CMD(CFI_SR_PSB | CFI_SR_ESB);
848 /*
849 * For chips that support status register, check device
850 * ready bit and Erase/Program status bit to know if
851 * operation succeeded.
852 */
853 cfi_send_gen_cmd(0x70, cfi->addr_unlock1, chip->start, map, cfi,
854 cfi->device_type, NULL);
855 curd = map_read(map, addr);
856
857 if (map_word_andequal(map, curd, ready, ready))
858 return !map_word_bitsset(map, curd, err);
859
860 return 0;
861 }
862
774 oldd = map_read(map, addr);863 oldd = map_read(map, addr);
775 curd = map_read(map, addr);864 curd = map_read(map, addr);
776 865
@@ -792,7 +881,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr · 15 unmodified lines
792 881
793 case FL_STATUS:882 case FL_STATUS:
794 for (;;) {883 for (;;) {
795 if (chip_ready(map, adr))884 if (chip_ready(map, chip, adr))
796 break;885 break;
797 886
798 if (time_after(jiffies, timeo)) {887 if (time_after(jiffies, timeo)) {
@@ -830,7 +919,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr · 31 unmodified lines
830 chip->state = FL_ERASE_SUSPENDING;919 chip->state = FL_ERASE_SUSPENDING;
831 chip->erase_suspended = 1;920 chip->erase_suspended = 1;
832 for (;;) {921 for (;;) {
833 if (chip_ready(map, adr))922 if (chip_ready(map, chip, adr))
834 break;923 break;
835 924
836 if (time_after(jiffies, timeo)) {925 if (time_after(jiffies, timeo)) {
@@ -1362,7 +1451,7 @@ static int do_otp_lock(struct map_info *map, struct flchip *chip, loff_t adr, · 525 unmodified lines
1362 /* wait for chip to become ready */1451 /* wait for chip to become ready */
1363 timeo = jiffies + msecs_to_jiffies(2);1452 timeo = jiffies + msecs_to_jiffies(2);
1364 for (;;) {1453 for (;;) {
1365 if (chip_ready(map, adr))1454 if (chip_ready(map, chip, adr))
1366 break;1455 break;
1367 1456
1368 if (time_after(jiffies, timeo)) {1457 if (time_after(jiffies, timeo)) {
@@ -1628,22 +1717,24 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip, · 259 unmodified lines
1628 continue;1717 continue;
1629 }1718 }
1630 1719
1631 if (time_after(jiffies, timeo) && !chip_ready(map, adr)){1720 if (time_after(jiffies, timeo) &&
1721 !chip_ready(map, chip, adr)) {
1632 xip_enable(map, chip, adr);1722 xip_enable(map, chip, adr);
1633 printk(KERN_WARNING "MTD %s(): software timeout\n", __func__);1723 printk(KERN_WARNING "MTD %s(): software timeout\n", __func__);
1634 xip_disable(map, chip, adr);1724 xip_disable(map, chip, adr);
1635 break;1725 break;
1636 }1726 }
1637 1727
1638 if (chip_ready(map, adr))1728 if (chip_ready(map, chip, adr))
1639 break;1729 break;
1640 1730
1641 /* Latency issues. Drop the lock, wait a while and retry */1731 /* Latency issues. Drop the lock, wait a while and retry */
1642 UDELAY(map, chip, adr, 1);1732 UDELAY(map, chip, adr, 1);
1643 }1733 }
1644 /* Did we succeed? */1734 /* Did we succeed? */
1645 if (!chip_good(map, adr, datum)) {1735 if (!chip_good(map, chip, adr, datum)) {
1646 /* reset on all failures. */1736 /* reset on all failures. */
1737 cfi_check_err_status(map, chip, adr);
1647 map_write(map, CMD(0xF0), chip->start);1738 map_write(map, CMD(0xF0), chip->start);
1648 /* FIXME - should have reset delay before continuing */1739 /* FIXME - should have reset delay before continuing */
1649 1740
@@ -1881,10 +1972,11 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, · 231 unmodified lines
1881 * We check "time_after" and "!chip_good" before checking "chip_good" to avoid1972 * We check "time_after" and "!chip_good" before checking "chip_good" to avoid
1882 * the failure due to scheduling.1973 * the failure due to scheduling.
1883 */1974 */
1884 if (time_after(jiffies, timeo) && !chip_good(map, adr, datum))1975 if (time_after(jiffies, timeo) &&
1976 !chip_good(map, chip, adr, datum))
1885 break;1977 break;
1886 1978
1887 if (chip_good(map, adr, datum)) {1979 if (chip_good(map, chip, adr, datum)) {
1888 xip_enable(map, chip, adr);1980 xip_enable(map, chip, adr);
1889 goto op_done;1981 goto op_done;
1890 }1982 }
@@ -1901,6 +1993,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, · 10 unmodified lines
1901 * See e.g.1993 * See e.g.
1902 * http://www.spansion.com/Support/Application%20Notes/MirrorBit_Write_Buffer_Prog_Page_Buffer_Read_AN.pdf1994 * http://www.spansion.com/Support/Application%20Notes/MirrorBit_Write_Buffer_Prog_Page_Buffer_Read_AN.pdf
1903 */1995 */
1996 cfi_check_err_status(map, chip, adr);
1904 cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi,1997 cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi,
1905 cfi->device_type, NULL);1998 cfi->device_type, NULL);
1906 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi,1999 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi,
@@ -2018,7 +2111,7 @@ static int cfi_amdstd_panic_wait(struct map_info *map, struct flchip *chip, · 111 unmodified lines
2018 * If the driver thinks the chip is idle, and no toggle bits2111 * If the driver thinks the chip is idle, and no toggle bits
2019 * are changing, then the chip is actually idle for sure.2112 * are changing, then the chip is actually idle for sure.
2020 */2113 */
2021 if (chip->state == FL_READY && chip_ready(map, adr))2114 if (chip->state == FL_READY && chip_ready(map, chip, adr))
2022 return 0;2115 return 0;
2023 2116
2024 /*2117 /*
@@ -2035,7 +2128,7 @@ static int cfi_amdstd_panic_wait(struct map_info *map, struct flchip *chip, · 10 unmodified lines
2035 2128
2036 /* wait for the chip to become ready */2129 /* wait for the chip to become ready */
2037 for (i = 0; i < jiffies_to_usecs(timeo); i++) {2130 for (i = 0; i < jiffies_to_usecs(timeo); i++) {
2038 if (chip_ready(map, adr))2131 if (chip_ready(map, chip, adr))
2039 return 0;2132 return 0;
2040 2133
2041 udelay(1);2134 udelay(1);
@@ -2099,14 +2192,15 @@ retry: · 57 unmodified lines
2099 map_write(map, datum, adr);2192 map_write(map, datum, adr);
2100 2193
2101 for (i = 0; i < jiffies_to_usecs(uWriteTimeout); i++) {2194 for (i = 0; i < jiffies_to_usecs(uWriteTimeout); i++) {
2102 if (chip_ready(map, adr))2195 if (chip_ready(map, chip, adr))
2103 break;2196 break;
2104 2197
2105 udelay(1);2198 udelay(1);
2106 }2199 }
2107 2200
2108 if (!chip_good(map, adr, datum)) {2201 if (!chip_good(map, chip, adr, datum)) {
2109 /* reset on all failures. */2202 /* reset on all failures. */
2203 cfi_check_err_status(map, chip, adr);
2110 map_write(map, CMD(0xF0), chip->start);2204 map_write(map, CMD(0xF0), chip->start);
2111 /* FIXME - should have reset delay before continuing */2205 /* FIXME - should have reset delay before continuing */
2112 2206
@@ -2300,7 +2394,7 @@ static int __xipram do_erase_chip(struct map_info *map, struct flchip *chip) · 187 unmodified lines
2300 chip->erase_suspended = 0;2394 chip->erase_suspended = 0;
2301 }2395 }
2302 2396
2303 if (chip_good(map, adr, map_word_ff(map)))2397 if (chip_good(map, chip, adr, map_word_ff(map)))
2304 break;2398 break;
2305 2399
2306 if (time_after(jiffies, timeo)) {2400 if (time_after(jiffies, timeo)) {
@@ -2316,6 +2410,7 @@ static int __xipram do_erase_chip(struct map_info *map, struct flchip *chip) · 9 unmodified lines
2316 /* Did we succeed? */2410 /* Did we succeed? */
2317 if (ret) {2411 if (ret) {
2318 /* reset on all failures. */2412 /* reset on all failures. */
2413 cfi_check_err_status(map, chip, adr);
2319 map_write(map, CMD(0xF0), chip->start);2414 map_write(map, CMD(0xF0), chip->start);
2320 /* FIXME - should have reset delay before continuing */2415 /* FIXME - should have reset delay before continuing */
2321 2416
@@ -2396,7 +2491,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip, · 74 unmodified lines
2396 chip->erase_suspended = 0;2491 chip->erase_suspended = 0;
2397 }2492 }
2398 2493
2399 if (chip_good(map, adr, map_word_ff(map)))2494 if (chip_good(map, chip, adr, map_word_ff(map)))
2400 break;2495 break;
2401 2496
2402 if (time_after(jiffies, timeo)) {2497 if (time_after(jiffies, timeo)) {
@@ -2412,6 +2507,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip, · 9 unmodified lines
2412 /* Did we succeed? */2507 /* Did we succeed? */
2413 if (ret) {2508 if (ret) {
2414 /* reset on all failures. */2509 /* reset on all failures. */
2510 cfi_check_err_status(map, chip, adr);
2415 map_write(map, CMD(0xF0), chip->start);2511 map_write(map, CMD(0xF0), chip->start);
2416 /* FIXME - should have reset delay before continuing */2512 /* FIXME - should have reset delay before continuing */
2417 2513
@@ -2587,7 +2683,7 @@ static int __maybe_unused do_ppb_xxlock(struct map_info *map, · 169 unmodified lines
2587 */2683 */
2588 timeo = jiffies + msecs_to_jiffies(2000); /* 2s max (un)locking */2684 timeo = jiffies + msecs_to_jiffies(2000); /* 2s max (un)locking */
2589 for (;;) {2685 for (;;) {
2590 if (chip_ready(map, adr))2686 if (chip_ready(map, chip, adr))
2591 break;2687 break;
2592 2688
2593 if (time_after(jiffies, timeo)) {2689 if (time_after(jiffies, timeo)) {
include/linux/mtd/cfi.h+7−0
@@ -233,6 +233,13 @@ struct cfi_pri_amdstd { · 232 unmodified lines
233 uint8_t VppMin;233 uint8_t VppMin;
234 uint8_t VppMax;234 uint8_t VppMax;
235 uint8_t TopBottom;235 uint8_t TopBottom;
236 /* Below field are added from version 1.5 */
237 uint8_t ProgramSuspend;
238 uint8_t UnlockBypass;
239 uint8_t SecureSiliconSector;
240 uint8_t SoftwareFeatures;
241#define CFI_POLL_STATUS_REG BIT(0)
242#define CFI_POLL_DQ BIT(1)
236} __packed;243} __packed;
237 244
238/* Vendor-Specific PRI for Atmel chips (command set 0x0002) */245/* Vendor-Specific PRI for Atmel chips (command set 0x0002) */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t