diff options
author | Benn Pörscke <benn.porscke@stericsson.com> | 2011-12-16 15:04:55 +0100 |
---|---|---|
committer | Benn Pörscke <benn.porscke@stericsson.com> | 2011-12-16 15:04:55 +0100 |
commit | 93f379e6cfadfded0d262192ca69d1abc096d90e (patch) | |
tree | 43f180e31ee26ee94f7d2dd559132c30c6476b4d /arch/arm | |
parent | 77955e37bd395f789900b8e180991ad67cabd899 (diff) |
Squashandroid-20111223
Change-Id: I2fcf46d1fc4b0cd4c61e5be3654c43b80db86015
Diffstat (limited to 'arch/arm')
30 files changed, 671 insertions, 248 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 3b1c685136f..65d28aeb746 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1704,6 +1704,15 @@ config DEPRECATED_PARAM_STRUCT This was deprecated in 2001 and announced to live on for 5 years. Some old boot loaders still use this way. +config ARM_FLUSH_CONSOLE_ON_RESTART + bool "Force flush the console on restart" + help + If the console is locked while the system is rebooted, the messages + in the temporary logbuffer would not have propogated to all the + console drivers. This option forces the console lock to be + released if it failed to be acquired, which will cause all the + pending messages to be flushed. + endmenu menu "Boot options" diff --git a/arch/arm/configs/u8500_defconfig b/arch/arm/configs/u8500_defconfig index f7843f524d4..f79a8183120 100755 --- a/arch/arm/configs/u8500_defconfig +++ b/arch/arm/configs/u8500_defconfig @@ -312,7 +312,6 @@ CONFIG_USB_G_ANDROID=y CONFIG_AB8500_USB=y CONFIG_MMC=y CONFIG_MMC_UNSAFE_RESUME=y -CONFIG_MMC_CLKGATE=y CONFIG_MMC_PARANOID_SD_INIT=y # CONFIG_MMC_BLOCK_BOUNCE is not set CONFIG_MMC_ARMMMCI=y @@ -406,7 +405,6 @@ CONFIG_DEBUG_INFO=y CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_FUNCTION_TRACER=y CONFIG_DEBUG_USER=y -CONFIG_DYNAMIC_DEBUG=y CONFIG_KEYS=y CONFIG_CRYPTO_MD5=m CONFIG_CRYPTO_SHA1=m diff --git a/arch/arm/configs/u8500_snowball_android_defconfig b/arch/arm/configs/u8500_snowball_android_defconfig index 1c406674762..aabc8e9f7b4 100644 --- a/arch/arm/configs/u8500_snowball_android_defconfig +++ b/arch/arm/configs/u8500_snowball_android_defconfig @@ -190,7 +190,6 @@ CONFIG_USB_G_ANDROID=y CONFIG_AB8500_USB=y CONFIG_MMC=y CONFIG_MMC_UNSAFE_RESUME=y -CONFIG_MMC_CLKGATE=y CONFIG_MMC_PARANOID_SD_INIT=y # CONFIG_MMC_BLOCK_BOUNCE is not set CONFIG_MMC_ARMMMCI=y diff --git a/arch/arm/configs/u9500_defconfig b/arch/arm/configs/u9500_defconfig index d99b32e9f99..74817555488 100755 --- a/arch/arm/configs/u9500_defconfig +++ b/arch/arm/configs/u9500_defconfig @@ -315,7 +315,6 @@ CONFIG_USB_G_ANDROID=y CONFIG_AB8500_USB=y CONFIG_MMC=y CONFIG_MMC_UNSAFE_RESUME=y -CONFIG_MMC_CLKGATE=y CONFIG_MMC_PARANOID_SD_INIT=y # CONFIG_MMC_BLOCK_BOUNCE is not set CONFIG_MMC_ARMMMCI=y diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index ccc587dbb95..23db0a90003 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -30,6 +30,7 @@ #include <linux/uaccess.h> #include <linux/random.h> #include <linux/hw_breakpoint.h> +#include <linux/console.h> #include <asm/cacheflush.h> #include <asm/processor.h> @@ -90,8 +91,37 @@ static int __init hlt_setup(char *__unused) __setup("nohlt", nohlt_setup); __setup("hlt", hlt_setup); +#ifdef CONFIG_ARM_FLUSH_CONSOLE_ON_RESTART +void arm_machine_flush_console(void) +{ + printk("\n"); + pr_emerg("Restarting %s\n", linux_banner); + if (console_trylock()) { + console_unlock(); + return; + } + + mdelay(50); + + local_irq_disable(); + if (!console_trylock()) + pr_emerg("arm_restart: Console was locked! Busting\n"); + else + pr_emerg("arm_restart: Console was locked!\n"); + console_unlock(); +} +#else +void arm_machine_flush_console(void) +{ +} +#endif + void arm_machine_restart(char mode, const char *cmd) { + /* Flush the console to make sure all the relevant messages make it + * out to the console drivers */ + arm_machine_flush_console(); + /* Disable interrupts first */ local_irq_disable(); local_fiq_disable(); diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig index 27ff6c55bc1..0db5f1850b9 100644 --- a/arch/arm/mach-ux500/Kconfig +++ b/arch/arm/mach-ux500/Kconfig @@ -73,6 +73,32 @@ config KEYLAYOUT_LAYOUT2 endchoice +choice + prompt "DBx500 sched_clock" + +config DBX500_SCHED_CLOCK_PRCMU + bool "PRCMU Timer sched_clock" + depends on CLKSRC_DBX500_PRCMU + select CLKSRC_DBX500_PRCMU_SCHED_CLOCK + help + Use the always on PRCMU Timer as sched_clock + +config DB5500_MTIMER_SCHED_CLOCK + bool "MTIMER sched_clock" + depends on CLKSRC_DB5500_MTIMER + select CLKSRC_DB5500_MTIMER_SCHED_CLOCK + help + Use the always on MTIMER as sched_clock + +config DBX500_MTU_SCHED_CLOCK + bool "MTU sched_clock" + depends on HAS_MTU + select NOMADIK_MTU_SCHED_CLOCK + help + Use the Multi Timer Unit as the sched_clock. + +endchoice + config UX500_DEBUG_UART int "Ux500 UART to use for low-level debug" default 2 diff --git a/arch/arm/mach-ux500/board-mop500-mcde.c b/arch/arm/mach-ux500/board-mop500-mcde.c index fd51f357faa..9d61e9ac3e4 100644 --- a/arch/arm/mach-ux500/board-mop500-mcde.c +++ b/arch/arm/mach-ux500/board-mop500-mcde.c @@ -313,7 +313,7 @@ static struct mcde_display_device av8100_hdmi = { .port = &av8100_port2, .chnl_id = MCDE_CHNL_B, .fifo = MCDE_FIFO_B, - .default_pixel_format = MCDE_OVLYPIXFMT_RGB888, + .default_pixel_format = MCDE_OVLYPIXFMT_RGBA8888, .native_x_res = 1280, .native_y_res = 720, .dev = { diff --git a/arch/arm/mach-ux500/board-mop500-pins.c b/arch/arm/mach-ux500/board-mop500-pins.c index 6241d490f2f..9788e45ec59 100644 --- a/arch/arm/mach-ux500/board-mop500-pins.c +++ b/arch/arm/mach-ux500/board-mop500-pins.c @@ -13,6 +13,7 @@ #include <asm/mach-types.h> #include <plat/pincfg.h> #include <linux/gpio/nomadik.h> +#include <linux/mfd/ab8500/gpio.h> #include <mach/hardware.h> #include <mach/suspend.h> @@ -201,6 +202,12 @@ static pin_cfg_t snowball_pins[] = { /* MMC0: MicroSD card */ GPIO21_MC0_DAT31DIR | PIN_OUTPUT_HIGH, + /* Snowball buttons */ + GPIO32_GPIO | PIN_INPUT_PULLUP, /* User PB */ + GPIO151_GPIO | PIN_INPUT_PULLUP, /* J1 pin 8 */ + GPIO152_GPIO | PIN_INPUT_PULLUP, /* J1 pin 9 */ + GPIO162_GPIO | PIN_INPUT_PULLUP, /* J1 pin 14 */ + /* MMC2: LAN */ GPIO86_SM_ADQ0, GPIO87_SM_ADQ1, @@ -237,6 +244,7 @@ static pin_cfg_t snowball_pins[] = { /* WLAN/GBF */ GPIO171_GPIO | PIN_OUTPUT_HIGH,/* GBF_ENA */ + GPIO161_GPIO | PIN_OUTPUT_LOW, /* WLAN_PMU_EN */ GPIO215_GPIO | PIN_OUTPUT_LOW,/* WLAN_ENA */ GPIO216_GPIO | PIN_INPUT_PULLUP,/* WLAN_IRQ */ }; @@ -246,23 +254,31 @@ static pin_cfg_t snowball_pins[] = { */ static UX500_PINS(mop500_pins_i2c0, - GPIO147_I2C0_SCL, - GPIO148_I2C0_SDA, + GPIO147_I2C0_SCL | + PIN_SLPM_GPIO | PIN_SLPM_INPUT_NOPULL, + GPIO148_I2C0_SDA | + PIN_SLPM_GPIO | PIN_SLPM_INPUT_NOPULL, ); static UX500_PINS(mop500_pins_i2c1, - GPIO16_I2C1_SCL, - GPIO17_I2C1_SDA, + GPIO16_I2C1_SCL | + PIN_SLPM_GPIO | PIN_SLPM_INPUT_NOPULL, + GPIO17_I2C1_SDA | + PIN_SLPM_GPIO | PIN_SLPM_INPUT_NOPULL, ); static UX500_PINS(mop500_pins_i2c2, - GPIO10_I2C2_SDA, - GPIO11_I2C2_SCL, + GPIO10_I2C2_SDA | + PIN_SLPM_GPIO | PIN_SLPM_INPUT_NOPULL, + GPIO11_I2C2_SCL | + PIN_SLPM_GPIO | PIN_SLPM_INPUT_NOPULL, ); static UX500_PINS(mop500_pins_i2c3, - GPIO229_I2C3_SDA, - GPIO230_I2C3_SCL, + GPIO229_I2C3_SDA | + PIN_SLPM_GPIO | PIN_SLPM_INPUT_NOPULL, + GPIO230_I2C3_SCL | + PIN_SLPM_GPIO | PIN_SLPM_INPUT_NOPULL, ); static UX500_PINS(mop500_pins_mcde_tvout, @@ -431,6 +447,7 @@ static pin_cfg_t mop500_pins_common_power_save_bank0[] = { GPIO8_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, GPIO9_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + /* 10-11 - I2C2 */ GPIO10_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, GPIO11_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, @@ -439,8 +456,10 @@ static pin_cfg_t mop500_pins_common_power_save_bank0[] = { GPIO14_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, GPIO15_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + /* 16-17 - I2C1 */ GPIO16_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, GPIO17_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO18_GPIO | PIN_SLPM_OUTPUT_HIGH | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, GPIO19_GPIO | PIN_SLPM_OUTPUT_HIGH | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, @@ -473,6 +492,7 @@ static pin_cfg_t mop500_pins_common_power_save_bank0_href60[] = { GPIO8_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, GPIO9_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + /* 10-11 - I2C2 */ GPIO10_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, GPIO11_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, @@ -481,11 +501,12 @@ static pin_cfg_t mop500_pins_common_power_save_bank0_href60[] = { GPIO14_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, GPIO15_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + /* 16-17 - I2C1 */ GPIO16_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, GPIO17_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO18_GPIO | PIN_SLPM_OUTPUT_HIGH | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, GPIO19_GPIO | PIN_SLPM_OUTPUT_HIGH | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, - GPIO20_GPIO | PIN_SLPM_OUTPUT_HIGH | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, GPIO21_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, GPIO22_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, @@ -626,9 +647,11 @@ static pin_cfg_t mop500_pins_common_power_save_bank4[] = { GPIO145_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, GPIO146_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, - GPIO147_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + /* 147-148 - I2C0 */ + GPIO147_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, GPIO148_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO149_GPIO | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, GPIO150_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, GPIO151_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, @@ -813,6 +836,7 @@ static pin_cfg_t mop500_pins_common_power_save_bank7[] = { GPIO227_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, GPIO228_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + /* 229-230 - I2C3 */ GPIO229_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, GPIO230_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, }; @@ -824,6 +848,7 @@ static pin_cfg_t mop500_pins_common_power_save_bank7_href60[] = { GPIO227_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, GPIO228_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + /* 229-230 - I2C3 */ GPIO229_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, GPIO230_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, }; @@ -971,6 +996,15 @@ int pins_for_u9500(void) return 0; } +static UX500_PINS(mop500_offchip_gpio_cfg, + /* + * Workaround for auto shutdown of 3.2MHz oscillator during + * deep sleep. APESPICSn/GPIO37 must be floating on the board + * to use this fix. + */ + AB8500_PIN_GPIO37 | PIN_OUTPUT_HIGH, +); + void __init mop500_pins_init(void) { nmk_config_pins(mop500_pins_common, @@ -985,16 +1019,6 @@ void __init mop500_pins_init(void) ux500_pins_add(mop500_runtime_pins_old, ARRAY_SIZE(mop500_runtime_pins_old)); - 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)); - switch (pinsfor) { case PINS_FOR_U9500: nmk_config_pins(u9500_pins, ARRAY_SIZE(u9500_pins)); @@ -1006,7 +1030,26 @@ void __init mop500_pins_init(void) break; } + 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)); + suspend_set_pins_force_fn(mop500_pins_suspend_force, mop500_pins_suspend_force_mux); } +static int __init mop500_offchip_gpio_init(void) +{ + if (machine_is_hrefv60()) + ux500_offchip_gpio_init(&mop500_offchip_gpio_cfg); + + return 0; +} +/* Let gpio chip drivers initialize. */ +late_initcall(mop500_offchip_gpio_init); diff --git a/arch/arm/mach-ux500/board-mop500-regulators.c b/arch/arm/mach-ux500/board-mop500-regulators.c index 276d3d62512..62940ef78a5 100644 --- a/arch/arm/mach-ux500/board-mop500-regulators.c +++ b/arch/arm/mach-ux500/board-mop500-regulators.c @@ -13,6 +13,48 @@ #include <linux/regulator/ab8500.h> #include "board-mop500-regulators.h" +#ifdef CONFIG_REGULATOR_FIXED_VOLTAGE +/* + * GPIO regulator controlled by the ab8500 GPIO16 + */ +static struct regulator_consumer_supply gpio_wlan_vbat_consumers[] = { + /* for cg2900 chip */ + REGULATOR_SUPPLY("vdd", "cg2900-uart.0"), + /* for cw1200 chip */ + REGULATOR_SUPPLY("vdd", "cw1200_wlan"), +}; + +struct regulator_init_data gpio_wlan_vbat_regulator = { + .constraints = { + .name = "WLAN-VBAT", + .min_uV = 3600000, + .max_uV = 3600000, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(gpio_wlan_vbat_consumers), + .consumer_supplies = gpio_wlan_vbat_consumers, +}; + +/* + * GPIO regulator controlled by the ab8500 GPIO26 + */ +static struct regulator_consumer_supply gpio_en_3v3_consumers[] = { + /* for LAN chip */ + REGULATOR_SUPPLY("vdd33a", "smsc911x.0"), +}; + +struct regulator_init_data gpio_en_3v3_regulator = { + .constraints = { + .name = "EN-3V3", + .min_uV = 3300000, + .max_uV = 3300000, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(gpio_en_3v3_consumers), + .consumer_supplies = gpio_en_3v3_consumers, +}; +#endif + /* * TPS61052 regulator */ @@ -38,6 +80,10 @@ struct regulator_init_data tps61052_regulator = { }; static struct regulator_consumer_supply ab8500_vaux1_consumers[] = { + /* lps001wp baromenter i2c dev name is 2-005c + * maybe change that in the driver, like for lsm303dlh drivers + */ + REGULATOR_SUPPLY("vdd", "2-005c"), /* Main display, u8500 R3 uib */ REGULATOR_SUPPLY("vddi", "mcde_disp_sony_acx424akp.0"), /* Main display, u8500 uib and ST uib */ diff --git a/arch/arm/mach-ux500/board-mop500-regulators.h b/arch/arm/mach-ux500/board-mop500-regulators.h index 0b94969604d..ed309081e14 100644 --- a/arch/arm/mach-ux500/board-mop500-regulators.h +++ b/arch/arm/mach-ux500/board-mop500-regulators.h @@ -16,5 +16,7 @@ extern struct ab8500_regulator_platform_data ab8500_regulator_plat_data; extern struct regulator_init_data tps61052_regulator; +extern struct regulator_init_data gpio_wlan_vbat_regulator; +extern struct regulator_init_data gpio_en_3v3_regulator; #endif diff --git a/arch/arm/mach-ux500/board-mop500-sdi.c b/arch/arm/mach-ux500/board-mop500-sdi.c index 20be9e90eff..73de147832b 100644 --- a/arch/arm/mach-ux500/board-mop500-sdi.c +++ b/arch/arm/mach-ux500/board-mop500-sdi.c @@ -32,6 +32,11 @@ static int sdi0_vsel = -1; static int mop500_sdi0_ios_handler(struct device *dev, struct mmc_ios *ios) { + static int power_mode = -1; + + if (power_mode == ios->power_mode) + return 0; + switch (ios->power_mode) { case MMC_POWER_UP: case MMC_POWER_ON: @@ -53,6 +58,7 @@ static int mop500_sdi0_ios_handler(struct device *dev, struct mmc_ios *ios) break; } + power_mode = ios->power_mode; return 0; } diff --git a/arch/arm/mach-ux500/board-mop500-stuib.c b/arch/arm/mach-ux500/board-mop500-stuib.c index 44a6d299c9f..a42f8081c70 100644 --- a/arch/arm/mach-ux500/board-mop500-stuib.c +++ b/arch/arm/mach-ux500/board-mop500-stuib.c @@ -55,11 +55,6 @@ static struct adp1653_platform_data __initdata adp1653_pdata_u8500_uib = { static struct i2c_board_info __initdata mop500_i2c2_devices[] = { { - /* LSM303DLH Accelerometer */ - I2C_BOARD_INFO("lsm303dlh_a", 0x18), - .platform_data = &lsm303dlh_pdata, - }, - { /* LSM303DLH Magnetometer */ I2C_BOARD_INFO("lsm303dlh_m", 0x1E), .platform_data = &lsm303dlh_pdata, @@ -81,6 +76,30 @@ static struct i2c_board_info __initdata mop500_i2c2_devices[] = { }; /* + * Break this out due to the fact that this have changed address on Snowball + */ +static struct i2c_board_info __initdata mop500_2_i2c2_devices[] = { + { + /* LSM303DLH Accelerometer */ + I2C_BOARD_INFO("lsm303dlh_a", 0x18), + .platform_data = &lsm303dlh_pdata, + }, +}; + +/* + * This is needed due to the fact that the i2c address changed in Snowball V7 =< + * and there is no way of knowing if the HW is Snowball V7 or higher so we just + * have to try and fail. + */ +static struct i2c_board_info __initdata snowball_i2c2_devices[] = { + { + /* LSM303DLH Accelerometer */ + I2C_BOARD_INFO("lsm303dlh_a", 0x19), + .platform_data = &lsm303dlh_pdata, + }, +}; + +/* * ux500 keymaps * * Organized row-wise as on the UIB, starting at the top-left @@ -172,6 +191,37 @@ static struct i2c_board_info __initdata mop500_i2c0_devices_stuib[] = { }; /* + * Register/Add i2c sensors for Snowball + */ +void mop500_sensors_probe_add_lsm303dlh_a(void) +{ + static const int busnum = 2; + struct i2c_adapter *adap; + struct i2c_client *client; + static const unsigned short i2c_addr_list[] = { + 0x18, 0x19, I2C_CLIENT_END }; + struct i2c_board_info i2c_info = { + /* LSM303DLH Accelerometer */ + I2C_BOARD_INFO("lsm303dlh_a", 0), + .platform_data = &lsm303dlh_pdata, + }; + + adap = i2c_get_adapter(busnum); + if (!adap) { + /* We have no i2c adapter yet lets create it. */ + pr_err(__FILE__ ": Could not get adapter %d\n", busnum); + return; + } + client = i2c_new_probed_device(adap, &i2c_info, + i2c_addr_list, NULL); + if (!client) + pr_err(__FILE__ ": failed to register %s to i2c%d\n", + i2c_info.type, + busnum); + i2c_put_adapter(adap); +} + +/* * BU21013 ROHM touchscreen interface on the STUIBs */ @@ -342,4 +392,25 @@ void __init mop500_stuib_init(void) } mop500_uib_i2c_add(2, mop500_i2c2_devices, ARRAY_SIZE(mop500_i2c2_devices)); + + + if (machine_is_snowball()) { + if (cpu_is_u8500v21()) { + /* This is ugly but we cant know what address + * to use */ + printk("%s: **** Try to add Accelometer and cpu_is_u8500v21 \n", + __func__); + mop500_sensors_probe_add_lsm303dlh_a(); + } else {/* Add the accelerometer with new addr */ + printk("%s: **** Try to add Accelometer old way \n", + __func__); + mop500_uib_i2c_add(2, snowball_i2c2_devices, + ARRAY_SIZE(snowball_i2c2_devices)); + } + } else { /* none snowball have the old addr */ + printk("%s: **** Ops on snowball but not a snowball Accelometer\n", + __func__); + mop500_uib_i2c_add(2, mop500_2_i2c2_devices, + ARRAY_SIZE(mop500_2_i2c2_devices)); + } } diff --git a/arch/arm/mach-ux500/board-mop500-u8500uib.c b/arch/arm/mach-ux500/board-mop500-u8500uib.c index 9e1cafa8893..18d12083528 100644 --- a/arch/arm/mach-ux500/board-mop500-u8500uib.c +++ b/arch/arm/mach-ux500/board-mop500-u8500uib.c @@ -86,6 +86,7 @@ static struct synaptics_rmi4_platform_data rmi4_i2c_dev_platformdata = { .irq_type = (IRQF_TRIGGER_FALLING | IRQF_SHARED), .x_flip = false, .y_flip = true, + .regulator_en = true, }; static struct i2c_board_info __initdata mop500_i2c3_devices_u8500[] = { diff --git a/arch/arm/mach-ux500/board-mop500-wlan.c b/arch/arm/mach-ux500/board-mop500-wlan.c index 1e5c24ba1ea..3b15a4ef695 100644 --- a/arch/arm/mach-ux500/board-mop500-wlan.c +++ b/arch/arm/mach-ux500/board-mop500-wlan.c @@ -14,8 +14,14 @@ #include <plat/pincfg.h> #include "pins.h" #include <mach/cw1200_plat.h> +#include <linux/clk.h> static void cw1200_release(struct device *dev); +static int cw1200_clk_ctrl(const struct cw1200_platform_data *pdata, + bool enable); + +static int cw1200_power_ctrl(const struct cw1200_platform_data *pdata, + bool enable); static struct resource cw1200_href_resources[] = { { @@ -62,7 +68,9 @@ static struct resource cw1200_u9500_resources[] = { }, }; -static struct cw1200_platform_data cw1200_platform_data = { 0 }; +static struct cw1200_platform_data cw1200_platform_data = { + .clk_ctrl = cw1200_clk_ctrl, +}; static struct platform_device cw1200_device = { .name = "cw1200_wlan", @@ -73,6 +81,8 @@ static struct platform_device cw1200_device = { }, }; +static struct clk *clk_dev; + const struct cw1200_platform_data *cw1200_get_platform_data(void) { return &cw1200_platform_data; @@ -107,6 +117,68 @@ static int cw1200_pins_enable(bool enable) return ret; } +static int cw1200_clk_ctrl(const struct cw1200_platform_data *pdata, + bool enable) +{ + static const char *clock_name = "sys_clk_out"; + int ret = 0; + + if (enable) { + clk_dev = clk_get(&cw1200_device.dev, clock_name); + if (IS_ERR(clk_dev)) { + ret = PTR_ERR(clk_dev); + dev_warn(&cw1200_device.dev, + "%s: Failed to get clk '%s': %d\n", + __func__, clock_name, ret); + } else { + ret = clk_enable(clk_dev); + if (ret) { + clk_put(clk_dev); + dev_warn(&cw1200_device.dev, + "%s: Failed to enable clk '%s': %d\n", + __func__, clock_name, ret); + } + } + } else { + clk_disable(clk_dev); + clk_put(clk_dev); + } + + return ret; +} + +static int cw1200_power_ctrl(const struct cw1200_platform_data *pdata, + bool enable) +{ + static const char *vdd_name = "vdd"; + struct regulator *vdd; + int ret = 0; + + vdd = regulator_get(&cw1200_device.dev, vdd_name); + if (IS_ERR(vdd)) { + ret = PTR_ERR(vdd); + dev_warn(&cw1200_device.dev, + "%s: Failed to get regulator '%s': %d\n", + __func__, vdd_name, ret); + } else { + if (enable) + ret = regulator_enable(vdd); + else + ret = regulator_disable(vdd); + + if (ret) { + dev_warn(&cw1200_device.dev, + "%s: Failed to %s regulator '%s': %d\n", + __func__, enable ? "enable" : "disable", + vdd_name, ret); + } + regulator_put(vdd); + } + return ret; +} + + + int __init mop500_wlan_init(void) { int ret; @@ -114,7 +186,9 @@ int __init mop500_wlan_init(void) if (pins_for_u9500()) { cw1200_device.num_resources = ARRAY_SIZE(cw1200_u9500_resources); cw1200_device.resource = cw1200_u9500_resources; - } else if (machine_is_u8500() || machine_is_nomadik()) { + } else if (machine_is_u8500() || + machine_is_nomadik() || + machine_is_snowball()) { cw1200_device.num_resources = ARRAY_SIZE(cw1200_href_resources); cw1200_device.resource = cw1200_href_resources; } else if (machine_is_hrefv60()) { @@ -129,13 +203,19 @@ int __init mop500_wlan_init(void) return -ENOTSUPP; } - cw1200_platform_data.mmc_id = "mmc3"; + if (machine_is_snowball()) + cw1200_platform_data.mmc_id = "mmc2"; + else + cw1200_platform_data.mmc_id = "mmc3"; cw1200_platform_data.reset = &cw1200_device.resource[0]; cw1200_platform_data.irq = &cw1200_device.resource[1]; cw1200_device.dev.release = cw1200_release; + if (machine_is_snowball()) + cw1200_platform_data.power_ctrl = cw1200_power_ctrl; + ret = cw1200_pins_enable(true); if (WARN_ON(ret)) return ret; diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index 11b4ad69f91..4420adf0bd9 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -157,7 +157,7 @@ static struct abx500_accdet_platform_data ab8500_accdet_pdata = { static struct gpio_keys_button snowball_key_array[] = { { - .gpio = 32, + .gpio = SNOWBALL_USER_PB_GPIO, .type = EV_KEY, .code = KEY_1, .desc = "userpb", @@ -166,7 +166,7 @@ static struct gpio_keys_button snowball_key_array[] = { .wakeup = 1, }, { - .gpio = 151, + .gpio = SNOWBALL_J1_PIN_8_GPIO, .type = EV_KEY, .code = KEY_2, .desc = "extkb1", @@ -175,7 +175,7 @@ static struct gpio_keys_button snowball_key_array[] = { .wakeup = 1, }, { - .gpio = 152, + .gpio = SNOWBALL_J1_PIN_9_GPIO, .type = EV_KEY, .code = KEY_3, .desc = "extkb2", @@ -184,16 +184,7 @@ static struct gpio_keys_button snowball_key_array[] = { .wakeup = 1, }, { - .gpio = 161, - .type = EV_KEY, - .code = KEY_4, - .desc = "extkb3", - .active_low = 1, - .debounce_interval = 50, - .wakeup = 1, - }, - { - .gpio = 162, + .gpio = SNOWBALL_J1_PIN_14_GPIO, .type = EV_KEY, .code = KEY_5, .desc = "extkb4", @@ -463,6 +454,32 @@ static struct ske_keypad_platform_data mop500_ske_keypad_data = { #endif +#ifdef CONFIG_REGULATOR_FIXED_VOLTAGE +/* + * GPIO-regulator wlan vbat data + */ +static struct fixed_voltage_config snowball_gpio_wlan_vbat_data = { + .supply_name = "WLAN-VBAT", + .gpio = SNOWBALL_EN_3V6_GPIO, + .microvolts = 3600000, + .enable_high = 1, + .init_data = &gpio_wlan_vbat_regulator, + .startup_delay = 3500, /* Startup time */ +}; + +/* + * GPIO-regulator en 3v3 vbat data + */ + +static struct fixed_voltage_config snowball_gpio_en_3v3_data = { + .supply_name = "EN-3V3", + .gpio = SNOWBALL_EN_3V3_ETH_GPIO, + .microvolts = 3300000, + .enable_high = 1, + .init_data = &gpio_en_3v3_regulator, + .startup_delay = 5000, /* 1200us according to data sheet */ +}; +#endif /* * TC35892 @@ -615,6 +632,24 @@ static void __init mop500_i2c_init(void) db8500_add_i2c3(&u8500_i2c3_data); } +#ifdef CONFIG_REGULATOR_FIXED_VOLTAGE +static struct platform_device snowball_gpio_wlan_vbat_regulator_device = { + .name = "reg-fixed-voltage", + .id = 0, + .dev = { + .platform_data = &snowball_gpio_wlan_vbat_data, + }, +}; + +static struct platform_device snowball_gpio_en_3v3_regulator_device = { + .name = "reg-fixed-voltage", + .id = 1, + .dev = { + .platform_data = &snowball_gpio_en_3v3_data, + }, +}; +#endif + #ifdef CONFIG_UX500_GPIO_KEYS static struct gpio_keys_button mop500_gpio_keys[] = { { @@ -861,17 +896,20 @@ static struct cryp_platform_data u8500_cryp1_platform_data = { } }; +static struct stedma40_chan_cfg u8500_hash_dma_cfg_tx = { + .dir = STEDMA40_MEM_TO_PERIPH, + .src_dev_type = STEDMA40_DEV_SRC_MEMORY, + .dst_dev_type = DB8500_DMA_DEV50_HAC1_TX, + .src_info.data_width = STEDMA40_WORD_WIDTH, + .dst_info.data_width = STEDMA40_WORD_WIDTH, + .mode = STEDMA40_MODE_LOGICAL, + .src_info.psize = STEDMA40_PSIZE_LOG_16, + .dst_info.psize = STEDMA40_PSIZE_LOG_16, +}; + static struct hash_platform_data u8500_hash1_platform_data = { - .mem_to_engine = { - .dir = STEDMA40_MEM_TO_PERIPH, - .src_dev_type = STEDMA40_DEV_SRC_MEMORY, - .dst_dev_type = DB8500_DMA_DEV50_HAC1_TX, - .src_info.data_width = STEDMA40_WORD_WIDTH, - .dst_info.data_width = STEDMA40_WORD_WIDTH, - .mode = STEDMA40_MODE_LOGICAL, - .src_info.psize = STEDMA40_PSIZE_LOG_16, - .dst_info.psize = STEDMA40_PSIZE_LOG_16, - }, + .mem_to_engine = &u8500_hash_dma_cfg_tx, + .dma_filter = stedma40_filter, }; /* add any platform devices here - TODO */ @@ -1123,6 +1161,10 @@ static struct platform_device *snowball_platform_devs[] __initdata = { &ux500_hwmem_device, &snowball_led_dev, &snowball_key_dev, +#ifdef CONFIG_REGULATOR_FIXED_VOLTAGE + &snowball_gpio_en_3v3_regulator_device, + &snowball_gpio_wlan_vbat_regulator_device, +#endif &snowball_sbnet_dev, &ux500_mcde_device, &ux500_b2r2_device, @@ -1158,9 +1200,10 @@ static void __init mop500_init_machine(void) hsi_register_board_info(u8500_hsi_devices, ARRAY_SIZE(u8500_hsi_devices)); #endif +#ifdef CONFIG_LEDS_PWM if (uib_is_stuib()) u8500_leds_data.num_leds = 2; - +#endif if (machine_is_snowball()) { platform_add_devices(snowball_platform_devs, ARRAY_SIZE(snowball_platform_devs)); diff --git a/arch/arm/mach-ux500/board-mop500.h b/arch/arm/mach-ux500/board-mop500.h index 36dd0a17adb..53a04eee085 100644 --- a/arch/arm/mach-ux500/board-mop500.h +++ b/arch/arm/mach-ux500/board-mop500.h @@ -11,16 +11,6 @@ #include <linux/mfd/ab8500/gpio.h> #include <mach/gpio.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 - -/* Snowball specific GPIO assignments, this board has no GPIO expander */ -#define SNOWBALL_ACCEL_INT1_GPIO 163 -#define SNOWBALL_ACCEL_INT2_GPIO 164 -#define SNOWBALL_MAGNET_DRDY_GPIO 165 - /* HREFv60-specific GPIO assignments, this board has no GPIO expander */ #define HREFV60_TOUCH_RST_GPIO 143 #define HREFV60_PROX_SENSE_GPIO 217 @@ -60,6 +50,16 @@ #define GPIO_SDMMC_EN MOP500_EGPIO(17) #define GPIO_SDMMC_1V8_3V_SEL MOP500_EGPIO(18) +/* Snowball GPIO for MMC card */ +#define SNOWBALL_SDMMC_EN_GPIO 217 +#define SNOWBALL_SDMMC_1V8_3V_GPIO 228 +#define SNOWBALL_SDMMC_CD_GPIO 218 + +/* Snowball specific GPIO assignments, this board has no GPIO expander */ +#define SNOWBALL_ACCEL_INT1_GPIO 163 +#define SNOWBALL_ACCEL_INT2_GPIO 164 +#define SNOWBALL_MAGNET_DRDY_GPIO 165 + /*Snowball AB8500 GPIO */ #define SNOWBALL_VSMPS2_1V8_GPIO AB8500_PIN_GPIO1 /* SYSCLKREQ2/GPIO1 */ #define SNOWBALL_PM_GPIO1_GPIO AB8500_PIN_GPIO2 /* SYSCLKREQ3/GPIO2 */ @@ -69,6 +69,12 @@ #define SNOWBALL_PME_ETH_GPIO AB8500_PIN_GPIO24 /* SYSCLKREQ7/GPIO24 */ #define SNOWBALL_EN_3V3_ETH_GPIO AB8500_PIN_GPIO26 /* GPIO26 */ +/*Snowball buttons GPIO */ +#define SNOWBALL_USER_PB_GPIO 32 +#define SNOWBALL_J1_PIN_8_GPIO 151 /* AP_GPIO151 */ +#define SNOWBALL_J1_PIN_9_GPIO 152 /* AP_GPIO152 */ +#define SNOWBALL_J1_PIN_14_GPIO 162 /* AP_GPIO162 */ + struct i2c_board_info; extern void mop500_sdi_init(void); diff --git a/arch/arm/mach-ux500/board-u5500-regulators.c b/arch/arm/mach-ux500/board-u5500-regulators.c index eae7e4fee22..7dc77bd4074 100644 --- a/arch/arm/mach-ux500/board-u5500-regulators.c +++ b/arch/arm/mach-ux500/board-u5500-regulators.c @@ -117,9 +117,7 @@ ab5500_regulator_init_data[AB5500_NUM_REGULATORS] = { }, [AB5500_LDO_SIM] = { .constraints = { - .boot_on = 1, - .always_on = 1, - .min_uV = 2900000, + .min_uV = 1875000, .max_uV = 2900000, .apply_uV = 1, .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | diff --git a/arch/arm/mach-ux500/board-u5500-sdi.c b/arch/arm/mach-ux500/board-u5500-sdi.c index 475e41e0628..ac2a7aac93d 100644 --- a/arch/arm/mach-ux500/board-u5500-sdi.c +++ b/arch/arm/mach-ux500/board-u5500-sdi.c @@ -66,6 +66,11 @@ static struct mmci_platform_data u5500_sdi0_data = { static int u5500_sdi1_ios_handler(struct device *dev, struct mmc_ios *ios) { + static int power_mode = -1; + + if (power_mode == ios->power_mode) + return 0; + switch (ios->power_mode) { case MMC_POWER_UP: case MMC_POWER_ON: @@ -85,6 +90,7 @@ static int u5500_sdi1_ios_handler(struct device *dev, struct mmc_ios *ios) break; } + power_mode = ios->power_mode; return 0; } diff --git a/arch/arm/mach-ux500/board-u5500.c b/arch/arm/mach-ux500/board-u5500.c index b2056bd28bb..9b615de8fac 100644 --- a/arch/arm/mach-ux500/board-u5500.c +++ b/arch/arm/mach-ux500/board-u5500.c @@ -530,17 +530,20 @@ static struct cryp_platform_data u5500_cryp1_platform_data = { } }; +static struct stedma40_chan_cfg u5500_hash_dma_cfg_tx = { + .dir = STEDMA40_MEM_TO_PERIPH, + .src_dev_type = STEDMA40_DEV_SRC_MEMORY, + .dst_dev_type = DB5500_DMA_DEV50_HASH1_TX, + .src_info.data_width = STEDMA40_WORD_WIDTH, + .dst_info.data_width = STEDMA40_WORD_WIDTH, + .mode = STEDMA40_MODE_LOGICAL, + .src_info.psize = STEDMA40_PSIZE_LOG_16, + .dst_info.psize = STEDMA40_PSIZE_LOG_16, +}; + static struct hash_platform_data u5500_hash1_platform_data = { - .mem_to_engine = { -.dir = STEDMA40_MEM_TO_PERIPH, -.src_dev_type = STEDMA40_DEV_SRC_MEMORY, -.dst_dev_type = DB5500_DMA_DEV50_HASH1_TX, -.src_info.data_width = STEDMA40_WORD_WIDTH, -.dst_info.data_width = STEDMA40_WORD_WIDTH, -.mode = STEDMA40_MODE_LOGICAL, -.src_info.psize = STEDMA40_PSIZE_LOG_16, -.dst_info.psize = STEDMA40_PSIZE_LOG_16, -}, + .mem_to_engine = &u5500_hash_dma_cfg_tx, + .dma_filter = stedma40_filter, }; static struct platform_device *u5500_platform_devices[] __initdata = { diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index d2def0828a6..67330b8dd24 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c @@ -179,82 +179,3 @@ void __init u8500_init_devices(void) return ; } - -#ifdef CONFIG_SYS_SOC -#define U8500_BB_UID_BASE (U8500_BACKUPRAM1_BASE + 0xFC0) -#define U8500_BB_UID_LENGTH 5 - -static ssize_t ux500_get_machine(char *buf, struct sysfs_soc_info *si) -{ - return sprintf(buf, "DB%2x00\n", dbx500_id.partnumber); -} - -static ssize_t ux500_get_soc_id(char *buf, struct sysfs_soc_info *si) -{ - void __iomem *uid_base; - int i; - ssize_t sz = 0; - - if (dbx500_id.partnumber == 0x85) { - uid_base = __io_address(U8500_BB_UID_BASE); - for (i = 0; i < U8500_BB_UID_LENGTH; i++) - sz += sprintf(buf + sz, "%08x", readl(uid_base + i * sizeof(u32))); - sz += sprintf(buf + sz, "\n"); - } - else { - /* Don't know where it is located for U5500 */ - sz = sprintf(buf, "N/A\n"); - } - - return sz; -} - -static ssize_t ux500_get_revision(char *buf, struct sysfs_soc_info *si) -{ - unsigned int rev = dbx500_id.revision; - - if (rev == 0x01) - return sprintf(buf, "%s\n", "ED"); - else if (rev >= 0xA0) - return sprintf(buf, "%d.%d\n" , (rev >> 4) - 0xA + 1, rev & 0xf); - - return sprintf(buf, "%s", "Unknown\n"); -} - -static ssize_t ux500_get_process(char *buf, struct sysfs_soc_info *si) -{ - if (dbx500_id.process == 0x00) - return sprintf(buf, "Standard\n"); - - return sprintf(buf, "%02xnm\n", dbx500_id.process); -} - -static ssize_t ux500_get_reset_code(char *buf, struct sysfs_soc_info *si) -{ - return sprintf(buf, "0x%04x\n", prcmu_get_reset_code()); -} - -static ssize_t ux500_get_reset_reason(char *buf, struct sysfs_soc_info *si) -{ - return sprintf(buf, "%s\n", - reboot_reason_string(prcmu_get_reset_code())); -} - -static struct sysfs_soc_info soc_info[] = { - SYSFS_SOC_ATTR_CALLBACK("machine", ux500_get_machine), - SYSFS_SOC_ATTR_VALUE("family", "Ux500"), - SYSFS_SOC_ATTR_CALLBACK("soc_id", ux500_get_soc_id), - SYSFS_SOC_ATTR_CALLBACK("revision", ux500_get_revision), - SYSFS_SOC_ATTR_CALLBACK("process", ux500_get_process), - SYSFS_SOC_ATTR_CALLBACK("reset_code", ux500_get_reset_code), - SYSFS_SOC_ATTR_CALLBACK("reset_reason", ux500_get_reset_reason), -}; - -static int __init ux500_sys_soc_init(void) -{ - return register_sysfs_soc(soc_info, ARRAY_SIZE(soc_info)); -} - -module_init(ux500_sys_soc_init); -#endif - diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c index bfdebbeab3e..ec106bbdc48 100644 --- a/arch/arm/mach-ux500/cpu.c +++ b/arch/arm/mach-ux500/cpu.c @@ -9,6 +9,7 @@ #include <linux/io.h> #include <linux/clk.h> #include <linux/delay.h> +#include <linux/sys_soc.h> #include <linux/clksrc-dbx500-prcmu.h> #include <linux/mfd/dbx500-prcmu.h> @@ -155,3 +156,82 @@ static int ux500_l2x0_init(void) } early_initcall(ux500_l2x0_init); #endif + +#ifdef CONFIG_SYS_SOC +#define U8500_BB_UID_BASE (U8500_BACKUPRAM1_BASE + 0xFC0) +#define U8500_BB_UID_LENGTH 5 + +static ssize_t ux500_get_machine(char *buf, struct sysfs_soc_info *si) +{ + return sprintf(buf, "DB%2x00\n", dbx500_id.partnumber); +} + +static ssize_t ux500_get_soc_id(char *buf, struct sysfs_soc_info *si) +{ + void __iomem *uid_base; + int i; + ssize_t sz = 0; + + if (dbx500_id.partnumber == 0x85) { + uid_base = __io_address(U8500_BB_UID_BASE); + for (i = 0; i < U8500_BB_UID_LENGTH; i++) + sz += sprintf(buf + sz, "%08x", + readl(uid_base + i * sizeof(u32))); + sz += sprintf(buf + sz, "\n"); + } else { + /* Don't know where it is located for U5500 */ + sz = sprintf(buf, "N/A\n"); + } + + return sz; +} + +static ssize_t ux500_get_revision(char *buf, struct sysfs_soc_info *si) +{ + unsigned int rev = dbx500_id.revision; + + if (rev == 0x01) + return sprintf(buf, "%s\n", "ED"); + else if (rev >= 0xA0) + return sprintf(buf, "%d.%d\n" , + (rev >> 4) - 0xA + 1, rev & 0xf); + + return sprintf(buf, "%s", "Unknown\n"); +} + +static ssize_t ux500_get_process(char *buf, struct sysfs_soc_info *si) +{ + if (dbx500_id.process == 0x00) + return sprintf(buf, "Standard\n"); + + return sprintf(buf, "%02xnm\n", dbx500_id.process); +} + +static ssize_t ux500_get_reset_code(char *buf, struct sysfs_soc_info *si) +{ + return sprintf(buf, "0x%04x\n", prcmu_get_reset_code()); +} + +static ssize_t ux500_get_reset_reason(char *buf, struct sysfs_soc_info *si) +{ + return sprintf(buf, "%s\n", + reboot_reason_string(prcmu_get_reset_code())); +} + +static struct sysfs_soc_info soc_info[] = { + SYSFS_SOC_ATTR_CALLBACK("machine", ux500_get_machine), + SYSFS_SOC_ATTR_VALUE("family", "Ux500"), + SYSFS_SOC_ATTR_CALLBACK("soc_id", ux500_get_soc_id), + SYSFS_SOC_ATTR_CALLBACK("revision", ux500_get_revision), + SYSFS_SOC_ATTR_CALLBACK("process", ux500_get_process), + SYSFS_SOC_ATTR_CALLBACK("reset_code", ux500_get_reset_code), + SYSFS_SOC_ATTR_CALLBACK("reset_reason", ux500_get_reset_reason), +}; + +static int __init ux500_sys_soc_init(void) +{ + return register_sysfs_soc(soc_info, ARRAY_SIZE(soc_info)); +} + +module_init(ux500_sys_soc_init); +#endif diff --git a/arch/arm/mach-ux500/dma-db8500.c b/arch/arm/mach-ux500/dma-db8500.c index e4e33c5b655..5a6ff377f03 100644 --- a/arch/arm/mach-ux500/dma-db8500.c +++ b/arch/arm/mach-ux500/dma-db8500.c @@ -231,6 +231,9 @@ static struct stedma40_platform_data dma40_plat_data = { /* Audio is using physical channel 2 from MMDSP */ .disabled_channels = {2, -1}, .use_esram_lcla = true, + /* Physical channels for which HW LLI should not be used */ + .soft_lli_chans = NULL, + .num_of_soft_lli_chans = 0, }; #ifdef CONFIG_UX500_CONTEXT diff --git a/arch/arm/mach-ux500/include/mach/crypto-ux500.h b/arch/arm/mach-ux500/include/mach/crypto-ux500.h index 9d1e1c52c13..80c4620d633 100644 --- a/arch/arm/mach-ux500/include/mach/crypto-ux500.h +++ b/arch/arm/mach-ux500/include/mach/crypto-ux500.h @@ -5,6 +5,7 @@ * License terms: GNU General Public License (GPL) version 2 */ #ifndef _CRYPTO_UX500_H +#include <linux/dmaengine.h> #include <plat/ste_dma40.h> struct cryp_platform_data { @@ -13,7 +14,8 @@ struct cryp_platform_data { }; struct hash_platform_data { - struct stedma40_chan_cfg mem_to_engine; + void *mem_to_engine; + bool (*dma_filter)(struct dma_chan *chan, void *filter_param); }; #endif diff --git a/arch/arm/mach-ux500/include/mach/mbox_channels-db5500.h b/arch/arm/mach-ux500/include/mach/mbox_channels-db5500.h index 0b2fc604873..c29dfff0ff7 100644 --- a/arch/arm/mach-ux500/include/mach/mbox_channels-db5500.h +++ b/arch/arm/mach-ux500/include/mach/mbox_channels-db5500.h @@ -68,5 +68,13 @@ int mbox_channel_send(struct mbox_channel_msg *msg); */ int mbox_channel_revoke_messages(u16 channel); +/** + * mbox_channel_deregister - de-register given mailbox channel. + * @channel: Mailbox channel number. + * + * Returns 0 on success or a negative error code on error. + */ +int mbox_channel_deregister(u16 channel); + #endif /*INC_STE_MBOX_H*/ diff --git a/arch/arm/mach-ux500/pins.c b/arch/arm/mach-ux500/pins.c index 4738103646d..c506080a115 100644 --- a/arch/arm/mach-ux500/pins.c +++ b/arch/arm/mach-ux500/pins.c @@ -12,6 +12,7 @@ #include <linux/spinlock.h> #include <linux/err.h> #include <plat/pincfg.h> +#include <linux/gpio.h> #include "pins.h" @@ -87,6 +88,44 @@ void ux500_pins_put(struct ux500_pins *pins) WARN_ON(!pins); } +void __init ux500_offchip_gpio_init(struct ux500_pins *pins) +{ + int err; + int i; + int gpio; + int output; + int value; + pin_cfg_t cfg; + + for (i=0; i < pins->num; i++) { + cfg = pins->cfg[i]; + gpio = PIN_NUM(cfg); + output = PIN_DIR(cfg); + value = PIN_VAL(cfg); + + err = gpio_request(gpio, "offchip_gpio_init"); + if (err < 0) { + pr_err("pins: gpio_request for gpio=%d failed with" + "err: %d\n", gpio, err); + /* Pin already requested. Try to configure rest. */ + continue; + } + + if (!output) { + err = gpio_direction_input(gpio); + if (err < 0) + pr_err("pins: gpio_direction_input for gpio=%d" + "failed with err: %d\n", gpio, err); + } else { + err = gpio_direction_output(gpio, value); + if (err < 0) + pr_err("pins: gpio_direction_output for gpio=" + "%d failed with err: %d\n", gpio, err); + } + gpio_free(gpio); + } +} + #ifdef CONFIG_DEBUG_FS #include <linux/debugfs.h> #include <linux/seq_file.h> diff --git a/arch/arm/mach-ux500/pins.h b/arch/arm/mach-ux500/pins.h index 0fa65cc6b96..0d36af2e7d9 100644 --- a/arch/arm/mach-ux500/pins.h +++ b/arch/arm/mach-ux500/pins.h @@ -36,6 +36,7 @@ struct ux500_pin_lookup { }; void __init ux500_pins_add(struct ux500_pin_lookup *pl, size_t num); +void __init ux500_offchip_gpio_init(struct ux500_pins *pins); struct ux500_pins *ux500_pins_get(const char *name); int ux500_pins_enable(struct ux500_pins *pins); int ux500_pins_disable(struct ux500_pins *pins); diff --git a/arch/arm/mach-ux500/pm/context.c b/arch/arm/mach-ux500/pm/context.c index b22e3ad7fd1..8c339ff948e 100644 --- a/arch/arm/mach-ux500/pm/context.c +++ b/arch/arm/mach-ux500/pm/context.c @@ -7,7 +7,6 @@ * License terms: GNU General Public License (GPL) version 2 * */ - #include <linux/init.h> #include <linux/io.h> #include <linux/smp.h> @@ -112,7 +111,9 @@ * Periph clock cluster context */ #define PRCC_BCK_EN 0x00 +#define PRCC_BCK_DIS 0x04 #define PRCC_KCK_EN 0x08 +#define PRCC_KCK_DIS 0x08 #define PRCC_BCK_STATUS 0x10 #define PRCC_KCK_STATUS 0x14 @@ -206,7 +207,6 @@ static DEFINE_PER_CPU(u32 *, varm_registers_pointer); static DEFINE_PER_CPU(u32[128], varm_cp15_backup_stack); static DEFINE_PER_CPU(u32 *, varm_cp15_pointer); - static ATOMIC_NOTIFIER_HEAD(context_ape_notifier_list); static ATOMIC_NOTIFIER_HEAD(context_arm_notifier_list); @@ -271,10 +271,19 @@ static void restore_prcc(void) for (i = 0; i < UX500_NR_PRCC_BANKS; i++) { clk_enable(context_prcc[i].clk); + writel(~context_prcc[i].bus_clk, + context_prcc[i].base + PRCC_BCK_DIS); + writel(~context_prcc[i].kern_clk, + context_prcc[i].base + PRCC_KCK_DIS); + writel(context_prcc[i].bus_clk, context_prcc[i].base + PRCC_BCK_EN); writel(context_prcc[i].kern_clk, context_prcc[i].base + PRCC_KCK_EN); + /* + * Consider having a while over KCK/BCK_STATUS + * to check that all clocks get disabled/enabled + */ clk_disable(context_prcc[i].clk); } @@ -372,7 +381,6 @@ static void restore_tpiu(void) * * This is per cpu so it needs to be called for each one. */ - static void save_gic_if_cpu(struct context_gic_cpu *c_gic_cpu) { c_gic_cpu->ctrl = readl_relaxed(c_gic_cpu->base + GIC_CPU_CTRL); @@ -399,7 +407,6 @@ static void restore_gic_if_cpu(struct context_gic_cpu *c_gic_cpu) * * Save SPI (Shared Peripheral Interrupt) settings, IRQ 32-159. */ - static void save_gic_dist_common(void) { int i; @@ -437,7 +444,6 @@ static void save_gic_dist_common(void) */ static void restore_gic_dist_common(void) { - int i; for (i = 0; i < GIC_DIST_CONFIG_COMMON_NUM; i++) @@ -464,8 +470,6 @@ static void restore_gic_dist_common(void) context_gic_dist_common.base + GIC_DIST_ENABLE_NS); } - - /* * Save GIC Dist CPU registers * @@ -507,7 +511,6 @@ static void save_gic_dist_cpu(struct context_gic_dist_cpu *c_gic) */ static void restore_gic_dist_cpu(struct context_gic_dist_cpu *c_gic) { - int i; for (i = 0; i < GIC_DIST_CONFIG_CPU_NUM; i++) @@ -537,7 +540,6 @@ static void restore_gic_dist_cpu(struct context_gic_dist_cpu *c_gic) */ void context_gic_dist_disable_unneeded_irqs(void) { - writel(0xffffffff, context_gic_dist_common.base + GIC_DIST_ENABLE_CLEAR_0); @@ -558,7 +560,6 @@ void context_gic_dist_disable_unneeded_irqs(void) writel(0xffffffff, context_gic_dist_common.base + GIC_DIST_ENABLE_CLEAR_128); - } static void save_scu(void) @@ -611,7 +612,6 @@ void context_vape_save(void) save_tpiu(); save_prcc(); - } /* @@ -700,7 +700,6 @@ void context_gpio_restore(void) writel(gpio_save[i][6], gpio_bankaddr[i] + NMK_GPIO_SLPC); } - } /* @@ -759,9 +758,7 @@ void context_gpio_mux_safe_switch(bool begin) writel(rwimsc[i], gpio_bankaddr[i] + NMK_GPIO_RWIMSC); writel(fwimsc[i], gpio_bankaddr[i] + NMK_GPIO_FWIMSC); } - } - } /* @@ -803,7 +800,6 @@ void context_varm_restore_common(void) */ void context_varm_save_core(void) { - int cpu = smp_processor_id(); atomic_notifier_call_chain(&context_arm_notifier_list, @@ -816,7 +812,6 @@ void context_varm_save_core(void) save_gic_if_cpu(&per_cpu(context_gic_cpu, cpu)); save_gic_dist_cpu(&per_cpu(context_gic_dist_cpu, cpu)); context_save_cp15_registers(&per_cpu(varm_cp15_pointer, cpu)); - } /* @@ -837,7 +832,6 @@ void context_varm_restore_core(void) atomic_notifier_call_chain(&context_arm_notifier_list, CONTEXT_ARM_CORE_RESTORE, NULL); - } /* @@ -901,7 +895,6 @@ static int __init context_init(void) writel(virt_to_phys(ux500_backup_ptr), IO_ADDRESS(U8500_EXT_RAM_LOC_BACKUPRAM_ADDR)); - if (cpu_is_u5500()) { writel(IO_ADDRESS(U5500_PUBLIC_BOOT_ROM_BASE), IO_ADDRESS(U8500_CPU0_BACKUPRAM_ADDR_PUBLIC_BOOT_ROM_LOG_ADDR)); diff --git a/arch/arm/mach-ux500/product.c b/arch/arm/mach-ux500/product.c index 5e8eba9b16a..8fee45c411d 100644 --- a/arch/arm/mach-ux500/product.c +++ b/arch/arm/mach-ux500/product.c @@ -30,13 +30,12 @@ static struct tee_product_config product_config; bool ux500_jtag_enabled(void) { #ifdef CONFIG_UX500_DEBUG_NO_LAUTERBACH - return false; + return false; #else - if (cpu_is_u5500()) - return readl_relaxed(__io_address(U5500_PRCMU_DBG_PWRCTRL)) - & PRCMU_DBG_PWRCTRL_A9DBGCLKEN; - - if (cpu_is_u8500()) + if (cpu_is_u5500()) + return readl_relaxed(__io_address(U5500_PRCMU_DBG_PWRCTRL)) + & PRCMU_DBG_PWRCTRL_A9DBGCLKEN; + if (cpu_is_u8500()) return (product_config.rt_flags & TEE_RT_FLAGS_JTAG_ENABLED) == TEE_RT_FLAGS_JTAG_ENABLED; @@ -96,8 +95,35 @@ static int __init product_detect(void) goto error1; } + switch(product_config.product_id) { + case TEE_PRODUCT_ID_8400: + pr_info("ux500-product: u8400 detected\n"); + break; + case TEE_PRODUCT_ID_8500: + pr_info("ux500-product: u8500 detected\n"); + break; + case TEE_PRODUCT_ID_9500: + pr_info("ux500-product: u9500 detected\n"); + break; + case TEE_PRODUCT_ID_5500: + pr_info("ux500-product: u5500 detected\n"); + break; + case TEE_PRODUCT_ID_7400: + pr_info("ux500-product: u7400 detected\n"); + break; + case TEE_PRODUCT_ID_8500C: + pr_info("ux500-product: u8500C detected\n"); + break; + case TEE_PRODUCT_ID_UNKNOWN: + default: + pr_info("ux500-product: UNKNOWN! (0x%x) detected\n", + product_config.product_id); + break; + } pr_info("ux500-product: JTAG is %s\n", ux500_jtag_enabled()? "enabled" : "disabled"); + + error1: (void) teec_finalize_context(&context); error0: diff --git a/arch/arm/mach-ux500/usb.c b/arch/arm/mach-ux500/usb.c index 5ba1b4373aa..5baae5f06aa 100644 --- a/arch/arm/mach-ux500/usb.c +++ b/arch/arm/mach-ux500/usb.c @@ -96,7 +96,47 @@ static u64 ux500_musb_dmamask = DMA_BIT_MASK(0); #endif static struct ux500_pins *usb_gpio_pins; +/** + * Fifo mode + * Sum of maxpacket <= 12 KB + * As ux500 provides 12 KB buffer size only + * + * Enable Double buffer for Mass Storage Class + * endpoint. + */ +static struct musb_fifo_cfg ux500_mode_cfg[] = { +{ .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, .mode = BUF_DOUBLE, }, +{ .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, .mode = BUF_DOUBLE, }, +{ .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, .mode = BUF_DOUBLE, }, +{ .hw_ep_num = 2, .style = FIFO_RX, .maxpacket = 512, .mode = BUF_DOUBLE, }, +{ .hw_ep_num = 3, .style = FIFO_TX, .maxpacket = 512, }, +{ .hw_ep_num = 3, .style = FIFO_RX, .maxpacket = 512, }, +{ .hw_ep_num = 4, .style = FIFO_TX, .maxpacket = 512, }, +{ .hw_ep_num = 4, .style = FIFO_RX, .maxpacket = 512, }, +{ .hw_ep_num = 5, .style = FIFO_TX, .maxpacket = 512, }, +{ .hw_ep_num = 5, .style = FIFO_RX, .maxpacket = 512, }, +{ .hw_ep_num = 6, .style = FIFO_TX, .maxpacket = 32, }, +{ .hw_ep_num = 6, .style = FIFO_RX, .maxpacket = 32, }, +{ .hw_ep_num = 7, .style = FIFO_TX, .maxpacket = 32, }, +{ .hw_ep_num = 7, .style = FIFO_RX, .maxpacket = 32, }, +{ .hw_ep_num = 8, .style = FIFO_TX, .maxpacket = 32, }, +{ .hw_ep_num = 8, .style = FIFO_RX, .maxpacket = 32, }, +{ .hw_ep_num = 9, .style = FIFO_TX, .maxpacket = 32, }, +{ .hw_ep_num = 9, .style = FIFO_RX, .maxpacket = 32, }, +{ .hw_ep_num = 10, .style = FIFO_TX, .maxpacket = 32, }, +{ .hw_ep_num = 10, .style = FIFO_RX, .maxpacket = 32, }, +{ .hw_ep_num = 11, .style = FIFO_TX, .maxpacket = 32, }, +{ .hw_ep_num = 11, .style = FIFO_RX, .maxpacket = 32, }, +{ .hw_ep_num = 12, .style = FIFO_TX, .maxpacket = 32, }, +{ .hw_ep_num = 12, .style = FIFO_RX, .maxpacket = 32, }, +{ .hw_ep_num = 13, .style = FIFO_RXTX, .maxpacket = 512, }, +{ .hw_ep_num = 14, .style = FIFO_RXTX, .maxpacket = 1024, }, +{ .hw_ep_num = 15, .style = FIFO_RXTX, .maxpacket = 1024, }, +}; + static struct musb_hdrc_config musb_hdrc_config = { + .fifo_cfg = ux500_mode_cfg, /* Fifo configuration */ + .fifo_cfg_size = ARRAY_SIZE(ux500_mode_cfg), .multipoint = true, .dyn_fifo = true, .num_eps = 16, diff --git a/arch/arm/plat-nomadik/include/plat/ste_dma40.h b/arch/arm/plat-nomadik/include/plat/ste_dma40.h index ec716f24bac..c97d61425db 100644 --- a/arch/arm/plat-nomadik/include/plat/ste_dma40.h +++ b/arch/arm/plat-nomadik/include/plat/ste_dma40.h @@ -141,6 +141,12 @@ struct stedma40_chan_cfg { * @memcpy_conf_phy: default configuration of physical channel memcpy * @memcpy_conf_log: default configuration of logical channel memcpy * @disabled_channels: A vector, ending with -1, that marks physical channels + * @soft_lli_chans: A vector, that marks physical channels will use LLI by SW + * which avoids HW bug that exists in some versions of the + * controller. SoftLLI introduces relink overhead that could + * impact performace for certain use cases. + * @num_of_soft_lli_chans: The number of channels that needs to be configured + * to use SoftLLI. * @use_esram_lcla: flag for mapping the lcla into esram region * that are for different reasons not available for the driver. */ @@ -153,29 +159,13 @@ struct stedma40_platform_data { struct stedma40_chan_cfg *memcpy_conf_phy; struct stedma40_chan_cfg *memcpy_conf_log; int disabled_channels[STEDMA40_MAX_PHYS]; + int *soft_lli_chans; + int num_of_soft_lli_chans; bool use_esram_lcla; }; struct d40_desc; -/** - * struct stedma40_cyclic_desc - Cyclic DMA descriptor - * @d40d: DMA driver internal descriptor - * @period_callback: callback to be called after every link/period if - * the DMA_PREP_INTERRUPT flag is used when preparing - * the transaction - * @period_callback_param: handle passed to the period_callback - * - * A pointer to a structure of this type is returned from the - * stedma40_cyclic_prep_sg() function. The period_callback and - * period_callback_param members can be set by the client. - */ -struct stedma40_cyclic_desc { - struct d40_desc *d40d; - dma_async_tx_callback period_callback; - void *period_callback_param; -}; - int stedma40_set_dev_addr(struct dma_chan *chan, dma_addr_t src_dev_addr, dma_addr_t dst_dev_addr); @@ -199,52 +189,6 @@ dma_addr_t stedma40_get_src_addr(struct dma_chan *chan); dma_addr_t stedma40_get_dst_addr(struct dma_chan *chan); /** - * stedma40_cyclic_prep_sg - prepare a cyclic DMA transfer - * @chan: the DMA channel to prepare - * @sgl: scatter list - * @sg_len: number of links in the scatter list - * @direction: transfer direction, to or from device - * @dma_flags: DMA_PREP_INTERRUPT if a callback is required after every link. - * See period_callback in struct stedma40_cyclic_desc. - * - * Must be called before trying to start a cyclic DMA transfer. Returns - * ERR_PTR(-errno) on failure. - */ -struct stedma40_cyclic_desc * -stedma40_cyclic_prep_sg(struct dma_chan *chan, - struct scatterlist *sgl, - unsigned int sg_len, - enum dma_data_direction direction, - unsigned long dma_flags); - -/** - * stedma40_cyclic_start - start the cyclic DMA transfer - * @chan: the DMA channel to start - * - * The cyclic DMA must have been prepared earlier with - * stedma40_cyclic_prep_sg(). - */ -int stedma40_cyclic_start(struct dma_chan *chan); - -/** - * stedma40_cyclic_stop() - stop the cyclic DMA transfer - * @chan: the DMA channel to stop - * - * Stops a cyclic DMA transfer which was previously started with - * stedma40_cyclic_start(). - */ -void stedma40_cyclic_stop(struct dma_chan *chan); - -/** - * stedma40_cyclic_free() - free cyclic DMA resources - * @chan: the DMA channel - * - * Must be called to free any resources used for cyclic DMA which have been - * allocated in stedma40_cyclic_prep_sg(). - */ -void stedma40_cyclic_free(struct dma_chan *chan); - -/** * setdma40_residue() - Returna the remaining bytes to transfer. * * @chan: dmaengine handle |