changeset 906:371979c5cc1e

ixdp425/GRG tweaks
author msalter
date Fri, 04 Apr 2003 14:52:31 +0000
parents e606543201f1
children a289defa82f0
files packages/hal/arm/xscale/grg/current/ChangeLog packages/hal/arm/xscale/grg/current/include/grg.h packages/hal/arm/xscale/grg/current/include/hal_plf_ints.h packages/hal/arm/xscale/grg/current/src/grg_misc.c packages/hal/arm/xscale/ixdp425/current/ChangeLog packages/hal/arm/xscale/ixdp425/current/include/hal_plf_ints.h packages/hal/arm/xscale/ixdp425/current/include/ixdp425.h packages/hal/arm/xscale/ixdp425/current/src/ixdp425_misc.c
diffstat 8 files changed, 422 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/packages/hal/arm/xscale/grg/current/ChangeLog
+++ b/packages/hal/arm/xscale/grg/current/ChangeLog
@@ -1,3 +1,9 @@
+2003-04-04  Mark Salter  <msalter@redhat.com>
+
+	* include/grg.h: Add GPIO line definitions.
+	* include/hal_plf_ints.h: Add GPIO IRQ definitions.
+	* src/grg_misc.c (plf_hardware_init): Initialize GPIO lines.
+
 2003-04-02  Mark Salter  <msalter@redhat.com>
 
 	* misc/redboot_ROM.ecm: Don't set I82559_WRITE_EEPROM.
--- a/packages/hal/arm/xscale/grg/current/include/grg.h
+++ b/packages/hal/arm/xscale/grg/current/include/grg.h
@@ -76,6 +76,25 @@
 
 
 // ------------------------------------------------------------------------
+// GPIO lines
+//
+#define GPIO_PWR_FAIL_IRQ_N 0
+#define GPIO_DSL_IRQ_N      1
+#define GPIO_SLIC_A_IRQ_N   2
+#define GPIO_SLIC_B_IRQ_N   3
+#define GPIO_DSP_IRQ_N      4
+#define GPIO_IDE_IRQ_N      5
+
+// GPIO lines used for SPI bus
+#define GPIO_SPI_CS1_N      7
+#define GPIO_SPI_CS0_N      8
+#define GPIO_SPI_SCK        9
+#define GPIO_SPI_SDI       10
+#define GPIO_SPI_SDO       13
+
+#define GPIO_IO_RESET_N    12
+
+// ------------------------------------------------------------------------
 // No Hex Display
 //
 #ifdef __ASSEMBLER__
--- a/packages/hal/arm/xscale/grg/current/include/hal_plf_ints.h
+++ b/packages/hal/arm/xscale/grg/current/include/hal_plf_ints.h
@@ -10,7 +10,7 @@
 //####ECOSGPLCOPYRIGHTBEGIN####
 // -------------------------------------------
 // This file is part of eCos, the Embedded Configurable Operating System.
-// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.
 //
 // eCos 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
@@ -57,6 +57,14 @@
 // start with variant ints
 #include CYGBLD_HAL_VAR_INTS_H
 
+#define CYGNUM_HAL_INTERRUPT_PWR_FAIL CYGNUM_HAL_INTERRUPT_GPIO0
+#define CYGNUM_HAL_INTERRUPT_DSL      CYGNUM_HAL_INTERRUPT_GPIO1
+#define CYGNUM_HAL_INTERRUPT_SLIC_A   CYGNUM_HAL_INTERRUPT_GPIO2
+#define CYGNUM_HAL_INTERRUPT_SLIC_B   CYGNUM_HAL_INTERRUPT_GPIO3
+#define CYGNUM_HAL_INTERRUPT_DSP      CYGNUM_HAL_INTERRUPT_GPIO4
+#define CYGNUM_HAL_INTERRUPT_IDE      CYGNUM_HAL_INTERRUPT_GPIO5
+
+
 // NB: Commented out because of errata on reset function of watchdog timer
 //
 #if 0
