File Index
Files and directories
Sign in
FILE

sleep.S

File preview with syntax highlighting.

linux-6.19.14/arch/arm/mach-davinci/sleep.S S
  1/* SPDX-License-Identifier: GPL-2.0-only */
  2/*
  3 * (C) Copyright 2009, Texas Instruments, Inc. https://www.ti.com/
  4 */
  5
  6/* replicated define because linux/bitops.h cannot be included in assembly */
  7#define BIT(nr)			(1 << (nr))
  8
  9#include <linux/linkage.h>
 10#include <asm/assembler.h>
 11#include "psc.h"
 12#include "ddr2.h"
 13
 14#include "clock.h"
 15
 16/* Arbitrary, hardware currently does not update PHYRDY correctly */
 17#define PHYRDY_CYCLES		0x1000
 18
 19/* Assume 25 MHz speed for the cycle conversions since PLLs are bypassed */
 20#define PLL_BYPASS_CYCLES	(PLL_BYPASS_TIME * 25)
 21#define PLL_RESET_CYCLES	(PLL_RESET_TIME	* 25)
 22#define PLL_LOCK_CYCLES		(PLL_LOCK_TIME * 25)
 23
 24#define DEEPSLEEP_SLEEPENABLE_BIT	BIT(31)
 25
 26	.text
 27	.arch	armv5te
 28/*
 29 * Move DaVinci into deep sleep state
 30 *
 31 * Note: This code is copied to internal SRAM by PM code. When the DaVinci
 32 *	 wakes up it continues execution at the point it went to sleep.
 33 * Register Usage:
 34 * 	r0: contains virtual base for DDR2 controller
 35 * 	r1: contains virtual base for DDR2 Power and Sleep controller (PSC)
 36 * 	r2: contains PSC number for DDR2
 37 * 	r3: contains virtual base DDR2 PLL controller
 38 * 	r4: contains virtual address of the DEEPSLEEP register
 39 */
 40ENTRY(davinci_cpu_suspend)
 41	stmfd	sp!, {r0-r12, lr}		@ save registers on stack
 42
 43	ldr 	ip, CACHE_FLUSH
 44	blx	ip
 45
 46	ldmia	r0, {r0-r4}
 47
 48	/*
 49	 * Switch DDR to self-refresh mode.
 50	 */
 51
 52	/* calculate SDRCR address */
 53	ldr	ip, [r0, #DDR2_SDRCR_OFFSET]
 54	bic	ip, ip, #DDR2_SRPD_BIT
 55	orr	ip, ip, #DDR2_LPMODEN_BIT
 56	str	ip, [r0, #DDR2_SDRCR_OFFSET]
 57
 58	ldr	ip, [r0, #DDR2_SDRCR_OFFSET]
 59	orr	ip, ip, #DDR2_MCLKSTOPEN_BIT
 60	str	ip, [r0, #DDR2_SDRCR_OFFSET]
 61
 62       mov	ip, #PHYRDY_CYCLES
 631:     subs	ip, ip, #0x1
 64       bne	1b
 65
 66       /* Disable DDR2 LPSC */
 67	mov	r7, r0
 68	mov	r0, #0x2
 69	bl davinci_ddr_psc_config
 70	mov	r0, r7
 71
 72	/* Disable clock to DDR PHY */
 73	ldr	ip, [r3, #PLLDIV1]
 74	bic	ip, ip, #PLLDIV_EN
 75	str	ip, [r3, #PLLDIV1]
 76
 77	/* Put the DDR PLL in bypass and power down */
 78	ldr	ip, [r3, #PLLCTL]
 79	bic	ip, ip, #PLLCTL_PLLENSRC
 80	bic	ip, ip, #PLLCTL_PLLEN
 81	str	ip, [r3, #PLLCTL]
 82
 83	/* Wait for PLL to switch to bypass */
 84       mov	ip, #PLL_BYPASS_CYCLES
 852:     subs	ip, ip, #0x1
 86       bne	2b
 87
 88       /* Power down the PLL */
 89	ldr	ip, [r3, #PLLCTL]
 90	orr	ip, ip, #PLLCTL_PLLPWRDN
 91	str	ip, [r3, #PLLCTL]
 92
 93	/* Go to deep sleep */
 94	ldr	ip, [r4]
 95	orr	ip, ip, #DEEPSLEEP_SLEEPENABLE_BIT
 96	/* System goes to sleep beyond after this instruction */
 97	str	ip, [r4]
 98
 99	/* Wake up from sleep */
100
101	/* Clear sleep enable */
102	ldr	ip, [r4]
103	bic	ip, ip, #DEEPSLEEP_SLEEPENABLE_BIT
104	str	ip, [r4]
105
106	/* initialize the DDR PLL controller */
107
108	/* Put PLL in reset */
109	ldr	ip, [r3, #PLLCTL]
110	bic	ip, ip, #PLLCTL_PLLRST
111	str	ip, [r3, #PLLCTL]
112
113	/* Clear PLL power down */
114	ldr	ip, [r3, #PLLCTL]
115	bic	ip, ip, #PLLCTL_PLLPWRDN
116	str	ip, [r3, #PLLCTL]
117
118       mov	ip, #PLL_RESET_CYCLES
1193:     subs	ip, ip, #0x1
120       bne	3b
121
122       /* Bring PLL out of reset */
123	ldr	ip, [r3, #PLLCTL]
124	orr	ip, ip, #PLLCTL_PLLRST
125	str	ip, [r3, #PLLCTL]
126
127	/* Wait for PLL to lock (assume prediv = 1, 25MHz OSCIN) */
128       mov	ip, #PLL_LOCK_CYCLES
1294:     subs	ip, ip, #0x1
130       bne	4b
131
132       /* Remove PLL from bypass mode */
133	ldr	ip, [r3, #PLLCTL]
134	bic	ip, ip, #PLLCTL_PLLENSRC
135	orr	ip, ip, #PLLCTL_PLLEN
136	str	ip, [r3, #PLLCTL]
137
138	/* Start 2x clock to DDR2 */
139
140	ldr	ip, [r3, #PLLDIV1]
141	orr	ip, ip, #PLLDIV_EN
142	str	ip, [r3, #PLLDIV1]
143
144	/* Enable VCLK */
145
146       /* Enable DDR2 LPSC */
147	mov	r7, r0
148	mov	r0, #0x3
149	bl davinci_ddr_psc_config
150	mov	r0, r7
151
152	/* clear  MCLKSTOPEN */
153
154	ldr	ip, [r0, #DDR2_SDRCR_OFFSET]
155	bic	ip, ip, #DDR2_MCLKSTOPEN_BIT
156	str	ip, [r0, #DDR2_SDRCR_OFFSET]
157
158	ldr	ip, [r0, #DDR2_SDRCR_OFFSET]
159	bic	ip, ip, #DDR2_LPMODEN_BIT
160	str	ip, [r0, #DDR2_SDRCR_OFFSET]
161
162	/* Restore registers and return */
163	ldmfd   sp!, {r0-r12, pc}
164
165ENDPROC(davinci_cpu_suspend)
166
167/*
168 * Disables or Enables DDR2 LPSC
169 * Register Usage:
170 * 	r0: Enable or Disable LPSC r0 = 0x3 => Enable, r0 = 0x2 => Disable LPSC
171 * 	r1: contains virtual base for DDR2 Power and Sleep controller (PSC)
172 * 	r2: contains PSC number for DDR2
173 */
174ENTRY(davinci_ddr_psc_config)
175	/* Set next state in mdctl for DDR2 */
176	mov	r6, #MDCTL
177	add	r6, r6, r2, lsl #2
178	ldr	ip, [r1, r6]
179	bic	ip, ip, #MDSTAT_STATE_MASK
180	orr	ip, ip, r0
181	str	ip, [r1, r6]
182
183	/* Enable the Power Domain Transition Command */
184	ldr	ip, [r1, #PTCMD]
185	orr	ip, ip, #0x1
186	str	ip, [r1, #PTCMD]
187
188	/* Check for Transition Complete (PTSTAT) */
189ptstat_done:
190	ldr	ip, [r1, #PTSTAT]
191	and	ip, ip, #0x1
192	cmp 	ip, #0x0
193	bne	ptstat_done
194
195	/* Check for DDR2 clock disable completion; */
196	mov	r6, #MDSTAT
197	add	r6, r6, r2, lsl #2
198ddr2clk_stop_done:
199	ldr	ip, [r1, r6]
200	and	ip, ip, #MDSTAT_STATE_MASK
201	cmp	ip, r0
202	bne	ddr2clk_stop_done
203
204	ret	lr
205ENDPROC(davinci_ddr_psc_config)
206
207CACHE_FLUSH:
208#ifdef CONFIG_CPU_V6
209	.word	v6_flush_kern_cache_all
210#else
211	.word   arm926_flush_kern_cache_all
212#endif
213
214ENTRY(davinci_cpu_suspend_sz)
215	.word	. - davinci_cpu_suspend
216ENDPROC(davinci_cpu_suspend_sz)
~/ Read-only file preview.