blob: f226b3e8dd3fdad699e399ee4714ac6217eeaae8 [file] [log] [blame]
Jon Loeliger126aa702006-05-30 17:47:00 -05001/*
2 * Copyright 2006 Freescale Semiconductor
3 * Jeff Brown
4 * Srikanth Srinivasan (srikanth.srinivasan@freescale.com)
5 *
6 * See file CREDITS for list of people who contributed to this
7 * project.
8 *
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.
13 *
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.
18 *
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,
22 * MA 02111-1307 USA
23 */
24
25#include <common.h>
26#include <watchdog.h>
27#include <command.h>
28#include <asm/cache.h>
29#include <mpc86xx.h>
30
31#include "pixis.h"
32
33
34/*
35 * Per table 27, page 58 of MPC8641HPCN spec.
36 */
37int set_px_sysclk(ulong sysclk)
38{
39 u8 sysclk_s, sysclk_r, sysclk_v, vclkh, vclkl, sysclk_aux;
40
41 switch (sysclk) {
42 case 33:
43 sysclk_s = 0x04;
44 sysclk_r = 0x04;
45 sysclk_v = 0x07;
46 sysclk_aux = 0x00;
47 break;
48 case 40:
49 sysclk_s = 0x01;
50 sysclk_r = 0x1F;
51 sysclk_v = 0x20;
52 sysclk_aux = 0x01;
53 break;
54 case 50:
55 sysclk_s = 0x01;
56 sysclk_r = 0x1F;
57 sysclk_v = 0x2A;
58 sysclk_aux = 0x02;
59 break;
60 case 66:
61 sysclk_s = 0x01;
62 sysclk_r = 0x04;
63 sysclk_v = 0x04;
64 sysclk_aux = 0x03;
65 break;
66 case 83:
67 sysclk_s = 0x01;
68 sysclk_r = 0x1F;
69 sysclk_v = 0x4B;
70 sysclk_aux = 0x04;
71 break;
72 case 100:
73 sysclk_s = 0x01;
74 sysclk_r = 0x1F;
75 sysclk_v = 0x5C;
76 sysclk_aux = 0x05;
77 break;
78 case 134:
79 sysclk_s = 0x06;
80 sysclk_r = 0x1F;
81 sysclk_v = 0x3B;
82 sysclk_aux = 0x06;
83 break;
84 case 166:
85 sysclk_s = 0x06;
86 sysclk_r = 0x1F;
87 sysclk_v = 0x4B;
88 sysclk_aux = 0x07;
89 break;
90 default:
91 printf("Unsupported SYSCLK frequency.\n");
92 return 0;
93 }
94
95 vclkh = (sysclk_s << 5) | sysclk_r ;
96 vclkl = sysclk_v;
97
98 out8(PIXIS_BASE + PIXIS_VCLKH, vclkh);
99 out8(PIXIS_BASE + PIXIS_VCLKL, vclkl);
100
101 out8(PIXIS_BASE + PIXIS_AUX,sysclk_aux);
102
103 return 1;
104}
105
106
107int set_px_mpxpll(ulong mpxpll)
108{
109 u8 tmp;
110 u8 val;
111
112 switch (mpxpll) {
113 case 2:
114 case 4:
115 case 6:
116 case 8:
117 case 10:
118 case 12:
119 case 14:
120 case 16:
121 val = (u8)mpxpll;
122 break;
123 default:
124 printf("Unsupported MPXPLL ratio.\n");
125 return 0;
126 }
127
128 tmp = in8(PIXIS_BASE + PIXIS_VSPEED1);
129 tmp = (tmp & 0xF0) | (val & 0x0F);
130 out8(PIXIS_BASE + PIXIS_VSPEED1, tmp);
131
132 return 1;
133}
134
135
136int set_px_corepll(ulong corepll)
137{
138 u8 tmp;
139 u8 val;
140
141 switch ((int)corepll) {
142 case 20:
143 val = 0x08;
144 break;
145 case 25:
146 val = 0x0C;
147 break;
148 case 30:
149 val = 0x10;
150 break;
151 case 35:
152 val = 0x1C;
153 break;
154 case 40:
155 val = 0x14;
156 break;
157 case 45:
158 val = 0x0E;
159 break;
160 default:
161 printf("Unsupported COREPLL ratio.\n");
162 return 0;
163 }
164
165 tmp = in8(PIXIS_BASE + PIXIS_VSPEED0);
166 tmp = (tmp & 0xE0) | (val & 0x1F);
167 out8(PIXIS_BASE + PIXIS_VSPEED0, tmp);
168
169 return 1;
170}
171
172
173void read_from_px_regs(int set)
174{
175 u8 mask = 0x1C;
176 u8 tmp = in8(PIXIS_BASE + PIXIS_VCFGEN0);
177
178 if (set)
179 tmp = tmp | mask;
180 else
181 tmp = tmp & ~mask;
182 out8(PIXIS_BASE + PIXIS_VCFGEN0, tmp);
183}
184
185
186void read_from_px_regs_altbank(int set)
187{
188 u8 mask = 0x04;
189 u8 tmp = in8(PIXIS_BASE + PIXIS_VCFGEN1);
190
191 if (set)
192 tmp = tmp | mask;
193 else
194 tmp = tmp & ~mask;
195 out8(PIXIS_BASE + PIXIS_VCFGEN1, tmp);
196}
197
198
199void set_altbank(void)
200{
201 u8 tmp;
202
203 tmp = in8(PIXIS_BASE + PIXIS_VBOOT);
204 tmp ^= 0x40;
205
206 out8(PIXIS_BASE + PIXIS_VBOOT, tmp);
207}
208
209
210void set_px_go(void)
211{
212 u8 tmp;
213
214 tmp = in8(PIXIS_BASE + PIXIS_VCTL);
215 tmp = tmp & 0x1E;
216 out8(PIXIS_BASE + PIXIS_VCTL, tmp);
217
218 tmp = in8(PIXIS_BASE + PIXIS_VCTL);
219 tmp = tmp | 0x01;
220 out8(PIXIS_BASE + PIXIS_VCTL, tmp);
221}
222
223
224void set_px_go_with_watchdog(void)
225{
226 u8 tmp;
227
228 tmp = in8(PIXIS_BASE + PIXIS_VCTL);
229 tmp = tmp & 0x1E;
230 out8(PIXIS_BASE + PIXIS_VCTL, tmp);
231
232 tmp = in8(PIXIS_BASE + PIXIS_VCTL);
233 tmp = tmp | 0x09;
234 out8(PIXIS_BASE + PIXIS_VCTL, tmp);
235}
236
237
238int disable_watchdog(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
239{
240 u8 tmp;
241
242 tmp = in8(PIXIS_BASE + PIXIS_VCTL);
243 tmp = tmp & 0x1E;
244 out8(PIXIS_BASE + PIXIS_VCTL, tmp);
245
246 /* setting VCTL[WDEN] to 0 to disable watch dog */
247 tmp = in8(PIXIS_BASE + PIXIS_VCTL);
248 tmp &= ~ 0x08;
249 out8(PIXIS_BASE + PIXIS_VCTL, tmp);
250
251 return 0;
252}
253
254
255U_BOOT_CMD(
256 diswd, 1, 0, disable_watchdog,
257 "diswd - Disable watchdog timer \n",
258 NULL
259);
260
261
262/*
263 * This function takes the non-integral cpu:mpx pll ratio
264 * and converts it to an integer that can be used to assign
265 * FPGA register values.
266 * input: strptr i.e. argv[2]
267 */
268
269ulong strfractoint(uchar *strptr)
270{
271 int i, j, retval;
272 int mulconst;
273 int intarr_len = 0, decarr_len = 0, no_dec = 0;
274 ulong intval = 0, decval = 0;
275 uchar intarr[3], decarr[3];
276
277 /* Assign the integer part to intarr[]
278 * If there is no decimal point i.e.
279 * if the ratio is an integral value
280 * simply create the intarr.
281 */
282 i = 0;
283 while (strptr[i] != 46) {
284 if (strptr[i] == 0) {
285 no_dec = 1;
286 break;
287 }
288 intarr[i] = strptr[i];
289 i++;
290 }
291
292 /* Assign length of integer part to intarr_len. */
293 intarr_len = i;
294 intarr[i] = '\0';
295
296 if (no_dec) {
297 /* Currently needed only for single digit corepll ratios */
298 mulconst=10;
299 decval = 0;
300 } else {
301 j = 0;
302 i++; /* Skipping the decimal point */
303 while ((strptr[i] > 47) && (strptr[i] < 58)) {
304 decarr[j] = strptr[i];
305 i++;
306 j++;
307 }
308
309 decarr_len = j;
310 decarr[j] = '\0';
311
312 mulconst = 1;
313 for (i = 0; i < decarr_len; i++)
314 mulconst *= 10;
315 decval = simple_strtoul(decarr, NULL, 10);
316 }
317
318 intval = simple_strtoul(intarr, NULL, 10);
319 intval = intval * mulconst;
320
321 retval = intval + decval;
322
323 return retval;
324}