From 865212abb5268d56ab5e1035426bbeebba01138e Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Mon, 7 Feb 2011 16:08:04 +0200 Subject: arm: mach-omap2: smartreflex: fix another memory leak Temporary strings with volt_* file names should be released after the debugfs entries are created. While at it, also simplify the string allocation, and use just snprintf() to create the name. The patch eliminates kmemleak reports with the following stack trace (multiple objects depending on HW): unreferenced object 0xcedbc5a0 (size 64): comm "swapper", pid 1, jiffies 4294929375 (age 423.734s) hex dump (first 32 bytes): 76 6f 6c 74 5f 39 37 35 30 30 30 00 00 00 00 00 volt_975000..... 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace: [] create_object+0x104/0x208 [] kmem_cache_alloc_trace+0xf0/0x17c [] omap_sr_probe+0x314/0x420 [] platform_drv_probe+0x18/0x1c [] driver_probe_device+0xc8/0x188 [] __driver_attach+0x68/0x8c [] bus_for_each_dev+0x44/0x74 [] bus_add_driver+0xa0/0x228 [] driver_register+0xa8/0x130 [] platform_driver_probe+0x18/0x8c [] sr_init+0x40/0x74 [] do_one_initcall+0xc8/0x1a0 [] kernel_init+0x150/0x218 [] kernel_thread_exit+0x0/0x8 [] 0xffffffff Signed-off-by: Aaro Koskinen Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/smartreflex.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) (limited to 'arch/arm/mach-omap2') diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c index 95ac336fe3f7..5a849c981733 100644 --- a/arch/arm/mach-omap2/smartreflex.c +++ b/arch/arm/mach-omap2/smartreflex.c @@ -926,19 +926,10 @@ static int __init omap_sr_probe(struct platform_device *pdev) } for (i = 0; i < sr_info->nvalue_count; i++) { - char *name; - char volt_name[32]; - - name = kzalloc(NVALUE_NAME_LEN + 1, GFP_KERNEL); - if (!name) { - dev_err(&pdev->dev, "%s: Unable to allocate memory" - " for n-value directory name\n", __func__); - return -ENOMEM; - } + char name[NVALUE_NAME_LEN + 1]; - strcpy(name, "volt_"); - sprintf(volt_name, "%d", volt_data[i].volt_nominal); - strcat(name, volt_name); + snprintf(name, sizeof(name), "volt_%d", + volt_data[i].volt_nominal); (void) debugfs_create_x32(name, S_IRUGO | S_IWUSR, nvalue_dir, &(sr_info->nvalue_table[i].nvalue)); } -- cgit v1.2.3 From b3329a33b5a3902e65c5517f41c374f5adb060e1 Mon Sep 17 00:00:00 2001 From: Shweta Gulati Date: Tue, 15 Feb 2011 13:40:30 +0530 Subject: OMAP2+: PM: SmartReflex: fix memory leaks in Smartreflex driver This Patch frees all the dynamically allocated memory which couldn't have been released in some error hitting cases. Signed-off-by: Shweta Gulati Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/smartreflex.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'arch/arm/mach-omap2') diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c index 5a849c981733..1a777e34d0c2 100644 --- a/arch/arm/mach-omap2/smartreflex.c +++ b/arch/arm/mach-omap2/smartreflex.c @@ -282,6 +282,7 @@ error: dev_err(&sr_info->pdev->dev, "%s: ERROR in registering" "interrupt handler. Smartreflex will" "not function as desired\n", __func__); + kfree(name); kfree(sr_info); return ret; } @@ -879,7 +880,7 @@ static int __init omap_sr_probe(struct platform_device *pdev) ret = sr_late_init(sr_info); if (ret) { pr_warning("%s: Error in SR late init\n", __func__); - return ret; + goto err_release_region; } } @@ -890,14 +891,17 @@ static int __init omap_sr_probe(struct platform_device *pdev) * not try to create rest of the debugfs entries. */ vdd_dbg_dir = omap_voltage_get_dbgdir(sr_info->voltdm); - if (!vdd_dbg_dir) - return -EINVAL; + if (!vdd_dbg_dir) { + ret = -EINVAL; + goto err_release_region; + } dbg_dir = debugfs_create_dir("smartreflex", vdd_dbg_dir); if (IS_ERR(dbg_dir)) { dev_err(&pdev->dev, "%s: Unable to create debugfs directory\n", __func__); - return PTR_ERR(dbg_dir); + ret = PTR_ERR(dbg_dir); + goto err_release_region; } (void) debugfs_create_file("autocomp", S_IRUGO | S_IWUSR, dbg_dir, @@ -913,7 +917,8 @@ static int __init omap_sr_probe(struct platform_device *pdev) if (IS_ERR(nvalue_dir)) { dev_err(&pdev->dev, "%s: Unable to create debugfs directory" "for n-values\n", __func__); - return PTR_ERR(nvalue_dir); + ret = PTR_ERR(nvalue_dir); + goto err_release_region; } omap_voltage_get_volttable(sr_info->voltdm, &volt_data); @@ -922,7 +927,8 @@ static int __init omap_sr_probe(struct platform_device *pdev) " corresponding vdd vdd_%s. Cannot create debugfs" "entries for n-values\n", __func__, sr_info->voltdm->name); - return -ENODATA; + ret = -ENODATA; + goto err_release_region; } for (i = 0; i < sr_info->nvalue_count; i++) { -- cgit v1.2.3 From 525a11381bcad9a7f55d0bac9c8676fe71819002 Mon Sep 17 00:00:00 2001 From: Hari Kanigeri Date: Wed, 2 Mar 2011 22:14:18 +0000 Subject: omap: mailbox: resolve hang issue omap4 interrupt disable bits is different. On rx kfifo full, the mbox rx interrupts wasn't getting disabled, and this is causing the rcm stress tests to hang. Signed-off-by: Hari Kanigeri Signed-off-by: Armando Uribe Signed-off-by: Fernando Guzman Lugo Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/mailbox.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'arch/arm/mach-omap2') diff --git a/arch/arm/mach-omap2/mailbox.c b/arch/arm/mach-omap2/mailbox.c index 0a585dfa9874..24b88504df0f 100644 --- a/arch/arm/mach-omap2/mailbox.c +++ b/arch/arm/mach-omap2/mailbox.c @@ -193,10 +193,12 @@ static void omap2_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_type_t irq) { struct omap_mbox2_priv *p = mbox->priv; - u32 l, bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; - l = mbox_read_reg(p->irqdisable); - l &= ~bit; - mbox_write_reg(l, p->irqdisable); + u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; + + if (!cpu_is_omap44xx()) + bit = mbox_read_reg(p->irqdisable) & ~bit; + + mbox_write_reg(bit, p->irqdisable); } static void omap2_mbox_ack_irq(struct omap_mbox *mbox, -- cgit v1.2.3 From e16b41bfd5efaa1f9521449f1f0e341ebec73398 Mon Sep 17 00:00:00 2001 From: Ricardo Salveti de Araujo Date: Mon, 31 Jan 2011 11:35:25 -0200 Subject: OMAP3630: PM: don't warn the user with a trace in case of PM34XX_ERRATUM In case in user has a OMAP3630 < ES1.2 the kernel should warn the user about the ERRATUM, but using pr_warn instead of WARN_ON is already enough, as there is nothing else the user can do besides changing the board. Signed-off-by: Ricardo Salveti de Araujo Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/cpuidle34xx.c | 2 +- arch/arm/mach-omap2/pm34xx.c | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'arch/arm/mach-omap2') diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c index f7b22a16f385..876eecab9f4d 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.c +++ b/arch/arm/mach-omap2/cpuidle34xx.c @@ -464,7 +464,7 @@ void omap_init_power_states(void) if (IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583)) { omap3_power_states[OMAP3_STATE_C7].valid = 0; cpuidle_params_table[OMAP3_STATE_C7].valid = 0; - WARN_ONCE(1, "%s: core off state C7 disabled due to i583\n", + pr_warn("%s: core off state C7 disabled due to i583\n", __func__); } } diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 2f864e4b085d..6ade4eaca922 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -928,8 +928,7 @@ void omap3_pm_off_mode_enable(int enable) pwrst->pwrdm == core_pwrdm && state == PWRDM_POWER_OFF) { pwrst->next_state = PWRDM_POWER_RET; - WARN_ONCE(1, - "%s: Core OFF disabled due to errata i583\n", + pr_warn("%s: Core OFF disabled due to errata i583\n", __func__); } else { pwrst->next_state = state; -- cgit v1.2.3 From eb05ead90ddb2a4e51d34f6c25f01c2e0653da59 Mon Sep 17 00:00:00 2001 From: "Menon, Nishanth" Date: Wed, 5 Jan 2011 20:49:35 +0000 Subject: OMAP3|4: OPP: make omapx_opp_init non-static omap3 and omap4 opp_init should be made non-static to allow for platform specific opp table tweaking. making these static conflicts with the definition in pm.h(global) as well. we include pm.h as well to ensure that there are no such prototype conflicts with actual implementation in the future. Signed-off-by: Nishanth Menon Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/opp3xxx_data.c | 3 ++- arch/arm/mach-omap2/opp4xxx_data.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'arch/arm/mach-omap2') diff --git a/arch/arm/mach-omap2/opp3xxx_data.c b/arch/arm/mach-omap2/opp3xxx_data.c index 0486fce8a92c..fd3a1af8d51e 100644 --- a/arch/arm/mach-omap2/opp3xxx_data.c +++ b/arch/arm/mach-omap2/opp3xxx_data.c @@ -21,6 +21,7 @@ #include #include "omap_opp_data.h" +#include "pm.h" static struct omap_opp_def __initdata omap34xx_opp_def_list[] = { /* MPU OPP1 */ @@ -88,7 +89,7 @@ static struct omap_opp_def __initdata omap36xx_opp_def_list[] = { /** * omap3_opp_init() - initialize omap3 opp table */ -static int __init omap3_opp_init(void) +int __init omap3_opp_init(void) { int r = -ENODEV; diff --git a/arch/arm/mach-omap2/opp4xxx_data.c b/arch/arm/mach-omap2/opp4xxx_data.c index a11fa566d8ee..f0e9939a7217 100644 --- a/arch/arm/mach-omap2/opp4xxx_data.c +++ b/arch/arm/mach-omap2/opp4xxx_data.c @@ -22,6 +22,7 @@ #include #include "omap_opp_data.h" +#include "pm.h" static struct omap_opp_def __initdata omap44xx_opp_def_list[] = { /* MPU OPP1 - OPP50 */ @@ -42,7 +43,7 @@ static struct omap_opp_def __initdata omap44xx_opp_def_list[] = { /** * omap4_opp_init() - initialize omap4 opp table */ -static int __init omap4_opp_init(void) +int __init omap4_opp_init(void) { int r = -ENODEV; -- cgit v1.2.3 From 8743410d4971c5510a7d09293f5f3f89d8081059 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Fri, 7 Jan 2011 09:41:13 -0600 Subject: OMAP3: beagle xm: enable up to 800MHz OPP OMP3630 silicon can enable higher frequencies only depending on the board characteristics meeting the recommended standards, and has to be selectively toggled. Beagle XM uses 3730 variant and the board design allows enabling 800MHz and 1GHz OPPs. However, We need Smart reflex class 1.5 and ABB to enable 1GHz safely. For the moment, we tweak the default table to allow for 800Mhz OPP usage. Reported-by: Koen Kooi Tested-by: Koen Kooi Signed-off-by: Nishanth Menon Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/board-omap3beagle.c | 50 +++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'arch/arm/mach-omap2') diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index 46d814ab5656..91b4e1438aec 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -45,10 +46,12 @@ #include #include #include +#include #include "mux.h" #include "hsmmc.h" #include "timer-gp.h" +#include "pm.h" #define NAND_BLOCK_SIZE SZ_128K @@ -610,6 +613,52 @@ static struct omap_musb_board_data musb_board_data = { .power = 100, }; +static void __init beagle_opp_init(void) +{ + int r = 0; + + /* Initialize the omap3 opp table */ + if (omap3_opp_init()) { + pr_err("%s: opp default init failed\n", __func__); + return; + } + + /* Custom OPP enabled for XM */ + if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) { + struct omap_hwmod *mh = omap_hwmod_lookup("mpu"); + struct omap_hwmod *dh = omap_hwmod_lookup("iva"); + struct device *dev; + + if (!mh || !dh) { + pr_err("%s: Aiee.. no mpu/dsp devices? %p %p\n", + __func__, mh, dh); + return; + } + /* Enable MPU 1GHz and lower opps */ + dev = &mh->od->pdev.dev; + r = opp_enable(dev, 800000000); + /* TODO: MPU 1GHz needs SR and ABB */ + + /* Enable IVA 800MHz and lower opps */ + dev = &dh->od->pdev.dev; + r |= opp_enable(dev, 660000000); + /* TODO: DSP 800MHz needs SR and ABB */ + if (r) { + pr_err("%s: failed to enable higher opp %d\n", + __func__, r); + /* + * Cleanup - disable the higher freqs - we dont care + * about the results + */ + dev = &mh->od->pdev.dev; + opp_disable(dev, 800000000); + dev = &dh->od->pdev.dev; + opp_disable(dev, 660000000); + } + } + return; +} + static void __init omap3_beagle_init(void) { omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); @@ -633,6 +682,7 @@ static void __init omap3_beagle_init(void) omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT); beagle_display_init(); + beagle_opp_init(); } MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board") -- cgit v1.2.3 From 5c56f32e80ac8ea9878a0a5eb9ca99c703e953ab Mon Sep 17 00:00:00 2001 From: Vasiliy Kulikov Date: Wed, 19 Jan 2011 15:57:22 +0300 Subject: OMAP: PM: SmartReflex: fix potential NULL dereference kzalloc() may fail, if so return -ENOMEM. Also Walter Harms suggested to use kasprintf() instead of kzalloc+strcpy+strcat. Signed-off-by: Vasiliy Kulikov Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/smartreflex.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'arch/arm/mach-omap2') diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c index 1a777e34d0c2..b57ae502e0c7 100644 --- a/arch/arm/mach-omap2/smartreflex.c +++ b/arch/arm/mach-omap2/smartreflex.c @@ -260,9 +260,11 @@ static int sr_late_init(struct omap_sr *sr_info) if (sr_class->class_type == SR_CLASS2 && sr_class->notify_flags && sr_info->irq) { - name = kzalloc(SMARTREFLEX_NAME_LEN + 1, GFP_KERNEL); - strcpy(name, "sr_"); - strcat(name, sr_info->voltdm->name); + name = kasprintf(GFP_KERNEL, "sr_%s", sr_info->voltdm->name); + if (name == NULL) { + ret = -ENOMEM; + goto error; + } ret = request_irq(sr_info->irq, sr_interrupt, 0, name, (void *)sr_info); if (ret) -- cgit v1.2.3 From df93bd76b61639fe9093ccbfc5d1a4bfb744ec47 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Fri, 21 Jan 2011 14:30:15 -0800 Subject: OMAP2+: remove unused UART base addresses from omap_globals Now that omap_hwmod + omap_device is used for OMAP UART device and driver code, we no longer need the UART physical addresses in omap_globals. Note that the #defines for the base addresses are still left in since they are used by DEBUG_LL and uncompress code. Build tested for OMAP1 (omap1_defconfig) and OMAP2+ (omap2plus_defconfig) Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/common.c | 14 -------------- arch/arm/plat-omap/include/plat/common.h | 4 ---- 2 files changed, 18 deletions(-) (limited to 'arch/arm/mach-omap2') diff --git a/arch/arm/mach-omap2/common.c b/arch/arm/mach-omap2/common.c index 778929f7e92d..994f0f00c704 100644 --- a/arch/arm/mach-omap2/common.c +++ b/arch/arm/mach-omap2/common.c @@ -50,9 +50,6 @@ static struct omap_globals omap242x_globals = { .ctrl = OMAP242X_CTRL_BASE, .prm = OMAP2420_PRM_BASE, .cm = OMAP2420_CM_BASE, - .uart1_phys = OMAP2_UART1_BASE, - .uart2_phys = OMAP2_UART2_BASE, - .uart3_phys = OMAP2_UART3_BASE, }; void __init omap2_set_globals_242x(void) @@ -71,9 +68,6 @@ static struct omap_globals omap243x_globals = { .ctrl = OMAP243X_CTRL_BASE, .prm = OMAP2430_PRM_BASE, .cm = OMAP2430_CM_BASE, - .uart1_phys = OMAP2_UART1_BASE, - .uart2_phys = OMAP2_UART2_BASE, - .uart3_phys = OMAP2_UART3_BASE, }; void __init omap2_set_globals_243x(void) @@ -92,10 +86,6 @@ static struct omap_globals omap3_globals = { .ctrl = OMAP343X_CTRL_BASE, .prm = OMAP3430_PRM_BASE, .cm = OMAP3430_CM_BASE, - .uart1_phys = OMAP3_UART1_BASE, - .uart2_phys = OMAP3_UART2_BASE, - .uart3_phys = OMAP3_UART3_BASE, - .uart4_phys = OMAP3_UART4_BASE, /* Only on 3630 */ }; void __init omap2_set_globals_3xxx(void) @@ -119,10 +109,6 @@ static struct omap_globals omap4_globals = { .prm = OMAP4430_PRM_BASE, .cm = OMAP4430_CM_BASE, .cm2 = OMAP4430_CM2_BASE, - .uart1_phys = OMAP4_UART1_BASE, - .uart2_phys = OMAP4_UART2_BASE, - .uart3_phys = OMAP4_UART3_BASE, - .uart4_phys = OMAP4_UART4_BASE, }; void __init omap2_set_globals_443x(void) diff --git a/arch/arm/plat-omap/include/plat/common.h b/arch/arm/plat-omap/include/plat/common.h index 29b2afb4288f..1b8095bb8d00 100644 --- a/arch/arm/plat-omap/include/plat/common.h +++ b/arch/arm/plat-omap/include/plat/common.h @@ -56,10 +56,6 @@ struct omap_globals { unsigned long prm; /* Power and Reset Management */ unsigned long cm; /* Clock Management */ unsigned long cm2; - unsigned long uart1_phys; - unsigned long uart2_phys; - unsigned long uart3_phys; - unsigned long uart4_phys; }; void omap2_set_globals_242x(void); -- cgit v1.2.3 From 51d070afd6f927752c76a0cc537c73737578bb93 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Thu, 27 Jan 2011 02:52:55 -0700 Subject: OMAP2/3: PM: remove unnecessary wakeup/sleep dependency clear The OMAP2 and OMAP3 PM code clears clockdomain wakeup and sleep dependencies. This is unnecessary after commit 6f7f63cc9adf3192e6fcac4e8bed5cc10fd924aa ("OMAP clockdomain: initialize clockdomain registers when the clockdomain layer starts") which clears these dependencies during clockdomain init. Signed-off-by: Paul Walmsley Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/pm24xx.c | 8 +------- arch/arm/mach-omap2/pm34xx.c | 15 --------------- 2 files changed, 1 insertion(+), 22 deletions(-) (limited to 'arch/arm/mach-omap2') diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c index 97feb3ab6a69..10f8747ba572 100644 --- a/arch/arm/mach-omap2/pm24xx.c +++ b/arch/arm/mach-omap2/pm24xx.c @@ -363,9 +363,6 @@ static const struct platform_suspend_ops __initdata omap_pm_ops; /* XXX This function should be shareable between OMAP2xxx and OMAP3 */ static int __init clkdms_setup(struct clockdomain *clkdm, void *unused) { - clkdm_clear_all_wkdeps(clkdm); - clkdm_clear_all_sleepdeps(clkdm); - if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO) omap2_clkdm_allow_idle(clkdm); else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP && @@ -411,10 +408,7 @@ static void __init prcm_setup_regs(void) pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF); omap2_clkdm_sleep(gfx_clkdm); - /* - * Clear clockdomain wakeup dependencies and enable - * hardware-supervised idle for all clkdms - */ + /* Enable hardware-supervised idle for all clkdms */ clkdm_for_each(clkdms_setup, NULL); clkdm_add_wkdep(mpu_clkdm, wkup_clkdm); diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 6ade4eaca922..b9427c75f427 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -695,21 +695,6 @@ static void __init prcm_setup_regs(void) u32 omap3630_grpsel_uart4_mask = cpu_is_omap3630() ? OMAP3630_GRPSEL_UART4_MASK : 0; - - /* XXX Reset all wkdeps. This should be done when initializing - * powerdomains */ - omap2_prm_write_mod_reg(0, OMAP3430_IVA2_MOD, PM_WKDEP); - omap2_prm_write_mod_reg(0, MPU_MOD, PM_WKDEP); - omap2_prm_write_mod_reg(0, OMAP3430_DSS_MOD, PM_WKDEP); - omap2_prm_write_mod_reg(0, OMAP3430_NEON_MOD, PM_WKDEP); - omap2_prm_write_mod_reg(0, OMAP3430_CAM_MOD, PM_WKDEP); - omap2_prm_write_mod_reg(0, OMAP3430_PER_MOD, PM_WKDEP); - if (omap_rev() > OMAP3430_REV_ES1_0) { - omap2_prm_write_mod_reg(0, OMAP3430ES2_SGX_MOD, PM_WKDEP); - omap2_prm_write_mod_reg(0, OMAP3430ES2_USBHOST_MOD, PM_WKDEP); - } else - omap2_prm_write_mod_reg(0, GFX_MOD, PM_WKDEP); - /* * Enable interface clock autoidle for all modules. * Note that in the long run this should be done by clockfw -- cgit v1.2.3 From 261bfb286eab32aa6129f48d2b2d24f20825757b Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Fri, 11 Feb 2011 20:42:11 +0530 Subject: omap3: pm: Use exported set_cr() instead of a custom one. Remove the custom restore_control_register() and use the exported set_cr() instead to set the system control register(SCTRL) value. No functional change. Signed-off-by: Santosh Shilimkar Cc: Kevin Hilman Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/pm34xx.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'arch/arm/mach-omap2') diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index b9427c75f427..1883a464aace 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -311,11 +311,6 @@ static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id) return IRQ_HANDLED; } -static void restore_control_register(u32 val) -{ - __asm__ __volatile__ ("mcr p15, 0, %0, c1, c0, 0" : : "r" (val)); -} - /* Function to restore the table entry that was modified for enabling MMU */ static void restore_table_entry(void) { @@ -337,7 +332,7 @@ static void restore_table_entry(void) control_reg_value = __raw_readl(scratchpad_address + OMAP343X_CONTROL_REG_VALUE_OFFSET); /* This will enable caches and prediction */ - restore_control_register(control_reg_value); + set_cr(control_reg_value); } void omap_sram_idle(void) -- cgit v1.2.3 From 8c5ca4d29bf44eb4eb004683ca745742040c7486 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Fri, 11 Feb 2011 20:42:12 +0530 Subject: omap3: cpuidle: Add description field to each C-state. Add a description field to each idle C-state. This helps to give better data with PowerTop and one don't have to refer to the code to link what Cx means from system point of view while analysing PowerTop data. No functional change. Signed-off-by: Santosh Shilimkar Cc: Kevin Hilman Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/cpuidle34xx.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'arch/arm/mach-omap2') diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c index 876eecab9f4d..cba437dd002b 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.c +++ b/arch/arm/mach-omap2/cpuidle34xx.c @@ -58,6 +58,7 @@ struct omap3_processor_cx { u32 core_state; u32 threshold; u32 flags; + const char *desc; }; struct omap3_processor_cx omap3_power_states[OMAP3_MAX_STATES]; @@ -365,6 +366,7 @@ void omap_init_power_states(void) omap3_power_states[OMAP3_STATE_C1].mpu_state = PWRDM_POWER_ON; omap3_power_states[OMAP3_STATE_C1].core_state = PWRDM_POWER_ON; omap3_power_states[OMAP3_STATE_C1].flags = CPUIDLE_FLAG_TIME_VALID; + omap3_power_states[OMAP3_STATE_C1].desc = "MPU ON + CORE ON"; /* C2 . MPU WFI + Core inactive */ omap3_power_states[OMAP3_STATE_C2].valid = @@ -380,6 +382,7 @@ void omap_init_power_states(void) omap3_power_states[OMAP3_STATE_C2].core_state = PWRDM_POWER_ON; omap3_power_states[OMAP3_STATE_C2].flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_CHECK_BM; + omap3_power_states[OMAP3_STATE_C2].desc = "MPU ON + CORE ON"; /* C3 . MPU CSWR + Core inactive */ omap3_power_states[OMAP3_STATE_C3].valid = @@ -395,6 +398,7 @@ void omap_init_power_states(void) omap3_power_states[OMAP3_STATE_C3].core_state = PWRDM_POWER_ON; omap3_power_states[OMAP3_STATE_C3].flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_CHECK_BM; + omap3_power_states[OMAP3_STATE_C3].desc = "MPU RET + CORE ON"; /* C4 . MPU OFF + Core inactive */ omap3_power_states[OMAP3_STATE_C4].valid = @@ -410,6 +414,7 @@ void omap_init_power_states(void) omap3_power_states[OMAP3_STATE_C4].core_state = PWRDM_POWER_ON; omap3_power_states[OMAP3_STATE_C4].flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_CHECK_BM; + omap3_power_states[OMAP3_STATE_C4].desc = "MPU OFF + CORE ON"; /* C5 . MPU CSWR + Core CSWR*/ omap3_power_states[OMAP3_STATE_C5].valid = @@ -425,6 +430,7 @@ void omap_init_power_states(void) omap3_power_states[OMAP3_STATE_C5].core_state = PWRDM_POWER_RET; omap3_power_states[OMAP3_STATE_C5].flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_CHECK_BM; + omap3_power_states[OMAP3_STATE_C5].desc = "MPU RET + CORE RET"; /* C6 . MPU OFF + Core CSWR */ omap3_power_states[OMAP3_STATE_C6].valid = @@ -440,6 +446,7 @@ void omap_init_power_states(void) omap3_power_states[OMAP3_STATE_C6].core_state = PWRDM_POWER_RET; omap3_power_states[OMAP3_STATE_C6].flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_CHECK_BM; + omap3_power_states[OMAP3_STATE_C6].desc = "MPU OFF + CORE RET"; /* C7 . MPU OFF + Core OFF */ omap3_power_states[OMAP3_STATE_C7].valid = @@ -455,6 +462,7 @@ void omap_init_power_states(void) omap3_power_states[OMAP3_STATE_C7].core_state = PWRDM_POWER_OFF; omap3_power_states[OMAP3_STATE_C7].flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_CHECK_BM; + omap3_power_states[OMAP3_STATE_C7].desc = "MPU OFF + CORE OFF"; /* * Erratum i583: implementation for ES rev < Es1.2 on 3630. We cannot @@ -512,6 +520,7 @@ int __init omap3_idle_init(void) if (cx->type == OMAP3_STATE_C1) dev->safe_state = state; sprintf(state->name, "C%d", count+1); + strncpy(state->desc, cx->desc, CPUIDLE_DESC_LEN); count++; } -- cgit v1.2.3 From 4071318983ff2dead7fd2caf85498bcd8956d93e Mon Sep 17 00:00:00 2001 From: Thara Gopinath Date: Tue, 15 Feb 2011 13:28:58 +0530 Subject: OMAP3: PM: Set/clear T2 bit for Smartreflex on TWL Voltage control on TWL can be done using VMODE/I2C1/I2C_SR. Since almost all platforms use I2C_SR on omap3, omap3_twl_init by default expects that OMAP's I2C_SR is plugged in to TWL's I2C and calls omap3_twl_set_sr_bit. On platforms where I2C_SR is not connected, the board files are expected to call omap3_twl_set_sr_bit(false) to ensure that I2C_SR path is not set for voltage control and prevent the default behavior of omap3_twl_init. Signed-off-by: Nishanth Menon Signed-off-by: Thara Gopinath Signed-off-by: Shweta Gulati Cc: linux-arm-kernel@lists.infradead.org Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/omap_twl.c | 60 ++++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-omap2/pm.h | 1 + 2 files changed, 61 insertions(+) (limited to 'arch/arm/mach-omap2') diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c index 00e1d2b53683..b341c36a93f3 100644 --- a/arch/arm/mach-omap2/omap_twl.c +++ b/arch/arm/mach-omap2/omap_twl.c @@ -59,8 +59,15 @@ static bool is_offset_valid; static u8 smps_offset; +/* + * Flag to ensure Smartreflex bit in TWL + * being cleared in board file is not overwritten. + */ +static bool __initdata twl_sr_enable_autoinit; +#define TWL4030_DCDC_GLOBAL_CFG 0x06 #define REG_SMPS_OFFSET 0xE0 +#define SMARTREFLEX_ENABLE BIT(3) static unsigned long twl4030_vsel_to_uv(const u8 vsel) { @@ -269,6 +276,18 @@ int __init omap3_twl_init(void) omap3_core_volt_info.vp_vddmax = OMAP3630_VP2_VLIMITTO_VDDMAX; } + /* + * The smartreflex bit on twl4030 specifies if the setting of voltage + * is done over the I2C_SR path. Since this setting is independent of + * the actual usage of smartreflex AVS module, we enable TWL SR bit + * by default irrespective of whether smartreflex AVS module is enabled + * on the OMAP side or not. This is because without this bit enabled, + * the voltage scaling through vp forceupdate/bypass mechanism of + * voltage scaling will not function on TWL over I2C_SR. + */ + if (!twl_sr_enable_autoinit) + omap3_twl_set_sr_bit(true); + voltdm = omap_voltage_domain_lookup("mpu"); omap_voltage_register_pmic(voltdm, &omap3_mpu_volt_info); @@ -277,3 +296,44 @@ int __init omap3_twl_init(void) return 0; } + +/** + * omap3_twl_set_sr_bit() - Set/Clear SR bit on TWL + * @enable: enable SR mode in twl or not + * + * If 'enable' is true, enables Smartreflex bit on TWL 4030 to make sure + * voltage scaling through OMAP SR works. Else, the smartreflex bit + * on twl4030 is cleared as there are platforms which use OMAP3 and T2 but + * use Synchronized Scaling Hardware Strategy (ENABLE_VMODE=1) and Direct + * Strategy Software Scaling Mode (ENABLE_VMODE=0), for setting the voltages, + * in those scenarios this bit is to be cleared (enable = false). + * + * Returns 0 on sucess, error is returned if I2C read/write fails. + */ +int __init omap3_twl_set_sr_bit(bool enable) +{ + u8 temp; + int ret; + if (twl_sr_enable_autoinit) + pr_warning("%s: unexpected multiple calls\n", __func__); + + ret = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &temp, + TWL4030_DCDC_GLOBAL_CFG); + if (ret) + goto err; + + if (enable) + temp |= SMARTREFLEX_ENABLE; + else + temp &= ~SMARTREFLEX_ENABLE; + + ret = twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, temp, + TWL4030_DCDC_GLOBAL_CFG); + if (!ret) { + twl_sr_enable_autoinit = true; + return 0; + } +err: + pr_err("%s: Error access to TWL4030 (%d)\n", __func__, ret); + return ret; +} diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h index 1c1b0ab5b978..f4a5f716422b 100644 --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h @@ -127,6 +127,7 @@ static inline void omap_enable_smartreflex_on_init(void) {} #ifdef CONFIG_TWL4030_CORE extern int omap3_twl_init(void); extern int omap4_twl_init(void); +extern int omap3_twl_set_sr_bit(bool enable); #else static inline int omap3_twl_init(void) { -- cgit v1.2.3 From 2de0baefaa7f2fad221bba6049e389e39990e2f0 Mon Sep 17 00:00:00 2001 From: Sanjeev Premi Date: Fri, 25 Feb 2011 18:57:20 +0530 Subject: OMAP3: PM: Initialize IVA only if available IVA device is not present in many OMAP3 variants. This patch ensures that initialization is tied to the presence of IVA on the device. Signed-off-by: Sanjeev Premi Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/pm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'arch/arm/mach-omap2') diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index d5a102c71989..6e4eb7ff95a8 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -83,7 +83,9 @@ static int _init_omap_device(char *name, struct device **new_dev) static void omap2_init_processor_devices(void) { _init_omap_device("mpu", &mpu_dev); - _init_omap_device("iva", &iva_dev); + if (omap3_has_iva()) + _init_omap_device("iva", &iva_dev); + if (cpu_is_omap44xx()) { _init_omap_device("l3_main_1", &l3_dev); _init_omap_device("dsp", &dsp_dev); -- cgit v1.2.3 From 85243a762457f7891ae525df39ad44323b3eeea6 Mon Sep 17 00:00:00 2001 From: Dave Martin Date: Fri, 4 Mar 2011 15:33:53 +0000 Subject: ARM: omap4: Provide do_wfi() for Thumb-2 For CONFIG_THUMB2_KERNEL, the existing definition of do_wfi() will insert invalid code into the instruction stream. Any assembler which can assemble Thumb-2 is guaranteed to accept the "wfi" mnemonic, so for the Thumb-2 case, just use the mnemonic. The ARM case is left as-is. Signed-off-by: Dave Martin Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/include/mach/omap4-common.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch/arm/mach-omap2') diff --git a/arch/arm/mach-omap2/include/mach/omap4-common.h b/arch/arm/mach-omap2/include/mach/omap4-common.h index 5b0270b28934..de441c05a6a6 100644 --- a/arch/arm/mach-omap2/include/mach/omap4-common.h +++ b/arch/arm/mach-omap2/include/mach/omap4-common.h @@ -17,8 +17,12 @@ * wfi used in low power code. Directly opcode is used instead * of instruction to avoid mulit-omap build break */ +#ifdef CONFIG_THUMB2_KERNEL +#define do_wfi() __asm__ __volatile__ ("wfi" : : : "memory") +#else #define do_wfi() \ __asm__ __volatile__ (".word 0xe320f003" : : : "memory") +#endif #ifdef CONFIG_CACHE_L2X0 extern void __iomem *l2cache_base; -- cgit v1.2.3 From f96bdfa0d036393741fce303ea98abb44452d042 Mon Sep 17 00:00:00 2001 From: Dave Martin Date: Fri, 4 Mar 2011 15:33:54 +0000 Subject: ARM: omap4: Convert END() to ENDPROC() for correct linkage with CONFIG_THUMB2_KERNEL Code marked with ENTRY() also needs a matching ENDPROC() directive, in order to ensure that the type and instruction set of the symbol are correctly annotated. ENDPROC() tags the affected symbol as a function symbol, which will ensure that link-time fixups don't accidentally switch to the wrong instruction set. Signed-off-by: Dave Martin Tested-by: Santosh Shilimkar Acked-by: Santosh Shilimkar Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/omap-headsmp.S | 2 +- arch/arm/mach-omap2/omap44xx-smc.S | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'arch/arm/mach-omap2') diff --git a/arch/arm/mach-omap2/omap-headsmp.S b/arch/arm/mach-omap2/omap-headsmp.S index 6ae937a06cc1..4ee6aeca885a 100644 --- a/arch/arm/mach-omap2/omap-headsmp.S +++ b/arch/arm/mach-omap2/omap-headsmp.S @@ -45,5 +45,5 @@ hold: ldr r12,=0x103 * should now contain the SVC stack for this core */ b secondary_startup -END(omap_secondary_startup) +ENDPROC(omap_secondary_startup) diff --git a/arch/arm/mach-omap2/omap44xx-smc.S b/arch/arm/mach-omap2/omap44xx-smc.S index 1980dc31a1a2..e69d37d95204 100644 --- a/arch/arm/mach-omap2/omap44xx-smc.S +++ b/arch/arm/mach-omap2/omap44xx-smc.S @@ -29,7 +29,7 @@ ENTRY(omap_smc1) dsb smc #0 ldmfd sp!, {r2-r12, pc} -END(omap_smc1) +ENDPROC(omap_smc1) ENTRY(omap_modify_auxcoreboot0) stmfd sp!, {r1-r12, lr} @@ -37,7 +37,7 @@ ENTRY(omap_modify_auxcoreboot0) dsb smc #0 ldmfd sp!, {r1-r12, pc} -END(omap_modify_auxcoreboot0) +ENDPROC(omap_modify_auxcoreboot0) ENTRY(omap_auxcoreboot_addr) stmfd sp!, {r2-r12, lr} @@ -45,7 +45,7 @@ ENTRY(omap_auxcoreboot_addr) dsb smc #0 ldmfd sp!, {r2-r12, pc} -END(omap_auxcoreboot_addr) +ENDPROC(omap_auxcoreboot_addr) ENTRY(omap_read_auxcoreboot0) stmfd sp!, {r2-r12, lr} @@ -54,4 +54,4 @@ ENTRY(omap_read_auxcoreboot0) smc #0 mov r0, r0, lsr #9 ldmfd sp!, {r2-r12, pc} -END(omap_read_auxcoreboot0) +ENDPROC(omap_read_auxcoreboot0) -- cgit v1.2.3 From 76d500182061dcc7508e6b829af097348fa7d804 Mon Sep 17 00:00:00 2001 From: Dave Martin Date: Fri, 4 Mar 2011 15:33:55 +0000 Subject: ARM: omap3: Remove hand-encoded SMC instructions For various reasons, Linux now only officially supports being built with tools which are new enough to understand the SMC instruction. Replacing the hand-encoded instructions when the mnemonic also allows for correct assembly in Thumb-2 (otherwise, the result is random data in the middle of the code). The Makefile already ensures that this file is built with a high enough gcc -march= flag (armv7-a). Signed-off-by: Dave Martin Tested-by: Santosh Shilimkar Tested-by: Jean Pihet Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/sleep34xx.S | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'arch/arm/mach-omap2') diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S index 98d8232808b8..a05c348885ac 100644 --- a/arch/arm/mach-omap2/sleep34xx.S +++ b/arch/arm/mach-omap2/sleep34xx.S @@ -133,7 +133,7 @@ ENTRY(save_secure_ram_context) mov r6, #0xff mcr p15, 0, r0, c7, c10, 4 @ data write barrier mcr p15, 0, r0, c7, c10, 5 @ data memory barrier - .word 0xE1600071 @ call SMI monitor (smi #1) + smc #1 @ call SMI monitor (smi #1) nop nop nop @@ -408,7 +408,7 @@ skipl2dis: adr r3, l2_inv_api_params @ r3 points to dummy parameters mcr p15, 0, r0, c7, c10, 4 @ data write barrier mcr p15, 0, r0, c7, c10, 5 @ data memory barrier - .word 0xE1600071 @ call SMI monitor (smi #1) + smc #1 @ call SMI monitor (smi #1) /* Write to Aux control register to set some bits */ mov r0, #42 @ set service ID for PPA mov r12, r0 @ copy secure Service ID in r12 @@ -419,7 +419,7 @@ skipl2dis: ldr r3, [r4, #0xBC] @ r3 points to parameters mcr p15, 0, r0, c7, c10, 4 @ data write barrier mcr p15, 0, r0, c7, c10, 5 @ data memory barrier - .word 0xE1600071 @ call SMI monitor (smi #1) + smc #1 @ call SMI monitor (smi #1) #ifdef CONFIG_OMAP3_L2_AUX_SECURE_SAVE_RESTORE /* Restore L2 aux control register */ @@ -434,7 +434,7 @@ skipl2dis: adds r3, r3, #8 @ r3 points to parameters mcr p15, 0, r0, c7, c10, 4 @ data write barrier mcr p15, 0, r0, c7, c10, 5 @ data memory barrier - .word 0xE1600071 @ call SMI monitor (smi #1) + smc #1 @ call SMI monitor (smi #1) #endif b logic_l1_restore @@ -443,18 +443,18 @@ l2_inv_api_params: l2_inv_gp: /* Execute smi to invalidate L2 cache */ mov r12, #0x1 @ set up to invalidate L2 - .word 0xE1600070 @ Call SMI monitor (smieq) + smc #0 @ Call SMI monitor (smieq) /* Write to Aux control register to set some bits */ ldr r4, scratchpad_base ldr r3, [r4,#0xBC] ldr r0, [r3,#4] mov r12, #0x3 - .word 0xE1600070 @ Call SMI monitor (smieq) + smc #0 @ Call SMI monitor (smieq) ldr r4, scratchpad_base ldr r3, [r4,#0xBC] ldr r0, [r3,#12] mov r12, #0x2 - .word 0xE1600070 @ Call SMI monitor (smieq) + smc #0 @ Call SMI monitor (smieq) logic_l1_restore: ldr r1, l2dis_3630 cmp r1, #0x1 @ Test if L2 re-enable needed on 3630 -- cgit v1.2.3 From ef7a87d34064eb87866d02547ee67060e5e49eb9 Mon Sep 17 00:00:00 2001 From: Dave Martin Date: Fri, 4 Mar 2011 15:33:56 +0000 Subject: ARM: omap3: Thumb-2 compatibility for sram34xx.S * Build unconditionally as ARM for correct interoperation with OMAP firmware. * Remove deprecated PC-relative stores * Add the required ENDPROC() directive for each ENTRY(). * .align before data words Signed-off-by: Dave Martin Tested-by: Jean Pihet Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/sram34xx.S | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) (limited to 'arch/arm/mach-omap2') diff --git a/arch/arm/mach-omap2/sram34xx.S b/arch/arm/mach-omap2/sram34xx.S index 7f893a29d500..1078bfbc25c7 100644 --- a/arch/arm/mach-omap2/sram34xx.S +++ b/arch/arm/mach-omap2/sram34xx.S @@ -34,6 +34,12 @@ #include "sdrc.h" #include "cm2xxx_3xxx.h" +/* + * This file needs be built unconditionally as ARM to interoperate correctly + * with non-Thumb-2-capable firmware. + */ + .arm + .text /* r1 parameters */ @@ -116,24 +122,36 @@ ENTRY(omap3_sram_configure_core_dpll) @ pull the extra args off the stack @ and store them in SRAM + +/* + * PC-relative stores are deprecated in ARMv7 and lead to undefined behaviour + * in Thumb-2: use a r7 as a base instead. + * Be careful not to clobber r7 when maintaing this file. + */ + THUMB( adr r7, omap3_sram_configure_core_dpll ) + .macro strtext Rt:req, label:req + ARM( str \Rt, \label ) + THUMB( str \Rt, [r7, \label - omap3_sram_configure_core_dpll] ) + .endm + ldr r4, [sp, #52] - str r4, omap_sdrc_rfr_ctrl_0_val + strtext r4, omap_sdrc_rfr_ctrl_0_val ldr r4, [sp, #56] - str r4, omap_sdrc_actim_ctrl_a_0_val + strtext r4, omap_sdrc_actim_ctrl_a_0_val ldr r4, [sp, #60] - str r4, omap_sdrc_actim_ctrl_b_0_val + strtext r4, omap_sdrc_actim_ctrl_b_0_val ldr r4, [sp, #64] - str r4, omap_sdrc_mr_0_val + strtext r4, omap_sdrc_mr_0_val ldr r4, [sp, #68] - str r4, omap_sdrc_rfr_ctrl_1_val + strtext r4, omap_sdrc_rfr_ctrl_1_val cmp r4, #0 @ if SDRC_RFR_CTRL_1 is 0, beq skip_cs1_params @ do not use cs1 params ldr r4, [sp, #72] - str r4, omap_sdrc_actim_ctrl_a_1_val + strtext r4, omap_sdrc_actim_ctrl_a_1_val ldr r4, [sp, #76] - str r4, omap_sdrc_actim_ctrl_b_1_val + strtext r4, omap_sdrc_actim_ctrl_b_1_val ldr r4, [sp, #80] - str r4, omap_sdrc_mr_1_val + strtext r4, omap_sdrc_mr_1_val skip_cs1_params: mrc p15, 0, r8, c1, c0, 0 @ read ctrl register bic r10, r8, #0x800 @ clear Z-bit, disable branch prediction @@ -271,6 +289,7 @@ skip_cs1_prog: ldr r12, [r11] @ posted-write barrier for SDRC bx lr + .align omap3_sdrc_power: .word OMAP34XX_SDRC_REGADDR(SDRC_POWER) omap3_cm_clksel1_pll: @@ -319,6 +338,7 @@ omap3_sdrc_dlla_ctrl: .word OMAP34XX_SDRC_REGADDR(SDRC_DLLA_CTRL) core_m2_mask_val: .word 0x07FFFFFF +ENDPROC(omap3_sram_configure_core_dpll) ENTRY(omap3_sram_configure_core_dpll_sz) .word . - omap3_sram_configure_core_dpll -- cgit v1.2.3 From dd31394779aa288eb6b9c42672ffcb6d05d6c414 Mon Sep 17 00:00:00 2001 From: Dave Martin Date: Fri, 4 Mar 2011 15:33:57 +0000 Subject: ARM: omap3: Thumb-2 compatibility for sleep34xx.S * Build unconditionally as ARM for correct interoperation with OMAP firmware. * Fix an out-of-range ADR when building for ARM. * Remove deprecated PC-relative stores. * Add the required ENDPROC() directive for each ENTRY(). * .align before data words. * Handle non-interworking return from v7_flush_dcache_all. Signed-off-by: Dave Martin Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/sleep34xx.S | 48 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 5 deletions(-) (limited to 'arch/arm/mach-omap2') diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S index a05c348885ac..0c1b33511fed 100644 --- a/arch/arm/mach-omap2/sleep34xx.S +++ b/arch/arm/mach-omap2/sleep34xx.S @@ -64,6 +64,11 @@ #define SDRC_DLLA_STATUS_V OMAP34XX_SDRC_REGADDR(SDRC_DLLA_STATUS) #define SDRC_DLLA_CTRL_V OMAP34XX_SDRC_REGADDR(SDRC_DLLA_CTRL) +/* + * This file needs be built unconditionally as ARM to interoperate correctly + * with non-Thumb-2-capable firmware. + */ + .arm /* * API functions @@ -82,6 +87,8 @@ ENTRY(get_restore_pointer) stmfd sp!, {lr} @ save registers on stack adr r0, restore ldmfd sp!, {pc} @ restore regs and return +ENDPROC(get_restore_pointer) + .align ENTRY(get_restore_pointer_sz) .word . - get_restore_pointer @@ -91,6 +98,8 @@ ENTRY(get_omap3630_restore_pointer) stmfd sp!, {lr} @ save registers on stack adr r0, restore_3630 ldmfd sp!, {pc} @ restore regs and return +ENDPROC(get_omap3630_restore_pointer) + .align ENTRY(get_omap3630_restore_pointer_sz) .word . - get_omap3630_restore_pointer @@ -100,6 +109,8 @@ ENTRY(get_es3_restore_pointer) stmfd sp!, {lr} @ save registers on stack adr r0, restore_es3 ldmfd sp!, {pc} @ restore regs and return +ENDPROC(get_es3_restore_pointer) + .align ENTRY(get_es3_restore_pointer_sz) .word . - get_es3_restore_pointer @@ -113,8 +124,10 @@ ENTRY(enable_omap3630_toggle_l2_on_restore) stmfd sp!, {lr} @ save registers on stack /* Setup so that we will disable and enable l2 */ mov r1, #0x1 - str r1, l2dis_3630 + adrl r2, l2dis_3630 @ may be too distant for plain adr + str r1, [r2] ldmfd sp!, {pc} @ restore regs and return +ENDPROC(enable_omap3630_toggle_l2_on_restore) .text /* Function to call rom code to save secure ram context */ @@ -139,12 +152,14 @@ ENTRY(save_secure_ram_context) nop nop ldmfd sp!, {r1-r12, pc} + .align sram_phy_addr_mask: .word SRAM_BASE_P high_mask: .word 0xffff api_params: .word 0x4, 0x0, 0x0, 0x1, 0x1 +ENDPROC(save_secure_ram_context) ENTRY(save_secure_ram_context_sz) .word . - save_secure_ram_context @@ -279,8 +294,18 @@ clean_l2: * - 'might' have to copy address, load and jump to it */ ldr r1, kernel_flush - mov lr, pc - bx r1 + blx r1 + /* + * The kernel doesn't interwork: v7_flush_dcache_all in particluar will + * always return in Thumb state when CONFIG_THUMB2_KERNEL is enabled. + * This sequence switches back to ARM. Note that .align may insert a + * nop: bx pc needs to be word-aligned in order to work. + */ + THUMB( .thumb ) + THUMB( .align ) + THUMB( bx pc ) + THUMB( nop ) + .arm omap3_do_wfi: ldr r4, sdrc_power @ read the SDRC_POWER register @@ -438,6 +463,7 @@ skipl2dis: #endif b logic_l1_restore + .align l2_inv_api_params: .word 0x1, 0x00 l2_inv_gp: @@ -607,6 +633,7 @@ usettbr0: /* This function implements the erratum ID i443 WA, applies to 34xx >= ES3.0 */ .text + .align 3 ENTRY(es3_sdrc_fix) ldr r4, sdrc_syscfg @ get config addr ldr r5, [r4] @ get value @@ -634,6 +661,7 @@ ENTRY(es3_sdrc_fix) str r5, [r4] @ kick off refreshes bx lr + .align sdrc_syscfg: .word SDRC_SYSCONFIG_P sdrc_mr_0: @@ -648,6 +676,7 @@ sdrc_emr2_1: .word SDRC_EMR2_1_P sdrc_manual_1: .word SDRC_MANUAL_1_P +ENDPROC(es3_sdrc_fix) ENTRY(es3_sdrc_fix_sz) .word . - es3_sdrc_fix @@ -682,6 +711,12 @@ wait_sdrc_ready: bic r5, r5, #0x40 str r5, [r4] +/* + * PC-relative stores lead to undefined behaviour in Thumb-2: use a r7 as a + * base instead. + * Be careful not to clobber r7 when maintaing this code. + */ + is_dll_in_lock_mode: /* Is dll in lock mode? */ ldr r4, sdrc_dlla_ctrl @@ -689,10 +724,11 @@ is_dll_in_lock_mode: tst r5, #0x4 bxne lr @ Return if locked /* wait till dll locks */ + adr r7, kick_counter wait_dll_lock_timed: ldr r4, wait_dll_lock_counter add r4, r4, #1 - str r4, wait_dll_lock_counter + str r4, [r7, #wait_dll_lock_counter - kick_counter] ldr r4, sdrc_dlla_status /* Wait 20uS for lock */ mov r6, #8 @@ -718,9 +754,10 @@ kick_dll: dsb ldr r4, kick_counter add r4, r4, #1 - str r4, kick_counter + str r4, [r7] @ kick_counter b wait_dll_lock_timed + .align cm_idlest1_core: .word CM_IDLEST1_CORE_V cm_idlest_ckgen: @@ -763,6 +800,7 @@ kick_counter: .word 0 wait_dll_lock_counter: .word 0 +ENDPROC(omap34xx_cpu_suspend) ENTRY(omap34xx_cpu_suspend_sz) .word . - omap34xx_cpu_suspend -- cgit v1.2.3 From b1ace38094c4926255343a81faba8fb4faf59a45 Mon Sep 17 00:00:00 2001 From: Anand S Sawant Date: Thu, 17 Feb 2011 21:27:30 +0530 Subject: OMAP2+: smartreflex: remove SR debug directory in omap_sr_remove() omap_sr_probe() creates the smartreflex debug directory and its underlying nvalue debug directory. These directories are removed in omap_sr_remove(). Basic smartreflex functionality tested on OMAP3630 Zoom3 & OMAP4430 SDP Signed-off-by: Anand S Sawant Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/smartreflex.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'arch/arm/mach-omap2') diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c index b57ae502e0c7..0ab4dd5081ee 100644 --- a/arch/arm/mach-omap2/smartreflex.c +++ b/arch/arm/mach-omap2/smartreflex.c @@ -54,6 +54,7 @@ struct omap_sr { struct list_head node; struct omap_sr_nvalue_table *nvalue_table; struct voltagedomain *voltdm; + struct dentry *dbg_dir; }; /* sr_list contains all the instances of smartreflex module */ @@ -823,7 +824,7 @@ static int __init omap_sr_probe(struct platform_device *pdev) struct omap_sr *sr_info = kzalloc(sizeof(struct omap_sr), GFP_KERNEL); struct omap_sr_data *pdata = pdev->dev.platform_data; struct resource *mem, *irq; - struct dentry *vdd_dbg_dir, *dbg_dir, *nvalue_dir; + struct dentry *vdd_dbg_dir, *nvalue_dir; struct omap_volt_data *volt_data; int i, ret = 0; @@ -898,24 +899,24 @@ static int __init omap_sr_probe(struct platform_device *pdev) goto err_release_region; } - dbg_dir = debugfs_create_dir("smartreflex", vdd_dbg_dir); - if (IS_ERR(dbg_dir)) { + sr_info->dbg_dir = debugfs_create_dir("smartreflex", vdd_dbg_dir); + if (IS_ERR(sr_info->dbg_dir)) { dev_err(&pdev->dev, "%s: Unable to create debugfs directory\n", __func__); - ret = PTR_ERR(dbg_dir); + ret = PTR_ERR(sr_info->dbg_dir); goto err_release_region; } - (void) debugfs_create_file("autocomp", S_IRUGO | S_IWUSR, dbg_dir, - (void *)sr_info, &pm_sr_fops); - (void) debugfs_create_x32("errweight", S_IRUGO, dbg_dir, + (void) debugfs_create_file("autocomp", S_IRUGO | S_IWUSR, + sr_info->dbg_dir, (void *)sr_info, &pm_sr_fops); + (void) debugfs_create_x32("errweight", S_IRUGO, sr_info->dbg_dir, &sr_info->err_weight); - (void) debugfs_create_x32("errmaxlimit", S_IRUGO, dbg_dir, + (void) debugfs_create_x32("errmaxlimit", S_IRUGO, sr_info->dbg_dir, &sr_info->err_maxlimit); - (void) debugfs_create_x32("errminlimit", S_IRUGO, dbg_dir, + (void) debugfs_create_x32("errminlimit", S_IRUGO, sr_info->dbg_dir, &sr_info->err_minlimit); - nvalue_dir = debugfs_create_dir("nvalue", dbg_dir); + nvalue_dir = debugfs_create_dir("nvalue", sr_info->dbg_dir); if (IS_ERR(nvalue_dir)) { dev_err(&pdev->dev, "%s: Unable to create debugfs directory" "for n-values\n", __func__); @@ -972,6 +973,8 @@ static int __devexit omap_sr_remove(struct platform_device *pdev) if (sr_info->autocomp_active) sr_stop_vddautocomp(sr_info); + if (sr_info->dbg_dir) + debugfs_remove_recursive(sr_info->dbg_dir); list_del(&sr_info->node); iounmap(sr_info->base); -- cgit v1.2.3 From 4444d712fd5b31f2348b57eaa2bbdc5e68c4e1b6 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Sun, 23 Jan 2011 19:00:34 +0530 Subject: OMAP3: PM: Use ARMv7 supported instructions instead of legacy CP15 ones On ARMv7 dsb, dmb instructions are supported and can be used directly instead of their cp15 equivalnet. Also remove the opcodes for smc and use the available instruction directly in OMAP3 low power asm code Signed-off-by: Santosh Shilimkar Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/sleep34xx.S | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'arch/arm/mach-omap2') diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S index 0c1b33511fed..1c17ee81cb12 100644 --- a/arch/arm/mach-omap2/sleep34xx.S +++ b/arch/arm/mach-omap2/sleep34xx.S @@ -144,8 +144,8 @@ ENTRY(save_secure_ram_context) mov r1, #0 @ set task id for ROM code in r1 mov r2, #4 @ set some flags in r2, r6 mov r6, #0xff - mcr p15, 0, r0, c7, c10, 4 @ data write barrier - mcr p15, 0, r0, c7, c10, 5 @ data memory barrier + dsb @ data write barrier + dmb @ data memory barrier smc #1 @ call SMI monitor (smi #1) nop nop @@ -314,9 +314,8 @@ omap3_do_wfi: str r5, [r4] @ write back to SDRC_POWER register /* Data memory barrier and Data sync barrier */ - mov r1, #0 - mcr p15, 0, r1, c7, c10, 4 - mcr p15, 0, r1, c7, c10, 5 + dsb + dmb /* * =================================== @@ -431,8 +430,8 @@ skipl2dis: mov r2, #4 @ set some flags in r2, r6 mov r6, #0xff adr r3, l2_inv_api_params @ r3 points to dummy parameters - mcr p15, 0, r0, c7, c10, 4 @ data write barrier - mcr p15, 0, r0, c7, c10, 5 @ data memory barrier + dsb @ data write barrier + dmb @ data memory barrier smc #1 @ call SMI monitor (smi #1) /* Write to Aux control register to set some bits */ mov r0, #42 @ set service ID for PPA @@ -442,8 +441,8 @@ skipl2dis: mov r6, #0xff ldr r4, scratchpad_base ldr r3, [r4, #0xBC] @ r3 points to parameters - mcr p15, 0, r0, c7, c10, 4 @ data write barrier - mcr p15, 0, r0, c7, c10, 5 @ data memory barrier + dsb @ data write barrier + dmb @ data memory barrier smc #1 @ call SMI monitor (smi #1) #ifdef CONFIG_OMAP3_L2_AUX_SECURE_SAVE_RESTORE @@ -457,8 +456,8 @@ skipl2dis: ldr r4, scratchpad_base ldr r3, [r4, #0xBC] adds r3, r3, #8 @ r3 points to parameters - mcr p15, 0, r0, c7, c10, 4 @ data write barrier - mcr p15, 0, r0, c7, c10, 5 @ data memory barrier + dsb @ data write barrier + dmb @ data memory barrier smc #1 @ call SMI monitor (smi #1) #endif b logic_l1_restore -- cgit v1.2.3 From 8409d57bc342536ffe96acc7cd6c7575d98d3edb Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Sun, 23 Jan 2011 16:04:39 +0530 Subject: OMAP3: PM: Fix the MMU on sequence in the asm code Add necessary barriers after enabling MMU. Also use the sane way to load pc and jump to it instead of executing ldma first up. Signed-off-by: Santosh Shilimkar Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/sleep34xx.S | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch/arm/mach-omap2') diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S index 1c17ee81cb12..a31845a201e9 100644 --- a/arch/arm/mach-omap2/sleep34xx.S +++ b/arch/arm/mach-omap2/sleep34xx.S @@ -617,12 +617,17 @@ usettbr0: ldr r2, cache_pred_disable_mask and r4, r2 mcr p15, 0, r4, c1, c0, 0 + dsb + isb + ldr r0, =restoremmu_on + bx r0 /* * ============================== * == Exit point from OFF mode == * ============================== */ +restoremmu_on: ldmfd sp!, {r0-r12, pc} @ restore regs and return -- cgit v1.2.3 From c9749a352383d4d2d25eb28062afd1a7eee115b7 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Sun, 23 Jan 2011 19:33:53 +0530 Subject: OMAP3: PM: Allow the cache clean when L1 is lost. When L1 cache is suppose to be lost, it needs to be cleaned before entrering to the low power mode. While at this, also fix few comments and remove un-necessary clean_l2 lable. Signed-off-by: Santosh Shilimkar Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/sleep34xx.S | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) (limited to 'arch/arm/mach-omap2') diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S index a31845a201e9..f75a166f0a21 100644 --- a/arch/arm/mach-omap2/sleep34xx.S +++ b/arch/arm/mach-omap2/sleep34xx.S @@ -188,12 +188,12 @@ ENTRY(omap34xx_cpu_suspend) stmfd sp!, {r0-r12, lr} @ save registers on stack /* - * r0 contains restore pointer in sdram + * r0 contains CPU context save/restore pointer in sdram * r1 contains information about saving context: * 0 - No context lost * 1 - Only L1 and logic lost - * 2 - Only L2 lost - * 3 - Both L1 and L2 lost + * 2 - Only L2 lost (Even L1 is retained we clean it along with L2) + * 3 - Both L1 and L2 lost and logic lost */ /* Directly jump to WFI is the context save is not required */ @@ -277,15 +277,6 @@ l1_logic_lost: stmia r8!, {r4} clean_caches: - /* - * Clean Data or unified cache to POU - * How to invalidate only L1 cache???? - #FIX_ME# - * mcr p15, 0, r11, c7, c11, 1 - */ - cmp r1, #0x1 @ Check whether L2 inval is required - beq omap3_do_wfi - -clean_l2: /* * jump out to kernel flush routine * - reuse that code is better -- cgit v1.2.3 From 46f557cb453b9f3b6dc36b8179c2c36932a2ea64 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Sun, 23 Jan 2011 21:37:03 +0530 Subject: OMAP3: PM: Remove un-necessary cp15 registers form low power cpu context The current code saves few un-necessary registers which are read-only or write-only, unused CP15 registers. Remove them and keep only necessary CP15 registers part of low power context save/restore. Signed-off-by: Santosh Shilimkar Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/sleep34xx.S | 156 +++++++++++----------------------------- 1 file changed, 40 insertions(+), 116 deletions(-) (limited to 'arch/arm/mach-omap2') diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S index f75a166f0a21..99e43cc5a503 100644 --- a/arch/arm/mach-omap2/sleep34xx.S +++ b/arch/arm/mach-omap2/sleep34xx.S @@ -214,66 +214,29 @@ save_context_wfi: beq clean_caches l1_logic_lost: - /* Store sp and spsr to SDRAM */ - mov r4, sp - mrs r5, spsr - mov r6, lr + mov r4, sp @ Store sp + mrs r5, spsr @ Store spsr + mov r6, lr @ Store lr stmia r8!, {r4-r6} - /* Save all ARM registers */ - /* Coprocessor access control register */ - mrc p15, 0, r6, c1, c0, 2 - stmia r8!, {r6} - /* TTBR0, TTBR1 and Translation table base control */ - mrc p15, 0, r4, c2, c0, 0 - mrc p15, 0, r5, c2, c0, 1 - mrc p15, 0, r6, c2, c0, 2 - stmia r8!, {r4-r6} - /* - * Domain access control register, data fault status register, - * and instruction fault status register - */ - mrc p15, 0, r4, c3, c0, 0 - mrc p15, 0, r5, c5, c0, 0 - mrc p15, 0, r6, c5, c0, 1 - stmia r8!, {r4-r6} - /* - * Data aux fault status register, instruction aux fault status, - * data fault address register and instruction fault address register - */ - mrc p15, 0, r4, c5, c1, 0 - mrc p15, 0, r5, c5, c1, 1 - mrc p15, 0, r6, c6, c0, 0 - mrc p15, 0, r7, c6, c0, 2 - stmia r8!, {r4-r7} - /* - * user r/w thread and process ID, user r/o thread and process ID, - * priv only thread and process ID, cache size selection - */ - mrc p15, 0, r4, c13, c0, 2 - mrc p15, 0, r5, c13, c0, 3 - mrc p15, 0, r6, c13, c0, 4 - mrc p15, 2, r7, c0, c0, 0 + + mrc p15, 0, r4, c1, c0, 2 @ Coprocessor access control register + mrc p15, 0, r5, c2, c0, 0 @ TTBR0 + mrc p15, 0, r6, c2, c0, 1 @ TTBR1 + mrc p15, 0, r7, c2, c0, 2 @ TTBCR stmia r8!, {r4-r7} - /* Data TLB lockdown, instruction TLB lockdown registers */ - mrc p15, 0, r5, c10, c0, 0 - mrc p15, 0, r6, c10, c0, 1 - stmia r8!, {r5-r6} - /* Secure or non secure vector base address, FCSE PID, Context PID*/ - mrc p15, 0, r4, c12, c0, 0 - mrc p15, 0, r5, c13, c0, 0 - mrc p15, 0, r6, c13, c0, 1 - stmia r8!, {r4-r6} - /* Primary remap, normal remap registers */ - mrc p15, 0, r4, c10, c2, 0 - mrc p15, 0, r5, c10, c2, 1 - stmia r8!,{r4-r5} - /* Store current cpsr*/ - mrs r2, cpsr - stmia r8!, {r2} + mrc p15, 0, r4, c3, c0, 0 @ Domain access Control Register + mrc p15, 0, r5, c10, c2, 0 @ PRRR + mrc p15, 0, r6, c10, c2, 1 @ NMRR + stmia r8!,{r4-r6} + + mrc p15, 0, r4, c13, c0, 1 @ Context ID + mrc p15, 0, r5, c13, c0, 2 @ User r/w thread and process ID + mrc p15, 0, r6, c12, c0, 0 @ Secure or NS vector base address + mrs r7, cpsr @ Store current cpsr + stmia r8!, {r4-r7} - mrc p15, 0, r4, c1, c0, 0 - /* save control register */ + mrc p15, 0, r4, c1, c0, 0 @ save control register stmia r8!, {r4} clean_caches: @@ -489,68 +452,29 @@ skipl2reen: ldr r4, scratchpad_base ldr r3, [r4,#0xBC] adds r3, r3, #16 + ldmia r3!, {r4-r6} - mov sp, r4 - msr spsr_cxsf, r5 - mov lr, r6 - - ldmia r3!, {r4-r9} - /* Coprocessor access Control Register */ - mcr p15, 0, r4, c1, c0, 2 - - /* TTBR0 */ - MCR p15, 0, r5, c2, c0, 0 - /* TTBR1 */ - MCR p15, 0, r6, c2, c0, 1 - /* Translation table base control register */ - MCR p15, 0, r7, c2, c0, 2 - /* Domain access Control Register */ - MCR p15, 0, r8, c3, c0, 0 - /* Data fault status Register */ - MCR p15, 0, r9, c5, c0, 0 - - ldmia r3!,{r4-r8} - /* Instruction fault status Register */ - MCR p15, 0, r4, c5, c0, 1 - /* Data Auxiliary Fault Status Register */ - MCR p15, 0, r5, c5, c1, 0 - /* Instruction Auxiliary Fault Status Register*/ - MCR p15, 0, r6, c5, c1, 1 - /* Data Fault Address Register */ - MCR p15, 0, r7, c6, c0, 0 - /* Instruction Fault Address Register*/ - MCR p15, 0, r8, c6, c0, 2 - ldmia r3!,{r4-r7} + mov sp, r4 @ Restore sp + msr spsr_cxsf, r5 @ Restore spsr + mov lr, r6 @ Restore lr - /* User r/w thread and process ID */ - MCR p15, 0, r4, c13, c0, 2 - /* User ro thread and process ID */ - MCR p15, 0, r5, c13, c0, 3 - /* Privileged only thread and process ID */ - MCR p15, 0, r6, c13, c0, 4 - /* Cache size selection */ - MCR p15, 2, r7, c0, c0, 0 - ldmia r3!,{r4-r8} - /* Data TLB lockdown registers */ - MCR p15, 0, r4, c10, c0, 0 - /* Instruction TLB lockdown registers */ - MCR p15, 0, r5, c10, c0, 1 - /* Secure or Nonsecure Vector Base Address */ - MCR p15, 0, r6, c12, c0, 0 - /* FCSE PID */ - MCR p15, 0, r7, c13, c0, 0 - /* Context PID */ - MCR p15, 0, r8, c13, c0, 1 - - ldmia r3!,{r4-r5} - /* Primary memory remap register */ - MCR p15, 0, r4, c10, c2, 0 - /* Normal memory remap register */ - MCR p15, 0, r5, c10, c2, 1 - - /* Restore cpsr */ - ldmia r3!,{r4} @ load CPSR from SDRAM - msr cpsr, r4 @ store cpsr + ldmia r3!, {r4-r7} + mcr p15, 0, r4, c1, c0, 2 @ Coprocessor access Control Register + mcr p15, 0, r5, c2, c0, 0 @ TTBR0 + mcr p15, 0, r6, c2, c0, 1 @ TTBR1 + mcr p15, 0, r7, c2, c0, 2 @ TTBCR + + ldmia r3!,{r4-r6} + mcr p15, 0, r4, c3, c0, 0 @ Domain access Control Register + mcr p15, 0, r5, c10, c2, 0 @ PRRR + mcr p15, 0, r6, c10, c2, 1 @ NMRR + + + ldmia r3!,{r4-r7} + mcr p15, 0, r4, c13, c0, 1 @ Context ID + mcr p15, 0, r5, c13, c0, 2 @ User r/w thread and process ID + mrc p15, 0, r6, c12, c0, 0 @ Secure or NS vector base address + msr cpsr, r7 @ store cpsr /* Enabling MMU here */ mrc p15, 0, r7, c2, c0, 2 @ Read TTBRControl -- cgit v1.2.3 From 9062511097683b4422f023d181b4a8b2db1a7a72 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Sun, 23 Jan 2011 22:51:09 +0530 Subject: OMAP3: PM: Clear the SCTLR C bit in asm code to prevent data cache allocation On the newer ARM processors like CortexA8, CortexA9, the caches can be speculatively loaded while they are getting flushed. Clear the SCTLR C bit to prevent further data cache allocation as part of cache clean routine Signed-off-by: Santosh Shilimkar Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/sleep34xx.S | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'arch/arm/mach-omap2') diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S index 99e43cc5a503..e60ac1f71bd4 100644 --- a/arch/arm/mach-omap2/sleep34xx.S +++ b/arch/arm/mach-omap2/sleep34xx.S @@ -246,6 +246,27 @@ clean_caches: * - it executes in a cached space so is faster than refetch per-block * - should be faster and will change with kernel * - 'might' have to copy address, load and jump to it + * Flush all data from the L1 data cache before disabling + * SCTLR.C bit. + */ + ldr r1, kernel_flush + mov lr, pc + bx r1 + + /* + * Clear the SCTLR.C bit to prevent further data cache + * allocation. Clearing SCTLR.C would make all the data accesses + * strongly ordered and would not hit the cache. + */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #(1 << 2) @ Disable the C bit + mcr p15, 0, r0, c1, c0, 0 + isb + + /* + * Invalidate L1 data cache. Even though only invalidate is + * necessary exported flush API is used here. Doing clean + * on already clean cache would be almost NOP. */ ldr r1, kernel_flush blx r1 @@ -295,6 +316,12 @@ omap3_do_wfi: nop bl wait_sdrc_ok + mrc p15, 0, r0, c1, c0, 0 + tst r0, #(1 << 2) @ Check C bit enabled? + orreq r0, r0, #(1 << 2) @ Enable the C bit if cleared + mcreq p15, 0, r0, c1, c0, 0 + isb + /* * =================================== * == Exit point from non-OFF modes == -- cgit v1.2.3