Commit bbc8d77db655be61a21d7623428c46c578a866d3
Committed by
Nicolas Pitre
1 parent
62158f817a
Exists in
smarc-imx_3.14.28_1.0.0_ga
and in
1 other branch
ARM: introduce common set_auxcr/get_auxcr functions
Move the private set_auxcr/get_auxcr functions from drivers/cpuidle/cpuidle-calxeda.c so they can be used across platforms. Signed-off-by: Rob Herring <rob.herring@calxeda.com> Cc: Russell King <linux@arm.linux.org.uk> Signed-off-by: Nicolas Pitre <nico@linaro.org> Acked-by: Tony Lindgren <tony@atomide.com> Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com> Reviewed-by: Will Deacon <will.deacon@arm.com>
Showing 2 changed files with 14 additions and 14 deletions Inline Diff
arch/arm/include/asm/cp15.h
1 | #ifndef __ASM_ARM_CP15_H | 1 | #ifndef __ASM_ARM_CP15_H |
2 | #define __ASM_ARM_CP15_H | 2 | #define __ASM_ARM_CP15_H |
3 | 3 | ||
4 | #include <asm/barrier.h> | 4 | #include <asm/barrier.h> |
5 | 5 | ||
6 | /* | 6 | /* |
7 | * CR1 bits (CP#15 CR1) | 7 | * CR1 bits (CP#15 CR1) |
8 | */ | 8 | */ |
9 | #define CR_M (1 << 0) /* MMU enable */ | 9 | #define CR_M (1 << 0) /* MMU enable */ |
10 | #define CR_A (1 << 1) /* Alignment abort enable */ | 10 | #define CR_A (1 << 1) /* Alignment abort enable */ |
11 | #define CR_C (1 << 2) /* Dcache enable */ | 11 | #define CR_C (1 << 2) /* Dcache enable */ |
12 | #define CR_W (1 << 3) /* Write buffer enable */ | 12 | #define CR_W (1 << 3) /* Write buffer enable */ |
13 | #define CR_P (1 << 4) /* 32-bit exception handler */ | 13 | #define CR_P (1 << 4) /* 32-bit exception handler */ |
14 | #define CR_D (1 << 5) /* 32-bit data address range */ | 14 | #define CR_D (1 << 5) /* 32-bit data address range */ |
15 | #define CR_L (1 << 6) /* Implementation defined */ | 15 | #define CR_L (1 << 6) /* Implementation defined */ |
16 | #define CR_B (1 << 7) /* Big endian */ | 16 | #define CR_B (1 << 7) /* Big endian */ |
17 | #define CR_S (1 << 8) /* System MMU protection */ | 17 | #define CR_S (1 << 8) /* System MMU protection */ |
18 | #define CR_R (1 << 9) /* ROM MMU protection */ | 18 | #define CR_R (1 << 9) /* ROM MMU protection */ |
19 | #define CR_F (1 << 10) /* Implementation defined */ | 19 | #define CR_F (1 << 10) /* Implementation defined */ |
20 | #define CR_Z (1 << 11) /* Implementation defined */ | 20 | #define CR_Z (1 << 11) /* Implementation defined */ |
21 | #define CR_I (1 << 12) /* Icache enable */ | 21 | #define CR_I (1 << 12) /* Icache enable */ |
22 | #define CR_V (1 << 13) /* Vectors relocated to 0xffff0000 */ | 22 | #define CR_V (1 << 13) /* Vectors relocated to 0xffff0000 */ |
23 | #define CR_RR (1 << 14) /* Round Robin cache replacement */ | 23 | #define CR_RR (1 << 14) /* Round Robin cache replacement */ |
24 | #define CR_L4 (1 << 15) /* LDR pc can set T bit */ | 24 | #define CR_L4 (1 << 15) /* LDR pc can set T bit */ |
25 | #define CR_DT (1 << 16) | 25 | #define CR_DT (1 << 16) |
26 | #define CR_IT (1 << 18) | 26 | #define CR_IT (1 << 18) |
27 | #define CR_ST (1 << 19) | 27 | #define CR_ST (1 << 19) |
28 | #define CR_FI (1 << 21) /* Fast interrupt (lower latency mode) */ | 28 | #define CR_FI (1 << 21) /* Fast interrupt (lower latency mode) */ |
29 | #define CR_U (1 << 22) /* Unaligned access operation */ | 29 | #define CR_U (1 << 22) /* Unaligned access operation */ |
30 | #define CR_XP (1 << 23) /* Extended page tables */ | 30 | #define CR_XP (1 << 23) /* Extended page tables */ |
31 | #define CR_VE (1 << 24) /* Vectored interrupts */ | 31 | #define CR_VE (1 << 24) /* Vectored interrupts */ |
32 | #define CR_EE (1 << 25) /* Exception (Big) Endian */ | 32 | #define CR_EE (1 << 25) /* Exception (Big) Endian */ |
33 | #define CR_TRE (1 << 28) /* TEX remap enable */ | 33 | #define CR_TRE (1 << 28) /* TEX remap enable */ |
34 | #define CR_AFE (1 << 29) /* Access flag enable */ | 34 | #define CR_AFE (1 << 29) /* Access flag enable */ |
35 | #define CR_TE (1 << 30) /* Thumb exception enable */ | 35 | #define CR_TE (1 << 30) /* Thumb exception enable */ |
36 | 36 | ||
37 | #ifndef __ASSEMBLY__ | 37 | #ifndef __ASSEMBLY__ |
38 | 38 | ||
39 | #if __LINUX_ARM_ARCH__ >= 4 | 39 | #if __LINUX_ARM_ARCH__ >= 4 |
40 | #define vectors_high() (cr_alignment & CR_V) | 40 | #define vectors_high() (cr_alignment & CR_V) |
41 | #else | 41 | #else |
42 | #define vectors_high() (0) | 42 | #define vectors_high() (0) |
43 | #endif | 43 | #endif |
44 | 44 | ||
45 | #ifdef CONFIG_CPU_CP15 | 45 | #ifdef CONFIG_CPU_CP15 |
46 | 46 | ||
47 | extern unsigned long cr_no_alignment; /* defined in entry-armv.S */ | 47 | extern unsigned long cr_no_alignment; /* defined in entry-armv.S */ |
48 | extern unsigned long cr_alignment; /* defined in entry-armv.S */ | 48 | extern unsigned long cr_alignment; /* defined in entry-armv.S */ |
49 | 49 | ||
50 | static inline unsigned int get_cr(void) | 50 | static inline unsigned int get_cr(void) |
51 | { | 51 | { |
52 | unsigned int val; | 52 | unsigned int val; |
53 | asm("mrc p15, 0, %0, c1, c0, 0 @ get CR" : "=r" (val) : : "cc"); | 53 | asm("mrc p15, 0, %0, c1, c0, 0 @ get CR" : "=r" (val) : : "cc"); |
54 | return val; | 54 | return val; |
55 | } | 55 | } |
56 | 56 | ||
57 | static inline void set_cr(unsigned int val) | 57 | static inline void set_cr(unsigned int val) |
58 | { | 58 | { |
59 | asm volatile("mcr p15, 0, %0, c1, c0, 0 @ set CR" | 59 | asm volatile("mcr p15, 0, %0, c1, c0, 0 @ set CR" |
60 | : : "r" (val) : "cc"); | 60 | : : "r" (val) : "cc"); |
61 | isb(); | 61 | isb(); |
62 | } | 62 | } |
63 | 63 | ||
64 | static inline unsigned int get_auxcr(void) | ||
65 | { | ||
66 | unsigned int val; | ||
67 | asm("mrc p15, 0, %0, c1, c0, 1 @ get AUXCR" : "=r" (val)); | ||
68 | return val; | ||
69 | } | ||
70 | |||
71 | static inline void set_auxcr(unsigned int val) | ||
72 | { | ||
73 | asm volatile("mcr p15, 0, %0, c1, c0, 1 @ set AUXCR" | ||
74 | : : "r" (val)); | ||
75 | isb(); | ||
76 | } | ||
77 | |||
64 | #ifndef CONFIG_SMP | 78 | #ifndef CONFIG_SMP |
65 | extern void adjust_cr(unsigned long mask, unsigned long set); | 79 | extern void adjust_cr(unsigned long mask, unsigned long set); |
66 | #endif | 80 | #endif |
67 | 81 | ||
68 | #define CPACC_FULL(n) (3 << (n * 2)) | 82 | #define CPACC_FULL(n) (3 << (n * 2)) |
69 | #define CPACC_SVC(n) (1 << (n * 2)) | 83 | #define CPACC_SVC(n) (1 << (n * 2)) |
70 | #define CPACC_DISABLE(n) (0 << (n * 2)) | 84 | #define CPACC_DISABLE(n) (0 << (n * 2)) |
71 | 85 | ||
72 | static inline unsigned int get_copro_access(void) | 86 | static inline unsigned int get_copro_access(void) |
73 | { | 87 | { |
74 | unsigned int val; | 88 | unsigned int val; |
75 | asm("mrc p15, 0, %0, c1, c0, 2 @ get copro access" | 89 | asm("mrc p15, 0, %0, c1, c0, 2 @ get copro access" |
76 | : "=r" (val) : : "cc"); | 90 | : "=r" (val) : : "cc"); |
77 | return val; | 91 | return val; |
78 | } | 92 | } |
79 | 93 | ||
80 | static inline void set_copro_access(unsigned int val) | 94 | static inline void set_copro_access(unsigned int val) |
81 | { | 95 | { |
82 | asm volatile("mcr p15, 0, %0, c1, c0, 2 @ set copro access" | 96 | asm volatile("mcr p15, 0, %0, c1, c0, 2 @ set copro access" |
83 | : : "r" (val) : "cc"); | 97 | : : "r" (val) : "cc"); |
84 | isb(); | 98 | isb(); |
85 | } | 99 | } |
86 | 100 | ||
87 | #else /* ifdef CONFIG_CPU_CP15 */ | 101 | #else /* ifdef CONFIG_CPU_CP15 */ |
88 | 102 | ||
89 | /* | 103 | /* |
90 | * cr_alignment and cr_no_alignment are tightly coupled to cp15 (at least in the | 104 | * cr_alignment and cr_no_alignment are tightly coupled to cp15 (at least in the |
91 | * minds of the developers). Yielding 0 for machines without a cp15 (and making | 105 | * minds of the developers). Yielding 0 for machines without a cp15 (and making |
92 | * it read-only) is fine for most cases and saves quite some #ifdeffery. | 106 | * it read-only) is fine for most cases and saves quite some #ifdeffery. |
93 | */ | 107 | */ |
94 | #define cr_no_alignment UL(0) | 108 | #define cr_no_alignment UL(0) |
95 | #define cr_alignment UL(0) | 109 | #define cr_alignment UL(0) |
96 | 110 | ||
97 | #endif /* ifdef CONFIG_CPU_CP15 / else */ | 111 | #endif /* ifdef CONFIG_CPU_CP15 / else */ |
98 | 112 | ||
99 | #endif /* ifndef __ASSEMBLY__ */ | 113 | #endif /* ifndef __ASSEMBLY__ */ |
100 | 114 | ||
101 | #endif | 115 | #endif |
102 | 116 |
drivers/cpuidle/cpuidle-calxeda.c
1 | /* | 1 | /* |
2 | * Copyright 2012 Calxeda, Inc. | 2 | * Copyright 2012 Calxeda, Inc. |
3 | * | 3 | * |
4 | * Based on arch/arm/plat-mxc/cpuidle.c: #v3.7 | 4 | * Based on arch/arm/plat-mxc/cpuidle.c: #v3.7 |
5 | * Copyright 2012 Freescale Semiconductor, Inc. | 5 | * Copyright 2012 Freescale Semiconductor, Inc. |
6 | * Copyright 2012 Linaro Ltd. | 6 | * Copyright 2012 Linaro Ltd. |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify it | 8 | * This program is free software; you can redistribute it and/or modify it |
9 | * under the terms and conditions of the GNU General Public License, | 9 | * under the terms and conditions of the GNU General Public License, |
10 | * version 2, as published by the Free Software Foundation. | 10 | * version 2, as published by the Free Software Foundation. |
11 | * | 11 | * |
12 | * This program is distributed in the hope it will be useful, but WITHOUT | 12 | * This program is distributed in the hope it will be useful, but WITHOUT |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
15 | * more details. | 15 | * more details. |
16 | * | 16 | * |
17 | * You should have received a copy of the GNU General Public License along with | 17 | * You should have received a copy of the GNU General Public License along with |
18 | * this program. If not, see <http://www.gnu.org/licenses/>. | 18 | * this program. If not, see <http://www.gnu.org/licenses/>. |
19 | * | 19 | * |
20 | * Maintainer: Rob Herring <rob.herring@calxeda.com> | 20 | * Maintainer: Rob Herring <rob.herring@calxeda.com> |
21 | */ | 21 | */ |
22 | 22 | ||
23 | #include <linux/cpuidle.h> | 23 | #include <linux/cpuidle.h> |
24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
25 | #include <linux/io.h> | 25 | #include <linux/io.h> |
26 | #include <linux/of.h> | 26 | #include <linux/of.h> |
27 | #include <linux/time.h> | 27 | #include <linux/time.h> |
28 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
29 | #include <linux/suspend.h> | 29 | #include <linux/suspend.h> |
30 | #include <asm/cpuidle.h> | 30 | #include <asm/cpuidle.h> |
31 | #include <asm/proc-fns.h> | 31 | #include <asm/proc-fns.h> |
32 | #include <asm/smp_scu.h> | 32 | #include <asm/smp_scu.h> |
33 | #include <asm/suspend.h> | 33 | #include <asm/suspend.h> |
34 | #include <asm/cacheflush.h> | 34 | #include <asm/cacheflush.h> |
35 | #include <asm/cp15.h> | 35 | #include <asm/cp15.h> |
36 | 36 | ||
37 | extern void highbank_set_cpu_jump(int cpu, void *jump_addr); | 37 | extern void highbank_set_cpu_jump(int cpu, void *jump_addr); |
38 | extern void *scu_base_addr; | 38 | extern void *scu_base_addr; |
39 | 39 | ||
40 | static inline unsigned int get_auxcr(void) | ||
41 | { | ||
42 | unsigned int val; | ||
43 | asm("mrc p15, 0, %0, c1, c0, 1 @ get AUXCR" : "=r" (val) : : "cc"); | ||
44 | return val; | ||
45 | } | ||
46 | |||
47 | static inline void set_auxcr(unsigned int val) | ||
48 | { | ||
49 | asm volatile("mcr p15, 0, %0, c1, c0, 1 @ set AUXCR" | ||
50 | : : "r" (val) : "cc"); | ||
51 | isb(); | ||
52 | } | ||
53 | |||
54 | static noinline void calxeda_idle_restore(void) | 40 | static noinline void calxeda_idle_restore(void) |
55 | { | 41 | { |
56 | set_cr(get_cr() | CR_C); | 42 | set_cr(get_cr() | CR_C); |
57 | set_auxcr(get_auxcr() | 0x40); | 43 | set_auxcr(get_auxcr() | 0x40); |
58 | scu_power_mode(scu_base_addr, SCU_PM_NORMAL); | 44 | scu_power_mode(scu_base_addr, SCU_PM_NORMAL); |
59 | } | 45 | } |
60 | 46 | ||
61 | static int calxeda_idle_finish(unsigned long val) | 47 | static int calxeda_idle_finish(unsigned long val) |
62 | { | 48 | { |
63 | /* Already flushed cache, but do it again as the outer cache functions | 49 | /* Already flushed cache, but do it again as the outer cache functions |
64 | * dirty the cache with spinlocks */ | 50 | * dirty the cache with spinlocks */ |
65 | flush_cache_all(); | 51 | flush_cache_all(); |
66 | 52 | ||
67 | set_auxcr(get_auxcr() & ~0x40); | 53 | set_auxcr(get_auxcr() & ~0x40); |
68 | set_cr(get_cr() & ~CR_C); | 54 | set_cr(get_cr() & ~CR_C); |
69 | 55 | ||
70 | scu_power_mode(scu_base_addr, SCU_PM_DORMANT); | 56 | scu_power_mode(scu_base_addr, SCU_PM_DORMANT); |
71 | 57 | ||
72 | cpu_do_idle(); | 58 | cpu_do_idle(); |
73 | 59 | ||
74 | /* Restore things if we didn't enter power-gating */ | 60 | /* Restore things if we didn't enter power-gating */ |
75 | calxeda_idle_restore(); | 61 | calxeda_idle_restore(); |
76 | return 1; | 62 | return 1; |
77 | } | 63 | } |
78 | 64 | ||
79 | static int calxeda_pwrdown_idle(struct cpuidle_device *dev, | 65 | static int calxeda_pwrdown_idle(struct cpuidle_device *dev, |
80 | struct cpuidle_driver *drv, | 66 | struct cpuidle_driver *drv, |
81 | int index) | 67 | int index) |
82 | { | 68 | { |
83 | highbank_set_cpu_jump(smp_processor_id(), cpu_resume); | 69 | highbank_set_cpu_jump(smp_processor_id(), cpu_resume); |
84 | cpu_suspend(0, calxeda_idle_finish); | 70 | cpu_suspend(0, calxeda_idle_finish); |
85 | return index; | 71 | return index; |
86 | } | 72 | } |
87 | 73 | ||
88 | static struct cpuidle_driver calxeda_idle_driver = { | 74 | static struct cpuidle_driver calxeda_idle_driver = { |
89 | .name = "calxeda_idle", | 75 | .name = "calxeda_idle", |
90 | .states = { | 76 | .states = { |
91 | ARM_CPUIDLE_WFI_STATE, | 77 | ARM_CPUIDLE_WFI_STATE, |
92 | { | 78 | { |
93 | .name = "PG", | 79 | .name = "PG", |
94 | .desc = "Power Gate", | 80 | .desc = "Power Gate", |
95 | .flags = CPUIDLE_FLAG_TIME_VALID, | 81 | .flags = CPUIDLE_FLAG_TIME_VALID, |
96 | .exit_latency = 30, | 82 | .exit_latency = 30, |
97 | .power_usage = 50, | 83 | .power_usage = 50, |
98 | .target_residency = 200, | 84 | .target_residency = 200, |
99 | .enter = calxeda_pwrdown_idle, | 85 | .enter = calxeda_pwrdown_idle, |
100 | }, | 86 | }, |
101 | }, | 87 | }, |
102 | .state_count = 2, | 88 | .state_count = 2, |
103 | }; | 89 | }; |
104 | 90 | ||
105 | static int __init calxeda_cpuidle_init(void) | 91 | static int __init calxeda_cpuidle_init(void) |
106 | { | 92 | { |
107 | if (!of_machine_is_compatible("calxeda,highbank")) | 93 | if (!of_machine_is_compatible("calxeda,highbank")) |
108 | return -ENODEV; | 94 | return -ENODEV; |
109 | 95 | ||
110 | return cpuidle_register(&calxeda_idle_driver, NULL); | 96 | return cpuidle_register(&calxeda_idle_driver, NULL); |
111 | } | 97 | } |
112 | module_init(calxeda_cpuidle_init); | 98 | module_init(calxeda_cpuidle_init); |
113 | 99 |