Commit cb413909 authored by Richard Weinberger's avatar Richard Weinberger
Browse files

Merge tag 'spi-nor/for-5.9' of...

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.
parents fbd9b543 e93a9773
Loading
Loading
Loading
Loading
+0 −11
Original line number Diff line number Diff line
@@ -9,17 +9,6 @@ config SPI_ASPEED_SMC
	  and support for the SPI flash memory controller (SPI) for
	  the host firmware. The implementation only supports SPI NOR.

config SPI_CADENCE_QUADSPI
	tristate "Cadence Quad SPI controller"
	depends on OF && (ARM || ARM64 || COMPILE_TEST)
	help
	  Enable support for the Cadence Quad SPI Flash controller.

	  Cadence QSPI is a specialized controller for connecting an SPI
	  Flash over 1/2/4-bit wide bus. Enable this option if you have a
	  device with a Cadence QSPI controller and want to access the
	  Flash as an MTD device.

config SPI_HISI_SFC
	tristate "Hisilicon FMC SPI NOR Flash Controller(SFC)"
	depends on ARCH_HISI || COMPILE_TEST
+0 −1
Original line number Diff line number Diff line
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_SPI_ASPEED_SMC)	+= aspeed-smc.o
obj-$(CONFIG_SPI_CADENCE_QUADSPI)	+= cadence-quadspi.o
obj-$(CONFIG_SPI_HISI_SFC)	+= hisi-sfc.o
obj-$(CONFIG_SPI_NXP_SPIFI)	+= nxp-spifi.o
obj-$(CONFIG_SPI_INTEL_SPI)	+= intel-spi.o
+2 −0
Original line number Diff line number Diff line
@@ -68,7 +68,9 @@ static const struct pci_device_id intel_spi_pci_ids[] = {
	{ PCI_VDEVICE(INTEL, 0x06a4), (unsigned long)&bxt_info },
	{ PCI_VDEVICE(INTEL, 0x18e0), (unsigned long)&bxt_info },
	{ PCI_VDEVICE(INTEL, 0x19e0), (unsigned long)&bxt_info },
	{ PCI_VDEVICE(INTEL, 0x1bca), (unsigned long)&bxt_info },
	{ PCI_VDEVICE(INTEL, 0x34a4), (unsigned long)&bxt_info },
	{ PCI_VDEVICE(INTEL, 0x43a4), (unsigned long)&cnl_info },
	{ PCI_VDEVICE(INTEL, 0x4b24), (unsigned long)&bxt_info },
	{ PCI_VDEVICE(INTEL, 0x4da4), (unsigned long)&bxt_info },
	{ PCI_VDEVICE(INTEL, 0xa0a4), (unsigned long)&bxt_info },
+11 −2
Original line number Diff line number Diff line
@@ -292,7 +292,7 @@ static int intel_spi_wait_hw_busy(struct intel_spi *ispi)
	u32 val;

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

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

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

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

	/*
	 * We hope that HW sequencer will do the right thing automatically and
	 * with the SW sequencer we cannot use preopcode anyway, so just ignore
	 * the Write Disable operation and pretend it was completed
	 * successfully.
	 */
	if (opcode == SPINOR_OP_WRDI)
		return 0;

	writel(0, ispi->base + FADDR);

	/* Write the value beforehand */
+38 −19
Original line number Diff line number Diff line
@@ -1907,15 +1907,16 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
}

/**
 * spi_nor_sr1_bit6_quad_enable() - Set the Quad Enable BIT(6) in the Status
 * Register 1.
 * spi_nor_sr1_bit6_quad_enable() - Set/Unset the Quad Enable BIT(6) in the
 *                                  Status Register 1.
 * @nor:	pointer to a 'struct spi_nor'
 * @enable:	true to enable Quad mode, false to disable Quad mode.
 *
 * Bit 6 of the Status Register 1 is the QE bit for Macronix like QSPI memories.
 *
 * Return: 0 on success, -errno otherwise.
 */
