diff options
Diffstat (limited to 'arch/arm/mach-ux500')
-rw-r--r-- | arch/arm/mach-ux500/Kconfig | 15 | ||||
-rw-r--r-- | arch/arm/mach-ux500/board-mop500-pins.c | 43 | ||||
-rw-r--r-- | arch/arm/mach-ux500/board-mop500-regulators.c | 9 | ||||
-rw-r--r-- | arch/arm/mach-ux500/board-mop500-sdi.c | 61 | ||||
-rw-r--r-- | arch/arm/mach-ux500/board-mop500-uib.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-ux500/board-mop500.c | 154 | ||||
-rw-r--r-- | arch/arm/mach-ux500/board-mop500.h | 5 | ||||
-rw-r--r-- | arch/arm/mach-ux500/clock.c | 48 | ||||
-rw-r--r-- | arch/arm/mach-ux500/cpu-db5500.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-ux500/include/mach/uncompress.h | 3 | ||||
-rw-r--r-- | arch/arm/mach-ux500/usb.c | 1 |
11 files changed, 313 insertions, 29 deletions
diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig index f8b9392ee347..4210cb434dbc 100644 --- a/arch/arm/mach-ux500/Kconfig +++ b/arch/arm/mach-ux500/Kconfig @@ -20,7 +20,7 @@ config UX500_SOC_DB8500 endmenu -menu "Ux500 target platform" +menu "Ux500 target platform (boards)" config MACH_U8500 bool "U8500 Development platform" @@ -29,6 +29,19 @@ config MACH_U8500 help Include support for the mop500 development platform. +config MACH_HREFV60 + bool "U85000 Development platform, HREFv60 version" + depends on UX500_SOC_DB8500 + help + Include support for the HREFv60 new development platform. + +config MACH_SNOWBALL + bool "U8500 Snowball platform" + depends on UX500_SOC_DB8500 + select MACH_U8500 + help + Include support for the snowball development platform. + config MACH_U5500 bool "U5500 Development platform" depends on UX500_SOC_DB5500 diff --git a/arch/arm/mach-ux500/board-mop500-pins.c b/arch/arm/mach-ux500/board-mop500-pins.c index 70cdbd60596a..f26fd76f72b4 100644 --- a/arch/arm/mach-ux500/board-mop500-pins.c +++ b/arch/arm/mach-ux500/board-mop500-pins.c @@ -236,6 +236,46 @@ static pin_cfg_t mop500_pins_hrefv60[] = { }; +static pin_cfg_t snowball_pins[] = { + /* SSP0, to AB8500 */ + GPIO143_SSP0_CLK, + GPIO144_SSP0_FRM, + GPIO145_SSP0_RXD | PIN_PULL_DOWN, + GPIO146_SSP0_TXD, + + /* MMC0: MicroSD card */ + GPIO21_MC0_DAT31DIR | PIN_OUTPUT_HIGH, + + /* MMC2: LAN */ + GPIO86_SM_ADQ0, + GPIO87_SM_ADQ1, + GPIO88_SM_ADQ2, + GPIO89_SM_ADQ3, + GPIO90_SM_ADQ4, + GPIO91_SM_ADQ5, + GPIO92_SM_ADQ6, + GPIO93_SM_ADQ7, + + GPIO94_SM_ADVn, + GPIO95_SM_CS0n, + GPIO96_SM_OEn, + GPIO97_SM_WEn, + + GPIO128_SM_CKO, + GPIO130_SM_FBCLK, + GPIO131_SM_ADQ8, + GPIO132_SM_ADQ9, + GPIO133_SM_ADQ10, + GPIO134_SM_ADQ11, + GPIO135_SM_ADQ12, + GPIO136_SM_ADQ13, + GPIO137_SM_ADQ14, + GPIO138_SM_ADQ15, + + /* RSTn_LAN */ + GPIO141_GPIO | PIN_OUTPUT_HIGH, +}; + void __init mop500_pins_init(void) { nmk_config_pins(mop500_pins_common, @@ -243,6 +283,9 @@ void __init mop500_pins_init(void) if (machine_is_hrefv60()) nmk_config_pins(mop500_pins_hrefv60, ARRAY_SIZE(mop500_pins_hrefv60)); + else if (machine_is_snowball()) + nmk_config_pins(snowball_pins, + ARRAY_SIZE(snowball_pins)); else nmk_config_pins(mop500_pins_default, ARRAY_SIZE(mop500_pins_default)); diff --git a/arch/arm/mach-ux500/board-mop500-regulators.c b/arch/arm/mach-ux500/board-mop500-regulators.c index 9ed0f90cfe23..c0bc833df903 100644 --- a/arch/arm/mach-ux500/board-mop500-regulators.c +++ b/arch/arm/mach-ux500/board-mop500-regulators.c @@ -272,7 +272,14 @@ struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = { .max_uV = 2900000, .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS, - .boot_on = 1, /* must be on for display */ + .boot_on = 1, /* display is on at boot */ + /* + * This voltage cannot be disabled right now because + * it is somehow affecting the external MMC + * functionality, though that typically will use + * AUX3. + */ + .always_on = 1, }, .num_consumer_supplies = ARRAY_SIZE(ab8500_vaux1_consumers), .consumer_supplies = ab8500_vaux1_consumers, diff --git a/arch/arm/mach-ux500/board-mop500-sdi.c b/arch/arm/mach-ux500/board-mop500-sdi.c index 7c6cb4fa47a9..d0cb9e5eb87c 100644 --- a/arch/arm/mach-ux500/board-mop500-sdi.c +++ b/arch/arm/mach-ux500/board-mop500-sdi.c @@ -32,13 +32,32 @@ #define MCI_DATA31DIREN (1 << 5) #define MCI_FBCLKEN (1 << 7) +/* GPIO pins used by the sdi0 level shifter */ +static int sdi0_en = -1; +static int sdi0_vsel = -1; + static u32 mop500_sdi0_vdd_handler(struct device *dev, unsigned int vdd, unsigned char power_mode) { - if (power_mode == MMC_POWER_UP) - gpio_set_value_cansleep(GPIO_SDMMC_EN, 1); - else if (power_mode == MMC_POWER_OFF) - gpio_set_value_cansleep(GPIO_SDMMC_EN, 0); + switch (power_mode) { + case MMC_POWER_UP: + case MMC_POWER_ON: + /* + * Level shifter voltage should depend on vdd to when deciding + * on either 1.8V or 2.9V. Once the decision has been made the + * level shifter must be disabled and re-enabled with a changed + * select signal in order to switch the voltage. Since there is + * no framework support yet for indicating 1.8V in vdd, use the + * default 2.9V. + */ + gpio_direction_output(sdi0_vsel, 0); + gpio_direction_output(sdi0_en, 1); + break; + case MMC_POWER_OFF: + gpio_direction_output(sdi0_vsel, 0); + gpio_direction_output(sdi0_en, 0); + break; + } return MCI_FBCLKEN | MCI_CMDDIREN | MCI_DATA0DIREN | MCI_DATA2DIREN | MCI_DATA31DIREN; @@ -67,8 +86,10 @@ static struct stedma40_chan_cfg mop500_sdi0_dma_cfg_tx = { static struct mmci_platform_data mop500_sdi0_data = { .vdd_handler = mop500_sdi0_vdd_handler, .ocr_mask = MMC_VDD_29_30, - .f_max = 100000000, - .capabilities = MMC_CAP_4_BIT_DATA, + .f_max = 50000000, + .capabilities = MMC_CAP_4_BIT_DATA | + MMC_CAP_SD_HIGHSPEED | + MMC_CAP_MMC_HIGHSPEED, .gpio_wp = -1, #ifdef CONFIG_STE_DMA40 .dma_filter = stedma40_filter, @@ -77,10 +98,6 @@ static struct mmci_platform_data mop500_sdi0_data = { #endif }; -/* GPIO pins used by the sdi0 level shifter */ -static int sdi0_en = -1; -static int sdi0_vsel = -1; - static void sdi0_configure(void) { int ret; @@ -140,7 +157,7 @@ static struct stedma40_chan_cfg mop500_sdi2_dma_cfg_tx = { static struct mmci_platform_data mop500_sdi2_data = { .ocr_mask = MMC_VDD_165_195, - .f_max = 100000000, + .f_max = 50000000, .capabilities = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, .gpio_cd = -1, .gpio_wp = -1, @@ -177,7 +194,7 @@ static struct stedma40_chan_cfg mop500_sdi4_dma_cfg_tx = { static struct mmci_platform_data mop500_sdi4_data = { .ocr_mask = MMC_VDD_29_30, - .f_max = 100000000, + .f_max = 50000000, .capabilities = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA | MMC_CAP_MMC_HIGHSPEED, .gpio_cd = -1, @@ -199,17 +216,27 @@ void __init mop500_sdi_init(void) /* PoP:ed eMMC on top of DB8500 v1.0 has problems with high speed */ if (!cpu_is_u8500v10()) mop500_sdi2_data.capabilities |= MMC_CAP_MMC_HIGHSPEED; - db8500_add_sdi2(&mop500_sdi2_data, periphid); + /* sdi2 on snowball is in ATL_B mode for FSMC (LAN) */ + if (!machine_is_snowball()) + db8500_add_sdi2(&mop500_sdi2_data, periphid); /* On-board eMMC */ db8500_add_sdi4(&mop500_sdi4_data, periphid); - if (machine_is_hrefv60()) { - mop500_sdi0_data.gpio_cd = HREFV60_SDMMC_CD_GPIO; - sdi0_en = HREFV60_SDMMC_EN_GPIO; - sdi0_vsel = HREFV60_SDMMC_1V8_3V_GPIO; + if (machine_is_hrefv60() || machine_is_snowball()) { + if (machine_is_hrefv60()) { + mop500_sdi0_data.gpio_cd = HREFV60_SDMMC_CD_GPIO; + sdi0_en = HREFV60_SDMMC_EN_GPIO; + sdi0_vsel = HREFV60_SDMMC_1V8_3V_GPIO; + } else if (machine_is_snowball()) { + mop500_sdi0_data.gpio_cd = SNOWBALL_SDMMC_CD_GPIO; + mop500_sdi0_data.cd_invert = true; + sdi0_en = SNOWBALL_SDMMC_EN_GPIO; + sdi0_vsel = SNOWBALL_SDMMC_1V8_3V_GPIO; + } sdi0_configure(); } + /* * On boards with the TC35892 GPIO expander, sdi0 will finally * be added when the TC35892 initializes and calls diff --git a/arch/arm/mach-ux500/board-mop500-uib.c b/arch/arm/mach-ux500/board-mop500-uib.c index 69cce41f602a..5af36aa56c08 100644 --- a/arch/arm/mach-ux500/board-mop500-uib.c +++ b/arch/arm/mach-ux500/board-mop500-uib.c @@ -25,7 +25,7 @@ struct uib { void (*init)(void); }; -static struct __initdata uib mop500_uibs[] = { +static struct uib __initdata mop500_uibs[] = { [STUIB] = { .name = "ST-UIB", .option = "stuib", diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index 2a08c07dec6d..cd54abaccd96 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -26,9 +26,11 @@ #include <linux/mfd/ab8500/gpio.h> #include <linux/leds-lp5521.h> #include <linux/input.h> +#include <linux/smsc911x.h> #include <linux/gpio_keys.h> #include <linux/delay.h> +#include <linux/leds.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> @@ -47,6 +49,26 @@ #include "board-mop500.h" #include "board-mop500-regulators.h" +static struct gpio_led snowball_led_array[] = { + { + .name = "user_led", + .default_trigger = "none", + .gpio = 142, + }, +}; + +static struct gpio_led_platform_data snowball_led_data = { + .leds = snowball_led_array, + .num_leds = ARRAY_SIZE(snowball_led_array), +}; + +static struct platform_device snowball_led_dev = { + .name = "leds-gpio", + .dev = { + .platform_data = &snowball_led_data, + }, +}; + static struct ab8500_gpio_platform_data ab8500_gpio_pdata = { .gpio_base = MOP500_AB8500_GPIO(0), .irq_base = MOP500_AB8500_VIR_GPIO_IRQ_BASE, @@ -69,6 +91,97 @@ static struct ab8500_gpio_platform_data ab8500_gpio_pdata = { 0x7A, 0x00, 0x00}, }; +static struct gpio_keys_button snowball_key_array[] = { + { + .gpio = 32, + .type = EV_KEY, + .code = KEY_1, + .desc = "userpb", + .active_low = 1, + .debounce_interval = 50, + .wakeup = 1, + }, + { + .gpio = 151, + .type = EV_KEY, + .code = KEY_2, + .desc = "extkb1", + .active_low = 1, + .debounce_interval = 50, + .wakeup = 1, + }, + { + .gpio = 152, + .type = EV_KEY, + .code = KEY_3, + .desc = "extkb2", + .active_low = 1, + .debounce_interval = 50, + .wakeup = 1, + }, + { + .gpio = 161, + .type = EV_KEY, + .code = KEY_4, + .desc = "extkb3", + .active_low = 1, + .debounce_interval = 50, + .wakeup = 1, + }, + { + .gpio = 162, + .type = EV_KEY, + .code = KEY_5, + .desc = "extkb4", + .active_low = 1, + .debounce_interval = 50, + .wakeup = 1, + }, +}; + +static struct gpio_keys_platform_data snowball_key_data = { + .buttons = snowball_key_array, + .nbuttons = ARRAY_SIZE(snowball_key_array), +}; + +static struct platform_device snowball_key_dev = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &snowball_key_data, + } +}; + +static struct smsc911x_platform_config snowball_sbnet_cfg = { + .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH, + .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, + .flags = SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY, + .shift = 1, +}; + +static struct resource sbnet_res[] = { + { + .name = "smsc911x-memory", + .start = (0x5000 << 16), + .end = (0x5000 << 16) + 0xffff, + .flags = IORESOURCE_MEM, + }, + { + .start = NOMADIK_GPIO_TO_IRQ(140), + .end = NOMADIK_GPIO_TO_IRQ(140), + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, + }, +}; + +static struct platform_device snowball_sbnet_dev = { + .name = "smsc911x", + .num_resources = ARRAY_SIZE(sbnet_res), + .resource = sbnet_res, + .dev = { + .platform_data = &snowball_sbnet_cfg, + }, +}; + static struct ab8500_platform_data ab8500_platdata = { .irq_base = MOP500_AB8500_IRQ_BASE, .regulator_reg_init = ab8500_regulator_reg_init, @@ -295,8 +408,9 @@ static void mop500_prox_deactivate(struct device *dev) } /* add any platform devices here - TODO */ -static struct platform_device *platform_devs[] __initdata = { +static struct platform_device *mop500_platform_devs[] __initdata = { &mop500_gpio_keys_device, + &ab8500_device, }; #ifdef CONFIG_STE_DMA40 @@ -478,6 +592,13 @@ static void __init mop500_uart_init(void) db8500_add_uart2(&uart2_plat); } +static struct platform_device *snowball_platform_devs[] __initdata = { + &snowball_led_dev, + &snowball_key_dev, + &snowball_sbnet_dev, + &ab8500_device, +}; + static void __init mop500_init_machine(void) { int i2c0_devs; @@ -487,24 +608,29 @@ static void __init mop500_init_machine(void) * all these GPIO pins to the internal GPIO controller * instead. */ - if (machine_is_hrefv60()) - mop500_gpio_keys[0].gpio = HREFV60_PROX_SENSE_GPIO; - else - mop500_gpio_keys[0].gpio = GPIO_PROX_SENSOR; + if (!machine_is_snowball()) { + if (machine_is_hrefv60()) + mop500_gpio_keys[0].gpio = HREFV60_PROX_SENSE_GPIO; + else + mop500_gpio_keys[0].gpio = GPIO_PROX_SENSOR; + } u8500_init_devices(); mop500_pins_init(); - platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); + if (machine_is_snowball()) + platform_add_devices(snowball_platform_devs, + ARRAY_SIZE(snowball_platform_devs)); + else + platform_add_devices(mop500_platform_devs, + ARRAY_SIZE(mop500_platform_devs)); mop500_i2c_init(); mop500_sdi_init(); mop500_spi_init(); mop500_uart_init(); - platform_device_register(&ab8500_device); - i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices); if (machine_is_hrefv60()) i2c0_devs -= NUM_PRE_V60_I2C0_DEVICES; @@ -512,6 +638,9 @@ static void __init mop500_init_machine(void) i2c_register_board_info(0, mop500_i2c0_devices, i2c0_devs); i2c_register_board_info(2, mop500_i2c2_devices, ARRAY_SIZE(mop500_i2c2_devices)); + + /* This board has full regulator constraints */ + regulator_has_full_constraints(); } MACHINE_START(U8500, "ST-Ericsson MOP500 platform") @@ -531,3 +660,12 @@ MACHINE_START(HREFV60, "ST-Ericsson U8500 Platform HREFv60+") .timer = &ux500_timer, .init_machine = mop500_init_machine, MACHINE_END + +MACHINE_START(SNOWBALL, "Calao Systems Snowball platform") + .boot_params = 0x100, + .map_io = u8500_map_io, + .init_irq = ux500_init_irq, + /* we re-use nomadik timer here */ + .timer = &ux500_timer, + .init_machine = mop500_init_machine, +MACHINE_END diff --git a/arch/arm/mach-ux500/board-mop500.h b/arch/arm/mach-ux500/board-mop500.h index 03a31cc9b084..ee77a8970c33 100644 --- a/arch/arm/mach-ux500/board-mop500.h +++ b/arch/arm/mach-ux500/board-mop500.h @@ -7,6 +7,11 @@ #ifndef __BOARD_MOP500_H #define __BOARD_MOP500_H +/* snowball GPIO for MMC card */ +#define SNOWBALL_SDMMC_EN_GPIO 217 +#define SNOWBALL_SDMMC_1V8_3V_GPIO 228 +#define SNOWBALL_SDMMC_CD_GPIO 218 + /* HREFv60-specific GPIO assignments, this board has no GPIO expander */ #define HREFV60_TOUCH_RST_GPIO 143 #define HREFV60_PROX_SENSE_GPIO 217 diff --git a/arch/arm/mach-ux500/clock.c b/arch/arm/mach-ux500/clock.c index 32ce90840ee1..b4e786a0fa4f 100644 --- a/arch/arm/mach-ux500/clock.c +++ b/arch/arm/mach-ux500/clock.c @@ -14,6 +14,7 @@ #include <linux/clk.h> #include <linux/io.h> #include <linux/clkdev.h> +#include <linux/cpufreq.h> #include <plat/mtu.h> #include <mach/hardware.h> @@ -759,6 +760,51 @@ err_out: late_initcall(clk_debugfs_init); #endif /* defined(CONFIG_DEBUG_FS) */ +unsigned long clk_smp_twd_rate = 400000000; + +unsigned long clk_smp_twd_get_rate(struct clk *clk) +{ + return clk_smp_twd_rate; +} + +static struct clk clk_smp_twd = { + .get_rate = clk_smp_twd_get_rate, + .name = "smp_twd", +}; + +static struct clk_lookup clk_smp_twd_lookup = { + .dev_id = "smp_twd", + .clk = &clk_smp_twd, +}; + +#ifdef CONFIG_CPU_FREQ + +static int clk_twd_cpufreq_transition(struct notifier_block *nb, + unsigned long state, void *data) +{ + struct cpufreq_freqs *f = data; + + if (state == CPUFREQ_PRECHANGE) { + /* Save frequency in simple Hz */ + clk_smp_twd_rate = f->new * 1000; + } + + return NOTIFY_OK; +} + +static struct notifier_block clk_twd_cpufreq_nb = { + .notifier_call = clk_twd_cpufreq_transition, +}; + +static int clk_init_smp_twd_cpufreq(void) +{ + return cpufreq_register_notifier(&clk_twd_cpufreq_nb, + CPUFREQ_TRANSITION_NOTIFIER); +} +late_initcall(clk_init_smp_twd_cpufreq); + +#endif + int __init clk_init(void) { if (cpu_is_u8500ed()) { @@ -779,6 +825,8 @@ int __init clk_init(void) else clkdev_add_table(u8500_v1_clks, ARRAY_SIZE(u8500_v1_clks)); + clkdev_add(&clk_smp_twd_lookup); + #ifdef CONFIG_DEBUG_FS clk_debugfs_add_table(u8500_common_clks, ARRAY_SIZE(u8500_common_clks)); if (cpu_is_u8500ed()) diff --git a/arch/arm/mach-ux500/cpu-db5500.c b/arch/arm/mach-ux500/cpu-db5500.c index c01bc19e3c5e..22705d246fc7 100644 --- a/arch/arm/mach-ux500/cpu-db5500.c +++ b/arch/arm/mach-ux500/cpu-db5500.c @@ -44,6 +44,7 @@ static struct map_desc u5500_io_desc[] __initdata = { __IO_DEV_DESC(U5500_GPIO3_BASE, SZ_4K), __IO_DEV_DESC(U5500_GPIO4_BASE, SZ_4K), __IO_DEV_DESC(U5500_PRCMU_BASE, SZ_4K), + __IO_DEV_DESC(U5500_PRCMU_TCDM_BASE, SZ_4K), }; static struct resource db5500_pmu_resources[] = { diff --git a/arch/arm/mach-ux500/include/mach/uncompress.h b/arch/arm/mach-ux500/include/mach/uncompress.h index 088b550c40df..7dd08074c37b 100644 --- a/arch/arm/mach-ux500/include/mach/uncompress.h +++ b/arch/arm/mach-ux500/include/mach/uncompress.h @@ -54,7 +54,8 @@ static inline void arch_decomp_setup(void) if (machine_is_u8500() || machine_is_svp8500v1() || machine_is_svp8500v2() || - machine_is_hrefv60()) + machine_is_hrefv60() || + machine_is_snowball()) ux500_uart_base = U8500_UART2_BASE; else if (machine_is_u5500()) ux500_uart_base = U5500_UART0_BASE; diff --git a/arch/arm/mach-ux500/usb.c b/arch/arm/mach-ux500/usb.c index 82e535953fd9..0a01cbdfe063 100644 --- a/arch/arm/mach-ux500/usb.c +++ b/arch/arm/mach-ux500/usb.c @@ -6,6 +6,7 @@ */ #include <linux/platform_device.h> #include <linux/usb/musb.h> +#include <linux/dma-mapping.h> #include <plat/ste_dma40.h> #include <mach/hardware.h> #include <mach/usb.h> |