Jesper Nilsson | f12bb5c | 2008-01-21 11:10:54 +0100 | [diff] [blame] | 1 | /* |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2 | * DRAM/SDRAM initialization - alter with care |
| 3 | * This file is intended to be included from other assembler files |
| 4 | * |
| 5 | * Note: This file may not modify r9 because r9 is used to carry |
| 6 | * information from the decompresser to the kernel |
| 7 | * |
| 8 | * Copyright (C) 2000, 2001 Axis Communications AB |
| 9 | * |
Jesper Nilsson | f12bb5c | 2008-01-21 11:10:54 +0100 | [diff] [blame] | 10 | * Authors: Mikael Starvik (starvik@axis.com) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 11 | * |
| 12 | */ |
| 13 | |
| 14 | /* Just to be certain the config file is included, we include it here |
Jean Delvare | c03983a | 2007-10-19 23:22:55 +0200 | [diff] [blame] | 15 | * explicitly instead of depending on it being included in the file that |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 16 | * uses this code. |
| 17 | */ |
| 18 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 19 | |
| 20 | ;; WARNING! The registers r8 and r9 are used as parameters carrying |
| 21 | ;; information from the decompressor (if the kernel was compressed). |
| 22 | ;; They should not be used in the code below. |
| 23 | |
| 24 | #ifndef CONFIG_SVINTO_SIM |
| 25 | move.d CONFIG_ETRAX_DEF_R_WAITSTATES, $r0 |
| 26 | move.d $r0, [R_WAITSTATES] |
| 27 | |
| 28 | move.d CONFIG_ETRAX_DEF_R_BUS_CONFIG, $r0 |
| 29 | move.d $r0, [R_BUS_CONFIG] |
| 30 | |
| 31 | #ifndef CONFIG_ETRAX_SDRAM |
| 32 | move.d CONFIG_ETRAX_DEF_R_DRAM_CONFIG, $r0 |
| 33 | move.d $r0, [R_DRAM_CONFIG] |
| 34 | |
| 35 | move.d CONFIG_ETRAX_DEF_R_DRAM_TIMING, $r0 |
| 36 | move.d $r0, [R_DRAM_TIMING] |
| 37 | #else |
| 38 | ;; Samsung SDRAMs seem to require to be initialized twice to work properly. |
| 39 | moveq 2, $r6 |
| 40 | _sdram_init: |
| 41 | |
| 42 | ; Refer to ETRAX 100LX Designers Reference for a description of SDRAM initialization |
| 43 | |
| 44 | ; Bank configuration |
| 45 | move.d CONFIG_ETRAX_DEF_R_SDRAM_CONFIG, $r0 |
| 46 | move.d $r0, [R_SDRAM_CONFIG] |
| 47 | |
| 48 | ; Calculate value of mrs_data |
| 49 | ; CAS latency = 2 && bus_width = 32 => 0x40 |
| 50 | ; CAS latency = 3 && bus_width = 32 => 0x60 |
| 51 | ; CAS latency = 2 && bus_width = 16 => 0x20 |
| 52 | ; CAS latency = 3 && bus_width = 16 => 0x30 |
| 53 | |
| 54 | ; Check if value is already supplied in kernel config |
| 55 | move.d CONFIG_ETRAX_DEF_R_SDRAM_TIMING, $r2 |
| 56 | and.d 0x00ff0000, $r2 |
| 57 | bne _set_timing |
| 58 | lsrq 16, $r2 |
| 59 | |
| 60 | move.d 0x40, $r2 ; Assume 32 bits and CAS latency = 2 |
| 61 | move.d CONFIG_ETRAX_DEF_R_SDRAM_TIMING, $r1 |
| 62 | move.d $r1, $r3 |
| 63 | and.d 0x03, $r1 ; Get CAS latency |
| 64 | and.d 0x1000, $r3 ; 50 or 100 MHz? |
| 65 | beq _speed_50 |
| 66 | nop |
| 67 | _speed_100: |
| 68 | cmp.d 0x00, $r1 ; CAS latency = 2? |
| 69 | beq _bw_check |
| 70 | nop |
| 71 | or.d 0x20, $r2 ; CAS latency = 3 |
| 72 | ba _bw_check |
| 73 | nop |
| 74 | _speed_50: |
| 75 | cmp.d 0x01, $r1 ; CAS latency = 2? |
| 76 | beq _bw_check |
| 77 | nop |
| 78 | or.d 0x20, $r2 ; CAS latency = 3 |
| 79 | _bw_check: |
| 80 | move.d CONFIG_ETRAX_DEF_R_SDRAM_CONFIG, $r1 |
| 81 | and.d 0x800000, $r1 ; DRAM width is bit 23 |
| 82 | bne _set_timing |
| 83 | nop |
| 84 | lsrq 1, $r2 ; 16 bits. Shift down value. |
| 85 | |
| 86 | ; Set timing parameters. Starts master clock |
| 87 | _set_timing: |
| 88 | move.d CONFIG_ETRAX_DEF_R_SDRAM_TIMING, $r1 |
| 89 | and.d 0x8000f9ff, $r1 ; Make sure mrs data and command is 0 |
| 90 | or.d 0x80000000, $r1 ; Make sure sdram enable bit is set |
| 91 | move.d $r1, $r5 |
| 92 | or.d 0x0000c000, $r1 ; ref = disable |
| 93 | lslq 16, $r2 ; mrs data starts at bit 16 |
| 94 | or.d $r2, $r1 |
| 95 | move.d $r1, [R_SDRAM_TIMING] |
| 96 | |
| 97 | ; Wait 200us |
| 98 | move.d 10000, $r2 |
| 99 | 1: bne 1b |
| 100 | subq 1, $r2 |
| 101 | |
| 102 | ; Issue initialization command sequence |
| 103 | move.d _sdram_commands_start, $r2 |
| 104 | and.d 0x000fffff, $r2 ; Make sure commands are read from flash |
| 105 | move.d _sdram_commands_end, $r3 |
| 106 | and.d 0x000fffff, $r3 |
| 107 | 1: clear.d $r4 |
| 108 | move.b [$r2+], $r4 |
| 109 | lslq 9, $r4 ; Command starts at bit 9 |
| 110 | or.d $r1, $r4 |
| 111 | move.d $r4, [R_SDRAM_TIMING] |
| 112 | nop ; Wait five nop cycles between each command |
| 113 | nop |
| 114 | nop |
| 115 | nop |
| 116 | nop |
| 117 | cmp.d $r2, $r3 |
| 118 | bne 1b |
| 119 | nop |
| 120 | move.d $r5, [R_SDRAM_TIMING] |
| 121 | subq 1, $r6 |
| 122 | bne _sdram_init |
| 123 | nop |
| 124 | ba _sdram_commands_end |
| 125 | nop |
| 126 | |
| 127 | _sdram_commands_start: |
| 128 | .byte 3 ; Precharge |
| 129 | .byte 0 ; nop |
| 130 | .byte 2 ; refresh |
| 131 | .byte 0 ; nop |
| 132 | .byte 2 ; refresh |
| 133 | .byte 0 ; nop |
| 134 | .byte 2 ; refresh |
| 135 | .byte 0 ; nop |
| 136 | .byte 2 ; refresh |
| 137 | .byte 0 ; nop |
| 138 | .byte 2 ; refresh |
| 139 | .byte 0 ; nop |
| 140 | .byte 2 ; refresh |
| 141 | .byte 0 ; nop |
| 142 | .byte 2 ; refresh |
| 143 | .byte 0 ; nop |
| 144 | .byte 2 ; refresh |
| 145 | .byte 0 ; nop |
| 146 | .byte 1 ; mrs |
| 147 | .byte 0 ; nop |
| 148 | _sdram_commands_end: |
| 149 | #endif |
| 150 | #endif |