From: Wenyou Yang <wenyou.yang@atmel.com> To: <nicolas.ferre@atmel.com>, <linux@arm.linux.org.uk> Cc: <linux-arm-kernel@lists.infradead.org>, <linux-kernel@vger.kernel.org>, <alexandre.belloni@free-electrons.com>, <sylvain.rochet@finsecur.com>, <peda@axentia.se>, <wenyou.yang@atmel.com>, <Patrice.VILCHEZ@atmel.com> Subject: [PATCH 5/7] pm: at91: add disable/enable the L1/L2 cache while suspend/resume Date: Mon, 26 Jan 2015 18:07:57 +0800 [thread overview] Message-ID: <1422266877-24628-1-git-send-email-wenyou.yang@atmel.com> (raw) In-Reply-To: <1422266617-24381-1-git-send-email-wenyou.yang@atmel.com> For the sama5, disable L1 D-cache and L2 cache before the cpu go to wfi, after wakeing up, enable L1 D-cache and L2 cache. Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com> --- arch/arm/mach-at91/pm.c | 9 ++++ arch/arm/mach-at91/pm_suspend.S | 107 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+) diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index f75dc32..50cde92 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -35,6 +35,9 @@ #include "generic.h" #include "pm.h" +void __weak at91_disable_l1_l2_cache(void) {} +void __weak at91_enable_l1_l2_cache(void) {} + struct at91_pm_struct at91_pm_data; static int at91_pm_valid_state(suspend_state_t state) @@ -142,8 +145,14 @@ static void at91_pm_suspend(suspend_state_t state) pm_data |= (state == PM_SUSPEND_MEM) ? AT91_PM_MODE(AT91_PM_SLOW_CLOCK) : 0; + /* Disable L1 D-cache and L2 cache */ + at91_disable_l1_l2_cache(); + at91_suspend_sram_fn(at91_pmc_base, at91_ramc_base[0], at91_ramc_base[1], pm_data); + + /* Enable L1 D-cache and L2 cache */ + at91_enable_l1_l2_cache(); } static int at91_pm_enter(suspend_state_t state) diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S index 88cf228..e6e7f7a 100644 --- a/arch/arm/mach-at91/pm_suspend.S +++ b/arch/arm/mach-at91/pm_suspend.S @@ -15,6 +15,7 @@ #include <linux/clk/at91_pmc.h> #include <mach/hardware.h> #include <mach/at91_ramc.h> +#include <asm/hardware/cache-l2x0.h> #include "pm.h" @@ -329,3 +330,109 @@ ram_restored: ENTRY(at91_pm_suspend_in_sram_sz) .word .-at91_pm_suspend_in_sram + +/*---------------------------------------*/ + +#if defined(CONFIG_CPU_V7) + +/* + * void at91_disable_l1_l2_cache(void) + * + * This function code disables, cleans & invalidates the L1 D-cache + * and cleans, invalidates & disable the L2 cache. + */ +ENTRY(at91_disable_l1_l2_cache) + stmfd sp!, {r4 - r12, lr} + + /* + * Flush all data from the L1 D-cache before disabling + * SCTLR.C bit. + */ + bl v7_flush_dcache_all + + /* + * 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 D-cache. Even though only invalidate is + * necessary exported flush API is used here. Doing clean + * on already clean cache would be almost NOP. + */ + bl v7_flush_dcache_all + + /* + * Clean and invalidate the L2 cache. + * Common cache-l2x0.c functions can't be used here since it + * uses spinlocks. We are out of coherency here with data cache + * disabled. The spinlock implementation uses exclusive load/store + * instruction which can fail without data cache being enabled. + * Because of this, CPU can lead to deadlock. + */ + ldr r1, at91_l2cc_base_addr + ldr r2, [r1] + cmp r2, #0 + beq skip_l2disable + mov r0, #0xff + str r0, [r2, #L2X0_CLEAN_INV_WAY] +wait: + ldr r0, [r2, #L2X0_CLEAN_INV_WAY] + mov r1, #0xff + ands r0, r0, r1 + bne wait + + mov r0, #0 + str r0, [r2, #L2X0_CTRL] + +l2x_sync: + ldr r0, [r2, #L2X0_CACHE_SYNC] + bic r0, r0, #0x1 + str r0, [r2, #L2X0_CACHE_SYNC] +sync: + ldr r0, [r2, #L2X0_CACHE_SYNC] + ands r0, r0, #0x1 + bne sync + +skip_l2disable: + ldmfd sp!, {r4 - r12, pc} +ENDPROC(at91_disable_l1_l2_cache) + +/* + * void at91_enable_l1_l2_cache(void) + * + * This function code enables the L1 D-cache and the L2 cache. + */ +ENTRY(at91_enable_l1_l2_cache) + stmfd sp!, {r4 - r12, lr} + + /* Enable the L2 cache */ + ldr r1, at91_l2cc_base_addr + ldr r2, [r1] + cmp r2, #0 + beq skip_l2en + ldr r0, [r2, #L2X0_CTRL] + ands r0, r0, #L2X0_CTRL_EN + bne skip_l2en @ Skip if already enabled + mov r0, #L2X0_CTRL_EN + str r0, [r2, #L2X0_CTRL] +skip_l2en: + + /* Enable the L1 D-cache */ + mrc p15, 0, r0, c1, c0, 0 + tst r0, #(1 << 2) @ Check C bit enabled? + orreq r0, r0, #(1 << 2) @ Enable the C bit + mcreq p15, 0, r0, c1, c0, 0 + isb + + ldmfd sp!, {r4 - r12, pc} +ENDPROC(at91_enable_l1_l2_cache) + +at91_l2cc_base_addr: + .word at91_l2cc_base +#endif -- 1.7.9.5
WARNING: multiple messages have this Message-ID (diff)
From: wenyou.yang@atmel.com (Wenyou Yang) To: linux-arm-kernel@lists.infradead.org Subject: [PATCH 5/7] pm: at91: add disable/enable the L1/L2 cache while suspend/resume Date: Mon, 26 Jan 2015 18:07:57 +0800 [thread overview] Message-ID: <1422266877-24628-1-git-send-email-wenyou.yang@atmel.com> (raw) In-Reply-To: <1422266617-24381-1-git-send-email-wenyou.yang@atmel.com> For the sama5, disable L1 D-cache and L2 cache before the cpu go to wfi, after wakeing up, enable L1 D-cache and L2 cache. Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com> --- arch/arm/mach-at91/pm.c | 9 ++++ arch/arm/mach-at91/pm_suspend.S | 107 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+) diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index f75dc32..50cde92 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -35,6 +35,9 @@ #include "generic.h" #include "pm.h" +void __weak at91_disable_l1_l2_cache(void) {} +void __weak at91_enable_l1_l2_cache(void) {} + struct at91_pm_struct at91_pm_data; static int at91_pm_valid_state(suspend_state_t state) @@ -142,8 +145,14 @@ static void at91_pm_suspend(suspend_state_t state) pm_data |= (state == PM_SUSPEND_MEM) ? AT91_PM_MODE(AT91_PM_SLOW_CLOCK) : 0; + /* Disable L1 D-cache and L2 cache */ + at91_disable_l1_l2_cache(); + at91_suspend_sram_fn(at91_pmc_base, at91_ramc_base[0], at91_ramc_base[1], pm_data); + + /* Enable L1 D-cache and L2 cache */ + at91_enable_l1_l2_cache(); } static int at91_pm_enter(suspend_state_t state) diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S index 88cf228..e6e7f7a 100644 --- a/arch/arm/mach-at91/pm_suspend.S +++ b/arch/arm/mach-at91/pm_suspend.S @@ -15,6 +15,7 @@ #include <linux/clk/at91_pmc.h> #include <mach/hardware.h> #include <mach/at91_ramc.h> +#include <asm/hardware/cache-l2x0.h> #include "pm.h" @@ -329,3 +330,109 @@ ram_restored: ENTRY(at91_pm_suspend_in_sram_sz) .word .-at91_pm_suspend_in_sram + +/*---------------------------------------*/ + +#if defined(CONFIG_CPU_V7) + +/* + * void at91_disable_l1_l2_cache(void) + * + * This function code disables, cleans & invalidates the L1 D-cache + * and cleans, invalidates & disable the L2 cache. + */ +ENTRY(at91_disable_l1_l2_cache) + stmfd sp!, {r4 - r12, lr} + + /* + * Flush all data from the L1 D-cache before disabling + * SCTLR.C bit. + */ + bl v7_flush_dcache_all + + /* + * 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 D-cache. Even though only invalidate is + * necessary exported flush API is used here. Doing clean + * on already clean cache would be almost NOP. + */ + bl v7_flush_dcache_all + + /* + * Clean and invalidate the L2 cache. + * Common cache-l2x0.c functions can't be used here since it + * uses spinlocks. We are out of coherency here with data cache + * disabled. The spinlock implementation uses exclusive load/store + * instruction which can fail without data cache being enabled. + * Because of this, CPU can lead to deadlock. + */ + ldr r1, at91_l2cc_base_addr + ldr r2, [r1] + cmp r2, #0 + beq skip_l2disable + mov r0, #0xff + str r0, [r2, #L2X0_CLEAN_INV_WAY] +wait: + ldr r0, [r2, #L2X0_CLEAN_INV_WAY] + mov r1, #0xff + ands r0, r0, r1 + bne wait + + mov r0, #0 + str r0, [r2, #L2X0_CTRL] + +l2x_sync: + ldr r0, [r2, #L2X0_CACHE_SYNC] + bic r0, r0, #0x1 + str r0, [r2, #L2X0_CACHE_SYNC] +sync: + ldr r0, [r2, #L2X0_CACHE_SYNC] + ands r0, r0, #0x1 + bne sync + +skip_l2disable: + ldmfd sp!, {r4 - r12, pc} +ENDPROC(at91_disable_l1_l2_cache) + +/* + * void at91_enable_l1_l2_cache(void) + * + * This function code enables the L1 D-cache and the L2 cache. + */ +ENTRY(at91_enable_l1_l2_cache) + stmfd sp!, {r4 - r12, lr} + + /* Enable the L2 cache */ + ldr r1, at91_l2cc_base_addr + ldr r2, [r1] + cmp r2, #0 + beq skip_l2en + ldr r0, [r2, #L2X0_CTRL] + ands r0, r0, #L2X0_CTRL_EN + bne skip_l2en @ Skip if already enabled + mov r0, #L2X0_CTRL_EN + str r0, [r2, #L2X0_CTRL] +skip_l2en: + + /* Enable the L1 D-cache */ + mrc p15, 0, r0, c1, c0, 0 + tst r0, #(1 << 2) @ Check C bit enabled? + orreq r0, r0, #(1 << 2) @ Enable the C bit + mcreq p15, 0, r0, c1, c0, 0 + isb + + ldmfd sp!, {r4 - r12, pc} +ENDPROC(at91_enable_l1_l2_cache) + +at91_l2cc_base_addr: + .word at91_l2cc_base +#endif -- 1.7.9.5
next prev parent reply other threads:[~2015-01-26 10:11 UTC|newest] Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top 2015-01-26 10:03 [PATCH 0/7] AT91 pm improvements for 3.20 Wenyou Yang 2015-01-26 10:03 ` Wenyou Yang 2015-01-26 10:04 ` [PATCH 1/7] pm: at91: achieve the memory controller's type from the dts file Wenyou Yang 2015-01-26 10:04 ` Wenyou Yang 2015-01-26 10:06 ` [PATCH 2/7] pm: at91: pm_suspend: add the WFI support for ARMv7 Wenyou Yang 2015-01-26 10:06 ` Wenyou Yang 2015-01-26 13:05 ` Sergei Shtylyov 2015-01-26 13:05 ` Sergei Shtylyov 2015-01-27 4:44 ` Yang, Wenyou 2015-01-27 4:44 ` Yang, Wenyou 2015-01-28 11:25 ` Lorenzo Pieralisi 2015-01-28 11:25 ` Lorenzo Pieralisi 2015-01-29 2:36 ` Yang, Wenyou 2015-01-29 2:36 ` Yang, Wenyou 2015-01-29 12:22 ` Lorenzo Pieralisi 2015-01-29 12:22 ` Lorenzo Pieralisi 2015-01-30 7:23 ` Yang, Wenyou 2015-01-30 7:23 ` Yang, Wenyou 2015-01-30 10:17 ` Lorenzo Pieralisi 2015-01-30 10:17 ` Lorenzo Pieralisi 2015-01-30 10:44 ` Lorenzo Pieralisi 2015-01-30 10:44 ` Lorenzo Pieralisi 2015-01-26 10:06 ` [PATCH 3/7] pm: at91: pm_suspend: MOR register KEY was missing Wenyou Yang 2015-01-26 10:06 ` Wenyou Yang 2015-01-26 10:07 ` [PATCH 4/7] ARM: at91: enable the L2 Cache controller Wenyou Yang 2015-01-26 10:07 ` Wenyou Yang 2015-01-26 11:46 ` Mark Rutland 2015-01-26 11:46 ` Mark Rutland 2015-01-26 12:45 ` Russell King - ARM Linux 2015-01-26 12:45 ` Russell King - ARM Linux 2015-01-26 22:36 ` Alexandre Belloni 2015-01-26 22:36 ` Alexandre Belloni 2015-01-27 5:11 ` Yang, Wenyou 2015-01-27 5:11 ` Yang, Wenyou 2015-01-26 10:07 ` Wenyou Yang [this message] 2015-01-26 10:07 ` [PATCH 5/7] pm: at91: add disable/enable the L1/L2 cache while suspend/resume Wenyou Yang 2015-01-26 10:08 ` [PATCH 6/7] pm: at91: add achieve the mpddrc peripheral ID and the DDR clock ID support Wenyou Yang 2015-01-26 10:08 ` Wenyou Yang 2015-01-26 11:49 ` Mark Rutland 2015-01-26 11:49 ` Mark Rutland 2015-01-27 5:24 ` Yang, Wenyou 2015-01-27 5:24 ` Yang, Wenyou 2015-01-26 10:08 ` [PATCH 7/7] pm: at91: add disable/enable the mpddrc's clock and DDR clock support Wenyou Yang 2015-01-26 10:08 ` Wenyou Yang
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1422266877-24628-1-git-send-email-wenyou.yang@atmel.com \ --to=wenyou.yang@atmel.com \ --cc=Patrice.VILCHEZ@atmel.com \ --cc=alexandre.belloni@free-electrons.com \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux@arm.linux.org.uk \ --cc=nicolas.ferre@atmel.com \ --cc=peda@axentia.se \ --cc=sylvain.rochet@finsecur.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.