1/* 2 * (C) Copyright 2000 - 2002 3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 4 * 5 * See file CREDITS for list of people who contributed to this 6 * project. 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License as 10 * published by the Free Software Foundation; either version 2 of 11 * the License, or (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 21 * MA 02111-1307 USA 22 */ 23 24#include <config.h> 25#include <mpc824x.h> 26#include <common.h> 27#include <command.h> 28 29DECLARE_GLOBAL_DATA_PTR; 30 31int checkcpu (void) 32{ 33 unsigned int pvr = get_pvr (); 34 unsigned int version = pvr >> 16; 35 unsigned char revision; 36 ulong clock = gd->cpu_clk; 37 char buf[32]; 38 39 puts ("CPU: "); 40 41 switch (version) { 42 case CPU_TYPE_8240: 43 puts ("MPC8240"); 44 break; 45 46 case CPU_TYPE_8245: 47 puts ("MPC8245"); 48 break; 49 50 default: 51 return -1; /*not valid for this source */ 52 } 53 54 CONFIG_READ_BYTE (REVID, revision); 55 56 if (revision) { 57 printf (" Revision %d.%d", 58 (revision & 0xf0) >> 4, 59 (revision & 0x0f)); 60 } else { 61 return -1; /* no valid CPU revision info */ 62 } 63 64 printf (" at %s MHz:", strmhz (buf, clock)); 65 66 printf (" %u kB I-Cache", checkicache () >> 10); 67 printf (" %u kB D-Cache", checkdcache () >> 10); 68 69 puts ("\n"); 70 71 return 0; 72} 73 74/* ------------------------------------------------------------------------- */ 75/* L1 i-cache */ 76 77int checkicache (void) 78{ 79 /*TODO*/ 80 return 128 * 4 * 32; 81}; 82 83/* ------------------------------------------------------------------------- */ 84/* L1 d-cache */ 85 86int checkdcache (void) 87{ 88 /*TODO*/ 89 return 128 * 4 * 32; 90 91}; 92 93/*------------------------------------------------------------------- */ 94 95int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 96{ 97 ulong msr, addr; 98 99 /* Interrupts and MMU off */ 100 __asm__ ("mtspr 81, 0"); 101 102 /* Interrupts and MMU off */ 103 __asm__ __volatile__ ("mfmsr %0":"=r" (msr):); 104 105 msr &= ~0x1030; 106 __asm__ __volatile__ ("mtmsr %0"::"r" (msr)); 107 108 /* 109 * Trying to execute the next instruction at a non-existing address 110 * should cause a machine check, resulting in reset 111 */ 112#ifdef CONFIG_SYS_RESET_ADDRESS 113 addr = CONFIG_SYS_RESET_ADDRESS; 114#else 115 /* 116 * note: when CONFIG_SYS_MONITOR_BASE points to a RAM address, 117 * CONFIG_SYS_MONITOR_BASE - sizeof (ulong) is usually a valid 118 * address. Better pick an address known to be invalid on 119 * your system and assign it to CONFIG_SYS_RESET_ADDRESS. 120 * "(ulong)-1" used to be a good choice for many systems... 121 */ 122 addr = CONFIG_SYS_MONITOR_BASE - sizeof (ulong); 123#endif 124 ((void (*)(void)) addr) (); 125 return 1; 126 127} 128 129/* ------------------------------------------------------------------------- */ 130 131/* 132 * Get timebase clock frequency (like cpu_clk in Hz) 133 * This is the sys_logic_clk (memory bus) divided by 4 134 */ 135unsigned long get_tbclk (void) 136{ 137 return ((get_bus_freq (0) + 2L) / 4L); 138} 139 140/* ------------------------------------------------------------------------- */ 141 142/* 143 * The MPC824x has an integrated PCI controller known as the MPC107. 144 * The following are MPC107 Bridge Controller and PCI Support functions 145 * 146 */ 147 148/* 149 * This procedure reads a 32-bit address MPC107 register, and returns 150 * a 32 bit value. It swaps the address to little endian before 151 * writing it to config address, and swaps the value to big endian 152 * before returning to the caller. 153 */ 154unsigned int mpc824x_mpc107_getreg (unsigned int regNum) 155{ 156 unsigned int temp; 157 158 /* swap the addr. to little endian */ 159 *(volatile unsigned int *) CHRP_REG_ADDR = PCISWAP (regNum); 160 temp = *(volatile unsigned int *) CHRP_REG_DATA; 161 return PCISWAP (temp); /* swap the data upon return */ 162} 163 164/* 165 * This procedure writes a 32-bit address MPC107 register. It swaps 166 * the address to little endian before writing it to config address. 167 */ 168 169void mpc824x_mpc107_setreg (unsigned int regNum, unsigned int regVal) 170{ 171 /* swap the addr. to little endian */ 172 *(volatile unsigned int *) CHRP_REG_ADDR = PCISWAP (regNum); 173 *(volatile unsigned int *) CHRP_REG_DATA = PCISWAP (regVal); 174 return; 175} 176 177 178/* 179 * Write a byte (8 bits) to a memory location. 180 */ 181void mpc824x_mpc107_write8 (unsigned int addr, unsigned char data) 182{ 183 *(unsigned char *) addr = data; 184 __asm__ ("sync"); 185} 186 187/* 188 * Write a word (16 bits) to a memory location after the value 189 * has been byte swapped (big to little endian or vice versa) 190 */ 191 192void mpc824x_mpc107_write16 (unsigned int address, unsigned short data) 193{ 194 *(volatile unsigned short *) address = BYTE_SWAP_16_BIT (data); 195 __asm__ ("sync"); 196} 197 198/* 199 * Write a long word (32 bits) to a memory location after the value 200 * has been byte swapped (big to little endian or vice versa) 201 */ 202 203void mpc824x_mpc107_write32 (unsigned int address, unsigned int data) 204{ 205 *(volatile unsigned int *) address = LONGSWAP (data); 206 __asm__ ("sync"); 207} 208 209/* 210 * Read a byte (8 bits) from a memory location. 211 */ 212unsigned char mpc824x_mpc107_read8 (unsigned int addr) 213{ 214 return *(volatile unsigned char *) addr; 215} 216 217 218/* 219 * Read a word (16 bits) from a memory location, and byte swap the 220 * value before returning to the caller. 221 */ 222unsigned short mpc824x_mpc107_read16 (unsigned int address) 223{ 224 unsigned short retVal; 225 226 retVal = BYTE_SWAP_16_BIT (*(unsigned short *) address); 227 return retVal; 228} 229 230 231/* 232 * Read a long word (32 bits) from a memory location, and byte 233 * swap the value before returning to the caller. 234 */ 235unsigned int mpc824x_mpc107_read32 (unsigned int address) 236{ 237 unsigned int retVal; 238 239 retVal = LONGSWAP (*(unsigned int *) address); 240 return (retVal); 241} 242 243 244/* 245 * Read a register in the Embedded Utilities Memory Block address 246 * space. 247 * Input: regNum - register number + utility base address. Example, 248 * the base address of EPIC is 0x40000, the register number 249 * being passed is 0x40000+the address of the target register. 250 * (See epic.h for register addresses). 251 * Output: The 32 bit little endian value of the register. 252 */ 253 254unsigned int mpc824x_eummbar_read (unsigned int regNum) 255{ 256 unsigned int temp; 257 258 temp = *(volatile unsigned int *) (EUMBBAR_VAL + regNum); 259 temp = PCISWAP (temp); 260 return temp; 261} 262 263 264/* 265 * Write a value to a register in the Embedded Utilities Memory 266 * Block address space. 267 * Input: regNum - register number + utility base address. Example, 268 * the base address of EPIC is 0x40000, the register 269 * number is 0x40000+the address of the target register. 270 * (See epic.h for register addresses). 271 * regVal - value to be written to the register. 272 */ 273 274void mpc824x_eummbar_write (unsigned int regNum, unsigned int regVal) 275{ 276 *(volatile unsigned int *) (EUMBBAR_VAL + regNum) = PCISWAP (regVal); 277 return; 278} 279 280/* ------------------------------------------------------------------------- */ 281