upstream u-boot with additional patches for our devices/boards: https://lists.denx.de/pipermail/u-boot/2017-March/282789.html (AXP crashes) ; Gbit ethernet patch for some LIME2 revisions ; with SPI flash support
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
u-boot/arch/powerpc/lib/immap.c

398 lines
7.3 KiB

powerpc: Partialy restore core of mpc8xx CS Systemes d'Information (CSSI) manufactures 8xx boards for critical communication systems. Those boards have been running U-Boot since 2010 and will have to be maintained until at least 2027. commit 5b8e76c35ec312a3f73126bd1a2d2c0965b98a9f ("powerpc, 8xx: remove support for 8xx") orphaned those boards by removing support for the mpc8xx CPU. This commit partially restores support for the 8xx, with the following limitations: - Restores support for MPC866 and MPC885 only - Does not restore IDE, PCMCIA, I2C, USB - Does not restore examples - Does not restore POST - Does not restore Ethernet on SCC - Does not restore console on SCC - Does not restore bedbug and kgdb support As the 866 and 885 do not support the following features, they are not restored either: - VIDEO / LCD - RTC clock The CPM uCODE patch is not restored either, because: - 866 and 885 already have support for I2C and SPI relocation without a uCODE patch - relocation of SMC, I2C or SPI is only needed for using SCCs for Ethernet or QMC The dynamic setup/calculation of clocks is removed, we expect the target being use with the clock and PLPRCR register defined in the configuration. All the clock settings for 8xx prior to 866 is removed as well as we now only support 866 and 885. This code is mature and addresses mature boards. Therefore all code enclosed in '#if 0/#endif' and '#if XX_DEBUG/#endif' is unneeded. The following files are not restored by this patch: - arch/powerpc/cpu/mpc8xx/bedbug_860.c - arch/powerpc/cpu/mpc8xx/fec.h - arch/powerpc/cpu/mpc8xx/kgdb.S - arch/powerpc/cpu/mpc8xx/plprcr_write.S - arch/powerpc/cpu/mpc8xx/scc.c - arch/powerpc/cpu/mpc8xx/upatch.c - arch/powerpc/cpu/mpc8xx/video.c - arch/powerpc/include/asm/status_led.h - arch/powerpc/lib/ide.c - arch/powerpc/lib/ide.h - doc/README.MPC866 - drivers/pcmcia/mpc8xx_pcmcia.c - drivers/rtc/mpc8xx.c - drivers/usb/gadget/mpc8xx_udc.c - drivers/video/mpc8xx_lcd.c - examples/standalone/test_burst.c - examples/standalone/test_burst.h - examples/standalone/test_burst_lib.S - examples/standalone/timer.c - include/mpc823_lcd.h - include/usb/mpc8xx_udc.h - post/cpu/mpc8xx/Makefile - post/cpu/mpc8xx/cache.c - post/cpu/mpc8xx/cache_8xx.S - post/cpu/mpc8xx/ether.c - post/cpu/mpc8xx/spr.c - post/cpu/mpc8xx/uart.c - post/cpu/mpc8xx/usb.c - post/cpu/mpc8xx/watchdog.c Some of the restored files are not located in a proper location. In order to keep traceability of the changes, they will be moved to their correct location and moved to Kconfig in a followup patch. This patch also declares CSSI as point of contact for the update of the 8xx platform, as those boards are the only ones still being maintained on the 8xx area. A later patch will add those boards to the tree. Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
7 years ago
/*
* (C) Copyright 2000-2003
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* SPDX-License-Identifier: GPL-2.0+
*/
/*
* MPC8xx Internal Memory Map Functions
*/
#include <common.h>
#include <command.h>
#if defined(CONFIG_8xx)
#include <asm/8xx_immap.h>
#include <commproc.h>
#include <asm/iopin_8xx.h>
DECLARE_GLOBAL_DATA_PTR;
int
do_siuinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
volatile sysconf8xx_t *sc = &immap->im_siu_conf;
printf ("SIUMCR= %08x SYPCR = %08x\n", sc->sc_siumcr, sc->sc_sypcr);
printf ("SWT = %08x\n", sc->sc_swt);
printf ("SIPEND= %08x SIMASK= %08x\n", sc->sc_sipend, sc->sc_simask);
printf ("SIEL = %08x SIVEC = %08x\n", sc->sc_siel, sc->sc_sivec);
printf ("TESR = %08x SDCR = %08x\n", sc->sc_tesr, sc->sc_sdcr);
return 0;
}
int
do_memcinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
volatile memctl8xx_t *memctl = &immap->im_memctl;
int nbanks = 8;
volatile uint *p = &memctl->memc_br0;
int i;
for (i = 0; i < nbanks; i++, p += 2) {
if (i < 10) {
printf ("BR%d = %08x OR%d = %08x\n",
i, p[0], i, p[1]);
} else {
printf ("BR%d = %08x OR%d = %08x\n",
i, p[0], i, p[1]);
}
}
printf ("MAR = %08x", memctl->memc_mar);
printf (" MCR = %08x\n", memctl->memc_mcr);
printf ("MAMR = %08x MBMR = %08x",
memctl->memc_mamr, memctl->memc_mbmr);
printf ("\nMSTAT = %04x\n", memctl->memc_mstat);
printf ("MPTPR = %04x MDR = %08x\n",
memctl->memc_mptpr, memctl->memc_mdr);
return 0;
}
int
do_carinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
volatile car8xx_t *car = &immap->im_clkrst;
printf ("SCCR = %08x\n", car->car_sccr);
printf ("PLPRCR= %08x\n", car->car_plprcr);
printf ("RSR = %08x\n", car->car_rsr);
return 0;
}
static int counter;
static void
header(void)
{
char *data = "\
-------------------------------- --------------------------------\
00000000001111111111222222222233 00000000001111111111222222222233\
01234567890123456789012345678901 01234567890123456789012345678901\
-------------------------------- --------------------------------\
";
int i;
if (counter % 2)
putc('\n');
counter = 0;
for (i = 0; i < 4; i++, data += 79)
printf("%.79s\n", data);
}
static void binary (char *label, uint value, int nbits)
{
uint mask = 1 << (nbits - 1);
int i, second = (counter++ % 2);
if (second)
putc (' ');
puts (label);
for (i = 32 + 1; i != nbits; i--)
putc (' ');
while (mask != 0) {
if (value & mask)
putc ('1');
else
putc ('0');
mask >>= 1;
}
if (second)
putc ('\n');
}
#define PA_NBITS 16
#define PA_NB_ODR 8
#define PB_NBITS 18
#define PB_NB_ODR 16
#define PC_NBITS 12
#define PD_NBITS 13
int
do_iopinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
volatile iop8xx_t *iop = &immap->im_ioport;
volatile ushort *l, *r;
volatile uint *R;
counter = 0;
header ();
/*
* Ports A & B
*/
l = &iop->iop_padir;
R = &immap->im_cpm.cp_pbdir;
binary ("PA_DIR", *l++, PA_NBITS);
binary ("PB_DIR", *R++, PB_NBITS);
binary ("PA_PAR", *l++, PA_NBITS);
binary ("PB_PAR", *R++, PB_NBITS);
binary ("PA_ODR", *l++, PA_NB_ODR);
binary ("PB_ODR", *R++, PB_NB_ODR);
binary ("PA_DAT", *l++, PA_NBITS);
binary ("PB_DAT", *R++, PB_NBITS);
header ();
/*
* Ports C & D
*/
l = &iop->iop_pcdir;
r = &iop->iop_pddir;
binary ("PC_DIR", *l++, PC_NBITS);
binary ("PD_DIR", *r++, PD_NBITS);
binary ("PC_PAR", *l++, PC_NBITS);
binary ("PD_PAR", *r++, PD_NBITS);
binary ("PC_SO ", *l++, PC_NBITS);
binary (" ", 0, 0);
r++;
binary ("PC_DAT", *l++, PC_NBITS);
binary ("PD_DAT", *r++, PD_NBITS);
binary ("PC_INT", *l++, PC_NBITS);
header ();
return 0;
}
/*
* set the io pins
* this needs a clean up for smaller tighter code
* use *uint and set the address based on cmd + port
*/
int
do_iopset (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
uint rcode = 0;
iopin_t iopin;
static uint port = 0;
static uint pin = 0;
static uint value = 0;
static enum {
DIR,
PAR,
SOR,
ODR,
DAT,
INT
} cmd = DAT;
if (argc != 5) {
puts ("iopset PORT PIN CMD VALUE\n");
return 1;
}
port = argv[1][0] - 'A';
if (port > 3)
port -= 0x20;
if (port > 3)
rcode = 1;
pin = simple_strtol (argv[2], NULL, 10);
if (pin > 31)
rcode = 1;
switch (argv[3][0]) {
case 'd':
if (argv[3][1] == 'a')
cmd = DAT;
else if (argv[3][1] == 'i')
cmd = DIR;
else
rcode = 1;
break;
case 'p':
cmd = PAR;
break;
case 'o':
cmd = ODR;
break;
case 's':
cmd = SOR;
break;
case 'i':
cmd = INT;
break;
default:
printf ("iopset: unknown command %s\n", argv[3]);
rcode = 1;
}
if (argv[4][0] == '1')
value = 1;
else if (argv[4][0] == '0')
value = 0;
else
rcode = 1;
if (rcode == 0) {
iopin.port = port;
iopin.pin = pin;
iopin.flag = 0;
switch (cmd) {
case DIR:
if (value)
iopin_set_out (&iopin);
else
iopin_set_in (&iopin);
break;
case PAR:
if (value)
iopin_set_ded (&iopin);
else
iopin_set_gen (&iopin);
break;
case SOR:
if (value)
iopin_set_opt2 (&iopin);
else
iopin_set_opt1 (&iopin);
break;
case ODR:
if (value)
iopin_set_odr (&iopin);
else
iopin_set_act (&iopin);
break;
case DAT:
if (value)
iopin_set_high (&iopin);
else
iopin_set_low (&iopin);
break;
case INT:
if (value)
iopin_set_falledge (&iopin);
else
iopin_set_anyedge (&iopin);
break;
}
}
return rcode;
}
static void prbrg (int n, uint val)
{
uint extc = (val >> 14) & 3;
uint cd = (val & CPM_BRG_CD_MASK) >> 1;
uint div16 = (val & CPM_BRG_DIV16) != 0;
ulong clock = gd->cpu_clk;
printf ("BRG%d:", n);
if (val & CPM_BRG_RST)
puts (" RESET");
else
puts (" ");
if (val & CPM_BRG_EN)
puts (" ENABLED");
else
puts (" DISABLED");
printf (" EXTC=%d", extc);
if (val & CPM_BRG_ATB)
puts (" ATB");
else
puts (" ");
printf (" DIVIDER=%4d", cd);
if (extc == 0 && cd != 0) {
uint baudrate;
if (div16)
baudrate = (clock / 16) / (cd + 1);
else
baudrate = clock / (cd + 1);
printf ("=%6d bps", baudrate);
} else {
puts (" ");
}
if (val & CPM_BRG_DIV16)
puts (" DIV16");
else
puts (" ");
putc ('\n');
}
int
do_brginfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
volatile cpm8xx_t *cp = &immap->im_cpm;
volatile uint *p = &cp->cp_brgc1;
int i = 1;
while (i <= 4)
prbrg (i++, *p++);
return 0;
}
/***************************************************/
U_BOOT_CMD(
siuinfo, 1, 1, do_siuinfo,
"print System Interface Unit (SIU) registers",
""
);
U_BOOT_CMD(
memcinfo, 1, 1, do_memcinfo,
"print Memory Controller registers",
""
);
U_BOOT_CMD(
carinfo, 1, 1, do_carinfo,
"print Clocks and Reset registers",
""
);
U_BOOT_CMD(
iopinfo, 1, 1, do_iopinfo,
"print I/O Port registers",
""
);
U_BOOT_CMD(
iopset, 5, 0, do_iopset,
"set I/O Port registers",
"PORT PIN CMD VALUE\nPORT: A-D, PIN: 0-31, CMD: [dat|dir|odr|sor], VALUE: 0|1"
);
U_BOOT_CMD(
brginfo, 1, 1, do_brginfo,
"print Baud Rate Generator (BRG) registers",
""
);
#endif