Skip to content

Commit cb41390

Browse files
Merge tag 'spi-nor/for-5.9' of https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux into mtd/next
SPI NOR core changes: - Disable Quad Mode in spi_nor_restore(). - Don't abort BFPT parsing when QER reserved value is used. - Add support/update capabilities for few flashes. - Drop s70fl01gs flash: it does not support RDSR(05h) which is critical for erase/write. - Merge the SPIMEM DTR bits in spi-nor/next to avoid conflicts during the release cycle. SPI NOR controller drivers changes: - Move the cadence-quadspi driver to spi-mem. The series was taken through the SPI tree. Merge it also in spi-nor/next to avoid conflicts during the release cycle. - intel-spi: - Add new PCI IDs. - Ignore the Write Disable command, the controller doesn't support it. - Fix performance regression.
2 parents fbd9b54 + e93a977 commit cb41390

File tree

20 files changed

+338
-390
lines changed

20 files changed

+338
-390
lines changed

drivers/mtd/spi-nor/controllers/Kconfig

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,6 @@ config SPI_ASPEED_SMC
99
and support for the SPI flash memory controller (SPI) for
1010
the host firmware. The implementation only supports SPI NOR.
1111

12-
config SPI_CADENCE_QUADSPI
13-
tristate "Cadence Quad SPI controller"
14-
depends on OF && (ARM || ARM64 || COMPILE_TEST)
15-
help
16-
Enable support for the Cadence Quad SPI Flash controller.
17-
18-
Cadence QSPI is a specialized controller for connecting an SPI
19-
Flash over 1/2/4-bit wide bus. Enable this option if you have a
20-
device with a Cadence QSPI controller and want to access the
21-
Flash as an MTD device.
22-
2312
config SPI_HISI_SFC
2413
tristate "Hisilicon FMC SPI NOR Flash Controller(SFC)"
2514
depends on ARCH_HISI || COMPILE_TEST

drivers/mtd/spi-nor/controllers/Makefile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
# SPDX-License-Identifier: GPL-2.0
22
obj-$(CONFIG_SPI_ASPEED_SMC) += aspeed-smc.o
3-
obj-$(CONFIG_SPI_CADENCE_QUADSPI) += cadence-quadspi.o
43
obj-$(CONFIG_SPI_HISI_SFC) += hisi-sfc.o
54
obj-$(CONFIG_SPI_NXP_SPIFI) += nxp-spifi.o
65
obj-$(CONFIG_SPI_INTEL_SPI) += intel-spi.o

drivers/mtd/spi-nor/controllers/intel-spi-pci.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,9 @@ static const struct pci_device_id intel_spi_pci_ids[] = {
6868
{ PCI_VDEVICE(INTEL, 0x06a4), (unsigned long)&bxt_info },
6969
{ PCI_VDEVICE(INTEL, 0x18e0), (unsigned long)&bxt_info },
7070
{ PCI_VDEVICE(INTEL, 0x19e0), (unsigned long)&bxt_info },
71+
{ PCI_VDEVICE(INTEL, 0x1bca), (unsigned long)&bxt_info },
7172
{ PCI_VDEVICE(INTEL, 0x34a4), (unsigned long)&bxt_info },
73+
{ PCI_VDEVICE(INTEL, 0x43a4), (unsigned long)&cnl_info },
7274
{ PCI_VDEVICE(INTEL, 0x4b24), (unsigned long)&bxt_info },
7375
{ PCI_VDEVICE(INTEL, 0x4da4), (unsigned long)&bxt_info },
7476
{ PCI_VDEVICE(INTEL, 0xa0a4), (unsigned long)&bxt_info },

drivers/mtd/spi-nor/controllers/intel-spi.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ static int intel_spi_wait_hw_busy(struct intel_spi *ispi)
292292
u32 val;
293293

294294
return readl_poll_timeout(ispi->base + HSFSTS_CTL, val,
295-
!(val & HSFSTS_CTL_SCIP), 40,
295+
!(val & HSFSTS_CTL_SCIP), 0,
296296
INTEL_SPI_TIMEOUT * 1000);
297297
}
298298

@@ -301,7 +301,7 @@ static int intel_spi_wait_sw_busy(struct intel_spi *ispi)
301301
u32 val;
302302

303303
return readl_poll_timeout(ispi->sregs + SSFSTS_CTL, val,
304-
!(val & SSFSTS_CTL_SCIP), 40,
304+
!(val & SSFSTS_CTL_SCIP), 0,
305305
INTEL_SPI_TIMEOUT * 1000);
306306
}
307307

@@ -612,6 +612,15 @@ static int intel_spi_write_reg(struct spi_nor *nor, u8 opcode, const u8 *buf,
612612
return 0;
613613
}
614614

