From 6120309d40a3d8cb18186dd6c9f2dd00af515a4e Mon Sep 17 00:00:00 2001 From: Vipin Kumar Date: Wed, 14 Mar 2012 11:47:14 +0530 Subject: [PATCH] --- yaml --- r: 298175 b: refs/heads/master c: e2f6bce8d94d2c82d4f7ae9d94743963a3b10136 h: refs/heads/master i: 298173: 0ec58c299f2f3c6ff277dd6bac357d4acb8e648a 298171: 04b7876bb3ccd62e0a3d903f87b5b8818d3d1360 298167: 51cf84d52297b25e087d3dc685fcac20eeb77f08 298159: 1372475d2420a9107df9152fff687ec9a97adda6 298143: b4a87629e2bf2c9cb99ca8c9d2d5ec8d59943ed5 298111: 5910f13e477b909af60de3f2f95c0b9d00ec97a0 v: v3 --- [refs] | 2 +- trunk/drivers/mtd/nand/fsmc_nand.c | 41 ++++++++++++++++++++++++------ trunk/include/linux/mtd/fsmc.h | 34 ++++++++++++++++++++----- 3 files changed, 62 insertions(+), 15 deletions(-) diff --git a/[refs] b/[refs] index c8ae5c18cd34..681510e2147b 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: f63acb75c5d8a9eb7cc5548e3e778d2a00bf3bae +refs/heads/master: e2f6bce8d94d2c82d4f7ae9d94743963a3b10136 diff --git a/trunk/drivers/mtd/nand/fsmc_nand.c b/trunk/drivers/mtd/nand/fsmc_nand.c index a5099607d203..e7ae63ab59c6 100644 --- a/trunk/drivers/mtd/nand/fsmc_nand.c +++ b/trunk/drivers/mtd/nand/fsmc_nand.c @@ -303,6 +303,8 @@ struct fsmc_nand_data { struct resource *resaddr; struct resource *resdata; + struct fsmc_nand_timings *dev_timings; + void __iomem *data_va; void __iomem *cmd_va; void __iomem *addr_va; @@ -383,21 +385,41 @@ static void fsmc_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) * FSMC registers */ static void fsmc_nand_setup(struct fsmc_regs *regs, uint32_t bank, - uint32_t busw) + uint32_t busw, struct fsmc_nand_timings *timings) { uint32_t value = FSMC_DEVTYPE_NAND | FSMC_ENABLE | FSMC_WAITON; + uint32_t tclr, tar, thiz, thold, twait, tset; + struct fsmc_nand_timings *tims; + struct fsmc_nand_timings default_timings = { + .tclr = FSMC_TCLR_1, + .tar = FSMC_TAR_1, + .thiz = FSMC_THIZ_1, + .thold = FSMC_THOLD_4, + .twait = FSMC_TWAIT_6, + .tset = FSMC_TSET_0, + }; + + if (timings) + tims = timings; + else + tims = &default_timings; + + tclr = (tims->tclr & FSMC_TCLR_MASK) << FSMC_TCLR_SHIFT; + tar = (tims->tar & FSMC_TAR_MASK) << FSMC_TAR_SHIFT; + thiz = (tims->thiz & FSMC_THIZ_MASK) << FSMC_THIZ_SHIFT; + thold = (tims->thold & FSMC_THOLD_MASK) << FSMC_THOLD_SHIFT; + twait = (tims->twait & FSMC_TWAIT_MASK) << FSMC_TWAIT_SHIFT; + tset = (tims->tset & FSMC_TSET_MASK) << FSMC_TSET_SHIFT; if (busw) writel(value | FSMC_DEVWID_16, ®s->bank_regs[bank].pc); else writel(value | FSMC_DEVWID_8, ®s->bank_regs[bank].pc); - writel(readl(®s->bank_regs[bank].pc) | FSMC_TCLR_1 | FSMC_TAR_1, + writel(readl(®s->bank_regs[bank].pc) | tclr | tar, ®s->bank_regs[bank].pc); - writel(FSMC_THIZ_1 | FSMC_THOLD_4 | FSMC_TWAIT_6 | FSMC_TSET_0, - ®s->bank_regs[bank].comm); - writel(FSMC_THIZ_1 | FSMC_THOLD_4 | FSMC_TWAIT_6 | FSMC_TSET_0, - ®s->bank_regs[bank].attrib); + writel(thiz | thold | twait | tset, ®s->bank_regs[bank].comm); + writel(thiz | thold | twait | tset, ®s->bank_regs[bank].attrib); } /* @@ -783,6 +805,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) host->select_chip = pdata->select_bank; host->partitions = pdata->partitions; host->nr_partitions = pdata->nr_partitions; + host->dev_timings = pdata->nand_timings; regs = host->regs_va; /* Link all private pointers */ @@ -807,7 +830,8 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) if (pdata->width == FSMC_NAND_BW16) nand->options |= NAND_BUSWIDTH_16; - fsmc_nand_setup(regs, host->bank, nand->options & NAND_BUSWIDTH_16); + fsmc_nand_setup(regs, host->bank, nand->options & NAND_BUSWIDTH_16, + host->dev_timings); if (AMBA_REV_BITS(host->pid) >= 8) { nand->ecc.read_page = fsmc_read_page_hwecc; @@ -979,7 +1003,8 @@ static int fsmc_nand_resume(struct device *dev) if (host) { clk_enable(host->clk); fsmc_nand_setup(host->regs_va, host->bank, - host->nand.options & NAND_BUSWIDTH_16); + host->nand.options & NAND_BUSWIDTH_16, + host->dev_timings); } return 0; } diff --git a/trunk/include/linux/mtd/fsmc.h b/trunk/include/linux/mtd/fsmc.h index e877325d9c51..c4ac07a19691 100644 --- a/trunk/include/linux/mtd/fsmc.h +++ b/trunk/include/linux/mtd/fsmc.h @@ -90,17 +90,29 @@ struct fsmc_regs { #define FSMC_ECCEN (1 << 6) #define FSMC_ECCPLEN_512 (0 << 7) #define FSMC_ECCPLEN_256 (1 << 7) -#define FSMC_TCLR_1 (1 << 9) -#define FSMC_TAR_1 (1 << 13) +#define FSMC_TCLR_1 (1) +#define FSMC_TCLR_SHIFT (9) +#define FSMC_TCLR_MASK (0xF) +#define FSMC_TAR_1 (1) +#define FSMC_TAR_SHIFT (13) +#define FSMC_TAR_MASK (0xF) /* sts register definitions */ #define FSMC_CODE_RDY (1 << 15) /* comm register definitions */ -#define FSMC_TSET_0 (0 << 0) -#define FSMC_TWAIT_6 (6 << 8) -#define FSMC_THOLD_4 (4 << 16) -#define FSMC_THIZ_1 (1 << 24) +#define FSMC_TSET_0 0 +#define FSMC_TSET_SHIFT 0 +#define FSMC_TSET_MASK 0xFF +#define FSMC_TWAIT_6 6 +#define FSMC_TWAIT_SHIFT 8 +#define FSMC_TWAIT_MASK 0xFF +#define FSMC_THOLD_4 4 +#define FSMC_THOLD_SHIFT 16 +#define FSMC_THOLD_MASK 0xFF +#define FSMC_THIZ_1 1 +#define FSMC_THIZ_SHIFT 24 +#define FSMC_THIZ_MASK 0xFF /* * There are 13 bytes of ecc for every 512 byte block in FSMC version 8 @@ -120,6 +132,15 @@ struct fsmc_eccplace { struct fsmc_nand_eccplace eccplace[MAX_ECCPLACE_ENTRIES]; }; +struct fsmc_nand_timings { + uint8_t tclr; + uint8_t tar; + uint8_t thiz; + uint8_t thold; + uint8_t twait; + uint8_t tset; +}; + /** * fsmc_nand_platform_data - platform specific NAND controller config * @partitions: partition table for the platform, use a default fallback @@ -133,6 +154,7 @@ struct fsmc_eccplace { * this may be set to NULL */ struct fsmc_nand_platform_data { + struct fsmc_nand_timings *nand_timings; struct mtd_partition *partitions; unsigned int nr_partitions; unsigned int options;