[ARM] pxa/balloon3: Add NAND driver

The NAND support is implemented through the gen_nand driver.

Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
This commit is contained in:
Marek Vasut 2010-07-28 03:32:05 +02:00 committed by Eric Miao
parent 02a453e4a5
commit e6a8ef5477
2 changed files with 176 additions and 3 deletions

View file

@ -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();

View file

@ -31,12 +31,15 @@ enum balloon3_features {
#define BALLOON3_CF_CONTROL_REG (BALLOON3_FPGA_VIRT + 0x00e00008)
/* FPGA / CPLD version register */
#define BALLOON3_FPGA_VER (BALLOON3_FPGA_VIRT + 0x00e0001c)
/* FPGA / CPLD registers for NAND flash */
#define BALLOON3_NAND_BASE (PXA_CS4_PHYS + 0x00e00000)
#define BALLOON3_NAND_IO_REG (BALLOON3_FPGA_VIRT + 0x00e00000)
#define BALLOON3_NAND_CONTROL2_REG (BALLOON3_FPGA_VIRT + 0x00e00010)
#define BALLOON3_NAND_STAT_REG (BALLOON3_FPGA_VIRT + 0x00e00010)
#define BALLOON3_NAND_CONTROL_REG (BALLOON3_FPGA_VIRT + 0x00e00014)
#define BALLOON3_NANDIO_IO_REG (BALLOON3_FPGA_VIRT + 0x00e00000)
/* fpga/cpld interrupt control register */
#define BALLOON3_INT_CONTROL_REG (BALLOON3_FPGA_VIRT + 0x00e0000C)
#define BALLOON3_NANDIO_CTL2_REG (BALLOON3_FPGA_VIRT + 0x00e00010)
#define BALLOON3_NANDIO_CTL_REG (BALLOON3_FPGA_VIRT + 0x00e00014)
#define BALLOON3_VERSION_REG (BALLOON3_FPGA_VIRT + 0x00e0001c)
#define BALLOON3_SAMOSA_ADDR_REG (BALLOON3_FPGA_VIRT + 0x00c00000)
@ -56,6 +59,22 @@ enum balloon3_features {
#define BALLOON3_BP_CF_NRDY_IRQ BALLOON3_IRQ(0)
#define BALLOON3_BP_NSTSCHG_IRQ BALLOON3_IRQ(1)
/* NAND Control register */
#define BALLOON3_NAND_CONTROL_FLWP (1 << 7)
#define BALLOON3_NAND_CONTROL_FLSE (1 << 6)
#define BALLOON3_NAND_CONTROL_FLCE3 (1 << 5)
#define BALLOON3_NAND_CONTROL_FLCE2 (1 << 4)
#define BALLOON3_NAND_CONTROL_FLCE1 (1 << 3)
#define BALLOON3_NAND_CONTROL_FLCE0 (1 << 2)
#define BALLOON3_NAND_CONTROL_FLALE (1 << 1)
#define BALLOON3_NAND_CONTROL_FLCLE (1 << 0)
/* NAND Status register */
#define BALLOON3_NAND_STAT_RNB (1 << 0)
/* NAND Control2 register */
#define BALLOON3_NAND_CONTROL2_16BIT (1 << 0)
/* GPIOs for irqs */
#define BALLOON3_GPIO_AUX_NIRQ (94)
#define BALLOON3_GPIO_CODEC_IRQ (95)
@ -69,6 +88,9 @@ enum balloon3_features {
#define BALLOON3_GPIO_S0_CD (105)
/* NAND */
#define BALLOON3_GPIO_RUN_NAND (102)
/* PCF8574A Leds */
#define BALLOON3_PCF_GPIO_BASE 160
#define BALLOON3_PCF_GPIO_LED0 (BALLOON3_PCF_GPIO_BASE + 0)