/* * linux/arch/arm/boot/compressed/head-xscale.S * * XScale specific tweaks. This is merged into head.S by the linker. * */ #include #include #include .section ".start", #alloc, #execinstr __XScale_start: @ Preserve r8/r7 i.e. kernel entry values /* * Voipac boot loader section */ #if defined(CONFIG_ARCH_LUBBOCK) && defined(CONFIG_ZBOOT_ROM) && (CONFIG_ZBOOT_ROM_TEXT == 0) b cold_start /* board configuration constants */ #define CLOCK_CPU_SPEED CLOCK_200MHz /* set cpu clock speed */ #define CLOCK_CPU_TURBO 0 /* 0/1 cpu turbo mode switch */ GPIO_GPSR0_VAL: .long 0xffffffff /* GPIO pin output set registers */ GPIO_GPSR1_VAL: .long 0xffffffff GPIO_GPSR2_VAL: .long 0xffffffff GPIO_GPCR0_VAL: .long 0x08022080 /* GPIO pin output clear registers */ GPIO_GPCR1_VAL: .long 0x00000000 GPIO_GPCR2_VAL: .long 0x00000000 GPIO_GPDR0_VAL: .long 0xc00220d8 /* GPIO pin direction registers */ GPIO_GPDR1_VAL: .long 0xfcffab82 GPIO_GPDR2_VAL: .long 0x0000ffff GPIO_GAFR0_L_VAL: .long 0x00000000 /* GPIO alternate function registers */ GPIO_GAFR0_U_VAL: .long 0xa5000010 GPIO_GAFR1_L_VAL: .long 0x599a9550 GPIO_GAFR1_U_VAL: .long 0xaaa5aaaa GPIO_GAFR2_L_VAL: .long 0xaaa00aaa GPIO_GAFR2_U_VAL: .long 0x00000000 MEM_MSC0_VAL: .long 0x2ef15af0 /* static memory controller */ MEM_MSC1_VAL: .long 0x32cc32cc MEM_MSC2_VAL: .long 0x3ff43ff4 PCMCIA_MECR_VAL: .long 0x00000000 /* pcmcia memory controller */ PCMCIA_MCMEM0_VAL: .long 0x00010504 PCMCIA_MCMEM1_VAL: .long 0x00010504 PCMCIA_MCATT0_VAL: .long 0x00010504 PCMCIA_MCATT1_VAL: .long 0x00010504 PCMCIA_MCIO0_VAL: .long 0x000fcfff PCMCIA_MCIO1_VAL: .long 0x000fcfff PERIPHERIAL_CLOCKS: .long 0x17def /* enable peripherial clocks */ /* initialize SDRAM memory controler */ .equ MEMORY_CTRL_MDCNFG, 0x00 .equ MEMORY_CTRL_MDREFR, 0x04 .equ MEMORY_CTRL_MDMRS, 0x40 .equ SLF_REFRESH, 0x400000 .equ HALF_MEMCLK, 0x0a4000 .equ MEMCLK_RUN, 0x52000 .equ MEMCLK_ENABLE, 0x9000 /* r0 = memory size, r1 = memory ctrl base */ const_00000fff: .long 0x0fff const_00000888: .long 0x0888 const_00220022: .long 0x00220022 const_deadbeef: .long 0xdeadbeef sdram_init: mov r2, #0x3800000 orr r2, r2, #SLF_REFRESH ldr r3, const_00000fff orr r3, r3, r2 str r3, [r1, #MEMORY_CTRL_MDREFR] cmp r4, #0x2000000 orrgt r2, r2, #0x30 /* 64MB SDRAM */ orrle r2, r2, #0x60 /* 32MB SDRAM */ str r2, [r1, #MEMORY_CTRL_MDREFR] /* set data refresh rate */ orr r2, r2, #MEMCLK_RUN str r2, [r1, #MEMORY_CTRL_MDREFR] /* set memclk free running */ bic r2, r2, #SLF_REFRESH str r2, [r1, #MEMORY_CTRL_MDREFR] /* clear self refresh */ orr r2, r2, #MEMCLK_ENABLE str r2, [r1, #MEMORY_CTRL_MDREFR] /* enable memclk */ .equ PART_ENABLE, 0x3 .equ ROWADDR_12b, 0x20 /* 32MB SDRAM on board */ .equ ROWADDR_13b, 0x40 /* 64MB SDRAM on board */ .equ CAS2_RAS5_RC8, 0x100 /* 50MHz memclk */ .equ CAS3_RAS7_RC10, 0x200 /* 100MHz memclk */ .equ CAS3_RAS7_RC11, 0x300 .equ DWIDTH_16BIT, 0x4 /* 16bit data bus width */ .equ SA1111_MODE, 0x1000 /* necessary for 64MB mode */ ldr r2, const_00000888 orr r2, r2, #CAS3_RAS7_RC10 cmp r4, #0x2000000 orrgt r2, r2, #ROWADDR_13b /* 64MB SDRAM */ orrgt r2, r2, #SA1111_MODE orrle r2, r2, #ROWADDR_12b /* 32MB SDRAM */ orrlt r2, r2, #DWIDTH_16BIT str r2, [r1, #MEMORY_CTRL_MDCNFG] mov r3, #0x400 /* delay to wait for memory */ mem_delay: nop nop subs r3, r3, #1 bne mem_delay nop nop nop orr r2, r2, #PART_ENABLE str r2, [r1, #MEMORY_CTRL_MDCNFG] ldr r2, const_00220022 str r2, [r1, #MEMORY_CTRL_MDMRS] mov pc, lr const_00002001: .long 0x2001 const_54410002: .long 0x54410002 cold_start: ldr r0, const_00002001 mcr p15,0,r0,c15,c1,0 /* allow access to all coprocesors */ nop nop nop mov r0, #0x78 mcr p15,0,r0,c1,c0,0 /* disable MMU, caches, write buffer */ nop nop nop mov r0, #0 mcr p15,0,r0,c8,c7,0 /* flush v4 TLB */ mcr p15,0,r0,c7,c7,0 /* flush v3/v4 caches */ mcr p15,0,r0,c7,c10,4 /* flush write buffer */ nop nop nop mvn r0, #0 mcr p15,0,r0,c3,c0,0 /* grant access to all domains */ /* initialize peripherals */ .equ PERIPHERALS_BASE, 0x40000000 mov r0, #PERIPHERALS_BASE /* initialize GPIO registers */ .equ GPIO_OFFS, 0xe00000 .equ GPIO_GPDR0, 0x0c .equ GPIO_GPSR0, 0x18 .equ GPIO_GPCR0, 0x24 .equ GPIO_GAFR0, 0x54 orr r2, r0, #GPIO_OFFS ldr r1, GPIO_GPSR0_VAL str r1, [r2, #GPIO_GPSR0] ldr r1, GPIO_GPSR1_VAL str r1, [r2, #(GPIO_GPSR0+4)] ldr r1, GPIO_GPSR2_VAL str r1, [r2, #(GPIO_GPSR0+8)] ldr r1, GPIO_GPCR0_VAL str r1, [r2, #GPIO_GPCR0] ldr r1, GPIO_GPCR1_VAL str r1, [r2, #(GPIO_GPCR0+4)] ldr r1, GPIO_GPCR2_VAL str r1, [r2, #(GPIO_GPCR0+8)] ldr r1, GPIO_GPDR0_VAL str r1, [r2, #GPIO_GPDR0] ldr r1, GPIO_GPDR1_VAL str r1, [r2, #(GPIO_GPDR0+4)] ldr r1, GPIO_GPDR2_VAL str r1, [r2, #(GPIO_GPDR0+8)] ldr r1, GPIO_GAFR0_L_VAL str r1, [r2, #GPIO_GAFR0] ldr r1, GPIO_GAFR0_U_VAL str r1, [r2, #(GPIO_GAFR0+4)] ldr r1, GPIO_GAFR1_L_VAL str r1, [r2, #(GPIO_GAFR0+8)] ldr r1, GPIO_GAFR1_U_VAL str r1, [r2, #(GPIO_GAFR0+0xc)] ldr r1, GPIO_GAFR2_L_VAL str r1, [r2, #(GPIO_GAFR0+0x10)] ldr r1, GPIO_GAFR2_U_VAL str r1, [r2, #(GPIO_GAFR0+0x14)] .equ PWR_CTRL_OFFS, 0xf00000 .equ PWR_CTRL_PSSR, 0x4 .equ PWR_PSSR_VAL, 0x20 orr r2, r0, #PWR_CTRL_OFFS mov r3, #PWR_PSSR_VAL str r3, [r2, #PWR_CTRL_PSSR] /* initialize pxa250 interupt controler */ .equ INTERUPT_CTRL_OFFS, 0xd00000 .equ INTERUPT_CTRL_ICMR, 0x04 orr r1, r0, #INTERUPT_CTRL_OFFS mov r2, #0 str r2, [r1, #INTERUPT_CTRL_ICMR] /* change core clock frequency */ .equ CLOCK_OFFS, 0x1300000 .equ CLOCK_CCCR, 0x0 .equ CLOCK_CKEN, 0x4 .equ CLOCK_200MHz, 0x100 .equ CLOCK_300MHz, 0x180 .equ CLOCK_400MHz, 0x200 orr r1, r0, #CLOCK_OFFS mov r2, #0 str r2, [r1, #CLOCK_CKEN] /* disable clocks */ mov r2, #0x41 orr r2, r2, #CLOCK_CPU_SPEED /* set core clock (L:27,M:2) */ str r2, [r1, #CLOCK_CCCR] mov r1, #(0x2 | CLOCK_CPU_TURBO) mcr p14,0,r1,c6,c0,0 /* enter frequency change sequence */ /* initialize pxa250 memory controler */ .equ MEMORY_CTRL_BASE, 0x48000000 .equ MEMORY_CTRL_MDCNFG, 0x00 .equ MEMORY_CTRL_MDREFR, 0x04 .equ MEMORY_CTRL_MDMRS, 0x40 mov r1, #MEMORY_CTRL_BASE /* initialize static memory controler */ .equ MEMORY_CTRL_MSC0, 0x8 .equ MEMORY_CTRL_MSC1, 0xc .equ MEMORY_CTRL_MSC2, 0x10 ldr r2, MEM_MSC0_VAL str r2, [r1, #MEMORY_CTRL_MSC0] ldr r3, [r1, #MEMORY_CTRL_MSC0] ldr r2, MEM_MSC1_VAL str r2, [r1, #MEMORY_CTRL_MSC1] ldr r3, [r1, #MEMORY_CTRL_MSC1] ldr r2, MEM_MSC2_VAL str r2, [r1, #MEMORY_CTRL_MSC2] ldr r2, [r1, #MEMORY_CTRL_MSC2] /* initialize pcmcia memory controler */ .equ MECR_OFFSET, 0x14 .equ MCMEM0_OFFSET, 0x28 .equ MCMEM1_OFFSET, 0x2c .equ MCATT0_OFFSET, 0x30 .equ MCATT1_OFFSET, 0x34 .equ MCIO0_OFFSET, 0x38 .equ MCIO1_OFFSET, 0x3c ldr r2, PCMCIA_MECR_VAL str r2, [r1, #MECR_OFFSET] ldr r2, PCMCIA_MCMEM0_VAL str r2, [r1, #MCMEM0_OFFSET] ldr r2, PCMCIA_MCMEM1_VAL str r2, [r1, #MCMEM1_OFFSET] ldr r2, PCMCIA_MCATT0_VAL str r2, [r1, #MCATT0_OFFSET] ldr r2, PCMCIA_MCATT1_VAL str r2, [r1, #MCATT1_OFFSET] ldr r2, PCMCIA_MCIO0_VAL str r2, [r1, #MCIO0_OFFSET] ldr r2, PCMCIA_MCIO1_VAL str r2, [r1, #MCIO1_OFFSET] /* initialize SDRAM memory controler */ mov r4, #0x4000000 /* init SDRAM as 64MB */ bl sdram_init /* autodetect sdram size */ .equ PHYS_SDRAM_1, 0xa0000000 mov r0, #0 mov r1, #(PHYS_SDRAM_1 + 0x2000000) /* SDRAM bank 2*/ mov r2, #(PHYS_SDRAM_1 + 0x3000000) str r0, [r1] /* clean both SDRAM banks */ str r0, [r2] ldr r0, const_deadbeef /* modify SDRAM bank 2 */ str r0, [r1] ldr r1, [r2] cmp r0, r1 /* compare r0, SDRAM bank 3 */ bne sdram_done mov r4, #0x2000000 /* init SDRAM as 32MB */ mov r1, #MEMORY_CTRL_BASE bl sdram_init mov r1, #(PHYS_SDRAM_1) /* SDRAM bank 0 */ ldr r2, const_deadbeef /* modify SDRAM bank 0 */ str r2, [r1] mov r0, #0 str r0, [r1, #4] /* discharge data bus */ ldr r0, [r1] cmp r0, r2 /* compare r0, SDRAM bank 0 */ beq sdram_done mov r4, #0x1000000 /* init SDRAM as 16MB */ mov r1, #MEMORY_CTRL_BASE bl sdram_init sdram_done: /* return sdram size in r4 */ /* enable peripherial clocks */ mov r0, #PERIPHERALS_BASE orr r1, r0, #CLOCK_OFFS ldr r2, PERIPHERIAL_CLOCKS str r2, [r1, #CLOCK_CKEN] /* initialize UART controler */ .equ UART_CTRL_OFFS, 0x100000 .equ UART_CTRL_IEN, 0x4 .equ UART_CTRL_FCTL, 0x8 .equ UART_CTRL_LCTL, 0xc .equ UART_CTRL_MCTL, 0x10 .equ UART_CTRL_BDLO, 0x0 .equ UART_CTRL_BDHI, 0x4 orr r1, r0, #UART_CTRL_OFFS mov r2, #0x80 strb r2, [r1, #UART_CTRL_LCTL] /* DLAB on */ mov r2, #0x18 /* clock = 14.7456MHz, [BDLO,BDHI]=14745600/16/baud_rate */ strb r2, [r1, #UART_CTRL_BDLO] mov r0, #0 strb r0, [r1, #UART_CTRL_BDHI] mov r2, #0x3 strb r2, [r1, #UART_CTRL_LCTL] /* DLAB off, 8-1-N */ sub r2, r2, #0x2 strb r2, [r1, #UART_CTRL_MCTL] /* DTR on */ mov r2, #0x40 strb r2, [r1, #UART_CTRL_IEN] /* disable interupts, enable UART */ strb r0, [r1, #UART_CTRL_FCTL] /* clear and turn on FIFOs */ .equ BOOT_PARAMS_BASE, 0xbe000 .equ BOOT_PARAMS_SIZE, 0x2000 mov r0, #BOOT_PARAMS_BASE mov r1, #0 skip_0s: ldr r3, [r0, r1] cmp r1, #BOOT_PARAMS_SIZE bgt inv_params cmp r3, #0 addeq r1, r1, #4 beq skip_0s add r0, r0, r1 mov r2, #PHYS_SDRAM_1 add r2, r2, #0x100 mov r1, #0 check_size: ldr r3, [r0, r1, LSL #2] add r1, r1, r3 cmp r3, #0xffffffff beq inv_params cmp r1, #BOOT_PARAMS_SIZE bgt inv_params cmp r3, #0 bne check_size copy_params: ldr r3, [r0], #4 str r3, [r2], #4 sub r1, r1, #1 cmp r1, #0 bgt copy_params mov r3, #4 str r3, [r2], #4 ldr r3, const_54410002 str r3, [r2], #4 str r4, [r2], #4 mov r3, #PHYS_SDRAM_1 str r3, [r2], #4 inv_params: /* write tag none */ mov r0, #0 str r0, [r2], #4 str r0, [r2] #endif @ Data cache might be active. @ Be sure to flush kernel binary out of the cache, @ whatever state it is, before it is turned off. @ This is done by fetching through currently executed @ memory to be sure we hit the same cache. bic r2, pc, #0x1f add r3, r2, #0x10000 @ 64 kb is quite enough... 1: ldr r0, [r2], #32 teq r2, r3 bne 1b mcr p15, 0, r0, c7, c10, 4 @ drain WB mcr p15, 0, r0, c7, c7, 0 @ flush I & D caches @ disabling MMU and caches mrc p15, 0, r0, c1, c0, 0 @ read control reg bic r0, r0, #0x05 @ clear DC, MMU bic r0, r0, #0x1000 @ clear Icache mcr p15, 0, r0, c1, c0, 0 #ifdef CONFIG_ARCH_LUBBOCK mov r7, #MACH_TYPE_LUBBOCK #endif #ifdef CONFIG_ARCH_PXA_IDP mov r7, #MACH_TYPE_PXA_IDP #endif #ifdef CONFIG_ARCH_TRIZEPS2 mov r7, #(MACH_TYPE_TRIZEPS2 & 0xFF00) add r7, r7, #(MACH_TYPE_TRIZEPS2 & 0xFF) #endif