2 * Copyright 2006 Freescale Semiconductor
4 * Srikanth Srinivasan (srikanth.srinivasan@freescale.com)
6 * See file CREDITS for list of people who contributed to this
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of
12 * the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
28 #include <asm/cache.h>
30 #include <asm/fsl_law.h>
40 uint lcrr
; /* local bus clock ratio register */
41 uint clkdiv
; /* clock divider portion of lcrr */
42 volatile immap_t
*immap
= (immap_t
*) CFG_IMMR
;
43 volatile ccsr_gur_t
*gur
= &immap
->im_gur
;
45 puts("Freescale PowerPC\n");
56 case PVR_VER(PVR_86xx
):
58 uint msscr0
= mfspr(MSSCR0
);
59 printf("E600 Core %d", (msscr0
& 0x20) ? 1 : 0 );
60 if (gur
->pordevsr
& MPC86xx_PORDEVSR_CORE1TE
)
61 puts("\n Core1Translation Enabled");
62 debug(" (MSSCR0=%x, PORDEVSR=%x)", msscr0
, gur
->pordevsr
);
69 printf(", Version: %d.%d, (0x%08x)\n", major
, minor
, pvr
);
72 ver
= SVR_SOC_VER(svr
);
79 if (SVR_SUBVER(svr
) == 1) {
92 printf(", Version: %d.%d, (0x%08x)\n", major
, minor
, svr
);
94 get_sys_info(&sysinfo
);
97 printf("CPU:%4lu MHz, ", sysinfo
.freqProcessor
/ 1000000);
98 printf("MPX:%4lu MHz, ", sysinfo
.freqSystemBus
/ 1000000);
99 printf("DDR:%4lu MHz, ", sysinfo
.freqSystemBus
/ 2000000);
101 #if defined(CFG_LBC_LCRR)
105 volatile immap_t
*immap
= (immap_t
*) CFG_IMMR
;
106 volatile ccsr_lbc_t
*lbc
= &immap
->im_lbc
;
111 clkdiv
= lcrr
& 0x0f;
112 if (clkdiv
== 2 || clkdiv
== 4 || clkdiv
== 8) {
113 printf("LBC:%4lu MHz\n",
114 sysinfo
.freqSystemBus
/ 1000000 / clkdiv
);
116 printf(" LBC: unknown (lcrr: 0x%08x)\n", lcrr
);
120 if (get_l2cr() & 0x80000000)
130 soft_restart(unsigned long addr
)
132 #if !defined(CONFIG_MPC8641HPCN) && !defined(CONFIG_MPC8610HPCD)
135 * SRR0 has system reset vector, SRR1 has default MSR value
136 * rfi restores MSR from SRR1 and sets the PC to the SRR0 value
139 __asm__
__volatile__ ("mtspr 26, %0" :: "r" (addr
));
140 __asm__
__volatile__ ("li 4, (1 << 6)" ::: "r4");
141 __asm__
__volatile__ ("mtspr 27, 4");
142 __asm__
__volatile__ ("rfi");
144 #else /* CONFIG_MPC8641HPCN */
146 out8(PIXIS_BASE
+ PIXIS_RST
, 0);
148 #endif /* !CONFIG_MPC8641HPCN */
150 while (1) ; /* not reached */
155 * No generic way to do board reset. Simply call soft_reset.
158 do_reset(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char *argv
[])
160 #if !defined(CONFIG_MPC8641HPCN) && !defined(CONFIG_MPC8610HPCD)
162 #ifdef CFG_RESET_ADDRESS
163 ulong addr
= CFG_RESET_ADDRESS
;
166 * note: when CFG_MONITOR_BASE points to a RAM address,
167 * CFG_MONITOR_BASE - sizeof (ulong) is usually a valid
168 * address. Better pick an address known to be invalid on your
169 * system and assign it to CFG_RESET_ADDRESS.
171 ulong addr
= CFG_MONITOR_BASE
- sizeof(ulong
);
174 /* flush and disable I/D cache */
175 __asm__
__volatile__ ("mfspr 3, 1008" ::: "r3");
176 __asm__
__volatile__ ("ori 5, 5, 0xcc00" ::: "r5");
177 __asm__
__volatile__ ("ori 4, 3, 0xc00" ::: "r4");
178 __asm__
__volatile__ ("andc 5, 3, 5" ::: "r5");
179 __asm__
__volatile__ ("sync");
180 __asm__
__volatile__ ("mtspr 1008, 4");
181 __asm__
__volatile__ ("isync");
182 __asm__
__volatile__ ("sync");
183 __asm__
__volatile__ ("mtspr 1008, 5");
184 __asm__
__volatile__ ("isync");
185 __asm__
__volatile__ ("sync");
189 #else /* CONFIG_MPC8641HPCN */
191 out8(PIXIS_BASE
+ PIXIS_RST
, 0);
193 #endif /* !CONFIG_MPC8641HPCN */
195 while (1) ; /* not reached */
200 * Get timebase clock frequency
207 get_sys_info(&sys_info
);
208 return (sys_info
.freqSystemBus
+ 3L) / 4L;
212 #if defined(CONFIG_WATCHDOG)
217 #endif /* CONFIG_WATCHDOG */
220 #if defined(CONFIG_DDR_ECC)
224 volatile immap_t
*immap
= (immap_t
*) CFG_IMMR
;
225 volatile ccsr_dma_t
*dma
= &immap
->im_dma
;
227 dma
->satr0
= 0x00040000;
228 dma
->datr0
= 0x00040000;
235 volatile immap_t
*immap
= (immap_t
*) CFG_IMMR
;
236 volatile ccsr_dma_t
*dma
= &immap
->im_dma
;
237 volatile uint status
= dma
->sr0
;
239 /* While the channel is busy, spin */
240 while ((status
& 4) == 4) {
245 printf("DMA Error: status = %x\n", status
);
251 dma_xfer(void *dest
, uint count
, void *src
)
253 volatile immap_t
*immap
= (immap_t
*) CFG_IMMR
;
254 volatile ccsr_dma_t
*dma
= &immap
->im_dma
;
256 dma
->dar0
= (uint
) dest
;
257 dma
->sar0
= (uint
) src
;
259 dma
->mr0
= 0xf000004;
261 dma
->mr0
= 0xf000005;
266 #endif /* CONFIG_DDR_ECC */
270 * Print out the state of various machine registers.
271 * Currently prints out LAWs and BR0/OR0
273 void mpc86xx_reginfo(void)
275 immap_t
*immap
= (immap_t
*)CFG_IMMR
;
276 ccsr_lbc_t
*lbc
= &immap
->im_lbc
;
280 printf ("Local Bus Controller Registers\n"
281 "\tBR0\t0x%08X\tOR0\t0x%08X \n", in_be32(&lbc
->br0
), in_be32(&lbc
->or0
));
282 printf("\tBR1\t0x%08X\tOR1\t0x%08X \n", in_be32(&lbc
->br1
), in_be32(&lbc
->or1
));
283 printf("\tBR2\t0x%08X\tOR2\t0x%08X \n", in_be32(&lbc
->br2
), in_be32(&lbc
->or2
));
284 printf("\tBR3\t0x%08X\tOR3\t0x%08X \n", in_be32(&lbc
->br3
), in_be32(&lbc
->or3
));
285 printf("\tBR4\t0x%08X\tOR4\t0x%08X \n", in_be32(&lbc
->br4
), in_be32(&lbc
->or4
));
286 printf("\tBR5\t0x%08X\tOR5\t0x%08X \n", in_be32(&lbc
->br5
), in_be32(&lbc
->or5
));
287 printf("\tBR6\t0x%08X\tOR6\t0x%08X \n", in_be32(&lbc
->br6
), in_be32(&lbc
->or6
));
288 printf("\tBR7\t0x%08X\tOR7\t0x%08X \n", in_be32(&lbc
->br7
), in_be32(&lbc
->or7
));