xref: /rk3399_rockchip-uboot/board/freescale/common/pixis.c (revision a89c33db96a1e55319a286dd4c3c05ca64ac6bfd)
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