From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755824AbbLXLIJ (ORCPT ); Thu, 24 Dec 2015 06:08:09 -0500 Received: from mail-bl2on0134.outbound.protection.outlook.com ([65.55.169.134]:12243 "EHLO na01-bl2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1755791AbbLXLIE (ORCPT ); Thu, 24 Dec 2015 06:08:04 -0500 Authentication-Results: spf=permerror (sender IP is 192.88.158.2) smtp.mailfrom=freescale.com; nxp.com; dkim=none (message not signed) header.d=none;nxp.com; dmarc=none action=none header.from=freescale.com; From: Yuan Yao To: , , CC: , , Subject: [PATCH v3 1/4] mtd: spi-nor: fsl-quadspi: add big-endian support Date: Thu, 24 Dec 2015 19:00:18 +0800 Message-ID: <1450954821-7483-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;BY2FFO11FD011;1:X7Lk+PnCdyv3w3VGGGq04kGQvukDipsq3cYUK57jjzsRBUB/elbn6/N2S2A1kMT8zKgZKIJWLdUjww8cQiQO83MjsdtqK1LuKLm+nvCuNIbgpTP2ZrEdv3C7MTdMSSNCPA8vhMjQINPLteivfmhEa1TsXVpTe9B2lgfy/5aOSckJAp7alLr6+Oi8+LMk7e4OgXKNt8njVcG3J3Q+c6HRTTsD+5Q0t5qbC4zjkIFFY9W3MLje/adPELu1+Wu1GtzRYN6CmOVtvIof22ML+UyOD6GZZZzvOgl4cEIio+Pv67omc52JCI/Iuc5wRf5JWhb/mwU+vz5XknY4Yy+wLvYnsWwR4aEr7KWEFwVIPgmWgPEb0lNXUkyduIqIHx5hAT2URne19yLRq6HJGOaC71DFuMPDZPK0nf4rdQruQWa/xjg= X-Forefront-Antispam-Report: CIP:192.88.158.2;CTRY:US;IPV:NLI;EFV:NLI;SFV:NSPM;SFS:(10019020)(6009001)(2980300002)(448002)(189002)(199003)(479174004)(5008740100001)(5003940100001)(1220700001)(47776003)(586003)(11100500001)(69596002)(19580405001)(1096002)(86362001)(2201001)(19580395003)(85326001)(229853001)(33646002)(87936001)(575784001)(50986999)(77096005)(5001960100002)(6806005)(92566002)(97736004)(189998001)(104016004)(4001450100002)(106466001)(50466002)(5001770100001)(81156007)(36756003)(48376002)(50226001)(7059030);DIR:OUT;SFP:1102;SCL:1;SRVR:SN2PR03MB079;H:az84smr01.freescale.net;FPR:;SPF:PermError;PTR:InfoDomainNonexistent;MX:1;A:1;LANG:en; MIME-Version: 1.0 Content-Type: text/plain X-Microsoft-Exchange-Diagnostics: 1;SN2PR03MB079;2:AR6TbNCJgEd+PiueDXtJLytHKTlFtwnjEJOx0SZ7gLrIWXpZqCeOfUz6TwoJrPoxm1O4ZVfAdr8iDAIyUt5wybVMvDrrVWJnBlEn0SNuxfOstwou+t/K3eRBHp4brSUGHhZi7CYaVTTqluKbQ4p6oA==;3:XyOeOWllZvPUzpb5Wb8HMoyP4K+iD/Aoqc5RZkeE6U9cMkkyD9iClAn1QoG57+FxBIua9/4x7ETySAros+Yu3ymX559Jre6X/+r6gQzQEZ4qyzc7BhO5qLjA4iBEBoXp2lHksiAoom/tzAqKysGoTVMAIZc+7OKZz2FUY5aEkgdLuwCrN+DUXEkIcrnWBjlOQD39v245m5yZksp73Gf3yOyVy3fbea2j+0wZgZKUtk0=;25:M7n13d8G0x9Sb9xGSsHdvqaT3wgXUiydFzwebHtRTPxFcpD+wev0ONKp/0MuOtSM6T14dXEZOPxDtYaSZw9dG4xOpFv6B4t9rGeY8/hf9lcXsqbs+mfAWLibBJldGr3m5FPNxozRsaewWpVO7uf2UAe15EOjo2qo37A43gxi9cnJjjFC9D1nZWn5l7a++7V/2gqCBXw6LaWLIPBUlwVi4hW3BbALZATYnfCobzJPLVYWBAByfCeV6ZfjWJx0v3dgjroRe08Cz0HwZIyjtBGIAw== X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:SN2PR03MB079; X-Microsoft-Exchange-Diagnostics: 1;SN2PR03MB079;20:vhv2LbbIp5z/4Po0PVtwACqcSoPndra/jw9uZp9mnxjsf2x1Nm6DlUvEd9LkEX8ptUihO1Fqih0zVU+7quLsNRm4kOiDj07COIZSM1hqiU5RR8Pz0aaoWYXKECsCt8R0dfofSb6m79YWCokWITxElTjbAgmEenCDlRfulg5VgrPjlDP70sZB4HPGQAxMOiLZXMElovR1XzLE6totImFXT8v5xqMBU2ZHZunqovcr+SXysYS1d1AB0xIJ+FM5hxgiskl+ocJHllI3ofxkcTGnPpUKkF4V5BG77Y8/5R2BwpfPyW3ph4Lx2oqlIwBpxegYfomv53M53TdTDFtZDO+sp+OLUmaTNQd7WhcDElQDyxk=;4:sVIw4vFGymESbxeoT3HZVXNqUKS4+TywdkaxZDl25hwI8ibRUp0p+1TMVml80kHOVBUy9etBCOxpOkHagaafmaGb/QgUgZC/5eazPxzWGE4YoV7iRzxH02U0NqXEGPIZYNOBGJ5O2W+YOUnsJ4EM0Y3zw7ALEQkxL9ATyQbTZ9PFYIXMaee4YPkJpDBWgqBZ5u0v+LjgTk3eAX3thmrrrPa1VlRcfDAxgB7KOX691RdhMVroVLvGTVKcEM2RpcQOgIbJHlVThFYswUXOxXWJnuY0c0RSJiK58rKmRDs9TOIdbvLEsKpvK9L7rmDInqrH3RaXE4XLDO5HkzYfOYCPj8nUPQijdXEQhT+EQZFPPzn2Qv6fVSUbdc59mX3Qx37nnsIcOJ2TOP1q1w5pf8jIMWARG7WKAn151qJTi6JE6PuoHflXV1WGmOr3oVj/x8Xe X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(185117386973197); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(601004)(2401047)(5005006)(520078)(8121501046)(10201501046)(3002001);SRVR:SN2PR03MB079;BCL:0;PCL:0;RULEID:;SRVR:SN2PR03MB079; X-Forefront-PRVS: 0800C0C167 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;SN2PR03MB079;23:JiYoB03j2fCfXjqb7wVgnaoA5RmvDNmIsrouuh0C+W?= =?us-ascii?Q?CLpElzMQdYkbLfV/nJd3Ohh/sVPhV5RF/V+2jmNuibc603OtSmziLIzUA/13?= =?us-ascii?Q?cwFJcsBqrIo4ytTlAtc1O90s92FkXeMMxVX65BuQq4b2Uf4FJO6XcVlz1j5j?= =?us-ascii?Q?iYcmdEAhFNqcDx+SgVVSE3DDgKjnBi0H1Di1anrFwvejuPqaGXZHxs+5fqUC?= =?us-ascii?Q?kV3uLd0hazgajBsnMSJCoQdgW7u+ZkBUTwLfaaOQKghrZRGCklz44kyDvbPg?= =?us-ascii?Q?oaOtlVpKT/IdZL+VLZazbpCX2WWanyr6dbX3GMGNHhqshTRv2Rp8v4j58XJ7?= =?us-ascii?Q?4MtdJ98nb9nCM9Ac8bYTpS34X72P1cgQQRghZCIjbqY/ZuE1l8kkYv9UMUlk?= =?us-ascii?Q?fa3LjQP+CatiVxov1CV1XPMOgWUUNHfi/7AhhrYLu2rzLNJfoVR/Eigyfb4J?= =?us-ascii?Q?TSLnPfDcR4ERh4MtzOrDivZar2qCZc7d6dtmEJMqPBdGJnZGLhwxsYGDNDJj?= =?us-ascii?Q?gGPvN4I7/OUCcJReRoS8b3VM48bYUwa4IBhh24P2M1eMJApvW1y/Y8VfwXBB?= =?us-ascii?Q?Yq9WIZJu8Fs/LQTrglNKsy6o8Xvhx2O4ev3R8X//hdyxl2Si4YUWB3rmIVVk?= =?us-ascii?Q?VnCDGRo4JQb7iygD8D6GcX9yR4xKvf4Cw4vmO61eNcfT3L1gV5u0WYCe+Jc0?= =?us-ascii?Q?0i2HxjTIcc/W/XLJih9kPFzJbqQRHerCR1krTa5rkSrDEkYtweSDfC4zMAnb?= =?us-ascii?Q?TaFZJQfeDYHzPNepT+WW8SncKjArUVkHp5PkpMLBFH6orYJJvYFjaMKyCd4g?= =?us-ascii?Q?RrypwS8Z2YJqgs2Br0axafBB+607X7NSXGbrxjau+MOoG4shLrileIu833Gp?= =?us-ascii?Q?XFbJkxOCBXyiBGzOy0j7dnr0NbaUoIhNzyUD4BRrALqAlPkSR5jKjrz87Vuf?= =?us-ascii?Q?SmfH40Kua212l2TlZ/tv+zwj6hgR3A5U4tVXsdQU1/3eg0U+fkxNOq3L5Kij?= =?us-ascii?Q?w/KU9Bbni7t+IFtBnp2ZPI9CcxZUqO1X2FbPeMl8PbWfZWaRpp9zNSfbXXZU?= =?us-ascii?Q?BFnR3hVXVEzykLvK8Kdfzaip3X?= X-Microsoft-Exchange-Diagnostics: 1;SN2PR03MB079;5:MVddDO1tTjKJfK4CLvu2C2bSFHec+joXqnrbLPjXaafZ5AV4pecAkIl/CVIaZMEPYm3nDzjxbPfOvlAVKOwZed+62XKfA8U9sB/smZilB+xXBKPDgcmBD4PjAiGBCciyUUbp5TPMZtZ52bWRJlrf/g==;24:j+l3f6z6gnOLVI12N+Mz1IUI5+bPyM6XMnwLwRrzmOSG+DkL70i7CNjde/jVao4xhrqDDsW3Z7A+2YTJkvyvoBNqG27VQCtPiKB9+87LrAc= X-OriginatorOrg: freescale.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 Dec 2015 11:08:00.1833 (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.158.2];Helo=[az84smr01.freescale.net] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN2PR03MB079 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 --- 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); -- 2.1.0.27.g96db324