blob: ee69e495b72d788c1f53fe94e3a662dd21122e1d [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
48 printf (" at %s MHz:", strmhz (buf, clock));
49
50 printf (" %u kB I-Cache", checkicache () >> 10);
51 printf (" %u kB D-Cache", checkdcache () >> 10);
52
53 puts ("\n");
54
55 return 0;
56}
57
58/* ------------------------------------------------------------------------- */
59/* L1 i-cache */
60
61int checkicache (void)
62{
63 /*TODO*/
64 return 128 * 4 * 32;
65};
66
67/* ------------------------------------------------------------------------- */
68/* L1 d-cache */
69
70int checkdcache (void)
71{
72 /*TODO*/
73 return 128 * 4 * 32;
74
75};
76
77/*------------------------------------------------------------------- */
78
Wolfgang Denk54841ab2010-06-28 22:00:46 +020079int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
wdenk4a9cbbe2002-08-27 09:48:53 +000080{
81 ulong msr, addr;
82
83 /* Interrupts and MMU off */
84 __asm__ ("mtspr 81, 0");
85
86 /* Interrupts and MMU off */
87 __asm__ __volatile__ ("mfmsr %0":"=r" (msr):);
88
89 msr &= ~0x1030;
90 __asm__ __volatile__ ("mtmsr %0"::"r" (msr));
91
92 /*
93 * Trying to execute the next instruction at a non-existing address
94 * should cause a machine check, resulting in reset
95 */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020096#ifdef CONFIG_SYS_RESET_ADDRESS
97 addr = CONFIG_SYS_RESET_ADDRESS;
wdenk4a9cbbe2002-08-27 09:48:53 +000098#else
99 /*
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200100 * note: when CONFIG_SYS_MONITOR_BASE points to a RAM address,
101 * CONFIG_SYS_MONITOR_BASE - sizeof (ulong) is usually a valid
wdenk8bde7f72003-06-27 21:31:46 +0000102 * address. Better pick an address known to be invalid on
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200103 * your system and assign it to CONFIG_SYS_RESET_ADDRESS.
wdenk8bde7f72003-06-27 21:31:46 +0000104 * "(ulong)-1" used to be a good choice for many systems...
wdenk4a9cbbe2002-08-27 09:48:53 +0000105 */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200106 addr = CONFIG_SYS_MONITOR_BASE - sizeof (ulong);
wdenk4a9cbbe2002-08-27 09:48:53 +0000107#endif
108 ((void (*)(void)) addr) ();
109 return 1;
110
111}
112
113/* ------------------------------------------------------------------------- */
114
115/*
116 * Get timebase clock frequency (like cpu_clk in Hz)
117 * This is the sys_logic_clk (memory bus) divided by 4
118 */
119unsigned long get_tbclk (void)
120{
121 return ((get_bus_freq (0) + 2L) / 4L);
122}
123
124/* ------------------------------------------------------------------------- */
125
126/*
127 * The MPC824x has an integrated PCI controller known as the MPC107.
128 * The following are MPC107 Bridge Controller and PCI Support functions
129 *
130 */
131
132/*
133 * This procedure reads a 32-bit address MPC107 register, and returns
134 * a 32 bit value. It swaps the address to little endian before
135 * writing it to config address, and swaps the value to big endian
136 * before returning to the caller.
137 */
138unsigned int mpc824x_mpc107_getreg (unsigned int regNum)
139{
140 unsigned int temp;
141
142 /* swap the addr. to little endian */
143 *(volatile unsigned int *) CHRP_REG_ADDR = PCISWAP (regNum);
144 temp = *(volatile unsigned int *) CHRP_REG_DATA;
145 return PCISWAP (temp); /* swap the data upon return */
146}
147
148/*
149 * This procedure writes a 32-bit address MPC107 register. It swaps
150 * the address to little endian before writing it to config address.
151 */
152
153void mpc824x_mpc107_setreg (unsigned int regNum, unsigned int regVal)
154{
155 /* swap the addr. to little endian */
156 *(volatile unsigned int *) CHRP_REG_ADDR = PCISWAP (regNum);
157 *(volatile unsigned int *) CHRP_REG_DATA = PCISWAP (regVal);
158 return;
159}
160
161
162/*
163 * Write a byte (8 bits) to a memory location.
164 */
165void mpc824x_mpc107_write8 (unsigned int addr, unsigned char data)
166{
167 *(unsigned char *) addr = data;
168 __asm__ ("sync");
169}
170
171/*
172 * Write a word (16 bits) to a memory location after the value
173 * has been byte swapped (big to little endian or vice versa)
174 */
175
176void mpc824x_mpc107_write16 (unsigned int address, unsigned short data)
177{
178 *(volatile unsigned short *) address = BYTE_SWAP_16_BIT (data);
179 __asm__ ("sync");
180}
181
182/*
183 * Write a long word (32 bits) to a memory location after the value
184 * has been byte swapped (big to little endian or vice versa)
185 */
186
187void mpc824x_mpc107_write32 (unsigned int address, unsigned int data)
188{
189 *(volatile unsigned int *) address = LONGSWAP (data);
190 __asm__ ("sync");
191}
192
193/*
194 * Read a byte (8 bits) from a memory location.
195 */
196unsigned char mpc824x_mpc107_read8 (unsigned int addr)
197{
198 return *(volatile unsigned char *) addr;
199}
200
201
202/*
203 * Read a word (16 bits) from a memory location, and byte swap the
204 * value before returning to the caller.
205 */
206unsigned short mpc824x_mpc107_read16 (unsigned int address)
207{
208 unsigned short retVal;
209
210 retVal = BYTE_SWAP_16_BIT (*(unsigned short *) address);
211 return retVal;
212}
213
214
215/*
216 * Read a long word (32 bits) from a memory location, and byte
217 * swap the value before returning to the caller.
218 */
219unsigned int mpc824x_mpc107_read32 (unsigned int address)
220{
221 unsigned int retVal;
222
223 retVal = LONGSWAP (*(unsigned int *) address);
224 return (retVal);
225}
226
227
228/*
229 * Read a register in the Embedded Utilities Memory Block address
230 * space.
231 * Input: regNum - register number + utility base address. Example,
232 * the base address of EPIC is 0x40000, the register number
233 * being passed is 0x40000+the address of the target register.
234 * (See epic.h for register addresses).
235 * Output: The 32 bit little endian value of the register.
236 */
237
238unsigned int mpc824x_eummbar_read (unsigned int regNum)
239{
240 unsigned int temp;
241
242 temp = *(volatile unsigned int *) (EUMBBAR_VAL + regNum);
243 temp = PCISWAP (temp);
244 return temp;
245}
246
247
248/*
249 * Write a value to a register in the Embedded Utilities Memory
250 * Block address space.
251 * Input: regNum - register number + utility base address. Example,
252 * the base address of EPIC is 0x40000, the register
253 * number is 0x40000+the address of the target register.
254 * (See epic.h for register addresses).
255 * regVal - value to be written to the register.
256 */
257
258void mpc824x_eummbar_write (unsigned int regNum, unsigned int regVal)
259{
260 *(volatile unsigned int *) (EUMBBAR_VAL + regNum) = PCISWAP (regVal);
261 return;
262}
263
264/* ------------------------------------------------------------------------- */