From 5e7257679cadf9a4acc340c8e8c1198c4a563d82 Mon Sep 17 00:00:00 2001 From: Ambresh K Date: Tue, 10 Jan 2012 09:02:06 +0530 Subject: OMAP4: HWMOD: UART1: disable smart-idle. UART module gets stuck in transition when smart-idle enabled. By enabling HWMOD_SWSUP_SIDLE flag in UART1 HWMOD, ensures that module's smart-idle feature is disabled and it is put to forced-idle and no-idle during pm-runtime. Seen similar issue with UART3 and was fixed by enabling HWMOD_SWSUP_SIDLE flag in uart3 HWMOD. Change-Id: Id1d97a498a5ffd7323be15be0ba8d0fc02e6df85 Signed-off-by: Ambresh K --- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 0cf5974..b5c5b10 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -5466,6 +5466,7 @@ static struct omap_hwmod_ocp_if *omap44xx_uart1_slaves[] = { static struct omap_hwmod omap44xx_uart1_hwmod = { .name = "uart1", .class = &omap44xx_uart_hwmod_class, + .flags = HWMOD_SWSUP_SIDLE, .mpu_irqs = omap44xx_uart1_irqs, .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_uart1_irqs), .sdma_reqs = omap44xx_uart1_sdma_reqs, -- cgit v1.1 From 2abeb4e5214dfa37705e3f0c26255846fdddd08b Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Wed, 14 Dec 2011 08:10:14 -0600 Subject: OMAP4: TWL: ensure PREQ1 results in all active VCOREs to be down Map VCORE1,2,3 appropriately to PREQ1 APP processor group so that only APP processor can control it's power down status when OFF mode is hit. Normally, OMAP sends a OFF voltage command to setup PMIC, However, it is equally important to ensure that TWL will switch off the relevant rail when the OFF voltage != 0. Change-Id: Id623ecdd26bee0504058132835e0112bac1a630e Signed-off-by: Nishanth Menon --- arch/arm/mach-omap2/omap_twl.c | 140 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c index f66cd2a..f8cd8f4 100644 --- a/arch/arm/mach-omap2/omap_twl.c +++ b/arch/arm/mach-omap2/omap_twl.c @@ -38,6 +38,24 @@ #define OMAP4_VDD_CORE_SR_VOLT_REG 0x61 #define OMAP4_VDD_CORE_SR_CMD_REG 0x62 +#define TWL6030_REG_VCORE1_CFG_GRP 0x52 +#define TWL6030_REG_VCORE1_CFG_TRANS 0x53 +#define TWL6030_REG_VCORE2_CFG_GRP 0x58 +#define TWL6030_REG_VCORE2_CFG_TRANS 0x59 +#define TWL6030_REG_VCORE3_CFG_GRP 0x5e +#define TWL6030_REG_VCORE3_CFG_TRANS 0x5f +#define TWL6030_BIT_APE_GRP BIT(0) +/* + * Setup CFG_TRANS mode as follows: + * 0x00 (OFF) when in OFF state(bit offset 4) and in sleep (bit offset 2) + * 0x01 (PWM/PFM Auto) when in ACTive state (bit offset 0) + * Dont trust Bootloader or reset values to set them up for kernel. + */ +#define TWL6030_REG_VCOREx_CFG_TRANS_MODE (0x00 << 4 | \ + 0x00 << 2 | \ + 0x01 << 0) +#define TWL6030_REG_VCOREx_CFG_TRANS_MODE_DESC "OFF=OFF SLEEP=OFF ACT=AUTO" + static bool is_offset_valid; static u8 smps_offset; /* @@ -50,6 +68,55 @@ static bool __initdata twl_sr_enable_autoinit; #define REG_SMPS_OFFSET 0xE0 #define SMARTREFLEX_ENABLE BIT(3) +/** + * struct twl_reg_setup_array - NULL terminated array giving configuration + * @addr: reg address to write to + * @val: value to write with + * @desc: description of this reg for error printing + * NOTE: a NULL pointer in this indicates end of array. + * + * VCORE register configurations as per need. + */ +struct twl_reg_setup_array { + u8 addr; + u8 val; + char *desc; +}; + +/** + * _twl_set_regs() - helper to setup a config array + * @gendesc: generic description - used with error message + * @sarray: NULL terminated array of configuration values + * + * Configures TWL with a set of values terminated. If any write fails, + * this continues till the last and returns back with the last error + * value. + */ +static int __init _twl_set_regs(char *gendesc, + struct twl_reg_setup_array *sarray) +{ + int i = 0; + int ret1; + int ret = 0; + + while (sarray->desc) { + ret1 = twl_i2c_write_u8(TWL6030_MODULE_ID0, + sarray->val, + sarray->addr); + if (ret1) { + pr_err("%s: %s: failed(%d), array index=%d, desc=%s, " + "reg=0x%02x, val=0x%02x\n", + __func__, gendesc, ret1, i, + sarray->desc, sarray->addr, sarray->val); + ret = ret1; + } + sarray++; + i++; + } + + return ret; +} + static unsigned long twl4030_vsel_to_uv(const u8 vsel) { return (((vsel * 125) + 6000)) * 100; @@ -302,6 +369,77 @@ static int __init twl_set_sr(struct voltagedomain *voltdm) return r; } + +/* OMAP4430 - All vcores: 1, 2 and 3 should go down with PREQ */ +static __initdata struct twl_reg_setup_array omap4430_twl6030_setup[] = { + { + .addr = TWL6030_REG_VCORE1_CFG_GRP, + .val = TWL6030_BIT_APE_GRP, + .desc = "Pull VCORE1 down along with App processor's PREQ1", + }, + { + .addr = TWL6030_REG_VCORE1_CFG_TRANS, + .val = TWL6030_REG_VCOREx_CFG_TRANS_MODE, + .desc = "VCORE1" TWL6030_REG_VCOREx_CFG_TRANS_MODE_DESC, + }, + { + .addr = TWL6030_REG_VCORE2_CFG_GRP, + .val = TWL6030_BIT_APE_GRP, + .desc = "Pull VCORE2 down along with App processor's PREQ1", + }, + { + .addr = TWL6030_REG_VCORE2_CFG_TRANS, + .val = TWL6030_REG_VCOREx_CFG_TRANS_MODE, + .desc = "VCORE2" TWL6030_REG_VCOREx_CFG_TRANS_MODE_DESC, + }, + { + .addr = TWL6030_REG_VCORE3_CFG_GRP, + .val = TWL6030_BIT_APE_GRP, + .desc = "Pull VCORE3 down along with App processor's PREQ1", + }, + { + .addr = TWL6030_REG_VCORE3_CFG_TRANS, + .val = TWL6030_REG_VCOREx_CFG_TRANS_MODE, + .desc = "VCORE3" TWL6030_REG_VCOREx_CFG_TRANS_MODE_DESC, + }, + { .desc = NULL} /* TERMINATOR */ +}; + +static int __init twl_set_4430vcore(struct voltagedomain *voltdm) +{ + return _twl_set_regs("OMAP4430 ", omap4430_twl6030_setup); +} + +/* OMAP4460 - VCORE3 is unused, 1 and 2 should go down with PREQ */ +static __initdata struct twl_reg_setup_array omap4460_twl6030_setup[] = { + { + .addr = TWL6030_REG_VCORE1_CFG_GRP, + .val = TWL6030_BIT_APE_GRP, + .desc = "Pull VCORE1 down along with App processor's PREQ1", + }, + { + .addr = TWL6030_REG_VCORE1_CFG_TRANS, + .val = TWL6030_REG_VCOREx_CFG_TRANS_MODE, + .desc = "VCORE1" TWL6030_REG_VCOREx_CFG_TRANS_MODE_DESC, + }, + { + .addr = TWL6030_REG_VCORE2_CFG_GRP, + .val = TWL6030_BIT_APE_GRP, + .desc = "Pull VCORE2 down along with App processor's PREQ1", + }, + { + .addr = TWL6030_REG_VCORE2_CFG_TRANS, + .val = TWL6030_REG_VCOREx_CFG_TRANS_MODE, + .desc = "VCORE2" TWL6030_REG_VCOREx_CFG_TRANS_MODE_DESC, + }, + { .desc = NULL} /* TERMINATOR */ +}; + +static int __init twl_set_4460vcore(struct voltagedomain *voltdm) +{ + return _twl_set_regs("OMAP4460 ", omap4460_twl6030_setup); +} + #define OMAP3_TWL4030_USED (CHIP_GE_OMAP3430ES2 | \ CHIP_GE_OMAP3630ES1_1 | \ CHIP_IS_OMAP3630ES1) @@ -327,11 +465,13 @@ static __initdata struct omap_pmic_map omap_twl_map[] = { .name = "core", .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP443X), .pmic_data = &omap443x_core_pmic, + .special_action = twl_set_4430vcore, }, { .name = "core", .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP446X), .pmic_data = &omap446x_core_pmic, + .special_action = twl_set_4460vcore, }, { .name = "iva", -- cgit v1.1 From 74ab8f91b7385871bdebe7c57bf11aa40988ed70 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Wed, 30 Nov 2011 03:15:13 -0600 Subject: OMAP4460: TWL6030: Setup VDD_core OFF voltage to retention voltage VDD_CORE must not be turned off before VDD_MPU due to OMAP4460 shifter/isolation implementation between MPU_VD and CORE_VD. Since PWR_REQ is being used for voltage control, this situation can be handled by using off voltage as retention voltage. This contributes to the dummy I2C_SR command to setup the voltage prior to the voltage going down to 0V for VDD_CORE along with PWR_REQ going low when device OFF mode is achieved. When device OFF mode is not achieved on an attempted OFF mode, this has no impact. Change-Id: Iceb41fbf6b361887c45eeba528ed7f836cff6482 Signed-off-by: Nishanth Menon --- arch/arm/mach-omap2/omap_twl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c index f8cd8f4..2d00a0c 100644 --- a/arch/arm/mach-omap2/omap_twl.c +++ b/arch/arm/mach-omap2/omap_twl.c @@ -330,7 +330,8 @@ static struct omap_voltdm_pmic omap446x_core_pmic = { .on_volt = 1200000, .onlp_volt = 1200000, .ret_volt = 830000, - .off_volt = 0, + /* OMAP4 + TWL + TPS limitation keep off_volt same as ret_volt */ + .off_volt = 830000, .volt_setup_time = 0, .switch_on_time = 549, .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET, -- cgit v1.1 From dd6f1606ff74a12e5ef8ed95f8e6bb655f4ed7a3 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Wed, 30 Nov 2011 02:58:13 -0600 Subject: OMAP4: PM: TPS6236x: ensure rampdown occurs fast on shutdown Enable the discharge capacitor to ensure ramp down occurs fast. Change-Id: I625b75e87e3a22239c14a3d22a3f7752999c05f1 Reported-by: Baek.Kyung-Han Signed-off-by: Nishanth Menon --- arch/arm/mach-omap2/omap_tps6236x.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/omap_tps6236x.c b/arch/arm/mach-omap2/omap_tps6236x.c index bfb5c00..8eff5e1 100644 --- a/arch/arm/mach-omap2/omap_tps6236x.c +++ b/arch/arm/mach-omap2/omap_tps6236x.c @@ -260,6 +260,9 @@ static int __init omap4_twl_tps62361_enable(struct voltagedomain *voltdm) /* We would like to ramp the voltage asap */ val |= REG_TPS6236X_RAMP_CTRL_RAMP_PFM; + /* We would like to ramp down the voltage asap as well*/ + val |= REG_TPS6236X_RAMP_CTRL_EN_DISC; + ret = omap_vc_bypass_send_i2c_msg(voltdm, voltdm->pmic->i2c_slave_addr, REG_TPS6236X_RAMP_CTRL, val); if (ret) -- cgit v1.1 From 24086fd101776098981ac97da917b9ec6acd0e65 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Fri, 16 Dec 2011 13:28:38 -0600 Subject: OMAP4: PM: TPS6236x: speed up voltage rampup rate Increase the voltage ramp rate to 32mv/uSec from 8mV/uSec This should fasten up our Voltage transition times and benefit latencies as well. Change-Id: I5246a75c2f7ec4cc187ba8ad63a7ad71c94616da Signed-off-by: Nishanth Menon --- arch/arm/mach-omap2/omap_tps6236x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/omap_tps6236x.c b/arch/arm/mach-omap2/omap_tps6236x.c index 8eff5e1..c369d7a 100644 --- a/arch/arm/mach-omap2/omap_tps6236x.c +++ b/arch/arm/mach-omap2/omap_tps6236x.c @@ -178,7 +178,7 @@ static u8 tps6236x_uv_to_vsel(unsigned long uv) } static struct omap_voltdm_pmic omap4_mpu_pmic = { - .slew_rate = 8000, + .slew_rate = 32000, .step_size = STEP_SIZE_TPS6236X, .on_volt = 1375000, .onlp_volt = 1375000, -- cgit v1.1 From 3966f20baf7f8898ee3125ae0f51febf3b329b52 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Fri, 16 Dec 2011 13:31:00 -0600 Subject: OMAP3+: PM: VC: vcbypass needs to wait for valid to clear valid bit is cleared when the command has been send to PMIC. Current code is waiting for the invert of this. fix the same. Change-Id: Ic9ae3b7a0c2f825edeb01e75602ee8fb07536900 Signed-off-by: Nishanth Menon --- arch/arm/mach-omap2/vc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c index 162ee9f..04a50fa 100644 --- a/arch/arm/mach-omap2/vc.c +++ b/arch/arm/mach-omap2/vc.c @@ -260,7 +260,7 @@ static int omap_vc_bypass_send_value(struct voltagedomain *voltdm, * NOTE: This is legacy code. The loop count and retry count needs * to be revisited. */ - while (!(vc_bypass_value & vc_valid)) { + while (vc_bypass_value & vc_valid) { loop_cnt++; if (retries_cnt > 10) { -- cgit v1.1 From 817c7dd8532bb5129550f912bd82a14bd088b362 Mon Sep 17 00:00:00 2001 From: Wenbiao Wang Date: Thu, 12 Jan 2012 21:45:15 -0600 Subject: OMAP4: PM: work around for CPU1 onlining from OFF/OSWR state on older PPA Originally detected in OMAP4430 ES2.3 HS samples, CPU1 crashes the device upon calling PPA service DEFAULT_POR_NS_SMP(0x25). Rootcause showed that cache maintenance operations required to be performed before handing over control of CPU1 to HLOS, were incomplete and not broadcasted from CPU0 to CPU1. Kernel workaround for this is to use WFI to put CPU1 in OFF state if CPU0 is not ready yet (this mechanism was in place in previous versions of this code base but was meant to address a different need). When putting CPU1 back to off, its internal MMU descriptors are reset and sync'd with CPU0. CPU1 is brought online by later kernel subsystems. Note: CPU0 power state is made to OFF for both OSWR and OFF modes. This issue has been analysed to impact all OMAP4 non GP devices. A config flag is introduced to allow platforms and distributions to enable/disable if PPA version requirement is not met. Change-Id: I82c5880ec2d9a98a54755dfbd01aa981cfed9852 [nm@ti.com, cileija@ti.com: improvements and rootcause support] Signed-off-by: Carlos Leija Signed-off-by: Nishanth Menon --- arch/arm/mach-omap2/Kconfig | 17 ++++++++++++++ arch/arm/mach-omap2/sleep44xx.S | 49 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 1cf7d51..a6de1b1 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -356,6 +356,23 @@ config OMAP_ALLOW_OSWR Which means the Logic of power domains can be lost now unlike the CSWR wherein the logic is retained +config OMAP4_PPA_CPU1_ONLINE_BUG + bool "Enable Support for CPU1 ONLINE WA for OSWR/OFF" + depends on ARCH_OMAP4 + depends on OMAP_ALLOW_OSWR + default y + help + If an non GP OMAP4 device is used and PPA revision is < v1.7.3, + the device does not perform the memory maintenance and TLB sync + operations required before releasing CPU1 to HLOS. This results + in crash while resuming from OFF mode. + + Disable this option *ONLY IF* you meet the minimum PPA version + requirement. + + If, on the other hand, you do not understand the change, leave the + default as enabled. + endmenu endif diff --git a/arch/arm/mach-omap2/sleep44xx.S b/arch/arm/mach-omap2/sleep44xx.S index 2b37f3b..b025e5f 100644 --- a/arch/arm/mach-omap2/sleep44xx.S +++ b/arch/arm/mach-omap2/sleep44xx.S @@ -346,6 +346,55 @@ ENTRY(omap4_cpu_resume) cmp r0, #1 @ is CPU0 already UP? beq ppa_cp15_cpu1_configure @ CPU1 HS go to next stage /* + * When CPU1 is released to control of HLOS in the case of OSWR + * and OFF mode, PPA below v1.7.3[1] is not performing all + * Memory coherency and TLB operations required. + * + * A WA to recover cleanly from this scenario is to switch CPU1 back to + * previous OFF state. This forces a reset of CPU1, which in turn + * forces CPU1 not to override MMU descriptors already in place in + * internal RAM setup by CPU0. CPU1 will also sync to the in-place + * descriptors on the next wakeup. CPU1 wakeup is done by + * later kernel subsystems depending on suspend or cpuidle path + * being exercised. + * NOTE - for OSWR, state provided is 2, and for OFF, state is 3, + * Since the bug impacts OFF and OSWR, we need to force a 0x3 to + * shut off CPU1 + * + * Since many distributions may not be able to update PPA OR would like + * to support platforms with older PPA, we provide a config option. + * This is simpler and makes the current code remain cleaner in + * comparison to a flag based handling in CPU1 recovery for + * board + PPA revision combinations. + * + * Having this config option enabled even on platforms with fixed PPA + * should not impact stability, however, ability to make CPU1 available + * for operations a little earlier is curtailed. + * + * Foot note [1]: + * v1.7.3 is the official TI PPA version. Custom PPA could have + * the relevant changes ported over to it. + */ +#ifdef CONFIG_OMAP4_PPA_CPU1_ONLINE_BUG + mov r0, #0x03 @ target CPU1 to OFF(mpusspd=OSWR/OFF) + mov r1, #0x00 @ Secure L1 is already clean + ldr r12, =SCU_POWER_SECURE_INDEX + dsb + smc #0 + + isb @ Necessary barriers before wfi + dsb + dmb + wfi @ wait for interrupt + nop + nop + + /* + * IF we came out of WFI immediately, something unknown happend. + * Fall through AND loop back to the checks. Failing which retry WFI. + */ +#endif + /* * CPU0 and CPU1 are release together from OFF mode, however, * CPU0 can be busy doing restore operations while waking * from OFF mode, However, for many PPA services we need -- cgit v1.1