提交 fc2b3472 编写于 作者: B Bin Meng 提交者: Cyrille Pitchen

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: NBin Meng <bmeng.cn@gmail.com>
Acked-by: NMika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: NCyrille Pitchen <cyrille.pitchen@wedev4u.fr>
上级 db2ce7f3
......@@ -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);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册