From 2eaf7621209898350e4c624c0b5e8570f8629466 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Mon, 12 Nov 2012 13:03:22 +0100 Subject: [PATCH] --- yaml --- r: 347191 b: refs/heads/master c: 19c0921c842e0aa9ce8c540c9134fd358acc9b28 h: refs/heads/master i: 347189: 2c97d3d8061116b7eb0a501d08a46f65b97686cd 347187: 6436aea44f31acb757e0c048681a4f4a220660e0 347183: 0d20b43babd3dac3145dbfd2e12c5689896b550c v: v3 --- [refs] | 2 +- trunk/drivers/mtd/nand/bcm47xxnflash/Makefile | 1 + .../mtd/nand/bcm47xxnflash/ops_bcm4706.c | 109 ++++++++++++++++++ 3 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 trunk/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c diff --git a/[refs] b/[refs] index 496eb03806b4..2f2166f60122 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: a5401370c520d573e9d62b3f8f34940c3b798a49 +refs/heads/master: 19c0921c842e0aa9ce8c540c9134fd358acc9b28 diff --git a/trunk/drivers/mtd/nand/bcm47xxnflash/Makefile b/trunk/drivers/mtd/nand/bcm47xxnflash/Makefile index 1d0693af6e98..4f688f9655ad 100644 --- a/trunk/drivers/mtd/nand/bcm47xxnflash/Makefile +++ b/trunk/drivers/mtd/nand/bcm47xxnflash/Makefile @@ -1,3 +1,4 @@ bcm47xxnflash-y += main.o +bcm47xxnflash- += ops_bcm4706.o obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH) += bcm47xxnflash.o diff --git a/trunk/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c b/trunk/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c new file mode 100644 index 000000000000..ae8a79387c27 --- /dev/null +++ b/trunk/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c @@ -0,0 +1,109 @@ +/* + * BCM47XX NAND flash driver + * + * Copyright (C) 2012 Rafał Miłecki + * + * 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 +#include +#include +#include + +#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; +}