aboutsummaryrefslogtreecommitdiff
path: root/arch/arm/mach-msm/idle-macros.S
blob: 3d0c93718fadca43a82c76640ec5acada3d1a8df (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <asm/hardware/cache-l2x0.h>

/* Add 300 NOPs after 'wfi' for 8x25 target */
.macro DELAY_8x25, rept
#ifdef CONFIG_ARCH_MSM8625
	.rept   \rept
	nop
	.endr
#endif
.endm

/* Switch between smp_to_amp/amp_to_smp configuration */
.macro SET_SMP_COHERENCY, on = 0
	ldr     r0, =target_type
	ldr     r0, [r0]
	mov     r1, #TARGET_IS_8625
	cmp     r0, r1
	bne     skip\@
	mrc	p15, 0, r0, c1, c0, 1	/* read ACTLR register */
	.if     \on
	orr	r0, r0, #(1 << 6)	/* Set the SMP bit in ACTLR */
	.else
	bic	r0, r0, #(1 << 6)	/* Clear the SMP bit */
	.endif
	mcr	p15, 0, r0, c1, c0, 1	/* write ACTLR register */
	isb
skip\@:
.endm

/*
 * Enable the "L2" cache, not require to restore the controller registers
 */
.macro ENABLE_8x25_L2
	ldr     r0, =target_type
	ldr     r0, [r0]
	mov     r1, #TARGET_IS_8625
	cmp     r0, r1
	bne     skip_enable\@
	ldr     r0, =apps_power_collapse
	ldr     r0, [r0]
	cmp     r0, #POWER_COLLAPSED
	bne     skip_enable\@
	ldr     r0, =l2x0_base_addr
	ldr	r0, [r0]
	mov	r1, #0x1
	str	r1, [r0, #L2X0_CTRL]
	dmb
skip_enable\@:
.endm

/*
 * Perform the required operation
 * operation: type of operation on l2 cache (e.g: clean&inv or inv)
 * l2_enable: enable or disable
 */
.macro DO_CACHE_OPERATION, operation, l2_enable
	ldr     r2, =l2x0_base_addr
	ldr	r2, [r2]
	ldr     r0, =0xffff
	str     r0, [r2, #\operation]
wait\@:
	ldr	r0, [r2, #\operation]
	ldr	r1, =0xffff
	ands    r0, r0, r1
	bne     wait\@
l2x_sync\@:
	mov	r0, #0x0
	str	r0, [r2, #L2X0_CACHE_SYNC]
sync\@:
	ldr	r0, [r2, #L2X0_CACHE_SYNC]
	ands	r0, r0, #0x1
	bne	sync\@
	mov     r1, #\l2_enable
	str     r1, [r2, #L2X0_CTRL]
.endm

/*
 * Clean and invalidate the L2 cache.
 * 1. Check the target type
 * 2. Check whether we are coming from PC are not
 * 3. Save 'aux', 'data latency', & 'prefetch ctlr' registers
 * 4. Start L2 clean & invalidation operation
 * 5. Disable the L2 cache
 */
.macro SUSPEND_8x25_L2
	ldr     r0, =target_type
	ldr     r0, [r0]
	mov     r1, #TARGET_IS_8625
	cmp     r0, r1
	bne     skip_suspend\@
	ldr	r0, =apps_power_collapse
	ldr	r0, [r0]
	cmp	r0, #POWER_COLLAPSED
	bne	skip_suspend\@
	ldr	r0, =l2x0_saved_ctrl_reg_val
	ldr	r1, =l2x0_base_addr
	ldr	r1, [r1]
	ldr	r2, [r1, #L2X0_AUX_CTRL]
	str	r2, [r0, #0x0] /* store aux_ctlr reg value */
	ldr     r2, [r1, #L2X0_DATA_LATENCY_CTRL]
	str     r2, [r0, #0x4] /* store data latency reg value */
	ldr     r2, [r1, #L2X0_PREFETCH_CTRL]
	str     r2, [r0, #0x8] /* store prefetch_ctlr reg value */
	DO_CACHE_OPERATION L2X0_CLEAN_INV_WAY OFF
	dmb
skip_suspend\@:
.endm

/*
 * Coming back from a successful PC
 * 1. Check the target type
 * 2. Check whether we are going to PC are not
 * 3. Disable the L2 cache
 * 4. Restore 'aux', 'data latency', & 'prefetch ctlr' reg
 * 5. Invalidate the cache
 * 6. Enable the L2 cache
 */
.macro RESUME_8x25_L2
	ldr     r0, =target_type
	ldr     r0, [r0]
	mov     r1, #TARGET_IS_8625
	cmp     r0, r1
	bne     skip_resume\@
	ldr	r0, =apps_power_collapse
	ldr	r0, [r0]
	cmp	r0, #POWER_COLLAPSED
	bne	skip_resume\@
	ldr     r1, =l2x0_base_addr
	ldr	r1, [r1]
	mov     r0, #0x0
	str     r0, [r1, #L2X0_CTRL]
	ldr     r0, =l2x0_saved_ctrl_reg_val
	ldr     r2, [r0, #0x0]
	str	r2, [r1, #L2X0_AUX_CTRL] /* restore aux_ctlr reg value */
	ldr	r2, [r0, #0x4]
	str	r2, [r1, #L2X0_DATA_LATENCY_CTRL]
	ldr	r2, [r0, #0x8]
	str     r2, [r1, #L2X0_PREFETCH_CTRL]
	DO_CACHE_OPERATION L2X0_INV_WAY ON
skip_resume\@:
.endm