From patchwork Mon Dec 6 17:35:35 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: tip-bot for Dave Martin X-Patchwork-Id: 379232 X-Patchwork-Delegate: khilman@deeprootsystems.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id oB6Hb0lJ005417 for ; Mon, 6 Dec 2010 17:37:00 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753848Ab0LFRgS (ORCPT ); Mon, 6 Dec 2010 12:36:18 -0500 Received: from mail-wy0-f174.google.com ([74.125.82.174]:44264 "EHLO mail-wy0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753644Ab0LFRgR (ORCPT ); Mon, 6 Dec 2010 12:36:17 -0500 Received: by mail-wy0-f174.google.com with SMTP id 28so12260626wyb.19 for ; Mon, 06 Dec 2010 09:36:16 -0800 (PST) Received: by 10.227.136.20 with SMTP id p20mr5930794wbt.222.1291656975892; Mon, 06 Dec 2010 09:36:15 -0800 (PST) Received: from e200948.cambridge.arm.com (host86-166-237-243.range86-166.btcentralplus.com [86.166.237.243]) by mx.google.com with ESMTPS id f35sm3600235wbf.14.2010.12.06.09.36.13 (version=SSLv3 cipher=RC4-MD5); Mon, 06 Dec 2010 09:36:14 -0800 (PST) From: Dave Martin To: linux-arm-kernel@lists.infradead.org Cc: Dave Martin , linux-omap@vger.kernel.org, linaro-dev@lists.linaro.org, Tony Lindgren Subject: [PATCH v2 1/3] ARM: omap: Enable low-level omap3 PM code to work with CONFIG_THUMB2_KERNEL Date: Mon, 6 Dec 2010 17:35:35 +0000 Message-Id: <1291656937-24992-2-git-send-email-dave.martin@linaro.org> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1291656937-24992-1-git-send-email-dave.martin@linaro.org> References: <1291656937-24992-1-git-send-email-dave.martin@linaro.org> Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Mon, 06 Dec 2010 17:37:01 +0000 (UTC) diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h index 0d75bfd..c333bfd 100644 --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h @@ -80,7 +80,9 @@ extern void save_secure_ram_context(u32 *addr); extern void omap3_save_scratchpad_contents(void); extern unsigned int omap24xx_idle_loop_suspend_sz; +extern char *const omap34xx_cpu_suspend_base; extern unsigned int omap34xx_suspend_sz; +extern char *const save_secure_ram_context_base; extern unsigned int save_secure_ram_context_sz; extern unsigned int omap24xx_cpu_suspend_sz; extern unsigned int omap34xx_cpu_suspend_sz; diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 0ec8a04..93f0ee8 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -982,11 +982,18 @@ static int __init clkdms_setup(struct clockdomain *clkdm, void *unused) void omap_push_sram_idle(void) { - _omap_sram_idle = omap_sram_push(omap34xx_cpu_suspend, + _omap_sram_idle = omap_sram_push(omap34xx_cpu_suspend_base, omap34xx_cpu_suspend_sz); - if (omap_type() != OMAP2_DEVICE_TYPE_GP) - _omap_save_secure_sram = omap_sram_push(save_secure_ram_context, + _omap_sram_idle += (char *)omap34xx_cpu_suspend - + omap34xx_cpu_suspend_base; + + if (omap_type() != OMAP2_DEVICE_TYPE_GP) { + _omap_save_secure_sram = omap_sram_push( + save_secure_ram_context_base, save_secure_ram_context_sz); + _omap_save_secure_sram += (char *)save_secure_ram_context - + save_secure_ram_context_base; + } } static int __init omap3_pm_init(void) diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S index 2fb205a..06ae955 100644 --- a/arch/arm/mach-omap2/sleep34xx.S +++ b/arch/arm/mach-omap2/sleep34xx.S @@ -61,6 +61,7 @@ .text /* Function to acquire the semaphore in scratchpad */ + .arm @ Do this in ARM for now, due to use of SWP. ENTRY(lock_scratchpad_sem) stmfd sp!, {lr} @ save registers on stack wait_sem: @@ -74,6 +75,9 @@ wait_loop: cmp r2, r0 @ did we succeed ? beq wait_sem @ no - try again ldmfd sp!, {pc} @ restore regs and return +ENDPROC(lock_scratchpad_sem) + THUMB( .thumb ) + .align sdrc_scratchpad_sem: .word SDRC_SCRATCHPAD_SEM_V ENTRY(lock_scratchpad_sem_sz) @@ -87,6 +91,7 @@ ENTRY(unlock_scratchpad_sem) mov r2,#0 str r2,[r3] ldmfd sp!, {pc} @ restore regs and return +ENDPROC(unlock_scratchpad_sem) ENTRY(unlock_scratchpad_sem_sz) .word . - unlock_scratchpad_sem @@ -96,6 +101,7 @@ 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) ENTRY(get_restore_pointer_sz) .word . - get_restore_pointer @@ -105,10 +111,16 @@ 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) ENTRY(get_es3_restore_pointer_sz) .word . - get_es3_restore_pointer -ENTRY(es3_sdrc_fix) +@ For simplicity, make this ARM so it gets called OK from es3_restore. +@ Demote to a local symbol, since this gives this function an ARM ABI interface +@ which won't be callable directly from a Thumb-2 kernel. This code +@ shouldn't be called from outside anyway... + .arm +es3_sdrc_fix: ldr r4, sdrc_syscfg @ get config addr ldr r5, [r4] @ get value tst r5, #0x100 @ is part access blocked @@ -134,6 +146,9 @@ ENTRY(es3_sdrc_fix) mov r5, #0x2 @ autorefresh command str r5, [r4] @ kick off refreshes bx lr +ENDPROC(es3_sdrc_fix) + THUMB( .thumb ) + .align sdrc_syscfg: .word SDRC_SYSCONFIG_P sdrc_mr_0: @@ -150,8 +165,12 @@ sdrc_manual_1: .word SDRC_MANUAL_1_P ENTRY(es3_sdrc_fix_sz) .word . - es3_sdrc_fix + THUMB( .thumb ) /* Function to call rom code to save secure ram context */ + .arm @ Do this in ARM for now, due to use of SMC, + @ in case the Secure World firmware may depends + @ on decoding the SMC instruction. ENTRY(save_secure_ram_context) stmfd sp!, {r1-r12, lr} @ save registers on stack save_secure_ram_debug: @@ -175,6 +194,9 @@ save_secure_ram_debug: nop nop ldmfd sp!, {r1-r12, pc} +ENDPROC(save_secure_ram_context) + THUMB( .thumb ) + .align sram_phy_addr_mask: .word SRAM_BASE_P high_mask: @@ -183,6 +205,8 @@ api_params: .word 0x4, 0x0, 0x0, 0x1, 0x1 ENTRY(save_secure_ram_context_sz) .word . - save_secure_ram_context +ENTRY(save_secure_ram_context_base) + .word save_secure_ram_context_base /* * Forces OMAP into idle state @@ -193,6 +217,7 @@ ENTRY(save_secure_ram_context_sz) * Note: This code get's copied to internal SRAM at boot. When the OMAP * wakes up it continues execution at the point it went to sleep. */ + .arm @ Do this in ARM for now, due to use of SMC. ENTRY(omap34xx_cpu_suspend) stmfd sp!, {r0-r12, lr} @ save registers on stack loop: @@ -563,10 +588,12 @@ loop2: mov r9, r4 /* create working copy of max way size*/ loop3: + mov r1, r9, lsl r5 + mov r2, r7, lsl r2 /* factor way and cache number into r11 */ - orr r11, r10, r9, lsl r5 + orr r11, r10, r1 /* factor index number into r11 */ - orr r11, r11, r7, lsl r2 + orr r11, r11, r2 /*clean & invalidate by set/way */ mcr p15, 0, r11, c7, c10, 2 /* decrement the way*/ @@ -631,7 +658,9 @@ wait_dll_lock: cmp r5, #0x4 bne wait_dll_lock bx lr +ENDPROC(omap34xx_cpu_suspend) + .align cm_idlest1_core: .word CM_IDLEST1_CORE_V sdrc_dlla_status: @@ -670,3 +699,5 @@ control_stat: .word CONTROL_STAT ENTRY(omap34xx_cpu_suspend_sz) .word . - omap34xx_cpu_suspend +ENTRY(omap34xx_cpu_suspend_base) + .word omap34xx_cpu_suspend diff --git a/arch/arm/mach-omap2/sram34xx.S b/arch/arm/mach-omap2/sram34xx.S index 3637274..65fd54f 100644 --- a/arch/arm/mach-omap2/sram34xx.S +++ b/arch/arm/mach-omap2/sram34xx.S @@ -105,29 +105,42 @@ * can satisfy the above requirement can enable the CONFIG_OMAP3_SDRC_AC_TIMING * option. */ +__omap3_sram_configure_core_dpll_base: @ Separate local symbol with the Thumb + @ bit _not_ set (for base address when + @ copying to sram). ENTRY(omap3_sram_configure_core_dpll) stmfd sp!, {r1-r12, lr} @ store regs to stack @ pull the extra args off the stack @ and store them in SRAM + +@ 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 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 @@ -264,7 +277,9 @@ configure_sdrc: skip_cs1_prog: ldr r12, [r11] @ posted-write barrier for SDRC bx lr +ENDPROC(omap3_sram_configure_core_dpll) + .align omap3_sdrc_power: .word OMAP34XX_SDRC_REGADDR(SDRC_POWER) omap3_cm_clksel1_pll: @@ -316,4 +331,5 @@ core_m2_mask_val: ENTRY(omap3_sram_configure_core_dpll_sz) .word . - omap3_sram_configure_core_dpll - +ENTRY(omap3_sram_configure_core_dpll_base) + .word __omap3_sram_configure_core_dpll_base diff --git a/arch/arm/plat-omap/include/plat/sram.h b/arch/arm/plat-omap/include/plat/sram.h index 5905100..2f27167 100644 --- a/arch/arm/plat-omap/include/plat/sram.h +++ b/arch/arm/plat-omap/include/plat/sram.h @@ -67,6 +67,7 @@ extern u32 omap3_sram_configure_core_dpll( u32 sdrc_rfr_ctrl_1, u32 sdrc_actim_ctrl_a_1, u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1); extern unsigned long omap3_sram_configure_core_dpll_sz; +extern char *omap3_sram_configure_core_dpll_base; #ifdef CONFIG_PM extern void omap_push_sram_idle(void); diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index e2c8eeb..61282f4 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c @@ -386,8 +386,11 @@ void omap3_sram_restore_context(void) omap_sram_ceil = omap_sram_base + omap_sram_size; _omap3_sram_configure_core_dpll = - omap_sram_push(omap3_sram_configure_core_dpll, + omap_sram_push(omap3_sram_configure_core_dpll_base, omap3_sram_configure_core_dpll_sz); + _omap3_sram_configure_core_dpll += + (char *)omap3_sram_configure_core_dpll - + omap3_sram_configure_core_dpll_base; omap_push_sram_idle(); } #endif /* CONFIG_PM */ @@ -395,8 +398,11 @@ void omap3_sram_restore_context(void) static int __init omap34xx_sram_init(void) { _omap3_sram_configure_core_dpll = - omap_sram_push(omap3_sram_configure_core_dpll, + omap_sram_push(omap3_sram_configure_core_dpll_base, omap3_sram_configure_core_dpll_sz); + _omap3_sram_configure_core_dpll += + (char *)omap3_sram_configure_core_dpll - + omap3_sram_configure_core_dpll_base; omap_push_sram_idle(); return 0; }