[BACK]Return to pxa2x0_apm_asm.S CVS log [TXT][DIR] Up to [local] / sys / arch / arm / xscale

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