int spi_nor_sr1_bit6_quad_enable(struct spi_nor *nor)
int spi_nor_sr1_bit6_quad_enable(struct spi_nor *nor, bool enable)
{
	int ret;

@@ -1923,45 +1924,56 @@ int spi_nor_sr1_bit6_quad_enable(struct spi_nor *nor)
	if (ret)
		return ret;

	if (nor->bouncebuf[0] & SR1_QUAD_EN_BIT6)
	if ((enable && (nor->bouncebuf[0] & SR1_QUAD_EN_BIT6)) ||
	    (!enable && !(nor->bouncebuf[0] & SR1_QUAD_EN_BIT6)))
		return 0;

	if (enable)
		nor->bouncebuf[0] |= SR1_QUAD_EN_BIT6;
	else
		nor->bouncebuf[0] &= ~SR1_QUAD_EN_BIT6;

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

/**
 * spi_nor_sr2_bit1_quad_enable() - set the Quad Enable BIT(1) in the Status
 * Register 2.
 * spi_nor_sr2_bit1_quad_enable() - set/unset the Quad Enable BIT(1) in the
 *                                  Status Register 2.
 * @nor:       pointer to a 'struct spi_nor'.
 * @enable:	true to enable Quad mode, false to disable Quad mode.
 *
 * Bit 1 of the Status Register 2 is the QE bit for Spansion like QSPI memories.
 *
 * Return: 0 on success, -errno otherwise.
 */
int spi_nor_sr2_bit1_quad_enable(struct spi_nor *nor)
int spi_nor_sr2_bit1_quad_enable(struct spi_nor *nor, bool enable)
{
	int ret;

	if (nor->flags & SNOR_F_NO_READ_CR)
		return spi_nor_write_16bit_cr_and_check(nor, SR2_QUAD_EN_BIT1);
		return spi_nor_write_16bit_cr_and_check(nor,
						enable ? SR2_QUAD_EN_BIT1 : 0);

	ret = spi_nor_read_cr(nor, nor->bouncebuf);
	if (ret)
		return ret;

	if (nor->bouncebuf[0] & SR2_QUAD_EN_BIT1)
	if ((enable && (nor->bouncebuf[0] & SR2_QUAD_EN_BIT1)) ||
	    (!enable && !(nor->bouncebuf[0] & SR2_QUAD_EN_BIT1)))
		return 0;

	if (enable)
		nor->bouncebuf[0] |= SR2_QUAD_EN_BIT1;
	else
		nor->bouncebuf[0] &= ~SR2_QUAD_EN_BIT1;

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

/**
 * spi_nor_sr2_bit7_quad_enable() - set QE bit in Status Register 2.
 * spi_nor_sr2_bit7_quad_enable() - set/unset QE bit in Status Register 2.
 * @nor:	pointer to a 'struct spi_nor'
 * @enable:	true to enable Quad mode, false to disable Quad mode.
 *
 * Set the Quad Enable (QE) bit in the Status Register 2.
 *
@@ -1971,7 +1983,7 @@ int spi_nor_sr2_bit1_quad_enable(struct spi_nor *nor)
 *
 * Return: 0 on success, -errno otherwise.
 */
int spi_nor_sr2_bit7_quad_enable(struct spi_nor *nor)
int spi_nor_sr2_bit7_quad_enable(struct spi_nor *nor, bool enable)
{
	u8 *sr2 = nor->bouncebuf;
	int ret;
@@ -1981,11 +1993,15 @@ int spi_nor_sr2_bit7_quad_enable(struct spi_nor *nor)
	ret = spi_nor_read_sr2(nor, sr2);
	if (ret)
		return ret;
	if (*sr2 & SR2_QUAD_EN_BIT7)
	if ((enable && (*sr2 & SR2_QUAD_EN_BIT7)) ||
	    (!enable && !(*sr2 & SR2_QUAD_EN_BIT7)))
		return 0;

	/* Update the Quad Enable bit. */
	if (enable)
		*sr2 |= SR2_QUAD_EN_BIT7;
	else
		*sr2 &= ~SR2_QUAD_EN_BIT7;

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

/**
 * spi_nor_quad_enable() - enable Quad I/O if needed.
 * spi_nor_quad_enable() - enable/disable Quad I/O if needed.
 * @nor:                pointer to a 'struct spi_nor'
 * @enable:             true to enable Quad mode. false to disable Quad mode.
 *
 * Return: 0 on success, -errno otherwise.
 */
static int spi_nor_quad_enable(struct spi_nor *nor)
static int spi_nor_quad_enable(struct spi_nor *nor, bool enable)
{
	if (!nor->params->quad_enable)
		return 0;
@@ -2912,7 +2929,7 @@ static int spi_nor_quad_enable(struct spi_nor *nor)
	      spi_nor_get_protocol_width(nor->write_proto) == 4))
		return 0;

	return nor->params->quad_enable(nor);
	return nor->params->quad_enable(nor, enable);
}

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

	err = spi_nor_quad_enable(nor);
	err = spi_nor_quad_enable(nor, true);
	if (err) {
		dev_dbg(nor->dev, "quad mode not supported\n");
		return err;
@@ -2983,6 +3000,8 @@ void spi_nor_restore(struct spi_nor *nor)
	if (nor->addr_width == 4 && !(nor->flags & SNOR_F_4B_OPCODES) &&
	    nor->flags & SNOR_F_BROKEN_RESET)
		nor->params->set_4byte_addr_mode(nor, false);

	spi_nor_quad_enable(nor, false);
}
EXPORT_SYMBOL_GPL(spi_nor_restore);

Loading