Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751895AbdIAH5t (ORCPT ); Fri, 1 Sep 2017 03:57:49 -0400 Received: from mail-io0-f194.google.com ([209.85.223.194]:33809 "EHLO mail-io0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751733AbdIAH43 (ORCPT ); Fri, 1 Sep 2017 03:56:29 -0400 X-Google-Smtp-Source: ADKCNb5QFvoGpjMmzDr47NOj8NQXLM3mtpAr9yA1C/NQPfubvcopqw5HmOtOUYsghnUEu5JIBsjYow== From: Bin Meng To: Mika Westerberg , Cyrille Pitchen , Marek Vasut , Boris Brezillon , Brian Norris , Richard Weinberger , David Woodhouse , linux-mtd , linux-kernel Cc: Stefan Roese Subject: [PATCH 05/10] spi-nor: intel-spi: Use SW sequencer for BYT/LPT Date: Fri, 1 Sep 2017 01:00:36 -0700 Message-Id: <1504252841-2445-6-git-send-email-bmeng.cn@gmail.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1504252841-2445-1-git-send-email-bmeng.cn@gmail.com> References: <1504252841-2445-1-git-send-email-bmeng.cn@gmail.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2993 Lines: 88 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 --- drivers/mtd/spi-nor/intel-spi.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/mtd/spi-nor/intel-spi.c b/drivers/mtd/spi-nor/intel-spi.c index c4a9de6..d0237fe 100644 --- a/drivers/mtd/spi-nor/intel-spi.c +++ b/drivers/mtd/spi-nor/intel-spi.c @@ -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,12 +326,24 @@ 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 * we are going to support as well. @@ -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); -- 2.9.2