From patchwork Tue Nov 13 12:00:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rajat Srivastava X-Patchwork-Id: 997046 X-Patchwork-Delegate: jagannadh.teki@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=nxp.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=nxp.com header.i=@nxp.com header.b="c3wFUrdf"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 42vR7F5DB2z9s9G for ; Tue, 13 Nov 2018 23:01:45 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id 0D667C21E02; Tue, 13 Nov 2018 12:01:32 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=SPF_HELO_PASS, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 25E50C224E0; Tue, 13 Nov 2018 12:01:13 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id CB5CCC224F0; Tue, 13 Nov 2018 12:01:10 +0000 (UTC) Received: from EUR01-HE1-obe.outbound.protection.outlook.com (mail-eopbgr130078.outbound.protection.outlook.com [40.107.13.78]) by lists.denx.de (Postfix) with ESMTPS id CE559C224F0 for ; Tue, 13 Nov 2018 12:00:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=DX50thqDA3bt+GkzfkFmHYrIM+EuAG3ChtGo2l5Xu9E=; b=c3wFUrdfl7ghNValQZB2ZdM34pprZUZnb6gvJ6MhyYERIqmODC2DcevyPp6iPlb4/cGeN+bp9oyjkPC6LEF5WJ3yNNaCFLb56CQj4oMK44BaKVAs7ff7zQD8Tjg2h/Is0N/PC1yaUnbRc75JXedKl1dlDQ7AAUVrXwCRtg9WVM0= Received: from AM4PR0401MB2372.eurprd04.prod.outlook.com (10.165.45.141) by AM4PR0401MB2260.eurprd04.prod.outlook.com (10.165.45.7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1294.28; Tue, 13 Nov 2018 12:00:44 +0000 Received: from AM4PR0401MB2372.eurprd04.prod.outlook.com ([fe80::5918:becc:173d:cd6a]) by AM4PR0401MB2372.eurprd04.prod.outlook.com ([fe80::5918:becc:173d:cd6a%9]) with mapi id 15.20.1294.045; Tue, 13 Nov 2018 12:00:44 +0000 From: Rajat Srivastava To: "u-boot@lists.denx.de" Thread-Topic: [PATCH v2 2/2] fsl_qspi: Access flash above 16MB using SFDP Thread-Index: AQHUe0iBwzryORv+ika/oPTERybTKg== Date: Tue, 13 Nov 2018 12:00:44 +0000 Message-ID: <20181113122807.32093-3-rajat.srivastava@nxp.com> References: <20181113122807.32093-1-rajat.srivastava@nxp.com> In-Reply-To: <20181113122807.32093-1-rajat.srivastava@nxp.com> Accept-Language: en-IN, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: BM1PR0101CA0031.INDPRD01.PROD.OUTLOOK.COM (2603:1096:b00:1a::17) To AM4PR0401MB2372.eurprd04.prod.outlook.com (2603:10a6:200:51::13) authentication-results: spf=none (sender IP is ) smtp.mailfrom=rajat.srivastava@nxp.com; x-ms-exchange-messagesentrepresentingtype: 1 x-originating-ip: [14.142.187.166] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; AM4PR0401MB2260; 6:dndASrGEfx2bzANgZmGBNe54O3ikj7Iq1B0ks8Dq53wvZwT2XqeNn9gyz59JYxORb9FgDQ+zdITafcVAKpvf4wELHw8iftkAOm6P6JZL4wrDry5He8dpTTw0ekNZ5A6LspdxLpXZYy6C1SbJEhEP7LabdnRAQJiOIHWI0btijGqJvJoAD05KLMvi7gyR/VQLNFnIeqYAdA/rz+KtNDVR3oKHLG7VghlcgADeVqdKy/6cub8eZjC7aRiGtroUFVIFwIjzeIKNIg8YHPl3oHy86PidYy4dg8qpbLE/6nopqUJLA9Z8ns0ewAkhnK/eJpOJvFblt+O8Pmcyg0l2Vr6+G6g8ykPqa8n0i1iOXholrj5JXxyQz/YLMs74+8w5aIV1MPOE1yVm7XZZirgdsxt8qnhXtddpnO8tB0hboLWunaOzXfT4e22NmCoYW8rybUEUKGz4K5CX9RlGHiT7YtRNow==; 5:IvL2SM3ftnjRozTEryVhoaZsEScsiBi3nmenwcKpIp55N3i01SA7gK1/ph9KdjDuFTlOwfK3bysRPk7LgBFtdao8R2R6lGllGQBPsjwnaKRmvsC2kVIOYO4QrNazoXsAi8tlWB1K0Xx6R0QYa27jq9L4bB1Mof7UcdHurzjPC8g=; 7:aoPU1eVmiE+UVpO7ZYt/ULneiMSK9dbvoop80OxzznT3nsV9JPDFeHIKsiy6JNYR/g4dZYMQkVPuRyKqF4JiHeiyAa2BuN6krcMg89pQiKc049bG0aJYw9XTZ4O4SfJuWdH/EH0lhbeaiK3xDMC/8w== x-ms-office365-filtering-correlation-id: 938b6e47-41ab-461d-e130-08d6495fa416 x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0; PCL:0; RULEID:(2390060)(7020095)(4652040)(8989299)(4534185)(7168020)(4627221)(201703031133081)(201702281549075)(8990200)(5600074)(711020)(4618075)(2017052603328)(7153060)(7193020); SRVR:AM4PR0401MB2260; x-ms-traffictypediagnostic: AM4PR0401MB2260: x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:(185117386973197); x-ms-exchange-senderadcheck: 1 x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(8121501046)(5005006)(3002001)(10201501046)(3231382)(944501410)(52105112)(93006095)(93001095)(6055026)(148016)(149066)(150057)(6041310)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123564045)(20161123560045)(20161123558120)(20161123562045)(201708071742011)(7699051)(76991095); SRVR:AM4PR0401MB2260; BCL:0; PCL:0; RULEID:; SRVR:AM4PR0401MB2260; x-forefront-prvs: 085551F5A8 x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(366004)(39860400002)(396003)(136003)(346002)(376002)(189003)(199004)(3846002)(99286004)(2906002)(6116002)(2900100001)(305945005)(6486002)(7736002)(6506007)(76176011)(5640700003)(26005)(4326008)(6436002)(186003)(386003)(256004)(14444005)(36756003)(53936002)(78486014)(6512007)(66066001)(52116002)(1076002)(55236004)(102836004)(2501003)(14454004)(97736004)(5660300001)(44832011)(486006)(68736007)(2616005)(476003)(86362001)(25786009)(11346002)(575784001)(446003)(106356001)(316002)(81166006)(81156014)(71200400001)(478600001)(8936002)(54906003)(105586002)(2351001)(8676002)(71190400001)(6916009); DIR:OUT; SFP:1101; SCL:1; SRVR:AM4PR0401MB2260; H:AM4PR0401MB2372.eurprd04.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; received-spf: None (protection.outlook.com: nxp.com does not designate permitted sender hosts) x-microsoft-antispam-message-info: 3v9RjEu9Mhlyja500q8CLs5Lf/yKSyUlEUkcM2bUQ5w2w66u2Y/FIS2WfGN1mHLe8fe0lXzWZuULX7sqNoo7K/BREepsAhYlT6YL9dyega/8IuAj+BQOR8YiQx1Vo1KRMpKEghYJyFOg/AD/8Gbv7HZJFimIo59d7Iok2UKpQtEqam0CRhLq/fkTA30XTiyBfriNisJiEq79Nfv5ltHrHbQRPOHlvdoEfkDqkVT79tfgHjdcdR66fzABSsuUhEIPCc/BFUbwAYXqRZ0qFIoLrK8GCMNNwll4cw/uHUCt2i43Ou/rkAdvTSzS/tJcj/xW++A9jIvKaW5q83C9QH0ZyzjhLh52qPrHHfyPXGYj/44= spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 938b6e47-41ab-461d-e130-08d6495fa416 X-MS-Exchange-CrossTenant-originalarrivaltime: 13 Nov 2018 12:00:44.5349 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM4PR0401MB2260 Cc: "jagan@openedev.com" , Rajat Srivastava Subject: [U-Boot] [PATCH v2 2/2] fsl_qspi: Access flash above 16MB using SFDP X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Add functionality to read SFDP parameters in fsl_qspi driver. Also, use the address width information from SFDP to enable flash access above 16 MB. Introduce a way to access parent structure by adding pointer to struct spi_slave in struct fsl_qspi_priv. Signed-off-by: Rajat Srivastava --- Changes in v2: - none --- drivers/spi/fsl_qspi.c | 103 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 96 insertions(+), 7 deletions(-) diff --git a/drivers/spi/fsl_qspi.c b/drivers/spi/fsl_qspi.c index 1598c4f698..615f36e351 100644 --- a/drivers/spi/fsl_qspi.c +++ b/drivers/spi/fsl_qspi.c @@ -26,7 +26,7 @@ DECLARE_GLOBAL_DATA_PTR; #define TX_BUFFER_SIZE 0x40 #endif -#define OFFSET_BITS_MASK GENMASK(23, 0) +#define SET_BITS_MASK(X) GENMASK(X, 0) #define FLASH_STATUS_WEL 0x02 @@ -47,6 +47,7 @@ DECLARE_GLOBAL_DATA_PTR; #endif #define SEQID_WRAR 13 #define SEQID_RDAR 14 +#define SEQID_RDSFDP 15 /* QSPI CMD */ #define QSPI_CMD_PP 0x02 /* Page program (up to 256 bytes) */ @@ -57,6 +58,7 @@ DECLARE_GLOBAL_DATA_PTR; #define QSPI_CMD_CHIP_ERASE 0xc7 /* Erase whole flash chip */ #define QSPI_CMD_SE 0xd8 /* Sector erase (usually 64KiB) */ #define QSPI_CMD_RDID 0x9f /* Read JEDEC ID */ +#define QSPI_CMD_RDSFDP 0x5a /* Read SFDP parameters from flash */ /* Used for Micron, winbond and Macronix flashes */ #define QSPI_CMD_WREAR 0xc5 /* EAR register write */ @@ -132,6 +134,7 @@ struct fsl_qspi_priv { u32 flash_num; u32 num_chipselect; struct fsl_qspi_regs *regs; + void *spi_slave; }; @@ -363,6 +366,19 @@ static void qspi_set_lut(struct fsl_qspi_priv *priv) qspi_write32(priv->flags, ®s->lut[lut_base + 1], OPRND0(1) | PAD0(LUT_PAD1) | INSTR0(LUT_WRITE)); + /* Read SFDP information */ + lut_base = SEQID_RDSFDP * 4; + qspi_write32(priv->flags, ®s->lut[lut_base], + OPRND0(QSPI_CMD_RDSFDP) | PAD0(LUT_PAD1) | + INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) | + PAD1(LUT_PAD1) | INSTR1(LUT_ADDR)); + qspi_write32(priv->flags, ®s->lut[lut_base + 1], + OPRND0(8) | PAD0(LUT_PAD1) | INSTR0(LUT_DUMMY) | + OPRND1(RX_BUFFER_SIZE) | PAD1(LUT_PAD1) | + INSTR1(LUT_READ)); + qspi_write32(priv->flags, ®s->lut[lut_base + 2], 0); + qspi_write32(priv->flags, ®s->lut[lut_base + 3], 0); + /* Lock the LUT */ qspi_write32(priv->flags, ®s->lutkey, LUT_KEY_VALUE); qspi_write32(priv->flags, ®s->lckcr, QSPI_LCKCR_LOCK); @@ -562,6 +578,61 @@ static void qspi_op_rdid(struct fsl_qspi_priv *priv, u32 *rxbuf, u32 len) qspi_write32(priv->flags, ®s->mcr, mcr_reg); } +static void qspi_op_rdsfdp(struct fsl_qspi_priv *priv, u32 *rxbuf, u32 len) +{ + struct fsl_qspi_regs *regs = priv->regs; + u32 mcr_reg, data; + int i, size; + u32 to_or_from; + u32 seqid; + + seqid = SEQID_RDSFDP; + + mcr_reg = qspi_read32(priv->flags, ®s->mcr); + qspi_write32(priv->flags, ®s->mcr, + QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK | + QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE); + qspi_write32(priv->flags, ®s->rbct, QSPI_RBCT_RXBRD_USEIPS); + + to_or_from = priv->sf_addr + priv->cur_amba_base; + + while (len > 0) { + WATCHDOG_RESET(); + + qspi_write32(priv->flags, ®s->sfar, to_or_from); + + size = (len > RX_BUFFER_SIZE) ? + RX_BUFFER_SIZE : len; + + qspi_write32(priv->flags, ®s->ipcr, + (seqid << QSPI_IPCR_SEQID_SHIFT) | + size); + while (qspi_read32(priv->flags, ®s->sr) & QSPI_SR_BUSY_MASK) + ; + + to_or_from += size; + len -= size; + + i = 0; + while ((size < RX_BUFFER_SIZE) && (size > 0)) { + data = qspi_read32(priv->flags, ®s->rbdr[i]); + data = qspi_endian_xchg(data); + if (size < 4) + memcpy(rxbuf, &data, size); + else + memcpy(rxbuf, &data, 4); + rxbuf++; + size -= 4; + i++; + } + qspi_write32(priv->flags, ®s->mcr, + qspi_read32(priv->flags, ®s->mcr) | + QSPI_MCR_CLR_RXF_MASK); + } + + qspi_write32(priv->flags, ®s->mcr, mcr_reg); +} + /* If not use AHB read, read data from ip interface */ static void qspi_op_read(struct fsl_qspi_priv *priv, u32 *rxbuf, u32 len) { @@ -772,14 +843,25 @@ int qspi_xfer(struct fsl_qspi_priv *priv, unsigned int bitlen, { u32 bytes = DIV_ROUND_UP(bitlen, 8); static u32 wr_sfaddr; - u32 txbuf; + u32 txbuf, bits_mask; + struct spi_flash *flash; + + flash = ((struct spi_slave *)(priv->spi_slave))->flash; WATCHDOG_RESET(); + if (flash->cmd_len == 5 && flash->size > SZ_16M) + bits_mask = SET_BITS_MASK(27); + else + bits_mask = SET_BITS_MASK(23); + if (dout) { if (flags & SPI_XFER_BEGIN) { priv->cur_seqid = *(u8 *)dout; - memcpy(&txbuf, dout, 4); + if (flash->size > SZ_16M && bytes > 4) + memcpy(&txbuf, dout + 1, 4); + else + memcpy(&txbuf, dout, 4); } if (flags == SPI_XFER_END) { @@ -790,20 +872,21 @@ int qspi_xfer(struct fsl_qspi_priv *priv, unsigned int bitlen, if (priv->cur_seqid == QSPI_CMD_FAST_READ || priv->cur_seqid == QSPI_CMD_RDAR) { - priv->sf_addr = swab32(txbuf) & OFFSET_BITS_MASK; + priv->sf_addr = swab32(txbuf) & bits_mask; } else if ((priv->cur_seqid == QSPI_CMD_SE) || (priv->cur_seqid == QSPI_CMD_BE_4K)) { - priv->sf_addr = swab32(txbuf) & OFFSET_BITS_MASK; + priv->sf_addr = swab32(txbuf) & bits_mask; qspi_op_erase(priv); } else if (priv->cur_seqid == QSPI_CMD_PP || priv->cur_seqid == QSPI_CMD_WRAR) { - wr_sfaddr = swab32(txbuf) & OFFSET_BITS_MASK; + wr_sfaddr = swab32(txbuf) & bits_mask; } else if ((priv->cur_seqid == QSPI_CMD_BRWR) || (priv->cur_seqid == QSPI_CMD_WREAR)) { #ifdef CONFIG_SPI_FLASH_BAR wr_sfaddr = 0; #endif - } + } else if (priv->cur_seqid == QSPI_CMD_RDSFDP) + priv->sf_addr = swab32(txbuf) & bits_mask; } if (din) { @@ -819,6 +902,8 @@ int qspi_xfer(struct fsl_qspi_priv *priv, unsigned int bitlen, qspi_op_rdid(priv, din, bytes); else if (priv->cur_seqid == QSPI_CMD_RDSR) qspi_op_rdsr(priv, din, bytes); + else if (priv->cur_seqid == QSPI_CMD_RDSFDP) + qspi_op_rdsfdp(priv, din, bytes); #ifdef CONFIG_SPI_FLASH_BAR else if ((priv->cur_seqid == QSPI_CMD_BRRD) || (priv->cur_seqid == QSPI_CMD_RDEAR)) { @@ -1044,9 +1129,13 @@ static int fsl_qspi_xfer(struct udevice *dev, unsigned int bitlen, { struct fsl_qspi_priv *priv; struct udevice *bus; + struct spi_slave *slave; bus = dev->parent; priv = dev_get_priv(bus); + slave = dev_get_parent_priv(dev); + + priv->spi_slave = slave; return qspi_xfer(priv, bitlen, dout, din, flags); }