Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 298175
b: refs/heads/master
c: e2f6bce
h: refs/heads/master
i:
  298173: 0ec58c2
  298171: 04b7876
  298167: 51cf84d
  298159: 1372475
  298143: b4a8762
  298111: 5910f13
v: v3
  • Loading branch information
Vipin Kumar authored and David Woodhouse committed Mar 26, 2012
1 parent 47ab229 commit 6120309
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 15 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: f63acb75c5d8a9eb7cc5548e3e778d2a00bf3bae
refs/heads/master: e2f6bce8d94d2c82d4f7ae9d94743963a3b10136
41 changes: 33 additions & 8 deletions trunk/drivers/mtd/nand/fsmc_nand.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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, &regs->bank_regs[bank].pc);
else
writel(value | FSMC_DEVWID_8, &regs->bank_regs[bank].pc);

writel(readl(&regs->bank_regs[bank].pc) | FSMC_TCLR_1 | FSMC_TAR_1,
writel(readl(&regs->bank_regs[bank].pc) | tclr | tar,
&regs->bank_regs[bank].pc);
writel(FSMC_THIZ_1 | FSMC_THOLD_4 | FSMC_TWAIT_6 | FSMC_TSET_0,
&regs->bank_regs[bank].comm);
writel(FSMC_THIZ_1 | FSMC_THOLD_4 | FSMC_TWAIT_6 | FSMC_TSET_0,
&regs->bank_regs[bank].attrib);
writel(thiz | thold | twait | tset, &regs->bank_regs[bank].comm);
writel(thiz | thold | twait | tset, &regs->bank_regs[bank].attrib);
}

/*
Expand Down Expand Up @@ -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 */
Expand All @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down
34 changes: 28 additions & 6 deletions trunk/include/linux/mtd/fsmc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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;
Expand Down

0 comments on commit 6120309

Please sign in to comment.