From patchwork Fri Jun 18 05:33:46 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Haojian Zhuang X-Patchwork-Id: 56109 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from bombadil.infradead.org (bombadil.infradead.org [18.85.46.34]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id C71351007D2 for ; Fri, 18 Jun 2010 15:36:21 +1000 (EST) Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.72 #1 (Red Hat Linux)) id 1OPUDX-0006rd-RD; Fri, 18 Jun 2010 05:34:15 +0000 Received: from mail-pw0-f49.google.com ([209.85.160.49]) by bombadil.infradead.org with esmtp (Exim 4.72 #1 (Red Hat Linux)) id 1OPUD5-0006WI-51; Fri, 18 Jun 2010 05:33:49 +0000 Received: by mail-pw0-f49.google.com with SMTP id 6so353711pwj.36 for ; Thu, 17 Jun 2010 22:33:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:received:date:message-id :subject:from:to:content-type; bh=1CJIXzo9G17+P3kQqx/ZtcbQ3R6/hVTqgbsYCvKG7qE=; b=jjxTn31lKwK9GcJ1H/U3TVm5Wdj+ViCRCMvb8kYW9kQStQa7FqXxozY1cNJene9Di/ +z5SLE+VUrSy8SBTdR1od650h2GEnBSb2akFBRJ6Ovph1pH7BOPBPO/nMWhYqxACnZzn KrD3o1X2fCxGaRZGSCVatQFG5onKZ2lJcJR4w= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:date:message-id:subject:from:to:content-type; b=acrLmbbn2mT5MkPfF4oRqOlukAcWmwHpO0+1/1qKNSjkyW7CoPu5XCoZtXelDgUrT0 D33yAZ0k4adfM3nfpZi6rW96JUdWid7Y4UrSYzv9UixYO+U03RD+4dfio2dZfcXFdDsH AgnUMBUo8e4ndznqorfCmoJtmQQKLOv58Jpdg= MIME-Version: 1.0 Received: by 10.142.122.9 with SMTP id u9mr357791wfc.339.1276839226659; Thu, 17 Jun 2010 22:33:46 -0700 (PDT) Received: by 10.142.114.3 with HTTP; Thu, 17 Jun 2010 22:33:46 -0700 (PDT) Date: Fri, 18 Jun 2010 13:33:46 +0800 Message-ID: Subject: [PATCH 03/25] pxa3xx_nand: remove the flash info in driver structure From: Haojian Zhuang To: Marc Kleine-Budde , David Woodhouse , David Woodhouse , linux-mtd@lists.infradead.org, Eric Miao , linux-arm-kernel X-CRM114-Version: 20090807-BlameThorstenAndJenny ( TRE 0.7.6 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20100618_013347_825996_B1593082 X-CRM114-Status: GOOD ( 25.63 ) X-Spam-Score: -0.1 (/) X-Spam-Report: SpamAssassin version 3.3.1 on bombadil.infradead.org summary: Content analysis details: (-0.1 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, low trust [209.85.160.49 listed in list.dnswl.org] 0.0 FREEMAIL_FROM Sender email is freemail (haojian.zhuang[at]gmail.com) -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-mtd-bounces@lists.infradead.org Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From 643765e6ae0f37902321f31e14b565896217dd3a Mon Sep 17 00:00:00 2001 From: Lei Wen Date: Wed, 2 Jun 2010 21:54:33 +0800 Subject: [PATCH 03/25] pxa3xx_nand: remove the flash info in driver structure After probe, all info already transfer to driver structure. There is no need to keep the original flash info. So that we could safely free the flash info in memory, which may grows larger when more flash is suported. Signed-off-by: Lei Wen Signed-off-by: Haojian Zhuang --- drivers/mtd/nand/pxa3xx_nand.c | 70 ++++++++++++++++++++++++++-------------- 1 files changed, 46 insertions(+), 24 deletions(-) } @@ -316,22 +323,29 @@ static int wait_for_event(struct pxa3xx_nand_info *info, uint32_t event) return -ETIMEDOUT; } -static int prepare_read_prog_cmd(struct pxa3xx_nand_info *info, - uint16_t cmd, int column, int page_addr) +static void pxa3xx_set_datasize(struct pxa3xx_nand_info *info) { - const struct pxa3xx_nand_flash *f = info->flash_info; + int oob_enable = info->reg_ndcr & NDCR_SPARE_EN; - /* calculate data size */ - switch (f->page_size) { - case 2048: - info->data_size = (info->use_ecc) ? 2088 : 2112; - break; - case 512: - info->data_size = (info->use_ecc) ? 520 : 528; - break; - default: - return -EINVAL; + info->data_size = info->page_size; + if (!oob_enable) { + info->oob_size = 0; + return; } + switch (info->page_size) { + case 2048: + info->oob_size = (info->use_ecc) ? 40 : 64; + break; + case 512: + info->oob_size = (info->use_ecc) ? 8 : 16; + break; + } +} + +static int prepare_read_prog_cmd(struct pxa3xx_nand_info *info, + uint16_t cmd, int column, int page_addr) +{ + pxa3xx_set_datasize(info); /* generate values for NDCBx registers */ info->ndcb0 = cmd | ((cmd & 0xff00) ? NDCB0_DBC : 0); @@ -442,6 +456,9 @@ static int handle_data_pio(struct pxa3xx_nand_info *info) case STATE_PIO_WRITING: __raw_writesl(info->mmio_base + NDDB, info->data_buff, DIV_ROUND_UP(info->data_size, 4)); + if (info->oob_size > 0) + __raw_writesl(info->mmio_base + NDDB, info->oob_buff, + DIV_ROUND_UP(info->oob_size, 4)); enable_int(info, NDSR_CS0_BBD | NDSR_CS0_CMDD); @@ -454,6 +471,10 @@ static int handle_data_pio(struct pxa3xx_nand_info *info) case STATE_PIO_READING: __raw_readsl(info->mmio_base + NDDB, info->data_buff, DIV_ROUND_UP(info->data_size, 4)); + if (info->oob_size > 0) + __raw_readsl(info->mmio_base + NDDB, info->oob_buff, + DIV_ROUND_UP(info->oob_size, 4)); + break; default: printk(KERN_ERR "%s: invalid state %d\n", __func__, @@ -468,7 +489,7 @@ static int handle_data_pio(struct pxa3xx_nand_info *info) static void start_data_dma(struct pxa3xx_nand_info *info, int dir_out) { struct pxa_dma_desc *desc = info->data_desc; - int dma_len = ALIGN(info->data_size, 32); + int dma_len = ALIGN(info->data_size + info->oob_size, 32); desc->ddadr = DDADR_STOP; desc->dcmd = DCMD_ENDIRQEN | DCMD_WIDTH4 | DCMD_BURST32 | dma_len; @@ -863,6 +884,8 @@ static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info, uint32_t ndcr = 0x00000FFF; /* disable all interrupts */ /* calculate flash information */ + info->page_size = f->page_size; + info->oob_buff = info->data_buff + f->page_size; info->oob_size = (f->page_size == 2048) ? 64 : 16; info->read_id_bytes = (f->page_size == 2048) ? 4 : 2; @@ -887,7 +910,6 @@ static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info, info->reg_ndcr = ndcr; pxa3xx_nand_set_timing(info, f->timing); - info->flash_info = f; return 0; } @@ -923,7 +945,6 @@ static int pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info) default_flash.dfc_width = ndcr & NDCR_DWIDTH_C ? 16 : 8; /* set info fields needed to __readid */ - info->flash_info = &default_flash; info->read_id_bytes = (default_flash.page_size == 2048) ? 4 : 2; info->reg_ndcr = ndcr; @@ -1056,10 +1077,9 @@ static struct nand_ecclayout hw_largepage_ecclayout = { static void pxa3xx_nand_init_mtd(struct mtd_info *mtd, struct pxa3xx_nand_info *info) { - const struct pxa3xx_nand_flash *f = info->flash_info; struct nand_chip *this = &info->nand_chip; - this->options = (f->flash_width == 16) ? NAND_BUSWIDTH_16: 0; + this->options = (info->reg_ndcr & NDCR_DWIDTH_C) ? NAND_BUSWIDTH_16: 0; this->waitfunc = pxa3xx_nand_waitfunc; this->select_chip = pxa3xx_nand_select_chip; @@ -1075,9 +1095,9 @@ static void pxa3xx_nand_init_mtd(struct mtd_info *mtd, this->ecc.hwctl = pxa3xx_nand_ecc_hwctl; this->ecc.calculate = pxa3xx_nand_ecc_calculate; this->ecc.correct = pxa3xx_nand_ecc_correct; - this->ecc.size = f->page_size; + this->ecc.size = info->page_size; - if (f->page_size == 2048) + if (info->page_size == 2048) this->ecc.layout = &hw_largepage_ecclayout; else this->ecc.layout = &hw_smallpage_ecclayout; @@ -1085,7 +1105,7 @@ static void pxa3xx_nand_init_mtd(struct mtd_info *mtd, this->chip_delay = 25; } -static int pxa3xx_nand_probe(struct platform_device *pdev) +static int __devinit pxa3xx_nand_probe(struct platform_device *pdev) { struct pxa3xx_nand_platform_data *pdata; struct pxa3xx_nand_info *info; @@ -1284,9 +1304,11 @@ static int pxa3xx_nand_resume(struct platform_device *pdev) struct mtd_info *mtd = (struct mtd_info *)platform_get_drvdata(pdev); struct pxa3xx_nand_info *info = mtd->priv; + nand_writel(info, NDTR0CS0, info->ndtr0cs0); + nand_writel(info, NDTR1CS0, info->ndtr1cs0); clk_enable(info->clk); - return pxa3xx_nand_config_flash(info, info->flash_info); + return 0; } #else #define pxa3xx_nand_suspend NULL diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index f939083..291610a 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c @@ -152,7 +152,6 @@ struct pxa3xx_nand_info { struct nand_chip nand_chip; struct platform_device *pdev; - const struct pxa3xx_nand_flash *flash_info; struct clk *clk; void __iomem *mmio_base; @@ -166,6 +165,7 @@ struct pxa3xx_nand_info { int drcmr_cmd; unsigned char *data_buff; + unsigned char *oob_buff; dma_addr_t data_buff_phys; size_t data_buff_size; int data_dma_ch; @@ -184,7 +184,8 @@ struct pxa3xx_nand_info { int use_ecc; /* use HW ECC ? */ int use_dma; /* use DMA ? */ - size_t data_size; /* data size in FIFO */ + unsigned int page_size; /* page size of attached chip */ + unsigned int data_size; /* data size in FIFO */ int retcode; struct completion cmd_complete; @@ -193,6 +194,10 @@ struct pxa3xx_nand_info { uint32_t ndcb1; uint32_t ndcb2; + /* timing calcuted from setting */ + uint32_t ndtr0cs0; + uint32_t ndtr1cs0; + /* calculated from pxa3xx_nand_flash data */ size_t oob_size; size_t read_id_bytes; @@ -293,6 +298,8 @@ static void pxa3xx_nand_set_timing(struct pxa3xx_nand_info *info, NDTR1_tWHR(ns2cycle(t->tWHR, nand_clk)) | NDTR1_tAR(ns2cycle(t->tAR, nand_clk)); + info->ndtr0cs0 = ndtr0; + info->ndtr1cs0 = ndtr1; nand_writel(info, NDTR0CS0, ndtr0); nand_writel(info, NDTR1CS0, ndtr1);