Linux Audio

Check our new training course

Yocto / OpenEmbedded training

Feb 10-13, 2025
Register
Loading...
Note: File does not exist in v5.4.
  1/*
  2 * arch/arm/mach-at91/pm_slow_clock.S
  3 *
  4 *  Copyright (C) 2006 Savin Zlobec
  5 *
  6 * AT91SAM9 support:
  7 *  Copyright (C) 2007 Anti Sullin <anti.sullin@artecdesign.ee
  8 *
  9 * This program is free software; you can redistribute it and/or modify
 10 * it under the terms of the GNU General Public License version 2 as
 11 * published by the Free Software Foundation.
 12 *
 13 */
 14
 15#include <linux/linkage.h>
 16#include <mach/hardware.h>
 17#include <mach/at91_pmc.h>
 18#include <mach/at91_ramc.h>
 19
 20
 21#ifdef CONFIG_SOC_AT91SAM9263
 22/*
 23 * FIXME either or both the SDRAM controllers (EB0, EB1) might be in use;
 24 * handle those cases both here and in the Suspend-To-RAM support.
 25 */
 26#warning Assuming EB1 SDRAM controller is *NOT* used
 27#endif
 28
 29/*
 30 * When SLOWDOWN_MASTER_CLOCK is defined we will also slow down the Master
 31 * clock during suspend by adjusting its prescalar and divisor.
 32 * NOTE: This hasn't been shown to be stable on SAM9s; and on the RM9200 there
 33 *       are errata regarding adjusting the prescalar and divisor.
 34 */
 35#undef SLOWDOWN_MASTER_CLOCK
 36
 37#define MCKRDY_TIMEOUT		1000
 38#define MOSCRDY_TIMEOUT 	1000
 39#define PLLALOCK_TIMEOUT	1000
 40#define PLLBLOCK_TIMEOUT	1000
 41
 42pmc	.req	r0
 43sdramc	.req	r1
 44ramc1	.req	r2
 45memctrl	.req	r3
 46tmp1	.req	r4
 47tmp2	.req	r5
 48
 49/*
 50 * Wait until master clock is ready (after switching master clock source)
 51 */
 52	.macro wait_mckrdy
 53	mov	tmp2, #MCKRDY_TIMEOUT
 541:	sub	tmp2, tmp2, #1
 55	cmp	tmp2, #0
 56	beq	2f
 57	ldr	tmp1, [pmc, #AT91_PMC_SR]
 58	tst	tmp1, #AT91_PMC_MCKRDY
 59	beq	1b
 602:
 61	.endm
 62
 63/*
 64 * Wait until master oscillator has stabilized.
 65 */
 66	.macro wait_moscrdy
 67	mov	tmp2, #MOSCRDY_TIMEOUT
 681:	sub	tmp2, tmp2, #1
 69	cmp	tmp2, #0
 70	beq	2f
 71	ldr	tmp1, [pmc, #AT91_PMC_SR]
 72	tst	tmp1, #AT91_PMC_MOSCS
 73	beq	1b
 742:
 75	.endm
 76
 77/*
 78 * Wait until PLLA has locked.
 79 */
 80	.macro wait_pllalock
 81	mov	tmp2, #PLLALOCK_TIMEOUT
 821:	sub	tmp2, tmp2, #1
 83	cmp	tmp2, #0
 84	beq	2f
 85	ldr	tmp1, [pmc, #AT91_PMC_SR]
 86	tst	tmp1, #AT91_PMC_LOCKA
 87	beq	1b
 882:
 89	.endm
 90
 91/*
 92 * Wait until PLLB has locked.
 93 */
 94	.macro wait_pllblock
 95	mov	tmp2, #PLLBLOCK_TIMEOUT
 961:	sub	tmp2, tmp2, #1
 97	cmp	tmp2, #0
 98	beq	2f
 99	ldr	tmp1, [pmc, #AT91_PMC_SR]
100	tst	tmp1, #AT91_PMC_LOCKB
101	beq	1b
1022:
103	.endm
104
105	.text
106
107/* void at91_slow_clock(void __iomem *pmc, void __iomem *sdramc,
108 *			void __iomem *ramc1, int memctrl)
109 */
110ENTRY(at91_slow_clock)
111	/* Save registers on stack */
112	stmfd	sp!, {r4 - r12, lr}
113
114	/*
115	 * Register usage:
116	 *  R0 = Base address of AT91_PMC
117	 *  R1 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS)
118	 *  R2 = Base address of second RAM Controller or 0 if not present
119	 *  R3 = Memory controller
120	 *  R4 = temporary register
121	 *  R5 = temporary register
122	 */
123
124	/* Drain write buffer */
125	mov	tmp1, #0
126	mcr	p15, 0, tmp1, c7, c10, 4
127
128	cmp	memctrl, #AT91_MEMCTRL_MC
129	bne	ddr_sr_enable
130
131	/*
132	 * at91rm9200 Memory controller
133	 */
134	/* Put SDRAM in self-refresh mode */
135	mov	tmp1, #1
136	str	tmp1, [sdramc, #AT91RM9200_SDRAMC_SRR]
137	b	sdr_sr_done
138
139	/*
140	 * DDRSDR Memory controller
141	 */
142ddr_sr_enable:
143	cmp	memctrl, #AT91_MEMCTRL_DDRSDR
144	bne	sdr_sr_enable
145
146	/* prepare for DDRAM self-refresh mode */
147	ldr	tmp1, [sdramc, #AT91_DDRSDRC_LPR]
148	str	tmp1, .saved_sam9_lpr
149	bic	tmp1, #AT91_DDRSDRC_LPCB
150	orr	tmp1, #AT91_DDRSDRC_LPCB_SELF_REFRESH
151
152	/* figure out if we use the second ram controller */
153	cmp	ramc1, #0
154	ldrne	tmp2, [ramc1, #AT91_DDRSDRC_LPR]
155	strne	tmp2, .saved_sam9_lpr1
156	bicne	tmp2, #AT91_DDRSDRC_LPCB
157	orrne	tmp2, #AT91_DDRSDRC_LPCB_SELF_REFRESH
158
159	/* Enable DDRAM self-refresh mode */
160	str	tmp1, [sdramc, #AT91_DDRSDRC_LPR]
161	strne	tmp2, [ramc1, #AT91_DDRSDRC_LPR]
162
163	b	sdr_sr_done
164
165	/*
166	 * SDRAMC Memory controller
167	 */
168sdr_sr_enable:
169	/* Enable SDRAM self-refresh mode */
170	ldr	tmp1, [sdramc, #AT91_SDRAMC_LPR]
171	str	tmp1, .saved_sam9_lpr
172
173	bic	tmp1, #AT91_SDRAMC_LPCB
174	orr	tmp1, #AT91_SDRAMC_LPCB_SELF_REFRESH
175	str	tmp1, [sdramc, #AT91_SDRAMC_LPR]
176
177sdr_sr_done:
178	/* Save Master clock setting */
179	ldr	tmp1, [pmc, #AT91_PMC_MCKR]
180	str	tmp1, .saved_mckr
181
182	/*
183	 * Set the Master clock source to slow clock
184	 */
185	bic	tmp1, tmp1, #AT91_PMC_CSS
186	str	tmp1, [pmc, #AT91_PMC_MCKR]
187
188	wait_mckrdy
189
190#ifdef SLOWDOWN_MASTER_CLOCK
191	/*
192	 * Set the Master Clock PRES and MDIV fields.
193	 *
194	 * See AT91RM9200 errata #27 and #28 for details.
195	 */
196	mov	tmp1, #0
197	str	tmp1, [pmc, #AT91_PMC_MCKR]
198
199	wait_mckrdy
200#endif
201
202	/* Save PLLA setting and disable it */
203	ldr	tmp1, [pmc, #AT91_CKGR_PLLAR]
204	str	tmp1, .saved_pllar
205
206	mov	tmp1, #AT91_PMC_PLLCOUNT
207	orr	tmp1, tmp1, #(1 << 29)		/* bit 29 always set */
208	str	tmp1, [pmc, #AT91_CKGR_PLLAR]
209
210	/* Save PLLB setting and disable it */
211	ldr	tmp1, [pmc, #AT91_CKGR_PLLBR]
212	str	tmp1, .saved_pllbr
213
214	mov	tmp1, #AT91_PMC_PLLCOUNT
215	str	tmp1, [pmc, #AT91_CKGR_PLLBR]
216
217	/* Turn off the main oscillator */
218	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
219	bic	tmp1, tmp1, #AT91_PMC_MOSCEN
220	str	tmp1, [pmc, #AT91_CKGR_MOR]
221
222	/* Wait for interrupt */
223	mcr	p15, 0, tmp1, c7, c0, 4
224
225	/* Turn on the main oscillator */
226	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
227	orr	tmp1, tmp1, #AT91_PMC_MOSCEN
228	str	tmp1, [pmc, #AT91_CKGR_MOR]
229
230	wait_moscrdy
231
232	/* Restore PLLB setting */
233	ldr	tmp1, .saved_pllbr
234	str	tmp1, [pmc, #AT91_CKGR_PLLBR]
235
236	tst	tmp1, #(AT91_PMC_MUL &  0xff0000)
237	bne	1f
238	tst	tmp1, #(AT91_PMC_MUL & ~0xff0000)
239	beq	2f
2401:
241	wait_pllblock
2422:
243
244	/* Restore PLLA setting */
245	ldr	tmp1, .saved_pllar
246	str	tmp1, [pmc, #AT91_CKGR_PLLAR]
247
248	tst	tmp1, #(AT91_PMC_MUL &  0xff0000)
249	bne	3f
250	tst	tmp1, #(AT91_PMC_MUL & ~0xff0000)
251	beq	4f
2523:
253	wait_pllalock
2544:
255
256#ifdef SLOWDOWN_MASTER_CLOCK
257	/*
258	 * First set PRES if it was not 0,
259	 * than set CSS and MDIV fields.
260	 *
261	 * See AT91RM9200 errata #27 and #28 for details.
262	 */
263	ldr	tmp1, .saved_mckr
264	tst	tmp1, #AT91_PMC_PRES
265	beq	2f
266	and	tmp1, tmp1, #AT91_PMC_PRES
267	str	tmp1, [pmc, #AT91_PMC_MCKR]
268
269	wait_mckrdy
270#endif
271
272	/*
273	 * Restore master clock setting
274	 */
2752:	ldr	tmp1, .saved_mckr
276	str	tmp1, [pmc, #AT91_PMC_MCKR]
277
278	wait_mckrdy
279
280	/*
281	 * at91rm9200 Memory controller
282	 * Do nothing - self-refresh is automatically disabled.
283	 */
284	cmp	memctrl, #AT91_MEMCTRL_MC
285	beq	ram_restored
286
287	/*
288	 * DDRSDR Memory controller
289	 */
290	cmp	memctrl, #AT91_MEMCTRL_DDRSDR
291	bne	sdr_en_restore
292	/* Restore LPR on AT91 with DDRAM */
293	ldr	tmp1, .saved_sam9_lpr
294	str	tmp1, [sdramc, #AT91_DDRSDRC_LPR]
295
296	/* if we use the second ram controller */
297	cmp	ramc1, #0
298	ldrne	tmp2, .saved_sam9_lpr1
299	strne	tmp2, [ramc1, #AT91_DDRSDRC_LPR]
300
301	b	ram_restored
302
303	/*
304	 * SDRAMC Memory controller
305	 */
306sdr_en_restore:
307	/* Restore LPR on AT91 with SDRAM */
308	ldr	tmp1, .saved_sam9_lpr
309	str	tmp1, [sdramc, #AT91_SDRAMC_LPR]
310
311ram_restored:
312	/* Restore registers, and return */
313	ldmfd	sp!, {r4 - r12, pc}
314
315
316.saved_mckr:
317	.word 0
318
319.saved_pllar:
320	.word 0
321
322.saved_pllbr:
323	.word 0
324
325.saved_sam9_lpr:
326	.word 0
327
328.saved_sam9_lpr1:
329	.word 0
330
331ENTRY(at91_slow_clock_sz)
332	.word .-at91_slow_clock