Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fc2b3472 authored by Bin Meng's avatar Bin Meng Committed by Cyrille Pitchen
Browse files

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: default avatarBin Meng <bmeng.cn@gmail.com>
Acked-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: default avatarCyrille Pitchen <cyrille.pitchen@wedev4u.fr>
parent db2ce7f3
Loading
Loading
Loading
Loading
+15 −15
Original line number Diff line number Diff line
@@ -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);