Commit 47228ca5 authored by Brian Norris's avatar Brian Norris

Merge tag 'spi-nor/for-4.12-v2' of git://github.com/spi-nor/linux into MTD

From Cyrille:
"""
This pull request contains the following notable changes:
- fixes in the hisi SPI controller driver.
- fixes in the intel SPI controller driver.
- fixes in the Mediatek SPI controller driver.
- fixes to some SPI flash memories not supported the Chip Erase command.
- add support to some new memory parts (Winbond, Macronix, Micron, ESMT).
- add new driver for the STM32 QSPI controller.
"""
parents 57e363b8 8abe904d
...@@ -106,4 +106,11 @@ config SPI_INTEL_SPI_PLATFORM ...@@ -106,4 +106,11 @@ config SPI_INTEL_SPI_PLATFORM
To compile this driver as a module, choose M here: the module To compile this driver as a module, choose M here: the module
will be called intel-spi-platform. will be called intel-spi-platform.
config SPI_STM32_QUADSPI
tristate "STM32 Quad SPI controller"
depends on ARCH_STM32
help
This enables support for the STM32 Quad SPI controller.
We only connect the NOR to this controller.
endif # MTD_SPI_NOR endif # MTD_SPI_NOR
...@@ -8,3 +8,4 @@ obj-$(CONFIG_MTD_MT81xx_NOR) += mtk-quadspi.o ...@@ -8,3 +8,4 @@ obj-$(CONFIG_MTD_MT81xx_NOR) += mtk-quadspi.o
obj-$(CONFIG_SPI_NXP_SPIFI) += nxp-spifi.o obj-$(CONFIG_SPI_NXP_SPIFI) += nxp-spifi.o
obj-$(CONFIG_SPI_INTEL_SPI) += intel-spi.o obj-$(CONFIG_SPI_INTEL_SPI) += intel-spi.o
obj-$(CONFIG_SPI_INTEL_SPI_PLATFORM) += intel-spi-platform.o obj-$(CONFIG_SPI_INTEL_SPI_PLATFORM) += intel-spi-platform.o
obj-$(CONFIG_SPI_STM32_QUADSPI) += stm32-quadspi.o
\ No newline at end of file
...@@ -448,8 +448,11 @@ static int hisi_spi_nor_probe(struct platform_device *pdev) ...@@ -448,8 +448,11 @@ static int hisi_spi_nor_probe(struct platform_device *pdev)
if (!host->buffer) if (!host->buffer)
return -ENOMEM; return -ENOMEM;
ret = clk_prepare_enable(host->clk);
if (ret)
return ret;
mutex_init(&host->lock); mutex_init(&host->lock);
clk_prepare_enable(host->clk);
hisi_spi_nor_init(host); hisi_spi_nor_init(host);
ret = hisi_spi_nor_register_all(host); ret = hisi_spi_nor_register_all(host);
if (ret) if (ret)
......
...@@ -704,7 +704,7 @@ static void intel_spi_fill_partition(struct intel_spi *ispi, ...@@ -704,7 +704,7 @@ static void intel_spi_fill_partition(struct intel_spi *ispi,
* whole partition read-only to be on the safe side. * whole partition read-only to be on the safe side.
*/ */
if (intel_spi_is_protected(ispi, base, limit)) if (intel_spi_is_protected(ispi, base, limit))
ispi->writeable = 0; ispi->writeable = false;
end = (limit << 12) + 4096; end = (limit << 12) + 4096;
if (end > part->size) if (end > part->size)
...@@ -728,7 +728,7 @@ struct intel_spi *intel_spi_probe(struct device *dev, ...@@ -728,7 +728,7 @@ struct intel_spi *intel_spi_probe(struct device *dev,
ispi->base = devm_ioremap_resource(dev, mem); ispi->base = devm_ioremap_resource(dev, mem);
if (IS_ERR(ispi->base)) if (IS_ERR(ispi->base))
return ispi->base; return ERR_CAST(ispi->base);
ispi->dev = dev; ispi->dev = dev;
ispi->info = info; ispi->info = info;
......
...@@ -104,6 +104,8 @@ ...@@ -104,6 +104,8 @@
#define MTK_NOR_MAX_RX_TX_SHIFT 6 #define MTK_NOR_MAX_RX_TX_SHIFT 6
/* can shift up to 56 bits (7 bytes) transfer by MTK_NOR_PRG_CMD */ /* can shift up to 56 bits (7 bytes) transfer by MTK_NOR_PRG_CMD */
#define MTK_NOR_MAX_SHIFT 7 #define MTK_NOR_MAX_SHIFT 7
/* nor controller 4-byte address mode enable bit */
#define MTK_NOR_4B_ADDR_EN BIT(4)
/* Helpers for accessing the program data / shift data registers */ /* Helpers for accessing the program data / shift data registers */
#define MTK_NOR_PRG_REG(n) (MTK_NOR_PRGDATA0_REG + 4 * (n)) #define MTK_NOR_PRG_REG(n) (MTK_NOR_PRGDATA0_REG + 4 * (n))
...@@ -230,10 +232,35 @@ static int mt8173_nor_write_buffer_disable(struct mt8173_nor *mt8173_nor) ...@@ -230,10 +232,35 @@ static int mt8173_nor_write_buffer_disable(struct mt8173_nor *mt8173_nor)
10000); 10000);
} }
static void mt8173_nor_set_addr_width(struct mt8173_nor *mt8173_nor)
{
u8 val;
struct spi_nor *nor = &mt8173_nor->nor;
val = readb(mt8173_nor->base + MTK_NOR_DUAL_REG);
switch (nor->addr_width) {
case 3:
val &= ~MTK_NOR_4B_ADDR_EN;
break;
case 4:
val |= MTK_NOR_4B_ADDR_EN;
break;
default:
dev_warn(mt8173_nor->dev, "Unexpected address width %u.\n",
nor->addr_width);
break;
}
writeb(val, mt8173_nor->base + MTK_NOR_DUAL_REG);
}
static void mt8173_nor_set_addr(struct mt8173_nor *mt8173_nor, u32 addr) static void mt8173_nor_set_addr(struct mt8173_nor *mt8173_nor, u32 addr)
{ {
int i; int i;
mt8173_nor_set_addr_width(mt8173_nor);
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
writeb(addr & 0xff, mt8173_nor->base + MTK_NOR_RADR0_REG + i * 4); writeb(addr & 0xff, mt8173_nor->base + MTK_NOR_RADR0_REG + i * 4);
addr >>= 8; addr >>= 8;
......
...@@ -85,6 +85,7 @@ struct flash_info { ...@@ -85,6 +85,7 @@ struct flash_info {
* Use dedicated 4byte address op codes * Use dedicated 4byte address op codes
* to support memory size above 128Mib. * to support memory size above 128Mib.
*/ */
#define NO_CHIP_ERASE BIT(12) /* Chip does not support chip erase */
}; };
#define JEDEC_MFR(info) ((info)->id[0]) #define JEDEC_MFR(info) ((info)->id[0])
...@@ -960,6 +961,8 @@ static const struct flash_info spi_nor_ids[] = { ...@@ -960,6 +961,8 @@ static const struct flash_info spi_nor_ids[] = {
/* ESMT */ /* ESMT */
{ "f25l32pa", INFO(0x8c2016, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_HAS_LOCK) }, { "f25l32pa", INFO(0x8c2016, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_HAS_LOCK) },
{ "f25l32qa", INFO(0x8c4116, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_HAS_LOCK) },
{ "f25l64qa", INFO(0x8c4117, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_HAS_LOCK) },
/* Everspin */ /* Everspin */
{ "mr25h256", CAT25_INFO( 32 * 1024, 1, 256, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, { "mr25h256", CAT25_INFO( 32 * 1024, 1, 256, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
...@@ -1013,11 +1016,14 @@ static const struct flash_info spi_nor_ids[] = { ...@@ -1013,11 +1016,14 @@ static const struct flash_info spi_nor_ids[] = {
{ "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, SECT_4K) }, { "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, SECT_4K) },
{ "mx25l3255e", INFO(0xc29e16, 0, 64 * 1024, 64, SECT_4K) }, { "mx25l3255e", INFO(0xc29e16, 0, 64 * 1024, 64, SECT_4K) },
{ "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, SECT_4K) }, { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, SECT_4K) },
{ "mx25u2033e", INFO(0xc22532, 0, 64 * 1024, 4, SECT_4K) },
{ "mx25u4035", INFO(0xc22533, 0, 64 * 1024, 8, SECT_4K) },
{ "mx25u8035", INFO(0xc22534, 0, 64 * 1024, 16, SECT_4K) },
{ "mx25u6435f", INFO(0xc22537, 0, 64 * 1024, 128, SECT_4K) }, { "mx25u6435f", INFO(0xc22537, 0, 64 * 1024, 128, SECT_4K) },
{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) }, { "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) },
{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) }, { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
{ "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) }, { "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) },
{ "mx25u25635f", INFO(0xc22539, 0, 64 * 1024, 512, SECT_4K) }, { "mx25u25635f", INFO(0xc22539, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_4B_OPCODES) },
{ "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) }, { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
{ "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, SPI_NOR_QUAD_READ) }, { "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, SPI_NOR_QUAD_READ) },
{ "mx66l1g55g", INFO(0xc2261b, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ) }, { "mx66l1g55g", INFO(0xc2261b, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ) },
...@@ -1031,10 +1037,11 @@ static const struct flash_info spi_nor_ids[] = { ...@@ -1031,10 +1037,11 @@ static const struct flash_info spi_nor_ids[] = {
{ "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) }, { "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) },
{ "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) }, { "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) },
{ "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_QUAD_READ) }, { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_QUAD_READ) },
{ "n25q256ax1", INFO(0x20bb19, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_QUAD_READ) },
{ "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, { "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
{ "n25q512ax3", INFO(0x20ba20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, { "n25q512ax3", INFO(0x20ba20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
{ "n25q00", INFO(0x20ba21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, { "n25q00", INFO(0x20ba21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) },
{ "n25q00a", INFO(0x20bb21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, { "n25q00a", INFO(0x20bb21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) },
/* PMC */ /* PMC */
{ "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) }, { "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) },
...@@ -1128,6 +1135,9 @@ static const struct flash_info spi_nor_ids[] = { ...@@ -1128,6 +1135,9 @@ static const struct flash_info spi_nor_ids[] = {
{ "w25x80", INFO(0xef3014, 0, 64 * 1024, 16, SECT_4K) }, { "w25x80", INFO(0xef3014, 0, 64 * 1024, 16, SECT_4K) },
{ "w25x16", INFO(0xef3015, 0, 64 * 1024, 32, SECT_4K) }, { "w25x16", INFO(0xef3015, 0, 64 * 1024, 32, SECT_4K) },
{ "w25x32", INFO(0xef3016, 0, 64 * 1024, 64, SECT_4K) }, { "w25x32", INFO(0xef3016, 0, 64 * 1024, 64, SECT_4K) },
{ "w25q20cl", INFO(0xef4012, 0, 64 * 1024, 4, SECT_4K) },
{ "w25q20bw", INFO(0xef5012, 0, 64 * 1024, 4, SECT_4K) },
{ "w25q20ew", INFO(0xef6012, 0, 64 * 1024, 4, SECT_4K) },
{ "w25q32", INFO(0xef4016, 0, 64 * 1024, 64, SECT_4K) }, { "w25q32", INFO(0xef4016, 0, 64 * 1024, 64, SECT_4K) },
{ {
"w25q32dw", INFO(0xef6016, 0, 64 * 1024, 64, "w25q32dw", INFO(0xef6016, 0, 64 * 1024, 64,
...@@ -1629,6 +1639,8 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode) ...@@ -1629,6 +1639,8 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
nor->flags |= SNOR_F_USE_FSR; nor->flags |= SNOR_F_USE_FSR;
if (info->flags & SPI_NOR_HAS_TB) if (info->flags & SPI_NOR_HAS_TB)
nor->flags |= SNOR_F_HAS_SR_TB; nor->flags |= SNOR_F_HAS_SR_TB;
if (info->flags & NO_CHIP_ERASE)
nor->flags |= SNOR_F_NO_OP_CHIP_ERASE;
#ifdef CONFIG_MTD_SPI_NOR_USE_4K_SECTORS #ifdef CONFIG_MTD_SPI_NOR_USE_4K_SECTORS
/* prefer "small sector" erase if possible */ /* prefer "small sector" erase if possible */
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment