1/* 2 * (C) Copyright 2003 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/* 28 * pf5200.c - main board support/init for the esd pf5200. 29 */ 30 31#include <common.h> 32#include <mpc5xxx.h> 33#include <pci.h> 34#include <command.h> 35#include <netdev.h> 36 37#include "mt46v16m16-75.h" 38 39void init_power_switch(void); 40 41static void sdram_start(int hi_addr) 42{ 43 long hi_addr_bit = hi_addr ? 0x01000000 : 0; 44 45 /* unlock mode register */ 46 *(vu_long *) MPC5XXX_SDRAM_CTRL = 47 SDRAM_CONTROL | 0x80000000 | hi_addr_bit; 48 __asm__ volatile ("sync"); 49 50 /* precharge all banks */ 51 *(vu_long *) MPC5XXX_SDRAM_CTRL = 52 SDRAM_CONTROL | 0x80000002 | hi_addr_bit; 53 __asm__ volatile ("sync"); 54 55 /* set mode register: extended mode */ 56 *(vu_long *) MPC5XXX_SDRAM_MODE = SDRAM_EMODE; 57 __asm__ volatile ("sync"); 58 59 /* set mode register: reset DLL */ 60 *(vu_long *) MPC5XXX_SDRAM_MODE = SDRAM_MODE | 0x04000000; 61 __asm__ volatile ("sync"); 62 63 /* precharge all banks */ 64 *(vu_long *) MPC5XXX_SDRAM_CTRL = 65 SDRAM_CONTROL | 0x80000002 | hi_addr_bit; 66 __asm__ volatile ("sync"); 67 68 /* auto refresh */ 69 *(vu_long *) MPC5XXX_SDRAM_CTRL = 70 SDRAM_CONTROL | 0x80000004 | hi_addr_bit; 71 __asm__ volatile ("sync"); 72 73 /* set mode register */ 74 *(vu_long *) MPC5XXX_SDRAM_MODE = SDRAM_MODE; 75 __asm__ volatile ("sync"); 76 77 /* normal operation */ 78 *(vu_long *) MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | hi_addr_bit; 79 __asm__ volatile ("sync"); 80} 81 82/* 83 * ATTENTION: Although partially referenced initdram does NOT make real use 84 * use of CONFIG_SYS_SDRAM_BASE. The code does not work if CONFIG_SYS_SDRAM_BASE 85 * is something else than 0x00000000. 86 */ 87 88phys_size_t initdram(int board_type) 89{ 90 ulong dramsize = 0; 91 ulong test1, test2; 92 93 /* setup SDRAM chip selects */ 94 *(vu_long *) MPC5XXX_SDRAM_CS0CFG = 0x0000001e; /* 2G at 0x0 */ 95 *(vu_long *) MPC5XXX_SDRAM_CS1CFG = 0x80000000; /* disabled */ 96 __asm__ volatile ("sync"); 97 98 /* setup config registers */ 99 *(vu_long *) MPC5XXX_SDRAM_CONFIG1 = SDRAM_CONFIG1; 100 *(vu_long *) MPC5XXX_SDRAM_CONFIG2 = SDRAM_CONFIG2; 101 __asm__ volatile ("sync"); 102 103 /* set tap delay */ 104 *(vu_long *) MPC5XXX_CDM_PORCFG = SDRAM_TAPDELAY; 105 __asm__ volatile ("sync"); 106 107 /* find RAM size using SDRAM CS0 only */ 108 sdram_start(0); 109 test1 = get_ram_size(CONFIG_SYS_SDRAM_BASE, 0x80000000); 110 sdram_start(1); 111 test2 = get_ram_size(CONFIG_SYS_SDRAM_BASE, 0x80000000); 112 113 if (test1 > test2) { 114 sdram_start(0); 115 dramsize = test1; 116 } else { 117 dramsize = test2; 118 } 119 120 /* memory smaller than 1MB is impossible */ 121 if (dramsize < (1 << 20)) 122 dramsize = 0; 123 124 /* set SDRAM CS0 size according to the amount of RAM found */ 125 if (dramsize > 0) { 126 *(vu_long *) MPC5XXX_SDRAM_CS0CFG = 127 0x13 + __builtin_ffs(dramsize >> 20) - 1; 128 /* let SDRAM CS1 start right after CS0 */ 129 *(vu_long *) MPC5XXX_SDRAM_CS1CFG = dramsize + 0x0000001e; /* 2G */ 130 } else { 131#if 0 132 *(vu_long *) MPC5XXX_SDRAM_CS0CFG = 0; /* disabled */ 133 /* let SDRAM CS1 start right after CS0 */ 134 *(vu_long *) MPC5XXX_SDRAM_CS1CFG = dramsize + 0x0000001e; /* 2G */ 135#else 136 *(vu_long *) MPC5XXX_SDRAM_CS0CFG = 137 0x13 + __builtin_ffs(0x08000000 >> 20) - 1; 138 /* let SDRAM CS1 start right after CS0 */ 139 *(vu_long *) MPC5XXX_SDRAM_CS1CFG = 0x08000000 + 0x0000001e; /* 2G */ 140#endif 141 } 142 143#if 0 144 /* find RAM size using SDRAM CS1 only */ 145 sdram_start(0); 146 get_ram_size((ulong *) (CONFIG_SYS_SDRAM_BASE + dramsize), 0x80000000); 147 sdram_start(1); 148 get_ram_size((ulong *) (CONFIG_SYS_SDRAM_BASE + dramsize), 0x80000000); 149 sdram_start(0); 150#endif 151 /* set SDRAM CS1 size according to the amount of RAM found */ 152 153 *(vu_long *) MPC5XXX_SDRAM_CS1CFG = dramsize; /* disabled */ 154 155 init_power_switch(); 156 return (dramsize); 157} 158 159int checkboard(void) 160{ 161 puts("Board: esd CPX CPU5200 (mecp5200)\n"); 162 return 0; 163} 164 165void flash_preinit(void) 166{ 167 /* 168 * Now, when we are in RAM, enable flash write 169 * access for detection process. 170 * Note that CS_BOOT cannot be cleared when 171 * executing in flash. 172 */ 173 *(vu_long *) MPC5XXX_BOOTCS_CFG &= ~0x1; /* clear RO */ 174} 175 176void flash_afterinit(ulong size) 177{ 178 if (size == CONFIG_SYS_FLASH_SIZE) { 179 /* adjust mapping */ 180 *(vu_long *) MPC5XXX_BOOTCS_START = 181 *(vu_long *) MPC5XXX_CS0_START = 182 START_REG(CONFIG_SYS_BOOTCS_START | size); 183 *(vu_long *) MPC5XXX_BOOTCS_STOP = 184 *(vu_long *) MPC5XXX_CS0_STOP = 185 STOP_REG(CONFIG_SYS_BOOTCS_START | size, size); 186 } 187} 188 189#ifdef CONFIG_PCI 190static struct pci_controller hose; 191 192extern void pci_mpc5xxx_init(struct pci_controller *); 193 194void pci_init_board(void) 195{ 196 pci_mpc5xxx_init(&hose); 197} 198#endif 199 200#if defined(CONFIG_CMD_IDE) && defined(CONFIG_IDE_RESET) 201 202#define GPIO_PSC1_4 0x01000000UL 203 204void init_ide_reset(void) 205{ 206 debug("init_ide_reset\n"); 207 208 /* Configure PSC1_4 as GPIO output for ATA reset */ 209 *(vu_long *) MPC5XXX_WU_GPIO_ENABLE |= GPIO_PSC1_4; 210 *(vu_long *) MPC5XXX_WU_GPIO_DIR |= GPIO_PSC1_4; 211} 212 213void ide_set_reset(int idereset) 214{ 215 debug("ide_reset(%d)\n", idereset); 216 217 if (idereset) 218 *(vu_long *) MPC5XXX_WU_GPIO_DATA_O &= ~GPIO_PSC1_4; 219 else 220 *(vu_long *) MPC5XXX_WU_GPIO_DATA_O |= GPIO_PSC1_4; 221} 222#endif 223 224#define MPC5XXX_SIMPLEIO_GPIO_ENABLE (MPC5XXX_GPIO + 0x0004) 225#define MPC5XXX_SIMPLEIO_GPIO_DIR (MPC5XXX_GPIO + 0x000C) 226#define MPC5XXX_SIMPLEIO_GPIO_DATA_OUTPUT (MPC5XXX_GPIO + 0x0010) 227#define MPC5XXX_SIMPLEIO_GPIO_DATA_INPUT (MPC5XXX_GPIO + 0x0014) 228 229#define MPC5XXX_INTERRUPT_GPIO_ENABLE (MPC5XXX_GPIO + 0x0020) 230#define MPC5XXX_INTERRUPT_GPIO_DIR (MPC5XXX_GPIO + 0x0028) 231#define MPC5XXX_INTERRUPT_GPIO_DATA_OUTPUT (MPC5XXX_GPIO + 0x002C) 232#define MPC5XXX_INTERRUPT_GPIO_STATUS (MPC5XXX_GPIO + 0x003C) 233 234#define GPIO_WU6 0x40000000UL 235#define GPIO_USB0 0x00010000UL 236#define GPIO_USB9 0x08000000UL 237#define GPIO_USB9S 0x00080000UL 238 239void init_power_switch(void) 240{ 241 debug("init_power_switch\n"); 242 243 /* Configure GPIO_WU6 as GPIO output for ATA reset */ 244 *(vu_long *) MPC5XXX_WU_GPIO_DATA_O |= GPIO_WU6; 245 *(vu_long *) MPC5XXX_WU_GPIO_ENABLE |= GPIO_WU6; 246 *(vu_long *) MPC5XXX_WU_GPIO_DIR |= GPIO_WU6; 247 __asm__ volatile ("sync"); 248 249 *(vu_long *) MPC5XXX_SIMPLEIO_GPIO_DATA_OUTPUT &= ~GPIO_USB0; 250 *(vu_long *) MPC5XXX_SIMPLEIO_GPIO_ENABLE |= GPIO_USB0; 251 *(vu_long *) MPC5XXX_SIMPLEIO_GPIO_DIR |= GPIO_USB0; 252 __asm__ volatile ("sync"); 253 254 *(vu_long *) MPC5XXX_INTERRUPT_GPIO_DATA_OUTPUT &= ~GPIO_USB9; 255 *(vu_long *) MPC5XXX_INTERRUPT_GPIO_ENABLE &= ~GPIO_USB9; 256 __asm__ volatile ("sync"); 257 258 if ((*(vu_long *) MPC5XXX_INTERRUPT_GPIO_STATUS & GPIO_USB9S) == 0) { 259 *(vu_long *) MPC5XXX_SIMPLEIO_GPIO_DATA_OUTPUT |= GPIO_USB0; 260 __asm__ volatile ("sync"); 261 } 262} 263 264int board_eth_init(bd_t *bis) 265{ 266 return pci_eth_init(bis); 267} 268