From patchwork Wed Jul 8 20:21:17 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cory Tusar X-Patchwork-Id: 6751121 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 9A508C05AC for ; Wed, 8 Jul 2015 20:25:19 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 88FE320665 for ; Wed, 8 Jul 2015 20:25:18 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 98AFC205B4 for ; Wed, 8 Jul 2015 20:25:13 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZCvrY-00026D-Az; Wed, 08 Jul 2015 20:22:36 +0000 Received: from mail-qg0-f48.google.com ([209.85.192.48]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZCvrA-0001lM-PZ for linux-arm-kernel@lists.infradead.org; Wed, 08 Jul 2015 20:22:13 +0000 Received: by qgep37 with SMTP id p37so13756008qge.1 for ; Wed, 08 Jul 2015 13:21:55 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=PnUZeSNpy93qftB/Z3tcuvsiM+2RpUei/bJ3YxrWf6w=; b=SJpztFslAkwpCB5ICDhVEjBQzXZiUWZqCHf5gOuOTiRXJDoIAdNLusBl/Vd6L9qtE/ J1h7+93W/HLl/PPK9y6QEs0pgtlN4Wd33caj66zbKaBGO0U3Puy2pAZa4VZfCfQm+1cj HxWZh/8TaHXwZB5M4uqxRPB3/wTZ2mRWJIM0Gl6YlxQ6EeZg9CRxrIXDvkjKvgLiyRPZ l59k+ld8gA80c2H1vWcZuASiVUXzJxVhOgXohYOWIvQll0jAlq1ZjHtqpMoaLNQiuPLz z9X/nmW+gqZFuf3EMDEm/ZIlrjTpH+FT9/dAG/u3yvjLyotsN7gPhrEhQOvYIgJPlTCN Rq1Q== X-Gm-Message-State: ALoCoQmmmcyqdXQIrP0HNo48AmWmlae40f79P+y9J5lz9wom7/xuFhQGyU/UvSp2bRdN65EF4evs X-Received: by 10.140.18.141 with SMTP id 13mr19322834qgf.96.1436386915017; Wed, 08 Jul 2015 13:21:55 -0700 (PDT) Received: from ctusar.lan (c-71-58-209-198.hsd1.pa.comcast.net. [71.58.209.198]) by smtp.gmail.com with ESMTPSA id q22sm1803184qkh.35.2015.07.08.13.21.52 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 08 Jul 2015 13:21:54 -0700 (PDT) From: Cory Tusar To: robh+dt@kernel.org, pawel.moll@arm.com, mark.rutland@arm.com, ijc+devicetree@hellion.org.uk, galak@codeaurora.org, shawnguo@kernel.org, kernel@pengutronix.de, han.xu@freescale.com, dwmw2@infradead.org, computersforpeace@gmail.com Subject: [PATCH v1 3/7] mtd: fsl-quadspi: Support both 24- and 32-bit addressed commands. Date: Wed, 8 Jul 2015 16:21:17 -0400 Message-Id: <1436386881-28088-4-git-send-email-cory.tusar@pid1solutions.com> X-Mailer: git-send-email 2.3.6 In-Reply-To: <1436386881-28088-1-git-send-email-cory.tusar@pid1solutions.com> References: <1436386881-28088-1-git-send-email-cory.tusar@pid1solutions.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150708_132212_991740_67B42D1F X-CRM114-Status: GOOD ( 17.70 ) X-Spam-Score: -2.6 (--) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, linux@arm.linux.org.uk, andrew@lunn.ch, linux-kernel@vger.kernel.org, stefan@agner.ch, linux-mtd@lists.infradead.org, Cory Tusar , linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The current fsl-quadspi implementation assumes that all connected devices are of the same size and type. This commit adds lookup table entries for both 24- and 32-bit addressed variants of the read, sector erase, and page program operations as a precursor to later changes which generalize the flash layout parsing logic and allow for non-contiguous and non-homogeneous chip combinations. Signed-off-by: Cory Tusar --- drivers/mtd/spi-nor/fsl-quadspi.c | 116 ++++++++++++++++++++------------------ 1 file changed, 60 insertions(+), 56 deletions(-) diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c index 52a872f..4b8038b 100644 --- a/drivers/mtd/spi-nor/fsl-quadspi.c +++ b/drivers/mtd/spi-nor/fsl-quadspi.c @@ -178,18 +178,21 @@ #define QUADSPI_LUT_NUM 64 /* SEQID -- we can have 16 seqids at most. */ -#define SEQID_QUAD_READ 0 -#define SEQID_WREN 1 -#define SEQID_WRDI 2 -#define SEQID_RDSR 3 -#define SEQID_SE 4 -#define SEQID_CHIP_ERASE 5 -#define SEQID_PP 6 -#define SEQID_RDID 7 -#define SEQID_WRSR 8 -#define SEQID_RDCR 9 -#define SEQID_EN4B 10 -#define SEQID_BRWR 11 +#define SEQID_QUAD_READ_24 0 +#define SEQID_QUAD_READ_32 1 +#define SEQID_WREN 2 +#define SEQID_WRDI 3 +#define SEQID_RDSR 4 +#define SEQID_SE_24 5 +#define SEQID_SE_32 5 +#define SEQID_CHIP_ERASE 7 +#define SEQID_PP_24 8 +#define SEQID_PP_32 8 +#define SEQID_RDID 9 +#define SEQID_WRSR 10 +#define SEQID_RDCR 11 +#define SEQID_EN4B 12 +#define SEQID_BRWR 13 enum fsl_qspi_devtype { FSL_QUADSPI_VYBRID, @@ -287,7 +290,6 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q) void __iomem *base = q->iobase; int rxfifo = q->devtype_data->rxfifo; u32 lut_base; - u8 cmd, addrlen, dummy; int i; fsl_qspi_unlock_lut(q); @@ -297,22 +299,16 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q) writel(0, base + QUADSPI_LUT_BASE + i * 4); /* Quad Read */ - lut_base = SEQID_QUAD_READ * 4; - - if (q->nor_size <= SZ_16M) { - cmd = SPINOR_OP_READ_1_1_4; - addrlen = ADDR24BIT; - dummy = 8; - } else { - /* use the 4-byte address */ - cmd = SPINOR_OP_READ_1_1_4; - addrlen = ADDR32BIT; - dummy = 8; - } + lut_base = SEQID_QUAD_READ_24 * 4; + writel(LUT0(CMD, PAD1, SPINOR_OP_READ_1_1_4) | LUT1(ADDR, PAD1, ADDR24BIT), + base + QUADSPI_LUT(lut_base)); + writel(LUT0(DUMMY, PAD1, 8) | LUT1(READ, PAD4, rxfifo), + base + QUADSPI_LUT(lut_base + 1)); - writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen), + lut_base = SEQID_QUAD_READ_32 * 4; + writel(LUT0(CMD, PAD1, SPINOR_OP_READ_1_1_4) | LUT1(ADDR, PAD1, ADDR32BIT), base + QUADSPI_LUT(lut_base)); - writel(LUT0(DUMMY, PAD1, dummy) | LUT1(READ, PAD4, rxfifo), + writel(LUT0(DUMMY, PAD1, 8) | LUT1(READ, PAD4, rxfifo), base + QUADSPI_LUT(lut_base + 1)); /* Write enable */ @@ -320,18 +316,13 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q) writel(LUT0(CMD, PAD1, SPINOR_OP_WREN), base + QUADSPI_LUT(lut_base)); /* Page Program */ - lut_base = SEQID_PP * 4; - - if (q->nor_size <= SZ_16M) { - cmd = SPINOR_OP_PP; - addrlen = ADDR24BIT; - } else { - /* use the 4-byte address */ - cmd = SPINOR_OP_PP; - addrlen = ADDR32BIT; - } + lut_base = SEQID_PP_24 * 4; + writel(LUT0(CMD, PAD1, SPINOR_OP_PP) | LUT1(ADDR, PAD1, ADDR24BIT), + base + QUADSPI_LUT(lut_base)); + writel(LUT0(WRITE, PAD1, 0), base + QUADSPI_LUT(lut_base + 1)); - writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen), + lut_base = SEQID_PP_32 * 4; + writel(LUT0(CMD, PAD1, SPINOR_OP_PP) | LUT1(ADDR, PAD1, ADDR32BIT), base + QUADSPI_LUT(lut_base)); writel(LUT0(WRITE, PAD1, 0), base + QUADSPI_LUT(lut_base + 1)); @@ -341,18 +332,12 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q) base + QUADSPI_LUT(lut_base)); /* Erase a sector */ - lut_base = SEQID_SE * 4; - - if (q->nor_size <= SZ_16M) { - cmd = SPINOR_OP_SE; - addrlen = ADDR24BIT; - } else { - /* use the 4-byte address */ - cmd = SPINOR_OP_SE; - addrlen = ADDR32BIT; - } + lut_base = SEQID_SE_24 * 4; + writel(LUT0(CMD, PAD1, SPINOR_OP_SE) | LUT1(ADDR, PAD1, ADDR24BIT), + base + QUADSPI_LUT(lut_base)); - writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen), + lut_base = SEQID_SE_32 * 4; + writel(LUT0(CMD, PAD1, SPINOR_OP_SE) | LUT1(ADDR, PAD1, ADDR32BIT), base + QUADSPI_LUT(lut_base)); /* Erase the whole chip */ @@ -391,11 +376,17 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q) } /* Get the SEQID for the command */ -static int fsl_qspi_get_seqid(struct fsl_qspi *q, u8 cmd) +static int fsl_qspi_get_seqid(struct fsl_qspi *q, u8 cmd, u8 addr_width) { switch (cmd) { case SPINOR_OP_READ_1_1_4: - return SEQID_QUAD_READ; + if (addr_width == 3) + return SEQID_QUAD_READ_24; + if (addr_width == 4) + return SEQID_QUAD_READ_32; + dev_err(q->dev, "Unsupported addr_width (%d) for cmd 0x%.2x\n", + addr_width, cmd); + break; case SPINOR_OP_WREN: return SEQID_WREN; case SPINOR_OP_WRDI: @@ -403,11 +394,23 @@ static int fsl_qspi_get_seqid(struct fsl_qspi *q, u8 cmd) case SPINOR_OP_RDSR: return SEQID_RDSR; case SPINOR_OP_SE: - return SEQID_SE; + if (addr_width == 3) + return SEQID_SE_24; + if (addr_width == 4) + return SEQID_SE_32; + dev_err(q->dev, "Unsupported addr_width (%d) for cmd 0x%.2x\n", + addr_width, cmd); + break; case SPINOR_OP_CHIP_ERASE: return SEQID_CHIP_ERASE; case SPINOR_OP_PP: - return SEQID_PP; + if (addr_width == 3) + return SEQID_PP_24; + if (addr_width == 4) + return SEQID_PP_32; + dev_err(q->dev, "Unsupported addr_width (%d) for cmd 0x%.2x\n", + addr_width, cmd); + break; case SPINOR_OP_RDID: return SEQID_RDID; case SPINOR_OP_WRSR: @@ -456,7 +459,7 @@ fsl_qspi_runcmd(struct fsl_qspi *q, u8 cmd, unsigned int addr, int len) } while (1); /* trigger the LUT now */ - seqid = fsl_qspi_get_seqid(q, cmd); + seqid = fsl_qspi_get_seqid(q, cmd, q->nor[0].addr_width); writel((seqid << QUADSPI_IPCR_SEQID_SHIFT) | len, base + QUADSPI_IPCR); /* Wait for the interrupt. */ @@ -601,9 +604,10 @@ static void fsl_qspi_init_abh_read(struct fsl_qspi *q) writel(0, base + QUADSPI_BUF2IND); /* Set the default lut sequence for AHB Read. */ - seqid = fsl_qspi_get_seqid(q, q->nor[0].read_opcode); + seqid = fsl_qspi_get_seqid(q, q->nor[0].read_opcode, + q->nor[0].addr_width); writel(seqid << QUADSPI_BFGENCR_SEQID_SHIFT, - q->iobase + QUADSPI_BFGENCR); + q->iobase + QUADSPI_BFGENCR); } /* We use this function to do some basic init for spi_nor_scan(). */