* [PATCH 1/4] mtd: prepare place for BCMA NAND flash driver(s)
@ 2012-09-12 20:21 Rafał Miłecki
2012-09-12 20:21 ` [PATCH 2/4] mtd: bcm47xxnflash: init NAND on BCM4706 Rafał Miłecki
` (4 more replies)
0 siblings, 5 replies; 8+ messages in thread
From: Rafał Miłecki @ 2012-09-12 20:21 UTC (permalink / raw)
To: linux-mtd, Artem Bityutskiy; +Cc: Rafał Miłecki
BCMA bus can contain NAND flash memory, it's registered in system as
platform device. This adds required hooks and place for controler
specific drivers.
At this point it doesn't work yet, so it's marked as BROKEN.
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
---
drivers/mtd/nand/Kconfig | 8 ++
drivers/mtd/nand/Makefile | 1 +
drivers/mtd/nand/bcm47xxnflash/Makefile | 3 +
drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h | 14 +++
drivers/mtd/nand/bcm47xxnflash/main.c | 108 ++++++++++++++++++++++++
5 files changed, 134 insertions(+), 0 deletions(-)
create mode 100644 drivers/mtd/nand/bcm47xxnflash/Makefile
create mode 100644 drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h
create mode 100644 drivers/mtd/nand/bcm47xxnflash/main.c
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 8ca4176..7460ac2 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -489,6 +489,14 @@ config MTD_NAND_GPMI_NAND
block, such as SD card. So pay attention to it when you enable
the GPMI.
+config MTD_NAND_BCM47XXNFLASH
+ tristate "Support for NAND flash on BCMA bus"
+ depends on BCMA_NFLASH && BROKEN
+ help
+ BCMA bus can have various flash memories attached, they are
+ registered by bcma as platform devices. This enables driver for
+ NAND flash memories.
+
config MTD_NAND_PLATFORM
tristate "Support for generic platform NAND driver"
depends on HAS_IOMEM
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index d4b4d87..8aa55d8 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -51,5 +51,6 @@ obj-$(CONFIG_MTD_NAND_MPC5121_NFC) += mpc5121_nfc.o
obj-$(CONFIG_MTD_NAND_RICOH) += r852.o
obj-$(CONFIG_MTD_NAND_JZ4740) += jz4740_nand.o
obj-$(CONFIG_MTD_NAND_GPMI_NAND) += gpmi-nand/
+obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH) += bcm47xxnflash/
nand-objs := nand_base.o nand_bbt.o
diff --git a/drivers/mtd/nand/bcm47xxnflash/Makefile b/drivers/mtd/nand/bcm47xxnflash/Makefile
new file mode 100644
index 0000000..1d0693a
--- /dev/null
+++ b/drivers/mtd/nand/bcm47xxnflash/Makefile
@@ -0,0 +1,3 @@
+bcm47xxnflash-y += main.o
+
+obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH) += bcm47xxnflash.o
diff --git a/drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h b/drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h
new file mode 100644
index 0000000..2e8864a
--- /dev/null
+++ b/drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h
@@ -0,0 +1,14 @@
+#ifndef __BCM47XXNFLASH_H
+#define __BCM47XXNFLASH_H
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+
+struct bcm47xxnflash {
+ struct bcma_drv_cc *cc;
+
+ struct nand_chip nand_chip;
+ struct mtd_info mtd;
+};
+
+#endif /* BCM47XXNFLASH */
diff --git a/drivers/mtd/nand/bcm47xxnflash/main.c b/drivers/mtd/nand/bcm47xxnflash/main.c
new file mode 100644
index 0000000..fc9139d
--- /dev/null
+++ b/drivers/mtd/nand/bcm47xxnflash/main.c
@@ -0,0 +1,108 @@
+/*
+ * 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/platform_device.h>
+#include <linux/bcma/bcma.h>
+
+#include "bcm47xxnflash.h"
+
+MODULE_DESCRIPTION("NAND flash driver for BCMA bus");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Rafał Miłecki");
+
+static const char *probes[] = { "bcm47xxpart", NULL };
+
+static int bcm47xxnflash_probe(struct platform_device *pdev)
+{
+ struct bcma_nflash *nflash = dev_get_platdata(&pdev->dev);
+ struct bcm47xxnflash *b47n;
+ int err = 0;
+
+ b47n = kzalloc(sizeof(*b47n), GFP_KERNEL);
+ if (!b47n) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ b47n->nand_chip.priv = b47n;
+ b47n->mtd.owner = THIS_MODULE;
+ b47n->mtd.priv = &b47n->nand_chip; /* Required */
+ b47n->cc = container_of(nflash, struct bcma_drv_cc, nflash);
+
+ if (0) {
+ /* TODO: init device */
+ } else {
+ pr_err("Device not supported\n");
+ err = -ENOTSUPP;
+ }
+ if (err) {
+ pr_err("Initialization failed: %d\n", err);
+ goto err_init;
+ }
+
+ err = mtd_device_parse_register(&b47n->mtd, probes, NULL, NULL, 0);
+ if (err) {
+ pr_err("Failed to register MTD device: %d\n", err);
+ goto err_dev_reg;
+ }
+
+ return 0;
+
+err_dev_reg:
+err_init:
+ kfree(b47n);
+out:
+ return err;
+}
+
+static int __devexit bcm47xxnflash_remove(struct platform_device *pdev)
+{
+ struct bcma_nflash *nflash = dev_get_platdata(&pdev->dev);
+
+ if (nflash->mtd)
+ mtd_device_unregister(nflash->mtd);
+
+ return 0;
+}
+
+static struct platform_driver bcm47xxnflash_driver = {
+ .remove = __devexit_p(bcm47xxnflash_remove),
+ .driver = {
+ .name = "bcma_nflash",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init bcm47xxnflash_init(void)
+{
+ int err;
+
+ /*
+ * Platform device "bcma_nflash" exists on SoCs and is registered very
+ * early, it won't be added during runtime (use platform_driver_probe).
+ */
+ err = platform_driver_probe(&bcm47xxnflash_driver, bcm47xxnflash_probe);
+ if (err)
+ pr_err("Failed to register serial flash driver: %d\n", err);
+
+ return err;
+}
+
+static void __exit bcm47xxnflash_exit(void)
+{
+ platform_driver_unregister(&bcm47xxnflash_driver);
+}
+
+module_init(bcm47xxnflash_init);
+module_exit(bcm47xxnflash_exit);
--
1.7.7
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/4] mtd: bcm47xxnflash: init NAND on BCM4706
2012-09-12 20:21 [PATCH 1/4] mtd: prepare place for BCMA NAND flash driver(s) Rafał Miłecki
@ 2012-09-12 20:21 ` Rafał Miłecki
2012-09-12 20:21 ` [PATCH 3/4] mtd: bcm47xxnflash: support for NAND_CMD_READID command Rafał Miłecki
` (3 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: Rafał Miłecki @ 2012-09-12 20:21 UTC (permalink / raw)
To: linux-mtd, Artem Bityutskiy; +Cc: Rafał Miłecki
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
---
drivers/mtd/nand/bcm47xxnflash/Makefile | 1 +
drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h | 2 +
drivers/mtd/nand/bcm47xxnflash/main.c | 4 +-
drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c | 110 ++++++++++++++++++++++++
4 files changed, 115 insertions(+), 2 deletions(-)
create mode 100644 drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c
diff --git a/drivers/mtd/nand/bcm47xxnflash/Makefile b/drivers/mtd/nand/bcm47xxnflash/Makefile
index 1d0693a..f05b119 100644
--- a/drivers/mtd/nand/bcm47xxnflash/Makefile
+++ b/drivers/mtd/nand/bcm47xxnflash/Makefile
@@ -1,3 +1,4 @@
bcm47xxnflash-y += main.o
+bcm47xxnflash-y += ops_bcm4706.o
obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH) += bcm47xxnflash.o
diff --git a/drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h b/drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h
index 2e8864a..149b74f 100644
--- a/drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h
+++ b/drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h
@@ -11,4 +11,6 @@ struct bcm47xxnflash {
struct mtd_info mtd;
};
+int bcm47xxnflash_ops_bcm4706_init(struct bcm47xxnflash *bcm47xxnflash);
+
#endif /* BCM47XXNFLASH */
diff --git a/drivers/mtd/nand/bcm47xxnflash/main.c b/drivers/mtd/nand/bcm47xxnflash/main.c
index fc9139d..2b8b05b 100644
--- a/drivers/mtd/nand/bcm47xxnflash/main.c
+++ b/drivers/mtd/nand/bcm47xxnflash/main.c
@@ -40,8 +40,8 @@ static int bcm47xxnflash_probe(struct platform_device *pdev)
b47n->mtd.priv = &b47n->nand_chip; /* Required */
b47n->cc = container_of(nflash, struct bcma_drv_cc, nflash);
- if (0) {
- /* TODO: init device */
+ if (b47n->cc->core->bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) {
+ err = bcm47xxnflash_ops_bcm4706_init(b47n);
} else {
pr_err("Device not supported\n");
err = -ENOTSUPP;
diff --git a/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c b/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c
new file mode 100644
index 0000000..38e3da6
--- /dev/null
+++ b/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c
@@ -0,0 +1,110 @@
+/*
+ * 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
+ **************************************************/
+
+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 col_mask;
+ u32 val;
+
+ b47n->nand_chip.select_chip = bcm47xxnflash_ops_bcm4706_select_chip;
+ b47n->nand_chip.ecc.mode = NAND_ECC_SOFT; /* 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_mask = (1 << col_bits) - 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;
+}
--
1.7.7
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 3/4] mtd: bcm47xxnflash: support for NAND_CMD_READID command
2012-09-12 20:21 [PATCH 1/4] mtd: prepare place for BCMA NAND flash driver(s) Rafał Miłecki
2012-09-12 20:21 ` [PATCH 2/4] mtd: bcm47xxnflash: init NAND on BCM4706 Rafał Miłecki
@ 2012-09-12 20:21 ` Rafał Miłecki
2012-09-12 20:21 ` [PATCH 4/4] mtd: bcm47xxnflash: implement reading Rafał Miłecki
` (2 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: Rafał Miłecki @ 2012-09-12 20:21 UTC (permalink / raw)
To: linux-mtd, Artem Bityutskiy; +Cc: Rafał Miłecki
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
---
drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h | 5 ++
drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c | 90 ++++++++++++++++++++++++
2 files changed, 95 insertions(+), 0 deletions(-)
diff --git a/drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h b/drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h
index 149b74f..53fb2ea 100644
--- a/drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h
+++ b/drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h
@@ -9,6 +9,11 @@ struct bcm47xxnflash {
struct nand_chip nand_chip;
struct mtd_info mtd;
+
+ unsigned curr_command;
+ int curr_column;
+
+ u8 id_data[8];
};
int bcm47xxnflash_ops_bcm4706_init(struct bcm47xxnflash *bcm47xxnflash);
diff --git a/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c b/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c
index 38e3da6..e86670b 100644
--- a/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c
+++ b/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c
@@ -16,6 +16,10 @@
#include "bcm47xxnflash.h"
+/* Broadcom uses 1'000'000 but it seems to be too many. Tests on WNDR4500 has
+ * shown 164 retries as maxiumum. */
+#define NFLASH_READY_RETRIES 1000
+
/**************************************************
* Various helpers
**************************************************/
@@ -25,6 +29,24 @@ static inline u8 bcm47xxnflash_ops_bcm4706_ns_to_cycle(u16 ns, u16 clock)
return ((ns * 1000 * clock) / 1000000) + 1;
}
+static int bcm47xxnflash_ops_bcm4706_ctl_cmd(struct bcma_drv_cc *cc, u32 code)
+{
+ int i = 0;
+
+ bcma_cc_write32(cc, BCMA_CC_NFLASH_CTL, 0x80000000 | code);
+ for (i = 0; i < NFLASH_READY_RETRIES; i++) {
+ if (!(bcma_cc_read32(cc, BCMA_CC_NFLASH_CTL) & 0x80000000)) {
+ i = 0;
+ break;
+ }
+ }
+ if (i) {
+ pr_err("NFLASH control command not ready!\n");
+ return -EBUSY;
+ }
+ return 0;
+}
+
/**************************************************
* NAND chip ops
**************************************************/
@@ -35,6 +57,72 @@ static void bcm47xxnflash_ops_bcm4706_select_chip(struct mtd_info *mtd,
return;
}
+static void bcm47xxnflash_ops_bcm4706_cmdfunc(struct mtd_info *mtd,
+ unsigned command, int column,
+ int page_addr)
+{
+ struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv;
+ struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv;
+ u32 ctlcode;
+ int i;
+
+ switch (command) {
+ case NAND_CMD_RESET:
+ pr_warn("Chip reset not implemented yet\n");
+ break;
+ case NAND_CMD_READID:
+ ctlcode = 0x40000000 | 0x01000000 | 0x00080000 | 0x00010000;
+ ctlcode |= NAND_CMD_READID;
+ if (bcm47xxnflash_ops_bcm4706_ctl_cmd(b47n->cc, ctlcode)) {
+ pr_err("READID error\n");
+ break;
+ }
+
+ /*
+ * Reading is specific, last one has to go without 0x40000000
+ * bit. We don't know how many reads NAND subsystem is going
+ * to perform, so cache everything.
+ */
+ for (i = 0; i < ARRAY_SIZE(b47n->id_data); i++) {
+ ctlcode = 0x40000000 | 0x00100000;
+ if (i == ARRAY_SIZE(b47n->id_data) - 1)
+ ctlcode &= ~0x40000000;
+ if (bcm47xxnflash_ops_bcm4706_ctl_cmd(b47n->cc,
+ ctlcode)) {
+ pr_err("READID error\n");
+ break;
+ }
+ b47n->id_data[i] = bcma_cc_read32(b47n->cc, BCMA_CC_NFLASH_DATA) & 0xFF;
+ }
+
+ b47n->curr_column = 0;
+ break;
+ default:
+ pr_err("Command 0x%X unsupported\n", command);
+ break;
+ }
+ b47n->curr_command = command;
+}
+
+static u8 bcm47xxnflash_ops_bcm4706_read_byte(struct mtd_info *mtd)
+{
+ struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv;
+ struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv;
+
+ switch (b47n->curr_command) {
+ case NAND_CMD_READID:
+ if (b47n->curr_column >= ARRAY_SIZE(b47n->id_data)) {
+ pr_err("Requested invalid id_data: %d\n",
+ b47n->curr_column);
+ return 0;
+ }
+ return b47n->id_data[b47n->curr_column++];
+ }
+
+ pr_err("Invalid command for byte read: 0x%X\n", b47n->curr_command);
+ return 0;
+}
+
/**************************************************
* Init
**************************************************/
@@ -52,6 +140,8 @@ int bcm47xxnflash_ops_bcm4706_init(struct bcm47xxnflash *b47n)
u32 val;
b47n->nand_chip.select_chip = bcm47xxnflash_ops_bcm4706_select_chip;
+ b47n->nand_chip.cmdfunc = bcm47xxnflash_ops_bcm4706_cmdfunc;
+ b47n->nand_chip.read_byte = bcm47xxnflash_ops_bcm4706_read_byte;
b47n->nand_chip.ecc.mode = NAND_ECC_SOFT; /* TODO: implement ECC */
/* Enable NAND flash access */
--
1.7.7
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 4/4] mtd: bcm47xxnflash: implement reading
2012-09-12 20:21 [PATCH 1/4] mtd: prepare place for BCMA NAND flash driver(s) Rafał Miłecki
2012-09-12 20:21 ` [PATCH 2/4] mtd: bcm47xxnflash: init NAND on BCM4706 Rafał Miłecki
2012-09-12 20:21 ` [PATCH 3/4] mtd: bcm47xxnflash: support for NAND_CMD_READID command Rafał Miłecki
@ 2012-09-12 20:21 ` Rafał Miłecki
2012-09-26 7:39 ` [PATCH 1/4] mtd: prepare place for BCMA NAND flash driver(s) Artem Bityutskiy
2012-09-26 7:41 ` Artem Bityutskiy
4 siblings, 0 replies; 8+ messages in thread
From: Rafał Miłecki @ 2012-09-12 20:21 UTC (permalink / raw)
To: linux-mtd, Artem Bityutskiy; +Cc: Rafał Miłecki
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
---
drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h | 1 +
drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c | 106 ++++++++++++++++++++++++
2 files changed, 107 insertions(+), 0 deletions(-)
diff --git a/drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h b/drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h
index 53fb2ea..e1cfdc5 100644
--- a/drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h
+++ b/drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h
@@ -11,6 +11,7 @@ struct bcm47xxnflash {
struct mtd_info mtd;
unsigned curr_command;
+ int curr_page_addr;
int curr_column;
u8 id_data[8];
diff --git a/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c b/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c
index e86670b..ca3eaf0 100644
--- a/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c
+++ b/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c
@@ -20,6 +20,8 @@
* shown 164 retries as maxiumum. */
#define NFLASH_READY_RETRIES 1000
+#define NFLASH_SECTOR_SIZE 512
+
/**************************************************
* Various helpers
**************************************************/
@@ -47,6 +49,80 @@ static int bcm47xxnflash_ops_bcm4706_ctl_cmd(struct bcma_drv_cc *cc, u32 code)
return 0;
}
+static int bcm47xxnflash_ops_bcm4706_poll(struct bcma_drv_cc *cc)
+{
+ int i;
+
+ for (i = 0; i < NFLASH_READY_RETRIES; i++) {
+ if (bcma_cc_read32(cc, BCMA_CC_NFLASH_CTL) & 0x04000000) {
+ if (bcma_cc_read32(cc, BCMA_CC_NFLASH_CTL) &
+ BCMA_CC_NFLASH_CTL_ERR) {
+ pr_err("Error on polling\n");
+ return -EBUSY;
+ } else {
+ return 0;
+ }
+ }
+ }
+
+ pr_err("Polling timeout!\n");
+ return -EBUSY;
+}
+
+/**************************************************
+ * R/W
+ **************************************************/
+
+static void bcm47xxnflash_ops_bcm4706_read(struct mtd_info *mtd, uint8_t *buf,
+ int len)
+{
+ struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv;
+ struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv;
+
+ u32 ctlcode;
+ u32 *dest = (u32 *)buf;
+ int i;
+ int toread;
+
+ BUG_ON(b47n->curr_page_addr & ~nand_chip->pagemask);
+ /* Don't validate column using nand_chip->page_shift, it may be bigger
+ * when accessing OOB */
+
+ while (len) {
+ /* We can read maximum of 0x200 bytes at once */
+ toread = min(len, 0x200);
+
+ /* Set page and column */
+ bcma_cc_write32(b47n->cc, BCMA_CC_NFLASH_COL_ADDR,
+ b47n->curr_column);
+ bcma_cc_write32(b47n->cc, BCMA_CC_NFLASH_ROW_ADDR,
+ b47n->curr_page_addr);
+
+ /* Prepare to read */
+ ctlcode = 0x40000000 | 0x00080000 | 0x00040000 | 0x00020000 |
+ 0x00010000;
+ ctlcode |= NAND_CMD_READSTART << 8;
+ if (bcm47xxnflash_ops_bcm4706_ctl_cmd(b47n->cc, ctlcode))
+ return;
+ if (bcm47xxnflash_ops_bcm4706_poll(b47n->cc))
+ return;
+
+ /* Eventually read some data :) */
+ for (i = 0; i < toread; i += 4, dest++) {
+ ctlcode = 0x40000000 | 0x30000000 | 0x00100000;
+ if (i == toread - 4) /* Last read goes without that */
+ ctlcode &= ~0x40000000;
+ if (bcm47xxnflash_ops_bcm4706_ctl_cmd(b47n->cc,
+ ctlcode))
+ return;
+ *dest = bcma_cc_read32(b47n->cc, BCMA_CC_NFLASH_DATA);
+ }
+
+ b47n->curr_column += toread;
+ len -= toread;
+ }
+}
+
/**************************************************
* NAND chip ops
**************************************************/
@@ -97,6 +173,14 @@ static void bcm47xxnflash_ops_bcm4706_cmdfunc(struct mtd_info *mtd,
b47n->curr_column = 0;
break;
+ case NAND_CMD_READ0:
+ b47n->curr_page_addr = page_addr;
+ b47n->curr_column = column;
+ break;
+ case NAND_CMD_READOOB:
+ b47n->curr_page_addr = page_addr;
+ b47n->curr_column = mtd->writesize + column;
+ break;
default:
pr_err("Command 0x%X unsupported\n", command);
break;
@@ -108,6 +192,7 @@ static u8 bcm47xxnflash_ops_bcm4706_read_byte(struct mtd_info *mtd)
{
struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv;
struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv;
+ u32 tmp = 0;
switch (b47n->curr_command) {
case NAND_CMD_READID:
@@ -117,12 +202,31 @@ static u8 bcm47xxnflash_ops_bcm4706_read_byte(struct mtd_info *mtd)
return 0;
}
return b47n->id_data[b47n->curr_column++];
+ case NAND_CMD_READOOB:
+ bcm47xxnflash_ops_bcm4706_read(mtd, (u8 *)&tmp, 4);
+ return tmp & 0xFF;
}
pr_err("Invalid command for byte read: 0x%X\n", b47n->curr_command);
return 0;
}
+static void bcm47xxnflash_ops_bcm4706_read_buf(struct mtd_info *mtd,
+ uint8_t *buf, int len)
+{
+ struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv;
+ struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv;
+
+ switch (b47n->curr_command) {
+ case NAND_CMD_READ0:
+ case NAND_CMD_READOOB:
+ bcm47xxnflash_ops_bcm4706_read(mtd, buf, len);
+ return;
+ }
+
+ pr_err("Invalid command for buf read: 0x%X\n", b47n->curr_command);
+}
+
/**************************************************
* Init
**************************************************/
@@ -142,6 +246,8 @@ int bcm47xxnflash_ops_bcm4706_init(struct bcm47xxnflash *b47n)
b47n->nand_chip.select_chip = bcm47xxnflash_ops_bcm4706_select_chip;
b47n->nand_chip.cmdfunc = bcm47xxnflash_ops_bcm4706_cmdfunc;
b47n->nand_chip.read_byte = bcm47xxnflash_ops_bcm4706_read_byte;
+ b47n->nand_chip.read_buf = bcm47xxnflash_ops_bcm4706_read_buf;
+ b47n->nand_chip.bbt_options = NAND_BBT_USE_FLASH;
b47n->nand_chip.ecc.mode = NAND_ECC_SOFT; /* TODO: implement ECC */
/* Enable NAND flash access */
--
1.7.7
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 1/4] mtd: prepare place for BCMA NAND flash driver(s)
2012-09-12 20:21 [PATCH 1/4] mtd: prepare place for BCMA NAND flash driver(s) Rafał Miłecki
` (2 preceding siblings ...)
2012-09-12 20:21 ` [PATCH 4/4] mtd: bcm47xxnflash: implement reading Rafał Miłecki
@ 2012-09-26 7:39 ` Artem Bityutskiy
2012-09-26 7:41 ` Rafał Miłecki
2012-09-26 7:41 ` Artem Bityutskiy
4 siblings, 1 reply; 8+ messages in thread
From: Artem Bityutskiy @ 2012-09-26 7:39 UTC (permalink / raw)
To: Rafał Miłecki; +Cc: linux-mtd
[-- Attachment #1: Type: text/plain, Size: 808 bytes --]
On Wed, 2012-09-12 at 22:21 +0200, Rafał Miłecki wrote:
> +config MTD_NAND_BCM47XXNFLASH
> + tristate "Support for NAND flash on BCMA bus"
> + depends on BCMA_NFLASH && BROKEN
> + help
> + BCMA bus can have various flash memories attached, they are
> + registered by bcma as platform devices. This enables driver for
> + NAND flash memories.
Could we please merge only non-broken stuff upstream. I understand your
intentions to merge something non-working first with a promise to make
it working later, but I do not think this is an acceptable approach.
Why exactly you mark this one as broken? If it is R/O so far, and
reading works, and you tested it (how?), we can merge it I guess, just
make it clear that it is R/O in Kconfig help text.
--
Best Regards,
Artem Bityutskiy
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/4] mtd: prepare place for BCMA NAND flash driver(s)
2012-09-26 7:39 ` [PATCH 1/4] mtd: prepare place for BCMA NAND flash driver(s) Artem Bityutskiy
@ 2012-09-26 7:41 ` Rafał Miłecki
2012-09-26 7:43 ` Artem Bityutskiy
0 siblings, 1 reply; 8+ messages in thread
From: Rafał Miłecki @ 2012-09-26 7:41 UTC (permalink / raw)
To: dedekind1; +Cc: linux-mtd
2012/9/26 Artem Bityutskiy <dedekind1@gmail.com>:
> On Wed, 2012-09-12 at 22:21 +0200, Rafał Miłecki wrote:
>> +config MTD_NAND_BCM47XXNFLASH
>> + tristate "Support for NAND flash on BCMA bus"
>> + depends on BCMA_NFLASH && BROKEN
>> + help
>> + BCMA bus can have various flash memories attached, they are
>> + registered by bcma as platform devices. This enables driver for
>> + NAND flash memories.
>
> Could we please merge only non-broken stuff upstream. I understand your
> intentions to merge something non-working first with a promise to make
> it working later, but I do not think this is an acceptable approach.
>
> Why exactly you mark this one as broken? If it is R/O so far, and
> reading works, and you tested it (how?), we can merge it I guess, just
> make it clear that it is R/O in Kconfig help text.
Yes, BROKEN can be dropped from this. I'll resend correct patchset
after checking it with verify/aiaiai (i'm almost done! :) )
--
Rafał
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/4] mtd: prepare place for BCMA NAND flash driver(s)
2012-09-12 20:21 [PATCH 1/4] mtd: prepare place for BCMA NAND flash driver(s) Rafał Miłecki
` (3 preceding siblings ...)
2012-09-26 7:39 ` [PATCH 1/4] mtd: prepare place for BCMA NAND flash driver(s) Artem Bityutskiy
@ 2012-09-26 7:41 ` Artem Bityutskiy
4 siblings, 0 replies; 8+ messages in thread
From: Artem Bityutskiy @ 2012-09-26 7:41 UTC (permalink / raw)
To: Rafał Miłecki; +Cc: linux-mtd
[-- Attachment #1: Type: text/plain, Size: 545 bytes --]
On Wed, 2012-09-12 at 22:21 +0200, Rafał Miłecki wrote:
> BCMA bus can contain NAND flash memory, it's registered in system as
> platform device. This adds required hooks and place for controler
> specific drivers.
> At this point it doesn't work yet, so it's marked as BROKEN.
>
> Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
If you send the next version of this, would you please base it on
l2-mtd.git tree, to make my job simpler, because otherwise I have to
solve small conflicts.
--
Best Regards,
Artem Bityutskiy
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/4] mtd: prepare place for BCMA NAND flash driver(s)
2012-09-26 7:41 ` Rafał Miłecki
@ 2012-09-26 7:43 ` Artem Bityutskiy
0 siblings, 0 replies; 8+ messages in thread
From: Artem Bityutskiy @ 2012-09-26 7:43 UTC (permalink / raw)
To: Rafał Miłecki; +Cc: linux-mtd
[-- Attachment #1: Type: text/plain, Size: 1215 bytes --]
On Wed, 2012-09-26 at 09:41 +0200, Rafał Miłecki wrote:
> 2012/9/26 Artem Bityutskiy <dedekind1@gmail.com>:
> > On Wed, 2012-09-12 at 22:21 +0200, Rafał Miłecki wrote:
> >> +config MTD_NAND_BCM47XXNFLASH
> >> + tristate "Support for NAND flash on BCMA bus"
> >> + depends on BCMA_NFLASH && BROKEN
> >> + help
> >> + BCMA bus can have various flash memories attached, they are
> >> + registered by bcma as platform devices. This enables driver for
> >> + NAND flash memories.
> >
> > Could we please merge only non-broken stuff upstream. I understand your
> > intentions to merge something non-working first with a promise to make
> > it working later, but I do not think this is an acceptable approach.
> >
> > Why exactly you mark this one as broken? If it is R/O so far, and
> > reading works, and you tested it (how?), we can merge it I guess, just
> > make it clear that it is R/O in Kconfig help text.
>
> Yes, BROKEN can be dropped from this. I'll resend correct patchset
> after checking it with verify/aiaiai (i'm almost done! :) )
Great, thanks. Do not forget to tell about R/O in the Kconfig text
please!
--
Best Regards,
Artem Bityutskiy
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2012-09-26 7:43 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-09-12 20:21 [PATCH 1/4] mtd: prepare place for BCMA NAND flash driver(s) Rafał Miłecki
2012-09-12 20:21 ` [PATCH 2/4] mtd: bcm47xxnflash: init NAND on BCM4706 Rafał Miłecki
2012-09-12 20:21 ` [PATCH 3/4] mtd: bcm47xxnflash: support for NAND_CMD_READID command Rafał Miłecki
2012-09-12 20:21 ` [PATCH 4/4] mtd: bcm47xxnflash: implement reading Rafał Miłecki
2012-09-26 7:39 ` [PATCH 1/4] mtd: prepare place for BCMA NAND flash driver(s) Artem Bityutskiy
2012-09-26 7:41 ` Rafał Miłecki
2012-09-26 7:43 ` Artem Bityutskiy
2012-09-26 7:41 ` Artem Bityutskiy
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).