+Mika Westerberg original author of the driver On 18/05/20 11:29 pm, Daniel Walker wrote: > From: Bobby Liu <bobbliu@xxxxxxxxx> > > How to use: > append softwareseq=1 while probe the driver. > example: > modprobe intel-spi writeable=1 softwareseq=1 > it will let driver use software sequence to write register for opt=EN4B > by default it's 0 if not specified, driver will do usual HW cycle > Could some one from Intel please review this patch? Regards Vignesh > Why this parameter is posted to user: > Intel PCH provides two groups of registers for SPI flash operation, > Hard Sequence registers and Software Sequence registers, > corresponding to intel_spi_hw_cycle() and intel_spi_sw_cycle() > respectively in driver code. But HW sequence register won't send EN4B > opcode to SPI flash. BIOS code use SW register to send EN4B. > > On some Cisco routers, two 32M SPI flashes, which require 4-byte address mode enabled, > are physically connected to an FPGA, one flash is active and one is inactive. > When we do BIOS upgrade, we need switch to the inactive one, > but unfortunately, this one is still 3-byte address mode as default, > after we do real-time switch, we need reload SPI driver to send EN4B code to > enable 4-byte address mode. > > Refering to our BIOS code, Software sequence register is processed > while sending EN4B opcode. So here we use sw_cycle in driver for EN4B as well. > > Why I don't just easily use software sequence for all: > 1.It will impact all flash operation, include flash W/R, high risk > 2.The only SPI type I can use is INTEL_SPI_BXT according to datasheet, > this will require using hw seq. > I tried to specify other SPI type, it couldn't work with Intel PCH. > If I force SW seq for all, during boot up, sw_cycle fails to read > vendor ID. > > In conclusion, I only use SW cycle for EN4B opcode to minimize impact. > It won't impact other users as well. > > Why the default flash can work at 4-byte address mode: > BIOS sets 4-byte address mode for the current active SPI flash with SW seq registers. > So we don't need append softwareseq=1 for normal boot up script, > it will only be used in BIOS upgrade script. > > Cc: xe-linux-external@xxxxxxxxx > Signed-off-by: Bobby Liu <bobbliu@xxxxxxxxx> > [ danielwa: edited the commit message a little. ] > Signed-off-by: Daniel Walker <danielwa@xxxxxxxxx> > --- > drivers/mtd/spi-nor/controllers/intel-spi.c | 16 ++++++++++++++++ > 1 file changed, 16 insertions(+) > > diff --git a/drivers/mtd/spi-nor/controllers/intel-spi.c b/drivers/mtd/spi-nor/controllers/intel-spi.c > index 61d2a0ad2131..e5a3d51a2e4d 100644 > --- a/drivers/mtd/spi-nor/controllers/intel-spi.c > +++ b/drivers/mtd/spi-nor/controllers/intel-spi.c > @@ -163,6 +163,10 @@ static bool writeable; > module_param(writeable, bool, 0); > MODULE_PARM_DESC(writeable, "Enable write access to SPI flash chip (default=0)"); > > +static bool softwareseq; > +module_param(softwareseq, bool, 0); > +MODULE_PARM_DESC(softwareseq, "Use software sequence for register write (default=0)"); > + > static void intel_spi_dump_regs(struct intel_spi *ispi) > { > u32 value; > @@ -619,6 +623,18 @@ static int intel_spi_write_reg(struct spi_nor *nor, u8 opcode, const u8 *buf, > if (ret) > return ret; > > + /* > + * Intel Skylake will not send EN4B to SPI flash if we use HW sequence > + * Here export one interface "softwareseq" to OS, > + * let driver user decide if use SW sequence or not > + */ > + if (opcode == SPINOR_OP_EN4B && softwareseq) { > + dev_info(ispi->dev, > + "Write register opcode is SPINOR_OP_EN4B, do SW cycle\n"); > + return intel_spi_sw_cycle(ispi, opcode, len, > + OPTYPE_WRITE_NO_ADDR); > + } > + > if (ispi->swseq_reg) > return intel_spi_sw_cycle(ispi, opcode, len, > OPTYPE_WRITE_NO_ADDR); > ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/