Add support for MP2USB board.
authorWolfgang Denk <wd@pollux.(none)>
Sun, 25 Sep 2005 23:14:38 +0000 (01:14 +0200)
committerWolfgang Denk <wd@pollux.(none)>
Sun, 25 Sep 2005 23:14:38 +0000 (01:14 +0200)
Patch by Eric Benard, 07 Apr 2005

CHANGELOG
MAKEALL
Makefile
board/mp2usb/Makefile [new file with mode: 0644]
board/mp2usb/config.mk [new file with mode: 0644]
board/mp2usb/dm9161.c [new file with mode: 0644]
board/mp2usb/flash.c [new file with mode: 0644]
board/mp2usb/mp2usb.c [new file with mode: 0644]
board/mp2usb/u-boot.lds [new file with mode: 0644]
include/configs/mp2usb.h [new file with mode: 0644]

index 7955d5fe9739274707a3c053773032d1f31172ab..33d48a09c612948a9809e138a335c8b9f7c0aa4b 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,9 @@
 Changes for U-Boot 1.1.4:
 ======================================================================
 
+* Add support for MP2USB board.
+  Patch by Eric Benard, 07 Apr 2005
+
 * Add board support for armadillo HT1070
   Patch by Rowel Atienza, 06 Apr 2005
 
diff --git a/MAKEALL b/MAKEALL
index 93bd4c9b1b9f0a58a94083dc3f51596c65d58069..ba6025143f404c5cf53d93a126bd480affd3851c 100755 (executable)
--- a/MAKEALL
+++ b/MAKEALL
@@ -179,10 +179,10 @@ LIST_ARM9="       \
        integratorcp_CM920T_ETM         integratorcp_CM922T_XA10        \
        integratorcp_CM926EJ_S          integratorcp_CM940T             \
        integratorcp_CM946E_S           integratorcp_CM966E_S           \
-       lpd7a400        mx1ads          mx1fs2          omap1510inn     \
-       omap1610h2      omap1610inn     omap730p2       scb9328         \
-       smdk2400        smdk2410        trab            VCMA9           \
-       versatile       voiceblue                                       \
+       lpd7a400        mp2usb          mx1ads          mx1fs2          \
+       omap1510inn     omap1610h2      omap1610inn     omap730p2       \
+       scb9328         smdk2400        smdk2410        trab            \
+       VCMA9           versatile       voiceblue                       \
 "
 
 #########################################################################
index 157201f8f77f78c9256102a1e25ac6b74eea44c3..12c186b49f1d4ede3027a0c09ee68d14e3eeaf88 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1390,6 +1390,9 @@ at91rm9200dk_config       :       unconfig
 cmc_pu2_config :       unconfig
        @./mkconfig $(@:_config=) arm arm920t cmc_pu2 NULL at91rm9200
 
+mp2usb_config  :       unconfig
+       @./mkconfig $(@:_config=) arm arm920t mp2usb NULL at91rm9200
+
 ########################################################################
 ## ARM Integrator boards
 ## There are two variants /AP && /CP
