|
@@ -27,6 +27,8 @@
|
|
|
#include <linux/mtd/partitions.h>
|
|
|
#include <linux/types.h>
|
|
|
#include <linux/i2c/pcf857x.h>
|
|
|
+#include <linux/mtd/nand.h>
|
|
|
+#include <linux/mtd/physmap.h>
|
|
|
|
|
|
#include <asm/setup.h>
|
|
|
#include <asm/mach-types.h>
|
|
@@ -529,6 +531,154 @@ static void __init balloon3_i2c_init(void)
|
|
|
static inline void balloon3_i2c_init(void) {}
|
|
|
#endif
|
|
|
|
|
|
+/******************************************************************************
|
|
|
+ * NAND
|
|
|
+ ******************************************************************************/
|
|
|
+#if defined(CONFIG_MTD_NAND_PLATFORM)||defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
|
|
|
+static uint16_t balloon3_ctl =
|
|
|
+ BALLOON3_NAND_CONTROL_FLCE0 | BALLOON3_NAND_CONTROL_FLCE1 |
|
|
|
+ BALLOON3_NAND_CONTROL_FLCE2 | BALLOON3_NAND_CONTROL_FLCE3 |
|
|
|
+ BALLOON3_NAND_CONTROL_FLWP;
|
|
|
+
|
|
|
+static void balloon3_nand_cmd_ctl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
|
|
|
+{
|
|
|
+ struct nand_chip *this = mtd->priv;
|
|
|
+
|
|
|
+ if (ctrl & NAND_CTRL_CHANGE) {
|
|
|
+ if (ctrl & NAND_CLE)
|
|
|
+ balloon3_ctl |= BALLOON3_NAND_CONTROL_FLCLE;
|
|
|
+ else
|
|
|
+ balloon3_ctl &= ~BALLOON3_NAND_CONTROL_FLCLE;
|
|
|
+
|
|
|
+ if (ctrl & NAND_ALE)
|
|
|
+ balloon3_ctl |= BALLOON3_NAND_CONTROL_FLALE;
|
|
|
+ else
|
|
|
+ balloon3_ctl &= ~BALLOON3_NAND_CONTROL_FLALE;
|
|
|
+
|
|
|
+ __raw_writel(balloon3_ctl, BALLOON3_NAND_CONTROL_REG);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (cmd != NAND_CMD_NONE)
|
|
|
+ writeb(cmd, this->IO_ADDR_W);
|
|
|
+}
|
|
|
+
|
|
|
+static void balloon3_nand_select_chip(struct mtd_info *mtd, int chip)
|
|
|
+{
|
|
|
+ if (chip < 0 || chip > 3)
|
|
|
+ return;
|
|
|
+
|
|
|
+ balloon3_ctl |= BALLOON3_NAND_CONTROL_FLCE0 |
|
|
|
+ BALLOON3_NAND_CONTROL_FLCE1 |
|
|
|
+ BALLOON3_NAND_CONTROL_FLCE2 |
|
|
|
+ BALLOON3_NAND_CONTROL_FLCE3;
|
|
|
+
|
|
|
+ /* Deassert correct nCE line */
|
|
|
+ balloon3_ctl &= ~(BALLOON3_NAND_CONTROL_FLCE0 << chip);
|
|
|
+
|
|
|
+ __raw_writew(balloon3_ctl, BALLOON3_NAND_CONTROL_REG);
|
|
|
+}
|
|
|
+
|
|
|
+static int balloon3_nand_probe(struct platform_device *pdev)
|
|
|
+{
|
|
|
+ void __iomem *temp_map;
|
|
|
+ uint16_t ver;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ __raw_writew(BALLOON3_NAND_CONTROL2_16BIT, BALLOON3_NAND_CONTROL2_REG);
|
|
|
+
|
|
|
+ ver = __raw_readw(BALLOON3_FPGA_VER);
|
|
|
+ if (ver > 0x0201)
|
|
|
+ pr_warn("The FPGA code, version 0x%04x, is newer than rel-0.3. "
|
|
|
+ "NAND support might be broken in this version!", ver);
|
|
|
+
|
|
|
+ /* Power up the NAND chips */
|
|
|
+ ret = gpio_request(BALLOON3_GPIO_RUN_NAND, "NAND");
|
|
|
+ if (ret)
|
|
|
+ goto err1;
|
|
|
+
|
|
|
+ ret = gpio_direction_output(BALLOON3_GPIO_RUN_NAND, 1);
|
|
|
+ if (ret)
|
|
|
+ goto err2;
|
|
|
+
|
|
|
+ gpio_set_value(BALLOON3_GPIO_RUN_NAND, 1);
|
|
|
+
|
|
|
+ /* Deassert all nCE lines and write protect line */
|
|
|
+ __raw_writel(balloon3_ctl, BALLOON3_NAND_CONTROL_REG);
|
|
|
+ return 0;
|
|
|
+
|
|
|
+err2:
|
|
|
+ gpio_free(BALLOON3_GPIO_RUN_NAND);
|
|
|
+err1:
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+static void balloon3_nand_remove(struct platform_device *pdev)
|
|
|
+{
|
|
|
+ /* Power down the NAND chips */
|
|
|
+ gpio_set_value(BALLOON3_GPIO_RUN_NAND, 0);
|
|
|
+ gpio_free(BALLOON3_GPIO_RUN_NAND);
|
|
|
+}
|
|
|
+
|
|
|
+static struct mtd_partition balloon3_partition_info[] = {
|
|
|
+ [0] = {
|
|
|
+ .name = "Boot",
|
|
|
+ .offset = 0,
|
|
|
+ .size = SZ_4M,
|
|
|
+ },
|
|
|
+ [1] = {
|
|
|
+ .name = "RootFS",
|
|
|
+ .offset = MTDPART_OFS_APPEND,
|
|
|
+ .size = MTDPART_SIZ_FULL
|
|
|
+ },
|
|
|
+};
|
|
|
+
|
|
|
+static const char *balloon3_part_probes[] = { "cmdlinepart", NULL };
|
|
|
+
|
|
|
+struct platform_nand_data balloon3_nand_pdata = {
|
|
|
+ .chip = {
|
|
|
+ .nr_chips = 4,
|
|
|
+ .chip_offset = 0,
|
|
|
+ .nr_partitions = ARRAY_SIZE(balloon3_partition_info),
|
|
|
+ .partitions = balloon3_partition_info,
|
|
|
+ .chip_delay = 50,
|
|
|
+ .part_probe_types = balloon3_part_probes,
|
|
|
+ },
|
|
|
+ .ctrl = {
|
|
|
+ .hwcontrol = 0,
|
|
|
+ .dev_ready = 0,
|
|
|
+ .select_chip = balloon3_nand_select_chip,
|
|
|
+ .cmd_ctrl = balloon3_nand_cmd_ctl,
|
|
|
+ .probe = balloon3_nand_probe,
|
|
|
+ .remove = balloon3_nand_remove,
|
|
|
+ },
|
|
|
+};
|
|
|
+
|
|
|
+static struct resource balloon3_nand_resource[] = {
|
|
|
+ [0] = {
|
|
|
+ .start = BALLOON3_NAND_BASE,
|
|
|
+ .end = BALLOON3_NAND_BASE + 0x4,
|
|
|
+ .flags = IORESOURCE_MEM,
|
|
|
+ },
|
|
|
+};
|
|
|
+
|
|
|
+static struct platform_device balloon3_nand = {
|
|
|
+ .name = "gen_nand",
|
|
|
+ .num_resources = ARRAY_SIZE(balloon3_nand_resource),
|
|
|
+ .resource = balloon3_nand_resource,
|
|
|
+ .id = -1,
|
|
|
+ .dev = {
|
|
|
+ .platform_data = &balloon3_nand_pdata,
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+static void __init balloon3_nand_init(void)
|
|
|
+{
|
|
|
+ platform_device_register(&balloon3_nand);
|
|
|
+}
|
|
|
+#else
|
|
|
+static inline void balloon3_nand_init(void) {}
|
|
|
+#endif
|
|
|
+
|
|
|
/******************************************************************************
|
|
|
* Machine init
|
|
|
******************************************************************************/
|
|
@@ -547,6 +697,7 @@ static void __init balloon3_init(void)
|
|
|
balloon3_lcd_init();
|
|
|
balloon3_leds_init();
|
|
|
balloon3_mmc_init();
|
|
|
+ balloon3_nand_init();
|
|
|
balloon3_nor_init();
|
|
|
balloon3_ts_init();
|
|
|
balloon3_udc_init();
|