Commit bbc8d77db655be61a21d7623428c46c578a866d3

Authored by Rob Herring
Committed by Nicolas Pitre
1 parent 62158f817a

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