-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
yaml --- r: 347191 b: refs/heads/master c: 19c0921 h: refs/heads/master i: 347189: 2c97d3d 347187: 6436aea 347183: 0d20b43 v: v3
- Loading branch information
Rafał Miłecki
authored and
Artem Bityutskiy
committed
Nov 22, 2012
1 parent
7606126
commit 2eaf762
Showing
3 changed files
with
111 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
--- | ||
refs/heads/master: a5401370c520d573e9d62b3f8f34940c3b798a49 | ||
refs/heads/master: 19c0921c842e0aa9ce8c540c9134fd358acc9b28 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
bcm47xxnflash-y += main.o | ||
bcm47xxnflash- += ops_bcm4706.o | ||
|
||
obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH) += bcm47xxnflash.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
/* | ||
* BCM47XX NAND flash driver | ||
* | ||
* Copyright (C) 2012 Rafał Miłecki <zajec5@gmail.com> | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License version 2 as | ||
* published by the Free Software Foundation. | ||
* | ||
*/ | ||
|
||
#include <linux/module.h> | ||
#include <linux/kernel.h> | ||
#include <linux/slab.h> | ||
#include <linux/bcma/bcma.h> | ||
|
||
#include "bcm47xxnflash.h" | ||
|
||
/************************************************** | ||
* Various helpers | ||
**************************************************/ | ||
|
||
static inline u8 bcm47xxnflash_ops_bcm4706_ns_to_cycle(u16 ns, u16 clock) | ||
{ | ||
return ((ns * 1000 * clock) / 1000000) + 1; | ||
} | ||
|
||
/************************************************** | ||
* NAND chip ops | ||
**************************************************/ | ||
|
||
/* Default nand_select_chip calls cmd_ctrl, which is not used in BCM4706 */ | ||
static void bcm47xxnflash_ops_bcm4706_select_chip(struct mtd_info *mtd, | ||
int chip) | ||
{ | ||
return; | ||
} | ||
|
||
/************************************************** | ||
* Init | ||
**************************************************/ | ||
|
||
int bcm47xxnflash_ops_bcm4706_init(struct bcm47xxnflash *b47n) | ||
{ | ||
int err; | ||
u32 freq; | ||
u16 clock; | ||
u8 w0, w1, w2, w3, w4; | ||
|
||
unsigned long chipsize; /* MiB */ | ||
u8 tbits, col_bits, col_size, row_bits, row_bsize; | ||
u32 val; | ||
|
||
b47n->nand_chip.select_chip = bcm47xxnflash_ops_bcm4706_select_chip; | ||
b47n->nand_chip.ecc.mode = NAND_ECC_NONE; /* TODO: implement ECC */ | ||
|
||
/* Enable NAND flash access */ | ||
bcma_cc_set32(b47n->cc, BCMA_CC_4706_FLASHSCFG, | ||
BCMA_CC_4706_FLASHSCFG_NF1); | ||
|
||
/* Configure wait counters */ | ||
if (b47n->cc->status & BCMA_CC_CHIPST_4706_PKG_OPTION) { | ||
freq = 100000000; | ||
} else { | ||
freq = bcma_chipco_pll_read(b47n->cc, 4); | ||
freq = (freq * 0xFFF) >> 3; | ||
freq = (freq * 25000000) >> 3; | ||
} | ||
clock = freq / 1000000; | ||
w0 = bcm47xxnflash_ops_bcm4706_ns_to_cycle(15, clock); | ||
w1 = bcm47xxnflash_ops_bcm4706_ns_to_cycle(20, clock); | ||
w2 = bcm47xxnflash_ops_bcm4706_ns_to_cycle(10, clock); | ||
w3 = bcm47xxnflash_ops_bcm4706_ns_to_cycle(10, clock); | ||
w4 = bcm47xxnflash_ops_bcm4706_ns_to_cycle(100, clock); | ||
bcma_cc_write32(b47n->cc, BCMA_CC_NFLASH_WAITCNT0, | ||
(w4 << 24 | w3 << 18 | w2 << 12 | w1 << 6 | w0)); | ||
|
||
/* Scan NAND */ | ||
err = nand_scan(&b47n->mtd, 1); | ||
if (err) { | ||
pr_err("Could not scan NAND flash: %d\n", err); | ||
goto exit; | ||
} | ||
|
||
/* Configure FLASH */ | ||
chipsize = b47n->nand_chip.chipsize >> 20; | ||
tbits = ffs(chipsize); /* find first bit set */ | ||
if (!tbits || tbits != fls(chipsize)) { | ||
pr_err("Invalid flash size: 0x%lX\n", chipsize); | ||
err = -ENOTSUPP; | ||
goto exit; | ||
} | ||
tbits += 19; /* Broadcom increases *index* by 20, we increase *pos* */ | ||
|
||
col_bits = b47n->nand_chip.page_shift + 1; | ||
col_size = (col_bits + 7) / 8; | ||
|
||
row_bits = tbits - col_bits + 1; | ||
row_bsize = (row_bits + 7) / 8; | ||
|
||
val = ((row_bsize - 1) << 6) | ((col_size - 1) << 4) | 2; | ||
bcma_cc_write32(b47n->cc, BCMA_CC_NFLASH_CONF, val); | ||
|
||
exit: | ||
if (err) | ||
bcma_cc_mask32(b47n->cc, BCMA_CC_4706_FLASHSCFG, | ||
~BCMA_CC_4706_FLASHSCFG_NF1); | ||
return err; | ||
} |