615+
/*
616+
* We hope that HW sequencer will do the right thing automatically and
617+
* with the SW sequencer we cannot use preopcode anyway, so just ignore
618+
* the Write Disable operation and pretend it was completed
619+
* successfully.
620+
*/
621+
if (opcode == SPINOR_OP_WRDI)
622+
return 0;
623+
615624
writel(0, ispi->base + FADDR);
616625

617626
/* Write the value beforehand */

drivers/mtd/spi-nor/core.c

Lines changed: 38 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1907,61 +1907,73 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
19071907
}
19081908

19091909
/**
1910-
* spi_nor_sr1_bit6_quad_enable() - Set the Quad Enable BIT(6) in the Status
1911-
* Register 1.
1910+
* spi_nor_sr1_bit6_quad_enable() - Set/Unset the Quad Enable BIT(6) in the
1911+
* Status Register 1.
19121912
* @nor: pointer to a 'struct spi_nor'
1913+
* @enable: true to enable Quad mode, false to disable Quad mode.
19131914
*
19141915
* Bit 6 of the Status Register 1 is the QE bit for Macronix like QSPI memories.
19151916
*
19161917
* Return: 0 on success, -errno otherwise.
19171918
*/
1918-
int spi_nor_sr1_bit6_quad_enable(struct spi_nor *nor)
1919+
int spi_nor_sr1_bit6_quad_enable(struct spi_nor *nor, bool enable)
19191920
{
19201921
int ret;
19211922

19221923
ret = spi_nor_read_sr(nor, nor->bouncebuf);
19231924
if (ret)
19241925
return ret;
19251926

1926-
if (nor->bouncebuf[0] & SR1_QUAD_EN_BIT6)
1927+
if ((enable && (nor->bouncebuf[0] & SR1_QUAD_EN_BIT6)) ||
1928+
(!enable && !(nor->bouncebuf[0] & SR1_QUAD_EN_BIT6)))
19271929
return 0;
19281930

1929-
nor->bouncebuf[0] |= SR1_QUAD_EN_BIT6;
1931+
if (enable)
1932+
nor->bouncebuf[0] |= SR1_QUAD_EN_BIT6;
1933+
else
1934+
nor->bouncebuf[0] &= ~SR1_QUAD_EN_BIT6;
19301935

19311936
return spi_nor_write_sr1_and_check(nor, nor->bouncebuf[0]);
19321937
}
19331938

19341939
/**
1935-
* spi_nor_sr2_bit1_quad_enable() - set the Quad Enable BIT(1) in the Status
1936-
* Register 2.
1940+
* spi_nor_sr2_bit1_quad_enable() - set/unset the Quad Enable BIT(1) in the
1941+
* Status Register 2.
19371942
* @nor: pointer to a 'struct spi_nor'.
1943+
* @enable: true to enable Quad mode, false to disable Quad mode.
19381944
*
19391945
* Bit 1 of the Status Register 2 is the QE bit for Spansion like QSPI memories.
19401946
*
19411947
* Return: 0 on success, -errno otherwise.
19421948
*/
1943-
int spi_nor_sr2_bit1_quad_enable(struct spi_nor *nor)
1949+
int spi_nor_sr2_bit1_quad_enable(struct spi_nor *nor, bool enable)
19441950
{
19451951
int ret;
19461952

19471953
if (nor->flags & SNOR_F_NO_READ_CR)
1948-
return spi_nor_write_16bit_cr_and_check(nor, SR2_QUAD_EN_BIT1);
1954+
return spi_nor_write_16bit_cr_and_check(nor,
1955+
enable ? SR2_QUAD_EN_BIT1 : 0);
19491956

19501957
ret = spi_nor_read_cr(nor, nor->bouncebuf);
19511958
if (ret)
19521959
return ret;
19531960

1954-
if (nor->bouncebuf[0] & SR2_QUAD_EN_BIT1)
1961+
if ((enable && (nor->bouncebuf[0] & SR2_QUAD_EN_BIT1)) ||
1962+
(!enable && !(nor->bouncebuf[0] & SR2_QUAD_EN_BIT1)))
19551963
return 0;
19561964

1957-
nor->bouncebuf[0] |= SR2_QUAD_EN_BIT1;
1965+
if (enable)
1966+
nor->bouncebuf[0] |= SR2_QUAD_EN_BIT1;
1967+
else
1968+
nor->bouncebuf[0] &= ~SR2_QUAD_EN_BIT1;
19581969

19591970
return spi_nor_write_16bit_cr_and_check(nor, nor->bouncebuf[0]);
19601971
}
19611972

