summaryrefslogtreecommitdiff
path: root/drivers/mtd/nand/raw
diff options
context:
space:
mode:
authorMiquel Raynal <miquel.raynal@bootlin.com>2021-05-05 23:37:49 +0200
committerMiquel Raynal <miquel.raynal@bootlin.com>2021-05-26 10:52:49 +0200
commit10938a08fc4055667da7518685fbd8ea7d09de1b (patch)
treee45b99614c392c64e500d5295f640986f8c89532 /drivers/mtd/nand/raw
parent698ddeb89e01840dec05ffdb538468782e641a56 (diff)
mtd: rawnand: arasan: Workaround a misbehaving prog type with NV-DDR
As explained in the comment introduced above the fix, the Arasan controller driver starts an operation when the prog register is being written with a "type" specific to the action to perform. The prog type used until now to perform a CHANGE READ COLUMN with an SDR interface was the PAGE READ type (CMD + ADDR + CMD + DATA). Unfortunately, for an unknown reason (let's call this a silicon bug) any CHANGE READ COLUMN performed this way in NV-DDR mode will fail: the data ready flag will never be triggered, nor will be the transfer complete flag. Forcefully, this leads to a timeout situation which is not easy to handle. Fortunately, it was spotted that sending the same commands through a different prog register "type", CHANGE READ COLUMN ENHANCED, would work all the time (even though this particular command is not supported by the core and is only available in a limited set of devices - we only care about the controller configuration and not the actual command which is sent to the device). So let's use this type instead when a CHANGE READ COLUMN is requested. Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Link: https://lore.kernel.org/linux-mtd/20210505213750.257417-22-miquel.raynal@bootlin.com
Diffstat (limited to 'drivers/mtd/nand/raw')
-rw-r--r--drivers/mtd/nand/raw/arasan-nand-controller.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/drivers/mtd/nand/raw/arasan-nand-controller.c b/drivers/mtd/nand/raw/arasan-nand-controller.c
index d5fab3cbaa54..307300eeb9cb 100644
--- a/drivers/mtd/nand/raw/arasan-nand-controller.c
+++ b/drivers/mtd/nand/raw/arasan-nand-controller.c
@@ -53,6 +53,7 @@
#define PROG_RST BIT(8)
#define PROG_GET_FEATURE BIT(9)
#define PROG_SET_FEATURE BIT(10)
+#define PROG_CHG_RD_COL_ENH BIT(14)
#define INTR_STS_EN_REG 0x14
#define INTR_SIG_EN_REG 0x18
@@ -622,7 +623,23 @@ static int anfc_param_read_type_exec(struct nand_chip *chip,
static int anfc_data_read_type_exec(struct nand_chip *chip,
const struct nand_subop *subop)
{
- return anfc_misc_data_type_exec(chip, subop, PROG_PGRD);
+ u32 prog_reg = PROG_PGRD;
+
+ /*
+ * Experience shows that while in SDR mode sending a CHANGE READ COLUMN
+ * command through the READ PAGE "type" always works fine, when in
+ * NV-DDR mode the same command simply fails. However, it was also
+ * spotted that any CHANGE READ COLUMN command sent through the CHANGE
+ * READ COLUMN ENHANCED "type" would correctly work in both cases (SDR
+ * and NV-DDR). So, for simplicity, let's program the controller with
+ * the CHANGE READ COLUMN ENHANCED "type" whenever we are requested to
+ * perform a CHANGE READ COLUMN operation.
+ */
+ if (subop->instrs[0].ctx.cmd.opcode == NAND_CMD_RNDOUT &&
+ subop->instrs[2].ctx.cmd.opcode == NAND_CMD_RNDOUTSTART)
+ prog_reg = PROG_CHG_RD_COL_ENH;
+
+ return anfc_misc_data_type_exec(chip, subop, prog_reg);
}
static int anfc_param_write_type_exec(struct nand_chip *chip,