blob: 964a17ca0801ab8847c5c00864e3e5f2e6763111 [file] [log] [blame]
Jon Loeligerd68e2ba2006-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
Jon Loeliger4fbb09c2006-08-22 12:25:27 -050095 vclkh = (sysclk_s << 5) | sysclk_r;
Jon Loeligerd68e2ba2006-05-30 17:47:00 -050096 vclkl = sysclk_v;
97
98 out8(PIXIS_BASE + PIXIS_VCLKH, vclkh);
99 out8(PIXIS_BASE + PIXIS_VCLKL, vclkl);
100
Jon Loeliger4fbb09c2006-08-22 12:25:27 -0500101 out8(PIXIS_BASE + PIXIS_AUX, sysclk_aux);
Jon Loeligerd68e2ba2006-05-30 17:47:00 -0500102
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:
Jon Loeliger4fbb09c2006-08-22 12:25:27 -0500121 val = (u8) mpxpll;
Jon Loeligerd68e2ba2006-05-30 17:47:00 -0500122 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);
Jon Loeliger4fbb09c2006-08-22 12:25:27 -0500248 tmp &= ~0x08;
Jon Loeligerd68e2ba2006-05-30 17:47:00 -0500249 out8(PIXIS_BASE + PIXIS_VCTL, tmp);
250
251 return 0;
252}
253
Jon Loeligerd68e2ba2006-05-30 17:47:00 -0500254U_BOOT_CMD(
Jon Loeliger4fbb09c2006-08-22 12:25:27 -0500255 diswd, 1, 0, disable_watchdog,
256 "diswd - Disable watchdog timer \n",
257 NULL);
Jon Loeligerd68e2ba2006-05-30 17:47:00 -0500258
259/*
260 * This function takes the non-integral cpu:mpx pll ratio
261 * and converts it to an integer that can be used to assign
262 * FPGA register values.
263 * input: strptr i.e. argv[2]
264 */
265
266ulong strfractoint(uchar *strptr)
267{
268 int i, j, retval;
269 int mulconst;
270 int intarr_len = 0, decarr_len = 0, no_dec = 0;
271 ulong intval = 0, decval = 0;
272 uchar intarr[3], decarr[3];
273
274 /* Assign the integer part to intarr[]
275 * If there is no decimal point i.e.
276 * if the ratio is an integral value
277 * simply create the intarr.
278 */
279 i = 0;
280 while (strptr[i] != 46) {
281 if (strptr[i] == 0) {
282 no_dec = 1;
283 break;
284 }
285 intarr[i] = strptr[i];
286 i++;
287 }
288
289 /* Assign length of integer part to intarr_len. */
290 intarr_len = i;
291 intarr[i] = '\0';
292
293 if (no_dec) {
294 /* Currently needed only for single digit corepll ratios */
Jon Loeliger4fbb09c2006-08-22 12:25:27 -0500295 mulconst = 10;
Jon Loeligerd68e2ba2006-05-30 17:47:00 -0500296 decval = 0;
297 } else {
298 j = 0;
Jon Loeliger4fbb09c2006-08-22 12:25:27 -0500299 i++; /* Skipping the decimal point */
Jon Loeligerd68e2ba2006-05-30 17:47:00 -0500300 while ((strptr[i] > 47) && (strptr[i] < 58)) {
301 decarr[j] = strptr[i];
302 i++;
303 j++;
304 }
305
306 decarr_len = j;
307 decarr[j] = '\0';
308
309 mulconst = 1;
310 for (i = 0; i < decarr_len; i++)
311 mulconst *= 10;
312 decval = simple_strtoul(decarr, NULL, 10);
313 }
314
315 intval = simple_strtoul(intarr, NULL, 10);
316 intval = intval * mulconst;
317
318 retval = intval + decval;
319
320 return retval;
321}