From 92d5ecba47feb9961c3b7525e947866c5f0d2de5 Mon Sep 17 00:00:00 2001 From: Albert Aribaud Date: Mon, 11 Oct 2010 13:13:28 +0200 Subject: arm: implement ELF relocations ELF relocation tables generated with linker option -pie can be used to fixup code and data in a single loop at relocation, removing the need for manual fixups anywhere else in the code. Signed-off-by: Albert Aribaud --- arch/arm/cpu/arm926ejs/start.S | 164 +++++++++++++++++++------------------- arch/arm/cpu/arm926ejs/u-boot.lds | 26 +++--- 2 files changed, 99 insertions(+), 91 deletions(-) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/arm926ejs/start.S b/arch/arm/cpu/arm926ejs/start.S index a960689..49ca839 100644 --- a/arch/arm/cpu/arm926ejs/start.S +++ b/arch/arm/cpu/arm926ejs/start.S @@ -10,6 +10,7 @@ * Copyright (c) 2002 Gary Jennejohn * Copyright (c) 2003 Richard Woodruff * Copyright (c) 2003 Kshitij + * Copyright (c) 2010 Albert Aribaud * * See file CREDITS for list of people who contributed to this * project. @@ -118,22 +119,19 @@ _fiq: _TEXT_BASE: .word TEXT_BASE -#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) -.globl _armboot_start -_armboot_start: - .word _start -#endif - /* * These are defined in the board-specific linker script. + * Subtracting _start from them lets the linker put their + * relative position in the executable instead of leaving + * them null. */ -.globl _bss_start -_bss_start: - .word __bss_start +.globl _bss_start_ofs +_bss_start_ofs: + .word __bss_start - _start -.globl _bss_end -_bss_end: - .word _end +.globl _bss_end_ofs +_bss_end_ofs: + .word _end - _start #ifdef CONFIG_USE_IRQ /* IRQ stack memory (calculated at run-time) */ @@ -153,30 +151,6 @@ FIQ_STACK_START: IRQ_STACK_START_IN: .word 0x0badc0de -.globl _datarel_start -_datarel_start: - .word __datarel_start - -.globl _datarelrolocal_start -_datarelrolocal_start: - .word __datarelrolocal_start - -.globl _datarellocal_start -_datarellocal_start: - .word __datarellocal_start - -.globl _datarelro_start -_datarelro_start: - .word __datarelro_start - -.globl _got_start -_got_start: - .word __got_start - -.globl _got_end -_got_end: - .word __got_end - /* * the actual reset code */ @@ -226,9 +200,8 @@ stack_setup: adr r0, _start ldr r2, _TEXT_BASE - ldr r3, _bss_start - sub r2, r3, r2 /* r2 <- size of armboot */ - add r2, r0, r2 /* r2 <- source end address */ + ldr r3, _bss_start_ofs + add r2, r0, r3 /* r2 <- source end address */ cmp r0, r6 beq clear_bss @@ -240,36 +213,54 @@ copy_loop: blo copy_loop #ifndef CONFIG_PRELOADER - /* fix got entries */ - ldr r1, _TEXT_BASE /* Text base */ - mov r0, r7 /* reloc addr */ - ldr r2, _got_start /* addr in Flash */ - ldr r3, _got_end /* addr in Flash */ - sub r3, r3, r1 - add r3, r3, r0 - sub r2, r2, r1 - add r2, r2, r0 - + /* + * fix .rel.dyn relocations + */ + ldr r0, _TEXT_BASE /* r0 <- Text base */ + sub r9, r7, r0 /* r9 <- relocation offset */ + ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */ + add r10, r10, r0 /* r10 <- sym table in FLASH */ + ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */ + add r2, r2, r0 /* r2 <- rel dyn start in FLASH */ + ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */ + add r3, r3, r0 /* r3 <- rel dyn end in FLASH */ fixloop: - ldr r4, [r2] - sub r4, r4, r1 - add r4, r4, r0 - str r4, [r2] - add r2, r2, #4 + ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */ + add r0, r9 /* r0 <- location to fix up in RAM */ + ldr r1, [r2, #4] + and r8, r1, #0xff + cmp r8, #23 /* relative fixup? */ + beq fixrel + cmp r8, #2 /* absolute fixup? */ + beq fixabs + /* ignore unknown type of fixup */ + b fixnext +fixabs: + /* absolute fix: set location to (offset) symbol value */ + mov r1, r1, LSR #4 /* r1 <- symbol index in .dynsym */ + add r1, r10, r1 /* r1 <- address of symbol in table */ + ldr r1, [r1, #4] /* r1 <- symbol value */ + add r1, r9 /* r1 <- relocated sym addr */ + b fixnext +fixrel: + /* relative fix: increase location by offset */ + ldr r1, [r0] + add r1, r1, r9 +fixnext: + str r1, [r0] + add r2, r2, #8 /* each rel.dyn entry is 8 bytes */ cmp r2, r3 - bne fixloop + blo fixloop #endif #endif /* #ifndef CONFIG_SKIP_RELOCATE_UBOOT */ clear_bss: #ifndef CONFIG_PRELOADER - ldr r0, _bss_start - ldr r1, _bss_end + ldr r0, _bss_start_ofs + ldr r1, _bss_end_ofs ldr r3, _TEXT_BASE /* Text base */ mov r4, r7 /* reloc addr */ - sub r0, r0, r3 add r0, r0, r4 - sub r1, r1, r3 add r1, r1, r4 mov r2, #0x00000000 /* clear */ @@ -287,24 +278,33 @@ clbss_l:str r2, [r0] /* clear loop... */ * initialization, now running from RAM. */ #ifdef CONFIG_NAND_SPL - ldr pc, _nand_boot - -_nand_boot: .word nand_boot + ldr r0, _nand_boot_ofs + adr r1, _start + add pc, r0, r1 +_nand_boot_ofs + : .word nand_boot - _start #else - ldr r0, _TEXT_BASE - ldr r2, _board_init_r - sub r2, r2, r0 - add r2, r2, r7 /* position from board_init_r in RAM */ + ldr r0, _board_init_r_ofs + adr r1, _start + add r0, r0, r1 + add lr, r0, r9 /* setup parameters for board_init_r */ mov r0, r5 /* gd_t */ mov r1, r7 /* dest_addr */ /* jump to it ... */ - mov lr, r2 mov pc, lr -_board_init_r: .word board_init_r +_board_init_r_ofs: + .word board_init_r - _start #endif +_rel_dyn_start_ofs: + .word __rel_dyn_start - _start +_rel_dyn_end_ofs: + .word __rel_dyn_end - _start +_dynsym_start_ofs: + .word __dynsym_start - _start + #else /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */ /* * the actual reset code @@ -333,10 +333,8 @@ relocate: /* relocate U-Boot to RAM */ ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ cmp r0, r1 /* don't reloc during debug */ beq stack_setup - ldr r2, _armboot_start - ldr r3, _bss_start - sub r2, r3, r2 /* r2 <- size of armboot */ - add r2, r0, r2 /* r2 <- source end address */ + ldr r3, _bss_start_ofs /* r3 <- _bss_start - _start */ + add r2, r0, r3 /* r2 <- source end address */ copy_loop: ldmia r0!, {r3-r10} /* copy from source address [r0] */ @@ -360,8 +358,11 @@ stack_setup: bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ clear_bss: - ldr r0, _bss_start /* find start of bss segment */ - ldr r1, _bss_end /* stop here */ + adr r2, _start + ldr r0, _bss_start_ofs /* find start of bss segment */ + add r0, r0, r2 + ldr r1, _bss_end_ofs /* stop here */ + add r1, r1, r2 mov r2, #0x00000000 /* clear */ #ifndef CONFIG_PRELOADER @@ -374,13 +375,16 @@ clbss_l:str r2, [r0] /* clear loop... */ bl red_LED_on #endif /* CONFIG_PRELOADER */ - ldr pc, _start_armboot + ldr r0, _start_armboot_ofs + adr r1, _start + add r0, r0, r1 + ldr pc, r0 -_start_armboot: +_start_armboot_ofs: #ifdef CONFIG_NAND_SPL - .word nand_boot + .word nand_boot - _start #else - .word start_armboot + .word start_armboot - _start #endif /* CONFIG_NAND_SPL */ #endif /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */ @@ -469,7 +473,7 @@ cpu_init_crit: sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12 #if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) - ldr r2, _armboot_start + adr r2, _start sub r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack #else @@ -507,7 +511,7 @@ cpu_init_crit: .macro get_bad_stack #if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) - ldr r13, _armboot_start @ setup our mode stack + adr r13, _start @ setup our mode stack sub r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack #else diff --git a/arch/arm/cpu/arm926ejs/u-boot.lds b/arch/arm/cpu/arm926ejs/u-boot.lds index 02eb8ca..72f45f8 100644 --- a/arch/arm/cpu/arm926ejs/u-boot.lds +++ b/arch/arm/cpu/arm926ejs/u-boot.lds @@ -41,21 +41,19 @@ SECTIONS . = ALIGN(4); .data : { *(.data) - __datarel_start = .; - *(.data.rel) - __datarelrolocal_start = .; - *(.data.rel.ro.local) - __datarellocal_start = .; - *(.data.rel.local) - __datarelro_start = .; - *(.data.rel.ro) } - __got_start = .; . = ALIGN(4); - .got : { *(.got) } - __got_end = .; + __rel_dyn_start = .; + .rel.dyn : { *(.rel.dyn) } + __rel_dyn_end = .; + + __dynsym_start = .; + .dynsym : { *(.dynsym) } + + . = ALIGN(4); + . = .; __u_boot_cmd_start = .; .u_boot_cmd : { *(.u_boot_cmd) } @@ -65,4 +63,10 @@ SECTIONS __bss_start = .; .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } _end = .; + + /DISCARD/ : { *(.dynstr*) } + /DISCARD/ : { *(.dynamic*) } + /DISCARD/ : { *(.plt*) } + /DISCARD/ : { *(.interp*) } + /DISCARD/ : { *(.gnu*) } } -- cgit v1.1 From 9710504d200599a6e7e7ac0046adca43cfccaf0f Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Mon, 11 Oct 2010 14:08:14 +0200 Subject: arm926ejs, tx25: add support for ELF relocations Signed-off-by: Heiko Schocher --- arch/arm/cpu/arm926ejs/start.S | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/arm926ejs/start.S b/arch/arm/cpu/arm926ejs/start.S index 49ca839..e882487 100644 --- a/arch/arm/cpu/arm926ejs/start.S +++ b/arch/arm/cpu/arm926ejs/start.S @@ -279,10 +279,10 @@ clbss_l:str r2, [r0] /* clear loop... */ */ #ifdef CONFIG_NAND_SPL ldr r0, _nand_boot_ofs - adr r1, _start - add pc, r0, r1 -_nand_boot_ofs - : .word nand_boot - _start + mov pc, r0 + +_nand_boot_ofs: + .word nand_boot #else ldr r0, _board_init_r_ofs adr r1, _start -- cgit v1.1 From c3d3a5418de3ce01248bb556b4bd3d293c4f9f1e Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Mon, 11 Oct 2010 14:08:15 +0200 Subject: armv7, beagle: add support for ELF relocations Signed-off-by: Heiko Schocher --- arch/arm/cpu/armv7/start.S | 131 +++++++++++++++++++++++++----------------- arch/arm/cpu/armv7/u-boot.lds | 7 +++ 2 files changed, 85 insertions(+), 53 deletions(-) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S index c392c5d..d5c053d 100644 --- a/arch/arm/cpu/armv7/start.S +++ b/arch/arm/cpu/armv7/start.S @@ -78,13 +78,13 @@ _armboot_start: /* * These are defined in the board-specific linker script. */ -.globl _bss_start -_bss_start: - .word __bss_start +.globl _bss_start_ofs +_bss_start_ofs: + .word __bss_start - _start -.globl _bss_end -_bss_end: - .word _end +.globl _bss_end_ofs +_bss_end_ofs: + .word _end - _start #ifdef CONFIG_USE_IRQ /* IRQ stack memory (calculated at run-time) */ @@ -104,29 +104,29 @@ FIQ_STACK_START: IRQ_STACK_START_IN: .word 0x0badc0de -.globl _datarel_start -_datarel_start: - .word __datarel_start +.globl _datarel_start_ofs +_datarel_start_ofs: + .word __datarel_start - _start -.globl _datarelrolocal_start -_datarelrolocal_start: - .word __datarelrolocal_start +.globl _datarelrolocal_start_ofs +_datarelrolocal_start_ofs: + .word __datarelrolocal_start - _start -.globl _datarellocal_start -_datarellocal_start: - .word __datarellocal_start +.globl _datarellocal_start_ofs +_datarellocal_start_ofs: + .word __datarellocal_start - _start -.globl _datarelro_start -_datarelro_start: - .word __datarelro_start +.globl _datarelro_start_ofs +_datarelro_start_ofs: + .word __datarelro_start - _start -.globl _got_start -_got_start: - .word __got_start +.globl _got_start_ofs +_got_start_ofs: + .word __got_start - _start -.globl _got_end -_got_end: - .word __got_end +.globl _got_end_Ofs +_got_end_ofs: + .word __got_end - _start /* * the actual reset code @@ -198,9 +198,8 @@ stack_setup: #ifndef CONFIG_SKIP_RELOCATE_UBOOT adr r0, _start ldr r2, _TEXT_BASE - ldr r3, _bss_start - sub r2, r3, r2 /* r2 <- size of armboot */ - add r2, r0, r2 /* r2 <- source end address */ + ldr r3, _bss_start_ofs + add r2, r0, r3 /* r2 <- source end address */ cmp r0, r6 #ifndef CONFIG_PRELOADER beq jump_2_ram @@ -213,33 +212,51 @@ copy_loop: blo copy_loop #ifndef CONFIG_PRELOADER - /* fix got entries */ - ldr r1, _TEXT_BASE - mov r0, r7 /* reloc addr */ - ldr r2, _got_start /* addr in Flash */ - ldr r3, _got_end /* addr in Flash */ - sub r3, r3, r1 - add r3, r3, r0 - sub r2, r2, r1 - add r2, r2, r0 - + /* + * fix .rel.dyn relocations + */ + ldr r0, _TEXT_BASE /* r0 <- Text base */ + sub r9, r7, r0 /* r9 <- relocation offset */ + ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */ + add r10, r10, r0 /* r10 <- sym table in FLASH */ + ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */ + add r2, r2, r0 /* r2 <- rel dyn start in FLASH */ + ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */ + add r3, r3, r0 /* r3 <- rel dyn end in FLASH */ fixloop: - ldr r4, [r2] - sub r4, r4, r1 - add r4, r4, r0 - str r4, [r2] - add r2, r2, #4 + ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */ + add r0, r9 /* r0 <- location to fix up in RAM */ + ldr r1, [r2, #4] + and r8, r1, #0xff + cmp r8, #23 /* relative fixup? */ + beq fixrel + cmp r8, #2 /* absolute fixup? */ + beq fixabs + /* ignore unknown type of fixup */ + b fixnext +fixabs: + /* absolute fix: set location to (offset) symbol value */ + mov r1, r1, LSR #4 /* r1 <- symbol index in .dynsym */ + add r1, r10, r1 /* r1 <- address of symbol in table */ + ldr r1, [r1, #4] /* r1 <- symbol value */ + add r1, r9 /* r1 <- relocated sym addr */ + b fixnext +fixrel: + /* relative fix: increase location by offset */ + ldr r1, [r0] + add r1, r1, r9 +fixnext: + str r1, [r0] + add r2, r2, #8 /* each rel.dyn entry is 8 bytes */ cmp r2, r3 - bne fixloop + blo fixloop clear_bss: - ldr r0, _bss_start - ldr r1, _bss_end + ldr r0, _bss_start_ofs + ldr r1, _bss_end_ofs ldr r3, _TEXT_BASE /* Text base */ mov r4, r7 /* reloc addr */ - sub r0, r0, r3 add r0, r0, r4 - sub r1, r1, r3 add r1, r1, r4 mov r2, #0x00000000 /* clear */ @@ -255,18 +272,26 @@ clbss_l:str r2, [r0] /* clear loop... */ * initialization, now running from RAM. */ jump_2_ram: - ldr r0, _TEXT_BASE - ldr r2, _board_init_r - sub r2, r2, r0 - add r2, r2, r7 /* position from board_init_r in RAM */ + ldr r0, _board_init_r_ofs + adr r1, _start + add r0, r0, r1 + add lr, r0, r9 /* setup parameters for board_init_r */ mov r0, r5 /* gd_t */ mov r1, r7 /* dest_addr */ /* jump to it ... */ - mov lr, r2 mov pc, lr -_board_init_r: .word board_init_r +_board_init_r_ofs: + .word board_init_r - _start + +_rel_dyn_start_ofs: + .word __rel_dyn_start - _start +_rel_dyn_end_ofs: + .word __rel_dyn_end - _start +_dynsym_start_ofs: + .word __dynsym_start - _start + #else /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */ /* * the actual reset code diff --git a/arch/arm/cpu/armv7/u-boot.lds b/arch/arm/cpu/armv7/u-boot.lds index d4fd3fc..88a0fec 100644 --- a/arch/arm/cpu/armv7/u-boot.lds +++ b/arch/arm/cpu/armv7/u-boot.lds @@ -53,6 +53,13 @@ SECTIONS __datarelro_start = .; *(.data.rel.ro) } + . = ALIGN(4); + __rel_dyn_start = .; + .rel.dyn : { *(.rel.dyn) } + __rel_dyn_end = .; + + __dynsym_start = .; + .dynsym : { *(.dynsym) } __got_start = .; . = ALIGN(4); -- cgit v1.1 From bafe7437a4c21a8935ffbb5dfe8b5f1994b9f1d4 Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Wed, 13 Oct 2010 07:57:14 +0200 Subject: arm1136, qong: add support for ELF relocations Signed-off-by: Wolfgang Denk Signed-off-by: Heiko Schocher cc: Albert ARIBAUD --- arch/arm/cpu/arm1136/start.S | 171 ++++++++++++++++++++++------------------ arch/arm/cpu/arm1136/u-boot.lds | 15 +++- 2 files changed, 108 insertions(+), 78 deletions(-) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/arm1136/start.S b/arch/arm/cpu/arm1136/start.S index 494768e..a86114b 100644 --- a/arch/arm/cpu/arm1136/start.S +++ b/arch/arm/cpu/arm1136/start.S @@ -89,48 +89,35 @@ _end_vect: _TEXT_BASE: .word TEXT_BASE -#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) -.globl _armboot_start -_armboot_start: - .word _start -#endif - /* * These are defined in the board-specific linker script. + * Subtracting _start from them lets the linker put their + * relative position in the executable instead of leaving + * them null. */ -.globl _bss_start -_bss_start: - .word __bss_start - -.globl _bss_end -_bss_end: - .word _end - -#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) -.globl _datarel_start -_datarel_start: - .word __datarel_start +.globl _bss_start_ofs +_bss_start_ofs: + .word __bss_start - _start -.globl _datarelrolocal_start -_datarelrolocal_start: - .word __datarelrolocal_start +.globl _bss_end_ofs +_bss_end_ofs: + .word _end - _start -.globl _datarellocal_start -_datarellocal_start: - .word __datarellocal_start +.globl _datarel_start_ofs +_datarel_start_ofs: + .word __datarel_start - _start -.globl _datarelro_start -_datarelro_start: - .word __datarelro_start +.globl _datarelrolocal_start_ofs +_datarelrolocal_start_ofs: + .word __datarelrolocal_start - _start -.globl _got_start -_got_start: - .word __got_start +.globl _datarellocal_start_ofs +_datarellocal_start_ofs: + .word __datarellocal_start - _start -.globl _got_end -_got_end: - .word __got_end -#endif +.globl _datarelro_start_ofs +_datarelro_start_ofs: + .word __datarelro_start - _start #ifdef CONFIG_USE_IRQ /* IRQ stack memory (calculated at run-time) */ @@ -225,9 +212,8 @@ stack_setup: adr r0, _start ldr r2, _TEXT_BASE - ldr r3, _bss_start - sub r2, r3, r2 /* r2 <- size of armboot */ - add r2, r0, r2 /* r2 <- source end address */ + ldr r3, _bss_start_ofs + add r2, r0, r3 /* r2 <- source end address */ cmp r0, r6 beq clear_bss @@ -239,36 +225,54 @@ copy_loop: blo copy_loop #ifndef CONFIG_PRELOADER - /* fix got entries */ - ldr r1, _TEXT_BASE - mov r0, r7 /* reloc addr */ - ldr r2, _got_start /* addr in Flash */ - ldr r3, _got_end /* addr in Flash */ - sub r3, r3, r1 - add r3, r3, r0 - sub r2, r2, r1 - add r2, r2, r0 - + /* + * fix .rel.dyn relocations + */ + ldr r0, _TEXT_BASE /* r0 <- Text base */ + sub r9, r7, r0 /* r9 <- relocation offset */ + ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */ + add r10, r10, r0 /* r10 <- sym table in FLASH */ + ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */ + add r2, r2, r0 /* r2 <- rel dyn start in FLASH */ + ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */ + add r3, r3, r0 /* r3 <- rel dyn end in FLASH */ fixloop: - ldr r4, [r2] - sub r4, r4, r1 - add r4, r4, r0 - str r4, [r2] - add r2, r2, #4 + ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */ + add r0, r9 /* r0 <- location to fix up in RAM */ + ldr r1, [r2, #4] + and r8, r1, #0xff + cmp r8, #23 /* relative fixup? */ + beq fixrel + cmp r8, #2 /* absolute fixup? */ + beq fixabs + /* ignore unknown type of fixup */ + b fixnext +fixabs: + /* absolute fix: set location to (offset) symbol value */ + mov r1, r1, LSR #4 /* r1 <- symbol index in .dynsym */ + add r1, r10, r1 /* r1 <- address of symbol in table */ + ldr r1, [r1, #4] /* r1 <- symbol value */ + add r1, r9 /* r1 <- relocated sym addr */ + b fixnext +fixrel: + /* relative fix: increase location by offset */ + ldr r1, [r0] + add r1, r1, r9 +fixnext: + str r1, [r0] + add r2, r2, #8 /* each rel.dyn entry is 8 bytes */ cmp r2, r3 - bne fixloop + ble fixloop #endif #endif /* #ifndef CONFIG_SKIP_RELOCATE_UBOOT */ clear_bss: #ifndef CONFIG_PRELOADER - ldr r0, _bss_start - ldr r1, _bss_end + ldr r0, _bss_start_ofs + ldr r1, _bss_end_ofs ldr r3, _TEXT_BASE /* Text base */ mov r4, r7 /* reloc addr */ - sub r0, r0, r3 add r0, r0, r4 - sub r1, r1, r3 add r1, r1, r4 mov r2, #0x00000000 /* clear */ @@ -283,24 +287,34 @@ clbss_l:str r2, [r0] /* clear loop... */ * initialization, now running from RAM. */ #ifdef CONFIG_NAND_SPL - ldr pc, _nand_boot - -_nand_boot: .word nand_boot + ldr r0, _nand_boot_ofs + adr r1, _start + add pc, r0, r1 +_nand_boot_ofs + : .word nand_boot - _start #else jump_2_ram: - ldr r0, _TEXT_BASE - ldr r2, _board_init_r - sub r2, r2, r0 - add r2, r2, r7 /* position from board_init_r in RAM */ + ldr r0, _board_init_r_ofs + adr r1, _start + add r0, r0, r1 + add lr, r0, r9 /* setup parameters for board_init_r */ mov r0, r5 /* gd_t */ mov r1, r7 /* dest_addr */ /* jump to it ... */ - mov lr, r2 mov pc, lr -_board_init_r: .word board_init_r +_board_init_r_ofs: + .word board_init_r - _start #endif + +_rel_dyn_start_ofs: + .word __rel_dyn_start - _start +_rel_dyn_end_ofs: + .word __rel_dyn_end - _start +_dynsym_start_ofs: + .word __dynsym_start - _start + #else /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */ /* * the actual reset code @@ -375,8 +389,11 @@ stack_setup: bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ clear_bss: - ldr r0, _bss_start /* find start of bss segment */ - ldr r1, _bss_end /* stop here */ + adr r2, _start + ldr r0, _bss_start_ofs /* find start of bss segment */ + add r0, r0, r2 + ldr r1, _bss_end_ofs /* stop here */ + add r1, r1, r2 mov r2, #0x00000000 /* clear */ #ifndef CONFIG_PRELOADER @@ -386,15 +403,19 @@ clbss_l:str r2, [r0] /* clear loop... */ bne clbss_l #endif - ldr pc, _start_armboot + ldr r0, _start_armboot_ofs + adr r1, _start + add r0, r0, r1 + ldr pc, r0 +_start_armboot_ofs: #ifdef CONFIG_NAND_SPL -_start_armboot: .word nand_boot + .word nand_boot - _start #else #ifdef CONFIG_ONENAND_IPL -_start_armboot: .word start_oneboot + .word start_oneboot - _start #else -_start_armboot: .word start_armboot + .word start_armboot - _start #endif /* CONFIG_ONENAND_IPL */ #endif /* CONFIG_NAND_SPL */ @@ -487,7 +508,7 @@ cpu_init_crit: #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) ldr r2, IRQ_STACK_START_IN @ set base 2 words into abort stack #else - ldr r2, _armboot_start + adr r2, _start sub r2, r2, #(CONFIG_SYS_MALLOC_LEN) sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack #endif @@ -524,8 +545,8 @@ cpu_init_crit: #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) ldr r13, IRQ_STACK_START_IN @ setup our mode stack (enter in banked mode) #else - ldr r13, _armboot_start @ setup our mode stack (enter in banked mode) - sub r13, r13, #(CONFIG_SYS_MALLOC_LEN) @ move past malloc pool + adr r13, _start @ setup our mode stack (enter in banked mode) + sub r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) @ move past malloc pool sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ move to reserved a couple spots for abort stack #endif diff --git a/arch/arm/cpu/arm1136/u-boot.lds b/arch/arm/cpu/arm1136/u-boot.lds index 1db4b49..31f43f0 100644 --- a/arch/arm/cpu/arm1136/u-boot.lds +++ b/arch/arm/cpu/arm1136/u-boot.lds @@ -59,11 +59,14 @@ SECTIONS *(.data.rel.ro) } - __got_start = .; . = ALIGN(4); - .got : { *(.got) } + __rel_dyn_start = .; + .rel.dyn : { *(.rel.dyn) } + __rel_dyn_end = .; + + __dynsym_start = .; + .dynsym : { *(.dynsym) } - __got_end = .; . = .; __u_boot_cmd_start = .; .u_boot_cmd : { *(.u_boot_cmd) } @@ -73,4 +76,10 @@ SECTIONS __bss_start = .; .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } _end = .; + + /DISCARD/ : { *(.dynstr*) } + /DISCARD/ : { *(.dynamic*) } + /DISCARD/ : { *(.plt*) } + /DISCARD/ : { *(.interp*) } + /DISCARD/ : { *(.gnu*) } } -- cgit v1.1 From ff9f475d5d46da7e4acf523a61aef65638765670 Mon Sep 17 00:00:00 2001 From: Jason Liu Date: Mon, 18 Oct 2010 11:09:26 +0800 Subject: MX5: rename mx51 to mx5 Rename mx51 to mx5 in order to support more mx51 like-style SOCs such as MX53 and the followings. Signed-off-by: Jason Liu --- arch/arm/cpu/armv7/mx5/Makefile | 48 ++++++ arch/arm/cpu/armv7/mx5/clock.c | 294 ++++++++++++++++++++++++++++++++ arch/arm/cpu/armv7/mx5/iomux.c | 166 ++++++++++++++++++ arch/arm/cpu/armv7/mx5/lowlevel_init.S | 291 +++++++++++++++++++++++++++++++ arch/arm/cpu/armv7/mx5/soc.c | 120 +++++++++++++ arch/arm/cpu/armv7/mx5/speed.c | 39 +++++ arch/arm/cpu/armv7/mx5/timer.c | 119 +++++++++++++ arch/arm/cpu/armv7/mx5/u-boot.lds | 73 ++++++++ arch/arm/cpu/armv7/mx51/Makefile | 48 ------ arch/arm/cpu/armv7/mx51/clock.c | 294 -------------------------------- arch/arm/cpu/armv7/mx51/iomux.c | 166 ------------------ arch/arm/cpu/armv7/mx51/lowlevel_init.S | 291 ------------------------------- arch/arm/cpu/armv7/mx51/soc.c | 114 ------------- arch/arm/cpu/armv7/mx51/speed.c | 39 ----- arch/arm/cpu/armv7/mx51/timer.c | 119 ------------- arch/arm/cpu/armv7/mx51/u-boot.lds | 73 -------- 16 files changed, 1150 insertions(+), 1144 deletions(-) create mode 100644 arch/arm/cpu/armv7/mx5/Makefile create mode 100644 arch/arm/cpu/armv7/mx5/clock.c create mode 100644 arch/arm/cpu/armv7/mx5/iomux.c create mode 100644 arch/arm/cpu/armv7/mx5/lowlevel_init.S create mode 100644 arch/arm/cpu/armv7/mx5/soc.c create mode 100644 arch/arm/cpu/armv7/mx5/speed.c create mode 100644 arch/arm/cpu/armv7/mx5/timer.c create mode 100644 arch/arm/cpu/armv7/mx5/u-boot.lds delete mode 100644 arch/arm/cpu/armv7/mx51/Makefile delete mode 100644 arch/arm/cpu/armv7/mx51/clock.c delete mode 100644 arch/arm/cpu/armv7/mx51/iomux.c delete mode 100644 arch/arm/cpu/armv7/mx51/lowlevel_init.S delete mode 100644 arch/arm/cpu/armv7/mx51/soc.c delete mode 100644 arch/arm/cpu/armv7/mx51/speed.c delete mode 100644 arch/arm/cpu/armv7/mx51/timer.c delete mode 100644 arch/arm/cpu/armv7/mx51/u-boot.lds (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/armv7/mx5/Makefile b/arch/arm/cpu/armv7/mx5/Makefile new file mode 100644 index 0000000..7cfaa2c --- /dev/null +++ b/arch/arm/cpu/armv7/mx5/Makefile @@ -0,0 +1,48 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2009 Freescale Semiconductor, Inc. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).a + +COBJS = soc.o clock.o iomux.o timer.o speed.o +SOBJS = lowlevel_init.o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/armv7/mx5/clock.c b/arch/arm/cpu/armv7/mx5/clock.c new file mode 100644 index 0000000..00f649c --- /dev/null +++ b/arch/arm/cpu/armv7/mx5/clock.c @@ -0,0 +1,294 @@ +/* + * (C) Copyright 2007 + * Sascha Hauer, Pengutronix + * + * (C) Copyright 2009 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include + +enum pll_clocks { + PLL1_CLOCK = 0, + PLL2_CLOCK, + PLL3_CLOCK, + PLL_CLOCKS, +}; + +struct mxc_pll_reg *mxc_plls[PLL_CLOCKS] = { + [PLL1_CLOCK] = (struct mxc_pll_reg *)PLL1_BASE_ADDR, + [PLL2_CLOCK] = (struct mxc_pll_reg *)PLL2_BASE_ADDR, + [PLL3_CLOCK] = (struct mxc_pll_reg *)PLL3_BASE_ADDR, +}; + +struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)MXC_CCM_BASE; + +/* + * Calculate the frequency of this pll. + */ +static u32 decode_pll(struct mxc_pll_reg *pll, u32 infreq) +{ + u32 mfi, mfn, mfd, pd; + + mfn = __raw_readl(&pll->mfn); + mfd = __raw_readl(&pll->mfd) + 1; + mfi = __raw_readl(&pll->op); + pd = (mfi & 0xF) + 1; + mfi = (mfi >> 4) & 0xF; + mfi = (mfi >= 5) ? mfi : 5; + + return ((4 * (infreq / 1000) * (mfi * mfd + mfn)) / (mfd * pd)) * 1000; +} + +/* + * Get mcu main rate + */ +u32 get_mcu_main_clk(void) +{ + u32 reg, freq; + + reg = (__raw_readl(&mxc_ccm->cacrr) & MXC_CCM_CACRR_ARM_PODF_MASK) >> + MXC_CCM_CACRR_ARM_PODF_OFFSET; + freq = decode_pll(mxc_plls[PLL1_CLOCK], CONFIG_SYS_MX5_HCLK); + return freq / (reg + 1); +} + +/* + * Get the rate of peripheral's root clock. + */ +static u32 get_periph_clk(void) +{ + u32 reg; + + reg = __raw_readl(&mxc_ccm->cbcdr); + if (!(reg & MXC_CCM_CBCDR_PERIPH_CLK_SEL)) + return decode_pll(mxc_plls[PLL2_CLOCK], CONFIG_SYS_MX5_HCLK); + reg = __raw_readl(&mxc_ccm->cbcmr); + switch ((reg & MXC_CCM_CBCMR_PERIPH_CLK_SEL_MASK) >> + MXC_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET) { + case 0: + return decode_pll(mxc_plls[PLL1_CLOCK], CONFIG_SYS_MX5_HCLK); + case 1: + return decode_pll(mxc_plls[PLL3_CLOCK], CONFIG_SYS_MX5_HCLK); + default: + return 0; + } + /* NOTREACHED */ +} + +/* + * Get the rate of ipg clock. + */ +static u32 get_ipg_clk(void) +{ + u32 ahb_podf, ipg_podf; + + ahb_podf = __raw_readl(&mxc_ccm->cbcdr); + ipg_podf = (ahb_podf & MXC_CCM_CBCDR_IPG_PODF_MASK) >> + MXC_CCM_CBCDR_IPG_PODF_OFFSET; + ahb_podf = (ahb_podf & MXC_CCM_CBCDR_AHB_PODF_MASK) >> + MXC_CCM_CBCDR_AHB_PODF_OFFSET; + return get_periph_clk() / ((ahb_podf + 1) * (ipg_podf + 1)); +} + +/* + * Get the rate of ipg_per clock. + */ +static u32 get_ipg_per_clk(void) +{ + u32 pred1, pred2, podf; + + if (__raw_readl(&mxc_ccm->cbcmr) & MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL) + return get_ipg_clk(); + /* Fixme: not handle what about lpm*/ + podf = __raw_readl(&mxc_ccm->cbcdr); + pred1 = (podf & MXC_CCM_CBCDR_PERCLK_PRED1_MASK) >> + MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET; + pred2 = (podf & MXC_CCM_CBCDR_PERCLK_PRED2_MASK) >> + MXC_CCM_CBCDR_PERCLK_PRED2_OFFSET; + podf = (podf & MXC_CCM_CBCDR_PERCLK_PODF_MASK) >> + MXC_CCM_CBCDR_PERCLK_PODF_OFFSET; + + return get_periph_clk() / ((pred1 + 1) * (pred2 + 1) * (podf + 1)); +} + +/* + * Get the rate of uart clk. + */ +static u32 get_uart_clk(void) +{ + unsigned int freq, reg, pred, podf; + + reg = __raw_readl(&mxc_ccm->cscmr1); + switch ((reg & MXC_CCM_CSCMR1_UART_CLK_SEL_MASK) >> + MXC_CCM_CSCMR1_UART_CLK_SEL_OFFSET) { + case 0x0: + freq = decode_pll(mxc_plls[PLL1_CLOCK], + CONFIG_SYS_MX5_HCLK); + break; + case 0x1: + freq = decode_pll(mxc_plls[PLL2_CLOCK], + CONFIG_SYS_MX5_HCLK); + break; + case 0x2: + freq = decode_pll(mxc_plls[PLL3_CLOCK], + CONFIG_SYS_MX5_HCLK); + break; + default: + return 66500000; + } + + reg = __raw_readl(&mxc_ccm->cscdr1); + + pred = (reg & MXC_CCM_CSCDR1_UART_CLK_PRED_MASK) >> + MXC_CCM_CSCDR1_UART_CLK_PRED_OFFSET; + + podf = (reg & MXC_CCM_CSCDR1_UART_CLK_PODF_MASK) >> + MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET; + freq /= (pred + 1) * (podf + 1); + + return freq; +} + +/* + * This function returns the low power audio clock. + */ +u32 get_lp_apm(void) +{ + u32 ret_val = 0; + u32 ccsr = __raw_readl(&mxc_ccm->ccsr); + + if (((ccsr >> 9) & 1) == 0) + ret_val = CONFIG_SYS_MX5_HCLK; + else + ret_val = ((32768 * 1024)); + + return ret_val; +} + +/* + * get cspi clock rate. + */ +u32 imx_get_cspiclk(void) +{ + u32 ret_val = 0, pdf, pre_pdf, clk_sel; + u32 cscmr1 = __raw_readl(&mxc_ccm->cscmr1); + u32 cscdr2 = __raw_readl(&mxc_ccm->cscdr2); + + pre_pdf = (cscdr2 & MXC_CCM_CSCDR2_CSPI_CLK_PRED_MASK) \ + >> MXC_CCM_CSCDR2_CSPI_CLK_PRED_OFFSET; + pdf = (cscdr2 & MXC_CCM_CSCDR2_CSPI_CLK_PODF_MASK) \ + >> MXC_CCM_CSCDR2_CSPI_CLK_PODF_OFFSET; + clk_sel = (cscmr1 & MXC_CCM_CSCMR1_CSPI_CLK_SEL_MASK) \ + >> MXC_CCM_CSCMR1_CSPI_CLK_SEL_OFFSET; + + switch (clk_sel) { + case 0: + ret_val = decode_pll(mxc_plls[PLL1_CLOCK], + CONFIG_SYS_MX5_HCLK) / + ((pre_pdf + 1) * (pdf + 1)); + break; + case 1: + ret_val = decode_pll(mxc_plls[PLL2_CLOCK], + CONFIG_SYS_MX5_HCLK) / + ((pre_pdf + 1) * (pdf + 1)); + break; + case 2: + ret_val = decode_pll(mxc_plls[PLL3_CLOCK], + CONFIG_SYS_MX5_HCLK) / + ((pre_pdf + 1) * (pdf + 1)); + break; + default: + ret_val = get_lp_apm() / ((pre_pdf + 1) * (pdf + 1)); + break; + } + + return ret_val; +} + +/* + * The API of get mxc clockes. + */ +unsigned int mxc_get_clock(enum mxc_clock clk) +{ + switch (clk) { + case MXC_ARM_CLK: + return get_mcu_main_clk(); + case MXC_AHB_CLK: + break; + case MXC_IPG_CLK: + return get_ipg_clk(); + case MXC_IPG_PERCLK: + return get_ipg_per_clk(); + case MXC_UART_CLK: + return get_uart_clk(); + case MXC_CSPI_CLK: + return imx_get_cspiclk(); + case MXC_FEC_CLK: + return decode_pll(mxc_plls[PLL1_CLOCK], + CONFIG_SYS_MX5_HCLK); + default: + break; + } + return -1; +} + +u32 imx_get_uartclk(void) +{ + return get_uart_clk(); +} + + +u32 imx_get_fecclk(void) +{ + return mxc_get_clock(MXC_IPG_CLK); +} + +/* + * Dump some core clockes. + */ +int do_mx5_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + u32 freq; + + freq = decode_pll(mxc_plls[PLL1_CLOCK], CONFIG_SYS_MX5_HCLK); + printf("pll1: %dMHz\n", freq / 1000000); + freq = decode_pll(mxc_plls[PLL2_CLOCK], CONFIG_SYS_MX5_HCLK); + printf("pll2: %dMHz\n", freq / 1000000); + freq = decode_pll(mxc_plls[PLL3_CLOCK], CONFIG_SYS_MX5_HCLK); + printf("pll3: %dMHz\n", freq / 1000000); + printf("ipg clock : %dHz\n", mxc_get_clock(MXC_IPG_CLK)); + printf("ipg per clock : %dHz\n", mxc_get_clock(MXC_IPG_PERCLK)); + + return 0; +} + +/***************************************************/ + +U_BOOT_CMD( + clockinfo, CONFIG_SYS_MAXARGS, 1, do_mx5_showclocks, + "display clocks\n", + "" +); diff --git a/arch/arm/cpu/armv7/mx5/iomux.c b/arch/arm/cpu/armv7/mx5/iomux.c new file mode 100644 index 0000000..e8928d5 --- /dev/null +++ b/arch/arm/cpu/armv7/mx5/iomux.c @@ -0,0 +1,166 @@ +/* + * (C) Copyright 2009 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include + +/* IOMUX register (base) addresses */ +enum iomux_reg_addr { + IOMUXGPR0 = IOMUXC_BASE_ADDR, + IOMUXGPR1 = IOMUXC_BASE_ADDR + 0x004, + IOMUXSW_MUX_CTL = IOMUXC_BASE_ADDR, + IOMUXSW_MUX_END = IOMUXC_BASE_ADDR + MUX_I_END, + IOMUXSW_PAD_CTL = IOMUXC_BASE_ADDR + PAD_I_START, + IOMUXSW_INPUT_CTL = IOMUXC_BASE_ADDR, +}; + +#define MUX_PIN_NUM_MAX (((MUX_I_END - MUX_I_START) >> 2) + 1) + +/* Get the iomux register address of this pin */ +static inline u32 get_mux_reg(iomux_pin_name_t pin) +{ + u32 mux_reg = PIN_TO_IOMUX_MUX(pin); + + if (is_soc_rev(CHIP_REV_2_0) < 0) { + /* + * Fixup register address: + * i.MX51 TO1 has offset with the register + * which is define as TO2. + */ + if ((pin == MX51_PIN_NANDF_RB5) || + (pin == MX51_PIN_NANDF_RB6) || + (pin == MX51_PIN_NANDF_RB7)) + ; /* Do nothing */ + else if (mux_reg >= 0x2FC) + mux_reg += 8; + else if (mux_reg >= 0x130) + mux_reg += 0xC; + } + mux_reg += IOMUXSW_MUX_CTL; + return mux_reg; +} + +/* Get the pad register address of this pin */ +static inline u32 get_pad_reg(iomux_pin_name_t pin) +{ + u32 pad_reg = PIN_TO_IOMUX_PAD(pin); + + if (is_soc_rev(CHIP_REV_2_0) < 0) { + /* + * Fixup register address: + * i.MX51 TO1 has offset with the register + * which is define as TO2. + */ + if ((pin == MX51_PIN_NANDF_RB5) || + (pin == MX51_PIN_NANDF_RB6) || + (pin == MX51_PIN_NANDF_RB7)) + ; /* Do nothing */ + else if (pad_reg == 0x4D0 - PAD_I_START) + pad_reg += 0x4C; + else if (pad_reg == 0x860 - PAD_I_START) + pad_reg += 0x9C; + else if (pad_reg >= 0x804 - PAD_I_START) + pad_reg += 0xB0; + else if (pad_reg >= 0x7FC - PAD_I_START) + pad_reg += 0xB4; + else if (pad_reg >= 0x4E4 - PAD_I_START) + pad_reg += 0xCC; + else + pad_reg += 8; + } + pad_reg += IOMUXSW_PAD_CTL; + return pad_reg; +} + +/* Get the last iomux register address */ +static inline u32 get_mux_end(void) +{ + if (is_soc_rev(CHIP_REV_2_0) < 0) + return IOMUXC_BASE_ADDR + (0x3F8 - 4); + else + return IOMUXC_BASE_ADDR + (0x3F0 - 4); +} + +/* + * This function is used to configure a pin through the IOMUX module. + * @param pin a pin number as defined in iomux_pin_name_t + * @param cfg an output function as defined in iomux_pin_cfg_t + * + * @return 0 if successful; Non-zero otherwise + */ +static void iomux_config_mux(iomux_pin_name_t pin, iomux_pin_cfg_t cfg) +{ + u32 mux_reg = get_mux_reg(pin); + + if ((mux_reg > get_mux_end()) || (mux_reg < IOMUXSW_MUX_CTL)) + return ; + if (cfg == IOMUX_CONFIG_GPIO) + writel(PIN_TO_ALT_GPIO(pin), mux_reg); + else + writel(cfg, mux_reg); +} + +/* + * Request ownership for an IO pin. This function has to be the first one + * being called before that pin is used. The caller has to check the + * return value to make sure it returns 0. + * + * @param pin a name defined by iomux_pin_name_t + * @param cfg an input function as defined in iomux_pin_cfg_t + * + */ +void mxc_request_iomux(iomux_pin_name_t pin, iomux_pin_cfg_t cfg) +{ + iomux_config_mux(pin, cfg); +} + +/* + * Release ownership for an IO pin + * + * @param pin a name defined by iomux_pin_name_t + * @param cfg an input function as defined in iomux_pin_cfg_t + */ +void mxc_free_iomux(iomux_pin_name_t pin, iomux_pin_cfg_t cfg) +{ +} + +/* + * This function configures the pad value for a IOMUX pin. + * + * @param pin a pin number as defined in iomux_pin_name_t + * @param config the ORed value of elements defined in iomux_pad_config_t + */ +void mxc_iomux_set_pad(iomux_pin_name_t pin, u32 config) +{ + u32 pad_reg = get_pad_reg(pin); + writel(config, pad_reg); +} + +unsigned int mxc_iomux_get_pad(iomux_pin_name_t pin) +{ + u32 pad_reg = get_pad_reg(pin); + return readl(pad_reg); +} diff --git a/arch/arm/cpu/armv7/mx5/lowlevel_init.S b/arch/arm/cpu/armv7/mx5/lowlevel_init.S new file mode 100644 index 0000000..783c81f --- /dev/null +++ b/arch/arm/cpu/armv7/mx5/lowlevel_init.S @@ -0,0 +1,291 @@ +/* + * Copyright (C) 2007, Guennadi Liakhovetski + * + * (C) Copyright 2009 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +/* + * L2CC Cache setup/invalidation/disable + */ +.macro init_l2cc + /* explicitly disable L2 cache */ + mrc 15, 0, r0, c1, c0, 1 + bic r0, r0, #0x2 + mcr 15, 0, r0, c1, c0, 1 + + /* reconfigure L2 cache aux control reg */ + mov r0, #0xC0 /* tag RAM */ + add r0, r0, #0x4 /* data RAM */ + orr r0, r0, #(1 << 24) /* disable write allocate delay */ + orr r0, r0, #(1 << 23) /* disable write allocate combine */ + orr r0, r0, #(1 << 22) /* disable write allocate */ + + cmp r3, #0x10 /* r3 contains the silicon rev */ + + /* disable write combine for TO 2 and lower revs */ + orrls r0, r0, #(1 << 25) + + mcr 15, 1, r0, c9, c0, 2 +.endm /* init_l2cc */ + +/* AIPS setup - Only setup MPROTx registers. + * The PACR default values are good.*/ +.macro init_aips + /* + * Set all MPROTx to be non-bufferable, trusted for R/W, + * not forced to user-mode. + */ + ldr r0, =AIPS1_BASE_ADDR + ldr r1, =0x77777777 + str r1, [r0, #0x0] + str r1, [r0, #0x4] + ldr r0, =AIPS2_BASE_ADDR + str r1, [r0, #0x0] + str r1, [r0, #0x4] + /* + * Clear the on and off peripheral modules Supervisor Protect bit + * for SDMA to access them. Did not change the AIPS control registers + * (offset 0x20) access type + */ +.endm /* init_aips */ + +/* M4IF setup */ +.macro init_m4if + /* VPU and IPU given higher priority (0x4) + * IPU accesses with ID=0x1 given highest priority (=0xA) + */ + ldr r0, =M4IF_BASE_ADDR + + ldr r1, =0x00000203 + str r1, [r0, #0x40] + + ldr r1, =0x0 + str r1, [r0, #0x44] + + ldr r1, =0x00120125 + str r1, [r0, #0x9C] + + ldr r1, =0x001901A3 + str r1, [r0, #0x48] + +.endm /* init_m4if */ + +.macro setup_pll pll, freq + ldr r2, =\pll + ldr r1, =0x00001232 + str r1, [r2, #PLL_DP_CTL] /* Set DPLL ON (set UPEN bit): BRMO=1 */ + mov r1, #0x2 + str r1, [r2, #PLL_DP_CONFIG] /* Enable auto-restart AREN bit */ + + str r3, [r2, #PLL_DP_OP] + str r3, [r2, #PLL_DP_HFS_OP] + + str r4, [r2, #PLL_DP_MFD] + str r4, [r2, #PLL_DP_HFS_MFD] + + str r5, [r2, #PLL_DP_MFN] + str r5, [r2, #PLL_DP_HFS_MFN] + + ldr r1, =0x00001232 + str r1, [r2, #PLL_DP_CTL] +1: ldr r1, [r2, #PLL_DP_CTL] + ands r1, r1, #0x1 + beq 1b +.endm + +.macro init_clock + ldr r0, =CCM_BASE_ADDR + + /* Gate of clocks to the peripherals first */ + ldr r1, =0x3FFFFFFF + str r1, [r0, #CLKCTL_CCGR0] + ldr r1, =0x0 + str r1, [r0, #CLKCTL_CCGR1] + str r1, [r0, #CLKCTL_CCGR2] + str r1, [r0, #CLKCTL_CCGR3] + + ldr r1, =0x00030000 + str r1, [r0, #CLKCTL_CCGR4] + ldr r1, =0x00FFF030 + str r1, [r0, #CLKCTL_CCGR5] + ldr r1, =0x00000300 + str r1, [r0, #CLKCTL_CCGR6] + + /* Disable IPU and HSC dividers */ + mov r1, #0x60000 + str r1, [r0, #CLKCTL_CCDR] + + /* Make sure to switch the DDR away from PLL 1 */ + ldr r1, =0x19239145 + str r1, [r0, #CLKCTL_CBCDR] + /* make sure divider effective */ +1: ldr r1, [r0, #CLKCTL_CDHIPR] + cmp r1, #0x0 + bne 1b + + /* Switch ARM to step clock */ + mov r1, #0x4 + str r1, [r0, #CLKCTL_CCSR] + mov r3, #DP_OP_800 + mov r4, #DP_MFD_800 + mov r5, #DP_MFN_800 + setup_pll PLL1_BASE_ADDR + + mov r3, #DP_OP_665 + mov r4, #DP_MFD_665 + mov r5, #DP_MFN_665 + setup_pll PLL3_BASE_ADDR + + /* Switch peripheral to PLL 3 */ + ldr r0, =CCM_BASE_ADDR + ldr r1, =0x000010C0 + orr r1,r1,#CONFIG_SYS_DDR_CLKSEL + str r1, [r0, #CLKCTL_CBCMR] + ldr r1, =0x13239145 + str r1, [r0, #CLKCTL_CBCDR] + mov r3, #DP_OP_665 + mov r4, #DP_MFD_665 + mov r5, #DP_MFN_665 + setup_pll PLL2_BASE_ADDR + + /* Switch peripheral to PLL2 */ + ldr r0, =CCM_BASE_ADDR + ldr r1, =0x19239145 + str r1, [r0, #CLKCTL_CBCDR] + ldr r1, =0x000020C0 + orr r1,r1,#CONFIG_SYS_DDR_CLKSEL + str r1, [r0, #CLKCTL_CBCMR] + + mov r3, #DP_OP_216 + mov r4, #DP_MFD_216 + mov r5, #DP_MFN_216 + setup_pll PLL3_BASE_ADDR + + + /* Set the platform clock dividers */ + ldr r0, =ARM_BASE_ADDR + ldr r1, =0x00000725 + str r1, [r0, #0x14] + + ldr r0, =CCM_BASE_ADDR + + /* Run 3.0 at Full speed, for other TO's wait till we increase VDDGP */ + ldr r1, =0x0 + ldr r3, [r1, #ROM_SI_REV] + cmp r3, #0x10 + movls r1, #0x1 + movhi r1, #0 + str r1, [r0, #CLKCTL_CACRR] + + /* Switch ARM back to PLL 1 */ + mov r1, #0 + str r1, [r0, #CLKCTL_CCSR] + + /* setup the rest */ + /* Use lp_apm (24MHz) source for perclk */ + ldr r1, =0x000020C2 + orr r1,r1,#CONFIG_SYS_DDR_CLKSEL + str r1, [r0, #CLKCTL_CBCMR] + /* ddr clock from PLL 1, all perclk dividers are 1 since using 24MHz */ + ldr r1, =CONFIG_SYS_CLKTL_CBCDR + str r1, [r0, #CLKCTL_CBCDR] + + /* Restore the default values in the Gate registers */ + ldr r1, =0xFFFFFFFF + str r1, [r0, #CLKCTL_CCGR0] + str r1, [r0, #CLKCTL_CCGR1] + str r1, [r0, #CLKCTL_CCGR2] + str r1, [r0, #CLKCTL_CCGR3] + str r1, [r0, #CLKCTL_CCGR4] + str r1, [r0, #CLKCTL_CCGR5] + str r1, [r0, #CLKCTL_CCGR6] + + /* Use PLL 2 for UART's, get 66.5MHz from it */ + ldr r1, =0xA5A2A020 + str r1, [r0, #CLKCTL_CSCMR1] + ldr r1, =0x00C30321 + str r1, [r0, #CLKCTL_CSCDR1] + + /* make sure divider effective */ +1: ldr r1, [r0, #CLKCTL_CDHIPR] + cmp r1, #0x0 + bne 1b + + mov r1, #0x0 + str r1, [r0, #CLKCTL_CCDR] + + /* for cko - for ARM div by 8 */ + mov r1, #0x000A0000 + add r1, r1, #0x00000F0 + str r1, [r0, #CLKCTL_CCOSR] +.endm + +.macro setup_wdog + ldr r0, =WDOG1_BASE_ADDR + mov r1, #0x30 + strh r1, [r0] +.endm + +.section ".text.init", "x" + +.globl lowlevel_init +lowlevel_init: + ldr r0, =GPIO1_BASE_ADDR + ldr r1, [r0, #0x0] + orr r1, r1, #(1 << 23) + str r1, [r0, #0x0] + ldr r1, [r0, #0x4] + orr r1, r1, #(1 << 23) + str r1, [r0, #0x4] + +#ifdef ENABLE_IMPRECISE_ABORT + mrs r1, spsr /* save old spsr */ + mrs r0, cpsr /* read out the cpsr */ + bic r0, r0, #0x100 /* clear the A bit */ + msr spsr, r0 /* update spsr */ + add lr, pc, #0x8 /* update lr */ + movs pc, lr /* update cpsr */ + nop + nop + nop + nop + msr spsr, r1 /* restore old spsr */ +#endif + + init_l2cc + + init_aips + + init_m4if + + init_clock + + /* r12 saved upper lr*/ + mov pc,lr + +/* Board level setting value */ +DDR_PERCHARGE_CMD: .word 0x04008008 +DDR_REFRESH_CMD: .word 0x00008010 +DDR_LMR1_W: .word 0x00338018 +DDR_LMR_CMD: .word 0xB2220000 +DDR_TIMING_W: .word 0xB02567A9 +DDR_MISC_W: .word 0x000A0104 diff --git a/arch/arm/cpu/armv7/mx5/soc.c b/arch/arm/cpu/armv7/mx5/soc.c new file mode 100644 index 0000000..7c7a565 --- /dev/null +++ b/arch/arm/cpu/armv7/mx5/soc.c @@ -0,0 +1,120 @@ +/* + * (C) Copyright 2007 + * Sascha Hauer, Pengutronix + * + * (C) Copyright 2009 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include + +#ifdef CONFIG_FSL_ESDHC +#include +#endif + +#if defined(CONFIG_MX51) +#define CPU_TYPE 0x51000 +#else +#error "CPU_TYPE not defined" +#endif + +u32 get_cpu_rev(void) +{ + int system_rev = CPU_TYPE; + int reg = __raw_readl(ROM_SI_REV); + + switch (reg) { + case 0x02: + system_rev |= CHIP_REV_1_1; + break; + case 0x10: + if ((__raw_readl(GPIO1_BASE_ADDR + 0x0) & (0x1 << 22)) == 0) + system_rev |= CHIP_REV_2_5; + else + system_rev |= CHIP_REV_2_0; + break; + case 0x20: + system_rev |= CHIP_REV_3_0; + break; + return system_rev; + default: + system_rev |= CHIP_REV_1_0; + break; + } + return system_rev; +} + + +#if defined(CONFIG_DISPLAY_CPUINFO) +int print_cpuinfo(void) +{ + u32 cpurev; + + cpurev = get_cpu_rev(); + printf("CPU: Freescale i.MX%x family rev%d.%d at %d MHz\n", + (cpurev & 0xFF000) >> 12, + (cpurev & 0x000F0) >> 4, + (cpurev & 0x0000F) >> 0, + mxc_get_clock(MXC_ARM_CLK) / 1000000); + return 0; +} +#endif + +/* + * Initializes on-chip ethernet controllers. + * to override, implement board_eth_init() + */ +#if defined(CONFIG_FEC_MXC) +extern int fecmxc_initialize(bd_t *bis); +#endif + +int cpu_eth_init(bd_t *bis) +{ + int rc = -ENODEV; + +#if defined(CONFIG_FEC_MXC) + rc = fecmxc_initialize(bis); +#endif + + return rc; +} + +/* + * Initializes on-chip MMC controllers. + * to override, implement board_mmc_init() + */ +int cpu_mmc_init(bd_t *bis) +{ +#ifdef CONFIG_FSL_ESDHC + return fsl_esdhc_mmc_init(bis); +#else + return 0; +#endif +} + + +void reset_cpu(ulong addr) +{ + __raw_writew(4, WDOG1_BASE_ADDR); +} diff --git a/arch/arm/cpu/armv7/mx5/speed.c b/arch/arm/cpu/armv7/mx5/speed.c new file mode 100644 index 0000000..a444def --- /dev/null +++ b/arch/arm/cpu/armv7/mx5/speed.c @@ -0,0 +1,39 @@ +/* + * (C) Copyright 2000-2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +int get_clocks(void) +{ + DECLARE_GLOBAL_DATA_PTR; + +#ifdef CONFIG_FSL_ESDHC + gd->sdhc_clk = mxc_get_clock(MXC_IPG_PERCLK); +#endif + return 0; +} diff --git a/arch/arm/cpu/armv7/mx5/timer.c b/arch/arm/cpu/armv7/mx5/timer.c new file mode 100644 index 0000000..3044fcf --- /dev/null +++ b/arch/arm/cpu/armv7/mx5/timer.c @@ -0,0 +1,119 @@ +/* + * (C) Copyright 2007 + * Sascha Hauer, Pengutronix + * + * (C) Copyright 2009 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +/* General purpose timers registers */ +struct mxc_gpt { + unsigned int control; + unsigned int prescaler; + unsigned int status; + unsigned int nouse[6]; + unsigned int counter; +}; + +static struct mxc_gpt *cur_gpt = (struct mxc_gpt *)GPT1_BASE_ADDR; + +/* General purpose timers bitfields */ +#define GPTCR_SWR (1<<15) /* Software reset */ +#define GPTCR_FRR (1<<9) /* Freerun / restart */ +#define GPTCR_CLKSOURCE_32 (4<<6) /* Clock source */ +#define GPTCR_TEN (1) /* Timer enable */ + +static ulong timestamp; +static ulong lastinc; + +int timer_init(void) +{ + int i; + + /* setup GP Timer 1 */ + __raw_writel(GPTCR_SWR, &cur_gpt->control); + + /* We have no udelay by now */ + for (i = 0; i < 100; i++) + __raw_writel(0, &cur_gpt->control); + + __raw_writel(0, &cur_gpt->prescaler); /* 32Khz */ + + /* Freerun Mode, PERCLK1 input */ + i = __raw_readl(&cur_gpt->control); + __raw_writel(i | GPTCR_CLKSOURCE_32 | GPTCR_TEN, &cur_gpt->control); + reset_timer_masked(); + return 0; +} + +void reset_timer(void) +{ + reset_timer_masked(); +} + +void reset_timer_masked(void) +{ + ulong val = __raw_readl(&cur_gpt->counter); + lastinc = val / (CONFIG_SYS_MX5_CLK32 / CONFIG_SYS_HZ); + timestamp = 0; +} + +ulong get_timer_masked(void) +{ + ulong val = __raw_readl(&cur_gpt->counter); + val /= (CONFIG_SYS_MX5_CLK32 / CONFIG_SYS_HZ); + if (val >= lastinc) + timestamp += (val - lastinc); + else + timestamp += ((0xFFFFFFFF / (CONFIG_SYS_MX5_CLK32 / CONFIG_SYS_HZ)) + - lastinc) + val; + lastinc = val; + return timestamp; +} + +ulong get_timer(ulong base) +{ + return get_timer_masked() - base; +} + +void set_timer(ulong t) +{ + timestamp = t; +} + +/* delay x useconds AND preserve advance timestamp value */ +void __udelay(unsigned long usec) +{ + unsigned long now, start, tmo; + tmo = usec * (CONFIG_SYS_MX5_CLK32 / 1000) / 1000; + + if (!tmo) + tmo = 1; + + now = start = readl(&cur_gpt->counter); + + while ((now - start) < tmo) + now = readl(&cur_gpt->counter); + +} diff --git a/arch/arm/cpu/armv7/mx5/u-boot.lds b/arch/arm/cpu/armv7/mx5/u-boot.lds new file mode 100644 index 0000000..55d6599 --- /dev/null +++ b/arch/arm/cpu/armv7/mx5/u-boot.lds @@ -0,0 +1,73 @@ +/* + * January 2004 - Changed to support H4 device + * Copyright (c) 2004 Texas Instruments + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * (C) Copyright 2009 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + arch/arm/cpu/armv7/start.o + *(.text) + } + + . = ALIGN(4); + .rodata : { *(.rodata) } + + . = ALIGN(4); + .data : { + *(.data) + __datarel_start = .; + *(.data.rel) + __datarelrolocal_start = .; + *(.data.rel.ro.local) + __datarellocal_start = .; + *(.data.rel.local) + __datarelro_start = .; + *(.data.rel.ro) + } + + __got_start = .; + . = ALIGN(4); + .got : { *(.got) } + __got_end = .; + + . = .; + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + . = ALIGN(4); + __bss_start = .; + .bss : { *(.bss) } + _end = .; +} diff --git a/arch/arm/cpu/armv7/mx51/Makefile b/arch/arm/cpu/armv7/mx51/Makefile deleted file mode 100644 index 7cfaa2c..0000000 --- a/arch/arm/cpu/armv7/mx51/Makefile +++ /dev/null @@ -1,48 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# (C) Copyright 2009 Freescale Semiconductor, Inc. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(SOC).a - -COBJS = soc.o clock.o iomux.o timer.o speed.o -SOBJS = lowlevel_init.o - -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) - -all: $(obj).depend $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/arch/arm/cpu/armv7/mx51/clock.c b/arch/arm/cpu/armv7/mx51/clock.c deleted file mode 100644 index a27227d..0000000 --- a/arch/arm/cpu/armv7/mx51/clock.c +++ /dev/null @@ -1,294 +0,0 @@ -/* - * (C) Copyright 2007 - * Sascha Hauer, Pengutronix - * - * (C) Copyright 2009 Freescale Semiconductor, Inc. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include - -enum pll_clocks { - PLL1_CLOCK = 0, - PLL2_CLOCK, - PLL3_CLOCK, - PLL_CLOCKS, -}; - -struct mxc_pll_reg *mxc_plls[PLL_CLOCKS] = { - [PLL1_CLOCK] = (struct mxc_pll_reg *)PLL1_BASE_ADDR, - [PLL2_CLOCK] = (struct mxc_pll_reg *)PLL2_BASE_ADDR, - [PLL3_CLOCK] = (struct mxc_pll_reg *)PLL3_BASE_ADDR, -}; - -struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)MXC_CCM_BASE; - -/* - * Calculate the frequency of this pll. - */ -static u32 decode_pll(struct mxc_pll_reg *pll, u32 infreq) -{ - u32 mfi, mfn, mfd, pd; - - mfn = __raw_readl(&pll->mfn); - mfd = __raw_readl(&pll->mfd) + 1; - mfi = __raw_readl(&pll->op); - pd = (mfi & 0xF) + 1; - mfi = (mfi >> 4) & 0xF; - mfi = (mfi >= 5) ? mfi : 5; - - return ((4 * (infreq / 1000) * (mfi * mfd + mfn)) / (mfd * pd)) * 1000; -} - -/* - * Get mcu main rate - */ -u32 get_mcu_main_clk(void) -{ - u32 reg, freq; - - reg = (__raw_readl(&mxc_ccm->cacrr) & MXC_CCM_CACRR_ARM_PODF_MASK) >> - MXC_CCM_CACRR_ARM_PODF_OFFSET; - freq = decode_pll(mxc_plls[PLL1_CLOCK], CONFIG_MX51_HCLK_FREQ); - return freq / (reg + 1); -} - -/* - * Get the rate of peripheral's root clock. - */ -static u32 get_periph_clk(void) -{ - u32 reg; - - reg = __raw_readl(&mxc_ccm->cbcdr); - if (!(reg & MXC_CCM_CBCDR_PERIPH_CLK_SEL)) - return decode_pll(mxc_plls[PLL2_CLOCK], CONFIG_MX51_HCLK_FREQ); - reg = __raw_readl(&mxc_ccm->cbcmr); - switch ((reg & MXC_CCM_CBCMR_PERIPH_CLK_SEL_MASK) >> - MXC_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET) { - case 0: - return decode_pll(mxc_plls[PLL1_CLOCK], CONFIG_MX51_HCLK_FREQ); - case 1: - return decode_pll(mxc_plls[PLL3_CLOCK], CONFIG_MX51_HCLK_FREQ); - default: - return 0; - } - /* NOTREACHED */ -} - -/* - * Get the rate of ipg clock. - */ -static u32 get_ipg_clk(void) -{ - u32 ahb_podf, ipg_podf; - - ahb_podf = __raw_readl(&mxc_ccm->cbcdr); - ipg_podf = (ahb_podf & MXC_CCM_CBCDR_IPG_PODF_MASK) >> - MXC_CCM_CBCDR_IPG_PODF_OFFSET; - ahb_podf = (ahb_podf & MXC_CCM_CBCDR_AHB_PODF_MASK) >> - MXC_CCM_CBCDR_AHB_PODF_OFFSET; - return get_periph_clk() / ((ahb_podf + 1) * (ipg_podf + 1)); -} - -/* - * Get the rate of ipg_per clock. - */ -static u32 get_ipg_per_clk(void) -{ - u32 pred1, pred2, podf; - - if (__raw_readl(&mxc_ccm->cbcmr) & MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL) - return get_ipg_clk(); - /* Fixme: not handle what about lpm*/ - podf = __raw_readl(&mxc_ccm->cbcdr); - pred1 = (podf & MXC_CCM_CBCDR_PERCLK_PRED1_MASK) >> - MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET; - pred2 = (podf & MXC_CCM_CBCDR_PERCLK_PRED2_MASK) >> - MXC_CCM_CBCDR_PERCLK_PRED2_OFFSET; - podf = (podf & MXC_CCM_CBCDR_PERCLK_PODF_MASK) >> - MXC_CCM_CBCDR_PERCLK_PODF_OFFSET; - - return get_periph_clk() / ((pred1 + 1) * (pred2 + 1) * (podf + 1)); -} - -/* - * Get the rate of uart clk. - */ -static u32 get_uart_clk(void) -{ - unsigned int freq, reg, pred, podf; - - reg = __raw_readl(&mxc_ccm->cscmr1); - switch ((reg & MXC_CCM_CSCMR1_UART_CLK_SEL_MASK) >> - MXC_CCM_CSCMR1_UART_CLK_SEL_OFFSET) { - case 0x0: - freq = decode_pll(mxc_plls[PLL1_CLOCK], - CONFIG_MX51_HCLK_FREQ); - break; - case 0x1: - freq = decode_pll(mxc_plls[PLL2_CLOCK], - CONFIG_MX51_HCLK_FREQ); - break; - case 0x2: - freq = decode_pll(mxc_plls[PLL3_CLOCK], - CONFIG_MX51_HCLK_FREQ); - break; - default: - return 66500000; - } - - reg = __raw_readl(&mxc_ccm->cscdr1); - - pred = (reg & MXC_CCM_CSCDR1_UART_CLK_PRED_MASK) >> - MXC_CCM_CSCDR1_UART_CLK_PRED_OFFSET; - - podf = (reg & MXC_CCM_CSCDR1_UART_CLK_PODF_MASK) >> - MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET; - freq /= (pred + 1) * (podf + 1); - - return freq; -} - -/* - * This function returns the low power audio clock. - */ -u32 get_lp_apm(void) -{ - u32 ret_val = 0; - u32 ccsr = __raw_readl(&mxc_ccm->ccsr); - - if (((ccsr >> 9) & 1) == 0) - ret_val = CONFIG_MX51_HCLK_FREQ; - else - ret_val = ((32768 * 1024)); - - return ret_val; -} - -/* - * get cspi clock rate. - */ -u32 imx_get_cspiclk(void) -{ - u32 ret_val = 0, pdf, pre_pdf, clk_sel; - u32 cscmr1 = __raw_readl(&mxc_ccm->cscmr1); - u32 cscdr2 = __raw_readl(&mxc_ccm->cscdr2); - - pre_pdf = (cscdr2 & MXC_CCM_CSCDR2_CSPI_CLK_PRED_MASK) \ - >> MXC_CCM_CSCDR2_CSPI_CLK_PRED_OFFSET; - pdf = (cscdr2 & MXC_CCM_CSCDR2_CSPI_CLK_PODF_MASK) \ - >> MXC_CCM_CSCDR2_CSPI_CLK_PODF_OFFSET; - clk_sel = (cscmr1 & MXC_CCM_CSCMR1_CSPI_CLK_SEL_MASK) \ - >> MXC_CCM_CSCMR1_CSPI_CLK_SEL_OFFSET; - - switch (clk_sel) { - case 0: - ret_val = decode_pll(mxc_plls[PLL1_CLOCK], - CONFIG_MX51_HCLK_FREQ) / - ((pre_pdf + 1) * (pdf + 1)); - break; - case 1: - ret_val = decode_pll(mxc_plls[PLL2_CLOCK], - CONFIG_MX51_HCLK_FREQ) / - ((pre_pdf + 1) * (pdf + 1)); - break; - case 2: - ret_val = decode_pll(mxc_plls[PLL3_CLOCK], - CONFIG_MX51_HCLK_FREQ) / - ((pre_pdf + 1) * (pdf + 1)); - break; - default: - ret_val = get_lp_apm() / ((pre_pdf + 1) * (pdf + 1)); - break; - } - - return ret_val; -} - -/* - * The API of get mxc clockes. - */ -unsigned int mxc_get_clock(enum mxc_clock clk) -{ - switch (clk) { - case MXC_ARM_CLK: - return get_mcu_main_clk(); - case MXC_AHB_CLK: - break; - case MXC_IPG_CLK: - return get_ipg_clk(); - case MXC_IPG_PERCLK: - return get_ipg_per_clk(); - case MXC_UART_CLK: - return get_uart_clk(); - case MXC_CSPI_CLK: - return imx_get_cspiclk(); - case MXC_FEC_CLK: - return decode_pll(mxc_plls[PLL1_CLOCK], - CONFIG_MX51_HCLK_FREQ); - default: - break; - } - return -1; -} - -u32 imx_get_uartclk(void) -{ - return get_uart_clk(); -} - - -u32 imx_get_fecclk(void) -{ - return mxc_get_clock(MXC_IPG_CLK); -} - -/* - * Dump some core clockes. - */ -int do_mx51_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ - u32 freq; - - freq = decode_pll(mxc_plls[PLL1_CLOCK], CONFIG_MX51_HCLK_FREQ); - printf("mx51 pll1: %dMHz\n", freq / 1000000); - freq = decode_pll(mxc_plls[PLL2_CLOCK], CONFIG_MX51_HCLK_FREQ); - printf("mx51 pll2: %dMHz\n", freq / 1000000); - freq = decode_pll(mxc_plls[PLL3_CLOCK], CONFIG_MX51_HCLK_FREQ); - printf("mx51 pll3: %dMHz\n", freq / 1000000); - printf("ipg clock : %dHz\n", mxc_get_clock(MXC_IPG_CLK)); - printf("ipg per clock : %dHz\n", mxc_get_clock(MXC_IPG_PERCLK)); - - return 0; -} - -/***************************************************/ - -U_BOOT_CMD( - clockinfo, CONFIG_SYS_MAXARGS, 1, do_mx51_showclocks, - "display mx51 clocks\n", - "" -); diff --git a/arch/arm/cpu/armv7/mx51/iomux.c b/arch/arm/cpu/armv7/mx51/iomux.c deleted file mode 100644 index 62b2954..0000000 --- a/arch/arm/cpu/armv7/mx51/iomux.c +++ /dev/null @@ -1,166 +0,0 @@ -/* - * (C) Copyright 2009 Freescale Semiconductor, Inc. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include - -/* IOMUX register (base) addresses */ -enum iomux_reg_addr { - IOMUXGPR0 = IOMUXC_BASE_ADDR, - IOMUXGPR1 = IOMUXC_BASE_ADDR + 0x004, - IOMUXSW_MUX_CTL = IOMUXC_BASE_ADDR, - IOMUXSW_MUX_END = IOMUXC_BASE_ADDR + MUX_I_END, - IOMUXSW_PAD_CTL = IOMUXC_BASE_ADDR + PAD_I_START, - IOMUXSW_INPUT_CTL = IOMUXC_BASE_ADDR, -}; - -#define MUX_PIN_NUM_MAX (((MUX_I_END - MUX_I_START) >> 2) + 1) - -/* Get the iomux register address of this pin */ -static inline u32 get_mux_reg(iomux_pin_name_t pin) -{ - u32 mux_reg = PIN_TO_IOMUX_MUX(pin); - - if (is_soc_rev(CHIP_REV_2_0) < 0) { - /* - * Fixup register address: - * i.MX51 TO1 has offset with the register - * which is define as TO2. - */ - if ((pin == MX51_PIN_NANDF_RB5) || - (pin == MX51_PIN_NANDF_RB6) || - (pin == MX51_PIN_NANDF_RB7)) - ; /* Do nothing */ - else if (mux_reg >= 0x2FC) - mux_reg += 8; - else if (mux_reg >= 0x130) - mux_reg += 0xC; - } - mux_reg += IOMUXSW_MUX_CTL; - return mux_reg; -} - -/* Get the pad register address of this pin */ -static inline u32 get_pad_reg(iomux_pin_name_t pin) -{ - u32 pad_reg = PIN_TO_IOMUX_PAD(pin); - - if (is_soc_rev(CHIP_REV_2_0) < 0) { - /* - * Fixup register address: - * i.MX51 TO1 has offset with the register - * which is define as TO2. - */ - if ((pin == MX51_PIN_NANDF_RB5) || - (pin == MX51_PIN_NANDF_RB6) || - (pin == MX51_PIN_NANDF_RB7)) - ; /* Do nothing */ - else if (pad_reg == 0x4D0 - PAD_I_START) - pad_reg += 0x4C; - else if (pad_reg == 0x860 - PAD_I_START) - pad_reg += 0x9C; - else if (pad_reg >= 0x804 - PAD_I_START) - pad_reg += 0xB0; - else if (pad_reg >= 0x7FC - PAD_I_START) - pad_reg += 0xB4; - else if (pad_reg >= 0x4E4 - PAD_I_START) - pad_reg += 0xCC; - else - pad_reg += 8; - } - pad_reg += IOMUXSW_PAD_CTL; - return pad_reg; -} - -/* Get the last iomux register address */ -static inline u32 get_mux_end(void) -{ - if (is_soc_rev(CHIP_REV_2_0) < 0) - return IOMUXC_BASE_ADDR + (0x3F8 - 4); - else - return IOMUXC_BASE_ADDR + (0x3F0 - 4); -} - -/* - * This function is used to configure a pin through the IOMUX module. - * @param pin a pin number as defined in iomux_pin_name_t - * @param cfg an output function as defined in iomux_pin_cfg_t - * - * @return 0 if successful; Non-zero otherwise - */ -static void iomux_config_mux(iomux_pin_name_t pin, iomux_pin_cfg_t cfg) -{ - u32 mux_reg = get_mux_reg(pin); - - if ((mux_reg > get_mux_end()) || (mux_reg < IOMUXSW_MUX_CTL)) - return ; - if (cfg == IOMUX_CONFIG_GPIO) - writel(PIN_TO_ALT_GPIO(pin), mux_reg); - else - writel(cfg, mux_reg); -} - -/* - * Request ownership for an IO pin. This function has to be the first one - * being called before that pin is used. The caller has to check the - * return value to make sure it returns 0. - * - * @param pin a name defined by iomux_pin_name_t - * @param cfg an input function as defined in iomux_pin_cfg_t - * - */ -void mxc_request_iomux(iomux_pin_name_t pin, iomux_pin_cfg_t cfg) -{ - iomux_config_mux(pin, cfg); -} - -/* - * Release ownership for an IO pin - * - * @param pin a name defined by iomux_pin_name_t - * @param cfg an input function as defined in iomux_pin_cfg_t - */ -void mxc_free_iomux(iomux_pin_name_t pin, iomux_pin_cfg_t cfg) -{ -} - -/* - * This function configures the pad value for a IOMUX pin. - * - * @param pin a pin number as defined in iomux_pin_name_t - * @param config the ORed value of elements defined in iomux_pad_config_t - */ -void mxc_iomux_set_pad(iomux_pin_name_t pin, u32 config) -{ - u32 pad_reg = get_pad_reg(pin); - writel(config, pad_reg); -} - -unsigned int mxc_iomux_get_pad(iomux_pin_name_t pin) -{ - u32 pad_reg = get_pad_reg(pin); - return readl(pad_reg); -} diff --git a/arch/arm/cpu/armv7/mx51/lowlevel_init.S b/arch/arm/cpu/armv7/mx51/lowlevel_init.S deleted file mode 100644 index 783c81f..0000000 --- a/arch/arm/cpu/armv7/mx51/lowlevel_init.S +++ /dev/null @@ -1,291 +0,0 @@ -/* - * Copyright (C) 2007, Guennadi Liakhovetski - * - * (C) Copyright 2009 Freescale Semiconductor, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include - -/* - * L2CC Cache setup/invalidation/disable - */ -.macro init_l2cc - /* explicitly disable L2 cache */ - mrc 15, 0, r0, c1, c0, 1 - bic r0, r0, #0x2 - mcr 15, 0, r0, c1, c0, 1 - - /* reconfigure L2 cache aux control reg */ - mov r0, #0xC0 /* tag RAM */ - add r0, r0, #0x4 /* data RAM */ - orr r0, r0, #(1 << 24) /* disable write allocate delay */ - orr r0, r0, #(1 << 23) /* disable write allocate combine */ - orr r0, r0, #(1 << 22) /* disable write allocate */ - - cmp r3, #0x10 /* r3 contains the silicon rev */ - - /* disable write combine for TO 2 and lower revs */ - orrls r0, r0, #(1 << 25) - - mcr 15, 1, r0, c9, c0, 2 -.endm /* init_l2cc */ - -/* AIPS setup - Only setup MPROTx registers. - * The PACR default values are good.*/ -.macro init_aips - /* - * Set all MPROTx to be non-bufferable, trusted for R/W, - * not forced to user-mode. - */ - ldr r0, =AIPS1_BASE_ADDR - ldr r1, =0x77777777 - str r1, [r0, #0x0] - str r1, [r0, #0x4] - ldr r0, =AIPS2_BASE_ADDR - str r1, [r0, #0x0] - str r1, [r0, #0x4] - /* - * Clear the on and off peripheral modules Supervisor Protect bit - * for SDMA to access them. Did not change the AIPS control registers - * (offset 0x20) access type - */ -.endm /* init_aips */ - -/* M4IF setup */ -.macro init_m4if - /* VPU and IPU given higher priority (0x4) - * IPU accesses with ID=0x1 given highest priority (=0xA) - */ - ldr r0, =M4IF_BASE_ADDR - - ldr r1, =0x00000203 - str r1, [r0, #0x40] - - ldr r1, =0x0 - str r1, [r0, #0x44] - - ldr r1, =0x00120125 - str r1, [r0, #0x9C] - - ldr r1, =0x001901A3 - str r1, [r0, #0x48] - -.endm /* init_m4if */ - -.macro setup_pll pll, freq - ldr r2, =\pll - ldr r1, =0x00001232 - str r1, [r2, #PLL_DP_CTL] /* Set DPLL ON (set UPEN bit): BRMO=1 */ - mov r1, #0x2 - str r1, [r2, #PLL_DP_CONFIG] /* Enable auto-restart AREN bit */ - - str r3, [r2, #PLL_DP_OP] - str r3, [r2, #PLL_DP_HFS_OP] - - str r4, [r2, #PLL_DP_MFD] - str r4, [r2, #PLL_DP_HFS_MFD] - - str r5, [r2, #PLL_DP_MFN] - str r5, [r2, #PLL_DP_HFS_MFN] - - ldr r1, =0x00001232 - str r1, [r2, #PLL_DP_CTL] -1: ldr r1, [r2, #PLL_DP_CTL] - ands r1, r1, #0x1 - beq 1b -.endm - -.macro init_clock - ldr r0, =CCM_BASE_ADDR - - /* Gate of clocks to the peripherals first */ - ldr r1, =0x3FFFFFFF - str r1, [r0, #CLKCTL_CCGR0] - ldr r1, =0x0 - str r1, [r0, #CLKCTL_CCGR1] - str r1, [r0, #CLKCTL_CCGR2] - str r1, [r0, #CLKCTL_CCGR3] - - ldr r1, =0x00030000 - str r1, [r0, #CLKCTL_CCGR4] - ldr r1, =0x00FFF030 - str r1, [r0, #CLKCTL_CCGR5] - ldr r1, =0x00000300 - str r1, [r0, #CLKCTL_CCGR6] - - /* Disable IPU and HSC dividers */ - mov r1, #0x60000 - str r1, [r0, #CLKCTL_CCDR] - - /* Make sure to switch the DDR away from PLL 1 */ - ldr r1, =0x19239145 - str r1, [r0, #CLKCTL_CBCDR] - /* make sure divider effective */ -1: ldr r1, [r0, #CLKCTL_CDHIPR] - cmp r1, #0x0 - bne 1b - - /* Switch ARM to step clock */ - mov r1, #0x4 - str r1, [r0, #CLKCTL_CCSR] - mov r3, #DP_OP_800 - mov r4, #DP_MFD_800 - mov r5, #DP_MFN_800 - setup_pll PLL1_BASE_ADDR - - mov r3, #DP_OP_665 - mov r4, #DP_MFD_665 - mov r5, #DP_MFN_665 - setup_pll PLL3_BASE_ADDR - - /* Switch peripheral to PLL 3 */ - ldr r0, =CCM_BASE_ADDR - ldr r1, =0x000010C0 - orr r1,r1,#CONFIG_SYS_DDR_CLKSEL - str r1, [r0, #CLKCTL_CBCMR] - ldr r1, =0x13239145 - str r1, [r0, #CLKCTL_CBCDR] - mov r3, #DP_OP_665 - mov r4, #DP_MFD_665 - mov r5, #DP_MFN_665 - setup_pll PLL2_BASE_ADDR - - /* Switch peripheral to PLL2 */ - ldr r0, =CCM_BASE_ADDR - ldr r1, =0x19239145 - str r1, [r0, #CLKCTL_CBCDR] - ldr r1, =0x000020C0 - orr r1,r1,#CONFIG_SYS_DDR_CLKSEL - str r1, [r0, #CLKCTL_CBCMR] - - mov r3, #DP_OP_216 - mov r4, #DP_MFD_216 - mov r5, #DP_MFN_216 - setup_pll PLL3_BASE_ADDR - - - /* Set the platform clock dividers */ - ldr r0, =ARM_BASE_ADDR - ldr r1, =0x00000725 - str r1, [r0, #0x14] - - ldr r0, =CCM_BASE_ADDR - - /* Run 3.0 at Full speed, for other TO's wait till we increase VDDGP */ - ldr r1, =0x0 - ldr r3, [r1, #ROM_SI_REV] - cmp r3, #0x10 - movls r1, #0x1 - movhi r1, #0 - str r1, [r0, #CLKCTL_CACRR] - - /* Switch ARM back to PLL 1 */ - mov r1, #0 - str r1, [r0, #CLKCTL_CCSR] - - /* setup the rest */ - /* Use lp_apm (24MHz) source for perclk */ - ldr r1, =0x000020C2 - orr r1,r1,#CONFIG_SYS_DDR_CLKSEL - str r1, [r0, #CLKCTL_CBCMR] - /* ddr clock from PLL 1, all perclk dividers are 1 since using 24MHz */ - ldr r1, =CONFIG_SYS_CLKTL_CBCDR - str r1, [r0, #CLKCTL_CBCDR] - - /* Restore the default values in the Gate registers */ - ldr r1, =0xFFFFFFFF - str r1, [r0, #CLKCTL_CCGR0] - str r1, [r0, #CLKCTL_CCGR1] - str r1, [r0, #CLKCTL_CCGR2] - str r1, [r0, #CLKCTL_CCGR3] - str r1, [r0, #CLKCTL_CCGR4] - str r1, [r0, #CLKCTL_CCGR5] - str r1, [r0, #CLKCTL_CCGR6] - - /* Use PLL 2 for UART's, get 66.5MHz from it */ - ldr r1, =0xA5A2A020 - str r1, [r0, #CLKCTL_CSCMR1] - ldr r1, =0x00C30321 - str r1, [r0, #CLKCTL_CSCDR1] - - /* make sure divider effective */ -1: ldr r1, [r0, #CLKCTL_CDHIPR] - cmp r1, #0x0 - bne 1b - - mov r1, #0x0 - str r1, [r0, #CLKCTL_CCDR] - - /* for cko - for ARM div by 8 */ - mov r1, #0x000A0000 - add r1, r1, #0x00000F0 - str r1, [r0, #CLKCTL_CCOSR] -.endm - -.macro setup_wdog - ldr r0, =WDOG1_BASE_ADDR - mov r1, #0x30 - strh r1, [r0] -.endm - -.section ".text.init", "x" - -.globl lowlevel_init -lowlevel_init: - ldr r0, =GPIO1_BASE_ADDR - ldr r1, [r0, #0x0] - orr r1, r1, #(1 << 23) - str r1, [r0, #0x0] - ldr r1, [r0, #0x4] - orr r1, r1, #(1 << 23) - str r1, [r0, #0x4] - -#ifdef ENABLE_IMPRECISE_ABORT - mrs r1, spsr /* save old spsr */ - mrs r0, cpsr /* read out the cpsr */ - bic r0, r0, #0x100 /* clear the A bit */ - msr spsr, r0 /* update spsr */ - add lr, pc, #0x8 /* update lr */ - movs pc, lr /* update cpsr */ - nop - nop - nop - nop - msr spsr, r1 /* restore old spsr */ -#endif - - init_l2cc - - init_aips - - init_m4if - - init_clock - - /* r12 saved upper lr*/ - mov pc,lr - -/* Board level setting value */ -DDR_PERCHARGE_CMD: .word 0x04008008 -DDR_REFRESH_CMD: .word 0x00008010 -DDR_LMR1_W: .word 0x00338018 -DDR_LMR_CMD: .word 0xB2220000 -DDR_TIMING_W: .word 0xB02567A9 -DDR_MISC_W: .word 0x000A0104 diff --git a/arch/arm/cpu/armv7/mx51/soc.c b/arch/arm/cpu/armv7/mx51/soc.c deleted file mode 100644 index f22ebe9..0000000 --- a/arch/arm/cpu/armv7/mx51/soc.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * (C) Copyright 2007 - * Sascha Hauer, Pengutronix - * - * (C) Copyright 2009 Freescale Semiconductor, Inc. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include - -#ifdef CONFIG_FSL_ESDHC -#include -#endif - -u32 get_cpu_rev(void) -{ - int reg; - int system_rev; - - reg = __raw_readl(ROM_SI_REV); - switch (reg) { - case 0x02: - system_rev = 0x51000 | CHIP_REV_1_1; - break; - case 0x10: - if ((__raw_readl(GPIO1_BASE_ADDR + 0x0) & (0x1 << 22)) == 0) - system_rev = 0x51000 | CHIP_REV_2_5; - else - system_rev = 0x51000 | CHIP_REV_2_0; - break; - case 0x20: - system_rev = 0x51000 | CHIP_REV_3_0; - break; - return system_rev; - default: - system_rev = 0x51000 | CHIP_REV_1_0; - break; - } - return system_rev; -} - - -#if defined(CONFIG_DISPLAY_CPUINFO) -int print_cpuinfo(void) -{ - u32 cpurev; - - cpurev = get_cpu_rev(); - printf("CPU: Freescale i.MX51 family rev%d.%d at %d MHz\n", - (cpurev & 0xF0) >> 4, - (cpurev & 0x0F) >> 4, - mxc_get_clock(MXC_ARM_CLK) / 1000000); - return 0; -} -#endif - -/* - * Initializes on-chip ethernet controllers. - * to override, implement board_eth_init() - */ -#if defined(CONFIG_FEC_MXC) -extern int fecmxc_initialize(bd_t *bis); -#endif - -int cpu_eth_init(bd_t *bis) -{ - int rc = -ENODEV; - -#if defined(CONFIG_FEC_MXC) - rc = fecmxc_initialize(bis); -#endif - - return rc; -} - -/* - * Initializes on-chip MMC controllers. - * to override, implement board_mmc_init() - */ -int cpu_mmc_init(bd_t *bis) -{ -#ifdef CONFIG_FSL_ESDHC - return fsl_esdhc_mmc_init(bis); -#else - return 0; -#endif -} - - -void reset_cpu(ulong addr) -{ - __raw_writew(4, WDOG1_BASE_ADDR); -} diff --git a/arch/arm/cpu/armv7/mx51/speed.c b/arch/arm/cpu/armv7/mx51/speed.c deleted file mode 100644 index a444def..0000000 --- a/arch/arm/cpu/armv7/mx51/speed.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * (C) Copyright 2000-2003 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. - * TsiChung Liew (Tsi-Chung.Liew@freescale.com) - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include - -int get_clocks(void) -{ - DECLARE_GLOBAL_DATA_PTR; - -#ifdef CONFIG_FSL_ESDHC - gd->sdhc_clk = mxc_get_clock(MXC_IPG_PERCLK); -#endif - return 0; -} diff --git a/arch/arm/cpu/armv7/mx51/timer.c b/arch/arm/cpu/armv7/mx51/timer.c deleted file mode 100644 index 110edbf..0000000 --- a/arch/arm/cpu/armv7/mx51/timer.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * (C) Copyright 2007 - * Sascha Hauer, Pengutronix - * - * (C) Copyright 2009 Freescale Semiconductor, Inc. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include - -/* General purpose timers registers */ -struct mxc_gpt { - unsigned int control; - unsigned int prescaler; - unsigned int status; - unsigned int nouse[6]; - unsigned int counter; -}; - -static struct mxc_gpt *cur_gpt = (struct mxc_gpt *)GPT1_BASE_ADDR; - -/* General purpose timers bitfields */ -#define GPTCR_SWR (1<<15) /* Software reset */ -#define GPTCR_FRR (1<<9) /* Freerun / restart */ -#define GPTCR_CLKSOURCE_32 (4<<6) /* Clock source */ -#define GPTCR_TEN (1) /* Timer enable */ - -static ulong timestamp; -static ulong lastinc; - -int timer_init(void) -{ - int i; - - /* setup GP Timer 1 */ - __raw_writel(GPTCR_SWR, &cur_gpt->control); - - /* We have no udelay by now */ - for (i = 0; i < 100; i++) - __raw_writel(0, &cur_gpt->control); - - __raw_writel(0, &cur_gpt->prescaler); /* 32Khz */ - - /* Freerun Mode, PERCLK1 input */ - i = __raw_readl(&cur_gpt->control); - __raw_writel(i | GPTCR_CLKSOURCE_32 | GPTCR_TEN, &cur_gpt->control); - reset_timer_masked(); - return 0; -} - -void reset_timer(void) -{ - reset_timer_masked(); -} - -void reset_timer_masked(void) -{ - ulong val = __raw_readl(&cur_gpt->counter); - lastinc = val / (CONFIG_MX51_CLK32 / CONFIG_SYS_HZ); - timestamp = 0; -} - -ulong get_timer_masked(void) -{ - ulong val = __raw_readl(&cur_gpt->counter); - val /= (CONFIG_MX51_CLK32 / CONFIG_SYS_HZ); - if (val >= lastinc) - timestamp += (val - lastinc); - else - timestamp += ((0xFFFFFFFF / (CONFIG_MX51_CLK32 / CONFIG_SYS_HZ)) - - lastinc) + val; - lastinc = val; - return timestamp; -} - -ulong get_timer(ulong base) -{ - return get_timer_masked() - base; -} - -void set_timer(ulong t) -{ - timestamp = t; -} - -/* delay x useconds AND preserve advance timestamp value */ -void __udelay(unsigned long usec) -{ - unsigned long now, start, tmo; - tmo = usec * (CONFIG_MX51_CLK32 / 1000) / 1000; - - if (!tmo) - tmo = 1; - - now = start = readl(&cur_gpt->counter); - - while ((now - start) < tmo) - now = readl(&cur_gpt->counter); - -} diff --git a/arch/arm/cpu/armv7/mx51/u-boot.lds b/arch/arm/cpu/armv7/mx51/u-boot.lds deleted file mode 100644 index 55d6599..0000000 --- a/arch/arm/cpu/armv7/mx51/u-boot.lds +++ /dev/null @@ -1,73 +0,0 @@ -/* - * January 2004 - Changed to support H4 device - * Copyright (c) 2004 Texas Instruments - * - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * (C) Copyright 2009 Freescale Semiconductor, Inc. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) -ENTRY(_start) -SECTIONS -{ - . = 0x00000000; - - . = ALIGN(4); - .text : - { - arch/arm/cpu/armv7/start.o - *(.text) - } - - . = ALIGN(4); - .rodata : { *(.rodata) } - - . = ALIGN(4); - .data : { - *(.data) - __datarel_start = .; - *(.data.rel) - __datarelrolocal_start = .; - *(.data.rel.ro.local) - __datarellocal_start = .; - *(.data.rel.local) - __datarelro_start = .; - *(.data.rel.ro) - } - - __got_start = .; - . = ALIGN(4); - .got : { *(.got) } - __got_end = .; - - . = .; - __u_boot_cmd_start = .; - .u_boot_cmd : { *(.u_boot_cmd) } - __u_boot_cmd_end = .; - - . = ALIGN(4); - __bss_start = .; - .bss : { *(.bss) } - _end = .; -} -- cgit v1.1 From 65e62d69415acd4cf8c297b8df7076694e796802 Mon Sep 17 00:00:00 2001 From: Jason Liu Date: Tue, 19 Oct 2010 16:22:14 +0800 Subject: MX5: Remove dead code with ENABLE_IMPRECISE_ABORT This code section is dead due to we never define ENABLE_IMPRECISE_ABORT for MX5 Signed-off-by: Jason Liu --- arch/arm/cpu/armv7/mx5/lowlevel_init.S | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/armv7/mx5/lowlevel_init.S b/arch/arm/cpu/armv7/mx5/lowlevel_init.S index 783c81f..e984870 100644 --- a/arch/arm/cpu/armv7/mx5/lowlevel_init.S +++ b/arch/arm/cpu/armv7/mx5/lowlevel_init.S @@ -257,20 +257,6 @@ lowlevel_init: orr r1, r1, #(1 << 23) str r1, [r0, #0x4] -#ifdef ENABLE_IMPRECISE_ABORT - mrs r1, spsr /* save old spsr */ - mrs r0, cpsr /* read out the cpsr */ - bic r0, r0, #0x100 /* clear the A bit */ - msr spsr, r0 /* update spsr */ - add lr, pc, #0x8 /* update lr */ - movs pc, lr /* update cpsr */ - nop - nop - nop - nop - msr spsr, r1 /* restore old spsr */ -#endif - init_l2cc init_aips -- cgit v1.1 From 5dca710a3d7703e41da0e9894f2d71f9e25bea6b Mon Sep 17 00:00:00 2001 From: Reinhard Meyer Date: Tue, 5 Oct 2010 16:54:35 +0200 Subject: AT91 clock/timer: move static data to global_data struct clock.c / timer.c used static data and are called before relocation. Move all static variables into global_data structure. Also cleanup timer.c from unused stubs and make it truly use 64 bit tick values. Signed-off-by: Reinhard Meyer --- arch/arm/cpu/arm926ejs/at91/clock.c | 55 ++++++++++++------------ arch/arm/cpu/arm926ejs/at91/timer.c | 85 ++++++++++++++++++------------------- 2 files changed, 69 insertions(+), 71 deletions(-) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/arm926ejs/at91/clock.c b/arch/arm/cpu/arm926ejs/at91/clock.c index ecf91f5..7a10a77 100644 --- a/arch/arm/cpu/arm926ejs/at91/clock.c +++ b/arch/arm/cpu/arm926ejs/at91/clock.c @@ -11,47 +11,46 @@ * (at your option) any later version. */ -#include +#include #include #include #include #include -static unsigned long cpu_clk_rate_hz; -static unsigned long main_clk_rate_hz; -static unsigned long mck_rate_hz; -static unsigned long plla_rate_hz; -static unsigned long pllb_rate_hz; -static u32 at91_pllb_usb_init; +#if !defined(CONFIG_AT91FAMILY) +# error You need to define CONFIG_AT91FAMILY in your board config! +#endif + +DECLARE_GLOBAL_DATA_PTR; unsigned long get_cpu_clk_rate(void) { - return cpu_clk_rate_hz; + return gd->cpu_clk_rate_hz; } unsigned long get_main_clk_rate(void) { - return main_clk_rate_hz; + return gd->main_clk_rate_hz; } unsigned long get_mck_clk_rate(void) { - return mck_rate_hz; + return gd->mck_rate_hz; } unsigned long get_plla_clk_rate(void) { - return plla_rate_hz; + return gd->plla_rate_hz; } unsigned long get_pllb_clk_rate(void) { - return pllb_rate_hz; + return gd->pllb_rate_hz; } u32 get_pllb_init(void) { - return at91_pllb_usb_init; + return gd->at91_pllb_usb_init; } static unsigned long at91_css_to_rate(unsigned long css) @@ -60,11 +59,11 @@ static unsigned long at91_css_to_rate(unsigned long css) case AT91_PMC_MCKR_CSS_SLOW: return AT91_SLOW_CLOCK; case AT91_PMC_MCKR_CSS_MAIN: - return main_clk_rate_hz; + return gd->main_clk_rate_hz; case AT91_PMC_MCKR_CSS_PLLA: - return plla_rate_hz; + return gd->plla_rate_hz; case AT91_PMC_MCKR_CSS_PLLB: - return pllb_rate_hz; + return gd->pllb_rate_hz; } return 0; @@ -163,10 +162,10 @@ int at91_clock_init(unsigned long main_clock) main_clock = tmp * (AT91_SLOW_CLOCK / 16); } #endif - main_clk_rate_hz = main_clock; + gd->main_clk_rate_hz = main_clock; /* report if PLLA is more than mildly overclocked */ - plla_rate_hz = at91_pll_rate(main_clock, readl(&pmc->pllar)); + gd->plla_rate_hz = at91_pll_rate(main_clock, readl(&pmc->pllar)); #ifdef CONFIG_USB_ATMEL /* @@ -175,9 +174,9 @@ int at91_clock_init(unsigned long main_clock) * * REVISIT: assumes MCK doesn't derive from PLLB! */ - at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | + gd->at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | AT91_PMC_PLLBR_USBDIV_2; - pllb_rate_hz = at91_pll_rate(main_clock, at91_pllb_usb_init); + gd->pllb_rate_hz = at91_pll_rate(main_clock, gd->at91_pllb_usb_init); #endif /* @@ -187,30 +186,30 @@ int at91_clock_init(unsigned long main_clock) mckr = readl(&pmc->mckr); #if defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45) /* plla divisor by 2 */ - plla_rate_hz /= (1 << ((mckr & 1 << 12) >> 12)); + gd->plla_rate_hz /= (1 << ((mckr & 1 << 12) >> 12)); #endif - mck_rate_hz = at91_css_to_rate(mckr & AT91_PMC_MCKR_CSS_MASK); - freq = mck_rate_hz; + gd->mck_rate_hz = at91_css_to_rate(mckr & AT91_PMC_MCKR_CSS_MASK); + freq = gd->mck_rate_hz; freq /= (1 << ((mckr & AT91_PMC_MCKR_PRES_MASK) >> 2)); /* prescale */ #if defined(CONFIG_AT91RM9200) /* mdiv */ - mck_rate_hz = freq / (1 + ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8)); + gd->mck_rate_hz = freq / (1 + ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8)); #elif defined(CONFIG_AT91SAM9G20) /* mdiv ; (x >> 7) = ((x >> 8) * 2) */ - mck_rate_hz = (mckr & AT91_PMC_MCKR_MDIV_MASK) ? + gd->mck_rate_hz = (mckr & AT91_PMC_MCKR_MDIV_MASK) ? freq / ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 7) : freq; if (mckr & AT91_PMC_MCKR_MDIV_MASK) freq /= 2; /* processor clock division */ #elif defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45) - mck_rate_hz = (mckr & AT91_PMC_MCKR_MDIV_MASK) == + gd->mck_rate_hz = (mckr & AT91_PMC_MCKR_MDIV_MASK) == (AT91_PMC_MCKR_MDIV_2 | AT91_PMC_MCKR_MDIV_4) ? freq / 3 : freq / (1 << ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8)); #else - mck_rate_hz = freq / (1 << ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8)); + gd->mck_rate_hz = freq / (1 << ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8)); #endif - cpu_clk_rate_hz = freq; + gd->cpu_clk_rate_hz = freq; return 0; } diff --git a/arch/arm/cpu/arm926ejs/at91/timer.c b/arch/arm/cpu/arm926ejs/at91/timer.c index 8efc34b..82b8d7e 100644 --- a/arch/arm/cpu/arm926ejs/at91/timer.c +++ b/arch/arm/cpu/arm926ejs/at91/timer.c @@ -30,55 +30,63 @@ #include #include +#if !defined(CONFIG_AT91FAMILY) +# error You need to define CONFIG_AT91FAMILY in your board config! +#endif + +DECLARE_GLOBAL_DATA_PTR; + /* * We're using the AT91CAP9/SAM9 PITC in 32 bit mode, by * setting the 20 bit counter period to its maximum (0xfffff). + * (See the relevant data sheets to understand that this really works) + * + * We do also mimic the typical powerpc way of incrementing + * two 32 bit registers called tbl and tbu. + * + * Those registers increment at 1/16 the main clock rate. */ -#define TIMER_LOAD_VAL 0xfffff -static ulong timestamp; -static ulong lastinc; -static ulong timer_freq; +#define TIMER_LOAD_VAL 0xfffff static inline unsigned long long tick_to_time(unsigned long long tick) { tick *= CONFIG_SYS_HZ; - do_div(tick, timer_freq); + do_div(tick, gd->timer_rate_hz); return tick; } static inline unsigned long long usec_to_tick(unsigned long long usec) { - usec *= timer_freq; + usec *= gd->timer_rate_hz; do_div(usec, 1000000); return usec; } -/* nothing really to do with interrupts, just starts up a counter. */ +/* + * Use the PITC in full 32 bit incrementing mode + */ int timer_init(void) { at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; at91_pit_t *pit = (at91_pit_t *) AT91_PIT_BASE; - /* - * Enable PITC Clock - * The clock is already enabled for system controller in boot - */ + + /* Enable PITC Clock */ writel(1 << AT91_ID_SYS, &pmc->pcer); /* Enable PITC */ writel(TIMER_LOAD_VAL | AT91_PIT_MR_EN , &pit->mr); - reset_timer_masked(); - - timer_freq = get_mck_clk_rate() >> 4; + gd->timer_rate_hz = gd->mck_rate_hz / 16; + gd->tbu = gd->tbl = 0; return 0; } /* - * timer without interrupts + * Get the current 64 bit timer tick count */ unsigned long long get_ticks(void) { @@ -86,28 +94,11 @@ unsigned long long get_ticks(void) ulong now = readl(&pit->piir); - if (now >= lastinc) /* normal mode (non roll) */ - /* move stamp forward with absolut diff ticks */ - timestamp += (now - lastinc); - else /* we have rollover of incrementer */ - timestamp += (0xFFFFFFFF - lastinc) + now; - lastinc = now; - return timestamp; -} - -void reset_timer_masked(void) -{ - /* reset time */ - at91_pit_t *pit = (at91_pit_t *) AT91_PIT_BASE; - - /* capture current incrementer value time */ - lastinc = readl(&pit->piir); - timestamp = 0; /* start "advancing" time stamp from 0 */ -} - -ulong get_timer_masked(void) -{ - return tick_to_time(get_ticks()); + /* increment tbu if tbl has rolled over */ + if (now < gd->tbl) + gd->tbu++; + gd->tbl = now; + return (((unsigned long long)gd->tbu) << 32) | gd->tbl; } void __udelay(unsigned long usec) @@ -119,24 +110,32 @@ void __udelay(unsigned long usec) tmp = get_ticks() + tmo; /* get current timestamp */ while (get_ticks() < tmp) /* loop till event */ - /*NOP*/; + ; } +/* + * reset_timer() and get_timer(base) are a pair of functions that are used by + * some timeout/sleep mechanisms in u-boot. + * + * reset_timer() marks the current time as epoch and + * get_timer(base) works relative to that epoch. + * + * The time is used in CONFIG_SYS_HZ units! + */ void reset_timer(void) { - reset_timer_masked(); + gd->timer_reset_value = get_ticks(); } ulong get_timer(ulong base) { - return get_timer_masked () - base; + return tick_to_time(get_ticks() - gd->timer_reset_value) - base; } /* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. + * Return the number of timer ticks per second. */ ulong get_tbclk(void) { - return timer_freq; + return gd->timer_rate_hz; } -- cgit v1.1 From 9f80a20e05f20ab6b20be3addee969e1306ee3d5 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Thu, 23 Sep 2010 08:32:54 +0200 Subject: PXA: pxafb: Fix indent problems Also change the initializer style Signed-off-by: Marek Vasut --- arch/arm/cpu/pxa/pxafb.c | 200 +++++++++++++++++++++++------------------------ 1 file changed, 100 insertions(+), 100 deletions(-) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/pxa/pxafb.c b/arch/arm/cpu/pxa/pxafb.c index 0ee6a75..50e9cc0 100644 --- a/arch/arm/cpu/pxa/pxafb.c +++ b/arch/arm/cpu/pxa/pxafb.c @@ -56,26 +56,26 @@ /* 640x480x16 @ 61 Hz */ vidinfo_t panel_info = { - vl_col: 640, - vl_row: 480, - vl_width: 640, - vl_height: 480, - vl_clkp: CONFIG_SYS_HIGH, - vl_oep: CONFIG_SYS_HIGH, - vl_hsp: CONFIG_SYS_HIGH, - vl_vsp: CONFIG_SYS_HIGH, - vl_dp: CONFIG_SYS_HIGH, - vl_bpix: LCD_BPP, - vl_lbw: 0, - vl_splt: 0, - vl_clor: 0, - vl_tft: 1, - vl_hpw: 40, - vl_blw: 56, - vl_elw: 56, - vl_vpw: 20, - vl_bfw: 8, - vl_efw: 8, + .vl_col = 640, + .vl_row = 480, + .vl_width = 640, + .vl_height = 480, + .vl_clkp = CONFIG_SYS_HIGH, + .vl_oep = CONFIG_SYS_HIGH, + .vl_hsp = CONFIG_SYS_HIGH, + .vl_vsp = CONFIG_SYS_HIGH, + .vl_dp = CONFIG_SYS_HIGH, + .vl_bpix = LCD_BPP, + .vl_lbw = 0, + .vl_splt = 0, + .vl_clor = 0, + .vl_tft = 1, + .vl_hpw = 40, + .vl_blw = 56, + .vl_elw = 56, + .vl_vpw = 20, + .vl_bfw = 8, + .vl_efw = 8, }; #endif /* CONFIG_PXA_VIDEO */ @@ -90,26 +90,26 @@ vidinfo_t panel_info = { # define REG_LCCR3 0x0340FF08 vidinfo_t panel_info = { - vl_col: 640, - vl_row: 480, - vl_width: 157, - vl_height: 118, - vl_clkp: CONFIG_SYS_HIGH, - vl_oep: CONFIG_SYS_HIGH, - vl_hsp: CONFIG_SYS_HIGH, - vl_vsp: CONFIG_SYS_HIGH, - vl_dp: CONFIG_SYS_HIGH, - vl_bpix: LCD_BPP, - vl_lbw: 0, - vl_splt: 1, - vl_clor: 1, - vl_tft: 0, - vl_hpw: 1, - vl_blw: 3, - vl_elw: 3, - vl_vpw: 1, - vl_bfw: 0, - vl_efw: 0, + .vl_col = 640, + .vl_row = 480, + .vl_width = 157, + .vl_height = 118, + .vl_clkp = CONFIG_SYS_HIGH, + .vl_oep = CONFIG_SYS_HIGH, + .vl_hsp = CONFIG_SYS_HIGH, + .vl_vsp = CONFIG_SYS_HIGH, + .vl_dp = CONFIG_SYS_HIGH, + .vl_bpix = LCD_BPP, + .vl_lbw = 0, + .vl_splt = 1, + .vl_clor = 1, + .vl_tft = 0, + .vl_hpw = 1, + .vl_blw = 3, + .vl_elw = 3, + .vl_vpw = 1, + .vl_bfw = 0, + .vl_efw = 0, }; #endif /* CONFIG_SHARP_LM8V31 */ /*----------------------------------------------------------------------*/ @@ -123,26 +123,26 @@ vidinfo_t panel_info = { # define REG_LCCR3 0x0340FF08 vidinfo_t panel_info = { - vl_col: 640, - vl_row: 480, - vl_width: 157, - vl_height: 118, - vl_clkp: CONFIG_SYS_HIGH, - vl_oep: CONFIG_SYS_HIGH, - vl_hsp: CONFIG_SYS_HIGH, - vl_vsp: CONFIG_SYS_HIGH, - vl_dp: CONFIG_SYS_HIGH, - vl_bpix: LCD_BPP, - vl_lbw: 0, - vl_splt: 1, - vl_clor: 1, - vl_tft: 1, - vl_hpw: 32, - vl_blw: 144, - vl_elw: 32, - vl_vpw: 2, - vl_bfw: 13, - vl_efw: 30, + .vl_col = 640, + .vl_row = 480, + .vl_width = 157, + .vl_height = 118, + .vl_clkp = CONFIG_SYS_HIGH, + .vl_oep = CONFIG_SYS_HIGH, + .vl_hsp = CONFIG_SYS_HIGH, + .vl_vsp = CONFIG_SYS_HIGH, + .vl_dp = CONFIG_SYS_HIGH, + .vl_bpix = LCD_BPP, + .vl_lbw = 0, + .vl_splt = 1, + .vl_clor = 1, + .vl_tft = 1, + .vl_hpw = 32, + .vl_blw = 144, + .vl_elw = 32, + .vl_vpw = 2, + .vl_bfw = 13, + .vl_efw = 30, }; #endif /* CONFIG_VOIPAC_LCD */ @@ -156,26 +156,26 @@ vidinfo_t panel_info = { #define REG_LCCR3 0x0340FF20 vidinfo_t panel_info = { - vl_col: 320, - vl_row: 240, - vl_width: 167, - vl_height: 109, - vl_clkp: CONFIG_SYS_HIGH, - vl_oep: CONFIG_SYS_HIGH, - vl_hsp: CONFIG_SYS_HIGH, - vl_vsp: CONFIG_SYS_HIGH, - vl_dp: CONFIG_SYS_HIGH, - vl_bpix: LCD_BPP, - vl_lbw: 1, - vl_splt: 0, - vl_clor: 1, - vl_tft: 0, - vl_hpw: 1, - vl_blw: 1, - vl_elw: 1, - vl_vpw: 7, - vl_bfw: 0, - vl_efw: 0, + .vl_col = 320, + .vl_row = 240, + .vl_width = 167, + .vl_height = 109, + .vl_clkp = CONFIG_SYS_HIGH, + .vl_oep = CONFIG_SYS_HIGH, + .vl_hsp = CONFIG_SYS_HIGH, + .vl_vsp = CONFIG_SYS_HIGH, + .vl_dp = CONFIG_SYS_HIGH, + .vl_bpix = LCD_BPP, + .vl_lbw = 1, + .vl_splt = 0, + .vl_clor = 1, + .vl_tft = 0, + .vl_hpw = 1, + .vl_blw = 1, + .vl_elw = 1, + .vl_vpw = 7, + .vl_bfw = 0, + .vl_efw = 0, }; #endif /* CONFIG_HITACHI_SX14 */ @@ -190,26 +190,26 @@ vidinfo_t panel_info = { # define REG_LCCR3 0x03b00009 vidinfo_t panel_info = { - vl_col: 240, - vl_row: 320, - vl_width: 240, - vl_height: 320, - vl_clkp: CONFIG_SYS_HIGH, - vl_oep: CONFIG_SYS_LOW, - vl_hsp: CONFIG_SYS_LOW, - vl_vsp: CONFIG_SYS_LOW, - vl_dp: CONFIG_SYS_HIGH, - vl_bpix: LCD_BPP, - vl_lbw: 0, - vl_splt: 1, - vl_clor: 1, - vl_tft: 1, - vl_hpw: 4, - vl_blw: 4, - vl_elw: 8, - vl_vpw: 4, - vl_bfw: 4, - vl_efw: 8, + .vl_col = 240, + .vl_row = 320, + .vl_width = 240, + .vl_height = 320, + .vl_clkp = CONFIG_SYS_HIGH, + .vl_oep = CONFIG_SYS_LOW, + .vl_hsp = CONFIG_SYS_LOW, + .vl_vsp = CONFIG_SYS_LOW, + .vl_dp = CONFIG_SYS_HIGH, + .vl_bpix = LCD_BPP, + .vl_lbw = 0, + .vl_splt = 1, + .vl_clor = 1, + .vl_tft = 1, + .vl_hpw = 4, + .vl_blw = 4, + .vl_elw = 8, + .vl_vpw = 4, + .vl_bfw = 4, + .vl_efw = 8, }; #endif /* CONFIG_LMS283GF05 */ -- cgit v1.1 From 3ba8bf7c6d6c09b9823b08b03d2d155907313238 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Thu, 9 Sep 2010 09:50:39 +0200 Subject: PXA: pxa-regs.h cleanup Signed-off-by: Marek Vasut --- arch/arm/cpu/pxa/cpu.c | 28 ++++++++++++-------- arch/arm/cpu/pxa/i2c.c | 69 ++++++++++++++++++++++++++++-------------------- arch/arm/cpu/pxa/pxafb.c | 64 ++++++++++++++++++++++++-------------------- arch/arm/cpu/pxa/timer.c | 7 ++--- arch/arm/cpu/pxa/usb.c | 61 +++++++++++++++++++----------------------- 5 files changed, 123 insertions(+), 106 deletions(-) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/pxa/cpu.c b/arch/arm/cpu/pxa/cpu.c index 800d120..330d013 100644 --- a/arch/arm/cpu/pxa/cpu.c +++ b/arch/arm/cpu/pxa/cpu.c @@ -30,10 +30,11 @@ * CPU specific code */ -#include -#include #include +#include #include +#include +#include static void cache_flush(void); @@ -71,17 +72,22 @@ void set_GPIO_mode(int gpio_mode) { int gpio = gpio_mode & GPIO_MD_MASK_NR; int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8; - int gafr; + int val; + + /* This below changes direction setting of GPIO "gpio" */ + val = readl(GPDR(gpio)); if (gpio_mode & GPIO_MD_MASK_DIR) - { - GPDR(gpio) |= GPIO_bit(gpio); - } + val |= GPIO_bit(gpio); else - { - GPDR(gpio) &= ~GPIO_bit(gpio); - } - gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2)); - GAFR(gpio) = gafr | (fn << (((gpio) & 0xf)*2)); + val &= ~GPIO_bit(gpio); + + writel(val, GPDR(gpio)); + + /* This below updates only AF of GPIO "gpio" */ + val = readl(GAFR(gpio)); + val &= ~(0x3 << (((gpio) & 0xf) * 2)); + val |= fn << (((gpio) & 0xf) * 2); + writel(val, GAFR(gpio)); } #endif /* CONFIG_CPU_MONAHANS */ diff --git a/arch/arm/cpu/pxa/i2c.c b/arch/arm/cpu/pxa/i2c.c index 6b72ba1..7aa49ae 100644 --- a/arch/arm/cpu/pxa/i2c.c +++ b/arch/arm/cpu/pxa/i2c.c @@ -33,6 +33,7 @@ /* FIXME: this file is PXA255 specific! What about other XScales? */ #include +#include #ifdef CONFIG_HARD_I2C @@ -93,19 +94,21 @@ struct i2c_msg { static void i2c_reset( void ) { - ICR &= ~ICR_IUE; /* disable unit */ - ICR |= ICR_UR; /* reset the unit */ + writel(readl(ICR) & ~ICR_IUE, ICR); /* disable unit */ + writel(readl(ICR) | ICR_UR, ICR); /* reset the unit */ udelay(100); - ICR &= ~ICR_IUE; /* disable unit */ + writel(readl(ICR) & ~ICR_IUE, ICR); /* disable unit */ #ifdef CONFIG_CPU_MONAHANS - CKENB |= (CKENB_4_I2C); /* | CKENB_1_PWM1 | CKENB_0_PWM0); */ + /* | CKENB_1_PWM1 | CKENB_0_PWM0); */ + writel(readl(CKENB) | (CKENB_4_I2C), CKENB); #else /* CONFIG_CPU_MONAHANS */ - CKEN |= CKEN14_I2C; /* set the global I2C clock on */ + /* set the global I2C clock on */ + writel(readl(CKEN) | CKEN14_I2C, CKEN); #endif - ISAR = I2C_PXA_SLAVE_ADDR; /* set our slave address */ - ICR = I2C_ICR_INIT; /* set control register values */ - ISR = I2C_ISR_INIT; /* set clear interrupt bits */ - ICR |= ICR_IUE; /* enable unit */ + writel(I2C_PXA_SLAVE_ADDR, ISAR); /* set our slave address */ + writel(I2C_ICR_INIT, ICR); /* set control reg values */ + writel(I2C_ISR_INIT, ISR); /* set clear interrupt bits */ + writel(readl(ICR) | ICR_IUE, ICR); /* enable unit */ udelay(100); } @@ -159,22 +162,26 @@ int i2c_transfer(struct i2c_msg *msg) goto transfer_error_bus_busy; /* start transmission */ - ICR &= ~ICR_START; - ICR &= ~ICR_STOP; - IDBR = msg->data; - if (msg->condition == I2C_COND_START) ICR |= ICR_START; - if (msg->condition == I2C_COND_STOP) ICR |= ICR_STOP; - if (msg->acknack == I2C_ACKNAK_SENDNAK) ICR |= ICR_ACKNAK; - if (msg->acknack == I2C_ACKNAK_SENDACK) ICR &= ~ICR_ACKNAK; - ICR &= ~ICR_ALDIE; - ICR |= ICR_TB; + writel(readl(ICR) & ~ICR_START, ICR); + writel(readl(ICR) & ~ICR_STOP, ICR); + writel(msg->data, IDBR); + if (msg->condition == I2C_COND_START) + writel(readl(ICR) | ICR_START, ICR); + if (msg->condition == I2C_COND_STOP) + writel(readl(ICR) | ICR_STOP, ICR); + if (msg->acknack == I2C_ACKNAK_SENDNAK) + writel(readl(ICR) | ICR_ACKNAK, ICR); + if (msg->acknack == I2C_ACKNAK_SENDACK) + writel(readl(ICR) & ~ICR_ACKNAK, ICR); + writel(readl(ICR) & ~ICR_ALDIE, ICR); + writel(readl(ICR) | ICR_TB, ICR); /* transmit register empty? */ if (!i2c_isr_set_cleared(ISR_ITE,0)) goto transfer_error_transmit_timeout; /* clear 'transmit empty' state */ - ISR |= ISR_ITE; + writel(readl(ISR) | ISR_ITE, ISR); /* wait for ACK from slave */ if (msg->acknack == I2C_ACKNAK_WAITACK) @@ -189,23 +196,27 @@ int i2c_transfer(struct i2c_msg *msg) goto transfer_error_bus_busy; /* start receive */ - ICR &= ~ICR_START; - ICR &= ~ICR_STOP; - if (msg->condition == I2C_COND_START) ICR |= ICR_START; - if (msg->condition == I2C_COND_STOP) ICR |= ICR_STOP; - if (msg->acknack == I2C_ACKNAK_SENDNAK) ICR |= ICR_ACKNAK; - if (msg->acknack == I2C_ACKNAK_SENDACK) ICR &= ~ICR_ACKNAK; - ICR &= ~ICR_ALDIE; - ICR |= ICR_TB; + writel(readl(ICR) & ~ICR_START, ICR); + writel(readl(ICR) & ~ICR_STOP, ICR); + if (msg->condition == I2C_COND_START) + writel(readl(ICR) | ICR_START, ICR); + if (msg->condition == I2C_COND_STOP) + writel(readl(ICR) | ICR_STOP, ICR); + if (msg->acknack == I2C_ACKNAK_SENDNAK) + writel(readl(ICR) | ICR_ACKNAK, ICR); + if (msg->acknack == I2C_ACKNAK_SENDACK) + writel(readl(ICR) & ~ICR_ACKNAK, ICR); + writel(readl(ICR) & ~ICR_ALDIE, ICR); + writel(readl(ICR) | ICR_TB, ICR); /* receive register full? */ if (!i2c_isr_set_cleared(ISR_IRF,0)) goto transfer_error_receive_timeout; - msg->data = IDBR; + msg->data = readl(IDBR); /* clear 'receive empty' state */ - ISR |= ISR_IRF; + writel(readl(ISR) | ISR_IRF, ISR); break; diff --git a/arch/arm/cpu/pxa/pxafb.c b/arch/arm/cpu/pxa/pxafb.c index 50e9cc0..cb004b2 100644 --- a/arch/arm/cpu/pxa/pxafb.c +++ b/arch/arm/cpu/pxa/pxafb.c @@ -35,6 +35,7 @@ #include #include #include +#include /* #define DEBUG */ @@ -377,12 +378,14 @@ static void pxafb_setup_gpio (vidinfo_t *vid) { debug("Setting GPIO for 4 bit data\n"); /* bits 58-61 */ - GPDR1 |= (0xf << 26); - GAFR1_U = (GAFR1_U & ~(0xff << 20)) | (0xaa << 20); + writel(readl(GPDR1) | (0xf << 26), GPDR1); + writel((readl(GAFR1_U) & ~(0xff << 20)) | (0xaa << 20), + GAFR1_U); /* bits 74-77 */ - GPDR2 |= (0xf << 10); - GAFR2_L = (GAFR2_L & ~(0xff << 20)) | (0xaa << 20); + writel(readl(GPDR2) | (0xf << 10), GPDR2); + writel((readl(GAFR2_L) & ~(0xff << 20)) | (0xaa << 20), + GAFR2_L); } /* 8 bit interface */ @@ -391,15 +394,17 @@ static void pxafb_setup_gpio (vidinfo_t *vid) { debug("Setting GPIO for 8 bit data\n"); /* bits 58-65 */ - GPDR1 |= (0x3f << 26); - GPDR2 |= (0x3); + writel(readl(GPDR1) | (0x3f << 26), GPDR1); + writel(readl(GPDR2) | (0x3), GPDR2); - GAFR1_U = (GAFR1_U & ~(0xfff << 20)) | (0xaaa << 20); - GAFR2_L = (GAFR2_L & ~0xf) | (0xa); + writel((readl(GAFR1_U) & ~(0xfff << 20)) | (0xaaa << 20), + GAFR1_U); + writel((readl(GAFR2_L) & ~0xf) | (0xa), GAFR2_L); /* bits 74-77 */ - GPDR2 |= (0xf << 10); - GAFR2_L = (GAFR2_L & ~(0xff << 20)) | (0xaa << 20); + writel(readl(GPDR2) | (0xf << 10), GPDR2); + writel((readl(GAFR2_L) & ~(0xff << 20)) | (0xaa << 20), + GAFR2_L); } /* 16 bit interface */ @@ -407,11 +412,12 @@ static void pxafb_setup_gpio (vidinfo_t *vid) { debug("Setting GPIO for 16 bit data\n"); /* bits 58-77 */ - GPDR1 |= (0x3f << 26); - GPDR2 |= 0x00003fff; + writel(readl(GPDR1) | (0x3f << 26), GPDR1); + writel(readl(GPDR2) | 0x00003fff, GPDR2); - GAFR1_U = (GAFR1_U & ~(0xfff << 20)) | (0xaaa << 20); - GAFR2_L = (GAFR2_L & 0xf0000000) | 0x0aaaaaaa; + writel((readl(GAFR1_U) & ~(0xfff << 20)) | (0xaaa << 20), + GAFR1_U); + writel((readl(GAFR2_L) & 0xf0000000) | 0x0aaaaaaa, GAFR2_L); } else { @@ -425,26 +431,26 @@ static void pxafb_enable_controller (vidinfo_t *vid) debug("Enabling LCD controller\n"); /* Sequence from 11.7.10 */ - LCCR3 = vid->pxa.reg_lccr3; - LCCR2 = vid->pxa.reg_lccr2; - LCCR1 = vid->pxa.reg_lccr1; - LCCR0 = vid->pxa.reg_lccr0 & ~LCCR0_ENB; - FDADR0 = vid->pxa.fdadr0; - FDADR1 = vid->pxa.fdadr1; - LCCR0 |= LCCR0_ENB; + writel(vid->pxa.reg_lccr3, LCCR3); + writel(vid->pxa.reg_lccr2, LCCR2); + writel(vid->pxa.reg_lccr1, LCCR1); + writel(vid->pxa.reg_lccr0 & ~LCCR0_ENB, LCCR0); + writel(vid->pxa.fdadr0, FDADR0); + writel(vid->pxa.fdadr1, FDADR1); + writel(readl(LCCR0) | LCCR0_ENB, LCCR0); #ifdef CONFIG_CPU_MONAHANS - CKENA |= CKENA_1_LCD; + writel(readl(CKENA) | CKENA_1_LCD, CKENA); #else - CKEN |= CKEN16_LCD; + writel(readl(CKEN) | CKEN16_LCD, CKEN); #endif - debug("FDADR0 = 0x%08x\n", (unsigned int)FDADR0); - debug("FDADR1 = 0x%08x\n", (unsigned int)FDADR1); - debug("LCCR0 = 0x%08x\n", (unsigned int)LCCR0); - debug("LCCR1 = 0x%08x\n", (unsigned int)LCCR1); - debug("LCCR2 = 0x%08x\n", (unsigned int)LCCR2); - debug("LCCR3 = 0x%08x\n", (unsigned int)LCCR3); + debug("FDADR0 = 0x%08x\n", readl(FDADR0)); + debug("FDADR1 = 0x%08x\n", readl(FDADR1)); + debug("LCCR0 = 0x%08x\n", readl(LCCR0)); + debug("LCCR1 = 0x%08x\n", readl(LCCR1)); + debug("LCCR2 = 0x%08x\n", readl(LCCR2)); + debug("LCCR3 = 0x%08x\n", readl(LCCR3)); } static int pxafb_init (vidinfo_t *vid) diff --git a/arch/arm/cpu/pxa/timer.c b/arch/arm/cpu/pxa/timer.c index 8d0f826..ec950c7 100644 --- a/arch/arm/cpu/pxa/timer.c +++ b/arch/arm/cpu/pxa/timer.c @@ -26,8 +26,9 @@ * MA 02111-1307 USA */ -#include #include +#include +#include #include #ifdef CONFIG_USE_IRQ @@ -86,7 +87,7 @@ void __udelay (unsigned long usec) void reset_timer_masked (void) { - OSCR = 0; + writel(0, OSCR); } ulong get_timer_masked (void) @@ -113,7 +114,7 @@ void udelay_masked (unsigned long usec) */ unsigned long long get_ticks(void) { - return OSCR; + return readl(OSCR); } /* diff --git a/arch/arm/cpu/pxa/usb.c b/arch/arm/cpu/pxa/usb.c index bd718a6..0311d5e 100644 --- a/arch/arm/cpu/pxa/usb.c +++ b/arch/arm/cpu/pxa/usb.c @@ -27,86 +27,79 @@ # if defined(CONFIG_CPU_MONAHANS) || defined(CONFIG_PXA27X) #include +#include #include int usb_cpu_init(void) { #if defined(CONFIG_CPU_MONAHANS) /* Enable USB host clock. */ - CKENA |= (CKENA_2_USBHOST | CKENA_20_UDC); + writel(readl(CKENA) | CKENA_2_USBHOST | CKENA_20_UDC, CKENA); udelay(100); #endif #if defined(CONFIG_PXA27X) /* Enable USB host clock. */ - CKEN |= CKEN10_USBHOST; + writel(readl(CKEN) | CKEN10_USBHOST, CKEN); #endif #if defined(CONFIG_CPU_MONAHANS) /* Configure Port 2 for Host (USB Client Registers) */ - UP2OCR = 0x3000c; + writel(0x3000c, UP2OCR); #endif - UHCHR |= UHCHR_FHR; + writel(readl(UHCHR) | UHCHR_FHR, UHCHR); wait_ms(11); - UHCHR &= ~UHCHR_FHR; + writel(readl(UHCHR) & ~UHCHR_FHR, UHCHR); - UHCHR |= UHCHR_FSBIR; - while (UHCHR & UHCHR_FSBIR) + writel(readl(UHCHR) | UHCHR_FSBIR, UHCHR); + while (readl(UHCHR) & UHCHR_FSBIR) udelay(1); #if defined(CONFIG_CPU_MONAHANS) - UHCHR &= ~UHCHR_SSEP0; + writel(readl(UHCHR) & ~UHCHR_SSEP0, UHCHR); #endif #if defined(CONFIG_PXA27X) - UHCHR &= ~UHCHR_SSEP2; + writel(readl(UHCHR) & ~UHCHR_SSEP2, UHCHR); #endif - UHCHR &= ~UHCHR_SSEP1; - UHCHR &= ~UHCHR_SSE; + writel(readl(UHCHR) & ~(UHCHR_SSEP1 | UHCHR_SSE), UHCHR); return 0; } int usb_cpu_stop(void) { - UHCHR |= UHCHR_FHR; + writel(readl(UHCHR) | UHCHR_FHR, UHCHR); udelay(11); - UHCHR &= ~UHCHR_FHR; + writel(readl(UHCHR) & ~UHCHR_FHR, UHCHR); - UHCCOMS |= 1; + writel(readl(UHCCOMS) | UHCHR_FHR, UHCCOMS); udelay(10); #if defined(CONFIG_CPU_MONAHANS) - UHCHR |= UHCHR_SSEP0; + writel(readl(UHCHR) | UHCHR_SSEP0, UHCHR); #endif #if defined(CONFIG_PXA27X) - UHCHR |= UHCHR_SSEP2; + writel(readl(UHCHR) | UHCHR_SSEP2, UHCHR); #endif - UHCHR |= UHCHR_SSEP1; - UHCHR |= UHCHR_SSE; - - return 0; -} - -int usb_cpu_init_fail(void) -{ - UHCHR |= UHCHR_FHR; - udelay(11); - UHCHR &= ~UHCHR_FHR; - - UHCCOMS |= 1; - udelay(10); + writel(readl(UHCHR) | UHCHR_SSEP1 | UHCHR_SSE, UHCHR); #if defined(CONFIG_CPU_MONAHANS) - UHCHR |= UHCHR_SSEP0; + /* Disable USB host clock. */ + writel(readl(CKENA) & ~(CKENA_2_USBHOST | CKENA_20_UDC), CKENA); + udelay(100); #endif #if defined(CONFIG_PXA27X) - UHCHR |= UHCHR_SSEP2; + /* Disable USB host clock. */ + writel(readl(CKEN) & ~CKEN10_USBHOST, CKEN); #endif - UHCHR |= UHCHR_SSEP1; - UHCHR |= UHCHR_SSE; return 0; } +int usb_cpu_init_fail(void) +{ + return usb_cpu_stop(); +} + # endif /* defined(CONFIG_CPU_MONAHANS) || defined(CONFIG_PXA27X) */ #endif /* defined(CONFIG_USB_OHCI) && defined(CONFIG_SYS_USB_OHCI_CPU_INIT) */ -- cgit v1.1 From f7d58d91666b6fda054a561d7041765393afabc0 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 18 Jul 2010 04:46:55 +0200 Subject: PXA: pxafb: Add ACX517AKN support ACX517AKN LCD panel is found in Palm Tungsten|C Signed-off-by: Marek Vasut --- arch/arm/cpu/pxa/pxafb.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/pxa/pxafb.c b/arch/arm/cpu/pxa/pxafb.c index cb004b2..d698395 100644 --- a/arch/arm/cpu/pxa/pxafb.c +++ b/arch/arm/cpu/pxa/pxafb.c @@ -216,6 +216,40 @@ vidinfo_t panel_info = { /*----------------------------------------------------------------------*/ +#ifdef CONFIG_ACX517AKN + +# define LCD_BPP LCD_COLOR8 + +/* you have to set lccr0 and lccr3 (including pcd) */ +# define REG_LCCR0 0x003008f9 +# define REG_LCCR3 0x03700006 + +vidinfo_t panel_info = { + .vl_col = 320, + .vl_row = 320, + .vl_width = 320, + .vl_height = 320, + .vl_clkp = CONFIG_SYS_HIGH, + .vl_oep = CONFIG_SYS_LOW, + .vl_hsp = CONFIG_SYS_LOW, + .vl_vsp = CONFIG_SYS_LOW, + .vl_dp = CONFIG_SYS_HIGH, + .vl_bpix = LCD_BPP, + .vl_lbw = 0, + .vl_splt = 1, + .vl_clor = 1, + .vl_tft = 1, + .vl_hpw = 0x04, + .vl_blw = 0x1c, + .vl_elw = 0x08, + .vl_vpw = 0x01, + .vl_bfw = 0x07, + .vl_efw = 0x08, +}; +#endif /* CONFIG_ACX517AKN */ + +/*----------------------------------------------------------------------*/ + #if LCD_BPP == LCD_COLOR8 void lcd_setcolreg (ushort regno, ushort red, ushort green, ushort blue); #endif -- cgit v1.1 From 42222be43cb85bc8fdcb40dc648c8adff6486c0e Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 19 Jul 2010 11:21:38 +0200 Subject: PXA: pxafb: Add support for Sharp LQ038J7DH53 This LCD panel is found in Palm LifeDrive handheld Signed-off-by: Marek Vasut --- arch/arm/cpu/pxa/pxafb.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/pxa/pxafb.c b/arch/arm/cpu/pxa/pxafb.c index d698395..2f0f707 100644 --- a/arch/arm/cpu/pxa/pxafb.c +++ b/arch/arm/cpu/pxa/pxafb.c @@ -250,6 +250,40 @@ vidinfo_t panel_info = { /*----------------------------------------------------------------------*/ +#ifdef CONFIG_LQ038J7DH53 + +# define LCD_BPP LCD_COLOR8 + +/* you have to set lccr0 and lccr3 (including pcd) */ +# define REG_LCCR0 0x003008f9 +# define REG_LCCR3 0x03700004 + +vidinfo_t panel_info = { + .vl_col = 320, + .vl_row = 480, + .vl_width = 320, + .vl_height = 480, + .vl_clkp = CONFIG_SYS_HIGH, + .vl_oep = CONFIG_SYS_LOW, + .vl_hsp = CONFIG_SYS_LOW, + .vl_vsp = CONFIG_SYS_LOW, + .vl_dp = CONFIG_SYS_HIGH, + .vl_bpix = LCD_BPP, + .vl_lbw = 0, + .vl_splt = 1, + .vl_clor = 1, + .vl_tft = 1, + .vl_hpw = 0x04, + .vl_blw = 0x20, + .vl_elw = 0x01, + .vl_vpw = 0x01, + .vl_bfw = 0x04, + .vl_efw = 0x01, +}; +#endif /* CONFIG_ACX517AKN */ + +/*----------------------------------------------------------------------*/ + #if LCD_BPP == LCD_COLOR8 void lcd_setcolreg (ushort regno, ushort red, ushort green, ushort blue); #endif -- cgit v1.1 From 8b71d2b710684f94a9956f69b7587ba49f8b2281 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Thu, 31 Dec 2009 03:44:22 +0100 Subject: PXA: pxafb: Marvell Littleton LCD definition Signed-off-by: Marek Vasut --- arch/arm/cpu/pxa/pxafb.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/pxa/pxafb.c b/arch/arm/cpu/pxa/pxafb.c index 2f0f707..987fa06 100644 --- a/arch/arm/cpu/pxa/pxafb.c +++ b/arch/arm/cpu/pxa/pxafb.c @@ -284,6 +284,39 @@ vidinfo_t panel_info = { /*----------------------------------------------------------------------*/ +#ifdef CONFIG_LITTLETON_LCD +# define LCD_BPP LCD_COLOR8 + +/* you have to set lccr0 and lccr3 (including pcd) */ +# define REG_LCCR0 0x003008f8 +# define REG_LCCR3 0x0300FF04 + +vidinfo_t panel_info = { + .vl_col = 480, + .vl_row = 640, + .vl_width = 480, + .vl_height = 640, + .vl_clkp = CONFIG_SYS_HIGH, + .vl_oep = CONFIG_SYS_HIGH, + .vl_hsp = CONFIG_SYS_HIGH, + .vl_vsp = CONFIG_SYS_HIGH, + .vl_dp = CONFIG_SYS_HIGH, + .vl_bpix = LCD_BPP, + .vl_lbw = 0, + .vl_splt = 0, + .vl_clor = 0, + .vl_tft = 1, + .vl_hpw = 9, + .vl_blw = 8, + .vl_elw = 24, + .vl_vpw = 2, + .vl_bfw = 2, + .vl_efw = 4, +}; +#endif /* CONFIG_LITTLETON_LCD */ + +/*----------------------------------------------------------------------*/ + #if LCD_BPP == LCD_COLOR8 void lcd_setcolreg (ushort regno, ushort red, ushort green, ushort blue); #endif -- cgit v1.1 From 2cad92fd674d035a04631b9ab044c030f95e0fec Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 28 Sep 2010 15:44:10 +0200 Subject: PXA: Fix reloc, Push lowlevel init into C code Firstly, this fixes relocation issues. I had to use part of Dcache as RAM for a while. I also moved around the lowlevel init code. It turned out so most of the lowlevel init code ended in cpu.c (and eventually was rewritten into C). This will also allow easier operation with FDT, multi-CPU-model support etc. in later releases. NOTE: This breaks most of the PXA boards (actually, the reloc stuff did already, this only finishes the doom). Signed-off-by: Marek Vasut --- arch/arm/cpu/pxa/cpu.c | 229 ++++++++++++++++++++++++++++++- arch/arm/cpu/pxa/start.S | 344 ++++++++++++++++++----------------------------- 2 files changed, 359 insertions(+), 214 deletions(-) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/pxa/cpu.c b/arch/arm/cpu/pxa/cpu.c index 330d013..3ea3458 100644 --- a/arch/arm/cpu/pxa/cpu.c +++ b/arch/arm/cpu/pxa/cpu.c @@ -30,11 +30,11 @@ * CPU specific code */ -#include #include #include #include #include +#include static void cache_flush(void); @@ -91,3 +91,230 @@ void set_GPIO_mode(int gpio_mode) writel(val, GAFR(gpio)); } #endif /* CONFIG_CPU_MONAHANS */ + +void pxa_wait_ticks(int ticks) +{ + writel(0, OSCR); + while (readl(OSCR) < ticks) + asm volatile("":::"memory"); +} + +inline void writelrb(uint32_t val, uint32_t addr) +{ + writel(val, addr); + asm volatile("":::"memory"); + readl(addr); + asm volatile("":::"memory"); +} + +void pxa_dram_init(void) +{ + uint32_t tmp; + int i; + /* + * 1) Initialize Asynchronous static memory controller + */ + + writelrb(CONFIG_SYS_MSC0_VAL, MSC0); + writelrb(CONFIG_SYS_MSC1_VAL, MSC1); + writelrb(CONFIG_SYS_MSC2_VAL, MSC2); + /* + * 2) Initialize Card Interface + */ + + /* MECR: Memory Expansion Card Register */ + writelrb(CONFIG_SYS_MECR_VAL, MECR); + /* MCMEM0: Card Interface slot 0 timing */ + writelrb(CONFIG_SYS_MCMEM0_VAL, MCMEM0); + /* MCMEM1: Card Interface slot 1 timing */ + writelrb(CONFIG_SYS_MCMEM1_VAL, MCMEM1); + /* MCATT0: Card Interface Attribute Space Timing, slot 0 */ + writelrb(CONFIG_SYS_MCATT0_VAL, MCATT0); + /* MCATT1: Card Interface Attribute Space Timing, slot 1 */ + writelrb(CONFIG_SYS_MCATT1_VAL, MCATT1); + /* MCIO0: Card Interface I/O Space Timing, slot 0 */ + writelrb(CONFIG_SYS_MCIO0_VAL, MCIO0); + /* MCIO1: Card Interface I/O Space Timing, slot 1 */ + writelrb(CONFIG_SYS_MCIO1_VAL, MCIO1); + + /* + * 3) Configure Fly-By DMA register + */ + + writelrb(CONFIG_SYS_FLYCNFG_VAL, FLYCNFG); + + /* + * 4) Initialize Timing for Sync Memory (SDCLK0) + */ + + /* + * Before accessing MDREFR we need a valid DRI field, so we set + * this to power on defaults + DRI field. + */ + + /* Read current MDREFR config and zero out DRI */ + tmp = readl(MDREFR) & ~0xfff; + /* Add user-specified DRI */ + tmp |= CONFIG_SYS_MDREFR_VAL & 0xfff; + /* Configure important bits */ + tmp |= MDREFR_K0RUN | MDREFR_SLFRSH; + tmp &= ~(MDREFR_APD | MDREFR_E1PIN); + + /* Write MDREFR back */ + writelrb(tmp, MDREFR); + + /* + * 5) Initialize Synchronous Static Memory (Flash/Peripherals) + */ + + /* Initialize SXCNFG register. Assert the enable bits. + * + * Write SXMRS to cause an MRS command to all enabled banks of + * synchronous static memory. Note that SXLCR need not be written + * at this time. + */ + writelrb(CONFIG_SYS_SXCNFG_VAL, SXCNFG); + + /* + * 6) Initialize SDRAM + */ + + writelrb(CONFIG_SYS_MDREFR_VAL & ~MDREFR_SLFRSH, MDREFR); + writelrb(CONFIG_SYS_MDREFR_VAL | MDREFR_E1PIN, MDREFR); + + /* + * 7) Write MDCNFG with MDCNFG:DEx deasserted (set to 0), to configure + * but not enable each SDRAM partition pair. + */ + + writelrb(CONFIG_SYS_MDCNFG_VAL & + ~(MDCNFG_DE0 | MDCNFG_DE1 | MDCNFG_DE2 | MDCNFG_DE3), MDCNFG); + /* Wait for the clock to the SDRAMs to stabilize, 100..200 usec. */ + pxa_wait_ticks(0x300); + + /* + * 8) Trigger a number (usually 8) refresh cycles by attempting + * non-burst read or write accesses to disabled SDRAM, as commonly + * specified in the power up sequence documented in SDRAM data + * sheets. The address(es) used for this purpose must not be + * cacheable. + */ + for (i = 9; i >= 0; i--) { + writel(i, 0xa0000000); + asm volatile("":::"memory"); + } + /* + * 9) Write MDCNFG with enable bits asserted (MDCNFG:DEx set to 1). + */ + + tmp = CONFIG_SYS_MDCNFG_VAL & + (MDCNFG_DE0 | MDCNFG_DE1 | MDCNFG_DE2 | MDCNFG_DE3); + tmp |= readl(MDCNFG); + writelrb(tmp, MDCNFG); + + /* + * 10) Write MDMRS. + */ + + writelrb(CONFIG_SYS_MDMRS_VAL, MDMRS); + + /* + * 11) Enable APD + */ + + if (CONFIG_SYS_MDREFR_VAL & MDREFR_APD) { + tmp = readl(MDREFR); + tmp |= MDREFR_APD; + writelrb(tmp, MDREFR); + } +} + +void pxa_gpio_setup(void) +{ + writel(CONFIG_SYS_GPSR0_VAL, GPSR0); + writel(CONFIG_SYS_GPSR1_VAL, GPSR1); + writel(CONFIG_SYS_GPSR2_VAL, GPSR2); +#if defined(CONFIG_PXA27X) || defined(CONFIG_CPU_MONAHANS) + writel(CONFIG_SYS_GPSR3_VAL, GPSR3); +#endif + + writel(CONFIG_SYS_GPCR0_VAL, GPCR0); + writel(CONFIG_SYS_GPCR1_VAL, GPCR1); + writel(CONFIG_SYS_GPCR2_VAL, GPCR2); +#if defined(CONFIG_PXA27X) || defined(CONFIG_CPU_MONAHANS) + writel(CONFIG_SYS_GPCR3_VAL, GPCR3); +#endif + + writel(CONFIG_SYS_GPDR0_VAL, GPDR0); + writel(CONFIG_SYS_GPDR1_VAL, GPDR1); + writel(CONFIG_SYS_GPDR2_VAL, GPDR2); +#if defined(CONFIG_PXA27X) || defined(CONFIG_CPU_MONAHANS) + writel(CONFIG_SYS_GPDR3_VAL, GPDR3); +#endif + + writel(CONFIG_SYS_GAFR0_L_VAL, GAFR0_L); + writel(CONFIG_SYS_GAFR0_U_VAL, GAFR0_U); + writel(CONFIG_SYS_GAFR1_L_VAL, GAFR1_L); + writel(CONFIG_SYS_GAFR1_U_VAL, GAFR1_U); + writel(CONFIG_SYS_GAFR2_L_VAL, GAFR2_L); + writel(CONFIG_SYS_GAFR2_U_VAL, GAFR2_U); +#if defined(CONFIG_PXA27X) || defined(CONFIG_CPU_MONAHANS) + writel(CONFIG_SYS_GAFR3_L_VAL, GAFR3_L); + writel(CONFIG_SYS_GAFR3_U_VAL, GAFR3_U); +#endif + + writel(CONFIG_SYS_PSSR_VAL, PSSR); +} + +void pxa_interrupt_setup(void) +{ + writel(0, ICLR); + writel(0, ICMR); +#if defined(CONFIG_PXA27X) || defined(CONFIG_CPU_MONAHANS) + writel(0, ICLR2); + writel(0, ICMR2); +#endif +} + +void pxa_clock_setup(void) +{ +#ifndef CONFIG_CPU_MONAHANS + writel(CONFIG_SYS_CKEN, CKEN); + writel(CONFIG_SYS_CCCR, CCCR); + asm volatile("mcr p14, 0, %0, c6, c0, 0"::"r"(2)); +#else +/* Set CKENA/CKENB/ACCR for MH */ +#endif + + /* enable the 32Khz oscillator for RTC and PowerManager */ + writel(OSCC_OON, OSCC); + while(!(readl(OSCC) & OSCC_OOK)) + asm volatile("":::"memory"); +} + +void pxa_wakeup(void) +{ + uint32_t rcsr; + + rcsr = readl(RCSR); + writel(rcsr & (RCSR_GPR | RCSR_SMR | RCSR_WDR | RCSR_HWR), RCSR); + + /* Wakeup */ + if (rcsr & RCSR_SMR) { + writel(PSSR_PH, PSSR); + pxa_dram_init(); + icache_disable(); + dcache_disable(); + asm volatile("mov pc, %0"::"r"(readl(PSSR))); + } +} + +int arch_cpu_init(void) +{ + pxa_gpio_setup(); +// pxa_wait_ticks(0x8000); + pxa_wakeup(); + pxa_interrupt_setup(); + pxa_clock_setup(); + return 0; +} diff --git a/arch/arm/cpu/pxa/start.S b/arch/arm/cpu/pxa/start.S index 9c5023b..684e44e 100644 --- a/arch/arm/cpu/pxa/start.S +++ b/arch/arm/cpu/pxa/start.S @@ -31,6 +31,14 @@ #include #include #include +#include + +/* takes care the CP15 update has taken place */ +.macro CPWAIT reg +mrc p15,0,\reg,c2,c0,0 +mov \reg,\reg +sub pc,pc,#4 +.endm .globl _start _start: b reset @@ -86,11 +94,9 @@ _fiq: .word fiq _TEXT_BASE: .word CONFIG_SYS_TEXT_BASE -#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) .globl _armboot_start _armboot_start: .word _start -#endif /* * These are defined in the board-specific linker script. @@ -115,7 +121,7 @@ FIQ_STACK_START: .word 0x0badc0de #endif /* CONFIG_USE_IRQ */ -#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) +#ifndef CONFIG_PRELOADER /* IRQ stack memory (calculated at run-time) + 8 bytes */ .globl IRQ_STACK_START_IN IRQ_STACK_START_IN: @@ -159,12 +165,84 @@ reset: msr cpsr,r0 /* - * we do sys-critical inits only at reboot, - * not when booting from ram! + * Enable MMU to use DCache as DRAM */ -#ifndef CONFIG_SKIP_LOWLEVEL_INIT - bl cpu_init_crit -#endif + /* Domain access -- enable for all CPs */ + ldr r0, =0x0000ffff + mcr p15, 0, r0, c3, c0, 0 + + /* Point TTBR to MMU table */ + ldr r0, =mmu_table + adr r2, _start + orr r0, r2 + mcr p15, 0, r0, c2, c0, 0 + +/* !!! Hereby, check if the code is running from SRAM !!! */ +/* If the code is running from SRAM, alias SRAM to 0x0 to simulate NOR. The code + * is linked to 0x0 too, so this makes things easier. */ + cmp r2, #0x5c000000 + + ldreq r1, [r0] + orreq r1, r2 + streq r1, [r0] + + /* Kick in MMU, ICache, DCache, BTB */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, #0x1b00 + bic r0, #0x0087 + orr r0, #0x1800 + orr r0, #0x0005 + mcr p15, 0, r0, c1, c0, 0 + CPWAIT r0 + + /* Unlock Icache, Dcache */ + mcr p15, 0, r0, c9, c1, 1 + mcr p15, 0, r0, c9, c2, 1 + + /* Flush Icache, Dcache, BTB */ + mcr p15, 0, r0, c7, c7, 0 + + /* Unlock I-TLB, D-TLB */ + mcr p15, 0, r0, c10, c4, 1 + mcr p15, 0, r0, c10, c8, 1 + + /* Flush TLB */ + mcr p15, 0, r0, c8, c7, 0 + /* Allocate 4096 bytes of Dcache as RAM */ + + /* Drain pending loads and stores */ + mcr p15, 0, r0, c7, c10, 4 + + mov r4, #0x00 + mov r5, #0x00 + mov r2, #0x01 + mcr p15, 0, r0, c9, c2, 0 + CPWAIT r0 + + /* 128 lines reserved (128 x 32bytes = 4096 bytes total) */ + mov r0, #128 + mov r1, #0xa0000000 +alloc: + mcr p15, 0, r1, c7, c2, 5 + /* Drain pending loads and stores */ + mcr p15, 0, r0, c7, c10, 4 + strd r4, [r1], #8 + strd r4, [r1], #8 + strd r4, [r1], #8 + strd r4, [r1], #8 + subs r0, #0x01 + bne alloc + /* Drain pending loads and stores */ + mcr p15, 0, r0, c7, c10, 4 + mov r2, #0x00 + mcr p15, 0, r2, c9, c2, 0 + CPWAIT r0 + + /* Jump to 0x0 ( + offset) if running from SRAM */ + adr r0, zerojmp + bic r0, #0x5c000000 + mov pc, r0 +zerojmp: /* Set stackpointer in internal RAM to call board_init_f */ call_board_init_f: @@ -201,11 +279,13 @@ stack_setup: beq clear_bss #ifndef CONFIG_SKIP_RELOCATE_UBOOT + stmfd sp!, {r0-r12} copy_loop: - ldmia r0!, {r9-r10} /* copy from source address [r0] */ - stmia r6!, {r9-r10} /* copy to target address [r1] */ + ldmia r0!, {r3-r5, r7-r11} /* copy from source address [r0] */ + stmia r6!, {r3-r5, r7-r11} /* copy to target address [r1] */ cmp r0, r2 /* until source end address [r2] */ blo copy_loop + ldmfd sp!, {r0-r12} #ifndef CONFIG_PRELOADER /* fix got entries */ @@ -274,218 +354,28 @@ _board_init_r: .word board_init_r /****************************************************************************/ /* */ -/* the actual reset code */ +/* the actual reset code for OneNAND IPL */ /* */ /****************************************************************************/ +#ifndef CONFIG_PXA27X +#error OneNAND IPL is not supported on PXA25x and 26x due to lack of SRAM +#endif + reset: - mrs r0,cpsr /* set the CPU to SVC32 mode */ - bic r0,r0,#0x1f /* (superviser mode, M=10011) */ + /* Set CPU to SVC32 mode */ + mrs r0,cpsr + bic r0,r0,#0x1f orr r0,r0,#0x13 msr cpsr,r0 - /* - * we do sys-critical inits only at reboot, - * not when booting from RAM! - */ -#ifndef CONFIG_SKIP_LOWLEVEL_INIT - bl cpu_init_crit /* we do sys-critical inits */ -#endif /* !CONFIG_SKIP_LOWLEVEL_INIT */ - -#ifndef CONFIG_SKIP_RELOCATE_UBOOT -relocate: /* relocate U-Boot to RAM */ - adr r0, _start /* r0 <- current position of code */ - ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ -#ifndef CONFIG_PRELOADER - cmp r0, r1 /* don't reloc during debug */ - beq stack_setup -#endif - - ldr r2, _armboot_start - ldr r3, _bss_start - sub r2, r3, r2 /* r2 <- size of armboot */ - add r2, r0, r2 /* r2 <- source end address */ - -copy_loop: - ldmia r0!, {r3-r10} /* copy from source address [r0] */ - stmia r1!, {r3-r10} /* copy to target address [r1] */ - cmp r0, r2 /* until source end address [r2] */ - blo copy_loop -#endif /* !CONFIG_SKIP_RELOCATE_UBOOT */ + /* Point stack at the end of SRAM and leave 32 words for abort-stack */ + ldr sp, =0x5c03ff80 - /* Set up the stack */ -stack_setup: - ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ -#ifdef CONFIG_PRELOADER - sub sp, r0, #128 /* leave 32 words for abort-stack */ -#else - sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */ - sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */ -#ifdef CONFIG_USE_IRQ - sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) -#endif /* CONFIG_USE_IRQ */ - sub sp, r0, #12 /* leave 3 words for abort-stack */ - bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ -#endif + /* Start OneNAND IPL */ + ldr pc, =start_oneboot -clear_bss: - ldr r0, _bss_start /* find start of bss segment */ - ldr r1, _bss_end /* stop here */ - mov r2, #0x00000000 /* clear */ - -#ifndef CONFIG_PRELOADER -clbss_l:str r2, [r0] /* clear loop... */ - add r0, r0, #4 - cmp r0, r1 - blo clbss_l -#endif - - ldr pc, _start_armboot - -#ifdef CONFIG_ONENAND_IPL -_start_armboot: .word start_oneboot -#else -_start_armboot: .word start_armboot -#endif -#endif /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */ - -/****************************************************************************/ -/* */ -/* CPU_init_critical registers */ -/* */ -/* - setup important registers */ -/* - setup memory timing */ -/* */ -/****************************************************************************/ -/* mk@tbd: Fix this! */ -#undef RCSR -#undef ICMR -#undef OSMR3 -#undef OSCR -#undef OWER -#undef OIER -#undef CCCR - -/* Interrupt-Controller base address */ -IC_BASE: .word 0x40d00000 -#define ICMR 0x04 - -/* Reset-Controller */ -RST_BASE: .word 0x40f00030 -#define RCSR 0x00 - -/* Operating System Timer */ -OSTIMER_BASE: .word 0x40a00000 -#define OSMR3 0x0C -#define OSCR 0x10 -#define OWER 0x18 -#define OIER 0x1C - -/* Clock Manager Registers */ -#ifdef CONFIG_CPU_MONAHANS -# ifndef CONFIG_SYS_MONAHANS_RUN_MODE_OSC_RATIO -# error "You have to define CONFIG_SYS_MONAHANS_RUN_MODE_OSC_RATIO!!" -# endif /* !CONFIG_SYS_MONAHANS_RUN_MODE_OSC_RATIO */ -# ifndef CONFIG_SYS_MONAHANS_TURBO_RUN_MODE_RATIO -# define CONFIG_SYS_MONAHANS_TURBO_RUN_MODE_RATIO 0x1 -# endif /* !CONFIG_SYS_MONAHANS_TURBO_RUN_MODE_RATIO */ -#else /* !CONFIG_CPU_MONAHANS */ -#ifdef CONFIG_SYS_CPUSPEED -CC_BASE: .word 0x41300000 -#define CCCR 0x00 -cpuspeed: .word CONFIG_SYS_CPUSPEED -#else /* !CONFIG_SYS_CPUSPEED */ -#error "You have to define CONFIG_SYS_CPUSPEED!!" -#endif /* CONFIG_SYS_CPUSPEED */ -#endif /* CONFIG_CPU_MONAHANS */ - - /* takes care the CP15 update has taken place */ - .macro CPWAIT reg - mrc p15,0,\reg,c2,c0,0 - mov \reg,\reg - sub pc,pc,#4 - .endm - -cpu_init_crit: - - /* mask all IRQs */ -#ifndef CONFIG_CPU_MONAHANS - ldr r0, IC_BASE - mov r1, #0x00 - str r1, [r0, #ICMR] -#else /* CONFIG_CPU_MONAHANS */ - /* Step 1 - Enable CP6 permission */ - mrc p15, 0, r1, c15, c1, 0 @ read CPAR - orr r1, r1, #0x40 - mcr p15, 0, r1, c15, c1, 0 - CPWAIT r1 - - /* Step 2 - Mask ICMR & ICMR2 */ - mov r1, #0 - mcr p6, 0, r1, c1, c0, 0 @ ICMR - mcr p6, 0, r1, c7, c0, 0 @ ICMR2 - - /* turn off all clocks but the ones we will definitly require */ - ldr r1, =CKENA - ldr r2, =(CKENA_22_FFUART | CKENA_10_SRAM | CKENA_9_SMC | CKENA_8_DMC) - str r2, [r1] - ldr r1, =CKENB - ldr r2, =(CKENB_6_IRQ) - str r2, [r1] -#endif /* !CONFIG_CPU_MONAHANS */ - - /* set clock speed */ -#ifdef CONFIG_CPU_MONAHANS - ldr r0, =ACCR - ldr r1, =(((CONFIG_SYS_MONAHANS_TURBO_RUN_MODE_RATIO<<8) & ACCR_XN_MASK) | (CONFIG_SYS_MONAHANS_RUN_MODE_OSC_RATIO & ACCR_XL_MASK)) - str r1, [r0] -#else /* !CONFIG_CPU_MONAHANS */ -#ifdef CONFIG_SYS_CPUSPEED - ldr r0, CC_BASE - ldr r1, cpuspeed - str r1, [r0, #CCCR] - mov r0, #2 - mcr p14, 0, r0, c6, c0, 0 - -setspeed_done: - -#endif /* CONFIG_SYS_CPUSPEED */ -#endif /* CONFIG_CPU_MONAHANS */ - - /* - * before relocating, we have to setup RAM timing - * because memory timing is board-dependend, you will - * find a lowlevel_init.S in your board directory. - */ - mov ip, lr - bl lowlevel_init - mov lr, ip - - /* Memory interfaces are working. Disable MMU and enable I-cache. */ - /* mk: hmm, this is not in the monahans docs, leave it now but - * check here if it doesn't work :-) */ - - ldr r0, =0x2001 /* enable access to all coproc. */ - mcr p15, 0, r0, c15, c1, 0 - CPWAIT r0 - - mcr p15, 0, r0, c7, c10, 4 /* drain the write & fill buffers */ - CPWAIT r0 - - mcr p15, 0, r0, c7, c7, 0 /* flush Icache, Dcache and BTB */ - CPWAIT r0 - - mcr p15, 0, r0, c8, c7, 0 /* flush instuction and data TLBs */ - CPWAIT r0 - - /* Enable the Icache */ -/* - mrc p15, 0, r0, c1, c0, 0 - orr r0, r0, #0x1800 - mcr p15, 0, r0, c1, c0, 0 - CPWAIT -*/ - mov pc, lr +#endif /* #if !defined(CONFIG_ONENAND_IPL) */ #ifndef CONFIG_PRELOADER /****************************************************************************/ @@ -676,6 +566,12 @@ fiq: /* perform a watchdog timeout for a soft reset. */ /* */ /****************************************************************************/ +/* Operating System Timer */ +OSTIMER_BASE: .word 0x40a00000 +#define OSMR3 0x0C +#define OSCR 0x10 +#define OWER 0x18 +#define OIER 0x1C .align 5 .globl reset_cpu @@ -703,3 +599,25 @@ reset_cpu: reset_endless: b reset_endless + +#ifndef CONFIG_PRELOADER +.section .mmudata, "a" + .align 14 + .globl mmu_table +mmu_table: + /* 0x00000000 - 0xa0000000 : 1:1, uncached mapping */ + .set __base, 0 + .rept 0xa00 + .word (__base << 20) | 0xc12 + .set __base, __base + 1 + .endr + + /* 0xa0000000 - 0xa0100000 : 1:1, cached mapping */ + .word (0xa00 << 20) | 0x1c1e + + .set __base, 0xa01 + .rept 0x1000 - 0xa01 + .word (__base << 20) | 0xc12 + .set __base, __base + 1 + .endr +#endif -- cgit v1.1 From d078b7c2ec8624e084e1493304816949ff382bda Mon Sep 17 00:00:00 2001 From: Stefano Babic Date: Tue, 19 Oct 2010 20:19:13 +0200 Subject: MX31: Removed warnings for iomux function Removed warnings generated in the mx31_set_pad() function. Signed-off-by: Stefano Babic --- arch/arm/cpu/arm1136/mx31/generic.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/arm1136/mx31/generic.c b/arch/arm/cpu/arm1136/mx31/generic.c index cbe8243..8bd23ee 100644 --- a/arch/arm/cpu/arm1136/mx31/generic.c +++ b/arch/arm/cpu/arm1136/mx31/generic.c @@ -93,17 +93,16 @@ void mx31_gpio_mux(unsigned long mode) void mx31_set_pad(enum iomux_pins pin, u32 config) { - u32 field, l; - void *reg; + u32 field, l, reg; pin &= IOMUX_PADNUM_MASK; reg = (IOMUXC_BASE + 0x154) + (pin + 2) / 3 * 4; field = (pin + 2) % 3; - l = __raw_readl(reg); + l = __REG(reg); l &= ~(0x1ff << (field * 10)); l |= config << (field * 10); - __raw_writel(l, reg); + __REG(reg) = l; } -- cgit v1.1