aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2019-04-14 00:03:06 -0400
committerTom Rini <trini@konsulko.com>2019-04-14 00:03:06 -0400
commit216800acf1fbf9f498455bf3c92d4513d9a4c681 (patch)
tree08ee65c9c73a954c71b6f6051725338f0f23fdcb /drivers
parentcf5eebeb18f7790d5030eb94f51fca0ebcd6e406 (diff)
parent59aea29a31869ed0fd5ffc4b95050db966fcaf6d (diff)
downloadu-boot-216800acf1fbf9f498455bf3c92d4513d9a4c681.zip
u-boot-216800acf1fbf9f498455bf3c92d4513d9a4c681.tar.gz
u-boot-216800acf1fbf9f498455bf3c92d4513d9a4c681.tar.bz2
Merge branch 'master' of git://git.denx.de/u-boot-spi
Conflicts: arch/arm/dts/armada-385-amc.dts arch/arm/dts/armada-xp-theadorable.dts arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi Signed-off-by: Tom Rini <trini@konsulko.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/mtdcore.c6
-rw-r--r--drivers/mtd/nand/spi/gigadevice.c79
-rw-r--r--drivers/mtd/spi/Kconfig6
-rw-r--r--drivers/mtd/spi/sf_probe.c1
-rw-r--r--drivers/mtd/spi/spi-nor-core.c14
-rw-r--r--drivers/mtd/spi/spi-nor-ids.c7
-rw-r--r--drivers/spi/cadence_qspi.c2
-rw-r--r--drivers/spi/cadence_qspi.h2
-rw-r--r--drivers/spi/cadence_qspi_apb.c7
-rw-r--r--drivers/spi/fsl_dspi.c30
-rw-r--r--drivers/spi/spi-mem.c2
-rw-r--r--drivers/spi/spi-uclass.c4
12 files changed, 107 insertions, 53 deletions
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index cb7ca38..89ac822 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -1051,13 +1051,13 @@ static int mtd_check_oob_ops(struct mtd_info *mtd, loff_t offs,
return -EINVAL;
if (ops->ooblen) {
- u64 maxooblen;
+ size_t maxooblen;
if (ops->ooboffs >= mtd_oobavail(mtd, ops))
return -EINVAL;
- maxooblen = ((mtd_div_by_ws(mtd->size, mtd) -
- mtd_div_by_ws(offs, mtd)) *
+ maxooblen = ((size_t)(mtd_div_by_ws(mtd->size, mtd) -
+ mtd_div_by_ws(offs, mtd)) *
mtd_oobavail(mtd, ops)) - ops->ooboffs;
if (ops->ooblen > maxooblen)
return -EINVAL;
diff --git a/drivers/mtd/nand/spi/gigadevice.c b/drivers/mtd/nand/spi/gigadevice.c
index 0bade20..3681c5e 100644
--- a/drivers/mtd/nand/spi/gigadevice.c
+++ b/drivers/mtd/nand/spi/gigadevice.c
@@ -12,12 +12,11 @@
#endif
#include <linux/mtd/spinand.h>
-#define SPINAND_MFR_GIGADEVICE 0xc8
+#define SPINAND_MFR_GIGADEVICE 0xC8
+#define GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS (1 << 4)
+#define GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS (3 << 4)
-#define GIGADEVICE_STATUS_ECC_MASK GENMASK(5, 4)
-#define GIGADEVICE_STATUS_ECC_NO_BITFLIPS (0 << 4)
-#define GIGADEVICE_STATUS_ECC_1TO7_BITFLIPS (1 << 4)
-#define GIGADEVICE_STATUS_ECC_8_BITFLIPS (3 << 4)
+#define GD5FXGQ4XEXXG_REG_STATUS2 0xf0
static SPINAND_OP_VARIANTS(read_cache_variants,
SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
@@ -35,8 +34,8 @@ static SPINAND_OP_VARIANTS(update_cache_variants,
SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
SPINAND_PROG_LOAD(false, 0, NULL, 0));
-static int gd5f1gq4u_ooblayout_ecc(struct mtd_info *mtd, int section,
- struct mtd_oob_region *region)
+static int gd5fxgq4xexxg_ooblayout_ecc(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *region)
{
if (section)
return -ERANGE;
@@ -47,38 +46,49 @@ static int gd5f1gq4u_ooblayout_ecc(struct mtd_info *mtd, int section,
return 0;
}
-static int gd5f1gq4u_ooblayout_free(struct mtd_info *mtd, int section,
- struct mtd_oob_region *region)
+static int gd5fxgq4xexxg_ooblayout_free(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *region)
{
if (section)
return -ERANGE;
- /* Reserve 2 bytes for the BBM. */
- region->offset = 2;
- region->length = 62;
+ /* Reserve 1 bytes for the BBM. */
+ region->offset = 1;
+ region->length = 63;
return 0;
}
-static const struct mtd_ooblayout_ops gd5f1gq4u_ooblayout = {
- .ecc = gd5f1gq4u_ooblayout_ecc,
- .free = gd5f1gq4u_ooblayout_free,
-};
-
-static int gd5f1gq4u_ecc_get_status(struct spinand_device *spinand,
- u8 status)
+static int gd5fxgq4xexxg_ecc_get_status(struct spinand_device *spinand,
+ u8 status)
{
- if (status)
- debug("%s (%d): status=%02x\n", __func__, __LINE__, status);
+ u8 status2;
+ struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQ4XEXXG_REG_STATUS2,
+ &status2);
+ int ret;
- switch (status & GIGADEVICE_STATUS_ECC_MASK) {
+ switch (status & STATUS_ECC_MASK) {
case STATUS_ECC_NO_BITFLIPS:
return 0;
- case GIGADEVICE_STATUS_ECC_1TO7_BITFLIPS:
- return 7;
-
- case GIGADEVICE_STATUS_ECC_8_BITFLIPS:
+ case GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS:
+ /*
+ * Read status2 register to determine a more fine grained
+ * bit error status
+ */
+ ret = spi_mem_exec_op(spinand->slave, &op);
+ if (ret)
+ return ret;
+
+ /*
+ * 4 ... 7 bits are flipped (1..4 can't be detected, so
+ * report the maximum of 4 in this case
+ */
+ /* bits sorted this way (3...0): ECCS1,ECCS0,ECCSE1,ECCSE0 */
+ return ((status & STATUS_ECC_MASK) >> 2) |
+ ((status2 & STATUS_ECC_MASK) >> 4);
+
+ case GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS:
return 8;
case STATUS_ECC_UNCOR_ERROR:
@@ -91,16 +101,21 @@ static int gd5f1gq4u_ecc_get_status(struct spinand_device *spinand,
return -EINVAL;
}
+static const struct mtd_ooblayout_ops gd5fxgq4xexxg_ooblayout = {
+ .ecc = gd5fxgq4xexxg_ooblayout_ecc,
+ .free = gd5fxgq4xexxg_ooblayout_free,
+};
+
static const struct spinand_info gigadevice_spinand_table[] = {
- SPINAND_INFO("GD5F1GQ4UC", 0xd1,
+ SPINAND_INFO("GD5F1GQ4UExxG", 0xd1,
NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
- NAND_ECCREQ(8, 2048),
+ NAND_ECCREQ(8, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
&write_cache_variants,
&update_cache_variants),
0,
- SPINAND_ECCINFO(&gd5f1gq4u_ooblayout,
- gd5f1gq4u_ecc_get_status)),
+ SPINAND_ECCINFO(&gd5fxgq4xexxg_ooblayout,
+ gd5fxgq4xexxg_ecc_get_status)),
};
static int gigadevice_spinand_detect(struct spinand_device *spinand)
@@ -109,8 +124,8 @@ static int gigadevice_spinand_detect(struct spinand_device *spinand)
int ret;
/*
- * Gigadevice SPI NAND read ID need a dummy byte,
- * so the first byte in raw_id is dummy.
+ * For GD NANDs, There is an address byte needed to shift in before IDs
+ * are read out, so the first byte in raw_id is dummy.
*/
if (id[1] != SPINAND_MFR_GIGADEVICE)
return 0;
diff --git a/drivers/mtd/spi/Kconfig b/drivers/mtd/spi/Kconfig
index 5671bca..d3b007a 100644
--- a/drivers/mtd/spi/Kconfig
+++ b/drivers/mtd/spi/Kconfig
@@ -62,6 +62,9 @@ config SF_DEFAULT_MODE
The default mode may be provided by the platform
to handle the common case when only a single serial
flash is present on the system.
+ Not used for boot with device tree; the SPI driver reads
+ speed and mode from platdata values computed from
+ available node.
config SF_DEFAULT_SPEED
int "SPI Flash default speed in Hz"
@@ -71,6 +74,9 @@ config SF_DEFAULT_SPEED
The default speed may be provided by the platform
to handle the common case when only a single serial
flash is present on the system.
+ Not used for boot with device tree; the SPI driver reads
+ speed and mode from platdata values computed from
+ available node.
if SPI_FLASH
diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c
index 7f1378f..73297e1 100644
--- a/drivers/mtd/spi/sf_probe.c
+++ b/drivers/mtd/spi/sf_probe.c
@@ -166,7 +166,6 @@ static const struct dm_spi_flash_ops spi_flash_std_ops = {
};
static const struct udevice_id spi_flash_std_ids[] = {
- { .compatible = "spi-flash" },
{ .compatible = "jedec,spi-nor" },
{ }
};
diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index b7f0733..c4e2f6a 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -524,8 +524,11 @@ static int read_bar(struct spi_nor *nor, const struct flash_info *info)
*/
static int spi_nor_erase_sector(struct spi_nor *nor, u32 addr)
{
- u8 buf[SPI_NOR_MAX_ADDR_WIDTH];
- int i;
+ struct spi_mem_op op =
+ SPI_MEM_OP(SPI_MEM_OP_CMD(nor->erase_opcode, 1),
+ SPI_MEM_OP_ADDR(nor->addr_width, addr, 1),
+ SPI_MEM_OP_NO_DUMMY,
+ SPI_MEM_OP_NO_DATA);
if (nor->erase)
return nor->erase(nor, addr);
@@ -534,12 +537,7 @@ static int spi_nor_erase_sector(struct spi_nor *nor, u32 addr)
* Default implementation, if driver doesn't have a specialized HW
* control
*/
- for (i = nor->addr_width - 1; i >= 0; i--) {
- buf[i] = addr & 0xff;
- addr >>= 8;
- }
-
- return nor->write_reg(nor, nor->erase_opcode, buf, nor->addr_width);
+ return spi_mem_exec_op(nor->spi, &op);
}
/*
diff --git a/drivers/mtd/spi/spi-nor-ids.c b/drivers/mtd/spi/spi-nor-ids.c
index 3215e24..ec92976 100644
--- a/drivers/mtd/spi/spi-nor-ids.c
+++ b/drivers/mtd/spi/spi-nor-ids.c
@@ -106,6 +106,11 @@ const struct flash_info spi_nor_ids[] = {
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
},
+ {
+ INFO("gd25lq128", 0xc86018, 0, 64 * 1024, 256,
+ SECT_4K | SPI_NOR_DUAL_READ |
+ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
+ },
#endif
#ifdef CONFIG_SPI_FLASH_ISSI /* ISSI */
/* ISSI */
@@ -142,6 +147,7 @@ const struct flash_info spi_nor_ids[] = {
{ INFO("mx25l25655e", 0xc22619, 0, 64 * 1024, 512, 0) },
{ INFO("mx66l51235l", 0xc2201a, 0, 64 * 1024, 1024, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
{ INFO("mx66u51235f", 0xc2253a, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
+ { INFO("mx66u2g45g", 0xc2253c, 0, 64 * 1024, 4096, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
{ INFO("mx66l1g45g", 0xc2201b, 0, 64 * 1024, 2048, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("mx25l1633e", 0xc22415, 0, 64 * 1024, 32, SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES | SECT_4K) },
#endif
@@ -187,6 +193,7 @@ const struct flash_info spi_nor_ids[] = {
{ INFO("s25fl116k", 0x014015, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("s25fl164k", 0x014017, 0, 64 * 1024, 128, SECT_4K) },
{ INFO("s25fl208k", 0x014014, 0, 64 * 1024, 16, SECT_4K | SPI_NOR_DUAL_READ) },
+ { INFO("s25fl064l", 0x016017, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
{ INFO("s25fl128l", 0x016018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
#endif
#ifdef CONFIG_SPI_FLASH_SST /* SST */
diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c
index 11fce9c..efdb178 100644
--- a/drivers/spi/cadence_qspi.c
+++ b/drivers/spi/cadence_qspi.c
@@ -256,7 +256,7 @@ static int cadence_spi_xfer(struct udevice *dev, unsigned int bitlen,
break;
case CQSPI_INDIRECT_WRITE:
err = cadence_qspi_apb_indirect_write_setup
- (plat, priv->cmd_len, cmd_buf);
+ (plat, priv->cmd_len, dm_plat->mode, cmd_buf);
if (!err) {
err = cadence_qspi_apb_indirect_write_execute
(plat, data_bytes, dout);
diff --git a/drivers/spi/cadence_qspi.h b/drivers/spi/cadence_qspi.h
index 055900d..b491407 100644
--- a/drivers/spi/cadence_qspi.h
+++ b/drivers/spi/cadence_qspi.h
@@ -60,7 +60,7 @@ int cadence_qspi_apb_indirect_read_setup(struct cadence_spi_platdata *plat,
int cadence_qspi_apb_indirect_read_execute(struct cadence_spi_platdata *plat,
unsigned int rxlen, u8 *rxbuf);
int cadence_qspi_apb_indirect_write_setup(struct cadence_spi_platdata *plat,
- unsigned int cmdlen, const u8 *cmdbuf);
+ unsigned int cmdlen, unsigned int tx_width, const u8 *cmdbuf);
int cadence_qspi_apb_indirect_write_execute(struct cadence_spi_platdata *plat,
unsigned int txlen, const u8 *txbuf);
diff --git a/drivers/spi/cadence_qspi_apb.c b/drivers/spi/cadence_qspi_apb.c
index a8af352..55a7501 100644
--- a/drivers/spi/cadence_qspi_apb.c
+++ b/drivers/spi/cadence_qspi_apb.c
@@ -77,6 +77,7 @@
#define CQSPI_REG_WR_INSTR 0x08
#define CQSPI_REG_WR_INSTR_OPCODE_LSB 0
+#define CQSPI_REG_WR_INSTR_TYPE_DATA_LSB 16
#define CQSPI_REG_DELAY 0x0C
#define CQSPI_REG_DELAY_TSLCH_LSB 0
@@ -686,7 +687,7 @@ failrd:
/* Opcode + Address (3/4 bytes) */
int cadence_qspi_apb_indirect_write_setup(struct cadence_spi_platdata *plat,
- unsigned int cmdlen, const u8 *cmdbuf)
+ unsigned int cmdlen, unsigned int tx_width, const u8 *cmdbuf)
{
unsigned int reg;
unsigned int addr_bytes = cmdlen > 4 ? 4 : 3;
@@ -702,6 +703,10 @@ int cadence_qspi_apb_indirect_write_setup(struct cadence_spi_platdata *plat,
/* Configure the opcode */
reg = cmdbuf[0] << CQSPI_REG_WR_INSTR_OPCODE_LSB;
+
+ if (tx_width & SPI_TX_QUAD)
+ reg |= CQSPI_INST_TYPE_QUAD << CQSPI_REG_WR_INSTR_TYPE_DATA_LSB;
+
writel(reg, plat->regbase + CQSPI_REG_WR_INSTR);
/* Setup write address. */
diff --git a/drivers/spi/fsl_dspi.c b/drivers/spi/fsl_dspi.c
index 764c942..a68a519 100644
--- a/drivers/spi/fsl_dspi.c
+++ b/drivers/spi/fsl_dspi.c
@@ -273,7 +273,18 @@ static int dspi_xfer(struct fsl_dspi_priv *priv, uint cs, unsigned int bitlen,
if (len > 1) {
int tmp_len = len - 1;
while (tmp_len--) {
- if (dout != NULL) {
+ if ((dout != NULL) && (din != NULL)) {
+ if (priv->charbit == 16) {
+ dspi_tx(priv, ctrl, *spi_wr16++);
+ *spi_rd16++ = dspi_rx(priv);
+ }
+ else {
+ dspi_tx(priv, ctrl, *spi_wr++);
+ *spi_rd++ = dspi_rx(priv);
+ }
+ }
+
+ else if (dout != NULL) {
if (priv->charbit == 16)
dspi_tx(priv, ctrl, *spi_wr16++);
else
@@ -281,7 +292,7 @@ static int dspi_xfer(struct fsl_dspi_priv *priv, uint cs, unsigned int bitlen,
dspi_rx(priv);
}
- if (din != NULL) {
+ else if (din != NULL) {
dspi_tx(priv, ctrl, DSPI_IDLE_VAL);
if (priv->charbit == 16)
*spi_rd16++ = dspi_rx(priv);
@@ -297,7 +308,18 @@ static int dspi_xfer(struct fsl_dspi_priv *priv, uint cs, unsigned int bitlen,
ctrl &= ~DSPI_TFR_CONT;
if (len) {
- if (dout != NULL) {
+ if ((dout != NULL) && (din != NULL)) {
+ if (priv->charbit == 16) {
+ dspi_tx(priv, ctrl, *spi_wr16++);
+ *spi_rd16++ = dspi_rx(priv);
+ }
+ else {
+ dspi_tx(priv, ctrl, *spi_wr++);
+ *spi_rd++ = dspi_rx(priv);
+ }
+ }
+
+ else if (dout != NULL) {
if (priv->charbit == 16)
dspi_tx(priv, ctrl, *spi_wr16);
else
@@ -305,7 +327,7 @@ static int dspi_xfer(struct fsl_dspi_priv *priv, uint cs, unsigned int bitlen,
dspi_rx(priv);
}
- if (din != NULL) {
+ else if (din != NULL) {
dspi_tx(priv, ctrl, DSPI_IDLE_VAL);
if (priv->charbit == 16)
*spi_rd16 = dspi_rx(priv);
diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index 1bb0987..b86eee7 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -214,7 +214,7 @@ int spi_mem_exec_op(struct spi_slave *slave, const struct spi_mem_op *op)
if (ret < 0)
return ret;
- if (ops->mem_ops) {
+ if (ops->mem_ops && ops->mem_ops->exec_op) {
#ifndef __UBOOT__
/*
* Flush the message queue before executing our SPI memory
diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c
index 2bc289a..88cb2a1 100644
--- a/drivers/spi/spi-uclass.c
+++ b/drivers/spi/spi-uclass.c
@@ -328,7 +328,9 @@ int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode,
}
plat = dev_get_parent_platdata(dev);
- if (!speed) {
+
+ /* get speed and mode from platdata when available */
+ if (plat->max_hz) {
speed = plat->max_hz;
mode = plat->mode;
}