From 8d9b2a925c726ad702580ced887eeb4f41f37370 Mon Sep 17 00:00:00 2001 From: Jurijs Soloveckis Date: Mon, 17 Oct 2011 10:21:00 +0200 Subject: ARM: u8500: Add control for modem and ape trace SD-card, mipi34 and mipi60 IFs can be configured for modem or ape trace, using u-boot cmd prompt. STM drv is controlled via kernel environment vars: Example: stm.microsd=[none|modem|ape], or stm.mipi34=[none|modem|ape], or stm.mipi60=[none|modem|ape] If trace set to ape, use stm.stm_ter=N to init STM_TER reg with decimal value N (default: N=0). ST-Ericsson ID: 349677 ST-Ericsson Linux next: N/A ST-Ericsson FOSS-OUT ID: Trivial Change-Id: Ie04e4c004417c4542259e3074f1fa2fd4f00ce6d Depends-On: I7bbcf263b83338d7b05413dd9dc0ac2ec4880601 Signed-off-by: Jurijs Soloveckis Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/34160 Reviewed-by: QATOOLS Reviewed-by: Jonas ABERG --- arch/arm/mach-ux500/board-mop500-regulators.c | 1 + arch/arm/mach-ux500/board-mop500-stm.c | 277 ++++++++++++++++++++++++-- drivers/misc/stm.c | 60 +++++- include/trace/stm.h | 5 +- 4 files changed, 326 insertions(+), 17 deletions(-) diff --git a/arch/arm/mach-ux500/board-mop500-regulators.c b/arch/arm/mach-ux500/board-mop500-regulators.c index 52426a42578..df34f6be694 100644 --- a/arch/arm/mach-ux500/board-mop500-regulators.c +++ b/arch/arm/mach-ux500/board-mop500-regulators.c @@ -63,6 +63,7 @@ static struct regulator_consumer_supply ab8500_vaux2_consumers[] = { }; static struct regulator_consumer_supply ab8500_vaux3_consumers[] = { + REGULATOR_SUPPLY("v-SD-STM", "stm"), /* External MMC slot power */ REGULATOR_SUPPLY("vmmc", "sdi0"), }; diff --git a/arch/arm/mach-ux500/board-mop500-stm.c b/arch/arm/mach-ux500/board-mop500-stm.c index 20d3f9a546b..d38595b11b2 100644 --- a/arch/arm/mach-ux500/board-mop500-stm.c +++ b/arch/arm/mach-ux500/board-mop500-stm.c @@ -13,13 +13,27 @@ #include #include #include +#include +#include + +#include #include #include -#include #include #include #include "pins-db8500.h" +#define HREFV60_SDMMC_EN_GPIO 169 +#define HREFV60_SDMMC_1V8_3V_GPIO 5 + +#define STM_DEVICE (&u8500_stm_device.dev) +#define STM_ERR(msg) dev_err(STM_DEVICE, msg) +#define STM_WARN(msg) dev_warn(STM_DEVICE, msg) + +static struct regulator *regulator_aux3; +static enum stm_connection_type + stm_current_connection = STM_STE_INVALID_CONNECTION; + static pin_cfg_t mop500_stm_mipi34_pins[] = { GPIO70_STMAPE_CLK | PIN_SLPM_USE_MUX_SETTINGS_IN_SLEEP, GPIO71_STMAPE_DAT3 | PIN_SLPM_USE_MUX_SETTINGS_IN_SLEEP, @@ -40,6 +54,15 @@ static pin_cfg_t mop500_stm_mipi60_pins[] = { GPIO159_STMAPE_DAT0, }; +static pin_cfg_t mop500_stm_ape_microsd_pins[] = { + GPIO23_MS_CLK | PIN_SLPM_USE_MUX_SETTINGS_IN_SLEEP, + GPIO24_MS_BS | PIN_SLPM_USE_MUX_SETTINGS_IN_SLEEP, + GPIO25_MS_DAT0 | PIN_SLPM_USE_MUX_SETTINGS_IN_SLEEP, + GPIO26_MS_DAT1 | PIN_SLPM_USE_MUX_SETTINGS_IN_SLEEP, + GPIO27_MS_DAT2 | PIN_SLPM_USE_MUX_SETTINGS_IN_SLEEP, + GPIO28_MS_DAT3 | PIN_SLPM_USE_MUX_SETTINGS_IN_SLEEP, +}; + static pin_cfg_t mop500_ske_pins[] = { GPIO153_KP_I7 | PIN_INPUT_PULLDOWN | PIN_SLPM_INPUT_PULLUP, GPIO154_KP_I6 | PIN_INPUT_PULLDOWN | PIN_SLPM_INPUT_PULLUP, @@ -59,35 +82,211 @@ static pin_cfg_t mop500_ske_pins[] = { GPIO168_KP_O0 | PIN_INPUT_PULLUP | PIN_SLPM_OUTPUT_LOW, }; +static pin_cfg_t mop500_stm_modem_microsd_pins[] = { + GPIO18_GPIO | PIN_OUTPUT_LOW, + GPIO19_GPIO | PIN_OUTPUT_HIGH, + GPIO20_GPIO | PIN_OUTPUT_HIGH, + GPIO22_GPIO | PIN_INPUT_PULLUP, + GPIO23_STMMOD_CLK | PIN_SLPM_USE_MUX_SETTINGS_IN_SLEEP, + GPIO24_UARTMOD_RXD | PIN_SLPM_USE_MUX_SETTINGS_IN_SLEEP, + GPIO25_STMMOD_DAT0 | PIN_SLPM_USE_MUX_SETTINGS_IN_SLEEP, + GPIO26_STMMOD_DAT1 | PIN_SLPM_USE_MUX_SETTINGS_IN_SLEEP, + GPIO27_STMMOD_DAT2 | PIN_SLPM_USE_MUX_SETTINGS_IN_SLEEP, + GPIO28_STMMOD_DAT3 | PIN_SLPM_USE_MUX_SETTINGS_IN_SLEEP, +}; + +/* sdi0 (removable MMC/SD/SDIO cards) */ +static pin_cfg_t mop500_sdi0_pins[] = { + 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, +}; + static int stm_ste_disable_ape_on_mipi60(void) { int retval; retval = nmk_config_pins_sleep(ARRAY_AND_SIZE(mop500_stm_mipi60_pins)); if (retval) - pr_err("STM: Failed to disable MIPI60\n"); + STM_ERR("Failed to disable MIPI60\n"); else { retval = nmk_config_pins(ARRAY_AND_SIZE(mop500_ske_pins)); if (retval) - pr_err("STM: Failed to enable SKE gpio\n"); + STM_ERR("Failed to enable SKE gpio\n"); } return retval; } -/* - * Manage STM output pins connection (MIP34/MIPI60 connectors) - */ +static int stm_enable_ape_microsd(void) +{ + int retval; + + /* + * Configure STM APE on GPIO23,GPIO28,GPIO27,GPIO26,GPIO25 + * On HREF board an external SD buffer exist (ST6G3244ME) + * to perform level conversion from 1.8v to 3.3V on SD card signals + * When STM is redirected on micro SD connector GPIO18,GP19,GPIO20 + * are configured in standard GPIO mode and are used to configure + * direction on external SD buffer ST6G3244ME. + */ + + retval = nmk_config_pins(ARRAY_AND_SIZE(mop500_stm_ape_microsd_pins)); + if (retval) + STM_ERR("Failed to enable STM APE on MICRO SD\n"); + + /* Enable altC1 on GPIO23-28 (STMAPE) */ + prcmu_enable_stm_ape(); + + return retval; +} + +static int stm_disable_ape_microsd(void) +{ + int retval; + + /* Disable altC1 on GPIO23-28 (STMAPE) */ + prcmu_disable_stm_ape(); + + /* Reconfigure GPIO for SD */ + retval = nmk_config_pins_sleep(ARRAY_AND_SIZE(mop500_sdi0_pins)); + if (retval) + STM_ERR("Failed to disable STM APE on MICRO SD " + "and to reconfigure GPIO for SD\n"); + + return retval; +} + +static int stm_enable_modem_microsd(void) +{ + int retval; + + /* + * Configure STM APE on GPIO23,GPIO28,GPIO27,GPIO26,GPIO25 + * On HREF board an external SD buffer exist (ST6G3244ME) + * to perform level conversion from 1.8v to 3.3V on SD card + * signals. When STM is redirected on micro SD connector + * GPIO18,GP19,GPIO20 are configured in standard GPIO mode + * and are used to configure direction on external SD buffer + * ST6G3244ME. + */ + + retval = nmk_config_pins(ARRAY_AND_SIZE(mop500_stm_modem_microsd_pins)); + if (retval) + STM_ERR("Failed to enable STM MODEM on MICRO SD\n"); + + return retval; +} + +static int stm_disable_modem_microsd(void) +{ + int retval; + + /* Reconfigure GPIO for SD */ + retval = nmk_config_pins_sleep(ARRAY_AND_SIZE(mop500_sdi0_pins)); + if (retval) + STM_ERR("Failed to disable STM MODEM on MICRO SD " + "and to reconfigure GPIO for SD\n"); + + return retval; +} + +/* Enable or disable micro sd card buffers on HREF */ +static void control_level_shifter_for_microsd(int gpio_dir) +{ + int gpio[2]; + + if (machine_is_hrefv60()) { + gpio[0] = HREFV60_SDMMC_EN_GPIO; + gpio[1] = HREFV60_SDMMC_1V8_3V_GPIO; + } else { + gpio[0] = MOP500_EGPIO(17); + gpio[1] = MOP500_EGPIO(18); + } + + /* Select the default 2.9V and enable / disable level shifter */ + gpio_direction_output(gpio[1], 0); + gpio_direction_output(gpio[0], gpio_dir); +} + +/* Enable micro sd card buffers on HREF */ +static int enable_level_shifter_for_microsd(void) +{ + control_level_shifter_for_microsd(1); + STM_WARN("Level Shifter for SD card connector on.\n"); + return 0; +} + +/* Disable micro sd card buffers on HREF */ +static int disable_level_shifter_for_microsd(void) +{ + control_level_shifter_for_microsd(0); + STM_WARN("Level Shifter for SD card connector off.\n"); + return 0; +} + +/* Enable VAUX3 to power on buffer on STM MICRO SD cable */ +static int enable_vaux3_for_microsd_cable(void) +{ + int error; + + regulator_aux3 = regulator_get(&u8500_stm_device.dev, "v-SD-STM"); + + if (IS_ERR(regulator_aux3)) { + error = PTR_ERR(regulator_aux3); + STM_ERR("Failed to get regulator, supply: v-SD-STM\n"); + return error; + } + + error = regulator_enable(regulator_aux3); + + if (error) { + STM_ERR("Unable to enable regulator on SD card connector\n"); + return error; + } + + STM_WARN("Regulator on SD card connector power on.\n"); + return error; +} + +/* Disable VAUX3 to power off buffer on STM MICRO SD cable */ +static int disable_vaux3_for_microsd_cable(void) +{ + int error = 0; + + error = regulator_disable(regulator_aux3); + + if (regulator_aux3) + regulator_put(regulator_aux3); + + STM_WARN("Regulator for stm on SD card connector power off.\n"); + + return error; + +} + static int stm_ste_connection(enum stm_connection_type con_type) { int retval = -EINVAL; + /* Check if connection type has been changed */ + if (con_type == stm_current_connection) + return 0; + if (con_type != STM_DISCONNECT) { /* Always enable MIPI34 GPIO pins */ retval = nmk_config_pins( ARRAY_AND_SIZE(mop500_stm_mipi34_pins)); if (retval) { - pr_err("STM: Failed to enable MIPI34\n"); - return retval; + STM_ERR("Failed to enable MIPI34\n"); + goto stm_ste_connection_error; } } @@ -111,12 +310,40 @@ static int stm_ste_connection(enum stm_connection_type con_type) /* Enable APE on MIPI60 */ retval = nmk_config_pins_sleep(ARRAY_AND_SIZE(mop500_ske_pins)); if (retval) - pr_err("STM: Failed to disable SKE GPIO\n"); + STM_ERR("Failed to disable SKE GPIO\n"); else { retval = nmk_config_pins( ARRAY_AND_SIZE(mop500_stm_mipi60_pins)); if (retval) - pr_err("STM: Failed to enable MIPI60\n"); + STM_ERR("Failed to enable MIPI60\n"); + } + break; + + case STM_STE_MODEM_ON_MICROSD: + /* Disable APE on micro SD */ + retval = stm_disable_ape_microsd(); + /* Enable modem on micro SD */ + if (!retval) + retval = stm_enable_modem_microsd(); + /* Enable SD card buffer and regulator on href */ + if (!retval && (stm_current_connection + != STM_STE_APE_ON_MICROSD)) { + enable_level_shifter_for_microsd(); + enable_vaux3_for_microsd_cable(); + } + break; + + case STM_STE_APE_ON_MICROSD: + /* Disable modem on micro SD */ + retval = stm_disable_modem_microsd(); + /* Enable ape on micro SD */ + if (!retval) + retval = stm_enable_ape_microsd(); + /* Enable SD card buffer and regulator on href */ + if (!retval && (stm_current_connection + != STM_STE_MODEM_ON_MICROSD)) { + enable_level_shifter_for_microsd(); + enable_vaux3_for_microsd_cable(); } break; @@ -124,15 +351,39 @@ static int stm_ste_connection(enum stm_connection_type con_type) retval = nmk_config_pins_sleep( ARRAY_AND_SIZE(mop500_stm_mipi34_pins)); if (retval) - pr_err("STM: Failed to disable MIPI34\n"); + STM_ERR("Failed to disable MIPI34\n"); retval = stm_ste_disable_ape_on_mipi60(); + if (retval) + STM_ERR("Failed to disable MIPI60\n"); + + retval = stm_disable_modem_microsd(); + if (retval) + STM_ERR("Failed to disable modem on microsd\n"); + + retval = stm_disable_ape_microsd(); + if (retval) + STM_ERR("Failed to disable ape on microsd\n"); break; default: - pr_err("STM: bad connection type\n"); - break; + STM_ERR("Bad connection type\n"); + goto stm_ste_connection_error; + } + + /* Disable power for microsd */ + if ((stm_current_connection == STM_STE_MODEM_ON_MICROSD) + || (stm_current_connection == STM_STE_APE_ON_MICROSD)) { + if ((con_type != STM_STE_MODEM_ON_MICROSD) + && (con_type != STM_STE_APE_ON_MICROSD)) { + disable_vaux3_for_microsd_cable(); + disable_level_shifter_for_microsd(); + } } + + stm_current_connection = con_type; + +stm_ste_connection_error: return retval; } diff --git a/drivers/misc/stm.c b/drivers/misc/stm.c index a05b2d14573..53c47c1693a 100644 --- a/drivers/misc/stm.c +++ b/drivers/misc/stm.c @@ -73,6 +73,33 @@ static u64 stm_printk_buf[1024/sizeof(u64)]; static arch_spinlock_t stm_buf_lock = (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED; +static char *mipi60 = "none"; +module_param(mipi60, charp, S_IRUGO); +MODULE_PARM_DESC(mipi60, "STM Trace to output on probe2 of mipi60 " + "('none' or 'ape' or 'modem')"); + +static char *mipi34 = "none"; +module_param(mipi34, charp, S_IRUGO); +MODULE_PARM_DESC(mipi34, "STM Trace to output on mipi34 " + "('none' or 'ape' or 'modem')"); + +static char *microsd = "none"; +module_param(microsd, charp, S_IRUGO); +MODULE_PARM_DESC(microsd, "STM Trace to output on SD card connector " + "('none' or 'ape' or 'modem')"); + +static unsigned int stm_ter; +module_param(stm_ter, uint, 0); +MODULE_PARM_DESC(stm_ter, "Value for STM_TER (trace control register). " + "Should be set by user as environment variable stm.stm_ter"); + +#define IS_APE_ON_MIPI34 (mipi34 && !strcmp(mipi34, "ape")) +#define IS_APE_ON_MIPI60 (mipi60 && !strcmp(mipi60, "ape")) +#define IS_APE_ON_MICROSD (microsd && !strcmp(microsd, "ape")) +#define IS_MODEM_ON_MICROSD (microsd && !strcmp(microsd, "modem")) + +static int stm_connection_set(void *data, u64 val); + int stm_alloc_channel(int offset) { int channel; @@ -251,6 +278,7 @@ EXPORT_SYMBOL(stm_trace_buffer_onchannel); static int stm_open(struct inode *inode, struct file *file) { struct channel_data *channel_data; + int retval = 0; channel_data = kzalloc(sizeof(struct channel_data), GFP_KERNEL); if (channel_data == NULL) @@ -260,7 +288,19 @@ static int stm_open(struct inode *inode, struct file *file) channel_data->numero = -1; /* Channel not yet allocated */ file->private_data = channel_data; - return 0; + /* + * Check if microsd is selected as trace interface + * and enable corresponding pins muxing. + */ + if (IS_MODEM_ON_MICROSD) + retval = stm_connection_set(NULL, STM_STE_MODEM_ON_MICROSD); + else if (IS_APE_ON_MICROSD) + retval = stm_connection_set(NULL, STM_STE_APE_ON_MICROSD); + + if (retval) + pr_alert("stm_open: failed to connect STM output\n"); + + return retval; } static int stm_release(struct inode *inode, struct file *file) @@ -338,6 +378,11 @@ static void stm_enable_src(unsigned int v) cr_val = readl(STM_CR); cr_val &= ~STM_CLOCK_MASK; writel(cr_val|(stm_clockdiv<stm_connection) { retval = stm.pdata->stm_connection(stm_connection); if (retval) { @@ -661,11 +713,13 @@ static int stm_connection_show(void *data, u64 *val) static int stm_connection_set(void *data, u64 val) { + int retval = 0; + if (stm.pdata->stm_connection) { stm_connection = val; - stm.pdata->stm_connection(val); + retval = stm.pdata->stm_connection(val); } - return 0; + return retval; } DEFINE_SIMPLE_ATTRIBUTE(stm_connection_fops, stm_connection_show, diff --git a/include/trace/stm.h b/include/trace/stm.h index 72e9136c25e..3cf11143c0e 100644 --- a/include/trace/stm.h +++ b/include/trace/stm.h @@ -64,7 +64,10 @@ enum stm_connection_type { STM_DEFAULT_CONNECTION = 1, STM_STE_MODEM_ON_MIPI34_NONE_ON_MIPI60 = 2, STM_STE_APE_ON_MIPI34_NONE_ON_MIPI60 = 3, - STM_STE_MODEM_ON_MIPI34_APE_ON_MIPI60 = 4 + STM_STE_MODEM_ON_MIPI34_APE_ON_MIPI60 = 4, + STM_STE_MODEM_ON_MICROSD = 5, + STM_STE_APE_ON_MICROSD = 6, + STM_STE_INVALID_CONNECTION = 0xff }; #ifdef __KERNEL__ -- cgit v1.2.3