From 030d2dd450a628b7a8e31e980af3d05854f68edb Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Jan 2010 14:59:56 -0700 Subject: mtd: Update ep93xx/ts72xx to use generic platform nand driver 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 32MiB NAND. Signed-off-by: H Hartley Sweeten Tested-by: Matthieu Crapet Cc: Jesse Off Signed-off-by: David Woodhouse --- arch/arm/mach-ep93xx/ts72xx.c | 188 +++++++++++++++++++++++++++++------------- 1 file changed, 131 insertions(+), 57 deletions(-) (limited to 'arch/arm/mach-ep93xx') diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c index 259f7822ba52..47a86f07831d 100644 --- a/arch/arm/mach-ep93xx/ts72xx.c +++ b/arch/arm/mach-ep93xx/ts72xx.c @@ -10,12 +10,16 @@ * your option) any later version. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include #include #include #include +#include +#include #include #include @@ -54,92 +58,162 @@ static struct map_desc ts72xx_io_desc[] __initdata = { } }; -static struct map_desc ts72xx_nand_io_desc[] __initdata = { - { - .virtual = TS72XX_NAND_DATA_VIRT_BASE, - .pfn = __phys_to_pfn(TS72XX_NAND1_DATA_PHYS_BASE), - .length = TS72XX_NAND_DATA_SIZE, - .type = MT_DEVICE, - }, { - .virtual = TS72XX_NAND_CONTROL_VIRT_BASE, - .pfn = __phys_to_pfn(TS72XX_NAND1_CONTROL_PHYS_BASE), - .length = TS72XX_NAND_CONTROL_SIZE, - .type = MT_DEVICE, - }, { - .virtual = TS72XX_NAND_BUSY_VIRT_BASE, - .pfn = __phys_to_pfn(TS72XX_NAND1_BUSY_PHYS_BASE), - .length = TS72XX_NAND_BUSY_SIZE, - .type = MT_DEVICE, +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 = __raw_readb(addr) & ~0x07; + 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(bits, addr); } -}; -static struct map_desc ts72xx_alternate_nand_io_desc[] __initdata = { + 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_nand_parts[] = { { - .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, + .mask_flags = MTD_WRITEABLE, /* force read-only */ }, { - .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 = 0, /* filled in later */ }, { - .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, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, }; -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)); + /* Factory TS-72xx boards only come with 32MiB or 128MiB NAND options */ + if (size == SZ_32M || size == SZ_128M) { + /* Set the "Linux" partition size */ + ts72xx_nand_parts[1].size = size - TS72XX_REDBOOT_PART_SIZE; - /* - * 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)); - } + chip->partitions = ts72xx_nand_parts; + chip->nr_partitions = ARRAY_SIZE(ts72xx_nand_parts); + } else { + pr_warning("Unknown nand disk size:%lluMiB\n", size >> 20); } } +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 ts72xx_nand_resource[] = { + { + .start = 0, /* filled in later */ + .end = 0, /* filled in later */ + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device ts72xx_nand_flash = { + .name = "gen_nand", + .id = -1, + .dev.platform_data = &ts72xx_nand_data, + .resource = ts72xx_nand_resource, + .num_resources = ARRAY_SIZE(ts72xx_nand_resource), +}; + + /************************************************************************* * 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 = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &ts72xx_flash_data, - }, - .num_resources = 1, - .resource = &ts72xx_flash_resource, +static struct platform_device ts72xx_nor_flash = { + .name = "physmap-flash", + .id = 0, + .dev.platform_data = &ts72xx_nor_data, + .resource = &ts72xx_nor_resource, + .num_resources = 1, }; 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 { + resource_size_t start; + + if (is_ts9420_installed()) + start = EP93XX_CS7_PHYS_BASE; + else + start = EP93XX_CS6_PHYS_BASE; + + ts72xx_nand_resource[0].start = start; + ts72xx_nand_resource[0].end = start + SZ_16M - 1; + + platform_device_register(&ts72xx_nand_flash); + } } + static unsigned char ts72xx_rtc_readbyte(unsigned long addr) { __raw_writeb(addr, TS72XX_RTC_INDEX_VIRT_BASE); -- cgit v1.2.2 From 7603757993e7ce3e63b2280ccf61d8058b7b2414 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Jan 2010 14:59:58 -0700 Subject: mtd: Remove now-defunct ts7250 nand driver The ts72xx platform has been updated to use the generic platform nand driver (plat_nand.c). This removes the now-defunct ts7250.c nand driver. Signed-off-by: H Hartley Sweeten Cc: Matthieu Crapet Cc: Jesse Off Signed-off-by: David Woodhouse --- arch/arm/mach-ep93xx/include/mach/ts72xx.h | 19 ------------------- 1 file changed, 19 deletions(-) (limited to 'arch/arm/mach-ep93xx') diff --git a/arch/arm/mach-ep93xx/include/mach/ts72xx.h b/arch/arm/mach-ep93xx/include/mach/ts72xx.h index 3bd934e9a7f1..61c0e132c63e 100644 --- a/arch/arm/mach-ep93xx/include/mach/ts72xx.h +++ b/arch/arm/mach-ep93xx/include/mach/ts72xx.h @@ -9,9 +9,6 @@ * febff000 22000000 4K model number register * febfe000 22400000 4K options register * febfd000 22800000 4K options register #2 - * febfc000 [67]0000000 4K NAND data register - * febfb000 [67]0400000 4K NAND control register - * febfa000 [67]0800000 4K NAND busy register * febf9000 10800000 4K TS-5620 RTC index register * febf8000 11700000 4K TS-5620 RTC data register */ @@ -41,22 +38,6 @@ #define TS72XX_OPTIONS2_TS9420_BOOT 0x02 -#define TS72XX_NAND1_DATA_PHYS_BASE 0x60000000 -#define TS72XX_NAND2_DATA_PHYS_BASE 0x70000000 -#define TS72XX_NAND_DATA_VIRT_BASE 0xfebfc000 -#define TS72XX_NAND_DATA_SIZE 0x00001000 - -#define TS72XX_NAND1_CONTROL_PHYS_BASE 0x60400000 -#define TS72XX_NAND2_CONTROL_PHYS_BASE 0x70400000 -#define TS72XX_NAND_CONTROL_VIRT_BASE 0xfebfb000 -#define TS72XX_NAND_CONTROL_SIZE 0x00001000 - -#define TS72XX_NAND1_BUSY_PHYS_BASE 0x60800000 -#define TS72XX_NAND2_BUSY_PHYS_BASE 0x70800000 -#define TS72XX_NAND_BUSY_VIRT_BASE 0xfebfa000 -#define TS72XX_NAND_BUSY_SIZE 0x00001000 - - #define TS72XX_RTC_INDEX_VIRT_BASE 0xfebf9000 #define TS72XX_RTC_INDEX_PHYS_BASE 0x10800000 #define TS72XX_RTC_INDEX_SIZE 0x00001000 -- cgit v1.2.2 From b370e082e7c4bd47195b2ec117ceeadd9286d8c0 Mon Sep 17 00:00:00 2001 From: Hartley Sweeten Date: Thu, 18 Mar 2010 18:04:06 +0100 Subject: ARM: 5992/1: ep93xx: pass platform startup data as __initdata A number of the peripherals for the ep93xx are registered at startup using platform_data that is passed from the board init code to the core code. This data is then copied to a local static variable in the core code. Since the data is copied, the original data can be marked as __initdata and discarded after startup is complete. This adds the __initdata tag to all the appropriate data in the various ep93xx board init's. Specifically, all the struct ep93xx_eth_data, struct ep93xxfb_mach_info, and struct i2c_gpio_platform_data. Also, document the various registration functions and note what data should be marked as __initdata. While here, also cleanup a couple over zealous whitespace tabs. Signed-off-by: H Hartley Sweeten Acked-by: Ryan Mallon Signed-off-by: Russell King --- arch/arm/mach-ep93xx/adssphere.c | 2 +- arch/arm/mach-ep93xx/core.c | 57 +++++++++++++++++++++++++++++--------- arch/arm/mach-ep93xx/edb93xx.c | 4 +-- arch/arm/mach-ep93xx/gesbc9312.c | 2 +- arch/arm/mach-ep93xx/micro9.c | 2 +- arch/arm/mach-ep93xx/simone.c | 6 ++-- arch/arm/mach-ep93xx/snappercl15.c | 6 ++-- arch/arm/mach-ep93xx/ts72xx.c | 2 +- 8 files changed, 56 insertions(+), 25 deletions(-) (limited to 'arch/arm/mach-ep93xx') diff --git a/arch/arm/mach-ep93xx/adssphere.c b/arch/arm/mach-ep93xx/adssphere.c index caf6d5154aec..3a1a855bfdca 100644 --- a/arch/arm/mach-ep93xx/adssphere.c +++ b/arch/arm/mach-ep93xx/adssphere.c @@ -41,7 +41,7 @@ static struct platform_device adssphere_flash = { .resource = &adssphere_flash_resource, }; -static struct ep93xx_eth_data adssphere_eth_data = { +static struct ep93xx_eth_data __initdata adssphere_eth_data = { .phy_id = 1, }; diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index 90fb591cbffa..5b1d836c2f05 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c @@ -330,6 +330,10 @@ static struct platform_device ep93xx_ohci_device = { .resource = ep93xx_ohci_resources, }; + +/************************************************************************* + * EP93xx ethernet peripheral handling + *************************************************************************/ static struct ep93xx_eth_data ep93xx_eth_data; static struct resource ep93xx_eth_resource[] = { @@ -354,6 +358,12 @@ static struct platform_device ep93xx_eth_device = { .resource = ep93xx_eth_resource, }; +/** + * ep93xx_register_eth - Register the built-in ethernet platform device. + * @data: platform specific ethernet configuration (__initdata) + * @copy_addr: flag indicating that the MAC address should be copied + * from the IndAd registers (as programmed by the bootloader) + */ void __init ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr) { if (copy_addr) @@ -370,11 +380,19 @@ void __init ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr) static struct i2c_gpio_platform_data ep93xx_i2c_data; static struct platform_device ep93xx_i2c_device = { - .name = "i2c-gpio", - .id = 0, - .dev.platform_data = &ep93xx_i2c_data, + .name = "i2c-gpio", + .id = 0, + .dev = { + .platform_data = &ep93xx_i2c_data, + }, }; +/** + * ep93xx_register_i2c - Register the i2c platform device. + * @data: platform specific i2c-gpio configuration (__initdata) + * @devices: platform specific i2c bus device information (__initdata) + * @num: the number of devices on the i2c bus + */ void __init ep93xx_register_i2c(struct i2c_gpio_platform_data *data, struct i2c_board_info *devices, int num) { @@ -404,11 +422,11 @@ void __init ep93xx_register_i2c(struct i2c_gpio_platform_data *data, *************************************************************************/ static struct gpio_led ep93xx_led_pins[] = { { - .name = "platform:grled", - .gpio = EP93XX_GPIO_LINE_GRLED, + .name = "platform:grled", + .gpio = EP93XX_GPIO_LINE_GRLED, }, { - .name = "platform:rdled", - .gpio = EP93XX_GPIO_LINE_RDLED, + .name = "platform:rdled", + .gpio = EP93XX_GPIO_LINE_RDLED, }, }; @@ -528,7 +546,7 @@ static struct platform_device ep93xx_fb_device = { .name = "ep93xx-fb", .id = -1, .dev = { - .platform_data = &ep93xxfb_data, + .platform_data = &ep93xxfb_data, .coherent_dma_mask = DMA_BIT_MASK(32), .dma_mask = &ep93xx_fb_device.dev.coherent_dma_mask, }, @@ -536,6 +554,10 @@ static struct platform_device ep93xx_fb_device = { .resource = ep93xx_fb_resource, }; +/** + * ep93xx_register_fb - Register the framebuffer platform device. + * @data: platform specific framebuffer configuration (__initdata) + */ void __init ep93xx_register_fb(struct ep93xxfb_mach_info *data) { ep93xxfb_data = *data; @@ -546,6 +568,8 @@ void __init ep93xx_register_fb(struct ep93xxfb_mach_info *data) /************************************************************************* * EP93xx matrix keypad peripheral handling *************************************************************************/ +static struct ep93xx_keypad_platform_data ep93xx_keypad_data; + static struct resource ep93xx_keypad_resource[] = { { .start = EP93XX_KEY_MATRIX_PHYS_BASE, @@ -559,15 +583,22 @@ static struct resource ep93xx_keypad_resource[] = { }; static struct platform_device ep93xx_keypad_device = { - .name = "ep93xx-keypad", - .id = -1, - .num_resources = ARRAY_SIZE(ep93xx_keypad_resource), - .resource = ep93xx_keypad_resource, + .name = "ep93xx-keypad", + .id = -1, + .dev = { + .platform_data = &ep93xx_keypad_data, + }, + .num_resources = ARRAY_SIZE(ep93xx_keypad_resource), + .resource = ep93xx_keypad_resource, }; +/** + * ep93xx_register_keypad - Register the keypad platform device. + * @data: platform specific keypad configuration (__initdata) + */ void __init ep93xx_register_keypad(struct ep93xx_keypad_platform_data *data) { - ep93xx_keypad_device.dev.platform_data = data; + ep93xx_keypad_data = *data; platform_device_register(&ep93xx_keypad_device); } diff --git a/arch/arm/mach-ep93xx/edb93xx.c b/arch/arm/mach-ep93xx/edb93xx.c index d22d67ac8b99..3884182cd362 100644 --- a/arch/arm/mach-ep93xx/edb93xx.c +++ b/arch/arm/mach-ep93xx/edb93xx.c @@ -74,7 +74,7 @@ static void __init edb93xx_register_flash(void) } } -static struct ep93xx_eth_data edb93xx_eth_data = { +static struct ep93xx_eth_data __initdata edb93xx_eth_data = { .phy_id = 1, }; @@ -82,7 +82,7 @@ static struct ep93xx_eth_data edb93xx_eth_data = { /************************************************************************* * EDB93xx i2c peripheral handling *************************************************************************/ -static struct i2c_gpio_platform_data edb93xx_i2c_gpio_data = { +static struct i2c_gpio_platform_data __initdata edb93xx_i2c_gpio_data = { .sda_pin = EP93XX_GPIO_LINE_EEDAT, .sda_is_open_drain = 0, .scl_pin = EP93XX_GPIO_LINE_EECLK, diff --git a/arch/arm/mach-ep93xx/gesbc9312.c b/arch/arm/mach-ep93xx/gesbc9312.c index 3da7ca816d19..a809618e9f05 100644 --- a/arch/arm/mach-ep93xx/gesbc9312.c +++ b/arch/arm/mach-ep93xx/gesbc9312.c @@ -41,7 +41,7 @@ static struct platform_device gesbc9312_flash = { .resource = &gesbc9312_flash_resource, }; -static struct ep93xx_eth_data gesbc9312_eth_data = { +static struct ep93xx_eth_data __initdata gesbc9312_eth_data = { .phy_id = 1, }; diff --git a/arch/arm/mach-ep93xx/micro9.c b/arch/arm/mach-ep93xx/micro9.c index c33360e82868..1cc911b4efa6 100644 --- a/arch/arm/mach-ep93xx/micro9.c +++ b/arch/arm/mach-ep93xx/micro9.c @@ -80,7 +80,7 @@ static void __init micro9_register_flash(void) /************************************************************************* * Micro9 Ethernet *************************************************************************/ -static struct ep93xx_eth_data micro9_eth_data = { +static struct ep93xx_eth_data __initdata micro9_eth_data = { .phy_id = 0x1f, }; diff --git a/arch/arm/mach-ep93xx/simone.c b/arch/arm/mach-ep93xx/simone.c index cd93990f1b99..388aec95f60e 100644 --- a/arch/arm/mach-ep93xx/simone.c +++ b/arch/arm/mach-ep93xx/simone.c @@ -49,17 +49,17 @@ static struct platform_device simone_flash = { }, }; -static struct ep93xx_eth_data simone_eth_data = { +static struct ep93xx_eth_data __initdata simone_eth_data = { .phy_id = 1, }; -static struct ep93xxfb_mach_info simone_fb_info = { +static struct ep93xxfb_mach_info __initdata simone_fb_info = { .num_modes = EP93XXFB_USE_MODEDB, .bpp = 16, .flags = EP93XXFB_USE_SDCSN0 | EP93XXFB_PCLK_FALLING, }; -static struct i2c_gpio_platform_data simone_i2c_gpio_data = { +static struct i2c_gpio_platform_data __initdata simone_i2c_gpio_data = { .sda_pin = EP93XX_GPIO_LINE_EEDAT, .sda_is_open_drain = 0, .scl_pin = EP93XX_GPIO_LINE_EECLK, diff --git a/arch/arm/mach-ep93xx/snappercl15.c b/arch/arm/mach-ep93xx/snappercl15.c index 51134b0382ca..38deaee40397 100644 --- a/arch/arm/mach-ep93xx/snappercl15.c +++ b/arch/arm/mach-ep93xx/snappercl15.c @@ -125,11 +125,11 @@ static struct platform_device snappercl15_nand_device = { .num_resources = ARRAY_SIZE(snappercl15_nand_resource), }; -static struct ep93xx_eth_data snappercl15_eth_data = { +static struct ep93xx_eth_data __initdata snappercl15_eth_data = { .phy_id = 1, }; -static struct i2c_gpio_platform_data snappercl15_i2c_gpio_data = { +static struct i2c_gpio_platform_data __initdata snappercl15_i2c_gpio_data = { .sda_pin = EP93XX_GPIO_LINE_EEDAT, .sda_is_open_drain = 0, .scl_pin = EP93XX_GPIO_LINE_EECLK, @@ -145,7 +145,7 @@ static struct i2c_board_info __initdata snappercl15_i2c_data[] = { }, }; -static struct ep93xxfb_mach_info snappercl15_fb_info = { +static struct ep93xxfb_mach_info __initdata snappercl15_fb_info = { .num_modes = EP93XXFB_USE_MODEDB, .bpp = 16, }; diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c index fac1ec7a60fb..9553031900b0 100644 --- a/arch/arm/mach-ep93xx/ts72xx.c +++ b/arch/arm/mach-ep93xx/ts72xx.c @@ -186,7 +186,7 @@ static struct platform_device ts72xx_wdt_device = { .resource = ts72xx_wdt_resources, }; -static struct ep93xx_eth_data ts72xx_eth_data = { +static struct ep93xx_eth_data __initdata ts72xx_eth_data = { .phy_id = 1, }; -- cgit v1.2.2 From 99e6a23adfadc2da2006f3715c4332c3bf502c07 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Sat, 27 Mar 2010 12:05:14 +0100 Subject: ARM: 5998/1: ep93xx: added chip revision reading function Added a new function: ep93xx_chip_revision() which reads chip revision from the sysconfig register. Signed-off-by: Mika Westerberg Acked-by: H Hartley Sweeten Signed-off-by: Russell King --- arch/arm/mach-ep93xx/core.c | 14 ++++++++++++++ arch/arm/mach-ep93xx/include/mach/platform.h | 8 ++++++++ 2 files changed, 22 insertions(+) (limited to 'arch/arm/mach-ep93xx') diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index 5b1d836c2f05..8d3f77e9fa86 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c @@ -222,6 +222,20 @@ void ep93xx_devcfg_set_clear(unsigned int set_bits, unsigned int clear_bits) } EXPORT_SYMBOL(ep93xx_devcfg_set_clear); +/** + * ep93xx_chip_revision() - returns the EP93xx chip revision + * + * See for more information. + */ +unsigned int ep93xx_chip_revision(void) +{ + unsigned int v; + + v = __raw_readl(EP93XX_SYSCON_SYSCFG); + v &= EP93XX_SYSCON_SYSCFG_REV_MASK; + v >>= EP93XX_SYSCON_SYSCFG_REV_SHIFT; + return v; +} /************************************************************************* * EP93xx peripheral handling diff --git a/arch/arm/mach-ep93xx/include/mach/platform.h b/arch/arm/mach-ep93xx/include/mach/platform.h index c6dc14dbca18..b663390b4d87 100644 --- a/arch/arm/mach-ep93xx/include/mach/platform.h +++ b/arch/arm/mach-ep93xx/include/mach/platform.h @@ -33,6 +33,14 @@ static inline void ep93xx_devcfg_clear_bits(unsigned int bits) ep93xx_devcfg_set_clear(0x00, bits); } +#define EP93XX_CHIP_REV_D0 3 +#define EP93XX_CHIP_REV_D1 4 +#define EP93XX_CHIP_REV_E0 5 +#define EP93XX_CHIP_REV_E1 6 +#define EP93XX_CHIP_REV_E2 7 + +unsigned int ep93xx_chip_revision(void); + void ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr); void ep93xx_register_i2c(struct i2c_gpio_platform_data *data, struct i2c_board_info *devices, int num); -- cgit v1.2.2 From 4fec9978822a66b25f5645eb20c115034a18cfd1 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Tue, 11 May 2010 15:34:54 +0100 Subject: ARM: 6124/1: ep93xx: SPI driver platform support code This patch adds platform side support code for the EP93xx SPI driver. This includes clock, resources and muxing. There is a new function: ep93xx_register_spi() which can be used by board support code to register new SPI devices for the board. This patch depends on patch 5998/1 ep93xx: added chip revision reading function Cc: Ryan Mallon Cc: David Brownell Cc: Grant Likely Signed-off-by: Mika Westerberg Acked-by: H Hartley Sweeten Acked-by: Martin Guy Signed-off-by: Russell King --- arch/arm/mach-ep93xx/clock.c | 13 +++++++ arch/arm/mach-ep93xx/core.c | 52 +++++++++++++++++++++++++ arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h | 1 + arch/arm/mach-ep93xx/include/mach/platform.h | 4 ++ 4 files changed, 70 insertions(+) (limited to 'arch/arm/mach-ep93xx') diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c index 5f80092b6ace..e29bdef9b2e2 100644 --- a/arch/arm/mach-ep93xx/clock.c +++ b/arch/arm/mach-ep93xx/clock.c @@ -96,6 +96,10 @@ static struct clk clk_keypad = { .enable_mask = EP93XX_SYSCON_KEYTCHCLKDIV_KEN, .set_rate = set_keytchclk_rate, }; +static struct clk clk_spi = { + .parent = &clk_xtali, + .rate = EP93XX_EXT_CLK_RATE, +}; static struct clk clk_pwm = { .parent = &clk_xtali, .rate = EP93XX_EXT_CLK_RATE, @@ -186,6 +190,7 @@ static struct clk_lookup clocks[] = { INIT_CK("ep93xx-ohci", NULL, &clk_usb_host), INIT_CK("ep93xx-keypad", NULL, &clk_keypad), INIT_CK("ep93xx-fb", NULL, &clk_video), + INIT_CK("ep93xx-spi.0", NULL, &clk_spi), INIT_CK(NULL, "pwm_clk", &clk_pwm), INIT_CK(NULL, "m2p0", &clk_m2p0), INIT_CK(NULL, "m2p1", &clk_m2p1), @@ -473,6 +478,14 @@ static int __init ep93xx_clock_init(void) /* Initialize the pll2 derived clocks */ clk_usb_host.rate = clk_pll2.rate / (((value >> 28) & 0xf) + 1); + /* + * EP93xx SSP clock rate was doubled in version E2. For more information + * see: + * http://www.cirrus.com/en/pubs/appNote/AN273REV4.pdf + */ + if (ep93xx_chip_revision() < EP93XX_CHIP_REV_E2) + clk_spi.rate /= 2; + pr_info("PLL1 running at %ld MHz, PLL2 at %ld MHz\n", clk_pll1.rate / 1000000, clk_pll2.rate / 1000000); pr_info("FCLK %ld MHz, HCLK %ld MHz, PCLK %ld MHz\n", diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index 8d3f77e9fa86..9092677f63eb 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c @@ -31,10 +31,12 @@ #include #include #include +#include #include #include #include +#include #include #include @@ -430,6 +432,56 @@ void __init ep93xx_register_i2c(struct i2c_gpio_platform_data *data, platform_device_register(&ep93xx_i2c_device); } +/************************************************************************* + * EP93xx SPI peripheral handling + *************************************************************************/ +static struct ep93xx_spi_info ep93xx_spi_master_data; + +static struct resource ep93xx_spi_resources[] = { + { + .start = EP93XX_SPI_PHYS_BASE, + .end = EP93XX_SPI_PHYS_BASE + 0x18 - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_EP93XX_SSP, + .end = IRQ_EP93XX_SSP, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device ep93xx_spi_device = { + .name = "ep93xx-spi", + .id = 0, + .dev = { + .platform_data = &ep93xx_spi_master_data, + }, + .num_resources = ARRAY_SIZE(ep93xx_spi_resources), + .resource = ep93xx_spi_resources, +}; + +/** + * ep93xx_register_spi() - registers spi platform device + * @info: ep93xx board specific spi master info (__initdata) + * @devices: SPI devices to register (__initdata) + * @num: number of SPI devices to register + * + * This function registers platform device for the EP93xx SPI controller and + * also makes sure that SPI pins are muxed so that I2S is not using those pins. + */ +void __init ep93xx_register_spi(struct ep93xx_spi_info *info, + struct spi_board_info *devices, int num) +{ + /* + * When SPI is used, we need to make sure that I2S is muxed off from + * SPI pins. + */ + ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_I2SONSSP); + + ep93xx_spi_master_data = *info; + spi_register_board_info(devices, num); + platform_device_register(&ep93xx_spi_device); +} /************************************************************************* * EP93xx LEDs diff --git a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h index 93e2ecc79ceb..b1e096f0c2d2 100644 --- a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h +++ b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h @@ -106,6 +106,7 @@ #define EP93XX_AAC_BASE EP93XX_APB_IOMEM(0x00080000) +#define EP93XX_SPI_PHYS_BASE EP93XX_APB_PHYS(0x000a0000) #define EP93XX_SPI_BASE EP93XX_APB_IOMEM(0x000a0000) #define EP93XX_IRDA_BASE EP93XX_APB_IOMEM(0x000b0000) diff --git a/arch/arm/mach-ep93xx/include/mach/platform.h b/arch/arm/mach-ep93xx/include/mach/platform.h index b663390b4d87..9a4413dd44bb 100644 --- a/arch/arm/mach-ep93xx/include/mach/platform.h +++ b/arch/arm/mach-ep93xx/include/mach/platform.h @@ -6,9 +6,11 @@ struct i2c_gpio_platform_data; struct i2c_board_info; +struct spi_board_info; struct platform_device; struct ep93xxfb_mach_info; struct ep93xx_keypad_platform_data; +struct ep93xx_spi_info; struct ep93xx_eth_data { @@ -44,6 +46,8 @@ unsigned int ep93xx_chip_revision(void); void ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr); void ep93xx_register_i2c(struct i2c_gpio_platform_data *data, struct i2c_board_info *devices, int num); +void ep93xx_register_spi(struct ep93xx_spi_info *info, + struct spi_board_info *devices, int num); void ep93xx_register_fb(struct ep93xxfb_mach_info *data); void ep93xx_register_pwm(int pwm0, int pwm1); int ep93xx_pwm_acquire_gpio(struct platform_device *pdev); -- cgit v1.2.2