diff options
author | Yang Zhang <yang.z.zhang@intel.com> | 2015-08-28 09:58:54 +0800 |
---|---|---|
committer | Yang Zhang <yang.z.zhang@intel.com> | 2015-09-01 12:44:00 +0800 |
commit | e44e3482bdb4d0ebde2d8b41830ac2cdb07948fb (patch) | |
tree | 66b09f592c55df2878107a468a91d21506104d3f /qemu/roms/u-boot/board/r360mpi | |
parent | 9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00 (diff) |
Add qemu 2.4.0
Change-Id: Ic99cbad4b61f8b127b7dc74d04576c0bcbaaf4f5
Signed-off-by: Yang Zhang <yang.z.zhang@intel.com>
Diffstat (limited to 'qemu/roms/u-boot/board/r360mpi')
-rw-r--r-- | qemu/roms/u-boot/board/r360mpi/Makefile | 8 | ||||
-rw-r--r-- | qemu/roms/u-boot/board/r360mpi/flash.c | 468 | ||||
-rw-r--r-- | qemu/roms/u-boot/board/r360mpi/pcmcia.c | 232 | ||||
-rw-r--r-- | qemu/roms/u-boot/board/r360mpi/r360mpi.c | 403 | ||||
-rw-r--r-- | qemu/roms/u-boot/board/r360mpi/u-boot.lds | 89 |
5 files changed, 1200 insertions, 0 deletions
diff --git a/qemu/roms/u-boot/board/r360mpi/Makefile b/qemu/roms/u-boot/board/r360mpi/Makefile new file mode 100644 index 000000000..f8f7fe75e --- /dev/null +++ b/qemu/roms/u-boot/board/r360mpi/Makefile @@ -0,0 +1,8 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y = r360mpi.o flash.o pcmcia.o diff --git a/qemu/roms/u-boot/board/r360mpi/flash.c b/qemu/roms/u-boot/board/r360mpi/flash.c new file mode 100644 index 000000000..996a22e5a --- /dev/null +++ b/qemu/roms/u-boot/board/r360mpi/flash.c @@ -0,0 +1,468 @@ +/* + * (C) Copyright 2001 + * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net + * + * (C) Copyright 2001 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* #define DEBUG */ + +#include <common.h> +#include <mpc8xx.h> + +flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips */ + +#if defined(CONFIG_ENV_IS_IN_FLASH) +# ifndef CONFIG_ENV_ADDR +# define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + CONFIG_ENV_OFFSET) +# endif +# ifndef CONFIG_ENV_SIZE +# define CONFIG_ENV_SIZE CONFIG_ENV_SECT_SIZE +# endif +# ifndef CONFIG_ENV_SECT_SIZE +# define CONFIG_ENV_SECT_SIZE CONFIG_ENV_SIZE +# endif +#endif + +/*----------------------------------------------------------------------- + * Protection Flags: + */ +#define FLAG_PROTECT_SET 0x01 +#define FLAG_PROTECT_CLEAR 0x02 + +/* Board support for 1 or 2 flash devices */ +#undef FLASH_PORT_WIDTH32 +#define FLASH_PORT_WIDTH16 + +#ifdef FLASH_PORT_WIDTH16 +#define FLASH_PORT_WIDTH ushort +#define FLASH_PORT_WIDTHV vu_short +#else +#define FLASH_PORT_WIDTH ulong +#define FLASH_PORT_WIDTHV vu_long +#endif + +#define FPW FLASH_PORT_WIDTH +#define FPWV FLASH_PORT_WIDTHV + +/*----------------------------------------------------------------------- + * Functions + */ +static ulong flash_get_size (FPW * addr, flash_info_t * info); +static int write_data (flash_info_t * info, ulong dest, FPW data); +static void flash_get_offsets (ulong base, flash_info_t * info); + +/*----------------------------------------------------------------------- + */ + +unsigned long flash_init (void) +{ + volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; + volatile memctl8xx_t *memctl = &immap->im_memctl; + unsigned long size_b0; + int i; + + /* Init: no FLASHes known */ + for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i) { + flash_info[i].flash_id = FLASH_UNKNOWN; + } + + /* Static FLASH Bank configuration here - FIXME XXX */ + size_b0 = flash_get_size ((FPW *) FLASH_BASE0_PRELIM, &flash_info[0]); + + if (flash_info[0].flash_id == FLASH_UNKNOWN) { + printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n", + size_b0, size_b0 << 20); + } + + /* Remap FLASH according to real size */ + memctl->memc_or0 = CONFIG_SYS_OR_TIMING_FLASH | (-size_b0 & 0xFFFF8000); + memctl->memc_br0 = (CONFIG_SYS_FLASH_BASE & BR_BA_MSK) | BR_PS_16 | BR_MS_GPCM | BR_V; + + /* Re-do sizing to get full correct info */ + size_b0 = flash_get_size ((FPW *) CONFIG_SYS_FLASH_BASE, &flash_info[0]); + + flash_get_offsets (CONFIG_SYS_FLASH_BASE, &flash_info[0]); + +#if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE + /* monitor protection ON by default */ + (void) flash_protect (FLAG_PROTECT_SET, + CONFIG_SYS_FLASH_BASE, + CONFIG_SYS_FLASH_BASE + monitor_flash_len - 1, + &flash_info[0]); +#endif + +#ifdef CONFIG_ENV_IS_IN_FLASH + /* ENV protection ON by default */ + flash_protect (FLAG_PROTECT_SET, + CONFIG_ENV_ADDR, + CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1, + &flash_info[0]); +#endif + + flash_info[0].size = size_b0; + + return (size_b0); +} + +/*----------------------------------------------------------------------- + */ +static void flash_get_offsets (ulong base, flash_info_t * info) +{ + int i; + + if (info->flash_id == FLASH_UNKNOWN) { + return; + } + + if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) { + for (i = 0; i < info->sector_count; i++) { + info->start[i] = base + (i * 0x00020000); + } + } +} + +/*----------------------------------------------------------------------- + */ +void flash_print_info (flash_info_t * info) +{ + int i; + + if (info->flash_id == FLASH_UNKNOWN) { + printf ("missing or unknown FLASH type\n"); + return; + } + + switch (info->flash_id & FLASH_VENDMASK) { + case FLASH_MAN_INTEL: + printf ("INTEL "); + break; + default: + printf ("Unknown Vendor "); + break; + } + + switch (info->flash_id & FLASH_TYPEMASK) { + case FLASH_28F320J3A: + printf ("28F320J3A\n"); + break; + case FLASH_28F640J3A: + printf ("28F640J3A\n"); + break; + case FLASH_28F128J3A: + printf ("28F128J3A\n"); + break; + default: + printf ("Unknown Chip Type\n"); + break; + } + + printf (" Size: %ld MB in %d Sectors\n", + info->size >> 20, info->sector_count); + + printf (" Sector Start Addresses:"); + for (i = 0; i < info->sector_count; ++i) { + if ((i % 5) == 0) + printf ("\n "); + printf (" %08lX%s", + info->start[i], + info->protect[i] ? " (RO)" : " "); + } + printf ("\n"); + return; +} + +/*----------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------- + */ + +/* + * The following code cannot be run from FLASH! + */ + +static ulong flash_get_size (FPW * addr, flash_info_t * info) +{ + FPW value; + + /* Make sure Block Lock Bits get cleared */ + addr[0] = (FPW) 0x00FF00FF; + addr[0] = (FPW) 0x00600060; + addr[0] = (FPW) 0x00D000D0; + addr[0] = (FPW) 0x00FF00FF; + + /* Write auto select command: read Manufacturer ID */ + addr[0x5555] = (FPW) 0x00AA00AA; + addr[0x2AAA] = (FPW) 0x00550055; + addr[0x5555] = (FPW) 0x00900090; + + value = addr[0]; + + debug("Manuf. ID @ 0x%08lx: 0x%08x\n", (ulong)addr, value); + + switch (value) { + case (FPW) INTEL_MANUFACT: + info->flash_id = FLASH_MAN_INTEL; + break; + default: + info->flash_id = FLASH_UNKNOWN; + info->sector_count = 0; + info->size = 0; + addr[0] = (FPW) 0x00FF00FF; /* restore read mode */ + return (0); /* no or unknown flash */ + } + + value = addr[1]; /* device ID */ + + debug("Device ID @ 0x%08lx: 0x%08x\n", (ulong)(&addr[1]), value); + + switch (value) { + case (FPW) INTEL_ID_28F320J3A: + info->flash_id += FLASH_28F320J3A; + info->sector_count = 32; + info->size = 0x00400000; + break; /* => 4 MB */ + + case (FPW) INTEL_ID_28F640J3A: + info->flash_id += FLASH_28F640J3A; + info->sector_count = 64; + info->size = 0x00800000; + break; /* => 8 MB */ + + case (FPW) INTEL_ID_28F128J3A: + info->flash_id += FLASH_28F128J3A; + info->sector_count = 128; + info->size = 0x01000000; + break; /* => 16 MB */ + + default: + info->flash_id = FLASH_UNKNOWN; + break; + } + + if (info->sector_count > CONFIG_SYS_MAX_FLASH_SECT) { + printf ("** ERROR: sector count %d > max (%d) **\n", + info->sector_count, CONFIG_SYS_MAX_FLASH_SECT); + info->sector_count = CONFIG_SYS_MAX_FLASH_SECT; + } + + addr[0] = (FPW) 0x00FF00FF; /* restore read mode */ + + return (info->size); +} + + +/*----------------------------------------------------------------------- + */ + +int flash_erase (flash_info_t * info, int s_first, int s_last) +{ + int flag, prot, sect; + ulong type, start, now, last; + int rcode = 0; + + if ((s_first < 0) || (s_first > s_last)) { + if (info->flash_id == FLASH_UNKNOWN) { + printf ("- missing\n"); + } else { + printf ("- no sectors to erase\n"); + } + return 1; + } + + type = (info->flash_id & FLASH_VENDMASK); + if ((type != FLASH_MAN_INTEL)) { + printf ("Can't erase unknown flash type %08lx - aborted\n", + info->flash_id); + return 1; + } + + prot = 0; + for (sect = s_first; sect <= s_last; ++sect) { + if (info->protect[sect]) { + prot++; + } + } + + if (prot) { + printf ("- Warning: %d protected sectors will not be erased!\n", + prot); + } else { + printf ("\n"); + } + + start = get_timer (0); + last = start; + /* Start erase on unprotected sectors */ + for (sect = s_first; sect <= s_last; sect++) { + if (info->protect[sect] == 0) { /* not protected */ + FPWV *addr = (FPWV *) (info->start[sect]); + FPW status; + + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts (); + + *addr = (FPW) 0x00500050; /* clear status register */ + *addr = (FPW) 0x00200020; /* erase setup */ + *addr = (FPW) 0x00D000D0; /* erase confirm */ + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts (); + + /* wait at least 80us - let's wait 1 ms */ + udelay (1000); + + while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) { + if ((now = get_timer (start)) > CONFIG_SYS_FLASH_ERASE_TOUT) { + printf ("Timeout\n"); + *addr = (FPW) 0x00B000B0; /* suspend erase */ + *addr = (FPW) 0x00FF00FF; /* reset to read mode */ + rcode = 1; + break; + } + + /* show that we're waiting */ + if ((now - last) > 1000) { /* every second */ + putc ('.'); + last = now; + } + } + + *addr = (FPW) 0x00FF00FF; /* reset to read mode */ + } + } + printf (" done\n"); + return rcode; +} + +/*----------------------------------------------------------------------- + * Copy memory to flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + * 4 - Flash not identified + */ + +int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) +{ + ulong cp, wp; + FPW data; + + int i, l, rc, port_width; + + if (info->flash_id == FLASH_UNKNOWN) { + return 4; + } +/* get lower word aligned address */ +#ifdef FLASH_PORT_WIDTH16 + wp = (addr & ~1); + port_width = 2; +#else + wp = (addr & ~3); + port_width = 4; +#endif + + /* + * handle unaligned start bytes + */ + if ((l = addr - wp) != 0) { + data = 0; + for (i = 0, cp = wp; i < l; ++i, ++cp) { + data = (data << 8) | (*(uchar *) cp); + } + for (; i < port_width && cnt > 0; ++i) { + data = (data << 8) | *src++; + --cnt; + ++cp; + } + for (; cnt == 0 && i < port_width; ++i, ++cp) { + data = (data << 8) | (*(uchar *) cp); + } + + if ((rc = write_data (info, wp, data)) != 0) { + return (rc); + } + wp += port_width; + } + + /* + * handle word aligned part + */ + while (cnt >= port_width) { + data = 0; + for (i = 0; i < port_width; ++i) { + data = (data << 8) | *src++; + } + if ((rc = write_data (info, wp, data)) != 0) { + return (rc); + } + wp += port_width; + cnt -= port_width; + } + + if (cnt == 0) { + return (0); + } + + /* + * handle unaligned tail bytes + */ + data = 0; + for (i = 0, cp = wp; i < port_width && cnt > 0; ++i, ++cp) { + data = (data << 8) | *src++; + --cnt; + } + for (; i < port_width; ++i, ++cp) { + data = (data << 8) | (*(uchar *) cp); + } + + return (write_data (info, wp, data)); +} + +/*----------------------------------------------------------------------- + * Write a word or halfword to Flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ +static int write_data (flash_info_t * info, ulong dest, FPW data) +{ + FPWV *addr = (FPWV *) dest; + ulong status; + ulong start; + int flag; + + /* Check if Flash is (sufficiently) erased */ + if ((*addr & data) != data) { + printf ("not erased at %08lx (%x)\n", (ulong) addr, *addr); + return (2); + } + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts (); + + *addr = (FPW) 0x00400040; /* write setup */ + *addr = data; + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts (); + + start = get_timer (0); + + while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) { + if (get_timer (start) > CONFIG_SYS_FLASH_WRITE_TOUT) { + *addr = (FPW) 0x00FF00FF; /* restore read mode */ + return (1); + } + } + + *addr = (FPW) 0x00FF00FF; /* restore read mode */ + + return (0); +} diff --git a/qemu/roms/u-boot/board/r360mpi/pcmcia.c b/qemu/roms/u-boot/board/r360mpi/pcmcia.c new file mode 100644 index 000000000..a939b31d4 --- /dev/null +++ b/qemu/roms/u-boot/board/r360mpi/pcmcia.c @@ -0,0 +1,232 @@ +#include <common.h> +#include <mpc8xx.h> +#include <pcmcia.h> + +#undef CONFIG_PCMCIA + +#if defined(CONFIG_CMD_PCMCIA) +#define CONFIG_PCMCIA +#endif + +#if defined(CONFIG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD) +#define CONFIG_PCMCIA +#endif + +#ifdef CONFIG_PCMCIA + +#define PCMCIA_BOARD_MSG "R360MPI" + +int pcmcia_hardware_enable(int slot) +{ + volatile immap_t *immap; + volatile pcmconf8xx_t *pcmp; + volatile sysconf8xx_t *sysp; + uint reg, mask; + + debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot); + + udelay(10000); + + immap = (immap_t *)CONFIG_SYS_IMMR; + sysp = (sysconf8xx_t *)(&(((immap_t *)CONFIG_SYS_IMMR)->im_siu_conf)); + pcmp = (pcmconf8xx_t *)(&(((immap_t *)CONFIG_SYS_IMMR)->im_pcmcia)); + + /* + * Configure SIUMCR to enable PCMCIA port B + * (VFLS[0:1] are not used for debugging, we connect FRZ# instead) + */ + sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */ + + /* clear interrupt state, and disable interrupts */ + pcmp->pcmc_pscr = PCMCIA_MASK(_slot_); + pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_); + + /* + * Disable interrupts, DMA, and PCMCIA buffers + * (isolate the interface) and assert RESET signal + */ + debug ("Disable PCMCIA buffers and assert RESET\n"); + reg = 0; + reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */ + reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */ + PCMCIA_PGCRX(_slot_) = reg; + udelay(500); + + /* + * Configure Ports A, B & C pins for + * 5 Volts Enable and 3 Volts enable + */ + immap->im_ioport.iop_pcpar &= ~(0x0400); + immap->im_ioport.iop_pcso &= ~(0x0400);/* + immap->im_ioport.iop_pcdir |= 0x0400;*/ + + immap->im_ioport.iop_papar &= ~(0x0200);/* + immap->im_ioport.iop_padir |= 0x0200;*/ +#if 0 + immap->im_ioport.iop_pbpar &= ~(0xC000); + immap->im_ioport.iop_pbdir &= ~(0xC000); +#endif + /* remove all power */ + + immap->im_ioport.iop_pcdat |= 0x0400; + immap->im_ioport.iop_padat |= 0x0200; + + /* + * Make sure there is a card in the slot, then configure the interface. + */ + udelay(10000); + debug ("[%d] %s: PIPR(%p)=0x%x\n", + __LINE__,__FUNCTION__, + &(pcmp->pcmc_pipr),pcmp->pcmc_pipr); + if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) { + printf (" No Card found\n"); + return (1); + } + + /* + * Power On. + */ + mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot); + reg = pcmp->pcmc_pipr; + debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n", + reg, + (reg&PCMCIA_VS1(slot))?"n":"ff", + (reg&PCMCIA_VS2(slot))?"n":"ff"); + if ((reg & mask) == mask) { + immap->im_ioport.iop_pcdat &= ~(0x4000); + puts (" 5.0V card found: "); + } else { + immap->im_ioport.iop_padat &= ~(0x0002); + puts (" 3.3V card found: "); + } + immap->im_ioport.iop_pcdir |= 0x0400; + immap->im_ioport.iop_padir |= 0x0200; +#if 0 + /* VCC switch error flag, PCMCIA slot INPACK_ pin */ + cp->cp_pbdir &= ~(0x0020 | 0x0010); + cp->cp_pbpar &= ~(0x0020 | 0x0010); + udelay(500000); +#endif + debug ("Enable PCMCIA buffers and stop RESET\n"); + reg = PCMCIA_PGCRX(_slot_); + reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */ + reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */ + PCMCIA_PGCRX(_slot_) = reg; + + udelay(250000); /* some cards need >150 ms to come up :-( */ + + debug ("# hardware_enable done\n"); + + return (0); +} + + +#if defined(CONFIG_CMD_PCMCIA) +int pcmcia_hardware_disable(int slot) +{ + volatile immap_t *immap; + u_long reg; + + debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot); + + immap = (immap_t *)CONFIG_SYS_IMMR; + + /* remove all power */ + immap->im_ioport.iop_pcdat |= 0x0400; + immap->im_ioport.iop_padat |= 0x0200; + + /* Configure PCMCIA General Control Register */ + debug ("Disable PCMCIA buffers and assert RESET\n"); + reg = 0; + reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */ + reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */ + PCMCIA_PGCRX(_slot_) = reg; + + udelay(10000); + + return (0); +} +#endif + + +int pcmcia_voltage_set(int slot, int vcc, int vpp) +{ + volatile immap_t *immap; + volatile pcmconf8xx_t *pcmp; + u_long reg; + + debug ("voltage_set: " + PCMCIA_BOARD_MSG + " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n", + 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10); + + immap = (immap_t *)CONFIG_SYS_IMMR; + pcmp = (pcmconf8xx_t *)(&(((immap_t *)CONFIG_SYS_IMMR)->im_pcmcia)); + /* + * Disable PCMCIA buffers (isolate the interface) + * and assert RESET signal + */ + debug ("Disable PCMCIA buffers and assert RESET\n"); + reg = PCMCIA_PGCRX(_slot_); + reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */ + reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */ + PCMCIA_PGCRX(_slot_) = reg; + udelay(500); + + /* + * Configure Ports A & C pins for + * 5 Volts Enable and 3 Volts enable, + * Turn off all power + */ + debug ("PCMCIA power OFF\n"); + immap->im_ioport.iop_pcpar &= ~(0x0400); + immap->im_ioport.iop_pcso &= ~(0x0400);/* + immap->im_ioport.iop_pcdir |= 0x0400;*/ + + immap->im_ioport.iop_papar &= ~(0x0200);/* + immap->im_ioport.iop_padir |= 0x0200;*/ + + immap->im_ioport.iop_pcdat |= 0x0400; + immap->im_ioport.iop_padat |= 0x0200; + + reg = 0; + switch(vcc) { + case 0: break; + case 33: reg |= 0x0200; break; + case 50: reg |= 0x0400; break; + default: goto done; + } + + /* Checking supported voltages */ + + debug ("PIPR: 0x%x --> %s\n", + pcmp->pcmc_pipr, + (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V"); + + if (reg & 0x0200) + immap->im_ioport.iop_pcdat &= !reg; + if (reg & 0x0400) + immap->im_ioport.iop_padat &= !reg; + immap->im_ioport.iop_pcdir |= 0x0200; + immap->im_ioport.iop_padir |= 0x0400; + if (reg) { + debug ("PCMCIA powered at %sV\n", + (reg&0x0400) ? "5.0" : "3.3"); + } else { + debug ("PCMCIA powered down\n"); + } + +done: + debug ("Enable PCMCIA buffers and stop RESET\n"); + reg = PCMCIA_PGCRX(_slot_); + reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */ + reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */ + PCMCIA_PGCRX(_slot_) = reg; + udelay(500); + + debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n", + slot+'A'); + return (0); +} + +#endif /* CCONFIG_PCMCIA */ diff --git a/qemu/roms/u-boot/board/r360mpi/r360mpi.c b/qemu/roms/u-boot/board/r360mpi/r360mpi.c new file mode 100644 index 000000000..d06aea7a2 --- /dev/null +++ b/qemu/roms/u-boot/board/r360mpi/r360mpi.c @@ -0,0 +1,403 @@ +/* + * (C) Copyright 2001-2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <config.h> +#include <mpc8xx.h> +#include <i2c.h> + +#include <commproc.h> +#include <command.h> +#include <malloc.h> + +#include <linux/types.h> +#include <linux/string.h> /* for strdup */ + + +/* + * Memory Controller Using + * + * CS0 - Flash memory (0x40000000) + * CS1 - FLASH memory (0x????????) + * CS2 - SDRAM (0x00000000) + * CS3 - + * CS4 - + * CS5 - + * CS6 - PCMCIA device + * CS7 - PCMCIA device + */ + +/* ------------------------------------------------------------------------- */ + +#define _not_used_ 0xffffffff + +const uint sdram_table[]= +{ + /* single read. (offset 0 in upm RAM) */ + 0x1f07fc04, 0xeeaefc04, 0x11adfc04, 0xefbbbc00, + 0x1ff77c47, + + /* MRS initialization (offset 5) */ + + 0x1ff77c34, 0xefeabc34, 0x1fb57c35, + + /* burst read. (offset 8 in upm RAM) */ + 0x1f07fc04, 0xeeaefc04, 0x10adfc04, 0xf0affc00, + 0xf0affc00, 0xf1affc00, 0xefbbbc00, 0x1ff77c47, + _not_used_, _not_used_, _not_used_, _not_used_, + _not_used_, _not_used_, _not_used_, _not_used_, + + /* single write. (offset 18 in upm RAM) */ + 0x1f27fc04, 0xeeaebc00, 0x01b93c04, 0x1ff77c47, + _not_used_, _not_used_, _not_used_, _not_used_, + + /* burst write. (offset 20 in upm RAM) */ + 0x1f07fc04, 0xeeaebc00, 0x10ad7c00, 0xf0affc00, + 0xf0affc00, 0xe1bbbc04, 0x1ff77c47, _not_used_, + _not_used_, _not_used_, _not_used_, _not_used_, + _not_used_, _not_used_, _not_used_, _not_used_, + + /* refresh. (offset 30 in upm RAM) */ + 0x1ff5fc84, 0xfffffc04, 0xfffffc04, 0xfffffc04, + 0xfffffc84, 0xfffffc07, _not_used_, _not_used_, + _not_used_, _not_used_, _not_used_, _not_used_, + + /* exception. (offset 3c in upm RAM) */ + 0x7ffffc07, _not_used_, _not_used_, _not_used_ }; + +/* ------------------------------------------------------------------------- */ + +/* + * Check Board Identity: + */ + +int checkboard (void) +{ + puts ("Board: R360 MPI Board\n"); + return 0; +} + +/* ------------------------------------------------------------------------- */ + +static long int dram_size (long int, long int *, long int); + +/* ------------------------------------------------------------------------- */ + +phys_size_t initdram (int board_type) +{ + volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; + volatile memctl8xx_t *memctl = &immap->im_memctl; + long int size8, size9; + long int size_b0 = 0; + unsigned long reg; + + upmconfig (UPMA, (uint *) sdram_table, + sizeof (sdram_table) / sizeof (uint)); + + /* + * Preliminary prescaler for refresh (depends on number of + * banks): This value is selected for four cycles every 62.4 us + * with two SDRAM banks or four cycles every 31.2 us with one + * bank. It will be adjusted after memory sizing. + */ + memctl->memc_mptpr = CONFIG_SYS_MPTPR_2BK_8K; + + memctl->memc_mar = 0x00000088; + + /* + * Map controller bank 2 to the SDRAM bank at + * preliminary address - these have to be modified after the + * SDRAM size has been determined. + */ + memctl->memc_or2 = CONFIG_SYS_OR2_PRELIM; + memctl->memc_br2 = CONFIG_SYS_BR2_PRELIM; + + memctl->memc_mamr = CONFIG_SYS_MAMR_8COL & (~(MAMR_PTAE)); /* no refresh yet */ + + udelay (200); + + /* perform SDRAM initializsation sequence */ + + memctl->memc_mcr = 0x80004105; /* SDRAM bank 0 */ + udelay (200); + memctl->memc_mcr = 0x80004230; /* SDRAM bank 0 - execute twice */ + udelay (200); + + memctl->memc_mamr |= MAMR_PTAE; /* enable refresh */ + + udelay (1000); + + /* + * Check Bank 2 Memory Size for re-configuration + * + * try 8 column mode + */ + size8 = dram_size (CONFIG_SYS_MAMR_8COL, (long *) SDRAM_BASE2_PRELIM, + SDRAM_MAX_SIZE); + + udelay (1000); + + /* + * try 9 column mode + */ + size9 = dram_size (CONFIG_SYS_MAMR_9COL, (long *) SDRAM_BASE2_PRELIM, + SDRAM_MAX_SIZE); + + if (size8 < size9) { /* leave configuration at 9 columns */ + size_b0 = size9; +/* debug ("SDRAM Bank 0 in 9 column mode: %ld MB\n", size >> 20); */ + } else { /* back to 8 columns */ + size_b0 = size8; + memctl->memc_mamr = CONFIG_SYS_MAMR_8COL; + udelay (500); +/* debug ("SDRAM Bank 0 in 8 column mode: %ld MB\n", size >> 20); */ + } + + udelay (1000); + + /* + * Adjust refresh rate depending on SDRAM type, both banks + * For types > 128 MBit leave it at the current (fast) rate + */ + if ((size_b0 < 0x02000000)) { + /* reduce to 15.6 us (62.4 us / quad) */ + memctl->memc_mptpr = CONFIG_SYS_MPTPR_2BK_4K; + udelay (1000); + } + + /* + * Final mapping + */ + + memctl->memc_or1 = ((-size_b0) & 0xFFFF0000) | CONFIG_SYS_OR_TIMING_SDRAM; + memctl->memc_br1 = (CONFIG_SYS_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V; + + /* adjust refresh rate depending on SDRAM type, one bank */ + reg = memctl->memc_mptpr; + reg >>= 1; /* reduce to CONFIG_SYS_MPTPR_1BK_8K / _4K */ + memctl->memc_mptpr = reg; + + udelay (10000); + +#ifdef CONFIG_CAN_DRIVER + /* Initialize OR3 / BR3 */ + memctl->memc_or3 = CONFIG_SYS_OR3_CAN; /* switch GPLB_5 to GPLA_5 */ + memctl->memc_br3 = CONFIG_SYS_BR3_CAN; + + /* Initialize MBMR */ + memctl->memc_mbmr = MBMR_GPL_B4DIS; /* GPL_B4 works as UPWAITB */ + + /* Initialize UPMB for CAN: single read */ + memctl->memc_mdr = 0xFFFFC004; + memctl->memc_mcr = 0x0100 | UPMB; + + memctl->memc_mdr = 0x0FFFD004; + memctl->memc_mcr = 0x0101 | UPMB; + + memctl->memc_mdr = 0x0FFFC000; + memctl->memc_mcr = 0x0102 | UPMB; + + memctl->memc_mdr = 0x3FFFC004; + memctl->memc_mcr = 0x0103 | UPMB; + + memctl->memc_mdr = 0xFFFFDC05; + memctl->memc_mcr = 0x0104 | UPMB; + + /* Initialize UPMB for CAN: single write */ + memctl->memc_mdr = 0xFFFCC004; + memctl->memc_mcr = 0x0118 | UPMB; + + memctl->memc_mdr = 0xCFFCD004; + memctl->memc_mcr = 0x0119 | UPMB; + + memctl->memc_mdr = 0x0FFCC000; + memctl->memc_mcr = 0x011A | UPMB; + + memctl->memc_mdr = 0x7FFCC004; + memctl->memc_mcr = 0x011B | UPMB; + + memctl->memc_mdr = 0xFFFDCC05; + memctl->memc_mcr = 0x011C | UPMB; +#endif + + return (size_b0); +} + +/* ------------------------------------------------------------------------- */ + +/* + * Check memory range for valid RAM. A simple memory test determines + * the actually available RAM size between addresses `base' and + * `base + maxsize'. Some (not all) hardware errors are detected: + * - short between address lines + * - short between data lines + */ + +static long int dram_size (long int mamr_value, + long int *base, long int maxsize) +{ + volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; + volatile memctl8xx_t *memctl = &immap->im_memctl; + + memctl->memc_mamr = mamr_value; + + return (get_ram_size(base, maxsize)); +} + +/* ------------------------------------------------------------------------- */ + +void r360_i2c_lcd_write (uchar data0, uchar data1) +{ + if (i2c_write (CONFIG_SYS_I2C_LCD_ADDR, data0, 1, &data1, 1)) { + printf("Can't write lcd data 0x%02X 0x%02X.\n", data0, data1); + } +} + +/* ------------------------------------------------------------------------- */ + +/*----------------------------------------------------------------------- + * Keyboard Controller + */ + +/* Number of bytes returned from Keyboard Controller */ +#define KEYBD_KEY_MAX 16 /* maximum key number */ +#define KEYBD_DATALEN ((KEYBD_KEY_MAX + 7) / 8) /* normal key scan data */ + +static uchar *key_match (uchar *); + +int misc_init_r (void) +{ + char kbd_data[KEYBD_DATALEN]; + char keybd_env[2 * KEYBD_DATALEN + 1]; + char *str; + int i; + + i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); + + i2c_read (CONFIG_SYS_I2C_KEY_ADDR, 0, 0, (uchar *)kbd_data, KEYBD_DATALEN); + + for (i = 0; i < KEYBD_DATALEN; ++i) { + sprintf (keybd_env + i + i, "%02X", kbd_data[i]); + } + setenv ("keybd", keybd_env); + + str = strdup ((char *)key_match ((uchar *)keybd_env)); /* decode keys */ + +#ifdef CONFIG_PREBOOT /* automatically configure "preboot" command on key match */ + setenv ("preboot", str); /* set or delete definition */ +#endif /* CONFIG_PREBOOT */ + if (str != NULL) { + free (str); + } + + return (0); +} + +/*----------------------------------------------------------------------- + * Check if pressed key(s) match magic sequence, + * and return the command string associated with that key(s). + * + * If no key press was decoded, NULL is returned. + * + * Note: the first character of the argument will be overwritten with + * the "magic charcter code" of the decoded key(s), or '\0'. + * + * + * Note: the string points to static environment data and must be + * saved before you call any function that modifies the environment. + */ +#ifdef CONFIG_PREBOOT + +static uchar kbd_magic_prefix[] = "key_magic"; +static uchar kbd_command_prefix[] = "key_cmd"; + +static uchar *key_match (uchar * kbd_str) +{ + uchar magic[sizeof (kbd_magic_prefix) + 1]; + uchar cmd_name[sizeof (kbd_command_prefix) + 1]; + uchar *str, *suffix; + uchar *kbd_magic_keys; + char *cmd; + + /* + * The following string defines the characters that can pe appended + * to "key_magic" to form the names of environment variables that + * hold "magic" key codes, i. e. such key codes that can cause + * pre-boot actions. If the string is empty (""), then only + * "key_magic" is checked (old behaviour); the string "125" causes + * checks for "key_magic1", "key_magic2" and "key_magic5", etc. + */ + if ((kbd_magic_keys = (uchar *)getenv ("magic_keys")) != NULL) { + /* loop over all magic keys; + * use '\0' suffix in case of empty string + */ + for (suffix = kbd_magic_keys; + *suffix || suffix == kbd_magic_keys; + ++suffix) { + sprintf ((char *)magic, "%s%c", kbd_magic_prefix, *suffix); + +#if 0 + printf ("### Check magic \"%s\"\n", magic); +#endif + + if ((str = (uchar *)getenv ((char *)magic)) != 0) { + +#if 0 + printf ("### Compare \"%s\" \"%s\"\n", + kbd_str, str); +#endif + if (strcmp ((char *)kbd_str, (char *)str) == 0) { + sprintf ((char *)cmd_name, "%s%c", + kbd_command_prefix, + *suffix); + + if ((cmd = getenv ((char *)cmd_name)) != 0) { +#if 0 + printf ("### Set PREBOOT to $(%s): \"%s\"\n", + cmd_name, cmd); +#endif + return ((uchar *)cmd); + } + } + } + } + } +#if 0 + printf ("### Delete PREBOOT\n"); +#endif + *kbd_str = '\0'; + return (NULL); +} +#endif /* CONFIG_PREBOOT */ + +/* Read Keyboard status */ +int do_kbd (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) +{ + uchar kbd_data[KEYBD_DATALEN]; + uchar keybd_env[2 * KEYBD_DATALEN + 1]; + int i; + + i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); + + /* Read keys */ + i2c_read (CONFIG_SYS_I2C_KEY_ADDR, 0, 0, kbd_data, KEYBD_DATALEN); + + puts ("Keys:"); + for (i = 0; i < KEYBD_DATALEN; ++i) { + sprintf ((char *)(keybd_env + i + i), "%02X", kbd_data[i]); + printf (" %02x", kbd_data[i]); + } + putc ('\n'); + setenv ("keybd", (char *)keybd_env); + return 0; +} + +U_BOOT_CMD( + kbd, 1, 1, do_kbd, + "read keyboard status", + "" +); diff --git a/qemu/roms/u-boot/board/r360mpi/u-boot.lds b/qemu/roms/u-boot/board/r360mpi/u-boot.lds new file mode 100644 index 000000000..5f69bc4eb --- /dev/null +++ b/qemu/roms/u-boot/board/r360mpi/u-boot.lds @@ -0,0 +1,89 @@ +/* + * (C) Copyright 2000-2010 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +OUTPUT_ARCH(powerpc) + +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .text : + { + /* WARNING - the following is hand-optimized to fit within */ + /* the sector layout of our flash chips! XXX FIXME XXX */ + arch/powerpc/cpu/mpc8xx/start.o (.text*) + arch/powerpc/cpu/mpc8xx/traps.o (.text*) + + *(.text*) + } + _etext = .; + PROVIDE (etext = .); + .rodata : + { + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) + } + + /* Read-write section, merged into data segment: */ + . = (. + 0x00FF) & 0xFFFFFF00; + _erotext = .; + PROVIDE (erotext = .); + .reloc : + { + _GOT2_TABLE_ = .; + KEEP(*(.got2)) + KEEP(*(.got)) + PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4); + _FIXUP_TABLE_ = .; + KEEP(*(.fixup)) + } + __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1; + __fixup_entries = (. - _FIXUP_TABLE_)>>2; + + .data : + { + *(.data*) + *(.sdata*) + } + _edata = .; + PROVIDE (edata = .); + + . = .; + + . = ALIGN(4); + .u_boot_list : { + KEEP(*(SORT(.u_boot_list*))); + } + + + . = .; + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + . = ALIGN(256); + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(256); + __init_end = .; + + __bss_start = .; + .bss (NOLOAD) : + { + *(.bss*) + *(.sbss*) + *(COMMON) + . = ALIGN(4); + } + __bss_end = . ; + PROVIDE (end = .); + . = ALIGN(128 * 1024); + .ppcenv : + { + common/env_embedded.o (.ppcenv) + } +} |