GNU Linux-libre 6.1.90-gnu
[releases.git] / arch / arm / mach-pxa / standby.S
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * PXA27x standby mode
4  *
5  * Author: David Burrage
6  *
7  * 2005 (c) MontaVista Software, Inc.
8  */
9
10 #include <linux/linkage.h>
11 #include <asm/assembler.h>
12
13 #include "pxa2xx-regs.h"
14
15                 .text
16
17 #ifdef CONFIG_PXA27x
18 ENTRY(pxa_cpu_standby)
19         ldr     r0, =PSSR
20         mov     r1, #(PSSR_PH | PSSR_STS)
21         mov     r2, #PWRMODE_STANDBY
22         mov     r3, #UNCACHED_PHYS_0    @ Read mem context in.
23         ldr     ip, [r3]
24         b       1f
25
26         .align  5
27 1:      mcr     p14, 0, r2, c7, c0, 0   @ put the system into Standby
28         str     r1, [r0]                @ make sure PSSR_PH/STS are clear
29         ret     lr
30
31 #endif
32
33 #ifdef CONFIG_PXA3xx
34
35 #define PXA3_MDCNFG             0x0000
36 #define PXA3_MDCNFG_DMCEN       (1 << 30)
37 #define PXA3_DDR_HCAL           0x0060
38 #define PXA3_DDR_HCAL_HCRNG     0x1f
39 #define PXA3_DDR_HCAL_HCPROG    (1 << 28)
40 #define PXA3_DDR_HCAL_HCEN      (1 << 31)
41 #define PXA3_DMCIER             0x0070
42 #define PXA3_DMCIER_EDLP        (1 << 29)
43 #define PXA3_DMCISR             0x0078
44 #define PXA3_RCOMP              0x0100
45 #define PXA3_RCOMP_SWEVAL       (1 << 31)
46
47 ENTRY(pm_enter_standby_start)
48         mov     r1, #0xf6000000                 @ DMEMC_REG_BASE (PXA3_MDCNFG)
49         add     r1, r1, #0x00100000
50
51         /*
52          * Preload the TLB entry for accessing the dynamic memory
53          * controller registers.  Note that page table lookups will
54          * fail until the dynamic memory controller has been
55          * reinitialised - and that includes MMU page table walks.
56          * This also means that only the dynamic memory controller
57          * can be reliably accessed in the code following standby.
58          */
59         ldr     r2, [r1]                        @ Dummy read PXA3_MDCNFG
60
61         mcr     p14, 0, r0, c7, c0, 0
62         .rept   8
63         nop
64         .endr
65
66         ldr     r0, [r1, #PXA3_DDR_HCAL]        @ Clear (and wait for) HCEN
67         bic     r0, r0, #PXA3_DDR_HCAL_HCEN
68         str     r0, [r1, #PXA3_DDR_HCAL]
69 1:      ldr     r0, [r1, #PXA3_DDR_HCAL]
70         tst     r0, #PXA3_DDR_HCAL_HCEN
71         bne     1b
72
73         ldr     r0, [r1, #PXA3_RCOMP]           @ Initiate RCOMP
74         orr     r0, r0, #PXA3_RCOMP_SWEVAL
75         str     r0, [r1, #PXA3_RCOMP]
76
77         mov     r0, #~0                         @ Clear interrupts
78         str     r0, [r1, #PXA3_DMCISR]
79
80         ldr     r0, [r1, #PXA3_DMCIER]          @ set DMIER[EDLP]
81         orr     r0, r0, #PXA3_DMCIER_EDLP
82         str     r0, [r1, #PXA3_DMCIER]
83
84         ldr     r0, [r1, #PXA3_DDR_HCAL]        @ clear HCRNG, set HCPROG, HCEN
85         bic     r0, r0, #PXA3_DDR_HCAL_HCRNG
86         orr     r0, r0, #PXA3_DDR_HCAL_HCEN | PXA3_DDR_HCAL_HCPROG
87         str     r0, [r1, #PXA3_DDR_HCAL]
88
89 1:      ldr     r0, [r1, #PXA3_DMCISR]
90         tst     r0, #PXA3_DMCIER_EDLP
91         beq     1b
92
93         ldr     r0, [r1, #PXA3_MDCNFG]          @ set PXA3_MDCNFG[DMCEN]
94         orr     r0, r0, #PXA3_MDCNFG_DMCEN
95         str     r0, [r1, #PXA3_MDCNFG]
96 1:      ldr     r0, [r1, #PXA3_MDCNFG]
97         tst     r0, #PXA3_MDCNFG_DMCEN
98         beq     1b
99
100         ldr     r0, [r1, #PXA3_DDR_HCAL]        @ set PXA3_DDR_HCAL[HCRNG]
101         orr     r0, r0, #2 @ HCRNG
102         str     r0, [r1, #PXA3_DDR_HCAL]
103
104         ldr     r0, [r1, #PXA3_DMCIER]          @ Clear the interrupt
105         bic     r0, r0, #0x20000000
106         str     r0, [r1, #PXA3_DMCIER]
107
108         ret     lr
109 ENTRY(pm_enter_standby_end)
110
111 #endif