]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/powerpc/cpu/mpc824x/cpu.c
Add GPL-2.0+ SPDX-License-Identifier to source files
[karo-tx-uboot.git] / arch / powerpc / cpu / mpc824x / cpu.c
1 /*
2  * (C) Copyright 2000 - 2002
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8 #include <config.h>
9 #include <mpc824x.h>
10 #include <common.h>
11 #include <command.h>
12
13 DECLARE_GLOBAL_DATA_PTR;
14
15 int checkcpu (void)
16 {
17         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
61 int checkicache (void)
62 {
63          /*TODO*/
64          return 128 * 4 * 32;
65 };
66
67 /* ------------------------------------------------------------------------- */
68 /* L1 d-cache                                                                */
69
70 int checkdcache (void)
71 {
72          /*TODO*/
73          return 128 * 4 * 32;
74
75 };
76
77 /*------------------------------------------------------------------- */
78
79 int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
80 {
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          */
96 #ifdef CONFIG_SYS_RESET_ADDRESS
97         addr = CONFIG_SYS_RESET_ADDRESS;
98 #else
99         /*
100          * note: when CONFIG_SYS_MONITOR_BASE points to a RAM address,
101          * CONFIG_SYS_MONITOR_BASE - sizeof (ulong) is usually a valid
102          * address. Better pick an address known to be invalid on
103          * your system and assign it to CONFIG_SYS_RESET_ADDRESS.
104          * "(ulong)-1" used to be a good choice for many systems...
105          */
106         addr = CONFIG_SYS_MONITOR_BASE - sizeof (ulong);
107 #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  */
119 unsigned 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  */
138 unsigned 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
153 void 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  */
165 void 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
176 void 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
187 void 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  */
196 unsigned 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  */
206 unsigned 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  */
219 unsigned 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
238 unsigned 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
258 void mpc824x_eummbar_write (unsigned int regNum, unsigned int regVal)
259 {
260         *(volatile unsigned int *) (EUMBBAR_VAL + regNum) = PCISWAP (regVal);
261         return;
262 }
263
264 /* ------------------------------------------------------------------------- */