summaryrefslogtreecommitdiff
path: root/arch/arm/mm/proc-v7.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mm/proc-v7.S')
-rw-r--r--arch/arm/mm/proc-v7.S208
1 files changed, 198 insertions, 10 deletions
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 9049c0764db2..e666e4fe029c 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -176,7 +176,9 @@ ENTRY(cpu_v7_set_pte_ext)
ARM( str r3, [r0, #2048]! )
THUMB( add r0, r0, #2048 )
THUMB( str r3, [r0] )
- mcr p15, 0, r0, c7, c10, 1 @ flush_pte
+ mrc p15, 0, r3, c0, c1, 7 @ read ID_MMFR3
+ tst r3, #0xf << 20 @ check the coherent walk bits
+ mcreq p15, 0, r0, c7, c10, 1 @ flush_pte
#endif
mov pc, lr
ENDPROC(cpu_v7_set_pte_ext)
@@ -212,38 +214,136 @@ ENDPROC(cpu_v7_set_pte_ext)
* NS1 = PRRR[19] = 1 - normal shareable property
* NOS = PRRR[24+n] = 1 - not outer shareable
*/
-.equ PRRR, 0xff0a81a8
-.equ NMRR, 0x40e040e0
+.equ PRRR, 0xff0a89a8
+.equ NMRR, 0xc0e044e0
/* Suspend/resume support: derived from arch/arm/mach-s5pv210/sleep.S */
.globl cpu_v7_suspend_size
-.equ cpu_v7_suspend_size, 4 * 9
+.equ cpu_v7_suspend_size, (4 * (10 + 4 + (16 * 2) + (16 * 2)))
+/* 10 CP15 registers
+ * 4 CP14 registers
+ * 16x2 CP14 breakpoint registers (maximum)
+ * 16x2 CP14 watchpoint registers (maximum)
+ */
+
+.macro save_brkpt cm
+ mrc p14, 0, r4, c0, \cm, 4
+ mrc p14, 0, r5, c0, \cm, 5
+ stmia r0!, {r4 - r5}
+.endm
+
+.macro restore_brkpt cm
+ ldmia r0!, {r4 - r5}
+ mcr p14, 0, r4, c0, \cm, 4
+ mcr p14, 0, r5, c0, \cm, 5
+.endm
+
+.macro save_wpt cm
+ mrc p14, 0, r4, c0, \cm, 6
+ mrc p14, 0, r5, c0, \cm, 7
+ stmia r0!, {r4 - r5}
+.endm
+
+.macro restore_wpt cm
+ ldmia r0!, {r4 - r5}
+ mcr p14, 0, r4, c0, \cm, 6
+ mcr p14, 0, r5, c0, \cm, 7
+.endm
+
#ifdef CONFIG_PM_SLEEP
ENTRY(cpu_v7_do_suspend)
- stmfd sp!, {r4 - r11, lr}
+ stmfd sp!, {r0, r3 - r11, lr}
+ mrc p15, 0, r3, c15, c0, 1 @ diag
mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID
mrc p15, 0, r5, c13, c0, 1 @ Context ID
mrc p15, 0, r6, c13, c0, 3 @ User r/o thread ID
- stmia r0!, {r4 - r6}
+ stmia r0!, {r3 - r6}
mrc p15, 0, r6, c3, c0, 0 @ Domain ID
mrc p15, 0, r7, c2, c0, 0 @ TTB 0
mrc p15, 0, r8, c2, c0, 1 @ TTB 1
mrc p15, 0, r9, c1, c0, 0 @ Control register
mrc p15, 0, r10, c1, c0, 1 @ Auxiliary control register
mrc p15, 0, r11, c1, c0, 2 @ Co-processor access control
- stmia r0, {r6 - r11}
- ldmfd sp!, {r4 - r11, pc}
+ stmia r0!, {r6 - r11}
+
+ /* Save CP14 debug controller context */
+ mrc p14, 0, r4, c0, c1, 0 @ DSCR
+ mrc p14, 0, r5, c0, c6, 0 @ WFAR
+ mrc p14, 0, r6, c0, c7, 0 @ VCR
+ mrc p14, 0, r7, c7, c9, 6 @ CLAIM
+ stmia r0!, {r4-r7}
+
+ mrc p14, 0, r8, c0, c0, 0 @ read IDR
+ mov r3, r8, lsr #24
+ and r3, r3, #0xf @ r3 has the number of brkpt
+ rsb r3, r3, #0xf
+
+ /* r3 = (15 - #of brkpt) ;
+ switch offset = r3*12 - 4 = (r3*3 - 1)<<2
+ */
+ add r3, r3, r3, lsl #1
+ sub r3, r3, #1
+ add pc, pc, r3, lsl #2
+
+ save_brkpt c15
+ save_brkpt c14
+ save_brkpt c13
+ save_brkpt c12
+ save_brkpt c11
+ save_brkpt c10
+ save_brkpt c9
+ save_brkpt c8
+ save_brkpt c7
+ save_brkpt c6
+ save_brkpt c5
+ save_brkpt c4
+ save_brkpt c3
+ save_brkpt c2
+ save_brkpt c1
+ save_brkpt c0
+
+ mov r3, r8, lsr #28 @ r3 has the number of wpt
+ rsb r3, r3, #0xf
+
+ /* r3 = (15 - #of wpt) ;
+ switch offset = r3*12 - 4 = (r3*3 - 1)<<2
+ */
+ add r3, r3, r3, lsl #1
+ sub r3, r3, #1
+ add pc, pc, r3, lsl #2
+
+ save_wpt c15
+ save_wpt c14
+ save_wpt c13
+ save_wpt c12
+ save_wpt c11
+ save_wpt c10
+ save_wpt c9
+ save_wpt c8
+ save_wpt c7
+ save_wpt c6
+ save_wpt c5
+ save_wpt c4
+ save_wpt c3
+ save_wpt c2
+ save_wpt c1
+ save_wpt c0
+
+ ldmfd sp!, {r0, r3 - r11, pc}
ENDPROC(cpu_v7_do_suspend)
ENTRY(cpu_v7_do_resume)
mov ip, #0
mcr p15, 0, ip, c8, c7, 0 @ invalidate TLBs
mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
- ldmia r0!, {r4 - r6}
+ ldmia r0!, {r3 - r6}
+#ifndef CONFIG_TRUSTED_FOUNDATIONS
+ mcr p15, 0, r3, c15, c0, 1 @ diag
+#endif
mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID
mcr p15, 0, r5, c13, c0, 1 @ Context ID
mcr p15, 0, r6, c13, c0, 3 @ User r/o thread ID
- ldmia r0, {r6 - r11}
+ ldmia r0!, {r6 - r11}
mcr p15, 0, r6, c3, c0, 0 @ Domain ID
mcr p15, 0, r7, c2, c0, 0 @ TTB 0
mcr p15, 0, r8, c2, c0, 1 @ TTB 1
@@ -257,6 +357,74 @@ ENTRY(cpu_v7_do_resume)
mcr p15, 0, r4, c10, c2, 0 @ write PRRR
mcr p15, 0, r5, c10, c2, 1 @ write NMRR
isb
+
+ /* Restore CP14 debug controller context */
+
+ ldmia r0!, {r2 - r5}
+ mcr p14, 0, r3, c0, c6, 0 @ WFAR
+ mcr p14, 0, r4, c0, c7, 0 @ VCR
+ mcr p14, 0, r5, c7, c8, 6 @ CLAIM
+
+ mrc p14, 0, r8, c0, c0, 0 @ read IDR
+ mov r3, r8, lsr #24
+ and r3, r3, #0xf @ r3 has the number of brkpt
+ rsb r3, r3, #0xf
+
+ /* r3 = (15 - #of wpt) ;
+ switch offset = r3*12 - 4 = (r3*3 - 1)<<2
+ */
+ add r3, r3, r3, lsl #1
+ sub r3, r3, #1
+ add pc, pc, r3, lsl #2
+
+ restore_brkpt c15
+ restore_brkpt c14
+ restore_brkpt c13
+ restore_brkpt c12
+ restore_brkpt c11
+ restore_brkpt c10
+ restore_brkpt c9
+ restore_brkpt c8
+ restore_brkpt c7
+ restore_brkpt c6
+ restore_brkpt c5
+ restore_brkpt c4
+ restore_brkpt c3
+ restore_brkpt c2
+ restore_brkpt c1
+ restore_brkpt c0
+
+ mov r3, r8, lsr #28 @ r3 has the number of wpt
+ rsb r3, r3, #0xf
+
+ /* r3 = (15 - #of wpt) ;
+ switch offset = r3*12 - 4 = (r3*3 - 1)<<2
+ */
+ add r3, r3, r3, lsl #1
+ sub r3, r3, #1
+ add pc, pc, r3, lsl #2
+
+start_restore_wpt:
+ restore_wpt c15
+ restore_wpt c14
+ restore_wpt c13
+ restore_wpt c12
+ restore_wpt c11
+ restore_wpt c10
+ restore_wpt c9
+ restore_wpt c8
+ restore_wpt c7
+ restore_wpt c6
+ restore_wpt c5
+ restore_wpt c4
+ restore_wpt c3
+ restore_wpt c2
+ restore_wpt c1
+ restore_wpt c0
+ isb
+
+ mcr p14, 0, r2, c0, c2, 2 @ DSCR
+ isb
dsb
mov r0, r9 @ control register
mov r2, r7, lsr #14 @ get TTB0 base
@@ -346,6 +514,17 @@ __v7_setup:
2: ldr r10, =0x00000c09 @ Cortex-A9 primary part number
teq r0, r10
bne 3f
+#ifndef CONFIG_TRUSTED_FOUNDATIONS
+ cmp r6, #0x10 @ power ctrl reg added r1p0
+ mrcge p15, 0, r10, c15, c0, 0 @ read power control register
+ orrge r10, r10, #1 @ enable dynamic clock gating
+ mcrge p15, 0, r10, c15, c0, 0 @ write power control register
+#ifdef CONFIG_ARM_ERRATA_720791
+ teq r5, #0x00100000 @ only present in r1p*
+ mrceq p15, 0, r10, c15, c0, 2 @ read "chicken power ctrl" reg
+ orreq r10, r10, #0x30 @ disable core clk gate on
+ mcreq p15, 0, r10, c15, c0, 2 @ instr-side waits
+#endif
#ifdef CONFIG_ARM_ERRATA_742230
cmp r6, #0x22 @ only present up to r2p2
mrcle p15, 0, r10, c15, c0, 1 @ read diagnostic register
@@ -365,6 +544,8 @@ __v7_setup:
teq r6, #0x20 @ present in r2p0
teqne r6, #0x21 @ present in r2p1
teqne r6, #0x22 @ present in r2p2
+ teqne r6, #0x27 @ present in r2p7
+ teqne r6, #0x29 @ present in r2p9
mrceq p15, 0, r10, c15, c0, 1 @ read diagnostic register
orreq r10, r10, #1 << 6 @ set bit #6
mcreq p15, 0, r10, c15, c0, 1 @ write diagnostic register
@@ -375,6 +556,13 @@ __v7_setup:
orrlt r10, r10, #1 << 11 @ set bit #11
mcrlt p15, 0, r10, c15, c0, 1 @ write diagnostic register
#endif
+#ifdef CONFIG_ARM_ERRATA_752520
+ cmp r6, #0x29 @ present prior to r2p9
+ mrclt p15, 0, r10, c15, c0, 1 @ read diagnostic register
+ orrlt r10, r10, #1 << 20 @ set bit #20
+ mcrlt p15, 0, r10, c15, c0, 1 @ write diagnostic register
+#endif
+#endif
3: mov r10, #0
#ifdef HARVARD_CACHE