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>
34 static ulong strfractoint(uchar *strptr);
40 void pixis_reset(void)
42 u8 *pixis_base = (u8 *)PIXIS_BASE;
43 out_8(pixis_base + PIXIS_RST, 0);
48 * Per table 27, page 58 of MPC8641HPCN spec.
50 int set_px_sysclk(ulong sysclk)
52 u8 sysclk_s, sysclk_r, sysclk_v, vclkh, vclkl, sysclk_aux;
53 u8 *pixis_base = (u8 *)PIXIS_BASE;
105 printf("Unsupported SYSCLK frequency.\n");
109 vclkh = (sysclk_s << 5) | sysclk_r;
112 out_8(pixis_base + PIXIS_VCLKH, vclkh);
113 out_8(pixis_base + PIXIS_VCLKL, vclkl);
115 out_8(pixis_base + PIXIS_AUX, sysclk_aux);
121 int set_px_mpxpll(ulong mpxpll)
125 u8 *pixis_base = (u8 *)PIXIS_BASE;
139 printf("Unsupported MPXPLL ratio.\n");
143 tmp = in_8(pixis_base + PIXIS_VSPEED1);
144 tmp = (tmp & 0xF0) | (val & 0x0F);
145 out_8(pixis_base + PIXIS_VSPEED1, tmp);
151 int set_px_corepll(ulong corepll)
155 u8 *pixis_base = (u8 *)PIXIS_BASE;
157 switch ((int)corepll) {
177 printf("Unsupported COREPLL ratio.\n");
181 tmp = in_8(pixis_base + PIXIS_VSPEED0);
182 tmp = (tmp & 0xE0) | (val & 0x1F);
183 out_8(pixis_base + PIXIS_VSPEED0, tmp);
189 void read_from_px_regs(int set)
191 u8 *pixis_base = (u8 *)PIXIS_BASE;
192 u8 mask = 0x1C; /* COREPLL, MPXPLL, SYSCLK controlled by PIXIS */
193 u8 tmp = in_8(pixis_base + PIXIS_VCFGEN0);
199 out_8(pixis_base + PIXIS_VCFGEN0, tmp);
203 void read_from_px_regs_altbank(int set)
205 u8 *pixis_base = (u8 *)PIXIS_BASE;
206 u8 mask = 0x04; /* FLASHBANK and FLASHMAP controlled by PIXIS */
207 u8 tmp = in_8(pixis_base + PIXIS_VCFGEN1);
213 out_8(pixis_base + PIXIS_VCFGEN1, tmp);
216 #ifndef CONFIG_SYS_PIXIS_VBOOT_MASK
217 #define CONFIG_SYS_PIXIS_VBOOT_MASK (0x40)
220 void clear_altbank(void)
223 u8 *pixis_base = (u8 *)PIXIS_BASE;
225 tmp = in_8(pixis_base + PIXIS_VBOOT);
226 tmp &= ~CONFIG_SYS_PIXIS_VBOOT_MASK;
228 out_8(pixis_base + PIXIS_VBOOT, tmp);
232 void set_altbank(void)
235 u8 *pixis_base = (u8 *)PIXIS_BASE;
237 tmp = in_8(pixis_base + PIXIS_VBOOT);
238 tmp |= CONFIG_SYS_PIXIS_VBOOT_MASK;
240 out_8(pixis_base + PIXIS_VBOOT, tmp);
247 u8 *pixis_base = (u8 *)PIXIS_BASE;
249 tmp = in_8(pixis_base + PIXIS_VCTL);
250 tmp = tmp & 0x1E; /* clear GO bit */
251 out_8(pixis_base + PIXIS_VCTL, tmp);
253 tmp = in_8(pixis_base + PIXIS_VCTL);
254 tmp = tmp | 0x01; /* set GO bit - start reset sequencer */
255 out_8(pixis_base + PIXIS_VCTL, tmp);
259 void set_px_go_with_watchdog(void)
262 u8 *pixis_base = (u8 *)PIXIS_BASE;
264 tmp = in_8(pixis_base + PIXIS_VCTL);
266 out_8(pixis_base + PIXIS_VCTL, tmp);
268 tmp = in_8(pixis_base + PIXIS_VCTL);
270 out_8(pixis_base + PIXIS_VCTL, tmp);
274 int pixis_disable_watchdog_cmd(cmd_tbl_t *cmdtp,
275 int flag, int argc, char *argv[])
278 u8 *pixis_base = (u8 *)PIXIS_BASE;
280 tmp = in_8(pixis_base + PIXIS_VCTL);
282 out_8(pixis_base + PIXIS_VCTL, tmp);
284 /* setting VCTL[WDEN] to 0 to disable watch dog */
285 tmp = in_8(pixis_base + PIXIS_VCTL);
287 out_8(pixis_base + PIXIS_VCTL, tmp);
293 diswd, 1, 0, pixis_disable_watchdog_cmd,
294 "Disable watchdog timer",
298 #ifdef CONFIG_PIXIS_SGMII_CMD
299 int pixis_set_sgmii(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
302 u8 *pixis_base = (u8 *)PIXIS_BASE;
307 if (strcmp(argv[1], "all") != 0)
308 which_tsec = simple_strtoul(argv[1], NULL, 0);
310 switch (which_tsec) {
313 mask = PIXIS_VSPEED2_TSEC1SER;
314 switch_mask = PIXIS_VCFGEN1_TSEC1SER;
319 mask = PIXIS_VSPEED2_TSEC2SER;
320 switch_mask = PIXIS_VCFGEN1_TSEC2SER;
325 mask = PIXIS_VSPEED2_TSEC3SER;
326 switch_mask = PIXIS_VCFGEN1_TSEC3SER;
331 mask = PIXIS_VSPEED2_TSEC4SER;
332 switch_mask = PIXIS_VCFGEN1_TSEC4SER;
336 mask = PIXIS_VSPEED2_MASK;
337 switch_mask = PIXIS_VCFGEN1_MASK;
341 /* Toggle whether the switches or FPGA control the settings */
342 if (!strcmp(argv[argc - 1], "switch"))
343 clrbits_8(pixis_base + PIXIS_VCFGEN1, switch_mask);
345 setbits_8(pixis_base + PIXIS_VCFGEN1, switch_mask);
347 /* If it's not the switches, enable or disable SGMII, as specified */
348 if (!strcmp(argv[argc - 1], "on"))
349 clrbits_8(pixis_base + PIXIS_VSPEED2, mask);
350 else if (!strcmp(argv[argc - 1], "off"))
351 setbits_8(pixis_base + PIXIS_VSPEED2, mask);
357 pixis_set_sgmii, CONFIG_SYS_MAXARGS, 1, 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"
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]
375 static ulong strfractoint(uchar *strptr)
379 int intarr_len = 0, decarr_len = 0, no_dec = 0;
380 ulong intval = 0, decval = 0;
381 uchar intarr[3], decarr[3];
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.
389 while (strptr[i] != '.') {
390 if (strptr[i] == 0) {
394 intarr[i] = strptr[i];
398 /* Assign length of integer part to intarr_len. */
403 /* Currently needed only for single digit corepll ratios */
408 i++; /* Skipping the decimal point */
409 while ((strptr[i] >= '0') && (strptr[i] <= '9')) {
410 decarr[j] = strptr[i];
419 for (i = 0; i < decarr_len; i++)
421 decval = simple_strtoul((char *)decarr, NULL, 10);
424 intval = simple_strtoul((char *)intarr, NULL, 10);
425 intval = intval * mulconst;
427 retval = intval + decval;
434 pixis_reset_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
438 char *p_cf_sysclk = NULL;
439 char *p_cf_corepll = NULL;
440 char *p_cf_mpxpll = NULL;
441 char *p_altbank = NULL;
443 unsigned int unknown_param = 0;
446 * No args is a simple reset request.
453 for (i = 1; i < argc; i++) {
454 if (strcmp(argv[i], "cf") == 0) {
459 p_cf_sysclk = argv[i+1];
460 p_cf_corepll = argv[i+2];
461 p_cf_mpxpll = argv[i+3];
466 if (strcmp(argv[i], "altbank") == 0) {
471 if (strcmp(argv[i], "wd") == 0) {
480 * Check that cf has all required parms
482 if ((p_cf && !(p_cf_sysclk && p_cf_corepll && p_cf_mpxpll))
484 #ifdef CONFIG_SYS_LONGHELP
491 * PIXIS seems to be sensitive to the ordering of
492 * the registers that are touched.
494 read_from_px_regs(0);
497 read_from_px_regs_altbank(0);
502 * Clock configuration specified.
505 unsigned long sysclk;
506 unsigned long corepll;
507 unsigned long mpxpll;
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);
513 if (!(set_px_sysclk(sysclk)
514 && set_px_corepll(corepll)
515 && set_px_mpxpll(mpxpll))) {
516 #ifdef CONFIG_SYS_LONGHELP
521 read_from_px_regs(1);
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'.
533 read_from_px_regs_altbank(1);
537 * Reset with watchdog specified.
540 set_px_go_with_watchdog();
546 * Shouldn't be reached.
553 pixis_reset, CONFIG_SYS_MAXARGS, 1, pixis_reset_cmd,
554 "Reset the board using the FPGA sequencer",
556 " pixis_reset [altbank]\n"
557 " pixis_reset altbank wd\n"
558 " pixis_reset altbank cf <SYSCLK freq> <COREPLL ratio> <MPXPLL ratio>\n"
559 " pixis_reset cf <SYSCLK freq> <COREPLL ratio> <MPXPLL ratio>"