Message ID | BD79186B4FD85F4B8E60E381CAEE190901DB7967@mi8nycmail19.Mi8.com |
---|---|
State | New, archived |
Headers | show |
Hi, In gmane.linux.drivers.mtd H Hartley Sweeten <hartleys@visionengravers.com> wrote: > > Update the ts72xx platform's nand driver support. > > This changes the ts72xx platform from using a custom nand driver > (ts7250.c) to the generic platform nand driver (plat_nand.c). > > Tested on TS-7250 with 32MB NAND. > > [snipped] > > +static const char *ts72xx_nand_part_probes[] = { "cmdlinepart", NULL }; > + > +#define TS72XX_BOOTROM_PART_SIZE (SZ_16K) > +#define TS72XX_REDBOOT_PART_SIZE (SZ_2M + SZ_1M) > + > +static struct mtd_partition ts72xx_part_info32[] = { > { > - .virtual = TS72XX_NAND_DATA_VIRT_BASE, > - .pfn = __phys_to_pfn(TS72XX_NAND1_DATA_PHYS_BASE), > - .length = TS72XX_NAND_DATA_SIZE, > - .type = MT_DEVICE, > + .name = "TS-BOOTROM", > + .offset = 0, > + .size = TS72XX_BOOTROM_PART_SIZE, > }, { > - .virtual = TS72XX_NAND_CONTROL_VIRT_BASE, > - .pfn = __phys_to_pfn(TS72XX_NAND1_CONTROL_PHYS_BASE), > - .length = TS72XX_NAND_CONTROL_SIZE, > - .type = MT_DEVICE, > + .name = "Linux", > + .offset = MTDPART_OFS_APPEND, > + .size = SZ_32M - TS72XX_REDBOOT_PART_SIZE, > }, { > - .virtual = TS72XX_NAND_BUSY_VIRT_BASE, > - .pfn = __phys_to_pfn(TS72XX_NAND1_BUSY_PHYS_BASE), > - .length = TS72XX_NAND_BUSY_SIZE, > - .type = MT_DEVICE, > - } > + .name = "RedBoot", > + .offset = MTDPART_OFS_APPEND, > + .size = MTDPART_SIZ_FULL, > + }, > }; > > -static struct map_desc ts72xx_alternate_nand_io_desc[] __initdata = { > +static struct mtd_partition ts72xx_part_info128[] = { > { > - .virtual = TS72XX_NAND_DATA_VIRT_BASE, > - .pfn = __phys_to_pfn(TS72XX_NAND2_DATA_PHYS_BASE), > - .length = TS72XX_NAND_DATA_SIZE, > - .type = MT_DEVICE, > + .name = "TS-BOOTROM", > + .offset = 0, > + .size = TS72XX_BOOTROM_PART_SIZE, > }, { > - .virtual = TS72XX_NAND_CONTROL_VIRT_BASE, > - .pfn = __phys_to_pfn(TS72XX_NAND2_CONTROL_PHYS_BASE), > - .length = TS72XX_NAND_CONTROL_SIZE, > - .type = MT_DEVICE, > + .name = "Linux", > + .offset = MTDPART_OFS_APPEND, > + .size = SZ_128M - TS72XX_REDBOOT_PART_SIZE, > }, { > - .virtual = TS72XX_NAND_BUSY_VIRT_BASE, > - .pfn = __phys_to_pfn(TS72XX_NAND2_BUSY_PHYS_BASE), > - .length = TS72XX_NAND_BUSY_SIZE, > - .type = MT_DEVICE, > - } > + .name = "RedBoot", > + .offset = MTDPART_OFS_APPEND, > + .size = MTDPART_SIZ_FULL, > + }, > }; > These struct's are almost identical so could you not... > -static void __init ts72xx_map_io(void) > +static void ts72xx_nand_set_parts(uint64_t size, > + struct platform_nand_chip *chip) > { > - ep93xx_map_io(); > - iotable_init(ts72xx_io_desc, ARRAY_SIZE(ts72xx_io_desc)); > - > - /* > - * The TS-7200 has NOR flash, the other models have NAND flash. > - */ > - if (!board_is_ts7200()) { > - if (is_ts9420_installed()) { > - iotable_init(ts72xx_alternate_nand_io_desc, > - ARRAY_SIZE(ts72xx_alternate_nand_io_desc)); > - } else { > - iotable_init(ts72xx_nand_io_desc, > - ARRAY_SIZE(ts72xx_nand_io_desc)); > - } > + switch (size) { > + case SZ_32M: > + chip->partitions = ts72xx_part_info32; > + chip->nr_partitions = ARRAY_SIZE(ts72xx_part_info32); > + break; > + case SZ_128M: > + chip->partitions = ts72xx_part_info128; > + chip->nr_partitions = ARRAY_SIZE(ts72xx_part_info128); > + break; > + default: > + pr_warning("ts72xx: Unknown nand disk size:%lluMB\n", size >> 20); > + break; > } > } > ----------- static struct mtd_partition ts72xx_part_info[] = { { /* gut feeling for *Joe Public* is to go MTD_WRITABLE */ .name = "TS-BOOTROM", .offset = 0, .size = TS72XX_BOOTROM_PART_SIZE, }, { .name = "Linux", .offset = MTDPART_OFS_APPEND, /* to be filled in later */ .size = 0, }, { /* mask MTD_WRITABLE here too? */ .name = "Redboot", .offset = MTDPART_OFS_APPEND, .size = MTDPART_SIZ_FULL, } }; static void ts72xx_nand_set_parts(....) { .... /* or I guess you could just bailout... */ if (size != SZ_32M && size != SZ_128M) pr_warning("ts72xx: Unknown nand disk size:%lluMB\n", size >> 20); chip->partitions = ts72xx_part_info; chip->nr_partitions = ARRAY_SIZE(ts72xx_part_info); ts72xx_part_info[1].size = size - TS72XX_REDBOOT_PART_SIZE; } --------- Cheers
On Wednesday, October 07, 2009 1:16 AM, Alexander Clouter wrote: > Hi, [snip] > These struct's are almost identical so could you not... [snip] > ----------- > static struct mtd_partition ts72xx_part_info[] = { > { > /* gut feeling for *Joe Public* is to go MTD_WRITABLE */ > .name = "TS-BOOTROM", > .offset = 0, > .size = TS72XX_BOOTROM_PART_SIZE, > }, { > .name = "Linux", > .offset = MTDPART_OFS_APPEND, > /* to be filled in later */ > .size = 0, > }, { > /* mask MTD_WRITABLE here too? */ > .name = "Redboot", > .offset = MTDPART_OFS_APPEND, > .size = MTDPART_SIZ_FULL, > } > }; > > static void ts72xx_nand_set_parts(....) > { > .... > > /* or I guess you could just bailout... */ > if (size != SZ_32M && size != SZ_128M) > pr_warning("ts72xx: Unknown nand disk size:%lluMB\n", size >> 20); > > chip->partitions = ts72xx_part_info; > chip->nr_partitions = ARRAY_SIZE(ts72xx_part_info); > > ts72xx_part_info[1].size = size - TS72XX_REDBOOT_PART_SIZE; > } Thanks for pointing that out. I like your change and will modify the patch. I didn't think about making the "TS-BOOTROM" and "RedBoot" partitions read-only. Probably a good idea, I'll add that also. Updated patch coming soon. Regards, Hartley
On Tue, 2009-10-06 at 18:19 -0400, H Hartley Sweeten wrote: > Update the ts72xx platform's nand driver support. > > This changes the ts72xx platform from using a custom nand driver > (ts7250.c) to the generic platform nand driver (plat_nand.c). > > Tested on TS-7250 with 32MB NAND. > > Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com> > Tested-by: Matthieu Crapet <mcrapet@gmail.com> > Cc: David Woodhouse <dwmw2@infradead.org> > Cc: <linux-arm-kernel@lists.infradead.org> > Cc: <linux-mtd@lists.infradead.org> Patches do not apply cleanly to current mtd tree. Please, refresh and resend.
On Sunday, October 11, 2009 4:30 AM, Artem Bityutskiy wrote: > On Tue, 2009-10-06 at 18:19 -0400, H Hartley Sweeten wrote: >> Update the ts72xx platform's nand driver support. >> >> This changes the ts72xx platform from using a custom nand driver >> (ts7250.c) to the generic platform nand driver (plat_nand.c). >> >> Tested on TS-7250 with 32MB NAND. >> >> Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com> >> Tested-by: Matthieu Crapet <mcrapet@gmail.com> >> Cc: David Woodhouse <dwmw2@infradead.org> >> Cc: <linux-arm-kernel@lists.infradead.org> >> Cc: <linux-mtd@lists.infradead.org> > > Patches do not apply cleanly to current mtd tree. Please, refresh > and resend. Strange. The original file in the mtd tree is identical to the one in the 2.6.32-rc3 tree. What was the problem with the patch? I will rebase it on the mtd tree anyway and repost with a diffstat. Regards, Hartley
diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c index 259f782..bbb757b 100644 --- a/arch/arm/mach-ep93xx/ts72xx.c +++ b/arch/arm/mach-ep93xx/ts72xx.c @@ -16,6 +16,8 @@ #include <linux/io.h> #include <linux/m48t86.h> #include <linux/mtd/physmap.h> +#include <linux/mtd/nand.h> +#include <linux/mtd/partitions.h> #include <mach/hardware.h> #include <mach/ts72xx.h> @@ -54,92 +56,185 @@ static struct map_desc ts72xx_io_desc[] __initdata = { } }; -static struct map_desc ts72xx_nand_io_desc[] __initdata = { +static void __init ts72xx_map_io(void) +{ + ep93xx_map_io(); + iotable_init(ts72xx_io_desc, ARRAY_SIZE(ts72xx_io_desc)); +} + + +/************************************************************************* + * NAND flash + *************************************************************************/ +#define TS72XX_NAND_CONTROL_ADDR_LINE 22 /* 0xN0400000 */ +#define TS72XX_NAND_BUSY_ADDR_LINE 23 /* 0xN0800000 */ + +static void ts72xx_nand_hwcontrol(struct mtd_info *mtd, + int cmd, unsigned int ctrl) +{ + struct nand_chip *chip = mtd->priv; + + if (ctrl & NAND_CTRL_CHANGE) { + void __iomem *addr = chip->IO_ADDR_R; + unsigned char bits; + + addr += (1 << TS72XX_NAND_CONTROL_ADDR_LINE); + + bits = (ctrl & NAND_NCE) << 2; /* bit 0 -> bit 2 */ + bits |= ctrl & NAND_CLE; /* bit 1 -> bit 1 */ + bits |= (ctrl & NAND_ALE) >> 2; /* bit 2 -> bit 0 */ + + __raw_writeb((__raw_readb(addr) & ~0x7) | bits, addr); + } + + if (cmd != NAND_CMD_NONE) + __raw_writeb(cmd, chip->IO_ADDR_W); +} + +static int ts72xx_nand_device_ready(struct mtd_info *mtd) +{ + struct nand_chip *chip = mtd->priv; + void __iomem *addr = chip->IO_ADDR_R; + + addr += (1 << TS72XX_NAND_BUSY_ADDR_LINE); + + return __raw_readb(addr) & 0x20; +} + +static const char *ts72xx_nand_part_probes[] = { "cmdlinepart", NULL }; + +#define TS72XX_BOOTROM_PART_SIZE (SZ_16K) +#define TS72XX_REDBOOT_PART_SIZE (SZ_2M + SZ_1M) + +static struct mtd_partition ts72xx_part_info32[] = { { - .virtual = TS72XX_NAND_DATA_VIRT_BASE, - .pfn = __phys_to_pfn(TS72XX_NAND1_DATA_PHYS_BASE), - .length = TS72XX_NAND_DATA_SIZE, - .type = MT_DEVICE, + .name = "TS-BOOTROM", + .offset = 0, + .size = TS72XX_BOOTROM_PART_SIZE, }, { - .virtual = TS72XX_NAND_CONTROL_VIRT_BASE, - .pfn = __phys_to_pfn(TS72XX_NAND1_CONTROL_PHYS_BASE), - .length = TS72XX_NAND_CONTROL_SIZE, - .type = MT_DEVICE, + .name = "Linux", + .offset = MTDPART_OFS_APPEND, + .size = SZ_32M - TS72XX_REDBOOT_PART_SIZE, }, { - .virtual = TS72XX_NAND_BUSY_VIRT_BASE, - .pfn = __phys_to_pfn(TS72XX_NAND1_BUSY_PHYS_BASE), - .length = TS72XX_NAND_BUSY_SIZE, - .type = MT_DEVICE, - } + .name = "RedBoot", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + }, }; -static struct map_desc ts72xx_alternate_nand_io_desc[] __initdata = { +static struct mtd_partition ts72xx_part_info128[] = { { - .virtual = TS72XX_NAND_DATA_VIRT_BASE, - .pfn = __phys_to_pfn(TS72XX_NAND2_DATA_PHYS_BASE), - .length = TS72XX_NAND_DATA_SIZE, - .type = MT_DEVICE, + .name = "TS-BOOTROM", + .offset = 0, + .size = TS72XX_BOOTROM_PART_SIZE, }, { - .virtual = TS72XX_NAND_CONTROL_VIRT_BASE, - .pfn = __phys_to_pfn(TS72XX_NAND2_CONTROL_PHYS_BASE), - .length = TS72XX_NAND_CONTROL_SIZE, - .type = MT_DEVICE, + .name = "Linux", + .offset = MTDPART_OFS_APPEND, + .size = SZ_128M - TS72XX_REDBOOT_PART_SIZE, }, { - .virtual = TS72XX_NAND_BUSY_VIRT_BASE, - .pfn = __phys_to_pfn(TS72XX_NAND2_BUSY_PHYS_BASE), - .length = TS72XX_NAND_BUSY_SIZE, - .type = MT_DEVICE, - } + .name = "RedBoot", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + }, }; -static void __init ts72xx_map_io(void) +static void ts72xx_nand_set_parts(uint64_t size, + struct platform_nand_chip *chip) { - ep93xx_map_io(); - iotable_init(ts72xx_io_desc, ARRAY_SIZE(ts72xx_io_desc)); - - /* - * The TS-7200 has NOR flash, the other models have NAND flash. - */ - if (!board_is_ts7200()) { - if (is_ts9420_installed()) { - iotable_init(ts72xx_alternate_nand_io_desc, - ARRAY_SIZE(ts72xx_alternate_nand_io_desc)); - } else { - iotable_init(ts72xx_nand_io_desc, - ARRAY_SIZE(ts72xx_nand_io_desc)); - } + switch (size) { + case SZ_32M: + chip->partitions = ts72xx_part_info32; + chip->nr_partitions = ARRAY_SIZE(ts72xx_part_info32); + break; + case SZ_128M: + chip->partitions = ts72xx_part_info128; + chip->nr_partitions = ARRAY_SIZE(ts72xx_part_info128); + break; + default: + pr_warning("ts72xx: Unknown nand disk size:%lluMB\n", size >> 20); + break; } } +static struct platform_nand_data ts72xx_nand_data = { + .chip = { + .nr_chips = 1, + .chip_offset = 0, + .chip_delay = 15, + .part_probe_types = ts72xx_nand_part_probes, + .set_parts = ts72xx_nand_set_parts, + }, + .ctrl = { + .cmd_ctrl = ts72xx_nand_hwcontrol, + .dev_ready = ts72xx_nand_device_ready, + }, +}; + +static struct resource ts7250_nand_resource[] = { + { + .start = EP93XX_CS6_PHYS_BASE, + .end = EP93XX_CS6_PHYS_BASE + SZ_16M - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct resource ts9420_nand_resource[] = { + { + .start = EP93XX_CS7_PHYS_BASE, + .end = EP93XX_CS7_PHYS_BASE + SZ_16M - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device ts72xx_nand_flash = { + .name = "gen_nand", + .id = -1, + .dev.platform_data = &ts72xx_nand_data, +}; + + /************************************************************************* * NOR flash (TS-7200 only) *************************************************************************/ -static struct physmap_flash_data ts72xx_flash_data = { +static struct physmap_flash_data ts72xx_nor_data = { .width = 2, }; -static struct resource ts72xx_flash_resource = { +static struct resource ts72xx_nor_resource = { .start = EP93XX_CS6_PHYS_BASE, .end = EP93XX_CS6_PHYS_BASE + SZ_16M - 1, .flags = IORESOURCE_MEM, }; -static struct platform_device ts72xx_flash = { +static struct platform_device ts72xx_nor_flash = { .name = "physmap-flash", .id = 0, .dev = { - .platform_data = &ts72xx_flash_data, + .platform_data = &ts72xx_nor_data, }, .num_resources = 1, - .resource = &ts72xx_flash_resource, + .resource = &ts72xx_nor_resource, }; static void __init ts72xx_register_flash(void) { - if (board_is_ts7200()) - platform_device_register(&ts72xx_flash); + if (board_is_ts7200()) { + platform_device_register(&ts72xx_nor_flash); + } else { + if (is_ts9420_installed()) { + ts72xx_nand_flash.resource = ts9420_nand_resource; + ts72xx_nand_flash.num_resources = + ARRAY_SIZE(ts9420_nand_resource); + } else { + ts72xx_nand_flash.resource = ts7250_nand_resource; + ts72xx_nand_flash.num_resources = + ARRAY_SIZE(ts7250_nand_resource); + } + platform_device_register(&ts72xx_nand_flash); + } } + static unsigned char ts72xx_rtc_readbyte(unsigned long addr) { __raw_writeb(addr, TS72XX_RTC_INDEX_VIRT_BASE);