diff options
author | Philippe Langlais <philippe.langlais@stericsson.com> | 2011-12-06 11:56:58 +0100 |
---|---|---|
committer | Philippe Langlais <philippe.langlais@stericsson.com> | 2011-12-06 11:56:58 +0100 |
commit | a45c0e513f98c6feb43248ccb8366c8b594cc7dc (patch) | |
tree | eb5f059bc2219eca4c4ed358da7877b507a89ad5 | |
parent | 84854e18bb413805c0c648db6e675f9d741bcc72 (diff) | |
parent | 7f680dd82f7619c42f8d41333e778483ca222831 (diff) |
Merge branch 'mach-plat' into linux-stable-ux500-3.1
61 files changed, 6600 insertions, 1348 deletions
diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig index a3e0c8692f0..a3a0dd9f60f 100644 --- a/arch/arm/mach-ux500/Kconfig +++ b/arch/arm/mach-ux500/Kconfig @@ -4,20 +4,25 @@ config UX500_SOC_COMMON bool default y select ARM_GIC - select HAS_MTU + select NOMADIK_GPIO select ARM_ERRATA_753970 select ARM_ERRATA_754322 + select SYS_SOC + select HAS_MTU + +config UX500_SOC_DBX500 + depends on UX500_SOC_DB5500 || UX500_SOC_DB8500 + bool menu "Ux500 SoC" config UX500_SOC_DB5500 bool "DB5500" - select MFD_DB5500_PRCMU + select UX500_SOC_DBX500 config UX500_SOC_DB8500 bool "DB8500" - select MFD_DB8500_PRCMU - select REGULATOR_DB8500_PRCMU + select UX500_SOC_DBX500 endmenu @@ -26,13 +31,13 @@ menu "Ux500 target platform (boards)" config MACH_U8500 bool "U8500 Development platform" depends on UX500_SOC_DB8500 - select TPS6105X help Include support for the mop500 development platform. config MACH_HREFV60 bool "U85000 Development platform, HREFv60 version" depends on UX500_SOC_DB8500 + select MACH_U8500 help Include support for the HREFv60 new development platform. @@ -50,6 +55,24 @@ config MACH_U5500 Include support for the U5500 development platform. endmenu +choice + prompt "Ux500 UIB Keylayout" + default KEYLAYOUT_LAYOUT1 + +config KEYLAYOUT_LAYOUT1 + bool "UIB Keylayout 1; for generic users" + help + Supported keylayout for some numerics, power/call buttons, + volume control etc + +config KEYLAYOUT_LAYOUT2 + bool "UIB Keylayout 2; for connectivity users" + help + Supports keylayout numerics 0-9, left/right/up/down/back/ + enter keys and special character "."(dot) + +endchoice + config UX500_DEBUG_UART int "Ux500 UART to use for low-level debug" default 2 @@ -57,6 +80,13 @@ config UX500_DEBUG_UART Choose the UART on which kernel low-level debug messages should be output. +config SENSORS1P_MOP + tristate "HAL and Proximity sensors support" + depends on REGULATOR && (GPIO_STMPE2401 || GPIO_TC35892) + help + Add support for Osram's SFH7741 Proximity Sensor and Samsumg + HED54XXU11 HAL Switch + config U5500_MODEM_IRQ bool "Modem IRQ support" depends on UX500_SOC_DB5500 @@ -64,11 +94,48 @@ config U5500_MODEM_IRQ help Add support for handling IRQ:s from modem side -config U5500_MBOX - bool "Mailbox support" - depends on U5500_MODEM_IRQ +config DBX500_PRCMU_DEBUG + bool "DBX500 PRCMU debug" + depends on ((MFD_DB5500_PRCMU || MFD_DB8500_PRCMU) && DEBUG_FS) + help + Add support for PRCMU debug + +config TEE_UX500 + bool "Trusted Execution Environment (TEE) ux500 hardware support" + depends on TEE_SUPPORT default y help - Add support for U5500 mailbox communication with modem side + Adds TEE hardware support for ux500 platforms. + +config TEE_SVP + bool "Trusted Execution Environment (TEE) ux500 SVP support" + depends on TEE_SUPPORT && UX500_SVP + default y + help + Adds TEE support for SVP in ux500 platforms. + +config UX500_DEBUG_HWREG + bool "Debug hardware registers from userspace" + depends on (DEBUG_FS && UX500_SOC_DB8500) + help + Adds various debug files to access registers. + This should never ever be used for anything else than debugging. + +config UX500_DEBUG_NO_LAUTERBACH + bool "Disable clocks needed for Lauterbach debugging" + help + Disable clocks needed for Lauterbach debugging at boot. + If yes, you will reduce the power consumption. + +config UX500_L2X0_PREFETCH_CTRL + bool "PL310 prefetch control" + depends on (UX500_SOC_DB8500 || UX500_SOC_DB5500) && \ + (TEE_UX500 && CACHE_L2X0) + default y + help + Adds interface to control instruction and data prefetch. + Communication with Trustzone is done through TEE driver. + +source "arch/arm/mach-ux500/pm/Kconfig" endif diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile index 1694916e682..128377f4078 100644 --- a/arch/arm/mach-ux500/Makefile +++ b/arch/arm/mach-ux500/Makefile @@ -1,20 +1,70 @@ # -# Makefile for the linux kernel, U8500 machine. +# Makefile for the linux kernel, UX500 machine. # -obj-y := clock.o cpu.o devices.o devices-common.o \ - id.o usb.o -obj-$(CONFIG_UX500_SOC_DB5500) += cpu-db5500.o dma-db5500.o -obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o +obj-y := clock.o cpu.o devices.o \ + devices-common.o id.o pins.o \ + usb.o reboot_reasons.o timer.o \ + uart-db8500.o clock-debug.o +obj-y += pm/ + + + +ifeq ($(CONFIG_UX500_SOC_DB5500), y) +obj-$(CONFIG_UX500_SOC_DBX500) += cpu-db5500.o dma-db5500.o \ + devices-db5500.o clock-db5500.o +endif +ifeq ($(CONFIG_UX500_SOC_DB8500), y) +obj-$(CONFIG_UX500_SOC_DBX500) += cpu-db8500.o devices-db8500.o \ + clock-db8500.o dma-db8500.o +endif obj-$(CONFIG_MACH_U8500) += board-mop500.o board-mop500-sdi.o \ board-mop500-regulators.o \ board-mop500-uib.o board-mop500-stuib.o \ - board-mop500-u8500uib.o \ - board-mop500-pins.o -obj-$(CONFIG_MACH_U5500) += board-u5500.o board-u5500-sdi.o + board-mop500-u8500uib.o board-mop500-pins.o \ + board-mop500-bm.o \ + board-pins-sleep-force.o +obj-$(CONFIG_SENSORS1P_MOP) += sensors1p.o +obj-$(CONFIG_MACH_U5500) += board-u5500.o board-u5500-sdi.o \ + board-u5500-regulators.o \ + board-u5500-pins.o +obj-$(CONFIG_U5500_MMIO) += board-u5500-mmio.o +obj-$(CONFIG_U8500_MMIO) += board-mop500-mmio.o obj-$(CONFIG_SMP) += platsmp.o headsmp.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o obj-$(CONFIG_U5500_MODEM_IRQ) += modem-irq-db5500.o -obj-$(CONFIG_U5500_MBOX) += mbox-db5500.o +obj-$(CONFIG_TEE_UX500) += tee_ux500.o product.o +obj-$(CONFIG_TEE_SVP) += tee_service_svp.o +obj-$(CONFIG_TEE_SVP) += tee_ta_start_modem_svp.o +obj-$(CONFIG_DB8500_MLOADER) += mloader-db8500.o +obj-$(CONFIG_U5500_MLOADER) += mloader-db5500.o +obj-$(CONFIG_UX500_DEBUG_HWREG) += hwreg.o +obj-$(CONFIG_HWMEM) += hwmem-int.o +obj-$(CONFIG_UX500_L2X0_PREFETCH_CTRL) += l2x0-prefetch.o +obj-$(CONFIG_AB5500_BM) += board-u5500-bm.o +obj-$(CONFIG_DBX500_PRCMU_DEBUG) += prcmu-debug.o + +obj-$(CONFIG_HWMEM) += dcache.o +ifdef CONFIG_STM_TRACE +obj-$(CONFIG_MACH_U8500) += board-mop500-stm.o +endif +ifdef CONFIG_SENSORS_LSM303DLH +obj-$(CONFIG_MACH_U8500) += board-mop500-sensors.o +endif +ifdef CONFIG_FB_MCDE +obj-$(CONFIG_MACH_U8500) += board-mop500-mcde.o +obj-$(CONFIG_MACH_U5500) += board-u5500-mcde.o +endif +ifdef CONFIG_STM_MSP_I2S +obj-$(CONFIG_MACH_U8500) += board-mop500-msp.o +endif +ifdef CONFIG_CW1200 +obj-$(CONFIG_MACH_U8500) += board-mop500-wlan.o +obj-$(CONFIG_MACH_U5500) += board-u5500-wlan.o +endif +ifdef CONFIG_TOUCHSCREEN_CYTTSP_SPI +obj-$(CONFIG_MACH_U8500) += board-mop500-cyttsp.o +obj-$(CONFIG_MACH_U5500) += board-u5500-cyttsp.o +endif diff --git a/arch/arm/mach-ux500/board-mop500-cyttsp.c b/arch/arm/mach-ux500/board-mop500-cyttsp.c new file mode 100755 index 00000000000..2aa27ea9b1f --- /dev/null +++ b/arch/arm/mach-ux500/board-mop500-cyttsp.c @@ -0,0 +1,226 @@ +/* + * Copyright (C) 2011 ST-Ericsson SA + * Author: Avinash A <avinash.a@stericsson.com> for ST-Ericsson + * License terms:GNU General Public License (GPL) version 2 + */ +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/spi/spi.h> +#include <linux/gpio.h> +#include <linux/cyttsp.h> +#include <linux/delay.h> +#include <linux/gpio/nomadik.h> +#include <linux/i2c.h> +#include <linux/input/matrix_keypad.h> +#include <linux/mfd/tc3589x.h> +#include <linux/mfd/dbx500-prcmu.h> +#include <linux/amba/pl022.h> +#include <plat/pincfg.h> +#include <mach/hardware.h> +#include <mach/irqs.h> +#include <mach/irqs-db8500.h> +#include "pins-db8500.h" +#include "board-mop500.h" +#include "devices-db8500.h" + +#define NUM_SSP_CLIENTS 10 + +/* cyttsp_gpio_board_init : configures the touch panel. */ +static int cyttsp_plat_init(int on) +{ + int ret; + + ret = gpio_direction_output(CYPRESS_SLAVE_SELECT_GPIO, 1); + if (ret < 0) { + pr_err("slave select gpio direction failed\n"); + gpio_free(CYPRESS_SLAVE_SELECT_GPIO); + return ret; + } + return 0; +} + +static struct pl022_ssp_controller mop500_spi2_data = { + .bus_id = SPI023_2_CONTROLLER, + .num_chipselect = NUM_SSP_CLIENTS, +}; + +static int cyttsp_wakeup(void) +{ + int ret; + + ret = gpio_request(CYPRESS_TOUCH_INT_PIN, "Wakeup_pin"); + if (ret < 0) { + pr_err("touch gpio failed\n"); + return ret; + } + ret = gpio_direction_output(CYPRESS_TOUCH_INT_PIN, 1); + if (ret < 0) { + pr_err("touch gpio direction failed\n"); + goto out; + } + gpio_set_value(CYPRESS_TOUCH_INT_PIN, 0); + gpio_set_value(CYPRESS_TOUCH_INT_PIN, 1); + /* + * To wake up the controller from sleep + * state the interrupt pin needs to be + * pulsed twice with a delay greater + * than 2 micro seconds. + */ + udelay(3); + gpio_set_value(CYPRESS_TOUCH_INT_PIN, 0); + gpio_set_value(CYPRESS_TOUCH_INT_PIN, 1); + ret = gpio_direction_input(CYPRESS_TOUCH_INT_PIN); + if (ret < 0) { + pr_err("touch gpio direction IN config failed\n"); + goto out; + } +out: + gpio_free(CYPRESS_TOUCH_INT_PIN); + return 0; +} +struct cyttsp_platform_data cyttsp_platdata = { + .maxx = 480, + .maxy = 854, + .flags = 0, + .gen = CY_GEN3, + .use_st = 0, + .use_mt = 1, + .use_trk_id = 0, + .use_hndshk = 0, + .use_sleep = 1, + .use_gestures = 0, + .use_load_file = 0, + .use_force_fw_update = 0, + .use_virtual_keys = 0, + /* activate up to 4 groups and set active distance */ + .gest_set = CY_GEST_GRP_NONE | CY_ACT_DIST, + /* change scn_type to enable finger and/or stylus detection */ + .scn_typ = 0xA5, /* autodetect finger+stylus; balanced mutual scan */ + .act_intrvl = CY_ACT_INTRVL_DFLT, /* Active refresh interval; ms */ + .tch_tmout = CY_TCH_TMOUT_DFLT, /* Active touch timeout; ms */ + .lp_intrvl = CY_LP_INTRVL_DFLT, /* Low power refresh interval; ms */ + .init = cyttsp_plat_init, + .mt_sync = input_mt_sync, + .wakeup = cyttsp_wakeup, + .name = CY_SPI_NAME, + .irq_gpio = CYPRESS_TOUCH_INT_PIN, + .rst_gpio = CYPRESS_TOUCH_RST_GPIO, +}; + +static void cyttsp_spi_cs_control(u32 command) +{ + if (command == SSP_CHIP_SELECT) + gpio_set_value(CYPRESS_SLAVE_SELECT_GPIO, 0); + else if (command == SSP_CHIP_DESELECT) + gpio_set_value(CYPRESS_SLAVE_SELECT_GPIO, 1); +} + +static struct pl022_config_chip cyttsp_ssp_config_chip = { + .com_mode = INTERRUPT_TRANSFER, + .iface = SSP_INTERFACE_MOTOROLA_SPI, + /* we can act as master only */ + .hierarchy = SSP_MASTER, + .slave_tx_disable = 0, + .rx_lev_trig = SSP_RX_1_OR_MORE_ELEM, + .tx_lev_trig = SSP_TX_16_OR_MORE_EMPTY_LOC, + .ctrl_len = SSP_BITS_16, + .wait_state = SSP_MWIRE_WAIT_ZERO, + .duplex = SSP_MICROWIRE_CHANNEL_FULL_DUPLEX, + .cs_control = cyttsp_spi_cs_control, +}; + +static struct spi_board_info cypress_spi_devices[] = { + { + .modalias = CY_SPI_NAME, + .controller_data = &cyttsp_ssp_config_chip, + .platform_data = &cyttsp_platdata, + .max_speed_hz = 1000000, + .bus_num = SPI023_2_CONTROLLER, + .chip_select = 0, + .mode = SPI_MODE_0, + } +}; + +/* + * TC35893 + */ +static const unsigned int sony_keymap[] = { + KEY(3, 1, KEY_END), + KEY(4, 1, KEY_HOME), + KEY(6, 4, KEY_VOLUMEDOWN), + KEY(4, 2, KEY_EMAIL), + KEY(3, 3, KEY_RIGHT), + KEY(2, 5, KEY_BACKSPACE), + + KEY(6, 7, KEY_MENU), + KEY(5, 0, KEY_ENTER), + KEY(4, 3, KEY_0), + KEY(3, 4, KEY_DOT), + KEY(5, 2, KEY_UP), + KEY(3, 5, KEY_DOWN), + + KEY(4, 5, KEY_SEND), + KEY(0, 5, KEY_BACK), + KEY(6, 2, KEY_VOLUMEUP), + KEY(1, 3, KEY_SPACE), + KEY(7, 6, KEY_LEFT), + KEY(5, 5, KEY_SEARCH), +}; + +static struct matrix_keymap_data sony_keymap_data = { + .keymap = sony_keymap, + .keymap_size = ARRAY_SIZE(sony_keymap), +}; + +static struct tc3589x_keypad_platform_data tc35893_data = { + .krow = TC_KPD_ROWS, + .kcol = TC_KPD_COLUMNS, + .debounce_period = TC_KPD_DEBOUNCE_PERIOD, + .settle_time = TC_KPD_SETTLE_TIME, + .irqtype = IRQF_TRIGGER_FALLING, + .enable_wakeup = true, + .keymap_data = &sony_keymap_data, + .no_autorepeat = true, +}; + +static struct tc3589x_platform_data tc3589x_keypad_data = { + .block = TC3589x_BLOCK_KEYPAD, + .keypad = &tc35893_data, + .irq_base = MOP500_EGPIO_IRQ_BASE, +}; + +static struct i2c_board_info __initdata mop500_i2c0_devices_u8500[] = { + { + I2C_BOARD_INFO("tc3589x", 0x44), + .platform_data = &tc3589x_keypad_data, + .irq = NOMADIK_GPIO_TO_IRQ(64), + .flags = I2C_CLIENT_WAKE, + }, +}; + +void mop500_cyttsp_init(void) +{ + int ret = 0; + + /* + * Enable the alternative C function + * in the PRCMU register + */ + prcmu_enable_spi2(); + ret = gpio_request(CYPRESS_SLAVE_SELECT_GPIO, "slave_select_gpio"); + if (ret < 0) + pr_err("slave select gpio failed\n"); + spi_register_board_info(cypress_spi_devices, + ARRAY_SIZE(cypress_spi_devices)); +} + +void __init mop500_u8500uib_r3_init(void) +{ + mop500_cyttsp_init(); + db8500_add_spi2(&mop500_spi2_data); + nmk_config_pin((GPIO64_GPIO | PIN_INPUT_PULLUP), false); + mop500_uib_i2c_add(0, mop500_i2c0_devices_u8500, + ARRAY_SIZE(mop500_i2c0_devices_u8500)); + mop500_uib_i2c_add(0, mop500_i2c0_devices_u8500, + ARRAY_SIZE(mop500_i2c0_devices_u8500)); +} diff --git a/arch/arm/mach-ux500/board-mop500-pins.c b/arch/arm/mach-ux500/board-mop500-pins.c index f26fd76f72b..3d32e9b059e 100644 --- a/arch/arm/mach-ux500/board-mop500-pins.c +++ b/arch/arm/mach-ux500/board-mop500-pins.c @@ -7,24 +7,29 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/gpio.h> +#include <linux/io.h> +#include <linux/string.h> #include <asm/mach-types.h> #include <plat/pincfg.h> +#include <linux/gpio/nomadik.h> + #include <mach/hardware.h> +#include <mach/suspend.h> #include "pins-db8500.h" +#include "pins.h" -static pin_cfg_t mop500_pins_common[] = { - /* I2C */ - GPIO147_I2C0_SCL, - GPIO148_I2C0_SDA, - GPIO16_I2C1_SCL, - GPIO17_I2C1_SDA, - GPIO10_I2C2_SDA, - GPIO11_I2C2_SCL, - GPIO229_I2C3_SDA, - GPIO230_I2C3_SCL, +#include "board-pins-sleep-force.h" +enum custom_pin_cfg_t { + PINS_FOR_DEFAULT, + PINS_FOR_U9500, +}; + +static enum custom_pin_cfg_t pinsfor; + +static pin_cfg_t mop500_pins_common[] = { /* MSP0 */ GPIO12_MSP0_TXD, GPIO13_MSP0_TFS, @@ -32,83 +37,20 @@ static pin_cfg_t mop500_pins_common[] = { GPIO15_MSP0_RXD, /* MSP2: HDMI */ - GPIO193_MSP2_TXD, - GPIO194_MSP2_TCK, - GPIO195_MSP2_TFS, + GPIO193_MSP2_TXD | PIN_INPUT_PULLDOWN, + GPIO194_MSP2_TCK | PIN_INPUT_PULLDOWN, + GPIO195_MSP2_TFS | PIN_INPUT_PULLDOWN, GPIO196_MSP2_RXD | PIN_OUTPUT_LOW, + /* LCD TE0 */ + GPIO68_LCD_VSI0 | PIN_INPUT_PULLUP, + /* Touch screen INTERFACE */ GPIO84_GPIO | PIN_INPUT_PULLUP, /* TOUCH_INT1 */ /* STMPE1601/tc35893 keypad IRQ */ GPIO218_GPIO | PIN_INPUT_PULLUP, - /* MMC0 (MicroSD card) */ - GPIO18_MC0_CMDDIR | PIN_OUTPUT_HIGH, - GPIO19_MC0_DAT0DIR | PIN_OUTPUT_HIGH, - GPIO20_MC0_DAT2DIR | PIN_OUTPUT_HIGH, - - GPIO22_MC0_FBCLK | PIN_INPUT_NOPULL, - GPIO23_MC0_CLK | PIN_OUTPUT_LOW, - GPIO24_MC0_CMD | PIN_INPUT_PULLUP, - GPIO25_MC0_DAT0 | PIN_INPUT_PULLUP, - GPIO26_MC0_DAT1 | PIN_INPUT_PULLUP, - GPIO27_MC0_DAT2 | PIN_INPUT_PULLUP, - GPIO28_MC0_DAT3 | PIN_INPUT_PULLUP, - - /* SDI1 (SDIO) */ - GPIO208_MC1_CLK | PIN_OUTPUT_LOW, - GPIO209_MC1_FBCLK | PIN_INPUT_NOPULL, - GPIO210_MC1_CMD | PIN_INPUT_PULLUP, - GPIO211_MC1_DAT0 | PIN_INPUT_PULLUP, - GPIO212_MC1_DAT1 | PIN_INPUT_PULLUP, - GPIO213_MC1_DAT2 | PIN_INPUT_PULLUP, - GPIO214_MC1_DAT3 | PIN_INPUT_PULLUP, - - /* MMC2 (On-board DATA INTERFACE eMMC) */ - GPIO128_MC2_CLK | PIN_OUTPUT_LOW, - GPIO129_MC2_CMD | PIN_INPUT_PULLUP, - GPIO130_MC2_FBCLK | PIN_INPUT_NOPULL, - GPIO131_MC2_DAT0 | PIN_INPUT_PULLUP, - GPIO132_MC2_DAT1 | PIN_INPUT_PULLUP, - GPIO133_MC2_DAT2 | PIN_INPUT_PULLUP, - GPIO134_MC2_DAT3 | PIN_INPUT_PULLUP, - GPIO135_MC2_DAT4 | PIN_INPUT_PULLUP, - GPIO136_MC2_DAT5 | PIN_INPUT_PULLUP, - GPIO137_MC2_DAT6 | PIN_INPUT_PULLUP, - GPIO138_MC2_DAT7 | PIN_INPUT_PULLUP, - - /* MMC4 (On-board STORAGE INTERFACE eMMC) */ - GPIO197_MC4_DAT3 | PIN_INPUT_PULLUP, - GPIO198_MC4_DAT2 | PIN_INPUT_PULLUP, - GPIO199_MC4_DAT1 | PIN_INPUT_PULLUP, - GPIO200_MC4_DAT0 | PIN_INPUT_PULLUP, - GPIO201_MC4_CMD | PIN_INPUT_PULLUP, - GPIO202_MC4_FBCLK | PIN_INPUT_NOPULL, - GPIO203_MC4_CLK | PIN_OUTPUT_LOW, - GPIO204_MC4_DAT7 | PIN_INPUT_PULLUP, - GPIO205_MC4_DAT6 | PIN_INPUT_PULLUP, - GPIO206_MC4_DAT5 | PIN_INPUT_PULLUP, - GPIO207_MC4_DAT4 | PIN_INPUT_PULLUP, - - /* SKE keypad */ - GPIO153_KP_I7, - GPIO154_KP_I6, - GPIO155_KP_I5, - GPIO156_KP_I4, - GPIO157_KP_O7, - GPIO158_KP_O6, - GPIO159_KP_O5, - GPIO160_KP_O4, - GPIO161_KP_I3, - GPIO162_KP_I2, - GPIO163_KP_I1, - GPIO164_KP_I0, - GPIO165_KP_O3, - GPIO166_KP_O2, - GPIO167_KP_O1, - GPIO168_KP_O0, - /* UART */ /* uart-0 pins gpio configuration should be * kept intact to prevent glitch in tx line @@ -128,9 +70,14 @@ static pin_cfg_t mop500_pins_common[] = { GPIO31_U2_CTSn | PIN_INPUT_PULLUP, GPIO32_U2_RTSn | PIN_OUTPUT_HIGH, - /* Display & HDMI HW sync */ - GPIO68_LCD_VSI0 | PIN_INPUT_PULLUP, - GPIO69_LCD_VSI1 | PIN_INPUT_PULLUP, + /* HSI */ + GPIO219_HSIR_FLA0, + GPIO220_HSIR_DAT0, + GPIO221_HSIR_RDY0, + GPIO222_HSIT_FLA0, + GPIO223_HSIT_DAT0, + GPIO224_HSIT_RDY0, + GPIO225_GPIO | PIN_INPUT_PULLDOWN, /* CA_WAKE0 */ }; static pin_cfg_t mop500_pins_default[] = { @@ -140,10 +87,13 @@ static pin_cfg_t mop500_pins_default[] = { GPIO145_SSP0_RXD | PIN_PULL_DOWN, GPIO146_SSP0_TXD, + /* XENON Flashgun INTERFACE */ + GPIO6_IP_GPIO0 | PIN_INPUT_PULLUP,/* XENON_FLASH_ID */ + GPIO7_IP_GPIO1 | PIN_INPUT_PULLUP,/* XENON_READY */ GPIO217_GPIO | PIN_INPUT_PULLUP, /* TC35892 IRQ */ - /* SDI0 (MicroSD card) */ + /* sdi0 (removable MMC/SD/SDIO cards) not handled by pm_runtime */ GPIO21_MC0_DAT31DIR | PIN_OUTPUT_HIGH, /* UART */ @@ -155,13 +105,11 @@ static pin_cfg_t mop500_pins_default[] = { static pin_cfg_t mop500_pins_hrefv60[] = { /* WLAN */ - GPIO4_GPIO | PIN_INPUT_PULLUP,/* WLAN_IRQ */ GPIO85_GPIO | PIN_OUTPUT_LOW,/* WLAN_ENA */ /* XENON Flashgun INTERFACE */ GPIO6_IP_GPIO0 | PIN_INPUT_PULLUP,/* XENON_FLASH_ID */ GPIO7_IP_GPIO1 | PIN_INPUT_PULLUP,/* XENON_READY */ - GPIO170_GPIO | PIN_OUTPUT_LOW, /* XENON_CHARGE */ /* Assistant LED INTERFACE */ GPIO21_GPIO | PIN_OUTPUT_LOW, /* XENON_EN1 */ @@ -172,7 +120,7 @@ static pin_cfg_t mop500_pins_hrefv60[] = { GPIO32_GPIO | PIN_INPUT_PULLDOWN, /* Magnetometer DRDY */ /* Display Interface */ - GPIO65_GPIO | PIN_OUTPUT_LOW, /* DISP1 RST */ + GPIO65_GPIO | PIN_OUTPUT_HIGH, /* DISP1 NO RST */ GPIO66_GPIO | PIN_OUTPUT_LOW, /* DISP2 RST */ /* Touch screen INTERFACE */ @@ -218,7 +166,7 @@ static pin_cfg_t mop500_pins_hrefv60[] = { GPIO145_GPIO | PIN_INPUT_PULLDOWN,/* HAL_SW */ /* Audio Amplifier Interface */ - GPIO149_GPIO | PIN_OUTPUT_LOW, /* VAUDIO_HF_EN */ + GPIO149_GPIO | PIN_OUTPUT_HIGH, /* VAUDIO_HF_EN, enable MAX8968 */ /* GBF INTERFACE */ GPIO171_GPIO | PIN_OUTPUT_LOW, /* GBF_ENA_RESET */ @@ -233,7 +181,20 @@ static pin_cfg_t mop500_pins_hrefv60[] = { /* Proximity Sensor */ GPIO217_GPIO | PIN_INPUT_PULLUP, + /* SD card detect */ + GPIO95_GPIO | PIN_INPUT_PULLUP, +}; +static pin_cfg_t u9500_pins[] = { + GPIO4_U1_RXD | PIN_INPUT_PULLUP, + GPIO5_U1_TXD | PIN_OUTPUT_HIGH, + GPIO144_GPIO | PIN_INPUT_PULLUP,/* WLAN_IRQ */ + GPIO226_GPIO | PIN_OUTPUT_HIGH, /* HSI AC_WAKE0 */ +}; + +static pin_cfg_t u8500_pins[] = { + GPIO226_GPIO | PIN_OUTPUT_LOW, /* WLAN_PMU_EN */ + GPIO4_GPIO | PIN_INPUT_PULLUP,/* WLAN_IRQ */ }; static pin_cfg_t snowball_pins[] = { @@ -274,12 +235,704 @@ static pin_cfg_t snowball_pins[] = { /* RSTn_LAN */ GPIO141_GPIO | PIN_OUTPUT_HIGH, + + /* Accelerometer/Magnetometer */ + GPIO163_GPIO | PIN_INPUT_PULLUP, /* ACCEL_IRQ1 */ + GPIO164_GPIO | PIN_INPUT_PULLUP, /* ACCEL_IRQ2 */ + GPIO165_GPIO | PIN_INPUT_PULLUP, /* MAG_DRDY */ + + /* WLAN/GBF */ + GPIO171_GPIO | PIN_OUTPUT_HIGH,/* GBF_ENA */ + GPIO215_GPIO | PIN_OUTPUT_LOW,/* WLAN_ENA */ + GPIO216_GPIO | PIN_INPUT_PULLUP,/* WLAN_IRQ */ }; +/* + * I2C + */ + +static UX500_PINS(mop500_pins_i2c0, + GPIO147_I2C0_SCL, + GPIO148_I2C0_SDA, +); + +static UX500_PINS(mop500_pins_i2c1, + GPIO16_I2C1_SCL, + GPIO17_I2C1_SDA, +); + +static UX500_PINS(mop500_pins_i2c2, + GPIO10_I2C2_SDA, + GPIO11_I2C2_SCL, +); + +static UX500_PINS(mop500_pins_i2c3, + GPIO229_I2C3_SDA, + GPIO230_I2C3_SCL, +); + +static UX500_PINS(mop500_pins_mcde_dpi, + GPIO64_LCDB_DE, + GPIO65_LCDB_HSO, + GPIO66_LCDB_VSO, + GPIO67_LCDB_CLK, + GPIO70_LCD_D0, + GPIO71_LCD_D1, + GPIO72_LCD_D2, + GPIO73_LCD_D3, + GPIO74_LCD_D4, + GPIO75_LCD_D5, + GPIO76_LCD_D6, + GPIO77_LCD_D7, + GPIO153_LCD_D24, + GPIO154_LCD_D25, + GPIO155_LCD_D26, + GPIO156_LCD_D27, + GPIO157_LCD_D28, + GPIO158_LCD_D29, + GPIO159_LCD_D30, + GPIO160_LCD_D31, + GPIO161_LCD_D32, + GPIO162_LCD_D33, + GPIO163_LCD_D34, + GPIO164_LCD_D35, + GPIO165_LCD_D36, + GPIO166_LCD_D37, + GPIO167_LCD_D38, + GPIO168_LCD_D39, +); + +static UX500_PINS(mop500_pins_mcde_tvout, + GPIO78_LCD_D8, + GPIO79_LCD_D9, + GPIO80_LCD_D10, + GPIO81_LCD_D11, + GPIO150_LCDA_CLK, +); + +static UX500_PINS(mop500_pins_mcde_hdmi, + GPIO69_LCD_VSI1 | PIN_INPUT_PULLUP, +); + +static UX500_PINS(mop500_pins_ske, + GPIO153_KP_I7 | PIN_INPUT_PULLDOWN | PIN_SLPM_INPUT_PULLUP, + GPIO154_KP_I6 | PIN_INPUT_PULLDOWN | PIN_SLPM_INPUT_PULLUP, + GPIO155_KP_I5 | PIN_INPUT_PULLDOWN | PIN_SLPM_INPUT_PULLUP, + GPIO156_KP_I4 | PIN_INPUT_PULLDOWN | PIN_SLPM_INPUT_PULLUP, + GPIO161_KP_I3 | PIN_INPUT_PULLDOWN | PIN_SLPM_INPUT_PULLUP, + GPIO162_KP_I2 | PIN_INPUT_PULLDOWN | PIN_SLPM_INPUT_PULLUP, + GPIO163_KP_I1 | PIN_INPUT_PULLDOWN | PIN_SLPM_INPUT_PULLUP, + GPIO164_KP_I0 | PIN_INPUT_PULLDOWN | PIN_SLPM_INPUT_PULLUP, + GPIO157_KP_O7 | PIN_INPUT_PULLUP | PIN_SLPM_OUTPUT_LOW, + GPIO158_KP_O6 | PIN_INPUT_PULLUP | PIN_SLPM_OUTPUT_LOW, + GPIO159_KP_O5 | PIN_INPUT_PULLUP | PIN_SLPM_OUTPUT_LOW, + GPIO160_KP_O4 | PIN_INPUT_PULLUP | PIN_SLPM_OUTPUT_LOW, + GPIO165_KP_O3 | PIN_INPUT_PULLUP | PIN_SLPM_OUTPUT_LOW, + GPIO166_KP_O2 | PIN_INPUT_PULLUP | PIN_SLPM_OUTPUT_LOW, + GPIO167_KP_O1 | PIN_INPUT_PULLUP | PIN_SLPM_OUTPUT_LOW, + GPIO168_KP_O0 | PIN_INPUT_PULLUP | PIN_SLPM_OUTPUT_LOW, +); + +/* sdi0 (removable MMC/SD/SDIO cards) */ +static UX500_PINS(mop500_pins_sdi0, + GPIO18_MC0_CMDDIR | PIN_OUTPUT_HIGH, + GPIO19_MC0_DAT0DIR | PIN_OUTPUT_HIGH, + GPIO20_MC0_DAT2DIR | PIN_OUTPUT_HIGH, + + GPIO22_MC0_FBCLK | PIN_INPUT_NOPULL, + GPIO23_MC0_CLK | PIN_OUTPUT_LOW, + GPIO24_MC0_CMD | PIN_INPUT_PULLUP, + GPIO25_MC0_DAT0 | PIN_INPUT_PULLUP, + GPIO26_MC0_DAT1 | PIN_INPUT_PULLUP, + GPIO27_MC0_DAT2 | PIN_INPUT_PULLUP, + GPIO28_MC0_DAT3 | PIN_INPUT_PULLUP, +); + +/* sdi1 (WLAN CW1200) */ +static UX500_PINS(mop500_pins_sdi1, + GPIO208_MC1_CLK | PIN_OUTPUT_LOW, + GPIO209_MC1_FBCLK | PIN_INPUT_NOPULL, + GPIO210_MC1_CMD | PIN_INPUT_PULLUP, + GPIO211_MC1_DAT0 | PIN_INPUT_PULLUP, + GPIO212_MC1_DAT1 | PIN_INPUT_PULLUP, + GPIO213_MC1_DAT2 | PIN_INPUT_PULLUP, + GPIO214_MC1_DAT3 | PIN_INPUT_PULLUP, +); + +/* sdi2 (POP eMMC) */ +static UX500_PINS(mop500_pins_sdi2, + GPIO128_MC2_CLK | PIN_OUTPUT_LOW, + GPIO129_MC2_CMD | PIN_INPUT_PULLUP, + GPIO130_MC2_FBCLK | PIN_INPUT_NOPULL, + GPIO131_MC2_DAT0 | PIN_INPUT_PULLUP, + GPIO132_MC2_DAT1 | PIN_INPUT_PULLUP, + GPIO133_MC2_DAT2 | PIN_INPUT_PULLUP, + GPIO134_MC2_DAT3 | PIN_INPUT_PULLUP, + GPIO135_MC2_DAT4 | PIN_INPUT_PULLUP, + GPIO136_MC2_DAT5 | PIN_INPUT_PULLUP, + GPIO137_MC2_DAT6 | PIN_INPUT_PULLUP, + GPIO138_MC2_DAT7 | PIN_INPUT_PULLUP, +); + +/* sdi4 (PCB eMMC) */ +static UX500_PINS(mop500_pins_sdi4, + GPIO197_MC4_DAT3 | PIN_INPUT_PULLUP, + GPIO198_MC4_DAT2 | PIN_INPUT_PULLUP, + GPIO199_MC4_DAT1 | PIN_INPUT_PULLUP, + GPIO200_MC4_DAT0 | PIN_INPUT_PULLUP, + GPIO201_MC4_CMD | PIN_INPUT_PULLUP, + GPIO202_MC4_FBCLK | PIN_INPUT_NOPULL, + GPIO203_MC4_CLK | PIN_OUTPUT_LOW, + GPIO204_MC4_DAT7 | PIN_INPUT_PULLUP, + GPIO205_MC4_DAT6 | PIN_INPUT_PULLUP, + GPIO206_MC4_DAT5 | PIN_INPUT_PULLUP, + GPIO207_MC4_DAT4 | PIN_INPUT_PULLUP, +); + +/* USB */ +static UX500_PINS(mop500_pins_usb, + GPIO256_USB_NXT, + GPIO257_USB_STP | PIN_OUTPUT_HIGH, + GPIO258_USB_XCLK, + GPIO259_USB_DIR, + GPIO260_USB_DAT7, + GPIO261_USB_DAT6, + GPIO262_USB_DAT5, + GPIO263_USB_DAT4, + GPIO264_USB_DAT3, + GPIO265_USB_DAT2, + GPIO266_USB_DAT1, + GPIO267_USB_DAT0, +); + +/* SPI2 */ +static UX500_PINS(mop500_pins_spi2, + GPIO216_GPIO | PIN_OUTPUT_HIGH, + GPIO218_SPI2_RXD | PIN_INPUT_PULLDOWN, + GPIO215_SPI2_TXD | PIN_OUTPUT_LOW, + GPIO217_SPI2_CLK | PIN_OUTPUT_LOW, +); + +static struct ux500_pin_lookup mop500_pins[] = { + PIN_LOOKUP("mcde-dpi", &mop500_pins_mcde_dpi), + PIN_LOOKUP("mcde-tvout", &mop500_pins_mcde_tvout), + PIN_LOOKUP("av8100-hdmi", &mop500_pins_mcde_hdmi), + PIN_LOOKUP("nmk-i2c.0", &mop500_pins_i2c0), + PIN_LOOKUP("nmk-i2c.1", &mop500_pins_i2c1), + PIN_LOOKUP("nmk-i2c.2", &mop500_pins_i2c2), + PIN_LOOKUP("nmk-i2c.3", &mop500_pins_i2c3), + PIN_LOOKUP("ske", &mop500_pins_ske), + PIN_LOOKUP("sdi0", &mop500_pins_sdi0), + PIN_LOOKUP("sdi1", &mop500_pins_sdi1), + PIN_LOOKUP("sdi2", &mop500_pins_sdi2), + PIN_LOOKUP("sdi4", &mop500_pins_sdi4), + PIN_LOOKUP("ab8500-usb.0", &mop500_pins_usb), + PIN_LOOKUP("spi2", &mop500_pins_spi2), +}; + +/* + * Sleep pin configuration for u8500 platform. + * If another HW is used the GPIO's must be configured + * correctly when entering sleep for optimal power + * consumption. + */ +static pin_cfg_t mop500_pins_common_power_save_bank0[] = { + GPIO0_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO1_GPIO | PIN_SLPM_OUTPUT_HIGH | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO2_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO3_GPIO | PIN_SLPM_DIR_OUTPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO4_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO5_GPIO | PIN_SLPM_OUTPUT_HIGH | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO6_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO7_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + 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, + 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, + + GPIO12_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO13_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + 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, + + 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, + GPIO23_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO24_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO25_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO26_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO27_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO28_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO29_U2_RXD | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_ENABLED, + GPIO30_U2_TXD | PIN_SLPM_DIR_OUTPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO31_U2_CTSn | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_ENABLED, +}; + +static pin_cfg_t mop500_pins_common_power_save_bank0_href60[] = { + GPIO0_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO1_GPIO | PIN_SLPM_OUTPUT_HIGH | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO2_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO3_GPIO | PIN_SLPM_DIR_OUTPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO4_GPIO | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO5_GPIO | PIN_SLPM_OUTPUT_HIGH | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO6_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO7_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + 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, + 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, + + GPIO12_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO13_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + 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, + + 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, + GPIO23_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO24_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO25_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO26_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO27_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO28_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO29_U2_RXD | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_ENABLED, + GPIO30_U2_TXD | PIN_SLPM_DIR_OUTPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO31_U2_CTSn | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_ENABLED, +}; + +static pin_cfg_t mop500_pins_common_power_save_bank1[] = { + GPIO32_U2_RTSn | PIN_SLPM_DIR_OUTPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO33_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO34_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO35_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO36_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, +}; + +static pin_cfg_t mop500_pins_common_power_save_bank2[] = { + GPIO64_GPIO | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO65_GPIO | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO66_GPIO | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO67_GPIO | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO68_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO69_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO70_STMAPE_CLK | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_DISABLE | PIN_SLPM_PDIS_DISABLED, + GPIO71_STMAPE_DAT3 | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_DISABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO72_STMAPE_DAT2 | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_DISABLE | PIN_SLPM_PDIS_DISABLED, + GPIO73_STMAPE_DAT1 | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_DISABLE | PIN_SLPM_PDIS_DISABLED, + GPIO74_STMAPE_DAT0 | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_DISABLE | PIN_SLPM_PDIS_DISABLED, + GPIO75_U2_RXD | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO76_U2_TXD | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO77_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO78_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO79_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO80_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO81_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO82_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO83_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO84_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO85_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO86_GPIO | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO87_GPIO | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO88_GPIO | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO89_GPIO | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO90_GPIO | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO91_GPIO | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO92_GPIO | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO93_GPIO | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO94_GPIO | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO95_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, +}; + +static pin_cfg_t mop500_pins_common_power_save_bank2_href60[] = { + GPIO64_GPIO | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO65_GPIO | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO66_GPIO | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO67_GPIO | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO68_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO69_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO70_STMAPE_CLK | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_DISABLE | PIN_SLPM_PDIS_DISABLED, + GPIO71_STMAPE_DAT3 | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_DISABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO72_STMAPE_DAT2 | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_DISABLE | PIN_SLPM_PDIS_DISABLED, + GPIO73_STMAPE_DAT1 | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_DISABLE | PIN_SLPM_PDIS_DISABLED, + GPIO74_STMAPE_DAT0 | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_DISABLE | PIN_SLPM_PDIS_DISABLED, + GPIO75_U2_RXD | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO76_U2_TXD | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO77_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO78_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO79_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO80_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO81_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO82_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO83_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO84_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO85_GPIO, + GPIO86_GPIO | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO87_GPIO | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO88_GPIO | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO89_GPIO | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO90_GPIO | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO91_GPIO | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO92_GPIO | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO93_GPIO | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO94_GPIO | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO95_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, +}; + +static pin_cfg_t mop500_pins_common_power_save_bank3[] = { + GPIO96_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO97_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, +}; + +static pin_cfg_t mop500_pins_common_power_save_bank4[] = { + GPIO128_MC2_CLK | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO129_MC2_CMD | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_ENABLED, + GPIO130_MC2_FBCLK | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_ENABLED, + GPIO131_MC2_DAT0 | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO132_MC2_DAT1 | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO133_MC2_DAT2 | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO134_MC2_DAT3 | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO135_MC2_DAT4 | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO136_MC2_DAT5 | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO137_MC2_DAT6 | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO138_MC2_DAT7 | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO139_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO140_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO141_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO142_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO143_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO144_GPIO | PIN_SLPM_OUTPUT_HIGH | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + 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, + + 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, + + GPIO152_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO153_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO154_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO155_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO156_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO157_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO158_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO159_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, +}; + +static pin_cfg_t mop500_pins_common_power_save_bank5[] = { + GPIO160_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO161_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO162_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO163_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO164_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO165_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO166_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO167_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO168_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO169_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO170_GPIO | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO171_GPIO | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, +}; + +static pin_cfg_t mop500_pins_common_power_save_bank5_href60[] = { + GPIO160_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO161_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO162_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO163_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO164_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO165_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO166_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO167_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO168_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO169_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO170_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO171_GPIO | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, +}; + +static pin_cfg_t mop500_pins_common_power_save_bank6[] = { + GPIO192_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO193_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO194_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO195_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO196_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO197_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO198_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO199_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO200_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO201_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO202_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO203_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO204_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO205_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO206_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO207_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO208_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO209_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO210_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO211_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO212_GPIO, + GPIO213_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO214_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO215_GPIO, + + GPIO216_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO217_GPIO | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO218_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO219_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO220_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO221_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO222_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO223_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, +}; + +static pin_cfg_t mop500_pins_common_power_save_bank6_href60[] = { + GPIO192_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO193_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO194_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO195_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO196_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO197_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO198_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO199_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO200_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO201_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO202_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO203_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO204_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO205_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO206_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO207_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO208_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO209_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO210_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO211_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO212_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO213_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO214_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO215_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO216_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO217_GPIO | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO218_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO219_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + + GPIO220_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO221_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO222_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO223_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, +}; + +static pin_cfg_t mop500_pins_common_power_save_bank7[] = { + GPIO224_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO225_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO226_GPIO | PIN_SLPM_DIR_OUTPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + 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, + 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, +}; + +static pin_cfg_t mop500_pins_common_power_save_bank7_href60[] = { + GPIO224_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO225_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO226_GPIO | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + 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, + 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, +}; + +static pin_cfg_t mop500_pins_common_power_save_bank8[] = { + GPIO256_GPIO | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_ENABLED, + GPIO257_GPIO | PIN_SLPM_OUTPUT_HIGH | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO258_GPIO | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_ENABLED, + GPIO259_GPIO | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_ENABLED, + + GPIO260_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_ENABLED, + GPIO261_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_ENABLED, + GPIO262_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_ENABLED, + GPIO263_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_ENABLED, + + GPIO264_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_ENABLED, + GPIO265_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_ENABLED, + GPIO266_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_ENABLED, + GPIO267_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_ENABLED, +}; + +static void mop500_pins_suspend_force(void) +{ + if (machine_is_hrefv60()) + sleep_pins_config_pm(mop500_pins_common_power_save_bank0_href60, + ARRAY_SIZE(mop500_pins_common_power_save_bank0_href60)); + else + sleep_pins_config_pm(mop500_pins_common_power_save_bank0, + ARRAY_SIZE(mop500_pins_common_power_save_bank0)); + + sleep_pins_config_pm(mop500_pins_common_power_save_bank1, + ARRAY_SIZE(mop500_pins_common_power_save_bank1)); + + if (machine_is_hrefv60()) + sleep_pins_config_pm(mop500_pins_common_power_save_bank2_href60, + ARRAY_SIZE(mop500_pins_common_power_save_bank2_href60)); + else + sleep_pins_config_pm(mop500_pins_common_power_save_bank2, + ARRAY_SIZE(mop500_pins_common_power_save_bank2)); + + sleep_pins_config_pm(mop500_pins_common_power_save_bank3, + ARRAY_SIZE(mop500_pins_common_power_save_bank3)); + + sleep_pins_config_pm(mop500_pins_common_power_save_bank4, + ARRAY_SIZE(mop500_pins_common_power_save_bank4)); + + if (machine_is_hrefv60()) + sleep_pins_config_pm(mop500_pins_common_power_save_bank5_href60, + ARRAY_SIZE(mop500_pins_common_power_save_bank5_href60)); + else + sleep_pins_config_pm(mop500_pins_common_power_save_bank5, + ARRAY_SIZE(mop500_pins_common_power_save_bank5)); + + if (machine_is_hrefv60()) + sleep_pins_config_pm(mop500_pins_common_power_save_bank6_href60, + ARRAY_SIZE(mop500_pins_common_power_save_bank6_href60)); + else + sleep_pins_config_pm(mop500_pins_common_power_save_bank6, + ARRAY_SIZE(mop500_pins_common_power_save_bank6)); + + if (machine_is_hrefv60()) + sleep_pins_config_pm(mop500_pins_common_power_save_bank7_href60, + ARRAY_SIZE(mop500_pins_common_power_save_bank7_href60)); + else + sleep_pins_config_pm(mop500_pins_common_power_save_bank7, + ARRAY_SIZE(mop500_pins_common_power_save_bank7)); + + sleep_pins_config_pm(mop500_pins_common_power_save_bank8, + ARRAY_SIZE(mop500_pins_common_power_save_bank8)); +} + +/* + * This function is called to force gpio power save + * mux settings during suspend. + * This is a temporary solution until all drivers are + * controlling their pin settings when in inactive mode. + */ +static void mop500_pins_suspend_force_mux(void) +{ + sleep_pins_config_pm_mux(mop500_pins_common_power_save_bank0, + ARRAY_SIZE(mop500_pins_common_power_save_bank0)); + + sleep_pins_config_pm_mux(mop500_pins_common_power_save_bank1, + ARRAY_SIZE(mop500_pins_common_power_save_bank1)); + + sleep_pins_config_pm_mux(mop500_pins_common_power_save_bank2, + ARRAY_SIZE(mop500_pins_common_power_save_bank2)); + + sleep_pins_config_pm_mux(mop500_pins_common_power_save_bank3, + ARRAY_SIZE(mop500_pins_common_power_save_bank3)); + + sleep_pins_config_pm_mux(mop500_pins_common_power_save_bank4, + ARRAY_SIZE(mop500_pins_common_power_save_bank4)); + + sleep_pins_config_pm_mux(mop500_pins_common_power_save_bank5, + ARRAY_SIZE(mop500_pins_common_power_save_bank5)); + + sleep_pins_config_pm_mux(mop500_pins_common_power_save_bank6, + ARRAY_SIZE(mop500_pins_common_power_save_bank6)); + + sleep_pins_config_pm_mux(mop500_pins_common_power_save_bank7, + ARRAY_SIZE(mop500_pins_common_power_save_bank7)); + + sleep_pins_config_pm_mux(mop500_pins_common_power_save_bank8, + ARRAY_SIZE(mop500_pins_common_power_save_bank8)); +} + +/* + * passing "pinsfor=" in kernel cmdline allows for custom + * configuration of GPIOs on u8500 derived boards. + */ +static int __init early_pinsfor(char *p) +{ + pinsfor = PINS_FOR_DEFAULT; + + if (strcmp(p, "u9500-21") == 0) + pinsfor = PINS_FOR_U9500; + + return 0; +} +early_param("pinsfor", early_pinsfor); + +int pins_for_u9500(void) +{ + if (pinsfor == PINS_FOR_U9500) + return 1; + + return 0; +} + void __init mop500_pins_init(void) { nmk_config_pins(mop500_pins_common, ARRAY_SIZE(mop500_pins_common)); + + ux500_pins_add(mop500_pins, ARRAY_SIZE(mop500_pins)); + if (machine_is_hrefv60()) nmk_config_pins(mop500_pins_hrefv60, ARRAY_SIZE(mop500_pins_hrefv60)); @@ -289,4 +942,19 @@ void __init mop500_pins_init(void) 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)); + break; + + case PINS_FOR_DEFAULT: + nmk_config_pins(u8500_pins, ARRAY_SIZE(u8500_pins)); + default: + break; + } + + suspend_set_pins_force_fn(mop500_pins_suspend_force, + mop500_pins_suspend_force_mux); } + diff --git a/arch/arm/mach-ux500/board-mop500-sdi.c b/arch/arm/mach-ux500/board-mop500-sdi.c index d0cb9e5eb87..4657c0073ab 100644 --- a/arch/arm/mach-ux500/board-mop500-sdi.c +++ b/arch/arm/mach-ux500/board-mop500-sdi.c @@ -16,10 +16,10 @@ #include <plat/ste_dma40.h> #include <mach/devices.h> #include <mach/hardware.h> +#include <mach/ste-dma40-db8500.h> #include "devices-db8500.h" #include "board-mop500.h" -#include "ste-dma40-db8500.h" /* * SDI 0 (MicroSD slot) @@ -211,11 +211,13 @@ void __init mop500_sdi_init(void) u32 periphid = 0; /* v2 has a new version of this block that need to be forced */ - if (cpu_is_u8500v2()) + if (cpu_is_u8500v20_or_later()) { periphid = 0x10480180; - /* PoP:ed eMMC on top of DB8500 v1.0 has problems with high speed */ - if (!cpu_is_u8500v10()) + + /* PoP:ed eMMC on DB8500 v1.0 has problems with high speed */ mop500_sdi2_data.capabilities |= MMC_CAP_MMC_HIGHSPEED; + } + /* sdi2 on snowball is in ATL_B mode for FSMC (LAN) */ if (!machine_is_snowball()) db8500_add_sdi2(&mop500_sdi2_data, periphid); diff --git a/arch/arm/mach-ux500/board-mop500-stuib.c b/arch/arm/mach-ux500/board-mop500-stuib.c index 8c979770d87..273869bf3ca 100644 --- a/arch/arm/mach-ux500/board-mop500-stuib.c +++ b/arch/arm/mach-ux500/board-mop500-stuib.c @@ -11,33 +11,70 @@ #include <linux/gpio.h> #include <linux/interrupt.h> #include <linux/i2c.h> +#ifdef CONFIG_U8500_FLASH +#include <../drivers/staging/camera_flash/adp1653_plat.h> +#endif #include <linux/input/matrix_keypad.h> #include <asm/mach-types.h> #include "board-mop500.h" -/* STMPE/SKE keypad use this key layout */ +/* + * ux500 keymaps + * + * Organized row-wise as on the UIB, starting at the top-left + * + * we support two key layouts, specific to requirements. The first + * keylayout includes controls for power/volume a few generic keys; + * the second key layout contains the full numeric layout, enter/back/left + * buttons along with a "."(dot), specifically for connectivity testing + */ static const unsigned int mop500_keymap[] = { +#if defined(CONFIG_KEYLAYOUT_LAYOUT1) KEY(2, 5, KEY_END), - KEY(4, 1, KEY_POWER), + KEY(4, 1, KEY_HOME), KEY(3, 5, KEY_VOLUMEDOWN), - KEY(1, 3, KEY_3), + KEY(1, 3, KEY_EMAIL), KEY(5, 2, KEY_RIGHT), - KEY(5, 0, KEY_9), + KEY(5, 0, KEY_BACKSPACE), KEY(0, 5, KEY_MENU), KEY(7, 6, KEY_ENTER), KEY(4, 5, KEY_0), - KEY(6, 7, KEY_2), + KEY(6, 7, KEY_DOT), KEY(3, 4, KEY_UP), KEY(3, 3, KEY_DOWN), KEY(6, 4, KEY_SEND), KEY(6, 2, KEY_BACK), KEY(4, 2, KEY_VOLUMEUP), - KEY(5, 5, KEY_1), + KEY(5, 5, KEY_SPACE), KEY(4, 3, KEY_LEFT), + KEY(3, 2, KEY_SEARCH), +#elif defined(CONFIG_KEYLAYOUT_LAYOUT2) + KEY(2, 5, KEY_RIGHT), + KEY(4, 1, KEY_ENTER), + KEY(3, 5, KEY_MENU), + KEY(1, 3, KEY_3), + KEY(5, 2, KEY_6), + KEY(5, 0, KEY_9), + + KEY(0, 5, KEY_UP), + KEY(7, 6, KEY_DOWN), + KEY(4, 5, KEY_0), + KEY(6, 7, KEY_2), + KEY(3, 4, KEY_5), + KEY(3, 3, KEY_8), + + KEY(6, 4, KEY_LEFT), + KEY(6, 2, KEY_BACK), + KEY(4, 2, KEY_KPDOT), + KEY(5, 5, KEY_1), + KEY(4, 3, KEY_4), KEY(3, 2, KEY_7), +#else +#warning "No keypad layout defined." +#endif }; static const struct matrix_keymap_data mop500_keymap_data = { @@ -73,6 +110,24 @@ static struct i2c_board_info __initdata mop500_i2c0_devices_stuib[] = { }, }; +#ifdef CONFIG_U8500_FLASH +/* + * Config data for the flash + */ +static struct adp1653_platform_data __initdata adp1653_pdata_u8500_uib = { + .irq_no = CAMERA_FLASH_INT_PIN +}; +#endif + +static struct i2c_board_info __initdata mop500_i2c2_devices_stuib[] = { +#ifdef CONFIG_U8500_FLASH + { + I2C_BOARD_INFO("adp1653", 0x30), + .platform_data = &adp1653_pdata_u8500_uib + } +#endif +}; + /* * BU21013 ROHM touchscreen interface on the STUIBs */ @@ -111,6 +166,7 @@ static int bu21013_gpio_board_init(int reset_pin) __func__); return retval; } + gpio_set_value_cansleep(reset_pin, 1); } return retval; @@ -133,7 +189,8 @@ static int bu21013_gpio_board_exit(int reset_pin) __func__); return retval; } - gpio_set_value(reset_pin, 0); + gpio_set_value_cansleep(reset_pin, 0); + gpio_free(reset_pin); } bu21013_devices--; @@ -176,11 +233,11 @@ static struct bu21013_platform_device tsc_plat2_device = { static struct i2c_board_info __initdata u8500_i2c3_devices_stuib[] = { { - I2C_BOARD_INFO("bu21013_tp", 0x5C), + I2C_BOARD_INFO("bu21013_ts", 0x5C), .platform_data = &tsc_plat_device, }, { - I2C_BOARD_INFO("bu21013_tp", 0x5D), + I2C_BOARD_INFO("bu21013_ts", 0x5D), .platform_data = &tsc_plat2_device, }, @@ -191,15 +248,25 @@ void __init mop500_stuib_init(void) if (machine_is_hrefv60()) { tsc_plat_device.cs_pin = HREFV60_TOUCH_RST_GPIO; tsc_plat2_device.cs_pin = HREFV60_TOUCH_RST_GPIO; +#ifdef CONFIG_U8500_FLASH + adp1653_pdata_u8500_uib.enable_gpio = + HREFV60_CAMERA_FLASH_ENABLE; +#endif } else { tsc_plat_device.cs_pin = GPIO_BU21013_CS; tsc_plat2_device.cs_pin = GPIO_BU21013_CS; - +#ifdef CONFIG_U8500_FLASH + adp1653_pdata_u8500_uib.enable_gpio = + GPIO_CAMERA_FLASH_ENABLE; +#endif } mop500_uib_i2c_add(0, mop500_i2c0_devices_stuib, ARRAY_SIZE(mop500_i2c0_devices_stuib)); + mop500_uib_i2c_add(2, mop500_i2c2_devices_stuib, + ARRAY_SIZE(mop500_i2c2_devices_stuib)); + mop500_uib_i2c_add(3, u8500_i2c3_devices_stuib, ARRAY_SIZE(u8500_i2c3_devices_stuib)); } diff --git a/arch/arm/mach-ux500/board-mop500-u8500uib.c b/arch/arm/mach-ux500/board-mop500-u8500uib.c index 8ce46c0fdfd..41eea4a79c8 100644 --- a/arch/arm/mach-ux500/board-mop500-u8500uib.c +++ b/arch/arm/mach-ux500/board-mop500-u8500uib.c @@ -8,12 +8,22 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/i2c.h> +#ifdef CONFIG_U8500_FLASH +#include <../drivers/staging/camera_flash/adp1653_plat.h> +#endif #include <linux/gpio.h> #include <linux/interrupt.h> +#ifdef CONFIG_SENSORS_LSM303DLH +#include <linux/lsm303dlh.h> +#endif +#ifdef CONFIG_SENSORS_L3G4200D +#include <linux/l3g4200d.h> +#endif #include <linux/mfd/tc3589x.h> #include <linux/input/matrix_keypad.h> -#include <mach/gpio.h> +#include <asm/mach-types.h> +#include <linux/gpio.h> #include <mach/irqs.h> #include "board-mop500.h" @@ -22,12 +32,75 @@ struct i2c_board_info __initdata __weak mop500_i2c3_devices_u8500[] = { }; +#ifdef CONFIG_SENSORS_LSM303DLH +/* + * LSM303DLH accelerometer + magnetometer & L3G4200D Gyroscope sensors + */ +static struct lsm303dlh_platform_data __initdata lsm303dlh_pdata_u8500 = { + .name_a = "lsm303dlh.0", + .name_m = "lsm303dlh.1", + .axis_map_x = 1, + .axis_map_y = 0, + .axis_map_z = 2, + .negative_x = 1, + .negative_y = 1, + .negative_z = 1, +}; +#endif + +#ifdef CONFIG_SENSORS_L3G4200D +static struct l3g4200d_gyr_platform_data __initdata l3g4200d_pdata_u8500 = { + .name_gyr = "l3g4200d", + .axis_map_x = 1, + .axis_map_y = 0, + .axis_map_z = 2, + .negative_x = 0, + .negative_y = 0, + .negative_z = 1, +}; +#endif + +#ifdef CONFIG_U8500_FLASH +static struct adp1653_platform_data __initdata adp1653_pdata_u8500_uib = { + .irq_no = CAMERA_FLASH_INT_PIN +}; +#endif + +static struct i2c_board_info __initdata mop500_i2c2_devices_u8500[] = { +#ifdef CONFIG_SENSORS_LSM303DLH + { + /* LSM303DLH Accelerometer */ + I2C_BOARD_INFO("lsm303dlh_a", 0x18), + .platform_data = &lsm303dlh_pdata_u8500, + }, + { + /* LSM303DLH Magnetometer */ + I2C_BOARD_INFO("lsm303dlh_m", 0x1E), + .platform_data = &lsm303dlh_pdata_u8500, + }, +#endif +#ifdef CONFIG_SENSORS_L3G4200D + { + /* L3G4200D Gyroscope */ + I2C_BOARD_INFO("l3g4200d", 0x68), + .platform_data = &l3g4200d_pdata_u8500, + }, +#endif +#ifdef CONFIG_U8500_FLASH + { + I2C_BOARD_INFO("adp1653", 0x30), + .platform_data = &adp1653_pdata_u8500_uib + } +#endif +}; + + /* * TC35893 */ static const unsigned int u8500_keymap[] = { KEY(3, 1, KEY_END), - KEY(4, 1, KEY_POWER), + KEY(4, 1, KEY_HOME), KEY(6, 4, KEY_VOLUMEDOWN), KEY(4, 2, KEY_EMAIL), KEY(3, 3, KEY_RIGHT), @@ -88,4 +161,28 @@ void __init mop500_u8500uib_init(void) mop500_uib_i2c_add(0, mop500_i2c0_devices_u8500, ARRAY_SIZE(mop500_i2c0_devices_u8500)); + if (machine_is_hrefv60()) { +#ifdef CONFIG_SENSORS_LSM303DLH + lsm303dlh_pdata_u8500.irq_a1 = HREFV60_ACCEL_INT1_GPIO; + lsm303dlh_pdata_u8500.irq_a2 = HREFV60_ACCEL_INT2_GPIO; + lsm303dlh_pdata_u8500.irq_m = HREFV60_MAGNET_DRDY_GPIO; +#endif +#ifdef CONFIG_U8500_FLASH + adp1653_pdata_u8500_uib.enable_gpio = + HREFV60_CAMERA_FLASH_ENABLE; +#endif + } else { +#ifdef CONFIG_SENSORS_LSM303DLH + lsm303dlh_pdata_u8500.irq_a1 = GPIO_ACCEL_INT1; + lsm303dlh_pdata_u8500.irq_a2 = GPIO_ACCEL_INT2; + lsm303dlh_pdata_u8500.irq_m = GPIO_MAGNET_DRDY; +#endif +#ifdef CONFIG_U8500_FLASH + adp1653_pdata_u8500_uib.enable_gpio = + GPIO_CAMERA_FLASH_ENABLE; +#endif + } + + mop500_uib_i2c_add(2, mop500_i2c2_devices_u8500, + ARRAY_SIZE(mop500_i2c2_devices_u8500)); } diff --git a/arch/arm/mach-ux500/board-mop500-uib.c b/arch/arm/mach-ux500/board-mop500-uib.c index 5af36aa56c0..8679b15643c 100644 --- a/arch/arm/mach-ux500/board-mop500-uib.c +++ b/arch/arm/mach-ux500/board-mop500-uib.c @@ -1,4 +1,5 @@ /* + * Copyright (C) ST-Ericsson SA 2010 * * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson @@ -10,13 +11,16 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/i2c.h> - #include <mach/hardware.h> +#include <asm/mach-types.h> + #include "board-mop500.h" enum mop500_uib { STUIB, U8500UIB, + U8500UIB_R3, + NO_UIB, }; struct uib { @@ -25,6 +29,8 @@ struct uib { void (*init)(void); }; +static u8 type_of_uib = NO_UIB; + static struct uib __initdata mop500_uibs[] = { [STUIB] = { .name = "ST-UIB", @@ -36,9 +42,16 @@ static struct uib __initdata mop500_uibs[] = { .option = "u8500uib", .init = mop500_u8500uib_init, }, +#ifdef CONFIG_TOUCHSCREEN_CYTTSP_SPI + [U8500UIB_R3] = { + .name = "U8500-UIBR3", + .option = "u8500uibr3", + .init = mop500_u8500uib_r3_init, + }, +#endif }; -static struct uib *mop500_uib; +static struct uib __initdata *mop500_uib; static int __init mop500_uib_setup(char *str) { @@ -64,7 +77,7 @@ __setup("uib=", mop500_uib_setup); * The UIBs are detected after the I2C host controllers are registered, so * i2c_register_board_info() can't be used. */ -void mop500_uib_i2c_add(int busnum, struct i2c_board_info *info, +void mop500_uib_i2c_add(int busnum, struct i2c_board_info const *info, unsigned n) { struct i2c_adapter *adap; @@ -90,26 +103,46 @@ void mop500_uib_i2c_add(int busnum, struct i2c_board_info *info, static void __init __mop500_uib_init(struct uib *uib, const char *why) { pr_info("%s (%s)\n", uib->name, why); + + if (strcmp("stuib", uib->option) == 0) + type_of_uib = STUIB; + else if (strcmp("u8500uib", uib->option) == 0) + type_of_uib = U8500UIB; + else if (strcmp("u8500uibr3", uib->option) == 0) + type_of_uib = U8500UIB_R3; + uib->init(); } +int uib_is_stuib(void) +{ + return (type_of_uib == STUIB); +} + +int uib_is_u8500uib(void) +{ + return (type_of_uib == U8500UIB); +} + +int uib_is_u8500uibr3(void) +{ + return (type_of_uib == U8500UIB_R3); +} + /* * Detect the UIB attached based on the presence or absence of i2c devices. */ static int __init mop500_uib_init(void) { - struct uib *uib = mop500_uib; + struct uib *uib = mop500_uibs; struct i2c_adapter *i2c0; + struct i2c_adapter *i2c3; int ret; - if (!cpu_is_u8500()) + /* snowball and non u8500 cpus dont have uib */ + if (!cpu_is_u8500() || machine_is_snowball()) return -ENODEV; - if (uib) { - __mop500_uib_init(uib, "from uib= boot argument"); - return 0; - } - i2c0 = i2c_get_adapter(0); if (!i2c0) { __mop500_uib_init(&mop500_uibs[STUIB], @@ -121,12 +154,28 @@ static int __init mop500_uib_init(void) ret = i2c_smbus_xfer(i2c0, 0x44, 0, I2C_SMBUS_WRITE, 0, I2C_SMBUS_QUICK, NULL); i2c_put_adapter(i2c0); - - if (ret == 0) - uib = &mop500_uibs[U8500UIB]; - else - uib = &mop500_uibs[STUIB]; - + i2c3 = i2c_get_adapter(3); + if (ret == 0) { + if (!i2c3) { + __mop500_uib_init(&mop500_uibs[STUIB], + "fallback, could not get i2c3"); + return -ENODEV; + } + ret = i2c_smbus_xfer(i2c3, 0x4B, 0, I2C_SMBUS_WRITE, 0, + I2C_SMBUS_QUICK, NULL); + i2c_put_adapter(i2c3); + if (ret == 0) + uib = &mop500_uibs[U8500UIB]; + else + uib = &mop500_uibs[U8500UIB_R3]; + } + else { + ret = i2c_smbus_xfer(i2c3, 0x5C, 0, I2C_SMBUS_WRITE, 0, + I2C_SMBUS_QUICK, NULL); + i2c_put_adapter(i2c3); + if (ret == 0) + uib = &mop500_uibs[STUIB]; + } __mop500_uib_init(uib, "detected"); return 0; diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index cd54abaccd9..7d2eea57d9e 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -19,18 +19,28 @@ #include <linux/amba/pl022.h> #include <linux/amba/serial.h> #include <linux/spi/spi.h> +#ifdef CONFIG_HSI +#include <linux/hsi/hsi.h> +#endif #include <linux/mfd/ab8500.h> #include <linux/regulator/ab8500.h> #include <linux/mfd/tc3589x.h> -#include <linux/mfd/tps6105x.h> #include <linux/mfd/ab8500/gpio.h> +#include <linux/regulator/fixed.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/mfd/ab8500/denc.h> +#ifdef CONFIG_STM_MSP_I2S +#include <linux/spi/stm_msp.h> +#endif +#include <linux/leds_pwm.h> +#include <linux/pwm_backlight.h> +#include <linux/gpio/nomadik.h> #include <linux/leds.h> + #include <asm/mach-types.h> #include <asm/mach/arch.h> @@ -41,13 +51,45 @@ #include <mach/hardware.h> #include <mach/setup.h> #include <mach/devices.h> +#include <mach/sensors1p.h> +#ifdef CONFIG_INPUT_AB8500_ACCDET +#include <mach/abx500-accdet.h> +#endif #include <mach/irqs.h> +#include <mach/ste-dma40-db8500.h> +#ifdef CONFIG_U8500_SIM_DETECT +#include <mach/sim_detect.h> +#endif +#ifdef CONFIG_CRYPTO_DEV_UX500 +#include <mach/crypto-ux500.h> +#endif +#ifdef CONFIG_AV8100 +#include <video/av8100.h> +#endif + +#ifdef CONFIG_KEYBOARD_NOMADIK_SKE +#include <plat/ske.h> +#include "pins.h" +#endif #include "pins-db8500.h" -#include "ste-dma40-db8500.h" #include "devices-db8500.h" #include "board-mop500.h" #include "board-mop500-regulators.h" +#include "board-mop500-bm.h" +#if defined(CONFIG_CW1200) || defined(CONFIG_CW1200_MODULE) +#include "board-mop500-wlan.h" +#endif +#if defined(CONFIG_USB_MUSB_UX500) || defined(CONFIG_USB_MUSB_UX500_MODULE) +#include "board-ux500-usb.h" +#endif + +#ifdef CONFIG_AB8500_DENC +static struct ab8500_denc_platform_data ab8500_denc_pdata = { + .ddr_enable = true, + .ddr_little_endian = false, +}; +#endif static struct gpio_led snowball_led_array[] = { { @@ -70,7 +112,7 @@ static struct platform_device snowball_led_dev = { }; static struct ab8500_gpio_platform_data ab8500_gpio_pdata = { - .gpio_base = MOP500_AB8500_GPIO(0), + .gpio_base = AB8500_PIN_GPIO1, .irq_base = MOP500_AB8500_VIR_GPIO_IRQ_BASE, /* config_reg is the initial configuration of ab8500 pins. * The pins can be configured as GPIO or alt functions based @@ -78,19 +120,44 @@ static struct ab8500_gpio_platform_data ab8500_gpio_pdata = { * register. This is the array of 7 configuration settings. * One has to compile time decide these settings. Below is the * explanation of these setting - * GpioSel1 = 0x00 => Pins GPIO1 to GPIO8 are not used as GPIO - * GpioSel2 = 0x1E => Pins GPIO10 to GPIO13 are configured as GPIO - * GpioSel3 = 0x80 => Pin GPIO24 is configured as GPIO - * GpioSel4 = 0x01 => Pin GPIo25 is configured as GPIO - * GpioSel5 = 0x7A => Pins GPIO34, GPIO36 to GPIO39 are conf as GPIO - * GpioSel6 = 0x00 => Pins GPIO41 & GPIo42 are not configured as GPIO + * GpioSel1 = 0x0F => Pin GPIO1 (SysClkReq2) + * Pin GPIO2 (SysClkReq3) + * Pin GPIO3 (SysClkReq4) + * Pin GPIO4 (SysClkReq6) are configured as GPIO + * GpioSel2 = 0x9E => Pins GPIO10 to GPIO13 are configured as GPIO + * GpioSel3 = 0x80 => Pin GPIO24 (SysClkReq7) is configured as GPIO + * GpioSel4 = 0x01 => Pin GPIO25 (SysClkReq8) is configured as GPIO + * GpioSel5 = 0x78 => Pin GPIO36 (ApeSpiClk) + Pin GPIO37 (ApeSpiCSn) + Pin GPIO38 (ApeSpiDout) + Pin GPIO39 (ApeSpiDin) are configured as GPIO + * GpioSel6 = 0x02 => Pin GPIO42 (SysClkReq5) is configured as GPIO * AlternaFunction = 0x00 => If Pins GPIO10 to 13 are not configured - * as GPIO then this register selectes the alternate fucntions + * as GPIO then this register selectes the alternate functions */ - .config_reg = {0x00, 0x1E, 0x80, 0x01, - 0x7A, 0x00, 0x00}, + .config_reg = {0x0F, 0x9E, 0x80, 0x01, 0x78, 0x02, 0x00}, + + /* config_direction allows for the initial GPIO direction to + * be set. For Snowball we set GPIO26 to output. + */ + .config_direction = {0x00, 0x00, 0x00, 0x02, 0x00, 0x00}, + + /* + * config_pullups allows for the intial configuration of the + * GPIO pullup/pulldown configuration. + */ + .config_pullups = {0xE0, 0x01, 0x00, 0x00, 0x00, 0x00}, }; +#ifdef CONFIG_INPUT_AB8500_ACCDET +static struct abx500_accdet_platform_data ab8500_accdet_pdata = { + .btn_keycode = KEY_MEDIA, + .accdet1_dbth = ACCDET1_TH_1200mV | ACCDET1_DB_70ms, + .accdet2122_th = ACCDET21_TH_1000mV | ACCDET22_TH_1000mV, + .video_ctrl_gpio = AB8500_PIN_GPIO35, +}; +#endif + static struct gpio_keys_button snowball_key_array[] = { { .gpio = 32, @@ -182,13 +249,38 @@ static struct platform_device snowball_sbnet_dev = { }, }; +#ifdef CONFIG_MODEM_U8500 +static struct platform_device u8500_modem_dev = { + .name = "u8500-modem", + .id = 0, + .dev = { + .platform_data = NULL, + }, +}; +#endif + static struct ab8500_platform_data ab8500_platdata = { .irq_base = MOP500_AB8500_IRQ_BASE, - .regulator_reg_init = ab8500_regulator_reg_init, - .num_regulator_reg_init = ARRAY_SIZE(ab8500_regulator_reg_init), - .regulator = ab8500_regulators, - .num_regulator = ARRAY_SIZE(ab8500_regulators), + .regulator = &ab8500_regulator_plat_data, +#ifdef CONFIG_AB8500_DENC + .denc = &ab8500_denc_pdata, +#endif + .battery = &ab8500_bm_data, + .charger = &ab8500_charger_plat_data, + .btemp = &ab8500_btemp_plat_data, + .fg = &ab8500_fg_plat_data, + .chargalg = &ab8500_chargalg_plat_data, .gpio = &ab8500_gpio_pdata, +#if defined(CONFIG_USB_MUSB_UX500) || defined(CONFIG_USB_MUSB_UX500_MODULE) + .usb = &abx500_usbgpio_plat_data, +#endif +#ifdef CONFIG_INPUT_AB8500_ACCDET + .accdet = &ab8500_accdet_pdata, +#endif +#ifdef CONFIG_PM + .pm_power_off = true, +#endif + .thermal_time_out = 20, /* seconds */ }; static struct resource ab8500_resources[] = { @@ -209,14 +301,198 @@ struct platform_device ab8500_device = { .resource = ab8500_resources, }; + + +#ifdef CONFIG_KEYBOARD_NOMADIK_SKE + +/* + * Nomadik SKE keypad + */ +#define ROW_PIN_I0 164 +#define ROW_PIN_I1 163 +#define ROW_PIN_I2 162 +#define ROW_PIN_I3 161 +#define ROW_PIN_I4 156 +#define ROW_PIN_I5 155 +#define ROW_PIN_I6 154 +#define ROW_PIN_I7 153 +#define COL_PIN_O0 168 +#define COL_PIN_O1 167 +#define COL_PIN_O2 166 +#define COL_PIN_O3 165 +#define COL_PIN_O4 160 +#define COL_PIN_O5 159 +#define COL_PIN_O6 158 +#define COL_PIN_O7 157 + +static int ske_kp_rows[] = { + ROW_PIN_I0, ROW_PIN_I1, ROW_PIN_I2, ROW_PIN_I3, + ROW_PIN_I4, ROW_PIN_I5, ROW_PIN_I6, ROW_PIN_I7, +}; +static int ske_kp_cols[] = { + COL_PIN_O0, COL_PIN_O1, COL_PIN_O2, COL_PIN_O3, + COL_PIN_O4, COL_PIN_O5, COL_PIN_O6, COL_PIN_O7, +}; + +static bool ske_config; +/* + * ske_set_gpio_row: request and set gpio rows + */ +static int ske_set_gpio_row(int gpio) +{ + int ret; + + if (!ske_config) { + ret = gpio_request(gpio, "ske-kp"); + if (ret < 0) { + pr_err("ske_set_gpio_row: gpio request failed\n"); + return ret; + } + } + + ret = gpio_direction_output(gpio, 1); + if (ret < 0) { + pr_err("ske_set_gpio_row: gpio direction failed\n"); + gpio_free(gpio); + } + + return ret; +} + /* - * TPS61052 + * ske_kp_init - enable the gpio configuration */ +static int ske_kp_init(void) +{ + struct ux500_pins *pins; + int ret, i; + + pins = ux500_pins_get("ske"); + if (pins) + ux500_pins_enable(pins); + + for (i = 0; i < SKE_KPD_MAX_ROWS; i++) { + ret = ske_set_gpio_row(ske_kp_rows[i]); + if (ret < 0) { + pr_err("ske_kp_init: failed init\n"); + return ret; + } + } + if (!ske_config) + ske_config = true; + + return 0; +} + +static int ske_kp_exit(void) +{ + struct ux500_pins *pins; + + pins = ux500_pins_get("ske"); + if (pins) + ux500_pins_disable(pins); + + return 0; +} -static struct tps6105x_platform_data mop500_tps61052_data = { - .mode = TPS6105X_MODE_VOLTAGE, - .regulator_data = &tps61052_regulator, + +static const unsigned int mop500_ske_keymap[] = { +#if defined(CONFIG_KEYLAYOUT_LAYOUT1) + KEY(2, 5, KEY_END), + KEY(4, 1, KEY_HOME), + KEY(3, 5, KEY_VOLUMEDOWN), + KEY(1, 3, KEY_EMAIL), + KEY(5, 2, KEY_RIGHT), + KEY(5, 0, KEY_BACKSPACE), + + KEY(0, 5, KEY_MENU), + KEY(7, 6, KEY_ENTER), + KEY(4, 5, KEY_0), + KEY(6, 7, KEY_DOT), + KEY(3, 4, KEY_UP), + KEY(3, 3, KEY_DOWN), + + KEY(6, 4, KEY_SEND), + KEY(6, 2, KEY_BACK), + KEY(4, 2, KEY_VOLUMEUP), + KEY(5, 5, KEY_SPACE), + KEY(4, 3, KEY_LEFT), + KEY(3, 2, KEY_SEARCH), +#elif defined(CONFIG_KEYLAYOUT_LAYOUT2) + KEY(2, 5, KEY_RIGHT), + KEY(4, 1, KEY_ENTER), + KEY(3, 5, KEY_MENU), + KEY(1, 3, KEY_3), + KEY(5, 2, KEY_6), + KEY(5, 0, KEY_9), + + KEY(0, 5, KEY_UP), + KEY(7, 6, KEY_DOWN), + KEY(4, 5, KEY_0), + KEY(6, 7, KEY_2), + KEY(3, 4, KEY_5), + KEY(3, 3, KEY_8), + + KEY(6, 4, KEY_LEFT), + KEY(6, 2, KEY_BACK), + KEY(4, 2, KEY_KPDOT), + KEY(5, 5, KEY_1), + KEY(4, 3, KEY_4), + KEY(3, 2, KEY_7), +#else +#warning "No keypad layout defined." +#endif +}; + +static struct matrix_keymap_data mop500_ske_keymap_data = { + .keymap = mop500_ske_keymap, + .keymap_size = ARRAY_SIZE(mop500_ske_keymap), +}; + + + +static struct ske_keypad_platform_data mop500_ske_keypad_data = { + .init = ske_kp_init, + .exit = ske_kp_exit, + .gpio_input_pins = ske_kp_rows, + .gpio_output_pins = ske_kp_cols, + .keymap_data = &mop500_ske_keymap_data, + .no_autorepeat = true, + .krow = SKE_KPD_MAX_ROWS, /* 8x8 matrix */ + .kcol = SKE_KPD_MAX_COLS, + .debounce_ms = 20, /* in timeout period */ + .switch_delay = 200, /* in jiffies */ +}; + +#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 @@ -239,53 +515,64 @@ static struct tc3589x_platform_data mop500_tc35892_data = { }; static struct lp5521_led_config lp5521_pri_led[] = { - [0] = { - .chan_nr = 0, - .led_current = 0x2f, - .max_current = 0x5f, - }, - [1] = { - .chan_nr = 1, - .led_current = 0x2f, - .max_current = 0x5f, - }, - [2] = { - .chan_nr = 2, - .led_current = 0x2f, - .max_current = 0x5f, - }, + [0] = { + .chan_nr = 0, + .led_current = 0x2f, + .max_current = 0x5f, + }, + [1] = { + .chan_nr = 1, + .led_current = 0x2f, + .max_current = 0x5f, + }, + [2] = { + .chan_nr = 2, + .led_current = 0x2f, + .max_current = 0x5f, + }, +}; + +#ifdef CONFIG_AV8100 +static struct av8100_platform_data av8100_plat_data = { + .irq = NOMADIK_GPIO_TO_IRQ(192), + .reset = MOP500_HDMI_RST_GPIO, + .inputclk_id = "sysclk2", + .regulator_pwr_id = "hdmi_1v8", + .alt_powerupseq = true, + .mclk_freq = 3, /* MCLK_RNG_31_38 */ }; +#endif static struct lp5521_platform_data __initdata lp5521_pri_data = { - .label = "lp5521_pri", - .led_config = &lp5521_pri_led[0], - .num_channels = 3, - .clock_mode = LP5521_CLOCK_EXT, + .label = "lp5521_pri", + .led_config = &lp5521_pri_led[0], + .num_channels = 3, + .clock_mode = LP5521_CLOCK_EXT, }; static struct lp5521_led_config lp5521_sec_led[] = { - [0] = { - .chan_nr = 0, - .led_current = 0x2f, - .max_current = 0x5f, - }, - [1] = { - .chan_nr = 1, - .led_current = 0x2f, - .max_current = 0x5f, - }, - [2] = { - .chan_nr = 2, - .led_current = 0x2f, - .max_current = 0x5f, - }, + [0] = { + .chan_nr = 0, + .led_current = 0x2f, + .max_current = 0x5f, + }, + [1] = { + .chan_nr = 1, + .led_current = 0x2f, + .max_current = 0x5f, + }, + [2] = { + .chan_nr = 2, + .led_current = 0x2f, + .max_current = 0x5f, + }, }; static struct lp5521_platform_data __initdata lp5521_sec_data = { - .label = "lp5521_sec", - .led_config = &lp5521_sec_led[0], - .num_channels = 3, - .clock_mode = LP5521_CLOCK_EXT, + .label = "lp5521_sec", + .led_config = &lp5521_sec_led[0], + .num_channels = 3, + .clock_mode = LP5521_CLOCK_EXT, }; static struct i2c_board_info __initdata mop500_i2c0_devices[] = { @@ -294,15 +581,26 @@ static struct i2c_board_info __initdata mop500_i2c0_devices[] = { .irq = NOMADIK_GPIO_TO_IRQ(217), .platform_data = &mop500_tc35892_data, }, - /* I2C0 devices only available prior to HREFv60 */ +#ifdef CONFIG_AV8100 { - I2C_BOARD_INFO("tps61052", 0x33), - .platform_data = &mop500_tps61052_data, + I2C_BOARD_INFO("av8100", 0x70), + .platform_data = &av8100_plat_data, }, +#endif + /* I2C0 devices only available prior to HREFv60 */ }; #define NUM_PRE_V60_I2C0_DEVICES 1 +static struct i2c_board_info __initdata snowball_i2c0_devices[] = { +#ifdef CONFIG_AV8100 + { + I2C_BOARD_INFO("av8100", 0x70), + .platform_data = &av8100_plat_data, + }, +#endif +}; + static struct i2c_board_info __initdata mop500_i2c2_devices[] = { { /* lp5521 LED driver, 1st device */ @@ -343,13 +641,13 @@ static struct nmk_i2c_controller u8500_i2c##id##_data = { \ /* * The board uses 4 i2c controllers, initialize all of * them with slave data setup time of 250 ns, - * Tx & Rx FIFO threshold values as 8 and standard + * Tx & Rx FIFO threshold values as 1 and standard * mode of operation */ -U8500_I2C_CONTROLLER(0, 0xe, 1, 8, 100000, 200, I2C_FREQ_MODE_FAST); -U8500_I2C_CONTROLLER(1, 0xe, 1, 8, 100000, 200, I2C_FREQ_MODE_FAST); -U8500_I2C_CONTROLLER(2, 0xe, 1, 8, 100000, 200, I2C_FREQ_MODE_FAST); -U8500_I2C_CONTROLLER(3, 0xe, 1, 8, 100000, 200, I2C_FREQ_MODE_FAST); +U8500_I2C_CONTROLLER(0, 0xe, 1, 8, 400000, 200, I2C_FREQ_MODE_FAST); +U8500_I2C_CONTROLLER(1, 0xe, 1, 8, 400000, 200, I2C_FREQ_MODE_FAST); +U8500_I2C_CONTROLLER(2, 0xe, 1, 8, 400000, 200, I2C_FREQ_MODE_FAST); +U8500_I2C_CONTROLLER(3, 0xe, 1, 8, 400000, 200, I2C_FREQ_MODE_FAST); static void __init mop500_i2c_init(void) { @@ -366,18 +664,25 @@ static struct gpio_keys_button mop500_gpio_keys[] = { .code = SW_FRONT_PROXIMITY, .active_low = 0, .can_disable = 1, + }, + { + .desc = "HED54XXU11 Hall Effect Sensor", + .type = EV_SW, + .code = SW_LID, /* FIXME arbitrary usage */ + .active_low = 0, + .can_disable = 1, } }; -static struct regulator *prox_regulator; -static int mop500_prox_activate(struct device *dev); -static void mop500_prox_deactivate(struct device *dev); +static struct regulator *sensors1p_regulator; +static int mop500_sensors1p_activate(struct device *dev); +static void mop500_sensors1p_deactivate(struct device *dev); static struct gpio_keys_platform_data mop500_gpio_keys_data = { .buttons = mop500_gpio_keys, .nbuttons = ARRAY_SIZE(mop500_gpio_keys), - .enable = mop500_prox_activate, - .disable = mop500_prox_deactivate, + .enable = mop500_sensors1p_activate, + .disable = mop500_sensors1p_deactivate, }; static struct platform_device mop500_gpio_keys_device = { @@ -388,31 +693,312 @@ static struct platform_device mop500_gpio_keys_device = { }, }; -static int mop500_prox_activate(struct device *dev) +#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 + +static int mop500_sensors1p_activate(struct device *dev) { - prox_regulator = regulator_get(&mop500_gpio_keys_device.dev, + sensors1p_regulator = regulator_get(&mop500_gpio_keys_device.dev, "vcc"); - if (IS_ERR(prox_regulator)) { - dev_err(&mop500_gpio_keys_device.dev, - "no regulator\n"); - return PTR_ERR(prox_regulator); + if (IS_ERR(sensors1p_regulator)) { + dev_err(&mop500_gpio_keys_device.dev, "no regulator\n"); + return PTR_ERR(sensors1p_regulator); } - regulator_enable(prox_regulator); + regulator_enable(sensors1p_regulator); return 0; } -static void mop500_prox_deactivate(struct device *dev) +static void mop500_sensors1p_deactivate(struct device *dev) { - regulator_disable(prox_regulator); - regulator_put(prox_regulator); + regulator_disable(sensors1p_regulator); + regulator_put(sensors1p_regulator); } +#ifdef CONFIG_LEDS_PWM +static struct led_pwm pwm_leds_data[] = { + [0] = { + .name = "lcd-backlight", + .pwm_id = 1, + .max_brightness = 255, + .lth_brightness = 90, + .pwm_period_ns = 1023, + }, +#ifdef CONFIG_DISPLAY_GENERIC_DSI_SECONDARY + [1] = { + .name = "sec-lcd-backlight", + .pwm_id = 2, + .max_brightness = 255, + .lth_brightness = 90, + .pwm_period_ns = 1023, + }, +#endif +}; + +static struct led_pwm_platform_data u8500_leds_data = { +#ifdef CONFIG_DISPLAY_GENERIC_DSI_SECONDARY + .num_leds = 2, +#else + .num_leds = 1, +#endif + .leds = pwm_leds_data, +}; + +static struct platform_device ux500_leds_device = { + .name = "leds_pwm", + .dev = { + .platform_data = &u8500_leds_data, + }, +}; +#endif + +#ifdef CONFIG_BACKLIGHT_PWM +static struct platform_pwm_backlight_data u8500_backlight_data[] = { + [0] = { + .pwm_id = 1, + .max_brightness = 255, + .dft_brightness = 200, + .lth_brightness = 90, + .pwm_period_ns = 1023, + }, + [1] = { + .pwm_id = 2, + .max_brightness = 255, + .dft_brightness = 200, + .lth_brightness = 90, + .pwm_period_ns = 1023, + }, +}; + +static struct platform_device ux500_backlight_device[] = { + [0] = { + .name = "pwm-backlight", + .id = 0, + .dev = { + .platform_data = &u8500_backlight_data[0], + }, + }, + [1] = { + .name = "pwm-backlight", + .id = 1, + .dev = { + .platform_data = &u8500_backlight_data[1], + }, + }, +}; +#endif + +/* Force feedback vibrator device */ +static struct platform_device ste_ff_vibra_device = { + .name = "ste_ff_vibra" +}; + +#ifdef CONFIG_HSI +static struct hsi_board_info __initdata u8500_hsi_devices[] = { + { + .name = "hsi_char", + .hsi_id = 0, + .port = 0, + .tx_cfg = { + .mode = HSI_MODE_FRAME, + .channels = 1, + .speed = 200000, + {.arb_mode = HSI_ARB_RR}, + }, + .rx_cfg = { + .mode = HSI_MODE_FRAME, + .channels = 1, + .speed = 200000, + {.flow = HSI_FLOW_SYNC}, + }, + }, + { + .name = "hsi_test", + .hsi_id = 0, + .port = 0, + .tx_cfg = { + .mode = HSI_MODE_FRAME, + .channels = 2, + .speed = 100000, + {.arb_mode = HSI_ARB_RR}, + }, + .rx_cfg = { + .mode = HSI_MODE_FRAME, + .channels = 2, + .speed = 200000, + {.flow = HSI_FLOW_SYNC}, + }, + }, + { + .name = "cfhsi_v3_driver", + .hsi_id = 0, + .port = 0, + .tx_cfg = { + .mode = HSI_MODE_STREAM, + .channels = 2, + .speed = 20000, + {.arb_mode = HSI_ARB_RR}, + }, + .rx_cfg = { + .mode = HSI_MODE_STREAM, + .channels = 2, + .speed = 200000, + {.flow = HSI_FLOW_SYNC}, + }, + }, +}; +#endif + +#ifdef CONFIG_U8500_SIM_DETECT +static struct sim_detect_platform_data sim_detect_pdata = { + .irq_num = MOP500_AB8500_VIR_GPIO_IRQ(6), +}; +struct platform_device u8500_sim_detect_device = { + .name = "sim-detect", + .id = 0, + .dev = { + .platform_data = &sim_detect_pdata, + }, +}; +#endif + +#ifdef CONFIG_SENSORS1P_MOP +static struct sensors1p_config sensors1p_config = { + /* SFH7741 */ + .proximity = { + .pin = EGPIO_PIN_7, + .startup_time = 120, /* ms */ + .regulator = "v-proximity", + }, + /* HED54XXU11 */ + .hal = { + .pin = EGPIO_PIN_8, + .startup_time = 100, /* Actually, I have no clue. */ + .regulator = "v-hal", + }, +}; + +struct platform_device sensors1p_device = { + .name = "sensors1p", + .dev = { + .platform_data = (void *)&sensors1p_config, + }, +}; +#endif + +#ifdef CONFIG_CRYPTO_DEV_UX500 +static struct cryp_platform_data u8500_cryp1_platform_data = { + .mem_to_engine = { + .dir = STEDMA40_MEM_TO_PERIPH, + .src_dev_type = STEDMA40_DEV_SRC_MEMORY, + .dst_dev_type = DB8500_DMA_DEV48_CAC1_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_4, + .dst_info.psize = STEDMA40_PSIZE_LOG_4, + }, + .engine_to_mem = { + .dir = STEDMA40_PERIPH_TO_MEM, + .src_dev_type = DB8500_DMA_DEV48_CAC1_RX, + .dst_dev_type = STEDMA40_DEV_DST_MEMORY, + .src_info.data_width = STEDMA40_WORD_WIDTH, + .dst_info.data_width = STEDMA40_WORD_WIDTH, + .mode = STEDMA40_MODE_LOGICAL, + .src_info.psize = STEDMA40_PSIZE_LOG_4, + .dst_info.psize = STEDMA40_PSIZE_LOG_4, + } +}; + +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, + }, +}; +#endif + /* add any platform devices here - TODO */ static struct platform_device *mop500_platform_devs[] __initdata = { +#ifdef CONFIG_SENSORS1P_MOP + &sensors1p_device, +#endif +#ifdef CONFIG_U8500_SIM_DETECT + &u8500_sim_detect_device, +#endif + &u8500_shrm_device, + &ste_ff_vibra_device, +#ifdef CONFIG_U8500_MMIO + &ux500_mmio_device, +#endif + &ux500_hwmem_device, +#ifdef CONFIG_FB_MCDE + &u8500_mcde_device, +#endif + &u8500_b2r2_device, + &u8500_thsens_device, +#ifdef CONFIG_STE_TRACE_MODEM + &u8500_trace_modem, +#endif &mop500_gpio_keys_device, - &ab8500_device, +#ifdef CONFIG_LEDS_PWM + &ux500_leds_device, +#endif +#ifdef CONFIG_BACKLIGHT_PWM + &ux500_backlight_device[0], + &ux500_backlight_device[1], +#endif +#ifdef CONFIG_DB8500_MLOADER + &mloader_fw_device, +#endif +#ifdef CONFIG_HSI + &u8500_hsi_device, +#endif +#ifdef CONFIG_MODEM_U8500 + &u8500_modem_dev, +#endif +}; + +#ifdef CONFIG_STM_MSP_I2S +/* + * MSP-SPI + */ + +#define NUM_MSP_CLIENTS 10 + +static struct stm_msp_controller mop500_msp2_spi_data = { + .id = 2, + .num_chipselect = NUM_MSP_CLIENTS, + .base_addr = U8500_MSP2_BASE, + .device_name = "msp2", }; +/* + * SSP + */ + +#define NUM_SSP_CLIENTS 10 + #ifdef CONFIG_STE_DMA40 static struct stedma40_chan_cfg ssp0_dma_cfg_rx = { .mode = STEDMA40_MODE_LOGICAL, @@ -434,27 +1020,33 @@ static struct stedma40_chan_cfg ssp0_dma_cfg_tx = { #endif static struct pl022_ssp_controller ssp0_platform_data = { - .bus_id = 0, + .bus_id = 4, #ifdef CONFIG_STE_DMA40 .enable_dma = 1, .dma_filter = stedma40_filter, .dma_rx_param = &ssp0_dma_cfg_rx, .dma_tx_param = &ssp0_dma_cfg_tx, -#else - .enable_dma = 0, #endif /* on this platform, gpio 31,142,144,214 & * 224 are connected as chip selects */ - .num_chipselect = 5, + .num_chipselect = NUM_SSP_CLIENTS, }; + static void __init mop500_spi_init(void) { db8500_add_ssp0(&ssp0_platform_data); + if (!machine_is_snowball()) + db8500_add_msp2_spi(&mop500_msp2_spi_data); } +#else +static void __init mop500_spi_init(void) +{ +} +#endif /* CONFIG_STM_MSP_I2S */ -#ifdef CONFIG_STE_DMA40 +#ifdef CONFIG_STE_DMA40_REMOVE static struct stedma40_chan_cfg uart0_dma_cfg_rx = { .mode = STEDMA40_MODE_LOGICAL, .dir = STEDMA40_PERIPH_TO_MEM, @@ -520,6 +1112,7 @@ static pin_cfg_t mop500_pins_uart0[] = { #define PRCC_K_SOFTRST_SET 0x18 #define PRCC_K_SOFTRST_CLEAR 0x1C +/* pl011 reset */ static void ux500_uart0_reset(void) { void __iomem *prcc_rst_set, *prcc_rst_clr; @@ -558,8 +1151,10 @@ static void ux500_uart0_exit(void) pr_err("pl011: uart pins_disable failed\n"); } + + static struct amba_pl011_data uart0_plat = { -#ifdef CONFIG_STE_DMA40 +#ifdef CONFIG_STE_DMA40_REMOVE .dma_filter = stedma40_filter, .dma_rx_param = &uart0_dma_cfg_rx, .dma_tx_param = &uart0_dma_cfg_tx, @@ -570,7 +1165,7 @@ static struct amba_pl011_data uart0_plat = { }; static struct amba_pl011_data uart1_plat = { -#ifdef CONFIG_STE_DMA40 +#ifdef CONFIG_STE_DMA40_REMOVE .dma_filter = stedma40_filter, .dma_rx_param = &uart1_dma_cfg_rx, .dma_tx_param = &uart1_dma_cfg_tx, @@ -578,7 +1173,7 @@ static struct amba_pl011_data uart1_plat = { }; static struct amba_pl011_data uart2_plat = { -#ifdef CONFIG_STE_DMA40 +#ifdef CONFIG_STE_DMA40_REMOVE .dma_filter = stedma40_filter, .dma_rx_param = &uart2_dma_cfg_rx, .dma_tx_param = &uart2_dma_cfg_tx, @@ -592,33 +1187,77 @@ static void __init mop500_uart_init(void) db8500_add_uart2(&uart2_plat); } +#ifdef CONFIG_CRYPTO_DEV_UX500 +static void __init u8500_cryp1_hash1_init(void) +{ + db8500_add_cryp1(&u8500_cryp1_platform_data); + db8500_add_hash1(&u8500_hash1_platform_data); +} +#endif + 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, +#endif +#ifdef CONFIG_REGULATOR_FIXED_VOLTAGE + &snowball_gpio_wlan_vbat_regulator_device, +#endif &snowball_sbnet_dev, - &ab8500_device, +#ifdef CONFIG_FB_MCDE + &u8500_mcde_device, +#endif + &u8500_b2r2_device, }; -static void __init mop500_init_machine(void) +/* + * On boards hrefpv60 and later, the accessory insertion/removal, + * button press/release are inverted. +*/ +static void accessory_detect_config(void) { - int i2c0_devs; +#ifdef CONFIG_INPUT_AB8500_ACCDET + if (machine_is_hrefv60()) + ab8500_accdet_pdata.is_detection_inverted = true; + else + ab8500_accdet_pdata.is_detection_inverted = false; +#endif +} +static void __init mop500_init_machine(void) +{ /* * The HREFv60 board removed a GPIO expander and routed * all these GPIO pins to the internal GPIO controller * instead. */ if (!machine_is_snowball()) { - if (machine_is_hrefv60()) + if (machine_is_hrefv60()) { mop500_gpio_keys[0].gpio = HREFV60_PROX_SENSE_GPIO; - else + mop500_gpio_keys[1].gpio = HREFV60_HAL_SW_GPIO; + } else { mop500_gpio_keys[0].gpio = GPIO_PROX_SENSOR; + mop500_gpio_keys[1].gpio = GPIO_HAL_SENSOR; + } } + accessory_detect_config(); + u8500_init_devices(); mop500_pins_init(); +#ifdef CONFIG_CRYPTO_DEV_UX500 + u8500_cryp1_hash1_init(); +#endif + +#ifdef CONFIG_HSI + hsi_register_board_info(u8500_hsi_devices, + ARRAY_SIZE(u8500_hsi_devices)); +#endif + if (machine_is_snowball()) platform_add_devices(snowball_platform_devs, ARRAY_SIZE(snowball_platform_devs)); @@ -630,13 +1269,30 @@ static void __init mop500_init_machine(void) mop500_sdi_init(); mop500_spi_init(); mop500_uart_init(); +#ifdef CONFIG_STM_MSP_I2S + mop500_msp_init(); +#endif +#if defined(CONFIG_CW1200) || defined(CONFIG_CW1200_MODULE) + mop500_wlan_init(); +#endif - i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices); - if (machine_is_hrefv60()) - i2c0_devs -= NUM_PRE_V60_I2C0_DEVICES; +#ifdef CONFIG_KEYBOARD_NOMADIK_SKE + db8500_add_ske_keypad(&mop500_ske_keypad_data); +#endif + + platform_device_register(&ab8500_device); + + /* Snowball jus have the av8100 on i2c0 */ + if (!machine_is_snowball()) + i2c_register_board_info(0, mop500_i2c0_devices, + ARRAY_SIZE(mop500_i2c0_devices)); + else + i2c_register_board_info(0, snowball_i2c0_devices, + ARRAY_SIZE(snowball_i2c0_devices)); - i2c_register_board_info(0, mop500_i2c0_devices, i2c0_devs); - i2c_register_board_info(2, mop500_i2c2_devices, + /* Snowball dont have any of these */ + if (!machine_is_snowball()) + i2c_register_board_info(2, mop500_i2c2_devices, ARRAY_SIZE(mop500_i2c2_devices)); /* This board has full regulator constraints */ @@ -661,7 +1317,7 @@ MACHINE_START(HREFV60, "ST-Ericsson U8500 Platform HREFv60+") .init_machine = mop500_init_machine, MACHINE_END -MACHINE_START(SNOWBALL, "Calao Systems Snowball platform") +MACHINE_START(SNOWBALL, "ST-Ericsson Snowball platform") .boot_params = 0x100, .map_io = u8500_map_io, .init_irq = ux500_init_irq, diff --git a/arch/arm/mach-ux500/board-mop500.h b/arch/arm/mach-ux500/board-mop500.h index ee77a8970c3..829a7bece6e 100644 --- a/arch/arm/mach-ux500/board-mop500.h +++ b/arch/arm/mach-ux500/board-mop500.h @@ -7,10 +7,19 @@ #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 +/* This defines the NOMADIK_NR_GPIO */ +#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 @@ -24,18 +33,43 @@ #define HREFV60_MAGNET_DRDY_GPIO 32 #define HREFV60_DISP1_RST_GPIO 65 #define HREFV60_DISP2_RST_GPIO 66 +#define HREFV60_MMIO_XENON_CHARGE 170 +#define HREFV60_XSHUTDOWN_SECONDARY_SENSOR 140 +#define HREFV60_CAMERA_FLASH_ENABLE 22 +#define XSHUTDOWN_PRIMARY_SENSOR 141 +#define XSHUTDOWN_SECONDARY_SENSOR 142 +#define CAMERA_FLASH_INT_PIN 7 +#define CYPRESS_TOUCH_INT_PIN 84 +#define CYPRESS_TOUCH_RST_GPIO 143 +#define CYPRESS_SLAVE_SELECT_GPIO 216 + +/* MOP500 generic GPIOs */ +#define MOP500_HDMI_RST_GPIO 196 /* GPIOs on the TC35892 expander */ -#define MOP500_EGPIO(x) (NOMADIK_NR_GPIO + (x)) +#define GPIO_MAGNET_DRDY MOP500_EGPIO(1) #define GPIO_SDMMC_CD MOP500_EGPIO(3) +#define GPIO_CAMERA_FLASH_ENABLE MOP500_EGPIO(4) +#define GPIO_MMIO_XENON_CHARGE MOP500_EGPIO(5) #define GPIO_PROX_SENSOR MOP500_EGPIO(7) +#define GPIO_HAL_SENSOR MOP500_EGPIO(8) +#define GPIO_ACCEL_INT1 MOP500_EGPIO(10) +#define GPIO_ACCEL_INT2 MOP500_EGPIO(11) #define GPIO_BU21013_CS MOP500_EGPIO(13) +#define MOP500_DISP2_RST_GPIO MOP500_EGPIO(14) +#define MOP500_DISP1_RST_GPIO MOP500_EGPIO(15) #define GPIO_SDMMC_EN MOP500_EGPIO(17) #define GPIO_SDMMC_1V8_3V_SEL MOP500_EGPIO(18) -#define MOP500_EGPIO_END MOP500_EGPIO(24) -/* GPIOs on the AB8500 mixed-signals circuit */ -#define MOP500_AB8500_GPIO(x) (MOP500_EGPIO_END + (x)) +/*Snowball AB8500 GPIO */ +#define SNOWBALL_VSMPS2_1V8_GPIO AB8500_PIN_GPIO1 /* SYSCLKREQ2/GPIO1 */ +#define SNOWBALL_PM_GPIO1_GPIO AB8500_PIN_GPIO2 /* SYSCLKREQ3/GPIO2 */ +#define SNOWBALL_WLAN_CLK_REQ_GPIO AB8500_PIN_GPIO3 /* SYSCLKREQ4/GPIO3 */ +#define SNOWBALL_PM_GPIO4_GPIO AB8500_PIN_GPIO4 /* SYSCLKREQ6/GPIO4 */ +#define SNOWBALL_EN_3V6_GPIO AB8500_PIN_GPIO16 /* PWMOUT3/GPIO16 */ +#define SNOWBALL_PME_ETH_GPIO AB8500_PIN_GPIO24 /* SYSCLKREQ7/GPIO24 */ +#define SNOWBALL_EN_3V3_ETH_GPIO AB8500_PIN_GPIO26 /* GPIO26 */ + struct i2c_board_info; @@ -43,9 +77,19 @@ extern void mop500_sdi_init(void); extern void mop500_sdi_tc35892_init(void); void __init mop500_u8500uib_init(void); void __init mop500_stuib_init(void); +void __init mop500_msp_init(void); void __init mop500_pins_init(void); +void mop500_cyttsp_init(void); +void __init mop500_u8500uib_r3_init(void); -void mop500_uib_i2c_add(int busnum, struct i2c_board_info *info, +void mop500_uib_i2c_add(int busnum, struct i2c_board_info const *info, unsigned n); +int msp13_i2s_init(void); +int msp13_i2s_exit(void); + +int uib_is_stuib(void); +int uib_is_u8500uib(void); +int uib_is_u8500uibr3(void); + #endif diff --git a/arch/arm/mach-ux500/board-pins-sleep-force.c b/arch/arm/mach-ux500/board-pins-sleep-force.c new file mode 100644 index 00000000000..bef6f4e6df4 --- /dev/null +++ b/arch/arm/mach-ux500/board-pins-sleep-force.c @@ -0,0 +1,267 @@ +/* + * Copyright (C) ST-Ericsson SA 2011 + * + * License terms: GNU General Public License (GPL) version 2 + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/gpio.h> +#include <linux/io.h> +#include <linux/string.h> + +#include <linux/gpio/nomadik.h> +#include <mach/hardware.h> + +#include "board-pins-sleep-force.h" +#include "pins-db8500.h" +#include "pins.h" + +static u32 u8500_gpio_banks[] = {U8500_GPIOBANK0_BASE, + U8500_GPIOBANK1_BASE, + U8500_GPIOBANK2_BASE, + U8500_GPIOBANK3_BASE, + U8500_GPIOBANK4_BASE, + U8500_GPIOBANK5_BASE, + U8500_GPIOBANK6_BASE, + U8500_GPIOBANK7_BASE, + U8500_GPIOBANK8_BASE}; + +/* + * This function is called to force gpio power save + * settings during suspend. + */ +void sleep_pins_config_pm(pin_cfg_t *cfgs, int num) +{ + int i = 0; + int gpio = 0; + u32 w_imsc = 0; + u32 imsc = 0; + u32 offset; + u32 bitmask = 1; + u32 dirs_register = 0; + u32 dirc_register = 0; + u32 dats_register = 0; + u32 datc_register = 0; + u32 pdis_register_disable = 0; + u32 pdis_register_enabled = 0; + u32 slpm_register_disabled = 0; + u32 slpm_register_enabled = 0; + u32 bankaddr = 0; + + gpio = PIN_NUM(cfgs[i]); + + /* Get the bank number the pin is mapped to */ + bankaddr = IO_ADDRESS(u8500_gpio_banks[(gpio >> GPIO_BLOCK_SHIFT)]); + + w_imsc = readl(bankaddr + NMK_GPIO_RWIMSC) | + readl(bankaddr + NMK_GPIO_FWIMSC); + + imsc = readl(bankaddr + NMK_GPIO_RIMSC) | + readl(bankaddr + NMK_GPIO_FIMSC); + + for (i = 0; i < num; i++) { + /* Get the pin number */ + gpio = PIN_NUM(cfgs[i]); + + /* get the offest into the register */ + offset = gpio % NMK_GPIO_PER_CHIP; + /* Set the bit to toggle */ + bitmask = 1 << offset ; + + /* Next we check for direction (INPUT/OUTPUT) */ + switch (PIN_SLPM_DIR(cfgs[i])) { + case GPIO_IS_INPUT: + /* GPIO is set to input */ + dirc_register |= bitmask; + + /* + * Next check for pull (PULLUP/PULLDOWN) + * and configure accordingly. + */ + switch (PIN_SLPM_PULL(cfgs[i])) { + case GPIO_PULL_UPDOWN_DISABLED: + pdis_register_disable |= bitmask; + break; + + case GPIO_IS_PULLUP: + dats_register |= bitmask; + pdis_register_enabled |= bitmask; + break; + + case GPIO_IS_PULLDOWN: + datc_register |= bitmask; + pdis_register_enabled |= bitmask; + break; + + case GPIO_PULL_NO_CHANGE: + break; + + default: + BUG(); + break; + + } + break; + + case GPIO_IS_OUTPUT: + /* GPIO is set to output */ + dirs_register |= bitmask; + + /* + * Since its output there should not + * be a need to disable PULL UP/DOWN + * but better safe than sorry. + */ + pdis_register_disable |= bitmask; + /* Next we check for setting GPIO HIGH/LOW */ + switch (PIN_SLPM_VAL(cfgs[i])) { + case GPIO_IS_OUTPUT_LOW: + /* GPIO is set to LOW */ + datc_register |= bitmask; + break; + + case GPIO_IS_OUTPUT_HIGH: + /* GPIO is set to high */ + dats_register |= bitmask; + break; + + case GPIO_IS_NO_CHANGE: + break; + + default: + BUG(); + break; + } + + break; + case GPIO_IS_NOT_CHANGED: + break; + + default: + BUG(); + break; + } + + /* Next check for Sleep Power Managment (SLPM) */ + switch (PIN_SLPM(cfgs[i])) { + case GPIO_WAKEUP_IS_ENABLED: + slpm_register_enabled |= bitmask; + break; + + case GPIO_WAKEUP_IS_DISBLED: + slpm_register_disabled |= bitmask; + break; + + default: + BUG(); + break; + } + + /* Next check for Sleep Power Managment (SLPM) */ + switch (PIN_SLPM_PDIS(cfgs[i])) { + case GPIO_PDIS_NO_CHANGE: + break; + + case GPIO_PDIS_DISABLED: + pdis_register_disable |= bitmask; + break; + + case GPIO_PDIS_ENABLED: + pdis_register_enabled |= bitmask; + break; + + default: + BUG(); + break; + } + + } + + /* Write the register settings GPIO direction */ + writel(dirs_register & ~w_imsc, bankaddr + NMK_GPIO_DIRS); + writel(dirc_register, bankaddr + NMK_GPIO_DIRC); + + writel(datc_register & ~w_imsc, bankaddr + NMK_GPIO_DATC); + writel(dats_register & ~w_imsc, bankaddr + NMK_GPIO_DATS); + + /* Write the PDIS enable/disable */ + writel(readl(bankaddr + NMK_GPIO_PDIS) + | (pdis_register_disable & ~w_imsc & ~imsc), bankaddr + NMK_GPIO_PDIS); + writel(readl(bankaddr + NMK_GPIO_PDIS) + & (~pdis_register_enabled & ~w_imsc & ~imsc), bankaddr + NMK_GPIO_PDIS); + + /* Write the SLPM enable/disable */ + writel(readl(bankaddr + NMK_GPIO_SLPC) | slpm_register_disabled, + bankaddr + NMK_GPIO_SLPC); + writel(readl(bankaddr + NMK_GPIO_SLPC) & ~slpm_register_enabled, + bankaddr + NMK_GPIO_SLPC); +} + +void sleep_pins_config_pm_mux(pin_cfg_t *cfgs, int num) +{ + int i = 0; + int gpio = 0; + u32 offset; + u32 bitmask = 1; + u32 gpio_afsla_register_set = 0; + u32 gpio_afslb_register_set = 0; + u32 gpio_afsla_register_clear = 0; + u32 gpio_afslb_register_clear = 0; + u32 bankaddr = 0; + + gpio = PIN_NUM(cfgs[i]); + + /* Get the bank number the pin is mapped to */ + bankaddr = IO_ADDRESS(u8500_gpio_banks[(gpio >> GPIO_BLOCK_SHIFT)]); + + for (i = 0; i < num; i++) { + /* Get the pin number */ + gpio = PIN_NUM(cfgs[i]); + + /* get the offset into the register */ + offset = gpio % NMK_GPIO_PER_CHIP; + /* Set the bit to toggle */ + bitmask = 1 << offset ; + + /* First check for ALT pin configuration */ + switch (PIN_ALT(cfgs[i])) { + case NMK_GPIO_ALT_GPIO: + /* Set bit to configured as GPIO */ + gpio_afsla_register_clear |= bitmask; + gpio_afslb_register_clear |= bitmask; + break; + + case NMK_GPIO_ALT_A: + /* ALT A setting so set corresponding bit */ + gpio_afsla_register_set |= bitmask; + break; + + case NMK_GPIO_ALT_B: + /* ALT B setting so set corresponding bit */ + gpio_afslb_register_set |= bitmask; + break; + + case NMK_GPIO_ALT_C: + /* ALT C setting so set corresponding bits */ + gpio_afsla_register_set |= bitmask; + gpio_afslb_register_set |= bitmask; + break; + + default: + BUG(); + break; + } + } + /* Set bits that configures GPIO */ + writel(readl(bankaddr + NMK_GPIO_AFSLA) + & ~gpio_afsla_register_clear, bankaddr + NMK_GPIO_AFSLA); + writel(readl(bankaddr + NMK_GPIO_AFSLB) + & ~gpio_afslb_register_clear, bankaddr + NMK_GPIO_AFSLB); + + /* Set bits that configures ALT_X */ + writel(readl(bankaddr + NMK_GPIO_AFSLA) + | gpio_afsla_register_set, bankaddr + NMK_GPIO_AFSLA); + writel(readl(bankaddr + NMK_GPIO_AFSLB) + | gpio_afslb_register_set, bankaddr + NMK_GPIO_AFSLB); +} diff --git a/arch/arm/mach-ux500/board-pins-sleep-force.h b/arch/arm/mach-ux500/board-pins-sleep-force.h new file mode 100644 index 00000000000..0949c9bfcda --- /dev/null +++ b/arch/arm/mach-ux500/board-pins-sleep-force.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) ST-Ericsson SA 2011 + * + * License terms: GNU General Public License (GPL) version 2 + */ + +#ifndef __BOARD_PINS_SLEEP_FORCE_H +#define __BOARD_PINS_SLEEP_FORCE_H + +#include <plat/pincfg.h> + +#define NMK_GPIO_PER_CHIP 32 +#define GPIO_BLOCK_SHIFT 5 + +#define GPIO_IS_NOT_CHANGED 0 +#define GPIO_IS_INPUT 1 +#define GPIO_IS_OUTPUT 2 + +#define GPIO_WAKEUP_IS_ENABLED 0 +#define GPIO_WAKEUP_IS_DISBLED 1 + +#define GPIO_IS_NO_CHANGE 0 +#define GPIO_IS_OUTPUT_LOW 1 +#define GPIO_IS_OUTPUT_HIGH 2 + +#define GPIO_PULL_NO_CHANGE 0 +#define GPIO_PULL_UPDOWN_DISABLED 1 +#define GPIO_IS_PULLUP 2 +#define GPIO_IS_PULLDOWN 3 + +#define GPIO_PDIS_NO_CHANGE 0 +#define GPIO_PDIS_DISABLED 1 +#define GPIO_PDIS_ENABLED 2 + +void sleep_pins_config_pm_mux(pin_cfg_t *cfgs, int num); +void sleep_pins_config_pm(pin_cfg_t *cfgs, int num); + +#endif diff --git a/arch/arm/mach-ux500/board-u5500-cyttsp.c b/arch/arm/mach-ux500/board-u5500-cyttsp.c new file mode 100755 index 00000000000..f0f8192fade --- /dev/null +++ b/arch/arm/mach-ux500/board-u5500-cyttsp.c @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2011 ST-Ericsson SA + * Author: Avinash A <avinash.a@stericsson.com> for ST-Ericsson + * License terms:GNU General Public License (GPL) version 2 + */ +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/spi/spi.h> +#include <linux/gpio.h> +#include <linux/cyttsp.h> +#include <linux/delay.h> +#include <linux/amba/pl022.h> +#include <plat/pincfg.h> +#include <mach/hardware.h> + +#include "pins-db5500.h" +#include "board-u5500.h" + +/* cyttsp_gpio_board_init : configures the touch panel. */ +static int cyttsp_plat_init(int on) +{ + int ret; + + ret = gpio_direction_output(CYPRESS_SLAVE_SELECT_GPIO, 1); + if (ret < 0) { + pr_err("slave select gpio direction failed\n"); + gpio_free(CYPRESS_SLAVE_SELECT_GPIO); + return ret; + } + + return 0; +} + +static int cyttsp_wakeup(void) +{ + int ret; + + ret = gpio_request(CYPRESS_TOUCH_INT_PIN, "Wakeup_pin"); + if (ret < 0) { + pr_err("touch gpio failed\n"); + return ret; + } + ret = gpio_direction_output(CYPRESS_TOUCH_INT_PIN, 1); + if (ret < 0) { + pr_err("touch gpio direction failed\n"); + goto out; + } + gpio_set_value(CYPRESS_TOUCH_INT_PIN, 0); + gpio_set_value(CYPRESS_TOUCH_INT_PIN, 1); + /* + * To wake up the controller from sleep + * state the interrupt pin needs to be + * pulsed twice with a delay greater + * than 2 micro seconds. + */ + udelay(3); + gpio_set_value(CYPRESS_TOUCH_INT_PIN, 0); + gpio_set_value(CYPRESS_TOUCH_INT_PIN, 1); + ret = gpio_direction_input(CYPRESS_TOUCH_INT_PIN); + if (ret < 0) { + pr_err("touch gpio direction IN config failed\n"); + goto out; + } +out: + gpio_free(CYPRESS_TOUCH_INT_PIN); + return 0; +} +static struct cyttsp_platform_data cyttsp_spi_platdata = { + .maxx = 480, + .maxy = 854, + .flags = 0, + .gen = CY_GEN3, + .use_st = 0, + .use_mt = 1, + .use_trk_id = 0, + .use_hndshk = 0, + .use_sleep = 1, + .use_gestures = 0, + .use_load_file = 0, + .use_force_fw_update = 0, + .use_virtual_keys = 0, + /* activate up to 4 groups and set active distance */ + .gest_set = CY_GEST_GRP_NONE | CY_ACT_DIST, + /* change scn_type to enable finger and/or stylus detection */ + .scn_typ = 0xA5, /* autodetect finger+stylus; balanced mutual scan */ + .act_intrvl = CY_ACT_INTRVL_DFLT, /* Active refresh interval; ms */ + .tch_tmout = CY_TCH_TMOUT_DFLT, /* Active touch timeout; ms */ + .lp_intrvl = CY_LP_INTRVL_DFLT, /* Low power refresh interval; ms */ + .init = cyttsp_plat_init, + .mt_sync = input_mt_sync, + .wakeup = cyttsp_wakeup, + .name = CY_SPI_NAME, + .irq_gpio = CYPRESS_TOUCH_INT_PIN, + .rst_gpio = CYPRESS_TOUCH_RST_GPIO, +}; + +static void cyttsp_spi_cs_control(u32 command) +{ + if (command == SSP_CHIP_SELECT) + gpio_set_value(CYPRESS_SLAVE_SELECT_GPIO, 0); + else if (command == SSP_CHIP_DESELECT) + gpio_set_value(CYPRESS_SLAVE_SELECT_GPIO, 1); +} + +static struct pl022_config_chip cyttsp_ssp_config_chip = { + .com_mode = INTERRUPT_TRANSFER, + .iface = SSP_INTERFACE_MOTOROLA_SPI, + /* we can act as master only */ + .hierarchy = SSP_MASTER, + .slave_tx_disable = 0, + .rx_lev_trig = SSP_RX_1_OR_MORE_ELEM, + .tx_lev_trig = SSP_TX_16_OR_MORE_EMPTY_LOC, + .ctrl_len = SSP_BITS_16, + .wait_state = SSP_MWIRE_WAIT_ZERO, + .duplex = SSP_MICROWIRE_CHANNEL_FULL_DUPLEX, + .cs_control = cyttsp_spi_cs_control, +}; + +static struct spi_board_info cypress_spi_devices[] = { + { + .modalias = CY_SPI_NAME, + .controller_data = &cyttsp_ssp_config_chip, + .platform_data = &cyttsp_spi_platdata, + .max_speed_hz = 1000000, + .bus_num = 1, + .chip_select = 0, + .mode = SPI_MODE_0, + } +}; + +void u5500_cyttsp_init(void) +{ + int ret = 0; + + ret = gpio_request(CYPRESS_SLAVE_SELECT_GPIO, "slave_select_gpio"); + if (ret < 0) { + pr_err("slave select gpio failed\n"); + return; + } + if (cpu_is_u5500v2()) + cyttsp_spi_platdata.invert = true; + spi_register_board_info(cypress_spi_devices, + ARRAY_SIZE(cypress_spi_devices)); +} + diff --git a/arch/arm/mach-ux500/board-u5500-pins.c b/arch/arm/mach-ux500/board-u5500-pins.c new file mode 100644 index 00000000000..4635f240815 --- /dev/null +++ b/arch/arm/mach-ux500/board-u5500-pins.c @@ -0,0 +1,193 @@ +/* + * Copyright (C) ST-Ericsson SA 2011 + * + * License terms: GNU General Public License (GPL) version 2 + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/gpio.h> +#include <linux/gpio/nomadik.h> +#include <plat/pincfg.h> + +#include "pins-db5500.h" +#include "pins.h" + +static pin_cfg_t u5500_pins_default[] = { + /* MSP */ + GPIO32_MSP0_TCK | PIN_INPUT_PULLDOWN, + GPIO33_MSP0_TFS | PIN_INPUT_PULLDOWN, + GPIO34_MSP0_TXD | PIN_INPUT_PULLDOWN, + GPIO35_MSP0_RXD | PIN_INPUT_PULLDOWN, + GPIO96_MSP1_TCK | PIN_INPUT_PULLDOWN, + GPIO97_MSP1_TFS | PIN_INPUT_PULLDOWN, + GPIO98_MSP1_TXD | PIN_INPUT_PULLDOWN, + GPIO99_MSP1_RXD | PIN_INPUT_PULLDOWN, + GPIO220_MSP2_TCK | PIN_OUTPUT_LOW, + GPIO221_MSP2_TFS | PIN_OUTPUT_LOW, + GPIO222_MSP2_TXD | PIN_OUTPUT_LOW, + + /* DISPLAY_ENABLE */ + GPIO226_GPIO | PIN_OUTPUT_LOW, + + /* Backlight Enable */ + GPIO224_GPIO | PIN_OUTPUT_HIGH, + + /* UART0 */ + GPIO28_U0_TXD | PIN_OUTPUT_HIGH, + GPIO29_U0_RXD | PIN_INPUT_PULLUP, + + /* UART3 */ + GPIO165_U3_RXD | PIN_INPUT_PULLUP, + GPIO166_U3_TXD | PIN_OUTPUT_HIGH, + GPIO167_U3_RTSn | PIN_OUTPUT_HIGH, + GPIO168_U3_CTSn | PIN_INPUT_PULLUP, + + /* AB5500 */ + GPIO78_IRQn | PIN_SLPM_NOCHANGE, + GPIO100_I2C0_SCL | PIN_INPUT_PULLUP | PIN_SLPM_NOCHANGE, + GPIO101_I2C0_SDA | PIN_SLPM_NOCHANGE, + + /* TOUCH_IRQ */ + GPIO179_GPIO | PIN_INPUT_PULLUP, + + /* SD-CARD detect/levelshifter pins */ + GPIO180_GPIO | PIN_INPUT_PULLUP, + GPIO227_GPIO, + GPIO185_GPIO, + + /* Display & HDMI HW sync */ + GPIO204_LCD_VSI1 | PIN_INPUT_PULLUP, + + /* Camera & MMIO XshutDown*/ + GPIO1_GPIO | PIN_OUTPUT_LOW, + GPIO2_GPIO | PIN_OUTPUT_LOW, + + /* USB chip select */ + GPIO76_GPIO | PIN_OUTPUT_LOW, + + GPIO202_ACCU0_RXD | PIN_INPUT_PULLUP | PIN_SLPM_NOCHANGE, + GPIO203_ACCU0_TXD | PIN_OUTPUT_HIGH | PIN_SLPM_NOCHANGE, + + /* Board Id Identification B5500 or S5500 */ + GPIO0_GPIO | PIN_INPUT_PULLUP, + +}; + +static UX500_PINS(db5500_kp_pins, + /* Keypad */ + GPIO128_KP_I0 | PIN_INPUT_PULLUP | PIN_SLPM_OUTPUT_LOW, + GPIO130_KP_I1 | PIN_INPUT_PULLUP | PIN_SLPM_INPUT_PULLUP, + GPIO132_KP_I2 | PIN_INPUT_PULLUP | PIN_SLPM_INPUT_PULLUP, + GPIO134_KP_I3 | PIN_INPUT_PULLUP | PIN_SLPM_INPUT_PULLUP, + GPIO137_KP_O4 | PIN_INPUT_PULLUP | PIN_SLPM_OUTPUT_LOW, + GPIO139_KP_O5 | PIN_INPUT_PULLUP | PIN_SLPM_OUTPUT_LOW, +); + +static UX500_PINS(db5500_pins_sdi0, + /* SDI0 (eMMC) */ + GPIO5_MC0_DAT0 | PIN_INPUT_PULLUP, + GPIO6_MC0_DAT1 | PIN_INPUT_PULLUP, + GPIO7_MC0_DAT2 | PIN_INPUT_PULLUP, + GPIO8_MC0_DAT3 | PIN_INPUT_PULLUP, + GPIO9_MC0_DAT4 | PIN_INPUT_PULLUP, + GPIO10_MC0_DAT5 | PIN_INPUT_PULLUP, + GPIO11_MC0_DAT6 | PIN_INPUT_PULLUP, + GPIO12_MC0_DAT7 | PIN_INPUT_PULLUP, + GPIO13_MC0_CMD | PIN_INPUT_PULLUP, + GPIO14_MC0_CLK | PIN_OUTPUT_LOW, +); + +static UX500_PINS(db5500_pins_sdi1, + /* SDI1 (SD-CARD) */ + GPIO191_MC1_DAT0 | PIN_INPUT_PULLUP, + GPIO192_MC1_DAT1 | PIN_INPUT_PULLUP, + GPIO193_MC1_DAT2 | PIN_INPUT_PULLUP, + GPIO194_MC1_DAT3 | PIN_INPUT_PULLUP, + GPIO195_MC1_CLK | PIN_OUTPUT_LOW, + GPIO196_MC1_CMD | PIN_INPUT_PULLUP, + GPIO197_MC1_CMDDIR | PIN_OUTPUT_HIGH, + GPIO198_MC1_FBCLK | PIN_INPUT_NOPULL, + GPIO199_MC1_DAT0DIR | PIN_OUTPUT_HIGH, +); + +static UX500_PINS(db5500_pins_sdi2, + /* SDI2 (eMMC) */ + GPIO16_MC2_CMD | PIN_INPUT_PULLUP, + GPIO17_MC2_CLK | PIN_OUTPUT_LOW, + GPIO23_MC2_DAT0 | PIN_INPUT_PULLUP, + GPIO19_MC2_DAT1 | PIN_INPUT_PULLUP, + GPIO24_MC2_DAT2 | PIN_INPUT_PULLUP, + GPIO20_MC2_DAT3 | PIN_INPUT_PULLUP, + GPIO25_MC2_DAT4 | PIN_INPUT_PULLUP, + GPIO21_MC2_DAT5 | PIN_INPUT_PULLUP, + GPIO26_MC2_DAT6 | PIN_INPUT_PULLUP, + GPIO22_MC2_DAT7 | PIN_INPUT_PULLUP +); + +static UX500_PINS(db5500_pins_sdi3, + /* SDI3 (SDIO) */ + GPIO171_MC3_DAT0 | PIN_INPUT_PULLUP | PIN_LOWEMI_ENABLED, + GPIO172_MC3_DAT1 | PIN_INPUT_PULLUP | PIN_LOWEMI_ENABLED, + GPIO173_MC3_DAT2 | PIN_INPUT_PULLUP | PIN_LOWEMI_ENABLED, + GPIO174_MC3_DAT3 | PIN_INPUT_PULLUP | PIN_LOWEMI_ENABLED, + GPIO175_MC3_CMD | PIN_INPUT_PULLUP | PIN_LOWEMI_ENABLED, + GPIO176_MC3_CLK | PIN_OUTPUT_LOW, +); + +static UX500_PINS(u5500_pins_i2c1, + GPIO3_I2C1_SCL, + GPIO4_I2C1_SDA, +); + +static UX500_PINS(u5500_pins_i2c2, + GPIO218_I2C2_SCL, + GPIO219_I2C2_SDA, +); + +static UX500_PINS(u5500_pins_i2c3, + GPIO177_I2C3_SCL, + GPIO178_I2C3_SDA, +); + +static UX500_PINS(u5500_pins_spi3, + GPIO186_GPIO | PIN_OUTPUT_HIGH, + GPIO188_SPI3_RXD | PIN_INPUT_PULLDOWN, + GPIO189_SPI3_TXD | PIN_OUTPUT_LOW, + GPIO190_SPI3_CLK | PIN_OUTPUT_LOW, +); + +/* USB */ +static UX500_PINS(u5500_pins_usb, + GPIO74_USB_NXT, + GPIO72_USB_STP | PIN_OUTPUT_HIGH, + GPIO75_USB_XCLK, + GPIO73_USB_DIR, + GPIO71_USB_DAT7, + GPIO70_USB_DAT6, + GPIO69_USB_DAT5, + GPIO68_USB_DAT4, + GPIO67_USB_DAT3, + GPIO66_USB_DAT2, + GPIO65_USB_DAT1, + GPIO64_USB_DAT0, +); + +static struct ux500_pin_lookup u5500_pins[] = { + PIN_LOOKUP("nmk-i2c.1", &u5500_pins_i2c1), + PIN_LOOKUP("nmk-i2c.2", &u5500_pins_i2c2), + PIN_LOOKUP("nmk-i2c.3", &u5500_pins_i2c3), + PIN_LOOKUP("spi3", &u5500_pins_spi3), + PIN_LOOKUP("db5500_kp", &db5500_kp_pins), + PIN_LOOKUP("ab5500-usb.0", &u5500_pins_usb), + PIN_LOOKUP("sdi0", &db5500_pins_sdi0), + PIN_LOOKUP("sdi1", &db5500_pins_sdi1), + PIN_LOOKUP("sdi2", &db5500_pins_sdi2), + PIN_LOOKUP("sdi3", &db5500_pins_sdi3), +}; + +void __init u5500_pins_init(void) +{ + nmk_config_pins(u5500_pins_default, ARRAY_SIZE(u5500_pins_default)); + ux500_pins_add(u5500_pins, ARRAY_SIZE(u5500_pins)); +} diff --git a/arch/arm/mach-ux500/board-u5500.c b/arch/arm/mach-ux500/board-u5500.c index e58f0f56242..7752f22d95e 100644 --- a/arch/arm/mach-ux500/board-u5500.c +++ b/arch/arm/mach-ux500/board-u5500.c @@ -1,16 +1,34 @@ /* * Copyright (C) ST-Ericsson SA 2010 * - * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson * License terms: GNU General Public License (GPL) version 2 */ #include <linux/init.h> #include <linux/platform_device.h> #include <linux/amba/bus.h> +#include <linux/amba/pl022.h> #include <linux/gpio.h> #include <linux/irq.h> #include <linux/i2c.h> +#ifdef CONFIG_STM_I2S +#include <linux/i2s/i2s.h> +#endif +#include <linux/mfd/abx500.h> +#include <linux/led-lm3530.h> +#include <../drivers/staging/ste_rmi4/synaptics_i2c_rmi4.h> +#include <linux/input/matrix_keypad.h> +#ifdef CONFIG_SENSORS_LSM303DLH +#include <linux/lsm303dlh.h> +#endif +#include <linux/leds-ab5500.h> +#ifdef CONFIG_TOUCHSCREEN_CYTTSP_SPI +#include <linux/cyttsp.h> +#endif + +#ifdef CONFIG_AV8100 +#include <video/av8100.h> +#endif #include <asm/mach/arch.h> #include <asm/mach-types.h> @@ -19,33 +37,130 @@ #include <plat/i2c.h> #include <mach/hardware.h> +#include <mach/ste-dma40-db5500.h> +#ifdef CONFIG_STM_I2S +#include <mach/msp.h> +#endif #include <mach/devices.h> #include <mach/setup.h> +#include <mach/db5500-keypad.h> +#include <mach/crypto-ux500.h> +#include <mach/usb.h> +#include <mach/abx500-accdet.h> #include "pins-db5500.h" +#include "pins.h" #include "devices-db5500.h" -#include <linux/led-lm3530.h> +#include "board-u5500.h" +#include "board-u5500-bm.h" +#include "board-u5500-wlan.h" +#include "board-ux500-usb.h" + +#ifdef CONFIG_SENSORS_LSM303DLH +/* + * LSM303DLH + */ + +static struct lsm303dlh_platform_data __initdata lsm303dlh_pdata = { + .name_a = "lsm303dlh.0", + .name_m = "lsm303dlh.1", + .axis_map_x = 1, + .axis_map_y = 0, + .axis_map_z = 2, + .negative_x = 0, + .negative_y = 0, + .negative_z = 1, +}; +#endif + +/* + * Touchscreen + */ +static struct synaptics_rmi4_platform_data rmi4_i2c_platformdata = { + .irq_number = NOMADIK_GPIO_TO_IRQ(179), + .irq_type = (IRQF_TRIGGER_FALLING | IRQF_SHARED), +#if defined(CONFIG_DISPLAY_GENERIC_DSI_PRIMARY_ROTATION_ANGLE) && \ + CONFIG_DISPLAY_GENERIC_DSI_PRIMARY_ROTATION_ANGLE == 270 + .x_flip = true, + .y_flip = false, +#else + .x_flip = false, + .y_flip = true, +#endif + .regulator_en = true, +}; + +static struct av8100_platform_data av8100_plat_data = { + .irq = NOMADIK_GPIO_TO_IRQ(223), + .reset = 225, + .alt_powerupseq = true, + .mclk_freq = 1, /* MCLK_RNG_22_27 */ +}; /* - * GPIO + * leds LM3530 */ +static struct lm3530_platform_data u5500_als_platform_data = { + .mode = LM3530_BL_MODE_MANUAL, + .als_input_mode = LM3530_INPUT_ALS1, + .max_current = LM3530_FS_CURR_26mA, + .pwm_pol_hi = true, + .als_avrg_time = LM3530_ALS_AVRG_TIME_512ms, + .brt_ramp_law = 1, /* Linear */ + .brt_ramp_fall = LM3530_RAMP_TIME_8s, + .brt_ramp_rise = LM3530_RAMP_TIME_8s, + .als1_resistor_sel = LM3530_ALS_IMPD_13_53kOhm, + .als2_resistor_sel = LM3530_ALS_IMPD_Z, + .als_vmin = 730, /* mV */ + .als_vmax = 1020, /* mV */ + .brt_val = 0x7F, /* Max brightness */ +}; -static pin_cfg_t u5500_pins[] = { - /* I2C */ - GPIO218_I2C2_SCL | PIN_INPUT_PULLUP, - GPIO219_I2C2_SDA | PIN_INPUT_PULLUP, - /* DISPLAY_ENABLE */ - GPIO226_GPIO | PIN_OUTPUT_LOW, +/* leds-ab5500 */ +static struct ab5500_hvleds_platform_data ab5500_hvleds_data = { + .hw_fade = false, + .leds = { + [0] = { + .name = "red", + .led_on = true, + .led_id = 0, + .fade_hi = 255, + .fade_lo = 0, + .max_current = 10, /* wrong value may damage h/w */ + }, + [1] = { + .name = "green", + .led_on = true, + .led_id = 1, + .fade_hi = 255, + .fade_lo = 0, + .max_current = 10, /* wrong value may damage h/w */ + }, + [2] { + .name = "blue", + .led_on = true, + .led_id = 2, + .fade_hi = 255, + .fade_lo = 0, + .max_current = 10, /* wrong value may damage h/w */ + }, + }, +}; - /* Backlight Enbale */ - GPIO224_GPIO | PIN_OUTPUT_HIGH, +static struct ab5500_ponkey_platform_data ab5500_ponkey_data = { + /* + * Shutdown time in secs. Can be set + * to 10sec, 5sec and 0sec(disabled) + */ + .shutdown_secs = 10, }; + /* * I2C */ -#define U5500_I2C_CONTROLLER(id, _slsu, _tft, _rft, clk, _sm) \ +#define U5500_I2C_CONTROLLER(id, _slsu, _tft, _rft, clk, t_out, _sm) \ static struct nmk_i2c_controller u5500_i2c##id##_data = { \ /* \ * slave data setup time, which is \ @@ -60,33 +175,58 @@ static struct nmk_i2c_controller u5500_i2c##id##_data = { \ .rft = _rft, \ /* std. mode operation */ \ .clk_freq = clk, \ + /* Slave response timeout(ms) */\ + .timeout = t_out, \ .sm = _sm, \ } + /* - * The board uses TODO <3> i2c controllers, initialize all of + * The board uses 3 i2c controllers, initialize all of * them with slave data setup time of 250 ns, * Tx & Rx FIFO threshold values as 1 and standard * mode of operation */ -U5500_I2C_CONTROLLER(2, 0xe, 1, 1, 400000, I2C_FREQ_MODE_FAST); +U5500_I2C_CONTROLLER(1, 0xe, 1, 10, 400000, 200, I2C_FREQ_MODE_FAST); +U5500_I2C_CONTROLLER(2, 0xe, 1, 10, 400000, 200, I2C_FREQ_MODE_FAST); +U5500_I2C_CONTROLLER(3, 0xe, 1, 10, 400000, 200, I2C_FREQ_MODE_FAST); -static struct lm3530_platform_data u5500_als_platform_data = { - .mode = LM3530_BL_MODE_MANUAL, - .als_input_mode = LM3530_INPUT_ALS1, - .max_current = LM3530_FS_CURR_26mA, - .pwm_pol_hi = true, - .als_avrg_time = LM3530_ALS_AVRG_TIME_512ms, - .brt_ramp_law = 1, /* Linear */ - .brt_ramp_fall = LM3530_RAMP_TIME_8s, - .brt_ramp_rise = LM3530_RAMP_TIME_8s, - .als1_resistor_sel = LM3530_ALS_IMPD_13_53kOhm, - .als2_resistor_sel = LM3530_ALS_IMPD_Z, - .als_vmin = 730, /* mV */ - .als_vmax = 1020, /* mV */ - .brt_val = 0x7F, /* Max brightness */ +static struct i2c_board_info __initdata u5500_i2c1_devices[] = { + { + I2C_BOARD_INFO("synaptics_rmi4_i2c", 0x4B), + .platform_data = &rmi4_i2c_platformdata, + }, +}; + +static struct i2c_board_info __initdata u5500v1_i2c2_sensor_devices[] = { +#ifdef CONFIG_SENSORS_LSM303DLH + { + /* LSM303DLH Accelerometer */ + I2C_BOARD_INFO("lsm303dlh_a", 0x19), + .platform_data = &lsm303dlh_pdata, + }, + { + /* LSM303DLH Magnetometer */ + I2C_BOARD_INFO("lsm303dlh_m", 0x1E), + .platform_data = &lsm303dlh_pdata, + }, +#endif }; +static struct i2c_board_info __initdata u5500v2_i2c2_sensor_devices[] = { +#ifdef CONFIG_SENSORS_LSM303DLH + { + /* LSM303DLHC Accelerometer */ + I2C_BOARD_INFO("lsm303dlhc_a", 0x19), + .platform_data = &lsm303dlh_pdata, + }, + { + /* LSM303DLH Magnetometer */ + I2C_BOARD_INFO("lsm303dlh_m", 0x1E), + .platform_data = &lsm303dlh_pdata, + }, +#endif +}; static struct i2c_board_info __initdata u5500_i2c2_devices[] = { { @@ -94,27 +234,431 @@ static struct i2c_board_info __initdata u5500_i2c2_devices[] = { I2C_BOARD_INFO("lm3530-led", 0x36), .platform_data = &u5500_als_platform_data, }, + { + I2C_BOARD_INFO("av8100", 0x70), + .platform_data = &av8100_plat_data, + }, +}; + +/* + * Keypad + */ + +#define ROW_PIN_I0 128 +#define ROW_PIN_I1 130 +#define ROW_PIN_I2 132 +#define ROW_PIN_I3 134 +#define COL_PIN_O4 137 +#define COL_PIN_O5 139 + +static int db5500_kp_rows[] = { + ROW_PIN_I0, ROW_PIN_I1, ROW_PIN_I2, ROW_PIN_I3, +}; + +static int db5500_kp_cols[] = { + COL_PIN_O4, COL_PIN_O5, +}; + +static bool db5500_config; +static int db5500_set_gpio_row(int gpio) +{ + int ret = -1; + + + if (!db5500_config) { + ret = gpio_request(gpio, "db5500_kpd"); + if (ret < 0) { + pr_err("db5500_set_gpio_row: gpio request failed\n"); + return ret; + } + } + + ret = gpio_direction_output(gpio, 1); + if (ret < 0) { + pr_err("db5500_set_gpio_row: gpio direction failed\n"); + gpio_free(gpio); + } + + return ret; +} + +static int db5500_kp_init(void) +{ + struct ux500_pins *pins; + int ret, i; + + pins = ux500_pins_get("db5500_kp"); + if (pins) + ux500_pins_enable(pins); + + for (i = 0; i < ARRAY_SIZE(db5500_kp_rows); i++) { + ret = db5500_set_gpio_row(db5500_kp_rows[i]); + if (ret < 0) { + pr_err("db5500_kp_init: failed init\n"); + return ret; + } + } + + if (!db5500_config) + db5500_config = true; + + return 0; +} + +static int db5500_kp_exit(void) +{ + struct ux500_pins *pins; + + pins = ux500_pins_get("db5500_kp"); + if (pins) + ux500_pins_disable(pins); + + return 0; +} + +static const unsigned int u5500_keymap[] = { + KEY(4, 0, KEY_CAMERA), /* Camera2 */ + KEY(4, 1, KEY_CAMERA_FOCUS), /* Camera1 */ + KEY(4, 2, KEY_MENU), + KEY(4, 3, KEY_BACK), + KEY(5, 2, KEY_SEND), + KEY(5, 3, KEY_HOME), +#ifndef CONFIG_INPUT_AB8500_PONKEY + /* AB5500 ONSWa is also hooked up to this key */ + KEY(8, 0, KEY_END), +#endif + KEY(8, 1, KEY_VOLUMEUP), + KEY(8, 2, KEY_VOLUMEDOWN), +}; + +static struct matrix_keymap_data u5500_keymap_data = { + .keymap = u5500_keymap, + .keymap_size = ARRAY_SIZE(u5500_keymap), +}; + +static struct db5500_keypad_platform_data u5500_keypad_board = { + .init = db5500_kp_init, + .exit = db5500_kp_exit, + .gpio_input_pins = db5500_kp_rows, + .gpio_output_pins = db5500_kp_cols, + .keymap_data = &u5500_keymap_data, + .no_autorepeat = true, + .krow = ARRAY_SIZE(db5500_kp_rows), + .kcol = ARRAY_SIZE(db5500_kp_cols), + .debounce_ms = 40, /* milliseconds */ + .switch_delay = 200, /* in jiffies */ +}; + +#ifdef CONFIG_STM_I2S +/* + * MSP + */ + +#define MSP_DMA(num, eventline) \ +static struct stedma40_chan_cfg msp##num##_dma_rx = { \ + .high_priority = true, \ + .dir = STEDMA40_PERIPH_TO_MEM, \ + .src_dev_type = eventline##_RX, \ + .dst_dev_type = STEDMA40_DEV_DST_MEMORY, \ + .src_info.psize = STEDMA40_PSIZE_LOG_4, \ + .dst_info.psize = STEDMA40_PSIZE_LOG_4, \ +}; \ + \ +static struct stedma40_chan_cfg msp##num##_dma_tx = { \ + .high_priority = true, \ + .dir = STEDMA40_MEM_TO_PERIPH, \ + .src_dev_type = STEDMA40_DEV_SRC_MEMORY, \ + .dst_dev_type = eventline##_TX, \ + .src_info.psize = STEDMA40_PSIZE_LOG_4, \ + .dst_info.psize = STEDMA40_PSIZE_LOG_4, \ +} + +MSP_DMA(0, DB5500_DMA_DEV9_MSP0); +MSP_DMA(1, DB5500_DMA_DEV10_MSP1); +MSP_DMA(2, DB5500_DMA_DEV11_MSP2); + +static struct msp_i2s_platform_data u5500_msp0_data = { + .id = MSP_0_I2S_CONTROLLER, + .msp_i2s_dma_rx = &msp0_dma_rx, + .msp_i2s_dma_tx = &msp0_dma_tx, +}; + +static struct msp_i2s_platform_data u5500_msp1_data = { + .id = MSP_1_I2S_CONTROLLER, + .msp_i2s_dma_rx = &msp1_dma_rx, + .msp_i2s_dma_tx = &msp1_dma_tx, +}; + +static struct msp_i2s_platform_data u5500_msp2_data = { + .id = MSP_2_I2S_CONTROLLER, + .msp_i2s_dma_rx = &msp2_dma_rx, + .msp_i2s_dma_tx = &msp2_dma_tx, +}; + +static struct i2s_board_info stm_i2s_board_info[] __initdata = { + { + .modalias = "i2s_device.0", + .id = 0, + .chip_select = 0, + }, + { + .modalias = "i2s_device.1", + .id = 1, + .chip_select = 1, + }, + { + .modalias = "i2s_device.2", + .id = 2, + .chip_select = 2, + }, +}; + +static void __init u5500_msp_init(void) +{ + db5500_add_msp0_i2s(&u5500_msp0_data); + db5500_add_msp1_i2s(&u5500_msp1_data); + db5500_add_msp2_i2s(&u5500_msp2_data); + + i2s_register_board_info(ARRAY_AND_SIZE(stm_i2s_board_info)); +} +#else +static void __init u5500_msp_init(void) +{ +} +#endif + +/* + * SPI + */ + +static struct pl022_ssp_controller u5500_spi3_data = { + .bus_id = 1, + .num_chipselect = 4, /* 3 possible CS lines + 1 for tests */ +}; + +static void __init u5500_spi_init(void) +{ + db5500_add_spi3(&u5500_spi3_data); +} + +static struct resource ab5500_resources[] = { + [0] = { + .start = IRQ_DB5500_PRCMU_ABB, + .end = IRQ_DB5500_PRCMU_ABB, + .flags = IORESOURCE_IRQ + } }; + +#ifdef CONFIG_INPUT_AB5500_ACCDET +static struct abx500_accdet_platform_data ab5500_accdet_pdata = { + .btn_keycode = KEY_MEDIA, + .accdet1_dbth = ACCDET1_TH_300mV | ACCDET1_DB_10ms, + .accdet2122_th = ACCDET21_TH_300mV | ACCDET22_TH_300mV, + .is_detection_inverted = false, + }; +#endif + +static struct ab5500_platform_data ab5500_plf_data = { + .irq = { + .base = IRQ_AB5500_BASE, + .count = AB5500_NR_IRQS, + }, + .pm_power_off = true, + .regulator = &u5500_ab5500_regulator_data, +#ifdef CONFIG_INPUT_AB5500_ACCDET + .dev_data[AB5500_DEVID_ACCDET] = &ab5500_accdet_pdata, + .dev_data_sz[AB5500_DEVID_ACCDET] = sizeof(ab5500_accdet_pdata), +#endif + .dev_data[AB5500_DEVID_LEDS] = &ab5500_hvleds_data, + .dev_data_sz[AB5500_DEVID_LEDS] = sizeof(ab5500_hvleds_data), + .init_settings = (struct abx500_init_settings[]){ + { + .bank = 0x3, + .reg = 0x17, + .setting = 0x0F, + }, + { + .bank = 0x3, + .reg = 0x18, + .setting = 0x10, + }, + }, + .init_settings_sz = 2, +#if defined(CONFIG_AB5500_BM) + .dev_data[AB5500_DEVID_CHARGALG] = &abx500_bm_pt_data, + .dev_data_sz[AB5500_DEVID_CHARGALG] = sizeof(abx500_bm_pt_data), + .dev_data[AB5500_DEVID_CHARGER] = &abx500_bm_pt_data, + .dev_data_sz[AB5500_DEVID_CHARGER] = sizeof(abx500_bm_pt_data), + .dev_data[AB5500_DEVID_FG] = &abx500_bm_pt_data, + .dev_data_sz[AB5500_DEVID_FG] = sizeof(abx500_bm_pt_data), + .dev_data[AB5500_DEVID_BTEMP] = &abx500_bm_pt_data, + .dev_data_sz[AB5500_DEVID_BTEMP] = sizeof(abx500_bm_pt_data), +#endif + .dev_data[AB5500_DEVID_ONSWA] = &ab5500_ponkey_data, + .dev_data_sz[AB5500_DEVID_ONSWA] = sizeof(ab5500_ponkey_data), + .dev_data[AB5500_DEVID_USB] = &abx500_usbgpio_plat_data, + .dev_data_sz[AB5500_DEVID_USB] = sizeof(abx500_usbgpio_plat_data), +}; + +static struct platform_device u5500_ab5500_device = { + .name = "ab5500-core", + .id = 0, + .dev = { + .platform_data = &ab5500_plf_data, + }, + .num_resources = 1, + .resource = ab5500_resources, +}; + +static struct platform_device u5500_mloader_device = { + .name = "db5500_mloader", + .id = -1, + .num_resources = 0, +}; + +static struct cryp_platform_data u5500_cryp1_platform_data = { + .mem_to_engine = { + .dir = STEDMA40_MEM_TO_PERIPH, + .src_dev_type = STEDMA40_DEV_SRC_MEMORY, + .dst_dev_type = DB5500_DMA_DEV48_CRYPTO1_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_4, + .dst_info.psize = STEDMA40_PSIZE_LOG_4, + }, + .engine_to_mem = { + .dir = STEDMA40_PERIPH_TO_MEM, + .src_dev_type = DB5500_DMA_DEV48_CRYPTO1_RX, + .dst_dev_type = STEDMA40_DEV_DST_MEMORY, + .src_info.data_width = STEDMA40_WORD_WIDTH, + .dst_info.data_width = STEDMA40_WORD_WIDTH, + .mode = STEDMA40_MODE_LOGICAL, + .src_info.psize = STEDMA40_PSIZE_LOG_4, + .dst_info.psize = STEDMA40_PSIZE_LOG_4, + } +}; + +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, +}, +}; + +static struct platform_device *u5500_platform_devices[] __initdata = { + &u5500_ab5500_device, +#ifdef CONFIG_FB_MCDE + &u5500_mcde_device, +#endif + &ux500_hwmem_device, + &u5500_b2r2_device, + &u5500_mloader_device, +#ifdef CONFIG_U5500_MMIO + &u5500_mmio_device, +#endif + &u5500_thsens_device, +}; + +/* + * This function check whether it is Small S5500 board + * GPIO0 is HIGH for S5500 + */ +bool is_s5500_board() +{ + int err , val ; + + err = gpio_request(GPIO_BOARD_VERSION, "Board Version"); + if (err) { + pr_err("Error %d while requesting GPIO for Board Version\n", + err); + return err; + } + + err = gpio_direction_input(GPIO_BOARD_VERSION); + if (err) { + pr_err("Error %d while setting GPIO for Board Version" + "output mode\n", err); + return err; + } + + val = gpio_get_value(GPIO_BOARD_VERSION); + + gpio_free(GPIO_BOARD_VERSION); + + return (val == 1); +} + + static void __init u5500_i2c_init(void) { + db5500_add_i2c1(&u5500_i2c1_data); db5500_add_i2c2(&u5500_i2c2_data); + db5500_add_i2c3(&u5500_i2c3_data); + + i2c_register_board_info(1, ARRAY_AND_SIZE(u5500_i2c1_devices)); i2c_register_board_info(2, ARRAY_AND_SIZE(u5500_i2c2_devices)); + + if (cpu_is_u5500v1()) + i2c_register_board_info(2, ARRAY_AND_SIZE(u5500v1_i2c2_sensor_devices)); + + if (cpu_is_u5500v2()) { + /* + * In V2 display is mounted in reverse direction, + * so need to change the intial + * settings of Accelerometer and Magnetometer + */ + lsm303dlh_pdata.negative_x = 1; + lsm303dlh_pdata.negative_y = 1; + i2c_register_board_info(2, ARRAY_AND_SIZE(u5500v2_i2c2_sensor_devices)); + } } + static void __init u5500_uart_init(void) { db5500_add_uart0(NULL); db5500_add_uart1(NULL); db5500_add_uart2(NULL); + db5500_add_uart3(NULL); +} + +static void __init u5500_cryp1_hash1_init(void) +{ + db5500_add_cryp1(&u5500_cryp1_platform_data); + db5500_add_hash1(&u5500_hash1_platform_data); } static void __init u5500_init_machine(void) { + u5500_regulators_init(); u5500_init_devices(); - nmk_config_pins(u5500_pins, ARRAY_SIZE(u5500_pins)); + u5500_pins_init(); + u5500_i2c_init(); + u5500_msp_init(); + u5500_spi_init(); + u5500_sdi_init(); u5500_uart_init(); + + u5500_wlan_init(); + + db5500_add_keypad(&u5500_keypad_board); + u5500_cryp1_hash1_init(); + +#ifdef CONFIG_TOUCHSCREEN_CYTTSP_SPI + u5500_cyttsp_init(); +#endif + + platform_add_devices(u5500_platform_devices, + ARRAY_SIZE(u5500_platform_devices)); } MACHINE_START(U5500, "ST-Ericsson U5500 Platform") @@ -124,3 +668,11 @@ MACHINE_START(U5500, "ST-Ericsson U5500 Platform") .timer = &ux500_timer, .init_machine = u5500_init_machine, MACHINE_END + +MACHINE_START(B5500, "ST-Ericsson U5500 Big Board") + .atag_offset = 0x00000100, + .map_io = u5500_map_io, + .init_irq = ux500_init_irq, + .timer = &ux500_timer, + .init_machine = u5500_init_machine, +MACHINE_END diff --git a/arch/arm/mach-ux500/board-u5500.h b/arch/arm/mach-ux500/board-u5500.h new file mode 100644 index 00000000000..85762e5efb1 --- /dev/null +++ b/arch/arm/mach-ux500/board-u5500.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * License terms: GNU General Public License (GPL) version 2 + */ + +#ifndef __BOARD_U5500_H +#define __BOARD_U5500_H + +#define GPIO_SDMMC_CD 180 +#define GPIO_MMC_CARD_CTRL 227 +#define GPIO_MMC_CARD_VSEL 185 +#define GPIO_BOARD_VERSION 0 +#define GPIO_PRIMARY_CAM_XSHUTDOWN 1 +#define GPIO_SECONDARY_CAM_XSHUTDOWN 2 +#define GPIO_CAMERA_PMIC_EN 212 +#define CYPRESS_TOUCH_INT_PIN 179 +#define CYPRESS_TOUCH_RST_GPIO 135 +#define CYPRESS_SLAVE_SELECT_GPIO 186 + + +struct ab5500_regulator_platform_data; +extern struct ab5500_regulator_platform_data u5500_ab5500_regulator_data; + +extern void u5500_pins_init(void); +extern void __init u5500_regulators_init(void); +void u5500_cyttsp_init(void); +bool is_s5500_board(); + +#endif diff --git a/arch/arm/mach-ux500/cpu-db5500.c b/arch/arm/mach-ux500/cpu-db5500.c index 22705d246fc..1a04ca99007 100644 --- a/arch/arm/mach-ux500/cpu-db5500.c +++ b/arch/arm/mach-ux500/cpu-db5500.c @@ -9,20 +9,23 @@ #include <linux/amba/bus.h> #include <linux/io.h> #include <linux/irq.h> +#include <linux/gpio/nomadik.h> -#include <asm/mach/map.h> #include <asm/pmu.h> +#include <asm/mach/map.h> +#include <asm/cacheflush.h> +#include <asm/tlbflush.h> -#include <plat/gpio.h> +#include <linux/gpio.h> #include <mach/hardware.h> #include <mach/devices.h> #include <mach/setup.h> #include <mach/irqs.h> #include <mach/usb.h> +#include <mach/ste-dma40-db5500.h> #include "devices-db5500.h" -#include "ste-dma40-db5500.h" static struct map_desc u5500_uart_io_desc[] __initdata = { __IO_DEV_DESC(U5500_UART0_BASE, SZ_4K), @@ -35,8 +38,11 @@ static struct map_desc u5500_io_desc[] __initdata = { __IO_DEV_DESC(U5500_L2CC_BASE, SZ_4K), __IO_DEV_DESC(U5500_TWD_BASE, SZ_4K), __IO_DEV_DESC(U5500_MTU0_BASE, SZ_4K), + __IO_DEV_DESC(U5500_MTU1_BASE, SZ_4K), __IO_DEV_DESC(U5500_SCU_BASE, SZ_4K), + __IO_DEV_DESC(U5500_RTC_BASE, SZ_4K), __IO_DEV_DESC(U5500_BACKUPRAM0_BASE, SZ_8K), + __MEM_DEV_DESC(U5500_BOOT_ROM_BASE, SZ_1M), __IO_DEV_DESC(U5500_GPIO0_BASE, SZ_4K), __IO_DEV_DESC(U5500_GPIO1_BASE, SZ_4K), @@ -45,26 +51,11 @@ static struct map_desc u5500_io_desc[] __initdata = { __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[] = { - [0] = { - .start = IRQ_DB5500_PMU0, - .end = IRQ_DB5500_PMU0, - .flags = IORESOURCE_IRQ, - }, - [1] = { - .start = IRQ_DB5500_PMU1, - .end = IRQ_DB5500_PMU1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device db5500_pmu_device = { - .name = "arm-pmu", - .id = ARM_PMU_DEVICE_CPU, - .num_resources = ARRAY_SIZE(db5500_pmu_resources), - .resource = db5500_pmu_resources, + __IO_DEV_DESC(U5500_CLKRST1_BASE, SZ_4K), + __IO_DEV_DESC(U5500_CLKRST2_BASE, SZ_4K), + __IO_DEV_DESC(U5500_CLKRST3_BASE, SZ_4K), + __IO_DEV_DESC(U5500_CLKRST5_BASE, SZ_4K), + __IO_DEV_DESC(U5500_CLKRST6_BASE, SZ_4K), }; static struct resource mbox0_resources[] = { @@ -151,11 +142,15 @@ static struct platform_device mbox2_device = { .num_resources = ARRAY_SIZE(mbox2_resources), }; +static struct platform_device db5500_prcmu_device = { + .name = "db5500-prcmu", +}; + static struct platform_device *db5500_platform_devs[] __initdata = { - &db5500_pmu_device, &mbox0_device, &mbox1_device, &mbox2_device, + &db5500_prcmu_device, }; static resource_size_t __initdata db5500_gpio_base[] = { @@ -179,6 +174,38 @@ static void __init db5500_add_gpios(void) IRQ_DB5500_GPIO0, &pdata); } +static u8 db5500_revision; + +bool cpu_is_u5500v1() +{ + return db5500_revision == 0xA0; +} + +bool cpu_is_u5500v2() +{ + return db5500_revision == 0xB0; +} + +static void db5500_rev_init(void) +{ + const char *version = "UNKNOWN"; + unsigned int asicid; + + /* As in devicemaps_init() */ + local_flush_tlb_all(); + flush_cache_all(); + + asicid = readl_relaxed(__io_address(U5500_ASIC_ID_ADDRESS)); + db5500_revision = asicid & 0xff; + + if (cpu_is_u5500v1()) + version = "1.0"; + else if (cpu_is_u5500v2()) + version = "2.0"; + + pr_info("DB5500 v%s [%#010x]\n", version, asicid); +} + void __init u5500_map_io(void) { /* @@ -191,6 +218,27 @@ void __init u5500_map_io(void) iotable_init(u5500_io_desc, ARRAY_SIZE(u5500_io_desc)); _PRCMU_BASE = __io_address(U5500_PRCMU_BASE); + + db5500_rev_init(); +} + +static void __init db5500_pmu_init(void) +{ + struct resource res[] = { + [0] = { + .start = IRQ_DB5500_PMU0, + .end = IRQ_DB5500_PMU0, + .flags = IORESOURCE_IRQ, + }, + [1] = { + .start = IRQ_DB5500_PMU1, + .end = IRQ_DB5500_PMU1, + .flags = IORESOURCE_IRQ, + }, + }; + + platform_device_register_simple("arm-pmu", ARM_PMU_DEVICE_CPU, + res, ARRAY_SIZE(res)); } static int usb_db5500_rx_dma_cfg[] = { @@ -217,7 +265,14 @@ static int usb_db5500_tx_dma_cfg[] = { void __init u5500_init_devices(void) { + ux500_init_devices(); + +#ifdef CONFIG_STM_TRACE + /* Early init for STM tracing */ + /* platform_device_register(&u5500_stm_device); */ +#endif db5500_add_gpios(); + db5500_pmu_init(); db5500_dma_init(); db5500_add_rtc(); db5500_add_usb(usb_db5500_rx_dma_cfg, usb_db5500_tx_dma_cfg); diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index 4598b06c8c5..6a6753e4965 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2009 ST-Ericsson + * Copyright (C) 2008-2009 ST-Ericsson SA * * Author: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com> * @@ -14,19 +14,22 @@ #include <linux/amba/bus.h> #include <linux/interrupt.h> #include <linux/irq.h> -#include <linux/gpio.h> +#include <linux/gpio/nomadik.h> #include <linux/platform_device.h> #include <linux/io.h> +#include <linux/sys_soc.h> #include <asm/mach/map.h> #include <asm/pmu.h> #include <mach/hardware.h> #include <mach/setup.h> #include <mach/devices.h> +#include <linux/mfd/dbx500-prcmu.h> +#include <mach/reboot_reasons.h> #include <mach/usb.h> +#include <mach/ste-dma40-db8500.h> #include "devices-db8500.h" -#include "ste-dma40-db8500.h" /* minimum static i/o mapping required to boot U8500 platforms */ static struct map_desc u8500_uart_io_desc[] __initdata = { @@ -40,8 +43,11 @@ static struct map_desc u8500_io_desc[] __initdata = { __IO_DEV_DESC(U8500_L2CC_BASE, SZ_4K), __IO_DEV_DESC(U8500_TWD_BASE, SZ_4K), __IO_DEV_DESC(U8500_MTU0_BASE, SZ_4K), + __IO_DEV_DESC(U8500_MTU1_BASE, SZ_4K), + __IO_DEV_DESC(U8500_RTC_BASE, SZ_4K), __IO_DEV_DESC(U8500_SCU_BASE, SZ_4K), __IO_DEV_DESC(U8500_BACKUPRAM0_BASE, SZ_8K), + __MEM_DEV_DESC(U8500_BOOT_ROM_BASE, SZ_1M), __IO_DEV_DESC(U8500_CLKRST1_BASE, SZ_4K), __IO_DEV_DESC(U8500_CLKRST2_BASE, SZ_4K), @@ -54,19 +60,6 @@ static struct map_desc u8500_io_desc[] __initdata = { __IO_DEV_DESC(U8500_GPIO1_BASE, SZ_4K), __IO_DEV_DESC(U8500_GPIO2_BASE, SZ_4K), __IO_DEV_DESC(U8500_GPIO3_BASE, SZ_4K), -}; - -static struct map_desc u8500_ed_io_desc[] __initdata = { - __IO_DEV_DESC(U8500_MTU0_BASE_ED, SZ_4K), - __IO_DEV_DESC(U8500_CLKRST7_BASE_ED, SZ_8K), -}; - -static struct map_desc u8500_v1_io_desc[] __initdata = { - __IO_DEV_DESC(U8500_MTU0_BASE, SZ_4K), - __IO_DEV_DESC(U8500_PRCMU_TCDM_BASE_V1, SZ_4K), -}; - -static struct map_desc u8500_v2_io_desc[] __initdata = { __IO_DEV_DESC(U8500_PRCMU_TCDM_BASE, SZ_4K), }; @@ -81,13 +74,6 @@ void __init u8500_map_io(void) iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc)); - if (cpu_is_u8500ed()) - iotable_init(u8500_ed_io_desc, ARRAY_SIZE(u8500_ed_io_desc)); - else if (cpu_is_u8500v1()) - iotable_init(u8500_v1_io_desc, ARRAY_SIZE(u8500_v1_io_desc)); - else if (cpu_is_u8500v2()) - iotable_init(u8500_v2_io_desc, ARRAY_SIZE(u8500_v2_io_desc)); - _PRCMU_BASE = __io_address(U8500_PRCMU_BASE); } @@ -136,36 +122,20 @@ static struct platform_device db8500_prcmu_device = { }; static struct platform_device *platform_devs[] __initdata = { - &u8500_dma40_device, + &u8500_gpio_devs[0], + &u8500_gpio_devs[1], + &u8500_gpio_devs[2], + &u8500_gpio_devs[3], + &u8500_gpio_devs[4], + &u8500_gpio_devs[5], + &u8500_gpio_devs[6], + &u8500_gpio_devs[7], + &u8500_gpio_devs[8], &db8500_pmu_device, &db8500_prcmu_device, + &u8500_wdt_device, }; -static resource_size_t __initdata db8500_gpio_base[] = { - U8500_GPIOBANK0_BASE, - U8500_GPIOBANK1_BASE, - U8500_GPIOBANK2_BASE, - U8500_GPIOBANK3_BASE, - U8500_GPIOBANK4_BASE, - U8500_GPIOBANK5_BASE, - U8500_GPIOBANK6_BASE, - U8500_GPIOBANK7_BASE, - U8500_GPIOBANK8_BASE, -}; - -static void __init db8500_add_gpios(void) -{ - struct nmk_gpio_platform_data pdata = { - /* No custom data yet */ - }; - - if (cpu_is_u8500v2()) - pdata.supports_sleepmode = true; - - dbx500_add_gpios(ARRAY_AND_SIZE(db8500_gpio_base), - IRQ_DB8500_GPIO0, &pdata); -} - static int usb_db8500_rx_dma_cfg[] = { DB8500_DMA_DEV38_USB_OTG_IEP_1_9, DB8500_DMA_DEV37_USB_OTG_IEP_2_10, @@ -193,11 +163,15 @@ static int usb_db8500_tx_dma_cfg[] = { */ void __init u8500_init_devices(void) { - if (cpu_is_u8500ed()) - dma40_u8500ed_fixup(); + ux500_init_devices(); +#ifdef CONFIG_STM_TRACE + /* Early init for STM tracing */ + platform_device_register(&u8500_stm_device); +#endif + + db8500_dma_init(); db8500_add_rtc(); - db8500_add_gpios(); db8500_add_usb(usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg); platform_device_register_simple("cpufreq-u8500", -1, NULL, 0); @@ -205,3 +179,82 @@ 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 1da23bb87c1..7274ab2f90f 100644 --- a/arch/arm/mach-ux500/cpu.c +++ b/arch/arm/mach-ux500/cpu.c @@ -8,8 +8,9 @@ #include <linux/platform_device.h> #include <linux/io.h> #include <linux/clk.h> -#include <linux/mfd/db8500-prcmu.h> -#include <linux/mfd/db5500-prcmu.h> +#include <linux/delay.h> +#include <linux/clksrc-dbx500-prcmu.h> +#include <linux/mfd/dbx500-prcmu.h> #include <asm/cacheflush.h> #include <asm/hardware/cache-l2x0.h> @@ -17,10 +18,10 @@ #include <asm/mach/map.h> #include <asm/localtimer.h> -#include <plat/mtu.h> #include <mach/hardware.h> #include <mach/setup.h> #include <mach/devices.h> +#include <mach/reboot_reasons.h> #include "clock.h" @@ -30,6 +31,36 @@ void __iomem *_PRCMU_BASE; static void __iomem *l2x0_base; #endif +void __init ux500_init_devices(void) +{ +#ifdef CONFIG_CACHE_L2X0 + BUG_ON(!l2x0_base); + + /* + * Unlock Data and Instruction Lock if locked. This is done here + * instead of in l2x0_init since doing it there appears to cause the + * second core boot to occasionaly fail. + */ + if (readl_relaxed(l2x0_base + L2X0_LOCKDOWN_WAY_D_BASE) & 0xFF) + writel_relaxed(0x0, l2x0_base + L2X0_LOCKDOWN_WAY_D_BASE); + + if (readl_relaxed(l2x0_base + L2X0_LOCKDOWN_WAY_I_BASE) & 0xFF) + writel_relaxed(0x0, l2x0_base + L2X0_LOCKDOWN_WAY_I_BASE); +#endif +} + +static void ux500_restart(char mode, const char *cmd) +{ + unsigned short reset_code; + + reset_code = reboot_reason_code(cmd); + prcmu_system_reset(reset_code); + + mdelay(1000); + printk("Reboot via PRCMU failed -- System halted\n"); + while (1); +} + void __init ux500_init_irq(void) { void __iomem *dist_base; @@ -50,10 +81,8 @@ void __init ux500_init_irq(void) * Init clocks here so that they are available for system timer * initialization. */ - if (cpu_is_u5500()) - db5500_prcmu_early_init(); - if (cpu_is_u8500()) - prcmu_early_init(); + prcmu_early_init(); + arm_pm_restart = ux500_restart; clk_init(); } @@ -119,30 +148,3 @@ static int ux500_l2x0_init(void) } early_initcall(ux500_l2x0_init); #endif - -static void __init ux500_timer_init(void) -{ -#ifdef CONFIG_LOCAL_TIMERS - /* Setup the local timer base */ - if (cpu_is_u5500()) - twd_base = __io_address(U5500_TWD_BASE); - else if (cpu_is_u8500()) - twd_base = __io_address(U8500_TWD_BASE); - else - ux500_unknown_soc(); -#endif - if (cpu_is_u5500()) - mtu_base = __io_address(U5500_MTU0_BASE); - else if (cpu_is_u8500ed()) - mtu_base = __io_address(U8500_MTU0_BASE_ED); - else if (cpu_is_u8500()) - mtu_base = __io_address(U8500_MTU0_BASE); - else - ux500_unknown_soc(); - - nmdk_timer_init(); -} - -struct sys_timer ux500_timer = { - .init = ux500_timer_init, -}; diff --git a/arch/arm/mach-ux500/devices-common.c b/arch/arm/mach-ux500/devices-common.c index 13a4ce046ae..1de666a8104 100644 --- a/arch/arm/mach-ux500/devices-common.c +++ b/arch/arm/mach-ux500/devices-common.c @@ -12,10 +12,18 @@ #include <linux/slab.h> #include <linux/platform_device.h> #include <linux/amba/bus.h> +#include <linux/pm.h> +#include <linux/gpio.h> +#include <linux/gpio/nomadik.h> -#include <plat/gpio.h> +#ifdef CONFIG_FB_MCDE +#include <video/mcde_display.h> +#include <video/mcde_display-av8100.h> +#include <video/mcde_fb.h> +#endif #include <mach/hardware.h> +#include <mach/pm.h> #include "devices-common.h" @@ -38,6 +46,7 @@ dbx500_add_amba_device(const char *name, resource_size_t base, dev->dma_mask = DMA_BIT_MASK(32); dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); + dev->dev.pm_domain = &ux500_amba_dev_power_domain; dev->irq[0] = irq; dev->irq[1] = NO_IRQ; @@ -68,6 +77,7 @@ dbx500_add_platform_device(const char *name, int id, void *pdata, dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); dev->dev.dma_mask = &dev->dev.coherent_dma_mask; + dev->dev.pm_domain = &ux500_dev_power_domain; ret = platform_device_add_resources(dev, res, resnum); if (ret) @@ -108,6 +118,22 @@ dbx500_add_platform_device_4k1irq(const char *name, int id, ARRAY_SIZE(resources)); } +struct platform_device * +dbx500_add_platform_device_noirq(const char *name, int id, + resource_size_t base, void *pdata) +{ + struct resource resources[] = { + [0] = { + .start = base, + .end = base + SZ_4K - 1, + .flags = IORESOURCE_MEM, + } + }; + + return dbx500_add_platform_device(name, id, pdata, resources, + ARRAY_SIZE(resources)); +} + static struct platform_device * dbx500_add_gpio(int id, resource_size_t addr, int irq, struct nmk_gpio_platform_data *pdata) @@ -140,7 +166,70 @@ void dbx500_add_gpios(resource_size_t *base, int num, int irq, pdata->first_gpio = first; pdata->first_irq = NOMADIK_GPIO_TO_IRQ(first); pdata->num_gpio = 32; - dbx500_add_gpio(i, base[i], irq, pdata); } } + +#ifdef CONFIG_FB_MCDE +void hdmi_fb_onoff(struct mcde_display_device *ddev, + bool enable, u8 cea, u8 vesa_cea_nr) +{ + struct fb_info *fbi; + u16 w, h; + u16 vw, vh; + u32 rotate = FB_ROTATE_UR; + struct display_driver_data *driver_data = dev_get_drvdata(&ddev->dev); + + dev_dbg(&ddev->dev, "%s\n", __func__); + dev_dbg(&ddev->dev, "en:%d cea:%d nr:%d\n", enable, cea, vesa_cea_nr); + + if (enable) { + if (ddev->enabled) { + dev_dbg(&ddev->dev, "Display is already enabled.\n"); + return; + } + + /* Create fb */ + if (ddev->fbi == NULL) { + /* Note: change when dynamic buffering is available */ + int buffering = 2; + + /* Get default values */ + mcde_dss_get_native_resolution(ddev, &w, &h); + vw = w; + vh = h * buffering; + + if (vesa_cea_nr != 0) + ddev->ceanr_convert(ddev, cea, vesa_cea_nr, + buffering, &w, &h, &vw, &vh); + + fbi = mcde_fb_create(ddev, w, h, vw, vh, + ddev->default_pixel_format, rotate); + + if (IS_ERR(fbi)) { + dev_warn(&ddev->dev, + "Failed to create fb for display %s\n", + ddev->name); + goto hdmi_fb_onoff_end; + } else { + dev_info(&ddev->dev, + "Framebuffer created (%s)\n", + ddev->name); + } + driver_data->fbdevname = (char *)dev_name(fbi->dev); + } + } else { + if (!ddev->enabled) { + dev_dbg(&ddev->dev, "Display %s is already disabled.\n", + ddev->name); + return; + } + mcde_fb_destroy(ddev); + } + +hdmi_fb_onoff_end: + return; +} +EXPORT_SYMBOL(hdmi_fb_onoff); +#endif + diff --git a/arch/arm/mach-ux500/devices-common.h b/arch/arm/mach-ux500/devices-common.h index 7825705033b..bbf551f6318 100644 --- a/arch/arm/mach-ux500/devices-common.h +++ b/arch/arm/mach-ux500/devices-common.h @@ -8,6 +8,8 @@ #ifndef __DEVICES_COMMON_H #define __DEVICES_COMMON_H +#include <linux/amba/serial.h> + extern struct amba_device * dbx500_add_amba_device(const char *name, resource_size_t base, int irq, void *pdata, unsigned int periphid); @@ -17,18 +19,24 @@ dbx500_add_platform_device_4k1irq(const char *name, int id, resource_size_t base, int irq, void *pdata); -struct spi_master_cntlr; +extern struct platform_device * +dbx500_add_platform_device_noirq(const char *name, int id, + resource_size_t base, void *pdata); + +struct stm_msp_controller; static inline struct amba_device * dbx500_add_msp_spi(const char *name, resource_size_t base, int irq, - struct spi_master_cntlr *pdata) + struct stm_msp_controller *pdata) { return dbx500_add_amba_device(name, base, irq, pdata, 0); } +struct pl022_ssp_controller; + static inline struct amba_device * dbx500_add_spi(const char *name, resource_size_t base, int irq, - struct spi_master_cntlr *pdata, + struct pl022_ssp_controller *pdata, u32 periphid) { return dbx500_add_amba_device(name, base, irq, pdata, periphid); @@ -79,6 +87,25 @@ dbx500_add_rtc(resource_size_t base, int irq) return dbx500_add_amba_device("rtc-pl031", base, irq, NULL, 0); } +struct cryp_platform_data; + +static inline struct platform_device * +dbx500_add_cryp1(int id, resource_size_t base, int irq, + struct cryp_platform_data *pdata) +{ + return dbx500_add_platform_device_4k1irq("cryp1", id, base, irq, + pdata); +} + +struct hash_platform_data; + +static inline struct platform_device * +dbx500_add_hash1(int id, resource_size_t base, + struct hash_platform_data *pdata) +{ + return dbx500_add_platform_device_noirq("hash1", id, base, pdata); +} + struct nmk_gpio_platform_data; void dbx500_add_gpios(resource_size_t *base, int num, int irq, diff --git a/arch/arm/mach-ux500/devices-db5500.c b/arch/arm/mach-ux500/devices-db5500.c new file mode 100644 index 00000000000..299e3f06479 --- /dev/null +++ b/arch/arm/mach-ux500/devices-db5500.c @@ -0,0 +1,280 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson + * + * Author: Pierre Peiffer <pierre.peiffer@stericsson.com> for ST-Ericsson. + * for the System Trace Module part. + * + * License terms: GNU General Public License (GPL) version 2 + */ + +#include <linux/platform_device.h> +#include <linux/interrupt.h> +#include <linux/platform_device.h> +#include <linux/gpio/nomadik.h> + +#include <mach/hardware.h> +#include <mach/devices.h> + +#ifdef CONFIG_FB_MCDE +#include <video/mcde.h> +#endif +#include <mach/db5500-regs.h> + +#include <linux/mfd/dbx500-prcmu.h> +#include <mach/pm.h> + +#define GPIO_DATA(_name, first, num) \ + { \ + .name = _name, \ + .first_gpio = first, \ + .first_irq = NOMADIK_GPIO_TO_IRQ(first), \ + .num_gpio = num, \ + .get_secondary_status = ux500_pm_gpio_read_wake_up_status, \ + .set_ioforce = ux500_pm_prcmu_set_ioforce, \ + } + +#define GPIO_RESOURCE(block) \ + { \ + .start = U5500_GPIOBANK##block##_BASE, \ + .end = U5500_GPIOBANK##block##_BASE + 127, \ + .flags = IORESOURCE_MEM, \ + }, \ + { \ + .start = IRQ_DB5500_GPIO##block, \ + .end = IRQ_DB5500_GPIO##block, \ + .flags = IORESOURCE_IRQ, \ + }, \ + { \ + .start = IRQ_DB5500_PRCMU_GPIO##block, \ + .end = IRQ_DB5500_PRCMU_GPIO##block, \ + .flags = IORESOURCE_IRQ, \ + } + +#define GPIO_DEVICE(block) \ + { \ + .name = "gpio", \ + .id = block, \ + .num_resources = 3, \ + .resource = &u5500_gpio_resources[block * 3], \ + .dev = { \ + .platform_data = &u5500_gpio_data[block], \ + }, \ + } + +static struct nmk_gpio_platform_data u5500_gpio_data[] = { + GPIO_DATA("GPIO-0-31", 0, 32), + GPIO_DATA("GPIO-32-63", 32, 4), /* 36..63 not routed to pin */ + GPIO_DATA("GPIO-64-95", 64, 19), /* 83..95 not routed to pin */ + GPIO_DATA("GPIO-96-127", 96, 6), /* 102..127 not routed to pin */ + GPIO_DATA("GPIO-128-159", 128, 21), /* 149..159 not routed to pin */ + GPIO_DATA("GPIO-160-191", 160, 32), + GPIO_DATA("GPIO-192-223", 192, 32), + GPIO_DATA("GPIO-224-255", 224, 4), /* 228..255 not routed to pin */ +}; + +static struct resource u5500_gpio_resources[] = { + GPIO_RESOURCE(0), + GPIO_RESOURCE(1), + GPIO_RESOURCE(2), + GPIO_RESOURCE(3), + GPIO_RESOURCE(4), + GPIO_RESOURCE(5), + GPIO_RESOURCE(6), + GPIO_RESOURCE(7), +}; + +struct platform_device u5500_gpio_devs[] = { + GPIO_DEVICE(0), + GPIO_DEVICE(1), + GPIO_DEVICE(2), + GPIO_DEVICE(3), + GPIO_DEVICE(4), + GPIO_DEVICE(5), + GPIO_DEVICE(6), + GPIO_DEVICE(7), +}; + +#define U5500_PWM_SIZE 0x20 +static struct resource u5500_pwm0_resource[] = { + { + .name = "PWM_BASE", + .start = U5500_PWM_BASE, + .end = U5500_PWM_BASE + U5500_PWM_SIZE - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct resource u5500_pwm1_resource[] = { + { + .name = "PWM_BASE", + .start = U5500_PWM_BASE + U5500_PWM_SIZE, + .end = U5500_PWM_BASE + U5500_PWM_SIZE * 2 - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct resource u5500_pwm2_resource[] = { + { + .name = "PWM_BASE", + .start = U5500_PWM_BASE + U5500_PWM_SIZE * 2, + .end = U5500_PWM_BASE + U5500_PWM_SIZE * 3 - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct resource u5500_pwm3_resource[] = { + { + .name = "PWM_BASE", + .start = U5500_PWM_BASE + U5500_PWM_SIZE * 3, + .end = U5500_PWM_BASE + U5500_PWM_SIZE * 4 - 1, + .flags = IORESOURCE_MEM, + }, +}; + +struct platform_device u5500_pwm0_device = { + .id = 0, + .name = "pwm", + .resource = u5500_pwm0_resource, + .num_resources = ARRAY_SIZE(u5500_pwm0_resource), +}; + +struct platform_device u5500_pwm1_device = { + .id = 1, + .name = "pwm", + .resource = u5500_pwm1_resource, + .num_resources = ARRAY_SIZE(u5500_pwm1_resource), +}; + +struct platform_device u5500_pwm2_device = { + .id = 2, + .name = "pwm", + .resource = u5500_pwm2_resource, + .num_resources = ARRAY_SIZE(u5500_pwm2_resource), +}; + +struct platform_device u5500_pwm3_device = { + .id = 3, + .name = "pwm", + .resource = u5500_pwm3_resource, + .num_resources = ARRAY_SIZE(u5500_pwm3_resource), +}; + +#ifdef CONFIG_FB_MCDE +static struct resource mcde_resources[] = { + [0] = { + .name = MCDE_IO_AREA, + .start = U5500_MCDE_BASE, + .end = U5500_MCDE_BASE + U5500_MCDE_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .name = MCDE_IO_AREA, + .start = U5500_DSI_LINK1_BASE, + .end = U5500_DSI_LINK1_BASE + U5500_DSI_LINK_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [2] = { + .name = MCDE_IO_AREA, + .start = U5500_DSI_LINK2_BASE, + .end = U5500_DSI_LINK2_BASE + U5500_DSI_LINK_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [3] = { + .name = MCDE_IRQ, + .start = IRQ_DB5500_DISP, + .end = IRQ_DB5500_DISP, + .flags = IORESOURCE_IRQ, + }, +}; + +static int mcde_platform_enable_dsipll(void) +{ + return prcmu_enable_dsipll(); +} + +static int mcde_platform_disable_dsipll(void) +{ + return prcmu_disable_dsipll(); +} + +static int mcde_platform_set_display_clocks(void) +{ + return prcmu_set_display_clocks(); +} + +static struct mcde_platform_data mcde_pdata = { + .num_dsilinks = 2, + .syncmux = 0x01, + .num_channels = 2, + .num_overlays = 3, + .regulator_mcde_epod_id = "vsupply", + .regulator_esram_epod_id = "v-esram12", +#ifdef CONFIG_MCDE_DISPLAY_DSI + .clock_dsi_id = "hdmi", + .clock_dsi_lp_id = "tv", +#endif + .clock_mcde_id = "mcde", + .platform_set_clocks = mcde_platform_set_display_clocks, + .platform_enable_dsipll = mcde_platform_enable_dsipll, + .platform_disable_dsipll = mcde_platform_disable_dsipll, +}; + +struct platform_device u5500_mcde_device = { + .name = "mcde", + .id = -1, + .dev = { + .platform_data = &mcde_pdata, + }, + .num_resources = ARRAY_SIZE(mcde_resources), + .resource = mcde_resources, +}; +#endif + +static struct resource b2r2_resources[] = { + [0] = { + .start = U5500_B2R2_BASE, + .end = U5500_B2R2_BASE + ((4*1024)-1), + .name = "b2r2_base", + .flags = IORESOURCE_MEM, + }, + [1] = { + .name = "B2R2_IRQ", + .start = IRQ_DB5500_B2R2, + .end = IRQ_DB5500_B2R2, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device u5500_b2r2_device = { + .name = "b2r2", + .id = 0, + .dev = { + .init_name = "b2r2_bus", + .coherent_dma_mask = ~0, + }, + .num_resources = ARRAY_SIZE(b2r2_resources), + .resource = b2r2_resources, +}; + +static struct resource u5500_thsens_resources[] = { + [0] = { + .name = "IRQ_HOTMON_LOW", + .start = IRQ_DB5500_PRCMU_TEMP_SENSOR_LOW, + .end = IRQ_DB5500_PRCMU_TEMP_SENSOR_LOW, + .flags = IORESOURCE_IRQ, + }, + [1] = { + .name = "IRQ_HOTMON_HIGH", + .start = IRQ_DB5500_PRCMU_TEMP_SENSOR_HIGH, + .end = IRQ_DB5500_PRCMU_TEMP_SENSOR_HIGH, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device u5500_thsens_device = { + .name = "db5500_temp", + .resource = u5500_thsens_resources, + .num_resources = ARRAY_SIZE(u5500_thsens_resources), +}; diff --git a/arch/arm/mach-ux500/devices-db5500.h b/arch/arm/mach-ux500/devices-db5500.h index 0c4bccd02b9..a6536edd2d1 100644 --- a/arch/arm/mach-ux500/devices-db5500.h +++ b/arch/arm/mach-ux500/devices-db5500.h @@ -17,6 +17,16 @@ #define db5500_add_i2c3(pdata) \ dbx500_add_i2c(3, U5500_I2C3_BASE, IRQ_DB5500_I2C3, pdata) +struct db5500_keypad_platform_data; + +static inline struct platform_device * +db5500_add_keypad(struct db5500_keypad_platform_data *pdata) +{ + return dbx500_add_platform_device_4k1irq("db5500-keypad", -1, + U5500_KEYPAD_BASE, + IRQ_DB5500_KBD, pdata); +} + #define db5500_add_msp0_i2s(pdata) \ dbx500_add_msp_i2s(0, U5500_MSP0_BASE, IRQ_DB5500_MSP0, pdata) #define db5500_add_msp1_i2s(pdata) \ @@ -37,21 +47,21 @@ #define db5500_add_usb(rx_cfg, tx_cfg) \ ux500_add_usb(U5500_USBOTG_BASE, IRQ_DB5500_USBOTG, rx_cfg, tx_cfg) -#define db5500_add_sdi0(pdata) \ +#define db5500_add_sdi0(pdata, pid) \ dbx500_add_sdi("sdi0", U5500_SDI0_BASE, IRQ_DB5500_SDMMC0, pdata, \ - 0x10480180) -#define db5500_add_sdi1(pdata) \ + pid) +#define db5500_add_sdi1(pdata, pid) \ dbx500_add_sdi("sdi1", U5500_SDI1_BASE, IRQ_DB5500_SDMMC1, pdata, \ - 0x10480180) -#define db5500_add_sdi2(pdata) \ - dbx500_add_sdi("sdi2", U5500_SDI2_BASE, IRQ_DB5500_SDMMC2, pdata \ - 0x10480180) -#define db5500_add_sdi3(pdata) \ - dbx500_add_sdi("sdi3", U5500_SDI3_BASE, IRQ_DB5500_SDMMC3, pdata \ - 0x10480180) -#define db5500_add_sdi4(pdata) \ - dbx500_add_sdi("sdi4", U5500_SDI4_BASE, IRQ_DB5500_SDMMC4, pdata \ - 0x10480180) + pid) +#define db5500_add_sdi2(pdata, pid) \ + dbx500_add_sdi("sdi2", U5500_SDI2_BASE, IRQ_DB5500_SDMMC2, pdata, \ + pid) +#define db5500_add_sdi3(pdata, pid) \ + dbx500_add_sdi("sdi3", U5500_SDI3_BASE, IRQ_DB5500_SDMMC3, pdata, \ + pid) +#define db5500_add_sdi4(pdata, pid) \ + dbx500_add_sdi("sdi4", U5500_SDI4_BASE, IRQ_DB5500_SDMMC4, pdata, \ + pid) /* This one has a bad peripheral ID in the U5500 silicon */ #define db5500_add_spi0(pdata) \ @@ -61,10 +71,10 @@ dbx500_add_spi("spi1", U5500_SPI1_BASE, IRQ_DB5500_SPI1, pdata, \ 0x10080023) #define db5500_add_spi2(pdata) \ - dbx500_add_spi("spi2", U5500_SPI2_BASE, IRQ_DB5500_SPI2, pdata \ + dbx500_add_spi("spi2", U5500_SPI2_BASE, IRQ_DB5500_SPI2, pdata, \ 0x10080023) #define db5500_add_spi3(pdata) \ - dbx500_add_spi("spi3", U5500_SPI3_BASE, IRQ_DB5500_SPI3, pdata \ + dbx500_add_spi("spi3", U5500_SPI3_BASE, IRQ_DB5500_SPI3, pdata, \ 0x10080023) #define db5500_add_uart0(plat) \ @@ -76,4 +86,9 @@ #define db5500_add_uart3(plat) \ dbx500_add_uart("uart3", U5500_UART3_BASE, IRQ_DB5500_UART3, plat) +#define db5500_add_cryp1(pdata) \ + dbx500_add_cryp1(-1, U5500_CRYP1_BASE, IRQ_DB5500_CRYP1, pdata) +#define db5500_add_hash1(pdata) \ + dbx500_add_hash1(-1, U5500_HASH1_BASE, pdata) + #endif diff --git a/arch/arm/mach-ux500/devices-db8500.c b/arch/arm/mach-ux500/devices-db8500.c index 73b17404b19..2d74f4acddb 100644 --- a/arch/arm/mach-ux500/devices-db8500.c +++ b/arch/arm/mach-ux500/devices-db8500.c @@ -10,172 +10,444 @@ #include <linux/interrupt.h> #include <linux/io.h> #include <linux/gpio.h> +#include <linux/gpio/nomadik.h> #include <linux/amba/bus.h> #include <linux/amba/pl022.h> +#include <plat/pincfg.h> #include <plat/ste_dma40.h> +#include <mach/devices.h> #include <mach/hardware.h> #include <mach/setup.h> +#include <mach/pm.h> +#ifdef CONFIG_FB_MCDE +#include <video/mcde.h> +#endif +#include <linux/mfd/dbx500-prcmu.h> +#ifdef CONFIG_HSI +#include <mach/hsi.h> +#endif +#include <mach/ste-dma40-db8500.h> -#include "ste-dma40-db8500.h" +#include "pins-db8500.h" -static struct resource dma40_resources[] = { +#define GPIO_DATA(_name, first, num) \ + { \ + .name = _name, \ + .first_gpio = first, \ + .first_irq = NOMADIK_GPIO_TO_IRQ(first), \ + .num_gpio = num, \ + .get_secondary_status = ux500_pm_gpio_read_wake_up_status, \ + .set_ioforce = ux500_pm_prcmu_set_ioforce, \ + .supports_sleepmode = true, \ + } + +#define GPIO_RESOURCE(block) \ + { \ + .start = U8500_GPIOBANK##block##_BASE, \ + .end = U8500_GPIOBANK##block##_BASE + 127, \ + .flags = IORESOURCE_MEM, \ + }, \ + { \ + .start = IRQ_DB8500_GPIO##block, \ + .end = IRQ_DB8500_GPIO##block, \ + .flags = IORESOURCE_IRQ, \ + }, \ + { \ + .start = IRQ_PRCMU_GPIO##block, \ + .end = IRQ_PRCMU_GPIO##block, \ + .flags = IORESOURCE_IRQ, \ + } + +#define GPIO_DEVICE(block) \ + { \ + .name = "gpio", \ + .id = block, \ + .num_resources = 3, \ + .resource = &u8500_gpio_resources[block * 3], \ + .dev = { \ + .platform_data = &u8500_gpio_data[block], \ + }, \ + } + +static struct nmk_gpio_platform_data u8500_gpio_data[] = { + GPIO_DATA("GPIO-0-31", 0, 32), + GPIO_DATA("GPIO-32-63", 32, 5), /* 37..63 not routed to pin */ + GPIO_DATA("GPIO-64-95", 64, 32), + GPIO_DATA("GPIO-96-127", 96, 2), /* 98..127 not routed to pin */ + GPIO_DATA("GPIO-128-159", 128, 32), + GPIO_DATA("GPIO-160-191", 160, 12), /* 172..191 not routed to pin */ + GPIO_DATA("GPIO-192-223", 192, 32), + GPIO_DATA("GPIO-224-255", 224, 7), /* 231..255 not routed to pin */ + GPIO_DATA("GPIO-256-288", 256, 12), /* 268..288 not routed to pin */ +}; + +static struct resource u8500_gpio_resources[] = { + GPIO_RESOURCE(0), + GPIO_RESOURCE(1), + GPIO_RESOURCE(2), + GPIO_RESOURCE(3), + GPIO_RESOURCE(4), + GPIO_RESOURCE(5), + GPIO_RESOURCE(6), + GPIO_RESOURCE(7), + GPIO_RESOURCE(8), +}; + +struct platform_device u8500_gpio_devs[] = { + GPIO_DEVICE(0), + GPIO_DEVICE(1), + GPIO_DEVICE(2), + GPIO_DEVICE(3), + GPIO_DEVICE(4), + GPIO_DEVICE(5), + GPIO_DEVICE(6), + GPIO_DEVICE(7), + GPIO_DEVICE(8), +}; + +static struct resource u8500_shrm_resources[] = { [0] = { - .start = U8500_DMA_BASE, - .end = U8500_DMA_BASE + SZ_4K - 1, + .start = U8500_SHRM_GOP_INTERRUPT_BASE, + .end = U8500_SHRM_GOP_INTERRUPT_BASE + ((4*4)-1), + .name = "shrm_gop_register_base", .flags = IORESOURCE_MEM, - .name = "base", }, [1] = { - .start = U8500_DMA_LCPA_BASE, - .end = U8500_DMA_LCPA_BASE + 2 * SZ_1K - 1, - .flags = IORESOURCE_MEM, - .name = "lcpa", + .start = IRQ_CA_WAKE_REQ_V1, + .end = IRQ_CA_WAKE_REQ_V1, + .name = "ca_irq_wake_req", + .flags = IORESOURCE_IRQ, }, [2] = { - .start = IRQ_DB8500_DMA, - .end = IRQ_DB8500_DMA, + .start = IRQ_AC_READ_NOTIFICATION_0_V1, + .end = IRQ_AC_READ_NOTIFICATION_0_V1, + .name = "ac_read_notification_0_irq", + .flags = IORESOURCE_IRQ, + }, + [3] = { + .start = IRQ_AC_READ_NOTIFICATION_1_V1, + .end = IRQ_AC_READ_NOTIFICATION_1_V1, + .name = "ac_read_notification_1_irq", + .flags = IORESOURCE_IRQ, + }, + [4] = { + .start = IRQ_CA_MSG_PEND_NOTIFICATION_0_V1, + .end = IRQ_CA_MSG_PEND_NOTIFICATION_0_V1, + .name = "ca_msg_pending_notification_0_irq", + .flags = IORESOURCE_IRQ, + }, + [5] = { + .start = IRQ_CA_MSG_PEND_NOTIFICATION_1_V1, + .end = IRQ_CA_MSG_PEND_NOTIFICATION_1_V1, + .name = "ca_msg_pending_notification_1_irq", .flags = IORESOURCE_IRQ, } }; -/* Default configuration for physcial memcpy */ -struct stedma40_chan_cfg dma40_memcpy_conf_phy = { - .mode = STEDMA40_MODE_PHYSICAL, - .dir = STEDMA40_MEM_TO_MEM, +struct platform_device u8500_shrm_device = { + .name = "u8500_shrm", + .id = 0, + .dev = { + .init_name = "shrm_bus", + .coherent_dma_mask = ~0, + }, + + .num_resources = ARRAY_SIZE(u8500_shrm_resources), + .resource = u8500_shrm_resources +}; + +#ifdef CONFIG_FB_MCDE +static struct resource mcde_resources[] = { + [0] = { + .name = MCDE_IO_AREA, + .start = U8500_MCDE_BASE, + .end = U8500_MCDE_BASE + U8500_MCDE_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .name = MCDE_IO_AREA, + .start = U8500_DSI_LINK1_BASE, + .end = U8500_DSI_LINK1_BASE + U8500_DSI_LINK_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [2] = { + .name = MCDE_IO_AREA, + .start = U8500_DSI_LINK2_BASE, + .end = U8500_DSI_LINK2_BASE + U8500_DSI_LINK_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [3] = { + .name = MCDE_IO_AREA, + .start = U8500_DSI_LINK3_BASE, + .end = U8500_DSI_LINK3_BASE + U8500_DSI_LINK_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [4] = { + .name = MCDE_IRQ, + .start = IRQ_DB8500_DISP, + .end = IRQ_DB8500_DISP, + .flags = IORESOURCE_IRQ, + }, +}; + +static int mcde_platform_enable_dsipll(void) +{ + return prcmu_enable_dsipll(); +} + +static int mcde_platform_disable_dsipll(void) +{ + return prcmu_disable_dsipll(); +} + +static int mcde_platform_set_display_clocks(void) +{ + return prcmu_set_display_clocks(); +} - .src_info.data_width = STEDMA40_BYTE_WIDTH, - .src_info.psize = STEDMA40_PSIZE_PHY_1, - .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, +static struct mcde_platform_data mcde_u8500_pdata = { + .num_dsilinks = 3, + /* + * [0] = 3: 24 bits DPI: connect LSB Ch B to D[0:7] + * [3] = 4: 24 bits DPI: connect MID Ch B to D[24:31] + * [4] = 5: 24 bits DPI: connect MSB Ch B to D[32:39] + * + * [1] = 3: TV out : connect LSB Ch B to D[8:15] + */ +#define DONT_CARE 0 + .outmux = { 3, 3, DONT_CARE, 4, 5 }, +#undef DONT_CARE + .syncmux = 0x00, /* DPI channel A and B on output pins A and B resp */ + .num_channels = 4, + .num_overlays = 6, +#ifdef CONFIG_MCDE_DISPLAY_DSI + .regulator_vana_id = "vdddsi1v2", +#endif + .regulator_mcde_epod_id = "vsupply", + .regulator_esram_epod_id = "v-esram34", +#ifdef CONFIG_MCDE_DISPLAY_DSI + .clock_dsi_id = "hdmi", + .clock_dsi_lp_id = "tv", +#endif + .clock_dpi_id = "lcd", + .clock_mcde_id = "mcde", + .platform_set_clocks = mcde_platform_set_display_clocks, + .platform_enable_dsipll = mcde_platform_enable_dsipll, + .platform_disable_dsipll = mcde_platform_disable_dsipll, +}; - .dst_info.data_width = STEDMA40_BYTE_WIDTH, - .dst_info.psize = STEDMA40_PSIZE_PHY_1, - .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, +struct platform_device u8500_mcde_device = { + .name = "mcde", + .id = -1, + .dev = { + .platform_data = &mcde_u8500_pdata, + }, + .num_resources = ARRAY_SIZE(mcde_resources), + .resource = mcde_resources, }; -/* Default configuration for logical memcpy */ -struct stedma40_chan_cfg dma40_memcpy_conf_log = { - .dir = STEDMA40_MEM_TO_MEM, +#endif /* CONFIG_FB_MCDE */ - .src_info.data_width = STEDMA40_BYTE_WIDTH, - .src_info.psize = STEDMA40_PSIZE_LOG_1, - .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, +static struct resource b2r2_resources[] = { + [0] = { + .start = U8500_B2R2_BASE, + .end = U8500_B2R2_BASE + ((4*1024)-1), + .name = "b2r2_base", + .flags = IORESOURCE_MEM, + }, + [1] = { + .name = "B2R2_IRQ", + .start = IRQ_DB8500_B2R2, + .end = IRQ_DB8500_B2R2, + .flags = IORESOURCE_IRQ, + }, +}; - .dst_info.data_width = STEDMA40_BYTE_WIDTH, - .dst_info.psize = STEDMA40_PSIZE_LOG_1, - .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, +struct platform_device u8500_b2r2_device = { + .name = "b2r2", + .id = 0, + .dev = { + .init_name = "b2r2_bus", + .coherent_dma_mask = ~0, + }, + .num_resources = ARRAY_SIZE(b2r2_resources), + .resource = b2r2_resources, }; /* - * Mapping between destination event lines and physical device address. - * The event line is tied to a device and therefore the address is constant. - * When the address comes from a primecell it will be configured in runtime - * and we set the address to -1 as a placeholder. + * WATCHDOG */ -static const dma_addr_t dma40_tx_map[DB8500_DMA_NR_DEV] = { - /* MUSB - these will be runtime-reconfigured */ - [DB8500_DMA_DEV39_USB_OTG_OEP_8] = -1, - [DB8500_DMA_DEV16_USB_OTG_OEP_7_15] = -1, - [DB8500_DMA_DEV17_USB_OTG_OEP_6_14] = -1, - [DB8500_DMA_DEV18_USB_OTG_OEP_5_13] = -1, - [DB8500_DMA_DEV19_USB_OTG_OEP_4_12] = -1, - [DB8500_DMA_DEV36_USB_OTG_OEP_3_11] = -1, - [DB8500_DMA_DEV37_USB_OTG_OEP_2_10] = -1, - [DB8500_DMA_DEV38_USB_OTG_OEP_1_9] = -1, - /* PrimeCells - run-time configured */ - [DB8500_DMA_DEV0_SPI0_TX] = -1, - [DB8500_DMA_DEV1_SD_MMC0_TX] = -1, - [DB8500_DMA_DEV2_SD_MMC1_TX] = -1, - [DB8500_DMA_DEV3_SD_MMC2_TX] = -1, - [DB8500_DMA_DEV8_SSP0_TX] = -1, - [DB8500_DMA_DEV9_SSP1_TX] = -1, - [DB8500_DMA_DEV11_UART2_TX] = -1, - [DB8500_DMA_DEV12_UART1_TX] = -1, - [DB8500_DMA_DEV13_UART0_TX] = -1, - [DB8500_DMA_DEV28_SD_MM2_TX] = -1, - [DB8500_DMA_DEV29_SD_MM0_TX] = -1, - [DB8500_DMA_DEV32_SD_MM1_TX] = -1, - [DB8500_DMA_DEV33_SPI2_TX] = -1, - [DB8500_DMA_DEV35_SPI1_TX] = -1, - [DB8500_DMA_DEV40_SPI3_TX] = -1, - [DB8500_DMA_DEV41_SD_MM3_TX] = -1, - [DB8500_DMA_DEV42_SD_MM4_TX] = -1, - [DB8500_DMA_DEV43_SD_MM5_TX] = -1, -}; - -/* Mapping between source event lines and physical device address */ -static const dma_addr_t dma40_rx_map[DB8500_DMA_NR_DEV] = { - /* MUSB - these will be runtime-reconfigured */ - [DB8500_DMA_DEV39_USB_OTG_IEP_8] = -1, - [DB8500_DMA_DEV16_USB_OTG_IEP_7_15] = -1, - [DB8500_DMA_DEV17_USB_OTG_IEP_6_14] = -1, - [DB8500_DMA_DEV18_USB_OTG_IEP_5_13] = -1, - [DB8500_DMA_DEV19_USB_OTG_IEP_4_12] = -1, - [DB8500_DMA_DEV36_USB_OTG_IEP_3_11] = -1, - [DB8500_DMA_DEV37_USB_OTG_IEP_2_10] = -1, - [DB8500_DMA_DEV38_USB_OTG_IEP_1_9] = -1, - /* PrimeCells */ - [DB8500_DMA_DEV0_SPI0_RX] = -1, - [DB8500_DMA_DEV1_SD_MMC0_RX] = -1, - [DB8500_DMA_DEV2_SD_MMC1_RX] = -1, - [DB8500_DMA_DEV3_SD_MMC2_RX] = -1, - [DB8500_DMA_DEV8_SSP0_RX] = -1, - [DB8500_DMA_DEV9_SSP1_RX] = -1, - [DB8500_DMA_DEV11_UART2_RX] = -1, - [DB8500_DMA_DEV12_UART1_RX] = -1, - [DB8500_DMA_DEV13_UART0_RX] = -1, - [DB8500_DMA_DEV28_SD_MM2_RX] = -1, - [DB8500_DMA_DEV29_SD_MM0_RX] = -1, - [DB8500_DMA_DEV32_SD_MM1_RX] = -1, - [DB8500_DMA_DEV33_SPI2_RX] = -1, - [DB8500_DMA_DEV35_SPI1_RX] = -1, - [DB8500_DMA_DEV40_SPI3_RX] = -1, - [DB8500_DMA_DEV41_SD_MM3_RX] = -1, - [DB8500_DMA_DEV42_SD_MM4_RX] = -1, - [DB8500_DMA_DEV43_SD_MM5_RX] = -1, -}; - -/* Reserved event lines for memcpy only */ -static int dma40_memcpy_event[] = { - DB8500_DMA_MEMCPY_TX_0, - DB8500_DMA_MEMCPY_TX_1, - DB8500_DMA_MEMCPY_TX_2, - DB8500_DMA_MEMCPY_TX_3, - DB8500_DMA_MEMCPY_TX_4, - DB8500_DMA_MEMCPY_TX_5, -}; - -static struct stedma40_platform_data dma40_plat_data = { - .dev_len = DB8500_DMA_NR_DEV, - .dev_rx = dma40_rx_map, - .dev_tx = dma40_tx_map, - .memcpy = dma40_memcpy_event, - .memcpy_len = ARRAY_SIZE(dma40_memcpy_event), - .memcpy_conf_phy = &dma40_memcpy_conf_phy, - .memcpy_conf_log = &dma40_memcpy_conf_log, - .disabled_channels = {-1}, -}; - -struct platform_device u8500_dma40_device = { - .dev = { - .platform_data = &dma40_plat_data, + +static struct resource u8500_wdt_resources[] = { + [0] = { + .start = U8500_TWD_BASE, + .end = U8500_TWD_BASE+0x37, + .flags = IORESOURCE_MEM, }, - .name = "dma40", - .id = 0, - .num_resources = ARRAY_SIZE(dma40_resources), - .resource = dma40_resources + [1] = { + .start = IRQ_LOCALWDOG, + .end = IRQ_LOCALWDOG, + .flags = IORESOURCE_IRQ, + } }; -void dma40_u8500ed_fixup(void) -{ - dma40_plat_data.memcpy = NULL; - dma40_plat_data.memcpy_len = 0; - dma40_resources[0].start = U8500_DMA_BASE_ED; - dma40_resources[0].end = U8500_DMA_BASE_ED + SZ_4K - 1; - dma40_resources[1].start = U8500_DMA_LCPA_BASE_ED; - dma40_resources[1].end = U8500_DMA_LCPA_BASE_ED + 2 * SZ_1K - 1; +struct platform_device u8500_wdt_device = { + .name = "mpcore_wdt", + .id = -1, + .resource = u8500_wdt_resources, + .num_resources = ARRAY_SIZE(u8500_wdt_resources), +}; + +struct platform_device u8500_prcmu_wdt_device = { + .name = "ux500_wdt", + .id = -1, +}; + +#ifdef CONFIG_HSI +/* + * HSI + */ +#define HSIR_OVERRUN(num) { \ + .start = IRQ_DB8500_HSIR_CH##num##_OVRRUN, \ + .end = IRQ_DB8500_HSIR_CH##num##_OVRRUN, \ + .flags = IORESOURCE_IRQ, \ + .name = "hsi_rx_overrun_ch"#num \ } +#define STE_HSI_PORT0_TX_CHANNEL_CFG(n) { \ + .dir = STEDMA40_MEM_TO_PERIPH, \ + .high_priority = true, \ + .mode = STEDMA40_MODE_LOGICAL, \ + .mode_opt = STEDMA40_LCHAN_SRC_LOG_DST_LOG, \ + .src_dev_type = STEDMA40_DEV_SRC_MEMORY, \ + .dst_dev_type = n,\ + .src_info.big_endian = false,\ + .src_info.data_width = STEDMA40_WORD_WIDTH,\ + .dst_info.big_endian = false,\ + .dst_info.data_width = STEDMA40_WORD_WIDTH,\ +}, + +#define STE_HSI_PORT0_RX_CHANNEL_CFG(n) { \ + .dir = STEDMA40_PERIPH_TO_MEM, \ + .high_priority = true, \ + .mode = STEDMA40_MODE_LOGICAL, \ + .mode_opt = STEDMA40_LCHAN_SRC_LOG_DST_LOG, \ + .src_dev_type = n,\ + .dst_dev_type = STEDMA40_DEV_DST_MEMORY, \ + .src_info.big_endian = false,\ + .src_info.data_width = STEDMA40_WORD_WIDTH,\ + .dst_info.big_endian = false,\ + .dst_info.data_width = STEDMA40_WORD_WIDTH,\ +}, + +static struct resource u8500_hsi_resources[] = { + { + .start = U8500_HSIR_BASE, + .end = U8500_HSIR_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + .name = "hsi_rx_base" + }, + { + .start = U8500_HSIT_BASE, + .end = U8500_HSIT_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + .name = "hsi_tx_base" + }, + { + .start = IRQ_DB8500_HSIRD0, + .end = IRQ_DB8500_HSIRD0, + .flags = IORESOURCE_IRQ, + .name = "hsi_rx_irq0" + }, + { + .start = IRQ_DB8500_HSITD0, + .end = IRQ_DB8500_HSITD0, + .flags = IORESOURCE_IRQ, + .name = "hsi_tx_irq0" + }, + { + .start = IRQ_DB8500_HSIR_EXCEP, + .end = IRQ_DB8500_HSIR_EXCEP, + .flags = IORESOURCE_IRQ, + .name = "hsi_rx_excep0" + }, + HSIR_OVERRUN(0), + HSIR_OVERRUN(1), + HSIR_OVERRUN(2), + HSIR_OVERRUN(3), + HSIR_OVERRUN(4), + HSIR_OVERRUN(5), + HSIR_OVERRUN(6), + HSIR_OVERRUN(7), +}; + +#ifdef CONFIG_STE_DMA40 +static struct stedma40_chan_cfg ste_hsi_port0_dma_tx_cfg[] = { + STE_HSI_PORT0_TX_CHANNEL_CFG(DB8500_DMA_DEV20_SLIM0_CH0_TX_HSI_TX_CH0) + STE_HSI_PORT0_TX_CHANNEL_CFG(DB8500_DMA_DEV21_SLIM0_CH1_TX_HSI_TX_CH1) + STE_HSI_PORT0_TX_CHANNEL_CFG(DB8500_DMA_DEV22_SLIM0_CH2_TX_HSI_TX_CH2) + STE_HSI_PORT0_TX_CHANNEL_CFG(DB8500_DMA_DEV23_SLIM0_CH3_TX_HSI_TX_CH3) +}; + +static struct stedma40_chan_cfg ste_hsi_port0_dma_rx_cfg[] = { + STE_HSI_PORT0_RX_CHANNEL_CFG(DB8500_DMA_DEV20_SLIM0_CH0_RX_HSI_RX_CH0) + STE_HSI_PORT0_RX_CHANNEL_CFG(DB8500_DMA_DEV21_SLIM0_CH1_RX_HSI_RX_CH1) + STE_HSI_PORT0_RX_CHANNEL_CFG(DB8500_DMA_DEV22_SLIM0_CH2_RX_HSI_RX_CH2) + STE_HSI_PORT0_RX_CHANNEL_CFG(DB8500_DMA_DEV23_SLIM0_CH3_RX_HSI_RX_CH3) +}; +#endif + +static struct ste_hsi_port_cfg ste_hsi_port0_cfg = { +#ifdef CONFIG_STE_DMA40 + .dma_filter = stedma40_filter, + .dma_tx_cfg = ste_hsi_port0_dma_tx_cfg, + .dma_rx_cfg = ste_hsi_port0_dma_rx_cfg +#endif +}; + +struct ste_hsi_platform_data u8500_hsi_platform_data = { + .num_ports = 1, + .use_dma = 1, + .port_cfg = &ste_hsi_port0_cfg, +}; + +struct platform_device u8500_hsi_device = { + .dev = { + .platform_data = &u8500_hsi_platform_data, + }, + .name = "ste_hsi", + .id = 0, + .resource = u8500_hsi_resources, + .num_resources = ARRAY_SIZE(u8500_hsi_resources) +}; +#endif /* CONFIG_HSI */ + +/* + * Thermal Sensor + */ + +static struct resource u8500_thsens_resources[] = { + { + .name = "IRQ_HOTMON_LOW", + .start = IRQ_PRCMU_HOTMON_LOW, + .end = IRQ_PRCMU_HOTMON_LOW, + .flags = IORESOURCE_IRQ, + }, + { + .name = "IRQ_HOTMON_HIGH", + .start = IRQ_PRCMU_HOTMON_HIGH, + .end = IRQ_PRCMU_HOTMON_HIGH, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device u8500_thsens_device = { + .name = "dbx500_temp", + .resource = u8500_thsens_resources, + .num_resources = ARRAY_SIZE(u8500_thsens_resources), +}; + struct resource keypad_resources[] = { [0] = { .start = U8500_SKE_BASE, diff --git a/arch/arm/mach-ux500/devices-db8500.h b/arch/arm/mach-ux500/devices-db8500.h index cbd4a9ae810..4a54a6f5aa6 100644 --- a/arch/arm/mach-ux500/devices-db8500.h +++ b/arch/arm/mach-ux500/devices-db8500.h @@ -98,4 +98,9 @@ db8500_add_ssp(const char *name, resource_size_t base, int irq, #define db8500_add_uart2(pdata) \ dbx500_add_uart("uart2", U8500_UART2_BASE, IRQ_DB8500_UART2, pdata) +#define db8500_add_cryp1(pdata) \ + dbx500_add_cryp1(-1, U8500_CRYP1_BASE, IRQ_DB8500_CRYP1, pdata) +#define db8500_add_hash1(pdata) \ + dbx500_add_hash1(-1, U8500_HASH1_BASE, pdata) + #endif diff --git a/arch/arm/mach-ux500/devices.c b/arch/arm/mach-ux500/devices.c index ea0a2f92ca7..151be4f3e68 100644 --- a/arch/arm/mach-ux500/devices.c +++ b/arch/arm/mach-ux500/devices.c @@ -14,6 +14,51 @@ #include <mach/hardware.h> #include <mach/setup.h> +#ifdef CONFIG_STE_TRACE_MODEM +#include <linux/db8500-modem-trace.h> +#endif + +#ifdef CONFIG_STE_TRACE_MODEM +static struct resource trace_resource = { + .start = 0, + .end = 0, + .name = "db8500-trace-area", + .flags = IORESOURCE_MEM +}; + +static struct db8500_trace_platform_data trace_pdata = { + .ape_base = U8500_APE_BASE, + .modem_base = U8500_MODEM_BASE, +}; + +struct platform_device u8500_trace_modem = { + .name = "db8500-modem-trace", + .id = 0, + .dev = { + .init_name = "db8500-modem-trace", + .platform_data = &trace_pdata, + }, + .num_resources = 1, + .resource = &trace_resource, +}; + +static int __init early_trace_modem(char *p) +{ + struct resource *data = &trace_resource; + u32 size = memparse(p, &p); + if (*p == '@') + data->start = memparse(p + 1, &p); + data->end = data->start + size -1; + return 0; +} + +early_param("mem_mtrace", early_trace_modem); +#endif + +struct platform_device ux500_hwmem_device = { + .name = "hwmem", +}; + void __init amba_add_devices(struct amba_device *devs[], int num) { int i; diff --git a/arch/arm/mach-ux500/dma-db5500.c b/arch/arm/mach-ux500/dma-db5500.c index 1cfab68ae41..d71c489d022 100644 --- a/arch/arm/mach-ux500/dma-db5500.c +++ b/arch/arm/mach-ux500/dma-db5500.c @@ -14,8 +14,7 @@ #include <plat/ste_dma40.h> #include <mach/setup.h> #include <mach/hardware.h> - -#include "ste-dma40-db5500.h" +#include <mach/ste-dma40-db5500.h> static struct resource dma40_resources[] = { [0] = { @@ -72,28 +71,128 @@ static struct stedma40_chan_cfg dma40_memcpy_conf_log = { * now. */ static const dma_addr_t dma40_rx_map[DB5500_DMA_NR_DEV] = { - [DB5500_DMA_DEV24_SDMMC0_RX] = -1, - [DB5500_DMA_DEV38_USB_OTG_IEP_8] = -1, - [DB5500_DMA_DEV23_USB_OTG_IEP_7_15] = -1, - [DB5500_DMA_DEV22_USB_OTG_IEP_6_14] = -1, - [DB5500_DMA_DEV21_USB_OTG_IEP_5_13] = -1, - [DB5500_DMA_DEV20_USB_OTG_IEP_4_12] = -1, - [DB5500_DMA_DEV6_USB_OTG_IEP_3_11] = -1, - [DB5500_DMA_DEV5_USB_OTG_IEP_2_10] = -1, - [DB5500_DMA_DEV4_USB_OTG_IEP_1_9] = -1, + [DB5500_DMA_DEV0_SPI0_RX] = 0, + [DB5500_DMA_DEV1_SPI1_RX] = 0, + [DB5500_DMA_DEV2_SPI2_RX] = 0, + [DB5500_DMA_DEV3_SPI3_RX] = 0, + [DB5500_DMA_DEV4_USB_OTG_IEP_1_9] = U5500_USBOTG_BASE, + [DB5500_DMA_DEV5_USB_OTG_IEP_2_10] = U5500_USBOTG_BASE, + [DB5500_DMA_DEV6_USB_OTG_IEP_3_11] = U5500_USBOTG_BASE, + [DB5500_DMA_DEV7_IRDA_RFS] = 0, + [DB5500_DMA_DEV8_IRDA_FIFO_RX] = 0, + [DB5500_DMA_DEV9_MSP0_RX] = U5500_MSP0_BASE + MSP_TX_RX_REG_OFFSET, + [DB5500_DMA_DEV10_MSP1_RX] = U5500_MSP1_BASE + MSP_TX_RX_REG_OFFSET, + [DB5500_DMA_DEV11_MSP2_RX] = U5500_MSP2_BASE + MSP_TX_RX_REG_OFFSET, + [DB5500_DMA_DEV12_UART0_RX] = 0, + [DB5500_DMA_DEV13_UART1_RX] = 0, + [DB5500_DMA_DEV14_UART2_RX] = 0, + [DB5500_DMA_DEV15_UART3_RX] = 0, + [DB5500_DMA_DEV16_USB_OTG_IEP_8] = U5500_USBOTG_BASE, + [DB5500_DMA_DEV17_USB_OTG_IEP_1_9] = U5500_USBOTG_BASE, + [DB5500_DMA_DEV18_USB_OTG_IEP_2_10] = U5500_USBOTG_BASE, + [DB5500_DMA_DEV19_USB_OTG_IEP_3_11] = U5500_USBOTG_BASE, + [DB5500_DMA_DEV20_USB_OTG_IEP_4_12] = U5500_USBOTG_BASE, + [DB5500_DMA_DEV21_USB_OTG_IEP_5_13] = U5500_USBOTG_BASE, + [DB5500_DMA_DEV22_USB_OTG_IEP_6_14] = U5500_USBOTG_BASE, + [DB5500_DMA_DEV23_USB_OTG_IEP_7_15] = U5500_USBOTG_BASE, + [DB5500_DMA_DEV24_SDMMC0_RX] = U5500_SDI0_BASE + SD_MMC_TX_RX_REG_OFFSET, + [DB5500_DMA_DEV25_SDMMC1_RX] = U5500_SDI1_BASE + SD_MMC_TX_RX_REG_OFFSET, + [DB5500_DMA_DEV26_SDMMC2_RX] = U5500_SDI2_BASE + SD_MMC_TX_RX_REG_OFFSET, + [DB5500_DMA_DEV27_SDMMC3_RX] = U5500_SDI3_BASE + SD_MMC_TX_RX_REG_OFFSET, + [DB5500_DMA_DEV28_SDMMC4_RX] = U5500_SDI4_BASE + SD_MMC_TX_RX_REG_OFFSET, + /* 29, 30 not used */ + [DB5500_DMA_DEV31_CRYPTO1_RX] = 0, /* v2 */ + /* 32 not used */ + [DB5500_DMA_DEV33_SDMMC0_RX] = U5500_SDI0_BASE + SD_MMC_TX_RX_REG_OFFSET, + [DB5500_DMA_DEV34_SDMMC1_RX] = U5500_SDI1_BASE + SD_MMC_TX_RX_REG_OFFSET, + [DB5500_DMA_DEV35_SDMMC2_RX] = U5500_SDI2_BASE + SD_MMC_TX_RX_REG_OFFSET, + [DB5500_DMA_DEV36_SDMMC3_RX] = U5500_SDI3_BASE + SD_MMC_TX_RX_REG_OFFSET, + [DB5500_DMA_DEV37_SDMMC4_RX] = U5500_SDI4_BASE + SD_MMC_TX_RX_REG_OFFSET, + [DB5500_DMA_DEV38_USB_OTG_IEP_8] = U5500_USBOTG_BASE, + [DB5500_DMA_DEV39_USB_OTG_IEP_1_9] = U5500_USBOTG_BASE, + [DB5500_DMA_DEV40_USB_OTG_IEP_2_10] = U5500_USBOTG_BASE, + [DB5500_DMA_DEV41_USB_OTG_IEP_3_11] = U5500_USBOTG_BASE, + [DB5500_DMA_DEV42_USB_OTG_IEP_4_12] = U5500_USBOTG_BASE, + [DB5500_DMA_DEV43_USB_OTG_IEP_5_13] = U5500_USBOTG_BASE, + [DB5500_DMA_DEV44_USB_OTG_IEP_6_14] = U5500_USBOTG_BASE, + [DB5500_DMA_DEV45_USB_OTG_IEP_7_15] = U5500_USBOTG_BASE, + [DB5500_DMA_DEV46_CRYPTO1_RX] = 0, /* v2 */ + [DB5500_DMA_DEV47_MCDE_RX] = 0, + [DB5500_DMA_DEV48_CRYPTO1_RX] = U5500_CRYP1_BASE + CRYP1_RX_REG_OFFSET, + /* 49, 50 not used */ + [DB5500_DMA_DEV49_I2C1_RX] = 0, + [DB5500_DMA_DEV50_I2C3_RX] = 0, + [DB5500_DMA_DEV51_I2C2_RX] = 0, + /* 54 - 60 not used */ + [DB5500_DMA_DEV61_CRYPTO0_RX] = 0, + /* 62, 63 not used */ }; /* Mapping between destination event lines and physical device address */ static const dma_addr_t dma40_tx_map[DB5500_DMA_NR_DEV] = { - [DB5500_DMA_DEV24_SDMMC0_TX] = -1, - [DB5500_DMA_DEV38_USB_OTG_OEP_8] = -1, - [DB5500_DMA_DEV23_USB_OTG_OEP_7_15] = -1, - [DB5500_DMA_DEV22_USB_OTG_OEP_6_14] = -1, - [DB5500_DMA_DEV21_USB_OTG_OEP_5_13] = -1, - [DB5500_DMA_DEV20_USB_OTG_OEP_4_12] = -1, - [DB5500_DMA_DEV6_USB_OTG_OEP_3_11] = -1, - [DB5500_DMA_DEV5_USB_OTG_OEP_2_10] = -1, - [DB5500_DMA_DEV4_USB_OTG_OEP_1_9] = -1, + [DB5500_DMA_DEV0_SPI0_TX] = 0, + [DB5500_DMA_DEV1_SPI1_TX] = 0, + [DB5500_DMA_DEV2_SPI2_TX] = 0, + [DB5500_DMA_DEV3_SPI3_TX] = 0, + [DB5500_DMA_DEV4_USB_OTG_OEP_1_9] = U5500_USBOTG_BASE, + [DB5500_DMA_DEV5_USB_OTG_OEP_2_10] = U5500_USBOTG_BASE, + [DB5500_DMA_DEV6_USB_OTG_OEP_3_11] = U5500_USBOTG_BASE, + [DB5500_DMA_DEV7_IRRC_TX] = 0, + [DB5500_DMA_DEV8_IRDA_FIFO_TX] = 0, + [DB5500_DMA_DEV9_MSP0_TX] = U5500_MSP0_BASE + MSP_TX_RX_REG_OFFSET, + [DB5500_DMA_DEV10_MSP1_TX] = U5500_MSP1_BASE + MSP_TX_RX_REG_OFFSET, + [DB5500_DMA_DEV11_MSP2_TX] = U5500_MSP2_BASE + MSP_TX_RX_REG_OFFSET, + [DB5500_DMA_DEV12_UART0_TX] = 0, + [DB5500_DMA_DEV13_UART1_TX] = 0, + [DB5500_DMA_DEV14_UART2_TX] = 0, + [DB5500_DMA_DEV15_UART3_TX] = 0, + [DB5500_DMA_DEV16_USB_OTG_OEP_8] = U5500_USBOTG_BASE, + [DB5500_DMA_DEV17_USB_OTG_OEP_1_9] = U5500_USBOTG_BASE, + [DB5500_DMA_DEV18_USB_OTG_OEP_2_10] = U5500_USBOTG_BASE, + [DB5500_DMA_DEV19_USB_OTG_OEP_3_11] = U5500_USBOTG_BASE, + [DB5500_DMA_DEV20_USB_OTG_OEP_4_12] = U5500_USBOTG_BASE, + [DB5500_DMA_DEV21_USB_OTG_OEP_5_13] = U5500_USBOTG_BASE, + [DB5500_DMA_DEV22_USB_OTG_OEP_6_14] = U5500_USBOTG_BASE, + [DB5500_DMA_DEV23_USB_OTG_OEP_7_15] = U5500_USBOTG_BASE, + [DB5500_DMA_DEV24_SDMMC0_TX] = U5500_SDI0_BASE + SD_MMC_TX_RX_REG_OFFSET, + [DB5500_DMA_DEV25_SDMMC1_TX] = U5500_SDI1_BASE + SD_MMC_TX_RX_REG_OFFSET, + [DB5500_DMA_DEV26_SDMMC2_TX] = U5500_SDI2_BASE + SD_MMC_TX_RX_REG_OFFSET, + [DB5500_DMA_DEV27_SDMMC3_TX] = U5500_SDI3_BASE + SD_MMC_TX_RX_REG_OFFSET, + [DB5500_DMA_DEV28_SDMMC4_TX] = U5500_SDI4_BASE + SD_MMC_TX_RX_REG_OFFSET, + /* 29 not used */ + [DB5500_DMA_DEV30_HASH1_TX] = 0, /* v2 */ + [DB5500_DMA_DEV31_CRYPTO1_TX] = 0, /* v2 */ + [DB5500_DMA_DEV32_FSMC_TX] = 0, + [DB5500_DMA_DEV33_SDMMC0_TX] = U5500_SDI0_BASE + SD_MMC_TX_RX_REG_OFFSET, + [DB5500_DMA_DEV34_SDMMC1_TX] = U5500_SDI1_BASE + SD_MMC_TX_RX_REG_OFFSET, + [DB5500_DMA_DEV35_SDMMC2_TX] = U5500_SDI2_BASE + SD_MMC_TX_RX_REG_OFFSET, + [DB5500_DMA_DEV36_SDMMC3_TX] = U5500_SDI3_BASE + SD_MMC_TX_RX_REG_OFFSET, + [DB5500_DMA_DEV37_SDMMC4_TX] = U5500_SDI4_BASE + SD_MMC_TX_RX_REG_OFFSET, + [DB5500_DMA_DEV38_USB_OTG_OEP_8] = U5500_USBOTG_BASE, + [DB5500_DMA_DEV39_USB_OTG_OEP_1_9] = U5500_USBOTG_BASE, + [DB5500_DMA_DEV40_USB_OTG_OEP_2_10] = U5500_USBOTG_BASE, + [DB5500_DMA_DEV41_USB_OTG_OEP_3_11] = U5500_USBOTG_BASE, + [DB5500_DMA_DEV42_USB_OTG_OEP_4_12] = U5500_USBOTG_BASE, + [DB5500_DMA_DEV43_USB_OTG_OEP_5_13] = U5500_USBOTG_BASE, + [DB5500_DMA_DEV44_USB_OTG_OEP_6_14] = U5500_USBOTG_BASE, + [DB5500_DMA_DEV45_USB_OTG_OEP_7_15] = U5500_USBOTG_BASE, + [DB5500_DMA_DEV46_CRYPTO1_TX] = 0, /* v2 */ + [DB5500_DMA_DEV47_STM_TX] = 0, + [DB5500_DMA_DEV48_CRYPTO1_TX] = U5500_CRYP1_BASE + CRYP1_TX_REG_OFFSET, + [DB5500_DMA_DEV49_CRYPTO1_TX_HASH1_TX] = 0, + [DB5500_DMA_DEV50_HASH1_TX] = U5500_HASH1_BASE + HASH1_TX_REG_OFFSET, + [DB5500_DMA_DEV51_I2C1_TX] = 0, + [DB5500_DMA_DEV52_I2C3_TX] = 0, + [DB5500_DMA_DEV53_I2C2_TX] = 0, + /* 54, 55 not used */ + [DB5500_DMA_MEMCPY_TX_1] = 0, + [DB5500_DMA_MEMCPY_TX_2] = 0, + [DB5500_DMA_MEMCPY_TX_3] = 0, + [DB5500_DMA_MEMCPY_TX_4] = 0, + [DB5500_DMA_MEMCPY_TX_5] = 0, + [DB5500_DMA_DEV61_CRYPTO0_TX] = 0, + [DB5500_DMA_DEV62_CRYPTO0_TX_HASH0_TX] = 0, + [DB5500_DMA_DEV63_HASH0_TX] = 0, }; static int dma40_memcpy_event[] = { diff --git a/arch/arm/mach-ux500/dma-db8500.c b/arch/arm/mach-ux500/dma-db8500.c new file mode 100644 index 00000000000..9976478fd80 --- /dev/null +++ b/arch/arm/mach-ux500/dma-db8500.c @@ -0,0 +1,312 @@ +/* + * Copyright (C) ST-Ericsson SA 2007-2010 + * + * Author: Per Friden <per.friden@stericsson.com> for ST-Ericsson + * Author: Jonas Aaberg <jonas.aberg@stericsson.com> for ST-Ericsson + * + * License terms: GNU General Public License (GPL) version 2 + */ + +#include <linux/kernel.h> +#include <linux/platform_device.h> + +#include <plat/ste_dma40.h> + +#ifdef CONFIG_HSI +#include <mach/hsi.h> +#endif +#include <mach/setup.h> +#include <mach/ste-dma40-db8500.h> +#include <mach/pm.h> +#include <mach/context.h> + + + +static struct resource dma40_resources[] = { + [0] = { + .start = U8500_DMA_BASE, + .end = U8500_DMA_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + .name = "base", + }, + [1] = { + .start = U8500_DMA_LCPA_BASE, + .end = U8500_DMA_LCPA_BASE + 2 * SZ_1K - 1, + .flags = IORESOURCE_MEM, + .name = "lcpa", + }, + [2] = { + .start = IRQ_DB8500_DMA, + .end = IRQ_DB8500_DMA, + .flags = IORESOURCE_IRQ + }, + [3] = { + .start = U8500_DMA_LCLA_BASE, + .end = U8500_DMA_LCLA_BASE + SZ_8K - 1, + .flags = IORESOURCE_MEM, + .name = "lcla_esram", + } +}; + +/* Default configuration for physcial memcpy */ +static struct stedma40_chan_cfg dma40_memcpy_conf_phy = { + .mode = STEDMA40_MODE_PHYSICAL, + .dir = STEDMA40_MEM_TO_MEM, + + .src_info.data_width = STEDMA40_BYTE_WIDTH, + .src_info.psize = STEDMA40_PSIZE_PHY_1, + .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, + + .dst_info.data_width = STEDMA40_BYTE_WIDTH, + .dst_info.psize = STEDMA40_PSIZE_PHY_1, + .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, + +}; + +/* Default configuration for logical memcpy */ +static struct stedma40_chan_cfg dma40_memcpy_conf_log = { + .dir = STEDMA40_MEM_TO_MEM, + + .src_info.data_width = STEDMA40_BYTE_WIDTH, + .src_info.psize = STEDMA40_PSIZE_LOG_1, + .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, + + .dst_info.data_width = STEDMA40_BYTE_WIDTH, + .dst_info.psize = STEDMA40_PSIZE_LOG_1, + .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, + +}; + +/* + * Mapping between soruce event lines and physical device address + * This was created assuming that the event line is tied to a device and + * therefore the address is constant, however this is not true for at least + * USB, and the values are just placeholders for USB. This table is preserved + * and used for now. + */ +static dma_addr_t dma40_rx_map[DB8500_DMA_NR_DEV] = { + [DB8500_DMA_DEV0_SPI0_RX] = 0, + [DB8500_DMA_DEV1_SD_MMC0_RX] = U8500_SDI0_BASE + SD_MMC_TX_RX_REG_OFFSET, + [DB8500_DMA_DEV2_SD_MMC1_RX] = 0, + [DB8500_DMA_DEV3_SD_MMC2_RX] = 0, + [DB8500_DMA_DEV4_I2C1_RX] = 0, + [DB8500_DMA_DEV5_I2C3_RX] = 0, + [DB8500_DMA_DEV6_I2C2_RX] = 0, + [DB8500_DMA_DEV7_I2C4_RX] = 0, + [DB8500_DMA_DEV8_SSP0_RX] = U8500_SSP0_BASE + SSP_TX_RX_REG_OFFSET, + [DB8500_DMA_DEV9_SSP1_RX] = 0, + [DB8500_DMA_DEV10_MCDE_RX] = 0, + [DB8500_DMA_DEV11_UART2_RX] = 0, + [DB8500_DMA_DEV12_UART1_RX] = 0, + [DB8500_DMA_DEV13_UART0_RX] = 0, + [DB8500_DMA_DEV14_MSP2_RX] = U8500_MSP2_BASE + MSP_TX_RX_REG_OFFSET, + [DB8500_DMA_DEV15_I2C0_RX] = 0, + [DB8500_DMA_DEV16_USB_OTG_IEP_7_15] = U8500_USBOTG_BASE, + [DB8500_DMA_DEV17_USB_OTG_IEP_6_14] = U8500_USBOTG_BASE, + [DB8500_DMA_DEV18_USB_OTG_IEP_5_13] = U8500_USBOTG_BASE, + [DB8500_DMA_DEV19_USB_OTG_IEP_4_12] = U8500_USBOTG_BASE, +#ifdef CONFIG_HSI + [DB8500_DMA_DEV20_SLIM0_CH0_RX_HSI_RX_CH0] = U8500_HSIR_BASE + 0x0 + STE_HSI_RX_BUFFERX, + [DB8500_DMA_DEV21_SLIM0_CH1_RX_HSI_RX_CH1] = U8500_HSIR_BASE + 0x4 + STE_HSI_RX_BUFFERX, + [DB8500_DMA_DEV22_SLIM0_CH2_RX_HSI_RX_CH2] = U8500_HSIR_BASE + 0x8 + STE_HSI_RX_BUFFERX, + [DB8500_DMA_DEV23_SLIM0_CH3_RX_HSI_RX_CH3] = U8500_HSIR_BASE + 0xC + STE_HSI_RX_BUFFERX, +#endif + [DB8500_DMA_DEV24_SRC_SXA0_RX_TX] = 0, + [DB8500_DMA_DEV25_SRC_SXA1_RX_TX] = 0, + [DB8500_DMA_DEV26_SRC_SXA2_RX_TX] = 0, + [DB8500_DMA_DEV27_SRC_SXA3_RX_TX] = 0, + [DB8500_DMA_DEV28_SD_MM2_RX] = U8500_SDI2_BASE + SD_MMC_TX_RX_REG_OFFSET, + [DB8500_DMA_DEV29_SD_MM0_RX] = U8500_SDI0_BASE + SD_MMC_TX_RX_REG_OFFSET, + [DB8500_DMA_DEV30_MSP3_RX] = U8500_MSP3_BASE + MSP_TX_RX_REG_OFFSET, + [DB8500_DMA_DEV31_MSP0_RX_SLIM0_CH0_RX] = U8500_MSP0_BASE + MSP_TX_RX_REG_OFFSET, + [DB8500_DMA_DEV32_SD_MM1_RX] = U8500_SDI1_BASE + SD_MMC_TX_RX_REG_OFFSET, + [DB8500_DMA_DEV33_SPI2_RX] = 0, + [DB8500_DMA_DEV34_I2C3_RX2] = 0, + [DB8500_DMA_DEV35_SPI1_RX] = 0, + [DB8500_DMA_DEV36_USB_OTG_IEP_3_11] = U8500_USBOTG_BASE, + [DB8500_DMA_DEV37_USB_OTG_IEP_2_10] = U8500_USBOTG_BASE, + [DB8500_DMA_DEV38_USB_OTG_IEP_1_9] = U8500_USBOTG_BASE, + [DB8500_DMA_DEV39_USB_OTG_IEP_8] = U8500_USBOTG_BASE, + [DB8500_DMA_DEV40_SPI3_RX] = 0, + [DB8500_DMA_DEV41_SD_MM3_RX] = 0, + [DB8500_DMA_DEV42_SD_MM4_RX] = U8500_SDI4_BASE + SD_MMC_TX_RX_REG_OFFSET, + [DB8500_DMA_DEV43_SD_MM5_RX] = 0, + [DB8500_DMA_DEV44_SRC_SXA4_RX_TX] = 0, + [DB8500_DMA_DEV45_SRC_SXA5_RX_TX] = 0, + [DB8500_DMA_DEV46_SLIM0_CH8_RX_SRC_SXA6_RX_TX] = 0, + [DB8500_DMA_DEV47_SLIM0_CH9_RX_SRC_SXA7_RX_TX] = 0, + [DB8500_DMA_DEV48_CAC1_RX] = U8500_CRYP1_BASE + CRYP1_RX_REG_OFFSET, + /* 49, 50 and 51 are not used */ + [DB8500_DMA_DEV52_SLIM0_CH4_RX_HSI_RX_CH4] = 0, + [DB8500_DMA_DEV53_SLIM0_CH5_RX_HSI_RX_CH5] = 0, + [DB8500_DMA_DEV54_SLIM0_CH6_RX_HSI_RX_CH6] = 0, + [DB8500_DMA_DEV55_SLIM0_CH7_RX_HSI_RX_CH7] = 0, + /* 56, 57, 58, 59 and 60 are not used */ + [DB8500_DMA_DEV61_CAC0_RX] = 0, + /* 62 and 63 are not used */ +}; + +/* Mapping between destination event lines and physical device address */ +static const dma_addr_t dma40_tx_map[DB8500_DMA_NR_DEV] = { + [DB8500_DMA_DEV0_SPI0_TX] = 0, + [DB8500_DMA_DEV1_SD_MMC0_TX] = U8500_SDI0_BASE + SD_MMC_TX_RX_REG_OFFSET, + [DB8500_DMA_DEV2_SD_MMC1_TX] = 0, + [DB8500_DMA_DEV3_SD_MMC2_TX] = 0, + [DB8500_DMA_DEV4_I2C1_TX] = 0, + [DB8500_DMA_DEV5_I2C3_TX] = 0, + [DB8500_DMA_DEV6_I2C2_TX] = 0, + [DB8500_DMA_DEV7_I2C4_TX] = 0, + [DB8500_DMA_DEV8_SSP0_TX] = U8500_SSP0_BASE + SSP_TX_RX_REG_OFFSET, + [DB8500_DMA_DEV9_SSP1_TX] = 0, + /* 10 is not used*/ + [DB8500_DMA_DEV11_UART2_TX] = 0, + [DB8500_DMA_DEV12_UART1_TX] = 0, + [DB8500_DMA_DEV13_UART0_TX] = 0, + [DB8500_DMA_DEV14_MSP2_TX] = U8500_MSP2_BASE + MSP_TX_RX_REG_OFFSET, + [DB8500_DMA_DEV15_I2C0_TX] = 0, + [DB8500_DMA_DEV16_USB_OTG_OEP_7_15] = U8500_USBOTG_BASE, + [DB8500_DMA_DEV17_USB_OTG_OEP_6_14] = U8500_USBOTG_BASE, + [DB8500_DMA_DEV18_USB_OTG_OEP_5_13] = U8500_USBOTG_BASE, + [DB8500_DMA_DEV19_USB_OTG_OEP_4_12] = U8500_USBOTG_BASE, +#ifdef CONFIG_HSI + [DB8500_DMA_DEV20_SLIM0_CH0_TX_HSI_TX_CH0] = U8500_HSIT_BASE + 0x0 + STE_HSI_TX_BUFFERX, + [DB8500_DMA_DEV21_SLIM0_CH1_TX_HSI_TX_CH1] = U8500_HSIT_BASE + 0x4 + STE_HSI_TX_BUFFERX, + [DB8500_DMA_DEV22_SLIM0_CH2_TX_HSI_TX_CH2] = U8500_HSIT_BASE + 0x8 + STE_HSI_TX_BUFFERX, + [DB8500_DMA_DEV23_SLIM0_CH3_TX_HSI_TX_CH3] = U8500_HSIT_BASE + 0xC + STE_HSI_TX_BUFFERX, +#endif + [DB8500_DMA_DEV24_DST_SXA0_RX_TX] = 0, + [DB8500_DMA_DEV25_DST_SXA1_RX_TX] = 0, + [DB8500_DMA_DEV26_DST_SXA2_RX_TX] = 0, + [DB8500_DMA_DEV27_DST_SXA3_RX_TX] = 0, + [DB8500_DMA_DEV28_SD_MM2_TX] = U8500_SDI2_BASE + SD_MMC_TX_RX_REG_OFFSET, + [DB8500_DMA_DEV29_SD_MM0_TX] = U8500_SDI0_BASE + SD_MMC_TX_RX_REG_OFFSET, + [DB8500_DMA_DEV30_MSP1_TX] = U8500_MSP1_BASE + MSP_TX_RX_REG_OFFSET, + [DB8500_DMA_DEV31_MSP0_TX_SLIM0_CH0_TX] = U8500_MSP0_BASE + MSP_TX_RX_REG_OFFSET, + [DB8500_DMA_DEV32_SD_MM1_TX] = U8500_SDI1_BASE + SD_MMC_TX_RX_REG_OFFSET, + [DB8500_DMA_DEV33_SPI2_TX] = 0, + [DB8500_DMA_DEV34_I2C3_TX2] = 0, + [DB8500_DMA_DEV35_SPI1_TX] = 0, + [DB8500_DMA_DEV36_USB_OTG_OEP_3_11] = U8500_USBOTG_BASE, + [DB8500_DMA_DEV37_USB_OTG_OEP_2_10] = U8500_USBOTG_BASE, + [DB8500_DMA_DEV38_USB_OTG_OEP_1_9] = U8500_USBOTG_BASE, + [DB8500_DMA_DEV39_USB_OTG_OEP_8] = U8500_USBOTG_BASE, + [DB8500_DMA_DEV40_SPI3_TX] = 0, + [DB8500_DMA_DEV41_SD_MM3_TX] = 0, + [DB8500_DMA_DEV42_SD_MM4_TX] = U8500_SDI4_BASE + SD_MMC_TX_RX_REG_OFFSET, + [DB8500_DMA_DEV43_SD_MM5_TX] = 0, + [DB8500_DMA_DEV44_DST_SXA4_RX_TX] = 0, + [DB8500_DMA_DEV45_DST_SXA5_RX_TX] = 0, + [DB8500_DMA_DEV46_SLIM0_CH8_TX_DST_SXA6_RX_TX] = 0, + [DB8500_DMA_DEV47_SLIM0_CH9_TX_DST_SXA7_RX_TX] = 0, + [DB8500_DMA_DEV48_CAC1_TX] = U8500_CRYP1_BASE + CRYP1_TX_REG_OFFSET, + [DB8500_DMA_DEV49_CAC1_TX_HAC1_TX] = 0, + [DB8500_DMA_DEV50_HAC1_TX] = U8500_HASH1_BASE + HASH1_TX_REG_OFFSET, + [DB8500_DMA_MEMCPY_TX_0] = 0, + [DB8500_DMA_DEV52_SLIM1_CH4_TX_HSI_TX_CH4] = 0, + [DB8500_DMA_DEV53_SLIM1_CH5_TX_HSI_TX_CH5] = 0, + [DB8500_DMA_DEV54_SLIM1_CH6_TX_HSI_TX_CH6] = 0, + [DB8500_DMA_DEV55_SLIM1_CH7_TX_HSI_TX_CH7] = 0, + [DB8500_DMA_MEMCPY_TX_1] = 0, + [DB8500_DMA_MEMCPY_TX_2] = 0, + [DB8500_DMA_MEMCPY_TX_3] = 0, + [DB8500_DMA_MEMCPY_TX_4] = 0, + [DB8500_DMA_MEMCPY_TX_5] = 0, + [DB8500_DMA_DEV61_CAC0_TX] = 0, + [DB8500_DMA_DEV62_CAC0_TX_HAC0_TX] = 0, + [DB8500_DMA_DEV63_HAC0_TX] = 0, +}; + +/* Reserved event lines for memcpy only */ +static int dma40_memcpy_event[] = { + DB8500_DMA_MEMCPY_TX_0, + DB8500_DMA_MEMCPY_TX_1, + DB8500_DMA_MEMCPY_TX_2, + DB8500_DMA_MEMCPY_TX_3, + DB8500_DMA_MEMCPY_TX_4, + DB8500_DMA_MEMCPY_TX_5, +}; + +static struct stedma40_platform_data dma40_plat_data = { + .dev_len = ARRAY_SIZE(dma40_rx_map), + .dev_rx = dma40_rx_map, + .dev_tx = dma40_tx_map, + .memcpy = dma40_memcpy_event, + .memcpy_len = ARRAY_SIZE(dma40_memcpy_event), + .memcpy_conf_phy = &dma40_memcpy_conf_phy, + .memcpy_conf_log = &dma40_memcpy_conf_log, + /* Audio is using physical channel 2 from MMDSP */ + .disabled_channels = {2, -1}, + .use_esram_lcla = false, +}; + +#ifdef CONFIG_UX500_CONTEXT +#define D40_DREG_GCC 0x000 +#define D40_DREG_LCPA 0x020 +#define D40_DREG_LCLA 0x024 + +static void __iomem *base; + +static int dma_context_notifier_call(struct notifier_block *this, + unsigned long event, void *data) +{ + static unsigned long lcpa; + static unsigned long lcla; + static unsigned long gcc; + + switch (event) { + case CONTEXT_APE_SAVE: + lcla = readl(base + D40_DREG_LCLA); + lcpa = readl(base + D40_DREG_LCPA); + gcc = readl(base + D40_DREG_GCC); + break; + + case CONTEXT_APE_RESTORE: + writel(gcc, base + D40_DREG_GCC); + writel(lcpa, base + D40_DREG_LCPA); + writel(lcla, base + D40_DREG_LCLA); + break; + } + return NOTIFY_OK; +} + +static struct notifier_block dma_context_notifier = { + .notifier_call = dma_context_notifier_call, +}; + +static void dma_context_notifier_init(void) +{ + base = ioremap(dma40_resources[0].start, resource_size(&dma40_resources[0])); + if (WARN_ON(!base)) + return; + + WARN_ON(context_ape_notifier_register(&dma_context_notifier)); +} +#else +static void dma_context_notifier_init(void) +{ +} +#endif + +static struct platform_device dma40_device = { + .dev = { + .platform_data = &dma40_plat_data, +#ifdef CONFIG_PM + .pm_domain = &ux500_dev_power_domain, +#endif + }, + .name = "dma40", + .id = 0, + .num_resources = ARRAY_SIZE(dma40_resources), + .resource = dma40_resources +}; + +void __init db8500_dma_init(void) +{ + int ret; + + ret = platform_device_register(&dma40_device); + if (ret) + dev_err(&dma40_device.dev, "unable to register device: %d\n", ret); + + dma_context_notifier_init(); +} diff --git a/arch/arm/mach-ux500/include/mach/db5500-regs.h b/arch/arm/mach-ux500/include/mach/db5500-regs.h index 6ad98329410..870c3ff574c 100644 --- a/arch/arm/mach-ux500/include/mach/db5500-regs.h +++ b/arch/arm/mach-ux500/include/mach/db5500-regs.h @@ -34,6 +34,7 @@ #define U5500_ICN_BASE 0xA0040000 #define U5500_B2R2_BASE 0xa0200000 #define U5500_BOOT_ROM_BASE 0x90000000 +#define U5500_ASIC_ID_ADDRESS (U5500_BOOT_ROM_BASE + 0x1FFF4) #define U5500_FSMC_BASE (U5500_PER1_BASE + 0x0000) #define U5500_SDI0_BASE (U5500_PER1_BASE + 0x1000) @@ -61,10 +62,14 @@ #define U5500_SCR_BASE (U5500_PER4_BASE + 0x5000) #define U5500_DMC_BASE (U5500_PER4_BASE + 0x6000) #define U5500_PRCMU_BASE (U5500_PER4_BASE + 0x7000) +#define U5500_PRCMU_TIMER_3_BASE (U5500_PER4_BASE + 0x07338) +#define U5500_PRCMU_TIMER_4_BASE (U5500_PER4_BASE + 0x07450) #define U5500_MSP1_BASE (U5500_PER4_BASE + 0x9000) #define U5500_GPIO2_BASE (U5500_PER4_BASE + 0xA000) #define U5500_CDETECT_BASE (U5500_PER4_BASE + 0xF000) #define U5500_PRCMU_TCDM_BASE (U5500_PER4_BASE + 0x18000) +#define U5500_PRCMU_TCPM_BASE (U5500_PER4_BASE + 0x10000) +#define U5500_TPIU_BASE (U5500_PER4_BASE + 0x50000) #define U5500_SPI0_BASE (U5500_PER5_BASE + 0x0000) #define U5500_SPI1_BASE (U5500_PER5_BASE + 0x1000) diff --git a/arch/arm/mach-ux500/include/mach/db8500-regs.h b/arch/arm/mach-ux500/include/mach/db8500-regs.h index 049997109cf..80e10f50282 100644 --- a/arch/arm/mach-ux500/include/mach/db8500-regs.h +++ b/arch/arm/mach-ux500/include/mach/db8500-regs.h @@ -22,7 +22,9 @@ #define U8500_ESRAM_DMA_LCPA_OFFSET 0x10000 #define U8500_DMA_LCPA_BASE (U8500_ESRAM_BANK0 + U8500_ESRAM_DMA_LCPA_OFFSET) -#define U8500_DMA_LCPA_BASE_ED (U8500_ESRAM_BANK4 + 0x4000) + +/* This address fulfills the 256k alignment requirement of the lcla base */ +#define U8500_DMA_LCLA_BASE U8500_ESRAM_BANK4 #define U8500_PER3_BASE 0x80000000 #define U8500_STM_BASE 0x80100000 @@ -40,15 +42,14 @@ #define U8500_ASIC_ID_BASE 0x9001D000 #define U8500_PER6_BASE 0xa03c0000 +#define U8500_PER7_BASE 0xa03d0000 #define U8500_PER5_BASE 0xa03e0000 -#define U8500_PER7_BASE_ED 0xa03d0000 #define U8500_SVA_BASE 0xa0100000 #define U8500_SIA_BASE 0xa0200000 #define U8500_SGA_BASE 0xa0300000 #define U8500_MCDE_BASE 0xa0350000 -#define U8500_DMA_BASE_ED 0xa0362000 #define U8500_DMA_BASE 0x801C0000 /* v1 */ #define U8500_SBAG_BASE 0xa0390000 @@ -66,13 +67,6 @@ #define U8500_GPIO2_BASE (U8500_PER2_BASE + 0xE000) #define U8500_GPIO3_BASE (U8500_PER5_BASE + 0x1E000) -/* per7 base addresses */ -#define U8500_CR_BASE_ED (U8500_PER7_BASE_ED + 0x8000) -#define U8500_MTU0_BASE_ED (U8500_PER7_BASE_ED + 0xa000) -#define U8500_MTU1_BASE_ED (U8500_PER7_BASE_ED + 0xb000) -#define U8500_TZPC0_BASE_ED (U8500_PER7_BASE_ED + 0xc000) -#define U8500_CLKRST7_BASE_ED (U8500_PER7_BASE_ED + 0xf000) - #define U8500_UART0_BASE (U8500_PER1_BASE + 0x0000) #define U8500_UART1_BASE (U8500_PER1_BASE + 0x1000) @@ -102,9 +96,10 @@ #define U8500_SCR_BASE (U8500_PER4_BASE + 0x05000) #define U8500_DMC_BASE (U8500_PER4_BASE + 0x06000) #define U8500_PRCMU_BASE (U8500_PER4_BASE + 0x07000) -#define U8500_PRCMU_TCDM_BASE_V1 (U8500_PER4_BASE + 0x0f000) #define U8500_PRCMU_TCDM_BASE (U8500_PER4_BASE + 0x68000) #define U8500_PRCMU_TCPM_BASE (U8500_PER4_BASE + 0x60000) +#define U8500_PRCMU_TIMER_3_BASE (U8500_PER4_BASE + 0x07338) +#define U8500_PRCMU_TIMER_4_BASE (U8500_PER4_BASE + 0x07450) /* per3 base addresses */ #define U8500_FSMC_BASE (U8500_PER3_BASE + 0x0000) diff --git a/arch/arm/mach-ux500/include/mach/devices.h b/arch/arm/mach-ux500/include/mach/devices.h index 020b6369a30..27e6b5faaa0 100644 --- a/arch/arm/mach-ux500/include/mach/devices.h +++ b/arch/arm/mach-ux500/include/mach/devices.h @@ -13,11 +13,24 @@ struct amba_device; extern struct platform_device u5500_gpio_devs[]; extern struct platform_device u8500_gpio_devs[]; +extern struct platform_device u8500_mcde_device; +extern struct platform_device u5500_mcde_device; +extern struct platform_device u8500_shrm_device; +extern struct platform_device u8500_b2r2_device; +extern struct platform_device u5500_b2r2_device; +extern struct platform_device u8500_trace_modem; +extern struct platform_device ux500_hwmem_device; +extern struct platform_device u8500_stm_device; extern struct amba_device ux500_pl031_device; - -extern struct platform_device u8500_dma40_device; +extern struct platform_device ux500_hash1_device; +extern struct platform_device ux500_cryp1_device; +extern struct platform_device mloader_fw_device; +extern struct platform_device u5500_thsens_device; +extern struct platform_device u8500_thsens_device; extern struct platform_device ux500_ske_keypad_device; - -void dma40_u8500ed_fixup(void); +extern struct platform_device u8500_wdt_device; +extern struct platform_device u8500_hsi_device; +extern struct platform_device ux500_mmio_device; +extern struct platform_device u5500_mmio_device; #endif diff --git a/arch/arm/mach-ux500/include/mach/hardware.h b/arch/arm/mach-ux500/include/mach/hardware.h index 470ac52663d..5983d53c3c9 100644 --- a/arch/arm/mach-ux500/include/mach/hardware.h +++ b/arch/arm/mach-ux500/include/mach/hardware.h @@ -10,25 +10,56 @@ #ifndef __MACH_HARDWARE_H #define __MACH_HARDWARE_H -/* macros to get at IO space when running virtually +/* + * Macros to get at IO space when running virtually * We dont map all the peripherals, let ioremap do * this for us. We map only very basic peripherals here. */ #define U8500_IO_VIRTUAL 0xf0000000 #define U8500_IO_PHYSICAL 0xa0000000 -/* this macro is used in assembly, so no cast */ +/* This macro is used in assembly, so no cast */ #define IO_ADDRESS(x) \ (((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + U8500_IO_VIRTUAL) /* typesafe io address */ #define __io_address(n) __io(IO_ADDRESS(n)) -/* used by some plat-nomadik code */ +/* Used by some plat-nomadik code */ #define io_p2v(n) __io_address(n) #include <mach/db8500-regs.h> #include <mach/db5500-regs.h> +/* + * FIFO offsets for IPs + */ +#define MSP_TX_RX_REG_OFFSET 0 +#define SSP_TX_RX_REG_OFFSET 0x8 +#define SPI_TX_RX_REG_OFFSET 0x8 +#define SD_MMC_TX_RX_REG_OFFSET 0x80 +#define CRYP1_RX_REG_OFFSET 0x10 +#define CRYP1_TX_REG_OFFSET 0x8 +#define HASH1_TX_REG_OFFSET 0x4 + +/* MSP related board specific declaration************************/ + +#define MSP_DATA_DELAY MSP_DELAY_0 +#define MSP_TX_CLOCK_EDGE MSP_FALLING_EDGE +#define MSP_RX_CLOCK_EDGE MSP_FALLING_EDGE + +#define MSP_0_CONTROLLER 1 +#define MSP_1_CONTROLLER 2 +#define MSP_2_CONTROLLER 3 +#define MSP_3_CONTROLLER 4 + +#define SSP_0_CONTROLLER 4 +#define SSP_1_CONTROLLER 5 + +#define SPI023_0_CONTROLLER 6 +#define SPI023_1_CONTROLLER 7 +#define SPI023_2_CONTROLLER 8 +#define SPI023_3_CONTROLLER 9 + #ifndef __ASSEMBLY__ #include <mach/id.h> @@ -36,6 +67,14 @@ extern void __iomem *_PRCMU_BASE; #define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x) + +#ifdef CONFIG_UX500_SOC_DB5500 +bool cpu_is_u5500v1(void); +bool cpu_is_u5500v2(void); +#else +static inline bool cpu_is_u5500v1(void) { return false; } +static inline bool cpu_is_u5500v2(void) { return false; } #endif +#endif /* __ASSEMBLY__ */ #endif /* __MACH_HARDWARE_H */ diff --git a/arch/arm/mach-ux500/include/mach/hcl_defs.h b/arch/arm/mach-ux500/include/mach/hcl_defs.h new file mode 100644 index 00000000000..efd37608cb3 --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/hcl_defs.h @@ -0,0 +1,252 @@ +/* + * Copyright (C) 2009 ST-Ericsson SA + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef _HCL_DEFS_H +#define _HCL_DEFS_H +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +//#include "platform_os.h" + +/*----------------------------------------------------------------------------- + * Type definition + *---------------------------------------------------------------------------*/ +typedef unsigned char t_uint8; +typedef signed char t_sint8; +typedef unsigned short t_uint16; +typedef signed short t_sint16; +typedef unsigned long t_uint32; +typedef signed long t_sint32; + +typedef unsigned int t_bitfield; + + + +#if !defined(FALSE) && !defined(TRUE) +typedef int t_bool; +#define FALSE 0 +#define TRUE 1 +#endif + +/* + * Definition of the different kind of addresses manipulated into a system with MMU + * (handle physical AND logical addresses) + */ + + +typedef t_uint32 t_physical_address; +typedef t_uint32 t_logical_address; + + + +/* + * Global frequency enumuration + * Added to avoid frequency conversion function which is required to convert one HCL + * frequency enumuration values to another HCL frequency enumuration values. + */ + +/*typedef enum { + HCL_FREQ_NOT_SUPPORTED=-1, + HCL_FREQ_8KHZ , + HCL_FREQ_11_25KHZ, + HCL_FREQ_12KHZ, + HCL_FREQ_16KHZ, + HCL_FREQ_22_05KHZ, + HCL_FREQ_22_5KHZ, + HCL_FREQ_24KHZ, + HCL_FREQ_32KHZ, + HCL_FREQ_44KHZ, + HCL_FREQ_44_1KHZ, + HCL_FREQ_48KHZ, + HCL_FREQ_64KHZ, + HCL_FREQ_88KHZ, + HCL_FREQ_88_2KHZ, + HCL_FREQ_96KHZ, + HCL_FREQ_128KHZ, + HCL_FREQ_176_4KHZ, + HCL_FREQ_192KHZ, + + HCL_FREQ_1MHZ, + HCL_FREQ_2MHZ, + HCL_FREQ_3MHZ, + HCL_FREQ_4MHZ, + HCL_FREQ_5MHZ, + HCL_FREQ_6MHZ, + HCL_FREQ_8MHZ, + HCL_FREQ_11MHZ, + HCL_FREQ_12MHZ, + HCL_FREQ_16MHZ, + HCL_FREQ_22MHZ, + HCL_FREQ_24MHZ, + HCL_FREQ_48MHZ +} t_frequency; + +*/ + +typedef struct { + t_physical_address physical; + t_logical_address logical; +} t_system_address; + + +/* + * Define a type used to manipulate size of various buffers + */ +typedef t_uint32 t_size; + +typedef struct { + t_bitfield minor:8; + t_bitfield major:8; + t_bitfield version:16; +} t_version; + + + + +/*----------------------------------------------------------------------------- + * Keyword definition + *---------------------------------------------------------------------------*/ +#define PUBLIC /* Extern by default */ +#define PRIVATE static + +#ifndef NULL +#define NULL (0) +#endif /* ndef NULL */ + + +/*----------------------------------------------------------------------------- + * Bit setting or clearing + *---------------------------------------------------------------------------*/ +#define HCL_SET_BITS(reg,mask) ((reg) |= (mask)) +#define HCL_CLEAR_BITS(reg,mask) ((reg) &= ~(mask)) +#define HCL_READ_BITS(reg,mask) ((reg) & (mask)) +#define HCL_WRITE_BITS(reg,val,mask) ((reg) = (((reg) & ~(mask)) | ((val) & (mask)))) +#define HCL_READ_REG(reg) (reg) +#define HCL_WRITE_REG(reg,val) ((reg) = (val)) + +/*----------------------------------------------------------------------------- + * field offset extraction from a structure + *---------------------------------------------------------------------------*/ +#define HCL_BITFIELD_OFFSET(typeName, fieldName) (t_uint32)(&(((typeName *)0)->fieldName)) + +/*----------------------------------------------------------------------------- + * Bit mask definition + *---------------------------------------------------------------------------*/ +#define MASK_NULL8 0x00 +#define MASK_NULL16 0x0000 +#define MASK_NULL32 0x00000000 +#define MASK_ALL8 0xFF +#define MASK_ALL16 0xFFFF +#define MASK_ALL32 0xFFFFFFFF + +#define MASK_BIT0 (1UL<<0) +#define MASK_BIT1 (1UL<<1) +#define MASK_BIT2 (1UL<<2) +#define MASK_BIT3 (1UL<<3) +#define MASK_BIT4 (1UL<<4) +#define MASK_BIT5 (1UL<<5) +#define MASK_BIT6 (1UL<<6) +#define MASK_BIT7 (1UL<<7) +#define MASK_BIT8 (1UL<<8) +#define MASK_BIT9 (1UL<<9) +#define MASK_BIT10 (1UL<<10) +#define MASK_BIT11 (1UL<<11) +#define MASK_BIT12 (1UL<<12) +#define MASK_BIT13 (1UL<<13) +#define MASK_BIT14 (1UL<<14) +#define MASK_BIT15 (1UL<<15) +#define MASK_BIT16 (1UL<<16) +#define MASK_BIT17 (1UL<<17) +#define MASK_BIT18 (1UL<<18) +#define MASK_BIT19 (1UL<<19) +#define MASK_BIT20 (1UL<<20) +#define MASK_BIT21 (1UL<<21) +#define MASK_BIT22 (1UL<<22) +#define MASK_BIT23 (1UL<<23) +#define MASK_BIT24 (1UL<<24) +#define MASK_BIT25 (1UL<<25) +#define MASK_BIT26 (1UL<<26) +#define MASK_BIT27 (1UL<<27) +#define MASK_BIT28 (1UL<<28) +#define MASK_BIT29 (1UL<<29) +#define MASK_BIT30 (1UL<<30) +#define MASK_BIT31 (1UL<<31) + +/*----------------------------------------------------------------------------- + * quartet shift definition + *---------------------------------------------------------------------------*/ +#define MASK_QUARTET (0xFUL) +#define SHIFT_QUARTET0 0 +#define SHIFT_QUARTET1 4 +#define SHIFT_QUARTET2 8 +#define SHIFT_QUARTET3 12 +#define SHIFT_QUARTET4 16 +#define SHIFT_QUARTET5 20 +#define SHIFT_QUARTET6 24 +#define SHIFT_QUARTET7 28 +#define MASK_QUARTET0 (MASK_QUARTET << SHIFT_QUARTET0) +#define MASK_QUARTET1 (MASK_QUARTET << SHIFT_QUARTET1) +#define MASK_QUARTET2 (MASK_QUARTET << SHIFT_QUARTET2) +#define MASK_QUARTET3 (MASK_QUARTET << SHIFT_QUARTET3) +#define MASK_QUARTET4 (MASK_QUARTET << SHIFT_QUARTET4) +#define MASK_QUARTET5 (MASK_QUARTET << SHIFT_QUARTET5) +#define MASK_QUARTET6 (MASK_QUARTET << SHIFT_QUARTET6) +#define MASK_QUARTET7 (MASK_QUARTET << SHIFT_QUARTET7) + +/*----------------------------------------------------------------------------- + * Byte shift definition + *---------------------------------------------------------------------------*/ +#define MASK_BYTE (0xFFUL) +#define SHIFT_BYTE0 0 +#define SHIFT_BYTE1 8 +#define SHIFT_BYTE2 16 +#define SHIFT_BYTE3 24 +#define MASK_BYTE0 (MASK_BYTE << SHIFT_BYTE0) +#define MASK_BYTE1 (MASK_BYTE << SHIFT_BYTE1) +#define MASK_BYTE2 (MASK_BYTE << SHIFT_BYTE2) +#define MASK_BYTE3 (MASK_BYTE << SHIFT_BYTE3) + +/*----------------------------------------------------------------------------- + * Halfword shift definition + *---------------------------------------------------------------------------*/ +#define MASK_HALFWORD (0xFFFFUL) +#define SHIFT_HALFWORD0 0 +#define SHIFT_HALFWORD1 16 +#define MASK_HALFWORD0 (MASK_HALFWORD << SHIFT_HALFWORD0) +#define MASK_HALFWORD1 (MASK_HALFWORD << SHIFT_HALFWORD1) + +/*----------------------------------------------------------------------------- + * Global constants definition + *---------------------------------------------------------------------------*/ + #define ONE_KB (1024) + #define ONE_MB (ONE_KB * ONE_KB) + + +/*----------------------------------------------------------------------------- + * Address translation macros declaration + *---------------------------------------------------------------------------*/ + +#define ARM_TO_AHB_ADDR(addr) (addr) +#define AHB_TO_ARM_ADDR(addr) (addr) + +/* For input parameters - would not be changed by the API */ +#define IN +/* For output parameters - would be changes by the API */ +#define OUT +/* For input-output parameters - provides input to the API but would be changed by the API */ +#define INOUT +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _HCL_DEFS_H */ + +/* End of file hcl_defs.h */ + + diff --git a/arch/arm/mach-ux500/include/mach/id.h b/arch/arm/mach-ux500/include/mach/id.h index 02b541a37ee..6f669eebc04 100644 --- a/arch/arm/mach-ux500/include/mach/id.h +++ b/arch/arm/mach-ux500/include/mach/id.h @@ -38,38 +38,36 @@ static inline unsigned int __attribute_const__ dbx500_revision(void) static inline bool __attribute_const__ cpu_is_u8500(void) { - return dbx500_partnumber() == 0x8500; +#ifdef CONFIG_UX500_SOC_DB8500 + /* partnumber 8520 also comes under 8500 */ + return ((dbx500_partnumber() >> 8) & 0xff) == 0x85; +#else + return false; +#endif +} + +static inline bool __attribute_const__ cpu_is_u8520(void) +{ +#ifdef CONFIG_UX500_SOC_DB8500 + return dbx500_partnumber() == 0x8520; +#else + return false; +#endif } static inline bool __attribute_const__ cpu_is_u5500(void) { +#ifdef CONFIG_UX500_SOC_DB5500 return dbx500_partnumber() == 0x5500; +#else + return false; +#endif } /* * 8500 revisions */ -static inline bool __attribute_const__ cpu_is_u8500ed(void) -{ - return cpu_is_u8500() && dbx500_revision() == 0x00; -} - -static inline bool __attribute_const__ cpu_is_u8500v1(void) -{ - return cpu_is_u8500() && (dbx500_revision() & 0xf0) == 0xA0; -} - -static inline bool __attribute_const__ cpu_is_u8500v10(void) -{ - return cpu_is_u8500() && dbx500_revision() == 0xA0; -} - -static inline bool __attribute_const__ cpu_is_u8500v11(void) -{ - return cpu_is_u8500() && dbx500_revision() == 0xA1; -} - static inline bool __attribute_const__ cpu_is_u8500v2(void) { return cpu_is_u8500() && ((dbx500_revision() & 0xf0) == 0xB0); @@ -85,9 +83,14 @@ static inline bool cpu_is_u8500v21(void) return cpu_is_u8500() && (dbx500_revision() == 0xB1); } +static inline bool cpu_is_u8500v22(void) +{ + return cpu_is_u8500() && (dbx500_revision() == 0xB2); +} + static inline bool cpu_is_u8500v20_or_later(void) { - return cpu_is_u8500() && !cpu_is_u8500v10() && !cpu_is_u8500v11(); + return cpu_is_u8500() && ((dbx500_revision() & 0xf0) >= 0xB0); } static inline bool ux500_is_svp(void) diff --git a/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h b/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h index 47969909836..a58aa51fccf 100644 --- a/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h +++ b/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h @@ -43,6 +43,8 @@ #define MOP500_AB8500_VIR_GPIO_IRQ_BASE \ MOP500_STMPE1601_IRQ_END +#define MOP500_AB8500_VIR_GPIO_IRQ(x) \ + (MOP500_AB8500_VIR_GPIO_IRQ_BASE + (x)) #define MOP500_AB8500_VIR_GPIO_IRQ_END \ (MOP500_AB8500_VIR_GPIO_IRQ_BASE + AB8500_VIR_GPIO_NR_IRQS) @@ -57,7 +59,7 @@ */ #if MOP500_IRQ_END > IRQ_BOARD_END #undef IRQ_BOARD_END -#define IRQ_BOARD_END MOP500_IRQ_END +#define IRQ_BOARD_END MOP500_IRQ_END #endif #endif diff --git a/arch/arm/mach-ux500/include/mach/irqs-board-u5500.h b/arch/arm/mach-ux500/include/mach/irqs-board-u5500.h index 29d972c7717..2294a47b3a2 100644 --- a/arch/arm/mach-ux500/include/mach/irqs-board-u5500.h +++ b/arch/arm/mach-ux500/include/mach/irqs-board-u5500.h @@ -7,13 +7,20 @@ #ifndef __MACH_IRQS_BOARD_U5500_H #define __MACH_IRQS_BOARD_U5500_H -#define AB5500_NR_IRQS 5 +#include <linux/mfd/abx500/ab5500.h> + +#define AB5500_NR_IRQS (AB5500_NUM_IRQ_REGS * 8) #define IRQ_AB5500_BASE IRQ_BOARD_START #define IRQ_AB5500_END (IRQ_AB5500_BASE + AB5500_NR_IRQS) #define U5500_IRQ_END IRQ_AB5500_END -#if IRQ_BOARD_END < U5500_IRQ_END +/* + * We may have several boards, but only one will run at a + * time, so the one with most IRQs will bump this ahead, + * but the IRQ_BOARD_START remains the same for either board. + */ +#if U5500_IRQ_END > IRQ_BOARD_END #undef IRQ_BOARD_END #define IRQ_BOARD_END U5500_IRQ_END #endif diff --git a/arch/arm/mach-ux500/include/mach/irqs-db5500.h b/arch/arm/mach-ux500/include/mach/irqs-db5500.h index 77239776a6f..4ea577aefa0 100644 --- a/arch/arm/mach-ux500/include/mach/irqs-db5500.h +++ b/arch/arm/mach-ux500/include/mach/irqs-db5500.h @@ -85,6 +85,36 @@ #ifdef CONFIG_UX500_SOC_DB5500 +/* Virtual interrupts corresponding to the PRCMU wakeups. */ +#define IRQ_DB5500_PRCMU_BASE IRQ_SOC_START + +#define IRQ_DB5500_PRCMU_RTC (IRQ_DB5500_PRCMU_BASE) +#define IRQ_DB5500_PRCMU_RTT0 (IRQ_DB5500_PRCMU_BASE + 1) +#define IRQ_DB5500_PRCMU_RTT1 (IRQ_DB5500_PRCMU_BASE + 2) +#define IRQ_DB5500_PRCMU_CD_IRQ (IRQ_DB5500_PRCMU_BASE + 3) +#define IRQ_DB5500_PRCMU_SRP_TIM (IRQ_DB5500_PRCMU_BASE + 4) +#define IRQ_DB5500_PRCMU_APE_REQ (IRQ_DB5500_PRCMU_BASE + 5) +#define IRQ_DB5500_PRCMU_USB (IRQ_DB5500_PRCMU_BASE + 6) +#define IRQ_DB5500_PRCMU_ABB (IRQ_DB5500_PRCMU_BASE + 7) +#define IRQ_DB5500_PRCMU_ARM (IRQ_DB5500_PRCMU_BASE + 8) +#define IRQ_DB5500_PRCMU_MODEM_SW_RESET_REQ (IRQ_DB5500_PRCMU_BASE + 9) +#define IRQ_DB5500_PRCMU_AC_WAKE_ACK (IRQ_DB5500_PRCMU_BASE + 10) +#define IRQ_DB5500_PRCMU_GPIO0 (IRQ_DB5500_PRCMU_BASE + 11) +#define IRQ_DB5500_PRCMU_GPIO1 (IRQ_DB5500_PRCMU_BASE + 12) +#define IRQ_DB5500_PRCMU_GPIO2 (IRQ_DB5500_PRCMU_BASE + 13) +#define IRQ_DB5500_PRCMU_GPIO3 (IRQ_DB5500_PRCMU_BASE + 14) +#define IRQ_DB5500_PRCMU_GPIO4 (IRQ_DB5500_PRCMU_BASE + 15) +#define IRQ_DB5500_PRCMU_GPIO5 (IRQ_DB5500_PRCMU_BASE + 16) +#define IRQ_DB5500_PRCMU_GPIO6 (IRQ_DB5500_PRCMU_BASE + 17) +#define IRQ_DB5500_PRCMU_GPIO7 (IRQ_DB5500_PRCMU_BASE + 18) +#define IRQ_DB5500_PRCMU_AC_REL_ACK (IRQ_DB5500_PRCMU_BASE + 19) +#define IRQ_DB5500_PRCMU_LOW_POWER_AUDIO (IRQ_DB5500_PRCMU_BASE + 20) +#define IRQ_DB5500_PRCMU_TEMP_SENSOR_LOW (IRQ_DB5500_PRCMU_BASE + 21) +#define IRQ_DB5500_PRCMU_TEMP_SENSOR_HIGH (IRQ_DB5500_PRCMU_BASE + 22) +#define IRQ_DB5500_PRCMU_END (IRQ_DB5500_PRCMU_BASE + 23) + +#define NUM_DB5500_PRCMU_WAKEUPS (IRQ_DB5500_PRCMU_END - IRQ_DB5500_PRCMU_BASE) + /* * After the GPIO ones we reserve a range of IRQ:s in which virtual * IRQ:s representing modem IRQ:s can be allocated diff --git a/arch/arm/mach-ux500/include/mach/irqs.h b/arch/arm/mach-ux500/include/mach/irqs.h index 9db68d264c5..a2876464d43 100644 --- a/arch/arm/mach-ux500/include/mach/irqs.h +++ b/arch/arm/mach-ux500/include/mach/irqs.h @@ -11,9 +11,7 @@ #define ASM_ARCH_IRQS_H #include <mach/hardware.h> - -#define IRQ_LOCALTIMER 29 -#define IRQ_LOCALWDOG 30 +#include <linux/gpio.h> /* Shared Peripheral Interrupt (SHPI) */ #define IRQ_SHPI_START 32 @@ -22,27 +20,34 @@ * MTU0 preserved for now until plat-nomadik is taught not to use it. Don't * add any other IRQs here, use the irqs-dbx500.h files. */ -#define IRQ_MTU0 (IRQ_SHPI_START + 4) +#define IRQ_MTU0 (IRQ_SHPI_START + 4) + +#define IRQ_LOCALTIMER 29 +#define IRQ_LOCALWDOG 30 + +/*********************************************************************/ #define DBX500_NR_INTERNAL_IRQS 160 /* After chip-specific IRQ numbers we have the GPIO ones */ -#define NOMADIK_NR_GPIO 288 #define NOMADIK_GPIO_TO_IRQ(gpio) ((gpio) + DBX500_NR_INTERNAL_IRQS) #define NOMADIK_IRQ_TO_GPIO(irq) ((irq) - DBX500_NR_INTERNAL_IRQS) + +#define GPIO_TO_IRQ NOMADIK_GPIO_TO_IRQ +#define IRQ_TO_GPIO NOMADIK_IRQ_TO_GPIO #define IRQ_GPIO_END NOMADIK_GPIO_TO_IRQ(NOMADIK_NR_GPIO) -#define IRQ_SOC_START IRQ_GPIO_END +#define IRQ_SOC_START IRQ_GPIO_END /* This will be overridden by SoC-specific irq headers */ -#define IRQ_SOC_END IRQ_SOC_START +#define IRQ_SOC_END IRQ_SOC_START + +#define IRQ_BOARD_START IRQ_SOC_END +/* This will be overridden by board-specific irq headers */ +#define IRQ_BOARD_END IRQ_BOARD_START #include <mach/irqs-db5500.h> #include <mach/irqs-db8500.h> -#define IRQ_BOARD_START IRQ_SOC_END -/* This will be overridden by board-specific irq headers */ -#define IRQ_BOARD_END IRQ_BOARD_START - #ifdef CONFIG_MACH_U8500 #include <mach/irqs-board-mop500.h> #endif @@ -51,6 +56,8 @@ #include <mach/irqs-board-u5500.h> #endif +#ifndef NR_IRQS #define NR_IRQS IRQ_BOARD_END +#endif #endif /* ASM_ARCH_IRQS_H */ diff --git a/arch/arm/mach-ux500/include/mach/memory.h b/arch/arm/mach-ux500/include/mach/memory.h index 2ef697a6700..ada8ad0c2d8 100644 --- a/arch/arm/mach-ux500/include/mach/memory.h +++ b/arch/arm/mach-ux500/include/mach/memory.h @@ -15,4 +15,12 @@ #define PLAT_PHYS_OFFSET UL(0x00000000) #define BUS_OFFSET UL(0x00000000) +#ifdef CONFIG_UX500_SOC_DB8500 +/* + * STE NMF CM driver only used on the U8500 allocate using dma_alloc_coherent: + * 8M for SIA and SVA data + 2M for SIA code + 2M for SVA code + */ +#define CONSISTENT_DMA_SIZE SZ_16M +#endif + #endif diff --git a/arch/arm/mach-ux500/include/mach/reboot_reasons.h b/arch/arm/mach-ux500/include/mach/reboot_reasons.h new file mode 100644 index 00000000000..2c21aab58c4 --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/reboot_reasons.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) ST-Ericsson SA 2011 + * Author: Rickard Evertsson <rickard.evertsson@stericsson.com> + * for ST-Ericsson. + * + * License terms: GNU General Public License (GPL) version 2 + * + * Use this file to customize your reboot / sw reset reasons. Add, remove or + * modify reasons in reboot_reasons[]. + * The reboot reasons will be saved to a secure location in TCDM memory and + * can be read at bootup by e.g. the bootloader, or at a later stage userspace + * since the code is exposed through sysfs. + */ + +#ifndef _REBOOT_REASONS_H +#define _REBOOT_REASONS_H + +/* + * These defines contains the codes that will be written down to a secure + * location before resetting. These values are exposed through a sysfs + * entry under /sys/socinfo, see mach-ux500/cpu-db8500.c + */ +#define SW_RESET_NO_ARGUMENT 0xBEEF +#define SW_RESET_FACTORY_RESET 0x4242 +#define SW_RESET_CRASH 0xDEAD +#define SW_RESET_NORMAL 0xc001 +#define SW_RESET_CHARGING 0xCAFE +#define SW_RESET_COLDSTART 0x0 +#define SW_RESET_RECOVERY 0x5502 + +/* + * The array reboot_reasons[] is used when you want to map a string to a reboot + * reason code + */ +struct reboot_reason { + const char *reason; + u16 code; +}; + +extern struct reboot_reason reboot_reasons[]; + +extern unsigned int reboot_reasons_size; + +u16 reboot_reason_code(const char *cmd); +const char *reboot_reason_string(u16 code); + +#endif diff --git a/arch/arm/mach-ux500/include/mach/sensors1p.h b/arch/arm/mach-ux500/include/mach/sensors1p.h new file mode 100644 index 00000000000..544e1d8bab5 --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/sensors1p.h @@ -0,0 +1,24 @@ + +/* + * Copyright (C) 2009-2010 ST-Ericsson AB + * License terms: GNU General Public License (GPL) version 2 + * Header file for 1 pin gpio sensors; + * Author: Jonas Aaberg <jonas.aberg@stericsson.com> + * + */ + +#ifndef __ASM_ARCH_SFH7741_H +#define __ASM_ARCH_SFH7741_H + +struct sensor_config { + int pin; + int startup_time; /* in ms */ + char regulator[32]; +}; + +struct sensors1p_config { + struct sensor_config hal; + struct sensor_config proximity; +}; + +#endif diff --git a/arch/arm/mach-ux500/include/mach/setup.h b/arch/arm/mach-ux500/include/mach/setup.h index a7d363fdb4c..cfb37baaa6f 100644 --- a/arch/arm/mach-ux500/include/mach/setup.h +++ b/arch/arm/mach-ux500/include/mach/setup.h @@ -18,6 +18,7 @@ void __init ux500_map_io(void); extern void __init u5500_map_io(void); extern void __init u8500_map_io(void); +extern void __init ux500_init_devices(void); extern void __init u5500_init_devices(void); extern void __init u8500_init_devices(void); @@ -26,6 +27,7 @@ extern void __init ux500_init_irq(void); extern void __init u5500_sdi_init(void); extern void __init db5500_dma_init(void); +extern void __init db8500_dma_init(void); /* We re-use nomadik_timer for this platform */ extern void nmdk_timer_init(void); diff --git a/arch/arm/mach-ux500/ste-dma40-db5500.h b/arch/arm/mach-ux500/include/mach/ste-dma40-db5500.h index cb2110c3285..0ddd4ab9020 100644 --- a/arch/arm/mach-ux500/ste-dma40-db5500.h +++ b/arch/arm/mach-ux500/include/mach/ste-dma40-db5500.h @@ -42,7 +42,9 @@ enum dma_src_dev_type { DB5500_DMA_DEV26_SDMMC2_RX = 26, DB5500_DMA_DEV27_SDMMC3_RX = 27, DB5500_DMA_DEV28_SDMMC4_RX = 28, - /* 29 - 32 not used */ + /* 29, 30 not used */ + DB5500_DMA_DEV31_CRYPTO1_RX = 31, /* v2 */ + /* 32 not used */ DB5500_DMA_DEV33_SDMMC0_RX = 33, DB5500_DMA_DEV34_SDMMC1_RX = 34, DB5500_DMA_DEV35_SDMMC2_RX = 35, @@ -56,7 +58,7 @@ enum dma_src_dev_type { DB5500_DMA_DEV43_USB_OTG_IEP_5_13 = 43, DB5500_DMA_DEV44_USB_OTG_IEP_6_14 = 44, DB5500_DMA_DEV45_USB_OTG_IEP_7_15 = 45, - /* 46 not used */ + DB5500_DMA_DEV46_CRYPTO1_RX = 46, /* v2 */ DB5500_DMA_DEV47_MCDE_RX = 47, DB5500_DMA_DEV48_CRYPTO1_RX = 48, /* 49, 50 not used */ @@ -98,7 +100,9 @@ enum dma_dest_dev_type { DB5500_DMA_DEV26_SDMMC2_TX = 26, DB5500_DMA_DEV27_SDMMC3_TX = 27, DB5500_DMA_DEV28_SDMMC4_TX = 28, - /* 29 - 31 not used */ + /* 29 not used */ + DB5500_DMA_DEV30_HASH1_TX = 30, /* v2 */ + DB5500_DMA_DEV31_CRYPTO1_TX = 31, /* v2 */ DB5500_DMA_DEV32_FSMC_TX = 32, DB5500_DMA_DEV33_SDMMC0_TX = 33, DB5500_DMA_DEV34_SDMMC1_TX = 34, @@ -113,7 +117,7 @@ enum dma_dest_dev_type { DB5500_DMA_DEV43_USB_OTG_OEP_5_13 = 43, DB5500_DMA_DEV44_USB_OTG_OEP_6_14 = 44, DB5500_DMA_DEV45_USB_OTG_OEP_7_15 = 45, - /* 46 not used */ + DB5500_DMA_DEV46_CRYPTO1_TX = 46, /* v2 */ DB5500_DMA_DEV47_STM_TX = 47, DB5500_DMA_DEV48_CRYPTO1_TX = 48, DB5500_DMA_DEV49_CRYPTO1_TX_HASH1_TX = 49, diff --git a/arch/arm/mach-ux500/ste-dma40-db8500.h b/arch/arm/mach-ux500/include/mach/ste-dma40-db8500.h index a616419bea7..65799a75199 100644 --- a/arch/arm/mach-ux500/ste-dma40-db8500.h +++ b/arch/arm/mach-ux500/include/mach/ste-dma40-db8500.h @@ -1,16 +1,19 @@ /* - * arch/arm/mach-ux500/ste_dma40_db8500.h - * DB8500-SoC-specific configuration for DMA40 - * - * Copyright (C) ST-Ericsson 2007-2010 + * Copyright (C) ST-Ericsson SA 2007-2010 + * Author: Per Friden <per.friden@stericsson.com> for ST-Ericsson + * Author: Jonas Aaberg <jonas.aberg@stericsson.com> for ST-Ericsson * License terms: GNU General Public License (GPL) version 2 - * Author: Per Friden <per.friden@stericsson.com> - * Author: Jonas Aaberg <jonas.aberg@stericsson.com> + * + * DB8500-SoC-specific configuration for DMA40 */ #ifndef STE_DMA40_DB8500_H #define STE_DMA40_DB8500_H #define DB8500_DMA_NR_DEV 64 +/* + * All entries with double names are multiplexed + * and can never be used at the same time. + */ enum dma_src_dev_type { DB8500_DMA_DEV0_SPI0_RX = 0, @@ -20,7 +23,7 @@ enum dma_src_dev_type { DB8500_DMA_DEV4_I2C1_RX = 4, DB8500_DMA_DEV5_I2C3_RX = 5, DB8500_DMA_DEV6_I2C2_RX = 6, - DB8500_DMA_DEV7_I2C4_RX = 7, /* Only on V1 and later */ + DB8500_DMA_DEV7_I2C4_RX = 7, DB8500_DMA_DEV8_SSP0_RX = 8, DB8500_DMA_DEV9_SSP1_RX = 9, DB8500_DMA_DEV10_MCDE_RX = 10, @@ -43,8 +46,6 @@ enum dma_src_dev_type { DB8500_DMA_DEV27_SRC_SXA3_RX_TX = 27, DB8500_DMA_DEV28_SD_MM2_RX = 28, DB8500_DMA_DEV29_SD_MM0_RX = 29, - DB8500_DMA_DEV30_MSP1_RX = 30, - /* On DB8500v2, MSP3 RX replaces MSP1 RX */ DB8500_DMA_DEV30_MSP3_RX = 30, DB8500_DMA_DEV31_MSP0_RX_SLIM0_CH0_RX = 31, DB8500_DMA_DEV32_SD_MM1_RX = 32, @@ -82,7 +83,7 @@ enum dma_dest_dev_type { DB8500_DMA_DEV4_I2C1_TX = 4, DB8500_DMA_DEV5_I2C3_TX = 5, DB8500_DMA_DEV6_I2C2_TX = 6, - DB8500_DMA_DEV7_I2C4_TX = 7, /* Only on V1 and later */ + DB8500_DMA_DEV7_I2C4_TX = 7, DB8500_DMA_DEV8_SSP0_TX = 8, DB8500_DMA_DEV9_SSP1_TX = 9, /* 10 is not used*/ diff --git a/arch/arm/mach-ux500/include/mach/system.h b/arch/arm/mach-ux500/include/mach/system.h index c0cd8006f1a..42bc8c72a79 100644 --- a/arch/arm/mach-ux500/include/mach/system.h +++ b/arch/arm/mach-ux500/include/mach/system.h @@ -8,6 +8,9 @@ #ifndef __ASM_ARCH_SYSTEM_H #define __ASM_ARCH_SYSTEM_H +#include <linux/mfd/dbx500-prcmu.h> +#include <mach/reboot_reasons.h> + static inline void arch_idle(void) { /* @@ -19,7 +22,10 @@ static inline void arch_idle(void) static inline void arch_reset(char mode, const char *cmd) { - /* yet to be implemented - TODO */ +#ifdef CONFIG_UX500_SOC_DB8500 + /* Call the PRCMU reset API (w/o reset reason code) */ + prcmu_system_reset(SW_RESET_NO_ARGUMENT); +#endif } #endif diff --git a/arch/arm/mach-ux500/include/mach/timex.h b/arch/arm/mach-ux500/include/mach/timex.h index d0942c17401..0ba497bd9d7 100644 --- a/arch/arm/mach-ux500/include/mach/timex.h +++ b/arch/arm/mach-ux500/include/mach/timex.h @@ -2,5 +2,6 @@ #define __ASM_ARCH_TIMEX_H #define CLOCK_TICK_RATE 110000000 +#define ARCH_HAS_READ_CURRENT_TIMER #endif diff --git a/arch/arm/mach-ux500/include/mach/uncompress.h b/arch/arm/mach-ux500/include/mach/uncompress.h index 7dd08074c37..894f7d23f06 100644 --- a/arch/arm/mach-ux500/include/mach/uncompress.h +++ b/arch/arm/mach-ux500/include/mach/uncompress.h @@ -52,8 +52,6 @@ static inline void arch_decomp_setup(void) { /* Check in run time if we run on an U8500 or U5500 */ if (machine_is_u8500() || - machine_is_svp8500v1() || - machine_is_svp8500v2() || machine_is_hrefv60() || machine_is_snowball()) ux500_uart_base = U8500_UART2_BASE; diff --git a/arch/arm/mach-ux500/include/mach/vmalloc.h b/arch/arm/mach-ux500/include/mach/vmalloc.h index a4945cb4117..e0c6c408552 100644 --- a/arch/arm/mach-ux500/include/mach/vmalloc.h +++ b/arch/arm/mach-ux500/include/mach/vmalloc.h @@ -15,4 +15,4 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#define VMALLOC_END 0xf0000000UL +#define VMALLOC_END 0xf7800000UL diff --git a/arch/arm/mach-ux500/l2x0-prefetch.c b/arch/arm/mach-ux500/l2x0-prefetch.c new file mode 100644 index 00000000000..48a4495533f --- /dev/null +++ b/arch/arm/mach-ux500/l2x0-prefetch.c @@ -0,0 +1,160 @@ +/* + * Copyright (C) ST-Ericsson SA 2011 + * + * Author: Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com> + * License terms: GNU General Public License (GPL) version 2 + */ + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/tee.h> +#include <linux/io.h> +#include <mach/hardware.h> +#include <asm/hardware/cache-l2x0.h> + +static struct tee_session session; +static struct tee_context context; +static void __iomem *l2x0_base; + +#define L2X0_PREFETCH_CTRL_REG (0x00000F60) +#define L2X0_PREFETCH_CTRL_BIT_DATA_EN (1 << 28) +#define L2X0_PREFETCH_CTRL_BIT_INST_EN (1 << 29) + +#define L2X0_UUID_TEE_TA_START_LOW 0xBC765EDE +#define L2X0_UUID_TEE_TA_START_MID 0x6724 +#define L2X0_UUID_TEE_TA_START_HIGH 0x11DF +#define L2X0_UUID_TEE_TA_START_CLOCKSEQ \ + {0x8E, 0x12, 0xEC, 0xDB, 0xDF, 0xD7, 0x20, 0x85} + +static void prefetch_enable(void) +{ + struct tee_operation operation; + u32 data; + int err; + int origin_err; + + data = readl(l2x0_base + L2X0_PREFETCH_CTRL_REG); + + pr_debug("l2x0-prefetch: %s start, preftect_ctrl=0x%08x\n", __func__, + data); + if (!(data & L2X0_PREFETCH_CTRL_BIT_INST_EN) || + !(data & L2X0_PREFETCH_CTRL_BIT_DATA_EN)) { + + data |= (L2X0_PREFETCH_CTRL_BIT_INST_EN | + L2X0_PREFETCH_CTRL_BIT_DATA_EN); + + operation.shm[0].buffer = &data; + operation.shm[0].size = sizeof(data); + operation.shm[0].flags = TEEC_MEM_INPUT; + operation.flags = TEEC_MEMREF_0_USED; + + err = teec_invoke_command(&session, + TEE_STA_SET_L2CC_PREFETCH_CTRL_REGISTER, + &operation, &origin_err); + if (err) + pr_err("l2x0-prefetch: prefetch enable failed, err=%d", + err); + } + pr_debug("l2x0-prefetch: %s end, prefetch_ctrl=0x%08x\n", __func__, + readl(l2x0_base + L2X0_PREFETCH_CTRL_REG)); +} + +static void prefetch_disable(void) +{ + struct tee_operation operation; + u32 data; + int err; + int origin_err; + + data = readl(l2x0_base + L2X0_PREFETCH_CTRL_REG); + + pr_debug("l2x0-prefetch: %s start, preftect_ctrl=0x%08x\n", __func__, + data); + if (data & (L2X0_PREFETCH_CTRL_BIT_INST_EN | + L2X0_PREFETCH_CTRL_BIT_DATA_EN)) { + + data &= ~(L2X0_PREFETCH_CTRL_BIT_INST_EN | + L2X0_PREFETCH_CTRL_BIT_DATA_EN); + + operation.shm[0].buffer = &data; + operation.shm[0].size = sizeof(data); + operation.shm[0].flags = TEEC_MEM_INPUT; + operation.flags = TEEC_MEMREF_0_USED; + + err = teec_invoke_command(&session, + TEE_STA_SET_L2CC_PREFETCH_CTRL_REGISTER, + &operation, &origin_err); + if (err) + pr_err("l2x0-prefetch: prefetch disable failed, err=%d", + err); + } + pr_debug("l2x0-prefetch: %s end, prefetch_ctrl=0x%08x\n", __func__, + readl(l2x0_base + L2X0_PREFETCH_CTRL_REG)); +} + +static int __init prefetch_ctrl_init(void) +{ + int err; + int origin_err; + /* Selects trustzone application needed for the job. */ + struct tee_uuid static_uuid = { + L2X0_UUID_TEE_TA_START_LOW, + L2X0_UUID_TEE_TA_START_MID, + L2X0_UUID_TEE_TA_START_HIGH, + L2X0_UUID_TEE_TA_START_CLOCKSEQ, + }; + + /* Get PL310 base address. It will be used as readonly. */ + if (cpu_is_u5500()) + l2x0_base = __io_address(U5500_L2CC_BASE); + else if (cpu_is_u8500()) + l2x0_base = __io_address(U8500_L2CC_BASE); + else + ux500_unknown_soc(); + + err = teec_initialize_context(NULL, &context); + if (err) { + pr_err("l2x0-prefetch: unable to initialize tee context," + " err = %d\n", err); + err = -EINVAL; + goto error0; + } + + err = teec_open_session(&context, &session, &static_uuid, + TEEC_LOGIN_PUBLIC, NULL, NULL, &origin_err); + if (err) { + pr_err("l2x0-prefetch: unable to open tee session," + " tee error = %d, origin error = %d\n", + err, origin_err); + err = -EINVAL; + goto error1; + } + + outer_cache.prefetch_enable = prefetch_enable; + outer_cache.prefetch_disable = prefetch_disable; + + pr_info("l2x0-prefetch: initialized.\n"); + + return 0; + +error1: + (void)teec_finalize_context(&context); +error0: + return err; +} + +static void __exit prefetch_ctrl_exit(void) +{ + outer_cache.prefetch_enable = NULL; + outer_cache.prefetch_disable = NULL; + + (void)teec_close_session(&session); + (void)teec_finalize_context(&context); +} + +/* Wait for TEE driver to be initialized. */ +late_initcall(prefetch_ctrl_init); +module_exit(prefetch_ctrl_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("PL310 prefetch control"); diff --git a/arch/arm/mach-ux500/mbox-db5500.c b/arch/arm/mach-ux500/mbox-db5500.c deleted file mode 100644 index 2b2d51caf9d..00000000000 --- a/arch/arm/mach-ux500/mbox-db5500.c +++ /dev/null @@ -1,565 +0,0 @@ -/* - * Copyright (C) ST-Ericsson SA 2010 - * Author: Stefan Nilsson <stefan.xk.nilsson@stericsson.com> for ST-Ericsson. - * Author: Martin Persson <martin.persson@stericsson.com> for ST-Ericsson. - * License terms: GNU General Public License (GPL), version 2. - */ - -/* - * Mailbox nomenclature: - * - * APE MODEM - * mbox pairX - * .......................... - * . . - * . peer . - * . send ---- . - * . --> | | . - * . | | . - * . ---- . - * . . - * . local . - * . rec ---- . - * . | | <-- . - * . | | . - * . ---- . - * ......................... - */ - -#include <linux/init.h> -#include <linux/module.h> -#include <linux/device.h> -#include <linux/interrupt.h> -#include <linux/spinlock.h> -#include <linux/errno.h> -#include <linux/io.h> -#include <linux/irq.h> -#include <linux/platform_device.h> -#include <linux/debugfs.h> -#include <linux/seq_file.h> -#include <linux/completion.h> -#include <mach/mbox-db5500.h> - -#define MBOX_NAME "mbox" - -#define MBOX_FIFO_DATA 0x000 -#define MBOX_FIFO_ADD 0x004 -#define MBOX_FIFO_REMOVE 0x008 -#define MBOX_FIFO_THRES_FREE 0x00C -#define MBOX_FIFO_THRES_OCCUP 0x010 -#define MBOX_FIFO_STATUS 0x014 - -#define MBOX_DISABLE_IRQ 0x4 -#define MBOX_ENABLE_IRQ 0x0 -#define MBOX_LATCH 1 - -/* Global list of all mailboxes */ -static struct list_head mboxs = LIST_HEAD_INIT(mboxs); - -static struct mbox *get_mbox_with_id(u8 id) -{ - u8 i; - struct list_head *pos = &mboxs; - for (i = 0; i <= id; i++) - pos = pos->next; - - return (struct mbox *) list_entry(pos, struct mbox, list); -} - -int mbox_send(struct mbox *mbox, u32 mbox_msg, bool block) -{ - int res = 0; - - spin_lock(&mbox->lock); - - dev_dbg(&(mbox->pdev->dev), - "About to buffer 0x%X to mailbox 0x%X." - " ri = %d, wi = %d\n", - mbox_msg, (u32)mbox, mbox->read_index, - mbox->write_index); - - /* Check if write buffer is full */ - while (((mbox->write_index + 1) % MBOX_BUF_SIZE) == mbox->read_index) { - if (!block) { - dev_dbg(&(mbox->pdev->dev), - "Buffer full in non-blocking call! " - "Returning -ENOMEM!\n"); - res = -ENOMEM; - goto exit; - } - spin_unlock(&mbox->lock); - dev_dbg(&(mbox->pdev->dev), - "Buffer full in blocking call! Sleeping...\n"); - mbox->client_blocked = 1; - wait_for_completion(&mbox->buffer_available); - dev_dbg(&(mbox->pdev->dev), - "Blocking send was woken up! Trying again...\n"); - spin_lock(&mbox->lock); - } - - mbox->buffer[mbox->write_index] = mbox_msg; - mbox->write_index = (mbox->write_index + 1) % MBOX_BUF_SIZE; - - /* - * Indicate that we want an IRQ as soon as there is a slot - * in the FIFO - */ - writel(MBOX_ENABLE_IRQ, mbox->virtbase_peer + MBOX_FIFO_THRES_FREE); - -exit: - spin_unlock(&mbox->lock); - return res; -} -EXPORT_SYMBOL(mbox_send); - -#if defined(CONFIG_DEBUG_FS) -/* - * Expected input: <value> <nbr sends> - * Example: "echo 0xdeadbeef 4 > mbox-node" sends 0xdeadbeef 4 times - */ -static ssize_t mbox_write_fifo(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t count) -{ - unsigned long mbox_mess; - unsigned long nbr_sends; - unsigned long i; - char int_buf[16]; - char *token; - char *val; - - struct mbox *mbox = (struct mbox *) dev->platform_data; - - strncpy((char *) &int_buf, buf, sizeof(int_buf)); - token = (char *) &int_buf; - - /* Parse message */ - val = strsep(&token, " "); - if ((val == NULL) || (strict_strtoul(val, 16, &mbox_mess) != 0)) - mbox_mess = 0xDEADBEEF; - - val = strsep(&token, " "); - if ((val == NULL) || (strict_strtoul(val, 10, &nbr_sends) != 0)) - nbr_sends = 1; - - dev_dbg(dev, "Will write 0x%lX %ld times using data struct at 0x%X\n", - mbox_mess, nbr_sends, (u32) mbox); - - for (i = 0; i < nbr_sends; i++) - mbox_send(mbox, mbox_mess, true); - - return count; -} - -static ssize_t mbox_read_fifo(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int mbox_value; - struct mbox *mbox = (struct mbox *) dev->platform_data; - - if ((readl(mbox->virtbase_local + MBOX_FIFO_STATUS) & 0x7) <= 0) - return sprintf(buf, "Mailbox is empty\n"); - - mbox_value = readl(mbox->virtbase_local + MBOX_FIFO_DATA); - writel(MBOX_LATCH, (mbox->virtbase_local + MBOX_FIFO_REMOVE)); - - return sprintf(buf, "0x%X\n", mbox_value); -} - -static DEVICE_ATTR(fifo, S_IWUGO | S_IRUGO, mbox_read_fifo, mbox_write_fifo); - -static int mbox_show(struct seq_file *s, void *data) -{ - struct list_head *pos; - u8 mbox_index = 0; - - list_for_each(pos, &mboxs) { - struct mbox *m = - (struct mbox *) list_entry(pos, struct mbox, list); - if (m == NULL) { - seq_printf(s, - "Unable to retrieve mailbox %d\n", - mbox_index); - continue; - } - - spin_lock(&m->lock); - if ((m->virtbase_peer == NULL) || (m->virtbase_local == NULL)) { - seq_printf(s, "MAILBOX %d not setup or corrupt\n", - mbox_index); - spin_unlock(&m->lock); - continue; - } - - seq_printf(s, - "===========================\n" - " MAILBOX %d\n" - " PEER MAILBOX DUMP\n" - "---------------------------\n" - "FIFO: 0x%X (%d)\n" - "Free Threshold: 0x%.2X (%d)\n" - "Occupied Threshold: 0x%.2X (%d)\n" - "Status: 0x%.2X (%d)\n" - " Free spaces (ot): %d (%d)\n" - " Occup spaces (ot): %d (%d)\n" - "===========================\n" - " LOCAL MAILBOX DUMP\n" - "---------------------------\n" - "FIFO: 0x%.X (%d)\n" - "Free Threshold: 0x%.2X (%d)\n" - "Occupied Threshold: 0x%.2X (%d)\n" - "Status: 0x%.2X (%d)\n" - " Free spaces (ot): %d (%d)\n" - " Occup spaces (ot): %d (%d)\n" - "===========================\n" - "write_index: %d\n" - "read_index : %d\n" - "===========================\n" - "\n", - mbox_index, - readl(m->virtbase_peer + MBOX_FIFO_DATA), - readl(m->virtbase_peer + MBOX_FIFO_DATA), - readl(m->virtbase_peer + MBOX_FIFO_THRES_FREE), - readl(m->virtbase_peer + MBOX_FIFO_THRES_FREE), - readl(m->virtbase_peer + MBOX_FIFO_THRES_OCCUP), - readl(m->virtbase_peer + MBOX_FIFO_THRES_OCCUP), - readl(m->virtbase_peer + MBOX_FIFO_STATUS), - readl(m->virtbase_peer + MBOX_FIFO_STATUS), - (readl(m->virtbase_peer + MBOX_FIFO_STATUS) >> 4) & 0x7, - (readl(m->virtbase_peer + MBOX_FIFO_STATUS) >> 7) & 0x1, - (readl(m->virtbase_peer + MBOX_FIFO_STATUS) >> 0) & 0x7, - (readl(m->virtbase_peer + MBOX_FIFO_STATUS) >> 3) & 0x1, - readl(m->virtbase_local + MBOX_FIFO_DATA), - readl(m->virtbase_local + MBOX_FIFO_DATA), - readl(m->virtbase_local + MBOX_FIFO_THRES_FREE), - readl(m->virtbase_local + MBOX_FIFO_THRES_FREE), - readl(m->virtbase_local + MBOX_FIFO_THRES_OCCUP), - readl(m->virtbase_local + MBOX_FIFO_THRES_OCCUP), - readl(m->virtbase_local + MBOX_FIFO_STATUS), - readl(m->virtbase_local + MBOX_FIFO_STATUS), - (readl(m->virtbase_local + MBOX_FIFO_STATUS) >> 4) & 0x7, - (readl(m->virtbase_local + MBOX_FIFO_STATUS) >> 7) & 0x1, - (readl(m->virtbase_local + MBOX_FIFO_STATUS) >> 0) & 0x7, - (readl(m->virtbase_local + MBOX_FIFO_STATUS) >> 3) & 0x1, - m->write_index, m->read_index); - mbox_index++; - spin_unlock(&m->lock); - } - - return 0; -} - -static int mbox_open(struct inode *inode, struct file *file) -{ - return single_open(file, mbox_show, NULL); -} - -static const struct file_operations mbox_operations = { - .owner = THIS_MODULE, - .open = mbox_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; -#endif - -static irqreturn_t mbox_irq(int irq, void *arg) -{ - u32 mbox_value; - int nbr_occup; - int nbr_free; - struct mbox *mbox = (struct mbox *) arg; - - spin_lock(&mbox->lock); - - dev_dbg(&(mbox->pdev->dev), - "mbox IRQ [%d] received. ri = %d, wi = %d\n", - irq, mbox->read_index, mbox->write_index); - - /* - * Check if we have any outgoing messages, and if there is space for - * them in the FIFO. - */ - if (mbox->read_index != mbox->write_index) { - /* - * Check by reading FREE for LOCAL since that indicates - * OCCUP for PEER - */ - nbr_free = (readl(mbox->virtbase_local + MBOX_FIFO_STATUS) - >> 4) & 0x7; - dev_dbg(&(mbox->pdev->dev), - "Status indicates %d empty spaces in the FIFO!\n", - nbr_free); - - while ((nbr_free > 0) && - (mbox->read_index != mbox->write_index)) { - /* Write the message and latch it into the FIFO */ - writel(mbox->buffer[mbox->read_index], - (mbox->virtbase_peer + MBOX_FIFO_DATA)); - writel(MBOX_LATCH, - (mbox->virtbase_peer + MBOX_FIFO_ADD)); - dev_dbg(&(mbox->pdev->dev), - "Wrote message 0x%X to addr 0x%X\n", - mbox->buffer[mbox->read_index], - (u32) (mbox->virtbase_peer + MBOX_FIFO_DATA)); - - nbr_free--; - mbox->read_index = - (mbox->read_index + 1) % MBOX_BUF_SIZE; - } - - /* - * Check if we still want IRQ:s when there is free - * space to send - */ - if (mbox->read_index != mbox->write_index) { - dev_dbg(&(mbox->pdev->dev), - "Still have messages to send, but FIFO full. " - "Request IRQ again!\n"); - writel(MBOX_ENABLE_IRQ, - mbox->virtbase_peer + MBOX_FIFO_THRES_FREE); - } else { - dev_dbg(&(mbox->pdev->dev), - "No more messages to send. " - "Do not request IRQ again!\n"); - writel(MBOX_DISABLE_IRQ, - mbox->virtbase_peer + MBOX_FIFO_THRES_FREE); - } - - /* - * Check if we can signal any blocked clients that it is OK to - * start buffering again - */ - if (mbox->client_blocked && - (((mbox->write_index + 1) % MBOX_BUF_SIZE) - != mbox->read_index)) { - dev_dbg(&(mbox->pdev->dev), - "Waking up blocked client\n"); - complete(&mbox->buffer_available); - mbox->client_blocked = 0; - } - } - - /* Check if we have any incoming messages */ - nbr_occup = readl(mbox->virtbase_local + MBOX_FIFO_STATUS) & 0x7; - if (nbr_occup == 0) - goto exit; - - if (mbox->cb == NULL) { - dev_dbg(&(mbox->pdev->dev), "No receive callback registered, " - "leaving %d incoming messages in fifo!\n", nbr_occup); - goto exit; - } - - /* Read and acknowledge the message */ - mbox_value = readl(mbox->virtbase_local + MBOX_FIFO_DATA); - writel(MBOX_LATCH, (mbox->virtbase_local + MBOX_FIFO_REMOVE)); - - /* Notify consumer of new mailbox message */ - dev_dbg(&(mbox->pdev->dev), "Calling callback for message 0x%X!\n", - mbox_value); - mbox->cb(mbox_value, mbox->client_data); - -exit: - dev_dbg(&(mbox->pdev->dev), "Exit mbox IRQ. ri = %d, wi = %d\n", - mbox->read_index, mbox->write_index); - spin_unlock(&mbox->lock); - - return IRQ_HANDLED; -} - -/* Setup is executed once for each mbox pair */ -struct mbox *mbox_setup(u8 mbox_id, mbox_recv_cb_t *mbox_cb, void *priv) -{ - struct resource *resource; - int irq; - int res; - struct mbox *mbox; - - mbox = get_mbox_with_id(mbox_id); - if (mbox == NULL) { - dev_err(&(mbox->pdev->dev), "Incorrect mailbox id: %d!\n", - mbox_id); - goto exit; - } - - /* - * Check if mailbox has been allocated to someone else, - * otherwise allocate it - */ - if (mbox->allocated) { - dev_err(&(mbox->pdev->dev), "Mailbox number %d is busy!\n", - mbox_id); - mbox = NULL; - goto exit; - } - mbox->allocated = true; - - dev_dbg(&(mbox->pdev->dev), "Initiating mailbox number %d: 0x%X...\n", - mbox_id, (u32)mbox); - - mbox->client_data = priv; - mbox->cb = mbox_cb; - - /* Get addr for peer mailbox and ioremap it */ - resource = platform_get_resource_byname(mbox->pdev, - IORESOURCE_MEM, - "mbox_peer"); - if (resource == NULL) { - dev_err(&(mbox->pdev->dev), - "Unable to retrieve mbox peer resource\n"); - mbox = NULL; - goto exit; - } - dev_dbg(&(mbox->pdev->dev), - "Resource name: %s start: 0x%X, end: 0x%X\n", - resource->name, resource->start, resource->end); - mbox->virtbase_peer = ioremap(resource->start, resource_size(resource)); - if (!mbox->virtbase_peer) { - dev_err(&(mbox->pdev->dev), "Unable to ioremap peer mbox\n"); - mbox = NULL; - goto exit; - } - dev_dbg(&(mbox->pdev->dev), - "ioremapped peer physical: (0x%X-0x%X) to virtual: 0x%X\n", - resource->start, resource->end, (u32) mbox->virtbase_peer); - - /* Get addr for local mailbox and ioremap it */ - resource = platform_get_resource_byname(mbox->pdev, - IORESOURCE_MEM, - "mbox_local"); - if (resource == NULL) { - dev_err(&(mbox->pdev->dev), - "Unable to retrieve mbox local resource\n"); - mbox = NULL; - goto exit; - } - dev_dbg(&(mbox->pdev->dev), - "Resource name: %s start: 0x%X, end: 0x%X\n", - resource->name, resource->start, resource->end); - mbox->virtbase_local = ioremap(resource->start, resource_size(resource)); - if (!mbox->virtbase_local) { - dev_err(&(mbox->pdev->dev), "Unable to ioremap local mbox\n"); - mbox = NULL; - goto exit; - } - dev_dbg(&(mbox->pdev->dev), - "ioremapped local physical: (0x%X-0x%X) to virtual: 0x%X\n", - resource->start, resource->end, (u32) mbox->virtbase_peer); - - init_completion(&mbox->buffer_available); - mbox->client_blocked = 0; - - /* Get IRQ for mailbox and allocate it */ - irq = platform_get_irq_byname(mbox->pdev, "mbox_irq"); - if (irq < 0) { - dev_err(&(mbox->pdev->dev), - "Unable to retrieve mbox irq resource\n"); - mbox = NULL; - goto exit; - } - - dev_dbg(&(mbox->pdev->dev), "Allocating irq %d...\n", irq); - res = request_irq(irq, mbox_irq, 0, mbox->name, (void *) mbox); - if (res < 0) { - dev_err(&(mbox->pdev->dev), - "Unable to allocate mbox irq %d\n", irq); - mbox = NULL; - goto exit; - } - - /* Set up mailbox to not launch IRQ on free space in mailbox */ - writel(MBOX_DISABLE_IRQ, mbox->virtbase_peer + MBOX_FIFO_THRES_FREE); - - /* - * Set up mailbox to launch IRQ on new message if we have - * a callback set. If not, do not raise IRQ, but keep message - * in FIFO for manual retrieval - */ - if (mbox_cb != NULL) - writel(MBOX_ENABLE_IRQ, - mbox->virtbase_local + MBOX_FIFO_THRES_OCCUP); - else - writel(MBOX_DISABLE_IRQ, - mbox->virtbase_local + MBOX_FIFO_THRES_OCCUP); - -#if defined(CONFIG_DEBUG_FS) - res = device_create_file(&(mbox->pdev->dev), &dev_attr_fifo); - if (res != 0) - dev_warn(&(mbox->pdev->dev), - "Unable to create mbox sysfs entry"); - - (void) debugfs_create_file("mbox", S_IFREG | S_IRUGO, NULL, - NULL, &mbox_operations); -#endif - - dev_info(&(mbox->pdev->dev), - "Mailbox driver with index %d initiated!\n", mbox_id); - -exit: - return mbox; -} -EXPORT_SYMBOL(mbox_setup); - - -int __init mbox_probe(struct platform_device *pdev) -{ - struct mbox local_mbox; - struct mbox *mbox; - int res = 0; - dev_dbg(&(pdev->dev), "Probing mailbox (pdev = 0x%X)...\n", (u32) pdev); - - memset(&local_mbox, 0x0, sizeof(struct mbox)); - - /* Associate our mbox data with the platform device */ - res = platform_device_add_data(pdev, - (void *) &local_mbox, - sizeof(struct mbox)); - if (res != 0) { - dev_err(&(pdev->dev), - "Unable to allocate driver platform data!\n"); - goto exit; - } - - mbox = (struct mbox *) pdev->dev.platform_data; - mbox->pdev = pdev; - mbox->write_index = 0; - mbox->read_index = 0; - - INIT_LIST_HEAD(&(mbox->list)); - list_add_tail(&(mbox->list), &mboxs); - - sprintf(mbox->name, "%s", MBOX_NAME); - spin_lock_init(&mbox->lock); - - dev_info(&(pdev->dev), "Mailbox driver loaded\n"); - -exit: - return res; -} - -static struct platform_driver mbox_driver = { - .driver = { - .name = MBOX_NAME, - .owner = THIS_MODULE, - }, -}; - -static int __init mbox_init(void) -{ - return platform_driver_probe(&mbox_driver, mbox_probe); -} - -module_init(mbox_init); - -void __exit mbox_exit(void) -{ - platform_driver_unregister(&mbox_driver); -} - -module_exit(mbox_exit); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("MBOX driver"); diff --git a/arch/arm/mach-ux500/pins-db8500.h b/arch/arm/mach-ux500/pins-db8500.h index f923764ee16..062c7acf457 100644 --- a/arch/arm/mach-ux500/pins-db8500.h +++ b/arch/arm/mach-ux500/pins-db8500.h @@ -35,40 +35,40 @@ #define GPIO4_GPIO PIN_CFG(4, GPIO) #define GPIO4_U1_RXD PIN_CFG(4, ALT_A) -#define GPIO4_I2C4_SCL PIN_CFG_PULL(4, ALT_B, UP) +#define GPIO4_I2C4_SCL PIN_CFG(4, ALT_B) #define GPIO4_IP_TRSTn PIN_CFG(4, ALT_C) #define GPIO5_GPIO PIN_CFG(5, GPIO) #define GPIO5_U1_TXD PIN_CFG(5, ALT_A) -#define GPIO5_I2C4_SDA PIN_CFG_PULL(5, ALT_B, UP) +#define GPIO5_I2C4_SDA PIN_CFG(5, ALT_B) #define GPIO5_IP_GPIO6 PIN_CFG(5, ALT_C) #define GPIO6_GPIO PIN_CFG(6, GPIO) #define GPIO6_U1_CTSn PIN_CFG(6, ALT_A) -#define GPIO6_I2C1_SCL PIN_CFG_PULL(6, ALT_B, UP) +#define GPIO6_I2C1_SCL PIN_CFG(6, ALT_B) #define GPIO6_IP_GPIO0 PIN_CFG(6, ALT_C) #define GPIO7_GPIO PIN_CFG(7, GPIO) #define GPIO7_U1_RTSn PIN_CFG(7, ALT_A) -#define GPIO7_I2C1_SDA PIN_CFG_PULL(7, ALT_B, UP) +#define GPIO7_I2C1_SDA PIN_CFG(7, ALT_B) #define GPIO7_IP_GPIO1 PIN_CFG(7, ALT_C) #define GPIO8_GPIO PIN_CFG(8, GPIO) -#define GPIO8_IPI2C_SDA PIN_CFG_PULL(8, ALT_A, UP) -#define GPIO8_I2C2_SDA PIN_CFG_PULL(8, ALT_B, UP) +#define GPIO8_IPI2C_SDA PIN_CFG(8, ALT_A) +#define GPIO8_I2C2_SDA PIN_CFG(8, ALT_B) #define GPIO9_GPIO PIN_CFG(9, GPIO) -#define GPIO9_IPI2C_SCL PIN_CFG_PULL(9, ALT_A, UP) -#define GPIO9_I2C2_SCL PIN_CFG_PULL(9, ALT_B, UP) +#define GPIO9_IPI2C_SCL PIN_CFG(9, ALT_A) +#define GPIO9_I2C2_SCL PIN_CFG(9, ALT_B) #define GPIO10_GPIO PIN_CFG(10, GPIO) -#define GPIO10_IPI2C_SDA PIN_CFG_PULL(10, ALT_A, UP) -#define GPIO10_I2C2_SDA PIN_CFG_PULL(10, ALT_B, UP) +#define GPIO10_IPI2C_SDA PIN_CFG(10, ALT_A) +#define GPIO10_I2C2_SDA PIN_CFG(10, ALT_B) #define GPIO10_IP_GPIO3 PIN_CFG(10, ALT_C) #define GPIO11_GPIO PIN_CFG(11, GPIO) -#define GPIO11_IPI2C_SCL PIN_CFG_PULL(11, ALT_A, UP) -#define GPIO11_I2C2_SCL PIN_CFG_PULL(11, ALT_B, UP) +#define GPIO11_IPI2C_SCL PIN_CFG(11, ALT_A) +#define GPIO11_I2C2_SCL PIN_CFG(11, ALT_B) #define GPIO11_IP_GPIO2 PIN_CFG(11, ALT_C) #define GPIO12_GPIO PIN_CFG(12, GPIO) @@ -87,66 +87,66 @@ #define GPIO16_GPIO PIN_CFG(16, GPIO) #define GPIO16_MSP0_RFS PIN_CFG(16, ALT_A) -#define GPIO16_I2C1_SCL PIN_CFG_PULL(16, ALT_B, UP) +#define GPIO16_I2C1_SCL PIN_CFG(16, ALT_B) #define GPIO16_SLIM0_DAT PIN_CFG(16, ALT_C) #define GPIO17_GPIO PIN_CFG(17, GPIO) #define GPIO17_MSP0_RCK PIN_CFG(17, ALT_A) -#define GPIO17_I2C1_SDA PIN_CFG_PULL(17, ALT_B, UP) +#define GPIO17_I2C1_SDA PIN_CFG(17, ALT_B) #define GPIO17_SLIM0_CLK PIN_CFG(17, ALT_C) #define GPIO18_GPIO PIN_CFG(18, GPIO) -#define GPIO18_MC0_CMDDIR PIN_CFG_PULL(18, ALT_A, UP) +#define GPIO18_MC0_CMDDIR PIN_CFG_INPUT(18, ALT_A, PULLUP) #define GPIO18_U2_RXD PIN_CFG(18, ALT_B) #define GPIO18_MS_IEP PIN_CFG(18, ALT_C) #define GPIO19_GPIO PIN_CFG(19, GPIO) -#define GPIO19_MC0_DAT0DIR PIN_CFG_PULL(19, ALT_A, UP) +#define GPIO19_MC0_DAT0DIR PIN_CFG_INPUT(19, ALT_A, PULLUP) #define GPIO19_U2_TXD PIN_CFG(19, ALT_B) #define GPIO19_MS_DAT0DIR PIN_CFG(19, ALT_C) #define GPIO20_GPIO PIN_CFG(20, GPIO) -#define GPIO20_MC0_DAT2DIR PIN_CFG_PULL(20, ALT_A, UP) +#define GPIO20_MC0_DAT2DIR PIN_CFG_INPUT(20, ALT_A, PULLUP) #define GPIO20_UARTMOD_TXD PIN_CFG(20, ALT_B) #define GPIO20_IP_TRIGOUT PIN_CFG(20, ALT_C) #define GPIO21_GPIO PIN_CFG(21, GPIO) -#define GPIO21_MC0_DAT31DIR PIN_CFG_PULL(21, ALT_A, UP) +#define GPIO21_MC0_DAT31DIR PIN_CFG_INPUT(21, ALT_A, PULLUP) #define GPIO21_MSP0_SCK PIN_CFG(21, ALT_B) #define GPIO21_MS_DAT31DIR PIN_CFG(21, ALT_C) #define GPIO22_GPIO PIN_CFG(22, GPIO) -#define GPIO22_MC0_FBCLK PIN_CFG_PULL(22, ALT_A, UP) +#define GPIO22_MC0_FBCLK PIN_CFG_INPUT(22, ALT_A, PULLUP) #define GPIO22_UARTMOD_RXD PIN_CFG(22, ALT_B) #define GPIO22_MS_FBCLK PIN_CFG(22, ALT_C) #define GPIO23_GPIO PIN_CFG(23, GPIO) -#define GPIO23_MC0_CLK PIN_CFG_PULL(23, ALT_A, UP) +#define GPIO23_MC0_CLK PIN_CFG_INPUT(23, ALT_A, PULLUP) #define GPIO23_STMMOD_CLK PIN_CFG(23, ALT_B) #define GPIO23_MS_CLK PIN_CFG(23, ALT_C) #define GPIO24_GPIO PIN_CFG(24, GPIO) -#define GPIO24_MC0_CMD PIN_CFG_PULL(24, ALT_A, UP) +#define GPIO24_MC0_CMD PIN_CFG_INPUT(24, ALT_A, PULLUP) #define GPIO24_UARTMOD_RXD PIN_CFG(24, ALT_B) #define GPIO24_MS_BS PIN_CFG(24, ALT_C) #define GPIO25_GPIO PIN_CFG(25, GPIO) -#define GPIO25_MC0_DAT0 PIN_CFG_PULL(25, ALT_A, UP) +#define GPIO25_MC0_DAT0 PIN_CFG_INPUT(25, ALT_A, PULLUP) #define GPIO25_STMMOD_DAT0 PIN_CFG(25, ALT_B) #define GPIO25_MS_DAT0 PIN_CFG(25, ALT_C) #define GPIO26_GPIO PIN_CFG(26, GPIO) -#define GPIO26_MC0_DAT1 PIN_CFG_PULL(26, ALT_A, UP) +#define GPIO26_MC0_DAT1 PIN_CFG_INPUT(26, ALT_A, PULLUP) #define GPIO26_STMMOD_DAT1 PIN_CFG(26, ALT_B) #define GPIO26_MS_DAT1 PIN_CFG(26, ALT_C) #define GPIO27_GPIO PIN_CFG(27, GPIO) -#define GPIO27_MC0_DAT2 PIN_CFG_PULL(27, ALT_A, UP) +#define GPIO27_MC0_DAT2 PIN_CFG_INPUT(27, ALT_A, PULLUP) #define GPIO27_STMMOD_DAT2 PIN_CFG(27, ALT_B) #define GPIO27_MS_DAT2 PIN_CFG(27, ALT_C) #define GPIO28_GPIO PIN_CFG(28, GPIO) -#define GPIO28_MC0_DAT3 PIN_CFG_PULL(28, ALT_A, UP) +#define GPIO28_MC0_DAT3 PIN_CFG_INPUT(28, ALT_A, PULLUP) #define GPIO28_STMMOD_DAT3 PIN_CFG(28, ALT_B) #define GPIO28_MS_DAT3 PIN_CFG(28, ALT_C) @@ -357,48 +357,48 @@ #define GPIO97_MC5_DAT7 PIN_CFG(97, ALT_C) #define GPIO128_GPIO PIN_CFG(128, GPIO) -#define GPIO128_MC2_CLK PIN_CFG_PULL(128, ALT_A, UP) +#define GPIO128_MC2_CLK PIN_CFG_INPUT(128, ALT_A, PULLUP) #define GPIO128_SM_CKO PIN_CFG(128, ALT_B) #define GPIO129_GPIO PIN_CFG(129, GPIO) -#define GPIO129_MC2_CMD PIN_CFG_PULL(129, ALT_A, UP) +#define GPIO129_MC2_CMD PIN_CFG_INPUT(129, ALT_A, PULLUP) #define GPIO129_SM_WAIT0n PIN_CFG(129, ALT_B) #define GPIO130_GPIO PIN_CFG(130, GPIO) -#define GPIO130_MC2_FBCLK PIN_CFG_PULL(130, ALT_A, UP) +#define GPIO130_MC2_FBCLK PIN_CFG_INPUT(130, ALT_A, PULLUP) #define GPIO130_SM_FBCLK PIN_CFG(130, ALT_B) #define GPIO130_MC2_RSTN PIN_CFG(130, ALT_C) #define GPIO131_GPIO PIN_CFG(131, GPIO) -#define GPIO131_MC2_DAT0 PIN_CFG_PULL(131, ALT_A, UP) +#define GPIO131_MC2_DAT0 PIN_CFG_INPUT(131, ALT_A, PULLUP) #define GPIO131_SM_ADQ8 PIN_CFG(131, ALT_B) #define GPIO132_GPIO PIN_CFG(132, GPIO) -#define GPIO132_MC2_DAT1 PIN_CFG_PULL(132, ALT_A, UP) +#define GPIO132_MC2_DAT1 PIN_CFG_INPUT(132, ALT_A, PULLUP) #define GPIO132_SM_ADQ9 PIN_CFG(132, ALT_B) #define GPIO133_GPIO PIN_CFG(133, GPIO) -#define GPIO133_MC2_DAT2 PIN_CFG_PULL(133, ALT_A, UP) +#define GPIO133_MC2_DAT2 PIN_CFG_INPUT(133, ALT_A, PULLUP) #define GPIO133_SM_ADQ10 PIN_CFG(133, ALT_B) #define GPIO134_GPIO PIN_CFG(134, GPIO) -#define GPIO134_MC2_DAT3 PIN_CFG_PULL(134, ALT_A, UP) +#define GPIO134_MC2_DAT3 PIN_CFG_INPUT(134, ALT_A, PULLUP) #define GPIO134_SM_ADQ11 PIN_CFG(134, ALT_B) #define GPIO135_GPIO PIN_CFG(135, GPIO) -#define GPIO135_MC2_DAT4 PIN_CFG_PULL(135, ALT_A, UP) +#define GPIO135_MC2_DAT4 PIN_CFG_INPUT(135, ALT_A, PULLUP) #define GPIO135_SM_ADQ12 PIN_CFG(135, ALT_B) #define GPIO136_GPIO PIN_CFG(136, GPIO) -#define GPIO136_MC2_DAT5 PIN_CFG_PULL(136, ALT_A, UP) +#define GPIO136_MC2_DAT5 PIN_CFG_INPUT(136, ALT_A, PULLUP) #define GPIO136_SM_ADQ13 PIN_CFG(136, ALT_B) #define GPIO137_GPIO PIN_CFG(137, GPIO) -#define GPIO137_MC2_DAT6 PIN_CFG_PULL(137, ALT_A, UP) +#define GPIO137_MC2_DAT6 PIN_CFG_INPUT(137, ALT_A, PULLUP) #define GPIO137_SM_ADQ14 PIN_CFG(137, ALT_B) #define GPIO138_GPIO PIN_CFG(138, GPIO) -#define GPIO138_MC2_DAT7 PIN_CFG_PULL(138, ALT_A, UP) +#define GPIO138_MC2_DAT7 PIN_CFG_INPUT(138, ALT_A, PULLUP) #define GPIO138_SM_ADQ15 PIN_CFG(138, ALT_B) #define GPIO139_GPIO PIN_CFG(139, GPIO) @@ -434,10 +434,10 @@ #define GPIO146_SSP0_TXD PIN_CFG(146, ALT_A) #define GPIO147_GPIO PIN_CFG(147, GPIO) -#define GPIO147_I2C0_SCL PIN_CFG_PULL(147, ALT_A, UP) +#define GPIO147_I2C0_SCL PIN_CFG(147, ALT_A) #define GPIO148_GPIO PIN_CFG(148, GPIO) -#define GPIO148_I2C0_SDA PIN_CFG_PULL(148, ALT_A, UP) +#define GPIO148_I2C0_SDA PIN_CFG(148, ALT_A) #define GPIO149_GPIO PIN_CFG(149, GPIO) #define GPIO149_IP_GPIO0 PIN_CFG(149, ALT_A) @@ -459,82 +459,82 @@ #define GPIO152_KP_O9 PIN_CFG(152, ALT_C) #define GPIO153_GPIO PIN_CFG(153, GPIO) -#define GPIO153_KP_I7 PIN_CFG_PULL(153, ALT_A, DOWN) +#define GPIO153_KP_I7 PIN_CFG(153, ALT_A) #define GPIO153_LCD_D24 PIN_CFG(153, ALT_B) #define GPIO153_U2_RXD PIN_CFG(153, ALT_C) #define GPIO154_GPIO PIN_CFG(154, GPIO) -#define GPIO154_KP_I6 PIN_CFG_PULL(154, ALT_A, DOWN) +#define GPIO154_KP_I6 PIN_CFG(154, ALT_A) #define GPIO154_LCD_D25 PIN_CFG(154, ALT_B) #define GPIO154_U2_TXD PIN_CFG(154, ALT_C) #define GPIO155_GPIO PIN_CFG(155, GPIO) -#define GPIO155_KP_I5 PIN_CFG_PULL(155, ALT_A, DOWN) +#define GPIO155_KP_I5 PIN_CFG(155, ALT_A) #define GPIO155_LCD_D26 PIN_CFG(155, ALT_B) #define GPIO155_STMAPE_CLK PIN_CFG(155, ALT_C) #define GPIO156_GPIO PIN_CFG(156, GPIO) -#define GPIO156_KP_I4 PIN_CFG_PULL(156, ALT_A, DOWN) +#define GPIO156_KP_I4 PIN_CFG(156, ALT_A) #define GPIO156_LCD_D27 PIN_CFG(156, ALT_B) #define GPIO156_STMAPE_DAT3 PIN_CFG(156, ALT_C) #define GPIO157_GPIO PIN_CFG(157, GPIO) -#define GPIO157_KP_O7 PIN_CFG_PULL(157, ALT_A, UP) +#define GPIO157_KP_O7 PIN_CFG(157, ALT_A) #define GPIO157_LCD_D28 PIN_CFG(157, ALT_B) #define GPIO157_STMAPE_DAT2 PIN_CFG(157, ALT_C) #define GPIO158_GPIO PIN_CFG(158, GPIO) -#define GPIO158_KP_O6 PIN_CFG_PULL(158, ALT_A, UP) +#define GPIO158_KP_O6 PIN_CFG(158, ALT_A) #define GPIO158_LCD_D29 PIN_CFG(158, ALT_B) #define GPIO158_STMAPE_DAT1 PIN_CFG(158, ALT_C) #define GPIO159_GPIO PIN_CFG(159, GPIO) -#define GPIO159_KP_O5 PIN_CFG_PULL(159, ALT_A, UP) +#define GPIO159_KP_O5 PIN_CFG(159, ALT_A) #define GPIO159_LCD_D30 PIN_CFG(159, ALT_B) #define GPIO159_STMAPE_DAT0 PIN_CFG(159, ALT_C) #define GPIO160_GPIO PIN_CFG(160, GPIO) -#define GPIO160_KP_O4 PIN_CFG_PULL(160, ALT_A, UP) +#define GPIO160_KP_O4 PIN_CFG(160, ALT_A) #define GPIO160_LCD_D31 PIN_CFG(160, ALT_B) #define GPIO160_NONE PIN_CFG(160, ALT_C) #define GPIO161_GPIO PIN_CFG(161, GPIO) -#define GPIO161_KP_I3 PIN_CFG_PULL(161, ALT_A, DOWN) +#define GPIO161_KP_I3 PIN_CFG(161, ALT_A) #define GPIO161_LCD_D32 PIN_CFG(161, ALT_B) #define GPIO161_UARTMOD_RXD PIN_CFG(161, ALT_C) #define GPIO162_GPIO PIN_CFG(162, GPIO) -#define GPIO162_KP_I2 PIN_CFG_PULL(162, ALT_A, DOWN) +#define GPIO162_KP_I2 PIN_CFG(162, ALT_A) #define GPIO162_LCD_D33 PIN_CFG(162, ALT_B) #define GPIO162_UARTMOD_TXD PIN_CFG(162, ALT_C) #define GPIO163_GPIO PIN_CFG(163, GPIO) -#define GPIO163_KP_I1 PIN_CFG_PULL(163, ALT_A, DOWN) +#define GPIO163_KP_I1 PIN_CFG(163, ALT_A) #define GPIO163_LCD_D34 PIN_CFG(163, ALT_B) #define GPIO163_STMMOD_CLK PIN_CFG(163, ALT_C) #define GPIO164_GPIO PIN_CFG(164, GPIO) -#define GPIO164_KP_I0 PIN_CFG_PULL(164, ALT_A, UP) +#define GPIO164_KP_I0 PIN_CFG(164, ALT_A) #define GPIO164_LCD_D35 PIN_CFG(164, ALT_B) #define GPIO164_STMMOD_DAT3 PIN_CFG(164, ALT_C) #define GPIO165_GPIO PIN_CFG(165, GPIO) -#define GPIO165_KP_O3 PIN_CFG_PULL(165, ALT_A, UP) +#define GPIO165_KP_O3 PIN_CFG(165, ALT_A) #define GPIO165_LCD_D36 PIN_CFG(165, ALT_B) #define GPIO165_STMMOD_DAT2 PIN_CFG(165, ALT_C) #define GPIO166_GPIO PIN_CFG(166, GPIO) -#define GPIO166_KP_O2 PIN_CFG_PULL(166, ALT_A, UP) +#define GPIO166_KP_O2 PIN_CFG(166, ALT_A) #define GPIO166_LCD_D37 PIN_CFG(166, ALT_B) #define GPIO166_STMMOD_DAT1 PIN_CFG(166, ALT_C) #define GPIO167_GPIO PIN_CFG(167, GPIO) -#define GPIO167_KP_O1 PIN_CFG_PULL(167, ALT_A, UP) +#define GPIO167_KP_O1 PIN_CFG(167, ALT_A) #define GPIO167_LCD_D38 PIN_CFG(167, ALT_B) #define GPIO167_STMMOD_DAT0 PIN_CFG(167, ALT_C) #define GPIO168_GPIO PIN_CFG(168, GPIO) -#define GPIO168_KP_O0 PIN_CFG_PULL(168, ALT_A, UP) +#define GPIO168_KP_O0 PIN_CFG(168, ALT_A) #define GPIO168_LCD_D39 PIN_CFG(168, ALT_B) #define GPIO168_NONE PIN_CFG(168, ALT_C) @@ -569,39 +569,39 @@ #define GPIO196_MSP2_RXD PIN_CFG(196, ALT_A) #define GPIO197_GPIO PIN_CFG(197, GPIO) -#define GPIO197_MC4_DAT3 PIN_CFG_PULL(197, ALT_A, UP) +#define GPIO197_MC4_DAT3 PIN_CFG_INPUT(197, ALT_A, PULLUP) #define GPIO198_GPIO PIN_CFG(198, GPIO) -#define GPIO198_MC4_DAT2 PIN_CFG_PULL(198, ALT_A, UP) +#define GPIO198_MC4_DAT2 PIN_CFG_INPUT(198, ALT_A, PULLUP) #define GPIO199_GPIO PIN_CFG(199, GPIO) -#define GPIO199_MC4_DAT1 PIN_CFG_PULL(199, ALT_A, UP) +#define GPIO199_MC4_DAT1 PIN_CFG_INPUT(199, ALT_A, PULLUP) #define GPIO200_GPIO PIN_CFG(200, GPIO) -#define GPIO200_MC4_DAT0 PIN_CFG_PULL(200, ALT_A, UP) +#define GPIO200_MC4_DAT0 PIN_CFG_INPUT(200, ALT_A, PULLUP) #define GPIO201_GPIO PIN_CFG(201, GPIO) -#define GPIO201_MC4_CMD PIN_CFG_PULL(201, ALT_A, UP) +#define GPIO201_MC4_CMD PIN_CFG_INPUT(201, ALT_A, PULLUP) #define GPIO202_GPIO PIN_CFG(202, GPIO) -#define GPIO202_MC4_FBCLK PIN_CFG_PULL(202, ALT_A, UP) +#define GPIO202_MC4_FBCLK PIN_CFG_INPUT(202, ALT_A, PULLUP) #define GPIO202_PWL PIN_CFG(202, ALT_B) #define GPIO202_MC4_RSTN PIN_CFG(202, ALT_C) #define GPIO203_GPIO PIN_CFG(203, GPIO) -#define GPIO203_MC4_CLK PIN_CFG_PULL(203, ALT_A, UP) +#define GPIO203_MC4_CLK PIN_CFG_INPUT(203, ALT_A, PULLUP) #define GPIO204_GPIO PIN_CFG(204, GPIO) -#define GPIO204_MC4_DAT7 PIN_CFG_PULL(204, ALT_A, UP) +#define GPIO204_MC4_DAT7 PIN_CFG_INPUT(204, ALT_A, PULLUP) #define GPIO205_GPIO PIN_CFG(205, GPIO) -#define GPIO205_MC4_DAT6 PIN_CFG_PULL(205, ALT_A, UP) +#define GPIO205_MC4_DAT6 PIN_CFG_INPUT(205, ALT_A, PULLUP) #define GPIO206_GPIO PIN_CFG(206, GPIO) -#define GPIO206_MC4_DAT5 PIN_CFG_PULL(206, ALT_A, UP) +#define GPIO206_MC4_DAT5 PIN_CFG_INPUT(206, ALT_A, PULLUP) #define GPIO207_GPIO PIN_CFG(207, GPIO) -#define GPIO207_MC4_DAT4 PIN_CFG_PULL(207, ALT_A, UP) +#define GPIO207_MC4_DAT4 PIN_CFG_INPUT(207, ALT_A, PULLUP) #define GPIO208_GPIO PIN_CFG(208, GPIO) #define GPIO208_MC1_CLK PIN_CFG(208, ALT_A) @@ -632,21 +632,25 @@ #define GPIO215_MC1_CMDDIR PIN_CFG(215, ALT_A) #define GPIO215_MC3_DAT2DIR PIN_CFG(215, ALT_B) #define GPIO215_CLKOUT1 PIN_CFG(215, ALT_C) +#define GPIO215_SPI2_TXD PIN_CFG(215, ALT_C) #define GPIO216_GPIO PIN_CFG(216, GPIO) #define GPIO216_MC1_DAT2DIR PIN_CFG(216, ALT_A) #define GPIO216_MC3_CMDDIR PIN_CFG(216, ALT_B) -#define GPIO216_I2C3_SDA PIN_CFG_PULL(216, ALT_C, UP) +#define GPIO216_I2C3_SDA PIN_CFG(216, ALT_C) +#define GPIO216_SPI2_FRM PIN_CFG(216, ALT_C) #define GPIO217_GPIO PIN_CFG(217, GPIO) #define GPIO217_MC1_DAT0DIR PIN_CFG(217, ALT_A) #define GPIO217_MC3_DAT31DIR PIN_CFG(217, ALT_B) #define GPIO217_CLKOUT2 PIN_CFG(217, ALT_C) +#define GPIO217_SPI2_CLK PIN_CFG(217, ALT_C) #define GPIO218_GPIO PIN_CFG(218, GPIO) #define GPIO218_MC1_DAT31DIR PIN_CFG(218, ALT_A) #define GPIO218_MC3_DAT0DIR PIN_CFG(218, ALT_B) -#define GPIO218_I2C3_SCL PIN_CFG_PULL(218, ALT_C, UP) +#define GPIO218_I2C3_SCL PIN_CFG(218, ALT_C) +#define GPIO218_SPI2_RXD PIN_CFG(218, ALT_C) #define GPIO219_GPIO PIN_CFG(219, GPIO) #define GPIO219_HSIR_FLA0 PIN_CFG(219, ALT_A) @@ -694,12 +698,12 @@ #define GPIO229_GPIO PIN_CFG(229, GPIO) #define GPIO229_CLKOUT1 PIN_CFG(229, ALT_A) #define GPIO229_PWL PIN_CFG(229, ALT_B) -#define GPIO229_I2C3_SDA PIN_CFG_PULL(229, ALT_C, UP) +#define GPIO229_I2C3_SDA PIN_CFG(229, ALT_C) #define GPIO230_GPIO PIN_CFG(230, GPIO) #define GPIO230_CLKOUT2 PIN_CFG(230, ALT_A) #define GPIO230_PWL PIN_CFG(230, ALT_B) -#define GPIO230_I2C3_SCL PIN_CFG_PULL(230, ALT_C, UP) +#define GPIO230_I2C3_SCL PIN_CFG(230, ALT_C) #define GPIO256_GPIO PIN_CFG(256, GPIO) #define GPIO256_USB_NXT PIN_CFG(256, ALT_A) diff --git a/arch/arm/mach-ux500/pins.c b/arch/arm/mach-ux500/pins.c new file mode 100644 index 00000000000..83a041d26f4 --- /dev/null +++ b/arch/arm/mach-ux500/pins.c @@ -0,0 +1,213 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson + * License terms: GNU General Public License (GPL), version 2 + */ + +#include <linux/kernel.h> +#include <linux/string.h> +#include <linux/device.h> +#include <linux/mutex.h> +#include <linux/spinlock.h> +#include <linux/err.h> +#include <plat/pincfg.h> + +#include "pins.h" + +static LIST_HEAD(pin_lookups); +static DEFINE_MUTEX(pin_lookups_mutex); +static DEFINE_SPINLOCK(pins_lock); + +void __init ux500_pins_add(struct ux500_pin_lookup *pl, size_t num) +{ + mutex_lock(&pin_lookups_mutex); + + while (num--) { + list_add_tail(&pl->node, &pin_lookups); + pl++; + } + + mutex_unlock(&pin_lookups_mutex); +} + +struct ux500_pins *ux500_pins_get(const char *name) +{ + struct ux500_pins *pins = NULL; + struct ux500_pin_lookup *pl; + + mutex_lock(&pin_lookups_mutex); + + list_for_each_entry(pl, &pin_lookups, node) { + if (!strcmp(pl->name, name)) { + pins = pl->pins; + goto out; + } + } + +out: + mutex_unlock(&pin_lookups_mutex); + return pins; +} + +int ux500_pins_enable(struct ux500_pins *pins) +{ + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&pins_lock, flags); + + if (pins->usage++ == 0) + ret = nmk_config_pins(pins->cfg, pins->num); + + spin_unlock_irqrestore(&pins_lock, flags); + return ret; +} + +int ux500_pins_disable(struct ux500_pins *pins) +{ + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&pins_lock, flags); + + if (WARN_ON(pins->usage == 0)) + goto out; + + if (--pins->usage == 0) + ret = nmk_config_pins_sleep(pins->cfg, pins->num); + +out: + spin_unlock_irqrestore(&pins_lock, flags); + return ret; +} + +void ux500_pins_put(struct ux500_pins *pins) +{ + WARN_ON(!pins); +} + +#ifdef CONFIG_DEBUG_FS +#include <linux/debugfs.h> +#include <linux/seq_file.h> +#include <linux/slab.h> +#include <linux/gpio/nomadik.h> + +#include <mach/gpio.h> + +static void show_pin(struct seq_file *s, pin_cfg_t pin) +{ + static const char *afnames[] = { + [NMK_GPIO_ALT_GPIO] = "GPIO", + [NMK_GPIO_ALT_A] = "A", + [NMK_GPIO_ALT_B] = "B", + [NMK_GPIO_ALT_C] = "C" + }; + static const char *pullnames[] = { + [NMK_GPIO_PULL_NONE] = "none", + [NMK_GPIO_PULL_UP] = "up", + [NMK_GPIO_PULL_DOWN] = "down", + [3] /* illegal */ = "??" + }; + + int pin_num = PIN_NUM(pin); + int pull = PIN_PULL(pin); + int af = PIN_ALT(pin); + int slpm = PIN_SLPM(pin); + int output = PIN_DIR(pin); + int val = PIN_VAL(pin); + int slpm_pull = PIN_SLPM_PULL(pin); + int slpm_dir = PIN_SLPM_DIR(pin); + int slpm_val = PIN_SLPM_VAL(pin); + int slpm_pdis = PIN_SLPM_PDIS(pin); + + seq_printf(s, + " pin %d [%#lx]: af %s, pull %s (%s%s) - slpm: %s%s%s%s%s\n", + pin_num, pin, afnames[af], + pullnames[pull], + output ? "output " : "input", + output ? (val ? "high" : "low") : "", + slpm ? "no-change/no-wakeup " : "input/wakeup ", + slpm_dir ? (slpm_dir == 1 ? "input " : "output " ) : "", + slpm_dir == 1 ? (slpm_pull == 0 ? "pull: none ": + (slpm_pull == NMK_GPIO_PULL_UP ? + "pull: up " : "pull: down ") ): "", + slpm_dir == 2 ? (slpm_val == 1 ? "low " : "high " ) : "", + slpm_pdis ? (slpm_pdis == 1 ? "pdis: dis" : "pdis: en") : + "pdis: no change"); +} + +static int pins_dbg_show(struct seq_file *s, void *iter) +{ + struct ux500_pin_lookup *pl; + int i; + bool *pins; + int prev = -2; + int first = 0; + + pins = kzalloc(sizeof(bool) * NOMADIK_NR_GPIO, GFP_KERNEL); + + mutex_lock(&pin_lookups_mutex); + + list_for_each_entry(pl, &pin_lookups, node) { + seq_printf(s, "\n%s (%d) usage: %d\n", + pl->name, pl->pins->num, pl->pins->usage); + for (i = 0; i < pl->pins->num; i++) { + show_pin(s, pl->pins->cfg[i]); + pins[PIN_NUM(pl->pins->cfg[i])] = true; + } + } + mutex_unlock(&pin_lookups_mutex); + + seq_printf(s, "\nSummary allocated pins:\n"); + for (i = 0; i < NOMADIK_NR_GPIO; i++) { + if (prev == i - 1) { + if (pins[i]) + prev = i; + else + if (prev > 0) { + if (first != prev) + seq_printf(s, "-%d, ", prev); + else + seq_printf(s, ", "); + } + continue; + } + if (pins[i]) { + seq_printf(s, "%d", i); + prev = i; + first = i; + } + } + if (prev == i - 1 && first != prev) + seq_printf(s, "-%d", prev); + + seq_printf(s, "\n"); + + return 0; +} + +static int pins_dbg_open(struct inode *inode, + struct file *file) +{ + return single_open(file, pins_dbg_show, inode->i_private); +} + +static const struct file_operations pins_fops = { + .open = pins_dbg_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static int __init pins_dbg_init(void) +{ + (void) debugfs_create_file("pins", S_IRUGO, + NULL, + NULL, + &pins_fops); + return 0; +} +late_initcall(pins_dbg_init); +#endif diff --git a/arch/arm/mach-ux500/pins.h b/arch/arm/mach-ux500/pins.h new file mode 100644 index 00000000000..0fa65cc6b96 --- /dev/null +++ b/arch/arm/mach-ux500/pins.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson + * License terms: GNU General Public License (GPL), version 2 + */ + +#ifndef __MACH_UX500_PINS_H +#define __MACH_UX500_PINS_H + +#include <linux/list.h> +#include <plat/pincfg.h> + +#define PIN_LOOKUP(_name, _pins) \ +{ \ + .name = _name, \ + .pins = _pins, \ +} + +#define UX500_PINS(name, pins...) \ +struct ux500_pins name = { \ + .cfg = (pin_cfg_t[]) {pins}, \ + .num = ARRAY_SIZE(((pin_cfg_t[]) {pins})), \ +} + +struct ux500_pins { + int usage; + int num; + pin_cfg_t *cfg; +}; + +struct ux500_pin_lookup { + struct list_head node; + const char *name; + struct ux500_pins *pins; +}; + +void __init ux500_pins_add(struct ux500_pin_lookup *pl, size_t num); +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); +void ux500_pins_put(struct ux500_pins *pins); +int pins_for_u9500(void); + +#endif diff --git a/arch/arm/mach-ux500/reboot_reasons.c b/arch/arm/mach-ux500/reboot_reasons.c new file mode 100644 index 00000000000..365b0c02e16 --- /dev/null +++ b/arch/arm/mach-ux500/reboot_reasons.c @@ -0,0 +1,77 @@ +/* + * Copyright (C) ST-Ericsson SA 2011 + * Author: Rickard Evertsson <rickard.evertsson@stericsson.com> + * for ST-Ericsson. + * + * License terms: GNU General Public License (GPL) version 2 + * + * Use this file to customize your reboot / sw reset reasons. Add, remove or + * modify reasons in reboot_reasons[]. + */ + +#include <linux/kernel.h> +#include <linux/string.h> +#include <mach/reboot_reasons.h> + +struct reboot_reason reboot_reasons[] = { + {"crash", SW_RESET_CRASH}, + {"factory-reset", SW_RESET_FACTORY_RESET}, + {"recovery", SW_RESET_RECOVERY}, + {"charging", SW_RESET_CHARGING}, + {"coldstart", SW_RESET_COLDSTART}, + {"none", SW_RESET_NO_ARGUMENT}, /* Normal Boot */ +}; + +unsigned int reboot_reasons_size = ARRAY_SIZE(reboot_reasons); + +/* + * The reboot reason string can be 255 characters long and the memory + * in which we save the sw reset reason is 2 bytes. Therefore we need to + * convert the string into a 16 bit pattern. + * + * See file reboot_reasons.h for conversion. + */ +u16 reboot_reason_code(const char *cmd) +{ + int i; + + if (cmd == NULL) { + if (oops_in_progress) { + /* if we're in an oops assume it's a crash */ + return SW_RESET_CRASH; + } else { + /* normal reboot w/o argument */ + return SW_RESET_NO_ARGUMENT; + } + } + + /* Search through reboot reason list */ + for (i = 0; i < reboot_reasons_size; i++) { + if (!strcmp(reboot_reasons[i].reason, cmd)) + return reboot_reasons[i].code; + } + + /* No valid reboot reason found */ + return SW_RESET_NO_ARGUMENT; +} + +/* + * The saved sw reset reason is a 2 byte code that is translated into + * a reboot reason string which is up to 255 characters long by this + * function. + * + * See file reboot_reasons.h for conversion. + */ +const char *reboot_reason_string(u16 code) +{ + int i; + + /* Search through reboot reason list */ + for (i = 0; i < reboot_reasons_size; i++) { + if (reboot_reasons[i].code == code) + return reboot_reasons[i].reason; + } + + /* No valid reboot reason code found */ + return "unknown"; +} diff --git a/arch/arm/mach-ux500/sensors1p.c b/arch/arm/mach-ux500/sensors1p.c new file mode 100644 index 00000000000..e7f4642b1d9 --- /dev/null +++ b/arch/arm/mach-ux500/sensors1p.c @@ -0,0 +1,298 @@ + +/* + * Copyright (C) 2009-2010 ST-Ericsson AB + * License terms: GNU General Public License (GPL) version 2 + * Simple userspace interface for + * Proximity Sensor Osram SFH 7741 and HAL switch Samsung HED54XXU11 + * Author: Jonas Aaberg <jonas.aberg@stericsson.com> + * + * This driver is only there for making Android happy. It is not ment + * for mainline. + */ + + +#include <linux/platform_device.h> +#include <linux/sysfs.h> +#include <linux/gpio.h> +#include <linux/delay.h> +#include <linux/jiffies.h> +#include <linux/slab.h> +#include <linux/regulator/consumer.h> +#include <linux/err.h> + +#include <mach/sensors1p.h> + +struct sensor { + struct regulator *regulator; + int pin; + int startup_time; + int active; + u64 when_enabled; +}; + +struct sensors1p { + struct sensor hal; + struct sensor proximity; +}; + +static int sensors1p_power_write(struct device *dev, + struct sensor *s, const char *buf) +{ + int val; + + if (sscanf(buf, "%d", &val) != 1) + return -EINVAL; + + if (val != 0 && val != 1) + return -EINVAL; + + if (val != s->active) { + if (val) { + regulator_enable(s->regulator); + s->when_enabled = get_jiffies_64() + + msecs_to_jiffies(s->startup_time); + } else + regulator_disable(s->regulator); + } + s->active = val; + + return strnlen(buf, PAGE_SIZE); + +} + +static ssize_t sensors1p_sysfs_hal_active_set(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + + + struct sensors1p *s = platform_get_drvdata(container_of(dev, + struct platform_device, + dev)); + return sensors1p_power_write(dev, &s->hal, buf); + +} + +static ssize_t sensors1p_sysfs_proximity_active_set(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + + + struct sensors1p *s = platform_get_drvdata(container_of(dev, + struct platform_device, + dev)); + return sensors1p_power_write(dev, &s->proximity, buf); + +} + +static ssize_t sensors1p_sysfs_hal_active_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct sensors1p *s = platform_get_drvdata(container_of(dev, + struct platform_device, + dev)); + return sprintf(buf, "%d", s->hal.active); +} + +static ssize_t sensors1p_sysfs_proximity_active_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct sensors1p *s = platform_get_drvdata(container_of(dev, + struct platform_device, + dev)); + return sprintf(buf, "%d", s->proximity.active); +} + +static int sensors1p_read(struct device *dev, struct sensor *s, char *buf) +{ + int ret; + + if (!s->active) + return -EINVAL; + + /* Only wait if read() is called before the sensor is up and running + * Since jiffies wraps, always sleep maximum time. + */ + if (time_before64(get_jiffies_64(), s->when_enabled)) + mdelay(s->startup_time); + + /* For some odd reason, setting direction in the probe function fails */ + ret = gpio_direction_input(s->pin); + + if (ret) + dev_err(dev, "Failed to set GPIO pin %d to input.\n", s->pin); + else + ret = gpio_get_value(s->pin); + + return sprintf(buf, "%d", ret); +} + +static ssize_t sensors1p_sysfs_hal_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct sensors1p *s = platform_get_drvdata(container_of(dev, + struct platform_device, + dev)); + return sensors1p_read(dev, &s->hal, buf); +} + +static ssize_t sensors1p_sysfs_proximity_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct sensors1p *s = platform_get_drvdata(container_of(dev, + struct platform_device, + dev)); + return sensors1p_read(dev, &s->proximity, buf); +} + +static DEVICE_ATTR(proximity_activate, 0666, + sensors1p_sysfs_proximity_active_get, + sensors1p_sysfs_proximity_active_set); +static DEVICE_ATTR(hal_activate, 0666, + sensors1p_sysfs_hal_active_get, + sensors1p_sysfs_hal_active_set); +static DEVICE_ATTR(proximity, 0444, sensors1p_sysfs_proximity_show, NULL); +static DEVICE_ATTR(hal, 0444, sensors1p_sysfs_hal_show, NULL); + +static struct attribute *sensors1p_attrs[] = { + &dev_attr_proximity_activate.attr, + &dev_attr_hal_activate.attr, + &dev_attr_proximity.attr, + &dev_attr_hal.attr, + NULL, +}; + +static struct attribute_group sensors1p_attr_group = { + .name = NULL, + .attrs = sensors1p_attrs, +}; + +static int __init sensors1p_probe(struct platform_device *pdev) +{ + int err = -EINVAL; + struct sensors1p_config *c; + struct sensors1p *s = NULL; + + if (!pdev) + goto out; + + c = pdev->dev.platform_data; + + if (c == NULL) { + dev_err(&pdev->dev, "Error: Missconfigured.\n"); + goto out; + } + + s = kzalloc(sizeof(struct sensors1p), GFP_KERNEL); + + if (s == NULL) { + dev_err(&pdev->dev, + "Could not allocate struct memory!\n"); + err = -ENOMEM; + goto out; + } + + s->hal.pin = c->hal.pin; + err = gpio_request(c->hal.pin, "hal sensor"); + if (err < 0) { + dev_err(&pdev->dev, "gpio_request failed with err: %d", err); + goto err_hal_gpio; + } + + s->proximity.pin = c->proximity.pin; + err = gpio_request(c->proximity.pin, "proximity sensor"); + if (err < 0) { + dev_err(&pdev->dev, "gpio_request failed with err: %d", err); + goto err_proximity_gpio; + } + + s->hal.startup_time = c->hal.startup_time; + s->proximity.startup_time = c->proximity.startup_time; + + + s->hal.regulator = regulator_get(&pdev->dev, c->hal.regulator); + + if (IS_ERR(s->hal.regulator)) { + dev_err(&pdev->dev, "regulator_get(\"%s\") failed.\n", + c->hal.regulator); + err = PTR_ERR(s->hal.regulator); + goto err_hal_reg; + } + s->proximity.regulator = regulator_get(&pdev->dev, + c->proximity.regulator); + + if (IS_ERR(s->proximity.regulator)) { + dev_err(&pdev->dev, "regulator_get(\"%s\") failed.\n", + c->proximity.regulator); + err = PTR_ERR(s->proximity.regulator); + goto err_proximity_reg; + } + + err = sysfs_create_group(&pdev->dev.kobj, &sensors1p_attr_group); + + if (err) { + dev_err(&pdev->dev, "Failed to create sysfs entries.\n"); + goto err_sysfs; + } + + platform_set_drvdata(pdev, s); + + return 0; + +err_sysfs: + regulator_put(s->proximity.regulator); +err_proximity_reg: + regulator_put(s->hal.regulator); +err_hal_reg: + gpio_free(s->proximity.pin); +err_proximity_gpio: + gpio_free(s->hal.pin); +err_hal_gpio: + kfree(s); +out: + return err; +} + +static int __exit sensors1p_remove(struct platform_device *pdev) +{ + struct sensors1p *s = platform_get_drvdata(pdev); + + sysfs_remove_group(&pdev->dev.kobj, &sensors1p_attr_group); + gpio_free(s->hal.pin); + gpio_free(s->proximity.pin); + regulator_put(s->hal.regulator); + regulator_put(s->proximity.regulator); + kfree(s); + return 0; +} + +static struct platform_driver sensors1p_driver = { + .remove = __exit_p(sensors1p_remove), + .driver = { + .name = "sensors1p", + .owner = THIS_MODULE, + }, +}; + +static int __init sensors1p_init(void) +{ + return platform_driver_probe(&sensors1p_driver, sensors1p_probe); +} + +static void __exit sensors1p_exit(void) +{ + platform_driver_unregister(&sensors1p_driver); +} + +late_initcall(sensors1p_init); +module_exit(sensors1p_exit); + +MODULE_AUTHOR("Jonas Aaberg <jonas.aberg@stericsson.com>"); +MODULE_DESCRIPTION("One pin gpio sensors driver (Proximity+HAL)"); +MODULE_LICENSE("GPLv2"); diff --git a/arch/arm/mach-ux500/timer.c b/arch/arm/mach-ux500/timer.c new file mode 100644 index 00000000000..8a8f747bd81 --- /dev/null +++ b/arch/arm/mach-ux500/timer.c @@ -0,0 +1,84 @@ +/* + * Copyright (C) ST-Ericsson SA 2011 + * + * License Terms: GNU General Public License v2 + * Author: Mattias Wallin <mattias.wallin@stericsson.com> for ST-Ericsson + */ +#include <linux/io.h> +#include <linux/clksrc-dbx500-prcmu.h> + +#include <asm/localtimer.h> + +#include <plat/mtu.h> + +#include <mach/setup.h> +#include <mach/hardware.h> +#include <mach/context.h> + +#ifdef CONFIG_UX500_CONTEXT +static int mtu_context_notifier_call(struct notifier_block *this, + unsigned long event, void *data) +{ + if (event == CONTEXT_APE_RESTORE) + nmdk_clksrc_reset(); + return NOTIFY_OK; +} + +static struct notifier_block mtu_context_notifier = { + .notifier_call = mtu_context_notifier_call, +}; +#endif + +static void ux500_timer_reset(void) +{ + nmdk_clkevt_reset(); +} + +static void __init ux500_timer_init(void) +{ + if (cpu_is_u5500()) { +#ifdef CONFIG_LOCAL_TIMERS + twd_base = __io_address(U5500_TWD_BASE); +#endif + mtu_base = __io_address(U5500_MTU0_BASE); + clksrc_dbx500_timer_base = __io_address(U5500_PRCMU_TIMER_3_BASE); + } else if (cpu_is_u8500()) { +#ifdef CONFIG_LOCAL_TIMERS + twd_base = __io_address(U8500_TWD_BASE); +#endif + mtu_base = __io_address(U8500_MTU0_BASE); + clksrc_dbx500_timer_base = __io_address(U8500_PRCMU_TIMER_4_BASE); + } else { + ux500_unknown_soc(); + } + + /* + * Here we register the timerblocks active in the system. + * Localtimers (twd) is started when both cpu is up and running. + * MTU register a clocksource, clockevent and sched_clock. + * Since the MTU is located in the VAPE power domain + * it will be cleared in sleep which makes it unsuitable. + * We however need it as a timer tick (clockevent) + * during boot to calibrate delay until twd is started. + * RTC-RTT have problems as timer tick during boot since it is + * depending on delay which is not yet calibrated. RTC-RTT is in the + * always-on powerdomain and is used as clockevent instead of twd when + * sleeping. + * The PRCMU timer 4(3 for DB5500) register a clocksource and + * sched_clock with higher rating then MTU since is always-on. + * + */ + + nmdk_timer_init(); + clksrc_dbx500_prcmu_init(); + +#ifdef CONFIG_UX500_CONTEXT + WARN_ON(context_ape_notifier_register(&mtu_context_notifier)); +#endif + +} + +struct sys_timer ux500_timer = { + .init = ux500_timer_init, + .resume = ux500_timer_reset, +}; diff --git a/arch/arm/plat-nomadik/Kconfig b/arch/arm/plat-nomadik/Kconfig index ce659015535..bca4914b4b9 100644 --- a/arch/arm/plat-nomadik/Kconfig +++ b/arch/arm/plat-nomadik/Kconfig @@ -15,10 +15,16 @@ if PLAT_NOMADIK config HAS_MTU bool - select HAVE_SCHED_CLOCK help Support for Multi Timer Unit. MTU provides access to multiple interrupt generating programmable 32-bit free running decrementing counters. +config NOMADIK_MTU_SCHED_CLOCK + bool + depends on HAS_MTU + select HAVE_SCHED_CLOCK + help + Use the Multi Timer Unit as the sched_clock. + endif diff --git a/arch/arm/plat-nomadik/include/plat/mtu.h b/arch/arm/plat-nomadik/include/plat/mtu.h index 3e740a0ef53..5c97b3ccf76 100644 --- a/arch/arm/plat-nomadik/include/plat/mtu.h +++ b/arch/arm/plat-nomadik/include/plat/mtu.h @@ -1,54 +1,11 @@ #ifndef __PLAT_MTU_H #define __PLAT_MTU_H -/* - * Guaranteed runtime conversion range in seconds for - * the clocksource and clockevent. - */ -#define MTU_MIN_RANGE 4 - /* should be set by the platform code */ extern void __iomem *mtu_base; -/* - * The MTU device hosts four different counters, with 4 set of - * registers. These are register names. - */ - -#define MTU_IMSC 0x00 /* Interrupt mask set/clear */ -#define MTU_RIS 0x04 /* Raw interrupt status */ -#define MTU_MIS 0x08 /* Masked interrupt status */ -#define MTU_ICR 0x0C /* Interrupt clear register */ - -/* per-timer registers take 0..3 as argument */ -#define MTU_LR(x) (0x10 + 0x10 * (x) + 0x00) /* Load value */ -#define MTU_VAL(x) (0x10 + 0x10 * (x) + 0x04) /* Current value */ -#define MTU_CR(x) (0x10 + 0x10 * (x) + 0x08) /* Control reg */ -#define MTU_BGLR(x) (0x10 + 0x10 * (x) + 0x0c) /* At next overflow */ - -/* bits for the control register */ -#define MTU_CRn_ENA 0x80 -#define MTU_CRn_PERIODIC 0x40 /* if 0 = free-running */ -#define MTU_CRn_PRESCALE_MASK 0x0c -#define MTU_CRn_PRESCALE_1 0x00 -#define MTU_CRn_PRESCALE_16 0x04 -#define MTU_CRn_PRESCALE_256 0x08 -#define MTU_CRn_32BITS 0x02 -#define MTU_CRn_ONESHOT 0x01 /* if 0 = wraps reloading from BGLR*/ - -/* Other registers are usual amba/primecell registers, currently not used */ -#define MTU_ITCR 0xff0 -#define MTU_ITOP 0xff4 - -#define MTU_PERIPH_ID0 0xfe0 -#define MTU_PERIPH_ID1 0xfe4 -#define MTU_PERIPH_ID2 0xfe8 -#define MTU_PERIPH_ID3 0xfeC - -#define MTU_PCELL0 0xff0 -#define MTU_PCELL1 0xff4 -#define MTU_PCELL2 0xff8 -#define MTU_PCELL3 0xffC +void nmdk_clkevt_reset(void); +void nmdk_clksrc_reset(void); struct clock_event_device *nmdk_clkevt_get(void); diff --git a/arch/arm/plat-nomadik/include/plat/pincfg.h b/arch/arm/plat-nomadik/include/plat/pincfg.h index 05a3936ae6d..c015133a7ad 100644 --- a/arch/arm/plat-nomadik/include/plat/pincfg.h +++ b/arch/arm/plat-nomadik/include/plat/pincfg.h @@ -24,6 +24,7 @@ * bit 16..18 - SLPM pull up/down state * bit 19..20 - SLPM direction * bit 21..22 - SLPM Value (if output) + * bit 23..25 - PDIS value (if input) * * to facilitate the definition, the following macros are provided * @@ -37,7 +38,6 @@ * SLPM value = same as normal * * PIN_CFG - default config with alternate function - * PIN_CFG_PULL - default config with alternate function and pull up/down */ typedef unsigned long pin_cfg_t; @@ -68,6 +68,10 @@ typedef unsigned long pin_cfg_t; /* These two replace the above in DB8500v2+ */ #define PIN_SLPM_WAKEUP_ENABLE (NMK_GPIO_SLPM_WAKEUP_ENABLE << PIN_SLPM_SHIFT) #define PIN_SLPM_WAKEUP_DISABLE (NMK_GPIO_SLPM_WAKEUP_DISABLE << PIN_SLPM_SHIFT) +#define PIN_SLPM_USE_MUX_SETTINGS_IN_SLEEP PIN_SLPM_WAKEUP_DISABLE + +#define PIN_SLPM_GPIO PIN_SLPM_WAKEUP_ENABLE /* In SLPM, pin is a gpio */ +#define PIN_SLPM_ALTFUNC PIN_SLPM_WAKEUP_DISABLE /* In SLPM, pin is altfunc */ #define PIN_DIR_SHIFT 14 #define PIN_DIR_MASK (0x1 << PIN_DIR_SHIFT) @@ -106,6 +110,20 @@ typedef unsigned long pin_cfg_t; #define PIN_SLPM_VAL_LOW ((1 + 0) << PIN_SLPM_VAL_SHIFT) #define PIN_SLPM_VAL_HIGH ((1 + 1) << PIN_SLPM_VAL_SHIFT) +#define PIN_SLPM_PDIS_SHIFT 23 +#define PIN_SLPM_PDIS_MASK (0x3 << PIN_SLPM_PDIS_SHIFT) +#define PIN_SLPM_PDIS(x) \ + (((x) & PIN_SLPM_PDIS_MASK) >> PIN_SLPM_PDIS_SHIFT) +#define PIN_SLPM_PDIS_NO_CHANGE (0 << PIN_SLPM_PDIS_SHIFT) +#define PIN_SLPM_PDIS_DISABLED (1 << PIN_SLPM_PDIS_SHIFT) +#define PIN_SLPM_PDIS_ENABLED (2 << PIN_SLPM_PDIS_SHIFT) + +#define PIN_LOWEMI_SHIFT 25 +#define PIN_LOWEMI_MASK (0x1 << PIN_LOWEMI_SHIFT) +#define PIN_LOWEMI(x) (((x) & PIN_LOWEMI_MASK) >> PIN_LOWEMI_SHIFT) +#define PIN_LOWEMI_DISABLED (0 << PIN_LOWEMI_SHIFT) +#define PIN_LOWEMI_ENABLED (1 << PIN_LOWEMI_SHIFT) + /* Shortcuts. Use these instead of separate DIR, PULL, and VAL. */ #define PIN_INPUT_PULLDOWN (PIN_DIR_INPUT | PIN_PULL_DOWN) #define PIN_INPUT_PULLUP (PIN_DIR_INPUT | PIN_PULL_UP) @@ -133,10 +151,6 @@ typedef unsigned long pin_cfg_t; (PIN_CFG_DEFAULT |\ (PIN_NUM(num) | PIN_##alt | PIN_OUTPUT_##val)) -#define PIN_CFG_PULL(num, alt, pull) \ - ((PIN_CFG_DEFAULT & ~PIN_PULL_MASK) |\ - (PIN_NUM(num) | PIN_##alt | PIN_PULL_##pull)) - extern int nmk_config_pin(pin_cfg_t cfg, bool sleep); extern int nmk_config_pins(pin_cfg_t *cfgs, int num); extern int nmk_config_pins_sleep(pin_cfg_t *cfgs, int num); diff --git a/arch/arm/plat-nomadik/include/plat/ste_dma40.h b/arch/arm/plat-nomadik/include/plat/ste_dma40.h index 685c78716d9..694587cb214 100644 --- a/arch/arm/plat-nomadik/include/plat/ste_dma40.h +++ b/arch/arm/plat-nomadik/include/plat/ste_dma40.h @@ -142,6 +142,7 @@ 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 + * @use_esram_lcla: flag for mapping the lcla into esram region * that are for different reasons not available for the driver. */ struct stedma40_platform_data { @@ -153,6 +154,7 @@ struct stedma40_platform_data { struct stedma40_chan_cfg *memcpy_conf_phy; struct stedma40_chan_cfg *memcpy_conf_log; int disabled_channels[STEDMA40_MAX_PHYS]; + bool use_esram_lcla; }; #ifdef CONFIG_STE_DMA40 diff --git a/arch/arm/plat-nomadik/timer.c b/arch/arm/plat-nomadik/timer.c index ef74e157a9d..7ca131e57df 100644 --- a/arch/arm/plat-nomadik/timer.c +++ b/arch/arm/plat-nomadik/timer.c @@ -17,14 +17,64 @@ #include <linux/clk.h> #include <linux/jiffies.h> #include <linux/err.h> +#include <linux/delay.h> #include <linux/sched.h> #include <asm/mach/time.h> #include <asm/sched_clock.h> -#include <plat/mtu.h> +/* + * Guaranteed runtime conversion range in seconds for + * the clocksource and clockevent. + */ +#define MTU_MIN_RANGE 4 + +/* + * The MTU device hosts four different counters, with 4 set of + * registers. These are register names. + */ + +#define MTU_IMSC 0x00 /* Interrupt mask set/clear */ +#define MTU_RIS 0x04 /* Raw interrupt status */ +#define MTU_MIS 0x08 /* Masked interrupt status */ +#define MTU_ICR 0x0C /* Interrupt clear register */ + +/* per-timer registers take 0..3 as argument */ +#define MTU_LR(x) (0x10 + 0x10 * (x) + 0x00) /* Load value */ +#define MTU_VAL(x) (0x10 + 0x10 * (x) + 0x04) /* Current value */ +#define MTU_CR(x) (0x10 + 0x10 * (x) + 0x08) /* Control reg */ +#define MTU_BGLR(x) (0x10 + 0x10 * (x) + 0x0c) /* At next overflow */ + +/* bits for the control register */ +#define MTU_CRn_ENA 0x80 +#define MTU_CRn_PERIODIC 0x40 /* if 0 = free-running */ +#define MTU_CRn_PRESCALE_MASK 0x0c +#define MTU_CRn_PRESCALE_1 0x00 +#define MTU_CRn_PRESCALE_16 0x04 +#define MTU_CRn_PRESCALE_256 0x08 +#define MTU_CRn_32BITS 0x02 +#define MTU_CRn_ONESHOT 0x01 /* if 0 = wraps reloading from BGLR*/ + +/* Other registers are usual amba/primecell registers, currently not used */ +#define MTU_ITCR 0xff0 +#define MTU_ITOP 0xff4 + +#define MTU_PERIPH_ID0 0xfe0 +#define MTU_PERIPH_ID1 0xfe4 +#define MTU_PERIPH_ID2 0xfe8 +#define MTU_PERIPH_ID3 0xfeC + +#define MTU_PCELL0 0xff0 +#define MTU_PCELL1 0xff4 +#define MTU_PCELL2 0xff8 +#define MTU_PCELL3 0xffC + +static bool clkevt_periodic; +static u32 clk_prescale; +static u32 nmdk_cycle; /* write-once */ void __iomem *mtu_base; /* Assigned by machine code */ +#ifdef CONFIG_NOMADIK_MTU_SCHED_CLOCK /* * Override the global weak sched_clock symbol with this * local implementation which uses the clocksource to get some @@ -48,32 +98,56 @@ static void notrace nomadik_update_sched_clock(void) u32 cyc = -readl(mtu_base + MTU_VAL(0)); update_sched_clock(&cd, cyc, (u32)~0); } +#endif /* Clockevent device: use one-shot mode */ +static int nmdk_clkevt_next(unsigned long evt, struct clock_event_device *ev) +{ + writel(1 << 1, mtu_base + MTU_IMSC); + writel(evt, mtu_base + MTU_LR(1)); + /* Load highest value, enable device, enable interrupts */ + writel(MTU_CRn_ONESHOT | clk_prescale | + MTU_CRn_32BITS | MTU_CRn_ENA, + mtu_base + MTU_CR(1)); + + return 0; +} + +void nmdk_clkevt_reset(void) +{ + if (clkevt_periodic) { + + /* Timer: configure load and background-load, and fire it up */ + writel(nmdk_cycle, mtu_base + MTU_LR(1)); + writel(nmdk_cycle, mtu_base + MTU_BGLR(1)); + + writel(MTU_CRn_PERIODIC | clk_prescale | + MTU_CRn_32BITS | MTU_CRn_ENA, + mtu_base + MTU_CR(1)); + writel(1 << 1, mtu_base + MTU_IMSC); + } else { + /* Generate an interrupt to start the clockevent again */ + (void) nmdk_clkevt_next(nmdk_cycle, NULL); + } +} + static void nmdk_clkevt_mode(enum clock_event_mode mode, struct clock_event_device *dev) { - u32 cr; switch (mode) { case CLOCK_EVT_MODE_PERIODIC: - pr_err("%s: periodic mode not supported\n", __func__); + clkevt_periodic = true; + nmdk_clkevt_reset(); break; case CLOCK_EVT_MODE_ONESHOT: - /* Load highest value, enable device, enable interrupts */ - cr = readl(mtu_base + MTU_CR(1)); - writel(0, mtu_base + MTU_LR(1)); - writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(1)); - writel(1 << 1, mtu_base + MTU_IMSC); + clkevt_periodic = false; break; case CLOCK_EVT_MODE_SHUTDOWN: case CLOCK_EVT_MODE_UNUSED: - /* disable irq */ writel(0, mtu_base + MTU_IMSC); /* disable timer */ - cr = readl(mtu_base + MTU_CR(1)); - cr &= ~MTU_CRn_ENA; - writel(cr, mtu_base + MTU_CR(1)); + writel(0, mtu_base + MTU_CR(1)); /* load some high default value */ writel(0xffffffff, mtu_base + MTU_LR(1)); break; @@ -82,21 +156,36 @@ static void nmdk_clkevt_mode(enum clock_event_mode mode, } } -static int nmdk_clkevt_next(unsigned long evt, struct clock_event_device *ev) -{ - /* writing the value has immediate effect */ - writel(evt, mtu_base + MTU_LR(1)); - return 0; -} - static struct clock_event_device nmdk_clkevt = { .name = "mtu_1", - .features = CLOCK_EVT_FEAT_ONESHOT, + .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC, .rating = 200, .set_mode = nmdk_clkevt_mode, .set_next_event = nmdk_clkevt_next, }; +#ifdef ARCH_HAS_READ_CURRENT_TIMER +static void nmdk_timer_delay_loop(unsigned long loops) +{ + unsigned long bclock, now; + + bclock = ~readl(mtu_base + MTU_VAL(0)); + do { + now = ~readl(mtu_base + MTU_VAL(0)); + /* If timer have been cleared (suspend) or wrapped we exit */ + if (unlikely(now < bclock)) + return; + } while ((now - bclock) < loops); +} + +/* Used to calibrate the delay */ +int read_current_timer(unsigned long *timer_val) +{ + *timer_val = ~readl(mtu_base + MTU_VAL(0)); + return 0; +} +#endif + /* * IRQ Handler for timer 1 of the MTU block. */ @@ -116,11 +205,28 @@ static struct irqaction nmdk_timer_irq = { .dev_id = &nmdk_clkevt, }; +void nmdk_clksrc_reset(void) +{ + /* Disable */ + writel(0, mtu_base + MTU_CR(0)); + + /* ClockSource: configure load and background-load, and fire it up */ + writel(nmdk_cycle, mtu_base + MTU_LR(0)); + writel(nmdk_cycle, mtu_base + MTU_BGLR(0)); + + writel(clk_prescale | MTU_CRn_32BITS | MTU_CRn_ENA, + mtu_base + MTU_CR(0)); +} + +struct clock_event_device *nmdk_clkevt_get(void) +{ + return &nmdk_clkevt; +} + void __init nmdk_timer_init(void) { unsigned long rate; struct clk *clk0; - u32 cr = MTU_CRn_32BITS; clk0 = clk_get_sys("mtu0", NULL); BUG_ON(IS_ERR(clk0)); @@ -138,30 +244,28 @@ void __init nmdk_timer_init(void) rate = clk_get_rate(clk0); if (rate > 32000000) { rate /= 16; - cr |= MTU_CRn_PRESCALE_16; + clk_prescale = MTU_CRn_PRESCALE_16; } else { - cr |= MTU_CRn_PRESCALE_1; + clk_prescale = MTU_CRn_PRESCALE_1; } + nmdk_cycle = (rate + HZ/2) / HZ; + + /* Timer 0 is the free running clocksource */ - writel(cr, mtu_base + MTU_CR(0)); - writel(0, mtu_base + MTU_LR(0)); - writel(0, mtu_base + MTU_BGLR(0)); - writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0)); + nmdk_clksrc_reset(); if (clocksource_mmio_init(mtu_base + MTU_VAL(0), "mtu_0", rate, 200, 32, clocksource_mmio_readl_down)) pr_err("timer: failed to initialize clock source %s\n", "mtu_0"); - +#ifdef CONFIG_NOMADIK_MTU_SCHED_CLOCK init_sched_clock(&cd, nomadik_update_sched_clock, 32, rate); - +#endif /* Timer 1 is used for events */ clockevents_calc_mult_shift(&nmdk_clkevt, rate, MTU_MIN_RANGE); - writel(cr | MTU_CRn_ONESHOT, mtu_base + MTU_CR(1)); /* off, currently */ - nmdk_clkevt.max_delta_ns = clockevent_delta2ns(0xffffffff, &nmdk_clkevt); nmdk_clkevt.min_delta_ns = @@ -171,4 +275,8 @@ void __init nmdk_timer_init(void) /* Register irq and clockevents */ setup_irq(IRQ_MTU0, &nmdk_timer_irq); clockevents_register_device(&nmdk_clkevt); +#ifdef ARCH_HAS_READ_CURRENT_TIMER + set_delay_fn(nmdk_timer_delay_loop); +#endif + } |