Annotation of sys/arch/arm/xscale/pxa2x0_apm_asm.S, Revision 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