1/* 2 * (C) Copyright 2005 3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 4 * 5 * (C) Copyright 2004 6 * Mark Jonas, Freescale Semiconductor, mark.jonas@motorola.com. 7 * 8 * See file CREDITS for list of people who contributed to this 9 * project. 10 * 11 * This program is free software; you can redistribute it and/or 12 * modify it under the terms of the GNU General Public License as 13 * published by the Free Software Foundation; either version 2 of 14 * the License, or (at your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program; if not, write to the Free Software 23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 24 * MA 02111-1307 USA 25 */ 26 27#include <common.h> 28#include <mpc5xxx.h> 29#include <pci.h> 30 31#if defined(CONFIG_MPC5200_DDR) 32#include "mt46v16m16-75.h" 33#else 34#include "mt48lc16m32s2-75.h" 35#endif 36 37#ifndef CONFIG_SYS_RAMBOOT 38static void sdram_start (int hi_addr) 39{ 40 long hi_addr_bit = hi_addr ? 0x01000000 : 0; 41 42 /* unlock mode register */ 43 *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000000 | hi_addr_bit; 44 __asm__ volatile ("sync"); 45 46 /* precharge all banks */ 47 *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000002 | hi_addr_bit; 48 __asm__ volatile ("sync"); 49 50#if SDRAM_DDR 51 /* set mode register: extended mode */ 52 *(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_EMODE; 53 __asm__ volatile ("sync"); 54 55 /* set mode register: reset DLL */ 56 *(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_MODE | 0x04000000; 57 __asm__ volatile ("sync"); 58#endif 59 60 /* precharge all banks */ 61 *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000002 | hi_addr_bit; 62 __asm__ volatile ("sync"); 63 64 /* auto refresh */ 65 *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000004 | hi_addr_bit; 66 __asm__ volatile ("sync"); 67 68 /* set mode register */ 69 *(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_MODE; 70 __asm__ volatile ("sync"); 71 72 /* normal operation */ 73 *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | hi_addr_bit; 74 __asm__ volatile ("sync"); 75} 76#endif 77 78/* 79 * ATTENTION: Although partially referenced initdram does NOT make real use 80 * use of CONFIG_SYS_SDRAM_BASE. The code does not work if CONFIG_SYS_SDRAM_BASE 81 * is something else than 0x00000000. 82 */ 83 84phys_size_t initdram (int board_type) 85{ 86 ulong dramsize = 0; 87 ulong dramsize2 = 0; 88#ifndef CONFIG_SYS_RAMBOOT 89 ulong test1, test2; 90 91 /* setup SDRAM chip selects */ 92 *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x0000001e;/* 2G at 0x0 */ 93 *(vu_long *)MPC5XXX_SDRAM_CS1CFG = 0x80000000;/* disabled */ 94 __asm__ volatile ("sync"); 95 96 /* setup config registers */ 97 *(vu_long *)MPC5XXX_SDRAM_CONFIG1 = SDRAM_CONFIG1; 98 *(vu_long *)MPC5XXX_SDRAM_CONFIG2 = SDRAM_CONFIG2; 99 __asm__ volatile ("sync"); 100 101#if SDRAM_DDR 102 /* set tap delay */ 103 *(vu_long *)MPC5XXX_CDM_PORCFG = SDRAM_TAPDELAY; 104 __asm__ volatile ("sync"); 105#endif 106 107 /* find RAM size using SDRAM CS0 only */ 108 sdram_start(0); 109 test1 = get_ram_size((ulong *)CONFIG_SYS_SDRAM_BASE, 0x80000000); 110 sdram_start(1); 111 test2 = get_ram_size((ulong *)CONFIG_SYS_SDRAM_BASE, 0x80000000); 112 if (test1 > test2) { 113 sdram_start(0); 114 dramsize = test1; 115 } else { 116 dramsize = test2; 117 } 118 119 /* memory smaller than 1MB is impossible */ 120 if (dramsize < (1 << 20)) { 121 dramsize = 0; 122 } 123 124 /* set SDRAM CS0 size according to the amount of RAM found */ 125 if (dramsize > 0) { 126 *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x13 + __builtin_ffs(dramsize >> 20) - 1; 127 } else { 128 *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0; /* disabled */ 129 } 130 131 /* let SDRAM CS1 start right after CS0 */ 132 *(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize + 0x0000001e;/* 2G */ 133 134 /* find RAM size using SDRAM CS1 only */ 135 if (!dramsize) 136 sdram_start(0); 137 test2 = test1 = get_ram_size((ulong *)(CONFIG_SYS_SDRAM_BASE + dramsize), 0x80000000); 138 if (!dramsize) { 139 sdram_start(1); 140 test2 = get_ram_size((ulong *)(CONFIG_SYS_SDRAM_BASE + dramsize), 0x80000000); 141 } 142 if (test1 > test2) { 143 sdram_start(0); 144 dramsize2 = test1; 145 } else { 146 dramsize2 = test2; 147 } 148 149 /* memory smaller than 1MB is impossible */ 150 if (dramsize2 < (1 << 20)) { 151 dramsize2 = 0; 152 } 153 154 /* set SDRAM CS1 size according to the amount of RAM found */ 155 if (dramsize2 > 0) { 156 *(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize 157 | (0x13 + __builtin_ffs(dramsize2 >> 20) - 1); 158 } else { 159 *(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize; /* disabled */ 160 } 161 162#else /* CONFIG_SYS_RAMBOOT */ 163 164 /* retrieve size of memory connected to SDRAM CS0 */ 165 dramsize = *(vu_long *)MPC5XXX_SDRAM_CS0CFG & 0xFF; 166 if (dramsize >= 0x13) { 167 dramsize = (1 << (dramsize - 0x13)) << 20; 168 } else { 169 dramsize = 0; 170 } 171 172 /* retrieve size of memory connected to SDRAM CS1 */ 173 dramsize2 = *(vu_long *)MPC5XXX_SDRAM_CS1CFG & 0xFF; 174 if (dramsize2 >= 0x13) { 175 dramsize2 = (1 << (dramsize2 - 0x13)) << 20; 176 } else { 177 dramsize2 = 0; 178 } 179 180#endif /* CONFIG_SYS_RAMBOOT */ 181 182 return dramsize + dramsize2; 183} 184 185int checkboard (void) 186{ 187 puts ("Board: CANMB\n"); 188 return 0; 189} 190 191int board_early_init_r (void) 192{ 193 *(vu_long *)MPC5XXX_BOOTCS_CFG &= ~0x1; /* clear RO */ 194 *(vu_long *)MPC5XXX_BOOTCS_START = 195 *(vu_long *)MPC5XXX_CS0_START = START_REG(CONFIG_SYS_FLASH_BASE); 196 *(vu_long *)MPC5XXX_BOOTCS_STOP = 197 *(vu_long *)MPC5XXX_CS0_STOP = STOP_REG(CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FLASH_SIZE); 198 return 0; 199} 200