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