summaryrefslogtreecommitdiffstats
path: root/u-boot/board/mpl
diff options
context:
space:
mode:
authorH. Nikolaus Schaller <hns@goldelico.com>2012-03-26 20:55:28 +0200
committerH. Nikolaus Schaller <hns@goldelico.com>2012-03-26 20:55:28 +0200
commit92988a21ad4c4c9504295ccb580c9f806134471b (patch)
tree5effc9f14170112450de05c67dafbe8d5034d595 /u-boot/board/mpl
parentca2b506783b676c95762c54ea24dcfdaae1947c9 (diff)
downloadbootable_bootloader_goldelico_gta04-92988a21ad4c4c9504295ccb580c9f806134471b.zip
bootable_bootloader_goldelico_gta04-92988a21ad4c4c9504295ccb580c9f806134471b.tar.gz
bootable_bootloader_goldelico_gta04-92988a21ad4c4c9504295ccb580c9f806134471b.tar.bz2
added boot script files to repository
Diffstat (limited to 'u-boot/board/mpl')
-rw-r--r--u-boot/board/mpl/common/common_util.c620
-rw-r--r--u-boot/board/mpl/common/common_util.h45
-rw-r--r--u-boot/board/mpl/common/flash.c886
-rw-r--r--u-boot/board/mpl/common/isa.c494
-rw-r--r--u-boot/board/mpl/common/isa.h57
-rw-r--r--u-boot/board/mpl/common/kbd.c645
-rw-r--r--u-boot/board/mpl/common/kbd.h35
-rw-r--r--u-boot/board/mpl/common/pci.c109
-rw-r--r--u-boot/board/mpl/common/pci_parts.h193
-rw-r--r--u-boot/board/mpl/common/piix4_pci.h165
-rw-r--r--u-boot/board/mpl/common/usb_uhci.c1169
-rw-r--r--u-boot/board/mpl/common/usb_uhci.h188
-rw-r--r--u-boot/board/mpl/mip405/Makefile56
-rw-r--r--u-boot/board/mpl/mip405/cmd_mip405.c65
-rw-r--r--u-boot/board/mpl/mip405/init.S221
-rw-r--r--u-boot/board/mpl/mip405/mip405.c805
-rw-r--r--u-boot/board/mpl/mip405/mip405.h183
-rw-r--r--u-boot/board/mpl/pati/Makefile54
-rw-r--r--u-boot/board/mpl/pati/cmd_pati.c449
-rw-r--r--u-boot/board/mpl/pati/pati.c616
-rw-r--r--u-boot/board/mpl/pati/pati.h440
-rw-r--r--u-boot/board/mpl/pati/pci_eeprom.h91
-rw-r--r--u-boot/board/mpl/pati/plx9056.h111
-rw-r--r--u-boot/board/mpl/pip405/Makefile59
-rw-r--r--u-boot/board/mpl/pip405/cmd_pip405.c69
-rw-r--r--u-boot/board/mpl/pip405/init.S218
-rw-r--r--u-boot/board/mpl/pip405/pip405.c955
-rw-r--r--u-boot/board/mpl/pip405/pip405.h148
-rw-r--r--u-boot/board/mpl/pip405/u-boot.lds.debug135
-rw-r--r--u-boot/board/mpl/vcma9/Makefile56
-rw-r--r--u-boot/board/mpl/vcma9/cmd_vcma9.c186
-rw-r--r--u-boot/board/mpl/vcma9/config.mk24
-rw-r--r--u-boot/board/mpl/vcma9/flash.c432
-rw-r--r--u-boot/board/mpl/vcma9/lowlevel_init.S212
-rw-r--r--u-boot/board/mpl/vcma9/vcma9.c362
-rw-r--r--u-boot/board/mpl/vcma9/vcma9.h134
36 files changed, 10687 insertions, 0 deletions
diff --git a/u-boot/board/mpl/common/common_util.c b/u-boot/board/mpl/common/common_util.c
new file mode 100644
index 0000000..d3300ed
--- /dev/null
+++ b/u-boot/board/mpl/common/common_util.c
@@ -0,0 +1,620 @@
+/*
+ * (C) Copyright 2001
+ * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+#include <command.h>
+#include <video_fb.h>
+#include "common_util.h"
+#include <asm/processor.h>
+#include <asm/byteorder.h>
+#include <i2c.h>
+#include <pci.h>
+#include <malloc.h>
+#include <bzlib.h>
+
+#ifdef CONFIG_PIP405
+#include "../pip405/pip405.h"
+#include <asm/4xx_pci.h>
+#endif
+#ifdef CONFIG_MIP405
+#include "../mip405/mip405.h"
+#include <asm/4xx_pci.h>
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#if defined(CONFIG_PATI)
+#define FIRM_START 0xFFF00000
+#endif
+
+extern int mem_test(ulong start, ulong ramsize, int quiet);
+
+#define I2C_BACKUP_ADDR 0x7C00 /* 0x200 bytes for backup */
+#define IMAGE_SIZE CONFIG_SYS_MONITOR_LEN /* ugly, but it works for now */
+
+extern flash_info_t flash_info[]; /* info for FLASH chips */
+
+static int
+mpl_prg(uchar *src, ulong size)
+{
+ ulong start;
+ flash_info_t *info;
+ int i, rc;
+#if defined(CONFIG_PATI)
+ int start_sect;
+#endif
+#if defined(CONFIG_PIP405) || defined(CONFIG_MIP405) || defined(CONFIG_PATI)
+ char *copystr = (char *)src;
+ ulong *magic = (ulong *)src;
+#endif
+
+ info = &flash_info[0];
+
+#if defined(CONFIG_PIP405) || defined(CONFIG_MIP405) || defined(CONFIG_PATI)
+ if (uimage_to_cpu (magic[0]) != IH_MAGIC) {
+ puts("Bad Magic number\n");
+ return -1;
+ }
+ /* some more checks before we delete the Flash... */
+ /* Checking the ISO_STRING prevents to program a
+ * wrong Firmware Image into the flash.
+ */
+ i = 4; /* skip Magic number */
+ while (1) {
+ if (strncmp(&copystr[i], "MEV-", 4) == 0)
+ break;
+ if (i++ >= 0x100) {
+ puts("Firmware Image for unknown Target\n");
+ return -1;
+ }
+ }
+ /* we have the ISO STRING, check */
+ if (strncmp(&copystr[i], CONFIG_ISO_STRING, sizeof(CONFIG_ISO_STRING)-1) != 0) {
+ printf("Wrong Firmware Image: %s\n", &copystr[i]);
+ return -1;
+ }
+#if !defined(CONFIG_PATI)
+ start = 0 - size;
+ for (i = info->sector_count-1; i > 0; i--) {
+ info->protect[i] = 0; /* unprotect this sector */
+ if (start >= info->start[i])
+ break;
+ }
+ /* set-up flash location */
+ /* now erase flash */
+ printf("Erasing at %lx (sector %d) (start %lx)\n",
+ start,i,info->start[i]);
+ if ((rc = flash_erase (info, i, info->sector_count-1)) != 0) {
+ puts("ERROR ");
+ flash_perror(rc);
+ return (1);
+ }
+
+#else /* #if !defined(CONFIG_PATI */
+ start = FIRM_START;
+ start_sect = -1;
+ for (i = 0; i < info->sector_count; i++) {
+ if (start < info->start[i]) {
+ start_sect = i - 1;
+ break;
+ }
+ }
+
+ info->protect[i - 1] = 0; /* unprotect this sector */
+ for (; i < info->sector_count; i++) {
+ if ((start + size) < info->start[i])
+ break;
+ info->protect[i] = 0; /* unprotect this sector */
+ }
+
+ i--;
+ /* set-up flash location */
+ /* now erase flash */
+ printf ("Erasing at %lx to %lx (sector %d to %d) (%lx to %lx)\n",
+ start, start + size, start_sect, i,
+ info->start[start_sect], info->start[i]);
+ if ((rc = flash_erase (info, start_sect, i)) != 0) {
+ puts ("ERROR ");
+ flash_perror (rc);
+ return (1);
+ }
+#endif /* defined(CONFIG_PATI) */
+
+#elif defined(CONFIG_VCMA9)
+ start = 0;
+ for (i = 0; i <info->sector_count; i++) {
+ info->protect[i] = 0; /* unprotect this sector */
+ if (size < info->start[i])
+ break;
+ }
+ /* set-up flash location */
+ /* now erase flash */
+ printf("Erasing at %lx (sector %d) (start %lx)\n",
+ start,0,info->start[0]);
+ if ((rc = flash_erase (info, 0, i)) != 0) {
+ puts("ERROR ");
+ flash_perror(rc);
+ return (1);
+ }
+
+#endif
+ printf("flash erased, programming from 0x%lx 0x%lx Bytes\n",
+ (ulong)src, size);
+ if ((rc = flash_write ((char *)src, start, size)) != 0) {
+ puts("ERROR ");
+ flash_perror(rc);
+ return (1);
+ }
+ puts("OK programming done\n");
+ return 0;
+}
+
+
+static int
+mpl_prg_image(uchar *ld_addr)
+{
+ unsigned long len;
+ uchar *data;
+ image_header_t *hdr = (image_header_t *)ld_addr;
+ int rc;
+
+#if defined(CONFIG_FIT)
+ if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
+ puts ("Non legacy image format not supported\n");
+ return -1;
+ }
+#endif
+
+ if (!image_check_magic (hdr)) {
+ puts("Bad Magic Number\n");
+ return 1;
+ }
+ image_print_contents (hdr);
+ if (!image_check_os (hdr, IH_OS_U_BOOT)) {
+ puts("No U-Boot Image\n");
+ return 1;
+ }
+ if (!image_check_type (hdr, IH_TYPE_FIRMWARE)) {
+ puts("No Firmware Image\n");
+ return 1;
+ }
+ if (!image_check_hcrc (hdr)) {
+ puts("Bad Header Checksum\n");
+ return 1;
+ }
+ puts("Verifying Checksum ... ");
+ if (!image_check_dcrc (hdr)) {
+ puts("Bad Data CRC\n");
+ return 1;
+ }
+ puts("OK\n");
+
+ data = (uchar *)image_get_data (hdr);
+ len = image_get_data_size (hdr);
+
+ if (image_get_comp (hdr) != IH_COMP_NONE) {
+ uchar *buf;
+ /* reserve space for uncompressed image */
+ if ((buf = malloc(IMAGE_SIZE)) == NULL) {
+ puts("Insufficient space for decompression\n");
+ return 1;
+ }
+
+ switch (image_get_comp (hdr)) {
+ case IH_COMP_GZIP:
+ puts("Uncompressing (GZIP) ... ");
+ rc = gunzip ((void *)(buf), IMAGE_SIZE, data, &len);
+ if (rc != 0) {
+ puts("GUNZIP ERROR\n");
+ free(buf);
+ return 1;
+ }
+ puts("OK\n");
+ break;
+#ifdef CONFIG_BZIP2
+ case IH_COMP_BZIP2:
+ puts("Uncompressing (BZIP2) ... ");
+ {
+ uint retlen = IMAGE_SIZE;
+ rc = BZ2_bzBuffToBuffDecompress ((char *)(buf), &retlen,
+ (char *)data, len, 0, 0);
+ len = retlen;
+ }
+ if (rc != BZ_OK) {
+ printf ("BUNZIP2 ERROR: %d\n", rc);
+ free(buf);
+ return 1;
+ }
+ puts("OK\n");
+ break;
+#endif
+ default:
+ printf ("Unimplemented compression type %d\n",
+ image_get_comp (hdr));
+ free(buf);
+ return 1;
+ }
+
+ rc = mpl_prg(buf, len);
+ free(buf);
+ } else {
+ rc = mpl_prg(data, len);
+ }
+
+ return(rc);
+}
+
+#if !defined(CONFIG_PATI)
+void get_backup_values(backup_t *buf)
+{
+ i2c_read(CONFIG_SYS_DEF_EEPROM_ADDR, I2C_BACKUP_ADDR,2,(void *)buf,sizeof(backup_t));
+}
+
+void set_backup_values(int overwrite)
+{
+ backup_t back;
+ int i;
+
+ get_backup_values(&back);
+ if(!overwrite) {
+ if(strncmp(back.signature,"MPL\0",4)==0) {
+ puts("Not possible to write Backup\n");
+ return;
+ }
+ }
+ memcpy(back.signature,"MPL\0",4);
+ i = getenv_f("serial#",back.serial_name,16);
+ if(i < 0) {
+ puts("Not possible to write Backup\n");
+ return;
+ }
+ back.serial_name[16]=0;
+ i = getenv_f("ethaddr",back.eth_addr,20);
+ if(i < 0) {
+ puts("Not possible to write Backup\n");
+ return;
+ }
+ back.eth_addr[20]=0;
+ i2c_write(CONFIG_SYS_DEF_EEPROM_ADDR, I2C_BACKUP_ADDR,2,(void *)&back,sizeof(backup_t));
+}
+
+void clear_env_values(void)
+{
+ backup_t back;
+ unsigned char env_crc[4];
+
+ memset(&back,0xff,sizeof(backup_t));
+ memset(env_crc,0x00,4);
+ i2c_write(CONFIG_SYS_DEF_EEPROM_ADDR,I2C_BACKUP_ADDR,2,(void *)&back,sizeof(backup_t));
+ i2c_write(CONFIG_SYS_DEF_EEPROM_ADDR,CONFIG_ENV_OFFSET,2,(void *)env_crc,4);
+}
+
+/*
+ * check crc of "older" environment
+ */
+int check_env_old_size(ulong oldsize)
+{
+ ulong crc, len, new;
+ unsigned off;
+ uchar buf[64];
+
+ /* read old CRC */
+ eeprom_read (CONFIG_SYS_DEF_EEPROM_ADDR,
+ CONFIG_ENV_OFFSET,
+ (uchar *)&crc, sizeof(ulong));
+
+ new = 0;
+ len = oldsize;
+ off = sizeof(long);
+ len = oldsize-off;
+ while (len > 0) {
+ int n = (len > sizeof(buf)) ? sizeof(buf) : len;
+
+ eeprom_read (CONFIG_SYS_DEF_EEPROM_ADDR, CONFIG_ENV_OFFSET+off, buf, n);
+ new = crc32 (new, buf, n);
+ len -= n;
+ off += n;
+ }
+
+ return (crc == new);
+}
+
+static ulong oldsizes[] = {
+ 0x200,
+ 0x800,
+ 0
+};
+
+void copy_old_env(ulong size)
+{
+ uchar name_buf[64];
+ uchar value_buf[0x800];
+ uchar c;
+ ulong len;
+ unsigned off;
+ uchar *name, *value;
+
+ name = &name_buf[0];
+ value = &value_buf[0];
+ len=size;
+ off = sizeof(long);
+ while (len > off) {
+ eeprom_read (CONFIG_SYS_DEF_EEPROM_ADDR, CONFIG_ENV_OFFSET+off, &c, 1);
+ if(c != '=') {
+ *name++=c;
+ off++;
+ }
+ else {
+ *name++='\0';
+ off++;
+ do {
+ eeprom_read (CONFIG_SYS_DEF_EEPROM_ADDR, CONFIG_ENV_OFFSET+off, &c, 1);
+ *value++=c;
+ off++;
+ if(c == '\0')
+ break;
+ } while(len > off);
+ name = &name_buf[0];
+ value = &value_buf[0];
+ if(strncmp((char *)name,"baudrate",8)!=0) {
+ setenv((char *)name,(char *)value);
+ }
+
+ }
+ }
+}
+
+
+void check_env(void)
+{
+ char *s;
+ int i=0;
+ char buf[32];
+ backup_t back;
+
+ s=getenv("serial#");
+ if(!s) {
+ while(oldsizes[i]) {
+ if(check_env_old_size(oldsizes[i]))
+ break;
+ i++;
+ }
+ if(!oldsizes[i]) {
+ /* no old environment has been found */
+ get_backup_values (&back);
+ if (strncmp (back.signature, "MPL\0", 4) == 0) {
+ sprintf (buf, "%s", back.serial_name);
+ setenv ("serial#", buf);
+ sprintf (buf, "%s", back.eth_addr);
+ setenv ("ethaddr", buf);
+ printf ("INFO: serial# and ethaddr recovered, use saveenv\n");
+ return;
+ }
+ }
+ else {
+ copy_old_env(oldsizes[i]);
+ puts("INFO: old environment ajusted, use saveenv\n");
+ }
+ }
+ else {
+ /* check if back up is set */
+ get_backup_values(&back);
+ if(strncmp(back.signature,"MPL\0",4)!=0) {
+ set_backup_values(0);
+ }
+ }
+}
+
+#endif /* #if !defined(CONFIG_PATI) */
+
+int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ ulong ld_addr;
+ int result;
+#if !defined(CONFIG_PATI)
+ ulong size = IMAGE_SIZE;
+ ulong src = MULTI_PURPOSE_SOCKET_ADDR;
+ backup_t back;
+#endif
+
+ if (strcmp(argv[1], "flash") == 0)
+ {
+#if defined(CONFIG_CMD_FDC)
+ if (strcmp(argv[2], "floppy") == 0) {
+ char *local_args[3];
+ extern int do_fdcboot (cmd_tbl_t *, int, int, char *[]);
+ puts("\nupdating bootloader image from floppy\n");
+ local_args[0] = argv[0];
+ if(argc==4) {
+ local_args[1] = argv[3];
+ local_args[2] = NULL;
+ ld_addr=simple_strtoul(argv[3], NULL, 16);
+ result=do_fdcboot(cmdtp, 0, 2, local_args);
+ }
+ else {
+ local_args[1] = NULL;
+ ld_addr=CONFIG_SYS_LOAD_ADDR;
+ result=do_fdcboot(cmdtp, 0, 1, local_args);
+ }
+ result=mpl_prg_image((uchar *)ld_addr);
+ return result;
+ }
+#endif
+ if (strcmp(argv[2], "mem") == 0) {
+ if(argc==4) {
+ ld_addr=simple_strtoul(argv[3], NULL, 16);
+ }
+ else {
+ ld_addr=load_addr;
+ }
+ printf ("\nupdating bootloader image from memory at %lX\n",ld_addr);
+ result=mpl_prg_image((uchar *)ld_addr);
+ return result;
+ }
+#if !defined(CONFIG_PATI)
+ if (strcmp(argv[2], "mps") == 0) {
+ puts("\nupdating bootloader image from MPS\n");
+ result=mpl_prg((uchar *)src,size);
+ return result;
+ }
+#endif /* #if !defined(CONFIG_PATI) */
+ }
+#if !defined(CONFIG_PATI)
+ if (strcmp(argv[1], "clearenvvalues") == 0)
+ {
+ if (strcmp(argv[2], "yes") == 0)
+ {
+ clear_env_values();
+ return 0;
+ }
+ }
+ if (strcmp(argv[1], "getback") == 0) {
+ get_backup_values(&back);
+ back.signature[3]=0;
+ back.serial_name[16]=0;
+ back.eth_addr[20]=0;
+ printf("GetBackUp: signature: %s\n",back.signature);
+ printf(" serial#: %s\n",back.serial_name);
+ printf(" ethaddr: %s\n",back.eth_addr);
+ return 0;
+ }
+ if (strcmp(argv[1], "setback") == 0) {
+ set_backup_values(1);
+ return 0;
+ }
+#endif
+ return cmd_usage(cmdtp);
+}
+
+
+#if defined(CONFIG_CMD_DOC)
+void doc_init (void)
+{
+ doc_probe(MULTI_PURPOSE_SOCKET_ADDR);
+}
+#endif
+
+
+#ifdef CONFIG_VIDEO
+/******************************************************
+ * Routines to display the Board information
+ * to the screen (since the VGA will be initialized as last,
+ * we must resend the infos)
+ */
+
+#ifdef CONFIG_CONSOLE_EXTRA_INFO
+extern GraphicDevice ctfb;
+extern int get_boot_mode(void);
+
+void video_get_info_str (int line_number, char *info)
+{
+ /* init video info strings for graphic console */
+ PPC4xx_SYS_INFO sys_info;
+ char rev;
+ int i,boot;
+ unsigned long pvr;
+ char buf[64];
+ char buf1[32], buf2[32], buf3[32], buf4[32];
+ char cpustr[16];
+ char *s, *e, bc;
+ switch (line_number)
+ {
+ case 2:
+ /* CPU and board infos */
+ pvr=get_pvr();
+ get_sys_info (&sys_info);
+ switch (pvr) {
+ case PVR_405GP_RB: rev='B'; break;
+ case PVR_405GP_RC: rev='C'; break;
+ case PVR_405GP_RD: rev='D'; break;
+ case PVR_405GP_RE: rev='E'; break;
+ case PVR_405GPR_RB: rev='B'; break;
+ default: rev='?'; break;
+ }
+ if(pvr==PVR_405GPR_RB)
+ sprintf(cpustr,"PPC405GPr %c",rev);
+ else
+ sprintf(cpustr,"PPC405GP %c",rev);
+ /* Board info */
+ i=0;
+ s=getenv ("serial#");
+#ifdef CONFIG_PIP405
+ if (!s || strncmp (s, "PIP405", 6)) {
+ sprintf(buf,"### No HW ID - assuming PIP405");
+ }
+#endif
+#ifdef CONFIG_MIP405
+ if (!s || strncmp (s, "MIP405", 6)) {
+ sprintf(buf,"### No HW ID - assuming MIP405");
+ }
+#endif
+ else {
+ for (e = s; *e; ++e) {
+ if (*e == ' ')
+ break;
+ }
+ for (; s < e; ++s) {
+ if (*s == '_') {
+ ++s;
+ break;
+ }
+ buf[i++] = *s;
+ }
+ sprintf(&buf[i]," SN ");
+ i+=4;
+ for (; s < e; ++s) {
+ buf[i++] = *s;
+ }
+ buf[i++]=0;
+ }
+ sprintf (info," %s %s %s MHz (%s/%s/%s MHz)",
+ buf, cpustr,
+ strmhz (buf1, gd->cpu_clk),
+ strmhz (buf2, sys_info.freqPLB),
+ strmhz (buf3, sys_info.freqPLB / sys_info.pllOpbDiv),
+ strmhz (buf4, sys_info.freqPLB / sys_info.pllExtBusDiv));
+ return;
+ case 3:
+ /* Memory Info */
+ boot = get_boot_mode();
+ bc = in8 (CONFIG_PORT_ADDR);
+ sprintf(info, " %luMB RAM, %luMB Flash Cfg 0x%02X %s %s",
+ gd->bd->bi_memsize / 0x100000,
+ gd->bd->bi_flashsize / 0x100000,
+ bc,
+ (boot & BOOT_MPS) ? "MPS boot" : "Flash boot",
+ ctfb.modeIdent);
+ return;
+ case 1:
+ sprintf (buf, "%s",CONFIG_IDENT_STRING);
+ sprintf (info, " %s", &buf[1]);
+ return;
+ }
+ /* no more info lines */
+ *info = 0;
+ return;
+}
+#endif /* CONFIG_CONSOLE_EXTRA_INFO */
+
+#endif /* CONFIG_VIDEO */
diff --git a/u-boot/board/mpl/common/common_util.h b/u-boot/board/mpl/common/common_util.h
new file mode 100644
index 0000000..29cd14f
--- /dev/null
+++ b/u-boot/board/mpl/common/common_util.h
@@ -0,0 +1,45 @@
+/*
+ * (C) Copyright 2001
+ * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+#ifndef _COMMON_UTIL_H_
+#define _COMMON_UTIL_H_
+
+typedef struct {
+ char signature[4];
+ char serial_name[17]; /* "MIP405_1000xxxxx" */
+ char eth_addr[21]; /* "00:60:C2:0a:00:00" */
+} backup_t;
+
+void get_backup_values(backup_t *buf);
+
+#if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
+#define BOOT_MPS 0x01
+#define BOOT_PCI 0x02
+#endif
+
+void check_env(void);
+#if defined(CONFIG_CMD_DOC)
+void doc_init (void);
+#endif
+
+#endif /* _COMMON_UTIL_H_ */
diff --git a/u-boot/board/mpl/common/flash.c b/u-boot/board/mpl/common/flash.c
new file mode 100644
index 0000000..61f031a
--- /dev/null
+++ b/u-boot/board/mpl/common/flash.c
@@ -0,0 +1,886 @@
+/*
+ * (C) Copyright 2000, 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Modified 4/5/2001
+ * Wait for completion of each sector erase command issued
+ * 4/5/2001
+ * Chris Hallinan - DS4.COM, Inc. - clh@net1plus.com
+ */
+
+/*
+ * Modified 3/7/2001
+ * - adapted for pip405, Denis Peter, MPL AG Switzerland
+ * TODO:
+ * clean-up
+ */
+
+#include <common.h>
+
+#if !defined(CONFIG_PATI)
+#include <asm/ppc4xx.h>
+#include <asm/processor.h>
+#include "common_util.h"
+#if defined(CONFIG_MIP405)
+#include "../mip405/mip405.h"
+#endif
+#if defined(CONFIG_PIP405)
+#include "../pip405/pip405.h"
+#endif
+#include <asm/4xx_pci.h>
+#else /* defined(CONFIG_PATI) */
+#include <mpc5xx.h>
+#endif
+
+flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips */
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+static ulong flash_get_size (vu_long *addr, flash_info_t *info);
+static int write_word (flash_info_t *info, ulong dest, ulong data);
+
+void unlock_intel_sectors(flash_info_t *info,ulong addr,ulong cnt);
+
+#define ADDR0 0x5555
+#define ADDR1 0x2aaa
+#define FLASH_WORD_SIZE unsigned short
+
+#define FALSE 0
+#define TRUE 1
+
+#if !defined(CONFIG_PATI)
+
+/*-----------------------------------------------------------------------
+ * Some CS switching routines:
+ *
+ * On PIP/MIP405 we have 3 (4) possible boot mode
+ *
+ * - Boot from Flash (Flash CS = CS0, MPS CS = CS1)
+ * - Boot from MPS (Flash CS = CS1, MPS CS = CS0)
+ * - Boot from PCI with Flash map (Flash CS = CS0, MPS CS = CS1)
+ * - Boot from PCI with MPS map (Flash CS = CS1, MPS CS = CS0)
+ * The flash init is the first board specific routine which is called
+ * after code relocation (running from SDRAM)
+ * The first thing we do is to map the Flash CS to the Flash area and
+ * the MPS CS to the MPS area. Since the flash size is unknown at this
+ * point, we use the max flash size and the lowest flash address as base.
+ *
+ * After flash detection we adjust the size of the CS area accordingly.
+ * The board_init_r will fill in wrong values in the board init structure,
+ * but this will be fixed in the misc_init_r routine:
+ * bd->bi_flashstart=0-flash_info[0].size
+ * bd->bi_flashsize=flash_info[0].size-CONFIG_SYS_MONITOR_LEN
+ * bd->bi_flashoffset=0
+ *
+ */
+int get_boot_mode(void)
+{
+ unsigned long pbcr;
+ int res = 0;
+ pbcr = mfdcr (CPC0_PSR);
+ if ((pbcr & PSR_ROM_WIDTH_MASK) == 0)
+ /* boot via MPS or MPS mapping */
+ res = BOOT_MPS;
+ if(pbcr & PSR_ROM_LOC)
+ /* boot via PCI.. */
+ res |= BOOT_PCI;
+ return res;
+}
+
+/* Map the flash high (in boot area)
+ This code can only be executed from SDRAM (after relocation).
+*/
+void setup_cs_reloc(void)
+{
+ int mode;
+ /* Since we are relocated, we can set-up the CS finaly
+ * but first of all, switch off PCI mapping (in case it was a PCI boot) */
+ out32r(PMM0MA,0L);
+ icache_enable (); /* we are relocated */
+ /* get boot mode */
+ mode=get_boot_mode();
+ /* we map the flash high in every case */
+ /* first findout on which cs the flash is */
+ if(mode & BOOT_MPS) {
+ /* map flash high on CS1 and MPS on CS0 */
+ mtdcr (EBC0_CFGADDR, PB0AP);
+ mtdcr (EBC0_CFGDATA, MPS_AP);
+ mtdcr (EBC0_CFGADDR, PB0CR);
+ mtdcr (EBC0_CFGDATA, MPS_CR);
+ /* we use the default values (max values) for the flash
+ * because its real size is not yet known */
+ mtdcr (EBC0_CFGADDR, PB1AP);
+ mtdcr (EBC0_CFGDATA, FLASH_AP);
+ mtdcr (EBC0_CFGADDR, PB1CR);
+ mtdcr (EBC0_CFGDATA, FLASH_CR_B);
+ }
+ else {
+ /* map flash high on CS0 and MPS on CS1 */
+ mtdcr (EBC0_CFGADDR, PB1AP);
+ mtdcr (EBC0_CFGDATA, MPS_AP);
+ mtdcr (EBC0_CFGADDR, PB1CR);
+ mtdcr (EBC0_CFGDATA, MPS_CR);
+ /* we use the default values (max values) for the flash
+ * because its real size is not yet known */
+ mtdcr (EBC0_CFGADDR, PB0AP);
+ mtdcr (EBC0_CFGDATA, FLASH_AP);
+ mtdcr (EBC0_CFGADDR, PB0CR);
+ mtdcr (EBC0_CFGDATA, FLASH_CR_B);
+ }
+}
+
+#endif /* #if !defined(CONFIG_PATI) */
+
+unsigned long flash_init (void)
+{
+ unsigned long size_b0;
+ int i;
+
+#if !defined(CONFIG_PATI)
+ unsigned long size_b1,flashcr,size_reg;
+ int mode;
+ extern char version_string;
+ char *p = &version_string;
+
+ /* Since we are relocated, we can set-up the CS finally */
+ setup_cs_reloc();
+ /* get and display boot mode */
+ mode=get_boot_mode();
+ if(mode & BOOT_PCI)
+ printf("(PCI Boot %s Map) ",(mode & BOOT_MPS) ?
+ "MPS" : "Flash");
+ else
+ printf("(%s Boot) ",(mode & BOOT_MPS) ?
+ "MPS" : "Flash");
+#endif /* #if !defined(CONFIG_PATI) */
+ /* 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((vu_long *)CONFIG_SYS_MONITOR_BASE, &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);
+ }
+ /* protect the bootloader */
+ /* Monitor protection ON by default */
+#if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
+ flash_protect(FLAG_PROTECT_SET,
+ CONFIG_SYS_MONITOR_BASE,
+ CONFIG_SYS_MONITOR_BASE+monitor_flash_len-1,
+ &flash_info[0]);
+#endif
+#if !defined(CONFIG_PATI)
+ /* protect reset vector */
+ flash_info[0].protect[flash_info[0].sector_count-1] = 1;
+ size_b1 = 0 ;
+ flash_info[0].size = size_b0;
+ /* set up flash cs according to the size */
+ size_reg=(flash_info[0].size >>20);
+ switch (size_reg) {
+ case 0:
+ case 1: i=0; break; /* <= 1MB */
+ case 2: i=1; break; /* = 2MB */
+ case 4: i=2; break; /* = 4MB */
+ case 8: i=3; break; /* = 8MB */
+ case 16: i=4; break; /* = 16MB */
+ case 32: i=5; break; /* = 32MB */
+ case 64: i=6; break; /* = 64MB */
+ case 128: i=7; break; /*= 128MB */
+ default:
+ printf("\n #### ERROR, wrong size %ld MByte reset board #####\n",size_reg);
+ while(1);
+ }
+ if(mode & BOOT_MPS) {
+ /* flash is on CS1 */
+ mtdcr(EBC0_CFGADDR, PB1CR);
+ flashcr = mfdcr (EBC0_CFGDATA);
+ /* we map the flash high in every case */
+ flashcr&=0x0001FFFF; /* mask out address bits */
+ flashcr|= ((0-flash_info[0].size) & 0xFFF00000); /* start addr */
+ flashcr|= (i << 17); /* size addr */
+ mtdcr(EBC0_CFGADDR, PB1CR);
+ mtdcr(EBC0_CFGDATA, flashcr);
+ }
+ else {
+ /* flash is on CS0 */
+ mtdcr(EBC0_CFGADDR, PB0CR);
+ flashcr = mfdcr (EBC0_CFGDATA);
+ /* we map the flash high in every case */
+ flashcr&=0x0001FFFF; /* mask out address bits */
+ flashcr|= ((0-flash_info[0].size) & 0xFFF00000); /* start addr */
+ flashcr|= (i << 17); /* size addr */
+ mtdcr(EBC0_CFGADDR, PB0CR);
+ mtdcr(EBC0_CFGDATA, flashcr);
+ }
+#if 0
+ /* enable this (PIP405/MIP405 only) if you want to test if
+ the relocation has be done ok.
+ This will disable both Chipselects */
+ mtdcr (EBC0_CFGADDR, PB0CR);
+ mtdcr (EBC0_CFGDATA, 0L);
+ mtdcr (EBC0_CFGADDR, PB1CR);
+ mtdcr (EBC0_CFGDATA, 0L);
+ printf("CS0 & CS1 switched off for test\n");
+#endif
+ /* patch version_string */
+ for(i=0;i<0x100;i++) {
+ if(*p=='\n') {
+ *p=0;
+ break;
+ }
+ p++;
+ }
+#else /* #if !defined(CONFIG_PATI) */
+#ifdef CONFIG_ENV_IS_IN_FLASH
+ /* ENV protection ON by default */
+ flash_protect(FLAG_PROTECT_SET,
+ CONFIG_ENV_ADDR,
+ CONFIG_ENV_ADDR+CONFIG_ENV_SECT_SIZE-1,
+ &flash_info[0]);
+#endif
+#endif /* #if !defined(CONFIG_PATI) */
+ return (size_b0);
+}
+
+
+/*-----------------------------------------------------------------------
+ */
+void flash_print_info (flash_info_t *info)
+{
+ int i;
+ int k;
+ int size;
+ int erased;
+ volatile unsigned long *flash;
+
+ if (info->flash_id == FLASH_UNKNOWN) {
+ printf ("missing or unknown FLASH type\n");
+ return;
+ }
+
+ switch (info->flash_id & FLASH_VENDMASK) {
+ case FLASH_MAN_AMD: printf ("AMD "); break;
+ case FLASH_MAN_FUJ: printf ("FUJITSU "); break;
+ case FLASH_MAN_SST: printf ("SST "); break;
+ case FLASH_MAN_INTEL: printf ("Intel "); break;
+ default: printf ("Unknown Vendor "); break;
+ }
+
+ switch (info->flash_id & FLASH_TYPEMASK) {
+ case FLASH_AM040: printf ("AM29F040 (512 Kbit, uniform sector size)\n");
+ break;
+ case FLASH_AM400B: printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
+ break;
+ case FLASH_AM400T: printf ("AM29LV400T (4 Mbit, top boot sector)\n");
+ break;
+ case FLASH_AM800B: printf ("AM29LV800B (8 Mbit, bottom boot sect)\n");
+ break;
+ case FLASH_AM800T: printf ("AM29LV800T (8 Mbit, top boot sector)\n");
+ break;
+ case FLASH_AM160B: printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
+ break;
+ case FLASH_AM160T: printf ("AM29LV160T (16 Mbit, top boot sector)\n");
+ break;
+ case FLASH_AM320B: printf ("AM29LV320B (32 Mbit, bottom boot sect)\n");
+ break;
+ case FLASH_AM320T: printf ("AM29LV320T (32 Mbit, top boot sector)\n");
+ break;
+ case FLASH_SST800A: printf ("SST39LF/VF800 (8 Mbit, uniform sector size)\n");
+ break;
+ case FLASH_SST160A: printf ("SST39LF/VF160 (16 Mbit, uniform sector size)\n");
+ break;
+ case FLASH_INTEL320T: printf ("TE28F320C3 (32 Mbit, top sector size)\n");
+ break;
+ case FLASH_AM640U: printf ("AM29LV640U (64 Mbit, uniform sector size)\n");
+ break;
+ default: printf ("Unknown Chip Type\n");
+ break;
+ }
+
+ printf (" Size: %ld KB in %d Sectors\n",
+ info->size >> 10, info->sector_count);
+
+ printf (" Sector Start Addresses:");
+ for (i=0; i<info->sector_count; ++i) {
+ /*
+ * Check if whole sector is erased
+ */
+ if (i != (info->sector_count-1))
+ size = info->start[i+1] - info->start[i];
+ else
+ size = info->start[0] + info->size - info->start[i];
+ erased = 1;
+ flash = (volatile unsigned long *)info->start[i];
+ size = size >> 2; /* divide by 4 for longword access */
+ for (k=0; k<size; k++) {
+ if (*flash++ != 0xffffffff) {
+ erased = 0;
+ break;
+ }
+ }
+ if ((i % 5) == 0)
+ printf ("\n ");
+ printf (" %08lX%s%s",
+ info->start[i],
+ erased ? " E" : " ",
+ info->protect[i] ? "RO " : " ");
+ }
+ printf ("\n");
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+
+/*-----------------------------------------------------------------------
+
+*/
+
+/*
+ * The following code cannot be run from FLASH!
+ */
+static ulong flash_get_size (vu_long *addr, flash_info_t *info)
+{
+ short i;
+ FLASH_WORD_SIZE value;
+ ulong base;
+ volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *)addr;
+
+ /* Write auto select command: read Manufacturer ID */
+ addr2[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
+ addr2[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
+ addr2[ADDR0] = (FLASH_WORD_SIZE)0x00900090;
+
+ value = addr2[0];
+ /* printf("flash_get_size value: %x\n",value); */
+ switch (value) {
+ case (FLASH_WORD_SIZE)AMD_MANUFACT:
+ info->flash_id = FLASH_MAN_AMD;
+ break;
+ case (FLASH_WORD_SIZE)FUJ_MANUFACT:
+ info->flash_id = FLASH_MAN_FUJ;
+ break;
+ case (FLASH_WORD_SIZE)INTEL_MANUFACT:
+ info->flash_id = FLASH_MAN_INTEL;
+ break;
+ case (FLASH_WORD_SIZE)SST_MANUFACT:
+ info->flash_id = FLASH_MAN_SST;
+ break;
+ default:
+ info->flash_id = FLASH_UNKNOWN;
+ info->sector_count = 0;
+ info->size = 0;
+ return (0); /* no or unknown flash */
+ }
+ value = addr2[1]; /* device ID */
+ /* printf("Device value %x\n",value); */
+ switch (value) {
+ case (FLASH_WORD_SIZE)AMD_ID_F040B:
+ info->flash_id += FLASH_AM040;
+ info->sector_count = 8;
+ info->size = 0x0080000; /* => 512 ko */
+ break;
+ case (FLASH_WORD_SIZE)AMD_ID_LV400T:
+ info->flash_id += FLASH_AM400T;
+ info->sector_count = 11;
+ info->size = 0x00080000;
+ break; /* => 0.5 MB */
+
+ case (FLASH_WORD_SIZE)AMD_ID_LV400B:
+ info->flash_id += FLASH_AM400B;
+ info->sector_count = 11;
+ info->size = 0x00080000;
+ break; /* => 0.5 MB */
+
+ case (FLASH_WORD_SIZE)AMD_ID_LV800T:
+ info->flash_id += FLASH_AM800T;
+ info->sector_count = 19;
+ info->size = 0x00100000;
+ break; /* => 1 MB */
+
+ case (FLASH_WORD_SIZE)AMD_ID_LV800B:
+ info->flash_id += FLASH_AM800B;
+ info->sector_count = 19;
+ info->size = 0x00100000;
+ break; /* => 1 MB */
+
+ case (FLASH_WORD_SIZE)AMD_ID_LV160T:
+ info->flash_id += FLASH_AM160T;
+ info->sector_count = 35;
+ info->size = 0x00200000;
+ break; /* => 2 MB */
+
+ case (FLASH_WORD_SIZE)AMD_ID_LV160B:
+ info->flash_id += FLASH_AM160B;
+ info->sector_count = 35;
+ info->size = 0x00200000;
+ break; /* => 2 MB */
+ case (FLASH_WORD_SIZE)AMD_ID_LV320T:
+ info->flash_id += FLASH_AM320T;
+ info->sector_count = 67;
+ info->size = 0x00400000;
+ break; /* => 4 MB */
+ case (FLASH_WORD_SIZE)AMD_ID_LV640U:
+ info->flash_id += FLASH_AM640U;
+ info->sector_count = 128;
+ info->size = 0x00800000;
+ break; /* => 8 MB */
+#if 0 /* enable when device IDs are available */
+
+ case (FLASH_WORD_SIZE)AMD_ID_LV320B:
+ info->flash_id += FLASH_AM320B;
+ info->sector_count = 67;
+ info->size = 0x00400000;
+ break; /* => 4 MB */
+#endif
+ case (FLASH_WORD_SIZE)SST_ID_xF800A:
+ info->flash_id += FLASH_SST800A;
+ info->sector_count = 16;
+ info->size = 0x00100000;
+ break; /* => 1 MB */
+ case (FLASH_WORD_SIZE)INTEL_ID_28F320C3T:
+ info->flash_id += FLASH_INTEL320T;
+ info->sector_count = 71;
+ info->size = 0x00400000;
+ break; /* => 4 MB */
+
+
+ case (FLASH_WORD_SIZE)SST_ID_xF160A:
+ info->flash_id += FLASH_SST160A;
+ info->sector_count = 32;
+ info->size = 0x00200000;
+ break; /* => 2 MB */
+
+ default:
+ info->flash_id = FLASH_UNKNOWN;
+ return (0); /* => no or unknown flash */
+
+ }
+ /* base address calculation */
+ base=0-info->size;
+ /* set up sector start address table */
+ if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
+ (info->flash_id == FLASH_AM040) ||
+ (info->flash_id == FLASH_AM640U)){
+ for (i = 0; i < info->sector_count; i++)
+ info->start[i] = base + (i * 0x00010000);
+ }
+ else {
+ if (info->flash_id & FLASH_BTYPE) {
+ /* set sector offsets for bottom boot block type */
+ info->start[0] = base + 0x00000000;
+ info->start[1] = base + 0x00004000;
+ info->start[2] = base + 0x00006000;
+ info->start[3] = base + 0x00008000;
+ for (i = 4; i < info->sector_count; i++)
+ info->start[i] = base + (i * 0x00010000) - 0x00030000;
+ }
+ else {
+ /* set sector offsets for top boot block type */
+ i = info->sector_count - 1;
+ if(info->sector_count==71) {
+
+ info->start[i--] = base + info->size - 0x00002000;
+ info->start[i--] = base + info->size - 0x00004000;
+ info->start[i--] = base + info->size - 0x00006000;
+ info->start[i--] = base + info->size - 0x00008000;
+ info->start[i--] = base + info->size - 0x0000A000;
+ info->start[i--] = base + info->size - 0x0000C000;
+ info->start[i--] = base + info->size - 0x0000E000;
+ for (; i >= 0; i--)
+ info->start[i] = base + i * 0x000010000;
+ }
+ else {
+ info->start[i--] = base + info->size - 0x00004000;
+ info->start[i--] = base + info->size - 0x00006000;
+ info->start[i--] = base + info->size - 0x00008000;
+ for (; i >= 0; i--)
+ info->start[i] = base + i * 0x00010000;
+ }
+ }
+ }
+
+ /* check for protected sectors */
+ for (i = 0; i < info->sector_count; i++) {
+ /* read sector protection at sector address, (A7 .. A0) = 0x02 */
+ /* D0 = 1 if protected */
+ addr2 = (volatile FLASH_WORD_SIZE *)(info->start[i]);
+ if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL)
+ info->protect[i] = 0;
+ else
+ info->protect[i] = addr2[2] & 1;
+ }
+
+ /*
+ * Prevent writes to uninitialized FLASH.
+ */
+ if (info->flash_id != FLASH_UNKNOWN) {
+ addr2 = (FLASH_WORD_SIZE *)info->start[0];
+ *addr2 = (FLASH_WORD_SIZE)0x00F000F0; /* reset bank */
+ }
+ return (info->size);
+}
+
+
+int wait_for_DQ7(flash_info_t *info, int sect)
+{
+ ulong start, now, last;
+ volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[sect]);
+
+ start = get_timer (0);
+ last = start;
+ while ((addr[0] & (FLASH_WORD_SIZE)0x00800080) != (FLASH_WORD_SIZE)0x00800080) {
+ if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
+ printf ("Timeout\n");
+ return ERR_TIMOUT;
+ }
+ /* show that we're waiting */
+ if ((now - last) > 1000) { /* every second */
+ putc ('.');
+ last = now;
+ }
+ }
+ return ERR_OK;
+}
+
+int intel_wait_for_DQ7(flash_info_t *info, int sect)
+{
+ ulong start, now, last, status;
+ volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[sect]);
+
+ start = get_timer (0);
+ last = start;
+ while ((addr[0] & (FLASH_WORD_SIZE)0x00800080) != (FLASH_WORD_SIZE)0x00800080) {
+ if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
+ printf ("Timeout\n");
+ return ERR_TIMOUT;
+ }
+ /* show that we're waiting */
+ if ((now - last) > 1000) { /* every second */
+ putc ('.');
+ last = now;
+ }
+ }
+ status = addr[0] & (FLASH_WORD_SIZE)0x00280028;
+ /* clear status register */
+ addr[0] = (FLASH_WORD_SIZE)0x00500050;
+ /* check status for block erase fail and VPP low */
+ return (status == 0 ? ERR_OK : ERR_NOT_ERASED);
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+int flash_erase (flash_info_t *info, int s_first, int s_last)
+{
+ volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[0]);
+ volatile FLASH_WORD_SIZE *addr2;
+ int flag, prot, sect, l_sect;
+ int i, 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;
+ }
+
+ if (info->flash_id == FLASH_UNKNOWN) {
+ printf ("Can't erase unknown flash type - aborted\n");
+ 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");
+ }
+
+ l_sect = -1;
+
+ /* Disable interrupts which might cause a timeout here */
+ flag = disable_interrupts();
+
+ /* Start erase on unprotected sectors */
+ for (sect = s_first; sect<=s_last; sect++) {
+ if (info->protect[sect] == 0) { /* not protected */
+ addr2 = (FLASH_WORD_SIZE *)(info->start[sect]);
+ /* printf("Erasing sector %p\n", addr2); */ /* CLH */
+ if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) {
+ addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
+ addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
+ addr[ADDR0] = (FLASH_WORD_SIZE)0x00800080;
+ addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
+ addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
+ addr2[0] = (FLASH_WORD_SIZE)0x00500050; /* block erase */
+ for (i=0; i<50; i++)
+ udelay(1000); /* wait 1 ms */
+ rcode |= wait_for_DQ7(info, sect);
+ }
+ else {
+ if((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL){
+ addr2[0] = (FLASH_WORD_SIZE)0x00600060; /* unlock sector */
+ addr2[0] = (FLASH_WORD_SIZE)0x00D000D0; /* sector erase */
+ intel_wait_for_DQ7(info, sect);
+ addr2[0] = (FLASH_WORD_SIZE)0x00200020; /* sector erase */
+ addr2[0] = (FLASH_WORD_SIZE)0x00D000D0; /* sector erase */
+ rcode |= intel_wait_for_DQ7(info, sect);
+ }
+ else {
+ addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
+ addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
+ addr[ADDR0] = (FLASH_WORD_SIZE)0x00800080;
+ addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
+ addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
+ addr2[0] = (FLASH_WORD_SIZE)0x00300030; /* sector erase */
+ rcode |= wait_for_DQ7(info, sect);
+ }
+ }
+ l_sect = sect;
+ /*
+ * Wait for each sector to complete, it's more
+ * reliable. According to AMD Spec, you must
+ * issue all erase commands within a specified
+ * timeout. This has been seen to fail, especially
+ * if printf()s are included (for debug)!!
+ */
+ /* wait_for_DQ7(info, sect); */
+ }
+ }
+
+ /* re-enable interrupts if necessary */
+ if (flag)
+ enable_interrupts();
+
+ /* wait at least 80us - let's wait 1 ms */
+ udelay (1000);
+
+#if 0
+ /*
+ * We wait for the last triggered sector
+ */
+ if (l_sect < 0)
+ goto DONE;
+ wait_for_DQ7(info, l_sect);
+
+DONE:
+#endif
+ /* reset to read mode */
+ addr = (FLASH_WORD_SIZE *)info->start[0];
+ addr[0] = (FLASH_WORD_SIZE)0x00F000F0; /* reset bank */
+
+ if (!rcode)
+ printf (" done\n");
+
+ return rcode;
+}
+
+
+void unlock_intel_sectors(flash_info_t *info,ulong addr,ulong cnt)
+{
+ int i;
+ volatile FLASH_WORD_SIZE *addr2;
+ long c;
+ c= (long)cnt;
+ for(i=info->sector_count-1;i>0;i--)
+ {
+ if(addr>=info->start[i])
+ break;
+ }
+ do {
+ addr2 = (FLASH_WORD_SIZE *)(info->start[i]);
+ addr2[0] = (FLASH_WORD_SIZE)0x00600060; /* unlock sector setup */
+ addr2[0] = (FLASH_WORD_SIZE)0x00D000D0; /* unlock sector */
+ intel_wait_for_DQ7(info, i);
+ i++;
+ c-=(info->start[i]-info->start[i-1]);
+ }while(c>0);
+}
+
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+
+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+ ulong cp, wp, data;
+ int i, l, rc;
+
+ if((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL){
+ unlock_intel_sectors(info,addr,cnt);
+ }
+ wp = (addr & ~3); /* get lower word aligned address */
+ /*
+ * 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<4 && cnt>0; ++i) {
+ data = (data << 8) | *src++;
+ --cnt;
+ ++cp;
+ }
+ for (; cnt==0 && i<4; ++i, ++cp) {
+ data = (data << 8) | (*(uchar *)cp);
+ }
+
+ if ((rc = write_word(info, wp, data)) != 0) {
+ return (rc);
+ }
+ wp += 4;
+ }
+
+ /*
+ * handle word aligned part
+ */
+ while (cnt >= 4) {
+ data = 0;
+ for (i=0; i<4; ++i) {
+ data = (data << 8) | *src++;
+ }
+ if ((rc = write_word(info, wp, data)) != 0) {
+ return (rc);
+ }
+ wp += 4;
+ if((wp % 0x10000)==0)
+ printf("."); /* show Progress */
+ cnt -= 4;
+ }
+
+ if (cnt == 0) {
+ return (0);
+ }
+
+ /*
+ * handle unaligned tail bytes
+ */
+ data = 0;
+ for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
+ data = (data << 8) | *src++;
+ --cnt;
+ }
+ for (; i<4; ++i, ++cp) {
+ data = (data << 8) | (*(uchar *)cp);
+ }
+ rc=write_word(info, wp, data);
+ return rc;
+}
+
+/*-----------------------------------------------------------------------
+ * Write a word to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static FLASH_WORD_SIZE *read_val = (FLASH_WORD_SIZE *)0x200000;
+
+static int write_word (flash_info_t *info, ulong dest, ulong data)
+{
+ volatile FLASH_WORD_SIZE *addr2 = (volatile FLASH_WORD_SIZE *)(info->start[0]);
+ volatile FLASH_WORD_SIZE *dest2 = (volatile FLASH_WORD_SIZE *)dest;
+ volatile FLASH_WORD_SIZE *data2;
+ ulong start;
+ ulong *data_p;
+ int flag;
+ int i;
+
+ data_p = &data;
+ data2 = (volatile FLASH_WORD_SIZE *)data_p;
+
+ /* Check if Flash is (sufficiently) erased */
+ if ((*((volatile FLASH_WORD_SIZE *)dest) &
+ (FLASH_WORD_SIZE)data) != (FLASH_WORD_SIZE)data) {
+ return (2);
+ }
+ /* Disable interrupts which might cause a timeout here */
+ flag = disable_interrupts();
+ for (i=0; i<4/sizeof(FLASH_WORD_SIZE); i++)
+ {
+ if((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL){
+ /* intel style writting */
+ dest2[i] = (FLASH_WORD_SIZE)0x00500050;
+ dest2[i] = (FLASH_WORD_SIZE)0x00400040;
+ *read_val++ = data2[i];
+ dest2[i] = data2[i];
+ if (flag)
+ enable_interrupts();
+ /* data polling for D7 */
+ start = get_timer (0);
+ udelay(10);
+ while ((dest2[i] & (FLASH_WORD_SIZE)0x00800080) != (FLASH_WORD_SIZE)0x00800080)
+ {
+ if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT)
+ return (1);
+ }
+ dest2[i] = (FLASH_WORD_SIZE)0x00FF00FF; /* return to read mode */
+ udelay(10);
+ dest2[i] = (FLASH_WORD_SIZE)0x00FF00FF; /* return to read mode */
+ if(dest2[i]!=data2[i])
+ printf("Error at %p 0x%04X != 0x%04X\n",&dest2[i],dest2[i],data2[i]);
+ }
+ else {
+ addr2[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
+ addr2[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
+ addr2[ADDR0] = (FLASH_WORD_SIZE)0x00A000A0;
+ dest2[i] = data2[i];
+ /* re-enable interrupts if necessary */
+ if (flag)
+ enable_interrupts();
+ /* data polling for D7 */
+ start = get_timer (0);
+ while ((dest2[i] & (FLASH_WORD_SIZE)0x00800080) !=
+ (data2[i] & (FLASH_WORD_SIZE)0x00800080)) {
+ if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
+ return (1);
+ }
+ }
+ }
+ }
+ return (0);
+}
+
+/*-----------------------------------------------------------------------
+ */
diff --git a/u-boot/board/mpl/common/isa.c b/u-boot/board/mpl/common/isa.c
new file mode 100644
index 0000000..5d467b4
--- /dev/null
+++ b/u-boot/board/mpl/common/isa.c
@@ -0,0 +1,494 @@
+/*
+ * (C) Copyright 2001
+ * Denis Peter, MPL AG Switzerland
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * TODO: clean-up
+ */
+
+#include <common.h>
+#include <asm/processor.h>
+#include <stdio_dev.h>
+#include "isa.h"
+#include "piix4_pci.h"
+#include "kbd.h"
+#include "video.h"
+
+
+#undef ISA_DEBUG
+
+#ifdef ISA_DEBUG
+#define PRINTF(fmt,args...) printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#if defined(CONFIG_PIP405)
+
+extern int drv_isa_kbd_init (void);
+
+/* fdc (logical device 0) */
+const SIO_LOGDEV_TABLE sio_fdc[] = {
+ {0x60, 3}, /* set IO to FDPort (3F0) */
+ {0x61, 0xF0}, /* set IO to FDPort (3F0) */
+ {0x70, 06}, /* set IRQ 6 for FDPort */
+ {0x74, 02}, /* set DMA 2 for FDPort */
+ {0xF0, 0x05}, /* set to PS2 type */
+ {0xF1, 0x00}, /* default value */
+ {0x30, 1}, /* and activate the device */
+ {0xFF, 0} /* end of device table */
+};
+/* paralell port (logical device 3) */
+const SIO_LOGDEV_TABLE sio_pport[] = {
+ {0x60, 3}, /* set IO to PPort (378) */
+ {0x61, 0x78}, /* set IO to PPort (378) */
+ {0x70, 07}, /* set IRQ 7 for PPort */
+ {0xF1, 00}, /* set PPort to normal */
+ {0x30, 1}, /* and activate the device */
+ {0xFF, 0} /* end of device table */
+};
+/* paralell port (logical device 3) Floppy assigned to lpt */
+const SIO_LOGDEV_TABLE sio_pport_fdc[] = {
+ {0x60, 3}, /* set IO to PPort (378) */
+ {0x61, 0x78}, /* set IO to PPort (378) */
+ {0x70, 07}, /* set IRQ 7 for PPort */
+ {0xF1, 02}, /* set PPort to Floppy */
+ {0x30, 1}, /* and activate the device */
+ {0xFF, 0} /* end of device table */
+};
+/* uart 1 (logical device 4) */
+const SIO_LOGDEV_TABLE sio_com1[] = {
+ {0x60, 3}, /* set IO to COM1 (3F8) */
+ {0x61, 0xF8}, /* set IO to COM1 (3F8) */
+ {0x70, 04}, /* set IRQ 4 for COM1 */
+ {0x30, 1}, /* and activate the device */
+ {0xFF, 0} /* end of device table */
+};
+/* uart 2 (logical device 5) */
+const SIO_LOGDEV_TABLE sio_com2[] = {
+ {0x60, 2}, /* set IO to COM2 (2F8) */
+ {0x61, 0xF8}, /* set IO to COM2 (2F8) */
+ {0x70, 03}, /* set IRQ 3 for COM2 */
+ {0x30, 1}, /* and activate the device */
+ {0xFF, 0} /* end of device table */
+};
+
+/* keyboard controller (logical device 7) */
+const SIO_LOGDEV_TABLE sio_keyboard[] = {
+ {0x70, 1}, /* set IRQ 1 for keyboard */
+ {0x72, 12}, /* set IRQ 12 for mouse */
+ {0xF0, 0}, /* disable Port92 (this is a PowerPC!!) */
+ {0x30, 1}, /* and activate the device */
+ {0xFF, 0} /* end of device table */
+};
+
+
+/*******************************************************************************
+* Config SuperIO FDC37C672
+********************************************************************************/
+unsigned char open_cfg_super_IO(int address)
+{
+ out8(CONFIG_SYS_ISA_IO_BASE_ADDRESS | address,0x55); /* open config */
+ out8(CONFIG_SYS_ISA_IO_BASE_ADDRESS | address,0x20); /* set address to DEV ID */
+ if(in8(CONFIG_SYS_ISA_IO_BASE_ADDRESS | address | 0x1)==0x40) /* ok Device ID is correct */
+ return TRUE;
+ else
+ return FALSE;
+}
+
+void close_cfg_super_IO(int address)
+{
+ out8(CONFIG_SYS_ISA_IO_BASE_ADDRESS | address,0xAA); /* close config */
+}
+
+
+unsigned char read_cfg_super_IO(int address, unsigned char function, unsigned char regaddr)
+{
+ /* assuming config reg is open */
+ out8(CONFIG_SYS_ISA_IO_BASE_ADDRESS | address,0x7); /* points to the function reg */
+ out8(CONFIG_SYS_ISA_IO_BASE_ADDRESS | address | 1,function); /* set the function no */
+ out8(CONFIG_SYS_ISA_IO_BASE_ADDRESS | address,regaddr); /* sets the address in the function */
+ return in8(CONFIG_SYS_ISA_IO_BASE_ADDRESS | address | 1);
+}
+
+void write_cfg_super_IO(int address, unsigned char function, unsigned char regaddr, unsigned char data)
+{
+ /* assuming config reg is open */
+ out8(CONFIG_SYS_ISA_IO_BASE_ADDRESS | address,0x7); /* points to the function reg */
+ out8(CONFIG_SYS_ISA_IO_BASE_ADDRESS | address | 1,function); /* set the function no */
+ out8(CONFIG_SYS_ISA_IO_BASE_ADDRESS | address,regaddr); /* sets the address in the function */
+ out8(CONFIG_SYS_ISA_IO_BASE_ADDRESS | address | 1,data); /* writes the data */
+}
+
+void isa_write_table(SIO_LOGDEV_TABLE *ldt,unsigned char ldev)
+{
+ while (ldt->index != 0xFF) {
+ write_cfg_super_IO(SIO_CFG_PORT, ldev, ldt->index, ldt->val);
+ ldt++;
+ } /* endwhile */
+}
+
+void isa_sio_loadtable(void)
+{
+ char *s = getenv("floppy");
+ /* setup Floppy device 0*/
+ isa_write_table((SIO_LOGDEV_TABLE *)&sio_fdc,0);
+ /* setup parallel port device 3 */
+ if(s && !strncmp(s, "lpt", 3)) {
+ printf("SIO: Floppy assigned to LPT\n");
+ /* floppy is assigned to the LPT */
+ isa_write_table((SIO_LOGDEV_TABLE *)&sio_pport_fdc,3);
+ }
+ else {
+ /*printf("Floppy assigned to internal port\n");*/
+ isa_write_table((SIO_LOGDEV_TABLE *)&sio_pport,3);
+ }
+ /* setup Com1 port device 4 */
+ isa_write_table((SIO_LOGDEV_TABLE *)&sio_com1,4);
+ /* setup Com2 port device 5 */
+ isa_write_table((SIO_LOGDEV_TABLE *)&sio_com2,5);
+ /* setup keyboards device 7 */
+ isa_write_table((SIO_LOGDEV_TABLE *)&sio_keyboard,7);
+}
+
+
+void isa_sio_setup(void)
+{
+ if(open_cfg_super_IO(SIO_CFG_PORT)==TRUE)
+ {
+ isa_sio_loadtable();
+ close_cfg_super_IO(0x3F0);
+ }
+}
+#endif
+
+/******************************************************************************
+ * IRQ Controller
+ * we use the Vector mode
+ */
+
+struct isa_irq_action {
+ interrupt_handler_t *handler;
+ void *arg;
+ int count;
+};
+
+static struct isa_irq_action isa_irqs[16];
+
+
+/*
+ * This contains the irq mask for both 8259A irq controllers,
+ */
+static unsigned int cached_irq_mask = 0xfff9;
+
+#define cached_imr1 (unsigned char)cached_irq_mask
+#define cached_imr2 (unsigned char)(cached_irq_mask>>8)
+#define IMR_1 CONFIG_SYS_ISA_IO_BASE_ADDRESS + PIIX4_ISA_INT1_OCW1
+#define IMR_2 CONFIG_SYS_ISA_IO_BASE_ADDRESS + PIIX4_ISA_INT2_OCW1
+#define ICW1_1 CONFIG_SYS_ISA_IO_BASE_ADDRESS + PIIX4_ISA_INT1_ICW1
+#define ICW1_2 CONFIG_SYS_ISA_IO_BASE_ADDRESS + PIIX4_ISA_INT2_ICW1
+#define ICW2_1 CONFIG_SYS_ISA_IO_BASE_ADDRESS + PIIX4_ISA_INT1_ICW2
+#define ICW2_2 CONFIG_SYS_ISA_IO_BASE_ADDRESS + PIIX4_ISA_INT2_ICW2
+#define ICW3_1 ICW2_1
+#define ICW3_2 ICW2_2
+#define ICW4_1 ICW2_1
+#define ICW4_2 ICW2_2
+#define ISR_1 ICW1_1
+#define ISR_2 ICW1_2
+
+
+void disable_8259A_irq(unsigned int irq)
+{
+ unsigned int mask = 1 << irq;
+
+ cached_irq_mask |= mask;
+ if (irq & 8)
+ out8(IMR_2,cached_imr2);
+ else
+ out8(IMR_1,cached_imr1);
+}
+
+void enable_8259A_irq(unsigned int irq)
+{
+ unsigned int mask = ~(1 << irq);
+
+ cached_irq_mask &= mask;
+ if (irq & 8)
+ out8(IMR_2,cached_imr2);
+ else
+ out8(IMR_1,cached_imr1);
+}
+/*
+int i8259A_irq_pending(unsigned int irq)
+{
+ unsigned int mask = 1<<irq;
+ int ret;
+
+ if (irq < 8)
+ ret = inb(0x20) & mask;
+ else
+ ret = inb(0xA0) & (mask >> 8);
+ spin_unlock_irqrestore(&i8259A_lock, flags);
+
+ return ret;
+}
+*/
+
+/*
+ * This function assumes to be called rarely. Switching between
+ * 8259A registers is slow.
+ */
+int i8259A_irq_real(unsigned int irq)
+{
+ int value;
+ int irqmask = 1<<irq;
+
+ if (irq < 8) {
+ out8(ISR_1,0x0B); /* ISR register */
+ value = in8(ISR_1) & irqmask;
+ out8(ISR_1,0x0A); /* back to the IRR register */
+ return value;
+ }
+ out8(ISR_2,0x0B); /* ISR register */
+ value = in8(ISR_2) & (irqmask >> 8);
+ out8(ISR_2,0x0A); /* back to the IRR register */
+ return value;
+}
+
+/*
+ * Careful! The 8259A is a fragile beast, it pretty
+ * much _has_ to be done exactly like this (mask it
+ * first, _then_ send the EOI, and the order of EOI
+ * to the two 8259s is important!
+ */
+void mask_and_ack_8259A(unsigned int irq)
+{
+ unsigned int irqmask = 1 << irq;
+ unsigned int temp_irqmask = cached_irq_mask;
+ /*
+ * Lightweight spurious IRQ detection. We do not want
+ * to overdo spurious IRQ handling - it's usually a sign
+ * of hardware problems, so we only do the checks we can
+ * do without slowing down good hardware unnecesserily.
+ *
+ * Note that IRQ7 and IRQ15 (the two spurious IRQs
+ * usually resulting from the 8259A-1|2 PICs) occur
+ * even if the IRQ is masked in the 8259A. Thus we
+ * can check spurious 8259A IRQs without doing the
+ * quite slow i8259A_irq_real() call for every IRQ.
+ * This does not cover 100% of spurious interrupts,
+ * but should be enough to warn the user that there
+ * is something bad going on ...
+ */
+ if (temp_irqmask & irqmask)
+ goto spurious_8259A_irq;
+ temp_irqmask |= irqmask;
+
+handle_real_irq:
+ if (irq & 8) {
+ in8(IMR_2); /* DUMMY - (do we need this?) */
+ out8(IMR_2,(unsigned char)(temp_irqmask>>8));
+ out8(ISR_2,0x60+(irq&7));/* 'Specific EOI' to slave */
+ out8(ISR_1,0x62); /* 'Specific EOI' to master-IRQ2 */
+ out8(IMR_2,cached_imr2); /* turn it on again */
+ } else {
+ in8(IMR_1); /* DUMMY - (do we need this?) */
+ out8(IMR_1,(unsigned char)temp_irqmask);
+ out8(ISR_1,0x60+irq); /* 'Specific EOI' to master */
+ out8(IMR_1,cached_imr1); /* turn it on again */
+ }
+
+ return;
+
+spurious_8259A_irq:
+ /*
+ * this is the slow path - should happen rarely.
+ */
+ if (i8259A_irq_real(irq))
+ /*
+ * oops, the IRQ _is_ in service according to the
+ * 8259A - not spurious, go handle it.
+ */
+ goto handle_real_irq;
+
+ {
+ static int spurious_irq_mask;
+ /*
+ * At this point we can be sure the IRQ is spurious,
+ * lets ACK and report it. [once per IRQ]
+ */
+ if (!(spurious_irq_mask & irqmask)) {
+ PRINTF("spurious 8259A interrupt: IRQ%d.\n", irq);
+ spurious_irq_mask |= irqmask;
+ }
+ /* irq_err_count++; */
+ /*
+ * Theoretically we do not have to handle this IRQ,
+ * but in Linux this does not cause problems and is
+ * simpler for us.
+ */
+ goto handle_real_irq;
+ }
+}
+
+void init_8259A(void)
+{
+ out8(IMR_1,0xff); /* mask all of 8259A-1 */
+ out8(IMR_2,0xff); /* mask all of 8259A-2 */
+
+ out8(ICW1_1,0x11); /* ICW1: select 8259A-1 init */
+ out8(ICW2_1,0x20 + 0); /* ICW2: 8259A-1 IR0-7 mapped to 0x20-0x27 */
+ out8(ICW3_1,0x04); /* 8259A-1 (the master) has a slave on IR2 */
+ out8(ICW4_1,0x01); /* master expects normal EOI */
+ out8(ICW1_2,0x11); /* ICW2: select 8259A-2 init */
+ out8(ICW2_2,0x20 + 8); /* ICW2: 8259A-2 IR0-7 mapped to 0x28-0x2f */
+ out8(ICW3_2,0x02); /* 8259A-2 is a slave on master's IR2 */
+ out8(ICW4_2,0x01); /* (slave's support for AEOI in flat mode
+ is to be investigated) */
+ udelay(10000); /* wait for 8259A to initialize */
+ out8(IMR_1,cached_imr1); /* restore master IRQ mask */
+ udelay(10000); /* wait for 8259A to initialize */
+ out8(IMR_2,cached_imr2); /* restore slave IRQ mask */
+}
+
+
+#define PCI_INT_ACK_ADDR 0xEED00000
+
+int handle_isa_int(void)
+{
+ unsigned long irqack;
+ unsigned char isr1,isr2,irq;
+ /* first we acknokledge the int via the PCI bus */
+ irqack=in32(PCI_INT_ACK_ADDR);
+ /* now we get the ISRs */
+ isr2=in8(ISR_2);
+ isr1=in8(ISR_1);
+ irq=(unsigned char)irqack;
+ irq-=32;
+/* if((irq==7)&&((isr1&0x80)==0)) {
+ PRINTF("IRQ7 detected but not in ISR\n");
+ }
+ else {
+*/ /* we should handle cascaded interrupts here also */
+ {
+/* printf("ISA Irq %d\n",irq); */
+ isa_irqs[irq].count++;
+ if(irq!=2) { /* just swallow the cascade irq 2 */
+ if (isa_irqs[irq].handler != NULL)
+ (*isa_irqs[irq].handler)(isa_irqs[irq].arg); /* call isr */
+ else {
+ PRINTF ("bogus interrupt vector 0x%x\n", irq);
+ }
+ }
+ }
+ /* issue EOI instruction to clear the IRQ */
+ mask_and_ack_8259A(irq);
+ return 0;
+}
+
+
+/******************************************************************
+ * Install and free an ISA interrupt handler.
+ */
+
+void isa_irq_install_handler(int vec, interrupt_handler_t *handler, void *arg)
+{
+ if (isa_irqs[vec].handler != NULL) {
+ printf ("ISA Interrupt vector %d: handler 0x%x replacing 0x%x\n",
+ vec, (uint)handler, (uint)isa_irqs[vec].handler);
+ }
+ isa_irqs[vec].handler = handler;
+ isa_irqs[vec].arg = arg;
+ enable_8259A_irq(vec);
+ PRINTF ("Install ISA IRQ %d ==> %p, @ %p mask=%04x\n", vec, handler, &isa_irqs[vec].handler,cached_irq_mask);
+
+}
+
+void isa_irq_free_handler(int vec)
+{
+ disable_8259A_irq(vec);
+ isa_irqs[vec].handler = NULL;
+ isa_irqs[vec].arg = NULL;
+ PRINTF ("Free ISA IRQ %d mask=%04x\n", vec, cached_irq_mask);
+
+}
+
+/****************************************************************************/
+void isa_init_irq_contr(void)
+{
+ int i;
+ /* disable all Interrupts */
+ /* first write icws controller 1 */
+ for(i=0;i<16;i++)
+ {
+ isa_irqs[i].handler=NULL;
+ isa_irqs[i].arg=NULL;
+ isa_irqs[i].count=0;
+ }
+ init_8259A();
+ out8(IMR_2,0xFF);
+}
+/*************************************************************************/
+
+void isa_show_irq(void)
+{
+ int vec;
+
+ printf ("\nISA Interrupt-Information:\n");
+ printf ("Nr Routine Arg Count\n");
+
+ for (vec=0; vec<16; vec++) {
+ if (isa_irqs[vec].handler != NULL) {
+ printf ("%02d %08lx %08lx %d\n",
+ vec,
+ (ulong)isa_irqs[vec].handler,
+ (ulong)isa_irqs[vec].arg,
+ isa_irqs[vec].count);
+ }
+ }
+}
+
+int isa_irq_get_count(int vec)
+{
+ return(isa_irqs[vec].count);
+}
+
+/******************************************************************
+ * Init the ISA bus and devices.
+ */
+
+#if defined(CONFIG_PIP405)
+
+int isa_init(void)
+{
+ isa_sio_setup();
+ isa_init_irq_contr();
+ drv_isa_kbd_init();
+ return 0;
+}
+#endif
diff --git a/u-boot/board/mpl/common/isa.h b/u-boot/board/mpl/common/isa.h
new file mode 100644
index 0000000..28ed219
--- /dev/null
+++ b/u-boot/board/mpl/common/isa.h
@@ -0,0 +1,57 @@
+/*
+ * (C) Copyright 2001
+ * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _ISA_H_
+#define _ISA_H_
+/* Super IO */
+#define SIO_CFG_PORT 0x3F0 /* Config Port Address */
+
+#if defined(CONFIG_PIP405)
+/* table fore SIO initialization */
+typedef struct {
+ const uchar index;
+ const uchar val;
+} SIO_LOGDEV_TABLE;
+
+typedef struct {
+ const uchar ldev;
+ const SIO_LOGDEV_TABLE *ldev_table;
+} SIO_TABLE;
+
+
+unsigned char open_cfg_super_IO(int address);
+unsigned char read_cfg_super_IO(int address, unsigned char function, unsigned char regaddr);
+void write_cfg_super_IO(int address, unsigned char function, unsigned char regaddr, unsigned char data);
+void close_cfg_super_IO(int address);
+void isa_sio_setup(void);
+#endif
+
+void isa_irq_install_handler(int vec, interrupt_handler_t *handler, void *arg);
+void isa_irq_free_handler(int vec);
+int handle_isa_int(void);
+void isa_init_irq_contr(void);
+void isa_show_irq(void);
+int isa_irq_get_count(int vec);
+
+
+#endif
diff --git a/u-boot/board/mpl/common/kbd.c b/u-boot/board/mpl/common/kbd.c
new file mode 100644
index 0000000..b0a9620
--- /dev/null
+++ b/u-boot/board/mpl/common/kbd.c
@@ -0,0 +1,645 @@
+/*
+ * (C) Copyright 2001
+ * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Source partly derived from:
+ * linux/drivers/char/pc_keyb.c
+ *
+ *
+ */
+#include <common.h>
+#include <asm/processor.h>
+#include <stdio_dev.h>
+#include "isa.h"
+#include "kbd.h"
+
+
+unsigned char kbd_read_status(void);
+unsigned char kbd_read_input(void);
+void kbd_send_data(unsigned char data);
+void disable_8259A_irq(unsigned int irq);
+void enable_8259A_irq(unsigned int irq);
+
+/* used only by send_data - set by keyboard_interrupt */
+
+
+#undef KBG_DEBUG
+
+#ifdef KBG_DEBUG
+#define PRINTF(fmt,args...) printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+#define KBD_STAT_KOBF 0x01
+#define KBD_STAT_IBF 0x02
+#define KBD_STAT_SYS 0x04
+#define KBD_STAT_CD 0x08
+#define KBD_STAT_LOCK 0x10
+#define KBD_STAT_MOBF 0x20
+#define KBD_STAT_TI_OUT 0x40
+#define KBD_STAT_PARERR 0x80
+
+#define KBD_INIT_TIMEOUT 1000 /* Timeout in ms for initializing the keyboard */
+#define KBC_TIMEOUT 250 /* Timeout in ms for sending to keyboard controller */
+#define KBD_TIMEOUT 2000 /* Timeout in ms for keyboard command acknowledge */
+/*
+ * Keyboard Controller Commands
+ */
+
+#define KBD_CCMD_READ_MODE 0x20 /* Read mode bits */
+#define KBD_CCMD_WRITE_MODE 0x60 /* Write mode bits */
+#define KBD_CCMD_GET_VERSION 0xA1 /* Get controller version */
+#define KBD_CCMD_MOUSE_DISABLE 0xA7 /* Disable mouse interface */
+#define KBD_CCMD_MOUSE_ENABLE 0xA8 /* Enable mouse interface */
+#define KBD_CCMD_TEST_MOUSE 0xA9 /* Mouse interface test */
+#define KBD_CCMD_SELF_TEST 0xAA /* Controller self test */
+#define KBD_CCMD_KBD_TEST 0xAB /* Keyboard interface test */
+#define KBD_CCMD_KBD_DISABLE 0xAD /* Keyboard interface disable */
+#define KBD_CCMD_KBD_ENABLE 0xAE /* Keyboard interface enable */
+#define KBD_CCMD_WRITE_AUX_OBUF 0xD3 /* Write to output buffer as if
+ initiated by the auxiliary device */
+#define KBD_CCMD_WRITE_MOUSE 0xD4 /* Write the following byte to the mouse */
+
+/*
+ * Keyboard Commands
+ */
+
+#define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */
+#define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */
+#define KBD_CMD_ENABLE 0xF4 /* Enable scanning */
+#define KBD_CMD_DISABLE 0xF5 /* Disable scanning */
+#define KBD_CMD_RESET 0xFF /* Reset */
+
+/*
+ * Keyboard Replies
+ */
+
+#define KBD_REPLY_POR 0xAA /* Power on reset */
+#define KBD_REPLY_ACK 0xFA /* Command ACK */
+#define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */
+
+/*
+ * Status Register Bits
+ */
+
+#define KBD_STAT_OBF 0x01 /* Keyboard output buffer full */
+#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */
+#define KBD_STAT_SELFTEST 0x04 /* Self test successful */
+#define KBD_STAT_CMD 0x08 /* Last write was a command write (0=data) */
+#define KBD_STAT_UNLOCKED 0x10 /* Zero if keyboard locked */
+#define KBD_STAT_MOUSE_OBF 0x20 /* Mouse output buffer full */
+#define KBD_STAT_GTO 0x40 /* General receive/xmit timeout */
+#define KBD_STAT_PERR 0x80 /* Parity error */
+
+#define AUX_STAT_OBF (KBD_STAT_OBF | KBD_STAT_MOUSE_OBF)
+
+/*
+ * Controller Mode Register Bits
+ */
+
+#define KBD_MODE_KBD_INT 0x01 /* Keyboard data generate IRQ1 */
+#define KBD_MODE_MOUSE_INT 0x02 /* Mouse data generate IRQ12 */
+#define KBD_MODE_SYS 0x04 /* The system flag (?) */
+#define KBD_MODE_NO_KEYLOCK 0x08 /* The keylock doesn't affect the keyboard if set */
+#define KBD_MODE_DISABLE_KBD 0x10 /* Disable keyboard interface */
+#define KBD_MODE_DISABLE_MOUSE 0x20 /* Disable mouse interface */
+#define KBD_MODE_KCC 0x40 /* Scan code conversion to PC format */
+#define KBD_MODE_RFU 0x80
+
+
+#define KDB_DATA_PORT 0x60
+#define KDB_COMMAND_PORT 0x64
+
+#define LED_SCR 0x01 /* scroll lock led */
+#define LED_CAP 0x04 /* caps lock led */
+#define LED_NUM 0x02 /* num lock led */
+
+#define KBD_BUFFER_LEN 0x20 /* size of the keyboardbuffer */
+
+
+static volatile char kbd_buffer[KBD_BUFFER_LEN];
+static volatile int in_pointer = 0;
+static volatile int out_pointer = 0;
+
+
+static unsigned char num_lock = 0;
+static unsigned char caps_lock = 0;
+static unsigned char scroll_lock = 0;
+static unsigned char shift = 0;
+static unsigned char ctrl = 0;
+static unsigned char alt = 0;
+static unsigned char e0 = 0;
+static unsigned char leds = 0;
+
+#define DEVNAME "kbd"
+
+/* Simple translation table for the keys */
+
+static unsigned char kbd_plain_xlate[] = {
+ 0xff,0x1b, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=','\b','\t', /* 0x00 - 0x0f */
+ 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']','\r',0xff, 'a', 's', /* 0x10 - 0x1f */
+ 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';','\'', '`',0xff,'\\', 'z', 'x', 'c', 'v', /* 0x20 - 0x2f */
+ 'b', 'n', 'm', ',', '.', '/',0xff,0xff,0xff, ' ',0xff,0xff,0xff,0xff,0xff,0xff, /* 0x30 - 0x3f */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff, '7', '8', '9', '-', '4', '5', '6', '+', '1', /* 0x40 - 0x4f */
+ '2', '3', '0', '.',0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 0x50 - 0x5F */
+ '\r',0xff,0xff
+ };
+
+static unsigned char kbd_shift_xlate[] = {
+ 0xff,0x1b, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+','\b','\t', /* 0x00 - 0x0f */
+ 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}','\r',0xff, 'A', 'S', /* 0x10 - 0x1f */
+ 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~',0xff, '|', 'Z', 'X', 'C', 'V', /* 0x20 - 0x2f */
+ 'B', 'N', 'M', '<', '>', '?',0xff,0xff,0xff, ' ',0xff,0xff,0xff,0xff,0xff,0xff, /* 0x30 - 0x3f */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff, '7', '8', '9', '-', '4', '5', '6', '+', '1', /* 0x40 - 0x4f */
+ '2', '3', '0', '.',0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 0x50 - 0x5F */
+ '\r',0xff,0xff
+ };
+
+static unsigned char kbd_ctrl_xlate[] = {
+ 0xff,0x1b, '1',0x00, '3', '4', '5',0x1E, '7', '8', '9', '0',0x1F, '=','\b','\t', /* 0x00 - 0x0f */
+ 0x11,0x17,0x05,0x12,0x14,0x18,0x15,0x09,0x0f,0x10,0x1b,0x1d,'\n',0xff,0x01,0x13, /* 0x10 - 0x1f */
+ 0x04,0x06,0x08,0x09,0x0a,0x0b,0x0c, ';','\'', '~',0x00,0x1c,0x1a,0x18,0x03,0x16, /* 0x20 - 0x2f */
+ 0x02,0x0e,0x0d, '<', '>', '?',0xff,0xff,0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xff, /* 0x30 - 0x3f */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff, '7', '8', '9', '-', '4', '5', '6', '+', '1', /* 0x40 - 0x4f */
+ '2', '3', '0', '.',0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 0x50 - 0x5F */
+ '\r',0xff,0xff
+ };
+
+/******************************************************************
+ * Init
+ ******************************************************************/
+int isa_kbd_init(void)
+{
+ char* result;
+ result=kbd_initialize();
+ if(result==NULL) {
+ PRINTF("AT Keyboard initialized\n");
+ irq_install_handler(25, (interrupt_handler_t *)handle_isa_int, NULL);
+ isa_irq_install_handler(KBD_INTERRUPT, (interrupt_handler_t *)kbd_interrupt, NULL);
+ return (1);
+ } else {
+ printf("%s\n",result);
+ return (-1);
+ }
+}
+
+#ifdef CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE
+extern int overwrite_console (void);
+#else
+int overwrite_console (void)
+{
+ return (0);
+}
+#endif
+
+int drv_isa_kbd_init (void)
+{
+ int error;
+ struct stdio_dev kbddev ;
+ char *stdinname = getenv ("stdin");
+
+ if(isa_kbd_init()==-1)
+ return -1;
+ memset (&kbddev, 0, sizeof(kbddev));
+ strcpy(kbddev.name, DEVNAME);
+ kbddev.flags = DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
+ kbddev.putc = NULL ;
+ kbddev.puts = NULL ;
+ kbddev.getc = kbd_getc ;
+ kbddev.tstc = kbd_testc ;
+
+ error = stdio_register (&kbddev);
+ if(error==0) {
+ /* check if this is the standard input device */
+ if(strcmp(stdinname,DEVNAME)==0) {
+ /* reassign the console */
+ if(overwrite_console()) {
+ return 1;
+ }
+ error=console_assign(stdin,DEVNAME);
+ if(error==0)
+ return 1;
+ else
+ return error;
+ }
+ return 1;
+ }
+ return error;
+}
+
+/******************************************************************
+ * Queue handling
+ ******************************************************************/
+/* puts character in the queue and sets up the in and out pointer */
+void kbd_put_queue(char data)
+{
+ if((in_pointer+1)==KBD_BUFFER_LEN) {
+ if(out_pointer==0) {
+ return; /* buffer full */
+ } else{
+ in_pointer=0;
+ }
+ } else {
+ if((in_pointer+1)==out_pointer)
+ return; /* buffer full */
+ in_pointer++;
+ }
+ kbd_buffer[in_pointer]=data;
+ return;
+}
+
+/* test if a character is in the queue */
+int kbd_testc(void)
+{
+ if(in_pointer==out_pointer)
+ return(0); /* no data */
+ else
+ return(1);
+}
+/* gets the character from the queue */
+int kbd_getc(void)
+{
+ char c;
+ while(in_pointer==out_pointer);
+ if((out_pointer+1)==KBD_BUFFER_LEN)
+ out_pointer=0;
+ else
+ out_pointer++;
+ c=kbd_buffer[out_pointer];
+ return (int)c;
+
+}
+
+
+/* set LEDs */
+
+void kbd_set_leds(void)
+{
+ if(caps_lock==0)
+ leds&=~LED_CAP; /* switch caps_lock off */
+ else
+ leds|=LED_CAP; /* switch on LED */
+ if(num_lock==0)
+ leds&=~LED_NUM; /* switch LED off */
+ else
+ leds|=LED_NUM; /* switch on LED */
+ if(scroll_lock==0)
+ leds&=~LED_SCR; /* switch LED off */
+ else
+ leds|=LED_SCR; /* switch on LED */
+ kbd_send_data(KBD_CMD_SET_LEDS);
+ kbd_send_data(leds);
+}
+
+
+void handle_keyboard_event (unsigned char scancode)
+{
+ unsigned char keycode;
+
+ /* Convert scancode to keycode */
+ PRINTF ("scancode %x\n", scancode);
+ if (scancode == 0xe0) {
+ e0 = 1; /* special charakters */
+ return;
+ }
+ if (e0 == 1) {
+ e0 = 0; /* delete flag */
+ if (!(((scancode & 0x7F) == 0x38) || /* the right ctrl key */
+ ((scancode & 0x7F) == 0x1D) || /* the right alt key */
+ ((scancode & 0x7F) == 0x35) || /* the right '/' key */
+ ((scancode & 0x7F) == 0x1C)))
+ /* the right enter key */
+ /* we swallow unknown e0 codes */
+ return;
+ }
+ /* special cntrl keys */
+ switch (scancode) {
+ case 0x2A:
+ case 0x36: /* shift pressed */
+ shift = 1;
+ return; /* do nothing else */
+ case 0xAA:
+ case 0xB6: /* shift released */
+ shift = 0;
+ return; /* do nothing else */
+ case 0x38: /* alt pressed */
+ alt = 1;
+ return; /* do nothing else */
+ case 0xB8: /* alt released */
+ alt = 0;
+ return; /* do nothing else */
+ case 0x1d: /* ctrl pressed */
+ ctrl = 1;
+ return; /* do nothing else */
+ case 0x9d: /* ctrl released */
+ ctrl = 0;
+ return; /* do nothing else */
+ case 0x46: /* scrollock pressed */
+ scroll_lock = ~scroll_lock;
+ kbd_set_leds ();
+ return; /* do nothing else */
+ case 0x3A: /* capslock pressed */
+ caps_lock = ~caps_lock;
+ kbd_set_leds ();
+ return;
+ case 0x45: /* numlock pressed */
+ num_lock = ~num_lock;
+ kbd_set_leds ();
+ return;
+ case 0xC6: /* scroll lock released */
+ case 0xC5: /* num lock released */
+ case 0xBA: /* caps lock released */
+ return; /* just swallow */
+ }
+ if ((scancode & 0x80) == 0x80) /* key released */
+ return;
+ /* now, decide which table we need */
+ if (scancode > (sizeof (kbd_plain_xlate) / sizeof (kbd_plain_xlate[0]))) { /* scancode not in list */
+ PRINTF ("unkown scancode %X\n", scancode);
+ return; /* swallow it */
+ }
+ /* setup plain code first */
+ keycode = kbd_plain_xlate[scancode];
+ if (caps_lock == 1) { /* caps_lock is pressed, overwrite plain code */
+ if (scancode > (sizeof (kbd_shift_xlate) / sizeof (kbd_shift_xlate[0]))) { /* scancode not in list */
+ PRINTF ("unkown caps-locked scancode %X\n", scancode);
+ return; /* swallow it */
+ }
+ keycode = kbd_shift_xlate[scancode];
+ if (keycode < 'A') { /* we only want the alphas capital */
+ keycode = kbd_plain_xlate[scancode];
+ }
+ }
+ if (shift == 1) { /* shift overwrites caps_lock */
+ if (scancode > (sizeof (kbd_shift_xlate) / sizeof (kbd_shift_xlate[0]))) { /* scancode not in list */
+ PRINTF ("unkown shifted scancode %X\n", scancode);
+ return; /* swallow it */
+ }
+ keycode = kbd_shift_xlate[scancode];
+ }
+ if (ctrl == 1) { /* ctrl overwrites caps_lock and shift */
+ if (scancode > (sizeof (kbd_ctrl_xlate) / sizeof (kbd_ctrl_xlate[0]))) { /* scancode not in list */
+ PRINTF ("unkown ctrl scancode %X\n", scancode);
+ return; /* swallow it */
+ }
+ keycode = kbd_ctrl_xlate[scancode];
+ }
+ /* check if valid keycode */
+ if (keycode == 0xff) {
+ PRINTF ("unkown scancode %X\n", scancode);
+ return; /* swallow unknown codes */
+ }
+
+ kbd_put_queue (keycode);
+ PRINTF ("%x\n", keycode);
+}
+
+/*
+ * This reads the keyboard status port, and does the
+ * appropriate action.
+ *
+ */
+unsigned char handle_kbd_event(void)
+{
+ unsigned char status = kbd_read_status();
+ unsigned int work = 10000;
+
+ while ((--work > 0) && (status & KBD_STAT_OBF)) {
+ unsigned char scancode;
+
+ scancode = kbd_read_input();
+
+ /* Error bytes must be ignored to make the
+ Synaptics touchpads compaq use work */
+ /* Ignore error bytes */
+ if (!(status & (KBD_STAT_GTO | KBD_STAT_PERR)))
+ {
+ if (status & KBD_STAT_MOUSE_OBF)
+ ; /* not supported: handle_mouse_event(scancode); */
+ else
+ handle_keyboard_event(scancode);
+ }
+ status = kbd_read_status();
+ }
+ if (!work)
+ PRINTF("pc_keyb: controller jammed (0x%02X).\n", status);
+ return status;
+}
+
+
+/******************************************************************************
+ * Lowlevel Part of keyboard section
+ */
+unsigned char kbd_read_status(void)
+{
+ return(in8(CONFIG_SYS_ISA_IO_BASE_ADDRESS + KDB_COMMAND_PORT));
+}
+
+unsigned char kbd_read_input(void)
+{
+ return(in8(CONFIG_SYS_ISA_IO_BASE_ADDRESS + KDB_DATA_PORT));
+}
+
+void kbd_write_command(unsigned char cmd)
+{
+ out8(CONFIG_SYS_ISA_IO_BASE_ADDRESS + KDB_COMMAND_PORT,cmd);
+}
+
+void kbd_write_output(unsigned char data)
+{
+ out8(CONFIG_SYS_ISA_IO_BASE_ADDRESS + KDB_DATA_PORT, data);
+}
+
+int kbd_read_data(void)
+{
+ int val;
+ unsigned char status;
+
+ val = -1;
+ status = kbd_read_status();
+ if (status & KBD_STAT_OBF) {
+ val = kbd_read_input();
+ if (status & (KBD_STAT_GTO | KBD_STAT_PERR))
+ val = -2;
+ }
+ return val;
+}
+
+int kbd_wait_for_input(void)
+{
+ unsigned long timeout;
+ int val;
+
+ timeout = KBD_TIMEOUT;
+ val=kbd_read_data();
+ while(val < 0)
+ {
+ if(timeout--==0)
+ return -1;
+ udelay(1000);
+ val=kbd_read_data();
+ }
+ return val;
+}
+
+
+int kb_wait(void)
+{
+ unsigned long timeout = KBC_TIMEOUT * 10;
+
+ do {
+ unsigned char status = handle_kbd_event();
+ if (!(status & KBD_STAT_IBF))
+ return 0; /* ok */
+ udelay(1000);
+ timeout--;
+ } while (timeout);
+ return 1;
+}
+
+void kbd_write_command_w(int data)
+{
+ if(kb_wait())
+ PRINTF("timeout in kbd_write_command_w\n");
+ kbd_write_command(data);
+}
+
+void kbd_write_output_w(int data)
+{
+ if(kb_wait())
+ PRINTF("timeout in kbd_write_output_w\n");
+ kbd_write_output(data);
+}
+
+void kbd_send_data(unsigned char data)
+{
+ unsigned char status;
+ disable_8259A_irq(1); /* disable interrupt */
+ kbd_write_output_w(data);
+ status = kbd_wait_for_input();
+ if (status == KBD_REPLY_ACK)
+ enable_8259A_irq(1); /* enable interrupt */
+}
+
+
+char * kbd_initialize(void)
+{
+ int status;
+
+ in_pointer = 0; /* delete in Buffer */
+ out_pointer = 0;
+ /*
+ * Test the keyboard interface.
+ * This seems to be the only way to get it going.
+ * If the test is successful a x55 is placed in the input buffer.
+ */
+ kbd_write_command_w(KBD_CCMD_SELF_TEST);
+ if (kbd_wait_for_input() != 0x55)
+ return "Kbd: failed self test";
+ /*
+ * Perform a keyboard interface test. This causes the controller
+ * to test the keyboard clock and data lines. The results of the
+ * test are placed in the input buffer.
+ */
+ kbd_write_command_w(KBD_CCMD_KBD_TEST);
+ if (kbd_wait_for_input() != 0x00)
+ return "Kbd: interface failed self test";
+ /*
+ * Enable the keyboard by allowing the keyboard clock to run.
+ */
+ kbd_write_command_w(KBD_CCMD_KBD_ENABLE);
+ status = kbd_wait_for_input();
+ /*
+ * Reset keyboard. If the read times out
+ * then the assumption is that no keyboard is
+ * plugged into the machine.
+ * This defaults the keyboard to scan-code set 2.
+ *
+ * Set up to try again if the keyboard asks for RESEND.
+ */
+ do {
+ kbd_write_output_w(KBD_CMD_RESET);
+ status = kbd_wait_for_input();
+ if (status == KBD_REPLY_ACK)
+ break;
+ if (status != KBD_REPLY_RESEND) {
+ PRINTF("status: %X\n",status);
+ return "Kbd: reset failed, no ACK";
+ }
+ } while (1);
+ if (kbd_wait_for_input() != KBD_REPLY_POR)
+ return "Kbd: reset failed, no POR";
+
+ /*
+ * Set keyboard controller mode. During this, the keyboard should be
+ * in the disabled state.
+ *
+ * Set up to try again if the keyboard asks for RESEND.
+ */
+ do {
+ kbd_write_output_w(KBD_CMD_DISABLE);
+ status = kbd_wait_for_input();
+ if (status == KBD_REPLY_ACK)
+ break;
+ if (status != KBD_REPLY_RESEND)
+ return "Kbd: disable keyboard: no ACK";
+ } while (1);
+
+ kbd_write_command_w(KBD_CCMD_WRITE_MODE);
+ kbd_write_output_w(KBD_MODE_KBD_INT
+ | KBD_MODE_SYS
+ | KBD_MODE_DISABLE_MOUSE
+ | KBD_MODE_KCC);
+
+ /* AMCC powerpc portables need this to use scan-code set 1 -- Cort */
+ kbd_write_command_w(KBD_CCMD_READ_MODE);
+ if (!(kbd_wait_for_input() & KBD_MODE_KCC)) {
+ /*
+ * If the controller does not support conversion,
+ * Set the keyboard to scan-code set 1.
+ */
+ kbd_write_output_w(0xF0);
+ kbd_wait_for_input();
+ kbd_write_output_w(0x01);
+ kbd_wait_for_input();
+ }
+ kbd_write_output_w(KBD_CMD_ENABLE);
+ if (kbd_wait_for_input() != KBD_REPLY_ACK)
+ return "Kbd: enable keyboard: no ACK";
+
+ /*
+ * Finally, set the typematic rate to maximum.
+ */
+ kbd_write_output_w(KBD_CMD_SET_RATE);
+ if (kbd_wait_for_input() != KBD_REPLY_ACK)
+ return "Kbd: Set rate: no ACK";
+ kbd_write_output_w(0x00);
+ if (kbd_wait_for_input() != KBD_REPLY_ACK)
+ return "Kbd: Set rate: no ACK";
+ return NULL;
+}
+
+void kbd_interrupt(void)
+{
+ handle_kbd_event();
+}
diff --git a/u-boot/board/mpl/common/kbd.h b/u-boot/board/mpl/common/kbd.h
new file mode 100644
index 0000000..229ba61
--- /dev/null
+++ b/u-boot/board/mpl/common/kbd.h
@@ -0,0 +1,35 @@
+/*
+ * (C) Copyright 2001
+ * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#ifndef _KBD_H_
+#define _KBD_H_
+
+extern int kbd_testc(void);
+extern int kbd_getc(void);
+extern void kbd_interrupt(void);
+extern char *kbd_initialize(void);
+
+unsigned char kbd_is_init(void);
+#define KBD_INTERRUPT 1
+#endif
diff --git a/u-boot/board/mpl/common/pci.c b/u-boot/board/mpl/common/pci.c
new file mode 100644
index 0000000..f9bb6ab
--- /dev/null
+++ b/u-boot/board/mpl/common/pci.c
@@ -0,0 +1,109 @@
+/*-----------------------------------------------------------------------------+
+| This source code is dual-licensed. You may use it under the terms of
+| the GNU General Public License version 2, or under the license below.
+|
+| This source code has been made available to you by IBM on an AS-IS
+| basis. Anyone receiving this source is licensed under IBM
+| copyrights to use it in any way he or she deems fit, including
+| copying it, modifying it, compiling it, and redistributing it either
+| with or without modifications. No license under IBM patents or
+| patent applications is to be implied by the copyright license.
+|
+| Any user of this software should understand that IBM cannot provide
+| technical support for this software and will not be responsible for
+| any consequences resulting from the use of this software.
+|
+| Any person who transfers this source code or any derivative work
+| must include the IBM copyright notice, this paragraph, and the
+| preceding two paragraphs in the transferred software.
+|
+| COPYRIGHT I B M CORPORATION 1995
+| LICENSED MATERIAL - PROGRAM PROPERTY OF I B M
++-----------------------------------------------------------------------------*/
+/*
+ * Adapted for PIP405 03.07.01
+ * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
+ *
+ * TODO: Clean-up
+ */
+
+#include <common.h>
+#include <pci.h>
+#include "isa.h"
+
+#ifdef CONFIG_405GP
+#ifdef CONFIG_PCI
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#include "piix4_pci.h"
+#include "pci_parts.h"
+
+void pci_pip405_write_regs(struct pci_controller *hose, pci_dev_t dev,
+ struct pci_config_table *entry)
+{
+ struct pci_pip405_config_entry *table;
+ int i;
+
+ table = (struct pci_pip405_config_entry*) entry->priv[0];
+
+ for (i=0; table[i].width; i++)
+ {
+#ifdef DEBUG
+ printf("Reg 0x%02X Value 0x%08lX Width %02d written\n",
+ table[i].index, table[i].val, table[i].width);
+#endif
+
+ switch(table[i].width)
+ {
+ case 1: pci_hose_write_config_byte(hose, dev, table[i].index, table[i].val); break;
+ case 2: pci_hose_write_config_word(hose, dev, table[i].index, table[i].val); break;
+ case 4: pci_hose_write_config_dword(hose, dev, table[i].index, table[i].val); break;
+ }
+ }
+}
+
+
+static void pci_pip405_fixup_irq(struct pci_controller *hose, pci_dev_t dev)
+{
+ unsigned char int_line = 0xff;
+ unsigned char pin;
+ /*
+ * Write pci interrupt line register
+ */
+ if(PCI_DEV(dev)==0) /* Device0 = PPC405 -> skip */
+ return;
+ pci_hose_read_config_byte(hose, dev, PCI_INTERRUPT_PIN, &pin);
+ if ((pin == 0) || (pin > 4))
+ return;
+
+ int_line = ((PCI_DEV(dev) + (pin-1) + 10) % 4) + 28;
+ pci_hose_write_config_byte(hose, dev, PCI_INTERRUPT_LINE, int_line);
+#ifdef DEBUG
+ printf("Fixup IRQ: dev %d (%x) int line %d 0x%x\n",
+ PCI_DEV(dev),dev,int_line,int_line);
+#endif
+}
+
+extern void pci_405gp_init(struct pci_controller *hose);
+
+
+static struct pci_controller hose = {
+ config_table: pci_pip405_config_table,
+ fixup_irq: pci_pip405_fixup_irq,
+};
+
+
+void pci_init_board(void)
+{
+ /*we want the ptrs to RAM not flash (ie don't use init list)*/
+ hose.fixup_irq = pci_pip405_fixup_irq;
+ hose.config_table = pci_pip405_config_table;
+#ifdef DEBUG
+ printf("Init PCI: fixup_irq=%p config_table=%p hose=%p\n",pci_pip405_fixup_irq,pci_pip405_config_table,hose);
+#endif
+ pci_405gp_init(&hose);
+}
+
+#endif /* CONFIG_PCI */
+#endif /* CONFIG_405GP */
diff --git a/u-boot/board/mpl/common/pci_parts.h b/u-boot/board/mpl/common/pci_parts.h
new file mode 100644
index 0000000..7bca961
--- /dev/null
+++ b/u-boot/board/mpl/common/pci_parts.h
@@ -0,0 +1,193 @@
+ /*
+ * (C) Copyright 2001
+ * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+#ifndef _PCI_PARTS_H_
+#define _PCI_PARTS_H_
+
+
+/* Board specific file containing:
+ * - PCI Memory Mapping
+ * - PCI IO Mapping
+ * - PCI Interrupt Mapping
+ */
+
+/* PIP405 PCI INT Routing:
+ * IRQ0 VECTOR
+ * PIXX4 IDSEL = AD16 INTA# 28 (Function 2 USB is INTD# = 31)
+ * VGA IDSEL = AD17 INTB# 29
+ * SCSI IDSEL = AD18 INTC# 30
+ * PC104 IDSEL0 = AD20 INTA# 28
+ * PC104 IDSEL1 = AD21 INTB# 29
+ * PC104 IDSEL2 = AD22 INTC# 30
+ * PC104 IDSEL3 = AD23 INTD# 31
+ *
+ * busdevfunc = EXXX XXXX BBBB BBBB DDDD DFFF RRRR RR00
+ * ^ ^ ^ ^ ^
+ * 31 23 15 10 7
+ * E = Enabled
+ * B = Bussnumber
+ * D = Devicenumber (Device0 = AD10)
+ * F = Functionnumber
+ * R = Registernumber
+ *
+ * Device = (busdevfunc>>11) + 10
+ * Vector = devicenumber % 4 + 28
+ *
+ */
+#define PCI_HIGHEST_ON_BOARD_ID 19
+/*#define PCI_DEV_NUMBER(x) (((x>>11) & 0x1f) + 10) */
+#define PCI_IRQ_VECTOR(x) ((PCI_DEV(x) + 10) % 4) + 28
+
+
+/* PCI Device List for PIP405 */
+
+/* Mapping:
+ * +-------------+------------+------------+--------------------------------+
+ * ¦ PCI MemAddr | PCI IOAddr | Local Addr | Device / Function |
+ * +-------------+------------+------------+--------------------------------+
+ * | 0x00000000 | | 0xA0000000 | ISA Memory (hard wired) |
+ * | 0x00FFFFFF | | 0xA0FFFFFF | |
+ * +-------------+------------+------------+--------------------------------+
+ * | | 0x00000000 | 0xE8000000 | ISA IO (hard wired) |
+ * | | 0x0000FFFF | 0xE800FFFF | |
+ * +-------------+------------+------------+--------------------------------+
+ * | 0x80000000 | | 0x80000000 | VGA Controller Memory |
+ * | 0x80FFFFFF | | 0x80FFFFFF | |
+ * +-------------+------------+------------+--------------------------------+
+ * | 0x81000000 | | 0x81000000 | SCSI Controller Memory |
+ * | 0x81FFFFFF | | 0x81FFFFFF | |
+ * +-------------+------------+------------+--------------------------------+
+ */
+
+struct pci_pip405_config_entry {
+ int index; /* address */
+ unsigned long val; /* value */
+ int width; /* data size */
+};
+
+extern void pci_pip405_write_regs(struct pci_controller *,
+ pci_dev_t,
+ struct pci_config_table *);
+
+/* PIIX4 ISA Bridge Function 0 */
+static struct pci_pip405_config_entry piix4_isa_bridge_f0[] = {
+ {PCI_CFG_PIIX4_SERIRQ, 0xD0, 1}, /* enable Continous SERIRQ Pin */
+ {PCI_CFG_PIIX4_GENCFG, 0x00018041, 4}, /* enable SERIRQs, ISA, PNP, GPI11 */
+ {PCI_CFG_PIIX4_TOM, 0xFE, 1}, /* Top of Memory */
+ {PCI_CFG_PIIX4_XBCS, 0x02C4, 2}, /* disable all peri CS */
+ {PCI_CFG_PIIX4_RTCCFG, 0x21, 1}, /* enable RTC */
+#if defined(CONFIG_PIP405)
+ {PCI_CFG_PIIX4_MBDMA, 0x82, 1}, /* set MBDMA0 to DMA 2 */
+ {PCI_CFG_PIIX4_MBDMA+1, 0x83, 1}, /* set MBDMA1 to DMA 3 */
+#endif
+ {PCI_CFG_PIIX4_DLC, 0x0, 1}, /* disable passive release feature */
+ { } /* end of device table */
+};
+
+/* PIIX4 IDE Controller Function 1 */
+static struct pci_pip405_config_entry piix4_ide_cntrl_f1[] = {
+ {PCI_CFG_PIIX4_BMIBA, 0x0001000, 4}, /* set BMI to a valid address */
+ {PCI_COMMAND, 0x0001, 2}, /* enable IO access */
+#if !defined(CONFIG_MIP405T)
+ {PCI_CFG_PIIX4_IDETIM, 0x80008000, 4}, /* enable Both IDE channels */
+#else
+ {PCI_CFG_PIIX4_IDETIM, 0x00008000, 4}, /* enable IDE channel0 */
+#endif
+ { } /* end of device table */
+};
+
+/* PIIX4 USB Controller Function 2 */
+static struct pci_pip405_config_entry piix4_usb_cntrl_f2[] = {
+#if !defined(CONFIG_MIP405T)
+ {PCI_INTERRUPT_LINE, 31, 1}, /* Int vector = 31 */
+ {PCI_BASE_ADDRESS_4, 0x0000E001, 4}, /* Set IO Address to 0xe000 to 0xe01F */
+ {PCI_LATENCY_TIMER, 0x80, 1}, /* Latency Timer 0x80 */
+ {0xC0, 0x2000, 2}, /* Legacy support */
+ {PCI_COMMAND, 0x0005, 2}, /* enable IO access and Master */
+#endif
+ { } /* end of device table */
+};
+
+/* PIIX4 Power Management Function 3 */
+static struct pci_pip405_config_entry piix4_pmm_cntrl_f3[] = {
+ {PCI_CFG_PIIX4_PMBA, 0x00004000, 4}, /* set PMBA to "valid" value */
+ {PCI_CFG_PIIX4_SMBBA, 0x00005000, 4}, /* set SMBBA to "valid" value */
+ {PCI_CFG_PIIX4_PMMISC, 0x01, 1}, /* enable PMBA IO access */
+ {PCI_COMMAND, 0x0001, 2}, /* enable IO access */
+ { } /* end of device table */
+};
+/* PPC405 Dummy only used to prevent autosetup on this host bridge */
+static struct pci_pip405_config_entry ppc405_dummy[] = {
+ { } /* end of device table */
+};
+
+void pci_405gp_setup_vga(struct pci_controller *hose, pci_dev_t dev,
+ struct pci_config_table *entry);
+
+
+static struct pci_config_table pci_pip405_config_table[]={
+ {PCI_VENDOR_ID_IBM, /* 405 dummy */
+ PCI_DEVICE_ID_IBM_405GP,
+ PCI_ANY_ID,
+ PCI_ANY_ID, PCI_ANY_ID, 0,
+ pci_pip405_write_regs, {(unsigned long) ppc405_dummy}},
+
+ {PCI_VENDOR_ID_INTEL, /* PIIX4 ISA Bridge Function 0 */
+ PCI_DEVICE_ID_INTEL_82371AB_0,
+ PCI_ANY_ID,
+ PCI_ANY_ID, PCI_ANY_ID, 0,
+ pci_pip405_write_regs, {(unsigned long) piix4_isa_bridge_f0}},
+
+ {PCI_VENDOR_ID_INTEL, /* PIIX4 IDE Controller Function 1 */
+ PCI_DEVICE_ID_INTEL_82371AB,
+ PCI_ANY_ID,
+ PCI_ANY_ID, PCI_ANY_ID, 1,
+ pci_pip405_write_regs, {(unsigned long) piix4_ide_cntrl_f1}},
+
+ {PCI_VENDOR_ID_INTEL, /* PIIX4 USB Controller Function 2 */
+ PCI_DEVICE_ID_INTEL_82371AB_2,
+ PCI_ANY_ID,
+ PCI_ANY_ID, PCI_ANY_ID, 2,
+ pci_pip405_write_regs, {(unsigned long) piix4_usb_cntrl_f2}},
+
+ {PCI_VENDOR_ID_INTEL, /* PIIX4 USB Controller Function 3 */
+ PCI_DEVICE_ID_INTEL_82371AB_3,
+ PCI_ANY_ID,
+ PCI_ANY_ID, PCI_ANY_ID, 3,
+ pci_pip405_write_regs, {(unsigned long) piix4_pmm_cntrl_f3}},
+
+ {PCI_ANY_ID,
+ PCI_ANY_ID,
+ PCI_CLASS_DISPLAY_VGA,
+ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+ pci_405gp_setup_vga},
+
+ {PCI_ANY_ID,
+ PCI_ANY_ID,
+ PCI_CLASS_NOT_DEFINED_VGA,
+ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+ pci_405gp_setup_vga},
+
+ { }
+};
+#endif /* _PCI_PARTS_H_ */
diff --git a/u-boot/board/mpl/common/piix4_pci.h b/u-boot/board/mpl/common/piix4_pci.h
new file mode 100644
index 0000000..0ff802e
--- /dev/null
+++ b/u-boot/board/mpl/common/piix4_pci.h
@@ -0,0 +1,165 @@
+/*
+ * (C) Copyright 2001
+ * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+
+#ifndef _PIIX4_PCI_H
+#define _PIIX4_PCI_H
+
+/***************************************************************************
+* Defines PIIX4 Config Registers
+****************************************************************************/
+
+/* Function 0 ISA Bridge */
+#define PCI_CFG_PIIX4_IORT 0x4C /* 8 bit ISA Recovery Timer Reg (default 0x4D) */
+#define PCI_CFG_PIIX4_XBCS 0x4E /* 16 bit XBus Chip select reg (default 0x0003) */
+#define PCI_CFG_PIIX4_PIRQC 0x60 /* PCI IRQ Route Register 4 x 8bit (default )*/
+#define PCI_CFG_PIIX4_SERIRQ 0x64
+#define PCI_CFG_PIIX4_TOM 0x69
+#define PCI_CFG_PIIX4_MSTAT 0x6A
+#define PCI_CFG_PIIX4_MBDMA 0x76
+#define PCI_CFG_PIIX4_APICBS 0x80
+#define PCI_CFG_PIIX4_DLC 0x82
+#define PCI_CFG_PIIX4_PDMACFG 0x90
+#define PCI_CFG_PIIX4_DDMABS 0x92
+#define PCI_CFG_PIIX4_GENCFG 0xB0
+#define PCI_CFG_PIIX4_RTCCFG 0xCB
+
+/* IO Addresses */
+#define PIIX4_ISA_DMA1_CH0BA 0x00
+#define PIIX4_ISA_DMA1_CH0CA 0x01
+#define PIIX4_ISA_DMA1_CH1BA 0x02
+#define PIIX4_ISA_DMA1_CH1CA 0x03
+#define PIIX4_ISA_DMA1_CH2BA 0x04
+#define PIIX4_ISA_DMA1_CH2CA 0x05
+#define PIIX4_ISA_DMA1_CH3BA 0x06
+#define PIIX4_ISA_DMA1_CH3CA 0x07
+#define PIIX4_ISA_DMA1_CMDST 0x08
+#define PIIX4_ISA_DMA1_REQ 0x09
+#define PIIX4_ISA_DMA1_WSBM 0x0A
+#define PIIX4_ISA_DMA1_CH_MOD 0x0B
+#define PIIX4_ISA_DMA1_CLR_PT 0x0C
+#define PIIX4_ISA_DMA1_M_CLR 0x0D
+#define PIIX4_ISA_DMA1_CLR_M 0x0E
+#define PIIX4_ISA_DMA1_RWAMB 0x0F
+
+#define PIIX4_ISA_DMA2_CH0BA 0xC0
+#define PIIX4_ISA_DMA2_CH0CA 0xC1
+#define PIIX4_ISA_DMA2_CH1BA 0xC2
+#define PIIX4_ISA_DMA2_CH1CA 0xC3
+#define PIIX4_ISA_DMA2_CH2BA 0xC4
+#define PIIX4_ISA_DMA2_CH2CA 0xC5
+#define PIIX4_ISA_DMA2_CH3BA 0xC6
+#define PIIX4_ISA_DMA2_CH3CA 0xC7
+#define PIIX4_ISA_DMA2_CMDST 0xD0
+#define PIIX4_ISA_DMA2_REQ 0xD2
+#define PIIX4_ISA_DMA2_WSBM 0xD4
+#define PIIX4_ISA_DMA2_CH_MOD 0xD6
+#define PIIX4_ISA_DMA2_CLR_PT 0xD8
+#define PIIX4_ISA_DMA2_M_CLR 0xDA
+#define PIIX4_ISA_DMA2_CLR_M 0xDC
+#define PIIX4_ISA_DMA2_RWAMB 0xDE
+
+#define PIIX4_ISA_INT1_ICW1 0x20
+#define PIIX4_ISA_INT1_OCW2 0x20
+#define PIIX4_ISA_INT1_OCW3 0x20
+#define PIIX4_ISA_INT1_ICW2 0x21
+#define PIIX4_ISA_INT1_ICW3 0x21
+#define PIIX4_ISA_INT1_ICW4 0x21
+#define PIIX4_ISA_INT1_OCW1 0x21
+
+#define PIIX4_ISA_INT1_ELCR 0x4D0
+
+#define PIIX4_ISA_INT2_ICW1 0xA0
+#define PIIX4_ISA_INT2_OCW2 0xA0
+#define PIIX4_ISA_INT2_OCW3 0xA0
+#define PIIX4_ISA_INT2_ICW2 0xA1
+#define PIIX4_ISA_INT2_ICW3 0xA1
+#define PIIX4_ISA_INT2_ICW4 0xA1
+#define PIIX4_ISA_INT2_OCW1 0xA1
+#define PIIX4_ISA_INT2_IMR 0xA1 /* read only */
+
+#define PIIX4_ISA_INT2_ELCR 0x4D1
+
+#define PIIX4_ISA_TMR0_CNT_ST 0x40
+#define PIIX4_ISA_TMR1_CNT_ST 0x41
+#define PIIX4_ISA_TMR2_CNT_ST 0x42
+#define PIIX4_ISA_TMR_TCW 0x43
+
+#define PIIX4_ISA_RST_XBUS 0x60
+
+#define PIIX4_ISA_NMI_CNT_ST 0x61
+#define PIIX4_ISA_NMI_ENABLE 0x70
+
+#define PIIX4_ISA_RTC_INDEX 0x70
+#define PIIX4_ISA_RTC_DATA 0x71
+#define PIIX4_ISA_RTCEXT_IND 0x70
+#define PIIX4_ISA_RTCEXT_DATA 0x71
+
+#define PIIX4_ISA_DMA1_CH2LPG 0x81
+#define PIIX4_ISA_DMA1_CH3LPG 0x82
+#define PIIX4_ISA_DMA1_CH1LPG 0x83
+#define PIIX4_ISA_DMA1_CH0LPG 0x87
+#define PIIX4_ISA_DMA2_CH2LPG 0x89
+#define PIIX4_ISA_DMA2_CH3LPG 0x8A
+#define PIIX4_ISA_DMA2_CH1LPG 0x8B
+#define PIIX4_ISA_DMA2_LPGRFR 0x8F
+
+#define PIIX4_ISA_PORT_92 0x92
+
+#define PIIX4_ISA_APM_CONTRL 0xB2
+#define PIIX4_ISA_APM_STATUS 0xB3
+
+#define PIIX4_ISA_COCPU_ERROR 0xF0
+
+/* Function 1 IDE Controller */
+#define PCI_CFG_PIIX4_BMIBA 0x20
+#define PCI_CFG_PIIX4_IDETIM 0x40
+#define PCI_CFG_PIIX4_SIDETIM 0x44
+#define PCI_CFG_PIIX4_UDMACTL 0x48
+#define PCI_CFG_PIIX4_UDMATIM 0x4A
+
+/* Function 2 USB Controller */
+#define PCI_CFG_PIIX4_SBRNUM 0x60
+#define PCI_CFG_PIIX4_LEGSUP 0xC0
+
+/* Function 3 Power Management */
+#define PCI_CFG_PIIX4_PMBA 0x40
+#define PCI_CFG_PIIX4_CNTA 0x44
+#define PCI_CFG_PIIX4_CNTB 0x48
+#define PCI_CFG_PIIX4_GPICTL 0x4C
+#define PCI_CFG_PIIX4_DEVRESD 0x50
+#define PCI_CFG_PIIX4_DEVACTA 0x54
+#define PCI_CFG_PIIX4_DEVACTB 0x58
+#define PCI_CFG_PIIX4_DEVRESA 0x5C
+#define PCI_CFG_PIIX4_DEVRESB 0x60
+#define PCI_CFG_PIIX4_DEVRESC 0x64
+#define PCI_CFG_PIIX4_DEVRESE 0x68
+#define PCI_CFG_PIIX4_DEVRESF 0x6C
+#define PCI_CFG_PIIX4_DEVRESG 0x70
+#define PCI_CFG_PIIX4_DEVRESH 0x74
+#define PCI_CFG_PIIX4_DEVRESI 0x78
+#define PCI_CFG_PIIX4_PMMISC 0x80
+#define PCI_CFG_PIIX4_SMBBA 0x90
+
+
+#endif
diff --git a/u-boot/board/mpl/common/usb_uhci.c b/u-boot/board/mpl/common/usb_uhci.c
new file mode 100644
index 0000000..a009437
--- /dev/null
+++ b/u-boot/board/mpl/common/usb_uhci.c
@@ -0,0 +1,1169 @@
+/*
+ * Part of this code has been derived from linux:
+ * Universal Host Controller Interface driver for USB (take II).
+ *
+ * (c) 1999-2001 Georg Acher, acher@in.tum.de (executive slave) (base guitar)
+ * Deti Fliegl, deti@fliegl.de (executive slave) (lead voice)
+ * Thomas Sailer, sailer@ife.ee.ethz.ch (chief consultant) (cheer leader)
+ * Roman Weissgaerber, weissg@vienna.at (virt root hub) (studio porter)
+ * (c) 2000 Yggdrasil Computing, Inc. (port of new PCI interface support
+ * from usb-ohci.c by Adam Richter, adam@yggdrasil.com).
+ * (C) 2000 David Brownell, david-b@pacbell.net (usb-ohci.c)
+ *
+ * HW-initalization based on material of
+ *
+ * (C) Copyright 1999 Linus Torvalds
+ * (C) Copyright 1999 Johannes Erdfelt
+ * (C) Copyright 1999 Randy Dunlap
+ * (C) Copyright 1999 Gregory P. Smith
+ *
+ *
+ * Adapted for U-Boot:
+ * (C) Copyright 2001 Denis Peter, MPL AG Switzerland
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ */
+
+/**********************************************************************
+ * How it works:
+ * -------------
+ * The framelist / Transfer descriptor / Queue Heads are similar like
+ * in the linux usb_uhci.c.
+ *
+ * During initialization, the following skeleton is allocated in init_skel:
+ *
+ * framespecific | common chain
+ *
+ * framelist[]
+ * [ 0 ]-----> TD ---------\
+ * [ 1 ]-----> TD ----------> TD ------> QH -------> QH -------> QH ---> NULL
+ * ... TD ---------/
+ * [1023]-----> TD --------/
+ *
+ * ^^ ^^ ^^ ^^ ^^
+ * 7 TDs for 1 TD for Start of Start of End Chain
+ * INT (2-128ms) 1ms-INT CTRL Chain BULK Chain
+ *
+ *
+ * Since this is a bootloader, the isochronous transfer descriptor have been removed.
+ *
+ * Interrupt Transfers.
+ * --------------------
+ * For Interupt transfers USB_MAX_TEMP_INT_TD Transfer descriptor are available. They
+ * will be inserted after the appropriate (depending the interval setting) skeleton TD.
+ * If an interrupt has been detected the dev->irqhandler is called. The status and number
+ * of transfered bytes is stored in dev->irq_status resp. dev->irq_act_len. If the
+ * dev->irqhandler returns 0, the interrupt TD is removed and disabled. If an 1 is returned,
+ * the interrupt TD will be reactivated.
+ *
+ * Control Transfers
+ * -----------------
+ * Control Transfers are issued by filling the tmp_td with the appropriate data and connect
+ * them to the qh_cntrl queue header. Before other control/bulk transfers can be issued,
+ * the programm has to wait for completion. This does not allows asynchronous data transfer.
+ *
+ * Bulk Transfers
+ * --------------
+ * Bulk Transfers are issued by filling the tmp_td with the appropriate data and connect
+ * them to the qh_bulk queue header. Before other control/bulk transfers can be issued,
+ * the programm has to wait for completion. This does not allows asynchronous data transfer.
+ *
+ *
+ */
+
+#include <common.h>
+#include <pci.h>
+
+#ifdef CONFIG_USB_UHCI
+
+#include <usb.h>
+#include "usb_uhci.h"
+
+#define USB_MAX_TEMP_TD 128 /* number of temporary TDs for bulk and control transfers */
+#define USB_MAX_TEMP_INT_TD 32 /* number of temporary TDs for Interrupt transfers */
+
+
+#undef USB_UHCI_DEBUG
+
+#ifdef USB_UHCI_DEBUG
+#define USB_UHCI_PRINTF(fmt,args...) printf (fmt ,##args)
+#else
+#define USB_UHCI_PRINTF(fmt,args...)
+#endif
+
+
+static int irqvec = -1; /* irq vector, if -1 uhci is stopped / reseted */
+unsigned int usb_base_addr; /* base address */
+
+static uhci_td_t td_int[8]; /* Interrupt Transfer descriptors */
+static uhci_qh_t qh_cntrl; /* control Queue Head */
+static uhci_qh_t qh_bulk; /* bulk Queue Head */
+static uhci_qh_t qh_end; /* end Queue Head */
+static uhci_td_t td_last; /* last TD (linked with end chain) */
+
+/* temporary tds */
+static uhci_td_t tmp_td[USB_MAX_TEMP_TD]; /* temporary bulk/control td's */
+static uhci_td_t tmp_int_td[USB_MAX_TEMP_INT_TD]; /* temporary interrupt td's */
+
+static unsigned long framelist[1024] __attribute__ ((aligned (0x1000))); /* frame list */
+
+static struct virt_root_hub rh; /* struct for root hub */
+
+/**********************************************************************
+ * some forward decleration
+ */
+int uhci_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
+ void *buffer, int transfer_len,struct devrequest *setup);
+
+/* fill a td with the approproiate data. Link, status, info and buffer
+ * are used by the USB controller itselfes, dev is used to identify the
+ * "connected" device
+ */
+void usb_fill_td(uhci_td_t* td,unsigned long link,unsigned long status,
+ unsigned long info, unsigned long buffer, unsigned long dev)
+{
+ td->link=swap_32(link);
+ td->status=swap_32(status);
+ td->info=swap_32(info);
+ td->buffer=swap_32(buffer);
+ td->dev_ptr=dev;
+}
+
+/* fill a qh with the approproiate data. Head and element are used by the USB controller
+ * itselfes. As soon as a valid dev_ptr is filled, a td chain is connected to the qh.
+ * Please note, that after completion of the td chain, the entry element is removed /
+ * marked invalid by the USB controller.
+ */
+void usb_fill_qh(uhci_qh_t* qh,unsigned long head,unsigned long element)
+{
+ qh->head=swap_32(head);
+ qh->element=swap_32(element);
+ qh->dev_ptr=0L;
+}
+
+/* get the status of a td->status
+ */
+unsigned long usb_uhci_td_stat(unsigned long status)
+{
+ unsigned long result=0;
+ result |= (status & TD_CTRL_NAK) ? USB_ST_NAK_REC : 0;
+ result |= (status & TD_CTRL_STALLED) ? USB_ST_STALLED : 0;
+ result |= (status & TD_CTRL_DBUFERR) ? USB_ST_BUF_ERR : 0;
+ result |= (status & TD_CTRL_BABBLE) ? USB_ST_BABBLE_DET : 0;
+ result |= (status & TD_CTRL_CRCTIMEO) ? USB_ST_CRC_ERR : 0;
+ result |= (status & TD_CTRL_BITSTUFF) ? USB_ST_BIT_ERR : 0;
+ result |= (status & TD_CTRL_ACTIVE) ? USB_ST_NOT_PROC : 0;
+ return result;
+}
+
+/* get the status and the transfered len of a td chain.
+ * called from the completion handler
+ */
+int usb_get_td_status(uhci_td_t *td,struct usb_device *dev)
+{
+ unsigned long temp,info;
+ unsigned long stat;
+ uhci_td_t *mytd=td;
+
+ if(dev->devnum==rh.devnum)
+ return 0;
+ dev->act_len=0;
+ stat=0;
+ do {
+ temp=swap_32((unsigned long)mytd->status);
+ stat=usb_uhci_td_stat(temp);
+ info=swap_32((unsigned long)mytd->info);
+ if(((info & 0xff)!= USB_PID_SETUP) &&
+ (((info >> 21) & 0x7ff)!= 0x7ff) &&
+ (temp & 0x7FF)!=0x7ff)
+ { /* if not setup and not null data pack */
+ dev->act_len+=(temp & 0x7FF) + 1; /* the transfered len is act_len + 1 */
+ }
+ if(stat) { /* status no ok */
+ dev->status=stat;
+ return -1;
+ }
+ temp=swap_32((unsigned long)mytd->link);
+ mytd=(uhci_td_t *)(temp & 0xfffffff0);
+ }while((temp & 0x1)==0); /* process all TDs */
+ dev->status=stat;
+ return 0; /* Ok */
+}
+
+
+/*-------------------------------------------------------------------
+ * LOW LEVEL STUFF
+ * assembles QHs und TDs for control, bulk and iso
+ *-------------------------------------------------------------------*/
+
+/* Submits a control message. That is a Setup, Data and Status transfer.
+ * Routine does not wait for completion.
+ */
+int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+ int transfer_len,struct devrequest *setup)
+{
+ unsigned long destination, status;
+ int maxsze = usb_maxpacket(dev, pipe);
+ unsigned long dataptr;
+ int len;
+ int pktsze;
+ int i=0;
+
+ if (!maxsze) {
+ USB_UHCI_PRINTF("uhci_submit_control_urb: pipesize for pipe %lx is zero\n", pipe);
+ return -1;
+ }
+ if(((pipe>>8)&0x7f)==rh.devnum) {
+ /* this is the root hub -> redirect it */
+ return uhci_submit_rh_msg(dev,pipe,buffer,transfer_len,setup);
+ }
+ USB_UHCI_PRINTF("uhci_submit_control start len %x, maxsize %x\n",transfer_len,maxsze);
+ /* The "pipe" thing contains the destination in bits 8--18 */
+ destination = (pipe & PIPE_DEVEP_MASK) | USB_PID_SETUP; /* Setup stage */
+ /* 3 errors */
+ status = (pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | (3 << 27);
+ /* (urb->transfer_flags & USB_DISABLE_SPD ? 0 : TD_CTRL_SPD); */
+ /* Build the TD for the control request, try forever, 8 bytes of data */
+ usb_fill_td(&tmp_td[i],UHCI_PTR_TERM ,status, destination | (7 << 21),(unsigned long)setup,(unsigned long)dev);
+#if 0
+ {
+ char *sp=(char *)setup;
+ printf("SETUP to pipe %lx: %x %x %x %x %x %x %x %x\n", pipe,
+ sp[0],sp[1],sp[2],sp[3],sp[4],sp[5],sp[6],sp[7]);
+ }
+#endif
+ dataptr = (unsigned long)buffer;
+ len=transfer_len;
+
+ /* If direction is "send", change the frame from SETUP (0x2D)
+ to OUT (0xE1). Else change it from SETUP to IN (0x69). */
+ destination = (pipe & PIPE_DEVEP_MASK) | ((pipe & USB_DIR_IN)==0 ? USB_PID_OUT : USB_PID_IN);
+ while (len > 0) {
+ /* data stage */
+ pktsze = len;
+ i++;
+ if (pktsze > maxsze)
+ pktsze = maxsze;
+ destination ^= 1 << TD_TOKEN_TOGGLE; /* toggle DATA0/1 */
+ usb_fill_td(&tmp_td[i],UHCI_PTR_TERM, status, destination | ((pktsze - 1) << 21),dataptr,(unsigned long)dev); /* Status, pktsze bytes of data */
+ tmp_td[i-1].link=swap_32((unsigned long)&tmp_td[i]);
+
+ dataptr += pktsze;
+ len -= pktsze;
+ }
+
+ /* Build the final TD for control status */
+ /* It's only IN if the pipe is out AND we aren't expecting data */
+
+ destination &= ~UHCI_PID;
+ if (((pipe & USB_DIR_IN)==0) || (transfer_len == 0))
+ destination |= USB_PID_IN;
+ else
+ destination |= USB_PID_OUT;
+ destination |= 1 << TD_TOKEN_TOGGLE; /* End in Data1 */
+ i++;
+ status &=~TD_CTRL_SPD;
+ /* no limit on errors on final packet , 0 bytes of data */
+ usb_fill_td(&tmp_td[i],UHCI_PTR_TERM, status | TD_CTRL_IOC, destination | (UHCI_NULL_DATA_SIZE << 21),0,(unsigned long)dev);
+ tmp_td[i-1].link=swap_32((unsigned long)&tmp_td[i]); /* queue status td */
+ /* usb_show_td(i+1);*/
+ USB_UHCI_PRINTF("uhci_submit_control end (%d tmp_tds used)\n",i);
+ /* first mark the control QH element terminated */
+ qh_cntrl.element=0xffffffffL;
+ /* set qh active */
+ qh_cntrl.dev_ptr=(unsigned long)dev;
+ /* fill in tmp_td_chain */
+ qh_cntrl.element=swap_32((unsigned long)&tmp_td[0]);
+ return 0;
+}
+
+/*-------------------------------------------------------------------
+ * Prepare TDs for bulk transfers.
+ */
+int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,int transfer_len)
+{
+ unsigned long destination, status,info;
+ unsigned long dataptr;
+ int maxsze = usb_maxpacket(dev, pipe);
+ int len;
+ int i=0;
+
+ if(transfer_len < 0) {
+ printf("Negative transfer length in submit_bulk\n");
+ return -1;
+ }
+ if (!maxsze)
+ return -1;
+ /* The "pipe" thing contains the destination in bits 8--18. */
+ destination = (pipe & PIPE_DEVEP_MASK) | usb_packetid (pipe);
+ /* 3 errors */
+ status = (pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | (3 << 27);
+ /* ((urb->transfer_flags & USB_DISABLE_SPD) ? 0 : TD_CTRL_SPD) | (3 << 27); */
+ /* Build the TDs for the bulk request */
+ len = transfer_len;
+ dataptr = (unsigned long)buffer;
+ do {
+ int pktsze = len;
+ if (pktsze > maxsze)
+ pktsze = maxsze;
+ /* pktsze bytes of data */
+ info = destination | (((pktsze - 1)&UHCI_NULL_DATA_SIZE) << 21) |
+ (usb_gettoggle (dev, usb_pipeendpoint (pipe), usb_pipeout (pipe)) << TD_TOKEN_TOGGLE);
+
+ if((len-pktsze)==0)
+ status |= TD_CTRL_IOC; /* last one generates INT */
+
+ usb_fill_td(&tmp_td[i],UHCI_PTR_TERM, status, info,dataptr,(unsigned long)dev); /* Status, pktsze bytes of data */
+ if(i>0)
+ tmp_td[i-1].link=swap_32((unsigned long)&tmp_td[i]);
+ i++;
+ dataptr += pktsze;
+ len -= pktsze;
+ usb_dotoggle (dev, usb_pipeendpoint (pipe), usb_pipeout (pipe));
+ } while (len > 0);
+ /* first mark the bulk QH element terminated */
+ qh_bulk.element=0xffffffffL;
+ /* set qh active */
+ qh_bulk.dev_ptr=(unsigned long)dev;
+ /* fill in tmp_td_chain */
+ qh_bulk.element=swap_32((unsigned long)&tmp_td[0]);
+ return 0;
+}
+
+
+/* search a free interrupt td
+ */
+uhci_td_t *uhci_alloc_int_td(void)
+{
+ int i;
+ for(i=0;i<USB_MAX_TEMP_INT_TD;i++) {
+ if(tmp_int_td[i].dev_ptr==0) /* no device assigned -> free TD */
+ return &tmp_int_td[i];
+ }
+ return NULL;
+}
+
+#if 0
+void uhci_show_temp_int_td(void)
+{
+ int i;
+ for(i=0;i<USB_MAX_TEMP_INT_TD;i++) {
+ if((tmp_int_td[i].dev_ptr&0x01)!=0x1L) /* no device assigned -> free TD */
+ printf("temp_td %d is assigned to dev %lx\n",i,tmp_int_td[i].dev_ptr);
+ }
+ printf("all others temp_tds are free\n");
+}
+#endif
+/*-------------------------------------------------------------------
+ * submits USB interrupt (ie. polling ;-)
+ */
+int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,int transfer_len, int interval)
+{
+ int nint, n;
+ unsigned long status, destination;
+ unsigned long info,tmp;
+ uhci_td_t *mytd;
+ if (interval < 0 || interval >= 256)
+ return -1;
+
+ if (interval == 0)
+ nint = 0;
+ else {
+ for (nint = 0, n = 1; nint <= 8; nint++, n += n) /* round interval down to 2^n */
+ {
+ if(interval < n) {
+ interval = n / 2;
+ break;
+ }
+ }
+ nint--;
+ }
+
+ USB_UHCI_PRINTF("Rounded interval to %i, chain %i\n", interval, nint);
+ mytd=uhci_alloc_int_td();
+ if(mytd==NULL) {
+ printf("No free INT TDs found\n");
+ return -1;
+ }
+ status = (pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | TD_CTRL_IOC | (3 << 27);
+/* (urb->transfer_flags & USB_DISABLE_SPD ? 0 : TD_CTRL_SPD) | (3 << 27);
+*/
+
+ destination =(pipe & PIPE_DEVEP_MASK) | usb_packetid (pipe) | (((transfer_len - 1) & 0x7ff) << 21);
+
+ info = destination | (usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe)) << TD_TOKEN_TOGGLE);
+ tmp = swap_32(td_int[nint].link);
+ usb_fill_td(mytd,tmp,status, info,(unsigned long)buffer,(unsigned long)dev);
+ /* Link it */
+ tmp = swap_32((unsigned long)mytd);
+ td_int[nint].link=tmp;
+
+ usb_dotoggle (dev, usb_pipeendpoint (pipe), usb_pipeout (pipe));
+
+ return 0;
+}
+
+/**********************************************************************
+ * Low Level functions
+ */
+
+
+void reset_hc(void)
+{
+
+ /* Global reset for 100ms */
+ out16r( usb_base_addr + USBPORTSC1,0x0204);
+ out16r( usb_base_addr + USBPORTSC2,0x0204);
+ out16r( usb_base_addr + USBCMD,USBCMD_GRESET | USBCMD_RS);
+ /* Turn off all interrupts */
+ out16r(usb_base_addr + USBINTR,0);
+ wait_ms(50);
+ out16r( usb_base_addr + USBCMD,0);
+ wait_ms(10);
+}
+
+void start_hc(void)
+{
+ int timeout = 1000;
+
+ while(in16r(usb_base_addr + USBCMD) & USBCMD_HCRESET) {
+ if (!--timeout) {
+ printf("USBCMD_HCRESET timed out!\n");
+ break;
+ }
+ }
+ /* Turn on all interrupts */
+ out16r(usb_base_addr + USBINTR,USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP);
+ /* Start at frame 0 */
+ out16r(usb_base_addr + USBFRNUM,0);
+ /* set Framebuffer base address */
+ out32r(usb_base_addr+USBFLBASEADD,(unsigned long)&framelist);
+ /* Run and mark it configured with a 64-byte max packet */
+ out16r(usb_base_addr + USBCMD,USBCMD_RS | USBCMD_CF | USBCMD_MAXP);
+}
+
+/* Initialize the skeleton
+ */
+void usb_init_skel(void)
+{
+ unsigned long temp;
+ int n;
+
+ for(n=0;n<USB_MAX_TEMP_INT_TD;n++)
+ tmp_int_td[n].dev_ptr=0L; /* no devices connected */
+ /* last td */
+ usb_fill_td(&td_last,UHCI_PTR_TERM,TD_CTRL_IOC ,0,0,0L);
+ /* usb_fill_td(&td_last,UHCI_PTR_TERM,0,0,0); */
+ /* End Queue Header */
+ usb_fill_qh(&qh_end,UHCI_PTR_TERM,(unsigned long)&td_last);
+ /* Bulk Queue Header */
+ temp=(unsigned long)&qh_end;
+ usb_fill_qh(&qh_bulk,temp | UHCI_PTR_QH,UHCI_PTR_TERM);
+ /* Control Queue Header */
+ temp=(unsigned long)&qh_bulk;
+ usb_fill_qh(&qh_cntrl, temp | UHCI_PTR_QH,UHCI_PTR_TERM);
+ /* 1ms Interrupt td */
+ temp=(unsigned long)&qh_cntrl;
+ usb_fill_td(&td_int[0],temp | UHCI_PTR_QH,0,0,0,0L);
+ temp=(unsigned long)&td_int[0];
+ for(n=1; n<8; n++)
+ usb_fill_td(&td_int[n],temp,0,0,0,0L);
+ for (n = 0; n < 1024; n++) {
+ /* link all framelist pointers to one of the interrupts */
+ int m, o;
+ if ((n&127)==127)
+ framelist[n]= swap_32((unsigned long)&td_int[0]);
+ else
+ for (o = 1, m = 2; m <= 128; o++, m += m)
+ if ((n & (m - 1)) == ((m - 1) / 2))
+ framelist[n]= swap_32((unsigned long)&td_int[o]);
+ }
+}
+
+/* check the common skeleton for completed transfers, and update the status
+ * of the "connected" device. Called from the IRQ routine.
+ */
+void usb_check_skel(void)
+{
+ struct usb_device *dev;
+ /* start with the control qh */
+ if(qh_cntrl.dev_ptr!=0) /* it's a device assigned check if this caused IRQ */
+ {
+ dev=(struct usb_device *)qh_cntrl.dev_ptr;
+ usb_get_td_status(&tmp_td[0],dev); /* update status */
+ if(!(dev->status & USB_ST_NOT_PROC)) { /* is not active anymore, disconnect devices */
+ qh_cntrl.dev_ptr=0;
+ }
+ }
+ /* now process the bulk */
+ if(qh_bulk.dev_ptr!=0) /* it's a device assigned check if this caused IRQ */
+ {
+ dev=(struct usb_device *)qh_bulk.dev_ptr;
+ usb_get_td_status(&tmp_td[0],dev); /* update status */
+ if(!(dev->status & USB_ST_NOT_PROC)) { /* is not active anymore, disconnect devices */
+ qh_bulk.dev_ptr=0;
+ }
+ }
+}
+
+/* check the interrupt chain, ubdate the status of the appropriate device,
+ * call the appropriate irqhandler and reactivate the TD if the irqhandler
+ * returns with 1
+ */
+void usb_check_int_chain(void)
+{
+ int i,res;
+ unsigned long link,status;
+ struct usb_device *dev;
+ uhci_td_t *td,*prevtd;
+
+ for(i=0;i<8;i++) {
+ prevtd = &td_int[i]; /* the first previous td is the skeleton td */
+ link=swap_32(td_int[i].link) & 0xfffffff0; /* next in chain */
+ td=(uhci_td_t *)link; /* assign it */
+ /* all interrupt TDs are finally linked to the td_int[0].
+ * so we process all until we find the td_int[0].
+ * if int0 chain points to a QH, we're also done
+ */
+ while(((i>0) && (link != (unsigned long)&td_int[0])) ||
+ ((i==0) && !(swap_32(td->link) & UHCI_PTR_QH)))
+ {
+ /* check if a device is assigned with this td */
+ status=swap_32(td->status);
+ if((td->dev_ptr!=0L) && !(status & TD_CTRL_ACTIVE)) {
+ /* td is not active and a device is assigned -> call irqhandler */
+ dev=(struct usb_device *)td->dev_ptr;
+ dev->irq_act_len=((status & 0x7FF)==0x7FF) ? 0 : (status & 0x7FF) + 1; /* transfered length */
+ dev->irq_status=usb_uhci_td_stat(status); /* get status */
+ res=dev->irq_handle(dev); /* call irqhandler */
+ if(res==1) {
+ /* reactivate */
+ status|=TD_CTRL_ACTIVE;
+ td->status=swap_32(status);
+ prevtd=td; /* previous td = this td */
+ }
+ else {
+ prevtd->link=td->link; /* link previous td directly to the nex td -> unlinked */
+ /* remove device pointer */
+ td->dev_ptr=0L;
+ }
+ } /* if we call the irq handler */
+ link=swap_32(td->link) & 0xfffffff0; /* next in chain */
+ td=(uhci_td_t *)link; /* assign it */
+ } /* process all td in this int chain */
+ } /* next interrupt chain */
+}
+
+
+/* usb interrupt service routine.
+ */
+void handle_usb_interrupt(void)
+{
+ unsigned short status;
+
+ /*
+ * Read the interrupt status, and write it back to clear the
+ * interrupt cause
+ */
+
+ status = in16r(usb_base_addr + USBSTS);
+
+ if (!status) /* shared interrupt, not mine */
+ return;
+ if (status != 1) {
+ /* remove host controller halted state */
+ if ((status&0x20) && ((in16r(usb_base_addr+USBCMD) && USBCMD_RS)==0)) {
+ out16r(usb_base_addr + USBCMD, USBCMD_RS | in16r(usb_base_addr + USBCMD));
+ }
+ }
+ usb_check_int_chain(); /* call interrupt handlers for int tds */
+ usb_check_skel(); /* call completion handler for common transfer routines */
+ out16r(usb_base_addr+USBSTS,status);
+}
+
+
+/* init uhci
+ */
+int usb_lowlevel_init(void)
+{
+ unsigned char temp;
+ int busdevfunc;
+
+ busdevfunc=pci_find_device(USB_UHCI_VEND_ID,USB_UHCI_DEV_ID,0); /* get PCI Device ID */
+ if(busdevfunc==-1) {
+ printf("Error USB UHCI (%04X,%04X) not found\n",USB_UHCI_VEND_ID,USB_UHCI_DEV_ID);
+ return -1;
+ }
+ pci_read_config_byte(busdevfunc,PCI_INTERRUPT_LINE,&temp);
+ irqvec = temp;
+ irq_free_handler(irqvec);
+ USB_UHCI_PRINTF("Interrupt Line = %d, is %d\n",irqvec);
+ pci_read_config_byte(busdevfunc,PCI_INTERRUPT_PIN,&temp);
+ USB_UHCI_PRINTF("Interrupt Pin = %ld\n",temp);
+ pci_read_config_dword(busdevfunc,PCI_BASE_ADDRESS_4,&usb_base_addr);
+ USB_UHCI_PRINTF("IO Base Address = 0x%lx\n",usb_base_addr);
+ usb_base_addr&=0xFFFFFFF0;
+ usb_base_addr+=CONFIG_SYS_ISA_IO_BASE_ADDRESS;
+ rh.devnum = 0;
+ usb_init_skel();
+ reset_hc();
+ start_hc();
+ irq_install_handler(irqvec, (interrupt_handler_t *)handle_usb_interrupt, NULL);
+ return 0;
+}
+
+/* stop uhci
+ */
+int usb_lowlevel_stop(void)
+{
+ if(irqvec==-1)
+ return 1;
+ irq_free_handler(irqvec);
+ reset_hc();
+ irqvec = -1;
+ return 0;
+}
+
+/*******************************************************************************************
+ * Virtual Root Hub
+ * Since the uhci does not have a real HUB, we simulate one ;-)
+ */
+#undef USB_RH_DEBUG
+
+#ifdef USB_RH_DEBUG
+#define USB_RH_PRINTF(fmt,args...) printf (fmt ,##args)
+static void usb_display_wValue(unsigned short wValue,unsigned short wIndex);
+static void usb_display_Req(unsigned short req);
+#else
+#define USB_RH_PRINTF(fmt,args...)
+static void usb_display_wValue(unsigned short wValue,unsigned short wIndex) {}
+static void usb_display_Req(unsigned short req) {}
+#endif
+
+static unsigned char root_hub_dev_des[] =
+{
+ 0x12, /* __u8 bLength; */
+ 0x01, /* __u8 bDescriptorType; Device */
+ 0x00, /* __u16 bcdUSB; v1.0 */
+ 0x01,
+ 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */
+ 0x00, /* __u8 bDeviceSubClass; */
+ 0x00, /* __u8 bDeviceProtocol; */
+ 0x08, /* __u8 bMaxPacketSize0; 8 Bytes */
+ 0x00, /* __u16 idVendor; */
+ 0x00,
+ 0x00, /* __u16 idProduct; */
+ 0x00,
+ 0x00, /* __u16 bcdDevice; */
+ 0x00,
+ 0x01, /* __u8 iManufacturer; */
+ 0x00, /* __u8 iProduct; */
+ 0x00, /* __u8 iSerialNumber; */
+ 0x01 /* __u8 bNumConfigurations; */
+};
+
+
+/* Configuration descriptor */
+static unsigned char root_hub_config_des[] =
+{
+ 0x09, /* __u8 bLength; */
+ 0x02, /* __u8 bDescriptorType; Configuration */
+ 0x19, /* __u16 wTotalLength; */
+ 0x00,
+ 0x01, /* __u8 bNumInterfaces; */
+ 0x01, /* __u8 bConfigurationValue; */
+ 0x00, /* __u8 iConfiguration; */
+ 0x40, /* __u8 bmAttributes;
+ Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */
+ 0x00, /* __u8 MaxPower; */
+
+ /* interface */
+ 0x09, /* __u8 if_bLength; */
+ 0x04, /* __u8 if_bDescriptorType; Interface */
+ 0x00, /* __u8 if_bInterfaceNumber; */
+ 0x00, /* __u8 if_bAlternateSetting; */
+ 0x01, /* __u8 if_bNumEndpoints; */
+ 0x09, /* __u8 if_bInterfaceClass; HUB_CLASSCODE */
+ 0x00, /* __u8 if_bInterfaceSubClass; */
+ 0x00, /* __u8 if_bInterfaceProtocol; */
+ 0x00, /* __u8 if_iInterface; */
+
+ /* endpoint */
+ 0x07, /* __u8 ep_bLength; */
+ 0x05, /* __u8 ep_bDescriptorType; Endpoint */
+ 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */
+ 0x03, /* __u8 ep_bmAttributes; Interrupt */
+ 0x08, /* __u16 ep_wMaxPacketSize; 8 Bytes */
+ 0x00,
+ 0xff /* __u8 ep_bInterval; 255 ms */
+};
+
+
+static unsigned char root_hub_hub_des[] =
+{
+ 0x09, /* __u8 bLength; */
+ 0x29, /* __u8 bDescriptorType; Hub-descriptor */
+ 0x02, /* __u8 bNbrPorts; */
+ 0x00, /* __u16 wHubCharacteristics; */
+ 0x00,
+ 0x01, /* __u8 bPwrOn2pwrGood; 2ms */
+ 0x00, /* __u8 bHubContrCurrent; 0 mA */
+ 0x00, /* __u8 DeviceRemovable; *** 7 Ports max *** */
+ 0xff /* __u8 PortPwrCtrlMask; *** 7 ports max *** */
+};
+
+static unsigned char root_hub_str_index0[] =
+{
+ 0x04, /* __u8 bLength; */
+ 0x03, /* __u8 bDescriptorType; String-descriptor */
+ 0x09, /* __u8 lang ID */
+ 0x04, /* __u8 lang ID */
+};
+
+static unsigned char root_hub_str_index1[] =
+{
+ 28, /* __u8 bLength; */
+ 0x03, /* __u8 bDescriptorType; String-descriptor */
+ 'U', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'H', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'C', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'I', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ ' ', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'R', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'o', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'o', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 't', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ ' ', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'H', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'u', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'b', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+};
+
+
+/*
+ * Root Hub Control Pipe (interrupt Pipes are not supported)
+ */
+
+
+int uhci_submit_rh_msg(struct usb_device *dev, unsigned long pipe, void *buffer,int transfer_len,struct devrequest *cmd)
+{
+ void *data = buffer;
+ int leni = transfer_len;
+ int len = 0;
+ int status = 0;
+ int stat = 0;
+ int i;
+
+ unsigned short cstatus;
+
+ unsigned short bmRType_bReq;
+ unsigned short wValue;
+ unsigned short wIndex;
+ unsigned short wLength;
+
+ if (usb_pipeint(pipe)) {
+ printf("Root-Hub submit IRQ: NOT implemented\n");
+#if 0
+ uhci->rh.urb = urb;
+ uhci->rh.send = 1;
+ uhci->rh.interval = urb->interval;
+ rh_init_int_timer (urb);
+#endif
+ return 0;
+ }
+ bmRType_bReq = cmd->requesttype | cmd->request << 8;
+ wValue = swap_16(cmd->value);
+ wIndex = swap_16(cmd->index);
+ wLength = swap_16(cmd->length);
+ usb_display_Req(bmRType_bReq);
+ for (i = 0; i < 8; i++)
+ rh.c_p_r[i] = 0;
+ USB_RH_PRINTF("Root-Hub: adr: %2x cmd(%1x): %02x%02x %04x %04x %04x\n",
+ dev->devnum, 8, cmd->requesttype,cmd->request, wValue, wIndex, wLength);
+
+ switch (bmRType_bReq) {
+ /* Request Destination:
+ without flags: Device,
+ RH_INTERFACE: interface,
+ RH_ENDPOINT: endpoint,
+ RH_CLASS means HUB here,
+ RH_OTHER | RH_CLASS almost ever means HUB_PORT here
+ */
+
+ case RH_GET_STATUS:
+ *(unsigned short *) data = swap_16(1);
+ len=2;
+ break;
+ case RH_GET_STATUS | RH_INTERFACE:
+ *(unsigned short *) data = swap_16(0);
+ len=2;
+ break;
+ case RH_GET_STATUS | RH_ENDPOINT:
+ *(unsigned short *) data = swap_16(0);
+ len=2;
+ break;
+ case RH_GET_STATUS | RH_CLASS:
+ *(unsigned long *) data = swap_32(0);
+ len=4;
+ break; /* hub power ** */
+ case RH_GET_STATUS | RH_OTHER | RH_CLASS:
+
+ status = in16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1));
+ cstatus = ((status & USBPORTSC_CSC) >> (1 - 0)) |
+ ((status & USBPORTSC_PEC) >> (3 - 1)) |
+ (rh.c_p_r[wIndex - 1] << (0 + 4));
+ status = (status & USBPORTSC_CCS) |
+ ((status & USBPORTSC_PE) >> (2 - 1)) |
+ ((status & USBPORTSC_SUSP) >> (12 - 2)) |
+ ((status & USBPORTSC_PR) >> (9 - 4)) |
+ (1 << 8) | /* power on ** */
+ ((status & USBPORTSC_LSDA) << (-8 + 9));
+
+ *(unsigned short *) data = swap_16(status);
+ *(unsigned short *) (data + 2) = swap_16(cstatus);
+ len=4;
+ break;
+ case RH_CLEAR_FEATURE | RH_ENDPOINT:
+ switch (wValue) {
+ case (RH_ENDPOINT_STALL):
+ len=0;
+ break;
+ }
+ break;
+
+ case RH_CLEAR_FEATURE | RH_CLASS:
+ switch (wValue) {
+ case (RH_C_HUB_OVER_CURRENT):
+ len=0; /* hub power over current ** */
+ break;
+ }
+ break;
+
+ case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
+ usb_display_wValue(wValue,wIndex);
+ switch (wValue) {
+ case (RH_PORT_ENABLE):
+ status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
+ status = (status & 0xfff5) & ~USBPORTSC_PE;
+ out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
+ len=0;
+ break;
+ case (RH_PORT_SUSPEND):
+ status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
+ status = (status & 0xfff5) & ~USBPORTSC_SUSP;
+ out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
+ len=0;
+ break;
+ case (RH_PORT_POWER):
+ len=0; /* port power ** */
+ break;
+ case (RH_C_PORT_CONNECTION):
+ status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
+ status = (status & 0xfff5) | USBPORTSC_CSC;
+ out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
+ len=0;
+ break;
+ case (RH_C_PORT_ENABLE):
+ status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
+ status = (status & 0xfff5) | USBPORTSC_PEC;
+ out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
+ len=0;
+ break;
+ case (RH_C_PORT_SUSPEND):
+/*** WR_RH_PORTSTAT(RH_PS_PSSC); */
+ len=0;
+ break;
+ case (RH_C_PORT_OVER_CURRENT):
+ len=0;
+ break;
+ case (RH_C_PORT_RESET):
+ rh.c_p_r[wIndex - 1] = 0;
+ len=0;
+ break;
+ }
+ break;
+ case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
+ usb_display_wValue(wValue,wIndex);
+ switch (wValue) {
+ case (RH_PORT_SUSPEND):
+ status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
+ status = (status & 0xfff5) | USBPORTSC_SUSP;
+ out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
+ len=0;
+ break;
+ case (RH_PORT_RESET):
+ status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
+ status = (status & 0xfff5) | USBPORTSC_PR;
+ out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
+ wait_ms(10);
+ status = (status & 0xfff5) & ~USBPORTSC_PR;
+ out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
+ udelay(10);
+ status = (status & 0xfff5) | USBPORTSC_PE;
+ out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
+ wait_ms(10);
+ status = (status & 0xfff5) | 0xa;
+ out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
+ len=0;
+ break;
+ case (RH_PORT_POWER):
+ len=0; /* port power ** */
+ break;
+ case (RH_PORT_ENABLE):
+ status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
+ status = (status & 0xfff5) | USBPORTSC_PE;
+ out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
+ len=0;
+ break;
+ }
+ break;
+
+ case RH_SET_ADDRESS:
+ rh.devnum = wValue;
+ len=0;
+ break;
+ case RH_GET_DESCRIPTOR:
+ switch ((wValue & 0xff00) >> 8) {
+ case (0x01): /* device descriptor */
+ i=sizeof(root_hub_config_des);
+ status=i > wLength ? wLength : i;
+ len = leni > status ? status : leni;
+ memcpy (data, root_hub_dev_des, len);
+ break;
+ case (0x02): /* configuration descriptor */
+ i=sizeof(root_hub_config_des);
+ status=i > wLength ? wLength : i;
+ len = leni > status ? status : leni;
+ memcpy (data, root_hub_config_des, len);
+ break;
+ case (0x03): /*string descriptors */
+ if(wValue==0x0300) {
+ i=sizeof(root_hub_str_index0);
+ status = i > wLength ? wLength : i;
+ len = leni > status ? status : leni;
+ memcpy (data, root_hub_str_index0, len);
+ break;
+ }
+ if(wValue==0x0301) {
+ i=sizeof(root_hub_str_index1);
+ status = i > wLength ? wLength : i;
+ len = leni > status ? status : leni;
+ memcpy (data, root_hub_str_index1, len);
+ break;
+ }
+ stat = USB_ST_STALLED;
+ }
+ break;
+
+ case RH_GET_DESCRIPTOR | RH_CLASS:
+ root_hub_hub_des[2] = 2;
+ i=sizeof(root_hub_hub_des);
+ status= i > wLength ? wLength : i;
+ len = leni > status ? status : leni;
+ memcpy (data, root_hub_hub_des, len);
+ break;
+ case RH_GET_CONFIGURATION:
+ *(unsigned char *) data = 0x01;
+ len = 1;
+ break;
+ case RH_SET_CONFIGURATION:
+ len=0;
+ break;
+ default:
+ stat = USB_ST_STALLED;
+ }
+ USB_RH_PRINTF("Root-Hub stat %lx port1: %x port2: %x\n\n",stat,
+ in16r(usb_base_addr + USBPORTSC1), in16r(usb_base_addr + USBPORTSC2));
+ dev->act_len=len;
+ dev->status=stat;
+ return stat;
+
+}
+
+/********************************************************************************
+ * Some Debug Routines
+ */
+
+#ifdef USB_RH_DEBUG
+
+static void usb_display_Req(unsigned short req)
+{
+ USB_RH_PRINTF("- Root-Hub Request: ");
+ switch (req) {
+ case RH_GET_STATUS:
+ USB_RH_PRINTF("Get Status ");
+ break;
+ case RH_GET_STATUS | RH_INTERFACE:
+ USB_RH_PRINTF("Get Status Interface ");
+ break;
+ case RH_GET_STATUS | RH_ENDPOINT:
+ USB_RH_PRINTF("Get Status Endpoint ");
+ break;
+ case RH_GET_STATUS | RH_CLASS:
+ USB_RH_PRINTF("Get Status Class");
+ break; /* hub power ** */
+ case RH_GET_STATUS | RH_OTHER | RH_CLASS:
+ USB_RH_PRINTF("Get Status Class Others");
+ break;
+ case RH_CLEAR_FEATURE | RH_ENDPOINT:
+ USB_RH_PRINTF("Clear Feature Endpoint ");
+ break;
+ case RH_CLEAR_FEATURE | RH_CLASS:
+ USB_RH_PRINTF("Clear Feature Class ");
+ break;
+ case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
+ USB_RH_PRINTF("Clear Feature Other Class ");
+ break;
+ case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
+ USB_RH_PRINTF("Set Feature Other Class ");
+ break;
+ case RH_SET_ADDRESS:
+ USB_RH_PRINTF("Set Address ");
+ break;
+ case RH_GET_DESCRIPTOR:
+ USB_RH_PRINTF("Get Descriptor ");
+ break;
+ case RH_GET_DESCRIPTOR | RH_CLASS:
+ USB_RH_PRINTF("Get Descriptor Class ");
+ break;
+ case RH_GET_CONFIGURATION:
+ USB_RH_PRINTF("Get Configuration ");
+ break;
+ case RH_SET_CONFIGURATION:
+ USB_RH_PRINTF("Get Configuration ");
+ break;
+ default:
+ USB_RH_PRINTF("****UNKNOWN**** 0x%04X ",req);
+ }
+ USB_RH_PRINTF("\n");
+
+}
+
+static void usb_display_wValue(unsigned short wValue,unsigned short wIndex)
+{
+ switch (wValue) {
+ case (RH_PORT_ENABLE):
+ USB_RH_PRINTF("Root-Hub: Enable Port %d\n",wIndex);
+ break;
+ case (RH_PORT_SUSPEND):
+ USB_RH_PRINTF("Root-Hub: Suspend Port %d\n",wIndex);
+ break;
+ case (RH_PORT_POWER):
+ USB_RH_PRINTF("Root-Hub: Port Power %d\n",wIndex);
+ break;
+ case (RH_C_PORT_CONNECTION):
+ USB_RH_PRINTF("Root-Hub: C Port Connection Port %d\n",wIndex);
+ break;
+ case (RH_C_PORT_ENABLE):
+ USB_RH_PRINTF("Root-Hub: C Port Enable Port %d\n",wIndex);
+ break;
+ case (RH_C_PORT_SUSPEND):
+ USB_RH_PRINTF("Root-Hub: C Port Suspend Port %d\n",wIndex);
+ break;
+ case (RH_C_PORT_OVER_CURRENT):
+ USB_RH_PRINTF("Root-Hub: C Port Over Current Port %d\n",wIndex);
+ break;
+ case (RH_C_PORT_RESET):
+ USB_RH_PRINTF("Root-Hub: C Port reset Port %d\n",wIndex);
+ break;
+ default:
+ USB_RH_PRINTF("Root-Hub: unknown %x %x\n",wValue,wIndex);
+ break;
+ }
+}
+
+#endif
+
+
+#ifdef USB_UHCI_DEBUG
+
+static int usb_display_td(uhci_td_t *td)
+{
+ unsigned long tmp;
+ int valid;
+
+ printf("TD at %p:\n",td);
+
+ tmp=swap_32(td->link);
+ printf("Link points to 0x%08lX, %s first, %s, %s\n",tmp&0xfffffff0,
+ ((tmp & 0x4)==0x4) ? "Depth" : "Breath",
+ ((tmp & 0x2)==0x2) ? "QH" : "TD",
+ ((tmp & 0x1)==0x1) ? "invalid" : "valid");
+ valid=((tmp & 0x1)==0x0);
+ tmp=swap_32(td->status);
+ printf(" %s %ld Errors %s %s %s \n %s %s %s %s %s %s\n Len 0x%lX\n",
+ (((tmp>>29)&0x1)==0x1) ? "SPD Enable" : "SPD Disable",
+ ((tmp>>28)&0x3),
+ (((tmp>>26)&0x1)==0x1) ? "Low Speed" : "Full Speed",
+ (((tmp>>25)&0x1)==0x1) ? "ISO " : "",
+ (((tmp>>24)&0x1)==0x1) ? "IOC " : "",
+ (((tmp>>23)&0x1)==0x1) ? "Active " : "Inactive ",
+ (((tmp>>22)&0x1)==0x1) ? "Stalled" : "",
+ (((tmp>>21)&0x1)==0x1) ? "Data Buffer Error" : "",
+ (((tmp>>20)&0x1)==0x1) ? "Babble" : "",
+ (((tmp>>19)&0x1)==0x1) ? "NAK" : "",
+ (((tmp>>18)&0x1)==0x1) ? "Bitstuff Error" : "",
+ (tmp&0x7ff));
+ tmp=swap_32(td->info);
+ printf(" MaxLen 0x%lX\n",((tmp>>21)&0x7FF));
+ printf(" %s Endpoint 0x%lX Dev Addr 0x%lX PID 0x%lX\n",((tmp>>19)&0x1)==0x1 ? "TOGGLE" : "",
+ ((tmp>>15)&0xF),((tmp>>8)&0x7F),tmp&0xFF);
+ tmp=swap_32(td->buffer);
+ printf(" Buffer 0x%08lX\n",tmp);
+ printf(" DEV %08lX\n",td->dev_ptr);
+ return valid;
+}
+
+
+void usb_show_td(int max)
+{
+ int i;
+ if(max>0) {
+ for(i=0;i<max;i++) {
+ usb_display_td(&tmp_td[i]);
+ }
+ }
+ else {
+ i=0;
+ do {
+ printf("tmp_td[%d]\n",i);
+ }while(usb_display_td(&tmp_td[i++]));
+ }
+}
+
+
+#endif
+#endif /* CONFIG_USB_UHCI */
+
+/* EOF */
diff --git a/u-boot/board/mpl/common/usb_uhci.h b/u-boot/board/mpl/common/usb_uhci.h
new file mode 100644
index 0000000..af80837
--- /dev/null
+++ b/u-boot/board/mpl/common/usb_uhci.h
@@ -0,0 +1,188 @@
+/*
+ * (C) Copyright 2001
+ * Denis Peter, MPL AG Switzerland
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * Note: Part of this code has been derived from linux
+ *
+ */
+#ifndef _USB_UHCI_H_
+#define _USB_UHCI_H_
+
+
+/* Command register */
+#define USBCMD 0
+#define USBCMD_RS 0x0001 /* Run/Stop */
+#define USBCMD_HCRESET 0x0002 /* Host reset */
+#define USBCMD_GRESET 0x0004 /* Global reset */
+#define USBCMD_EGSM 0x0008 /* Global Suspend Mode */
+#define USBCMD_FGR 0x0010 /* Force Global Resume */
+#define USBCMD_SWDBG 0x0020 /* SW Debug mode */
+#define USBCMD_CF 0x0040 /* Config Flag (sw only) */
+#define USBCMD_MAXP 0x0080 /* Max Packet (0 = 32, 1 = 64) */
+
+/* Status register */
+#define USBSTS 2
+#define USBSTS_USBINT 0x0001 /* Interrupt due to IOC */
+#define USBSTS_ERROR 0x0002 /* Interrupt due to error */
+#define USBSTS_RD 0x0004 /* Resume Detect */
+#define USBSTS_HSE 0x0008 /* Host System Error - basically PCI problems */
+#define USBSTS_HCPE 0x0010 /* Host Controller Process Error - the scripts were buggy */
+#define USBSTS_HCH 0x0020 /* HC Halted */
+
+/* Interrupt enable register */
+#define USBINTR 4
+#define USBINTR_TIMEOUT 0x0001 /* Timeout/CRC error enable */
+#define USBINTR_RESUME 0x0002 /* Resume interrupt enable */
+#define USBINTR_IOC 0x0004 /* Interrupt On Complete enable */
+#define USBINTR_SP 0x0008 /* Short packet interrupt enable */
+
+#define USBFRNUM 6
+#define USBFLBASEADD 8
+#define USBSOF 12
+
+/* USB port status and control registers */
+#define USBPORTSC1 16
+#define USBPORTSC2 18
+#define USBPORTSC_CCS 0x0001 /* Current Connect Status ("device present") */
+#define USBPORTSC_CSC 0x0002 /* Connect Status Change */
+#define USBPORTSC_PE 0x0004 /* Port Enable */
+#define USBPORTSC_PEC 0x0008 /* Port Enable Change */
+#define USBPORTSC_LS 0x0030 /* Line Status */
+#define USBPORTSC_RD 0x0040 /* Resume Detect */
+#define USBPORTSC_LSDA 0x0100 /* Low Speed Device Attached */
+#define USBPORTSC_PR 0x0200 /* Port Reset */
+#define USBPORTSC_SUSP 0x1000 /* Suspend */
+
+/* Legacy support register */
+#define USBLEGSUP 0xc0
+#define USBLEGSUP_DEFAULT 0x2000 /* only PIRQ enable set */
+
+#define UHCI_NULL_DATA_SIZE 0x7ff /* for UHCI controller TD */
+#define UHCI_PID 0xff /* PID MASK */
+
+#define UHCI_PTR_BITS 0x000F
+#define UHCI_PTR_TERM 0x0001
+#define UHCI_PTR_QH 0x0002
+#define UHCI_PTR_DEPTH 0x0004
+
+/* for TD <status>: */
+#define TD_CTRL_SPD (1 << 29) /* Short Packet Detect */
+#define TD_CTRL_C_ERR_MASK (3 << 27) /* Error Counter bits */
+#define TD_CTRL_LS (1 << 26) /* Low Speed Device */
+#define TD_CTRL_IOS (1 << 25) /* Isochronous Select */
+#define TD_CTRL_IOC (1 << 24) /* Interrupt on Complete */
+#define TD_CTRL_ACTIVE (1 << 23) /* TD Active */
+#define TD_CTRL_STALLED (1 << 22) /* TD Stalled */
+#define TD_CTRL_DBUFERR (1 << 21) /* Data Buffer Error */
+#define TD_CTRL_BABBLE (1 << 20) /* Babble Detected */
+#define TD_CTRL_NAK (1 << 19) /* NAK Received */
+#define TD_CTRL_CRCTIMEO (1 << 18) /* CRC/Time Out Error */
+#define TD_CTRL_BITSTUFF (1 << 17) /* Bit Stuff Error */
+#define TD_CTRL_ACTLEN_MASK 0x7ff /* actual length, encoded as n - 1 */
+
+#define TD_CTRL_ANY_ERROR (TD_CTRL_STALLED | TD_CTRL_DBUFERR | \
+ TD_CTRL_BABBLE | TD_CTRL_CRCTIME | TD_CTRL_BITSTUFF)
+
+#define TD_TOKEN_TOGGLE 19
+
+/* ------------------------------------------------------------------------------------
+ Virtual Root HUB
+ ------------------------------------------------------------------------------------ */
+/* destination of request */
+#define RH_INTERFACE 0x01
+#define RH_ENDPOINT 0x02
+#define RH_OTHER 0x03
+
+#define RH_CLASS 0x20
+#define RH_VENDOR 0x40
+
+/* Requests: bRequest << 8 | bmRequestType */
+#define RH_GET_STATUS 0x0080
+#define RH_CLEAR_FEATURE 0x0100
+#define RH_SET_FEATURE 0x0300
+#define RH_SET_ADDRESS 0x0500
+#define RH_GET_DESCRIPTOR 0x0680
+#define RH_SET_DESCRIPTOR 0x0700
+#define RH_GET_CONFIGURATION 0x0880
+#define RH_SET_CONFIGURATION 0x0900
+#define RH_GET_STATE 0x0280
+#define RH_GET_INTERFACE 0x0A80
+#define RH_SET_INTERFACE 0x0B00
+#define RH_SYNC_FRAME 0x0C80
+/* Our Vendor Specific Request */
+#define RH_SET_EP 0x2000
+
+/* Hub port features */
+#define RH_PORT_CONNECTION 0x00
+#define RH_PORT_ENABLE 0x01
+#define RH_PORT_SUSPEND 0x02
+#define RH_PORT_OVER_CURRENT 0x03
+#define RH_PORT_RESET 0x04
+#define RH_PORT_POWER 0x08
+#define RH_PORT_LOW_SPEED 0x09
+#define RH_C_PORT_CONNECTION 0x10
+#define RH_C_PORT_ENABLE 0x11
+#define RH_C_PORT_SUSPEND 0x12
+#define RH_C_PORT_OVER_CURRENT 0x13
+#define RH_C_PORT_RESET 0x14
+
+/* Hub features */
+#define RH_C_HUB_LOCAL_POWER 0x00
+#define RH_C_HUB_OVER_CURRENT 0x01
+
+#define RH_DEVICE_REMOTE_WAKEUP 0x00
+#define RH_ENDPOINT_STALL 0x01
+
+/* Our Vendor Specific feature */
+#define RH_REMOVE_EP 0x00
+
+
+#define RH_ACK 0x01
+#define RH_REQ_ERR -1
+#define RH_NACK 0x00
+
+
+/* Transfer descriptor structure */
+typedef struct {
+ unsigned long link; /* next td/qh (LE)*/
+ unsigned long status; /* status of the td */
+ unsigned long info; /* Max Lenght / Endpoint / device address and PID */
+ unsigned long buffer; /* pointer to data buffer (LE) */
+ unsigned long dev_ptr; /* pointer to the assigned device (BE) */
+ unsigned long res[3]; /* reserved (TDs must be 8Byte aligned) */
+} uhci_td_t, *puhci_td_t;
+
+/* Queue Header structure */
+typedef struct {
+ unsigned long head; /* Next QH (LE)*/
+ unsigned long element; /* Queue element pointer (LE) */
+ unsigned long res[5]; /* reserved */
+ unsigned long dev_ptr; /* if 0 no tds have been assigned to this qh */
+} uhci_qh_t, *puhci_qh_t;
+
+struct virt_root_hub {
+ int devnum; /* Address of Root Hub endpoint */
+ int numports; /* number of ports */
+ int c_p_r[8]; /* C_PORT_RESET */
+};
+
+
+#endif /* _USB_UHCI_H_ */
diff --git a/u-boot/board/mpl/mip405/Makefile b/u-boot/board/mpl/mip405/Makefile
new file mode 100644
index 0000000..042cd83
--- /dev/null
+++ b/u-boot/board/mpl/mip405/Makefile
@@ -0,0 +1,56 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+ifneq ($(OBJTREE),$(SRCTREE))
+$(shell mkdir -p $(obj)../common)
+endif
+
+LIB = $(obj)lib$(BOARD).o
+
+COBJS = $(BOARD).o ../common/flash.o cmd_mip405.o ../common/pci.o \
+ ../common/usb_uhci.o ../common/common_util.o
+
+SOBJS = init.o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+SOBJS := $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(OBJS) $(SOBJS)
+ $(call cmd_link_o_target, $(OBJS) $(SOBJS))
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak $(obj).depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/u-boot/board/mpl/mip405/cmd_mip405.c b/u-boot/board/mpl/mip405/cmd_mip405.c
new file mode 100644
index 0000000..f7cc37b
--- /dev/null
+++ b/u-boot/board/mpl/mip405/cmd_mip405.c
@@ -0,0 +1,65 @@
+/*
+ * (C) Copyright 2001
+ * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * hacked for MIP405
+ */
+
+#include <common.h>
+#include <command.h>
+#include "mip405.h"
+#include "../common/common_util.h"
+
+
+extern void print_mip405_info(void);
+extern int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+
+
+/* ------------------------------------------------------------------------- */
+
+int do_mip405(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+
+ ulong led_on;
+
+ if (strcmp(argv[1], "info") == 0)
+ {
+ print_mip405_info();
+ return 0;
+ }
+ if (strcmp(argv[1], "led") == 0)
+ {
+ led_on = (ulong)simple_strtoul(argv[2], NULL, 10);
+ user_led0(led_on);
+ return 0;
+ }
+ return (do_mplcommon(cmdtp, flag, argc, argv));
+}
+U_BOOT_CMD(
+ mip405, 8, 1, do_mip405,
+ "MIP405 specific Cmds",
+ "flash mem [SrcAddr] - updates U-Boot with image in memory\n"
+ "mip405 flash mps - updates U-Boot with image from MPS\n"
+ "mip405 info - displays board information\n"
+ "mip405 led <on> - switches LED on (on=1) or off (on=0)"
+);
+
+/* ------------------------------------------------------------------------- */
diff --git a/u-boot/board/mpl/mip405/init.S b/u-boot/board/mpl/mip405/init.S
new file mode 100644
index 0000000..39a1d68
--- /dev/null
+++ b/u-boot/board/mpl/mip405/init.S
@@ -0,0 +1,221 @@
+/*------------------------------------------------------------------------------+
+ * This source code is dual-licensed. You may use it under the terms of
+ * the GNU General Public License version 2, or under the license below.
+ *
+ * This source code has been made available to you by IBM on an AS-IS
+ * basis. Anyone receiving this source is licensed under IBM
+ * copyrights to use it in any way he or she deems fit, including
+ * copying it, modifying it, compiling it, and redistributing it either
+ * with or without modifications. No license under IBM patents or
+ * patent applications is to be implied by the copyright license.
+ *
+ * Any user of this software should understand that IBM cannot provide
+ * technical support for this software and will not be responsible for
+ * any consequences resulting from the use of this software.
+ *
+ * Any person who transfers this source code or any derivative work
+ * must include the IBM copyright notice, this paragraph, and the
+ * preceding two paragraphs in the transferred software.
+ *
+ * COPYRIGHT I B M CORPORATION 1995
+ * LICENSED MATERIAL - PROGRAM PROPERTY OF I B M
+ *-------------------------------------------------------------------------------*/
+
+/*-----------------------------------------------------------------------------
+ * Function: ext_bus_cntlr_init
+ * Description: Initializes the External Bus Controller for the external
+ * peripherals. IMPORTANT: For pass1 this code must run from
+ * cache since you can not reliably change a peripheral banks
+ * timing register (pbxap) while running code from that bank.
+ * For ex., since we are running from ROM on bank 0, we can NOT
+ * execute the code that modifies bank 0 timings from ROM, so
+ * we run it from cache.
+ * Bank 0 - Flash or Multi Purpose Socket
+ * Bank 1 - Multi Purpose Socket or Flash (set in C-Code)
+ * Bank 2 - UART 1 (set in C-Code)
+ * Bank 3 - UART 2 (set in C-Code)
+ * Bank 4 - not used
+ * Bank 5 - not used
+ * Bank 6 - not used
+ * Bank 7 - PLD Register
+ *-----------------------------------------------------------------------------*/
+#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
+
+#include <configs/MIP405.h>
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+#include <asm/cache.h>
+#include <asm/mmu.h>
+#include <asm/ppc4xx.h>
+#include "mip405.h"
+
+
+ .globl ext_bus_cntlr_init
+ext_bus_cntlr_init:
+ mflr r4 /* save link register */
+ mfdcr r3,CPC0_PSR /* get strapping reg */
+ andi. r0, r3, PSR_ROM_LOC /* mask out irrelevant bits */
+ bnelr /* jump back if PCI boot */
+
+ bl ..getAddr
+..getAddr:
+ mflr r3 /* get address of ..getAddr */
+ mtlr r4 /* restore link register */
+ addi r4,0,14 /* set ctr to 14; used to prefetch */
+ mtctr r4 /* 14 cache lines to fit this function */
+ /* in cache (gives us 8x14=112 instrctns) */
+..ebcloop:
+ icbt r0,r3 /* prefetch cache line for addr in r3 */
+ addi r3,r3,32 /* move to next cache line */
+ bdnz ..ebcloop /* continue for 14 cache lines */
+
+ /*-------------------------------------------------------------------
+ * Delay to ensure all accesses to ROM are complete before changing
+ * bank 0 timings.
+ *------------------------------------------------------------------- */
+ addis r3,0,0x0
+ ori r3,r3,0xA000
+ mtctr r3
+..spinlp:
+ bdnz ..spinlp /* spin loop */
+
+ /*-----------------------------------------------------------------------
+ * decide boot up mode
+ *----------------------------------------------------------------------- */
+ addi r4,0,PB0CR
+ mtdcr EBC0_CFGADDR,r4
+ mfdcr r4,EBC0_CFGDATA
+
+ andi. r0, r4, 0x2000 /* mask out irrelevant bits */
+ beq 0f /* jump if 8 bit bus width */
+
+ /* setup 16 bit things
+ *-----------------------------------------------------------------------
+ * Memory Bank 0 (16 Bit Flash) initialization
+ *---------------------------------------------------------------------- */
+
+ addi r4,0,PB1AP
+ mtdcr EBC0_CFGADDR,r4
+ addis r4,0,(FLASH_AP_B)@h
+ ori r4,r4,(FLASH_AP_B)@l
+ mtdcr EBC0_CFGDATA,r4
+
+ addi r4,0,PB0CR
+ mtdcr EBC0_CFGADDR,r4
+ /* BS=0x010(4MB),BU=0x3(R/W), */
+ addis r4,0,(FLASH_CR_B)@h
+ ori r4,r4,(FLASH_CR_B)@l
+ mtdcr EBC0_CFGDATA,r4
+ b 1f
+
+0:
+
+ /* 8Bit boot mode: */
+ /*-----------------------------------------------------------------------
+ * Memory Bank 0 Multi Purpose Socket initialization
+ *----------------------------------------------------------------------- */
+ /* 0x7F8FFE80 slowest boot */
+ addi r4,0,PB1AP
+ mtdcr EBC0_CFGADDR,r4
+ addis r4,0,(MPS_AP_B)@h
+ ori r4,r4,(MPS_AP_B)@l
+ mtdcr EBC0_CFGDATA,r4
+
+ addi r4,0,PB0CR
+ mtdcr EBC0_CFGADDR,r4
+ /* BS=0x010(4MB),BU=0x3(R/W), */
+ addis r4,0,(MPS_CR_B)@h
+ ori r4,r4,(MPS_CR_B)@l
+
+ mtdcr EBC0_CFGDATA,r4
+
+
+1:
+ /*-----------------------------------------------------------------------
+ * Memory Bank 2-3-4-5-6 (not used) initialization
+ *-----------------------------------------------------------------------*/
+ addi r4,0,PB1CR
+ mtdcr EBC0_CFGADDR,r4
+ addis r4,0,0x0000
+ ori r4,r4,0x0000
+ mtdcr EBC0_CFGDATA,r4
+
+ addi r4,0,PB2CR
+ mtdcr EBC0_CFGADDR,r4
+ addis r4,0,0x0000
+ ori r4,r4,0x0000
+ mtdcr EBC0_CFGDATA,r4
+
+ addi r4,0,PB3CR
+ mtdcr EBC0_CFGADDR,r4
+ addis r4,0,0x0000
+ ori r4,r4,0x0000
+ mtdcr EBC0_CFGDATA,r4
+
+ addi r4,0,PB4CR
+ mtdcr EBC0_CFGADDR,r4
+ addis r4,0,0x0000
+ ori r4,r4,0x0000
+ mtdcr EBC0_CFGDATA,r4
+
+ addi r4,0,PB5CR
+ mtdcr EBC0_CFGADDR,r4
+ addis r4,0,0x0000
+ ori r4,r4,0x0000
+ mtdcr EBC0_CFGDATA,r4
+
+ addi r4,0,PB6CR
+ mtdcr EBC0_CFGADDR,r4
+ addis r4,0,0x0000
+ ori r4,r4,0x0000
+ mtdcr EBC0_CFGDATA,r4
+
+ addi r4,0,PB7CR
+ mtdcr EBC0_CFGADDR,r4
+ addis r4,0,0x0000
+ ori r4,r4,0x0000
+ mtdcr EBC0_CFGDATA,r4
+ nop /* pass2 DCR errata #8 */
+ blr
+
+#if defined(CONFIG_BOOT_PCI)
+ .section .bootpg,"ax"
+ .globl _start_pci
+/*******************************************
+ */
+
+_start_pci:
+ /* first handle errata #68 / PCI_18 */
+ iccci r0, r0 /* invalidate I-cache */
+ lis r31, 0
+ mticcr r31 /* ICCR = 0 (all uncachable) */
+ isync
+
+ mfccr0 r28 /* set CCR0[24] = 1 */
+ ori r28, r28, 0x0080
+ mtccr0 r28
+
+ /* setup PMM0MA (0xEF400004) and PMM0PCIHA (0xEF40000C) */
+ lis r28, 0xEF40
+ addi r28, r28, 0x0004
+ stw r31, 0x0C(r28) /* clear PMM0PCIHA */
+ lis r29, 0xFFF8 /* open 512 kByte */
+ addi r29, r29, 0x0001/* and enable this region */
+ stwbrx r29, r0, r28 /* write PMM0MA */
+
+ lis r28, 0xEEC0 /* address of PCIC0_CFGADDR */
+ addi r29, r28, 4 /* add 4 to r29 -> PCIC0_CFGDATA */
+
+ lis r31, 0x8000 /* set en bit bus 0 */
+ ori r31, r31, 0x304C/* device 6 func 0 reg 4C (XBCS register) */
+ stwbrx r31, r0, r28 /* write it */
+
+ lwbrx r31, r0, r29 /* load XBCS register */
+ oris r31, r31, 0x02C4/* clear BIOSCS WPE, set lower, extended and 1M extended BIOS enable */
+ stwbrx r31, r0, r29 /* write back XBCS register */
+
+ nop
+ nop
+ b _start /* normal start */
+#endif
diff --git a/u-boot/board/mpl/mip405/mip405.c b/u-boot/board/mpl/mip405/mip405.c
new file mode 100644
index 0000000..e93d994
--- /dev/null
+++ b/u-boot/board/mpl/mip405/mip405.c
@@ -0,0 +1,805 @@
+/*
+ * (C) Copyright 2001
+ * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * TODO: clean-up
+ */
+
+/*
+ * How do I program the SDRAM Timing Register (SDRAM0_TR) for a specific SDRAM or DIMM?
+ *
+ * As an example, consider a case where PC133 memory with CAS Latency equal to 2 is being
+ * used with a 200MHz 405GP. For a typical 128Mb, PC133 SDRAM, the relevant minimum
+ * parameters from the datasheet are:
+ * Tclk = 7.5ns (CL = 2)
+ * Trp = 15ns
+ * Trc = 60ns
+ * Trcd = 15ns
+ * Trfc = 66ns
+ *
+ * If we are operating the 405GP with the MemClk output frequency set to 100 MHZ, the clock
+ * period is 10ns and the parameters needed for the Timing Register are:
+ * CASL = CL = 2 clock cycles
+ * PTA = Trp = 15ns / 10ns = 2 clock cycles
+ * CTP = Trc - Trcd - Trp = (60ns - 15ns - 15ns) / 10ns= 3 clock cycles
+ * LDF = 2 clock cycles (but can be extended to meet board-level timing)
+ * RFTA = Trfc = 66ns / 10ns= 7 clock cycles
+ * RCD = Trcd = 15ns / 10ns= 2 clock cycles
+ *
+ * The actual bit settings in the register would be:
+ *
+ * CASL = 0b01
+ * PTA = 0b01
+ * CTP = 0b10
+ * LDF = 0b01
+ * RFTA = 0b011
+ * RCD = 0b01
+ *
+ * If Trfc is not specified in the datasheet for PC100 or PC133 memory, set RFTA = Trc
+ * instead. Figure 24 in the PC SDRAM Specification Rev. 1.7 shows refresh to active delay
+ * defined as Trc rather than Trfc.
+ * When using DIMM modules, most but not all of the required timing parameters can be read
+ * from the Serial Presence Detect (SPD) EEPROM on the module. Specifically, Trc and Trfc
+ * are not available from the EEPROM
+ */
+
+#include <common.h>
+#include "mip405.h"
+#include <asm/processor.h>
+#include <asm/ppc4xx.h>
+#include <asm/ppc4xx-i2c.h>
+#include <miiphy.h>
+#include "../common/common_util.h"
+#include <stdio_dev.h>
+#include <i2c.h>
+#include <rtc.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#undef SDRAM_DEBUG
+#define ENABLE_ECC /* for ecc boards */
+#define FALSE 0
+#define TRUE 1
+
+/* stdlib.h causes some compatibility problems; should fixe these! -- wd */
+#ifndef __ldiv_t_defined
+typedef struct {
+ long int quot; /* Quotient */
+ long int rem; /* Remainder */
+} ldiv_t;
+extern ldiv_t ldiv (long int __numer, long int __denom);
+# define __ldiv_t_defined 1
+#endif
+
+
+#define PLD_PART_REG PER_PLD_ADDR + 0
+#define PLD_VERS_REG PER_PLD_ADDR + 1
+#define PLD_BOARD_CFG_REG PER_PLD_ADDR + 2
+#define PLD_IRQ_REG PER_PLD_ADDR + 3
+#define PLD_COM_MODE_REG PER_PLD_ADDR + 4
+#define PLD_EXT_CONF_REG PER_PLD_ADDR + 5
+
+#define MEGA_BYTE (1024*1024)
+
+typedef struct {
+ unsigned char boardtype; /* Board revision and Population Options */
+ unsigned char cal; /* cas Latency (will be programmend as cal-1) */
+ unsigned char trp; /* datain27 in clocks */
+ unsigned char trcd; /* datain29 in clocks */
+ unsigned char tras; /* datain30 in clocks */
+ unsigned char tctp; /* tras - trcd in clocks */
+ unsigned char am; /* Address Mod (will be programmed as am-1) */
+ unsigned char sz; /* log binary => Size = (4MByte<<sz) 5 = 128, 4 = 64, 3 = 32, 2 = 16, 1=8 */
+ unsigned char ecc; /* if true, ecc is enabled */
+} sdram_t;
+#if defined(CONFIG_MIP405T)
+const sdram_t sdram_table[] = {
+ { 0x0F, /* MIP405T Rev A, 64MByte -1 Board */
+ 3, /* Case Latenty = 3 */
+ 3, /* trp 20ns / 7.5 ns datain[27] */
+ 3, /* trcd 20ns /7.5 ns (datain[29]) */
+ 6, /* tras 44ns /7.5 ns (datain[30]) */
+ 4, /* tcpt 44 - 20ns = 24ns */
+ 2, /* Address Mode = 2 (12x9x4) */
+ 3, /* size value (32MByte) */
+ 0}, /* ECC disabled */
+ { 0xff, /* terminator */
+ 0xff,
+ 0xff,
+ 0xff,
+ 0xff,
+ 0xff,
+ 0xff,
+ 0xff }
+};
+#else
+const sdram_t sdram_table[] = {
+ { 0x0f, /* Rev A, 128MByte -1 Board */
+ 3, /* Case Latenty = 3 */
+ 3, /* trp 20ns / 7.5 ns datain[27] */
+ 3, /* trcd 20ns /7.5 ns (datain[29]) */
+ 6, /* tras 44ns /7.5 ns (datain[30]) */
+ 4, /* tcpt 44 - 20ns = 24ns */
+ 3, /* Address Mode = 3 */
+ 5, /* size value */
+ 1}, /* ECC enabled */
+ { 0x07, /* Rev A, 64MByte -2 Board */
+ 3, /* Case Latenty = 3 */
+ 3, /* trp 20ns / 7.5 ns datain[27] */
+ 3, /* trcd 20ns /7.5 ns (datain[29]) */
+ 6, /* tras 44ns /7.5 ns (datain[30]) */
+ 4, /* tcpt 44 - 20ns = 24ns */
+ 2, /* Address Mode = 2 */
+ 4, /* size value */
+ 1}, /* ECC enabled */
+ { 0x03, /* Rev A, 128MByte -4 Board */
+ 3, /* Case Latenty = 3 */
+ 3, /* trp 20ns / 7.5 ns datain[27] */
+ 3, /* trcd 20ns /7.5 ns (datain[29]) */
+ 6, /* tras 44ns /7.5 ns (datain[30]) */
+ 4, /* tcpt 44 - 20ns = 24ns */
+ 3, /* Address Mode = 3 */
+ 5, /* size value */
+ 1}, /* ECC enabled */
+ { 0x1f, /* Rev B, 128MByte -3 Board */
+ 3, /* Case Latenty = 3 */
+ 3, /* trp 20ns / 7.5 ns datain[27] */
+ 3, /* trcd 20ns /7.5 ns (datain[29]) */
+ 6, /* tras 44ns /7.5 ns (datain[30]) */
+ 4, /* tcpt 44 - 20ns = 24ns */
+ 3, /* Address Mode = 3 */
+ 5, /* size value */
+ 1}, /* ECC enabled */
+ { 0x2f, /* Rev C, 128MByte -3 Board */
+ 3, /* Case Latenty = 3 */
+ 3, /* trp 20ns / 7.5 ns datain[27] */
+ 3, /* trcd 20ns /7.5 ns (datain[29]) */
+ 6, /* tras 44ns /7.5 ns (datain[30]) */
+ 4, /* tcpt 44 - 20ns = 24ns */
+ 3, /* Address Mode = 3 */
+ 5, /* size value */
+ 1}, /* ECC enabled */
+ { 0xff, /* terminator */
+ 0xff,
+ 0xff,
+ 0xff,
+ 0xff,
+ 0xff,
+ 0xff,
+ 0xff }
+};
+#endif /*CONFIG_MIP405T */
+void SDRAM_err (const char *s)
+{
+#ifndef SDRAM_DEBUG
+ (void) get_clocks ();
+ gd->baudrate = 9600;
+ serial_init ();
+#endif
+ serial_puts ("\n");
+ serial_puts (s);
+ serial_puts ("\n enable SDRAM_DEBUG for more info\n");
+ for (;;);
+}
+
+
+unsigned char get_board_revcfg (void)
+{
+ out8 (PER_BOARD_ADDR, 0);
+ return (in8 (PER_BOARD_ADDR));
+}
+
+
+#ifdef SDRAM_DEBUG
+
+void write_hex (unsigned char i)
+{
+ char cc;
+
+ cc = i >> 4;
+ cc &= 0xf;
+ if (cc > 9)
+ serial_putc (cc + 55);
+ else
+ serial_putc (cc + 48);
+ cc = i & 0xf;
+ if (cc > 9)
+ serial_putc (cc + 55);
+ else
+ serial_putc (cc + 48);
+}
+
+void write_4hex (unsigned long val)
+{
+ write_hex ((unsigned char) (val >> 24));
+ write_hex ((unsigned char) (val >> 16));
+ write_hex ((unsigned char) (val >> 8));
+ write_hex ((unsigned char) val);
+}
+
+#endif
+
+
+int init_sdram (void)
+{
+ unsigned long tmp, baseaddr;
+ unsigned short i;
+ unsigned char trp_clocks,
+ trcd_clocks,
+ tras_clocks,
+ trc_clocks,
+ tctp_clocks;
+ unsigned char cal_val;
+ unsigned char bc;
+ unsigned long sdram_tim, sdram_bank;
+
+ /*i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);*/
+ (void) get_clocks ();
+ gd->baudrate = 9600;
+ serial_init ();
+ /* set up the pld */
+ mtdcr (EBC0_CFGADDR, PB7AP);
+ mtdcr (EBC0_CFGDATA, PLD_AP);
+ mtdcr (EBC0_CFGADDR, PB7CR);
+ mtdcr (EBC0_CFGDATA, PLD_CR);
+ /* THIS IS OBSOLETE */
+ /* set up the board rev reg*/
+ mtdcr (EBC0_CFGADDR, PB5AP);
+ mtdcr (EBC0_CFGDATA, BOARD_AP);
+ mtdcr (EBC0_CFGADDR, PB5CR);
+ mtdcr (EBC0_CFGDATA, BOARD_CR);
+#ifdef SDRAM_DEBUG
+ /* get all informations from PLD */
+ serial_puts ("\nPLD Part 0x");
+ bc = in8 (PLD_PART_REG);
+ write_hex (bc);
+ serial_puts ("\nPLD Vers 0x");
+ bc = in8 (PLD_VERS_REG);
+ write_hex (bc);
+ serial_puts ("\nBoard Rev 0x");
+ bc = in8 (PLD_BOARD_CFG_REG);
+ write_hex (bc);
+ serial_puts ("\n");
+#endif
+ /* check board */
+ bc = in8 (PLD_PART_REG);
+#if defined(CONFIG_MIP405T)
+ if((bc & 0x80)==0)
+ SDRAM_err ("U-Boot configured for a MIP405T not for a MIP405!!!\n");
+#else
+ if((bc & 0x80)==0x80)
+ SDRAM_err ("U-Boot configured for a MIP405 not for a MIP405T!!!\n");
+#endif
+ /* set-up the chipselect machine */
+ mtdcr (EBC0_CFGADDR, PB0CR); /* get cs0 config reg */
+ tmp = mfdcr (EBC0_CFGDATA);
+ if ((tmp & 0x00002000) == 0) {
+ /* MPS Boot, set up the flash */
+ mtdcr (EBC0_CFGADDR, PB1AP);
+ mtdcr (EBC0_CFGDATA, FLASH_AP);
+ mtdcr (EBC0_CFGADDR, PB1CR);
+ mtdcr (EBC0_CFGDATA, FLASH_CR);
+ } else {
+ /* Flash boot, set up the MPS */
+ mtdcr (EBC0_CFGADDR, PB1AP);
+ mtdcr (EBC0_CFGDATA, MPS_AP);
+ mtdcr (EBC0_CFGADDR, PB1CR);
+ mtdcr (EBC0_CFGDATA, MPS_CR);
+ }
+ /* set up UART0 (CS2) and UART1 (CS3) */
+ mtdcr (EBC0_CFGADDR, PB2AP);
+ mtdcr (EBC0_CFGDATA, UART0_AP);
+ mtdcr (EBC0_CFGADDR, PB2CR);
+ mtdcr (EBC0_CFGDATA, UART0_CR);
+ mtdcr (EBC0_CFGADDR, PB3AP);
+ mtdcr (EBC0_CFGDATA, UART1_AP);
+ mtdcr (EBC0_CFGADDR, PB3CR);
+ mtdcr (EBC0_CFGDATA, UART1_CR);
+ bc = in8 (PLD_BOARD_CFG_REG);
+#ifdef SDRAM_DEBUG
+ serial_puts ("\nstart SDRAM Setup\n");
+ serial_puts ("\nBoard Rev: ");
+ write_hex (bc);
+ serial_puts ("\n");
+#endif
+ i = 0;
+ baseaddr = CONFIG_SYS_SDRAM_BASE;
+ while (sdram_table[i].sz != 0xff) {
+ if (sdram_table[i].boardtype == bc)
+ break;
+ i++;
+ }
+ if (sdram_table[i].boardtype != bc)
+ SDRAM_err ("No SDRAM table found for this board!!!\n");
+#ifdef SDRAM_DEBUG
+ serial_puts (" found table ");
+ write_hex (i);
+ serial_puts (" \n");
+#endif
+ /* since the ECC initialisation needs some time,
+ * we show that we're alive
+ */
+ if (sdram_table[i].ecc)
+ serial_puts ("\nInitializing SDRAM, Please stand by");
+ cal_val = sdram_table[i].cal - 1; /* Cas Latency */
+ trp_clocks = sdram_table[i].trp; /* 20ns / 7.5 ns datain[27] */
+ trcd_clocks = sdram_table[i].trcd; /* 20ns /7.5 ns (datain[29]) */
+ tras_clocks = sdram_table[i].tras; /* 44ns /7.5 ns (datain[30]) */
+ /* ctp = ((trp + tras) - trp - trcd) => tras - trcd */
+ tctp_clocks = sdram_table[i].tctp; /* 44 - 20ns = 24ns */
+ /* trc_clocks is sum of trp_clocks + tras_clocks */
+ trc_clocks = trp_clocks + tras_clocks;
+ /* get SDRAM timing register */
+ mtdcr (SDRAM0_CFGADDR, SDRAM0_TR);
+ sdram_tim = mfdcr (SDRAM0_CFGDATA) & ~0x018FC01F;
+ /* insert CASL value */
+ sdram_tim |= ((unsigned long) (cal_val)) << 23;
+ /* insert PTA value */
+ sdram_tim |= ((unsigned long) (trp_clocks - 1)) << 18;
+ /* insert CTP value */
+ sdram_tim |=
+ ((unsigned long) (trc_clocks - trp_clocks -
+ trcd_clocks)) << 16;
+ /* insert LDF (always 01) */
+ sdram_tim |= ((unsigned long) 0x01) << 14;
+ /* insert RFTA value */
+ sdram_tim |= ((unsigned long) (trc_clocks - 4)) << 2;
+ /* insert RCD value */
+ sdram_tim |= ((unsigned long) (trcd_clocks - 1)) << 0;
+
+ tmp = ((unsigned long) (sdram_table[i].am - 1) << 13); /* AM = 3 */
+ /* insert SZ value; */
+ tmp |= ((unsigned long) sdram_table[i].sz << 17);
+ /* get SDRAM bank 0 register */
+ mtdcr (SDRAM0_CFGADDR, SDRAM0_B0CR);
+ sdram_bank = mfdcr (SDRAM0_CFGDATA) & ~0xFFCEE001;
+ sdram_bank |= (baseaddr | tmp | 0x01);
+
+#ifdef SDRAM_DEBUG
+ serial_puts ("sdtr: ");
+ write_4hex (sdram_tim);
+ serial_puts ("\n");
+#endif
+
+ /* write SDRAM timing register */
+ mtdcr (SDRAM0_CFGADDR, SDRAM0_TR);
+ mtdcr (SDRAM0_CFGDATA, sdram_tim);
+
+#ifdef SDRAM_DEBUG
+ serial_puts ("mb0cf: ");
+ write_4hex (sdram_bank);
+ serial_puts ("\n");
+#endif
+
+ /* write SDRAM bank 0 register */
+ mtdcr (SDRAM0_CFGADDR, SDRAM0_B0CR);
+ mtdcr (SDRAM0_CFGDATA, sdram_bank);
+
+ if (get_bus_freq (tmp) > 110000000) { /* > 110MHz */
+ /* get SDRAM refresh interval register */
+ mtdcr (SDRAM0_CFGADDR, SDRAM0_RTR);
+ tmp = mfdcr (SDRAM0_CFGDATA) & ~0x3FF80000;
+ tmp |= 0x07F00000;
+ } else {
+ /* get SDRAM refresh interval register */
+ mtdcr (SDRAM0_CFGADDR, SDRAM0_RTR);
+ tmp = mfdcr (SDRAM0_CFGDATA) & ~0x3FF80000;
+ tmp |= 0x05F00000;
+ }
+ /* write SDRAM refresh interval register */
+ mtdcr (SDRAM0_CFGADDR, SDRAM0_RTR);
+ mtdcr (SDRAM0_CFGDATA, tmp);
+ /* enable ECC if used */
+#if defined(ENABLE_ECC) && !defined(CONFIG_BOOT_PCI)
+ if (sdram_table[i].ecc) {
+ /* disable checking for all banks */
+ unsigned long *p;
+#ifdef SDRAM_DEBUG
+ serial_puts ("disable ECC.. ");
+#endif
+ mtdcr (SDRAM0_CFGADDR, SDRAM0_ECCCFG);
+ tmp = mfdcr (SDRAM0_CFGDATA);
+ tmp &= 0xff0fffff; /* disable all banks */
+ mtdcr (SDRAM0_CFGADDR, SDRAM0_ECCCFG);
+ /* set up SDRAM Controller with ECC enabled */
+#ifdef SDRAM_DEBUG
+ serial_puts ("setup SDRAM Controller.. ");
+#endif
+ mtdcr (SDRAM0_CFGDATA, tmp);
+ mtdcr (SDRAM0_CFGADDR, SDRAM0_CFG);
+ tmp = (mfdcr (SDRAM0_CFGDATA) & ~0xFFE00000) | 0x90800000;
+ mtdcr (SDRAM0_CFGADDR, SDRAM0_CFG);
+ mtdcr (SDRAM0_CFGDATA, tmp);
+ udelay (600);
+#ifdef SDRAM_DEBUG
+ serial_puts ("fill the memory..\n");
+#endif
+ serial_puts (".");
+ /* now, fill all the memory */
+ tmp = ((4 * MEGA_BYTE) << sdram_table[i].sz);
+ p = (unsigned long) 0;
+ while ((unsigned long) p < tmp) {
+ *p++ = 0L;
+ if (!((unsigned long) p % 0x00800000)) /* every 8MByte */
+ serial_puts (".");
+ }
+ /* enable bank 0 */
+ serial_puts (".");
+#ifdef SDRAM_DEBUG
+ serial_puts ("enable ECC\n");
+#endif
+ udelay (400);
+ mtdcr (SDRAM0_CFGADDR, SDRAM0_ECCCFG);
+ tmp = mfdcr (SDRAM0_CFGDATA);
+ tmp |= 0x00800000; /* enable bank 0 */
+ mtdcr (SDRAM0_CFGDATA, tmp);
+ udelay (400);
+ } else
+#endif
+ {
+ /* enable SDRAM controller with no ECC, 32-bit SDRAM width, 16 byte burst */
+ mtdcr (SDRAM0_CFGADDR, SDRAM0_CFG);
+ tmp = (mfdcr (SDRAM0_CFGDATA) & ~0xFFE00000) | 0x80C00000;
+ mtdcr (SDRAM0_CFGADDR, SDRAM0_CFG);
+ mtdcr (SDRAM0_CFGDATA, tmp);
+ udelay (400);
+ }
+ serial_puts ("\n");
+ return (0);
+}
+
+int board_early_init_f (void)
+{
+ init_sdram ();
+
+ /*-------------------------------------------------------------------------+
+ | Interrupt controller setup for the PIP405 board.
+ | Note: IRQ 0-15 405GP internally generated; active high; level sensitive
+ | IRQ 16 405GP internally generated; active low; level sensitive
+ | IRQ 17-24 RESERVED
+ | IRQ 25 (EXT IRQ 0) SouthBridge; active low; level sensitive
+ | IRQ 26 (EXT IRQ 1) NMI: active low; level sensitive
+ | IRQ 27 (EXT IRQ 2) SMI: active Low; level sensitive
+ | IRQ 28 (EXT IRQ 3) PCI SLOT 3; active low; level sensitive
+ | IRQ 29 (EXT IRQ 4) PCI SLOT 2; active low; level sensitive
+ | IRQ 30 (EXT IRQ 5) PCI SLOT 1; active low; level sensitive
+ | IRQ 31 (EXT IRQ 6) PCI SLOT 0; active low; level sensitive
+ | Note for MIP405 board:
+ | An interrupt taken for the SouthBridge (IRQ 25) indicates that
+ | the Interrupt Controller in the South Bridge has caused the
+ | interrupt. The IC must be read to determine which device
+ | caused the interrupt.
+ |
+ +-------------------------------------------------------------------------*/
+ mtdcr (UIC0SR, 0xFFFFFFFF); /* clear all ints */
+ mtdcr (UIC0ER, 0x00000000); /* disable all ints */
+ mtdcr (UIC0CR, 0x00000000); /* set all to be non-critical (for now) */
+ mtdcr (UIC0PR, 0xFFFFFF80); /* set int polarities */
+ mtdcr (UIC0TR, 0x10000000); /* set int trigger levels */
+ mtdcr (UIC0VCR, 0x00000001); /* set vect base=0,INT0 highest priority */
+ mtdcr (UIC0SR, 0xFFFFFFFF); /* clear all ints */
+ return 0;
+}
+
+
+/*
+ * Get some PLD Registers
+ */
+
+unsigned short get_pld_parvers (void)
+{
+ unsigned short result;
+ unsigned char rc;
+
+ rc = in8 (PLD_PART_REG);
+ result = (unsigned short) rc << 8;
+ rc = in8 (PLD_VERS_REG);
+ result |= rc;
+ return result;
+}
+
+
+void user_led0 (unsigned char on)
+{
+ if (on)
+ out8 (PLD_COM_MODE_REG, (in8 (PLD_COM_MODE_REG) | 0x4));
+ else
+ out8 (PLD_COM_MODE_REG, (in8 (PLD_COM_MODE_REG) & 0xfb));
+}
+
+
+void ide_set_reset (int idereset)
+{
+ /* if reset = 1 IDE reset will be asserted */
+ if (idereset)
+ out8 (PLD_COM_MODE_REG, (in8 (PLD_COM_MODE_REG) | 0x1));
+ else {
+ udelay (10000);
+ out8 (PLD_COM_MODE_REG, (in8 (PLD_COM_MODE_REG) & 0xfe));
+ }
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+void get_pcbrev_var(unsigned char *pcbrev, unsigned char *var)
+{
+#if !defined(CONFIG_MIP405T)
+ unsigned char bc,rc,tmp;
+ int i;
+
+ bc = in8 (PLD_BOARD_CFG_REG);
+ tmp = ~bc;
+ tmp &= 0xf;
+ rc = 0;
+ for (i = 0; i < 4; i++) {
+ rc <<= 1;
+ rc += (tmp & 0x1);
+ tmp >>= 1;
+ }
+ rc++;
+ if(( (((bc>>4) & 0xf)==0x2) /* Rev C PCB or */
+ || (((bc>>4) & 0xf)==0x1)) /* Rev B PCB with */
+ && (rc==0x1)) /* Population Option 1 is a -3 */
+ rc=3;
+ *pcbrev=(bc >> 4) & 0xf;
+ *var=rc;
+#else
+ unsigned char bc;
+ bc = in8 (PLD_BOARD_CFG_REG);
+ *pcbrev=(bc >> 4) & 0xf;
+ *var=16-(bc & 0xf);
+#endif
+}
+
+/*
+ * Check Board Identity:
+ */
+/* serial String: "MIP405_1000" OR "MIP405T_1000" */
+#if !defined(CONFIG_MIP405T)
+#define BOARD_NAME "MIP405"
+#else
+#define BOARD_NAME "MIP405T"
+#endif
+
+int checkboard (void)
+{
+ char s[50];
+ unsigned char bc, var;
+ int i;
+ backup_t *b = (backup_t *) s;
+
+ puts ("Board: ");
+ get_pcbrev_var(&bc,&var);
+ i = getenv_f("serial#", (char *)s, 32);
+ if ((i == 0) || strncmp ((char *)s, BOARD_NAME,sizeof(BOARD_NAME))) {
+ get_backup_values (b);
+ if (strncmp (b->signature, "MPL\0", 4) != 0) {
+ puts ("### No HW ID - assuming " BOARD_NAME);
+ printf ("-%d Rev %c", var, 'A' + bc);
+ } else {
+ b->serial_name[sizeof(BOARD_NAME)-1] = 0;
+ printf ("%s-%d Rev %c SN: %s", b->serial_name, var,
+ 'A' + bc, &b->serial_name[sizeof(BOARD_NAME)]);
+ }
+ } else {
+ s[sizeof(BOARD_NAME)-1] = 0;
+ printf ("%s-%d Rev %c SN: %s", s, var,'A' + bc,
+ &s[sizeof(BOARD_NAME)]);
+ }
+ bc = in8 (PLD_EXT_CONF_REG);
+ printf (" Boot Config: 0x%x\n", bc);
+ return (0);
+}
+
+
+/* ------------------------------------------------------------------------- */
+/* ------------------------------------------------------------------------- */
+/*
+ initdram(int board_type) reads EEPROM via I2c. EEPROM contains all of
+ the necessary info for SDRAM controller configuration
+*/
+/* ------------------------------------------------------------------------- */
+/* ------------------------------------------------------------------------- */
+static int test_dram (unsigned long ramsize);
+
+phys_size_t initdram (int board_type)
+{
+
+ unsigned long bank_reg[4], tmp, bank_size;
+ int i, ds;
+ unsigned long TotalSize;
+
+ ds = 0;
+ /* since the DRAM controller is allready set up, calculate the size with the
+ bank registers */
+ mtdcr (SDRAM0_CFGADDR, SDRAM0_B0CR);
+ bank_reg[0] = mfdcr (SDRAM0_CFGDATA);
+ mtdcr (SDRAM0_CFGADDR, SDRAM0_B1CR);
+ bank_reg[1] = mfdcr (SDRAM0_CFGDATA);
+ mtdcr (SDRAM0_CFGADDR, SDRAM0_B2CR);
+ bank_reg[2] = mfdcr (SDRAM0_CFGDATA);
+ mtdcr (SDRAM0_CFGADDR, SDRAM0_B3CR);
+ bank_reg[3] = mfdcr (SDRAM0_CFGDATA);
+ TotalSize = 0;
+ for (i = 0; i < 4; i++) {
+ if ((bank_reg[i] & 0x1) == 0x1) {
+ tmp = (bank_reg[i] >> 17) & 0x7;
+ bank_size = 4 << tmp;
+ TotalSize += bank_size;
+ } else
+ ds = 1;
+ }
+ mtdcr (SDRAM0_CFGADDR, SDRAM0_ECCCFG);
+ tmp = mfdcr (SDRAM0_CFGDATA);
+
+ if (!tmp)
+ printf ("No ");
+ printf ("ECC ");
+
+ test_dram (TotalSize * MEGA_BYTE);
+ return (TotalSize * MEGA_BYTE);
+}
+
+/* ------------------------------------------------------------------------- */
+
+
+static int test_dram (unsigned long ramsize)
+{
+#ifdef SDRAM_DEBUG
+ mem_test (0L, ramsize, 1);
+#endif
+ /* not yet implemented */
+ return (1);
+}
+
+/* used to check if the time in RTC is valid */
+static unsigned long start;
+static struct rtc_time tm;
+extern flash_info_t flash_info[]; /* info for FLASH chips */
+
+int misc_init_r (void)
+{
+ /* adjust flash start and size as well as the offset */
+ gd->bd->bi_flashstart=0-flash_info[0].size;
+ gd->bd->bi_flashsize=flash_info[0].size-CONFIG_SYS_MONITOR_LEN;
+ gd->bd->bi_flashoffset=0;
+
+ /* check, if RTC is running */
+ rtc_get (&tm);
+ start=get_timer(0);
+ /* if MIP405 has booted from PCI, reset CCR0[24] as described in errata PCI_18 */
+ if (mfdcr(CPC0_PSR) & PSR_ROM_LOC)
+ mtspr(SPRN_CCR0, (mfspr(SPRN_CCR0) & ~0x80));
+
+ return (0);
+}
+
+
+void print_mip405_rev (void)
+{
+ unsigned char part, vers, pcbrev, var;
+
+ get_pcbrev_var(&pcbrev,&var);
+ part = in8 (PLD_PART_REG);
+ vers = in8 (PLD_VERS_REG);
+ printf ("Rev: " BOARD_NAME "-%d Rev %c PLD %d Vers %d\n",
+ var, pcbrev + 'A', part & 0x7F, vers);
+}
+
+
+extern int mk_date (char *, struct rtc_time *);
+
+int last_stage_init (void)
+{
+ unsigned long stop;
+ struct rtc_time newtm;
+ char *s;
+
+ /* write correct LED configuration */
+ if (miiphy_write("ppc_4xx_eth0", 0x1, 0x14, 0x2402) != 0) {
+ printf ("Error writing to the PHY\n");
+ }
+ /* since LED/CFG2 is not connected on the -2,
+ * write to correct capability information */
+ if (miiphy_write("ppc_4xx_eth0", 0x1, 0x4, 0x01E1) != 0) {
+ printf ("Error writing to the PHY\n");
+ }
+ print_mip405_rev ();
+ stdio_print_current_devices ();
+ check_env ();
+ /* check if RTC time is valid */
+ stop=get_timer(start);
+ while(stop<1200) { /* we wait 1.2 sec to check if the RTC is running */
+ udelay(1000);
+ stop=get_timer(start);
+ }
+ rtc_get (&newtm);
+ if(tm.tm_sec==newtm.tm_sec) {
+ s=getenv("defaultdate");
+ if(!s)
+ mk_date ("010112001970", &newtm);
+ else
+ if(mk_date (s, &newtm)!=0) {
+ printf("RTC: Bad date format in defaultdate\n");
+ return 0;
+ }
+ rtc_reset ();
+ rtc_set(&newtm);
+ }
+ return 0;
+}
+
+/***************************************************************************
+ * some helping routines
+ */
+
+int overwrite_console (void)
+{
+ return ((in8 (PLD_EXT_CONF_REG) & 0x1)==0); /* return TRUE if console should be overwritten */
+}
+
+
+/************************************************************************
+* Print MIP405 Info
+************************************************************************/
+void print_mip405_info (void)
+{
+ unsigned char part, vers, cfg, irq_reg, com_mode, ext;
+
+ part = in8 (PLD_PART_REG);
+ vers = in8 (PLD_VERS_REG);
+ cfg = in8 (PLD_BOARD_CFG_REG);
+ irq_reg = in8 (PLD_IRQ_REG);
+ com_mode = in8 (PLD_COM_MODE_REG);
+ ext = in8 (PLD_EXT_CONF_REG);
+
+ printf ("PLD Part %d version %d\n", part & 0x7F, vers);
+ printf ("Board Revision %c\n", ((cfg >> 4) & 0xf) + 'A');
+ printf ("Population Options %d %d %d %d\n", (cfg) & 0x1,
+ (cfg >> 1) & 0x1, (cfg >> 2) & 0x1, (cfg >> 3) & 0x1);
+ printf ("User LED %s\n", (com_mode & 0x4) ? "on" : "off");
+ printf ("UART Clocks %d\n", (com_mode >> 4) & 0x3);
+#if !defined(CONFIG_MIP405T)
+ printf ("User Config Switch %d %d %d %d %d %d %d %d\n",
+ (ext) & 0x1, (ext >> 1) & 0x1, (ext >> 2) & 0x1,
+ (ext >> 3) & 0x1, (ext >> 4) & 0x1, (ext >> 5) & 0x1,
+ (ext >> 6) & 0x1, (ext >> 7) & 0x1);
+ printf ("SER1 uses handshakes %s\n",
+ (ext & 0x80) ? "DTR/DSR" : "RTS/CTS");
+#else
+ printf ("User Config Switch %d %d %d %d %d %d %d %d\n",
+ (ext) & 0x1, (ext >> 1) & 0x1, (ext >> 2) & 0x1,
+ (ext >> 3) & 0x1, (ext >> 4) & 0x1, (ext >> 5) & 0x1,
+ (ext >> 6) & 0x1,(ext >> 7) & 0x1);
+#endif
+ printf ("IDE Reset %s\n", (ext & 0x01) ? "asserted" : "not asserted");
+ printf ("IRQs:\n");
+ printf (" PIIX INTR: %s\n", (irq_reg & 0x80) ? "inactive" : "active");
+#if !defined(CONFIG_MIP405T)
+ printf (" UART0 IRQ: %s\n", (irq_reg & 0x40) ? "inactive" : "active");
+ printf (" UART1 IRQ: %s\n", (irq_reg & 0x20) ? "inactive" : "active");
+#endif
+ printf (" PIIX SMI: %s\n", (irq_reg & 0x10) ? "inactive" : "active");
+ printf (" PIIX INIT: %s\n", (irq_reg & 0x8) ? "inactive" : "active");
+ printf (" PIIX NMI: %s\n", (irq_reg & 0x4) ? "inactive" : "active");
+}
diff --git a/u-boot/board/mpl/mip405/mip405.h b/u-boot/board/mpl/mip405/mip405.h
new file mode 100644
index 0000000..fd7e78a
--- /dev/null
+++ b/u-boot/board/mpl/mip405/mip405.h
@@ -0,0 +1,183 @@
+/*
+ * (C) Copyright 2001
+ * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+ /****************************************************************************
+ * Global routines used for MIP405
+ *****************************************************************************/
+#ifndef __ASSEMBLY__
+/*int switch_cs(unsigned char boot);*/
+
+extern int mem_test(unsigned long start, unsigned long ramsize,int mode);
+
+void user_led0(unsigned char on);
+
+
+#endif
+/* timings */
+/* PLD (CS7) */
+#define PLD_BME 0 /* Burst disable */
+#define PLD_TWE 5 /* 5 * 30ns 120ns Waitstates (access=TWT+1+TH) */
+#define PLD_CSN 1 /* Chipselect is driven inactive for 1 Cycle BTW transfers */
+#define PLD_OEN 1 /* Cycles from CS low to OE low */
+#define PLD_WBN 1 /* Cycles from CS low to WE low */
+#define PLD_WBF 1 /* Cycles from WE high to CS high */
+#define PLD_TH 2 /* Number of hold cycles after transfer */
+#define PLD_RE 0 /* Ready disabled */
+#define PLD_SOR 1 /* Sample on Ready disabled */
+#define PLD_BEM 0 /* Byte Write only active on Write cycles */
+#define PLD_PEN 0 /* Parity disable */
+#define PLD_AP ((PLD_BME << 31) + (PLD_TWE << 23) + (PLD_CSN << 18) + (PLD_OEN << 16) + (PLD_WBN << 14) + \
+ (PLD_WBF << 12) + (PLD_TH << 9) + (PLD_RE << 8) + (PLD_SOR << 7) + (PLD_BEM << 6) + (PLD_PEN << 5))
+
+/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
+#define PLD_BS 0 /* 1 MByte */
+/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
+#define PLD_BU 3 /* R/W */
+/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
+#define PLD_BW 0 /* 16Bit */
+#define PLD_CR ((PER_PLD_ADDR & 0xfff00000) + (PLD_BS << 17) + (PLD_BU << 15) + (PLD_BW << 13))
+
+
+/* timings */
+
+#define PER_BOARD_ADDR (PER_UART1_ADDR+(1024*1024))
+/* Dummy CS to get the board revision */
+#define BOARD_BME 0 /* Burst disable */
+#define BOARD_TWE 255 /* 255 * 30ns 120ns Waitstates (access=TWT+1+TH) */
+#define BOARD_CSN 1 /* Chipselect is driven inactive for 1 Cycle BTW transfers */
+#define BOARD_OEN 1 /* Cycles from CS low to OE low */
+#define BOARD_WBN 1 /* Cycles from CS low to WE low */
+#define BOARD_WBF 1 /* Cycles from WE high to CS high */
+#define BOARD_TH 2 /* Number of hold cycles after transfer */
+#define BOARD_RE 0 /* Ready disabled */
+#define BOARD_SOR 1 /* Sample on Ready disabled */
+#define BOARD_BEM 0 /* Byte Write only active on Write cycles */
+#define BOARD_PEN 0 /* Parity disable */
+#define BOARD_AP ((BOARD_BME << 31) + (BOARD_TWE << 23) + (BOARD_CSN << 18) + (BOARD_OEN << 16) + (BOARD_WBN << 14) + \
+ (BOARD_WBF << 12) + (BOARD_TH << 9) + (BOARD_RE << 8) + (BOARD_SOR << 7) + (BOARD_BEM << 6) + (BOARD_PEN << 5))
+
+/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
+#define BOARD_BS 0 /* 1 MByte */
+/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
+#define BOARD_BU 3 /* R/W */
+/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
+#define BOARD_BW 0 /* 16Bit */
+#define BOARD_CR ((PER_BOARD_ADDR & 0xfff00000) + (BOARD_BS << 17) + (BOARD_BU << 15) + (BOARD_BW << 13))
+
+
+/* UART0 CS2 */
+#define UART0_BME 0 /* Burst disable */
+#define UART0_TWE 7 /* 7 * 30ns 210ns Waitstates (access=TWT+1+TH) */
+#define UART0_CSN 1 /* Chipselect is driven inactive for 1 Cycle BTW transfers */
+#define UART0_OEN 1 /* Cycles from CS low to OE low */
+#define UART0_WBN 1 /* Cycles from CS low to WE low */
+#define UART0_WBF 1 /* Cycles from WE high to CS high */
+#define UART0_TH 2 /* Number of hold cycles after transfer */
+#define UART0_RE 0 /* Ready disabled */
+#define UART0_SOR 1 /* Sample on Ready disabled */
+#define UART0_BEM 0 /* Byte Write only active on Write cycles */
+#define UART0_PEN 0 /* Parity disable */
+#define UART0_AP ((UART0_BME << 31) + (UART0_TWE << 23) + (UART0_CSN << 18) + (UART0_OEN << 16) + (UART0_WBN << 14) + \
+ (UART0_WBF << 12) + (UART0_TH << 9) + (UART0_RE << 8) + (UART0_SOR << 7) + (UART0_BEM << 6) + (UART0_PEN << 5))
+
+/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
+#define UART0_BS 0 /* 1 MByte */
+/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
+#define UART0_BU 3 /* R/W */
+/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
+#define UART0_BW 0 /* 8Bit */
+#define UART0_CR ((PER_UART0_ADDR & 0xfff00000) + (UART0_BS << 17) + (UART0_BU << 15) + (UART0_BW << 13))
+
+/* UART1 CS3 */
+#define UART1_AP UART0_AP /* same timing as UART0 */
+#define UART1_CR ((PER_UART1_ADDR & 0xfff00000) + (UART0_BS << 17) + (UART0_BU << 15) + (UART0_BW << 13))
+
+
+/* Flash CS0 or CS 1 */
+/* 0x7F8FFE80 slowest timing at all... */
+#define FLASH_BME_B 1 /* Burst enable */
+#define FLASH_FWT_B 0x6 /* 6 * 30ns 210ns First Wait Access */
+#define FLASH_BWT_B 0x6 /* 6 * 30ns 210ns Burst Wait Access */
+#define FLASH_BME 0 /* Burst disable */
+#define FLASH_TWE 0xb/* 11 * 30ns 330ns Waitstates (access=TWT+1+TH) */
+#define FLASH_CSN 0 /* Chipselect is driven inactive for 1 Cycle BTW transfers */
+#define FLASH_OEN 1 /* Cycles from CS low to OE low */
+#define FLASH_WBN 1 /* Cycles from CS low to WE low */
+#define FLASH_WBF 1 /* Cycles from WE high to CS high */
+#define FLASH_TH 2 /* Number of hold cycles after transfer */
+#define FLASH_RE 0 /* Ready disabled */
+#define FLASH_SOR 1 /* Sample on Ready disabled */
+#define FLASH_BEM 0 /* Byte Write only active on Write cycles */
+#define FLASH_PEN 0 /* Parity disable */
+/* Access Parameter Register for non Boot */
+#define FLASH_AP ((FLASH_BME << 31) + (FLASH_TWE << 23) + (FLASH_CSN << 18) + (FLASH_OEN << 16) + (FLASH_WBN << 14) + \
+ (FLASH_WBF << 12) + (FLASH_TH << 9) + (FLASH_RE << 8) + (FLASH_SOR << 7) + (FLASH_BEM << 6) + (FLASH_PEN << 5))
+/* Access Parameter Register for Boot */
+#define FLASH_AP_B ((FLASH_BME_B << 31) + (FLASH_FWT_B << 26) + (FLASH_BWT_B << 23) + (FLASH_CSN << 18) + (FLASH_OEN << 16) + (FLASH_WBN << 14) + \
+ (FLASH_WBF << 12) + (FLASH_TH << 9) + (FLASH_RE << 8) + (FLASH_SOR << 7) + (FLASH_BEM << 6) + (FLASH_PEN << 5))
+
+/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
+#define FLASH_BS FLASH_SIZE_PRELIM /* 4 MByte */
+/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
+#define FLASH_BU 3 /* R/W */
+/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
+#define FLASH_BW 1 /* 16Bit */
+/* CR register for Boot */
+#define FLASH_CR_B ((FLASH_BASE_PRELIM & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13))
+/* CR register for non Boot */
+#define FLASH_CR ((MULTI_PURPOSE_SOCKET_ADDR & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13))
+
+/* MPS CS1 or CS0 */
+/* Boot CS: */
+#define MPS_BME_B 1 /* Burst enable */
+#define MPS_FWT_B 0x6/* 6 * 30ns 210ns First Wait Access */
+#define MPS_BWT_B 0x6 /* 6 * 30ns 210ns Burst Wait Access */
+#define MPS_BME 0 /* Burst disable */
+#define MPS_TWE 0xb/* 11 * 30ns 330ns Waitstates (access=TWT+1+TH) */
+#define MPS_CSN 0 /* Chipselect is driven inactive for 1 Cycle BTW transfers */
+#define MPS_OEN 1 /* Cycles from CS low to OE low */
+#define MPS_WBN 1 /* Cycles from CS low to WE low */
+#define MPS_WBF 1 /* Cycles from WE high to CS high */
+#define MPS_TH 2 /* Number of hold cycles after transfer */
+#define MPS_RE 0 /* Ready disabled */
+#define MPS_SOR 1 /* Sample on Ready disabled */
+#define MPS_BEM 0 /* Byte Write only active on Write cycles */
+#define MPS_PEN 0 /* Parity disable */
+/* Access Parameter Register for non Boot */
+#define MPS_AP ((MPS_BME << 31) + (MPS_TWE << 23) + (MPS_CSN << 18) + (MPS_OEN << 16) + (MPS_WBN << 14) + \
+ (MPS_WBF << 12) + (MPS_TH << 9) + (MPS_RE << 8) + (MPS_SOR << 7) + (MPS_BEM << 6) + (MPS_PEN << 5))
+/* Access Parameter Register for Boot */
+#define MPS_AP_B ((MPS_BME_B << 31) + (MPS_FWT_B << 26) + (MPS_BWT_B << 23) + (MPS_CSN << 18) + (MPS_OEN << 16) + (MPS_WBN << 14) + \
+ (MPS_WBF << 12) + (MPS_TH << 9) + (MPS_RE << 8) + (MPS_SOR << 7) + (MPS_BEM << 6) + (MPS_PEN << 5))
+
+/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
+#define MPS_BS 2 /* 4 MByte */
+#define MPS_BS_B FLASH_SIZE_PRELIM /* 1 MByte */
+/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
+#define MPS_BU 3 /* R/W */
+/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
+#define MPS_BW 0 /* 8Bit */
+/* CR register for Boot */
+#define MPS_CR_B ((FLASH_BASE_PRELIM & 0xfff00000) + (MPS_BS_B << 17) + (MPS_BU << 15) + (MPS_BW << 13))
+/* CR register for non Boot */
+#define MPS_CR ((MULTI_PURPOSE_SOCKET_ADDR & 0xfff00000) + (MPS_BS << 17) + (MPS_BU << 15) + (MPS_BW << 13))
diff --git a/u-boot/board/mpl/pati/Makefile b/u-boot/board/mpl/pati/Makefile
new file mode 100644
index 0000000..937dfec
--- /dev/null
+++ b/u-boot/board/mpl/pati/Makefile
@@ -0,0 +1,54 @@
+#
+# (C) Copyright 2001-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+ifneq ($(OBJTREE),$(SRCTREE))
+$(shell mkdir -p $(obj)../common)
+endif
+
+LIB = $(obj)lib$(BOARD).o
+
+COBJS := pati.o ../common/flash.o cmd_pati.o ../common/common_util.o
+#### cmd_pati.o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+SOBJS := $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(obj).depend $(OBJS)
+ $(call cmd_link_o_target, $(OBJS))
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak $(obj).depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/u-boot/board/mpl/pati/cmd_pati.c b/u-boot/board/mpl/pati/cmd_pati.c
new file mode 100644
index 0000000..aba11d5
--- /dev/null
+++ b/u-boot/board/mpl/pati/cmd_pati.c
@@ -0,0 +1,449 @@
+/*
+ * (C) Copyright 2001
+ * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * Adapted for PATI
+ */
+
+#include <common.h>
+#include <command.h>
+#define PLX9056_LOC
+#include "plx9056.h"
+#include "pati.h"
+#include "pci_eeprom.h"
+
+extern void show_pld_regs(void);
+extern int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+
+extern void user_led0(int led_on);
+extern void user_led1(int led_on);
+
+/* ------------------------------------------------------------------------- */
+#if defined(CONFIG_SYS_PCI_CON_DEVICE)
+extern void pci_con_disc(void);
+extern void pci_con_connect(void);
+#endif
+
+/******************************************************************************
+ * Eeprom Support
+ ******************************************************************************/
+unsigned long get32(unsigned long addr)
+{
+ unsigned long *p=(unsigned long *)addr;
+ return *p;
+}
+
+void set32(unsigned long addr,unsigned long data)
+{
+ unsigned long *p=(unsigned long *)addr;
+ *p=data;
+}
+
+#define PCICFG_GET_REG(x) (get32((x) + PCI_CONFIG_BASE))
+#define PCICFG_SET_REG(x,y) (set32((x) + PCI_CONFIG_BASE,(y)))
+
+
+/******************************************************************************
+ * reload_pci_eeprom
+ ******************************************************************************/
+
+static void reload_pci_eeprom(void)
+{
+ unsigned long reg;
+ /* Set Bit 29 and clear it again */
+ reg=PCICFG_GET_REG(PCI9056_EEPROM_CTRL_STAT);
+ udelay(1);
+ /* set it*/
+ reg|=(1<<29);
+ PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg);
+ /* EECLK @ 33MHz = 125kHz
+ * -> extra long load = 32 * 16bit = 512Bit @ 125kHz = 4.1msec
+ * use 20msec
+ */
+ udelay(20000); /* wait 20ms */
+ reg &= ~(1<<29); /* set it low */
+ PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg);
+ udelay(1); /* wait some time */
+}
+
+/******************************************************************************
+ * clock_pci_eeprom
+ ******************************************************************************/
+
+static void clock_pci_eeprom(void)
+{
+ unsigned long reg;
+ /* clock is low, data is valid */
+ reg=PCICFG_GET_REG(PCI9056_EEPROM_CTRL_STAT);
+ udelay(1);
+ /* set clck high */
+ reg|=(1<<24);
+ PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg);
+ udelay(1); /* wait some time */
+ reg &= ~(1<<24); /* set clock low */
+ PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg);
+ udelay(1); /* wait some time */
+}
+
+/******************************************************************************
+ * send_pci_eeprom_cmd
+ ******************************************************************************/
+static void send_pci_eeprom_cmd(unsigned long cmd, unsigned char len)
+{
+ unsigned long reg;
+ int i;
+ reg=PCICFG_GET_REG(PCI9056_EEPROM_CTRL_STAT);
+ /* Clear all EEPROM bits */
+ reg &= ~(0xF << 24);
+ /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */
+ PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg);
+ udelay(1); /* wait some time */
+ /* Enable EEPROM Chip Select */
+ reg |= (1 << 25);
+ PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg);
+ /* Send EEPROM command - one bit at a time */
+ for (i = (int)(len-1); i >= 0; i--) {
+ /* Check if current bit is 0 or 1 */
+ if (cmd & (1 << i))
+ PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,(reg | (1<<26)));
+ else
+ PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg);
+ clock_pci_eeprom();
+ }
+}
+
+/******************************************************************************
+ * write_pci_eeprom_offs
+ ******************************************************************************/
+static void write_pci_eeprom_offs(unsigned short offset, unsigned short value)
+{
+ unsigned long reg;
+ int bitpos, cmdshft, cmdlen, timeout;
+ /* we're using the Eeprom 93CS66 */
+ cmdshft = 2;
+ cmdlen = EE66_CMD_LEN;
+ /* Send Write_Enable command to EEPROM */
+ send_pci_eeprom_cmd((EE_WREN << cmdshft),cmdlen);
+ /* Send EEPROM Write command and offset to EEPROM */
+ send_pci_eeprom_cmd((EE_WRITE << cmdshft) | (offset / 2),cmdlen);
+ reg=PCICFG_GET_REG(PCI9056_EEPROM_CTRL_STAT);
+ /* Clear all EEPROM bits */
+ reg &= ~(0xF << 24);
+ /* Make sure EEDO Input is disabled for some PLX chips */
+ reg &= ~(1 << 31);
+ /* Enable EEPROM Chip Select */
+ reg |= (1 << 25);
+ /* Write 16-bit value to EEPROM - one bit at a time */
+ for (bitpos = 15; bitpos >= 0; bitpos--) {
+ /* Get bit value and shift into result */
+ if (value & (1 << bitpos))
+ PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,(reg | (1<<26)));
+ else
+ PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg );
+ clock_pci_eeprom();
+ } /* for */
+ /* Deselect Chip */
+ PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg & ~(1 << 25));
+ /* Re-select Chip */
+ PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg | (1 << 25));
+ /* A small delay is needed to let EEPROM complete */
+ timeout = 0;
+ do {
+ udelay(10);
+ reg=PCICFG_GET_REG(PCI9056_EEPROM_CTRL_STAT);
+ timeout++;
+ } while (((reg & (1 << 27)) == 0) && timeout < 20000);
+ /* Send Write_Disable command to EEPROM */
+ send_pci_eeprom_cmd((EE_WDS << cmdshft),cmdlen);
+ /* Clear Chip Select and all other EEPROM bits */
+ PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg & ~(0xF << 24));
+}
+
+
+/******************************************************************************
+ * read_pci_eeprom_offs
+ ******************************************************************************/
+static void read_pci_eeprom_offs(unsigned short offset, unsigned short *pvalue)
+{
+ unsigned long reg;
+ int bitpos, cmdshft, cmdlen;
+ /* we're using the Eeprom 93CS66 */
+ cmdshft = 2;
+ cmdlen = EE66_CMD_LEN;
+ /* Send EEPROM read command and offset to EEPROM */
+ send_pci_eeprom_cmd((EE_READ << cmdshft) | (offset / 2),cmdlen);
+ /* Set EEPROM write output bit */
+ reg=PCICFG_GET_REG(PCI9056_EEPROM_CTRL_STAT);
+ /* Set EEDO Input enable */
+ reg |= (1 << 31);
+ PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg | (1 << 26));
+ /* Get 16-bit value from EEPROM - one bit at a time */
+ for (bitpos = 0; bitpos < 16; bitpos++) {
+ clock_pci_eeprom();
+ udelay(10);
+ reg=PCICFG_GET_REG(PCI9056_EEPROM_CTRL_STAT);
+ /* Get bit value and shift into result */
+ if (reg & (1 << 27))
+ *pvalue = (unsigned short)((*pvalue << 1) | 1);
+ else
+ *pvalue = (unsigned short)(*pvalue << 1);
+ }
+ /* Clear EEDO Input enable */
+ reg &= ~(1 << 31);
+ /* Clear Chip Select and all other EEPROM bits */
+ PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg & ~(0xF << 24));
+}
+
+
+/******************************************************************************
+ * EEPROM read/writes
+******************************************************************************/
+
+#undef EEPROM_DBG
+static int pati_pci_eeprom_erase(void)
+{
+ int i;
+ printf("Erasing EEPROM ");
+ for( i=0; i < PATI_EEPROM_LAST_OFFSET; i+=2) {
+ write_pci_eeprom_offs(i,0xffff);
+ if((i%0x10))
+ printf(".");
+ }
+ printf("\nDone\n");
+ return 0;
+}
+
+static int pati_pci_eeprom_prg(void)
+{
+ int i;
+ i=0;
+ printf("Programming EEPROM ");
+ while(pati_eeprom[i].offset<0xffff) {
+ write_pci_eeprom_offs(pati_eeprom[i].offset,pati_eeprom[i].value);
+ #ifdef EEPROM_DBG
+ printf("0x%04X: 0x%04X\n",pati_eeprom[i].offset, pati_eeprom[i].value);
+ #else
+ if((i%0x10))
+ printf(".");
+ #endif
+ i++;
+ }
+ printf("\nDone\n");
+ return 0;
+}
+
+static int pati_pci_eeprom_write(unsigned short offset, unsigned long addr, unsigned short size)
+{
+ int i;
+ unsigned short value;
+ unsigned short *buffer =(unsigned short *)addr;
+ if((offset + size) > PATI_EEPROM_LAST_OFFSET) {
+ size = PATI_EEPROM_LAST_OFFSET - offset;
+ }
+ printf("Write To EEPROM from 0x%lX to 0x%X 0x%X words\n", addr, offset, size/2);
+ for( i = offset; i< (offset + size); i+=2) {
+ value = *buffer++;
+ write_pci_eeprom_offs(i,value);
+ #ifdef EEPROM_DBG
+ printf("0x%04X: 0x%04X\n",i, value);
+ #else
+ if((i%0x10))
+ printf(".");
+ #endif
+ }
+ printf("\nDone\n");
+ return 0;
+}
+
+static int pati_pci_eeprom_read(unsigned short offset, unsigned long addr, unsigned short size)
+{
+ int i;
+ unsigned short value = 0;
+ unsigned short *buffer =(unsigned short *)addr;
+ if((offset + size) > PATI_EEPROM_LAST_OFFSET) {
+ size = PATI_EEPROM_LAST_OFFSET - offset;
+ }
+ printf("Read from EEPROM from 0x%X to 0x%lX 0x%X words\n", offset, addr, size/2);
+ for( i = offset; i< (offset + size); i+=2) {
+ read_pci_eeprom_offs(i,&value);
+ *buffer++=value;
+ #ifdef EEPROM_DBG
+ printf("0x%04X: 0x%04X\n",i, value);
+ #else
+ if((i%0x10))
+ printf(".");
+ #endif
+ }
+ printf("\nDone\n");
+ return 0;
+}
+
+/******************************************************************************
+ * PCI Bridge Registers Dump
+*******************************************************************************/
+static void display_pci_regs(void)
+{
+ printf(" PCI9056_SPACE0_RANGE %08lX\n",PCICFG_GET_REG(PCI9056_SPACE0_RANGE));
+ printf(" PCI9056_SPACE0_REMAP %08lX\n",PCICFG_GET_REG(PCI9056_SPACE0_REMAP));
+ printf(" PCI9056_LOCAL_DMA_ARBIT %08lX\n",PCICFG_GET_REG(PCI9056_LOCAL_DMA_ARBIT));
+ printf(" PCI9056_ENDIAN_DESC %08lX\n",PCICFG_GET_REG(PCI9056_ENDIAN_DESC));
+ printf(" PCI9056_EXP_ROM_RANGE %08lX\n",PCICFG_GET_REG(PCI9056_EXP_ROM_RANGE));
+ printf(" PCI9056_EXP_ROM_REMAP %08lX\n",PCICFG_GET_REG(PCI9056_EXP_ROM_REMAP));
+ printf(" PCI9056_SPACE0_ROM_DESC %08lX\n",PCICFG_GET_REG(PCI9056_SPACE0_ROM_DESC));
+ printf(" PCI9056_DM_RANGE %08lX\n",PCICFG_GET_REG(PCI9056_DM_RANGE));
+ printf(" PCI9056_DM_MEM_BASE %08lX\n",PCICFG_GET_REG(PCI9056_DM_MEM_BASE));
+ printf(" PCI9056_DM_IO_BASE %08lX\n",PCICFG_GET_REG(PCI9056_DM_IO_BASE));
+ printf(" PCI9056_DM_PCI_MEM_REMAP %08lX\n",PCICFG_GET_REG(PCI9056_DM_PCI_MEM_REMAP));
+ printf(" PCI9056_DM_PCI_IO_CONFIG %08lX\n",PCICFG_GET_REG(PCI9056_DM_PCI_IO_CONFIG));
+ printf(" PCI9056_SPACE1_RANGE %08lX\n",PCICFG_GET_REG(PCI9056_SPACE1_RANGE));
+ printf(" PCI9056_SPACE1_REMAP %08lX\n",PCICFG_GET_REG(PCI9056_SPACE1_REMAP));
+ printf(" PCI9056_SPACE1_DESC %08lX\n",PCICFG_GET_REG(PCI9056_SPACE1_DESC));
+ printf(" PCI9056_DM_DAC %08lX\n",PCICFG_GET_REG(PCI9056_DM_DAC));
+ printf(" PCI9056_MAILBOX0 %08lX\n",PCICFG_GET_REG(PCI9056_MAILBOX0));
+ printf(" PCI9056_MAILBOX1 %08lX\n",PCICFG_GET_REG(PCI9056_MAILBOX1));
+ printf(" PCI9056_MAILBOX2 %08lX\n",PCICFG_GET_REG(PCI9056_MAILBOX2));
+ printf(" PCI9056_MAILBOX3 %08lX\n",PCICFG_GET_REG(PCI9056_MAILBOX3));
+ printf(" PCI9056_MAILBOX4 %08lX\n",PCICFG_GET_REG(PCI9056_MAILBOX4));
+ printf(" PCI9056_MAILBOX5 %08lX\n",PCICFG_GET_REG(PCI9056_MAILBOX5));
+ printf(" PCI9056_MAILBOX6 %08lX\n",PCICFG_GET_REG(PCI9056_MAILBOX6));
+ printf(" PCI9056_MAILBOX7 %08lX\n",PCICFG_GET_REG(PCI9056_MAILBOX7));
+ printf(" PCI9056_PCI_TO_LOC_DBELL %08lX\n",PCICFG_GET_REG(PCI9056_PCI_TO_LOC_DBELL));
+ printf(" PCI9056_LOC_TO_PCI_DBELL %08lX\n",PCICFG_GET_REG(PCI9056_LOC_TO_PCI_DBELL));
+ printf(" PCI9056_INT_CTRL_STAT %08lX\n",PCICFG_GET_REG(PCI9056_INT_CTRL_STAT));
+ printf(" PCI9056_EEPROM_CTRL_STAT %08lX\n",PCICFG_GET_REG(PCI9056_EEPROM_CTRL_STAT));
+ printf(" PCI9056_PERM_VENDOR_ID %08lX\n",PCICFG_GET_REG(PCI9056_PERM_VENDOR_ID));
+ printf(" PCI9056_REVISION_ID %08lX\n",PCICFG_GET_REG(PCI9056_REVISION_ID));
+ printf(" \n");
+ printf(" PCI9056_VENDOR_ID %08lX\n",PCICFG_GET_REG(PCI9056_VENDOR_ID));
+ printf(" PCI9056_COMMAND %08lX\n",PCICFG_GET_REG(PCI9056_COMMAND));
+ printf(" PCI9056_REVISION %08lX\n",PCICFG_GET_REG(PCI9056_REVISION));
+ printf(" PCI9056_CACHE_SIZE %08lX\n",PCICFG_GET_REG(PCI9056_CACHE_SIZE));
+ printf(" PCI9056_RTR_BASE %08lX\n",PCICFG_GET_REG(PCI9056_RTR_BASE));
+ printf(" PCI9056_RTR_IO_BASE %08lX\n",PCICFG_GET_REG(PCI9056_RTR_IO_BASE));
+ printf(" PCI9056_LOCAL_BASE0 %08lX\n",PCICFG_GET_REG(PCI9056_LOCAL_BASE0));
+ printf(" PCI9056_LOCAL_BASE1 %08lX\n",PCICFG_GET_REG(PCI9056_LOCAL_BASE1));
+ printf(" PCI9056_UNUSED_BASE1 %08lX\n",PCICFG_GET_REG(PCI9056_UNUSED_BASE1));
+ printf(" PCI9056_UNUSED_BASE2 %08lX\n",PCICFG_GET_REG(PCI9056_UNUSED_BASE2));
+ printf(" PCI9056_CIS_PTR %08lX\n",PCICFG_GET_REG(PCI9056_CIS_PTR));
+ printf(" PCI9056_SUB_ID %08lX\n",PCICFG_GET_REG(PCI9056_SUB_ID));
+ printf(" PCI9056_EXP_ROM_BASE %08lX\n",PCICFG_GET_REG(PCI9056_EXP_ROM_BASE));
+ printf(" PCI9056_CAP_PTR %08lX\n",PCICFG_GET_REG(PCI9056_CAP_PTR));
+ printf(" PCI9056_INT_LINE %08lX\n",PCICFG_GET_REG(PCI9056_INT_LINE));
+ printf(" PCI9056_PM_CAP_ID %08lX\n",PCICFG_GET_REG(PCI9056_PM_CAP_ID));
+ printf(" PCI9056_PM_CSR %08lX\n",PCICFG_GET_REG(PCI9056_PM_CSR));
+ printf(" PCI9056_HS_CAP_ID %08lX\n",PCICFG_GET_REG(PCI9056_HS_CAP_ID));
+ printf(" PCI9056_VPD_CAP_ID %08lX\n",PCICFG_GET_REG(PCI9056_VPD_CAP_ID));
+ printf(" PCI9056_VPD_DATA %08lX\n",PCICFG_GET_REG(PCI9056_VPD_DATA));
+}
+
+
+int do_pati(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ if (strcmp(argv[1], "info") == 0)
+ {
+ show_pld_regs();
+ return 0;
+ }
+ if (strcmp(argv[1], "pci") == 0)
+ {
+ display_pci_regs();
+ return 0;
+ }
+ if (strcmp(argv[1], "led") == 0)
+ {
+ int led_nr,led_on;
+ led_nr = (int)simple_strtoul(argv[2], NULL, 10);
+ led_on = (int)simple_strtoul(argv[3], NULL, 10);
+ if(!led_nr)
+ user_led0(led_on);
+ else
+ user_led1(led_on);
+ return 0;
+ }
+#if defined(CONFIG_SYS_PCI_CON_DEVICE)
+ if (strcmp(argv[1], "con") == 0) {
+ pci_con_connect();
+ return 0;
+ }
+ if (strcmp(argv[1], "disc") == 0) {
+ pci_con_disc();
+ return 0;
+ }
+#endif
+ if (strcmp(argv[1], "eeprom") == 0) {
+ unsigned long addr;
+ int size, offset;
+ offset = 0;
+ size = PATI_EEPROM_LAST_OFFSET;
+ if(argc>2) {
+ if(argc>3) {
+ addr = simple_strtoul(argv[3], NULL, 16);
+ if(argc>4)
+ offset = (int) simple_strtoul(argv[4], NULL, 16);
+ if(argc>5)
+ size = (int) simple_strtoul(argv[5], NULL, 16);
+ if (strcmp(argv[2], "read") == 0) {
+ return (pati_pci_eeprom_read(offset, addr, size));
+ }
+ if (strcmp(argv[2], "write") == 0) {
+ return (pati_pci_eeprom_write(offset, addr, size));
+ }
+ }
+ if (strcmp(argv[2], "prg") == 0) {
+ return (pati_pci_eeprom_prg());
+ }
+ if (strcmp(argv[2], "era") == 0) {
+ return (pati_pci_eeprom_erase());
+ }
+ if (strcmp(argv[2], "reload") == 0) {
+ reload_pci_eeprom();
+ return 0;
+ }
+
+
+ }
+ }
+
+ return (do_mplcommon(cmdtp, flag, argc, argv));
+}
+
+U_BOOT_CMD(
+ pati, 8, 1, do_pati,
+ "PATI specific Cmds",
+ "info - displays board information\n"
+ "pati pci - displays PCI registers\n"
+ "pati led <nr> <on> \n"
+ " - switch LED <nr> <on>\n"
+ "pati flash mem [SrcAddr]\n"
+ " - updates U-Boot with image in memory\n"
+ "pati eeprom <cmd> - PCI EEPROM sub-system\n"
+ " read <addr> <offset> <size>\n"
+ " - read PCI EEPROM to <addr> from <offset> <size> words\n"
+ " write <addr> <offset> <size>\n"
+ " - write PCI EEPROM from <addr> to <offset> <size> words\n"
+ " prg - programm PCI EEPROM with default values\n"
+ " era - erase PCI EEPROM (write all word to 0xffff)\n"
+ " reload- Reload PCI Bridge with EEPROM Values\n"
+ " NOTE: <addr> must start on word boundary\n"
+ " <offset> and <size> must be even byte values"
+);
+
+/* ------------------------------------------------------------------------- */
diff --git a/u-boot/board/mpl/pati/pati.c b/u-boot/board/mpl/pati/pati.c
new file mode 100644
index 0000000..7f1164a
--- /dev/null
+++ b/u-boot/board/mpl/pati/pati.c
@@ -0,0 +1,616 @@
+/*
+ * (C) Copyright 2003
+ * Martin Winistoerfer, martinwinistoerfer@gmx.ch.
+ * Atapted for PATI
+ * Denis Peter, d.peter@mpl.ch
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/***********************************************************************************
+ * Bits for the SDRAM controller
+ * -----------------------------
+ *
+ * CAL: CAS Latency. If cleared to 0 (default) the SDRAM controller asserts TA# on
+ * the 2nd Clock after ACTIVE command (CAS Latency = 2). If set to 1 the SDRAM
+ * controller asserts TA# on the 3rd Clock after ACTIVE command (CAS Latency = 3).
+ * RCD: RCD ACTIVE to READ or WRITE Delay (Ras to Cas Delay). If cleared 0 (default)
+ * tRCD of the SDRAM must equal or less 25ns. If set to 1 tRCD must be equal or less 50ns.
+ * WREC:Write Recovery. If cleared 0 (default) tWR of the SDRAM must equal or less 25ns.
+ * If set to 1 tWR must be equal or less 50ns.
+ * RP: Precharge Command Time. If cleared 0 (default) tRP of the SDRAM must equal or less
+ * 25ns. If set to 1 tRP must be equal or less 50ns.
+ * RC: Auto Refresh to Active Time. If cleared 0 (default) tRC of the SDRAM must equal
+ * or less 75ns. If set to 1 tRC must be equal or less 100ns.
+ * LMR: Bit to set the Mode Register of the SDRAM. If set, the next access to the SDRAM
+ * is the Load Mode Register Command.
+ * IIP: Init in progress. Set to 1 for starting the init sequence
+ * (Precharge All). As long this bit is set, the Precharge All is still in progress.
+ * After command has completed, wait at least for 8 refresh (200usec) before proceed.
+ **********************************************************************************/
+
+#include <common.h>
+#include <mpc5xx.h>
+#include <stdio_dev.h>
+#include <pci_ids.h>
+#define PLX9056_LOC
+#include "plx9056.h"
+#include "pati.h"
+
+#if defined(__APPLE__)
+/* Leading underscore on symbols */
+# define SYM_CHAR "_"
+#else /* No leading character on symbols */
+# define SYM_CHAR
+#endif
+
+#undef SDRAM_DEBUG
+/*
+ * Macros to generate global absolutes.
+ */
+#define GEN_SYMNAME(str) SYM_CHAR #str
+#define GEN_VALUE(str) #str
+#define GEN_ABS(name, value) \
+ asm (".globl " GEN_SYMNAME(name)); \
+ asm (GEN_SYMNAME(name) " = " GEN_VALUE(value))
+
+
+/************************************************************************
+ * Early debug routines
+ */
+void write_hex (unsigned char i)
+{
+ char cc;
+
+ cc = i >> 4;
+ cc &= 0xf;
+ if (cc > 9)
+ serial_putc (cc + 55);
+ else
+ serial_putc (cc + 48);
+ cc = i & 0xf;
+ if (cc > 9)
+ serial_putc (cc + 55);
+ else
+ serial_putc (cc + 48);
+}
+
+#if defined(SDRAM_DEBUG)
+
+void write_4hex (unsigned long val)
+{
+ write_hex ((unsigned char) (val >> 24));
+ write_hex ((unsigned char) (val >> 16));
+ write_hex ((unsigned char) (val >> 8));
+ write_hex ((unsigned char) val);
+}
+
+#endif
+
+unsigned long in32(unsigned long addr)
+{
+ unsigned long *p=(unsigned long *)addr;
+ return *p;
+}
+
+void out32(unsigned long addr,unsigned long data)
+{
+ unsigned long *p=(unsigned long *)addr;
+ *p=data;
+}
+
+typedef struct {
+ unsigned short boardtype; /* Board revision and Population Options */
+ unsigned char cal; /* cas Latency 0:CAL=2 1:CAL=3 */
+ unsigned char rcd; /* ras to cas delay 0:<25ns 1:<50ns*/
+ unsigned char wrec; /* write recovery 0:<25ns 1:<50ns */
+ unsigned char pr; /* Precharge Command Time 0:<25ns 1:<50ns */
+ unsigned char rc; /* Auto Refresh to Active Time 0:<75ns 1:<100ns */
+ unsigned char sz; /* log binary => Size = (4MByte<<sz) 5 = 128, 4 = 64, 3 = 32, 2 = 16, 1=8 */
+} sdram_t;
+
+const sdram_t sdram_table[] = {
+ { 0x0000, /* PATI Rev A, 16MByte -1 Board */
+ 1, /* Case Latenty = 3 */
+ 0, /* ras to cas delay 0 (20ns) */
+ 0, /* write recovery 0:<25ns 1:<50ns*/
+ 0, /* Precharge Command Time 0 (20ns) */
+ 0, /* Auto Refresh to Active Time 0 (68) */
+ 2 /* log binary => Size 2 = 16MByte, 1=8 */
+ },
+ { 0xffff, /* terminator */
+ 0xff,
+ 0xff,
+ 0xff,
+ 0xff,
+ 0xff,
+ 0xff }
+};
+
+
+extern int mem_test (unsigned long start, unsigned long ramsize, int quiet);
+
+/*
+ * Get RAM size.
+ */
+phys_size_t initdram(int board_type)
+{
+ unsigned char board_rev;
+ unsigned long reg;
+ unsigned long lmr;
+ int i,timeout;
+
+#if defined(SDRAM_DEBUG)
+ reg=in32(PLD_CONFIG_BASE+PLD_PART_ID);
+ puts("\n\nSYSTEM part 0x"); write_4hex(SYSCNTR_PART(reg));
+ puts(" Vers 0x"); write_4hex(SYSCNTR_ID(reg));
+ puts("\nSDRAM part 0x"); write_4hex(SDRAM_PART(reg));
+ puts(" Vers 0x"); write_4hex(SDRAM_ID(reg));
+ reg=in32(PLD_CONFIG_BASE+PLD_BOARD_TIMING);
+ puts("\nBoard rev. 0x"); write_4hex(SYSCNTR_BREV(reg));
+ putc('\n');
+#endif
+ reg=in32(PLD_CONFIG_BASE+PLD_BOARD_TIMING);
+ board_rev=(unsigned char)(SYSCNTR_BREV(reg));
+ i=0;
+ while(1) {
+ if(sdram_table[i].boardtype==0xffff) {
+ puts("ERROR, found no table for Board 0x");
+ write_hex(board_rev);
+ while(1);
+ }
+ if(sdram_table[i].boardtype==(unsigned char)board_rev)
+ break;
+ i++;
+ }
+ /* Set CAL, RCD, WREQ, PR and RC Bits */
+#if defined(SDRAM_DEBUG)
+ puts("Set CAL, RCD, WREQ, PR and RC Bits\n");
+#endif
+ /* mask bits */
+ reg &= ~(SET_REG_BIT(1,SDRAM_CAL) | SET_REG_BIT(1,SDRAM_RCD) | SET_REG_BIT(1,SDRAM_WREQ) |
+ SET_REG_BIT(1,SDRAM_PR) | SET_REG_BIT(1,SDRAM_RC) | SET_REG_BIT(1,SDRAM_LMR) |
+ SET_REG_BIT(1,SDRAM_IIP) | SET_REG_BIT(1,SDRAM_RES0));
+ /* set bits */
+ reg |= (SET_REG_BIT(sdram_table[i].cal,SDRAM_CAL) |
+ SET_REG_BIT(sdram_table[i].rcd,SDRAM_RCD) |
+ SET_REG_BIT(sdram_table[i].wrec,SDRAM_WREQ) |
+ SET_REG_BIT(sdram_table[i].pr,SDRAM_PR) |
+ SET_REG_BIT(sdram_table[i].rc,SDRAM_RC));
+
+ out32(PLD_CONFIG_BASE+PLD_BOARD_TIMING,reg);
+ /* step 2 set IIP */
+#if defined(SDRAM_DEBUG)
+ puts("step 2 set IIP\n");
+#endif
+ /* step 2 set IIP */
+ reg |= SET_REG_BIT(1,SDRAM_IIP);
+ timeout=0;
+ while (timeout!=0xffff) {
+ __asm__ volatile("eieio");
+ reg=in32(PLD_CONFIG_BASE+PLD_BOARD_TIMING);
+ if((reg & SET_REG_BIT(1,SDRAM_IIP))==0)
+ break;
+ timeout++;
+ udelay(1);
+ }
+ /* wait for at least 8 refresh */
+ udelay(1000);
+ /* set LMR */
+ reg |= SET_REG_BIT(1,SDRAM_LMR);
+ out32(PLD_CONFIG_BASE+PLD_BOARD_TIMING,reg);
+ __asm__ volatile("eieio");
+ lmr=0x00000002; /* sequential burst 4 data */
+ if(sdram_table[i].cal==1)
+ lmr|=0x00000030; /* cal = 3 */
+ else
+ lmr|=0000000020; /* cal = 2 */
+ /* rest standard operation programmed write burst length */
+ /* we have a x32 bit bus to the SDRAM, so shift the addr with 2 */
+ lmr<<=2;
+ in32(CONFIG_SYS_SDRAM_BASE + lmr);
+ /* ok, we're done, return SDRAM size */
+ return ((0x400000 << sdram_table[i].sz)); /* log2 value of 4MByte */
+}
+
+
+void set_flash_vpp(int ext_vpp, int ext_wp, int int_vpp)
+{
+ unsigned long reg;
+ reg=in32(PLD_CONF_REG2+PLD_CONFIG_BASE);
+ reg &= ~(SET_REG_BIT(1,SYSCNTR_CPU_VPP) |
+ SET_REG_BIT(1,SYSCNTR_FL_VPP) |
+ SET_REG_BIT(1,SYSCNTR_FL_WP));
+
+ reg |= (SET_REG_BIT(int_vpp,SYSCNTR_CPU_VPP) |
+ SET_REG_BIT(ext_vpp,SYSCNTR_FL_VPP) |
+ SET_REG_BIT(ext_wp,SYSCNTR_FL_WP));
+ out32(PLD_CONF_REG2+PLD_CONFIG_BASE,reg);
+ udelay(100);
+}
+
+
+void show_pld_regs(void)
+{
+ unsigned long reg,reg1;
+ reg=in32(PLD_CONFIG_BASE+PLD_PART_ID);
+ printf("\nSYSTEM part %ld, Vers %ld\n",SYSCNTR_PART(reg),SYSCNTR_ID(reg));
+ printf("SDRAM part %ld, Vers %ld\n",SDRAM_PART(reg),SDRAM_ID(reg));
+ reg=in32(PLD_CONFIG_BASE+PLD_BOARD_TIMING);
+ printf("Board rev. %c\n",(char) (SYSCNTR_BREV(reg)+'A'));
+ printf("Waitstates %ld\n",GET_SYSCNTR_FLWAIT(reg));
+ printf("SDRAM: CAL=%ld RCD=%ld WREQ=%ld PR=%ld\n RC=%ld LMR=%ld IIP=%ld\n",
+ GET_REG_BIT(reg,SDRAM_CAL),GET_REG_BIT(reg,SDRAM_RCD),
+ GET_REG_BIT(reg,SDRAM_WREQ),GET_REG_BIT(reg,SDRAM_PR),
+ GET_REG_BIT(reg,SDRAM_RC),GET_REG_BIT(reg,SDRAM_LMR),
+ GET_REG_BIT(reg,SDRAM_IIP));
+ reg=in32(PLD_CONFIG_BASE+PLD_CONF_REG1);
+ reg1=in32(PLD_CONFIG_BASE+PLD_CONF_REG2);
+ printf("HW Config: FLAG=%ld IP=%ld index=%ld PRPM=%ld\n ICW=%ld ISB=%ld BDIS=%ld PCIM=%ld\n",
+ GET_REG_BIT(reg,SYSCNTR_FLAG),GET_REG_BIT(reg,SYSCNTR_IP),
+ GET_SYSCNTR_BOOTIND(reg),GET_REG_BIT(reg,SYSCNTR_PRM),
+ GET_REG_BIT(reg,SYSCNTR_ICW),GET_SYSCNTR_ISB(reg),
+ GET_REG_BIT(reg1,SYSCNTR_BDIS),GET_REG_BIT(reg1,SYSCNTR_PCIM));
+ printf("Switches: MUX=%ld PCI_DIS=%ld Boot_EN=%ld Config=%ld\n",GET_SDRAM_MUX(reg),
+ GET_REG_BIT(reg,SDRAM_PDIS),GET_REG_BIT(reg1,SYSCNTR_BOOTEN),
+ GET_SYSCNTR_CFG(reg1));
+ printf("Misc: RIP=%ld CPU_VPP=%ld FLSH_VPP=%ld FLSH_WP=%ld\n\n",
+ GET_REG_BIT(reg,SDRAM_RIP),GET_REG_BIT(reg1,SYSCNTR_CPU_VPP),
+ GET_REG_BIT(reg1,SYSCNTR_FL_VPP),GET_REG_BIT(reg1,SYSCNTR_FL_WP));
+}
+
+
+/****************************************************************
+ * Setting IOs
+ * -----------
+ * GPIO6 is User LED1
+ * GPIO7 is Interrupt PLX (Output)
+ * GPIO5 is User LED0
+ * GPIO2 is PLX USERi (Output)
+ * GPIO1 is PLX Interrupt (Input)
+ ****************************************************************/
+ void init_ios(void)
+ {
+ volatile immap_t * immr = (immap_t *) CONFIG_SYS_IMMR;
+ volatile sysconf5xx_t *sysconf = &immr->im_siu_conf;
+ unsigned long reg;
+ reg=sysconf->sc_sgpiocr; /* Data direction register */
+ reg &= ~0x67000000;
+ reg |= 0x27000000; /* set outpupts */
+ sysconf->sc_sgpiocr=reg; /* Data direction register */
+ reg=sysconf->sc_sgpiodt2; /* Data register */
+ /* set output to 0 */
+ reg &= ~0x27000000;
+ /* set IRQ and USERi to 1 */
+ reg |= 0x28000000;
+ sysconf->sc_sgpiodt2=reg; /* Data register */
+}
+
+void user_led0(int led_on)
+{
+ volatile immap_t * immr = (immap_t *) CONFIG_SYS_IMMR;
+ volatile sysconf5xx_t *sysconf = &immr->im_siu_conf;
+ unsigned long reg;
+ reg=sysconf->sc_sgpiodt2; /* Data register */
+ if(led_on) /* set output to 1 */
+ reg |= 0x04000000;
+ else
+ reg &= ~0x04000000;
+ sysconf->sc_sgpiodt2=reg; /* Data register */
+}
+
+void user_led1(int led_on)
+{
+ volatile immap_t * immr = (immap_t *) CONFIG_SYS_IMMR;
+ volatile sysconf5xx_t *sysconf = &immr->im_siu_conf;
+ unsigned long reg;
+ reg=sysconf->sc_sgpiodt2; /* Data register */
+ if(led_on) /* set output to 1 */
+ reg |= 0x02000000;
+ else
+ reg &= ~0x02000000;
+ sysconf->sc_sgpiodt2=reg; /* Data register */
+}
+
+
+/****************************************************************
+ * Last Stage Init
+ ****************************************************************/
+int last_stage_init (void)
+{
+ init_ios();
+ return 0;
+}
+
+/****************************************************************
+ * Check the board
+ ****************************************************************/
+
+#define BOARD_NAME "PATI"
+
+int checkboard (void)
+{
+ char s[50];
+ ulong reg;
+ char rev;
+ int i;
+
+ puts ("\nBoard: ");
+ reg=in32(PLD_CONFIG_BASE+PLD_BOARD_TIMING);
+ rev=(char)(SYSCNTR_BREV(reg)+'A');
+ i = getenv_f("serial#", s, 32);
+ if ((i == -1)) {
+ puts ("### No HW ID - assuming " BOARD_NAME);
+ printf(" Rev. %c\n",rev);
+ }
+ else {
+ s[sizeof(BOARD_NAME)-1] = 0;
+ printf ("%s-1 Rev %c SN: %s\n", s,rev,
+ &s[sizeof(BOARD_NAME)]);
+ }
+ set_flash_vpp(1,0,0); /* set Flash VPP */
+ return 0;
+}
+
+
+#ifdef CONFIG_SYS_PCI_CON_DEVICE
+/************************************************************************
+ * PCI Communication
+ *
+ * Alive (Pinging):
+ * ----------------
+ * PCI Host sends message ALIVE, Local acknowledges with ALIVE
+ *
+ * PCI_CON console over PCI:
+ * -------------------------
+ * Local side:
+ * - uses PCI9056_LOC_TO_PCI_DBELL register to signal that
+ * data is avaible (PCIMSG_CONN)
+ * - uses PCI9056_MAILBOX1 to send data
+ * - uses PCI9056_MAILBOX0 to receive data
+ * PCI side:
+ * - uses PCI9056_PCI_TO_LOC_DBELL register to signal that
+ * data is avaible (PCIMSG_CONN)
+ * - uses PCI9056_MAILBOX0 to send data
+ * - uses PCI9056_MAILBOX1 to receive data
+ *
+ * How it works:
+ * Send:
+ * - check if PCICON_TRANSMIT_REG is empty
+ * - write data or'ed with 0x80000000 into the PCICON_TRANSMIT_REG
+ * - write PCIMSG_CONN into the PCICON_DBELL_REG to signal a data
+ * is waiting
+ * Receive:
+ * - get an interrupt via the PCICON_ACK_REG register message
+ * PCIMSG_CONN
+ * - write the data from the PCICON_RECEIVE_REG into the receive
+ * buffer and if the receive buffer is not full, clear the
+ * PCICON_RECEIVE_REG (this allows the counterpart to write more data)
+ * - Clear the interrupt by writing 0xFFFFFFFF to the PCICON_ACK_REG
+ *
+ * The PCICON_RECEIVE_REG must be cleared by the routine which reads
+ * the receive buffer if the buffer is not full any more
+ *
+ */
+
+#undef PCI_CON_DEBUG
+
+#ifdef PCI_CON_DEBUG
+#define PCI_CON_PRINTF(fmt,args...) serial_printf (fmt ,##args)
+#else
+#define PCI_CON_PRINTF(fmt,args...)
+#endif
+
+
+/*********************************************************
+ * we work only with a receive buffer on eiter side.
+ * Transmit buffer is free, if mailbox is cleared.
+ * Transmit character is or'ed with 0x80000000
+ * PATI receive register MAILBOX0
+ * PATI transmit register MAILBOX1
+ *********************************************************/
+#define PCICON_RECEIVE_REG PCI9056_MAILBOX0
+#define PCICON_TRANSMIT_REG PCI9056_MAILBOX1
+#define PCICON_DBELL_REG PCI9056_LOC_TO_PCI_DBELL
+#define PCICON_ACK_REG PCI9056_PCI_TO_LOC_DBELL
+
+
+#define PCIMSG_ALIVE 0x1
+#define PCIMSG_CONN 0x2
+#define PCIMSG_DISC 0x3
+#define PCIMSG_CON_DATA 0x5
+
+
+#define PCICON_GET_REG(x) (in32(x + PCI_CONFIG_BASE))
+#define PCICON_SET_REG(x,y) (out32(x + PCI_CONFIG_BASE,y))
+#define PCICON_TX_FLAG 0x80000000
+
+
+#define REC_BUFFER_SIZE 0x100
+int recbuf[REC_BUFFER_SIZE];
+static int r_ptr = 0;
+int w_ptr;
+struct stdio_dev pci_con_dev;
+int conn=0;
+int buff_full=0;
+
+void pci_con_put_it(const char c)
+{
+ /* Test for completition */
+ unsigned long reg;
+ do {
+ reg=PCICON_GET_REG(PCICON_TRANSMIT_REG);
+ }while(reg);
+ reg=PCICON_TX_FLAG + c;
+ PCICON_SET_REG(PCICON_TRANSMIT_REG,reg);
+ PCICON_SET_REG(PCICON_DBELL_REG,PCIMSG_CON_DATA);
+}
+
+void pci_con_putc(const char c)
+{
+ pci_con_put_it(c);
+ if(c == '\n')
+ pci_con_put_it('\r');
+}
+
+
+int pci_con_getc(void)
+{
+ int res;
+ int diff;
+ while(r_ptr==(volatile int)w_ptr);
+ res=recbuf[r_ptr++];
+ if(r_ptr==REC_BUFFER_SIZE)
+ r_ptr=0;
+ if(w_ptr<r_ptr)
+ diff=r_ptr+REC_BUFFER_SIZE-w_ptr;
+ else
+ diff=r_ptr-w_ptr;
+ if((diff<(REC_BUFFER_SIZE-4)) && buff_full) {
+ /* clear Mail box */
+ buff_full=0;
+ PCICON_SET_REG(PCICON_RECEIVE_REG,0L);
+ }
+ return res;
+}
+
+int pci_con_tstc(void)
+{
+ if(r_ptr==(volatile int)w_ptr)
+ return 0;
+ return 1;
+}
+
+void pci_con_puts (const char *s)
+{
+ while (*s) {
+ pci_con_putc(*s);
+ ++s;
+ }
+}
+
+void pci_con_init (void)
+{
+ w_ptr = 0;
+ r_ptr = 0;
+ PCICON_SET_REG(PCICON_RECEIVE_REG,0L);
+ conn=1;
+}
+
+/*******************************************
+ * IRQ routine
+ ******************************************/
+int pci_dorbell_irq(void)
+{
+ unsigned long reg,data;
+ int diff;
+ reg=PCICON_GET_REG(PCI9056_INT_CTRL_STAT);
+ PCI_CON_PRINTF(" PCI9056_INT_CTRL_STAT = %08lX\n",reg);
+ if(reg & (1<<20) ) {
+ /* read doorbell */
+ reg=PCICON_GET_REG(PCICON_ACK_REG);
+ switch(reg) {
+ case PCIMSG_ALIVE:
+ PCI_CON_PRINTF(" Alive\n");
+ PCICON_SET_REG(PCICON_DBELL_REG,PCIMSG_ALIVE);
+ break;
+ case PCIMSG_CONN:
+ PCI_CON_PRINTF(" Conn %d",conn);
+ w_ptr = 0;
+ r_ptr = 0;
+ buff_full=0;
+ PCICON_SET_REG(PCICON_RECEIVE_REG,0L);
+ conn=1;
+ PCI_CON_PRINTF(" ... %d\n",conn);
+ break;
+ case PCIMSG_CON_DATA:
+ data=PCICON_GET_REG(PCICON_RECEIVE_REG);
+ recbuf[w_ptr++]=(int)(data&0xff);
+ PCI_CON_PRINTF(" Data Console %lX, %X %d %d %X\n",data,((int)(data&0xFF)),
+ r_ptr,w_ptr,recbuf[w_ptr-1]);
+ if(w_ptr==REC_BUFFER_SIZE)
+ w_ptr=0;
+ if(w_ptr<r_ptr)
+ diff=r_ptr+REC_BUFFER_SIZE-w_ptr;
+ else
+ diff=r_ptr-w_ptr;
+ if(diff>(REC_BUFFER_SIZE-4))
+ buff_full=1;
+ else
+ /* clear Mail box */
+ PCICON_SET_REG(PCICON_RECEIVE_REG,0L);
+ break;
+ default:
+ serial_printf(" PCI9056_PCI_TO_LOC_DBELL = %08lX\n",reg);
+ }
+ /* clear IRQ */
+ PCICON_SET_REG(PCICON_ACK_REG,~0L);
+ }
+ return 0;
+}
+
+void pci_con_connect(void)
+{
+ unsigned long reg;
+ conn=0;
+ reg=PCICON_GET_REG(PCI9056_INT_CTRL_STAT);
+ /* default 0x0f010180 */
+ reg &= 0xff000000;
+ reg |= 0x00030000; /* enable local dorbell */
+ reg |= 0x00000300; /* enable PCI dorbell */
+ PCICON_SET_REG(PCI9056_INT_CTRL_STAT , reg);
+ irq_install_handler (0x2, (interrupt_handler_t *) pci_dorbell_irq,NULL);
+ memset (&pci_con_dev, 0, sizeof (pci_con_dev));
+ strcpy (pci_con_dev.name, "pci_con");
+ pci_con_dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
+ pci_con_dev.putc = pci_con_putc;
+ pci_con_dev.puts = pci_con_puts;
+ pci_con_dev.getc = pci_con_getc;
+ pci_con_dev.tstc = pci_con_tstc;
+ stdio_register (&pci_con_dev);
+ printf("PATI ready for PCI connection, type ctrl-c for exit\n");
+ do {
+ udelay(10);
+ if((volatile int)conn)
+ break;
+ if(ctrlc()) {
+ irq_free_handler(0x2);
+ return;
+ }
+ }while(1);
+ console_assign(stdin,"pci_con");
+ console_assign(stderr,"pci_con");
+ console_assign(stdout,"pci_con");
+}
+
+void pci_con_disc(void)
+{
+ console_assign(stdin,"serial");
+ console_assign(stderr,"serial");
+ console_assign(stdout,"serial");
+ PCICON_SET_REG(PCICON_DBELL_REG,PCIMSG_DISC);
+ /* reconnection */
+ irq_free_handler(0x02);
+ pci_con_connect();
+}
+#endif /* #ifdef CONFIG_SYS_PCI_CON_DEVICE */
+
+/*
+ * Absolute environment address for linker file.
+ */
+GEN_ABS(env_start, CONFIG_ENV_OFFSET + CONFIG_SYS_FLASH_BASE);
diff --git a/u-boot/board/mpl/pati/pati.h b/u-boot/board/mpl/pati/pati.h
new file mode 100644
index 0000000..86c7a41
--- /dev/null
+++ b/u-boot/board/mpl/pati/pati.h
@@ -0,0 +1,440 @@
+/*
+ * (C) Copyright 2003
+ * Denis Peter, d.peter@mpl.ch
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+/************************************************************************
+ * MACROS and register definitions for PATI Registers
+ ************************************************************************/
+#ifndef __PATI_H_
+#define __PATI_H_ 1
+
+#define PLD_PART_ID 0x0
+#define PLD_BOARD_TIMING 0x4
+#define PLD_CONF_REG1 0x8
+#define PLD_CONF_REG2 0xC
+#define PLD_CONF_RES 0x10
+
+#define SET_REG_BIT(y,x) (y<<(31-x))
+#define GET_REG_BIT(y,x) ((y>>(31-x)) & 0x1L)
+
+/* SDRAM Controller PLD_PART_ID */
+/* 9 10 11 12 13 14 19 31 */
+#define SDRAM_PART3 9
+#define SDRAM_PART2 10
+#define SDRAM_PART1 11
+#define SDRAM_PART0 12
+#define SDRAM_ID3 13
+#define SDRAM_ID2 14
+#define SDRAM_ID1 19
+#define SDRAM_ID0 31
+
+#define SDRAM_PART(x) ( \
+ (GET_REG_BIT(x,SDRAM_PART3)<<3) |\
+ (GET_REG_BIT(x,SDRAM_PART2)<<2) |\
+ (GET_REG_BIT(x,SDRAM_PART1)<<1) |\
+ (GET_REG_BIT(x,SDRAM_PART0)))
+
+#define SDRAM_ID(x) ( \
+ (GET_REG_BIT(x,SDRAM_ID3)<<3) |\
+ (GET_REG_BIT(x,SDRAM_ID2)<<2) |\
+ (GET_REG_BIT(x,SDRAM_ID1)<<1) |\
+ (GET_REG_BIT(x,SDRAM_ID0)))
+
+/* System Controller */
+/* 0 1 3 4 5 16 20 28 29 30 */
+#define SYSCNTR_PART4 0
+#define SYSCNTR_PART3 1
+#define SYSCNTR_PART2 3
+#define SYSCNTR_PART1 4
+#define SYSCNTR_PART0 5
+#define SYSCNTR_ID4 16
+#define SYSCNTR_ID3 20
+#define SYSCNTR_ID2 28
+#define SYSCNTR_ID1 29
+#define SYSCNTR_ID0 30
+
+#define SYSCNTR_PART(x) ( \
+ (GET_REG_BIT(x,SYSCNTR_PART4)<<4) |\
+ (GET_REG_BIT(x,SYSCNTR_PART3)<<3) |\
+ (GET_REG_BIT(x,SYSCNTR_PART2)<<2) |\
+ (GET_REG_BIT(x,SYSCNTR_PART1)<<1) |\
+ (GET_REG_BIT(x,SYSCNTR_PART0)))
+
+#define SYSCNTR_ID(x) ( \
+ (GET_REG_BIT(x,SYSCNTR_ID4)<<4) |\
+ (GET_REG_BIT(x,SYSCNTR_ID3)<<3) |\
+ (GET_REG_BIT(x,SYSCNTR_ID2)<<2) |\
+ (GET_REG_BIT(x,SYSCNTR_ID1)<<1) |\
+ (GET_REG_BIT(x,SYSCNTR_ID0)))
+
+/* SDRAM Controller PLD_BOARD_TIMING */
+/* 9 10 11 12 13 14 19 31 */
+#define SDRAM_CAL 9
+#define SDRAM_RCD 10
+#define SDRAM_WREQ 11
+#define SDRAM_PR 12
+#define SDRAM_RC 13
+#define SDRAM_LMR 14
+#define SDRAM_IIP 19
+#define SDRAM_RES0 31
+/* System Controller */
+/* 0 1 3 4 5 16 20 28 29 30 */
+#define SYSCNTR_BREV0 0
+#define SYSCNTR_BREV1 1
+#define SYSCNTR_BREV2 3
+#define SYSCNTR_BREV3 4
+#define SYSCNTR_RES0 5
+#define SYSCNTR_RES1 16
+#define SYSCNTR_RES2 20
+#define SYSCNTR_FLWAIT2 28
+#define SYSCNTR_FLWAIT1 29
+#define SYSCNTR_FLWAIT0 30
+
+#define SYSCNTR_BREV(x) ( \
+ (GET_REG_BIT(x,SYSCNTR_BREV3)<<3) |\
+ (GET_REG_BIT(x,SYSCNTR_BREV2)<<2) |\
+ (GET_REG_BIT(x,SYSCNTR_BREV1)<<1) |\
+ (GET_REG_BIT(x,SYSCNTR_BREV0)))
+
+#define GET_SYSCNTR_FLWAIT(x) ( \
+ (GET_REG_BIT(x,SYSCNTR_FLWAIT2)<<2) |\
+ (GET_REG_BIT(x,SYSCNTR_FLWAIT1)<<1) |\
+ (GET_REG_BIT(x,SYSCNTR_FLWAIT0)))
+
+#define SET_SYSCNTR_FLWAIT(x) ( \
+ (SET_REG_BIT(((x & 0x04)!=0),SYSCNTR_FLWAIT2)) |\
+ (SET_REG_BIT(((x & 0x02)!=0)x,SYSCNTR_FLWAIT1)) |\
+ (SET_REG_BIT(((x & 0x01)!=0)x,SYSCNTR_FLWAIT0)))
+
+/* SDRAM Controller REG 2*/
+/* 9 10 11 12 13 14 19 31 */
+#define SDRAM_MUX0 9
+#define SDRAM_MUX1 10
+#define SDRAM_PDIS 11
+#define SDRAM_RES1 12
+#define SDRAM_RES2 13
+#define SDRAM_RES3 14
+#define SDRAM_RES4 19
+#define SDRAM_RIP 31
+
+#define GET_SDRAM_MUX(x) ( \
+ (GET_REG_BIT(x,SDRAM_MUX1)<<1)| \
+ (GET_REG_BIT(x,SDRAM_MUX0)))
+
+
+/* System Controller */
+/* 0 1 3 4 5 16 20 28 29 30 */
+#define SYSCNTR_FLAG 0
+#define SYSCNTR_IP 1
+#define SYSCNTR_BIND2 3
+#define SYSCNTR_BIND1 4
+#define SYSCNTR_BIND0 5
+#define SYSCNTR_PRM 16
+#define SYSCNTR_ICW 20
+#define SYSCNTR_ISB2 28
+#define SYSCNTR_ISB1 29
+#define SYSCNTR_ISB0 30
+
+#define GET_SYSCNTR_BOOTIND(x) ( \
+ (GET_REG_BIT(x,SYSCNTR_BIND2)<<2) |\
+ (GET_REG_BIT(x,SYSCNTR_BIND1)<<1) |\
+ (GET_REG_BIT(x,SYSCNTR_BIND0)))
+
+#define SET_SYSCNTR_BOOTIND(x) ( \
+ (SET_REG_BIT(((x & 0x04)!=0),SYSCNTR_BIND2)) |\
+ (SET_REG_BIT(((x & 0x02)!=0)x,SYSCNTR_BIND1))| \
+ (SET_REG_BIT(((x & 0x01)!=0)x,SYSCNTR_BIND0)))
+
+#define GET_SYSCNTR_ISB(x) ( \
+ (GET_REG_BIT(x,SYSCNTR_ISB2)<<2)| \
+ (GET_REG_BIT(x,SYSCNTR_ISB1)<<1)| \
+ (GET_REG_BIT(x,SYSCNTR_ISB0)))
+
+#define SET_SYSCNTR_ISB(x) ( \
+ (SET_REG_BIT(((x & 0x04)!=0),SYSCNTR_ISB2))| \
+ (SET_REG_BIT(((x & 0x02)!=0)x,SYSCNTR_ISB))| \
+ (SET_REG_BIT(((x & 0x01)!=0)x,SYSCNTR_ISB0)))
+
+/* SDRAM Controller REG 3*/
+/* 9 10 11 12 13 14 19 31 */
+#define SDRAM_RES5 9
+#define SDRAM_CFG1 10
+#define SDRAM_CFG2 11
+#define SDRAM_CFG3 12
+#define SDRAM_RES6 13
+#define SDRAM_CFG5 14
+#define SDRAM_CFG6 19
+#define SDRAM_RES7 31
+
+#define GET_SDRAM_CFG(x) ( \
+ (GET_REG_BIT(x,SDRAM_CFG6)<<4) |\
+ (GET_REG_BIT(x,SDRAM_CFG5)<<3) |\
+ (GET_REG_BIT(x,SDRAM_CFG3)<<2) |\
+ (GET_REG_BIT(x,SDRAM_CFG2)<<1) |\
+ (GET_REG_BIT(x,SDRAM_CFG1)))
+
+/* System Controller */
+/* 0 1 3 4 5 16 20 28 29 30 */
+#define SYSCNTR_BDIS 0
+#define SYSCNTR_PCIM 1
+#define SYSCNTR_CFG0 3
+#define SYSCNTR_CFG1 4
+#define SYSCNTR_CFG2 5
+#define SYSCNTR_CFG3 16
+#define SYSCNTR_BOOTEN 20
+#define SYSCNTR_CPU_VPP 28
+#define SYSCNTR_FL_VPP 29
+#define SYSCNTR_FL_WP 30
+
+#define GET_SYSCNTR_CFG(x) ( \
+ (GET_REG_BIT(x,SYSCNTR_CFG3)<<3)| \
+ (GET_REG_BIT(x,SYSCNTR_CFG2)<<2)| \
+ (GET_REG_BIT(x,SYSCNTR_CFG1)<<1)| \
+ (GET_REG_BIT(x,SYSCNTR_CFG0)))
+
+
+/***************************************************************
+ * MISC Defines
+ ***************************************************************/
+
+#define PCI_VENDOR_ID_MPL 0x18E6
+#define PCI_DEVICE_ID_PATI 0x00DA
+
+#if defined(CONFIG_MIP405)
+#define PATI_FIRMWARE_START_OFFSET 0x00300000
+#define PATI_ISO_STRING "MEV-10084-001"
+#endif
+
+#define PATI_ENDIAN_MODE 0x3E
+
+/*******************************************
+ * PATI Mapping:
+ * -------------
+ * PCI Map:
+ * -------
+ * All addreses are mapped into the memory area
+ * (IO Area on some areas may also be possible)
+ * - pci_cfg_mem_base: fixed address to the PLX config area size 512Bytes
+ * - pci_space0_addr: configurable
+ * - pci_space1_addr configurable
+ *
+ * Local Map:
+ * ----------
+ * Local addresses (Remap)
+ * - SDRAM 0x06000000 Size 16MByte mask 0xff000000
+ * - EPLD CFG 0x07000000 Size 512Bytes
+ * - FLASH 0x03000000 Size up to 8MByte
+ * - CPU 0x01000000 Size 4MByte (only accessable if special configured)
+ *
+ * Implemention:
+ * -------------
+ * To prevent using large resources reservation on the host following
+ * PCI mapping is choosed:
+ * - pci_cfg_mem_base: fixed address to the PLX config area size 512Bytes
+ * - pci_space0_addr: configured to the EPLD Config Area size 256Bytes
+ * - pci_space1_addr: configured to the SDRAM Area size 1MBytes, this
+ * space is used to switch between SDRAM, Flash and CPU
+ *
+ */
+
+/* Attribute definitions */
+#define PATI_BUS_SIZE_8 0
+#define PATI_BUS_SIZE_16 1
+#define PATI_BUS_SIZE_32 3
+
+#define PATI_SPACE0_MASK (0xFEFFFE00) /* Mask Attributes */
+#define PATI_SPACE1_MASK (0x00000000) /* Mask Attributes */
+
+#define PATI_EXTRA_LONG_EEPROM 1
+
+#define SPACE0_TA_ENABLE (1<<6)
+#define SPACE1_TA_ENABLE (1<<6)
+
+/* Config Area */
+#define PATI_LOC_CFG_ADDR 0x07000000 /* Local Address */
+#define PATI_LOC_CFG_MASK 0xFFFFFF00 /* 256 Bytes */
+/* Attributes */
+#define PATI_LOC_CFG_BUS_SIZE PATI_BUS_SIZE_32 /* 32 Bit */
+#define PATI_LOC_CFG_BURST 0 /* No Burst */
+#define PATI_LOC_CFG_NO_PREFETCH 1 /* No Prefetch */
+#define PATI_LOC_CFG_TA_ENABLE 1 /* Enable TA */
+
+#define PATI_LOC_CFG_SPACE0_ATTR ( \
+ PATI_LOC_CFG_BUS_SIZE | \
+ (PATI_LOC_CFG_TA_ENABLE << 6) | \
+ (PATI_LOC_CFG_NO_PREFETCH << 8) | \
+ (PATI_LOC_CFG_BURST << 24) | \
+ (PATI_EXTRA_LONG_EEPROM << 25))
+
+/* should never be used */
+#define PATI_LOC_CFG_SPACE1_ATTR ( \
+ PATI_LOC_CFG_BUS_SIZE | \
+ (PATI_LOC_CFG_TA_ENABLE << 6) | \
+ (PATI_LOC_CFG_NO_PREFETCH << 9) | \
+ (PATI_LOC_CFG_BURST << 8))
+
+
+/* SDRAM Area */
+#define PATI_LOC_SDRAM_ADDR 0x06000000 /* Local Address */
+#define PATI_LOC_SDRAM_MASK 0xFFF00000 /* 1MByte */
+/* Attributes */
+#define PATI_LOC_SDRAM_BUS_SIZE PATI_BUS_SIZE_32 /* 32 Bit */
+#define PATI_LOC_SDRAM_BURST 0 /* No Burst */
+#define PATI_LOC_SDRAM_NO_PREFETCH 0 /* Prefetch */
+#define PATI_LOC_SDRAM_TA_ENABLE 1 /* Enable TA */
+
+/* should never be used */
+#define PATI_LOC_SDRAM_SPACE0_ATTR ( \
+ PATI_LOC_SDRAM_BUS_SIZE | \
+ (PATI_LOC_SDRAM_TA_ENABLE << 6) | \
+ (PATI_LOC_SDRAM_NO_PREFETCH << 8) | \
+ (PATI_LOC_SDRAM_BURST << 24) | \
+ (PATI_EXTRA_LONG_EEPROM << 25))
+
+#define PATI_LOC_SDRAM_SPACE1_ATTR ( \
+ PATI_LOC_SDRAM_BUS_SIZE | \
+ (PATI_LOC_SDRAM_TA_ENABLE << 6) | \
+ (PATI_LOC_SDRAM_NO_PREFETCH << 9) | \
+ (PATI_LOC_SDRAM_BURST << 8))
+
+
+/* Flash Area */
+#define PATI_LOC_FLASH_ADDR 0x03000000 /* Local Address */
+#define PATI_LOC_FLASH_MASK 0xFFF00000 /* 1MByte */
+/* Attributes */
+#define PATI_LOC_FLASH_BUS_SIZE PATI_BUS_SIZE_16 /* 16 Bit */
+#define PATI_LOC_FLASH_BURST 0 /* No Burst */
+#define PATI_LOC_FLASH_NO_PREFETCH 1 /* No Prefetch */
+#define PATI_LOC_FLASH_TA_ENABLE 1 /* Enable TA */
+
+/* should never be used */
+#define PATI_LOC_FLASH_SPACE0_ATTR ( \
+ PATI_LOC_FLASH_BUS_SIZE | \
+ (PATI_LOC_FLASH_TA_ENABLE << 6) | \
+ (PATI_LOC_FLASH_NO_PREFETCH << 8) | \
+ (PATI_LOC_FLASH_BURST << 24) | \
+ (PATI_EXTRA_LONG_EEPROM << 25))
+
+#define PATI_LOC_FLASH_SPACE1_ATTR ( \
+ PATI_LOC_FLASH_BUS_SIZE | \
+ (PATI_LOC_FLASH_TA_ENABLE << 6) | \
+ (PATI_LOC_FLASH_NO_PREFETCH << 9) | \
+ (PATI_LOC_FLASH_BURST << 8))
+
+
+/* CPU Area */
+#define PATI_LOC_CPU_ADDR 0x01000000 /* Local Address */
+#define PATI_LOC_CPU_MASK 0xFFF00000 /* 1Mbyte */
+/* Attributes */
+#define PATI_LOC_CPU_BUS_SIZE PATI_BUS_SIZE_32 /* 32 Bit */
+#define PATI_LOC_CPU_BURST 0 /* No Burst */
+#define PATI_LOC_CPU_NO_PREFETCH 1 /* No Prefetch */
+#define PATI_LOC_CPU_TA_ENABLE 1 /* Enable TA */
+
+/* should never be used */
+#define PATI_LOC_CPU_SPACE0_ATTR ( \
+ PATI_LOC_CPU_BUS_SIZE | \
+ (PATI_LOC_CPU_TA_ENABLE << 6) | \
+ (PATI_LOC_CPU_NO_PREFETCH << 8) | \
+ (PATI_LOC_CPU_BURST << 24) | \
+ (PATI_EXTRA_CPU_EEPROM << 25))
+
+#define PATI_LOC_CPU_SPACE1_ATTR ( \
+ PATI_LOC_CPU_BUS_SIZE | \
+ (PATI_LOC_CPU_TA_ENABLE << 6) | \
+ (PATI_LOC_CPU_NO_PREFETCH << 9) | \
+ (PATI_LOC_CPU_BURST << 8))
+
+/***************************************************
+ * Hardware Config word definition
+ ***************************************************/
+#define BOOT_EXT_FLASH 0x00000000
+#define BOOT_INT_FLASH 0x00000004
+#define BOOT_FROM_PCI 0x00000006
+#define BOOT_FROM_SDRAM 0x00000005
+
+#define ENABLE_INT_ARB 0x00000008
+
+#define INITIAL_IRQ_PREF 0x00000010
+
+#define INITIAL_MEM_0M 0x00000000
+#define INITIAL_MEM_4M 0x00000080
+#define INITIAL_MEM_8M 0x00000040
+#define INITIAL_MEM_12M 0x000000C0
+#define INITIAL_MEM_16M 0x00000020
+#define INITIAL_MEM_20M 0x000000A0
+#define INITIAL_MEM_24M 0x00000060
+#define INITIAL_MEM_28M 0x000000E0
+/* CONF */
+#define INTERNAL_HWCONF 0x00000100
+/* PRPM */
+#define LOCAL_CPU_SLAVE 0x00000200
+/* BDIS */
+#define DISABLE_MEM_CNTR 0x00000400
+/* PCIM */
+#define PCI_MASTER_ONLY 0x00000800
+
+
+#define PATI_HW_START ((BOOT_EXT_FLASH | INITIAL_MEM_28M | INITIAL_IRQ_PREF))
+#define PATI_HW_PCI_ONLY ((BOOT_EXT_FLASH | INITIAL_MEM_28M | INITIAL_IRQ_PREF | PCI_MASTER_ONLY))
+#define PATI_HW_CPU_ACC ((BOOT_EXT_FLASH | INITIAL_MEM_12M | INITIAL_IRQ_PREF | PCI_MASTER_ONLY))
+#define PATI_HW_CPU_SLAVE ((BOOT_EXT_FLASH | INITIAL_MEM_12M | INITIAL_IRQ_PREF | PCI_MASTER_ONLY | LOCAL_CPU_SLAVE))
+
+/***************************************************
+ * Direct Master Config
+ ***************************************************/
+#define PATI_DMASTER_PCI_ADDR 0x01000000
+#define PATI_BUS_MASTER 1
+
+
+#define PATI_DMASTER_MASK 0xFFF00000 /* 1MByte */
+#define PATI_DMASTER_ADDR 0x01000000 /* Local Address */
+
+#define PATI_DMASTER_MEMORY_EN 0x00000001 /* 0x00000001 */
+#define PATI_DMASTER_READ_AHEAD 0x00000004 /* 0x00000004 */
+#define PATI_DMASTER_READ_NOT_AHEAD 0x00000000 /* 0x00000004 */
+#define PATI_DMASTER_PRE_SIZE_CNTRL_0 0x00000000
+#define PATI_DMASTER_PRE_SIZE_CNTRL_4 0x00000008
+#define PATI_DMASTER_PRE_SIZE_CNTRL_8 0x00001000
+#define PATI_DMASTER_PRE_SIZE_CNTRL_16 0x00001008
+#define PATI_DMASTER_REL_PCI 0x00000000
+#define PATI_DMASTER_NOT_REL_PCI 0x00000010
+#define PATI_DMASTER_WR_INVAL 0x00000200
+#define PATI_DMASTER_NOT_WR_INVAL 0x00000000
+#define PATI_DMASTER_PRE_LIMIT 0x00000800
+#define PATI_DMASTER_PRE_CONT 0x00000000
+#define PATI_DMASTER_DELAY_WR_0 0x00000000
+#define PATI_DMASTER_DELAY_WR_4 0x00004000
+#define PATI_DMASTER_DELAY_WR_8 0x00008000
+#define PATI_DMASTER_DELAY_WR_16 0x0000C000
+
+#define PATI_DMASTER_PCI_ADDR_MASK 0xFFFF0000
+
+#define PATI_DMASTER_ATTR \
+ PATI_DMASTER_MEMORY_EN | \
+ PATI_DMASTER_READ_AHEAD | \
+ PATI_DMASTER_PRE_SIZE_CNTRL_4 | \
+ PATI_DMASTER_REL_PCI | \
+ PATI_DMASTER_NOT_WR_INVAL | \
+ PATI_DMASTER_PRE_LIMIT | \
+ PATI_DMASTER_DELAY_WR_0
+
+
+#endif /* #ifndef __PATI_H_ */
diff --git a/u-boot/board/mpl/pati/pci_eeprom.h b/u-boot/board/mpl/pati/pci_eeprom.h
new file mode 100644
index 0000000..af34b86
--- /dev/null
+++ b/u-boot/board/mpl/pati/pci_eeprom.h
@@ -0,0 +1,91 @@
+
+#ifndef __PCI_EEPROM_H_
+#define __PCI_EEPROM_H_ 1
+
+#include "pati.h"
+/******************************************************************************
+ * Eeprom Support
+ ******************************************************************************/
+/**********************************************
+* Definitions
+**********************************************/
+#define EE46_CMD_LEN 9 /* Bits in instructions */
+#define EE56_CMD_LEN 11 /* Bits in instructions */
+#define EE66_CMD_LEN 11 /* Bits in instructions */
+#define EE_READ 0x0180 /* 01 1000 0000 read instruction */
+#define EE_WRITE 0x0140 /* 01 0100 0000 write instruction */
+#define EE_WREN 0x0130 /* 01 0011 0000 write enable instruction */
+#define EE_WRALL 0x0110 /* 01 0001 0000 write all registers */
+#define EE_PRREAD 0x0180 /* 01 1000 0000 read address stored in Protect Register */
+#define EE_PRWRITE 0x0140 /* 01 0100 0000 write the address into PR */
+#define EE_WDS 0x0100 /* 01 0000 0000 write disable instruction */
+#define EE_PREN 0x0130 /* 01 0011 0000 protect enable instruction */
+#define EE_PRCLEAR 0x01FF /* 01 1111 1111 clear protect register instr */
+#define EE_PRDS 0x0100 /* 01 0000 0000 ONE TIME ONLY, permenant */
+
+/***************************************************
+ * EEPROM
+ ***************************************************/
+#define LOW_WORD(x) (((x) & 0xFFFF))
+#define HIGH_WORD(x) (((x) >> 16) & 0xFFFF)
+
+typedef struct pci_eeprom_t {
+ unsigned short offset;
+ unsigned short value;
+} pci_eeprom;
+
+static pci_eeprom pati_eeprom[] = {
+ { 0x00,PCI_DEVICE_ID_PATI }, /* PCI Device ID PCIIDR[31:16] */
+ { 0x02,PCI_VENDOR_ID_MPL }, /* PCI Vendor ID PCIIDR[15:0] */
+ { 0x04,PCI_CLASS_PROCESSOR_POWERPC }, /* PCI Class Code PCICCR[23:8] */
+ { 0x06,0x00BA }, /* PCI Class Code / PCI Revision ID PCICCR[7:0] / PCIREV[7:0] */
+ { 0x08,0x0007 }, /* PCI Maximum Latency / PCI Minimum Grant PCIMLR[7:0] / PCIMGR[7:0] */
+ { 0x0A,0x0100 }, /* PCI Interrupt Pin / PCI Interrupt Line PCIIPR[7:0] / PCIILR[7:0] */
+ { 0x0C,0x0000 }, /* MSW of Mailbox 0 (User Defined) PCI9056_MAILBOX0[31:16] */
+ { 0x0E,0x0000 }, /* LSW of Mailbox 0 (User Defined) PCI9056_MAILBOX0[15:0] */
+ { 0x10,0x0000 }, /* MSW of Mailbox 1 (User Defined) PCI9056_MAILBOX1[31:16] */
+ { 0x12,0x0000 }, /* LSW of Mailbox 1 (User Defined) PCI9056_MAILBOX1[15:0] */
+ { 0x14,HIGH_WORD(PATI_LOC_CFG_MASK) }, /* MSW of Direct Slave Local Address Space 0 Range LAS0RR[31:16] */
+ { 0x16,LOW_WORD(PATI_LOC_CFG_MASK) }, /* LSW of Direct Slave Local Address Space 0 Range LAS0RR[15:0] */
+ { 0x18,HIGH_WORD(PATI_LOC_CFG_ADDR) }, /* MSW of Direct Slave Local Address Space 0 Local Base Address (Remap) LAS0BA[31:16] (CFG) */
+ { 0x1A,LOW_WORD(PATI_LOC_CFG_ADDR)|1 }, /* LSW of Direct Slave Local Address Space 0 Local Base Address (Remap) LAS0BA[15:2, 0], Reserved [1] */
+ { 0x1C,0x0000 }, /* MSW of Mode/DMA Arbitration MARBR[31, 29:16] or DMAARB[31, 29:16], Reserved [30] */
+ { 0x1E,0x0000 }, /* LSW of Mode/DMA Arbitration MARBR[15:0] or DMAARB[15:0] */
+ { 0x20,0x0030 }, /* Local Miscellaneous Control 2 / Serial EEPROM WP Addr Boundary LMISC2[5:0], Res[7:6] / PROT_AREA[6:0], Res[7] */
+ { 0x22,0x0510 }, /* Local Miscellaneous Control 1 / Local Bus Big/Little Endian Descriptor LMISC1[7:0] / BIGEND[7:0] */
+ { 0x24,0x0000 }, /* MSW of Direct Slave Expansion ROM Range EROMRR[31:16] */
+ { 0x26,0x0000 }, /* LSW of Direct Slave Expansion ROM Range EROMRR[15:11, 0], Reserved [10:1] */
+ { 0x28,0x0000 }, /* MSW of Direct Slave Expansion ROM Local Base Address (Remap) and BREQo Control EROMBA[31:16] */
+ { 0x2A,0x0000 }, /* LSW of Direct Slave Expansion ROM Local Base Address (Remap) and BREQo Control EROMBA[15:11, 5:0], Reserved [10:6] */
+ { 0x2C,(0x4243 | HIGH_WORD((PATI_LOC_CFG_SPACE0_ATTR))) }, /* MSW of Local Address Space 0/Expansion ROM Bus Region Descriptor LBRD0[31:16] */
+ { 0x2E,LOW_WORD(PATI_LOC_CFG_SPACE0_ATTR) }, /* LSW of Local Address Space 0/Expansion ROM Bus Region Descriptor LBRD0[15:0] */
+ { 0x30,HIGH_WORD(PATI_DMASTER_MASK) }, /* MSW of Local Range for Direct Master-to-PCI DMRR[31:16] */
+ { 0x32,LOW_WORD(PATI_DMASTER_MASK) }, /* LSW of Local Range for Direct Master-to-PCI (Reserved) DMRR[15:0] */
+ { 0x34,HIGH_WORD(PATI_DMASTER_ADDR) }, /* MSW of Local Base Address for Direct Master-to-PCI Memory DMLBAM[31:16] */
+ { 0x36,LOW_WORD(PATI_DMASTER_ADDR) }, /* LSW of Local Base Address for Direct Master-to-PCI Memory (Reserved) DMLBAM[15:0] */
+ { 0x38,0x0000 }, /* MSW of Local Bus Address for Direct Master-to-PCI I/O Configuration DMLBAI[31:16] */
+ { 0x3A,0x0000 }, /* LSW of Local Bus Address for Direct Master-to-PCI I/O Configuration (Reserved) DMLBAI[15:0] */
+ { 0x3C,0x0000 }, /* MSW of PCI Base Address (Remap) for Direct Master-to-PCI Memory DMPBAM[31:16] */
+ { 0x3E,0x0000 }, /* LSW of PCI Base Address (Remap) for Direct Master-to-PCI Memory DMPBAM[15:0] */
+ { 0x40,0x0000 }, /* MSW of PCI Configuration Address for Direct Master-to-PCI I/O Configuration DMCFGA[31, 23:16] Reserved [30:24]*/
+ { 0x42,0x0000 }, /* LSW of PCI Configuration Address for Direct Master-to-PCI I/O Configuration DMCFGA[15:0] */
+ { 0x44,0x0000 }, /* PCI Subsystem ID PCISID[15:0] */
+ { 0x46,0x0000 }, /* PCI Subsystem Vendor ID PCISVID[15:0] */
+ { 0x48,HIGH_WORD(PATI_LOC_SDRAM_MASK) }, /* MSW of Direct Slave Local Address Space 1 Range (1 MB) LAS1RR[31:16] */
+ { 0x4A,LOW_WORD(PATI_LOC_SDRAM_MASK) }, /* LSW of Direct Slave Local Address Space 1 Range (1 MB) LAS1RR[15:0] */
+ { 0x4C,HIGH_WORD(PATI_LOC_SDRAM_ADDR) }, /* MSW of Direct Slave Local Address Space 1 Local Base Address (Remap) LAS1BA[31:16] (SDRAM) */
+ { 0x4E,LOW_WORD(PATI_LOC_SDRAM_ADDR) | 0x1 }, /* LSW of Direct Slave Local Address Space 1 Local Base Address (Remap) LAS1BA[15:2, 0], Reserved [1] */
+ { 0x50,HIGH_WORD(PATI_LOC_SDRAM_SPACE1_ATTR) }, /* MSW of Local Address Space 1 Bus Region Descriptor LBRD1[31:16] */
+ { 0x52,LOW_WORD(PATI_LOC_SDRAM_SPACE1_ATTR) }, /* LSW of Local Address Space 1 Bus Region Descriptor (Reserved) LBRD1[15:0] */
+ { 0x54,0x0000 }, /* Hot Swap Control/Status (Reserved) Reserved */
+ { 0x56,0x0000 }, /* Hot Swap Next Capability Pointer / Hot Swap Control HS_NEXT[7:0] / HS_CNTL[7:0] */
+ { 0x58,0x0000 }, /* Reserved Reserved */
+ { 0x5A,0x0000 }, /* PCI Arbiter Control PCIARB[3:0], Reserved [15:4] */
+ { 0x5C,0x0000 }, /* Power Management Capabilities PMC[15:9, 2:0] */
+ { 0x5E,0x0000 }, /* Power Management Next Capability Pointer (Reserved) / Power Management Capability ID (Reserved) Reserved*/
+ { 0x60,0x0000 }, /* Power Management Data / PMCSR Bridge Support Extension (Reserved) PMDATA[7:0] / Reserved */
+ { 0x62,0x0000 }, /* Power Management Control/Status PMCSR[14:8] */
+ { 0xFFFF,0xFFFF} /* terminaror */
+};
+#define PATI_EEPROM_LAST_OFFSET 0x64
+#endif /* #ifndef __PCI_EEPROM_H_ */
diff --git a/u-boot/board/mpl/pati/plx9056.h b/u-boot/board/mpl/pati/plx9056.h
new file mode 100644
index 0000000..cd4df18
--- /dev/null
+++ b/u-boot/board/mpl/pati/plx9056.h
@@ -0,0 +1,111 @@
+/*
+ * (C) Copyright 2003
+ * Denis Peter, d.peter@mpl.ch
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+/* PLX9096 register definitions
+*/
+#ifndef __PLX9056_H_
+#define __PLX9056_H_ 1
+
+#include <pci.h>
+
+#ifdef PLX9056_LOC
+#define LOCAL_OFFSET 0x080
+/* PCI Config regs */
+#else
+#define LOCAL_OFFSET 0x000
+#endif
+
+#define PCI9056_VENDOR_ID PCI_VENDOR_ID
+/*#define PCI9656_DEVICE_ID PCI_DEVICE_ID */
+#define PCI9056_COMMAND PCI_COMMAND
+/*#define PCI9656_STATUS PCI_STATUS */
+#define PCI9056_REVISION PCI_REVISION_ID
+
+#define PCI9056_CACHE_SIZE PCI_CACHE_LINE_SIZE
+#define PCI9056_RTR_BASE PCI_BASE_ADDRESS_0
+#define PCI9056_RTR_IO_BASE PCI_BASE_ADDRESS_1
+#define PCI9056_LOCAL_BASE0 PCI_BASE_ADDRESS_2
+#define PCI9056_LOCAL_BASE1 PCI_BASE_ADDRESS_3
+#define PCI9056_UNUSED_BASE1 PCI_BASE_ADDRESS_4
+#define PCI9056_UNUSED_BASE2 PCI_BASE_ADDRESS_5
+#define PCI9056_CIS_PTR PCI_CARDBUS_CIS
+#define PCI9056_SUB_ID PCI_SUBSYSTEM_VENDOR_ID
+#define PCI9056_EXP_ROM_BASE PCI_ROM_ADDRESS
+#define PCI9056_CAP_PTR PCI_CAPABILITY_LIST
+#define PCI9056_INT_LINE PCI_INTERRUPT_LINE
+
+#if defined(PLX9056_LOC)
+ #define PCI9056_PM_CAP_ID 0x180
+ #define PCI9056_PM_CSR 0x184
+ #define PCI9056_HS_CAP_ID 0x188
+ #define PCI9056_VPD_CAP_ID 0x18C
+ #define PCI9056_VPD_DATA 0x190
+#endif
+
+
+#define PCI_DEVICE_ID_PLX9056 0x9056
+
+/* Local Configuration Registers Accessible via the PCI Base address + Variable */
+#define PCI9056_SPACE0_RANGE (0x000 + LOCAL_OFFSET)
+#define PCI9056_SPACE0_REMAP (0x004 + LOCAL_OFFSET)
+#define PCI9056_LOCAL_DMA_ARBIT (0x008 + LOCAL_OFFSET)
+#define PCI9056_ENDIAN_DESC (0x00c + LOCAL_OFFSET)
+#define PCI9056_EXP_ROM_RANGE (0x010 + LOCAL_OFFSET)
+#define PCI9056_EXP_ROM_REMAP (0x014 + LOCAL_OFFSET)
+#define PCI9056_SPACE0_ROM_DESC (0x018 + LOCAL_OFFSET)
+#define PCI9056_DM_RANGE (0x01c + LOCAL_OFFSET)
+#define PCI9056_DM_MEM_BASE (0x020 + LOCAL_OFFSET)
+#define PCI9056_DM_IO_BASE (0x024 + LOCAL_OFFSET)
+#define PCI9056_DM_PCI_MEM_REMAP (0x028 + LOCAL_OFFSET)
+#define PCI9056_DM_PCI_IO_CONFIG (0x02c + LOCAL_OFFSET)
+#define PCI9056_SPACE1_RANGE (0x0f0 + LOCAL_OFFSET)
+#define PCI9056_SPACE1_REMAP (0x0f4 + LOCAL_OFFSET)
+#define PCI9056_SPACE1_DESC (0x0f8 + LOCAL_OFFSET)
+#define PCI9056_DM_DAC (0x0fc + LOCAL_OFFSET)
+
+#ifdef PLX9056_LOC
+#define PCI9056_ARBITER_CTRL 0x1A0
+#define PCI9056_ABORT_ADDRESS 0x1A4
+#endif
+
+/* Runtime registers PCI Address + LOCAL_OFFSET */
+#ifdef PLX9056_LOC
+#define PCI9056_MAILBOX0 0x0C0
+#define PCI9056_MAILBOX1 0x0C4
+#else
+#define PCI9056_MAILBOX0 0x078
+#define PCI9056_MAILBOX1 0x07c
+#endif
+
+#define PCI9056_MAILBOX2 (0x048 + LOCAL_OFFSET)
+#define PCI9056_MAILBOX3 (0x04c + LOCAL_OFFSET)
+#define PCI9056_MAILBOX4 (0x050 + LOCAL_OFFSET)
+#define PCI9056_MAILBOX5 (0x054 + LOCAL_OFFSET)
+#define PCI9056_MAILBOX6 (0x058 + LOCAL_OFFSET)
+#define PCI9056_MAILBOX7 (0x05c + LOCAL_OFFSET)
+#define PCI9056_PCI_TO_LOC_DBELL (0x060 + LOCAL_OFFSET)
+#define PCI9056_LOC_TO_PCI_DBELL (0x064 + LOCAL_OFFSET)
+#define PCI9056_INT_CTRL_STAT (0x068 + LOCAL_OFFSET)
+#define PCI9056_EEPROM_CTRL_STAT (0x06c + LOCAL_OFFSET)
+#define PCI9056_PERM_VENDOR_ID (0x070 + LOCAL_OFFSET)
+#define PCI9056_REVISION_ID (0x074 + LOCAL_OFFSET)
+
+#endif /* #ifndef __PLX9056_H_ */
diff --git a/u-boot/board/mpl/pip405/Makefile b/u-boot/board/mpl/pip405/Makefile
new file mode 100644
index 0000000..8b4bbc5
--- /dev/null
+++ b/u-boot/board/mpl/pip405/Makefile
@@ -0,0 +1,59 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+ifneq ($(OBJTREE),$(SRCTREE))
+$(shell mkdir -p $(obj)../common)
+endif
+
+LIB = $(obj)lib$(BOARD).o
+
+COBJS = $(BOARD).o \
+ ../common/flash.o cmd_pip405.o ../common/pci.o \
+ ../common/isa.o ../common/kbd.o \
+ ../common/usb_uhci.o \
+ ../common/common_util.o
+
+SOBJS = init.o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+SOBJS := $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(OBJS) $(SOBJS)
+ $(call cmd_link_o_target, $(OBJS) $(SOBJS))
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak $(obj).depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/u-boot/board/mpl/pip405/cmd_pip405.c b/u-boot/board/mpl/pip405/cmd_pip405.c
new file mode 100644
index 0000000..554c8d1
--- /dev/null
+++ b/u-boot/board/mpl/pip405/cmd_pip405.c
@@ -0,0 +1,69 @@
+/*
+ * (C) Copyright 2001
+ * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * hacked for PIP405
+ */
+
+#include <common.h>
+#include <command.h>
+#include "pip405.h"
+#include "../common/common_util.h"
+
+
+extern void print_pip405_info(void);
+extern int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+
+
+/* ------------------------------------------------------------------------- */
+
+int do_pip405(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+
+ ulong led_on,led_nr;
+
+ if (strcmp(argv[1], "info") == 0)
+ {
+ print_pip405_info();
+ return 0;
+ }
+ if (strcmp(argv[1], "led") == 0)
+ {
+ led_nr = (ulong)simple_strtoul(argv[2], NULL, 10);
+ led_on = (ulong)simple_strtoul(argv[3], NULL, 10);
+ if(!led_nr)
+ user_led0(led_on);
+ else
+ user_led1(led_on);
+ return 0;
+ }
+
+ return (do_mplcommon(cmdtp, flag, argc, argv));
+}
+U_BOOT_CMD(
+ pip405, 6, 1, do_pip405,
+ "PIP405 specific Cmds",
+ "flash mem [SrcAddr] - updates U-Boot with image in memory\n"
+ "pip405 flash floppy [SrcAddr] - updates U-Boot with image from floppy\n"
+ "pip405 flash mps - updates U-Boot with image from MPS"
+);
+
+/* ------------------------------------------------------------------------- */
diff --git a/u-boot/board/mpl/pip405/init.S b/u-boot/board/mpl/pip405/init.S
new file mode 100644
index 0000000..b77517f
--- /dev/null
+++ b/u-boot/board/mpl/pip405/init.S
@@ -0,0 +1,218 @@
+/*------------------------------------------------------------------------------+
+ * This source code is dual-licensed. You may use it under the terms of
+ * the GNU General Public License version 2, or under the license below.
+ *
+ * This source code has been made available to you by IBM on an AS-IS
+ * basis. Anyone receiving this source is licensed under IBM
+ * copyrights to use it in any way he or she deems fit, including
+ * copying it, modifying it, compiling it, and redistributing it either
+ * with or without modifications. No license under IBM patents or
+ * patent applications is to be implied by the copyright license.
+ *
+ * Any user of this software should understand that IBM cannot provide
+ * technical support for this software and will not be responsible for
+ * any consequences resulting from the use of this software.
+ *
+ * Any person who transfers this source code or any derivative work
+ * must include the IBM copyright notice, this paragraph, and the
+ * preceding two paragraphs in the transferred software.
+ *
+ * COPYRIGHT I B M CORPORATION 1995
+ * LICENSED MATERIAL - PROGRAM PROPERTY OF I B M
+ *-------------------------------------------------------------------------------*/
+
+/*-----------------------------------------------------------------------------
+ * Function: ext_bus_cntlr_init
+ * Description: Initializes the External Bus Controller for the external
+ * peripherals. IMPORTANT: For pass1 this code must run from
+ * cache since you can not reliably change a peripheral banks
+ * timing register (pbxap) while running code from that bank.
+ * For ex., since we are running from ROM on bank 0, we can NOT
+ * execute the code that modifies bank 0 timings from ROM, so
+ * we run it from cache.
+ * Bank 0 - Flash or Multi Purpose Socket
+ * Bank 1 - Multi Purpose Socket or Flash
+ * Bank 2 - not used
+ * Bank 3 - not used
+ * Bank 4 - not used
+ * Bank 5 - not used
+ * Bank 6 - used to switch on the 12V for the Multipurpose socket
+ * Bank 7 - Config Register
+ *-----------------------------------------------------------------------------*/
+#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
+
+#include <configs/PIP405.h>
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+#include <asm/cache.h>
+#include <asm/mmu.h>
+#include <asm/ppc4xx.h>
+#include "pip405.h"
+
+ .globl ext_bus_cntlr_init
+ ext_bus_cntlr_init:
+ mflr r4 /* save link register */
+ mfdcr r3,CPC0_PSR /* get strapping reg */
+ andi. r0, r3, PSR_ROM_LOC /* mask out irrelevant bits */
+ bnelr /* jump back if PCI boot */
+
+ bl ..getAddr
+..getAddr:
+ mflr r3 /* get address of ..getAddr */
+ mtlr r4 /* restore link register */
+ addi r4,0,14 /* set ctr to 14; used to prefetch */
+ mtctr r4 /* 14 cache lines to fit this function */
+ /* in cache (gives us 8x14=112 instrctns) */
+..ebcloop:
+ icbt r0,r3 /* prefetch cache line for addr in r3 */
+ addi r3,r3,32 /* move to next cache line */
+ bdnz ..ebcloop /* continue for 14 cache lines */
+
+ /*-------------------------------------------------------------------
+ * Delay to ensure all accesses to ROM are complete before changing
+ * bank 0 timings.
+ *------------------------------------------------------------------- */
+ addis r3,0,0x0
+ ori r3,r3,0xA000
+ mtctr r3
+..spinlp:
+ bdnz ..spinlp /* spin loop */
+
+ /*-----------------------------------------------------------------------
+ * decide boot up mode
+ *----------------------------------------------------------------------- */
+ addi r4,0,PB0CR
+ mtdcr EBC0_CFGADDR,r4
+ mfdcr r4,EBC0_CFGDATA
+
+ andi. r0, r4, 0x2000 /* mask out irrelevant bits */
+ beq 0f /* jump if 8 bit bus width */
+
+ /* setup 16 bit things
+ *-----------------------------------------------------------------------
+ * Memory Bank 0 (16 Bit Flash) initialization
+ *---------------------------------------------------------------------- */
+
+ addi r4,0,PB1AP
+ mtdcr EBC0_CFGADDR,r4
+ addis r4,0,(FLASH_AP_B)@h
+ ori r4,r4,(FLASH_AP_B)@l
+ mtdcr EBC0_CFGDATA,r4
+
+ addi r4,0,PB0CR
+ mtdcr EBC0_CFGADDR,r4
+ /* BS=0x010(4MB),BU=0x3(R/W), */
+ addis r4,0,(FLASH_CR_B)@h
+ ori r4,r4,(FLASH_CR_B)@l
+ mtdcr EBC0_CFGDATA,r4
+ b 1f
+
+0:
+ /* 8Bit boot mode: */
+ /*-----------------------------------------------------------------------
+ * Memory Bank 0 Multi Purpose Socket initialization
+ *----------------------------------------------------------------------- */
+ /* 0x7F8FFE80 slowest boot */
+ addi r4,0,PB1AP
+ mtdcr EBC0_CFGADDR,r4
+ addis r4,0,(MPS_AP_B)@h
+ ori r4,r4,(MPS_AP_B)@l
+ mtdcr EBC0_CFGDATA,r4
+
+ addi r4,0,PB0CR
+ mtdcr EBC0_CFGADDR,r4
+ /* BS=0x010(4MB),BU=0x3(R/W), */
+ addis r4,0,(MPS_CR_B)@h
+ ori r4,r4,(MPS_CR_B)@l
+ mtdcr EBC0_CFGDATA,r4
+
+
+1:
+ /*-----------------------------------------------------------------------
+ * Memory Bank 2-3-4-5-6 (not used) initialization
+ *-----------------------------------------------------------------------*/
+ addi r4,0,PB1CR
+ mtdcr EBC0_CFGADDR,r4
+ addis r4,0,0x0000
+ ori r4,r4,0x0000
+ mtdcr EBC0_CFGDATA,r4
+
+ addi r4,0,PB2CR
+ mtdcr EBC0_CFGADDR,r4
+ addis r4,0,0x0000
+ ori r4,r4,0x0000
+ mtdcr EBC0_CFGDATA,r4
+
+ addi r4,0,PB3CR
+ mtdcr EBC0_CFGADDR,r4
+ addis r4,0,0x0000
+ ori r4,r4,0x0000
+ mtdcr EBC0_CFGDATA,r4
+
+ addi r4,0,PB4CR
+ mtdcr EBC0_CFGADDR,r4
+ addis r4,0,0x0000
+ ori r4,r4,0x0000
+ mtdcr EBC0_CFGDATA,r4
+
+ addi r4,0,PB5CR
+ mtdcr EBC0_CFGADDR,r4
+ addis r4,0,0x0000
+ ori r4,r4,0x0000
+ mtdcr EBC0_CFGDATA,r4
+
+ addi r4,0,PB6CR
+ mtdcr EBC0_CFGADDR,r4
+ addis r4,0,0x0000
+ ori r4,r4,0x0000
+ mtdcr EBC0_CFGDATA,r4
+
+ addi r4,0,PB7CR
+ mtdcr EBC0_CFGADDR,r4
+ addis r4,0,0x0000
+ ori r4,r4,0x0000
+ mtdcr EBC0_CFGDATA,r4
+ nop /* pass2 DCR errata #8 */
+ blr
+
+#if defined(CONFIG_BOOT_PCI)
+ .section .bootpg,"ax"
+ .globl _start_pci
+/*******************************************
+ */
+
+_start_pci:
+ /* first handle errata #68 / PCI_18 */
+ iccci r0, r0 /* invalidate I-cache */
+ lis r31, 0
+ mticcr r31 /* ICCR = 0 (all uncachable) */
+ isync
+
+ mfccr0 r28 /* set CCR0[24] = 1 */
+ ori r28, r28, 0x0080
+ mtccr0 r28
+
+ /* setup PMM0MA (0xEF400004) and PMM0PCIHA (0xEF40000C) */
+ lis r28, 0xEF40
+ addi r28, r28, 0x0004
+ stw r31, 0x0C(r28) /* clear PMM0PCIHA */
+ lis r29, 0xFFF8 /* open 512 kByte */
+ addi r29, r29, 0x0001/* and enable this region */
+ stwbrx r29, r0, r28 /* write PMM0MA */
+
+ lis r28, 0xEEC0 /* address of PCIC0_CFGADDR */
+ addi r29, r28, 4 /* add 4 to r29 -> PCIC0_CFGDATA */
+
+ lis r31, 0x8000 /* set en bit bus 0 */
+ ori r31, r31, 0x304C/* device 6 func 0 reg 4C (XBCS register) */
+ stwbrx r31, r0, r28 /* write it */
+
+ lwbrx r31, r0, r29 /* load XBCS register */
+ oris r31, r31, 0x02C4/* clear BIOSCS WPE, set lower, extended and 1M extended BIOS enable */
+ stwbrx r31, r0, r29 /* write back XBCS register */
+
+ nop
+ nop
+ b _start /* normal start */
+#endif
diff --git a/u-boot/board/mpl/pip405/pip405.c b/u-boot/board/mpl/pip405/pip405.c
new file mode 100644
index 0000000..7b48c06
--- /dev/null
+++ b/u-boot/board/mpl/pip405/pip405.c
@@ -0,0 +1,955 @@
+/*
+ * (C) Copyright 2001
+ * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * TODO: clean-up
+ */
+
+#include <common.h>
+#include "pip405.h"
+#include <asm/processor.h>
+#include <i2c.h>
+#include <stdio_dev.h>
+#include "../common/isa.h"
+#include "../common/common_util.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#undef SDRAM_DEBUG
+
+#define FALSE 0
+#define TRUE 1
+
+/* stdlib.h causes some compatibility problems; should fixe these! -- wd */
+#ifndef __ldiv_t_defined
+typedef struct {
+ long int quot; /* Quotient */
+ long int rem; /* Remainder */
+} ldiv_t;
+extern ldiv_t ldiv (long int __numer, long int __denom);
+
+# define __ldiv_t_defined 1
+#endif
+
+
+typedef enum {
+ SDRAM_NO_ERR,
+ SDRAM_SPD_COMM_ERR,
+ SDRAM_SPD_CHKSUM_ERR,
+ SDRAM_UNSUPPORTED_ERR,
+ SDRAM_UNKNOWN_ERR
+} SDRAM_ERR;
+
+typedef struct {
+ const unsigned char mode;
+ const unsigned char row;
+ const unsigned char col;
+ const unsigned char bank;
+} SDRAM_SETUP;
+
+static const SDRAM_SETUP sdram_setup_table[] = {
+ {1, 11, 9, 2},
+ {1, 11, 10, 2},
+ {2, 12, 9, 4},
+ {2, 12, 10, 4},
+ {3, 13, 9, 4},
+ {3, 13, 10, 4},
+ {3, 13, 11, 4},
+ {4, 12, 8, 2},
+ {4, 12, 8, 4},
+ {5, 11, 8, 2},
+ {5, 11, 8, 4},
+ {6, 13, 8, 2},
+ {6, 13, 8, 4},
+ {7, 13, 9, 2},
+ {7, 13, 10, 2},
+ {0, 0, 0, 0}
+};
+
+static const unsigned char cal_indextable[] = {
+ 9, 23, 25
+};
+
+
+/*
+ * translate ns.ns/10 coding of SPD timing values
+ * into 10 ps unit values
+ */
+
+unsigned short NS10to10PS (unsigned char spd_byte, unsigned char spd_version)
+{
+ unsigned short ns, ns10;
+
+ /* isolate upper nibble */
+ ns = (spd_byte >> 4) & 0x0F;
+ /* isolate lower nibble */
+ ns10 = (spd_byte & 0x0F);
+
+ return (ns * 100 + ns10 * 10);
+}
+
+/*
+ * translate ns.ns/4 coding of SPD timing values
+ * into 10 ps unit values
+ */
+
+unsigned short NS4to10PS (unsigned char spd_byte, unsigned char spd_version)
+{
+ unsigned short ns, ns4;
+
+ /* isolate upper 6 bits */
+ ns = (spd_byte >> 2) & 0x3F;
+ /* isloate lower 2 bits */
+ ns4 = (spd_byte & 0x03);
+
+ return (ns * 100 + ns4 * 25);
+}
+
+/*
+ * translate ns coding of SPD timing values
+ * into 10 ps unit values
+ */
+
+unsigned short NSto10PS (unsigned char spd_byte)
+{
+ return (spd_byte * 100);
+}
+
+void SDRAM_err (const char *s)
+{
+#ifndef SDRAM_DEBUG
+ (void) get_clocks ();
+ gd->baudrate = 9600;
+ serial_init ();
+#endif
+ serial_puts ("\n");
+ serial_puts (s);
+ serial_puts ("\n enable SDRAM_DEBUG for more info\n");
+ for (;;);
+}
+
+
+#ifdef SDRAM_DEBUG
+
+void write_hex (unsigned char i)
+{
+ char cc;
+
+ cc = i >> 4;
+ cc &= 0xf;
+ if (cc > 9)
+ serial_putc (cc + 55);
+ else
+ serial_putc (cc + 48);
+ cc = i & 0xf;
+ if (cc > 9)
+ serial_putc (cc + 55);
+ else
+ serial_putc (cc + 48);
+}
+
+void write_4hex (unsigned long val)
+{
+ write_hex ((unsigned char) (val >> 24));
+ write_hex ((unsigned char) (val >> 16));
+ write_hex ((unsigned char) (val >> 8));
+ write_hex ((unsigned char) val);
+}
+
+#endif
+
+int board_early_init_f (void)
+{
+ unsigned char dataout[1];
+ unsigned char datain[128];
+ unsigned long sdram_size = 0;
+ SDRAM_SETUP *t = (SDRAM_SETUP *) sdram_setup_table;
+ unsigned long memclk;
+ unsigned long tmemclk = 0;
+ unsigned long tmp, bank, baseaddr, bank_size;
+ unsigned short i;
+ unsigned char rows, cols, banks, sdram_banks, density;
+ unsigned char supported_cal, trp_clocks, trcd_clocks, tras_clocks,
+ trc_clocks, tctp_clocks;
+ unsigned char cal_index, cal_val, spd_version, spd_chksum;
+ unsigned char buf[8];
+ /* set up the config port */
+ mtdcr (EBC0_CFGADDR, PB7AP);
+ mtdcr (EBC0_CFGDATA, CONFIG_PORT_AP);
+ mtdcr (EBC0_CFGADDR, PB7CR);
+ mtdcr (EBC0_CFGDATA, CONFIG_PORT_CR);
+
+ memclk = get_bus_freq (tmemclk);
+ tmemclk = 1000000000 / (memclk / 100); /* in 10 ps units */
+
+#ifdef SDRAM_DEBUG
+ (void) get_clocks ();
+ gd->baudrate = 9600;
+ serial_init ();
+ serial_puts ("\nstart SDRAM Setup\n");
+#endif
+
+ /* Read Serial Presence Detect Information */
+ i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+ dataout[0] = 0;
+ for (i = 0; i < 128; i++)
+ datain[i] = 127;
+ i2c_read(SPD_EEPROM_ADDRESS,0,1,datain,128);
+#ifdef SDRAM_DEBUG
+ serial_puts ("\ni2c_read returns ");
+ write_hex (i);
+ serial_puts ("\n");
+#endif
+
+#ifdef SDRAM_DEBUG
+ for (i = 0; i < 128; i++) {
+ write_hex (datain[i]);
+ serial_puts (" ");
+ if (((i + 1) % 16) == 0)
+ serial_puts ("\n");
+ }
+ serial_puts ("\n");
+#endif
+ spd_chksum = 0;
+ for (i = 0; i < 63; i++) {
+ spd_chksum += datain[i];
+ } /* endfor */
+ if (datain[63] != spd_chksum) {
+#ifdef SDRAM_DEBUG
+ serial_puts ("SPD chksum: 0x");
+ write_hex (datain[63]);
+ serial_puts (" != calc. chksum: 0x");
+ write_hex (spd_chksum);
+ serial_puts ("\n");
+#endif
+ SDRAM_err ("SPD checksum Error");
+ }
+ /* SPD seems to be ok, use it */
+
+ /* get SPD version */
+ spd_version = datain[62];
+
+ /* do some sanity checks on the kind of RAM */
+ if ((datain[0] < 0x80) || /* less than 128 valid bytes in SPD */
+ (datain[2] != 0x04) || /* if not SDRAM */
+ (!((datain[6] == 0x40) || (datain[6] == 0x48))) || /* or not (64 Bit or 72 Bit) */
+ (datain[7] != 0x00) || (datain[8] != 0x01) || /* or not LVTTL signal levels */
+ (datain[126] == 0x66)) /* or a 66MHz modules */
+ SDRAM_err ("unsupported SDRAM");
+#ifdef SDRAM_DEBUG
+ serial_puts ("SDRAM sanity ok\n");
+#endif
+
+ /* get number of rows/cols/banks out of byte 3+4+5 */
+ rows = datain[3];
+ cols = datain[4];
+ banks = datain[5];
+
+ /* get number of SDRAM banks out of byte 17 and
+ supported CAS latencies out of byte 18 */
+ sdram_banks = datain[17];
+ supported_cal = datain[18] & ~0x81;
+
+ while (t->mode != 0) {
+ if ((t->row == rows) && (t->col == cols)
+ && (t->bank == sdram_banks))
+ break;
+ t++;
+ } /* endwhile */
+
+#ifdef SDRAM_DEBUG
+ serial_puts ("rows: ");
+ write_hex (rows);
+ serial_puts (" cols: ");
+ write_hex (cols);
+ serial_puts (" banks: ");
+ write_hex (banks);
+ serial_puts (" mode: ");
+ write_hex (t->mode);
+ serial_puts ("\n");
+#endif
+ if (t->mode == 0)
+ SDRAM_err ("unsupported SDRAM");
+ /* get tRP, tRCD, tRAS and density from byte 27+29+30+31 */
+#ifdef SDRAM_DEBUG
+ serial_puts ("tRP: ");
+ write_hex (datain[27]);
+ serial_puts ("\ntRCD: ");
+ write_hex (datain[29]);
+ serial_puts ("\ntRAS: ");
+ write_hex (datain[30]);
+ serial_puts ("\n");
+#endif
+
+ trp_clocks = (NSto10PS (datain[27]) + (tmemclk - 1)) / tmemclk;
+ trcd_clocks = (NSto10PS (datain[29]) + (tmemclk - 1)) / tmemclk;
+ tras_clocks = (NSto10PS (datain[30]) + (tmemclk - 1)) / tmemclk;
+ density = datain[31];
+
+ /* trc_clocks is sum of trp_clocks + tras_clocks */
+ trc_clocks = trp_clocks + tras_clocks;
+ /* ctp = ((trp + tras) - trp - trcd) => tras - trcd */
+ tctp_clocks =
+ ((NSto10PS (datain[30]) - NSto10PS (datain[29])) +
+ (tmemclk - 1)) / tmemclk;
+
+#ifdef SDRAM_DEBUG
+ serial_puts ("c_RP: ");
+ write_hex (trp_clocks);
+ serial_puts ("\nc_RCD: ");
+ write_hex (trcd_clocks);
+ serial_puts ("\nc_RAS: ");
+ write_hex (tras_clocks);
+ serial_puts ("\nc_RC: (RP+RAS): ");
+ write_hex (trc_clocks);
+ serial_puts ("\nc_CTP: ((RP+RAS)-RP-RCD): ");
+ write_hex (tctp_clocks);
+ serial_puts ("\nt_CTP: RAS - RCD: ");
+ write_hex ((unsigned
+ char) ((NSto10PS (datain[30]) -
+ NSto10PS (datain[29])) >> 8));
+ write_hex ((unsigned char) (NSto10PS (datain[30]) - NSto10PS (datain[29])));
+ serial_puts ("\ntmemclk: ");
+ write_hex ((unsigned char) (tmemclk >> 8));
+ write_hex ((unsigned char) (tmemclk));
+ serial_puts ("\n");
+#endif
+
+
+ cal_val = 255;
+ for (i = 6, cal_index = 0; (i > 0) && (cal_index < 3); i--) {
+ /* is this CAS latency supported ? */
+ if ((supported_cal >> i) & 0x01) {
+ buf[0] = datain[cal_indextable[cal_index]];
+ if (cal_index < 2) {
+ if (NS10to10PS (buf[0], spd_version) <= tmemclk)
+ cal_val = i;
+ } else {
+ /* SPD bytes 25+26 have another format */
+ if (NS4to10PS (buf[0], spd_version) <= tmemclk)
+ cal_val = i;
+ } /* endif */
+ cal_index++;
+ } /* endif */
+ } /* endfor */
+#ifdef SDRAM_DEBUG
+ serial_puts ("CAL: ");
+ write_hex (cal_val + 1);
+ serial_puts ("\n");
+#endif
+
+ if (cal_val == 255)
+ SDRAM_err ("unsupported SDRAM");
+
+ /* get SDRAM timing register */
+ mtdcr (SDRAM0_CFGADDR, SDRAM0_TR);
+ tmp = mfdcr (SDRAM0_CFGDATA) & ~0x018FC01F;
+ /* insert CASL value */
+/* tmp |= ((unsigned long)cal_val) << 23; */
+ tmp |= ((unsigned long) cal_val) << 23;
+ /* insert PTA value */
+ tmp |= ((unsigned long) (trp_clocks - 1)) << 18;
+ /* insert CTP value */
+/* tmp |= ((unsigned long)(trc_clocks - trp_clocks - trcd_clocks - 1)) << 16; */
+ tmp |= ((unsigned long) (trc_clocks - trp_clocks - trcd_clocks)) << 16;
+ /* insert LDF (always 01) */
+ tmp |= ((unsigned long) 0x01) << 14;
+ /* insert RFTA value */
+ tmp |= ((unsigned long) (trc_clocks - 4)) << 2;
+ /* insert RCD value */
+ tmp |= ((unsigned long) (trcd_clocks - 1)) << 0;
+
+#ifdef SDRAM_DEBUG
+ serial_puts ("sdtr: ");
+ write_4hex (tmp);
+ serial_puts ("\n");
+#endif
+
+ /* write SDRAM timing register */
+ mtdcr (SDRAM0_CFGADDR, SDRAM0_TR);
+ mtdcr (SDRAM0_CFGDATA, tmp);
+ baseaddr = CONFIG_SYS_SDRAM_BASE;
+ bank_size = (((unsigned long) density) << 22) / 2;
+ /* insert AM value */
+ tmp = ((unsigned long) t->mode - 1) << 13;
+ /* insert SZ value; */
+ switch (bank_size) {
+ case 0x00400000:
+ tmp |= ((unsigned long) 0x00) << 17;
+ break;
+ case 0x00800000:
+ tmp |= ((unsigned long) 0x01) << 17;
+ break;
+ case 0x01000000:
+ tmp |= ((unsigned long) 0x02) << 17;
+ break;
+ case 0x02000000:
+ tmp |= ((unsigned long) 0x03) << 17;
+ break;
+ case 0x04000000:
+ tmp |= ((unsigned long) 0x04) << 17;
+ break;
+ case 0x08000000:
+ tmp |= ((unsigned long) 0x05) << 17;
+ break;
+ case 0x10000000:
+ tmp |= ((unsigned long) 0x06) << 17;
+ break;
+ default:
+ SDRAM_err ("unsupported SDRAM");
+ } /* endswitch */
+ /* get SDRAM bank 0 register */
+ mtdcr (SDRAM0_CFGADDR, SDRAM0_B0CR);
+ bank = mfdcr (SDRAM0_CFGDATA) & ~0xFFCEE001;
+ bank |= (baseaddr | tmp | 0x01);
+#ifdef SDRAM_DEBUG
+ serial_puts ("bank0: baseaddr: ");
+ write_4hex (baseaddr);
+ serial_puts (" banksize: ");
+ write_4hex (bank_size);
+ serial_puts (" mb0cf: ");
+ write_4hex (bank);
+ serial_puts ("\n");
+#endif
+ baseaddr += bank_size;
+ sdram_size += bank_size;
+
+ /* write SDRAM bank 0 register */
+ mtdcr (SDRAM0_CFGADDR, SDRAM0_B0CR);
+ mtdcr (SDRAM0_CFGDATA, bank);
+
+ /* get SDRAM bank 1 register */
+ mtdcr (SDRAM0_CFGADDR, SDRAM0_B1CR);
+ bank = mfdcr (SDRAM0_CFGDATA) & ~0xFFCEE001;
+ sdram_size = 0;
+
+#ifdef SDRAM_DEBUG
+ serial_puts ("bank1: baseaddr: ");
+ write_4hex (baseaddr);
+ serial_puts (" banksize: ");
+ write_4hex (bank_size);
+#endif
+ if (banks == 2) {
+ bank |= (baseaddr | tmp | 0x01);
+ baseaddr += bank_size;
+ sdram_size += bank_size;
+ } /* endif */
+#ifdef SDRAM_DEBUG
+ serial_puts (" mb1cf: ");
+ write_4hex (bank);
+ serial_puts ("\n");
+#endif
+ /* write SDRAM bank 1 register */
+ mtdcr (SDRAM0_CFGADDR, SDRAM0_B1CR);
+ mtdcr (SDRAM0_CFGDATA, bank);
+
+ /* get SDRAM bank 2 register */
+ mtdcr (SDRAM0_CFGADDR, SDRAM0_B2CR);
+ bank = mfdcr (SDRAM0_CFGDATA) & ~0xFFCEE001;
+
+ bank |= (baseaddr | tmp | 0x01);
+
+#ifdef SDRAM_DEBUG
+ serial_puts ("bank2: baseaddr: ");
+ write_4hex (baseaddr);
+ serial_puts (" banksize: ");
+ write_4hex (bank_size);
+ serial_puts (" mb2cf: ");
+ write_4hex (bank);
+ serial_puts ("\n");
+#endif
+
+ baseaddr += bank_size;
+ sdram_size += bank_size;
+
+ /* write SDRAM bank 2 register */
+ mtdcr (SDRAM0_CFGADDR, SDRAM0_B2CR);
+ mtdcr (SDRAM0_CFGDATA, bank);
+
+ /* get SDRAM bank 3 register */
+ mtdcr (SDRAM0_CFGADDR, SDRAM0_B3CR);
+ bank = mfdcr (SDRAM0_CFGDATA) & ~0xFFCEE001;
+
+#ifdef SDRAM_DEBUG
+ serial_puts ("bank3: baseaddr: ");
+ write_4hex (baseaddr);
+ serial_puts (" banksize: ");
+ write_4hex (bank_size);
+#endif
+
+ if (banks == 2) {
+ bank |= (baseaddr | tmp | 0x01);
+ baseaddr += bank_size;
+ sdram_size += bank_size;
+ }
+ /* endif */
+#ifdef SDRAM_DEBUG
+ serial_puts (" mb3cf: ");
+ write_4hex (bank);
+ serial_puts ("\n");
+#endif
+
+ /* write SDRAM bank 3 register */
+ mtdcr (SDRAM0_CFGADDR, SDRAM0_B3CR);
+ mtdcr (SDRAM0_CFGDATA, bank);
+
+
+ /* get SDRAM refresh interval register */
+ mtdcr (SDRAM0_CFGADDR, SDRAM0_RTR);
+ tmp = mfdcr (SDRAM0_CFGDATA) & ~0x3FF80000;
+
+ if (tmemclk < NSto10PS (16))
+ tmp |= 0x05F00000;
+ else
+ tmp |= 0x03F80000;
+
+ /* write SDRAM refresh interval register */
+ mtdcr (SDRAM0_CFGADDR, SDRAM0_RTR);
+ mtdcr (SDRAM0_CFGDATA, tmp);
+
+ /* enable SDRAM controller with no ECC, 32-bit SDRAM width, 16 byte burst */
+ mtdcr (SDRAM0_CFGADDR, SDRAM0_CFG);
+ tmp = (mfdcr (SDRAM0_CFGDATA) & ~0xFFE00000) | 0x80E00000;
+ mtdcr (SDRAM0_CFGADDR, SDRAM0_CFG);
+ mtdcr (SDRAM0_CFGDATA, tmp);
+
+
+ /*-------------------------------------------------------------------------+
+ | Interrupt controller setup for the PIP405 board.
+ | Note: IRQ 0-15 405GP internally generated; active high; level sensitive
+ | IRQ 16 405GP internally generated; active low; level sensitive
+ | IRQ 17-24 RESERVED
+ | IRQ 25 (EXT IRQ 0) SouthBridg; active low; level sensitive
+ | IRQ 26 (EXT IRQ 1) NMI: active low; level sensitive
+ | IRQ 27 (EXT IRQ 2) SMI: active Low; level sensitive
+ | IRQ 28 (EXT IRQ 3) PCI SLOT 3; active low; level sensitive
+ | IRQ 29 (EXT IRQ 4) PCI SLOT 2; active low; level sensitive
+ | IRQ 30 (EXT IRQ 5) PCI SLOT 1; active low; level sensitive
+ | IRQ 31 (EXT IRQ 6) PCI SLOT 0; active low; level sensitive
+ | Note for PIP405 board:
+ | An interrupt taken for the SouthBridge (IRQ 25) indicates that
+ | the Interrupt Controller in the South Bridge has caused the
+ | interrupt. The IC must be read to determine which device
+ | caused the interrupt.
+ |
+ +-------------------------------------------------------------------------*/
+ mtdcr (UIC0SR, 0xFFFFFFFF); /* clear all ints */
+ mtdcr (UIC0ER, 0x00000000); /* disable all ints */
+ mtdcr (UIC0CR, 0x00000000); /* set all to be non-critical (for now) */
+ mtdcr (UIC0PR, 0xFFFFFF80); /* set int polarities */
+ mtdcr (UIC0TR, 0x10000000); /* set int trigger levels */
+ mtdcr (UIC0VCR, 0x00000001); /* set vect base=0,INT0 highest priority */
+ mtdcr (UIC0SR, 0xFFFFFFFF); /* clear all ints */
+
+ return 0;
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Check Board Identity:
+ */
+
+int checkboard (void)
+{
+ char s[50];
+ unsigned char bc;
+ int i;
+ backup_t *b = (backup_t *) s;
+
+ puts ("Board: ");
+
+ i = getenv_f("serial#", (char *)s, 32);
+ if ((i == 0) || strncmp ((char *)s, "PIP405", 6)) {
+ get_backup_values (b);
+ if (strncmp (b->signature, "MPL\0", 4) != 0) {
+ puts ("### No HW ID - assuming PIP405");
+ } else {
+ b->serial_name[6] = 0;
+ printf ("%s SN: %s", b->serial_name,
+ &b->serial_name[7]);
+ }
+ } else {
+ s[6] = 0;
+ printf ("%s SN: %s", s, &s[7]);
+ }
+ bc = in8 (CONFIG_PORT_ADDR);
+ printf (" Boot Config: 0x%x\n", bc);
+ return (0);
+}
+
+
+/* ------------------------------------------------------------------------- */
+/* ------------------------------------------------------------------------- */
+/*
+ initdram(int board_type) reads EEPROM via I2c. EEPROM contains all of
+ the necessary info for SDRAM controller configuration
+*/
+/* ------------------------------------------------------------------------- */
+/* ------------------------------------------------------------------------- */
+static int test_dram (unsigned long ramsize);
+
+phys_size_t initdram (int board_type)
+{
+ unsigned long bank_reg[4], tmp, bank_size;
+ int i, ds;
+ unsigned long TotalSize;
+
+ ds = 0;
+ /* since the DRAM controller is allready set up,
+ * calculate the size with the bank registers
+ */
+ mtdcr (SDRAM0_CFGADDR, SDRAM0_B0CR);
+ bank_reg[0] = mfdcr (SDRAM0_CFGDATA);
+ mtdcr (SDRAM0_CFGADDR, SDRAM0_B1CR);
+ bank_reg[1] = mfdcr (SDRAM0_CFGDATA);
+ mtdcr (SDRAM0_CFGADDR, SDRAM0_B2CR);
+ bank_reg[2] = mfdcr (SDRAM0_CFGDATA);
+ mtdcr (SDRAM0_CFGADDR, SDRAM0_B3CR);
+ bank_reg[3] = mfdcr (SDRAM0_CFGDATA);
+ TotalSize = 0;
+ for (i = 0; i < 4; i++) {
+ if ((bank_reg[i] & 0x1) == 0x1) {
+ tmp = (bank_reg[i] >> 17) & 0x7;
+ bank_size = 4 << tmp;
+ TotalSize += bank_size;
+ } else
+ ds = 1;
+ }
+ if (ds == 1)
+ printf ("single-sided DIMM ");
+ else
+ printf ("double-sided DIMM ");
+ test_dram (TotalSize * 1024 * 1024);
+ /* bank 2 (SDRAM Clock 2) is not usable if 133MHz SDRAM IF */
+ (void) get_clocks();
+ if (gd->cpu_clk > 220000000)
+ TotalSize /= 2;
+ return (TotalSize * 1024 * 1024);
+}
+
+/* ------------------------------------------------------------------------- */
+
+
+static int test_dram (unsigned long ramsize)
+{
+ /* not yet implemented */
+ return (1);
+}
+
+
+extern flash_info_t flash_info[]; /* info for FLASH chips */
+
+int misc_init_r (void)
+{
+ /* adjust flash start and size as well as the offset */
+ gd->bd->bi_flashstart=0-flash_info[0].size;
+ gd->bd->bi_flashsize=flash_info[0].size-CONFIG_SYS_MONITOR_LEN;
+ gd->bd->bi_flashoffset=0;
+
+ /* if PIP405 has booted from PCI, reset CCR0[24] as described in errata PCI_18 */
+ if (mfdcr(CPC0_PSR) & PSR_ROM_LOC)
+ mtspr(SPRN_CCR0, (mfspr(SPRN_CCR0) & ~0x80));
+
+ return (0);
+}
+
+/***************************************************************************
+ * some helping routines
+ */
+
+int overwrite_console (void)
+{
+ return (in8 (CONFIG_PORT_ADDR) & 0x1); /* return TRUE if console should be overwritten */
+}
+
+
+extern int isa_init (void);
+
+
+void print_pip405_rev (void)
+{
+ unsigned char part, vers, cfg;
+
+ part = in8 (PLD_PART_REG);
+ vers = in8 (PLD_VERS_REG);
+ cfg = in8 (PLD_BOARD_CFG_REG);
+ printf ("Rev: PIP405-%d Rev %c PLD%d %d PLD%d %d\n",
+ 16 - ((cfg >> 4) & 0xf), (cfg & 0xf) + 'A', part & 0xf,
+ vers & 0xf, (part >> 4) & 0xf, (vers >> 4) & 0xf);
+}
+
+extern void check_env(void);
+
+
+int last_stage_init (void)
+{
+ print_pip405_rev ();
+ isa_init ();
+ stdio_print_current_devices ();
+ check_env();
+ return 0;
+}
+
+/************************************************************************
+* Print PIP405 Info
+************************************************************************/
+void print_pip405_info (void)
+{
+ unsigned char part, vers, cfg, ledu, sysman, flashcom, can, serpwr,
+ compwr, nicvga, scsirst;
+
+ part = in8 (PLD_PART_REG);
+ vers = in8 (PLD_VERS_REG);
+ cfg = in8 (PLD_BOARD_CFG_REG);
+ ledu = in8 (PLD_LED_USER_REG);
+ sysman = in8 (PLD_SYS_MAN_REG);
+ flashcom = in8 (PLD_FLASH_COM_REG);
+ can = in8 (PLD_CAN_REG);
+ serpwr = in8 (PLD_SER_PWR_REG);
+ compwr = in8 (PLD_COM_PWR_REG);
+ nicvga = in8 (PLD_NIC_VGA_REG);
+ scsirst = in8 (PLD_SCSI_RST_REG);
+ printf ("PLD Part %d version %d\n",
+ part & 0xf, vers & 0xf);
+ printf ("PLD Part %d version %d\n",
+ (part >> 4) & 0xf, (vers >> 4) & 0xf);
+ printf ("Board Revision %c\n", (cfg & 0xf) + 'A');
+ printf ("Population Options %d %d %d %d\n",
+ (cfg >> 4) & 0x1, (cfg >> 5) & 0x1,
+ (cfg >> 6) & 0x1, (cfg >> 7) & 0x1);
+ printf ("User LED0 %s User LED1 %s\n",
+ ((ledu & 0x1) == 0x1) ? "on" : "off",
+ ((ledu & 0x2) == 0x2) ? "on" : "off");
+ printf ("Additionally Options %d %d\n",
+ (ledu >> 2) & 0x1, (ledu >> 3) & 0x1);
+ printf ("User Config Switch %d %d %d %d\n",
+ (ledu >> 4) & 0x1, (ledu >> 5) & 0x1,
+ (ledu >> 6) & 0x1, (ledu >> 7) & 0x1);
+ switch (sysman & 0x3) {
+ case 0:
+ printf ("PCI Clocks are running\n");
+ break;
+ case 1:
+ printf ("PCI Clocks are stopped in POS State\n");
+ break;
+ case 2:
+ printf ("PCI Clocks are stopped when PCI_STP# is asserted\n");
+ break;
+ case 3:
+ printf ("PCI Clocks are stopped\n");
+ break;
+ }
+ switch ((sysman >> 2) & 0x3) {
+ case 0:
+ printf ("Main Clocks are running\n");
+ break;
+ case 1:
+ printf ("Main Clocks are stopped in POS State\n");
+ break;
+ case 2:
+ case 3:
+ printf ("PCI Clocks are stopped\n");
+ break;
+ }
+ printf ("INIT asserts %sINT2# (SMI)\n",
+ ((sysman & 0x10) == 0x10) ? "" : "not ");
+ printf ("INIT asserts %sINT1# (NMI)\n",
+ ((sysman & 0x20) == 0x20) ? "" : "not ");
+ printf ("INIT occured %d\n", (sysman >> 6) & 0x1);
+ printf ("SER1 is routed to %s\n",
+ ((flashcom & 0x1) == 0x1) ? "RS485" : "RS232");
+ printf ("COM2 is routed to %s\n",
+ ((flashcom & 0x2) == 0x2) ? "RS485" : "RS232");
+ printf ("RS485 is configured as %s duplex\n",
+ ((flashcom & 0x4) == 0x4) ? "full" : "half");
+ printf ("RS485 is connected to %s\n",
+ ((flashcom & 0x8) == 0x8) ? "COM1" : "COM2");
+ printf ("SER1 uses handshakes %s\n",
+ ((flashcom & 0x10) == 0x10) ? "DTR/DSR" : "RTS/CTS");
+ printf ("Bootflash is %swriteprotected\n",
+ ((flashcom & 0x20) == 0x20) ? "not " : "");
+ printf ("Bootflash VPP is %s\n",
+ ((flashcom & 0x40) == 0x40) ? "on" : "off");
+ printf ("Bootsector is %swriteprotected\n",
+ ((flashcom & 0x80) == 0x80) ? "not " : "");
+ switch ((can) & 0x3) {
+ case 0:
+ printf ("CAN Controller is on address 0x1000..0x10FF\n");
+ break;
+ case 1:
+ printf ("CAN Controller is on address 0x8000..0x80FF\n");
+ break;
+ case 2:
+ printf ("CAN Controller is on address 0xE000..0xE0FF\n");
+ break;
+ case 3:
+ printf ("CAN Controller is disabled\n");
+ break;
+ }
+ switch ((can >> 2) & 0x3) {
+ case 0:
+ printf ("CAN Controller Reset is ISA Reset\n");
+ break;
+ case 1:
+ printf ("CAN Controller Reset is ISA Reset and POS State\n");
+ break;
+ case 2:
+ case 3:
+ printf ("CAN Controller is in reset\n");
+ break;
+ }
+ if (((can >> 4) < 3) || ((can >> 4) == 8) || ((can >> 4) == 13))
+ printf ("CAN Interrupt is disabled\n");
+ else
+ printf ("CAN Interrupt is ISA INT%d\n", (can >> 4) & 0xf);
+ switch (serpwr & 0x3) {
+ case 0:
+ printf ("SER0 Drivers are enabled\n");
+ break;
+ case 1:
+ printf ("SER0 Drivers are disabled in the POS state\n");
+ break;
+ case 2:
+ case 3:
+ printf ("SER0 Drivers are disabled\n");
+ break;
+ }
+ switch ((serpwr >> 2) & 0x3) {
+ case 0:
+ printf ("SER1 Drivers are enabled\n");
+ break;
+ case 1:
+ printf ("SER1 Drivers are disabled in the POS state\n");
+ break;
+ case 2:
+ case 3:
+ printf ("SER1 Drivers are disabled\n");
+ break;
+ }
+ switch (compwr & 0x3) {
+ case 0:
+ printf ("COM1 Drivers are enabled\n");
+ break;
+ case 1:
+ printf ("COM1 Drivers are disabled in the POS state\n");
+ break;
+ case 2:
+ case 3:
+ printf ("COM1 Drivers are disabled\n");
+ break;
+ }
+ switch ((compwr >> 2) & 0x3) {
+ case 0:
+ printf ("COM2 Drivers are enabled\n");
+ break;
+ case 1:
+ printf ("COM2 Drivers are disabled in the POS state\n");
+ break;
+ case 2:
+ case 3:
+ printf ("COM2 Drivers are disabled\n");
+ break;
+ }
+ switch ((nicvga) & 0x3) {
+ case 0:
+ printf ("PHY is running\n");
+ break;
+ case 1:
+ printf ("PHY is in Power save mode in POS state\n");
+ break;
+ case 2:
+ case 3:
+ printf ("PHY is in Power save mode\n");
+ break;
+ }
+ switch ((nicvga >> 2) & 0x3) {
+ case 0:
+ printf ("VGA is running\n");
+ break;
+ case 1:
+ printf ("VGA is in Power save mode in POS state\n");
+ break;
+ case 2:
+ case 3:
+ printf ("VGA is in Power save mode\n");
+ break;
+ }
+ printf ("PHY is %sreseted\n", ((nicvga & 0x10) == 0x10) ? "" : "not ");
+ printf ("VGA is %sreseted\n", ((nicvga & 0x20) == 0x20) ? "" : "not ");
+ printf ("Reserved Configuration is %d %d\n", (nicvga >> 6) & 0x1,
+ (nicvga >> 7) & 0x1);
+ switch ((scsirst) & 0x3) {
+ case 0:
+ printf ("SCSI Controller is running\n");
+ break;
+ case 1:
+ printf ("SCSI Controller is in Power save mode in POS state\n");
+ break;
+ case 2:
+ case 3:
+ printf ("SCSI Controller is in Power save mode\n");
+ break;
+ }
+ printf ("SCSI termination is %s\n",
+ ((scsirst & 0x4) == 0x4) ? "disabled" : "enabled");
+ printf ("SCSI Controller is %sreseted\n",
+ ((scsirst & 0x10) == 0x10) ? "" : "not ");
+ printf ("IDE disks are %sreseted\n",
+ ((scsirst & 0x20) == 0x20) ? "" : "not ");
+ printf ("ISA Bus is %sreseted\n",
+ ((scsirst & 0x40) == 0x40) ? "" : "not ");
+ printf ("Super IO is %sreseted\n",
+ ((scsirst & 0x80) == 0x80) ? "" : "not ");
+}
+
+void user_led0 (unsigned char on)
+{
+ if (on == TRUE)
+ out8 (PLD_LED_USER_REG, (in8 (PLD_LED_USER_REG) | 0x1));
+ else
+ out8 (PLD_LED_USER_REG, (in8 (PLD_LED_USER_REG) & 0xfe));
+}
+
+void user_led1 (unsigned char on)
+{
+ if (on == TRUE)
+ out8 (PLD_LED_USER_REG, (in8 (PLD_LED_USER_REG) | 0x2));
+ else
+ out8 (PLD_LED_USER_REG, (in8 (PLD_LED_USER_REG) & 0xfd));
+}
+
+void ide_set_reset (int idereset)
+{
+ /* if reset = 1 IDE reset will be asserted */
+ unsigned char resreg;
+
+ resreg = in8 (PLD_SCSI_RST_REG);
+ if (idereset == 1)
+ resreg |= 0x20;
+ else {
+ udelay(10000);
+ resreg &= 0xdf;
+ }
+ out8 (PLD_SCSI_RST_REG, resreg);
+}
diff --git a/u-boot/board/mpl/pip405/pip405.h b/u-boot/board/mpl/pip405/pip405.h
new file mode 100644
index 0000000..704ab2c
--- /dev/null
+++ b/u-boot/board/mpl/pip405/pip405.h
@@ -0,0 +1,148 @@
+/*
+ * (C) Copyright 2001
+ * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+ /****************************************************************************
+ * Global routines used for PIP405
+ *****************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+extern int mem_test(unsigned long start, unsigned long ramsize,int mode);
+
+void print_pip405_info(void);
+
+void user_led0(unsigned char on);
+void user_led1(unsigned char on);
+
+
+#define PLD_BASE_ADDRESS CONFIG_SYS_ISA_IO_BASE_ADDRESS + 0x800
+#define PLD_PART_REG PLD_BASE_ADDRESS + 0
+#define PLD_VERS_REG PLD_BASE_ADDRESS + 1
+#define PLD_BOARD_CFG_REG PLD_BASE_ADDRESS + 2
+#define PLD_LED_USER_REG PLD_BASE_ADDRESS + 3
+#define PLD_SYS_MAN_REG PLD_BASE_ADDRESS + 4
+#define PLD_FLASH_COM_REG PLD_BASE_ADDRESS + 5
+#define PLD_CAN_REG PLD_BASE_ADDRESS + 6
+#define PLD_SER_PWR_REG PLD_BASE_ADDRESS + 7
+#define PLD_COM_PWR_REG PLD_BASE_ADDRESS + 8
+#define PLD_NIC_VGA_REG PLD_BASE_ADDRESS + 9
+#define PLD_SCSI_RST_REG PLD_BASE_ADDRESS + 0xA
+
+#define PIIX4_VENDOR_ID 0x8086
+#define PIIX4_IDE_DEV_ID 0x7111
+
+#endif
+
+/* timings */
+
+/* CS Config register (CS7) */
+#define CONFIG_PORT_BME 0 /* Burst disable */
+#define CONFIG_PORT_TWE 255 /* 255 * 30ns 120ns Waitstates (access=TWT+1+TH) */
+#define CONFIG_PORT_CSN 1 /* Chipselect is driven inactive for 1 Cycle BTW transfers */
+#define CONFIG_PORT_OEN 1 /* Cycles from CS low to OE low */
+#define CONFIG_PORT_WBN 1 /* Cycles from CS low to WE low */
+#define CONFIG_PORT_WBF 1 /* Cycles from WE high to CS high */
+#define CONFIG_PORT_TH 2 /* Number of hold cycles after transfer */
+#define CONFIG_PORT_RE 0 /* Ready disabled */
+#define CONFIG_PORT_SOR 1 /* Sample on Ready disabled */
+#define CONFIG_PORT_BEM 0 /* Byte Write only active on Write cycles */
+#define CONFIG_PORT_PEN 0 /* Parity disable */
+#define CONFIG_PORT_AP ((CONFIG_PORT_BME << 31) + (CONFIG_PORT_TWE << 23) + (CONFIG_PORT_CSN << 18) + (CONFIG_PORT_OEN << 16) + (CONFIG_PORT_WBN << 14) + \
+ (CONFIG_PORT_WBF << 12) + (CONFIG_PORT_TH << 9) + (CONFIG_PORT_RE << 8) + (CONFIG_PORT_SOR << 7) + (CONFIG_PORT_BEM << 6) + (CONFIG_PORT_PEN << 5))
+
+/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
+#define CONFIG_PORT_BS 0 /* 1 MByte */
+/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
+#define CONFIG_PORT_BU 3 /* R/W */
+/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
+#define CONFIG_PORT_BW 0 /* 16Bit */
+#define CONFIG_PORT_CR ((CONFIG_PORT_ADDR & 0xfff00000) + (CONFIG_PORT_BS << 17) + (CONFIG_PORT_BU << 15) + (CONFIG_PORT_BW << 13))
+
+/* Flash CS0 or CS 1 */
+/* 0x7F8FFE80 slowest timing at all... */
+#define FLASH_BME_B 1 /* Burst enable */
+#define FLASH_FWT_B 0x6 /* 6 * 30ns 210ns First Wait Access */
+#define FLASH_BWT_B 0x6 /* 6 * 30ns 210ns Burst Wait Access */
+#define FLASH_BME 0 /* Burst disable */
+#define FLASH_TWE 0xb/* 11 * 30ns 330ns Waitstates (access=TWT+1+TH) */
+#define FLASH_CSN 0 /* Chipselect is driven inactive for 1 Cycle BTW transfers */
+#define FLASH_OEN 1 /* Cycles from CS low to OE low */
+#define FLASH_WBN 1 /* Cycles from CS low to WE low */
+#define FLASH_WBF 1 /* Cycles from WE high to CS high */
+#define FLASH_TH 2 /* Number of hold cycles after transfer */
+#define FLASH_RE 0 /* Ready disabled */
+#define FLASH_SOR 1 /* Sample on Ready disabled */
+#define FLASH_BEM 0 /* Byte Write only active on Write cycles */
+#define FLASH_PEN 0 /* Parity disable */
+/* Access Parameter Register for non Boot */
+#define FLASH_AP ((FLASH_BME << 31) + (FLASH_TWE << 23) + (FLASH_CSN << 18) + (FLASH_OEN << 16) + (FLASH_WBN << 14) + \
+ (FLASH_WBF << 12) + (FLASH_TH << 9) + (FLASH_RE << 8) + (FLASH_SOR << 7) + (FLASH_BEM << 6) + (FLASH_PEN << 5))
+/* Access Parameter Register for Boot */
+#define FLASH_AP_B ((FLASH_BME_B << 31) + (FLASH_FWT_B << 26) + (FLASH_BWT_B << 23) + (FLASH_CSN << 18) + (FLASH_OEN << 16) + (FLASH_WBN << 14) + \
+ (FLASH_WBF << 12) + (FLASH_TH << 9) + (FLASH_RE << 8) + (FLASH_SOR << 7) + (FLASH_BEM << 6) + (FLASH_PEN << 5))
+
+/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
+#define FLASH_BS FLASH_SIZE_PRELIM /* 4 MByte */
+/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
+#define FLASH_BU 3 /* R/W */
+/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
+#define FLASH_BW 1 /* 16Bit */
+/* CR register for Boot */
+#define FLASH_CR_B ((FLASH_BASE_PRELIM & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13))
+/* CR register for non Boot */
+#define FLASH_CR ((MULTI_PURPOSE_SOCKET_ADDR & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13))
+
+/* MPS CS1 or CS0 */
+/* Boot CS: */
+#define MPS_BME_B 1 /* Burst enable */
+#define MPS_FWT_B 0x6/* 6 * 30ns 210ns First Wait Access */
+#define MPS_BWT_B 0x6 /* 6 * 30ns 210ns Burst Wait Access */
+#define MPS_BME 0 /* Burst disable */
+#define MPS_TWE 0xb/* 11 * 30ns 330ns Waitstates (access=TWT+1+TH) */
+#define MPS_CSN 0 /* Chipselect is driven inactive for 1 Cycle BTW transfers */
+#define MPS_OEN 1 /* Cycles from CS low to OE low */
+#define MPS_WBN 1 /* Cycles from CS low to WE low */
+#define MPS_WBF 1 /* Cycles from WE high to CS high */
+#define MPS_TH 2 /* Number of hold cycles after transfer */
+#define MPS_RE 0 /* Ready disabled */
+#define MPS_SOR 1 /* Sample on Ready disabled */
+#define MPS_BEM 0 /* Byte Write only active on Write cycles */
+#define MPS_PEN 0 /* Parity disable */
+/* Access Parameter Register for non Boot */
+#define MPS_AP ((MPS_BME << 31) + (MPS_TWE << 23) + (MPS_CSN << 18) + (MPS_OEN << 16) + (MPS_WBN << 14) + \
+ (MPS_WBF << 12) + (MPS_TH << 9) + (MPS_RE << 8) + (MPS_SOR << 7) + (MPS_BEM << 6) + (MPS_PEN << 5))
+/* Access Parameter Register for Boot */
+#define MPS_AP_B ((MPS_BME_B << 31) + (MPS_FWT_B << 26) + (MPS_BWT_B << 23) + (MPS_CSN << 18) + (MPS_OEN << 16) + (MPS_WBN << 14) + \
+ (MPS_WBF << 12) + (MPS_TH << 9) + (MPS_RE << 8) + (MPS_SOR << 7) + (MPS_BEM << 6) + (MPS_PEN << 5))
+
+/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
+#define MPS_BS 2 /* 4 MByte */
+#define MPS_BS_B FLASH_SIZE_PRELIM /* 1 MByte */
+/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
+#define MPS_BU 3 /* R/W */
+/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
+#define MPS_BW 0 /* 8Bit */
+/* CR register for Boot */
+#define MPS_CR_B ((FLASH_BASE_PRELIM & 0xfff00000) + (MPS_BS << 17) + (MPS_BU << 15) + (MPS_BW << 13))
+/* CR register for non Boot */
+#define MPS_CR ((MULTI_PURPOSE_SOCKET_ADDR & 0xfff00000) + (MPS_BS << 17) + (MPS_BU << 15) + (MPS_BW << 13))
diff --git a/u-boot/board/mpl/pip405/u-boot.lds.debug b/u-boot/board/mpl/pip405/u-boot.lds.debug
new file mode 100644
index 0000000..0e9cdcf
--- /dev/null
+++ b/u-boot/board/mpl/pip405/u-boot.lds.debug
@@ -0,0 +1,135 @@
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_ARCH(powerpc)
+/* Do we need any of these for elf?
+ __DYNAMIC = 0; */
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = + SIZEOF_HEADERS;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) }
+ .plt : { *(.plt) }
+ .text :
+ {
+ /* WARNING - the following is hand-optimized to fit within */
+ /* the sector layout of our flash chips! XXX FIXME XXX */
+
+ mpc8xx/start.o (.text)
+ common/dlmalloc.o (.text)
+ lib/vsprintf.o (.text)
+ lib/crc32.o (.text)
+ arch/powerpc/lib/extable.o (.text)
+
+ common/env_embedded.o(.text)
+
+ *(.text)
+ *(.got1)
+ }
+ _etext = .;
+ PROVIDE (etext = .);
+ .rodata :
+ {
+ *(.rodata)
+ *(.rodata1)
+ *(.rodata.str1.4)
+ *(.eh_frame)
+ }
+ .fini : { *(.fini) } =0
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+
+ /* Read-write section, merged into data segment: */
+ . = (. + 0x0FFF) & 0xFFFFF000;
+ _erotext = .;
+ PROVIDE (erotext = .);
+ .reloc :
+ {
+ *(.got)
+ _GOT2_TABLE_ = .;
+ *(.got2)
+ _FIXUP_TABLE_ = .;
+ *(.fixup)
+ }
+ __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+ __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.dynamic)
+ CONSTRUCTORS
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) }
+ __u_boot_cmd_end = .;
+
+
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
+
+ . = ALIGN(4096);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(4096);
+ __init_end = .;
+
+ __bss_start = .;
+ .bss :
+ {
+ *(.sbss) *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ _end = . ;
+ PROVIDE (end = .);
+}
diff --git a/u-boot/board/mpl/vcma9/Makefile b/u-boot/board/mpl/vcma9/Makefile
new file mode 100644
index 0000000..27cef1d
--- /dev/null
+++ b/u-boot/board/mpl/vcma9/Makefile
@@ -0,0 +1,56 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+ifneq ($(OBJTREE),$(SRCTREE))
+$(shell mkdir -p $(obj)../common)
+endif
+
+LIB = $(obj)lib$(BOARD).o
+
+COBJS := vcma9.o flash.o cmd_vcma9.o
+COBJS += ../common/common_util.o
+
+SOBJS := lowlevel_init.o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+SOBJS := $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(obj).depend $(OBJS) $(SOBJS)
+ $(call cmd_link_o_target, $(OBJS) $(SOBJS))
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak $(obj).depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/u-boot/board/mpl/vcma9/cmd_vcma9.c b/u-boot/board/mpl/vcma9/cmd_vcma9.c
new file mode 100644
index 0000000..0d5f46e
--- /dev/null
+++ b/u-boot/board/mpl/vcma9/cmd_vcma9.c
@@ -0,0 +1,186 @@
+/*
+ * (C) Copyright 2002
+ * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
+ *
+ * adapted for VCMA9
+ * David Mueller, ELSOFT AG, d.mueller@elsoft.ch
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+#include <command.h>
+#include <net.h>
+#include "vcma9.h"
+#include "../common/common_util.h"
+
+#if defined(CONFIG_CS8900)
+#include <../drivers/net/cs8900.h>
+
+static uchar cs8900_chksum(ushort data)
+{
+ return((data >> 8) & 0x00FF) + (data & 0x00FF);
+}
+
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+extern void print_vcma9_info(void);
+extern int vcma9_cantest(int);
+extern int vcma9_nandtest(void);
+extern int vcma9_nanderase(void);
+extern int vcma9_nandread(ulong);
+extern int vcma9_nandwrite(ulong);
+extern int vcma9_dactest(int);
+extern int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+
+/* ------------------------------------------------------------------------- */
+
+int do_vcma9(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ struct eth_device *dev;
+ char cs8900_name[10];
+ if (strcmp(argv[1], "info") == 0)
+ {
+ print_vcma9_info();
+ return 0;
+ }
+#if defined(CONFIG_CS8900)
+ if (strcmp(argv[1], "cs8900") == 0) {
+ sprintf(cs8900_name, "%s-0", CS8900_DRIVERNAME);
+ dev = eth_get_dev_by_name(cs8900_name);
+ if (!dev) {
+ printf("Couldn't find CS8900 driver");
+ return 0;
+ }
+ if (strcmp(argv[2], "read") == 0) {
+ uchar addr; ushort data;
+
+ addr = simple_strtoul(argv[3], NULL, 16);
+ cs8900_e2prom_read(dev, addr, &data);
+ printf("0x%2.2X: 0x%4.4X\n", addr, data);
+ } else if (strcmp(argv[2], "write") == 0) {
+ uchar addr; ushort data;
+
+ addr = simple_strtoul(argv[3], NULL, 16);
+ data = simple_strtoul(argv[4], NULL, 16);
+ cs8900_e2prom_write(dev, addr, data);
+ } else if (strcmp(argv[2], "setaddr") == 0) {
+ uchar addr, i, csum; ushort data;
+ uchar ethaddr[6];
+
+ /* check for valid ethaddr */
+ if (eth_getenv_enetaddr("ethaddr", ethaddr)) {
+ addr = 1;
+ data = 0x2158;
+ cs8900_e2prom_write(dev, addr, data);
+ csum = cs8900_chksum(data);
+ addr++;
+ for (i = 0; i < 6; i+=2) {
+ data = ethaddr[i+1] << 8 |
+ ethaddr[i];
+ cs8900_e2prom_write(dev, addr, data);
+ csum += cs8900_chksum(data);
+ addr++;
+ }
+ /* calculate header link byte */
+ data = 0xA100 | (addr * 2);
+ cs8900_e2prom_write(dev, 0, data);
+ csum += cs8900_chksum(data);
+ /* write checksum word */
+ cs8900_e2prom_write(dev, addr, (0 - csum) << 8);
+ } else {
+ puts("\nplease defined 'ethaddr'\n");
+ }
+ } else if (strcmp(argv[2], "dump") == 0) {
+ uchar addr = 0, endaddr, csum; ushort data;
+
+ puts("Dump of CS8900 config device: ");
+ cs8900_e2prom_read(dev, addr, &data);
+ if ((data & 0xE000) == 0xA000) {
+ endaddr = (data & 0x00FF) / 2;
+ csum = cs8900_chksum(data);
+ for (addr = 1; addr <= endaddr; addr++) {
+ cs8900_e2prom_read(dev, addr, &data);
+ printf("\n0x%2.2X: 0x%4.4X", addr, data);
+ csum += cs8900_chksum(data);
+ }
+ printf("\nChecksum: %s", (csum == 0) ? "ok" : "wrong");
+ } else {
+ puts("no valid config found");
+ }
+ puts("\n");
+ }
+
+ return 0;
+ }
+#endif
+#if 0
+ if (strcmp(argv[1], "cantest") == 0) {
+ if (argc >= 3)
+ vcma9_cantest(strcmp(argv[2], "s") ? 0 : 1);
+ else
+ vcma9_cantest(0);
+ return 0;
+ }
+ if (strcmp(argv[1], "nandtest") == 0) {
+ vcma9_nandtest();
+ return 0;
+ }
+ if (strcmp(argv[1], "nanderase") == 0) {
+ vcma9_nanderase();
+ return 0;
+ }
+ if (strcmp(argv[1], "nandread") == 0) {
+ ulong offset = 0;
+
+ if (argc >= 3)
+ offset = simple_strtoul(argv[2], NULL, 16);
+
+ vcma9_nandread(offset);
+ return 0;
+ }
+ if (strcmp(argv[1], "nandwrite") == 0) {
+ ulong offset = 0;
+
+ if (argc >= 3)
+ offset = simple_strtoul(argv[2], NULL, 16);
+
+ vcma9_nandwrite(offset);
+ return 0;
+ }
+ if (strcmp(argv[1], "dactest") == 0) {
+ if (argc >= 3)
+ vcma9_dactest(strcmp(argv[2], "s") ? 0 : 1);
+ else
+ vcma9_dactest(0);
+ return 0;
+ }
+#endif
+
+ return (do_mplcommon(cmdtp, flag, argc, argv));
+}
+
+U_BOOT_CMD(
+ vcma9, 6, 1, do_vcma9,
+ "VCMA9 specific commands",
+ "flash mem [SrcAddr]\n - updates U-Boot with image in memory"
+);
diff --git a/u-boot/board/mpl/vcma9/config.mk b/u-boot/board/mpl/vcma9/config.mk
new file mode 100644
index 0000000..e345913
--- /dev/null
+++ b/u-boot/board/mpl/vcma9/config.mk
@@ -0,0 +1,24 @@
+#
+# (C) Copyright 2002, 2003
+# David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
+#
+# MPL VCMA9 board with S3C2410X (ARM920T) cpu
+#
+# see http://www.mpl.ch/ for more information about the MPL VCMA9
+#
+
+#
+# MPL VCMA9 has 1 bank of minimal 16 MB DRAM
+# from 0x30000000
+#
+# Linux-Kernel is expected to be at 3000'8000, entry 3000'8000
+# optionally with a ramdisk at 3040'0000
+#
+# we load ourself to 33F8'0000
+#
+# download area is 3080'0000
+#
+
+
+#CONFIG_SYS_TEXT_BASE = 0x30F80000
+CONFIG_SYS_TEXT_BASE = 0x33F80000
diff --git a/u-boot/board/mpl/vcma9/flash.c b/u-boot/board/mpl/vcma9/flash.c
new file mode 100644
index 0000000..7abf9cf
--- /dev/null
+++ b/u-boot/board/mpl/vcma9/flash.c
@@ -0,0 +1,432 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+ulong myflush (void);
+
+
+#define FLASH_BANK_SIZE PHYS_FLASH_SIZE
+#define MAIN_SECT_SIZE 0x10000 /* 64 KB */
+
+flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
+
+
+#define CMD_READ_ARRAY 0x000000F0
+#define CMD_UNLOCK1 0x000000AA
+#define CMD_UNLOCK2 0x00000055
+#define CMD_ERASE_SETUP 0x00000080
+#define CMD_ERASE_CONFIRM 0x00000030
+#define CMD_PROGRAM 0x000000A0
+#define CMD_UNLOCK_BYPASS 0x00000020
+
+#define MEM_FLASH_ADDR1 (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x00000555 << 1)))
+#define MEM_FLASH_ADDR2 (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x000002AA << 1)))
+
+#define BIT_ERASE_DONE 0x00000080
+#define BIT_RDY_MASK 0x00000080
+#define BIT_PROGRAM_ERROR 0x00000020
+#define BIT_TIMEOUT 0x80000000 /* our flag */
+
+#define READY 1
+#define ERR 2
+#define TMO 4
+
+/*-----------------------------------------------------------------------
+ */
+
+ulong flash_init (void)
+{
+ int i, j;
+ ulong size = 0;
+
+ for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
+ ulong flashbase = 0;
+
+ flash_info[i].flash_id =
+#if defined(CONFIG_AMD_LV400)
+ (AMD_MANUFACT & FLASH_VENDMASK) |
+ (AMD_ID_LV400B & FLASH_TYPEMASK);
+#elif defined(CONFIG_AMD_LV800)
+ (AMD_MANUFACT & FLASH_VENDMASK) |
+ (AMD_ID_LV800B & FLASH_TYPEMASK);
+#else
+#error "Unknown flash configured"
+#endif
+ flash_info[i].size = FLASH_BANK_SIZE;
+ flash_info[i].sector_count = CONFIG_SYS_MAX_FLASH_SECT;
+ memset (flash_info[i].protect, 0, CONFIG_SYS_MAX_FLASH_SECT);
+ if (i == 0)
+ flashbase = PHYS_FLASH_1;
+ else
+ panic ("configured too many flash banks!\n");
+ for (j = 0; j < flash_info[i].sector_count; j++) {
+ if (j <= 3) {
+ /* 1st one is 16 KB */
+ if (j == 0) {
+ flash_info[i].start[j] =
+ flashbase + 0;
+ }
+
+ /* 2nd and 3rd are both 8 KB */
+ if ((j == 1) || (j == 2)) {
+ flash_info[i].start[j] =
+ flashbase + 0x4000 + (j -
+ 1) *
+ 0x2000;
+ }
+
+ /* 4th 32 KB */
+ if (j == 3) {
+ flash_info[i].start[j] =
+ flashbase + 0x8000;
+ }
+ } else {
+ flash_info[i].start[j] =
+ flashbase + (j - 3) * MAIN_SECT_SIZE;
+ }
+ }
+ size += flash_info[i].size;
+ }
+
+ flash_protect (FLAG_PROTECT_SET,
+ CONFIG_SYS_FLASH_BASE,
+ CONFIG_SYS_FLASH_BASE + monitor_flash_len - 1,
+ &flash_info[0]);
+
+ flash_protect (FLAG_PROTECT_SET,
+ CONFIG_ENV_ADDR,
+ CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1, &flash_info[0]);
+
+ return size;
+}
+
+/*-----------------------------------------------------------------------
+ */
+void flash_print_info (flash_info_t * info)
+{
+ int i;
+
+ switch (info->flash_id & FLASH_VENDMASK) {
+ case (AMD_MANUFACT & FLASH_VENDMASK):
+ puts ("AMD: ");
+ break;
+ default:
+ puts ("Unknown Vendor ");
+ break;
+ }
+
+ switch (info->flash_id & FLASH_TYPEMASK) {
+ case (AMD_ID_LV400B & FLASH_TYPEMASK):
+ puts ("1x Amd29LV400BB (4Mbit)\n");
+ break;
+ case (AMD_ID_LV800B & FLASH_TYPEMASK):
+ puts ("1x Amd29LV800BB (8Mbit)\n");
+ break;
+ default:
+ puts ("Unknown Chip Type\n");
+ goto Done;
+ break;
+ }
+
+ printf (" Size: %ld MB in %d Sectors\n",
+ info->size >> 20, info->sector_count);
+
+ puts (" Sector Start Addresses:");
+ for (i = 0; i < info->sector_count; i++) {
+ if ((i % 5) == 0) {
+ puts ("\n ");
+ }
+ printf (" %08lX%s", info->start[i],
+ info->protect[i] ? " (RO)" : " ");
+ }
+ puts ("\n");
+
+Done: ;
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+int flash_erase (flash_info_t * info, int s_first, int s_last)
+{
+ ushort result;
+ int iflag, cflag, prot, sect;
+ int rc = ERR_OK;
+ int chip;
+
+ /* first look for protection bits */
+
+ if (info->flash_id == FLASH_UNKNOWN)
+ return ERR_UNKNOWN_FLASH_TYPE;
+
+ if ((s_first < 0) || (s_first > s_last)) {
+ return ERR_INVAL;
+ }
+
+ if ((info->flash_id & FLASH_VENDMASK) !=
+ (AMD_MANUFACT & FLASH_VENDMASK)) {
+ return ERR_UNKNOWN_FLASH_VENDOR;
+ }
+
+ prot = 0;
+ for (sect = s_first; sect <= s_last; ++sect) {
+ if (info->protect[sect]) {
+ prot++;
+ }
+ }
+ if (prot)
+ return ERR_PROTECTED;
+
+ /*
+ * Disable interrupts which might cause a timeout
+ * here. Remember that our exception vectors are
+ * at address 0 in the flash, and we don't want a
+ * (ticker) exception to happen while the flash
+ * chip is in programming mode.
+ */
+ cflag = icache_status ();
+ icache_disable ();
+ iflag = disable_interrupts ();
+
+ /* Start erase on unprotected sectors */
+ for (sect = s_first; sect <= s_last && !ctrlc (); sect++) {
+ printf ("Erasing sector %2d ... ", sect);
+
+ /* arm simple, non interrupt dependent timer */
+ reset_timer_masked ();
+
+ if (info->protect[sect] == 0) { /* not protected */
+ vu_short *addr = (vu_short *) (info->start[sect]);
+
+ MEM_FLASH_ADDR1 = CMD_UNLOCK1;
+ MEM_FLASH_ADDR2 = CMD_UNLOCK2;
+ MEM_FLASH_ADDR1 = CMD_ERASE_SETUP;
+
+ MEM_FLASH_ADDR1 = CMD_UNLOCK1;
+ MEM_FLASH_ADDR2 = CMD_UNLOCK2;
+ *addr = CMD_ERASE_CONFIRM;
+
+ /* wait until flash is ready */
+ chip = 0;
+
+ do {
+ result = *addr;
+
+ /* check timeout */
+ if (get_timer_masked () >
+ CONFIG_SYS_FLASH_ERASE_TOUT) {
+ MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
+ chip = TMO;
+ break;
+ }
+
+ if (!chip
+ && (result & 0xFFFF) & BIT_ERASE_DONE)
+ chip = READY;
+
+ if (!chip
+ && (result & 0xFFFF) & BIT_PROGRAM_ERROR)
+ chip = ERR;
+
+ } while (!chip);
+
+ MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
+
+ if (chip == ERR) {
+ rc = ERR_PROG_ERROR;
+ goto outahere;
+ }
+ if (chip == TMO) {
+ rc = ERR_TIMOUT;
+ goto outahere;
+ }
+
+ puts ("ok.\n");
+ } else { /* it was protected */
+
+ puts ("protected!\n");
+ }
+ }
+
+ if (ctrlc ())
+ puts ("User Interrupt!\n");
+
+ outahere:
+ /* allow flash to settle - wait 10 ms */
+ udelay_masked (10000);
+
+ if (iflag)
+ enable_interrupts ();
+
+ if (cflag)
+ icache_enable ();
+
+ return rc;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash
+ */
+
+static int write_hword (flash_info_t * info, ulong dest, ushort data)
+{
+ vu_short *addr = (vu_short *) dest;
+ ushort result;
+ int rc = ERR_OK;
+ int cflag, iflag;
+ int chip;
+
+ /*
+ * Check if Flash is (sufficiently) erased
+ */
+ result = *addr;
+ if ((result & data) != data)
+ return ERR_NOT_ERASED;
+
+
+ /*
+ * Disable interrupts which might cause a timeout
+ * here. Remember that our exception vectors are
+ * at address 0 in the flash, and we don't want a
+ * (ticker) exception to happen while the flash
+ * chip is in programming mode.
+ */
+ cflag = icache_status ();
+ icache_disable ();
+ iflag = disable_interrupts ();
+
+ MEM_FLASH_ADDR1 = CMD_UNLOCK1;
+ MEM_FLASH_ADDR2 = CMD_UNLOCK2;
+ MEM_FLASH_ADDR1 = CMD_PROGRAM;
+ *addr = data;
+
+ /* arm simple, non interrupt dependent timer */
+ reset_timer_masked ();
+
+ /* wait until flash is ready */
+ chip = 0;
+ do {
+ result = *addr;
+
+ /* check timeout */
+ if (get_timer_masked () > CONFIG_SYS_FLASH_ERASE_TOUT) {
+ chip = ERR | TMO;
+ break;
+ }
+ if (!chip && ((result & 0x80) == (data & 0x80)))
+ chip = READY;
+
+ if (!chip && ((result & 0xFFFF) & BIT_PROGRAM_ERROR)) {
+ result = *addr;
+
+ if ((result & 0x80) == (data & 0x80))
+ chip = READY;
+ else
+ chip = ERR;
+ }
+
+ } while (!chip);
+
+ *addr = CMD_READ_ARRAY;
+
+ if (chip == ERR || *addr != data)
+ rc = ERR_PROG_ERROR;
+
+ if (iflag)
+ enable_interrupts ();
+
+ if (cflag)
+ icache_enable ();
+
+ return rc;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash.
+ */
+
+int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
+{
+ ulong cp, wp;
+ int l;
+ int i, rc;
+ ushort data;
+
+ wp = (addr & ~1); /* get lower word aligned address */
+
+ /*
+ * 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 << 8);
+ }
+ for (; i < 2 && cnt > 0; ++i) {
+ data = (data >> 8) | (*src++ << 8);
+ --cnt;
+ ++cp;
+ }
+ for (; cnt == 0 && i < 2; ++i, ++cp) {
+ data = (data >> 8) | (*(uchar *) cp << 8);
+ }
+
+ if ((rc = write_hword (info, wp, data)) != 0) {
+ return (rc);
+ }
+ wp += 2;
+ }
+
+ /*
+ * handle word aligned part
+ */
+ while (cnt >= 2) {
+ data = *((vu_short *) src);
+ if ((rc = write_hword (info, wp, data)) != 0) {
+ return (rc);
+ }
+ src += 2;
+ wp += 2;
+ cnt -= 2;
+ }
+
+ if (cnt == 0) {
+ return ERR_OK;
+ }
+
+ /*
+ * handle unaligned tail bytes
+ */
+ data = 0;
+ for (i = 0, cp = wp; i < 2 && cnt > 0; ++i, ++cp) {
+ data = (data >> 8) | (*src++ << 8);
+ --cnt;
+ }
+ for (; i < 2; ++i, ++cp) {
+ data = (data >> 8) | (*(uchar *) cp << 8);
+ }
+
+ return write_hword (info, wp, data);
+}
diff --git a/u-boot/board/mpl/vcma9/lowlevel_init.S b/u-boot/board/mpl/vcma9/lowlevel_init.S
new file mode 100644
index 0000000..062e868
--- /dev/null
+++ b/u-boot/board/mpl/vcma9/lowlevel_init.S
@@ -0,0 +1,212 @@
+/*
+ * Memory Setup stuff - taken from blob memsetup.S
+ *
+ * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and
+ * Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl)
+ *
+ * Modified for the Samsung SMDK2410 by
+ * (C) Copyright 2002
+ * David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+
+#include <config.h>
+#include <version.h>
+
+
+/* some parameters for the board */
+
+#define BWSCON 0x48000000
+#define PLD_BASE 0x2C000000
+#define SDRAM_REG 0x2C000106
+
+/* BWSCON */
+#define DW8 (0x0)
+#define DW16 (0x1)
+#define DW32 (0x2)
+#define WAIT (0x1<<2)
+#define UBLB (0x1<<3)
+
+/* BANKSIZE */
+#define BURST_EN (0x1<<7)
+
+#define B1_BWSCON (DW16)
+#define B2_BWSCON (DW32)
+#define B3_BWSCON (DW32)
+#define B4_BWSCON (DW16 + WAIT + UBLB)
+#define B5_BWSCON (DW8 + UBLB)
+#define B6_BWSCON (DW32)
+#define B7_BWSCON (DW32)
+
+/* BANK0CON */
+#define B0_Tacs 0x0 /* 0clk */
+#define B0_Tcos 0x1 /* 1clk */
+/*#define B0_Tcos 0x0 0clk */
+#define B0_Tacc 0x7 /* 14clk */
+/*#define B0_Tacc 0x5 8clk */
+#define B0_Tcoh 0x0 /* 0clk */
+#define B0_Tah 0x0 /* 0clk */
+#define B0_Tacp 0x0 /* page mode is not used */
+#define B0_PMC 0x0 /* page mode disabled */
+
+/* BANK1CON */
+#define B1_Tacs 0x0 /* 0clk */
+#define B1_Tcos 0x1 /* 1clk */
+/*#define B1_Tcos 0x0 0clk */
+#define B1_Tacc 0x7 /* 14clk */
+/*#define B1_Tacc 0x5 8clk */
+#define B1_Tcoh 0x0 /* 0clk */
+#define B1_Tah 0x0 /* 0clk */
+#define B1_Tacp 0x0 /* page mode is not used */
+#define B1_PMC 0x0 /* page mode disabled */
+
+#define B2_Tacs 0x3 /* 4clk */
+#define B2_Tcos 0x3 /* 4clk */
+#define B2_Tacc 0x7 /* 14clk */
+#define B2_Tcoh 0x3 /* 4clk */
+#define B2_Tah 0x3 /* 4clk */
+#define B2_Tacp 0x0 /* page mode is not used */
+#define B2_PMC 0x0 /* page mode disabled */
+
+#define B3_Tacs 0x3 /* 4clk */
+#define B3_Tcos 0x3 /* 4clk */
+#define B3_Tacc 0x7 /* 14clk */
+#define B3_Tcoh 0x3 /* 4clk */
+#define B3_Tah 0x3 /* 4clk */
+#define B3_Tacp 0x0 /* page mode is not used */
+#define B3_PMC 0x0 /* page mode disabled */
+
+#define B4_Tacs 0x3 /* 4clk */
+#define B4_Tcos 0x1 /* 1clk */
+#define B4_Tacc 0x7 /* 14clk */
+#define B4_Tcoh 0x1 /* 1clk */
+#define B4_Tah 0x0 /* 0clk */
+#define B4_Tacp 0x0 /* page mode is not used */
+#define B4_PMC 0x0 /* page mode disabled */
+
+#define B5_Tacs 0x0 /* 0clk */
+#define B5_Tcos 0x3 /* 4clk */
+#define B5_Tacc 0x5 /* 8clk */
+#define B5_Tcoh 0x2 /* 2clk */
+#define B5_Tah 0x1 /* 1clk */
+#define B5_Tacp 0x0 /* page mode is not used */
+#define B5_PMC 0x0 /* page mode disabled */
+
+#define B6_MT 0x3 /* SDRAM */
+#define B6_Trcd 0x1 /* 3clk */
+#define B6_SCAN 0x2 /* 10bit */
+
+#define B7_MT 0x3 /* SDRAM */
+#define B7_Trcd 0x1 /* 3clk */
+#define B7_SCAN 0x2 /* 10bit */
+
+/* REFRESH parameter */
+#define REFEN 0x1 /* Refresh enable */
+#define TREFMD 0x0 /* CBR(CAS before RAS)/Auto refresh */
+#define Trp 0x0 /* 2clk */
+#define Trc 0x3 /* 7clk */
+#define Tchr 0x2 /* 3clk */
+#define REFCNT 1113 /* period=15.6us, HCLK=60Mhz, (2048+1-15.6*60) */
+/**************************************/
+
+_TEXT_BASE:
+ .word CONFIG_SYS_TEXT_BASE
+
+.globl lowlevel_init
+lowlevel_init:
+ /* memory control configuration */
+ /* make r0 relative the current location so that it */
+ /* reads SMRDATA out of FLASH rather than memory ! */
+ ldr r0, =CSDATA
+ ldr r1, _TEXT_BASE
+ sub r0, r0, r1
+ ldr r1, =BWSCON /* Bus Width Status Controller */
+ add r2, r0, #CSDATA_END-CSDATA
+0:
+ ldr r3, [r0], #4
+ str r3, [r1], #4
+ cmp r2, r0
+ bne 0b
+
+ /* PLD access is now possible */
+ /* r0 == SDRAMDATA */
+ /* r1 == SDRAM controller regs */
+ ldr r2, =PLD_BASE
+ ldrb r3, [r2, #SDRAM_REG-PLD_BASE]
+ mov r4, #SDRAMDATA1_END-SDRAMDATA
+ /* calculate start and end point */
+ mla r0, r3, r4, r0
+ add r2, r0, r4
+0:
+ ldr r3, [r0], #4
+ str r3, [r1], #4
+ cmp r2, r0
+ bne 0b
+
+ /* everything is fine now */
+ mov pc, lr
+
+ .ltorg
+/* the literal pools origin */
+
+CSDATA:
+ .word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
+ .word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))
+ .word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))
+ .word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))
+ .word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))
+ .word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))
+ .word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))
+CSDATA_END:
+
+SDRAMDATA:
+/* 4Mx8x4 */
+ .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
+ .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
+ .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
+ .word 0x32 + BURST_EN
+ .word 0x30
+ .word 0x30
+SDRAMDATA1_END:
+
+/* 8Mx8x4 (not implemented yet) */
+ .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
+ .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
+ .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
+ .word 0x32 + BURST_EN
+ .word 0x30
+ .word 0x30
+
+/* 2Mx8x4 (not implemented yet) */
+ .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
+ .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
+ .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
+ .word 0x32 + BURST_EN
+ .word 0x30
+ .word 0x30
+
+/* 4Mx8x2 (not implemented yet) */
+ .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
+ .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
+ .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
+ .word 0x32 + BURST_EN
+ .word 0x30
+ .word 0x30
diff --git a/u-boot/board/mpl/vcma9/vcma9.c b/u-boot/board/mpl/vcma9/vcma9.c
new file mode 100644
index 0000000..978e6fd
--- /dev/null
+++ b/u-boot/board/mpl/vcma9/vcma9.c
@@ -0,0 +1,362 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <netdev.h>
+#include <asm/arch/s3c24x0_cpu.h>
+#include <stdio_dev.h>
+#include <i2c.h>
+
+#include "vcma9.h"
+#include "../common/common_util.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define FCLK_SPEED 1
+
+#if FCLK_SPEED==0 /* Fout = 203MHz, Fin = 12MHz for Audio */
+#define M_MDIV 0xC3
+#define M_PDIV 0x4
+#define M_SDIV 0x1
+#elif FCLK_SPEED==1 /* Fout = 202.8MHz */
+#define M_MDIV 0xA1
+#define M_PDIV 0x3
+#define M_SDIV 0x1
+#endif
+
+#define USB_CLOCK 1
+
+#if USB_CLOCK==0
+#define U_M_MDIV 0xA1
+#define U_M_PDIV 0x3
+#define U_M_SDIV 0x1
+#elif USB_CLOCK==1
+#define U_M_MDIV 0x48
+#define U_M_PDIV 0x3
+#define U_M_SDIV 0x2
+#endif
+
+static inline void delay(unsigned long loops)
+{
+ __asm__ volatile ("1:\n"
+ "subs %0, %1, #1\n"
+ "bne 1b":"=r" (loops):"0" (loops));
+}
+
+/*
+ * Miscellaneous platform dependent initialisations
+ */
+
+int board_init(void)
+{
+ struct s3c24x0_clock_power * const clk_power =
+ s3c24x0_get_base_clock_power();
+ struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio();
+
+ /* to reduce PLL lock time, adjust the LOCKTIME register */
+ clk_power->locktime = 0xFFFFFF;
+
+ /* configure MPLL */
+ clk_power->mpllcon = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);
+
+ /* some delay between MPLL and UPLL */
+ delay (4000);
+
+ /* configure UPLL */
+ clk_power->upllcon = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);
+
+ /* some delay between MPLL and UPLL */
+ delay (8000);
+
+ /* set up the I/O ports */
+ gpio->gpacon = 0x007FFFFF;
+ gpio->gpbcon = 0x002AAAAA;
+ gpio->gpbup = 0x000002BF;
+ gpio->gpccon = 0xAAAAAAAA;
+ gpio->gpcup = 0x0000FFFF;
+ gpio->gpdcon = 0xAAAAAAAA;
+ gpio->gpdup = 0x0000FFFF;
+ gpio->gpecon = 0xAAAAAAAA;
+ gpio->gpeup = 0x000037F7;
+ gpio->gpfcon = 0x00000000;
+ gpio->gpfup = 0x00000000;
+ gpio->gpgcon = 0xFFEAFF5A;
+ gpio->gpgup = 0x0000F0DC;
+ gpio->gphcon = 0x0028AAAA;
+ gpio->gphup = 0x00000656;
+
+ /* setup correct IRQ modes for NIC */
+ /* rising edge mode */
+ gpio->extint2 = (gpio->extint2 & ~(7<<8)) | (4<<8);
+
+ /* select USB port 2 to be host or device (fix to host for now) */
+ gpio->misccr |= 0x08;
+
+ /* init serial */
+ gd->baudrate = CONFIG_BAUDRATE;
+ gd->have_console = 1;
+ serial_init();
+
+ /* arch number of VCMA9-Board */
+ gd->bd->bi_arch_number = MACH_TYPE_MPL_VCMA9;
+
+ /* adress of boot parameters */
+ gd->bd->bi_boot_params = 0x30000100;
+
+ icache_enable();
+ dcache_enable();
+
+ return 0;
+}
+
+/*
+ * NAND flash initialization.
+ */
+#if defined(CONFIG_CMD_NAND)
+extern ulong
+nand_probe(ulong physadr);
+
+
+static inline void NF_Reset(void)
+{
+ int i;
+
+ NF_SetCE(NFCE_LOW);
+ NF_Cmd(0xFF); /* reset command */
+ for(i = 0; i < 10; i++); /* tWB = 100ns. */
+ NF_WaitRB(); /* wait 200~500us; */
+ NF_SetCE(NFCE_HIGH);
+}
+
+
+static inline void NF_Init(void)
+{
+#if 0 /* a little bit too optimistic */
+#define TACLS 0
+#define TWRPH0 3
+#define TWRPH1 0
+#else
+#define TACLS 0
+#define TWRPH0 4
+#define TWRPH1 2
+#endif
+
+ NF_Conf((1<<15)|(0<<14)|(0<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0));
+ /*nand->NFCONF = (1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0); */
+ /* 1 1 1 1, 1 xxx, r xxx, r xxx */
+ /* En 512B 4step ECCR nFCE=H tACLS tWRPH0 tWRPH1 */
+
+ NF_Reset();
+}
+
+void
+nand_init(void)
+{
+ struct s3c2410_nand * const nand = s3c2410_get_base_nand();
+
+ NF_Init();
+#ifdef DEBUG
+ printf("NAND flash probing at 0x%.8lX\n", (ulong)nand);
+#endif
+ printf ("%4lu MB\n", nand_probe((ulong)nand) >> 20);
+}
+#endif
+
+/*
+ * Get some Board/PLD Info
+ */
+
+static u8 Get_PLD_ID(void)
+{
+ VCMA9_PLD * const pld = VCMA9_get_base_PLD();
+
+ return(pld->ID);
+}
+
+static u8 Get_PLD_BOARD(void)
+{
+ VCMA9_PLD * const pld = VCMA9_get_base_PLD();
+
+ return(pld->BOARD);
+}
+
+static u8 Get_PLD_SDRAM(void)
+{
+ VCMA9_PLD * const pld = VCMA9_get_base_PLD();
+
+ return(pld->SDRAM);
+}
+
+static u8 Get_PLD_Version(void)
+{
+ return((Get_PLD_ID() >> 4) & 0x0F);
+}
+
+static u8 Get_PLD_Revision(void)
+{
+ return(Get_PLD_ID() & 0x0F);
+}
+
+#if 0 /* not used */
+static int Get_Board_Config(void)
+{
+ u8 config = Get_PLD_BOARD() & 0x03;
+
+ if (config == 3)
+ return 1;
+ else
+ return 0;
+}
+#endif
+
+static uchar Get_Board_PCB(void)
+{
+ return(((Get_PLD_BOARD() >> 4) & 0x03) + 'A');
+}
+
+static u8 Get_SDRAM_ChipNr(void)
+{
+ switch ((Get_PLD_SDRAM() >> 4) & 0x0F) {
+ case 0: return 4;
+ case 1: return 1;
+ case 2: return 2;
+ default: return 0;
+ }
+}
+
+static ulong Get_SDRAM_ChipSize(void)
+{
+ switch (Get_PLD_SDRAM() & 0x0F) {
+ case 0: return 16 * (1024*1024);
+ case 1: return 32 * (1024*1024);
+ case 2: return 8 * (1024*1024);
+ case 3: return 8 * (1024*1024);
+ default: return 0;
+ }
+}
+static const char * Get_SDRAM_ChipGeom(void)
+{
+ switch (Get_PLD_SDRAM() & 0x0F) {
+ case 0: return "4Mx8x4";
+ case 1: return "8Mx8x4";
+ case 2: return "2Mx8x4";
+ case 3: return "4Mx8x2";
+ default: return "unknown";
+ }
+}
+
+static void Show_VCMA9_Info(char *board_name, char *serial)
+{
+ printf("Board: %s SN: %s PCB Rev: %c PLD(%d,%d)\n",
+ board_name, serial, Get_Board_PCB(), Get_PLD_Version(), Get_PLD_Revision());
+ printf("SDRAM: %d chips %s\n", Get_SDRAM_ChipNr(), Get_SDRAM_ChipGeom());
+}
+
+int dram_init(void)
+{
+ gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+ gd->bd->bi_dram[0].size = Get_SDRAM_ChipSize() * Get_SDRAM_ChipNr();
+
+ return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Check Board Identity:
+ */
+
+int checkboard(void)
+{
+ char s[50];
+ int i;
+ backup_t *b = (backup_t *) s;
+
+ i = getenv_f("serial#", s, 32);
+ if ((i < 0) || strncmp (s, "VCMA9", 5)) {
+ get_backup_values (b);
+ if (strncmp (b->signature, "MPL\0", 4) != 0) {
+ puts ("### No HW ID - assuming VCMA9");
+ } else {
+ b->serial_name[5] = 0;
+ Show_VCMA9_Info(b->serial_name, &b->serial_name[6]);
+ }
+ } else {
+ s[5] = 0;
+ Show_VCMA9_Info(s, &s[6]);
+ }
+ /*printf("\n");*/
+ return(0);
+}
+
+
+int last_stage_init(void)
+{
+ checkboard();
+ stdio_print_current_devices();
+ check_env();
+ return 0;
+}
+
+/***************************************************************************
+ * some helping routines
+ */
+#if !CONFIG_USB_KEYBOARD
+int overwrite_console(void)
+{
+ /* return TRUE if console should be overwritten */
+ return 0;
+}
+#endif
+
+/************************************************************************
+* Print VCMA9 Info
+************************************************************************/
+void print_vcma9_info(void)
+{
+ char s[50];
+ int i;
+
+ if ((i = getenv_f("serial#", s, 32)) < 0) {
+ puts ("### No HW ID - assuming VCMA9");
+ printf("i %d", i*24);
+ } else {
+ s[5] = 0;
+ Show_VCMA9_Info(s, &s[6]);
+ }
+}
+
+#ifdef CONFIG_CMD_NET
+int board_eth_init(bd_t *bis)
+{
+ int rc = 0;
+#ifdef CONFIG_CS8900
+ rc = cs8900_initialize(0, CONFIG_CS8900_BASE);
+#endif
+ return rc;
+}
+#endif
diff --git a/u-boot/board/mpl/vcma9/vcma9.h b/u-boot/board/mpl/vcma9/vcma9.h
new file mode 100644
index 0000000..94fd2fa
--- /dev/null
+++ b/u-boot/board/mpl/vcma9/vcma9.h
@@ -0,0 +1,134 @@
+/*
+ * (C) Copyright 2002, 2003
+ * David Mueller, ELSOFT AG, d.mueller@elsoft.ch
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+ /****************************************************************************
+ * Global routines used for VCMA9
+ *****************************************************************************/
+
+#include <asm/arch/s3c24x0_cpu.h>
+
+extern int mem_test(unsigned long start, unsigned long ramsize,int mode);
+
+void print_vcma9_info(void);
+
+#if defined(CONFIG_CMD_NAND)
+typedef enum {
+ NFCE_LOW,
+ NFCE_HIGH
+} NFCE_STATE;
+
+static inline void NF_Conf(u16 conf)
+{
+ struct s3c2410_nand * const nand = s3c2410_get_base_nand();
+
+ nand->NFCONF = conf;
+}
+
+static inline void NF_Cmd(u8 cmd)
+{
+ struct s3c2410_nand * const nand = s3c2410_get_base_nand();
+
+ nand->NFCMD = cmd;
+}
+
+static inline void NF_CmdW(u8 cmd)
+{
+ NF_Cmd(cmd);
+ udelay(1);
+}
+
+static inline void NF_Addr(u8 addr)
+{
+ struct s3c2410_nand * const nand = s3c2410_get_base_nand();
+
+ nand->NFADDR = addr;
+}
+
+static inline void NF_SetCE(NFCE_STATE s)
+{
+ struct s3c2410_nand * const nand = s3c2410_get_base_nand();
+
+ switch (s) {
+ case NFCE_LOW:
+ nand->NFCONF &= ~(1<<11);
+ break;
+
+ case NFCE_HIGH:
+ nand->NFCONF |= (1<<11);
+ break;
+ }
+}
+
+static inline void NF_WaitRB(void)
+{
+ struct s3c2410_nand * const nand = s3c2410_get_base_nand();
+
+ while (!(nand->NFSTAT & (1<<0)));
+}
+
+static inline void NF_Write(u8 data)
+{
+ struct s3c2410_nand * const nand = s3c2410_get_base_nand();
+
+ nand->NFDATA = data;
+}
+
+static inline u8 NF_Read(void)
+{
+ struct s3c2410_nand * const nand = s3c2410_get_base_nand();
+
+ return(nand->NFDATA);
+}
+
+static inline void NF_Init_ECC(void)
+{
+ struct s3c2410_nand * const nand = s3c2410_get_base_nand();
+
+ nand->NFCONF |= (1<<12);
+}
+
+static inline u32 NF_Read_ECC(void)
+{
+ struct s3c2410_nand * const nand = s3c2410_get_base_nand();
+
+ return(nand->NFECC);
+}
+
+#endif
+
+/* VCMA9 PLD regsiters */
+typedef struct {
+ u8 ID;
+ u8 NIC;
+ u8 CAN;
+ u8 MISC;
+ u8 GPCD;
+ u8 BOARD;
+ u8 SDRAM;
+} /*__attribute__((__packed__))*/ VCMA9_PLD;
+
+#define VCMA9_PLD_BASE 0x2C000100
+static inline VCMA9_PLD *VCMA9_get_base_PLD(void)
+{
+ return (VCMA9_PLD * const)VCMA9_PLD_BASE;
+}