13d98b858SHaiying Wang /* 23d98b858SHaiying Wang * Copyright 2006 Freescale Semiconductor 33d98b858SHaiying Wang * Jeff Brown 43d98b858SHaiying Wang * Srikanth Srinivasan (srikanth.srinivasan@freescale.com) 53d98b858SHaiying Wang * 63d98b858SHaiying Wang * See file CREDITS for list of people who contributed to this 73d98b858SHaiying Wang * project. 83d98b858SHaiying Wang * 93d98b858SHaiying Wang * This program is free software; you can redistribute it and/or 103d98b858SHaiying Wang * modify it under the terms of the GNU General Public License as 113d98b858SHaiying Wang * published by the Free Software Foundation; either version 2 of 123d98b858SHaiying Wang * the License, or (at your option) any later version. 133d98b858SHaiying Wang * 143d98b858SHaiying Wang * This program is distributed in the hope that it will be useful, 153d98b858SHaiying Wang * but WITHOUT ANY WARRANTY; without even the implied warranty of 163d98b858SHaiying Wang * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 173d98b858SHaiying Wang * GNU General Public License for more details. 183d98b858SHaiying Wang * 193d98b858SHaiying Wang * You should have received a copy of the GNU General Public License 203d98b858SHaiying Wang * along with this program; if not, write to the Free Software 213d98b858SHaiying Wang * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 223d98b858SHaiying Wang * MA 02111-1307 USA 233d98b858SHaiying Wang */ 243d98b858SHaiying Wang 253d98b858SHaiying Wang #include <common.h> 263d98b858SHaiying Wang #include <command.h> 273d98b858SHaiying Wang #include <watchdog.h> 28314d5b6cSLiew Tsi Chung-r5aahp #include <asm/cache.h> 295a8a163aSAndy Fleming #include <asm/io.h> 30ad8f8687SJon Loeliger 313d98b858SHaiying Wang #include "pixis.h" 323d98b858SHaiying Wang 333d98b858SHaiying Wang 343d98b858SHaiying Wang static ulong strfractoint(uchar *strptr); 353d98b858SHaiying Wang 363d98b858SHaiying Wang 373d98b858SHaiying Wang /* 383d98b858SHaiying Wang * Simple board reset. 393d98b858SHaiying Wang */ 403d98b858SHaiying Wang void pixis_reset(void) 413d98b858SHaiying Wang { 423d98b858SHaiying Wang out8(PIXIS_BASE + PIXIS_RST, 0); 433d98b858SHaiying Wang } 443d98b858SHaiying Wang 453d98b858SHaiying Wang 463d98b858SHaiying Wang /* 473d98b858SHaiying Wang * Per table 27, page 58 of MPC8641HPCN spec. 483d98b858SHaiying Wang */ 493d98b858SHaiying Wang int set_px_sysclk(ulong sysclk) 503d98b858SHaiying Wang { 513d98b858SHaiying Wang u8 sysclk_s, sysclk_r, sysclk_v, vclkh, vclkl, sysclk_aux; 523d98b858SHaiying Wang 533d98b858SHaiying Wang switch (sysclk) { 543d98b858SHaiying Wang case 33: 553d98b858SHaiying Wang sysclk_s = 0x04; 563d98b858SHaiying Wang sysclk_r = 0x04; 573d98b858SHaiying Wang sysclk_v = 0x07; 583d98b858SHaiying Wang sysclk_aux = 0x00; 593d98b858SHaiying Wang break; 603d98b858SHaiying Wang case 40: 613d98b858SHaiying Wang sysclk_s = 0x01; 623d98b858SHaiying Wang sysclk_r = 0x1F; 633d98b858SHaiying Wang sysclk_v = 0x20; 643d98b858SHaiying Wang sysclk_aux = 0x01; 653d98b858SHaiying Wang break; 663d98b858SHaiying Wang case 50: 673d98b858SHaiying Wang sysclk_s = 0x01; 683d98b858SHaiying Wang sysclk_r = 0x1F; 693d98b858SHaiying Wang sysclk_v = 0x2A; 703d98b858SHaiying Wang sysclk_aux = 0x02; 713d98b858SHaiying Wang break; 723d98b858SHaiying Wang case 66: 733d98b858SHaiying Wang sysclk_s = 0x01; 743d98b858SHaiying Wang sysclk_r = 0x04; 753d98b858SHaiying Wang sysclk_v = 0x04; 763d98b858SHaiying Wang sysclk_aux = 0x03; 773d98b858SHaiying Wang break; 783d98b858SHaiying Wang case 83: 793d98b858SHaiying Wang sysclk_s = 0x01; 803d98b858SHaiying Wang sysclk_r = 0x1F; 813d98b858SHaiying Wang sysclk_v = 0x4B; 823d98b858SHaiying Wang sysclk_aux = 0x04; 833d98b858SHaiying Wang break; 843d98b858SHaiying Wang case 100: 853d98b858SHaiying Wang sysclk_s = 0x01; 863d98b858SHaiying Wang sysclk_r = 0x1F; 873d98b858SHaiying Wang sysclk_v = 0x5C; 883d98b858SHaiying Wang sysclk_aux = 0x05; 893d98b858SHaiying Wang break; 903d98b858SHaiying Wang case 134: 913d98b858SHaiying Wang sysclk_s = 0x06; 923d98b858SHaiying Wang sysclk_r = 0x1F; 933d98b858SHaiying Wang sysclk_v = 0x3B; 943d98b858SHaiying Wang sysclk_aux = 0x06; 953d98b858SHaiying Wang break; 963d98b858SHaiying Wang case 166: 973d98b858SHaiying Wang sysclk_s = 0x06; 983d98b858SHaiying Wang sysclk_r = 0x1F; 993d98b858SHaiying Wang sysclk_v = 0x4B; 1003d98b858SHaiying Wang sysclk_aux = 0x07; 1013d98b858SHaiying Wang break; 1023d98b858SHaiying Wang default: 1033d98b858SHaiying Wang printf("Unsupported SYSCLK frequency.\n"); 1043d98b858SHaiying Wang return 0; 1053d98b858SHaiying Wang } 1063d98b858SHaiying Wang 1073d98b858SHaiying Wang vclkh = (sysclk_s << 5) | sysclk_r; 1083d98b858SHaiying Wang vclkl = sysclk_v; 1093d98b858SHaiying Wang 1103d98b858SHaiying Wang out8(PIXIS_BASE + PIXIS_VCLKH, vclkh); 1113d98b858SHaiying Wang out8(PIXIS_BASE + PIXIS_VCLKL, vclkl); 1123d98b858SHaiying Wang 1133d98b858SHaiying Wang out8(PIXIS_BASE + PIXIS_AUX, sysclk_aux); 1143d98b858SHaiying Wang 1153d98b858SHaiying Wang return 1; 1163d98b858SHaiying Wang } 1173d98b858SHaiying Wang 1183d98b858SHaiying Wang 1193d98b858SHaiying Wang int set_px_mpxpll(ulong mpxpll) 1203d98b858SHaiying Wang { 1213d98b858SHaiying Wang u8 tmp; 1223d98b858SHaiying Wang u8 val; 1233d98b858SHaiying Wang 1243d98b858SHaiying Wang switch (mpxpll) { 1253d98b858SHaiying Wang case 2: 1263d98b858SHaiying Wang case 4: 1273d98b858SHaiying Wang case 6: 1283d98b858SHaiying Wang case 8: 1293d98b858SHaiying Wang case 10: 1303d98b858SHaiying Wang case 12: 1313d98b858SHaiying Wang case 14: 1323d98b858SHaiying Wang case 16: 1333d98b858SHaiying Wang val = (u8) mpxpll; 1343d98b858SHaiying Wang break; 1353d98b858SHaiying Wang default: 1363d98b858SHaiying Wang printf("Unsupported MPXPLL ratio.\n"); 1373d98b858SHaiying Wang return 0; 1383d98b858SHaiying Wang } 1393d98b858SHaiying Wang 1403d98b858SHaiying Wang tmp = in8(PIXIS_BASE + PIXIS_VSPEED1); 1413d98b858SHaiying Wang tmp = (tmp & 0xF0) | (val & 0x0F); 1423d98b858SHaiying Wang out8(PIXIS_BASE + PIXIS_VSPEED1, tmp); 1433d98b858SHaiying Wang 1443d98b858SHaiying Wang return 1; 1453d98b858SHaiying Wang } 1463d98b858SHaiying Wang 1473d98b858SHaiying Wang 1483d98b858SHaiying Wang int set_px_corepll(ulong corepll) 1493d98b858SHaiying Wang { 1503d98b858SHaiying Wang u8 tmp; 1513d98b858SHaiying Wang u8 val; 1523d98b858SHaiying Wang 1533d98b858SHaiying Wang switch ((int)corepll) { 1543d98b858SHaiying Wang case 20: 1553d98b858SHaiying Wang val = 0x08; 1563d98b858SHaiying Wang break; 1573d98b858SHaiying Wang case 25: 1583d98b858SHaiying Wang val = 0x0C; 1593d98b858SHaiying Wang break; 1603d98b858SHaiying Wang case 30: 1613d98b858SHaiying Wang val = 0x10; 1623d98b858SHaiying Wang break; 1633d98b858SHaiying Wang case 35: 1643d98b858SHaiying Wang val = 0x1C; 1653d98b858SHaiying Wang break; 1663d98b858SHaiying Wang case 40: 1673d98b858SHaiying Wang val = 0x14; 1683d98b858SHaiying Wang break; 1693d98b858SHaiying Wang case 45: 1703d98b858SHaiying Wang val = 0x0E; 1713d98b858SHaiying Wang break; 1723d98b858SHaiying Wang default: 1733d98b858SHaiying Wang printf("Unsupported COREPLL ratio.\n"); 1743d98b858SHaiying Wang return 0; 1753d98b858SHaiying Wang } 1763d98b858SHaiying Wang 1773d98b858SHaiying Wang tmp = in8(PIXIS_BASE + PIXIS_VSPEED0); 1783d98b858SHaiying Wang tmp = (tmp & 0xE0) | (val & 0x1F); 1793d98b858SHaiying Wang out8(PIXIS_BASE + PIXIS_VSPEED0, tmp); 1803d98b858SHaiying Wang 1813d98b858SHaiying Wang return 1; 1823d98b858SHaiying Wang } 1833d98b858SHaiying Wang 1843d98b858SHaiying Wang 1853d98b858SHaiying Wang void read_from_px_regs(int set) 1863d98b858SHaiying Wang { 18716c3cde0SJames Yang u8 mask = 0x1C; /* COREPLL, MPXPLL, SYSCLK controlled by PIXIS */ 1883d98b858SHaiying Wang u8 tmp = in8(PIXIS_BASE + PIXIS_VCFGEN0); 1893d98b858SHaiying Wang 1903d98b858SHaiying Wang if (set) 1913d98b858SHaiying Wang tmp = tmp | mask; 1923d98b858SHaiying Wang else 1933d98b858SHaiying Wang tmp = tmp & ~mask; 1943d98b858SHaiying Wang out8(PIXIS_BASE + PIXIS_VCFGEN0, tmp); 1953d98b858SHaiying Wang } 1963d98b858SHaiying Wang 1973d98b858SHaiying Wang 1983d98b858SHaiying Wang void read_from_px_regs_altbank(int set) 1993d98b858SHaiying Wang { 20016c3cde0SJames Yang u8 mask = 0x04; /* FLASHBANK and FLASHMAP controlled by PIXIS */ 2013d98b858SHaiying Wang u8 tmp = in8(PIXIS_BASE + PIXIS_VCFGEN1); 2023d98b858SHaiying Wang 2033d98b858SHaiying Wang if (set) 2043d98b858SHaiying Wang tmp = tmp | mask; 2053d98b858SHaiying Wang else 2063d98b858SHaiying Wang tmp = tmp & ~mask; 2073d98b858SHaiying Wang out8(PIXIS_BASE + PIXIS_VCFGEN1, tmp); 2083d98b858SHaiying Wang } 2093d98b858SHaiying Wang 2106d0f6bcfSJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_SYS_PIXIS_VBOOT_MASK 2116d0f6bcfSJean-Christophe PLAGNIOL-VILLARD #define CONFIG_SYS_PIXIS_VBOOT_MASK (0x40) 212db74b3c1SJason Jin #endif 2133d98b858SHaiying Wang 21416c3cde0SJames Yang void clear_altbank(void) 21516c3cde0SJames Yang { 21616c3cde0SJames Yang u8 tmp; 21716c3cde0SJames Yang 21816c3cde0SJames Yang tmp = in8(PIXIS_BASE + PIXIS_VBOOT); 2196d0f6bcfSJean-Christophe PLAGNIOL-VILLARD tmp &= ~CONFIG_SYS_PIXIS_VBOOT_MASK; 22016c3cde0SJames Yang 22116c3cde0SJames Yang out8(PIXIS_BASE + PIXIS_VBOOT, tmp); 22216c3cde0SJames Yang } 22316c3cde0SJames Yang 22416c3cde0SJames Yang 2253d98b858SHaiying Wang void set_altbank(void) 2263d98b858SHaiying Wang { 2273d98b858SHaiying Wang u8 tmp; 2283d98b858SHaiying Wang 2293d98b858SHaiying Wang tmp = in8(PIXIS_BASE + PIXIS_VBOOT); 2306d0f6bcfSJean-Christophe PLAGNIOL-VILLARD tmp |= CONFIG_SYS_PIXIS_VBOOT_MASK; 2313d98b858SHaiying Wang 2323d98b858SHaiying Wang out8(PIXIS_BASE + PIXIS_VBOOT, tmp); 2333d98b858SHaiying Wang } 2343d98b858SHaiying Wang 2353d98b858SHaiying Wang 2363d98b858SHaiying Wang void set_px_go(void) 2373d98b858SHaiying Wang { 2383d98b858SHaiying Wang u8 tmp; 2393d98b858SHaiying Wang 2403d98b858SHaiying Wang tmp = in8(PIXIS_BASE + PIXIS_VCTL); 24116c3cde0SJames Yang tmp = tmp & 0x1E; /* clear GO bit */ 2423d98b858SHaiying Wang out8(PIXIS_BASE + PIXIS_VCTL, tmp); 2433d98b858SHaiying Wang 2443d98b858SHaiying Wang tmp = in8(PIXIS_BASE + PIXIS_VCTL); 24516c3cde0SJames Yang tmp = tmp | 0x01; /* set GO bit - start reset sequencer */ 2463d98b858SHaiying Wang out8(PIXIS_BASE + PIXIS_VCTL, tmp); 2473d98b858SHaiying Wang } 2483d98b858SHaiying Wang 2493d98b858SHaiying Wang 2503d98b858SHaiying Wang void set_px_go_with_watchdog(void) 2513d98b858SHaiying Wang { 2523d98b858SHaiying Wang u8 tmp; 2533d98b858SHaiying Wang 2543d98b858SHaiying Wang tmp = in8(PIXIS_BASE + PIXIS_VCTL); 2553d98b858SHaiying Wang tmp = tmp & 0x1E; 2563d98b858SHaiying Wang out8(PIXIS_BASE + PIXIS_VCTL, tmp); 2573d98b858SHaiying Wang 2583d98b858SHaiying Wang tmp = in8(PIXIS_BASE + PIXIS_VCTL); 2593d98b858SHaiying Wang tmp = tmp | 0x09; 2603d98b858SHaiying Wang out8(PIXIS_BASE + PIXIS_VCTL, tmp); 2613d98b858SHaiying Wang } 2623d98b858SHaiying Wang 2633d98b858SHaiying Wang 2643d98b858SHaiying Wang int pixis_disable_watchdog_cmd(cmd_tbl_t *cmdtp, 2653d98b858SHaiying Wang int flag, int argc, char *argv[]) 2663d98b858SHaiying Wang { 2673d98b858SHaiying Wang u8 tmp; 2683d98b858SHaiying Wang 2693d98b858SHaiying Wang tmp = in8(PIXIS_BASE + PIXIS_VCTL); 2703d98b858SHaiying Wang tmp = tmp & 0x1E; 2713d98b858SHaiying Wang out8(PIXIS_BASE + PIXIS_VCTL, tmp); 2723d98b858SHaiying Wang 2733d98b858SHaiying Wang /* setting VCTL[WDEN] to 0 to disable watch dog */ 2743d98b858SHaiying Wang tmp = in8(PIXIS_BASE + PIXIS_VCTL); 2753d98b858SHaiying Wang tmp &= ~0x08; 2763d98b858SHaiying Wang out8(PIXIS_BASE + PIXIS_VCTL, tmp); 2773d98b858SHaiying Wang 2783d98b858SHaiying Wang return 0; 2793d98b858SHaiying Wang } 2803d98b858SHaiying Wang 2813d98b858SHaiying Wang U_BOOT_CMD( 2823d98b858SHaiying Wang diswd, 1, 0, pixis_disable_watchdog_cmd, 2832fb2604dSPeter Tyser "Disable watchdog timer", 284*a89c33dbSWolfgang Denk "" 285*a89c33dbSWolfgang Denk ); 2863d98b858SHaiying Wang 287bff188baSLiu Yu #ifdef CONFIG_PIXIS_SGMII_CMD 2885a8a163aSAndy Fleming int pixis_set_sgmii(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) 2895a8a163aSAndy Fleming { 2905a8a163aSAndy Fleming int which_tsec = -1; 2915a8a163aSAndy Fleming uchar mask; 2925a8a163aSAndy Fleming uchar switch_mask; 2935a8a163aSAndy Fleming 2945a8a163aSAndy Fleming if (argc > 2) 2955a8a163aSAndy Fleming if (strcmp(argv[1], "all") != 0) 2965a8a163aSAndy Fleming which_tsec = simple_strtoul(argv[1], NULL, 0); 2975a8a163aSAndy Fleming 2985a8a163aSAndy Fleming switch (which_tsec) { 299bff188baSLiu Yu #ifdef CONFIG_TSEC1 3005a8a163aSAndy Fleming case 1: 3015a8a163aSAndy Fleming mask = PIXIS_VSPEED2_TSEC1SER; 3025a8a163aSAndy Fleming switch_mask = PIXIS_VCFGEN1_TSEC1SER; 3035a8a163aSAndy Fleming break; 304bff188baSLiu Yu #endif 305bff188baSLiu Yu #ifdef CONFIG_TSEC2 306bff188baSLiu Yu case 2: 307bff188baSLiu Yu mask = PIXIS_VSPEED2_TSEC2SER; 308bff188baSLiu Yu switch_mask = PIXIS_VCFGEN1_TSEC2SER; 309bff188baSLiu Yu break; 310bff188baSLiu Yu #endif 311bff188baSLiu Yu #ifdef CONFIG_TSEC3 3125a8a163aSAndy Fleming case 3: 3135a8a163aSAndy Fleming mask = PIXIS_VSPEED2_TSEC3SER; 3145a8a163aSAndy Fleming switch_mask = PIXIS_VCFGEN1_TSEC3SER; 3155a8a163aSAndy Fleming break; 316bff188baSLiu Yu #endif 317bff188baSLiu Yu #ifdef CONFIG_TSEC4 318bff188baSLiu Yu case 4: 319bff188baSLiu Yu mask = PIXIS_VSPEED2_TSEC4SER; 320bff188baSLiu Yu switch_mask = PIXIS_VCFGEN1_TSEC4SER; 321bff188baSLiu Yu break; 322bff188baSLiu Yu #endif 3235a8a163aSAndy Fleming default: 324bff188baSLiu Yu mask = PIXIS_VSPEED2_MASK; 325bff188baSLiu Yu switch_mask = PIXIS_VCFGEN1_MASK; 3265a8a163aSAndy Fleming break; 3275a8a163aSAndy Fleming } 3285a8a163aSAndy Fleming 3295a8a163aSAndy Fleming /* Toggle whether the switches or FPGA control the settings */ 3305a8a163aSAndy Fleming if (!strcmp(argv[argc - 1], "switch")) 3315a8a163aSAndy Fleming clrbits_8((unsigned char *)PIXIS_BASE + PIXIS_VCFGEN1, 3325a8a163aSAndy Fleming switch_mask); 3335a8a163aSAndy Fleming else 3345a8a163aSAndy Fleming setbits_8((unsigned char *)PIXIS_BASE + PIXIS_VCFGEN1, 3355a8a163aSAndy Fleming switch_mask); 3365a8a163aSAndy Fleming 3375a8a163aSAndy Fleming /* If it's not the switches, enable or disable SGMII, as specified */ 3385a8a163aSAndy Fleming if (!strcmp(argv[argc - 1], "on")) 3395a8a163aSAndy Fleming clrbits_8((unsigned char *)PIXIS_BASE + PIXIS_VSPEED2, mask); 3405a8a163aSAndy Fleming else if (!strcmp(argv[argc - 1], "off")) 3415a8a163aSAndy Fleming setbits_8((unsigned char *)PIXIS_BASE + PIXIS_VSPEED2, mask); 3425a8a163aSAndy Fleming 3435a8a163aSAndy Fleming return 0; 3445a8a163aSAndy Fleming } 3455a8a163aSAndy Fleming 3465a8a163aSAndy Fleming U_BOOT_CMD( 3476d0f6bcfSJean-Christophe PLAGNIOL-VILLARD pixis_set_sgmii, CONFIG_SYS_MAXARGS, 1, pixis_set_sgmii, 3485a8a163aSAndy Fleming "pixis_set_sgmii" 3495a8a163aSAndy Fleming " - Enable or disable SGMII mode for a given TSEC \n", 3505a8a163aSAndy Fleming "\npixis_set_sgmii [TSEC num] <on|off|switch>\n" 3515a8a163aSAndy Fleming " TSEC num: 1,2,3,4 or 'all'. 'all' is default.\n" 3525a8a163aSAndy Fleming " on - enables SGMII\n" 3535a8a163aSAndy Fleming " off - disables SGMII\n" 354*a89c33dbSWolfgang Denk " switch - use switch settings" 355*a89c33dbSWolfgang Denk ); 3565a8a163aSAndy Fleming #endif 3575a8a163aSAndy Fleming 3583d98b858SHaiying Wang /* 3593d98b858SHaiying Wang * This function takes the non-integral cpu:mpx pll ratio 3603d98b858SHaiying Wang * and converts it to an integer that can be used to assign 3613d98b858SHaiying Wang * FPGA register values. 3623d98b858SHaiying Wang * input: strptr i.e. argv[2] 3633d98b858SHaiying Wang */ 3643d98b858SHaiying Wang 3653d98b858SHaiying Wang static ulong strfractoint(uchar *strptr) 3663d98b858SHaiying Wang { 3673d98b858SHaiying Wang int i, j, retval; 3683d98b858SHaiying Wang int mulconst; 3693d98b858SHaiying Wang int intarr_len = 0, decarr_len = 0, no_dec = 0; 3703d98b858SHaiying Wang ulong intval = 0, decval = 0; 3713d98b858SHaiying Wang uchar intarr[3], decarr[3]; 3723d98b858SHaiying Wang 3733d98b858SHaiying Wang /* Assign the integer part to intarr[] 3743d98b858SHaiying Wang * If there is no decimal point i.e. 3753d98b858SHaiying Wang * if the ratio is an integral value 3763d98b858SHaiying Wang * simply create the intarr. 3773d98b858SHaiying Wang */ 3783d98b858SHaiying Wang i = 0; 37916c3cde0SJames Yang while (strptr[i] != '.') { 3803d98b858SHaiying Wang if (strptr[i] == 0) { 3813d98b858SHaiying Wang no_dec = 1; 3823d98b858SHaiying Wang break; 3833d98b858SHaiying Wang } 3843d98b858SHaiying Wang intarr[i] = strptr[i]; 3853d98b858SHaiying Wang i++; 3863d98b858SHaiying Wang } 3873d98b858SHaiying Wang 3883d98b858SHaiying Wang /* Assign length of integer part to intarr_len. */ 3893d98b858SHaiying Wang intarr_len = i; 3903d98b858SHaiying Wang intarr[i] = '\0'; 3913d98b858SHaiying Wang 3923d98b858SHaiying Wang if (no_dec) { 3933d98b858SHaiying Wang /* Currently needed only for single digit corepll ratios */ 3943d98b858SHaiying Wang mulconst = 10; 3953d98b858SHaiying Wang decval = 0; 3963d98b858SHaiying Wang } else { 3973d98b858SHaiying Wang j = 0; 3983d98b858SHaiying Wang i++; /* Skipping the decimal point */ 39916c3cde0SJames Yang while ((strptr[i] >= '0') && (strptr[i] <= '9')) { 4003d98b858SHaiying Wang decarr[j] = strptr[i]; 4013d98b858SHaiying Wang i++; 4023d98b858SHaiying Wang j++; 4033d98b858SHaiying Wang } 4043d98b858SHaiying Wang 4053d98b858SHaiying Wang decarr_len = j; 4063d98b858SHaiying Wang decarr[j] = '\0'; 4073d98b858SHaiying Wang 4083d98b858SHaiying Wang mulconst = 1; 4093d98b858SHaiying Wang for (i = 0; i < decarr_len; i++) 4103d98b858SHaiying Wang mulconst *= 10; 411cdd917a4SWolfgang Denk decval = simple_strtoul((char *)decarr, NULL, 10); 4123d98b858SHaiying Wang } 4133d98b858SHaiying Wang 414cdd917a4SWolfgang Denk intval = simple_strtoul((char *)intarr, NULL, 10); 4153d98b858SHaiying Wang intval = intval * mulconst; 4163d98b858SHaiying Wang 4173d98b858SHaiying Wang retval = intval + decval; 4183d98b858SHaiying Wang 4193d98b858SHaiying Wang return retval; 4203d98b858SHaiying Wang } 4213d98b858SHaiying Wang 4223d98b858SHaiying Wang 4233d98b858SHaiying Wang int 4243d98b858SHaiying Wang pixis_reset_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) 4253d98b858SHaiying Wang { 42616c3cde0SJames Yang unsigned int i; 42716c3cde0SJames Yang char *p_cf = NULL; 42816c3cde0SJames Yang char *p_cf_sysclk = NULL; 42916c3cde0SJames Yang char *p_cf_corepll = NULL; 43016c3cde0SJames Yang char *p_cf_mpxpll = NULL; 43116c3cde0SJames Yang char *p_altbank = NULL; 43216c3cde0SJames Yang char *p_wd = NULL; 43316c3cde0SJames Yang unsigned int unknown_param = 0; 4343d98b858SHaiying Wang 4353d98b858SHaiying Wang /* 4363d98b858SHaiying Wang * No args is a simple reset request. 4373d98b858SHaiying Wang */ 4383d98b858SHaiying Wang if (argc <= 1) { 4393d98b858SHaiying Wang pixis_reset(); 4403d98b858SHaiying Wang /* not reached */ 4413d98b858SHaiying Wang } 4423d98b858SHaiying Wang 44316c3cde0SJames Yang for (i = 1; i < argc; i++) { 44416c3cde0SJames Yang if (strcmp(argv[i], "cf") == 0) { 44516c3cde0SJames Yang p_cf = argv[i]; 44616c3cde0SJames Yang if (i + 3 >= argc) { 44716c3cde0SJames Yang break; 44816c3cde0SJames Yang } 44916c3cde0SJames Yang p_cf_sysclk = argv[i+1]; 45016c3cde0SJames Yang p_cf_corepll = argv[i+2]; 45116c3cde0SJames Yang p_cf_mpxpll = argv[i+3]; 45216c3cde0SJames Yang i += 3; 45316c3cde0SJames Yang continue; 45416c3cde0SJames Yang } 45516c3cde0SJames Yang 45616c3cde0SJames Yang if (strcmp(argv[i], "altbank") == 0) { 45716c3cde0SJames Yang p_altbank = argv[i]; 45816c3cde0SJames Yang continue; 45916c3cde0SJames Yang } 46016c3cde0SJames Yang 46116c3cde0SJames Yang if (strcmp(argv[i], "wd") == 0) { 46216c3cde0SJames Yang p_wd = argv[i]; 46316c3cde0SJames Yang continue; 46416c3cde0SJames Yang } 46516c3cde0SJames Yang 46616c3cde0SJames Yang unknown_param = 1; 46716c3cde0SJames Yang } 4683d98b858SHaiying Wang 4693d98b858SHaiying Wang /* 47016c3cde0SJames Yang * Check that cf has all required parms 4713d98b858SHaiying Wang */ 47216c3cde0SJames Yang if ((p_cf && !(p_cf_sysclk && p_cf_corepll && p_cf_mpxpll)) 47316c3cde0SJames Yang || unknown_param) { 474f7fecc3eSEd Swarthout #ifdef CONFIG_SYS_LONGHELP 47516c3cde0SJames Yang puts(cmdtp->help); 476f7fecc3eSEd Swarthout #endif 4773d98b858SHaiying Wang return 1; 4783d98b858SHaiying Wang } 4793d98b858SHaiying Wang 4803d98b858SHaiying Wang /* 48116c3cde0SJames Yang * PIXIS seems to be sensitive to the ordering of 48216c3cde0SJames Yang * the registers that are touched. 4833d98b858SHaiying Wang */ 4843d98b858SHaiying Wang read_from_px_regs(0); 48516c3cde0SJames Yang 48616c3cde0SJames Yang if (p_altbank) { 4873d98b858SHaiying Wang read_from_px_regs_altbank(0); 48816c3cde0SJames Yang } 48916c3cde0SJames Yang clear_altbank(); 49016c3cde0SJames Yang 49116c3cde0SJames Yang /* 49216c3cde0SJames Yang * Clock configuration specified. 49316c3cde0SJames Yang */ 49416c3cde0SJames Yang if (p_cf) { 49516c3cde0SJames Yang unsigned long sysclk; 49616c3cde0SJames Yang unsigned long corepll; 49716c3cde0SJames Yang unsigned long mpxpll; 49816c3cde0SJames Yang 49916c3cde0SJames Yang sysclk = simple_strtoul(p_cf_sysclk, NULL, 10); 50016c3cde0SJames Yang corepll = strfractoint((uchar *) p_cf_corepll); 50116c3cde0SJames Yang mpxpll = simple_strtoul(p_cf_mpxpll, NULL, 10); 50216c3cde0SJames Yang 50316c3cde0SJames Yang if (!(set_px_sysclk(sysclk) 50416c3cde0SJames Yang && set_px_corepll(corepll) 50516c3cde0SJames Yang && set_px_mpxpll(mpxpll))) { 506f7fecc3eSEd Swarthout #ifdef CONFIG_SYS_LONGHELP 50716c3cde0SJames Yang puts(cmdtp->help); 508f7fecc3eSEd Swarthout #endif 5093d98b858SHaiying Wang return 1; 5103d98b858SHaiying Wang } 51116c3cde0SJames Yang read_from_px_regs(1); 51216c3cde0SJames Yang } 51316c3cde0SJames Yang 51416c3cde0SJames Yang /* 51516c3cde0SJames Yang * Altbank specified 51616c3cde0SJames Yang * 51716c3cde0SJames Yang * NOTE CHANGE IN BEHAVIOR: previous code would default 51816c3cde0SJames Yang * to enabling watchdog if altbank is specified. 51916c3cde0SJames Yang * Now the watchdog must be enabled explicitly using 'wd'. 52016c3cde0SJames Yang */ 52116c3cde0SJames Yang if (p_altbank) { 5223d98b858SHaiying Wang set_altbank(); 5233d98b858SHaiying Wang read_from_px_regs_altbank(1); 52416c3cde0SJames Yang } 5253d98b858SHaiying Wang 5263d98b858SHaiying Wang /* 52716c3cde0SJames Yang * Reset with watchdog specified. 5283d98b858SHaiying Wang */ 52916c3cde0SJames Yang if (p_wd) { 5303d98b858SHaiying Wang set_px_go_with_watchdog(); 5313d98b858SHaiying Wang } else { 53216c3cde0SJames Yang set_px_go(); 5333d98b858SHaiying Wang } 5343d98b858SHaiying Wang 5353d98b858SHaiying Wang /* 53616c3cde0SJames Yang * Shouldn't be reached. 5373d98b858SHaiying Wang */ 5383d98b858SHaiying Wang return 0; 5393d98b858SHaiying Wang } 5403d98b858SHaiying Wang 5413d98b858SHaiying Wang 5423d98b858SHaiying Wang U_BOOT_CMD( 5436d0f6bcfSJean-Christophe PLAGNIOL-VILLARD pixis_reset, CONFIG_SYS_MAXARGS, 1, pixis_reset_cmd, 5442fb2604dSPeter Tyser "Reset the board using the FPGA sequencer", 5453d98b858SHaiying Wang " pixis_reset\n" 5463d98b858SHaiying Wang " pixis_reset [altbank]\n" 5473d98b858SHaiying Wang " pixis_reset altbank wd\n" 5483d98b858SHaiying Wang " pixis_reset altbank cf <SYSCLK freq> <COREPLL ratio> <MPXPLL ratio>\n" 549*a89c33dbSWolfgang Denk " pixis_reset cf <SYSCLK freq> <COREPLL ratio> <MPXPLL ratio>" 5503d98b858SHaiying Wang ); 551