]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/powerpc/cpu/mpc824x/cpu.c
Merge 'u-boot-microblaze/zynq' into (u-boot-arm/master'
[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         print_size(checkicache(), " I-Cache ");
51         print_size(checkdcache(), " D-Cache\n");
52
53         return 0;
54 }
55
56 /* ------------------------------------------------------------------------- */
57 /* L1 i-cache                                                                */
58
59 int checkicache (void)
60 {
61          /*TODO*/
62          return 128 * 4 * 32;
63 };
64
65 /* ------------------------------------------------------------------------- */
66 /* L1 d-cache                                                                */
67
68 int checkdcache (void)
69 {
70          /*TODO*/
71          return 128 * 4 * 32;
72
73 };
74
75 /*------------------------------------------------------------------- */
76
77 int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
78 {
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          */
94 #ifdef CONFIG_SYS_RESET_ADDRESS
95         addr = CONFIG_SYS_RESET_ADDRESS;
96 #else
97         /*
98          * note: when CONFIG_SYS_MONITOR_BASE points to a RAM address,
99          * CONFIG_SYS_MONITOR_BASE - sizeof (ulong) is usually a valid
100          * address. Better pick an address known to be invalid on
101          * your system and assign it to CONFIG_SYS_RESET_ADDRESS.
102          * "(ulong)-1" used to be a good choice for many systems...
103          */
104         addr = CONFIG_SYS_MONITOR_BASE - sizeof (ulong);
105 #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  */
117 unsigned 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  */
136 unsigned 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
151 void 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  */
163 void 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
174 void 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
185 void 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  */
194 unsigned 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  */
204 unsigned 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  */
217 unsigned 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
236 unsigned 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
256 void mpc824x_eummbar_write (unsigned int regNum, unsigned int regVal)
257 {
258         *(volatile unsigned int *) (EUMBBAR_VAL + regNum) = PCISWAP (regVal);
259         return;
260 }
261
262 /* ------------------------------------------------------------------------- */