Merge with /home/sr/git/u-boot
[platform/kernel/u-boot.git] / cpu / mpc83xx / cpu.c
1 /*
2  * Copyright 2004 Freescale Semiconductor, Inc.
3  *
4  * See file CREDITS for list of people who contributed to this
5  * project.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 of
10  * the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20  * MA 02111-1307 USA
21  *
22  * Change log:
23  *
24  * 20050101: Eran Liberty (liberty@freescale.com)
25  *           Initial file creating (porting from 85XX & 8260)
26  */
27
28 /*
29  * CPU specific code for the MPC83xx family.
30  *
31  * Derived from the MPC8260 and MPC85xx.
32  */
33
34 #include <common.h>
35 #include <watchdog.h>
36 #include <command.h>
37 #include <mpc83xx.h>
38 #include <asm/processor.h>
39
40
41 int checkcpu(void)
42 {
43         DECLARE_GLOBAL_DATA_PTR;
44         ulong clock = gd->cpu_clk;
45         u32 pvr = get_pvr();
46         char buf[32];
47
48         if ((pvr & 0xFFFF0000) != PVR_83xx) {
49                 puts("Not MPC83xx Family!!!\n");
50                 return -1;
51         }
52
53         puts("CPU: MPC83xx, ");
54         switch(pvr) {
55         case PVR_8349_REV10:
56                 break;
57         case PVR_8349_REV11:
58                 break;
59         default:
60                 puts("Rev: Unknown\n");
61                 return -1;      /* Not sure what this is */
62         }
63         printf("Rev: %02x at %s MHz\n",pvr & 0x0000FFFF, strmhz(buf, clock));
64         return 0;
65 }
66
67
68 void upmconfig (uint upm, uint *table, uint size)
69 {
70         hang();         /* FIXME: upconfig() needed? */
71 }
72
73
74 int
75 do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
76 {
77         ulong msr;
78 #ifndef MPC83xx_RESET
79         ulong addr;
80 #endif
81
82         volatile immap_t *immap = (immap_t *) CFG_IMMRBAR;
83
84 #ifdef MPC83xx_RESET
85         /* Interrupts and MMU off */
86         __asm__ __volatile__ ("mfmsr    %0":"=r" (msr):);
87
88         msr &= ~( MSR_EE | MSR_IR | MSR_DR);
89         __asm__ __volatile__ ("mtmsr    %0"::"r" (msr));
90
91         /* enable Reset Control Reg */
92         immap->reset.rpr = 0x52535445;
93
94         /* confirm Reset Control Reg is enabled */
95         while(!((immap->reset.rcer) & RCER_CRE));
96
97         printf("Resetting the board.");
98         printf("\n");
99
100         udelay(200);
101
102         /* perform reset, only one bit */
103         immap->reset.rcr = RCR_SWHR;
104
105 #else   /* ! MPC83xx_RESET */
106
107         immap->reset.rmr = RMR_CSRE;    /* Checkstop Reset enable */
108
109         /* Interrupts and MMU off */
110         __asm__ __volatile__ ("mfmsr    %0":"=r" (msr):);
111
112         msr &= ~(MSR_ME | MSR_EE | MSR_IR | MSR_DR);
113         __asm__ __volatile__ ("mtmsr    %0"::"r" (msr));
114
115         /*
116          * Trying to execute the next instruction at a non-existing address
117          * should cause a machine check, resulting in reset
118          */
119         addr = CFG_RESET_ADDRESS;
120
121         printf("resetting the board.");
122         printf("\n");
123         ((void (*)(void)) addr) ();
124 #endif  /* MPC83xx_RESET */
125
126         return 1;
127 }
128
129
130 /*
131  * Get timebase clock frequency (like cpu_clk in Hz)
132  */
133
134 unsigned long get_tbclk(void)
135 {
136         DECLARE_GLOBAL_DATA_PTR;
137
138         ulong tbclk;
139
140         tbclk = (gd->bus_clk + 3L) / 4L;
141
142         return tbclk;
143 }
144
145
146 #if defined(CONFIG_WATCHDOG)
147 void watchdog_reset (void)
148 {
149         hang();         /* FIXME: implement watchdog_reset()? */
150 }
151 #endif /* CONFIG_WATCHDOG */