From patchwork Tue Jan 26 07:23:55 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: yao yuan X-Patchwork-Id: 8118261 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 56C739F859 for ; Tue, 26 Jan 2016 07:34:30 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E399B202FF for ; Tue, 26 Jan 2016 07:34:28 +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 7A923202BE for ; Tue, 26 Jan 2016 07:34:27 +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 1aNy7J-0001oS-U7; Tue, 26 Jan 2016 07:32:45 +0000 Received: from mail-by2on0134.outbound.protection.outlook.com ([207.46.100.134] helo=na01-by2-obe.outbound.protection.outlook.com) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1aNy7G-0001m9-4p; Tue, 26 Jan 2016 07:32:43 +0000 Received: from BY2PR03CA071.namprd03.prod.outlook.com (10.141.249.44) by BN1PR03MB072.namprd03.prod.outlook.com (10.255.225.156) with Microsoft SMTP Server (TLS) id 15.1.365.19; Tue, 26 Jan 2016 07:32:18 +0000 Received: from BY2FFO11OLC008.protection.gbl (2a01:111:f400:7c0c::136) by BY2PR03CA071.outlook.office365.com (2a01:111:e400:2c5d::44) with Microsoft SMTP Server (TLS) id 15.1.390.13 via Frontend Transport; Tue, 26 Jan 2016 07:32:17 +0000 Authentication-Results: spf=permerror (sender IP is 192.88.168.50) smtp.mailfrom=freescale.com; nxp.com; dkim=none (message not signed) header.d=none; nxp.com; dmarc=none action=none header.from=freescale.com; Received-SPF: PermError (protection.outlook.com: domain of freescale.com used an invalid SPF mechanism) Received: from tx30smr01.am.freescale.net (192.88.168.50) by BY2FFO11OLC008.mail.protection.outlook.com (10.1.14.255) with Microsoft SMTP Server (TLS) id 15.1.355.15 via Frontend Transport; Tue, 26 Jan 2016 07:32:17 +0000 Received: from titan.ap.freescale.net ([10.192.208.233]) by tx30smr01.am.freescale.net (8.14.3/8.14.0) with ESMTP id u0Q7WBbW009330; Tue, 26 Jan 2016 00:32:13 -0700 From: Yuan Yao To: , , Subject: [PATCH v4 1/7] mtd: spi-nor: fsl-quadspi: add big-endian support Date: Tue, 26 Jan 2016 15:23:55 +0800 Message-ID: <1453793041-35868-1-git-send-email-yao.yuan@freescale.com> X-Mailer: git-send-email 2.1.0.27.g96db324 X-EOPAttributedMessage: 0 X-Microsoft-Exchange-Diagnostics: 1; BY2FFO11OLC008; 1:tc8nG29FI8tPBCT+RpA3yHYHR2N7a6F0oQPf3qVlrdzUBRB4NoRIkb2ECq6m4v118JIqQk/YtdOdUUHTFPUqWN/b0wqdjq0nczuguz3qAAhq+XjI/JYnYdzacTdUKy1XF0IyJlURb56jBrLHwEFdgNtneiYWeMj9NnRzQE4XgQRBThQDCKxVGVmX5Oe2VeObliuQhQin5p05ndHjl+g7vW/A/XTSdxvQlqlll0nLzbUaNp1Lgr2V1+gDS62FhfSZL9jEcraQ8fukPqWW1MeOSv8blvwsS76qPuCfmPB7WvBQ8v9vpRSVEa9lzDgb47fZ/p5v5J839u/RMItxF1BxMriVBpBAIBS0zO8p9ARpUANaGR38xcrEJ4l5DYekocXQdteyGn+9kaFAbomhgs5wmambkaBNK2j5HH6lNH5s/rFeXYpVyRziLGHxvj0GKSD0 X-Forefront-Antispam-Report: CIP:192.88.168.50; CTRY:US; IPV:NLI; EFV:NLI; SFV:NSPM; SFS:(10019020)(6009001)(2980300002)(448002)(189002)(199003)(479174004)(4326007)(2201001)(2906002)(50466002)(87936001)(4001450100002)(19580405001)(575784001)(86362001)(92566002)(33646002)(36756003)(5003940100001)(85326001)(50226001)(1220700001)(104016004)(77096005)(1096002)(11100500001)(229853001)(5001960100002)(106466001)(48376002)(81156007)(19580395003)(5001770100001)(97736004)(47776003)(6806005)(5008740100001)(50986999)(586003)(189998001)(7059030); DIR:OUT; SFP:1102; SCL:1; SRVR:BN1PR03MB072; H:tx30smr01.am.freescale.net; FPR:; SPF:PermError; PTR:InfoDomainNonexistent; MX:1; A:1; LANG:en; MIME-Version: 1.0 X-MS-Office365-Filtering-Correlation-Id: 3b65cb76-14fa-4f55-631f-08d32622d165 X-Microsoft-Exchange-Diagnostics: 1; BN1PR03MB072; 2:TxiXf7jqJ+taNjoEk/141mGOqqoQ3XnLVI63v1VlcnuBe4pScXtUK3uPP53hJk/tzkmZajrS9aGCwr5TFQ26WDYSe/VMdzKnIXB89krOgzpHIAIq0f++WDISpGa4gRM1Anhc/soqsbQibF3Od9WUHVu7Uh/TCaBtXqRABa0Yvl0cGTxlQlJw0Q2HnuuaCAbk; 3:eEEOiYIoeJJp9o+YRf/WedGtUrXx5tCsrMnj/kmQUXukXHKuf/i6DcmcPinMCxNjH69xZz3qGRBAX95Cnf41/WWLZV1ArAE15OdwPfOiezbJhZvw7ZNewsAkreIHC5jXo9LiLjVUSHGrewHtbvTGt3Cht5ILtcR5pX1SD/v7Jw2G7x5qVo4ABuQ+laW7ixH/4MrhW3o+08Y/UvL0/f8b9l/cmUJsWSf3yQ9pSBRFFWk=; 25:6XNwmxTbMj9ylcD4E6wqbnRaPch5NIfjkXxdkELY+jPg4RXuBcQEpTPDLTo4lYYZKaDVX/wOP4Cg2mvEIUnkZVV9IIOt/Lc501eCXuiFvLnMKDzZzyrjDCKDo/SAY1prtAdsqpEGcf47CAd5XbMnP2dbNVhoPvq+YeSAv64bXPP2FHsjTiN/srWRQHvN8WDt2PgPRtZYC8akCFdDolDCmEwtfKgXCoJimuAq39+i6StOXQyephnUdE8+X0WV9gRq X-Exchange-Antispam-Report-Test: UriScan:; BCL:0; PCL:0; RULEID:; SRVR:BN1PR03MB072; UriScan:(185117386973197)(101931422205132); X-Microsoft-Exchange-Diagnostics: 1; BN1PR03MB072; 20:DmWsmGHa1HKVd7Jv0XQB1126pgixBjiP3bx3rj49X1EjCxbaJqJ2AhKAVYyLPSSN6uxOBCi0M2Lk8Aj18GJjjvvsQz8xJ7BAVMw3vxGbA+k/amPoEGJFaEmfcErzNBlmf7RX/VTEUuKrUDISEttF1ZGMxiJi/iUUmfTNRfoesdf+LXC/RuPJhQVt8RzmBx8IKjAa6L+L0xrx45KKfifdC/fxuqIadmxYTU46XIFFzmeUTsB8zlF0jP1Qpwn1wCHoXHXRhkqHEP/8Vmww1Ojde5TgMNbq92EGjTuP28ldtIzxuUw0lSzvixxfg1YVreSGXniwrqq+H7hBEOANt49U6jaUEU2dBFIMQsanWBPoUZqjrI7OtJ1eu6HncX6GuXpe7laLS0zUc/1HIFSdIDkMagF44JKp5MYFJOzn+5/a8lJHtcGDM2deqdPSbVN7VlRk X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(2401047)(13024025)(13015025)(5005006)(13023025)(520078)(13018025)(8121501046)(13017025)(3002001)(10201501046); SRVR:BN1PR03MB072; BCL:0; PCL:0; RULEID:; SRVR:BN1PR03MB072; X-Microsoft-Exchange-Diagnostics: 1; BN1PR03MB072; 4:BjxI6+uLvEcQ7fBchkdWhu6JhVTjGivU/edxsxgDVYy9qWIjzrMhUwx41OluhYRM+Ao9EsfIhZQDZSL8Z2NQtfXHQRJN49zVCl0uhc4lqWKLDOTAX6t07X5lAZINcISgWvg6WTEjcaDzvmNNYDfq41jWAWhVPfGunXr9o2YVXnPIoHWutOdjpqgXkM4AQk4p9pfXU1tzo4bn/NVIz8ipyzrGW66kKaFFU3JztSdYTMLOfmFiD8zRHLC9PmniXiSlzWJKwyM1SnUxf7JVjP7I9M+LgIaeBIYTsGOMzS9kh/sB9mfxTU/gcCNnQbsyOcS4rE97ZQGCFh+JbHxY8/jkTSnz3ezN/7vi1S32dkHXtAtsC32AvQ5Zec2OpzgSZoKV0jZ3itz6iS3ANV56Y3uw9DPQaMoRDaDA/oXgmauD7ONrxftfVCmo6B/f8bknUB4y/jQyLmJGOAkNLdhCbyFSJHzFwtkLxrW5TduQ1Z/oBWYcHxX/5MpUXnSVhfgLAfS0r6xUcE94z2mBEaDlFsC3U08sBFZb+yeFLp4RzclaU2ylOhSmM+H1pGkHWdoYd9K5 X-Forefront-PRVS: 08331F819E X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; BN1PR03MB072; 23:C0TXUSpmIZys200SktQtWjP9iUIRwRGRt3JIVrq33q?= =?us-ascii?Q?9xvJRWp79WutW/roNzdI02VuspT4fs7aIug1nGETeDpGVFQJQnj/dlf89frv?= =?us-ascii?Q?+8lCcp1gDFtTGpULfWEPfEuG8MoTjFZfibg//wIuAqAO1o0qGr7asVwJr/PC?= =?us-ascii?Q?a10O5kx0zJKExXjVofI6HG7OzciedlMRcB3xkINOBsTZX9pTpIgZSeoH2GJP?= =?us-ascii?Q?cxkfYI1GqkIR2SeGWLmp6nD6kQ1N7DZfr37zbkr21qcXZDbk81QZxwtBBDML?= =?us-ascii?Q?BuIWbKIvMZDmEbBIf/kejfkc311P5aENPNXXZgiMdQ7O+8y/0g/Lj/2ibpaS?= =?us-ascii?Q?+DSaIjqmXM4MW0+KXGqxL43lB40vYo9gVzaO4N2MgOWnPAqs+j2K6DKLle3Z?= =?us-ascii?Q?EDWfkyWB6CWhyXk+sArOa6W7oFP0i6oxRbckw5lWS9HN6L/WjUqaOsJcNVPW?= =?us-ascii?Q?+UELXQPlXNZ9AeoAxKmlTiFzVk9Gfv1ZjBiFwJ5qcfa6qnE/PIlyDVFffJ+y?= =?us-ascii?Q?uA9Ij8h+YcOxejf/4ba3qRQ2/tSABN89blYtLVes/e3gwzd8qpplaNTgfaDM?= =?us-ascii?Q?bkuObvHUd152CAkqhTd0WR558XvinEjcuP2SI9VyN38lHltT075HDlpSp0M3?= =?us-ascii?Q?IThSQ/1dk/QAxZMOG4VTqLOVtJ7jYH+WRPpq8fSnvtmF3v43atX4dZnT1SPJ?= =?us-ascii?Q?G9P5UQa5fzdZ1achOVGW+T4meqzmnHe2OZjM4m+3nxiNVXL/SPHZVKNBBavC?= =?us-ascii?Q?LSF2v6jQvIV16aQp4tALR6BEfX8wl635tVjAUtZ/cKZqAkyzwimW+PY/KsJm?= =?us-ascii?Q?sMqvXbBizk8Qe0Jpr4nGc+Hf5H9OVd+x5nTWTkWZTQJ72Vw1r625w5L5aPnG?= =?us-ascii?Q?e+zXHuTUe0r6UOHA6NrgnTT2Le9D4enusy6D63jp6uvCBMXMepNEFmAsUhj1?= =?us-ascii?Q?dyqYPLGkTtCSvl6qE2L4lkoPPfIQV+pAMvzspgPL2BqaWQQvDsRKmPJuxPPb?= =?us-ascii?Q?WmciaTVB++s202sJnx/jO5k7x8uTmp/92Gaw5MygrubuTi2zOZRTAAwlWq8/?= =?us-ascii?Q?lHFY7RE3xcGTbnDWIZ9BJSAUDMlVINDYN1MLjBXm8D9cDGkA=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1; BN1PR03MB072; 5:9aPMSSxoFCaTuTgSv+iIRzU9wJYjB+SH/aTFnTFOHojiqZ4dSzOQ+sY64d4BZpjBfSMXCUGLtwEZfhDGxO9kdAoIIHhbCce1Y9UTJL+g8Mx/4eSMZvGg23amrTnRI+J2mSzrpQhuepNsSY1//cK/wQ==; 24:TIu/1mnVW0BCfndGBu7AQDRyMSYiTRTE9ywcQ4LqnDYe2XIndj1DoNRKsXFtCTFDVOMtv6gTMRfA2OfszqYJeGWxuKKQNGvV01bEWD3OSxE= X-OriginatorOrg: freescale.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 26 Jan 2016 07:32:17.1170 (UTC) X-MS-Exchange-CrossTenant-Id: 710a03f5-10f6-4d38-9ff4-a80b81da590d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=710a03f5-10f6-4d38-9ff4-a80b81da590d; Ip=[192.88.168.50]; Helo=[tx30smr01.am.freescale.net] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN1PR03MB072 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160125_233242_285633_B42347AD X-CRM114-Status: GOOD ( 19.48 ) X-Spam-Score: -1.9 (-) 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-kernel@vger.kernel.org, linux-mtd@lists.infradead.org, yao.yuan@nxp.com, linux-arm-kernel@lists.infradead.org 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.2 required=5.0 tests=BAD_ENC_HEADER,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 Add R/W functions for big- or little-endian registers: The qSPI controller's endian is independent of the CPU core's endian. So far, the qSPI have two versions for big-endian and little-endian. Signed-off-by: Yuan Yao Acked-by: Han xu Acked-by: Han xu --- Changed in v4: No changes. Changed in v3: Update my email to Changed in v2: Rebase to the lastest code. --- drivers/mtd/spi-nor/fsl-quadspi.c | 157 +++++++++++++++++++++++--------------- 1 file changed, 97 insertions(+), 60 deletions(-) diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c index 54640f1..04e8a93 100644 --- a/drivers/mtd/spi-nor/fsl-quadspi.c +++ b/drivers/mtd/spi-nor/fsl-quadspi.c @@ -275,6 +275,7 @@ struct fsl_qspi { u32 clk_rate; unsigned int chip_base_addr; /* We may support two chips. */ bool has_second_chip; + bool big_endian; struct mutex lock; struct pm_qos_request pm_qos_req; }; @@ -300,6 +301,28 @@ static inline int needs_wakeup_wait_mode(struct fsl_qspi *q) } /* + * R/W functions for big- or little-endian registers: + * The qSPI controller's endian is independent of the CPU core's endian. + * So far, although the CPU core is little-endian but the qSPI have two + * versions for big-endian and little-endian. + */ +static void qspi_writel(struct fsl_qspi *q, u32 val, void __iomem *addr) +{ + if (q->big_endian) + iowrite32be(val, addr); + else + iowrite32(val, addr); +} + +static u32 qspi_readl(struct fsl_qspi *q, void __iomem *addr) +{ + if (q->big_endian) + return ioread32be(addr); + else + return ioread32(addr); +} + +/* * An IC bug makes us to re-arrange the 32-bit data. * The following chips, such as IMX6SLX, have fixed this bug. */ @@ -310,14 +333,14 @@ static inline u32 fsl_qspi_endian_xchg(struct fsl_qspi *q, u32 a) static inline void fsl_qspi_unlock_lut(struct fsl_qspi *q) { - writel(QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY); - writel(QUADSPI_LCKER_UNLOCK, q->iobase + QUADSPI_LCKCR); + qspi_writel(q, QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY); + qspi_writel(q, QUADSPI_LCKER_UNLOCK, q->iobase + QUADSPI_LCKCR); } static inline void fsl_qspi_lock_lut(struct fsl_qspi *q) { - writel(QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY); - writel(QUADSPI_LCKER_LOCK, q->iobase + QUADSPI_LCKCR); + qspi_writel(q, QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY); + qspi_writel(q, QUADSPI_LCKER_LOCK, q->iobase + QUADSPI_LCKCR); } static irqreturn_t fsl_qspi_irq_handler(int irq, void *dev_id) @@ -326,8 +349,8 @@ static irqreturn_t fsl_qspi_irq_handler(int irq, void *dev_id) u32 reg; /* clear interrupt */ - reg = readl(q->iobase + QUADSPI_FR); - writel(reg, q->iobase + QUADSPI_FR); + reg = qspi_readl(q, q->iobase + QUADSPI_FR); + qspi_writel(q, reg, q->iobase + QUADSPI_FR); if (reg & QUADSPI_FR_TFF_MASK) complete(&q->c); @@ -348,7 +371,7 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q) /* Clear all the LUT table */ for (i = 0; i < QUADSPI_LUT_NUM; i++) - writel(0, base + QUADSPI_LUT_BASE + i * 4); + qspi_writel(q, 0, base + QUADSPI_LUT_BASE + i * 4); /* Quad Read */ lut_base = SEQID_QUAD_READ * 4; @@ -364,14 +387,15 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q) dummy = 8; } - writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen), + qspi_writel(q, LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen), base + QUADSPI_LUT(lut_base)); - writel(LUT0(DUMMY, PAD1, dummy) | LUT1(FSL_READ, PAD4, rxfifo), + qspi_writel(q, LUT0(DUMMY, PAD1, dummy) | LUT1(FSL_READ, PAD4, rxfifo), base + QUADSPI_LUT(lut_base + 1)); /* Write enable */ lut_base = SEQID_WREN * 4; - writel(LUT0(CMD, PAD1, SPINOR_OP_WREN), base + QUADSPI_LUT(lut_base)); + qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WREN), + base + QUADSPI_LUT(lut_base)); /* Page Program */ lut_base = SEQID_PP * 4; @@ -385,13 +409,15 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q) addrlen = ADDR32BIT; } - writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen), + qspi_writel(q, LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen), base + QUADSPI_LUT(lut_base)); - writel(LUT0(FSL_WRITE, PAD1, 0), base + QUADSPI_LUT(lut_base + 1)); + qspi_writel(q, LUT0(FSL_WRITE, PAD1, 0), + base + QUADSPI_LUT(lut_base + 1)); /* Read Status */ lut_base = SEQID_RDSR * 4; - writel(LUT0(CMD, PAD1, SPINOR_OP_RDSR) | LUT1(FSL_READ, PAD1, 0x1), + qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDSR) | + LUT1(FSL_READ, PAD1, 0x1), base + QUADSPI_LUT(lut_base)); /* Erase a sector */ @@ -400,40 +426,46 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q) cmd = q->nor[0].erase_opcode; addrlen = q->nor_size <= SZ_16M ? ADDR24BIT : ADDR32BIT; - writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen), + qspi_writel(q, LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen), base + QUADSPI_LUT(lut_base)); /* Erase the whole chip */ lut_base = SEQID_CHIP_ERASE * 4; - writel(LUT0(CMD, PAD1, SPINOR_OP_CHIP_ERASE), + qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_CHIP_ERASE), base + QUADSPI_LUT(lut_base)); /* READ ID */ lut_base = SEQID_RDID * 4; - writel(LUT0(CMD, PAD1, SPINOR_OP_RDID) | LUT1(FSL_READ, PAD1, 0x8), + qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDID) | + LUT1(FSL_READ, PAD1, 0x8), base + QUADSPI_LUT(lut_base)); /* Write Register */ lut_base = SEQID_WRSR * 4; - writel(LUT0(CMD, PAD1, SPINOR_OP_WRSR) | LUT1(FSL_WRITE, PAD1, 0x2), + qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WRSR) | + LUT1(FSL_WRITE, PAD1, 0x2), base + QUADSPI_LUT(lut_base)); /* Read Configuration Register */ lut_base = SEQID_RDCR * 4; - writel(LUT0(CMD, PAD1, SPINOR_OP_RDCR) | LUT1(FSL_READ, PAD1, 0x1), + qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDCR) | + LUT1(FSL_READ, PAD1, 0x1), base + QUADSPI_LUT(lut_base)); /* Write disable */ lut_base = SEQID_WRDI * 4; - writel(LUT0(CMD, PAD1, SPINOR_OP_WRDI), base + QUADSPI_LUT(lut_base)); + qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WRDI), + base + QUADSPI_LUT(lut_base)); /* Enter 4 Byte Mode (Micron) */ lut_base = SEQID_EN4B * 4; - writel(LUT0(CMD, PAD1, SPINOR_OP_EN4B), base + QUADSPI_LUT(lut_base)); + qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_EN4B), + base + QUADSPI_LUT(lut_base)); /* Enter 4 Byte Mode (Spansion) */ lut_base = SEQID_BRWR * 4; - writel(LUT0(CMD, PAD1, SPINOR_OP_BRWR), base + QUADSPI_LUT(lut_base)); + qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_BRWR), + base + QUADSPI_LUT(lut_base)); fsl_qspi_lock_lut(q); } @@ -488,15 +520,16 @@ fsl_qspi_runcmd(struct fsl_qspi *q, u8 cmd, unsigned int addr, int len) q->chip_base_addr, addr, len, cmd); /* save the reg */ - reg = readl(base + QUADSPI_MCR); + reg = qspi_readl(q, base + QUADSPI_MCR); - writel(q->memmap_phy + q->chip_base_addr + addr, base + QUADSPI_SFAR); - writel(QUADSPI_RBCT_WMRK_MASK | QUADSPI_RBCT_RXBRD_USEIPS, + qspi_writel(q, q->memmap_phy + q->chip_base_addr + addr, + base + QUADSPI_SFAR); + qspi_writel(q, QUADSPI_RBCT_WMRK_MASK | QUADSPI_RBCT_RXBRD_USEIPS, base + QUADSPI_RBCT); - writel(reg | QUADSPI_MCR_CLR_RXF_MASK, base + QUADSPI_MCR); + qspi_writel(q, reg | QUADSPI_MCR_CLR_RXF_MASK, base + QUADSPI_MCR); do { - reg2 = readl(base + QUADSPI_SR); + reg2 = qspi_readl(q, base + QUADSPI_SR); if (reg2 & (QUADSPI_SR_IP_ACC_MASK | QUADSPI_SR_AHB_ACC_MASK)) { udelay(1); dev_dbg(q->dev, "The controller is busy, 0x%x\n", reg2); @@ -507,21 +540,22 @@ fsl_qspi_runcmd(struct fsl_qspi *q, u8 cmd, unsigned int addr, int len) /* trigger the LUT now */ seqid = fsl_qspi_get_seqid(q, cmd); - writel((seqid << QUADSPI_IPCR_SEQID_SHIFT) | len, base + QUADSPI_IPCR); + qspi_writel(q, (seqid << QUADSPI_IPCR_SEQID_SHIFT) | len, + base + QUADSPI_IPCR); /* Wait for the interrupt. */ if (!wait_for_completion_timeout(&q->c, msecs_to_jiffies(1000))) { dev_err(q->dev, "cmd 0x%.2x timeout, addr@%.8x, FR:0x%.8x, SR:0x%.8x\n", - cmd, addr, readl(base + QUADSPI_FR), - readl(base + QUADSPI_SR)); + cmd, addr, qspi_readl(q, base + QUADSPI_FR), + qspi_readl(q, base + QUADSPI_SR)); err = -ETIMEDOUT; } else { err = 0; } /* restore the MCR */ - writel(reg, base + QUADSPI_MCR); + qspi_writel(q, reg, base + QUADSPI_MCR); return err; } @@ -533,7 +567,7 @@ static void fsl_qspi_read_data(struct fsl_qspi *q, int len, u8 *rxbuf) int i = 0; while (len > 0) { - tmp = readl(q->iobase + QUADSPI_RBDR + i * 4); + tmp = qspi_readl(q, q->iobase + QUADSPI_RBDR + i * 4); tmp = fsl_qspi_endian_xchg(q, tmp); dev_dbg(q->dev, "chip addr:0x%.8x, rcv:0x%.8x\n", q->chip_base_addr, tmp); @@ -561,9 +595,9 @@ static inline void fsl_qspi_invalid(struct fsl_qspi *q) { u32 reg; - reg = readl(q->iobase + QUADSPI_MCR); + reg = qspi_readl(q, q->iobase + QUADSPI_MCR); reg |= QUADSPI_MCR_SWRSTHD_MASK | QUADSPI_MCR_SWRSTSD_MASK; - writel(reg, q->iobase + QUADSPI_MCR); + qspi_writel(q, reg, q->iobase + QUADSPI_MCR); /* * The minimum delay : 1 AHB + 2 SFCK clocks. @@ -572,7 +606,7 @@ static inline void fsl_qspi_invalid(struct fsl_qspi *q) udelay(1); reg &= ~(QUADSPI_MCR_SWRSTHD_MASK | QUADSPI_MCR_SWRSTSD_MASK); - writel(reg, q->iobase + QUADSPI_MCR); + qspi_writel(q, reg, q->iobase + QUADSPI_MCR); } static int fsl_qspi_nor_write(struct fsl_qspi *q, struct spi_nor *nor, @@ -586,20 +620,20 @@ static int fsl_qspi_nor_write(struct fsl_qspi *q, struct spi_nor *nor, q->chip_base_addr, to, count); /* clear the TX FIFO. */ - tmp = readl(q->iobase + QUADSPI_MCR); - writel(tmp | QUADSPI_MCR_CLR_TXF_MASK, q->iobase + QUADSPI_MCR); + tmp = qspi_readl(q, q->iobase + QUADSPI_MCR); + qspi_writel(q, tmp | QUADSPI_MCR_CLR_TXF_MASK, q->iobase + QUADSPI_MCR); /* fill the TX data to the FIFO */ for (j = 0, i = ((count + 3) / 4); j < i; j++) { tmp = fsl_qspi_endian_xchg(q, *txbuf); - writel(tmp, q->iobase + QUADSPI_TBDR); + qspi_writel(q, tmp, q->iobase + QUADSPI_TBDR); txbuf++; } /* fill the TXFIFO upto 16 bytes for i.MX7d */ if (needs_fill_txfifo(q)) for (; i < 4; i++) - writel(tmp, q->iobase + QUADSPI_TBDR); + qspi_writel(q, tmp, q->iobase + QUADSPI_TBDR); /* Trigger it */ ret = fsl_qspi_runcmd(q, opcode, to, count); @@ -615,10 +649,10 @@ static void fsl_qspi_set_map_addr(struct fsl_qspi *q) int nor_size = q->nor_size; void __iomem *base = q->iobase; - writel(nor_size + q->memmap_phy, base + QUADSPI_SFA1AD); - writel(nor_size * 2 + q->memmap_phy, base + QUADSPI_SFA2AD); - writel(nor_size * 3 + q->memmap_phy, base + QUADSPI_SFB1AD); - writel(nor_size * 4 + q->memmap_phy, base + QUADSPI_SFB2AD); + qspi_writel(q, nor_size + q->memmap_phy, base + QUADSPI_SFA1AD); + qspi_writel(q, nor_size * 2 + q->memmap_phy, base + QUADSPI_SFA2AD); + qspi_writel(q, nor_size * 3 + q->memmap_phy, base + QUADSPI_SFB1AD); + qspi_writel(q, nor_size * 4 + q->memmap_phy, base + QUADSPI_SFB2AD); } /* @@ -640,24 +674,26 @@ static void fsl_qspi_init_abh_read(struct fsl_qspi *q) int seqid; /* AHB configuration for access buffer 0/1/2 .*/ - writel(QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF0CR); - writel(QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF1CR); - writel(QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF2CR); + qspi_writel(q, QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF0CR); + qspi_writel(q, QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF1CR); + qspi_writel(q, QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF2CR); /* * Set ADATSZ with the maximum AHB buffer size to improve the * read performance. */ - writel(QUADSPI_BUF3CR_ALLMST_MASK | ((q->devtype_data->ahb_buf_size / 8) - << QUADSPI_BUF3CR_ADATSZ_SHIFT), base + QUADSPI_BUF3CR); + qspi_writel(q, QUADSPI_BUF3CR_ALLMST_MASK | + ((q->devtype_data->ahb_buf_size / 8) + << QUADSPI_BUF3CR_ADATSZ_SHIFT), + base + QUADSPI_BUF3CR); /* We only use the buffer3 */ - writel(0, base + QUADSPI_BUF0IND); - writel(0, base + QUADSPI_BUF1IND); - writel(0, base + QUADSPI_BUF2IND); + qspi_writel(q, 0, base + QUADSPI_BUF0IND); + qspi_writel(q, 0, base + QUADSPI_BUF1IND); + qspi_writel(q, 0, base + QUADSPI_BUF2IND); /* Set the default lut sequence for AHB Read. */ seqid = fsl_qspi_get_seqid(q, q->nor[0].read_opcode); - writel(seqid << QUADSPI_BFGENCR_SEQID_SHIFT, + qspi_writel(q, seqid << QUADSPI_BFGENCR_SEQID_SHIFT, q->iobase + QUADSPI_BFGENCR); } @@ -713,7 +749,7 @@ static int fsl_qspi_nor_setup(struct fsl_qspi *q) return ret; /* Reset the module */ - writel(QUADSPI_MCR_SWRSTSD_MASK | QUADSPI_MCR_SWRSTHD_MASK, + qspi_writel(q, QUADSPI_MCR_SWRSTSD_MASK | QUADSPI_MCR_SWRSTHD_MASK, base + QUADSPI_MCR); udelay(1); @@ -721,24 +757,24 @@ static int fsl_qspi_nor_setup(struct fsl_qspi *q) fsl_qspi_init_lut(q); /* Disable the module */ - writel(QUADSPI_MCR_MDIS_MASK | QUADSPI_MCR_RESERVED_MASK, + qspi_writel(q, QUADSPI_MCR_MDIS_MASK | QUADSPI_MCR_RESERVED_MASK, base + QUADSPI_MCR); - reg = readl(base + QUADSPI_SMPR); - writel(reg & ~(QUADSPI_SMPR_FSDLY_MASK + reg = qspi_readl(q, base + QUADSPI_SMPR); + qspi_writel(q, reg & ~(QUADSPI_SMPR_FSDLY_MASK | QUADSPI_SMPR_FSPHS_MASK | QUADSPI_SMPR_HSENA_MASK | QUADSPI_SMPR_DDRSMP_MASK), base + QUADSPI_SMPR); /* Enable the module */ - writel(QUADSPI_MCR_RESERVED_MASK | QUADSPI_MCR_END_CFG_MASK, + qspi_writel(q, QUADSPI_MCR_RESERVED_MASK | QUADSPI_MCR_END_CFG_MASK, base + QUADSPI_MCR); /* clear all interrupt status */ - writel(0xffffffff, q->iobase + QUADSPI_FR); + qspi_writel(q, 0xffffffff, q->iobase + QUADSPI_FR); /* enable the interrupt */ - writel(QUADSPI_RSER_TFIE, q->iobase + QUADSPI_RSER); + qspi_writel(q, QUADSPI_RSER_TFIE, q->iobase + QUADSPI_RSER); return 0; } @@ -954,6 +990,7 @@ static int fsl_qspi_probe(struct platform_device *pdev) if (IS_ERR(q->iobase)) return PTR_ERR(q->iobase); + q->big_endian = of_property_read_bool(np, "big-endian"); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "QuadSPI-memory"); if (!devm_request_mem_region(dev, res->start, resource_size(res), @@ -1101,8 +1138,8 @@ static int fsl_qspi_remove(struct platform_device *pdev) } /* disable the hardware */ - writel(QUADSPI_MCR_MDIS_MASK, q->iobase + QUADSPI_MCR); - writel(0x0, q->iobase + QUADSPI_RSER); + qspi_writel(q, QUADSPI_MCR_MDIS_MASK, q->iobase + QUADSPI_MCR); + qspi_writel(q, 0x0, q->iobase + QUADSPI_RSER); mutex_destroy(&q->lock);