--- a/packages/hal/arm/xscale/grg/current/src/grg_misc.c
+++ b/packages/hal/arm/xscale/grg/current/src/grg_misc.c
@@ -75,6 +75,53 @@
 void
 plf_hardware_init(void)
 {
+    // POWER_FAIL IRQ
+    HAL_GPIO_OUTPUT_DISABLE(GPIO_PWR_FAIL_IRQ_N);   
+    HAL_INTERRUPT_CONFIGURE(CYGNUM_HAL_INTERRUPT_PWR_FAIL, 1, 0);
+
+    // DSL IRQ
+    HAL_GPIO_OUTPUT_DISABLE(GPIO_DSL_IRQ_N);
+    HAL_INTERRUPT_CONFIGURE(CYGNUM_HAL_INTERRUPT_DSL, 1, 0);
+
+    // SLIC_A IRQ
+    HAL_GPIO_OUTPUT_DISABLE(GPIO_SLIC_A_IRQ_N);
+    HAL_INTERRUPT_CONFIGURE(CYGNUM_HAL_INTERRUPT_SLIC_A, 1, 0);
+
+    // SLIC_B IRQ
+    HAL_GPIO_OUTPUT_DISABLE(GPIO_SLIC_B_IRQ_N);
+    HAL_INTERRUPT_CONFIGURE(CYGNUM_HAL_INTERRUPT_SLIC_B, 1, 0);
+
+    // DSP IRQ
+    HAL_GPIO_OUTPUT_DISABLE(GPIO_DSP_IRQ_N);
+    HAL_INTERRUPT_CONFIGURE(CYGNUM_HAL_INTERRUPT_DSP, 1, 0);
+
+    // IDE IRQ
+    HAL_GPIO_OUTPUT_DISABLE(GPIO_IDE_IRQ_N);
+    HAL_INTERRUPT_CONFIGURE(CYGNUM_HAL_INTERRUPT_IDE, 1, 0);
+
+    // IO RESET_N  (DSP/SLICs)
+    HAL_GPIO_OUTPUT_SET(GPIO_IO_RESET_N);
+    HAL_GPIO_OUTPUT_ENABLE(GPIO_IO_RESET_N);
+    
+    // SPI_CS1_N
+    HAL_GPIO_OUTPUT_SET(GPIO_SPI_CS1_N);
+    HAL_GPIO_OUTPUT_ENABLE(GPIO_SPI_CS1_N);   // Eth PHY
+
+    // SPI_CS0_N
+    HAL_GPIO_OUTPUT_SET(GPIO_SPI_CS0_N);
+    HAL_GPIO_OUTPUT_ENABLE(GPIO_SPI_CS0_N);   // SLICs
+
+    // SPI_SCK
+    HAL_GPIO_OUTPUT_CLEAR(GPIO_SPI_SCK);
+    HAL_GPIO_OUTPUT_ENABLE(GPIO_SPI_SCK);
+
+    // SPI_SDI
+    HAL_GPIO_OUTPUT_CLEAR(GPIO_SPI_SDI);
+    HAL_GPIO_OUTPUT_ENABLE(GPIO_SPI_SDI);
+
+    // SPI_SDI
+    HAL_GPIO_OUTPUT_DISABLE(GPIO_SPI_SDI);
+
 #ifdef CYGPKG_IO_PCI
     extern void hal_plf_pci_init(void);
     hal_plf_pci_init();
--- a/packages/hal/arm/xscale/ixdp425/current/ChangeLog
+++ b/packages/hal/arm/xscale/ixdp425/current/ChangeLog
@@ -1,3 +1,11 @@
+2003-04-04  Mark Salter  <msalter@redhat.com>
+
+	* include/hal_plf_ints.h: Add GPIO IRQ defines.
+	* include/ixdp425.h: Add GPIO line definitions.
+	* src/ixdp425_misc.c (plf_hardware_init): Setup GPIO IRQ lines.
+	Add support to read/write serial EEPROM. Add support for
+	getting/setting NPE ethernet addresses from EEPROM.
+
 2003-04-02  Mark Salter  <msalter@redhat.com>
 
 	* misc/redboot_ROM.ecm: Don't set I82559_WRITE_EEPROM.
--- a/packages/hal/arm/xscale/ixdp425/current/include/hal_plf_ints.h
+++ b/packages/hal/arm/xscale/ixdp425/current/include/hal_plf_ints.h
@@ -57,8 +57,11 @@
 // start with variant ints
 #include CYGBLD_HAL_VAR_INTS_H
 
-#define CYGNUM_HAL_INTERRUPT_NPEB_PHY CYGNUM_HAL_INTERRUPT_GPIO4
-#define CYGNUM_HAL_INTERRUPT_NPEC_PHY CYGNUM_HAL_INTERRUPT_GPIO5
+#define CYGNUM_HAL_INTERRUPT_ETH1 CYGNUM_HAL_INTERRUPT_GPIO5
+#define CYGNUM_HAL_INTERRUPT_ETH0 CYGNUM_HAL_INTERRUPT_GPIO4
+#define CYGNUM_HAL_INTERRUPT_HSS0 CYGNUM_HAL_INTERRUPT_GPIO3
+#define CYGNUM_HAL_INTERRUPT_HSS1 CYGNUM_HAL_INTERRUPT_GPIO2
+#define CYGNUM_HAL_INTERRUPT_DSL  CYGNUM_HAL_INTERRUPT_GPIO1
 
 // NB: Commented out because of errata on reset function of watchdog timer
 //
--- a/packages/hal/arm/xscale/ixdp425/current/include/ixdp425.h
+++ b/packages/hal/arm/xscale/ixdp425/current/include/ixdp425.h
@@ -11,7 +11,7 @@
 //####ECOSGPLCOPYRIGHTBEGIN####
 // -------------------------------------------
 // This file is part of eCos, the Embedded Configurable Operating System.
-// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.
 //
 // eCos 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
@@ -81,6 +81,16 @@
 #define IXP425_SDRAM_REFRESH_CNT  0x081
 #define IXP425_SDRAM_SET_MODE_CMD SDRAM_IR_MODE_SET_CAS3
 
+// ------------------------------------------------------------------------
+// GPIO lines
+
+#define GPIO_EEPROM_SDA  7
+#define GPIO_EEPROM_SCL  6
+#define GPIO_ENET1_INT_N 5
+#define GPIO_ENET0_INT_N 4
+#define GPIO_HSS0_INT_N  3
+#define GPIO_HSS1_INT_N  2
+#define GPIO_DSL_INT_N   1
 
 // ------------------------------------------------------------------------
 // 4 Digit Hex Display
--- a/packages/hal/arm/xscale/ixdp425/current/src/ixdp425_misc.c
+++ b/packages/hal/arm/xscale/ixdp425/current/src/ixdp425_misc.c
@@ -71,7 +71,6 @@
 //
 // Platform specific initialization
 //
-
 void
 plf_hardware_init(void)
 {
@@ -80,24 +79,333 @@ plf_hardware_init(void)
     *IXP425_GPCLKR |= GPCLKR_CLK1_ENABLE;
     *IXP425_GPCLKR |= GPCLKR_CLK1_PCLK2;
 
+    HAL_GPIO_OUTPUT_CLEAR(GPIO_EEPROM_SCL);
+    HAL_GPIO_OUTPUT_ENABLE(GPIO_EEPROM_SCL);
+
+    HAL_GPIO_OUTPUT_SET(GPIO_EEPROM_SDA);
+    HAL_GPIO_OUTPUT_ENABLE(GPIO_EEPROM_SDA);
+
     // ENET-0 IRQ line
-    HAL_GPIO_OUTPUT_DISABLE(4);
-    HAL_INTERRUPT_CONFIGURE(CYGNUM_HAL_INTERRUPT_GPIO4, 1, 0);
+    HAL_GPIO_OUTPUT_DISABLE(GPIO_ENET0_INT_N);
+    HAL_INTERRUPT_CONFIGURE(CYGNUM_HAL_INTERRUPT_ETH0, 1, 0);
 
     // ENET-1 IRQ line
-    HAL_GPIO_OUTPUT_DISABLE(5);
-    HAL_INTERRUPT_CONFIGURE(CYGNUM_HAL_INTERRUPT_GPIO5, 1, 0);
+    HAL_GPIO_OUTPUT_DISABLE(GPIO_ENET1_INT_N);
+    HAL_INTERRUPT_CONFIGURE(CYGNUM_HAL_INTERRUPT_ETH1, 1, 0);
+
+    // HSS IRQ lines
+    HAL_GPIO_OUTPUT_DISABLE(GPIO_HSS0_INT_N);
+    HAL_INTERRUPT_CONFIGURE(CYGNUM_HAL_INTERRUPT_HSS0, 1, 0);
+    HAL_GPIO_OUTPUT_DISABLE(GPIO_HSS1_INT_N);
+    HAL_INTERRUPT_CONFIGURE(CYGNUM_HAL_INTERRUPT_HSS1, 1, 0);
+
+    // DSL IRQ line
+    HAL_GPIO_OUTPUT_DISABLE(GPIO_DSL_INT_N);
+    HAL_INTERRUPT_CONFIGURE(CYGNUM_HAL_INTERRUPT_DSL, 1, 0);
+
+    *IXP425_EXP_CS4 = (EXP_ADDR_T(3) | EXP_SETUP_T(3) | EXP_STROBE_T(15) | EXP_HOLD_T(3) | \
+		       EXP_RECOVERY_T(15) | EXP_SZ_512 | EXP_WR_EN | EXP_CS_EN);
+    *IXP425_EXP_CS5 = (EXP_ADDR_T(3) | EXP_SETUP_T(3) | EXP_STROBE_T(15) | EXP_HOLD_T(3) | \
+		       EXP_RECOVERY_T(15) | EXP_SZ_512 | EXP_WR_EN | EXP_CS_EN);
 
 #ifdef CYGPKG_IO_PCI
     extern void hal_plf_pci_init(void);
     hal_plf_pci_init();
 #endif
+}
 
-    *IXP425_EXP_CS4 = (EXP_ADDR_T(3) | EXP_SETUP_T(3) | EXP_STROBE_T(15) | EXP_HOLD_T(3) | \
-		       EXP_RECOVERY_T(15) | EXP_SZ_512 | EXP_WR_EN | EXP_CS_EN);
-    *IXP425_EXP_CS5 = (EXP_ADDR_T(3) | EXP_SETUP_T(3) | EXP_STROBE_T(15) | EXP_HOLD_T(3) | \
-		       EXP_RECOVERY_T(15) | EXP_SZ_512 | EXP_WR_EN | EXP_CS_EN);
+// --------------------------------------------------------------------------------------
+// EEPROM Support 
+//
+#ifdef CYGPKG_DEVS_ETH_INTEL_NPE
+
+#define CLK_LO()      HAL_GPIO_OUTPUT_CLEAR(GPIO_EEPROM_SCL)
+#define CLK_HI()      HAL_GPIO_OUTPUT_SET(GPIO_EEPROM_SCL)
+
+#define DATA_LO()     HAL_GPIO_OUTPUT_CLEAR(GPIO_EEPROM_SDA)
+#define DATA_HI()     HAL_GPIO_OUTPUT_SET(GPIO_EEPROM_SDA)
+
+
+// returns non-zero if ACK bit seen
+static int
+eeprom_start(cyg_uint8 b)
+{
+    int i;
+
+    CLK_HI();
+    hal_delay_us(5);
+    DATA_LO();
+    hal_delay_us(5);
+    CLK_LO();
+
+    for (i = 7; i >= 0; i--) {
+	if (b & (1 << i))
+	    DATA_HI();
+	else
+	    DATA_LO();
+	hal_delay_us(5);
+	CLK_HI();
+	hal_delay_us(5);
+	CLK_LO();
+    }
+    hal_delay_us(5);
+    HAL_GPIO_OUTPUT_DISABLE(GPIO_EEPROM_SDA);
+    CLK_HI();
+    hal_delay_us(5);
+    i = (*IXP425_GPINR & (1 << GPIO_EEPROM_SDA)) ? 0 : 1;
+    CLK_LO();
+    hal_delay_us(5);
+    HAL_GPIO_OUTPUT_ENABLE(GPIO_EEPROM_SDA);
+
+    return i;
+}
+
+
+static void
+eeprom_stop(void)
+{
+    int i;
+    
+    hal_delay_us(5);
+    DATA_LO();
+    hal_delay_us(5);
+    CLK_HI();
+    hal_delay_us(5);
+    DATA_HI();
+    hal_delay_us(5);
+    CLK_LO();
+    hal_delay_us(5);
+}
+
+
+static int
+eeprom_putb(cyg_uint8 b)
+{
+    int i;
+
+    for (i = 7; i >= 0; i--) {
+	if (b & (1 << i))
+	    DATA_HI();
+	else
+	    DATA_LO();
+	CLK_HI();
+	hal_delay_us(5);
+	CLK_LO();
+	hal_delay_us(5);
+    }
+    HAL_GPIO_OUTPUT_DISABLE(GPIO_EEPROM_SDA);
+    CLK_HI();
+    hal_delay_us(5);
+    i = (*IXP425_GPINR & (1 << GPIO_EEPROM_SDA)) ? 0 : 1;
+    CLK_LO();
+    hal_delay_us(5);
+
+    DATA_HI();
+    HAL_GPIO_OUTPUT_ENABLE(GPIO_EEPROM_SDA);
+
+    return i;
+}
+
+
+static cyg_uint8
+eeprom_getb(int more)
+{
+    int i;
+    cyg_uint8 b = 0;
+
+    HAL_GPIO_OUTPUT_DISABLE(GPIO_EEPROM_SDA);
+    hal_delay_us(5);
+
+    for (i = 7; i >= 0; i--) {
+	b <<= 1;
+	if (*IXP425_GPINR & (1 << GPIO_EEPROM_SDA))
+	    b |= 1;
+	CLK_HI();
+	hal_delay_us(5);
+	CLK_LO();
+	hal_delay_us(5);
+    }
+    HAL_GPIO_OUTPUT_ENABLE(GPIO_EEPROM_SDA);
+    if (more)
+	DATA_LO();
+    else
+	DATA_HI();
+    hal_delay_us(5);
+    CLK_HI();
+    hal_delay_us(5);
+    CLK_LO();
+    hal_delay_us(5);
+
+    return b;
 }
 
+
+static int
+eeprom_read(int addr, cyg_uint8 *buf, int nbytes)
+{
+    cyg_uint8 start_byte;
+    int i;
+
+    start_byte = 0xA0;  // write
+
+    if (addr & (1 << 8))
+	start_byte |= 2;
+
+    
+    for (i = 0; i < 10; i++)
+	if (eeprom_start(start_byte))
+	    break;
+
+    if (i == 10) {
+	diag_printf("eeprom_read: Can't get write start ACK\n");
+	return 0;
+    }
+
+    if (!eeprom_putb(addr & 0xff)) {
+	diag_printf("eeprom_read: Can't get address ACK\n");
+	return 0;
+    }
+
+    start_byte |= 1; // READ command
+    if (!eeprom_start(start_byte)) {
+	diag_printf("eeprom_read: Can't get read start ACK\n");
+	return 0;
+    }
+
+    for (i = 0; i < (nbytes - 1); i++)
+	*buf++ = eeprom_getb(1);
+
+    *buf++ = eeprom_getb(0);
+    hal_delay_us(5);
+    eeprom_stop();
+
+    return nbytes;
+}
+
+static void
+eeprom_write(int addr, cyg_uint8 val)
+{
+    cyg_uint8 start_byte;
+    int i;
+
+    start_byte = 0xA0;  // write
+
+    if (addr & (1 << 8))
+	start_byte |= 2;
+
+    for (i = 0; i < 10; i++)
+	if (eeprom_start(start_byte))
+	    break;
+
+    if (i == 10) {
+	diag_printf("eeprom_write: Can't get start ACK\n");
+	return;
+    }
+
+    if (!eeprom_putb(addr & 0xff)) {
+	diag_printf("eeprom_write: Can't get address ACK\n");
+	return;
+    }
+
+    if (!eeprom_putb(val)) {
+	diag_printf("eeprom_write: no data ACK\n");
+	return;
+    }
+    eeprom_stop();
+}
+
+
+#define MAC_EEPROM_OFFSET(p)  (0x100 + ((p) * 6))
+
+int
+cyghal_get_npe_esa(int port, cyg_uint8 *buf)
+{
+    if (port != 0 && port != 1)
+	return 0;
+
+    if (eeprom_read(MAC_EEPROM_OFFSET(port), buf, 6) != 6)
+	return 0;
+
+    // don't use broadcast address
+    if (buf[0] == 0xff && buf[1] == 0xff && buf[2] == 0xff &&
+        buf[3] == 0xff && buf[4] == 0xff && buf[5] == 0xff)
+	return 0;
+
+    return 1;
+}
+
+
+#ifdef CYGPKG_REDBOOT
+#include <redboot.h>
+
+static void
+do_set_npe_mac(int argc, char *argv[])
+{
+    bool portnum_set;
+    int  portnum, i;
+    char *addr = 0;
+    struct option_info opts[1];
+    cyg_uint8  mac[6];
+    
+    init_opts(&opts[0], 'p', true, OPTION_ARG_TYPE_NUM, 
+              (void **)&portnum, (bool *)&portnum_set, "port number");
+    if (!scan_opts(argc, argv, 1, opts, 1, (void *)&addr,
+		   OPTION_ARG_TYPE_STR, "MAC address")) {
+        return;
+    }
+
+    if ((!portnum_set && addr) ||
+	(portnum_set && portnum != 0 && portnum != 1)) {
+	diag_printf("Must specify port with \"-p <0|1>\"\n");
+	return;
+    }
+
+    if (!portnum_set) {
+	for (i = 0; i < 2; i++) {
+	    cyghal_get_npe_esa(i, mac);
+	    diag_printf("NPE eth%d mac: %02x:%02x:%02x:%02x:%02x:%02x\n",
+			i, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+	}
+	return;
+    }
+
+    if (!addr) {
+	cyghal_get_npe_esa(portnum, mac);
+	diag_printf("NPE eth%d mac: %02x:%02x:%02x:%02x:%02x:%02x\n",
+		    portnum, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+	return;
+    }
+
+    // parse MAC address from user.
+    // acceptable formats are "nn:nn:nn:nn:nn:nn" and "nnnnnnnnnnnn"
+    for (i = 0; i < 6; i++) {
+	if (!_is_hex(addr[0]) || !_is_hex(addr[1]))
+	    break;
+	mac[i] = (_from_hex(addr[0]) * 16) + _from_hex(addr[1]);
+	addr += 2;
+	if (*addr == ':')
+	    addr++;
+    }
+    
+    if (i != 6 || *addr != '\0') {
+	diag_printf("Malformed MAC address.\n");
+	return;
+    }
+
+    for (i = 0; i < 6; i++) {
+	eeprom_write(MAC_EEPROM_OFFSET(portnum) + i, mac[i]);
+	hal_delay_us(100000);
+    }
+}
+
+RedBoot_cmd("set_npe_mac", 
+            "Set/Read MAC address for NPE ethernet ports", 
+            "[-p <portnum>] [xx:xx:xx:xx:xx:xx]",
+            do_set_npe_mac);
+
+#endif // CYGPKG_REDBOOT
+
+#endif // CYGPKG_DEVS_ETH_INTEL_NPE
+
 // ------------------------------------------------------------------------
 // EOF ixdp425_misc.c