spi-nor: intel-spi: Use SW sequencer for BYT/LPT
Baytrail/Lynx Point SPI controller's HW sequencer only supports basic operations. This is determined by the chipset design, however current codes try to use register values in OPMENU0/OPMENU1 to see whether SW sequencer should be used, which is wrong. In fact OPMENU0/OPMENU1 can remain unprogrammed by some bootloaders. Signed-off-by: Bin Meng <bmeng.cn@gmail.com> Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Cyrille Pitchen <cyrille.pitchen@wedev4u.fr>
This commit is contained in:
parent
db2ce7f3c7
commit
fc2b347261
|
@ -290,6 +290,7 @@ static int intel_spi_init(struct intel_spi *ispi)
|
|||
ispi->pregs = ispi->base + BYT_PR;
|
||||
ispi->nregions = BYT_FREG_NUM;
|
||||
ispi->pr_num = BYT_PR_NUM;
|
||||
ispi->swseq = true;
|
||||
|
||||
if (writeable) {
|
||||
/* Disable write protection */
|
||||
|
@ -310,6 +311,7 @@ static int intel_spi_init(struct intel_spi *ispi)
|
|||
ispi->pregs = ispi->base + LPT_PR;
|
||||
ispi->nregions = LPT_FREG_NUM;
|
||||
ispi->pr_num = LPT_PR_NUM;
|
||||
ispi->swseq = true;
|
||||
break;
|
||||
|
||||
case INTEL_SPI_BXT:
|
||||
|
@ -324,11 +326,23 @@ static int intel_spi_init(struct intel_spi *ispi)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Disable #SMI generation */
|
||||
/* Disable #SMI generation from HW sequencer */
|
||||
val = readl(ispi->base + HSFSTS_CTL);
|
||||
val &= ~HSFSTS_CTL_FSMIE;
|
||||
writel(val, ispi->base + HSFSTS_CTL);
|
||||
|
||||
/*
|
||||
* Some controllers can only do basic operations using hardware
|
||||
* sequencer. All other operations are supposed to be carried out
|
||||
* using software sequencer.
|
||||
*/
|
||||
if (ispi->swseq) {
|
||||
/* Disable #SMI generation from SW sequencer */
|
||||
val = readl(ispi->sregs + SSFSTS_CTL);
|
||||
val &= ~SSFSTS_CTL_FSMIE;
|
||||
writel(val, ispi->sregs + SSFSTS_CTL);
|
||||
}
|
||||
|
||||
/*
|
||||
* BIOS programs allowed opcodes and then locks down the register.
|
||||
* So read back what opcodes it decided to support. That's the set
|
||||
|
@ -337,13 +351,6 @@ static int intel_spi_init(struct intel_spi *ispi)
|
|||
opmenu0 = readl(ispi->sregs + OPMENU0);
|
||||
opmenu1 = readl(ispi->sregs + OPMENU1);
|
||||
|
||||
/*
|
||||
* Some controllers can only do basic operations using hardware
|
||||
* sequencer. All other operations are supposed to be carried out
|
||||
* using software sequencer. If we find that BIOS has programmed
|
||||
* opcodes for the software sequencer we use that over the hardware
|
||||
* sequencer.
|
||||
*/
|
||||
if (opmenu0 && opmenu1) {
|
||||
for (i = 0; i < ARRAY_SIZE(ispi->opcodes) / 2; i++) {
|
||||
ispi->opcodes[i] = opmenu0 >> i * 8;
|
||||
|
@ -353,13 +360,6 @@ static int intel_spi_init(struct intel_spi *ispi)
|
|||
val = readl(ispi->sregs + PREOP_OPTYPE);
|
||||
ispi->preopcodes[0] = val;
|
||||
ispi->preopcodes[1] = val >> 8;
|
||||
|
||||
/* Disable #SMI generation from SW sequencer */
|
||||
val = readl(ispi->sregs + SSFSTS_CTL);
|
||||
val &= ~SSFSTS_CTL_FSMIE;
|
||||
writel(val, ispi->sregs + SSFSTS_CTL);
|
||||
|
||||
ispi->swseq = true;
|
||||
}
|
||||
|
||||
intel_spi_dump_regs(ispi);
|
||||
|
|
Loading…
Reference in New Issue