19621973
/**
1963-
* spi_nor_sr2_bit7_quad_enable() - set QE bit in Status Register 2.
1974+
* spi_nor_sr2_bit7_quad_enable() - set/unset QE bit in Status Register 2.
19641975
* @nor: pointer to a 'struct spi_nor'
1976+
* @enable: true to enable Quad mode, false to disable Quad mode.
19651977
*
19661978
* Set the Quad Enable (QE) bit in the Status Register 2.
19671979
*
@@ -1971,7 +1983,7 @@ int spi_nor_sr2_bit1_quad_enable(struct spi_nor *nor)
19711983
*
19721984
* Return: 0 on success, -errno otherwise.
19731985
*/
1974-
int spi_nor_sr2_bit7_quad_enable(struct spi_nor *nor)
1986+
int spi_nor_sr2_bit7_quad_enable(struct spi_nor *nor, bool enable)
19751987
{
19761988
u8 *sr2 = nor->bouncebuf;
19771989
int ret;
@@ -1981,11 +1993,15 @@ int spi_nor_sr2_bit7_quad_enable(struct spi_nor *nor)
19811993
ret = spi_nor_read_sr2(nor, sr2);
19821994
if (ret)
19831995
return ret;
1984-
if (*sr2 & SR2_QUAD_EN_BIT7)
1996+
if ((enable && (*sr2 & SR2_QUAD_EN_BIT7)) ||
1997+
(!enable && !(*sr2 & SR2_QUAD_EN_BIT7)))
19851998
return 0;
19861999

19872000
/* Update the Quad Enable bit. */
1988-
*sr2 |= SR2_QUAD_EN_BIT7;
2001+
if (enable)
2002+
*sr2 |= SR2_QUAD_EN_BIT7;
2003+
else
2004+
*sr2 &= ~SR2_QUAD_EN_BIT7;
19892005

19902006
ret = spi_nor_write_sr2(nor, sr2);
19912007
if (ret)
@@ -2898,12 +2914,13 @@ static int spi_nor_init_params(struct spi_nor *nor)
28982914
}
28992915

29002916
/**
2901-
* spi_nor_quad_enable() - enable Quad I/O if needed.
2917+
* spi_nor_quad_enable() - enable/disable Quad I/O if needed.
29022918
* @nor: pointer to a 'struct spi_nor'
2919+
* @enable: true to enable Quad mode. false to disable Quad mode.
29032920
*
29042921
* Return: 0 on success, -errno otherwise.
29052922
*/
2906-
static int spi_nor_quad_enable(struct spi_nor *nor)
2923+
static int spi_nor_quad_enable(struct spi_nor *nor, bool enable)
29072924
{
29082925
if (!nor->params->quad_enable)
29092926
return 0;
@@ -2912,7 +2929,7 @@ static int spi_nor_quad_enable(struct spi_nor *nor)
29122929
spi_nor_get_protocol_width(nor->write_proto) == 4))
29132930
return 0;
29142931

2915-
return nor->params->quad_enable(nor);
2932+
return nor->params->quad_enable(nor, enable);
29162933
}
29172934

