]> Git Repo - J-u-boot.git/blame - board/freescale/common/pixis.c
85xx/86xx: Replace in8/out8 with in_8/out_8 on FSL boards
[J-u-boot.git] / board / freescale / common / pixis.c
CommitLineData
126aa70f
JL
1/*
2 * Copyright 2006 Freescale Semiconductor
3 * Jeff Brown
4 * Srikanth Srinivasan ([email protected])
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>
126aa70f 26#include <command.h>
3d98b858 27#include <watchdog.h>
314d5b6c 28#include <asm/cache.h>
5a8a163a 29#include <asm/io.h>
ad8f8687 30
126aa70f
JL
31#include "pixis.h"
32
33
3d98b858
HW
34static ulong strfractoint(uchar *strptr);
35
36
37/*
38 * Simple board reset.
39 */
40void pixis_reset(void)
41{
048e7efe
KG
42 u8 *pixis_base = (u8 *)PIXIS_BASE;
43 out_8(pixis_base + PIXIS_RST, 0);
3d98b858
HW
44}
45
46
126aa70f
JL
47/*
48 * Per table 27, page 58 of MPC8641HPCN spec.
49 */
50int set_px_sysclk(ulong sysclk)
51{
52 u8 sysclk_s, sysclk_r, sysclk_v, vclkh, vclkl, sysclk_aux;
048e7efe 53 u8 *pixis_base = (u8 *)PIXIS_BASE;
126aa70f
JL
54
55 switch (sysclk) {
56 case 33:
57 sysclk_s = 0x04;
58 sysclk_r = 0x04;
59 sysclk_v = 0x07;
60 sysclk_aux = 0x00;
61 break;
62 case 40:
63 sysclk_s = 0x01;
64 sysclk_r = 0x1F;
65 sysclk_v = 0x20;
66 sysclk_aux = 0x01;
67 break;
68 case 50:
69 sysclk_s = 0x01;
70 sysclk_r = 0x1F;
71 sysclk_v = 0x2A;
72 sysclk_aux = 0x02;
73 break;
74 case 66:
75 sysclk_s = 0x01;
76 sysclk_r = 0x04;
77 sysclk_v = 0x04;
78 sysclk_aux = 0x03;
79 break;
80 case 83:
81 sysclk_s = 0x01;
82 sysclk_r = 0x1F;
83 sysclk_v = 0x4B;
84 sysclk_aux = 0x04;
85 break;
86 case 100:
87 sysclk_s = 0x01;
88 sysclk_r = 0x1F;
89 sysclk_v = 0x5C;
90 sysclk_aux = 0x05;
91 break;
92 case 134:
93 sysclk_s = 0x06;
94 sysclk_r = 0x1F;
95 sysclk_v = 0x3B;
96 sysclk_aux = 0x06;
97 break;
98 case 166:
99 sysclk_s = 0x06;
100 sysclk_r = 0x1F;
101 sysclk_v = 0x4B;
102 sysclk_aux = 0x07;
103 break;
104 default:
105 printf("Unsupported SYSCLK frequency.\n");
106 return 0;
107 }
108
80e955c7 109 vclkh = (sysclk_s << 5) | sysclk_r;
126aa70f
JL
110 vclkl = sysclk_v;
111
048e7efe
KG
112 out_8(pixis_base + PIXIS_VCLKH, vclkh);
113 out_8(pixis_base + PIXIS_VCLKL, vclkl);
126aa70f 114
048e7efe 115 out_8(pixis_base + PIXIS_AUX, sysclk_aux);
126aa70f
JL
116
117 return 1;
118}
119
120
121int set_px_mpxpll(ulong mpxpll)
122{
123 u8 tmp;
124 u8 val;
048e7efe 125 u8 *pixis_base = (u8 *)PIXIS_BASE;
126aa70f
JL
126
127 switch (mpxpll) {
128 case 2:
129 case 4:
130 case 6:
131 case 8:
132 case 10:
133 case 12:
134 case 14:
135 case 16:
80e955c7 136 val = (u8) mpxpll;
126aa70f
JL
137 break;
138 default:
139 printf("Unsupported MPXPLL ratio.\n");
140 return 0;
141 }
142
048e7efe 143 tmp = in_8(pixis_base + PIXIS_VSPEED1);
126aa70f 144 tmp = (tmp & 0xF0) | (val & 0x0F);
048e7efe 145 out_8(pixis_base + PIXIS_VSPEED1, tmp);
126aa70f
JL
146
147 return 1;
148}
149
150
151int set_px_corepll(ulong corepll)
152{
153 u8 tmp;
154 u8 val;
048e7efe 155 u8 *pixis_base = (u8 *)PIXIS_BASE;
126aa70f
JL
156
157 switch ((int)corepll) {
158 case 20:
159 val = 0x08;
160 break;
161 case 25:
162 val = 0x0C;
163 break;
164 case 30:
165 val = 0x10;
166 break;
167 case 35:
168 val = 0x1C;
169 break;
170 case 40:
171 val = 0x14;
172 break;
173 case 45:
174 val = 0x0E;
175 break;
176 default:
177 printf("Unsupported COREPLL ratio.\n");
178 return 0;
179 }
180
048e7efe 181 tmp = in_8(pixis_base + PIXIS_VSPEED0);
126aa70f 182 tmp = (tmp & 0xE0) | (val & 0x1F);
048e7efe 183 out_8(pixis_base + PIXIS_VSPEED0, tmp);
126aa70f
JL
184
185 return 1;
186}
187
188
189void read_from_px_regs(int set)
190{
048e7efe 191 u8 *pixis_base = (u8 *)PIXIS_BASE;
16c3cde0 192 u8 mask = 0x1C; /* COREPLL, MPXPLL, SYSCLK controlled by PIXIS */
048e7efe 193 u8 tmp = in_8(pixis_base + PIXIS_VCFGEN0);
126aa70f
JL
194
195 if (set)
196 tmp = tmp | mask;
197 else
198 tmp = tmp & ~mask;
048e7efe 199 out_8(pixis_base + PIXIS_VCFGEN0, tmp);
126aa70f
JL
200}
201
202
203void read_from_px_regs_altbank(int set)
204{
048e7efe 205 u8 *pixis_base = (u8 *)PIXIS_BASE;
16c3cde0 206 u8 mask = 0x04; /* FLASHBANK and FLASHMAP controlled by PIXIS */
048e7efe 207 u8 tmp = in_8(pixis_base + PIXIS_VCFGEN1);
126aa70f
JL
208
209 if (set)
210 tmp = tmp | mask;
211 else
212 tmp = tmp & ~mask;
048e7efe 213 out_8(pixis_base + PIXIS_VCFGEN1, tmp);
126aa70f
JL
214}
215
6d0f6bcf
JCPV
216#ifndef CONFIG_SYS_PIXIS_VBOOT_MASK
217#define CONFIG_SYS_PIXIS_VBOOT_MASK (0x40)
db74b3c1 218#endif
126aa70f 219
16c3cde0
JY
220void clear_altbank(void)
221{
222 u8 tmp;
048e7efe 223 u8 *pixis_base = (u8 *)PIXIS_BASE;
16c3cde0 224
048e7efe 225 tmp = in_8(pixis_base + PIXIS_VBOOT);
6d0f6bcf 226 tmp &= ~CONFIG_SYS_PIXIS_VBOOT_MASK;
16c3cde0 227
048e7efe 228 out_8(pixis_base + PIXIS_VBOOT, tmp);
16c3cde0
JY
229}
230
231
126aa70f
JL
232void set_altbank(void)
233{
234 u8 tmp;
048e7efe 235 u8 *pixis_base = (u8 *)PIXIS_BASE;
126aa70f 236
048e7efe 237 tmp = in_8(pixis_base + PIXIS_VBOOT);
6d0f6bcf 238 tmp |= CONFIG_SYS_PIXIS_VBOOT_MASK;
126aa70f 239
048e7efe 240 out_8(pixis_base + PIXIS_VBOOT, tmp);
126aa70f
JL
241}
242
243
244void set_px_go(void)
245{
246 u8 tmp;
048e7efe 247 u8 *pixis_base = (u8 *)PIXIS_BASE;
126aa70f 248
048e7efe 249 tmp = in_8(pixis_base + PIXIS_VCTL);
16c3cde0 250 tmp = tmp & 0x1E; /* clear GO bit */
048e7efe 251 out_8(pixis_base + PIXIS_VCTL, tmp);
126aa70f 252
048e7efe 253 tmp = in_8(pixis_base + PIXIS_VCTL);
16c3cde0 254 tmp = tmp | 0x01; /* set GO bit - start reset sequencer */
048e7efe 255 out_8(pixis_base + PIXIS_VCTL, tmp);
126aa70f
JL
256}
257
258
259void set_px_go_with_watchdog(void)
260{
261 u8 tmp;
048e7efe 262 u8 *pixis_base = (u8 *)PIXIS_BASE;
126aa70f 263
048e7efe 264 tmp = in_8(pixis_base + PIXIS_VCTL);
126aa70f 265 tmp = tmp & 0x1E;
048e7efe 266 out_8(pixis_base + PIXIS_VCTL, tmp);
126aa70f 267
048e7efe 268 tmp = in_8(pixis_base + PIXIS_VCTL);
126aa70f 269 tmp = tmp | 0x09;
048e7efe 270 out_8(pixis_base + PIXIS_VCTL, tmp);
126aa70f
JL
271}
272
273
3d98b858
HW
274int pixis_disable_watchdog_cmd(cmd_tbl_t *cmdtp,
275 int flag, int argc, char *argv[])
126aa70f
JL
276{
277 u8 tmp;
048e7efe 278 u8 *pixis_base = (u8 *)PIXIS_BASE;
126aa70f 279
048e7efe 280 tmp = in_8(pixis_base + PIXIS_VCTL);
126aa70f 281 tmp = tmp & 0x1E;
048e7efe 282 out_8(pixis_base + PIXIS_VCTL, tmp);
126aa70f
JL
283
284 /* setting VCTL[WDEN] to 0 to disable watch dog */
048e7efe 285 tmp = in_8(pixis_base + PIXIS_VCTL);
80e955c7 286 tmp &= ~0x08;
048e7efe 287 out_8(pixis_base + PIXIS_VCTL, tmp);
126aa70f
JL
288
289 return 0;
290}
291
126aa70f 292U_BOOT_CMD(
a89c33db
WD
293 diswd, 1, 0, pixis_disable_watchdog_cmd,
294 "Disable watchdog timer",
295 ""
296);
126aa70f 297
bff188ba 298#ifdef CONFIG_PIXIS_SGMII_CMD
5a8a163a
AF
299int pixis_set_sgmii(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
300{
301 int which_tsec = -1;
048e7efe 302 u8 *pixis_base = (u8 *)PIXIS_BASE;
5a8a163a
AF
303 uchar mask;
304 uchar switch_mask;
305
306 if (argc > 2)
307 if (strcmp(argv[1], "all") != 0)
308 which_tsec = simple_strtoul(argv[1], NULL, 0);
309
310 switch (which_tsec) {
bff188ba 311#ifdef CONFIG_TSEC1
5a8a163a
AF
312 case 1:
313 mask = PIXIS_VSPEED2_TSEC1SER;
314 switch_mask = PIXIS_VCFGEN1_TSEC1SER;
315 break;
bff188ba
LY
316#endif
317#ifdef CONFIG_TSEC2
318 case 2:
319 mask = PIXIS_VSPEED2_TSEC2SER;
320 switch_mask = PIXIS_VCFGEN1_TSEC2SER;
321 break;
322#endif
323#ifdef CONFIG_TSEC3
5a8a163a
AF
324 case 3:
325 mask = PIXIS_VSPEED2_TSEC3SER;
326 switch_mask = PIXIS_VCFGEN1_TSEC3SER;
327 break;
bff188ba
LY
328#endif
329#ifdef CONFIG_TSEC4
330 case 4:
331 mask = PIXIS_VSPEED2_TSEC4SER;
332 switch_mask = PIXIS_VCFGEN1_TSEC4SER;
333 break;
334#endif
5a8a163a 335 default:
bff188ba
LY
336 mask = PIXIS_VSPEED2_MASK;
337 switch_mask = PIXIS_VCFGEN1_MASK;
5a8a163a
AF
338 break;
339 }
340
341 /* Toggle whether the switches or FPGA control the settings */
342 if (!strcmp(argv[argc - 1], "switch"))
048e7efe 343 clrbits_8(pixis_base + PIXIS_VCFGEN1, switch_mask);
5a8a163a 344 else
048e7efe 345 setbits_8(pixis_base + PIXIS_VCFGEN1, switch_mask);
5a8a163a
AF
346
347 /* If it's not the switches, enable or disable SGMII, as specified */
348 if (!strcmp(argv[argc - 1], "on"))
048e7efe 349 clrbits_8(pixis_base + PIXIS_VSPEED2, mask);
5a8a163a 350 else if (!strcmp(argv[argc - 1], "off"))
048e7efe 351 setbits_8(pixis_base + PIXIS_VSPEED2, mask);
5a8a163a
AF
352
353 return 0;
354}
355
356U_BOOT_CMD(
a89c33db
WD
357 pixis_set_sgmii, CONFIG_SYS_MAXARGS, 1, pixis_set_sgmii,
358 "pixis_set_sgmii"
359 " - Enable or disable SGMII mode for a given TSEC \n",
360 "\npixis_set_sgmii [TSEC num] <on|off|switch>\n"
361 " TSEC num: 1,2,3,4 or 'all'. 'all' is default.\n"
362 " on - enables SGMII\n"
363 " off - disables SGMII\n"
364 " switch - use switch settings"
365);
5a8a163a
AF
366#endif
367
126aa70f
JL
368/*
369 * This function takes the non-integral cpu:mpx pll ratio
370 * and converts it to an integer that can be used to assign
371 * FPGA register values.
372 * input: strptr i.e. argv[2]
373 */
374
3d98b858 375static ulong strfractoint(uchar *strptr)
126aa70f
JL
376{
377 int i, j, retval;
378 int mulconst;
379 int intarr_len = 0, decarr_len = 0, no_dec = 0;
380 ulong intval = 0, decval = 0;
381 uchar intarr[3], decarr[3];
382
383 /* Assign the integer part to intarr[]
384 * If there is no decimal point i.e.
385 * if the ratio is an integral value
386 * simply create the intarr.
387 */
388 i = 0;
16c3cde0 389 while (strptr[i] != '.') {
126aa70f
JL
390 if (strptr[i] == 0) {
391 no_dec = 1;
392 break;
393 }
394 intarr[i] = strptr[i];
395 i++;
396 }
397
398 /* Assign length of integer part to intarr_len. */
399 intarr_len = i;
400 intarr[i] = '\0';
401
402 if (no_dec) {
403 /* Currently needed only for single digit corepll ratios */
80e955c7 404 mulconst = 10;
126aa70f
JL
405 decval = 0;
406 } else {
407 j = 0;
80e955c7 408 i++; /* Skipping the decimal point */
16c3cde0 409 while ((strptr[i] >= '0') && (strptr[i] <= '9')) {
126aa70f
JL
410 decarr[j] = strptr[i];
411 i++;
412 j++;
413 }
414
415 decarr_len = j;
416 decarr[j] = '\0';
417
418 mulconst = 1;
419 for (i = 0; i < decarr_len; i++)
420 mulconst *= 10;
cdd917a4 421 decval = simple_strtoul((char *)decarr, NULL, 10);
126aa70f
JL
422 }
423
cdd917a4 424 intval = simple_strtoul((char *)intarr, NULL, 10);
126aa70f
JL
425 intval = intval * mulconst;
426
427 retval = intval + decval;
428
429 return retval;
430}
3d98b858
HW
431
432
433int
434pixis_reset_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
435{
16c3cde0
JY
436 unsigned int i;
437 char *p_cf = NULL;
438 char *p_cf_sysclk = NULL;
439 char *p_cf_corepll = NULL;
440 char *p_cf_mpxpll = NULL;
441 char *p_altbank = NULL;
442 char *p_wd = NULL;
443 unsigned int unknown_param = 0;
3d98b858
HW
444
445 /*
446 * No args is a simple reset request.
447 */
448 if (argc <= 1) {
449 pixis_reset();
450 /* not reached */
451 }
452
16c3cde0
JY
453 for (i = 1; i < argc; i++) {
454 if (strcmp(argv[i], "cf") == 0) {
455 p_cf = argv[i];
456 if (i + 3 >= argc) {
457 break;
458 }
459 p_cf_sysclk = argv[i+1];
460 p_cf_corepll = argv[i+2];
461 p_cf_mpxpll = argv[i+3];
462 i += 3;
463 continue;
464 }
3d98b858 465
16c3cde0
JY
466 if (strcmp(argv[i], "altbank") == 0) {
467 p_altbank = argv[i];
468 continue;
3d98b858
HW
469 }
470
16c3cde0
JY
471 if (strcmp(argv[i], "wd") == 0) {
472 p_wd = argv[i];
473 continue;
3d98b858
HW
474 }
475
16c3cde0
JY
476 unknown_param = 1;
477 }
3d98b858 478
16c3cde0
JY
479 /*
480 * Check that cf has all required parms
481 */
482 if ((p_cf && !(p_cf_sysclk && p_cf_corepll && p_cf_mpxpll))
53677ef1 483 || unknown_param) {
f7fecc3e 484#ifdef CONFIG_SYS_LONGHELP
16c3cde0 485 puts(cmdtp->help);
f7fecc3e 486#endif
16c3cde0
JY
487 return 1;
488 }
489
490 /*
491 * PIXIS seems to be sensitive to the ordering of
492 * the registers that are touched.
493 */
494 read_from_px_regs(0);
495
496 if (p_altbank) {
497 read_from_px_regs_altbank(0);
498 }
499 clear_altbank();
500
501 /*
502 * Clock configuration specified.
503 */
504 if (p_cf) {
505 unsigned long sysclk;
506 unsigned long corepll;
507 unsigned long mpxpll;
508
509 sysclk = simple_strtoul(p_cf_sysclk, NULL, 10);
510 corepll = strfractoint((uchar *) p_cf_corepll);
511 mpxpll = simple_strtoul(p_cf_mpxpll, NULL, 10);
512
513 if (!(set_px_sysclk(sysclk)
514 && set_px_corepll(corepll)
515 && set_px_mpxpll(mpxpll))) {
f7fecc3e 516#ifdef CONFIG_SYS_LONGHELP
16c3cde0 517 puts(cmdtp->help);
f7fecc3e 518#endif
3d98b858
HW
519 return 1;
520 }
16c3cde0
JY
521 read_from_px_regs(1);
522 }
3d98b858 523
16c3cde0
JY
524 /*
525 * Altbank specified
526 *
527 * NOTE CHANGE IN BEHAVIOR: previous code would default
528 * to enabling watchdog if altbank is specified.
529 * Now the watchdog must be enabled explicitly using 'wd'.
530 */
531 if (p_altbank) {
532 set_altbank();
533 read_from_px_regs_altbank(1);
534 }
535
536 /*
537 * Reset with watchdog specified.
538 */
539 if (p_wd) {
540 set_px_go_with_watchdog();
3d98b858 541 } else {
16c3cde0 542 set_px_go();
3d98b858
HW
543 }
544
16c3cde0
JY
545 /*
546 * Shouldn't be reached.
547 */
3d98b858
HW
548 return 0;
549}
550
551
552U_BOOT_CMD(
6d0f6bcf 553 pixis_reset, CONFIG_SYS_MAXARGS, 1, pixis_reset_cmd,
2fb2604d 554 "Reset the board using the FPGA sequencer",
3d98b858
HW
555 " pixis_reset\n"
556 " pixis_reset [altbank]\n"
557 " pixis_reset altbank wd\n"
558 " pixis_reset altbank cf <SYSCLK freq> <COREPLL ratio> <MPXPLL ratio>\n"
a89c33db
WD
559 " pixis_reset cf <SYSCLK freq> <COREPLL ratio> <MPXPLL ratio>"
560);
This page took 0.182481 seconds and 4 git commands to generate.