- Support for PN62 boards added.
- Boards without FLASH are now supported (CFG_NO_FLASH and
CFG_ENV_IS_NOWHERE added).
- Network driver for AMD PCnet/FAST III 79C973 (CONFIG_PCNET and
CONFIG_PCNET_79C973) added.
- Enhanced "pci" command implemented (allowing PCI conf. accesses).
- The "mm" command now accepts the "-" key stroke to go back to the
previous address.
Modifications for 1.2.0:
======================================================================
+* Patch by Wolfgang Grandegger, 07 Aug 2002:
+ - Support for PN62 boards added.
+ - Boards without FLASH are now supported (CFG_NO_FLASH and
+ CFG_ENV_IS_NOWHERE added).
+ - Network driver for AMD PCnet/FAST III 79C973 (CONFIG_PCNET and
+ CONFIG_PCNET_79C973) added.
+ - Enhanced "pci" command implemented (allowing PCI conf. accesses).
+ - The "mm" command now accepts the "-" key stroke to go back to the
+ previous address.
+
* Patch by Greg Allen, 6 Aug 2002:
Support for UTX8245 Board
OXC_config: unconfig
@./mkconfig $(@:_config=) ppc mpc824x oxc
+PN62_config: unconfig
+ @./mkconfig $(@:_config=) ppc mpc824x pn62
+
Sandpoint8240_config: unconfig
@./mkconfig $(@:_config=) ppc mpc824x sandpoint
}
@./mkconfig -a $(call xtract_82xx,$@) ppc mpc8260 tqm8260
-
#########################################################################
## 74xx/7xx Systems
#########################################################################
--- /dev/null
+#
+# (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
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = lib$(BOARD).a
+
+OBJS = $(BOARD).o cmd_pn62.o misc.o
+
+$(LIB): .depend $(OBJS)
+ $(AR) crv $@ $^
+
+#########################################################################
+
+.depend: Makefile $(OBJS:.o=.c)
+ $(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Wolfgang Grandegger, DENX Software Engineering, wg@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 <ppcboot.h>
+#include <malloc.h>
+#include <net.h>
+#include <asm/io.h>
+#include <pci.h>
+#include <cmd_autoscript.h>
+#include <cmd_bsp.h>
+
+#include "pn62.h"
+
+#if (CONFIG_COMMANDS & CFG_CMD_BSP)
+
+extern int do_bootm (cmd_tbl_t *, bd_t *, int, int, char *[]);
+
+/*
+ * Command led: controls the various LEDs 0..11 on the PN62 card.
+ */
+int do_led (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+{
+ unsigned int number, function;
+
+ if (argc != 3) {
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+ }
+ number = simple_strtoul(argv[1], NULL, 10);
+ if (number > PN62_LED_MAX)
+ return 1;
+ function = simple_strtoul(argv[2], NULL, 16);
+ set_led (number, function);
+ return 0;
+}
+
+/*
+ * Command loadpci: loads a image over PCI.
+ */
+#define CMD_MOVE_WINDOW 0x1
+#define CMD_BOOT_IMAGE 0x2
+
+int do_loadpci (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+{
+ char *s;
+ ulong addr = 0, count = 0;
+ u32 off;
+ int cmd, rcode = 0;
+
+ /* pre-set load_addr */
+ if ((s = getenv("loadaddr")) != NULL) {
+ addr = simple_strtoul(s, NULL, 16);
+ }
+
+ switch (argc) {
+ case 1:
+ break;
+ case 2:
+ addr = simple_strtoul(argv[1], NULL, 16);
+ break;
+ default:
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+ }
+
+ printf ("## Ready for image download ...\n");
+
+ show_startup_phase(12);
+
+ while (1) {
+ /* Alive indicator */
+ i2155x_write_scrapad(BOOT_PROTO, BOOT_PROTO_READY);
+
+ /* Toggle status LEDs */
+ cmd = (count / 200) % 4; /* downscale */
+ set_led(4, cmd == 0 ? LED_1 : LED_0);
+ set_led(5, cmd == 1 ? LED_1 : LED_0);
+ set_led(6, cmd == 2 ? LED_1 : LED_0);
+ set_led(7, cmd == 3 ? LED_1 : LED_0);
+ udelay(1000);
+ count++;
+
+ cmd = i2155x_read_scrapad(BOOT_CMD);
+
+ if (cmd == BOOT_CMD_MOVE) {
+ off = i2155x_read_scrapad(BOOT_DATA);
+ off += addr;
+ i2155x_set_bar_base(3, off);
+ printf ("## BAR3 Addr moved = 0x%08x\n", off);
+ i2155x_write_scrapad(BOOT_CMD, ~cmd);
+ show_startup_phase(13);
+ }
+ else if (cmd == BOOT_CMD_BOOT) {
+ set_led(4, LED_1);
+ set_led(5, LED_1);
+ set_led(6, LED_1);
+ set_led(7, LED_1);
+
+ i2155x_write_scrapad(BOOT_CMD, ~cmd);
+ show_startup_phase(14);
+ break;
+ }
+
+ /* Abort if ctrl-c was pressed */
+ if (ctrlc()) {
+ printf("\nAbort\n");
+ return 0;
+ }
+
+ }
+
+ /* Repoint to the default shared memory */
+ i2155x_set_bar_base(3, PN62_SMEM_DEFAULT);
+
+ load_addr = addr;
+ printf ("## Start Addr = 0x%08lx\n", addr);
+
+ show_startup_phase(15);
+
+ /* Loading ok, check if we should attempt an auto-start */
+ if (((s = getenv("autostart")) != NULL) && (strcmp(s,"yes") == 0)) {
+ char *local_args[2];
+ local_args[0] = argv[0];
+ local_args[1] = NULL;
+
+ printf ("Automatic boot of image at addr 0x%08lX ...\n",
+ load_addr);
+ rcode = do_bootm (cmdtp, bd, 0, 1, local_args);
+ }
+
+#ifdef CONFIG_AUTOSCRIPT
+ if (load_addr) {
+ char *s;
+
+ if (((s = getenv("autoscript")) != NULL) && (strcmp(s,"yes") == 0)) {
+ printf("Running autoscript at addr 0x%08lX ...\n", load_addr);
+ rcode = autoscript (bd, load_addr);
+ }
+ }
+#endif
+ return rcode;
+}
+
+#endif
--- /dev/null
+#
+# (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
+#
+
+#
+# PN62 boards
+#
+
+TEXT_BASE = 0xFFF00000
+
+PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE)
--- /dev/null
+/*
+ * (C) Copyright 2002 Wolfgang Grandegger <wg@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 <ppcboot.h>
+#include <mpc824x.h>
+#include <asm/io.h>
+#include <pci.h>
+
+#include "pn62.h"
+
+typedef struct {
+ pci_dev_t devno;
+ volatile u32 *csr;
+
+} i2155x_t;
+
+static i2155x_t i2155x = { 0, NULL };
+
+static struct pci_device_id i2155x_ids[] = {
+ { 0x1011, 0x0046 }, /* i21554 */
+ { 0x8086, 0xb555 } /* i21555 */
+};
+
+int i2155x_init(void)
+{
+ pci_dev_t devno;
+ u32 val;
+ int i;
+
+ /*
+ * Find the Intel bridge.
+ */
+ if ((devno = pci_find_devices(i2155x_ids, 0)) < 0) {
+ printf("Error: Intel bridge 2155x not found!\n");
+ return -1;
+ }
+ i2155x.devno = devno;
+
+ /*
+ * Get auto-configured base address for CSR access.
+ */
+ pci_read_config_dword(devno, PCI_BASE_ADDRESS_1, &val);
+ if (val & PCI_BASE_ADDRESS_SPACE_IO) {
+ val &= PCI_BASE_ADDRESS_IO_MASK;
+ i2155x.csr = (volatile u32 *)(_IO_BASE + val);
+ } else {
+ val &= PCI_BASE_ADDRESS_MEM_MASK;
+ i2155x.csr = (volatile u32 *)val;
+ }
+
+ /*
+ * Translate downstream memory 2 (bar3) to base of shared memory.
+ */
+ i2155x_set_bar_base(3, PN62_SMEM_DEFAULT);
+
+ /*
+ * Enable memory space, I/O space and bus master bits
+ * in both Primary and Secondary command registers.
+ */
+ val = PCI_COMMAND_MEMORY|PCI_COMMAND_MASTER|PCI_COMMAND_IO;
+ pci_write_config_word(devno, 0x44, val);
+ pci_write_config_word(devno, 0x04, val);
+
+ /*
+ * Clear scratchpad registers.
+ */
+ for (i = 0; i < (I2155X_SCRAPAD_MAX - 1); i++) {
+ i2155x_write_scrapad(i, 0x0);
+ }
+
+ /*
+ * Set interrupt line for Linux.
+ */
+ pci_write_config_byte(devno, PCI_INTERRUPT_LINE, 3);
+
+ return 0;
+}
+
+/*
+ * Access the Scratchpad registers 0..7 of the Intel bridge.
+ */
+void i2155x_write_scrapad(int idx, u32 val)
+{
+ if (idx >= 0 && idx < I2155X_SCRAPAD_MAX)
+ out_le32(i2155x.csr + (I2155X_SCRAPAD_ADDR/4) + idx, val);
+ else
+ printf("i2155x_write_scrapad: invalid index\n");
+}
+
+u32 i2155x_read_scrapad(int idx)
+{
+ if (idx >= 0 && idx < I2155X_SCRAPAD_MAX)
+ return in_le32(i2155x.csr + (I2155X_SCRAPAD_ADDR/4) + idx);
+ else
+ printf("i2155x_read_scrapad: invalid index\n");
+ return -1;
+}
+
+void i2155x_set_bar_base(int bar, u32 base)
+{
+ if (bar >= 2 && bar <= 4) {
+ pci_write_config_dword(i2155x.devno,
+ I2155X_BAR2_BASE + (bar - 2) * 4,
+ base);
+ }
+}
+
+/*
+ * Read Vital Product Data (VPD) from the Serial EPROM attached
+ * to the Intel bridge.
+ */
+int i2155x_read_vpd(int offset, int size, unsigned char *data)
+{
+ int i, n;
+ u16 val16;
+
+ for (i = 0; i < size; i++) {
+ pci_write_config_word(i2155x.devno, I2155X_VPD_ADDR,
+ offset + i - I2155X_VPD_START);
+ for (n = 10000; n > 0; n--) {
+ pci_read_config_word(i2155x.devno, I2155X_VPD_ADDR, &val16);
+ if ((val16 & 0x8000) != 0) /* wait for completion */
+ break;
+ udelay(100);
+ }
+ if (n == 0) {
+ printf("i2155x_read_vpd: TIMEOUT\n");
+ return -1;
+ }
+
+ pci_read_config_byte(i2155x.devno, I2155X_VPD_DATA, &data[i]);
+ }
+
+ return i;
+}
+
+static struct pci_device_id am79c95x_ids [] = {
+ { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE },
+ { }
+};
+
+
+/*
+ * Initialize the AMD ethernet controllers.
+ */
+int am79c95x_init(void)
+{
+ pci_dev_t devno;
+ int i;
+
+ /*
+ * Set interrupt line for Linux.
+ */
+ for (i = 0; i < 2; i++) {
+ if ((devno = pci_find_devices(am79c95x_ids, i)) < 0)
+ break;
+ pci_write_config_byte(devno, PCI_INTERRUPT_LINE, 2+i);
+ }
+ if (i < 2)
+ printf("Error: Only %d AMD Ethernet Controller found!\n", i);
+
+ return 0;
+}
+
+
+void set_led(unsigned int number, unsigned int function)
+{
+ volatile u8 *addr;
+
+ if ((number >= 0) && (number < PN62_LED_MAX) &&
+ (function >= 0) && (function <= LED_LAST_FUNCTION)) {
+ addr = (volatile u8 *)(PN62_LED_BASE + number * 8);
+ out_8(addr, function&0xff);
+ }
+}
+
+/*
+ * Show fatal error indicated by Kinght Rider(tm) effect
+ * in LEDS 0-7. LEDS 8-11 contain 4 bit error code.
+ * Note: this function will not terminate.
+ */
+void fatal_error(unsigned int error_code)
+{
+ int i, d;
+
+ for (i = 0; i < 12; i++) {
+ set_led(i, LED_0);
+ }
+
+ /*
+ * Write error code.
+ */
+ set_led(8, (error_code & 0x01) ? LED_1 : LED_0);
+ set_led(9, (error_code & 0x02) ? LED_1 : LED_0);
+ set_led(10, (error_code & 0x04) ? LED_1 : LED_0);
+ set_led(11, (error_code & 0x08) ? LED_1 : LED_0);
+
+ /*
+ * Yay - Knight Rider effect!
+ */
+ while(1) {
+ unsigned int delay = 2000;
+
+ for (i = 0; i < 8; i++) {
+ set_led(i, LED_1);
+ for (d = 0; d < delay; d++);
+ set_led(i, LED_0);
+ }
+
+ for (i = 7; i > 0; i--) {
+ set_led(i, LED_1);
+ for (d = 0; d < delay; d++);
+ set_led(i, LED_0);
+ }
+ }
+}
--- /dev/null
+/*
+ * (C) Copyright 2002 Wolfgang Grandegger <wg@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 <ppcboot.h>
+#include <mpc824x.h>
+#include <pci.h>
+
+#include "pn62.h"
+
+
+static int get_serial_number(char *string, int size);
+static int get_mac_address(int id, u8* mac, char *string, int size);
+
+#ifdef CONFIG_SHOW_BOOT_PROGRESS
+void show_boot_progress(int phase)
+{
+ /*
+ * Show phases of the bootm command on the front panel
+ * LEDs and the scratchpad register #3 as well. We use
+ * blinking LEDs for logical "1".
+ */
+ if (phase > 0) {
+ set_led( 8, (phase & 0x1) ? LED_SLOW_CLOCK : LED_0);
+ set_led( 9, (phase & 0x2) ? LED_SLOW_CLOCK : LED_0);
+ set_led(10, (phase & 0x4) ? LED_SLOW_CLOCK : LED_0);
+ set_led(11, (phase & 0x8) ? LED_SLOW_CLOCK : LED_0);
+ }
+ i2155x_write_scrapad(BOOT_STATUS, phase);
+ if (phase < 0)
+ i2155x_write_scrapad(BOOT_DONE, BOOT_DONE_ERROR);
+}
+#endif
+
+void show_startup_phase(int phase) {
+ /*
+ * Show the phase of PPCboot startup on the front panel
+ * LEDs and the scratchpad register #3 as well.
+ */
+ if (phase > 0) {
+ set_led( 8, (phase & 0x1) ? LED_1 : LED_0);
+ set_led( 9, (phase & 0x2) ? LED_1 : LED_0);
+ set_led(10, (phase & 0x4) ? LED_1 : LED_0);
+ set_led(11, (phase & 0x8) ? LED_1 : LED_0);
+ }
+ i2155x_write_scrapad(BOOT_STATUS, phase);
+ if (phase < 0)
+ i2155x_write_scrapad(BOOT_DONE, BOOT_DONE_ERROR);
+}
+
+int checkboard (void)
+{
+ show_startup_phase(1);
+ puts ( "PN62\n" );
+ return 0;
+}
+
+long int initdram (int board_type)
+{
+ int i, cnt;
+ volatile uchar * base= CFG_SDRAM_BASE;
+ volatile ulong * addr;
+ ulong save[32];
+ ulong val, ret = 0;
+
+ show_startup_phase(2);
+
+ for (i=0, cnt=(CFG_MAX_RAM_SIZE / sizeof(long)) >> 1; cnt > 0; cnt >>= 1) {
+ addr = (volatile ulong *)base + cnt;
+ save[i++] = *addr;
+ *addr = ~cnt;
+ }
+
+ addr = (volatile ulong *)base;
+ save[i] = *addr;
+ *addr = 0;
+
+ if (*addr != 0) {
+ *addr = save[i];
+ goto Done;
+ }
+
+ for (cnt = 1; cnt <= CFG_MAX_RAM_SIZE / sizeof(long); cnt <<= 1) {
+ addr = (volatile ulong *)base + cnt;
+ val = *addr;
+ *addr = save[--i];
+ if (val != ~cnt) {
+ ulong new_bank0_end = cnt * sizeof(long) - 1;
+ ulong mear1 = mpc824x_mpc107_getreg(MEAR1);
+ ulong emear1 = mpc824x_mpc107_getreg(EMEAR1);
+ mear1 = (mear1 & 0xFFFFFF00) |
+ ((new_bank0_end & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT);
+ emear1 = (emear1 & 0xFFFFFF00) |
+ ((new_bank0_end & MICR_ADDR_MASK) >> MICR_EADDR_SHIFT);
+ mpc824x_mpc107_setreg(MEAR1, mear1);
+ mpc824x_mpc107_setreg(EMEAR1, emear1);
+
+ ret = cnt * sizeof(long);
+ goto Done;
+ }
+ }
+
+ ret = CFG_MAX_RAM_SIZE;
+ Done:
+ show_startup_phase(3);
+ return ret;
+}
+
+/*
+ * Initialize PCI Devices. We rely on auto-configuration.
+ */
+#ifndef CONFIG_PCI_PNP
+#error "CONFIG_PCI_PNP is not defined, please correct!"
+#endif
+
+struct pci_controller hose = {
+};
+
+void pci_init (bd_t *bd)
+{
+ show_startup_phase(4);
+ pci_mpc824x_init(bd, &hose);
+
+ show_startup_phase(5);
+ i2155x_init();
+ show_startup_phase(6);
+ am79c95x_init();
+ show_startup_phase(7);
+}
+
+void misc_init_r (bd_t *bd)
+{
+ char str[20];
+ u8 mac[6];
+
+ show_startup_phase(8);
+ /*
+ * Get serial number and ethernet addresses if not already defined
+ * and update the board info structure and the environment.
+ */
+ if (getenv("serial#") == NULL &&
+ get_serial_number(str, strlen(str)) > 0) {
+ setenv("serial#", str);
+ }
+ show_startup_phase(9);
+
+ if (getenv("ethaddr") == NULL &&
+ get_mac_address(0, mac, str, sizeof(str)) > 0) {
+ setenv("ethaddr", str);
+ memcpy(bd->bi_enetaddr, mac, 6);
+ }
+ show_startup_phase(10);
+
+ if (getenv("eth1addr") == NULL &&
+ get_mac_address(1, mac, str, sizeof(str)) > 0) {
+ setenv("eth1addr", str);
+ memcpy(bd->bi_enet1addr, mac, 6);
+ }
+ show_startup_phase(11);
+
+ /* Tell everybody that PPCboot is up and runnig */
+ i2155x_write_scrapad(0, 0x12345678);
+}
+
+static int get_serial_number (char* string, int size)
+{
+ int i;
+ char c;
+
+ if (size < I2155X_VPD_SN_SIZE)
+ size = I2155X_VPD_SN_SIZE;
+ for (i = 0; i < (size - 1); i++) {
+ i2155x_read_vpd(I2155X_VPD_SN_START + i, 1, &c);
+ if (c == '\0')
+ break;
+ string[i] = c;
+ }
+ string[i] = '\0'; /* make sure it's terminated */
+
+ return i;
+}
+
+static int get_mac_address (int id, u8* mac, char* string, int size)
+{
+ if (size < 6*3)
+ return -1;
+
+ i2155x_read_vpd(I2155X_VPD_MAC0_START + 6 * id, 6, mac);
+ return sprintf(string, "%02x:%02x:%02x:%02x:%02x:%02x",
+ mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
+}
--- /dev/null
+/*
+ * (C) Copyright 2002 Wolfgang Grandegger <wg@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
+ */
+
+#ifndef _PN62_H_
+#define _PN62_H_
+
+/*
+ * Definitions for the Intel Bridge 21554 or 21555.
+ */
+#define I2155X_VPD_ADDR 0xe6
+#define I2155X_VPD_DATA 0xe8
+
+#define I2155X_VPD_START 0x80
+#define I2155X_VPD_SN_START 0x80
+#define I2155X_VPD_SN_SIZE 0x10
+#define I2155X_VPD_MAC0_START 0x90
+#define I2155X_VPD_MAC1_START 0x96
+
+#define I2155X_SCRAPAD_ADDR 0xa8
+#define I2155X_SCRAPAD_MAX 8
+
+#define I2155X_BAR2_BASE 0x98
+#define I2155X_BAR3_BASE 0x9c
+#define I2155X_BAR4_BASE 0xa0
+
+#define I2155X_BAR2_SETUP 0xb0
+#define I2155X_BAR3_SETUP 0xb4
+#define I2155X_BAR4_SETUP 0xb8
+
+/*
+ * Interrupt request numbers
+ */
+#define PN62_IRQ_HOST 0x0
+#define PN62_IRQ_PLX9054 0x1
+#define PN62_IRQ_ETH0 0x2
+#define PN62_IRQ_ETH1 0x3
+#define PN62_IRQ_COM1 0x4
+#define PN62_IRQ_COM2 0x4
+
+/*
+ * Miscellaneous definitons.
+ */
+#define PN62_SMEM_DEFAULT 0x1f00000
+
+/*
+ * Definitions for boot protocol using Scratchpad registers.
+ */
+#define BOOT_DONE 0
+#define BOOT_DONE_CLEAR 0x00dead00
+#define BOOT_DONE_ERROR 0xbad0dead
+#define BOOT_DONE_PPCBOOT 0x12345678
+#define BOOT_DONE_LINUX 0x87654321
+#define BOOT_CMD 1
+#define BOOT_CMD_MOVE 0x1
+#define BOOT_CMD_BOOT 0x2
+#define BOOT_DATA 2
+#define BOOT_PROTO 3
+#define BOOT_PROTO_READY 0x23456789
+#define BOOT_PROTO_CLEAR 0x00000000
+#define BOOT_STATUS 4
+
+/*
+ * LED Definitions:
+ */
+#define PN62_LED_BASE 0xff800300
+#define PN62_LED_MAX 12
+
+/*
+ * LED0 - 7 mounted on top of board, D1 - D8
+ * LED8 - 11 upper four LEDs on the front panel of the board.
+ */
+#define LED_0 0x00 /* OFF */
+#define LED_1 0x01 /* ON */
+#define LED_SLOW_CLOCK 0x02 /* SLOW 1Hz ish */
+#define LED_nSLOW_CLOCK 0x03 /* inverse of above */
+#define LED_WATCHDOG_OUT 0x06 /* Reset Watchdog level */
+#define LED_WATCHDOG_CLOCK 0x07 /* clock to watchdog */
+
+/*
+ * LED's currently setup in AMD79C973 device as the following:
+ * LED0 100Mbit
+ * LED1 LNKSE
+ * LED2 TX Activity
+ * LED3 RX Activity
+ */
+#define LED_E0_LED0 0x08 /* Ethernet Port 0 LED 0 */
+#define LED_E0_LED1 0x09 /* Ethernet Port 0 LED 1 */
+#define LED_E0_LED2 0x0A /* Ethernet Port 0 LED 2 */
+#define LED_E0_LED3 0x0B /* Ethernet Port 0 LED 3 */
+#define LED_E1_LED0 0x0C /* Ethernet Port 1 LED 0 */
+#define LED_E1_LED1 0x0D /* Ethernet Port 1 LED 1 */
+#define LED_E1_LED2 0x0E /* Ethernet Port 1 LED 2 */
+#define LED_E1_LED3 0x0F /* Ethernet Port 1 LED 3 */
+#define LED_STROBE0 0x10 /* Processor Strobe 0 */
+#define LED_STROBE1 0x11 /* Processor Strobe 1 */
+#define LED_STROBE2 0x12 /* Processor Strobe 2 */
+#define LED_STROBE3 0x13 /* Processor Strobe 3 */
+#define LED_STROBE4 0x14 /* Processor Strobe 4 */
+#define LED_STROBE5 0x15 /* Processor Strobe 5 */
+#define LED_STROBE6 0x16 /* Processor Strobe 6 */
+#define LED_STROBE7 0x17 /* Processor Strobe 7 */
+#define LED_HOST_STROBE0 0x18 /* Host strobe 0 */
+#define LED_HOST_STROBE1 0x19 /* Host strobe 1 */
+#define LED_HOST_STROBE2 0x1A /* Host strobe 2 */
+#define LED_HOST_STROBE3 0x1B /* Host strobe 3 */
+#define LED_HOST_STROBE4 0x1C /* Host strobe 4 */
+#define LED_HOST_STROBE5 0x1D /* Host strobe 5 */
+#define LED_HOST_STROBE6 0x1E /* Host strobe 6 */
+#define LED_HOST_STROBE7 0x1F /* Host strobe 7 */
+#define LED_MPC_INT0 0x20 /* MPC8240 INT 0 */
+#define LED_MPC_INT1 0x21 /* MPC8240 INT 1 */
+#define LED_MPC_INT2 0x22 /* MPC8240 INT 2 */
+#define LED_MPC_INT3 0x23 /* MPC8240 INT 3 */
+#define LED_MPC_INT4 0x24 /* MPC8240 INT 4 */
+#define LED_UART0_CS 0x25 /* UART 0 Chip Select */
+#define LED_UART1_CS 0x26 /* UART 1 Chip Select */
+#define LED_SRAM_CS 0x27 /* SRAM Chip Select */
+#define LED_SRAM_WR 0x28 /* SRAM WR Signal */
+#define LED_SRAM_RD 0x29 /* SRAM RD Signal */
+#define LED_MPC_RCS0 0x2A /* MPC8240 RCS0 Signal */
+#define LED_S_PCI_FRAME 0x2B /* Secondary PCI Frame Signal */
+#define LED_MPC_CS0 0x2C /* MPC8240 CS0 Signal */
+#define LED_HOST_INT 0x2D /* MPC8240 to Host Interrupt signal */
+#define LED_LAST_FUNCTION LED_HOST_INT /* last function */
+
+/*
+ * Forward declarations
+ */
+int i2155x_init (void);
+void i2155x_write_scrapad(int idx, u32 val);
+u32 i2155x_read_scrapad (int idx);
+void i2155x_set_bar_base (int bar, u32 addr);
+int i2155x_read_vpd (int offset, int size, unsigned char *data);
+
+int am79c95x_init (void);
+
+void set_led (unsigned int number, unsigned int function);
+void fatal_error (unsigned int error_code);
+void show_startup_phase (int phase);
+
+
+#endif /* _PN62_H_ */
--- /dev/null
+/*
+ * (C) Copyright 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
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* 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 :
+ {
+ cpu/mpc824x/start.o (.text)
+ common/board.o (.text)
+ lib_ppc/ppcstring.o (.text)
+ lib_generic/vsprintf.o (.text)
+ lib_generic/crc32.o (.text)
+ lib_generic/zlib.o (.text)
+
+ . = DEFINED(env_offset) ? env_offset : .;
+ common/environment.o (.text)
+
+ *(.text)
+
+ *(.fixup)
+ *(.got1)
+ . = ALIGN(16);
+ *(.rodata)
+ *(.rodata1)
+ }
+ .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 = .);
+
+ __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 = .);
+}
+
load_sernum_ethaddr(bd);
#endif
-#ifdef CFG_GT_6426x
- /* handle the 2nd and 3rd ethernet addresses */
+#if defined(CFG_GT_6426x) || defined(CONFIG_PN62)
+ /* handle the 2nd ethernet address */
i = getenv_r ("eth1addr", tmp, sizeof(tmp));
s = (i > 0) ? tmp : NULL;
if (s)
s = (*e) ? e+1 : e;
}
+#endif
+#if defined(CFG_GT_6426x)
+ /* handle the 3rd ethernet address */
i = getenv_r ("eth2addr", tmp, sizeof(tmp));
s = (i > 0) ? tmp : NULL;
{
char *s;
cmd_tbl_t *cmdtp;
+#ifndef CFG_NO_FLASH
ulong flash_size;
+#endif
ulong reloc_off = dest_addr - CFG_MONITOR_BASE;
extern void malloc_bin_reloc (ulong);
*/
trap_init(dest_addr);
+#if !defined(CFG_NO_FLASH)
puts ("FLASH: ");
if ((flash_size = flash_init ()) > 0) {
#else
bd->bi_flashoffset = 0;
#endif
+#else
+
+ bd->bi_flashsize = 0;
+ bd->bi_flashstart = 0;
+ bd->bi_flashoffset = 0;
+#endif /* !CFG_NO_FLASH */
WATCHDOG_RESET();
for (i=0; i<6; ++i) {
printf ("%c%02X", i ? ':' : ' ', bd->bi_enetaddr[i]);
}
+#ifdef CONFIG_PN62
+ printf ("\neth1addr =");
+ for (i=0; i<6; ++i) {
+ printf ("%c%02X", i ? ':' : ' ', bd->bi_enet1addr[i]);
+ }
+#endif /* CONFIG_PN62 */
#ifdef CONFIG_HERMES
print_str ("ethspeed", strmhz(buf, bd->bi_ethspeed));
#endif
if (crc32 (0, (char *)data, len) != checksum) {
printf ("Bad Header Checksum\n");
- SHOW_BOOT_PROGRESS (-1);
+ SHOW_BOOT_PROGRESS (-2);
return 1;
}
SHOW_BOOT_PROGRESS (3);
printf (" Verifying Checksum ... ");
if (crc32 (0, (char *)data, len) != hdr->ih_dcrc) {
printf ("Bad Data CRC\n");
- SHOW_BOOT_PROGRESS (-1);
+ SHOW_BOOT_PROGRESS (-3);
return 1;
}
printf ("OK\n");
if (hdr->ih_arch != IH_CPU_PPC) {
printf ("Unsupported Architecture\n");
- SHOW_BOOT_PROGRESS (-1);
+ SHOW_BOOT_PROGRESS (-4);
return 1;
}
SHOW_BOOT_PROGRESS (5);
data += 4;
break;
default: printf ("Wrong Image Type for %s command\n", cmdtp->name);
- SHOW_BOOT_PROGRESS (-1);
- return 1;
+ SHOW_BOOT_PROGRESS (-5);
+ return 1;
}
SHOW_BOOT_PROGRESS (6);
if (gunzip ((void *)hdr->ih_load, 0x400000,
(uchar *)data, (int *)&len) != 0) {
printf ("GUNZIP ERROR - must RESET board to recover\n");
+ SHOW_BOOT_PROGRESS (-6);
do_reset (cmdtp, bd, flag, argc, argv);
}
break;
if (iflag)
enable_interrupts();
printf ("Unimplemented compression type %d\n", hdr->ih_comp);
- SHOW_BOOT_PROGRESS (-1);
+ SHOW_BOOT_PROGRESS (-7);
return 1;
}
printf ("OK\n");
if (iflag)
enable_interrupts();
printf ("Can't boot image type %d\n", hdr->ih_type);
- SHOW_BOOT_PROGRESS (-1);
+ SHOW_BOOT_PROGRESS (-8);
return 1;
}
SHOW_BOOT_PROGRESS (8);
#endif /* CFG_CMD_ELF */
}
- SHOW_BOOT_PROGRESS (-1);
+ SHOW_BOOT_PROGRESS (-9);
#ifdef DEBUG
printf ("\n## Control returned to monitor - resetting...\n");
do_reset (cmdtp, bd, flag, argc, argv);
if (hdr->ih_magic != IH_MAGIC) {
printf ("Bad Magic Number\n");
- SHOW_BOOT_PROGRESS (-1);
+ SHOW_BOOT_PROGRESS (-10);
do_reset (cmdtp, bd, flag, argc, argv);
}
if (crc32 (0, (char *)data, len) != checksum) {
printf ("Bad Header Checksum\n");
- SHOW_BOOT_PROGRESS (-1);
+ SHOW_BOOT_PROGRESS (-11);
do_reset (cmdtp, bd, flag, argc, argv);
}
if (csum != hdr->ih_dcrc) {
printf ("Bad Data CRC\n");
- SHOW_BOOT_PROGRESS (-1);
+ SHOW_BOOT_PROGRESS (-12);
do_reset (cmdtp, bd, flag, argc, argv);
}
printf ("OK\n");
(hdr->ih_arch != IH_CPU_PPC) ||
(hdr->ih_type != IH_TYPE_RAMDISK) ) {
printf ("No Linux PPC Ramdisk Image\n");
- SHOW_BOOT_PROGRESS (-1);
+ SHOW_BOOT_PROGRESS (-13);
do_reset (cmdtp, bd, flag, argc, argv);
}
#if (CONFIG_COMMANDS & CFG_CMD_I2C)
+
/* Display values from last command.
* Memory modify remembered values are different from display memory.
*/
static int
mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[]);
+extern int cmd_get_data_size(char* arg, int default_size);
/*
* Syntax:
* New command specified. Check for a size specification.
* Defaults to byte if no or incorrect specification.
*/
- size = 1;
- if (argv[0][3] == '.') {
- if (argv[0][4] == 'b') {
- size = 1;
- } else if (argv[0][4] == 'w') {
- size = 2;
- } else if (argv[0][4] == 'l') {
- size = 4;
- }
- }
+ size = cmd_get_data_size(argv[0], 1);
/*
* Chip is always specified.
#include <command.h>
#include <cmd_mem.h>
+#if (CONFIG_COMMANDS & (CFG_CMD_MEMORY | CFG_CMD_PCI | CFG_CMD_I2C))
+int cmd_get_data_size(char* arg, int default_size)
+{
+ /* Check for a size specification .b, .w or .l.
+ */
+ int len = strlen(arg);
+ if (len > 2 && arg[len-2] == '.') {
+ switch(arg[len-1]) {
+ case 'b':
+ return 1;
+ case 'w':
+ return 2;
+ case 'l':
+ return 4;
+ }
+ }
+ return default_size;
+}
+#endif
+
#if (CONFIG_COMMANDS & CFG_CMD_MEMORY)
static int mod_mem(cmd_tbl_t *, int, int, int, char *[]);
/* New command specified. Check for a size specification.
* Defaults to long if no or incorrect specification.
*/
- size = 4;
- if (argv[0][2] == '.') {
- if (argv[0][3] == 'b') {
- size = 1;
- } else if (argv[0][3] == 'w') {
- size = 2;
- }
- }
+ size = cmd_get_data_size(argv[0], 4);
/* Address is specified since argc > 1
*/
/* Check for size specification.
*/
- size = 4;
- if (argv[0][2] == '.') {
- if (argv[0][3] == 'b') {
- size = 1;
- } else if (argv[0][3] == 'w') {
- size = 2;
- }
- }
+ size = cmd_get_data_size(argv[0], 4);
/* Address is specified since argc > 1
*/
/* Check for size specification.
*/
- size = 4;
- if (argv[0][3] == '.') {
- if (argv[0][4] == 'b') {
- size = 1;
- } else if (argv[0][4] == 'w') {
- size = 2;
- }
- }
+ size = cmd_get_data_size(argv[0], 4);
addr1 = simple_strtoul(argv[1], NULL, 16);
addr1 += base_address;
/* Check for size specification.
*/
- size = 4;
- if (argv[0][2] == '.') {
- if (argv[0][3] == 'b') {
- size = 1;
- } else if (argv[0][3] == 'w') {
- size = 2;
- }
- }
+ size = cmd_get_data_size(argv[0], 4);
addr = simple_strtoul(argv[1], NULL, 16);
addr += base_address;
return 1;
}
+#ifndef CFG_NO_FLASH
/* check if we are copying to Flash */
if (addr2info(dest) != NULL) {
int rc;
return 1;
}
}
+#endif
while (count-- > 0) {
if (size == 4)
/* Check for a size spefication.
* Defaults to long if no or incorrect specification.
*/
- size = 4;
- if (argv[0][4] == '.') {
- if (argv[0][5] == 'b')
- size = 1;
- else if (argv[0][5] == 'w')
- size = 2;
- }
+ size = cmd_get_data_size(argv[0], 4);
/* Address is always specified.
*/
/* New command specified. Check for a size specification.
* Defaults to long if no or incorrect specification.
*/
- size = 4;
- if (argv[0][2] == '.') {
- if (argv[0][3] == 'b') {
- size = 1;
- } else if (argv[0][3] == 'w') {
- size = 2;
- }
- }
+ size = cmd_get_data_size(argv[0], 4);
/* Address is specified since argc > 1
*/
printf(" %02x", *((u_char *)addr));
nbytes = readline (" ? ");
- if (nbytes == 0) {
+ if (nbytes == 0 || (nbytes == 1 && console_buffer[0] == '-')) {
/* <CR> pressed as only input, don't modify current
- * location and move to next.
+ * location and move to next. "-" pressed will go back.
*/
if (incrflag)
- addr += size;
+ addr += nbytes ? -size : size;
nbytes = 1;
#ifdef CONFIG_BOOT_RETRY_TIME
reset_cmd_timeout(); /* good enough to not time out */
# endif /* ENV, FLASH */
# endif /* ENV_IS_EMBEDDED */
+
+/*--- NOWHERE ---------------------------------------------------------*/
+#elif defined(CFG_ENV_IS_NOWHERE) /* Environment is nowhere */
+static env_t *env_ptr = NULL;
+
#else
-# error Define one of CFG_ENV_IS_IN_NVRAM, CFG_ENV_IS_IN_EEPROM, CFG_ENV_IS_IN_FLASH
+# error Define one of CFG_ENV_IS_IN_NVRAM, CFG_ENV_IS_IN_EEPROM, CFG_ENV_IS_IN_FLASH, CFG_ENV_IS_NOWHERE
#endif /* CFG_ENV_IS_IN_FLASH */
/*----------------------------------------------------------------------*/
get_env_addr = get_env_addr_memory;
if (idata->env_valid == 0) {
-#if defined(CONFIG_GTH) /* Environment not changable */
+#if defined(CONFIG_GTH) || defined(CFG_ENV_IS_NOWHERE) /* Environment not changable */
puts ("Using default environment\n\n");
#else
puts ("*** Warning - bad CRC, using default environment\n\n");
eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+offsetof(env_t,data),
env_ptr->data,
ENV_SIZE);
-# else
+# elif !defined(CFG_ENV_IS_NOWHERE)
DEBUGF ("%s[%d] read ENV from NVRAM/FLASH\n",__FUNCTION__,__LINE__);
memcpy (env_ptr->data,
((env_t *)CFG_ENV_ADDR)->data,
*
* (C) Copyright 2002
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * Wolfgang Grandegger, DENX Software Engineering, wg@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
#if (CONFIG_COMMANDS & CFG_CMD_PCI)
-unsigned char ShortPCIListing = 0;
+extern int cmd_get_data_size(char* arg, int default_size);
-/*
- * Follows routines for the output of infos about devices on PCI bus.
- */
-
-void pciinfo(int BusNum);
+unsigned char ShortPCIListing = 1;
/*
- * Subroutine: do_pciinfo
- *
- * Description: Handler for 'pciinfo' command..
- *
- * Inputs: argv[1] may contain the number of the bus to be scanned.
- * Default is bus 0.
- *
- * Return: None
- *
+ * Follows routines for the output of infos about devices on PCI bus.
*/
-int do_pciinfo(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
-{
- char *s;
- int bus_no = 0;
-
- if (argc == 2)
- {
- bus_no = (int)simple_strtoul(argv[1], NULL, 10);
- }
-
- if ((s = getenv("pci_listing")) != NULL)
- ShortPCIListing = (strcmp(s, "short") == 0) ? 1 : 0;
- else
- ShortPCIListing = 0;
-
- pciinfo(bus_no);
-
- return 0;
-}
void pci_header_show(pci_dev_t dev);
void pci_header_show_brief(pci_dev_t dev);
* Depending on the define CFG_SHORT_PCI_LISTING
* the output will be more or less exhaustive.
*
- * Inputs: bus_no the number of the bus to be scanned.
+ * Inputs: bus_no the number of the bus to be scanned.
*
* Return: None
*
*/
-void pciinfo(int BusNum)
+void pciinfo(int BusNum, int ShortPCIListing)
{
int Device;
int Function;
printf("Scanning PCI devices on bus %d\n", BusNum);
if (ShortPCIListing) {
- printf("No. VendorId DeviceId Device Class Sub-Class\n");
- printf("________________________________________________________\n");
+ printf("BusDevFun VendorId DeviceId Device Class Sub-Class\n");
+ printf("_____________________________________________________________\n");
}
for (Device = 0; Device < PCI_MAX_PCI_DEVICES; Device++) {
continue;
pci_read_config_byte(dev, PCI_HEADER_TYPE, &HeaderType);
-
+
if (ShortPCIListing)
{
- printf("%02d.%d ", Device, Function);
+ printf("%02x.%02x.%02x ", BusNum, Device, Function);
pci_header_show_brief(dev);
}
else
{
- printf("\nFound PCI device %d, function %d:\n",
- Device, Function);
+ printf("\nFound PCI device %02x.%02x.%02x:\n",
+ BusNum, Device, Function);
pci_header_show(dev);
}
}
#undef PRINT2
}
+/* Convert the "bus.device.function" identifier into a number.
+ */
+static pci_dev_t get_pci_dev(char* name)
+{
+ char cnum[12];
+ int len, i, iold, n;
+ int bdfs[3] = {0,0,0};
+
+ len = strlen(name);
+ if (len > 8)
+ return -1;
+ for (i = 0, iold = 0, n = 0; i < len; i++) {
+ if (name[i] == '.') {
+ memcpy(cnum, &name[iold], i - iold);
+ cnum[i - iold] = '\0';
+ bdfs[n++] = simple_strtoul(cnum, NULL, 16);
+ iold = i + 1;
+ }
+ }
+ strcpy(cnum, &name[iold]);
+ if (n == 0)
+ n = 1;
+ bdfs[n] = simple_strtoul(cnum, NULL, 16);
+ return PCI_BDF(bdfs[0], bdfs[1], bdfs[2]);
+}
+
+static int pci_cfg_display(pci_dev_t bdf, ulong addr, ulong size, ulong length)
+{
+#define DISP_LINE_LEN 16
+ ulong i, nbytes, linebytes;
+ int rc = 0;
+
+ if (length == 0)
+ length = 0x40 / size; /* Standard PCI configuration space */
+
+ /* Print the lines.
+ * once, and all accesses are with the specified bus width.
+ */
+ nbytes = length * size;
+ do {
+ uint val4;
+ ushort val2;
+ u_char val1;
+
+ printf("%08lx:", addr);
+ linebytes = (nbytes>DISP_LINE_LEN)?DISP_LINE_LEN:nbytes;
+ for (i=0; i<linebytes; i+= size) {
+ if (size == 4) {
+ pci_read_config_dword(bdf, addr, &val4);
+ printf(" %08x", val4);
+ } else if (size == 2) {
+ pci_read_config_word(bdf, addr, &val2);
+ printf(" %04x", val2);
+ } else {
+ pci_read_config_byte(bdf, addr, &val1);
+ printf(" %02x", val1);
+ }
+ addr += size;
+ }
+ printf("\n");
+ nbytes -= linebytes;
+ if (ctrlc()) {
+ rc = 1;
+ break;
+ }
+ } while (nbytes > 0);
+
+ return (rc);
+}
+
+static int pci_cfg_write (pci_dev_t bdf, ulong addr, ulong size, ulong value)
+{
+ if (size == 4) {
+ pci_write_config_dword(bdf, addr, value);
+ }
+ else if (size == 2) {
+ ushort val = value & 0xffff;
+ pci_write_config_word(bdf, addr, val);
+ }
+ else {
+ u_char val = value & 0xff;
+ pci_write_config_byte(bdf, addr, val);
+ }
+ return 0;
+}
+
+static int
+pci_cfg_modify (pci_dev_t bdf, ulong addr, ulong size, ulong value, int incrflag)
+{
+ ulong i;
+ int nbytes;
+ extern char console_buffer[];
+ uint val4;
+ ushort val2;
+ u_char val1;
+
+ /* Print the address, followed by value. Then accept input for
+ * the next value. A non-converted value exits.
+ */
+ do {
+ printf("%08lx:", addr);
+ if (size == 4) {
+ pci_read_config_dword(bdf, addr, &val4);
+ printf(" %08x", val4);
+ }
+ else if (size == 2) {
+ pci_read_config_word(bdf, addr, &val2);
+ printf(" %04x", val2);
+ }
+ else {
+ pci_read_config_byte(bdf, addr, &val1);
+ printf(" %02x", val1);
+ }
+
+ nbytes = readline (" ? ");
+ if (nbytes == 0 || (nbytes == 1 && console_buffer[0] == '-')) {
+ /* <CR> pressed as only input, don't modify current
+ * location and move to next. "-" pressed will go back.
+ */
+ if (incrflag)
+ addr += nbytes ? -size : size;
+ nbytes = 1;
+#ifdef CONFIG_BOOT_RETRY_TIME
+ reset_cmd_timeout(); /* good enough to not time out */
+#endif
+ }
+#ifdef CONFIG_BOOT_RETRY_TIME
+ else if (nbytes == -2) {
+ break; /* timed out, exit the command */
+ }
+#endif
+ else {
+ char *endp;
+ i = simple_strtoul(console_buffer, &endp, 16);
+ nbytes = endp - console_buffer;
+ if (nbytes) {
+#ifdef CONFIG_BOOT_RETRY_TIME
+ /* good enough to not time out
+ */
+ reset_cmd_timeout();
+#endif
+ pci_cfg_write (bdf, addr, size, i);
+ if (incrflag)
+ addr += size;
+ }
+ }
+ } while (nbytes);
+
+ return 0;
+}
+
+/* PCI Configuration Space access commands
+ *
+ * Syntax:
+ * pci display[.b, .w, .l] bus.device.function} [addr] [len]
+ * pci next[.b, .w, .l] bus.device.function [addr]
+ * pci modify[.b, .w, .l] bus.device.function [addr]
+ * pci write[.b, .w, .l] bus.device.function addr value
+ */
+int do_pci (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+{
+ ulong addr = 0, value = 0, size = 0;
+ pci_dev_t bdf = 0;
+ char cmd = 's';
+
+ if (argc > 1)
+ cmd = argv[1][0];
+
+ switch (cmd) {
+ case 'd': /* display */
+ case 'n': /* next */
+ case 'm': /* modify */
+ case 'w': /* write */
+ /* Check for a size specification. */
+ size = cmd_get_data_size(argv[1], 4);
+ if (argc > 3)
+ addr = simple_strtoul(argv[3], NULL, 16);
+ if (argc > 4)
+ value = simple_strtoul(argv[4], NULL, 16);
+ case 'h': /* header */
+ if (argc < 3)
+ goto usage;
+ if ((bdf = get_pci_dev(argv[2])) == -1)
+ return 1;
+ break;
+ default: /* scan bus */
+ value = 1; /* short listing */
+ bdf = 0; /* bus number */
+ if (argc > 1) {
+ if (argv[argc-1][0] == 'l') {
+ value = 0;
+ argc--;
+ }
+ if (argc > 1)
+ bdf = simple_strtoul(argv[1], NULL, 16);
+ }
+ pciinfo(bdf, value);
+ return 0;
+ }
+
+ switch (argv[1][0]) {
+ case 'h': /* header */
+ pci_header_show(bdf);
+ return 0;
+ case 'd': /* display */
+ return pci_cfg_display(bdf, addr, size, value);
+ case 'n': /* next */
+ if (argc < 4)
+ goto usage;
+ return pci_cfg_modify(bdf, addr, size, value, 0);
+ case 'm': /* modify */
+ if (argc < 4)
+ goto usage;
+ return pci_cfg_modify(bdf, addr, size, value, 1);
+ case 'w': /* write */
+ if (argc < 5)
+ goto usage;
+ return pci_cfg_write(bdf, addr, size, value);
+ }
+
+ return 1;
+ usage:
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+}
+
#endif /* (CONFIG_COMMANDS & CFG_CMD_PCI) */
#endif /* CONFIG_PCI */
CMD_TBL_MW
CMD_TBL_NEXT
CMD_TBL_NM
- CMD_TBL_PCIINFO
+ CMD_TBL_PCI
CMD_TBL_PRINTENV
CMD_TBL_PROTECT
CMD_TBL_RARPB
#include <ppcboot.h>
#include <flash.h>
+#if !defined(CFG_NO_FLASH)
+
extern flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
/*-----------------------------------------------------------------------
/*-----------------------------------------------------------------------
*/
+
+#endif /* !CFG_NO_FLASH */
CONFIG_WRITE_HALFWORD(PCICR, 0x06); /* Bus Master, respond to PCI memory space acesses*/
/* CONFIG_WRITE_HALFWORD(PCISR, 0xffff); */ /*reset PCISR*/
-#if defined(CONFIG_MUSENKI)
+#if defined(CONFIG_MUSENKI) || defined(CONFIG_PN62)
/* Why is this here, you ask? Try, just try setting 0x8000
* in PCIACR with CONFIG_WRITE_HALFWORD()
* this one was a stumper, and we are annoyed
CONFIG_READ_WORD(PICR2, val);
val= val & ~ (PICR2_CF_SNOOP_WS_MASK | PICR2_CF_APHASE_WS_MASK); /*mask off waitstate bits*/
- CONFIG_WRITE_WORD(PICR2, val | PICR2_CF_SNOOP_WS_1WS | PICR2_CF_APHASE_WS_1WS); /*1 wait state*/
+#ifndef CONFIG_PN62
+ val |= PICR2_CF_SNOOP_WS_1WS | PICR2_CF_APHASE_WS_1WS; /*1 wait state*/
+#endif
+ CONFIG_WRITE_WORD(PICR2, val);
+
CONFIG_WRITE_WORD(EUMBBAR, CFG_EUMB_ADDR);
#ifndef CFG_RAMBOOT
CONFIG_WRITE_WORD(MCCR1, (CFG_ROMNAL << MCCR1_ROMNAL_SHIFT) |
* should define CFG_ACTORW to 0 if they don't want to set it, or even, if
* its not set, we define it to zero in this file
*/
-#if defined(CONFIG_CU824)
+#if defined(CONFIG_CU824) || defined(CONFIG_PN62)
CONFIG_WRITE_WORD(MCCR4,
(CFG_PRETOACT << MCCR4_PRETOACT_SHIFT) |
(CFG_ACTTOPRE << MCCR4_ACTTOPRE_SHIFT) |
LIB = libdrivers.a
OBJS = ns87308.o ns16550.o serial.o pci_auto.o pci.o pci_indirect.o \
- eepro100.o dc2114x.o w83c553f.o sym53c8xx.o
+ eepro100.o dc2114x.o w83c553f.o sym53c8xx.o pcnet.o
all: $(LIB)
$(LIB): $(OBJS)
--- /dev/null
+/*
+ * (C) Copyright 2002 Wolfgang Grandegger, wg@denx.de.
+ *
+ * This driver for AMD PCnet network controllers is derived from the
+ * Linux driver pcnet32.c written 1996-1999 by Thomas Bogendoerfer.
+ *
+ * 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 <ppcboot.h>
+#include <malloc.h>
+#include <net.h>
+#include <asm/io.h>
+#include <pci.h>
+
+#if 0
+#define PCNET_DEBUG_LEVEL 0 /* 0=off, 1=init, 2=rx/tx */
+#endif
+
+#if PCNET_DEBUG_LEVEL > 0
+#define DEBUG1(fmt,args...) printf (fmt ,##args)
+#if PCNET_DEBUG_LEVEL > 1
+#define DEBUG2(fmt,args...) printf (fmt ,##args)
+#else
+#define DEBUG2(fmt,args...)
+#endif
+#else
+#define DEBUG1(fmt,args...)
+#define DEBUG2(fmt,args...)
+#endif
+
+#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI) \
+ && defined(CONFIG_PCNET)
+
+#if !defined(CONF_PCNET_79C973) && defined(CONF_PCNET_79C975)
+#error "Macro for PCnet chip version is not defined!"
+#endif
+
+/*
+ * Set the number of Tx and Rx buffers, using Log_2(# buffers).
+ * Reasonable default values are 4 Tx buffers, and 16 Rx buffers.
+ * That translates to 2 (4 == 2^^2) and 4 (16 == 2^^4).
+ */
+#define PCNET_LOG_TX_BUFFERS 0
+#define PCNET_LOG_RX_BUFFERS 2
+
+#define TX_RING_SIZE (1 << (PCNET_LOG_TX_BUFFERS))
+#define TX_RING_LEN_BITS ((PCNET_LOG_TX_BUFFERS) << 12)
+
+#define RX_RING_SIZE (1 << (PCNET_LOG_RX_BUFFERS))
+#define RX_RING_LEN_BITS ((PCNET_LOG_RX_BUFFERS) << 4)
+
+#define PKT_BUF_SZ 1544
+
+/* The PCNET Rx and Tx ring descriptors. */
+struct pcnet_rx_head {
+ u32 base;
+ s16 buf_length;
+ s16 status;
+ u32 msg_length;
+ u32 reserved;
+};
+
+struct pcnet_tx_head {
+ u32 base;
+ s16 length;
+ s16 status;
+ u32 misc;
+ u32 reserved;
+};
+
+/* The PCNET 32-Bit initialization block, described in databook. */
+struct pcnet_init_block {
+ u16 mode;
+ u16 tlen_rlen;
+ u8 phys_addr[6];
+ u16 reserved;
+ u32 filter[2];
+ /* Receive and transmit ring base, along with extra bits. */
+ u32 rx_ring;
+ u32 tx_ring;
+ u32 reserved2;
+};
+
+typedef struct pcnet_priv {
+ struct pcnet_rx_head rx_ring[RX_RING_SIZE];
+ struct pcnet_tx_head tx_ring[TX_RING_SIZE];
+ struct pcnet_init_block init_block;
+ /* Receive Buffer space */
+ unsigned char rx_buf[RX_RING_SIZE][PKT_BUF_SZ + 4];
+ int cur_rx;
+ int cur_tx;
+} pcnet_priv_t;
+
+static pcnet_priv_t *lp;
+
+/* Offsets from base I/O address for WIO mode */
+#define PCNET_RDP 0x10
+#define PCNET_RAP 0x12
+#define PCNET_RESET 0x14
+#define PCNET_BDP 0x16
+
+static u16 pcnet_read_csr (struct eth_device *dev, int index)
+{
+ outw (index, dev->iobase+PCNET_RAP);
+ return inw (dev->iobase+PCNET_RDP);
+}
+
+static void pcnet_write_csr (struct eth_device *dev, int index, u16 val)
+{
+ outw (index, dev->iobase+PCNET_RAP);
+ outw (val, dev->iobase+PCNET_RDP);
+}
+
+static u16 pcnet_read_bcr (struct eth_device *dev, int index)
+{
+ outw (index, dev->iobase+PCNET_RAP);
+ return inw (dev->iobase+PCNET_BDP);
+}
+
+static void pcnet_write_bcr (struct eth_device *dev, int index, u16 val)
+{
+ outw (index, dev->iobase+PCNET_RAP);
+ outw (val, dev->iobase+PCNET_BDP);
+}
+
+static void pcnet_reset (struct eth_device *dev)
+{
+ inw (dev->iobase+PCNET_RESET);
+}
+
+static int pcnet_check (struct eth_device *dev)
+{
+ outw (88, dev->iobase+PCNET_RAP);
+ return (inw (dev->iobase+PCNET_RAP) == 88);
+}
+
+static int pcnet_init( struct eth_device* dev, bd_t *bis);
+static int pcnet_send (struct eth_device* dev, volatile void *packet,
+ int length);
+static int pcnet_recv (struct eth_device* dev);
+static void pcnet_halt (struct eth_device* dev);
+static int pcnet_probe(struct eth_device* dev, bd_t *bis, int dev_num);
+
+#define PCI_TO_MEM(d,a) pci_phys_to_mem((pci_dev_t)d->priv, (u_long)(a))
+#define PCI_TO_MEM_LE(d,a) (u32)(cpu_to_le32(PCI_TO_MEM(d,a)))
+
+static struct pci_device_id supported[] = {
+ { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE },
+ { }
+};
+
+
+int pcnet_initialize(bd_t *bis)
+{
+ pci_dev_t devbusfn;
+ struct eth_device* dev;
+ u16 command, status;
+ int dev_nr = 0;
+
+ DEBUG1("\npcnet_initialize...\n");
+
+ for (dev_nr = 0; ; dev_nr++) {
+
+ /*
+ * Find the PCnet PCI device(s).
+ */
+ if ((devbusfn = pci_find_devices(supported, dev_nr)) < 0) {
+ break;
+ }
+
+ /*
+ * Allocate and pre-fill the device structure.
+ */
+ dev = (struct eth_device*) malloc(sizeof *dev);
+ dev->priv = (void *)devbusfn;
+ sprintf(dev->name, "pcnet#%d", dev_nr);
+
+ /*
+ * Setup the PCI device.
+ */
+ pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, &dev->iobase);
+ dev->iobase &= ~0xf;
+
+ DEBUG1("%s: devbusfn=0x%x iobase=0x%x: ",
+ dev->name, devbusfn, dev->iobase);
+
+ command = PCI_COMMAND_IO | PCI_COMMAND_MASTER;
+ pci_write_config_word(devbusfn, PCI_COMMAND, command);
+ pci_read_config_word(devbusfn, PCI_COMMAND, &status);
+ if ((status & command) != command) {
+ printf("%s: Couldn't enable IO access or Bus Mastering\n",
+ dev->name);
+ free(dev);
+ continue;
+ }
+
+ pci_write_config_byte(devbusfn, PCI_LATENCY_TIMER, 0x40);
+
+ /*
+ * Probe the PCnet chip.
+ */
+ if (pcnet_probe(dev, bis, dev_nr) < 0) {
+ free(dev);
+ continue;
+ }
+
+ /*
+ * Setup device structure and register the driver.
+ */
+ dev->init = pcnet_init;
+ dev->halt = pcnet_halt;
+ dev->send = pcnet_send;
+ dev->recv = pcnet_recv;
+
+ eth_register(dev);
+ }
+
+ udelay(10 * 1000);
+
+ return dev_nr;
+}
+
+static int pcnet_probe(struct eth_device* dev, bd_t *bis, int dev_nr)
+{
+ int chip_version;
+ char *chipname;
+#ifdef PCNET_HAS_PROM
+ int i;
+#endif
+
+ /* Reset the PCnet controller */
+ pcnet_reset(dev);
+
+ /* Check if register access is working */
+ if (pcnet_read_csr(dev, 0) != 4 || !pcnet_check(dev)) {
+ printf("%s: CSR register access check failed\n", dev->name);
+ return -1;
+ }
+
+ /* Identify the chip */
+ chip_version = pcnet_read_csr(dev, 88) | (pcnet_read_csr(dev,89) << 16);
+ if ((chip_version & 0xfff) != 0x003)
+ return -1;
+ chip_version = (chip_version >> 12) & 0xffff;
+ switch (chip_version) {
+#ifdef CONFIG_PCNET_79C973
+ case 0x2625:
+ chipname = "PCnet/FAST III 79C973"; /* PCI */
+ break;
+#endif
+#ifdef CONFIG_PCNET_79C975
+ case 0x2627:
+ chipname = "PCnet/FAST III 79C975"; /* PCI */
+ break;
+#endif
+ default:
+ printf("%s: PCnet version %#x not supported\n",
+ dev->name, chip_version);
+ return -1;
+ }
+
+ DEBUG1("AMD %s\n", chipname);
+
+#ifdef PCNET_HAS_PROM
+ /*
+ * In most chips, after a chip reset, the ethernet address is read from
+ * the station address PROM at the base address and programmed into the
+ * "Physical Address Registers" CSR12-14.
+ */
+ for (i = 0; i < 3; i++) {
+ unsigned int val;
+ val = pcnet_read_csr(dev, i+12) & 0x0ffff;
+ /* There may be endianness issues here. */
+ dev->dev_addr[2*i] = val & 0x0ff;
+ dev->dev_addr[2*i+1] = (val >> 8) & 0x0ff;
+ }
+#endif /* PCNET_HAS_PROM */
+
+ return 0;
+}
+
+static int pcnet_init(struct eth_device* dev, bd_t *bis)
+{
+ int i, val;
+ u32 addr;
+
+ DEBUG1("%s: pcnet_init...\n", dev->name);
+
+ /* Switch pcnet to 32bit mode */
+ pcnet_write_bcr (dev, 20, 2);
+
+#ifdef CONFIG_PN62
+ /* Setup LED registers */
+ val = pcnet_read_bcr (dev, 2) | 0x1000;
+ pcnet_write_bcr (dev, 2, val); /* enable LEDPE */
+ pcnet_write_bcr (dev, 4, 0x5080); /* 100MBit */
+ pcnet_write_bcr (dev, 5, 0x40c0); /* LNKSE */
+ pcnet_write_bcr (dev, 6, 0x4090); /* TX Activity */
+ pcnet_write_bcr (dev, 7, 0x4084); /* RX Activity */
+#endif
+
+ /* Set/reset autoselect bit */
+ val = pcnet_read_bcr (dev, 2) & ~2;
+ val |= 2;
+ pcnet_write_bcr (dev, 2, val);
+
+ /* Enable auto negotiate, setup, disable fd */
+ val = pcnet_read_bcr(dev, 32) & ~0x98;
+ val |= 0x20;
+ pcnet_write_bcr(dev, 32, val);
+
+ /*
+ * We only maintain one structure because the drivers will never
+ * be used concurrently. In 32bit mode the RX and TX ring entries
+ * must be aligned on 16-byte boundaries.
+ */
+ if (lp == NULL) {
+ addr = (u32)malloc(sizeof(pcnet_priv_t) + 0x10);
+ addr = (addr + 0xf) & ~0xf;
+ lp = (pcnet_priv_t *)addr;
+ }
+
+ lp->init_block.mode = cpu_to_le16(0x0000);
+ lp->init_block.filter[0] = 0x00000000;
+ lp->init_block.filter[1] = 0x00000000;
+
+ /*
+ * Initialize the Rx ring.
+ */
+ lp->cur_rx = 0;
+ for (i = 0; i < RX_RING_SIZE; i++) {
+ lp->rx_ring[i].base = PCI_TO_MEM_LE(dev, lp->rx_buf[i]);
+ lp->rx_ring[i].buf_length = cpu_to_le16(-PKT_BUF_SZ);
+ lp->rx_ring[i].status = cpu_to_le16(0x8000);
+ DEBUG1("Rx%d: base=0x%x buf_length=0x%x status=0x%x\n",
+ i, lp->rx_ring[i].base, lp->rx_ring[i].buf_length,
+ lp->rx_ring[i].status);
+ }
+
+ /*
+ * Initialize the Tx ring. The Tx buffer address is filled in as
+ * needed, but we do need to clear the upper ownership bit.
+ */
+ lp->cur_tx = 0;
+ for (i = 0; i < TX_RING_SIZE; i++) {
+ lp->tx_ring[i].base = 0;
+ lp->tx_ring[i].status = 0;
+ }
+
+ /*
+ * Setup Init Block.
+ */
+ DEBUG1("Init block at 0x%p: MAC", &lp->init_block);
+
+ for (i = 0; i < 6; i++) {
+ lp->init_block.phys_addr[i] = dev->enetaddr[i];
+ DEBUG1(" %02x", lp->init_block.phys_addr[i]);
+ }
+
+ lp->init_block.tlen_rlen = cpu_to_le16(TX_RING_LEN_BITS |
+ RX_RING_LEN_BITS);
+ lp->init_block.rx_ring = PCI_TO_MEM_LE(dev, lp->rx_ring);
+ lp->init_block.tx_ring = PCI_TO_MEM_LE(dev, lp->tx_ring);
+
+ DEBUG1("\ntlen_rlen=0x%x rx_ring=0x%x tx_ring=0x%x\n",
+ lp->init_block.tlen_rlen,
+ lp->init_block.rx_ring, lp->init_block.tx_ring);
+
+ /*
+ * Tell the controller where the Init Block is located.
+ */
+ addr = PCI_TO_MEM(dev, &lp->init_block);
+ pcnet_write_csr(dev, 1, addr & 0xffff);
+ pcnet_write_csr(dev, 2, (addr >> 16) & 0xffff);
+
+ pcnet_write_csr (dev, 4, 0x0915);
+ pcnet_write_csr (dev, 0, 0x0001); /* start */
+
+ /* Wait for Init Done bit */
+ for (i = 10000; i > 0; i--) {
+ if (pcnet_read_csr (dev, 0) & 0x0100)
+ break;
+ udelay(10);
+ }
+ if (i <= 0) {
+ printf("%s: TIMEOUT: controller init failed\n", dev->name);
+ pcnet_reset (dev);
+ return 0;
+ }
+
+ /*
+ * Finally start network controller operation.
+ */
+ pcnet_write_csr (dev, 0, 0x0002);
+
+ return 1;
+}
+
+static int pcnet_send(struct eth_device* dev, volatile void *packet, int pkt_len)
+{
+ int i, status;
+ struct pcnet_tx_head *entry = &lp->tx_ring[lp->cur_tx];
+
+ DEBUG2("Tx%d: %d bytes from 0x%p ", lp->cur_tx, pkt_len, packet);
+
+ /* Wait for completion by testing the OWN bit */
+ for (i = 1000; i > 0; i--) {
+ status = le16_to_cpu(entry->status);
+ if ((status & 0x8000) == 0)
+ break;
+ udelay(100);
+ DEBUG2(".");
+ }
+ if (i <= 0) {
+ printf("%s: TIMEOUT: Tx%d failed (status = 0x%x)\n",
+ dev->name, lp->cur_tx, status);
+ pkt_len = 0;
+ goto failure;
+ }
+
+ /*
+ * Setup Tx ring. Caution: the write order is important here,
+ * set the status with the "ownership" bits last.
+ */
+ status = 0x8300;
+ entry->length = le16_to_cpu(-pkt_len);
+ entry->misc = 0x00000000;
+ entry->base = PCI_TO_MEM_LE(dev, packet);
+ entry->status = le16_to_cpu(status);
+
+ /* Trigger an immediate send poll. */
+ pcnet_write_csr (dev, 0, 0x0008);
+
+ failure:
+ if (++lp->cur_tx >= TX_RING_SIZE)
+ lp->cur_tx = 0;
+
+ DEBUG2("done\n");
+ return pkt_len;
+}
+
+static int pcnet_recv(struct eth_device* dev)
+{
+ struct pcnet_rx_head *entry;
+ int pkt_len = 0;
+ u16 status;
+
+ while (1) {
+ entry = &lp->rx_ring[lp->cur_rx];
+ /*
+ * If we own the next entry, it's a new packet. Send it up.
+ */
+ if (((status = le16_to_cpu(entry->status)) & 0x8000) != 0) {
+ break;
+ }
+ status >>= 8;
+
+ if (status != 0x03) { /* There was an error. */
+
+ printf("%s: Rx%d", dev->name, lp->cur_rx);
+ DEBUG1(" (status=0x%x)", status);
+ if (status & 0x20) printf(" Frame");
+ if (status & 0x10) printf(" Overflow");
+ if (status & 0x08) printf(" CRC");
+ if (status & 0x04) printf(" Fifo");
+ printf(" Error\n");
+ entry->status &= le16_to_cpu(0x03ff);
+
+ } else {
+
+ pkt_len = (le32_to_cpu(entry->msg_length) & 0xfff) - 4;
+ if (pkt_len < 60) {
+ printf("%s: Rx%d: invalid packet length %d\n",
+ dev->name, lp->cur_rx, pkt_len);
+ } else {
+ NetReceive(lp->rx_buf[lp->cur_rx], pkt_len);
+ DEBUG2("Rx%d: %d bytes from 0x%p\n",
+ lp->cur_rx, pkt_len, lp->rx_buf[lp->cur_rx]);
+ }
+ }
+ entry->status |= cpu_to_le16(0x8000);
+
+ if (++lp->cur_rx >= RX_RING_SIZE)
+ lp->cur_rx = 0;
+ }
+ return pkt_len;
+}
+
+static void pcnet_halt(struct eth_device* dev)
+{
+ int i;
+
+ DEBUG1("%s: pcnet_halt...\n", dev->name);
+
+ /* Reset the PCnet controller */
+ pcnet_reset (dev);
+
+ /* Wait for Stop bit */
+ for (i = 1000; i > 0; i--) {
+ if (pcnet_read_csr (dev, 0) & 0x4)
+ break;
+ udelay(10);
+ }
+ if (i <= 0) {
+ printf("%s: TIMEOUT: controller reset failed\n", dev->name);
+ }
+}
+
+#endif
#endif /* CONFIG_PCIPPC2 , CONFIG_PCIPPC6 */
/* ----------------------------------------------------------------------------*/
+/* ----- PN62 -----------------------------------------------------------------*/
+#if defined(CONFIG_PN62)
+
+#define CMD_TBL_BSP MK_CMD_TBL_ENTRY( \
+ "loadpci", 5, 2, 1, do_loadpci, \
+ "loadpci - load binary file over PCI\n", \
+ "[addr]\n" \
+ " - load binary file over PCI to address 'addr'\n" \
+), MK_CMD_TBL_ENTRY( \
+ "led" , 3, 3, 1, do_led, \
+ "led - set LED 0..11 on the PN62 board\n", \
+ "i fun\n" \
+ " - set 'i'th LED to function 'fun'\n" \
+),
+
+extern int do_loadpci (cmd_tbl_t *, bd_t *, int, int, char *[]);
+extern int do_led (cmd_tbl_t *, bd_t *, int, int, char *[]);
+#endif /* CONFIG_PN62 */
+/* ----------------------------------------------------------------------------*/
+
#else
#define CMD_TBL_BSP
#endif /* CFG_CMD_BSP */
#define _CMD_PCI_H
#if (CONFIG_COMMANDS & CFG_CMD_PCI)
-#define CMD_TBL_PCIINFO MK_CMD_TBL_ENTRY( \
- "pciinfo", 3, 2, 1, do_pciinfo, \
- "pciinfo - print information about PCI devices\n", \
- "[ bus ]\n" \
- " - print information about PCI devices on PCI-Bus 'bus'\n" \
+#define CMD_TBL_PCI MK_CMD_TBL_ENTRY( \
+ "pci", 3, 5, 1, do_pci, \
+ "pci - list and access PCI Configuraton Space\n", \
+ "[bus] [long]\n" \
+ " - short or long list of PCI devices on bus 'bus'\n" \
+ "pci header b.d.f\n" \
+ " - show header of PCI device 'bus.device.function'\n" \
+ "pci display[.b, .w, .l] b.d.f [address] [# of objects]\n" \
+ " - display PCI configuration space (CFG)\n" \
+ "pci next[.b, .w, .l] b.d.f address\n" \
+ " - modify, read and keep CFG address\n" \
+ "pci modify[.b, .w, .l] b.d.f address\n" \
+ " - modify, auto increment CFG address\n" \
+ "pci write[.b, .w, .l] b.d.f address value\n" \
+ " - write to CFG address\n" \
),
-int do_pciinfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]);
+int do_pci (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]);
#else
-#define CMD_TBL_PCIINFO
+#define CMD_TBL_PCI
#endif /* CFG_CMD_PCI */
#endif /* _CMD_PCI_H */
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Wolfgang Grandegger, DENX Software Engineering, wg@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
+ */
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_MPC824X 1
+#define CONFIG_MPC8240 1
+#define CONFIG_PN62 1
+
+#define CONFIG_CONS_INDEX 1
+
+
+#define REMOVE_COMMANDS ( CFG_CMD_AUTOSCRIPT | \
+ CFG_CMD_LOADS | \
+ CFG_CMD_ENV | \
+ CFG_CMD_FLASH )
+
+#define CONFIG_COMMANDS ( (CONFIG_CMD_DFL & ~REMOVE_COMMANDS) |\
+ CFG_CMD_PCI |\
+ CFG_CMD_BSP)
+
+#define CONFIG_BAUDRATE 19200 /* console baudrate */
+
+#define CONFIG_BOOTDELAY 1 /* autoboot after n seconds */
+
+#define CONFIG_CLOCKS_IN_MHZ 1 /* clocks passsed to Linux in MHz */
+
+#define CONFIG_SERVERIP 10.0.0.201
+#define CONFIG_IPADDR 10.0.0.200
+#define CONFIG_ROOTPATH /opt/eldk/ppc_82xx
+#define CONFIG_NETMASK 255.255.255.0
+#undef CONFIG_BOOTARGS
+#if 0
+/* Boot Linux with NFS root filesystem */
+#define CONFIG_BOOTCOMMAND \
+ "setenv verify y;" \
+ "setenv bootargs console=ttyS0,19200 mem=31M quiet " \
+ "root=/dev/nfs rw nfsroot=$(serverip):$(rootpath) " \
+ "ip=$(ipaddr):$(serverip)::$(netmask):pn62:eth0:off;" \
+ "loadp 100000; bootm"
+ /* "tftpboot 100000 pImage; bootm" */
+#else
+/* Boot Linux with RAMdisk based filesystem (initrd, BusyBox) */
+#define CONFIG_BOOTCOMMAND \
+ "setenv verify n;" \
+ "setenv bootargs console=ttyS0,19200 mem=31M quiet " \
+ "root=/dev/ram rw " \
+ "ip=$(ipaddr):$(serverip)::$(netmask):pn62:eth0:off;" \
+ "loadp 200000; bootm"
+#endif
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP 1 /* undef to save memory */
+#define CFG_PROMPT "=> " /* Monitor Command Prompt */
+#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
+#define CFG_MAXARGS 16 /* max number of command args */
+#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
+#define CFG_LOAD_ADDR 0x00100000 /* default load address */
+#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */
+
+#define CONFIG_PRAM 1024 /* reserve 1 MB protected RAM */
+
+#define CONFIG_MISC_INIT_R 1 /* call misc_init_r() on init */
+
+#define CONFIG_SHOW_BOOT_PROGRESS 1 /* Show boot progress on LEDs */
+
+/*
+ * PCI stuff
+ */
+#define CONFIG_PCI /* include pci support */
+#define CONFIG_PCI_PNP /* we need Plug 'n Play */
+#if 0
+#define CONFIG_PCI_SCAN_SHOW /* show PCI auto-scan at boot */
+#endif
+
+/*
+ * Networking stuff
+ */
+#define CONFIG_NET_MULTI /* Multi ethernet cards support */
+
+#define CONFIG_PCNET /* there are 2 AMD PCnet 79C973 */
+#define CONFIG_PCNET_79C973
+
+#define _IO_BASE 0xfe000000 /* points to PCI I/O space */
+
+
+/*
+ * Start addresses for the final memory configuration
+ * (Set up by the startup code)
+ * Please note that CFG_SDRAM_BASE _must_ start at 0
+ */
+#define CFG_SDRAM_BASE 0x00000000
+#define CFG_MAX_RAM_SIZE 0x10000000
+
+#define CFG_RESET_ADDRESS 0xfff00100
+
+#undef CFG_RAMBOOT
+#define CFG_MONITOR_LEN 0x00030000
+#define CFG_MONITOR_BASE TEXT_BASE
+
+/*#define CFG_INIT_DATA_SIZE 256*/
+#define CFG_INIT_DATA_SIZE 128
+
+#define CFG_INIT_RAM_ADDR 0x40000000
+#define CFG_INIT_RAM_END 0x1000
+#define CFG_INIT_DATA_OFFSET (CFG_INIT_RAM_END - CFG_INIT_DATA_SIZE)
+
+
+#define CFG_NO_FLASH 1 /* There is no FLASH memory */
+
+#define CFG_ENV_IS_NOWHERE 1 /* Store ENV in memory only */
+#define CFG_ENV_OFFSET 0x00004000 /* Offset of Environment Sector */
+#define CFG_ENV_SIZE 0x00002000 /* Total Size of Environment Sector */
+
+#define CFG_MALLOC_LEN (512 << 10) /* Reserve 512 kB for malloc() */
+
+#define CFG_MEMTEST_START 0x00004000 /* memtest works on */
+#define CFG_MEMTEST_END 0x01f00000 /* 0 ... 32 MB in DRAM */
+
+/*
+ * Serial port configuration
+ */
+#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
+
+#define CFG_NS16550
+#define CFG_NS16550_SERIAL
+
+#define CFG_NS16550_REG_SIZE 1
+
+#define CFG_NS16550_CLK 1843200
+
+#define CFG_NS16550_COM1 0xff800008
+#define CFG_NS16550_COM2 0xff800000
+
+/*
+ * Low Level Configuration Settings
+ * (address mappings, register initial values, etc.)
+ * You should know what you are doing if you make changes here.
+ */
+
+#define CONFIG_SYS_CLK_FREQ 33333333 /* external frequency to pll */
+#define CONFIG_PLL_PCI_TO_MEM_MULTIPLIER 3
+
+#define CFG_EUMB_ADDR 0xFCE00000
+
+/* MCCR1 */
+#define CFG_ROMNAL 3 /* rom/flash next access time */
+#define CFG_ROMFAL 7 /* rom/flash access time */
+
+/* MCCR2 */
+#define CFG_ASRISE 6 /* ASRISE in clocks */
+#define CFG_ASFALL 12 /* ASFALL in clocks */
+#define CFG_REFINT 5600 /* REFINT in clocks */
+
+/* MCCR3 */
+#define CFG_BSTOPRE 0x3cf /* Burst To Precharge */
+#define CFG_REFREC 2 /* Refresh to activate interval */
+#define CFG_RDLAT 3 /* data latency from read command */
+
+/* MCCR4 */
+#define CFG_PRETOACT 1 /* Precharge to activate interval */
+#define CFG_ACTTOPRE 3 /* Activate to Precharge interval */
+#define CFG_ACTORW 2 /* Activate to R/W */
+#define CFG_SDMODE_CAS_LAT 2 /* SDMODE CAS latency */
+#define CFG_SDMODE_WRAP 0 /* SDMODE Wrap type */
+#define CFG_SDMODE_BURSTLEN 2 /* SDMODE Burst length 2=4, 3=8 */
+#define CFG_REGISTERD_TYPE_BUFFER 1
+
+/* Memory bank settings:
+ *
+ * only bits 20-29 are actually used from these vales to set the
+ * start/qend address the upper two bits will be 0, and the lower 20
+ * bits will be set to 0x00000 for a start address, or 0xfffff for an
+ * end address
+ */
+#define CFG_BANK0_START 0x00000000
+#define CFG_BANK0_END (CFG_MAX_RAM_SIZE - 1)
+#define CFG_BANK0_ENABLE 1
+#define CFG_BANK1_START 0x00000000
+#define CFG_BANK1_END 0x00000000
+#define CFG_BANK1_ENABLE 0
+#define CFG_BANK2_START 0x00000000
+#define CFG_BANK2_END 0x00000000
+#define CFG_BANK2_ENABLE 0
+#define CFG_BANK3_START 0x00000000
+#define CFG_BANK3_END 0x00000000
+#define CFG_BANK3_ENABLE 0
+#define CFG_BANK4_START 0x00000000
+#define CFG_BANK4_END 0x00000000
+#define CFG_BANK4_ENABLE 0
+#define CFG_BANK5_START 0x00000000
+#define CFG_BANK5_END 0x00000000
+#define CFG_BANK5_ENABLE 0
+#define CFG_BANK6_START 0x00000000
+#define CFG_BANK6_END 0x00000000
+#define CFG_BANK6_ENABLE 0
+#define CFG_BANK7_START 0x00000000
+#define CFG_BANK7_END 0x00000000
+#define CFG_BANK7_ENABLE 0
+
+/*
+ * Memory bank enable bitmask, specifying which of the banks defined above
+ * are actually present. MSB is for bank #7, LSB is for bank #0.
+ */
+#define CFG_BANK_ENABLE 0x01
+
+#define CFG_ODCR 0xff /* configures line driver impedances, */
+ /* see 8240 book for bit definitions */
+#define CFG_PGMAX 0x32 /* how long the 8240 retains the */
+ /* currently accessed page in memory */
+ /* see 8240 book for details */
+
+/* SDRAM 0 - 256MB */
+#define CFG_IBAT0L (CFG_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE)
+#define CFG_IBAT0U (CFG_SDRAM_BASE | BATU_BL_256M | BATU_VS | BATU_VP)
+
+#define CFG_IBAT1L (CFG_INIT_RAM_ADDR | BATL_PP_10 | BATL_MEMCOHERENCE)
+#define CFG_IBAT1U (CFG_INIT_RAM_ADDR | BATU_BL_128K | BATU_VS | BATU_VP)
+
+/* PCI memory space */
+#define CFG_IBAT2L (0x80000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
+#define CFG_IBAT2U (0x80000000 | BATU_BL_256M | BATU_VS | BATU_VP)
+
+/* Config addrs, etc */
+#define CFG_IBAT3L (0xF0000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
+#define CFG_IBAT3U (0xF0000000 | BATU_BL_256M | BATU_VS | BATU_VP)
+
+#define CFG_DBAT0L CFG_IBAT0L
+#define CFG_DBAT0U CFG_IBAT0U
+#define CFG_DBAT1L CFG_IBAT1L
+#define CFG_DBAT1U CFG_IBAT1U
+#define CFG_DBAT2L CFG_IBAT2L
+#define CFG_DBAT2U CFG_IBAT2U
+#define CFG_DBAT3L CFG_IBAT3L
+#define CFG_DBAT3U CFG_IBAT3U
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 8 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
+
+/*
+ * Cache Configuration
+ */
+#define CFG_CACHELINE_SIZE 32 /* For MPC8240 CPU */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+# define CFG_CACHELINE_SHIFT 5 /* log base 2 of the above value */
+#endif
+
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
+#define BOOTFLAG_WARM 0x02 /* Software reboot */
+
+
+#endif /* __CONFIG_H */
#ifndef _FLASH_H_
#define _FLASH_H_
+#ifndef CFG_NO_FLASH
/*-----------------------------------------------------------------------
* FLASH Info: contains chip specific data, per FLASH bank
*/
#define FLASH_ERASE_TIMEOUT 120000 /* timeout for erasing in ms */
#define FLASH_WRITE_TIMEOUT 500 /* timeout for writes in ms */
+#endif /* !CFG_NO_FLASH */
+
#endif /* _FLASH_H_ */
#if defined(CONFIG_HYMOD)
hymod_conf_t bi_hymod_conf; /* hymod configuration information */
#endif
-#if defined(CFG_GT_6426x)
- /* the board has two or three onboard ethernet ports */
+#if defined(CFG_GT_6426x) || defined(CONFIG_PN62)
+ /* second onboard ethernet port */
unsigned char bi_enet1addr[6];
+#endif
+#if defined(CFG_GT_6426x)
+ /* third onboard ethernet port */
unsigned char bi_enet2addr[6];
#endif
#if defined(CONFIG_NX823)
defined(CONFIG_W7O) || \
defined(CONFIG_WALNUT405)
void pci_init (bd_t *);
-void pciinfo (int);
+void pciinfo (int, int);
#endif
#if defined(CONFIG_CCM) || defined(CONFIG_COGENT) || \
extern int eepro100_initialize(bd_t*);
extern int dc21x4x_initialize(bd_t*);
+extern int pcnet_initialize(bd_t*);
extern int fec_initialize(bd_t*);
extern int scc_initialize(bd_t*);
#ifdef CONFIG_TULIP
dc21x4x_initialize(bis);
#endif
+#ifdef CONFIG_PCNET
+ pcnet_initialize(bis);
+#endif
#ifdef CFG_GT_6426x
gt6426x_eth_initialize(bis);
#endif