diff --git a/board/mp2usb/Makefile b/board/mp2usb/Makefile
new file mode 100644 (file)
index 0000000..8f16511
--- /dev/null
@@ -0,0 +1,46 @@
+#
+# (C) Copyright 2003
+# 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
+
+LIB    = lib$(BOARD).a
+
+OBJS   := mp2usb.o dm9161.o flash.o
+
+$(LIB):        $(OBJS) $(SOBJS)
+       $(AR) crv $@ $(OBJS) $(SOBJS)
+
+clean:
+       rm -f $(SOBJS) $(OBJS)
+
+distclean:     clean
+       rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+.depend:       Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
+               $(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+
+-include .depend
+
+#########################################################################
diff --git a/board/mp2usb/config.mk b/board/mp2usb/config.mk
new file mode 100644 (file)
index 0000000..e299bfd
--- /dev/null
@@ -0,0 +1,3 @@
+TEXT_BASE = 0x27F00000
+## For testing: load at 0x20100000 and "go" at 0x201000A4
+#TEXT_BASE = 0x20100000
diff --git a/board/mp2usb/dm9161.c b/board/mp2usb/dm9161.c
new file mode 100644 (file)
index 0000000..73537c0
--- /dev/null
@@ -0,0 +1,243 @@
+/*
+ * (C) Copyright 2003
+ * Author : Hamid Ikdoumi (Atmel)
+ *
+ * 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 <at91rm9200_net.h>
+#include <net.h>
+#include <dm9161.h>
+
+#ifdef CONFIG_DRIVER_ETHER
+
+#if (CONFIG_COMMANDS & CFG_CMD_NET)
+
+/*
+ * Name:
+ *     dm9161_IsPhyConnected
+ * Description:
+ *     Reads the 2 PHY ID registers
+ * Arguments:
+ *     p_mac - pointer to AT91S_EMAC struct
+ * Return value:
+ *     TRUE - if id read successfully
+ *     FALSE- if error
+ */
+static unsigned int dm9161_IsPhyConnected (AT91PS_EMAC p_mac)
+{
+       unsigned short Id1, Id2;
+
+       at91rm9200_EmacEnableMDIO (p_mac);
+       at91rm9200_EmacReadPhy (p_mac, DM9161_PHYID1, &Id1);
+       at91rm9200_EmacReadPhy (p_mac, DM9161_PHYID2, &Id2);
+       at91rm9200_EmacDisableMDIO (p_mac);
+
+       if ((Id1 == (DM9161_PHYID1_OUI >> 6)) &&
+               ((Id2 >> 10) == (DM9161_PHYID1_OUI & DM9161_LSB_MASK)))
+               return TRUE;
+
+       return FALSE;
+}
+
+/*
+ * Name:
+ *     dm9161_GetLinkSpeed
+ * Description:
+ *     Link parallel detection status of MAC is checked and set in the
+ *     MAC configuration registers
+ * Arguments:
+ *     p_mac - pointer to MAC
+ * Return value:
+ *     TRUE - if link status set succesfully
+ *     FALSE - if link status not set
+ */
+static UCHAR dm9161_GetLinkSpeed (AT91PS_EMAC p_mac)
+{
+       unsigned short stat1, stat2;
+
+       if (!at91rm9200_EmacReadPhy (p_mac, DM9161_BMSR, &stat1))
+               return FALSE;
+
+       if (!(stat1 & DM9161_LINK_STATUS))      /* link status up? */
+               return FALSE;
+
+       if (!at91rm9200_EmacReadPhy (p_mac, DM9161_DSCSR, &stat2))
+               return FALSE;
+
+       if ((stat1 & DM9161_100BASE_TX_FD) && (stat2 & DM9161_100FDX)) {
+               /*set Emac for 100BaseTX and Full Duplex  */
+               p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD;
+               return TRUE;
+       }
+
+       if ((stat1 & DM9161_10BASE_T_FD) && (stat2 & DM9161_10FDX)) {
+               /*set MII for 10BaseT and Full Duplex  */
+               p_mac->EMAC_CFG = (p_mac->EMAC_CFG &
+                               ~(AT91C_EMAC_SPD | AT91C_EMAC_FD))
+                               | AT91C_EMAC_FD;
+               return TRUE;
+       }
+
+       if ((stat1 & DM9161_100BASE_T4_HD) && (stat2 & DM9161_100HDX)) {
+               /*set MII for 100BaseTX and Half Duplex  */
+               p_mac->EMAC_CFG = (p_mac->EMAC_CFG &
+                               ~(AT91C_EMAC_SPD | AT91C_EMAC_FD))
+                               | AT91C_EMAC_SPD;
+               return TRUE;
+       }
+
+       if ((stat1 & DM9161_10BASE_T_HD) && (stat2 & DM9161_10HDX)) {
+               /*set MII for 10BaseT and Half Duplex  */
+               p_mac->EMAC_CFG &= ~(AT91C_EMAC_SPD | AT91C_EMAC_FD);
+               return TRUE;
+       }
+       return FALSE;
+}
+
+
+/*
+ * Name:
+ *     dm9161_InitPhy
+ * Description:
+ *     MAC starts checking its link by using parallel detection and
+ *     Autonegotiation and the same is set in the MAC configuration registers
+ * Arguments:
+ *     p_mac - pointer to struct AT91S_EMAC
+ * Return value:
+ *     TRUE - if link status set succesfully
+ *     FALSE - if link status not set
+ */
+static UCHAR dm9161_InitPhy (AT91PS_EMAC p_mac)
+{
+       UCHAR ret = TRUE;
+       unsigned short IntValue;
+
+       at91rm9200_EmacEnableMDIO (p_mac);
+
+       if (!dm9161_GetLinkSpeed (p_mac)) {
+               /* Try another time */
+               ret = dm9161_GetLinkSpeed (p_mac);
+       }
+
+       /* Disable PHY Interrupts */
+       at91rm9200_EmacReadPhy (p_mac, DM9161_MDINTR, &IntValue);
+       /* clear FDX, SPD, Link, INTR masks */
+       IntValue &= ~(DM9161_FDX_MASK | DM9161_SPD_MASK |
+                     DM9161_LINK_MASK | DM9161_INTR_MASK);
+       at91rm9200_EmacWritePhy (p_mac, DM9161_MDINTR, &IntValue);
+       at91rm9200_EmacDisableMDIO (p_mac);
+
+       return (ret);
+}
+
+
+/*
+ * Name:
+ *     dm9161_AutoNegotiate
+ * Description:
+ *     MAC Autonegotiates with the partner status of same is set in the
+ *     MAC configuration registers
+ * Arguments:
+ *     dev - pointer to struct net_device
+ * Return value:
+ *     TRUE - if link status set successfully
+ *     FALSE - if link status not set
+ */
+static UCHAR dm9161_AutoNegotiate (AT91PS_EMAC p_mac, int *status)
+{
+       unsigned short value;
+       unsigned short PhyAnar;
+       unsigned short PhyAnalpar;
+
+       /* Set dm9161 control register */
+       if (!at91rm9200_EmacReadPhy (p_mac, DM9161_BMCR, &value))
+               return FALSE;
+       value &= ~DM9161_AUTONEG;       /* remove autonegotiation enable */
+       value |= DM9161_ISOLATE;        /* Electrically isolate PHY */
+       if (!at91rm9200_EmacWritePhy (p_mac, DM9161_BMCR, &value))
+               return FALSE;
+
+       /* Set the Auto_negotiation Advertisement Register */
+       /* MII advertising for Next page, 100BaseTxFD and HD, 10BaseTFD and HD, IEEE 802.3 */
+       PhyAnar = DM9161_NP | DM9161_TX_FDX | DM9161_TX_HDX |
+                 DM9161_10_FDX | DM9161_10_HDX | DM9161_AN_IEEE_802_3;
+       if (!at91rm9200_EmacWritePhy (p_mac, DM9161_ANAR, &PhyAnar))
+               return FALSE;
+
+       /* Read the Control Register     */
+       if (!at91rm9200_EmacReadPhy (p_mac, DM9161_BMCR, &value))
+               return FALSE;
+
+       value |= DM9161_SPEED_SELECT | DM9161_AUTONEG | DM9161_DUPLEX_MODE;
+       if (!at91rm9200_EmacWritePhy (p_mac, DM9161_BMCR, &value))
+               return FALSE;
+       /* Restart Auto_negotiation  */
+       value |= DM9161_RESTART_AUTONEG;
+       if (!at91rm9200_EmacWritePhy (p_mac, DM9161_BMCR, &value))
+               return FALSE;
+
+       /*check AutoNegotiate complete */
+       udelay (10000);
+       at91rm9200_EmacReadPhy (p_mac, DM9161_BMSR, &value);
+       if (!(value & DM9161_AUTONEG_COMP))
+               return FALSE;
+
+       /* Get the AutoNeg Link partner base page */
+       if (!at91rm9200_EmacReadPhy (p_mac, DM9161_ANLPAR, &PhyAnalpar))
+               return FALSE;
+
+       if ((PhyAnar & DM9161_TX_FDX) && (PhyAnalpar & DM9161_TX_FDX)) {
+               /*set MII for 100BaseTX and Full Duplex  */
+               p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD;
+               return TRUE;
+       }
+
+       if ((PhyAnar & DM9161_10_FDX) && (PhyAnalpar & DM9161_10_FDX)) {
+               /*set MII for 10BaseT and Full Duplex  */
+               p_mac->EMAC_CFG = (p_mac->EMAC_CFG &
+                               ~(AT91C_EMAC_SPD | AT91C_EMAC_FD))
+                               | AT91C_EMAC_FD;
+               return TRUE;
+       }
+       return FALSE;
+}
+
+
+/*
+ * Name:
+ *     at91rm92000_GetPhyInterface
+ * Description:
+ *     Initialise the interface functions to the PHY
+ * Arguments:
+ *     None
+ * Return value:
+ *     None
+ */
+void at91rm92000_GetPhyInterface(AT91PS_PhyOps p_phyops)
+{
+       p_phyops->Init = dm9161_InitPhy;
+       p_phyops->IsPhyConnected = dm9161_IsPhyConnected;
+       p_phyops->GetLinkSpeed = dm9161_GetLinkSpeed;
+       p_phyops->AutoNegotiate = dm9161_AutoNegotiate;
+}
+
+#endif /* CONFIG_COMMANDS & CFG_CMD_NET */
+
+#endif /* CONFIG_DRIVER_ETHER */
diff --git a/board/mp2usb/flash.c b/board/mp2usb/flash.c
new file mode 100644 (file)
index 0000000..070dbf6
--- /dev/null
@@ -0,0 +1,557 @@
+/*
+ * (C) Copyright 2001
+ * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
+ *
+ * (C) Copyright 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * Modified for the MP2USB by (C) Copyright 2005 Eric Benard
+ * ebenard@eukrea.com
+ *
+ * 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 <linux/byteorder/swab.h>
+
+#define CFG_MAX_FLASH_BANKS    1
+#define PHYS_FLASH_SECT_SIZE   0x00020000 /* 128 KB sectors (x1) */
+
+flash_info_t flash_info[CFG_MAX_FLASH_BANKS];  /* info for FLASH chips */
+
+#define FLASH_PORT_WIDTH       ushort
+#define FLASH_PORT_WIDTHV      vu_short
+#define SWAP(x)                        __swab16(x)
+
+#define FPW                    FLASH_PORT_WIDTH
+#define FPWV                   FLASH_PORT_WIDTHV
+
+#define mb() __asm__ __volatile__ ("" : : : "memory")
+
+/* Intel-compatible flash commands */
+#define INTEL_PROGRAM  0x00100010
+#define INTEL_ERASE    0x00200020
+#define INTEL_PROG     0x00400040
+#define INTEL_CLEAR    0x00500050
+#define INTEL_LOCKBIT  0x00600060
+#define INTEL_PROTECT  0x00010001
+#define INTEL_STATUS   0x00700070
+#define INTEL_READID   0x00900090
+#define INTEL_SUSPEND  0x00B000B0
+#define INTEL_CONFIRM  0x00D000D0
+#define INTEL_RESET    0xFFFFFFFF
+
+/* Intel-compatible flash status bits */
+#define INTEL_FINISHED 0x00800080
+#define INTEL_OK       0x00800080
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+static ulong flash_get_size (FPW *addr, flash_info_t *info);
+static int write_data (flash_info_t *info, ulong dest, FPW data);
+static void flash_get_offsets (ulong base, flash_info_t *info);
+void inline spin_wheel (void);
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long flash_init (void)
+{
+       int i;
+       ulong size = 0;
+
+       for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
+               switch (i) {
+               case 0:
+                       flash_get_size ((FPW *) PHYS_FLASH_1, &flash_info[i]);
+                       flash_get_offsets (PHYS_FLASH_1, &flash_info[i]);
+                       break;
+               default:
+                       panic ("configured too many flash banks!\n");
+                       break;
+               }
+               size += flash_info[i].size;
+       }
+
+       /* Protect monitor and environment sectors
+        */
+       flash_protect ( FLAG_PROTECT_SET,
+                       CFG_FLASH_BASE,
+                       CFG_FLASH_BASE + monitor_flash_len - 1,
+                       &flash_info[0] );
+
+       flash_protect ( FLAG_PROTECT_SET,
+                       CFG_ENV_ADDR,
+                       CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0] );
+
+       return size;
+}
+
+/*-----------------------------------------------------------------------
+ */
+static void flash_get_offsets (ulong base, flash_info_t *info)
+{
+       int i;
+
+       if (info->flash_id == FLASH_UNKNOWN) {
+               return;
+       }
+
+       if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
+               for (i = 0; i < info->sector_count; i++) {
+                       info->start[i] = base + (i * PHYS_FLASH_SECT_SIZE);
+                       info->protect[i] = 0;
+               }
+       }
+}
+
+/*-----------------------------------------------------------------------
+ */
+void flash_print_info (flash_info_t *info)
+{
+       int i;
+
+       if (info->flash_id == FLASH_UNKNOWN) {
+               printf ("missing or unknown FLASH type\n");
+               return;
+       }
+
+       switch (info->flash_id & FLASH_VENDMASK) {
+       case FLASH_MAN_INTEL:
+               printf ("INTEL ");
+               break;
+       default:
+               printf ("Unknown Vendor ");
+               break;
+       }
+
+       switch (info->flash_id & FLASH_TYPEMASK) {
+       case FLASH_28F640J3A:
+               printf ("28F640J3A\n");
+               break;
+       case FLASH_28F128J3A:
+               printf ("28F128J3A\n");
+               break;
+       default:
+               printf ("Unknown Chip Type\n");
+               break;
+       }
+
+       printf ("  Size: %ld MB in %d Sectors\n",
+                       info->size >> 20, info->sector_count);
+
+       printf ("  Sector Start Addresses:");
+       for (i = 0; i < info->sector_count; ++i) {
+               if ((i % 5) == 0)
+                       printf ("\n   ");
+               printf (" %08lX%s",
+                       info->start[i],
+                       info->protect[i] ? " (RO)" : "     ");
+       }
+       printf ("\n");
+       return;
+}
+
+/*
+ * The following code cannot be run from FLASH!
+ */
+static ulong flash_get_size (FPW *addr, flash_info_t *info)
+{
+       volatile FPW value;
+
+       /* Write auto select command: read Manufacturer ID */
+       addr[0x5555] = (FPW) 0x00AA00AA;
+       addr[0x2AAA] = (FPW) 0x00550055;
+       addr[0x5555] = (FPW) 0x00900090;
+
+       mb ();
+       value = addr[0];
+
+       switch (value) {
+
+       case (FPW) INTEL_MANUFACT:
+               info->flash_id = FLASH_MAN_INTEL;
+               break;
+
+       default:
+               info->flash_id = FLASH_UNKNOWN;
+               info->sector_count = 0;
+               info->size = 0;
+               addr[0] = (FPW) INTEL_RESET;    /* restore read mode */
+               return (0);                     /* no or unknown flash  */
+       }
+
+       mb ();
+       value = addr[1];                        /* device ID        */
+
+       switch (value) {
+
+       case (FPW) INTEL_ID_28F640J3A:
+               info->flash_id += FLASH_28F640J3A;
+               info->sector_count = 64;
+               info->size = 0x00800000;
+               break;                          /* => 8 MB     */
+
+       case (FPW) INTEL_ID_28F128J3A:
+               info->flash_id += FLASH_28F128J3A;
+               info->sector_count = 128;
+               info->size = 0x01000000;
+               break;                          /* => 16 MB     */
+
+       default:
+               info->flash_id = FLASH_UNKNOWN;
+               break;
+       }
+
+       if (info->sector_count > CFG_MAX_FLASH_SECT) {
+               printf ("** ERROR: sector count %d > max (%d) **\n",
+                       info->sector_count, CFG_MAX_FLASH_SECT);
+               info->sector_count = CFG_MAX_FLASH_SECT;
+       }
+
+       addr[0] = (FPW) INTEL_RESET;            /* restore read mode */
+
+       return (info->size);
+}
+
+
+/*-----------------------------------------------------------------------
+ */
+
+int flash_erase (flash_info_t *info, int s_first, int s_last)
+{
+       int flag, prot, sect;
+       ulong type, start, last;
+       int rcode = 0;
+       int cflag, iflag;
+
+       if ((s_first < 0) || (s_first > s_last)) {
+               if (info->flash_id == FLASH_UNKNOWN) {
+                       printf ("- missing\n");
+               } else {
+                       printf ("- no sectors to erase\n");
+               }
+               return 1;
+       }
+
+       type = (info->flash_id & FLASH_VENDMASK);
+       if ((type != FLASH_MAN_INTEL)) {
+               printf ("Can't erase unknown flash type %08lx - aborted\n",
+                       info->flash_id);
+               return 1;
+       }
+
+       prot = 0;
+       for (sect = s_first; sect <= s_last; ++sect) {
+               if (info->protect[sect]) {
+                       prot++;
+               }
+       }
+
+       if (prot) {
+               printf ("- Warning: %d protected sectors will not be erased!\n",
+                       prot);
+       } else {
+               printf ("\n");
+       }
+
+       start = get_timer (0);
+       last = start;
+
+       /*
+        * 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 ();
+
+       /* 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 */
+                       FPWV *addr = (FPWV *) (info->start[sect]);
+                       FPW status;
+
+                       printf ("Erasing sector %2d ... ", sect);
+
+                       /* arm simple, non interrupt dependent timer */
+                       reset_timer_masked ();
+
+                       *addr = (FPW) INTEL_CLEAR;      /* clear status register */
+                       *addr = (FPW) INTEL_ERASE;      /* erase setup */
+                       *addr = (FPW) INTEL_CONFIRM;    /* erase confirm */
+
+                       while (((status = *addr) & (FPW) INTEL_FINISHED) != (FPW) INTEL_FINISHED) {
+                               if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) {
+                                       printf ("Timeout\n");
+                                       *addr = (FPW) INTEL_SUSPEND;    /* suspend erase     */
+                                       *addr = (FPW) INTEL_RESET;      /* reset to read mode */
+                                       rcode = 1;
+                                       break;
+                               }
+                       }
+
+                       *addr = INTEL_CLEAR;    /* clear status register cmd.   */
+                       *addr = INTEL_RESET;    /* resest to read mode          */
+
+                       printf (" done\n");
+               }
+       }
+
+       if (iflag)
+               enable_interrupts ();
+
+       if (cflag)
+               icache_enable ();
+
+       return rcode;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ * 4 - Flash not identified
+ */
+
+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+       ulong cp, wp;
+       FPW data;
+       int count, i, l, rc, port_width;
+
+       if (info->flash_id == FLASH_UNKNOWN) {
+               return 4;
+       }
+
+       /* get lower word aligned address */
+       wp = (addr & ~1);
+       port_width = 2;
+
+       /*
+        * handle unaligned start bytes
+        */
+       if ((l = addr - wp) != 0) {
+               data = 0;
+               for (i = 0, cp = wp; i < l; ++i, ++cp) {
+                       data = (data << 8) | (*(uchar *) cp);
+               }
+               for (; i < port_width && cnt > 0; ++i) {
+                       data = (data << 8) | *src++;
+                       --cnt;
+                       ++cp;
+               }
+               for (; cnt == 0 && i < port_width; ++i, ++cp) {
+                       data = (data << 8) | (*(uchar *) cp);
+               }
+
+               if ((rc = write_data (info, wp, SWAP (data))) != 0) {
+                       return (rc);
+               }
+               wp += port_width;
+       }
+
+       /*
+        * handle word aligned part
+        */
+       count = 0;
+       while (cnt >= port_width) {
+               data = 0;
+               for (i = 0; i < port_width; ++i) {
+                       data = (data << 8) | *src++;
+               }
+               if ((rc = write_data (info, wp, SWAP (data))) != 0) {
+                       return (rc);
+               }
+               wp += port_width;
+               cnt -= port_width;
+               if (count++ > 0x800) {
+                       spin_wheel ();
+                       count = 0;
+               }
+       }
+
+       if (cnt == 0) {
+               return (0);
+       }
+
+       /*
+        * handle unaligned tail bytes
+        */
+       data = 0;
+       for (i = 0, cp = wp; i < port_width && cnt > 0; ++i, ++cp) {
+               data = (data << 8) | *src++;
+               --cnt;
+       }
+       for (; i < port_width; ++i, ++cp) {
+               data = (data << 8) | (*(uchar *) cp);
+       }
+
+       return (write_data (info, wp, SWAP (data)));
+}
+
+/*-----------------------------------------------------------------------
+ * Write a word or halfword to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int write_data (flash_info_t *info, ulong dest, FPW data)
+{
+       FPWV *addr = (FPWV *) dest;
+       ulong status;
+       int cflag, iflag;
+       int flag;
+
+       /* Check if Flash is (sufficiently) erased */
+       if ((*addr & data) != data) {
+               printf ("not erased at %08lx (%lx)\n", (ulong) addr, *addr);
+               return (2);
+       }
+       /*
+        * 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 ();
+
+       /* Disable interrupts which might cause a timeout here */
+       /*flag = disable_interrupts (); */
+
+       *addr = (FPW) INTEL_PROG;       /* write setup */
+       *addr = data;
+
+       /* arm simple, non interrupt dependent timer */
+       reset_timer_masked ();
+
+       /* wait while polling the status register */
+       while (((status = *addr) & (FPW) INTEL_FINISHED) != (FPW) INTEL_FINISHED) {
+               if (get_timer_masked () > CFG_FLASH_WRITE_TOUT) {
+                       *addr = (FPW) INTEL_RESET;      /* restore read mode */
+                       return (1);
+               }
+       }
+
+       *addr = (FPW) INTEL_RESET;      /* restore read mode */
+
+       if (iflag)
+               enable_interrupts ();
+
+       if (cflag)
+               icache_enable ();
+
+       return (0);
+}
+
+void inline spin_wheel (void)
+{
+       static int p = 0;
+       static char w[] = "\\/-";
+
+       printf ("\010%c", w[p]);
+       (++p == 3) ? (p = 0) : 0;
+}
+
+/*-----------------------------------------------------------------------
+ * Set/Clear sector's lock bit, returns:
+ * 0 - OK
+ * 1 - Error (timeout, voltage problems, etc.)
+ */
+int flash_real_protect(flash_info_t *info, long sector, int prot)
+{
+       int i;
+       int rc = 0;
+       FPWV *addr = (FPWV *)(info->start[sector]);
+       int flag = disable_interrupts();
+
+       *addr = (FPW) INTEL_CLEAR;      /* Clear status register */
+       if (prot) {                     /* Set sector lock bit */
+               *addr = (FPW) INTEL_LOCKBIT;    /* Sector lock bit */
+               *addr = (FPW) INTEL_PROTECT;    /* set */
+       }
+       else {                          /* Clear sector lock bit */
+               *addr = (FPW) INTEL_LOCKBIT;    /* All sectors lock bits */
+               *addr = (FPW) INTEL_CONFIRM;    /* clear */
+       }
+
+       reset_timer_masked ();
+
+       while ((*addr & (FPW) INTEL_FINISHED) != (FPW) INTEL_FINISHED) {
+               if (get_timer_masked () > CFG_FLASH_UNLOCK_TOUT) {
+                       printf("Flash lock bit operation timed out\n");
+                       rc = 1;
+                       break;
+               }
+       }
+
+       if (*addr != (FPW) INTEL_OK) {
+               printf("Flash lock bit operation failed at %08X, CSR=%08X\n",
+                      (uint)addr, (uint)*addr);
+               rc = 1;
+       }
+
+       if (!rc)
+               info->protect[sector] = prot;
+
+       /*
+        * Clear lock bit command clears all sectors lock bits, so
+        * we have to restore lock bits of protected sectors.
+        */
+       if (!prot)
+       {
+               for (i = 0; i < info->sector_count; i++)
+               {
+                       if (info->protect[i])
+                       {
+                               reset_timer_masked ();
+                               addr = (FPWV *) (info->start[i]);
+                               *addr = (FPW) INTEL_LOCKBIT;    /* Sector lock bit */
+                               *addr = (FPW) INTEL_PROTECT;    /* set */
+                               while ((*addr & (FPW) INTEL_FINISHED) != (FPW) INTEL_FINISHED)
+                               {
+                                       if (get_timer_masked () > CFG_FLASH_UNLOCK_TOUT)
+                                       {
+                                               printf("Flash lock bit operation timed out\n");
+                                               rc = 1;
+                                               break;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       if (flag)
+               enable_interrupts();
+
+       *addr = (FPW) INTEL_RESET;              /* Reset to read array mode */
+
+       return rc;
+}
diff --git a/board/mp2usb/mp2usb.c b/board/mp2usb/mp2usb.c
new file mode 100644 (file)
index 0000000..b22f2e1
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * Modified for the MP2USB by (C) Copyright 2005 Eric Benard
+ * ebenard@eukrea.com
+ *
+ * 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 <asm/arch/AT91RM9200.h>
+#include <asm/mach-types.h>
+
+/* ------------------------------------------------------------------------- */
+/*
+ * Miscelaneous platform dependent initialisations
+ */
+
+int board_init (void)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+
+       /* Enable Ctrlc */
+       console_init_f ();
+
+       /* memory and cpu-speed are setup before relocation */
+       /* so we do _nothing_ here */
+
+       /* arch number of MP2USB-Board. */
+       gd->bd->bi_arch_number = MACH_TYPE_MP2USB;
+       /* adress of boot parameters */
+       gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
+
+       return 0;
+}
+
+int dram_init (void)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+
+       gd->bd->bi_dram[0].start = PHYS_SDRAM;
+       gd->bd->bi_dram[0].size = PHYS_SDRAM_SIZE;
+       return 0;
+}
diff --git a/board/mp2usb/u-boot.lds b/board/mp2usb/u-boot.lds
new file mode 100644 (file)
index 0000000..76df6b2
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@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_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+       . = 0x00000000;
+
+       . = ALIGN(4);
+       .text      :
+       {
+         cpu/arm920t/start.o   (.text)
+         *(.text)
+       }
+
+       . = ALIGN(4);
+       .rodata : { *(.rodata) }
+
+       . = ALIGN(4);
+       .data : { *(.data) }
+
+       . = ALIGN(4);
+       .got : { *(.got) }
+
+       __u_boot_cmd_start = .;
+       .u_boot_cmd : { *(.u_boot_cmd) }
+       __u_boot_cmd_end = .;
+
+       . = ALIGN(4);
+       __bss_start = .;
+       .bss : { *(.bss) }
+       _end = .;
+}
diff --git a/include/configs/mp2usb.h b/include/configs/mp2usb.h
new file mode 100644 (file)
index 0000000..005e912
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ * 2004-2005 Gary Jennejohn <garyj@denx.de>
+ *
+ * Modified for the MP2USB by (C) Copyright 2005 Eric Benard
+ * ebenard@eukrea.com
+ *
+ * Configuration settings for the MP2USB board.
+ *
+ * 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 __CONFIG_H
+#define __CONFIG_H
+
+/* ARM asynchronous clock */
+#define AT91C_MAIN_CLOCK       179712000       /* from 18.432 MHz crystal (18432000 / 4 * 45) */
+#define AT91C_MASTER_CLOCK     (AT91C_MAIN_CLOCK/3)    /* peripheral clock */
+
+#define AT91_SLOW_CLOCK                32768   /* slow clock */
+
+#define CONFIG_ARM920T         1       /* This is an ARM920T Core      */
+#define CONFIG_AT91RM9200      1       /* It's an Atmel AT91RM9200 SoC */
+#define CONFIG_AT91RM9200DK    1       /* on an AT91RM9200DK Board     */
+#define CONFIG_MP2USB          1       /* on an MP2USB Board           */
+#undef  CONFIG_USE_IRQ                 /* we don't need IRQ/FIQ stuff  */
+#define USE_920T_MMU           1
+
+#define CONFIG_CMDLINE_TAG     1       /* enable passing of ATAGs      */
+#define CONFIG_SETUP_MEMORY_TAGS 1
+#define CONFIG_INITRD_TAG      1
+
+#define CFG_ATMEL_PLL_INIT_BUG 1
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+#define CFG_USE_MAIN_OSCILLATOR                1
+/* flash */
+#define MC_PUIA_VAL    0x00000000
+#define MC_PUP_VAL     0x00000000
+#define MC_PUER_VAL    0x00000000
+#define MC_ASR_VAL     0x00000000
+#define MC_AASR_VAL    0x00000000
+#define EBI_CFGR_VAL   0x00000000
+#define SMC2_CSR_VAL   0x00003084 /* 16bit, 2 TDF, 4 WS */
+
+/* clocks */
+#define PLLAR_VAL      0x20263E04 /* 180 MHz for PCK */
+#define PLLBR_VAL      0x10483E0E /* 48 MHz (divider by 2 for USB) */
+#define MCKR_VAL       0x00000202 /* PCK/3 = MCK Master Clock = 60MHz from PLLA */
+
+/* sdram */
+#define PIOC_ASR_VAL   0xFFFF0000 /* Configure PIOC as peripheral (D16/D31) */
+#define PIOC_BSR_VAL   0x00000000
+#define PIOC_PDR_VAL   0xFFFF0000
+#define EBI_CSA_VAL    0x00000002 /* CS1=SDRAM */
+#define SDRC_CR_VAL    0x3211295A /* set up the SDRAM */
+#define SDRAM          0x20000000 /* address of the SDRAM */
+#define SDRAM1         0x20000020 /* address of the SDRAM */
+#define SDRAM_VAL      0x00000000 /* value written to SDRAM */
+#define SDRC_MR_VAL    0x00000002 /* Precharge All */
+#define SDRC_MR_VAL1   0x00000004 /* refresh */
+#define SDRC_MR_VAL2   0x00000003 /* Load Mode Register */
+#define SDRC_MR_VAL3   0x00000000 /* Normal Mode */
+#define SDRC_TR_VAL    0x000002E0 /* Write refresh rate */
+#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
+
+/*
+ * Size of malloc() pool
+ */
+#define CFG_MALLOC_LEN (CFG_ENV_SIZE + 128*1024)
+#define CFG_GBL_DATA_SIZE      128     /* size in bytes reserved for initial data */
+
+#define CONFIG_BAUDRATE                115200
+
+#define CFG_AT91C_BRGR_DIVISOR 33      /* hardcode so no __divsi3 : AT91C_MASTER_CLOCK /(baudrate * 16) */
+
+/*
+ * Hardware drivers
+ */
+
+/* define one of these to choose the DBGU, USART0  or USART1 as console */
+#define CONFIG_DBGU
+#undef CONFIG_USART0
+#undef CONFIG_USART1
+
+#undef CONFIG_HWFLOW                   /* don't include RTS/CTS flow control support   */
+
+#undef CONFIG_MODEM_SUPPORT            /* disable modem initialization stuff */
+
+#undef CONFIG_HARD_I2C
+
+#ifdef CONFIG_HARD_I2C
+#define CFG_I2C_SPEED          0       /* not used */
+#define CFG_I2C_SLAVE          0       /* not used */
+#define CONFIG_RTC_RS5C372A            /* RICOH I2C RTC */
+#define CFG_I2C_RTC_ADDR       0x32
+#define CFG_I2C_EEPROM_ADDR    0x50
+#define CFG_I2C_EEPROM_ADDR_LEN 1
+#define CFG_I2C_EEPROM_ADDR_OVERFLOW
+#endif
+/* still about 20 kB free with this defined */
+#define CFG_LONGHELP
+
+#define CONFIG_BOOTDELAY      3
+
+#ifdef CONFIG_HARD_I2C
+#define CONFIG_COMMANDS                \
+                      ((CONFIG_CMD_DFL | \
+                       CFG_CMD_DATE    | \
+                       CFG_CMD_DHCP    | \
+                       CFG_CMD_EEPROM  | \
+                       CFG_CMD_I2C     | \
+                       CFG_CMD_NFS     | \
+                       CFG_CMD_SNTP    | \
+                       CFG_CMD_MISC))
+#else
+#define CONFIG_COMMANDS                \
+                      ((CONFIG_CMD_DFL | \
+                       CFG_CMD_DHCP    | \
+                       CFG_CMD_NFS     | \
+                       CFG_CMD_SNTP    | \
+                       CFG_CMD_CACHE)  & \
+                     ~(CFG_CMD_BDI | \
+                       CFG_CMD_IMI | \
+                       CFG_CMD_AUTOSCRIPT | \
+                       CFG_CMD_FPGA | \
+                       CFG_CMD_MISC | \
+                       CFG_CMD_LOADS ))
+#define CONFIG_TIMESTAMP
+#endif
+#define CFG_LONGHELP
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+#define CONFIG_NR_DRAM_BANKS   1
+#define PHYS_SDRAM             0x20000000
+#define PHYS_SDRAM_SIZE                0x08000000      /* 128 megs */
+
+#define CFG_MEMTEST_START      PHYS_SDRAM
+#define CFG_MEMTEST_END                CFG_MEMTEST_START + PHYS_SDRAM_SIZE - 262144
+
+#define CONFIG_DRIVER_ETHER
+#define CONFIG_NET_RETRY_COUNT         20
+#undef CONFIG_AT91C_USE_RMII
+
+#define PHYS_FLASH_1                   0x10000000
+#define PHYS_FLASH_SIZE                        0x1000000  /* 16 megs main flash */
+#define CFG_FLASH_BASE                 PHYS_FLASH_1
+#define CFG_MONITOR_BASE               CFG_FLASH_BASE
+#define CFG_MAX_FLASH_BANKS            1
+#define CFG_MAX_FLASH_SECT             256
+#define CFG_FLASH_ERASE_TOUT           (2 * CFG_HZ)    /* Timeout for Flash Erase */
+#define CFG_FLASH_WRITE_TOUT           (2 * CFG_HZ)    /* Timeout for Flash Write */
+#define CFG_FLASH_LOCK_TOUT            (10*CFG_HZ)     /* Timeout for Flash Set Lock Bit */
+#define CFG_FLASH_UNLOCK_TOUT          (10*CFG_HZ)     /* Timeout for Flash Clear Lock Bits */
+#define CFG_FLASH_PROTECTION                           /* "Real" (hardware) sectors protection */
+
+#define CFG_ENV_IS_IN_FLASH            1
+#define CFG_ENV_OFFSET                 0x20000         /* after u-boot.bin */
+#define CFG_ENV_ADDR                   (CFG_FLASH_BASE+CFG_ENV_OFFSET)
+#define CFG_ENV_SIZE                   0x20000
+
+#define CFG_LOAD_ADDR          0x21000000  /* default load address */
+
+#define CFG_BAUDRATE_TABLE     { 115200, 57600, 38400, 19200, 9600 }
+
+#define CFG_PROMPT             "=> "           /* Monitor Command Prompt */
+#define CFG_CBSIZE             256             /* Console I/O Buffer Size */
+#define CFG_MAXARGS            32              /* max number of command args */
+#define CFG_PBSIZE             (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
+
+#ifndef __ASSEMBLY__
+/*-----------------------------------------------------------------------
+ * Board specific extension for bd_info
+ *
+ * This structure is embedded in the global bd_info (bd_t) structure
+ * and can be used by the board specific code (eg board/...)
+ */
+
+struct bd_info_ext {
+       /* helper variable for board environment handling
+        *
+        * env_crc_valid == 0    =>   uninitialised
+        * env_crc_valid  > 0    =>   environment crc in flash is valid
+        * env_crc_valid  < 0    =>   environment crc in flash is invalid
+        */
+       int env_crc_valid;
+};
+#endif /* __ASSEMBLY__ */
+
+#define CFG_HZ 1000
+#define CFG_HZ_CLOCK (AT91C_MASTER_CLOCK/2)    /* AT91C_TC0_CMR is implicitly set to */
+                                               /* AT91C_TC_TIMER_DIV1_CLOCK */
+
+#define CONFIG_STACKSIZE       (32*1024)       /* regular stack */
+
+#ifdef CONFIG_USE_IRQ
+#error CONFIG_USE_IRQ not supported
+#endif
+
+#define CFG_DEVICE_NULLDEV      1      /* enble null device            */
+#undef CONFIG_SILENT_CONSOLE           /* enable silent startup        */
+
+#define CONFIG_AUTOBOOT_KEYED
+#define CONFIG_AUTOBOOT_PROMPT "Press SPACE to abort autoboot in %d seconds\n"
+#define CONFIG_AUTOBOOT_STOP_STR " "
+#define CONFIG_AUTOBOOT_DELAY_STR "d"
+
+#define CONFIG_VERSION_VARIABLE        1       /* include version env variable */
+
+#endif /* __CONFIG_H */