From patchwork Mon Oct 12 19:54:08 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jagan Teki X-Patchwork-Id: 529397 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 2E9C2140D95 for ; Tue, 13 Oct 2015 06:55:17 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id C2BBC4B85E; Mon, 12 Oct 2015 21:55:14 +0200 (CEST) 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 UlUwMrHwkxsT; Mon, 12 Oct 2015 21:55:14 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 544084B794; Mon, 12 Oct 2015 21:55:14 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 7021D4B794 for ; Mon, 12 Oct 2015 21:55:10 +0200 (CEST) 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 8jSFkZqBXwyB for ; Mon, 12 Oct 2015 21:55:10 +0200 (CEST) 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-pa0-f46.google.com (mail-pa0-f46.google.com [209.85.220.46]) by theia.denx.de (Postfix) with ESMTPS id C20FB4B792 for ; Mon, 12 Oct 2015 21:55:06 +0200 (CEST) Received: by pabrc13 with SMTP id rc13so26958505pab.0 for ; Mon, 12 Oct 2015 12:55:04 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=from:to:cc:subject:date:message-id; bh=oD+9lg5Z7vLxjzvz2iH2jolovrxExjiXnZANcXuSsj8=; b=SCfZBgc1mDOXIpy69DfsyZD9Pk0q7FD5wTRNvOCMW60NA7D+tUdALJNAeTf0TVOOpg DqStbyVx0cM9TuaEQ/rRCEjDmbbpfaQN7Gm8l7Q5tz6+icrEvQbtg0jYPatQ2RsgejVd 5MnY8XgUpvQS1sY9N6IifiCCzG3JWjkrqX9xT1X72fiLMq693kFoSWm4zAOy9QL55JnZ mgBNr39LY8kVKRxJOHFGfKjiPkwzv6ia2O5O3Und3i8iMQitxvwnsvMLUahYJO4lZ1FH PTZ3m/pOoaa3zz3xHO4ICpTLAk2meuQnaGZVrxDQPo3tzKoNH4xm6hNVPpDeTVWT4J+Q +Zdg== X-Received: by 10.66.219.195 with SMTP id pq3mr35701517pac.98.1444679704785; Mon, 12 Oct 2015 12:55:04 -0700 (PDT) Received: from localhost.localdomain ([123.236.183.133]) by smtp.gmail.com with ESMTPSA id g12sm4613845pat.36.2015.10.12.12.55.02 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 12 Oct 2015 12:55:03 -0700 (PDT) From: Jagan Teki To: u-boot@lists.denx.de Date: Tue, 13 Oct 2015 01:24:08 +0530 Message-Id: <1444679655-30349-1-git-send-email-jteki@openedev.com> X-Mailer: git-send-email 1.9.1 Cc: Jagan Teki Subject: [U-Boot] [PATCH 1/8] sf: Add MTD support to spi_flash 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" This patch adds mtd_info support to spi_flash layer, MTD has proven core for flash operations so adding MTD to spi_flash will extends more functionality. Signed-off-by: Jagan Teki Reviewed-by: Heiko Schocher --- drivers/mtd/spi/sf_ops.c | 45 +++++++++++++++++++++++++-------------------- drivers/mtd/spi/sf_probe.c | 26 ++++++++++++++++++-------- include/spi_flash.h | 9 +++++---- 3 files changed, 48 insertions(+), 32 deletions(-) diff --git a/drivers/mtd/spi/sf_ops.c b/drivers/mtd/spi/sf_ops.c index 703099f..f5ee376 100644 --- a/drivers/mtd/spi/sf_ops.c +++ b/drivers/mtd/spi/sf_ops.c @@ -146,7 +146,7 @@ static int spi_flash_read_bar(struct spi_flash *flash, u8 idcode0) u8 curr_bank = 0; int ret; - if (flash->size <= SPI_FLASH_16MB_BOUN) + if (flash->mtd->size <= SPI_FLASH_16MB_BOUN) goto bank_end; switch (idcode0) { @@ -176,8 +176,8 @@ static void spi_flash_dual(struct spi_flash *flash, u32 *addr) { switch (flash->dual_flash) { case SF_DUAL_STACKED_FLASH: - if (*addr >= (flash->size >> 1)) { - *addr -= flash->size >> 1; + if (*addr >= (flash->mtd->size >> 1)) { + *addr -= flash->mtd->size >> 1; flash->spi->flags |= SPI_XFER_U_PAGE; } else { flash->spi->flags &= ~SPI_XFER_U_PAGE; @@ -303,7 +303,7 @@ static int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, u8 cmd[SPI_FLASH_CMD_LEN]; int ret = -1; - erase_size = flash->erase_size; + erase_size = mtd->erasesize; if (offset % erase_size || len % erase_size) { debug("SF: Erase offset/length not multiple of erase size\n"); return -1; @@ -693,7 +693,7 @@ int spi_flash_decode_fdt(const void *blob, struct spi_flash *flash) return 0; } - if (flash->size != size) { + if (flash->mtd->size != size) { debug("%s: Memory map must cover entire device\n", __func__); return -1; } @@ -705,6 +705,7 @@ int spi_flash_decode_fdt(const void *blob, struct spi_flash *flash) int spi_flash_scan(struct spi_flash *flash) { + struct mtd_info *mtd = flash->mtd; const struct spi_flash_params *params; u16 jedec, ext_jedec; u8 idcode[5]; @@ -754,24 +755,27 @@ int spi_flash_scan(struct spi_flash *flash) /* Assign spi data */ flash->name = params->name; + mtd->type = MTD_NORFLASH; + mtd->writesize = 1; + mtd->flags = MTD_CAP_NORFLASH; flash->memory_map = flash->spi->memory_map; flash->dual_flash = flash->spi->option; /* Assign spi_flash ops */ - flash->write = spi_flash_cmd_write_ops; + mtd->_write = spi_flash_cmd_write_ops; #if defined(CONFIG_SPI_FLASH_SST) if (params->flags & SST_WR) flash->flags |= SNOR_F_SST_WR; if (params->flags & SNOR_F_SST_WR) { if (flash->spi->op_mode_tx & SPI_OPM_TX_BP) - flash->write = sst_write_bp; + mtd->_write = sst_write_bp; else - flash->write = sst_write_wp; + mtd->_write = sst_write_wp; } #endif - flash->erase = spi_flash_cmd_erase_ops; - flash->read = spi_flash_cmd_read_ops; + mtd->_erase = spi_flash_cmd_erase_ops; + mtd->_read = spi_flash_cmd_read_ops; /* Compute the flash size */ flash->shift = (flash->dual_flash & SF_DUAL_PARALLEL_FLASH) ? 1 : 0; @@ -790,27 +794,28 @@ int spi_flash_scan(struct spi_flash *flash) flash->page_size = 256; } flash->page_size <<= flash->shift; + mtd->writebufsize = flash->page_size; flash->sector_size = params->sector_size << flash->shift; - flash->size = flash->sector_size * params->nr_sectors << flash->shift; + mtd->size = flash->sector_size * params->nr_sectors << flash->shift; #ifdef CONFIG_SF_DUAL_FLASH if (flash->dual_flash & SF_DUAL_STACKED_FLASH) - flash->size <<= 1; + mtd->size <<= 1; #endif /* Compute erase sector and command */ if (params->flags & SECT_4K) { flash->erase_cmd = CMD_ERASE_4K; - flash->erase_size = 4096 << flash->shift; + mtd->erasesize = 4096 << flash->shift; } else if (params->flags & SECT_32K) { flash->erase_cmd = CMD_ERASE_32K; - flash->erase_size = 32768 << flash->shift; + mtd->erasesize = 32768 << flash->shift; } else { flash->erase_cmd = CMD_ERASE_64K; - flash->erase_size = flash->sector_size; + mtd->erasesize = flash->sector_size; } /* Now erase size becomes valid sector size */ - flash->sector_size = flash->erase_size; + flash->sector_size = mtd->erasesize; /* Look for the fastest read cmd */ cmd = fls(params->e_rd_cmd & flash->spi->op_mode_rx); @@ -882,8 +887,8 @@ int spi_flash_scan(struct spi_flash *flash) #ifndef CONFIG_SPL_BUILD printf("SF: Detected %s with page size ", flash->name); print_size(flash->page_size, ", erase size "); - print_size(flash->erase_size, ", total "); - print_size(flash->size, ""); + print_size(mtd->erasesize, ", total "); + print_size(mtd->size, ""); if (flash->memory_map) printf(", mapped at %p", flash->memory_map); puts("\n"); @@ -891,9 +896,9 @@ int spi_flash_scan(struct spi_flash *flash) #ifndef CONFIG_SPI_FLASH_BAR if (((flash->dual_flash == SF_SINGLE_FLASH) && - (flash->size > SPI_FLASH_16MB_BOUN)) || + (mtd->size > SPI_FLASH_16MB_BOUN)) || ((flash->dual_flash > SF_SINGLE_FLASH) && - (flash->size > SPI_FLASH_16MB_BOUN << 1))) { + (mtd->size > SPI_FLASH_16MB_BOUN << 1))) { puts("SF: Warning - Only lower 16MiB accessible,"); puts(" Full access #define CONFIG_SPI_FLASH_BAR\n"); } diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index 87ac33e..b8704e2 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -14,9 +14,15 @@ #include #include #include +#include #include "sf_internal.h" +struct spi_flash_priv { + struct spi_flash flash; + struct mtd_info mtd; +}; + #ifndef CONFIG_DM_SPI_FLASH struct spi_flash *spi_flash_probe_tail(struct spi_slave *bus) { @@ -123,12 +129,19 @@ int spi_flash_std_erase(struct udevice *dev, u32 offset, size_t len) int spi_flash_std_probe(struct udevice *dev) { - struct spi_flash *flash = dev_get_uclass_priv(dev); + struct spi_flash_priv *priv = dev_get_uclass_priv(dev); struct spi_slave *slave = dev_get_parentdata(dev); + struct spi_flash *flash; int ret; - flash->dev = dev; + flash = &priv->flash; + flash->mtd = &priv->mtd; + flash->spi = slave; + flash->priv = priv; + + priv->mtd.priv = flash; + flash->dev = dev; /* Claim spi bus */ ret = spi_claim_bus(slave); @@ -143,19 +156,16 @@ int spi_flash_std_probe(struct udevice *dev) goto err_scan; } -#ifdef CONFIG_SPI_FLASH_MTD - ret = spi_flash_mtd_register(flash); + ret = add_mtd_device(&priv->mtd); if (ret) { printf("SF: failed to register mtd device: %d\n", ret); goto err_mtd; } -#endif + return ret; -#ifdef CONFIG_SPI_FLASH_MTD err_mtd: spi_free_slave(slave); -#endif err_scan: spi_release_bus(slave); return ret; @@ -177,7 +187,7 @@ U_BOOT_DRIVER(spi_flash_std) = { .id = UCLASS_SPI_FLASH, .of_match = spi_flash_std_ids, .probe = spi_flash_std_probe, - .priv_auto_alloc_size = sizeof(struct spi_flash), + .priv_auto_alloc_size = sizeof(struct spi_flash_priv), .ops = &spi_flash_std_ops, }; diff --git a/include/spi_flash.h b/include/spi_flash.h index 0732172..d0af8d3 100644 --- a/include/spi_flash.h +++ b/include/spi_flash.h @@ -17,6 +17,7 @@ #include /* Because we dereference struct udevice here */ #include +#include #ifndef CONFIG_SF_DEFAULT_SPEED # define CONFIG_SF_DEFAULT_SPEED 1000000 @@ -36,16 +37,15 @@ struct spi_slave; /** * struct spi_flash - SPI flash structure * + * @mtd: point to a mtd_info structure * @spi: SPI slave * @dev: SPI flash device * @name: Name of SPI flash * @dual_flash: Indicates dual flash memories - dual stacked, parallel * @shift: Flash shift useful in dual parallel * @flags: Indication of spi flash flags - * @size: Total flash size * @page_size: Write (page) size * @sector_size: Sector size - * @erase_size: Erase size * @bank_read_cmd: Bank read cmd * @bank_write_cmd: Bank write cmd * @bank_curr: Current flash bank @@ -54,6 +54,7 @@ struct spi_slave; * @write_cmd: Write cmd - page and quad program. * @dummy_byte: Dummy cycles for read operation. * @memory_map: Address of read-only SPI flash access + * @priv: the private data * @read: Flash read ops: Read len bytes at offset into buf * Supported cmds: Fast Array Read * @write: Flash write ops: Write len bytes from buf into offset @@ -63,6 +64,7 @@ struct spi_slave; * return 0 - Success, 1 - Failure */ struct spi_flash { + struct mtd_info *mtd; struct spi_slave *spi; #ifdef CONFIG_DM_SPI_FLASH struct udevice *dev; @@ -72,10 +74,8 @@ struct spi_flash { u8 shift; u16 flags; - u32 size; u32 page_size; u32 sector_size; - u32 erase_size; #ifdef CONFIG_SPI_FLASH_BAR u8 bank_read_cmd; u8 bank_write_cmd; @@ -87,6 +87,7 @@ struct spi_flash { u8 dummy_byte; void *memory_map; + void *priv; int (*read)(struct spi_flash *flash, u32 offset, size_t len, void *buf); int (*write)(struct spi_flash *flash, u32 offset, size_t len, const void *buf);