Commit 10938a08 authored by Miquel Raynal's avatar Miquel Raynal
Browse files

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: default avatarMiquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20210505213750.257417-22-miquel.raynal@bootlin.com
parent 698ddeb8
Loading
Loading
Loading
Loading
+18 −1
Original line number Diff line number Diff line
@@ -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,