29182935
/**
@@ -2936,7 +2953,7 @@ static int spi_nor_init(struct spi_nor *nor)
29362953
{
29372954
int err;
29382955

2939-
err = spi_nor_quad_enable(nor);
2956+
err = spi_nor_quad_enable(nor, true);
29402957
if (err) {
29412958
dev_dbg(nor->dev, "quad mode not supported\n");
29422959
return err;
@@ -2983,6 +3000,8 @@ void spi_nor_restore(struct spi_nor *nor)
29833000
if (nor->addr_width == 4 && !(nor->flags & SNOR_F_4B_OPCODES) &&
29843001
nor->flags & SNOR_F_BROKEN_RESET)
29853002
nor->params->set_4byte_addr_mode(nor, false);
3003+
3004+
spi_nor_quad_enable(nor, false);
29863005
}
29873006
EXPORT_SYMBOL_GPL(spi_nor_restore);
29883007

drivers/mtd/spi-nor/core.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ struct spi_nor_locking_ops {
198198
* higher index in the array, the higher priority.
199199
* @erase_map: the erase map parsed from the SFDP Sector Map Parameter
200200
* Table.
201-
* @quad_enable: enables SPI NOR quad mode.
201+
* @quad_enable: enables/disables SPI NOR Quad mode.
202202
* @set_4byte_addr_mode: puts the SPI NOR in 4 byte addressing mode.
203203
* @convert_addr: converts an absolute address into something the flash
204204
* will understand. Particularly useful when pagesize is
@@ -219,7 +219,7 @@ struct spi_nor_flash_parameter {
219219

220220
struct spi_nor_erase_map erase_map;
221221

222-
int (*quad_enable)(struct spi_nor *nor);
222+
int (*quad_enable)(struct spi_nor *nor, bool enable);
223223
int (*set_4byte_addr_mode)(struct spi_nor *nor, bool enable);
224224
u32 (*convert_addr)(struct spi_nor *nor, u32 addr);
225225
int (*setup)(struct spi_nor *nor, const struct spi_nor_hwcaps *hwcaps);
@@ -406,9 +406,9 @@ int spi_nor_write_ear(struct spi_nor *nor, u8 ear);
406406
int spi_nor_wait_till_ready(struct spi_nor *nor);
407407
int spi_nor_lock_and_prep(struct spi_nor *nor);
408408
void spi_nor_unlock_and_unprep(struct spi_nor *nor);
409-
int spi_nor_sr1_bit6_quad_enable(struct spi_nor *nor);
410-
int spi_nor_sr2_bit1_quad_enable(struct spi_nor *nor);
411-
int spi_nor_sr2_bit7_quad_enable(struct spi_nor *nor);
409+
int spi_nor_sr1_bit6_quad_enable(struct spi_nor *nor, bool enable);
410+
int spi_nor_sr2_bit1_quad_enable(struct spi_nor *nor, bool enable);
411+
int spi_nor_sr2_bit7_quad_enable(struct spi_nor *nor, bool enable);
412412

413413
int spi_nor_xread_sr(struct spi_nor *nor, u8 *sr);
414414
ssize_t spi_nor_read_data(struct spi_nor *nor, loff_t from, size_t len,

drivers/mtd/spi-nor/macronix.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ static const struct flash_info macronix_parts[] = {
5252
{ "mx25u6435f", INFO(0xc22537, 0, 64 * 1024, 128, SECT_4K) },
5353
{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) },
5454
{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
55+
{ "mx25r1635f", INFO(0xc22815, 0, 64 * 1024, 32,
56+
SECT_4K | SPI_NOR_DUAL_READ |
57+
SPI_NOR_QUAD_READ) },
5558
{ "mx25r3235f", INFO(0xc22816, 0, 64 * 1024, 64,
5659
SECT_4K | SPI_NOR_DUAL_READ |
5760
SPI_NOR_QUAD_READ) },
@@ -84,6 +87,9 @@ static const struct flash_info macronix_parts[] = {
8487
SPI_NOR_QUAD_READ) },
8588
{ "mx66l1g55g", INFO(0xc2261b, 0, 64 * 1024, 2048,
8689
SPI_NOR_QUAD_READ) },
90+
{ "mx66u2g45g", INFO(0xc2253c, 0, 64 * 1024, 4096,
91+
SECT_4K | SPI_NOR_DUAL_READ |
92+
SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
8793
};
8894

8995
static void macronix_default_init(struct spi_nor *nor)

drivers/mtd/spi-nor/micron-st.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ static const struct flash_info st_parts[] = {
7171
SECT_4K | USE_FSR | SPI_NOR_QUAD_READ |
7272
NO_CHIP_ERASE) },
7373
{ "mt25qu02g", INFO(0x20bb22, 0, 64 * 1024, 4096,
74-
SECT_4K | USE_FSR | SPI_NOR_QUAD_READ |
75-
NO_CHIP_ERASE) },
74+
SECT_4K | USE_FSR | SPI_NOR_DUAL_READ |
75+
SPI_NOR_QUAD_READ | NO_CHIP_ERASE) },
7676

7777
{ "m25p05", INFO(0x202010, 0, 32 * 1024, 2, 0) },
7878
{ "m25p10", INFO(0x202011, 0, 32 * 1024, 4, 0) },

drivers/mtd/spi-nor/sfdp.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,8 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,
598598
break;
599599

600600
default:
601-
return -EINVAL;
601+
dev_dbg(nor->dev, "BFPT QER reserved value used\n");
602+
break;
602603
}
603604

604605
/* Stop here if not JESD216 rev C or later. */

drivers/mtd/spi-nor/spansion.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ static const struct flash_info spansion_parts[] = {
6464
{ "s25fs512s", INFO6(0x010220, 0x4d0081, 256 * 1024, 256,
6565
SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR)
6666
.fixups = &s25fs_s_fixups, },
67-
{ "s70fl01gs", INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) },
6867
{ "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) },
6968
{ "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256, 0) },
7069
{ "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024, 64,
@@ -84,7 +83,8 @@ static const struct flash_info spansion_parts[] = {
8483
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
8584
{ "s25fl016k", INFO(0xef4015, 0, 64 * 1024, 32,
8685
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
87-
{ "s25fl064k", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) },
86+
{ "s25fl064k", INFO(0xef4017, 0, 64 * 1024, 128,
87+
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
8888
{ "s25fl116k", INFO(0x014015, 0, 64 * 1024, 32,
8989
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
9090
{ "s25fl132k", INFO(0x014016, 0, 64 * 1024, 64, SECT_4K) },

0 commit comments

Comments
 (0)