Annotation of sys/arch/arm/xscale/pxa2x0_apm_asm.S, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: pxa2x0_apm_asm.S,v 1.2 2006/10/19 10:55:56 tom Exp $ */
2:
3: /*
4: * Copyright (c) 2005 Uwe Stuehler <uwe@openbsd.org>
5: *
6: * Permission to use, copy, modify, and distribute this software for any
7: * purpose with or without fee is hereby granted, provided that the above
8: * copyright notice and this permission notice appear in all copies.
9: *
10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17: */
18:
19: #include <machine/asm.h>
20: #include <machine/cpu.h>
21:
22: #include <arch/arm/xscale/pxa2x0reg.h>
23: #include <arch/arm/sa11x0/sa11x0_reg.h>
24:
25: /* XXX replace with values defined elsewhere. */
26: #define DCACHE_CACHELINECOUNT 1024
27: #define CACHELINESIZE 32
28:
29: /* cp14 register 6 */
30: #define CLKCFG_T (1<<0) /* turbo */
31: #define CLKCFG_F (1<<1) /* frequency change */
32: #define CLKCFG_HT (1<<2) /* half-turbo */
33: #define CLKCFG_B (1<<3) /* fast-bus */
34:
35: /* cp14 register 7 */
36: #define PWRMODE_NORMAL (0<<0)
37: #define PWRMODE_IDLE (1<<0)
38: #define PWRMODE_STANDBY (2<<0)
39: #define PWRMODE_SLEEP (3<<0)
40: #define PWRMODE_DEEP_SLEEP (7<<0)
41:
42: /* XXX */
43: #define MDREFR_C3000 (MDREFR_K0DB2|MDREFR_E1PIN|MDREFR_K1RUN|\
44: MDREFR_K1DB2|MDREFR_K2DB2|MDREFR_APD)
45: #define MDREFR_DRI_91MHZ (0x13<<0)
46: #define MDREFR_HIGH (MDREFR_C3000 | 0x030)
47: #define MDREFR_LOW (MDREFR_C3000 | 0x00b)
48: #define MDREFR_SPEED_91 (MDREFR_C3000 | MDREFR_DRI_91MHZ)
49: #define MDREFR_SPEED_LOW (MDREFR_C3000 | 0x017)
50: #define MSC0_HIGH \
51: ( 7 << MSC_RRR_SHIFT << 16) | \
52: (15 << MSC_RDN_SHIFT << 16) | \
53: (15 << MSC_RDF_SHIFT << 16) | \
54: (MSC_RT_NONBURST << 16) | \
55: ( 2 << MSC_RRR_SHIFT) | \
56: (13 << MSC_RDN_SHIFT) | \
57: (13 << MSC_RDF_SHIFT) | \
58: MSC_RBW /* PXA271 */ | \
59: MSC_RT_NONBURST
60: #define MSC1_HIGH \
61: ( 7 << MSC_RRR_SHIFT << 16) | \
62: (15 << MSC_RDN_SHIFT << 16) | \
63: (15 << MSC_RDF_SHIFT << 16) | \
64: (MSC_RT_VLIO << 16) | \
65: ( 3 << MSC_RRR_SHIFT) | \
66: ( 4 << MSC_RDN_SHIFT) | \
67: (13 << MSC_RDF_SHIFT) | \
68: MSC_RT_VLIO
69: #define MSC2_HIGH \
70: ( 7 << MSC_RRR_SHIFT << 16) | \
71: (15 << MSC_RDN_SHIFT << 16) | \
72: (15 << MSC_RDF_SHIFT << 16) | \
73: (MSC_RT_NONBURST << 16) | \
74: ( 3 << MSC_RRR_SHIFT) | \
75: ( 4 << MSC_RDN_SHIFT) | \
76: (13 << MSC_RDF_SHIFT) | \
77: MSC_RT_VLIO
78: #define MSC0_LOW \
79: ( 7 << MSC_RRR_SHIFT << 16) | \
80: (15 << MSC_RDN_SHIFT << 16) | \
81: (15 << MSC_RDF_SHIFT << 16) | \
82: (MSC_RT_NONBURST << 16) | \
83: ( 1 << MSC_RRR_SHIFT) | \
84: ( 8 << MSC_RDN_SHIFT) | \
85: ( 8 << MSC_RDF_SHIFT) | \
86: MSC_RBW /* PXA271 */ | \
87: MSC_RT_NONBURST
88: #define MSC1_LOW \
89: ( 7 << MSC_RRR_SHIFT << 16) | \
90: (15 << MSC_RDN_SHIFT << 16) | \
91: (15 << MSC_RDF_SHIFT << 16) | \
92: (MSC_RT_VLIO << 16) | \
93: ( 1 << MSC_RRR_SHIFT) | \
94: ( 2 << MSC_RDN_SHIFT) | \
95: ( 6 << MSC_RDF_SHIFT) | \
96: MSC_RT_VLIO
97: #define MSC2_LOW \
98: ( 7 << MSC_RRR_SHIFT << 16) | \
99: (15 << MSC_RDN_SHIFT << 16) | \
100: (15 << MSC_RDF_SHIFT << 16) | \
101: (MSC_RT_NONBURST << 16) | \
102: ( 1 << MSC_RRR_SHIFT) | \
103: ( 2 << MSC_RDN_SHIFT) | \
104: ( 6 << MSC_RDF_SHIFT) | \
105: MSC_RT_VLIO
106:
107: .text
108: .global _C_LABEL(vector_page)
109: .global _C_LABEL(xscale_cache_clean_addr)
110: .global _C_LABEL(pxa2x0_clkman_ioh)
111: .global _C_LABEL(pxa2x0_memctl_ioh)
112:
113: .Lvector_page:
114: .word _C_LABEL(vector_page)
115: .Lxscale_cache_clean_addr:
116: .word _C_LABEL(xscale_cache_clean_addr)
117:
118: .Lgpioiohp: .word _C_LABEL(pxa2x0_gpio_ioh)
119: .Lclkmaniohp: .word _C_LABEL(pxa2x0_clkman_ioh)
120: .Lmemctliohp: .word _C_LABEL(pxa2x0_memctl_ioh)
121:
122: .Lsleepdata: .word sleepdata
123: .Lsleepdata_phys: .word sleepdata - 0xc0200000 + 0xa0200000 /* XXX */
124: .Lsleepdata_svc: .word sleepdata_svc
125:
126: .Lcccr_high: .word CCCR_A | CCCR_TURBO_X2 | CCCR_RUN_X16
127: .Lmdrefr_high: .word MDREFR_HIGH
128: .Lmsc0_high: .word MSC0_HIGH
129: .Lmsc1_high: .word MSC1_HIGH
130: .Lmsc2_high: .word MSC2_HIGH
131: .Lmdrefr_low: .word MDREFR_LOW
132: .Lmsc0_low: .word MSC0_LOW
133: .Lmsc1_low: .word MSC1_LOW
134: .Lmsc2_low: .word MSC2_LOW
135:
136: /*
137: * void pxa2x0_cpu_suspend(void)
138: *
139: * Enter sleep mode without automatic voltage change. The core must
140: * be in low power mode, and interrupts disabled.
141: */
142: ENTRY(pxa2x0_cpu_suspend)
143: stmdb sp!, {r0-r12, lr}
144:
145: ldr r3, .Lsleepdata /* Point to the data area. */
146: ldr r2, =pxa2x0_cpu_resume_virt
147: str r2, [r3], #4
148:
149: mrc p15, 0, r2, c1, c0, 0 /* Load MMU control register. */
150: mov r0, #0xff000000
151: orr r0, r0, #0x00ff0000
152: bic r2, r2, r0 /* Clear undefined bits. */
153: str r2, [r3], #4 /* Save MMU control register. */
154:
155: mrc p15, 0, r2, c2, c0, 0 /* Load TTB address. */
156: mov r0, #0x00003f00
157: orr r0, r0, #0x000000ff
158: bic r2, r2, r0 /* Clear undefined bits. */
159: str r2, [r3], #4 /* Save TTB address. */
160:
161: mrc p15, 0, r2, c3, c0, 0 /* Load domain access control. */
162: str r2, [r3], #4 /* Save domain access control. */
163:
164: mrs r2, spsr /* Load SVC saved CPSR. */
165: str r2, [r3], #4 /* Save SVC saved CPSR. */
166: str sp, [r3], #4 /* Save SVC stack pointer. */
167:
168: mov r1, #(PSR_FIQ32_MODE | I32_bit | F32_bit)
169: msr cpsr, r1 /* Enter FIQ mode. */
170: mrs r2, spsr /* Load FIQ mode saved CPSR. */
171: stmia r3!, {r2, r8-r12, sp, lr} /* Save FIQ mode registers. */
172:
173: mov r1, #(PSR_IRQ32_MODE | I32_bit | F32_bit)
174: msr cpsr, r1 /* Enter IRQ mode. */
175: mrs r0, spsr /* Load IRQ mode saved CPSR. */
176: stmia r3!, {r0, sp, lr} /* Save IRQ mode registers. */
177:
178: mov r1, #(PSR_ABT32_MODE | I32_bit | F32_bit)
179: msr cpsr, r1 /* Enter ABT mode. */
180: mrs r0, spsr /* Load ABT mode saved CPSR. */
181: stmia r3!, {r0, sp, lr} /* Save ABT mode registers. */
182:
183: mov r1, #(PSR_UND32_MODE | I32_bit | F32_bit)
184: msr cpsr, r1 /* Enter UND mode. */
185: mrs r0, spsr /* Load UND mode saved CPSR. */
186: stmia r3!, {r0, sp, lr} /* Save UND mode registers. */
187:
188: mov r1, #(PSR_SYS32_MODE | I32_bit | F32_bit)
189: msr cpsr, r1 /* Enter SYS mode. */
190: stmia r3!, {sp, lr} /* Save SYS mode registers. */
191:
192: mov r1, #(PSR_SVC32_MODE | I32_bit | F32_bit)
193: msr cpsr, r1 /* Return to SVC mode. */
194:
195: /* At this point all critical registers have been saved. */
196:
197: mov r0, #0
198: mcr p15, 0, r0, c7, c10, 4 /* XXX does exactly what? */
199:
200: mov r1, #DCACHE_CACHELINECOUNT
201: ldr r0, .Lxscale_cache_clean_addr
202:
203: cache_flush_loop:
204: mrs r2, cpsr
205: orr r2, r2, #(I32_bit|F32_bit)
206: msr cpsr_c, r2 /* disable IRQ/FIQ */
207:
208: mcr p15, 0, r0, c7, c2, 5 /* allocate cache line */
209: mcr p15, 0, r0, c7, c6, 1 /* flush D cache single entry */
210:
211: mrs r2, cpsr
212: and r2, r2, #~(I32_bit|F32_bit)
213: msr cpsr_c, r2 /* enable IRQ/FIQ */
214:
215: add r0, r0, #CACHELINESIZE
216: subs r1, r1, #1
217: bne cache_flush_loop
218:
219: mov r0, #0
220: mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */
221:
222: b 1f
223: 1:
224: nop
225: nop
226: nop
227: nop
228: nop
229: nop
230: nop
231: nop
232: nop
233: nop
234: nop
235:
236: /* Prepare to enter sleep mode. */
237: mov r1, #PWRMODE_SLEEP
238:
239: /* Prepare to put SDRAM into self-refresh mode. */
240: ldr r4, .Lmemctliohp
241: ldr r4, [r4]
242: add r4, r4, #MEMCTL_MDREFR
243: ldr r5, [r4]
244: orr r5, r5, #MDREFR_SLFRSH
245:
246: /* XXX prepare pointer to physical address 0, but for whom? */
247: ldr r2, .Lvector_page
248:
249: /*
250: * Execute the rest of this routine from cache. The needed values
251: * are now in registers.
252: */
253: b 1f
254: /* XXX tell as(1) to dump the literal pool here, but why? */
255: .ltorg
256: .align 5
257: 1:
258:
259: /* Put SDRAM into self-refresh mode manually. */
260: str r5, [r4]
261: nop
262:
263: /*
264: * Enter sleep mode. Exit from sleep mode returns the processor
265: * to normal run mode. Execution resumes at the physical address
266: * stored in the PSPR after the required boot sequence (a short
267: * excursion into the ROM boot loader).
268: */
269: mcr p14, 0, r1, c7, c0, 0
270:
271: /* Just in case that wake-up does not resume at */
272: nop
273: nop
274: nop
275: 1:
276: b 1b
277:
278: /*
279: * void pxa2x0_cpu_resume(void)
280: */
281: .align 5
282: ENTRY(pxa2x0_cpu_resume)
283: /* XXX C3000-specific */
284: ldr r0, .Lmdrefr_addr_phys
285: b 1f
286: .align 5
287: 1:
288: ldr r2, [r0]
289: bic r2, r2, #MDREFR_DRI & 0x000000ff
290: bic r2, r2, #MDREFR_DRI & 0x0000ff00
291: orr r2, r2, #MDREFR_DRI_91MHZ
292: str r2, [r0]
293: b 1f
294: .align 5
295: 1:
296: ldr r0, .Lsleepdata_phys /* Point to PA of saved data. */
297:
298: ldmia r0!, {r7-r10}
299: mcr p15, 0, r10, c3, c0, 0 /* Restore domain access control. */
300: mcr p15, 0, r9, c2, c0, 0 /* Restore TTB address. */
301: mcr p15, 0, r0, c8, c7, 0 /* Flush I+D TLBs. */
302: mcr p15, 0, r0, c7, c7, 0 /* Flush I+D BTB. */
303: mcr p15, 0, r8, c1, c0, 0 /* Restore MMU control. */
304: mov pc, r7 /* Jump to virtual address. */
305: nop
306: nop
307: nop
308: nop
309: nop
310: nop
311: nop
312: nop
313:
314: pxa2x0_cpu_resume_virt:
315: ldr r2, .Lsleepdata_svc /* Load VA of saved registers. */
316:
317: /* Restore SVC mode SPSR and stack pointer. */
318: ldr r0, [r2], #4
319: msr spsr, r0
320: ldr sp, [r2], #4
321:
322: /* Restore FIQ mode registers. */
323: mov r1, #(PSR_FIQ32_MODE | I32_bit | F32_bit)
324: msr cpsr, r1
325: ldr r0, [r2], #4
326: msr spsr, r0
327: ldr r8, [r2], #4
328: ldr r9, [r2], #4
329: ldr r10, [r2], #4
330: ldr r11, [r2], #4
331: ldr r12, [r2], #4
332: ldr sp, [r2], #4
333: ldr lr, [r2], #4
334:
335: /* Restore IRQ mode registers. */
336: mov r1, #(PSR_IRQ32_MODE | I32_bit | F32_bit)
337: msr cpsr, r1
338: ldr r0, [r2], #4
339: msr spsr, r0
340: ldr sp, [r2], #4
341: ldr lr, [r2], #4
342:
343: /* Restore ABT mode registers. */
344: mov r1, #(PSR_ABT32_MODE | I32_bit | F32_bit)
345: msr cpsr, r1
346: ldr r0, [r2], #4
347: msr spsr, r0
348: ldr sp, [r2], #4
349: ldr lr, [r2], #4
350:
351: /* Restore UND mode registers. */
352: mov r1, #(PSR_UND32_MODE | I32_bit | F32_bit)
353: msr cpsr, r1
354: ldr r0, [r2], #4
355: msr spsr, r0
356: ldr sp, [r2], #4
357: ldr lr, [r2], #4
358:
359: /* Restore SYS mode registers. */
360: mov r1, #(PSR_SYS32_MODE | I32_bit | F32_bit)
361: msr cpsr, r1
362: ldr sp, [r2], #4
363: ldr lr, [r2], #4
364:
365: /* Return to SVC mode. */
366: mov r1, #(PSR_SVC32_MODE | I32_bit | F32_bit)
367: msr cpsr, r1
368:
369: ldmia sp!, {r0-r12, pc}
370:
371: .Lmdrefr_addr_phys:
372: .word PXA2X0_MEMCTL_BASE + MEMCTL_MDREFR
373:
374: .data
375:
376: /*
377: * Saved processor state
378: */
379: sleepdata:
380: .word 0 /* =pxa2x0_cpu_resume_virt */
381: .word 0 /* MMU control */
382: .word 0 /* MMU TTB address */
383: .word 0 /* MMU domain access control */
384: sleepdata_svc:
385: .word 0 /* SVC mode saved CPSR */
386: .word 0 /* SVC mode stack pointer */
387: .word 0 /* FIQ mode saved CPSR */
388: .word 0 /* FIQ mode r8 */
389: .word 0 /* FIQ mode r9 */
390: .word 0 /* FIQ mode r10 */
391: .word 0 /* FIQ mode r11 */
392: .word 0 /* FIQ mode r12 */
393: .word 0 /* FIQ mode stack pointer */
394: .word 0 /* FIQ mode link register */
395: .word 0 /* IRQ mode saved CPSR */
396: .word 0 /* IRQ mode stack pointer */
397: .word 0 /* IRQ mode link register */
398: .word 0 /* ABT mode saved CPSR */
399: .word 0 /* ABT mode stack pointer */
400: .word 0 /* ABT mode link register */
401: .word 0 /* UND mode saved CPSR */
402: .word 0 /* UND mode stack pointer */
403: .word 0 /* UND mode link register */
404: .word 0 /* SYS mode stack pointer */
405: .word 0 /* SYS mode link register */
406:
407: .text
408:
409: /*
410: * void pxa27x_run_mode(void)
411: *
412: * Disable half-turbo and turbo mode, but keep fast-bus mode.
413: * Memory and LCD clock is not changed, so no reconfiguration is
414: * necessary.
415: */
416: ENTRY(pxa27x_run_mode)
417: stmdb sp!, {r0}
418: mrc p14, 0, r0, c6, c0, 0
419: and r0, r0, #~(CLKCFG_HT | CLKCFG_F| CLKCFG_T)
420: mcr p14, 0, r0, c6, c0, 0
421: ldmia sp!, {r0}
422: mov pc, lr
423:
424: /*
425: * void pxa27x_fastbus_run_mode(int enable, u_int32_t mdrefr)
426: *
427: * Enter normal run mode with fast-bus mode enabled or disabled.
428: * The new value of MDREFR is programmed before or after CLKCFG,
429: * as appropriate.
430: */
431: .align 5
432: ENTRY(pxa27x_fastbus_run_mode)
433: stmdb sp!, {r0-r2, lr}
434: ldr r2, .Lmemctliohp
435: ldr r2, [r2]
436: cmp r0, #0
437: beq disable_fastbus
438: b enable_fastbus
439: .align 5
440: enable_fastbus:
441: /* Enter normal run mode with fast-bus mode enabled. */
442: mov r0, #CLKCFG_B
443: mcr p14, 0, r0, c6, c0, 0
444: /* Set the new SDRAM refresh rate. */
445: str r1, [r2, #MEMCTL_MDREFR]
446: ldr r0, [r2, #MEMCTL_MDREFR]
447: mov r0, r0
448: ldmia sp!, {r0-r2, pc}
449: .align 5
450: disable_fastbus:
451: /* Set the new SDRAM refresh rate. */
452: str r1, [r2, #MEMCTL_MDREFR]
453: ldr r0, [r2, #MEMCTL_MDREFR]
454: mov r0, r0
455: /* Enter normal run mode with fast-bus mode disabled. */
456: mov r0, #0x0
457: mcr p14, 0, r0, c6, c0, 0
458: ldmia sp!, {r0-r2, pc}
459:
460: /* Keep these offsets in sync with struct memcfg. */
461: #define memcfg_mdrefr_high 0x00
462: #define memcfg_mdrefr_low 0x04
463: #define memcfg_mdrefr_low2 0x08 /* unused */
464: #define memcfg_msc_high 0x0c
465: #define memcfg_msc_low 0x18
466: #define memcfg_mdrefr_91 0x24
467:
468: /*
469: * void pxa27x_frequency_change(int cccr, int clkcfg,
470: * struct pxa2x0_memcfg *memcfg)
471: *
472: * Change the core PLL frequency and SDRAM refresh rate, ensuring the
473: * proper sequence of operations. If the CCCR_A bit is clear and L
474: * is not equal to 7 the result is undefined.
475: */
476: .align 5
477: ENTRY(pxa27x_frequency_change)
478: stmdb sp!, {r0-r5, lr}
479:
480: /* Always write to CCCR before a frequency change. */
481: ldr r3, .Lclkmaniohp
482: ldr r3, [r3]
483: str r0, [r3, #CLKMAN_CCCR]
484:
485: /* Load the needed values into registers to avoid SDRAM access. */
486: and r3, r0, #CCCR_L_MASK
487: ldr r0, .Lmemctliohp
488: ldr r0, [r0]
489: cmp r3, #CCCR_RUN_X7 /* L=7 is 91MHz mode */
490: beq frequency_change_91
491: and r3, r1, #CLKCFG_B
492: cmp r3, #CLKCFG_B
493: bne frequency_change_208
494: /* FALLTHROUGH */
495: frequency_change_high:
496: ldr r3, [r2, #memcfg_mdrefr_low]
497: ldr r4, [r2, #memcfg_mdrefr_high]
498: add r2, r2, #memcfg_msc_high
499: bl frequency_change_on_cache /* XXX why BL? */
500: frequency_change_208:
501: ldr r3, [r2, #memcfg_mdrefr_low]
502: ldr r4, [r2, #memcfg_mdrefr_low]
503: add r2, r2, #memcfg_msc_high
504: bl frequency_change_on_cache
505: frequency_change_91:
506: ldr r3, [r2, #memcfg_mdrefr_low]
507: ldr r4, [r2, #memcfg_mdrefr_91]
508: add r2, r2, #memcfg_msc_low
509: bl frequency_change_on_cache
510:
511: /* Align execution to a cache line. */
512: .align 5
513: frequency_change_on_cache:
514: /* Change to a low SDRAM refresh rate. Wait until the store to
515: * MDREFR is complete, following section 2.4 I/O Ordering and
516: * 6.5.1.4 of the PXA27x Developer's Manual. */
517: str r3, [r0, #MEMCTL_MDREFR]
518: ldr r5, [r0, #MEMCTL_MDREFR]
519: mov r5, r5
520: /* Program new CLKCFG value, starting a core PLL frequency change
521: * if CLKCFG_F is set. */
522: mcr p14, 0, r1, c6, c0, 0
523: /* Change SDRAM clock frequency to 104MHz, and ensure that the
524: * store to MDREFR is complete before the next SDRAM access. */
525: str r4, [r0, #MEMCTL_MDREFR]
526: ldr r5, [r0, #MEMCTL_MDREFR]
527: mov r5, r5
528: /* Configure synchronous, static, and VLIO interfaces. */
529: ldr r1, [r2], #4
530: str r1, [r0, #MEMCTL_MSC0]
531: ldr r1, [r2], #4
532: str r1, [r0, #MEMCTL_MSC1]
533: ldr r1, [r2]
534: str r1, [r0, #MEMCTL_MSC2]
535: ldmia sp!, {r0-r5, pc}
536:
537: /*
538: * void pxa27x_cpu_speed_91(void)
539: *
540: * Switch core run frequency to 91 MHz.
541: */
542: .align 5
543: ENTRY(pxa27x_cpu_speed_91)
544: stmdb sp!, {r0-r3, lr}
545:
546: ldr r0, .Lclkmaniohp
547: ldr r0, [r0]
548: ldr r1, .Lcccr_91
549: str r1, [r0, #CLKMAN_CCCR]
550:
551: ldr r0, .Lmemctliohp
552: ldr r0, [r0]
553: ldr r2, .Lmdrefr_91
554: ldr r3, .Lmdrefr_low
555:
556: bl 1f
557: .align 5
558: 1:
559: str r3, [r0, #MEMCTL_MDREFR]
560: ldr r3, [r0, #MEMCTL_MDREFR]
561:
562: mov r1, #CLKCFG_F
563: mcr p14, 0, r1, c6, c0, 0
564: str r2, [r0, #MEMCTL_MDREFR]
565: ldr r2, [r0, #MEMCTL_MDREFR]
566:
567: ldr r1, .Lmsc0_low
568: str r1, [r0, #MEMCTL_MSC0]
569: ldr r1, .Lmsc1_low
570: str r1, [r0, #MEMCTL_MSC1]
571: ldr r1, .Lmsc2_low
572: str r1, [r0, #MEMCTL_MSC2]
573:
574: ldmia sp!, {r0-r3, pc}
575:
576: .Lcccr_91: .word CCCR_TURBO_X1 | CCCR_RUN_X7
577: .Lmdrefr_91: .word MDREFR_SPEED_91
CVSweb