From patchwork Tue Mar 22 07:38:28 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jagan Teki X-Patchwork-Id: 600488 X-Patchwork-Delegate: jagannadh.teki@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 3qTlN94hjpz9s5l for ; Tue, 22 Mar 2016 18:54:49 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 0B112A7906; Tue, 22 Mar 2016 08:47:47 +0100 (CET) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id NPmtTXE-ABBU; Tue, 22 Mar 2016 08:47:46 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 640E5A7949; Tue, 22 Mar 2016 08:47:34 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 7A8BEA77C2 for ; Tue, 22 Mar 2016 08:45:46 +0100 (CET) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ZUB4KqRO3EKN for ; Tue, 22 Mar 2016 08:45:46 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-pf0-f195.google.com (mail-pf0-f195.google.com [209.85.192.195]) by theia.denx.de (Postfix) with ESMTPS id 10904A78A8 for ; Tue, 22 Mar 2016 08:44:43 +0100 (CET) Received: by mail-pf0-f195.google.com with SMTP id x3so34317240pfb.0 for ; Tue, 22 Mar 2016 00:44:43 -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=MZhcvJk0g0KOG4SmQ4ba7nJ8gA9SaCYE0aO9f/eCoBg=; b=ijEN1WfddvADJqEVoF81vl0k3qO6V0PRyQlaPehtw2ajw6+CXbWe/4SGdWO3zHjvrV KLKL27jIPC6zuljkTHB1j+SmqdTxf/BECqqZIgQ+NwZ4y2S98B8kfCzP4cvqPYYmtQo0 0oTHGViRvPu3kjgojUV653VXwqdiVCtoy3XpY9o2XghFoGDrjECTRMTtpimWEDfq2Dhz jQ/DIK0P6bU1jhKoDWZJWs8L4ZvP2lMcWkeb81olqKmnb6MRxa8fU9dlk9zJkZ1qdjb7 LiZyHlWco4LX4p4G77+Isz9A6zXSsUmrTd0EXOFaQf3zegZ4eLZgMdw9Ryg3vBaFg1gO YH6A== X-Gm-Message-State: AD7BkJKUVRwbGTfhNcr8L+uuEJ7JW1ZdDkvHjBPEMhzaUpXjOA8j4DDy7MeUIeRi6VLxEw== X-Received: by 10.66.145.194 with SMTP id sw2mr51200981pab.69.1458632682476; Tue, 22 Mar 2016 00:44:42 -0700 (PDT) Received: from jteki-Latitude-E7450.amcc.com ([182.73.239.130]) by smtp.gmail.com with ESMTPSA id ko9sm45814957pab.37.2016.03.22.00.44.38 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 22 Mar 2016 00:44:41 -0700 (PDT) From: Jagan Teki To: u-boot@lists.denx.de Date: Tue, 22 Mar 2016 13:08:28 +0530 Message-Id: <1458632319-24866-76-git-send-email-jteki@openedev.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1458632319-24866-1-git-send-email-jteki@openedev.com> References: <1458632319-24866-1-git-send-email-jteki@openedev.com> Cc: Michal Simek , Siva Durga Prasad Paladugu , Jagan Teki Subject: [U-Boot] [PATCH v7 76/87] mtd: spi-nor: Move opcode handling in m25p80 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.15 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" It's required to handling opcode in spi drivers interface layer, m25p80 from spi-nor, becuase some spi-nor controller drivers like fsl_qspi have separate opcode's to handling the same operations. Cc: Simon Glass Cc: Bin Meng Cc: Mugunthan V N Cc: Michal Simek Cc: Siva Durga Prasad Paladugu Signed-off-by: Jagan Teki --- drivers/mtd/spi-nor/m25p80.c | 53 ++++++++++++++++++++++++++++-------- drivers/mtd/spi-nor/spi-nor.c | 62 +++++++------------------------------------ include/linux/mtd/spi-nor.h | 10 +++---- 3 files changed, 56 insertions(+), 69 deletions(-) diff --git a/drivers/mtd/spi-nor/m25p80.c b/drivers/mtd/spi-nor/m25p80.c index cf27ba0..560e5b2 100644 --- a/drivers/mtd/spi-nor/m25p80.c +++ b/drivers/mtd/spi-nor/m25p80.c @@ -17,14 +17,24 @@ #include #include +#define MAX_CMD_SIZE 6 struct m25p { struct spi_slave *spi; struct spi_nor spi_nor; #ifndef CONFIG_DM_MTD_SPI_NOR struct mtd_info mtd; #endif + u8 command[MAX_CMD_SIZE]; }; +static void spi_nor_addr(u32 addr, u8 *cmd) +{ + /* cmd[0] is actual command */ + cmd[1] = addr >> 16; + cmd[2] = addr >> 8; + cmd[3] = addr >> 0; +} + static int m25p80_read_reg(struct spi_nor *nor, u8 cmd, u8 *val, int len) { struct m25p *flash = nor->priv; @@ -112,8 +122,8 @@ static int m25p80_read_mmap(struct spi_nor *nor, void *data, return ret; } -static int m25p80_read(struct spi_nor *nor, const u8 *cmd, size_t cmd_len, - void *data, size_t data_len) +static int m25p80_read(struct spi_nor *nor, loff_t from, size_t len, + u_char *buf) { struct m25p *flash = nor->priv; struct spi_slave *spi = flash->spi; @@ -125,12 +135,16 @@ static int m25p80_read(struct spi_nor *nor, const u8 *cmd, size_t cmd_len, return ret; } + flash->command[0] = nor->read_opcode; + spi_nor_addr(from, flash->command); + if (nor->flags & SNOR_F_U_PAGE) spi->flags |= SPI_XFER_U_PAGE; - ret = spi_write_then_read(spi, cmd, cmd_len, NULL, data, data_len); + ret = spi_write_then_read(spi, flash->command, 4 + nor->read_dummy, + NULL, buf, len); if (ret < 0) { - debug("m25p80: error %d reading %x\n", ret, *cmd); + debug("m25p80: error %d reading %x\n", ret, flash->command[0]); return ret; } @@ -139,11 +153,12 @@ static int m25p80_read(struct spi_nor *nor, const u8 *cmd, size_t cmd_len, return ret; } -static int m25p80_write(struct spi_nor *nor, const u8 *cmd, size_t cmd_len, - const void *data, size_t data_len) +static int m25p80_write(struct spi_nor *nor, loff_t to, size_t len, + const u_char *buf) { struct m25p *flash = nor->priv; struct spi_slave *spi = flash->spi; + int cmd_sz = 4; int ret; ret = spi_claim_bus(spi); @@ -152,12 +167,22 @@ static int m25p80_write(struct spi_nor *nor, const u8 *cmd, size_t cmd_len, return ret; } + if (nor->program_opcode == SNOR_OP_AAI_WP) + cmd_sz = 1; + + flash->command[0] = nor->program_opcode; + spi_nor_addr(to, flash->command); + if (nor->flags & SNOR_F_U_PAGE) spi->flags |= SPI_XFER_U_PAGE; - ret = spi_write_then_read(spi, cmd, cmd_len, data, NULL, data_len); + debug("m25p80: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %zu\n", + buf, flash->command[0], flash->command[1], flash->command[2], + flash->command[3], len); + + ret = spi_write_then_read(spi, flash->command, cmd_sz, buf, NULL, len); if (ret < 0) { - debug("m25p80: error %d writing %x\n", ret, *cmd); + debug("m25p80: error %d writing %x\n", ret, flash->command[0]); return ret; } @@ -166,7 +191,7 @@ static int m25p80_write(struct spi_nor *nor, const u8 *cmd, size_t cmd_len, return ret; } -static int m25p80_erase(struct spi_nor *nor, const u8 *cmd, size_t cmd_len) +static int m25p80_erase(struct spi_nor *nor, loff_t offset) { struct m25p *flash = nor->priv; struct spi_slave *spi = flash->spi; @@ -178,12 +203,18 @@ static int m25p80_erase(struct spi_nor *nor, const u8 *cmd, size_t cmd_len) return ret; } + flash->command[0] = nor->erase_opcode; + spi_nor_addr(offset, flash->command); + if (nor->flags & SNOR_F_U_PAGE) spi->flags |= SPI_XFER_U_PAGE; - ret = spi_write_then_read(spi, cmd, cmd_len, NULL, NULL, 0); + debug("m25p80: erase %2x %2x %2x %2x (%llx)\n", flash->command[0], + flash->command[1], flash->command[2], flash->command[3], offset); + + ret = spi_write_then_read(spi, flash->command, 4, NULL, NULL, 0); if (ret < 0) { - debug("m25p80: error %d writing %x\n", ret, *cmd); + debug("m25p80: error %d writing %x\n", ret, flash->command[0]); return ret; } diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 97f5eaa..cb9ab21 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -32,14 +32,6 @@ static inline int write_disable(struct spi_nor *nor) return nor->write_reg(nor, SNOR_OP_WRDI, NULL, 0); } -static void spi_nor_addr(u32 addr, u8 *cmd) -{ - /* cmd[0] is actual command */ - cmd[1] = addr >> 16; - cmd[2] = addr >> 8; - cmd[3] = addr >> 0; -} - static int read_sr(struct spi_nor *nor) { u8 sr; @@ -487,7 +479,6 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) { struct spi_nor *nor = mtd->priv; u32 addr, len, erase_addr; - u8 cmd[SNOR_MAX_CMD_SIZE]; uint32_t rem; int ret = -1; @@ -506,7 +497,6 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) } } - cmd[0] = nor->erase_opcode; while (len) { erase_addr = addr; @@ -519,14 +509,9 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) if (ret < 0) return ret; #endif - spi_nor_addr(erase_addr, cmd); - - debug("spi-nor: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1], - cmd[2], cmd[3], erase_addr); - write_enable(nor); - ret = nor->erase(nor, cmd, sizeof(cmd)); + ret = nor->erase(nor, erase_addr); if (ret < 0) goto erase_err; @@ -556,7 +541,6 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t offset, size_t len, struct spi_nor *nor = mtd->priv; u32 byte_addr, page_size, write_addr; size_t chunk_len, actual; - u8 cmd[SNOR_MAX_CMD_SIZE]; int ret = -1; if (mtd->_is_locked) { @@ -569,7 +553,6 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t offset, size_t len, page_size = nor->page_size; - cmd[0] = nor->program_opcode; for (actual = 0; actual < len; actual += chunk_len) { write_addr = offset; @@ -589,15 +572,9 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t offset, size_t len, chunk_len = min(chunk_len, (size_t)nor->max_write_size); - spi_nor_addr(write_addr, cmd); - - debug("spi-nor: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %zu\n", - buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len); - write_enable(nor); - ret = nor->write(nor, cmd, sizeof(cmd), - buf + actual, chunk_len); + ret = nor->write(nor, write_addr, chunk_len, buf + actual); if (ret < 0) break; @@ -617,7 +594,6 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len, { struct spi_nor *nor = mtd->priv; u32 remain_len, read_len, read_addr; - u8 cmd[SNOR_MAX_CMD_SIZE], cmdsz; int bank_sel = 0; int ret = -1; @@ -632,8 +608,6 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len, return ret; } - cmdsz = SNOR_MAX_CMD_SIZE + nor->read_dummy; - cmd[0] = nor->read_opcode; while (len) { read_addr = from; @@ -654,9 +628,7 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len, else read_len = remain_len; - spi_nor_addr(read_addr, cmd); - - ret = nor->read(nor, cmd, cmdsz, buf, read_len); + ret = nor->read(nor, read_addr, read_len, buf); if (ret < 0) break; @@ -674,21 +646,14 @@ static int sst_byte_write(struct spi_nor *nor, u32 offset, const void *buf, size_t *retlen) { int ret; - u8 cmd[4] = { - SNOR_OP_BP, - offset >> 16, - offset >> 8, - offset, - }; - - debug("spi-nor: 0x%p => cmd = { 0x%02x 0x%06x }\n", - buf, cmd[0], offset); ret = write_enable(nor); if (ret) return ret; - ret = nor->write(nor, cmd, sizeof(cmd), buf, 1); + nor->program_opcode = SNOR_OP_BP; + + ret = nor->write(nor, offset, 1, buf); if (ret) return ret; @@ -701,9 +666,8 @@ static int sst_write_wp(struct mtd_info *mtd, loff_t offset, size_t len, size_t *retlen, const u_char *buf) { struct spi_nor *nor = mtd->priv; - size_t actual, cmd_len; + size_t actual; int ret; - u8 cmd[4]; /* If the data is not word aligned, write out leading single byte */ actual = offset % 2; @@ -718,17 +682,10 @@ static int sst_write_wp(struct mtd_info *mtd, loff_t offset, size_t len, if (ret) goto done; - cmd_len = 4; - cmd[0] = SNOR_OP_AAI_WP; - cmd[1] = offset >> 16; - cmd[2] = offset >> 8; - cmd[3] = offset; - for (; actual < len - 1; actual += 2) { - debug("spi-nor: 0x%p => cmd = { 0x%02x 0x%06llx }\n", - buf + actual, cmd[0], offset); + nor->program_opcode = SNOR_OP_AAI_WP; - ret = nor->write(nor, cmd, cmd_len, buf + actual, 2); + ret = nor->write(nor, offset, 2, buf + actual); if (ret) { debug("spi-nor: sst word program failed\n"); break; @@ -738,7 +695,6 @@ static int sst_write_wp(struct mtd_info *mtd, loff_t offset, size_t len, if (ret) break; - cmd_len = 1; offset += 2; *retlen += 2; } diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 4749ff4..19a5dd0 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -224,11 +224,11 @@ struct spi_nor { int (*read_mmap)(struct spi_nor *nor, void *data, void *offset, size_t len); - int (*read)(struct spi_nor *nor, const u8 *opcode, size_t cmd_len, - void *data, size_t data_len); - int (*write)(struct spi_nor *nor, const u8 *cmd, size_t cmd_len, - const void *data, size_t data_len); - int (*erase)(struct spi_nor *nor, const u8 *cmd, size_t cmd_len); + int (*read)(struct spi_nor *nor, loff_t from, size_t len, + u_char *read_buf); + int (*write)(struct spi_nor *nor, loff_t to, size_t len, + const u_char *write_buf); + int (*erase)(struct spi_nor *nor, loff_t offs); int (*flash_lock)(struct spi_nor *nor, loff_t ofs, uint64_t len); int (*flash_unlock)(struct spi_nor *nor, loff_t ofs, uint64_t len);