[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     ! 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