FSL: Generalize PIXIS reset command parsing.

Before, the order of arguments to the pixis_reset
command needed to be supplied in a hard-coded order.
Generalize the command parsing to allow any order.

Signed-off-by: James Yang <james.yang@freescale.com>
Acked-by: Jon Loeliger <jdl@freescale.com>
This commit is contained in:
James Yang 2008-01-16 11:58:08 -06:00 committed by Jon Loeliger
parent ad8f8687b7
commit 16c3cde050

View file

@ -183,7 +183,7 @@ int set_px_corepll(ulong corepll)
void read_from_px_regs(int set) void read_from_px_regs(int set)
{ {
u8 mask = 0x1C; u8 mask = 0x1C; /* COREPLL, MPXPLL, SYSCLK controlled by PIXIS */
u8 tmp = in8(PIXIS_BASE + PIXIS_VCFGEN0); u8 tmp = in8(PIXIS_BASE + PIXIS_VCFGEN0);
if (set) if (set)
@ -196,7 +196,7 @@ void read_from_px_regs(int set)
void read_from_px_regs_altbank(int set) void read_from_px_regs_altbank(int set)
{ {
u8 mask = 0x04; u8 mask = 0x04; /* FLASHBANK and FLASHMAP controlled by PIXIS */
u8 tmp = in8(PIXIS_BASE + PIXIS_VCFGEN1); u8 tmp = in8(PIXIS_BASE + PIXIS_VCFGEN1);
if (set) if (set)
@ -207,15 +207,26 @@ void read_from_px_regs_altbank(int set)
} }
#ifndef CFG_PIXIS_VBOOT_MASK #ifndef CFG_PIXIS_VBOOT_MASK
#define CFG_PIXIS_VBOOT_MASK 0x40 #define CFG_PIXIS_VBOOT_MASK (0x40)
#endif #endif
void clear_altbank(void)
{
u8 tmp;
tmp = in8(PIXIS_BASE + PIXIS_VBOOT);
tmp &= ~CFG_PIXIS_VBOOT_MASK;
out8(PIXIS_BASE + PIXIS_VBOOT, tmp);
}
void set_altbank(void) void set_altbank(void)
{ {
u8 tmp; u8 tmp;
tmp = in8(PIXIS_BASE + PIXIS_VBOOT); tmp = in8(PIXIS_BASE + PIXIS_VBOOT);
tmp ^= CFG_PIXIS_VBOOT_MASK; tmp |= CFG_PIXIS_VBOOT_MASK;
out8(PIXIS_BASE + PIXIS_VBOOT, tmp); out8(PIXIS_BASE + PIXIS_VBOOT, tmp);
} }
@ -226,11 +237,11 @@ void set_px_go(void)
u8 tmp; u8 tmp;
tmp = in8(PIXIS_BASE + PIXIS_VCTL); tmp = in8(PIXIS_BASE + PIXIS_VCTL);
tmp = tmp & 0x1E; tmp = tmp & 0x1E; /* clear GO bit */
out8(PIXIS_BASE + PIXIS_VCTL, tmp); out8(PIXIS_BASE + PIXIS_VCTL, tmp);
tmp = in8(PIXIS_BASE + PIXIS_VCTL); tmp = in8(PIXIS_BASE + PIXIS_VCTL);
tmp = tmp | 0x01; tmp = tmp | 0x01; /* set GO bit - start reset sequencer */
out8(PIXIS_BASE + PIXIS_VCTL, tmp); out8(PIXIS_BASE + PIXIS_VCTL, tmp);
} }
@ -292,7 +303,7 @@ static ulong strfractoint(uchar *strptr)
* simply create the intarr. * simply create the intarr.
*/ */
i = 0; i = 0;
while (strptr[i] != 46) { while (strptr[i] != '.') {
if (strptr[i] == 0) { if (strptr[i] == 0) {
no_dec = 1; no_dec = 1;
break; break;
@ -312,7 +323,7 @@ static ulong strfractoint(uchar *strptr)
} else { } else {
j = 0; j = 0;
i++; /* Skipping the decimal point */ i++; /* Skipping the decimal point */
while ((strptr[i] > 47) && (strptr[i] < 58)) { while ((strptr[i] >= '0') && (strptr[i] <= '9')) {
decarr[j] = strptr[i]; decarr[j] = strptr[i];
i++; i++;
j++; j++;
@ -339,8 +350,14 @@ static ulong strfractoint(uchar *strptr)
int int
pixis_reset_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) pixis_reset_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{ {
ulong val; unsigned int i;
ulong corepll; char *p_cf = NULL;
char *p_cf_sysclk = NULL;
char *p_cf_corepll = NULL;
char *p_cf_mpxpll = NULL;
char *p_altbank = NULL;
char *p_wd = NULL;
unsigned int unknown_param = 0;
/* /*
* No args is a simple reset request. * No args is a simple reset request.
@ -350,116 +367,97 @@ pixis_reset_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
/* not reached */ /* not reached */
} }
if (strcmp(argv[1], "cf") == 0) { for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "cf") == 0) {
/* p_cf = argv[i];
* Reset with frequency changed: if (i + 3 >= argc) {
* cf <SYSCLK freq> <COREPLL ratio> <MPXPLL ratio> break;
*/
if (argc < 5) {
puts(cmdtp->usage);
return 1;
}
read_from_px_regs(0);
val = set_px_sysclk(simple_strtoul(argv[2], NULL, 10));
corepll = strfractoint((uchar *)argv[3]);
val = val + set_px_corepll(corepll);
val = val + set_px_mpxpll(simple_strtoul(argv[4], NULL, 10));
if (val == 3) {
puts("Setting registers VCFGEN0 and VCTL\n");
read_from_px_regs(1);
puts("Resetting board with values from ");
puts("VSPEED0, VSPEED1, VCLKH, and VCLKL \n");
set_px_go();
} else {
puts(cmdtp->usage);
return 1;
}
while (1) ; /* Not reached */
} else if (strcmp(argv[1], "altbank") == 0) {
/*
* Reset using alternate flash bank:
*/
if (argv[2] == 0) {
/*
* Reset from alternate bank without changing
* frequency and without watchdog timer enabled.
* altbank
*/
read_from_px_regs(0);
read_from_px_regs_altbank(0);
if (argc > 2) {
puts(cmdtp->usage);
return 1;
} }
puts("Setting registers VCFGNE1, VBOOT, and VCTL\n"); p_cf_sysclk = argv[i+1];
set_altbank(); p_cf_corepll = argv[i+2];
read_from_px_regs_altbank(1); p_cf_mpxpll = argv[i+3];
puts("Resetting board to boot from the other bank.\n"); i += 3;
set_px_go(); continue;
} else if (strcmp(argv[2], "cf") == 0) {
/*
* Reset with frequency changed
* altbank cf <SYSCLK freq> <COREPLL ratio>
* <MPXPLL ratio>
*/
read_from_px_regs(0);
read_from_px_regs_altbank(0);
val = set_px_sysclk(simple_strtoul(argv[3], NULL, 10));
corepll = strfractoint((uchar *)argv[4]);
val = val + set_px_corepll(corepll);
val = val + set_px_mpxpll(simple_strtoul(argv[5],
NULL, 10));
if (val == 3) {
puts("Setting registers VCFGEN0, VCFGEN1, VBOOT, and VCTL\n");
set_altbank();
read_from_px_regs(1);
read_from_px_regs_altbank(1);
puts("Enabling watchdog timer on the FPGA\n");
puts("Resetting board with values from ");
puts("VSPEED0, VSPEED1, VCLKH and VCLKL ");
puts("to boot from the other bank.\n");
set_px_go_with_watchdog();
} else {
puts(cmdtp->usage);
return 1;
}
while (1) ; /* Not reached */
} else if (strcmp(argv[2], "wd") == 0) {
/*
* Reset from alternate bank without changing
* frequencies but with watchdog timer enabled:
* altbank wd
*/
read_from_px_regs(0);
read_from_px_regs_altbank(0);
puts("Setting registers VCFGEN1, VBOOT, and VCTL\n");
set_altbank();
read_from_px_regs_altbank(1);
puts("Enabling watchdog timer on the FPGA\n");
puts("Resetting board to boot from the other bank.\n");
set_px_go_with_watchdog();
while (1) ; /* Not reached */
} else {
puts(cmdtp->usage);
return 1;
} }
} else { if (strcmp(argv[i], "altbank") == 0) {
puts(cmdtp->usage); p_altbank = argv[i];
continue;
}
if (strcmp(argv[i], "wd") == 0) {
p_wd = argv[i];
continue;
}
unknown_param = 1;
}
/*
* Check that cf has all required parms
*/
if ((p_cf && !(p_cf_sysclk && p_cf_corepll && p_cf_mpxpll))
|| unknown_param) {
puts(cmdtp->help);
return 1; return 1;
} }
/*
* PIXIS seems to be sensitive to the ordering of
* the registers that are touched.
*/
read_from_px_regs(0);
if (p_altbank) {
read_from_px_regs_altbank(0);
}
clear_altbank();
/*
* Clock configuration specified.
*/
if (p_cf) {
unsigned long sysclk;
unsigned long corepll;
unsigned long mpxpll;
sysclk = simple_strtoul(p_cf_sysclk, NULL, 10);
corepll = strfractoint((uchar *) p_cf_corepll);
mpxpll = simple_strtoul(p_cf_mpxpll, NULL, 10);
if (!(set_px_sysclk(sysclk)
&& set_px_corepll(corepll)
&& set_px_mpxpll(mpxpll))) {
puts(cmdtp->help);
return 1;
}
read_from_px_regs(1);
}
/*
* Altbank specified
*
* NOTE CHANGE IN BEHAVIOR: previous code would default
* to enabling watchdog if altbank is specified.
* Now the watchdog must be enabled explicitly using 'wd'.
*/
if (p_altbank) {
set_altbank();
read_from_px_regs_altbank(1);
}
/*
* Reset with watchdog specified.
*/
if (p_wd) {
set_px_go_with_watchdog();
} else {
set_px_go();
}
/*
* Shouldn't be reached.
*/
return 0; return 0;
} }