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