blob: eaa4e87070b7f95b3020dc69816a2a54eb8b6491 [file] [log] [blame]
wdenk4a9cbbe2002-08-27 09:48:53 +00001/*
2 * (C) Copyright 2000 - 2002
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 *
Wolfgang Denk1a459662013-07-08 09:37:19 +02005 * SPDX-License-Identifier: GPL-2.0+
wdenk4a9cbbe2002-08-27 09:48:53 +00006 */
7
8#include <config.h>
9#include <mpc824x.h>
10#include <common.h>
11#include <command.h>
12
Wolfgang Denkd87080b2006-03-31 18:32:53 +020013DECLARE_GLOBAL_DATA_PTR;
14
wdenk4a9cbbe2002-08-27 09:48:53 +000015int checkcpu (void)
16{
wdenk4a9cbbe2002-08-27 09:48:53 +000017 unsigned int pvr = get_pvr ();
18 unsigned int version = pvr >> 16;
19 unsigned char revision;
20 ulong clock = gd->cpu_clk;
21 char buf[32];
22
23 puts ("CPU: ");
24
25 switch (version) {
26 case CPU_TYPE_8240:
27 puts ("MPC8240");
28 break;
29
30 case CPU_TYPE_8245:
31 puts ("MPC8245");
32 break;
33
34 default:
35 return -1; /*not valid for this source */
36 }
37
38 CONFIG_READ_BYTE (REVID, revision);
39
40 if (revision) {
41 printf (" Revision %d.%d",
42 (revision & 0xf0) >> 4,
43 (revision & 0x0f));
44 } else {
45 return -1; /* no valid CPU revision info */
46 }
47
Shruti Kanetkar6b44d9e2013-08-15 11:25:38 -050048 printf(" at %s MHz: ", strmhz(buf, clock));
wdenk4a9cbbe2002-08-27 09:48:53 +000049
Shruti Kanetkar2f848f92013-08-15 11:25:37 -050050 print_size(checkicache(), " I-Cache ");
51 print_size(checkdcache(), " D-Cache\n");
wdenk4a9cbbe2002-08-27 09:48:53 +000052
53 return 0;
54}
55
56/* ------------------------------------------------------------------------- */
57/* L1 i-cache */
58
59int checkicache (void)
60{
61 /*TODO*/
62 return 128 * 4 * 32;
63};
64
65/* ------------------------------------------------------------------------- */
66/* L1 d-cache */
67
68int checkdcache (void)
69{
70 /*TODO*/
71 return 128 * 4 * 32;
72
73};
74
75/*------------------------------------------------------------------- */
76
Wolfgang Denk54841ab2010-06-28 22:00:46 +020077int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
wdenk4a9cbbe2002-08-27 09:48:53 +000078{
79 ulong msr, addr;
80
81 /* Interrupts and MMU off */
82 __asm__ ("mtspr 81, 0");
83
84 /* Interrupts and MMU off */
85 __asm__ __volatile__ ("mfmsr %0":"=r" (msr):);
86
87 msr &= ~0x1030;
88 __asm__ __volatile__ ("mtmsr %0"::"r" (msr));
89
90 /*
91 * Trying to execute the next instruction at a non-existing address
92 * should cause a machine check, resulting in reset
93 */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020094#ifdef CONFIG_SYS_RESET_ADDRESS
95 addr = CONFIG_SYS_RESET_ADDRESS;
wdenk4a9cbbe2002-08-27 09:48:53 +000096#else
97 /*
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020098 * note: when CONFIG_SYS_MONITOR_BASE points to a RAM address,
99 * CONFIG_SYS_MONITOR_BASE - sizeof (ulong) is usually a valid
wdenk8bde7f72003-06-27 21:31:46 +0000100 * address. Better pick an address known to be invalid on
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200101 * your system and assign it to CONFIG_SYS_RESET_ADDRESS.
wdenk8bde7f72003-06-27 21:31:46 +0000102 * "(ulong)-1" used to be a good choice for many systems...
wdenk4a9cbbe2002-08-27 09:48:53 +0000103 */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200104 addr = CONFIG_SYS_MONITOR_BASE - sizeof (ulong);
wdenk4a9cbbe2002-08-27 09:48:53 +0000105#endif
106 ((void (*)(void)) addr) ();
107 return 1;
108
109}
110
111/* ------------------------------------------------------------------------- */
112
113/*
114 * Get timebase clock frequency (like cpu_clk in Hz)
115 * This is the sys_logic_clk (memory bus) divided by 4
116 */
117unsigned long get_tbclk (void)
118{
119 return ((get_bus_freq (0) + 2L) / 4L);
120}
121
122/* ------------------------------------------------------------------------- */
123
124/*
125 * The MPC824x has an integrated PCI controller known as the MPC107.
126 * The following are MPC107 Bridge Controller and PCI Support functions
127 *
128 */
129
130/*
131 * This procedure reads a 32-bit address MPC107 register, and returns
132 * a 32 bit value. It swaps the address to little endian before
133 * writing it to config address, and swaps the value to big endian
134 * before returning to the caller.
135 */
136unsigned int mpc824x_mpc107_getreg (unsigned int regNum)
137{
138 unsigned int temp;
139
140 /* swap the addr. to little endian */
141 *(volatile unsigned int *) CHRP_REG_ADDR = PCISWAP (regNum);
142 temp = *(volatile unsigned int *) CHRP_REG_DATA;
143 return PCISWAP (temp); /* swap the data upon return */
144}
145
146/*
147 * This procedure writes a 32-bit address MPC107 register. It swaps
148 * the address to little endian before writing it to config address.
149 */
150
151void mpc824x_mpc107_setreg (unsigned int regNum, unsigned int regVal)
152{
153 /* swap the addr. to little endian */
154 *(volatile unsigned int *) CHRP_REG_ADDR = PCISWAP (regNum);
155 *(volatile unsigned int *) CHRP_REG_DATA = PCISWAP (regVal);
156 return;
157}
158
159
160/*
161 * Write a byte (8 bits) to a memory location.
162 */
163void mpc824x_mpc107_write8 (unsigned int addr, unsigned char data)
164{
165 *(unsigned char *) addr = data;
166 __asm__ ("sync");
167}
168
169/*
170 * Write a word (16 bits) to a memory location after the value
171 * has been byte swapped (big to little endian or vice versa)
172 */
173
174void mpc824x_mpc107_write16 (unsigned int address, unsigned short data)
175{
176 *(volatile unsigned short *) address = BYTE_SWAP_16_BIT (data);
177 __asm__ ("sync");
178}
179
180/*
181 * Write a long word (32 bits) to a memory location after the value
182 * has been byte swapped (big to little endian or vice versa)
183 */
184
185void mpc824x_mpc107_write32 (unsigned int address, unsigned int data)
186{
187 *(volatile unsigned int *) address = LONGSWAP (data);
188 __asm__ ("sync");
189}
190
191/*
192 * Read a byte (8 bits) from a memory location.
193 */
194unsigned char mpc824x_mpc107_read8 (unsigned int addr)
195{
196 return *(volatile unsigned char *) addr;
197}
198
199
200/*
201 * Read a word (16 bits) from a memory location, and byte swap the
202 * value before returning to the caller.
203 */
204unsigned short mpc824x_mpc107_read16 (unsigned int address)
205{
206 unsigned short retVal;
207
208 retVal = BYTE_SWAP_16_BIT (*(unsigned short *) address);
209 return retVal;
210}
211
212
213/*
214 * Read a long word (32 bits) from a memory location, and byte
215 * swap the value before returning to the caller.
216 */
217unsigned int mpc824x_mpc107_read32 (unsigned int address)
218{
219 unsigned int retVal;
220
221 retVal = LONGSWAP (*(unsigned int *) address);
222 return (retVal);
223}
224
225
226/*
227 * Read a register in the Embedded Utilities Memory Block address
228 * space.
229 * Input: regNum - register number + utility base address. Example,
230 * the base address of EPIC is 0x40000, the register number
231 * being passed is 0x40000+the address of the target register.
232 * (See epic.h for register addresses).
233 * Output: The 32 bit little endian value of the register.
234 */
235
236unsigned int mpc824x_eummbar_read (unsigned int regNum)
237{
238 unsigned int temp;
239
240 temp = *(volatile unsigned int *) (EUMBBAR_VAL + regNum);
241 temp = PCISWAP (temp);
242 return temp;
243}
244
245
246/*
247 * Write a value to a register in the Embedded Utilities Memory
248 * Block address space.
249 * Input: regNum - register number + utility base address. Example,
250 * the base address of EPIC is 0x40000, the register
251 * number is 0x40000+the address of the target register.
252 * (See epic.h for register addresses).
253 * regVal - value to be written to the register.
254 */
255
256void mpc824x_eummbar_write (unsigned int regNum, unsigned int regVal)
257{
258 *(volatile unsigned int *) (EUMBBAR_VAL + regNum) = PCISWAP (regVal);
259 return;
260}
261
262/* ------------------------------------------------------------------------- */