Skip to content
Snippets Groups Projects
Commit a06752e3 authored by Wolfgang Denk's avatar Wolfgang Denk
Browse files

* Patch by Sean Chang, 9 Aug 2004:

  - Added I2C support for ML300.
  - Added support for ML300 to read out its environment information
    stored on the EEPROM.
  - Added support to use board specific parameters as part of
    U-Boot's environment information.
  - Updated MLD files to support configuration for new features
    above.

* Patches by Travis Sawyer, 5 Aug 2004:
  - Remove incorrect bridge settings for eth group 6
  - Add call to setup bridge in ppc_440x_eth_initialize
  - Fix ppc_440x_eth_init to reset the phy only if its the
    first time through, otherwise, just check the phy for the
    autonegotiated speed/duplex.  This allows the use of netconsole
  - only print the speed/duplex the first time the phy is reset.
parent da93ed81
No related branches found
No related tags found
No related merge requests found
Showing
with 1719 additions and 158 deletions
...@@ -2,6 +2,23 @@ ...@@ -2,6 +2,23 @@
Changes since U-Boot 1.1.1: Changes since U-Boot 1.1.1:
====================================================================== ======================================================================
* Patch by Sean Chang, 9 Aug 2004:
- Added I2C support for ML300.
- Added support for ML300 to read out its environment information
stored on the EEPROM.
- Added support to use board specific parameters as part of
U-Boot's environment information.
- Updated MLD files to support configuration for new features
above.
* Patches by Travis Sawyer, 5 Aug 2004:
- Remove incorrect bridge settings for eth group 6
- Add call to setup bridge in ppc_440x_eth_initialize
- Fix ppc_440x_eth_init to reset the phy only if its the
first time through, otherwise, just check the phy for the
autonegotiated speed/duplex. This allows the use of netconsole
- only print the speed/duplex the first time the phy is reset.
* Patch by Shlomo Kut, 29 Mar 2004: * Patch by Shlomo Kut, 29 Mar 2004:
Add support for MKS Instruments "Quantum" board Add support for MKS Instruments "Quantum" board
......
/* $Id: xipif_v1_23_b.c,v 1.1 2002/03/18 23:24:52 linnj Exp $ */
/******************************************************************************
*
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
* AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
* SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE,
* OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
* APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
* THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
* AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
* FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY
* WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
* IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
* REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
* INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* (c) Copyright 2002 Xilinx Inc.
* All rights reserved.
*
******************************************************************************/
/******************************************************************************
*
* FILENAME:
*
* xipif.c
*
* DESCRIPTION:
*
* This file contains the implementation of the XIpIf component. The
* XIpIf component encapsulates the IPIF, which is the standard interface
* that IP must adhere to when connecting to a bus. The purpose of this
* component is to encapsulate the IPIF processing such that maintainability
* is increased. This component does not provide a lot of abstraction from
* from the details of the IPIF as it is considered a building block for
* device drivers. A device driver designer must be familiar with the
* details of the IPIF hardware to use this component.
*
* The IPIF hardware provides a building block for all hardware devices such
* that each device does not need to reimplement these building blocks. The
* IPIF contains other building blocks, such as FIFOs and DMA channels, which
* are also common to many devices. These blocks are implemented as separate
* hardware blocks and instantiated within the IPIF. The primary hardware of
* the IPIF which is implemented by this software component is the interrupt
* architecture. Since there are many blocks of a device which may generate
* interrupts, all the interrupt processing is contained in the common part
* of the device, the IPIF. This interrupt processing is for the device level
* only and does not include any processing for the interrupt controller.
*
* A device is a mechanism such as an Ethernet MAC. The device is made
* up of several parts which include an IPIF and the IP. The IPIF contains most
* of the device infrastructure which is common to all devices, such as
* interrupt processing, DMA channels, and FIFOs. The infrastructure may also
* be referred to as IPIF internal blocks since they are part of the IPIF and
* are separate blocks that can be selected based upon the needs of the device.
* The IP of the device is the logic that is unique to the device and interfaces
* to the IPIF of the device.
*
* In general, there are two levels of registers within the IPIF. The first
* level, referred to as the device level, contains registers which are for the
* entire device. The second level, referred to as the IP level, contains
* registers which are specific to the IP of the device. The two levels of
* registers are designed to be hierarchical such that the device level is
* is a more general register set above the more specific registers of the IP.
* The IP level of registers provides functionality which is typically common
* across all devices and allows IP designers to focus on the unique aspects
* of the IP.
*
* The interrupt registers of the IPIF are parameterizable such that the only
* the number of bits necessary for the device are implemented. The functions
* of this component do not attempt to validate that the passed in arguments are
* valid based upon the number of implemented bits. This is necessary to
* maintain the level of performance required for the common components. Bits
* of the registers are assigned starting at the least significant bit of the
* registers.
*
* Critical Sections
*
* It is the responsibility of the device driver designer to use critical
* sections as necessary when calling functions of the IPIF. This component
* does not use critical sections and it does access registers using
* read-modify-write operations. Calls to IPIF functions from a main thread
* and from an interrupt context could produce unpredictable behavior such that
* the caller must provide the appropriate critical sections.
*
* Mutual Exclusion
*
* The functions of the IPIF are not thread safe such that the caller of all
* functions is responsible for ensuring mutual exclusion for an IPIF. Mutual
* exclusion across multiple IPIF components is not necessary.
*
* NOTES:
*
* None.
*
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.23b jhl 02/27/01 Repartioned to reduce size
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xipif_v1_23_b.h"
#include "xio.h"
/************************** Constant Definitions *****************************/
/* the following constant is used to generate bit masks for register testing
* in the self test functions, it defines the starting bit mask that is to be
* shifted from the LSB to MSB in creating a register test mask
*/
#define XIIF_V123B_FIRST_BIT_MASK 1UL
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Variable Definitions *****************************/
/************************** Function Prototypes ******************************/
static XStatus IpIntrSelfTest(u32 RegBaseAddress, u32 IpRegistersWidth);
/******************************************************************************
*
* FUNCTION:
*
* XIpIf_SelfTest
*
* DESCRIPTION:
*
* This function performs a self test on the specified IPIF component. Many
* of the registers in the IPIF are tested to ensure proper operation. This
* function is destructive because the IPIF is reset at the start of the test
* and at the end of the test to ensure predictable results. The IPIF reset
* also resets the entire device that uses the IPIF. This function exits with
* all interrupts for the device disabled.
*
* ARGUMENTS:
*
* InstancePtr points to the XIpIf to operate on.
*
* DeviceRegistersWidth contains the number of bits in the device interrupt
* registers. The hardware is parameterizable such that only the number of bits
* necessary to support a device are implemented. This value must be between 0
* and 32 with 0 indicating there are no device interrupt registers used.
*
* IpRegistersWidth contains the number of bits in the IP interrupt registers
* of the device. The hardware is parameterizable such that only the number of
* bits necessary to support a device are implemented. This value must be
* between 0 and 32 with 0 indicating there are no IP interrupt registers used.
*
* RETURN VALUE:
*
* A value of XST_SUCCESS indicates the test was successful with no errors.
* Any one of the following error values may also be returned.
*
* XST_IPIF_RESET_REGISTER_ERROR The value of a register at reset was
* not valid
* XST_IPIF_IP_STATUS_ERROR A write to the IP interrupt status
* register did not read back correctly
* XST_IPIF_IP_ACK_ERROR One or more bits in the IP interrupt
* status register did not reset when acked
* XST_IPIF_IP_ENABLE_ERROR The IP interrupt enable register
* did not read back correctly based upon
* what was written to it
*
* NOTES:
*
* None.
*
******************************************************************************/
/* the following constant defines the maximum number of bits which may be
* used in the registers at the device and IP levels, this is based upon the
* number of bits available in the registers
*/
#define XIIF_V123B_MAX_REG_BIT_COUNT 32
XStatus
XIpIfV123b_SelfTest(u32 RegBaseAddress, u8 IpRegistersWidth)
{
XStatus Status;
/* assert to verify arguments are valid */
XASSERT_NONVOID(IpRegistersWidth <= XIIF_V123B_MAX_REG_BIT_COUNT);
/* reset the IPIF such that it's in a known state before the test
* and interrupts are globally disabled
*/
XIIF_V123B_RESET(RegBaseAddress);
/* perform the self test on the IP interrupt registers, if
* it is not successful exit with the status
*/
Status = IpIntrSelfTest(RegBaseAddress, IpRegistersWidth);
if (Status != XST_SUCCESS) {
return Status;
}
/* reset the IPIF such that it's in a known state before exiting test */
XIIF_V123B_RESET(RegBaseAddress);
/* reaching this point means there were no errors, return success */
return XST_SUCCESS;
}
/******************************************************************************
*
* FUNCTION:
*
* IpIntrSelfTest
*
* DESCRIPTION:
*
* Perform a self test on the IP interrupt registers of the IPIF. This
* function modifies registers of the IPIF such that they are not guaranteed
* to be in the same state when it returns. Any bits in the IP interrupt
* status register which are set are assumed to be set by default after a reset
* and are not tested in the test.
*
* ARGUMENTS:
*
* InstancePtr points to the XIpIf to operate on.
*
* IpRegistersWidth contains the number of bits in the IP interrupt registers
* of the device. The hardware is parameterizable such that only the number of
* bits necessary to support a device are implemented. This value must be
* between 0 and 32 with 0 indicating there are no IP interrupt registers used.
*
* RETURN VALUE:
*
* A status indicating XST_SUCCESS if the test was successful. Otherwise, one
* of the following values is returned.
*
* XST_IPIF_RESET_REGISTER_ERROR The value of a register at reset was
* not valid
* XST_IPIF_IP_STATUS_ERROR A write to the IP interrupt status
* register did not read back correctly
* XST_IPIF_IP_ACK_ERROR One or more bits in the IP status
* register did not reset when acked
* XST_IPIF_IP_ENABLE_ERROR The IP interrupt enable register
* did not read back correctly based upon
* what was written to it
* NOTES:
*
* None.
*
******************************************************************************/
static XStatus
IpIntrSelfTest(u32 RegBaseAddress, u32 IpRegistersWidth)
{
/* ensure that the IP interrupt interrupt enable register is zero
* as it should be at reset, the interrupt status is dependent upon the
* IP such that it's reset value is not known
*/
if (XIIF_V123B_READ_IIER(RegBaseAddress) != 0) {
return XST_IPIF_RESET_REGISTER_ERROR;
}
/* if there are any used IP interrupts, then test all of the interrupt
* bits in all testable registers
*/
if (IpRegistersWidth > 0) {
u32 BitCount;
u32 IpInterruptMask = XIIF_V123B_FIRST_BIT_MASK;
u32 Mask = XIIF_V123B_FIRST_BIT_MASK; /* bits assigned MSB to LSB */
u32 InterruptStatus;
/* generate the register masks to be used for IP register tests, the
* number of bits supported by the hardware is parameterizable such
* that only that number of bits are implemented in the registers, the
* bits are allocated starting at the MSB of the registers
*/
for (BitCount = 1; BitCount < IpRegistersWidth; BitCount++) {
Mask = Mask << 1;
IpInterruptMask |= Mask;
}
/* get the current IP interrupt status register contents, any bits
* already set must default to 1 at reset in the device and these
* bits can't be tested in the following test, remove these bits from
* the mask that was generated for the test
*/
InterruptStatus = XIIF_V123B_READ_IISR(RegBaseAddress);
IpInterruptMask &= ~InterruptStatus;
/* set the bits in the device status register and verify them by reading
* the register again, all bits of the register are latched
*/
XIIF_V123B_WRITE_IISR(RegBaseAddress, IpInterruptMask);
InterruptStatus = XIIF_V123B_READ_IISR(RegBaseAddress);
if ((InterruptStatus & IpInterruptMask) != IpInterruptMask)
{
return XST_IPIF_IP_STATUS_ERROR;
}
/* test to ensure that the bits set in the IP interrupt status register
* can be cleared by acknowledging them in the IP interrupt status
* register then read it again and verify it was cleared
*/
XIIF_V123B_WRITE_IISR(RegBaseAddress, IpInterruptMask);
InterruptStatus = XIIF_V123B_READ_IISR(RegBaseAddress);
if ((InterruptStatus & IpInterruptMask) != 0) {
return XST_IPIF_IP_ACK_ERROR;
}
/* set the IP interrupt enable set register and then read the IP
* interrupt enable register and verify the interrupts were enabled
*/
XIIF_V123B_WRITE_IIER(RegBaseAddress, IpInterruptMask);
if (XIIF_V123B_READ_IIER(RegBaseAddress) != IpInterruptMask) {
return XST_IPIF_IP_ENABLE_ERROR;
}
/* clear the IP interrupt enable register and then read the
* IP interrupt enable register and verify the interrupts were disabled
*/
XIIF_V123B_WRITE_IIER(RegBaseAddress, 0);
if (XIIF_V123B_READ_IIER(RegBaseAddress) != 0) {
return XST_IPIF_IP_ENABLE_ERROR;
}
}
return XST_SUCCESS;
}
/* $Id: xipif_v1_23_b.h,v 1.1 2002/03/18 23:24:52 linnj Exp $ */
/****************************************************************************** /******************************************************************************
* *
* Author: Xilinx, Inc. * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
* * AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
* * SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE,
* This program is free software; you can redistribute it and/or modify it * OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
* under the terms of the GNU General Public License as published by the * APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
* Free Software Foundation; either version 2 of the License, or (at your * THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
* option) any later version. * AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
* * FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY
* * WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A * IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS * REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD, * INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE * FOR A PARTICULAR PURPOSE.
* FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING *
* ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION. * (c) Copyright 2002 Xilinx Inc.
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO * All rights reserved.
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
* WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
* CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE.
*
*
* Xilinx hardware products are not intended for use in life support
* appliances, devices, or systems. Use in such applications is
* expressly prohibited.
*
*
* (c) Copyright 2002-2004 Xilinx Inc.
* All rights reserved.
*
*
* 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.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
* *
******************************************************************************/ ******************************************************************************/
/****************************************************************************** /******************************************************************************
...@@ -575,7 +558,7 @@ ...@@ -575,7 +558,7 @@
* *
* RETURN VALUE: * RETURN VALUE:
* *
* TRUE if interrupts are enabled for the IPIF, FALSE otherwise. * XTRUE if interrupts are enabled for the IPIF, XFALSE otherwise.
* *
* NOTES: * NOTES:
* *
......
...@@ -19,22 +19,23 @@ ...@@ -19,22 +19,23 @@
# along with this program; if not, write to the Free Software # along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, # Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA # MA 02111-1307 USA
#
include $(TOPDIR)/config.mk include $(TOPDIR)/config.mk
CFLAGS += -I../ml300 -I../common -I../xilinx_enet CFLAGS += -I../ml300 -I../common -I../xilinx_enet -I../xilinx_iic
LIB = lib$(BOARD).a LIB = lib$(BOARD).a
OBJS = $(BOARD).o serial.o \ OBJS = $(BOARD).o \
../xilinx_enet/emac_adapter.o ../xilinx_enet/xemac.o \ serial.o \
../xilinx_enet/emac_adapter.o ../xilinx_enet/xemac.o \
../xilinx_enet/xemac_options.o ../xilinx_enet/xemac_polled.o \ ../xilinx_enet/xemac_options.o ../xilinx_enet/xemac_polled.o \
../xilinx_enet/xemac_intr.o ../xilinx_enet/xemac_g.o \ ../xilinx_enet/xemac_intr.o ../xilinx_enet/xemac_g.o \
../xilinx_enet/xemac_intr_dma.o \ ../xilinx_enet/xemac_intr_dma.o ../xilinx_iic/iic_adapter.o \
../xilinx_iic/xiic_l.o ../common/xipif_v1_23_b.o \
../common/xbasic_types.o ../common/xdma_channel.o \ ../common/xbasic_types.o ../common/xdma_channel.o \
../common/xdma_channel_sg.o ../common/xpacket_fifo_v1_00_b.o \ ../common/xdma_channel_sg.o ../common/xpacket_fifo_v1_00_b.o \
../common/xversion.o ../common/xversion.o \
SOBJS = init.o SOBJS = init.o
......
...@@ -42,6 +42,10 @@ ...@@ -42,6 +42,10 @@
#include <asm/processor.h> #include <asm/processor.h>
#include "xparameters.h" #include "xparameters.h"
#ifdef CFG_ENV_IS_IN_EEPROM
extern void convert_env(void);
#endif
int int
board_pre_init(void) board_pre_init(void)
{ {
...@@ -51,22 +55,25 @@ board_pre_init(void) ...@@ -51,22 +55,25 @@ board_pre_init(void)
int int
checkboard(void) checkboard(void)
{ {
unsigned char *s = getenv("serial#"); uchar tmp[64]; /* long enough for environment variables */
unsigned char *e; uchar *s, *e;
int i = getenv_r("L", tmp, sizeof (tmp));
if (!s || strncmp(s, "ML300", 9)) { if (i < 0) {
printf("### No HW ID - assuming ML300"); printf("### No HW ID - assuming ML300");
} else { } else {
for (e = s; *e; ++e) { for (e = tmp; *e; ++e) {
if (*e == ' ') if (*e == ' ')
break; break;
} }
for (; s < e; ++s) { printf("### Board Serial# is ");
for (s = tmp; s < e; ++s) {
putc(*s); putc(*s);
} }
}
}
putc('\n'); putc('\n');
return (0); return (0);
...@@ -107,3 +114,15 @@ get_PCI_freq(void) ...@@ -107,3 +114,15 @@ get_PCI_freq(void)
val = sys_info.freqPCI; val = sys_info.freqPCI;
return val; return val;
} }
#ifdef CONFIG_MISC_INIT_R
int
misc_init_r()
{
/* convert env name and value to u-boot standard */
convert_env();
return 0;
}
#endif
#!/bin/bash #!/bin/bash
if[$ if [ $# -ne 1 ]
# -ne 1 ] then
then echo "usage: Ltypes filename" > &2 exit 2 fi FILE = "$1" echo "usage: Ltypes filename" >&2
exit 2
fi
FILE="$1"
#TMPFILE='mktemp "${FILE}.XXXXXX"' || exit 1 #TMPFILE='mktemp "${FILE}.XXXXXX"' || exit 1
TMPFILE = $ { TMPFILE=${FILE}.`date "+%s"`
FILE} touch $TMPFILE || exit 1
. ` date "+%s" ` touch $TMPFILE || exit 1
# Change all the Xilinx types to Linux types and put the result into a temp file # Change all the Xilinx types to Linux types and put the result into a temp file
sed sed \
- e 's/\bXTRUE\b/TRUE/g' -e 's/\bXTRUE\b/TRUE/g' \
- e 's/\bXFALSE\b/FALSE/g' -e 's/\bXFALSE\b/FALSE/g' \
- e 's/\bXNULL\b/NULL/g' -e 's/\bXNULL\b/NULL/g' \
- e 's/<asm/delay.h>/<asm\/delay.h>/g' -e 's/"xenv.h"/<asm\/delay.h>/g' \
- e 's/\bXENV_USLEEP\b/udelay/g' -e 's/\bXENV_USLEEP\b/udelay/g' \
- e 's/\bXuint8\b/u8/g' -e 's/\bXuint8\b/u8/g' \
- e 's/\bXuint16\b/u16/g' -e 's/\bXuint16\b/u16/g' \
- e 's/\bXuint32\b/u32/g' -e 's/\bXuint32\b/u32/g' \
- e 's/\bXint8\b/s8/g' -e 's/\bXint8\b/s8/g' \
- e 's/\bXint16\b/s16/g' -e 's/\bXint16\b/s16/g' \
- e 's/\bXint32\b/s32/g' - e 's/\bXboolean\b/u32/g' "${FILE}" > "${TMPFILE}" -e 's/\bXint32\b/s32/g' \
-e 's/\bXboolean\b/u32/g' \
"${FILE}" > "${TMPFILE}"
# Overlay the original file with the temp file # Overlay the original file with the temp file
mv "${TMPFILE}" "${FILE}" mv "${TMPFILE}" "${FILE}"
# Are we doing xbasic_types.h? # Are we doing xbasic_types.h?
if["${FILE##*/}" = xbasic_types.h] if [ "${FILE##*/}" = xbasic_types.h ]
then then
# Remember as you're reading this that we've already gone through the prior # Remember as you're reading this that we've already gone through the prior
# sed script. We need to do some other things to xbasic_types.h: # sed script. We need to do some other things to xbasic_types.h:
# 1) Add ifndefs around TRUE and FALSE defines # 1) Add ifndefs around TRUE and FALSE defines
# 2) Remove definition of NULL as NULL # 2) Remove definition of NULL as NULL
# 3) Replace most of the primitive types section with a #include # 3) Replace most of the primitive types section with a #include
sed - e '/u32 true/,/#define false/Ic\ sed \
-e '/u32 true/,/#define false/Ic\
#ifndef TRUE\ #ifndef TRUE\
#define TRUE 1\ #define TRUE 1\
#endif\ #endif\
#ifndef FALSE\ #ifndef FALSE\
#define FALSE 0\ #define FALSE 0\
#endif' - e '/#define[[:space:]][[:space:]]*NULL[[:space:]][[:space:]]*NULL/d' - e '/typedef[[:space:]][[:space:]]*unsigned[[:space:]][[:space:]]*char[[:space:]][[:space:]]*u8/,/typedef[[:space:]][[:space:]]*unsigned[[:space:]][[:space:]]*long[[:space:]][[:space:]]*u32.*boolean/c\ #endif' \
#include <linux/types.h>' "${FILE}" > "${TMPFILE}" mv "${TMPFILE}" "${FILE}" fi -e '/#define[[:space:]][[:space:]]*NULL[[:space:]][[:space:]]*NULL/d' \
-e '/typedef[[:space:]][[:space:]]*unsigned[[:space:]][[:space:]]*char[[:space:]][[:space:]]*u8/,/typedef[[:space:]][[:space:]]*unsigned[[:space:]][[:space:]]*long[[:space:]][[:space:]]*u32.*boolean/c\
#include <linux/types.h>' \
"${FILE}" > "${TMPFILE}"
mv "${TMPFILE}" "${FILE}"
fi
...@@ -42,7 +42,11 @@ BEGIN ARRAY connected_periphs PROPERTY desc = "Peripherals connected to U-Boot"; ...@@ -42,7 +42,11 @@ BEGIN ARRAY connected_periphs PROPERTY desc = "Peripherals connected to U-Boot";
PROPERTY size = 0; PROPERTY size = 0;
PARAM name = periph_name, desc = "Name of Peripheral connected", type = string; PARAM name = periph_name, desc = "Name of Peripheral connected", type = string;
END ARRAY END ARRAY
PARAMETER name = TARGET_DIR, desc = PARAMETER name = TARGET_DIR, desc = "Target Directory for U-Boot BSP", type = string;
"Target Directory for U-Boot BSP", type = string;
# location of persistent storage in the IIC EEPROM (defaults are set for ML300)
PARAMETER name = IIC_PERSISTENT_BASEADDR, desc = "Start of persistent storage block in the EEPROM address space", type = int, default = 1024;
PARAMETER name = IIC_PERSISTENT_HIGHADDR, desc = "End of persistent storage block in the EEPROM address space", type = int, default = 2047;
PARAMETER name = IIC_PERSISTENT_EEPROMADDR, desc = "Address of the EEPROM on the IIC bus", type = int, default = 0xA0;
END LIBRARY END LIBRARY
...@@ -76,12 +76,18 @@ proc generate {libname} { ...@@ -76,12 +76,18 @@ proc generate {libname} {
xredefine_uartns550 $drv "xparameters.h" xredefine_uartns550 $drv "xparameters.h"
} elseif {[string compare -nocase $drvname "emac"] == 0} { } elseif {[string compare -nocase $drvname "emac"] == 0} {
xredefine_emac $drv "xparameters.h" xredefine_emac $drv "xparameters.h"
} elseif {[string compare -nocase $drvname "iic"] == 0} {
xredefine_iic $drv "xparameters.h"
} }
} }
} }
# define core_clock # define core_clock
xredefine_params $libname "xparameters.h" "CORE_CLOCK_FREQ_HZ" xredefine_params $libname "xparameters.h" "CORE_CLOCK_FREQ_HZ"
# define the values for the persistent storage in IIC
xredefine_params $libname "xparameters.h" "IIC_PERSISTENT_BASEADDR" "IIC_PERSISTENT_HIGHADDR" "IIC_PERSISTENT_EEPROMADDR"
} }
proc xget_corefreq {} { proc xget_corefreq {} {
...@@ -117,7 +123,16 @@ proc xredefine_params {handle file_name args} { ...@@ -117,7 +123,16 @@ proc xredefine_params {handle file_name args} {
if {$value != ""} { if {$value != ""} {
set value [xformat_addr_string $value $arg] set value [xformat_addr_string $value $arg]
set name [string toupper $arg]
if {[string compare -nocase $arg "IIC_PERSISTENT_BASEADDR"] == 0} {
set name "PERSISTENT_0_IIC_0_BASEADDR"
} elseif {[string compare -nocase $arg "IIC_PERSISTENT_HIGHADDR"] == 0} {
set name "PERSISTENT_0_IIC_0_HIGHADDR"
} elseif {[string compare -nocase $arg "IIC_PERSISTENT_EEPROMADDR"] == 0} {
set name "PERSISTENT_0_IIC_0_EEPROMADDR"
} else {
set name [string toupper $arg]
}
set name [format "XPAR_%s" $name] set name [format "XPAR_%s" $name]
puts $file_handle "#define $name $value" puts $file_handle "#define $name $value"
} }
...@@ -140,6 +155,11 @@ proc xredefine_emac {drvhandle file_name} { ...@@ -140,6 +155,11 @@ proc xredefine_emac {drvhandle file_name} {
} }
proc xredefine_iic {drvhandle file_name} {
xredefine_include_file $drvhandle $file_name "iic" "C_BASEADDR" "C_HIGHADDR" "C_TEN_BIT_ADR" "DEVICE_ID"
}
####################### #######################
proc xredefine_include_file {drv_handle file_name drv_string args} { proc xredefine_include_file {drv_handle file_name drv_string args} {
...@@ -221,6 +241,8 @@ proc post_generate {lib_handle} { ...@@ -221,6 +241,8 @@ proc post_generate {lib_handle} {
if {[string compare -nocase $drvname "emac"] == 0} { if {[string compare -nocase $drvname "emac"] == 0} {
xcopy_emac $drv $dirname xcopy_emac $drv $dirname
} elseif {[string compare -nocase $drvname "iic"] == 0} {
xcopy_iic $drv $dirname
} }
} }
...@@ -267,6 +289,11 @@ proc xcopy_emac {drv_handle dirname} { ...@@ -267,6 +289,11 @@ proc xcopy_emac {drv_handle dirname} {
xcopy_dir $dirname $emac xcopy_dir $dirname $emac
} }
proc xcopy_iic {drv_handle dirname} {
set iic "board/xilinx/xilinx_iic"
xcopy_dir $dirname $iic
}
proc xcopy_dir {srcdir dstdir} { proc xcopy_dir {srcdir dstdir} {
set dstdirname [format "%s%s" "uboot/" $dstdir] set dstdirname [format "%s%s" "uboot/" $dstdir]
......
/******************************************************************* /*******************************************************************
* *
* CAUTION: This file is automatically generated by libgen. * CAUTION: This file is automatically generated by libgen.
* Version: Xilinx EDK 6.1.2 EDK_G.14 * Version: Xilinx EDK 6.2 EDK_Gm.11
* DO NOT EDIT. * DO NOT EDIT.
* *
* Author: Xilinx, Inc. * Copyright (c) 2003 Xilinx, Inc. All rights reserved.
*
*
* 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.
*
*
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
* XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
* FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
* ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
* WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
* CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE.
*
*
* Xilinx hardware products are not intended for use in life support
* appliances, devices, or systems. Use in such applications is
* expressly prohibited.
*
*
* (c) Copyright 2002-2004 Xilinx Inc.
* All rights reserved.
*
*
* 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.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
* *
* Description: Driver parameters * Description: Driver parameters
* *
*******************************************************************/ *******************************************************************/
/******************************************************************/
/* U-Boot Redefines */
/******************************************************************/
#define XPAR_UARTNS550_0_BASEADDR (XPAR_OPB_UART16550_0_BASEADDR+0x1000)
#define XPAR_UARTNS550_0_HIGHADDR XPAR_OPB_UART16550_0_HIGHADDR
#define XPAR_UARTNS550_0_CLOCK_FREQ_HZ XPAR_XUARTNS550_CLOCK_HZ
#define XPAR_UARTNS550_0_DEVICE_ID XPAR_OPB_UART16550_0_DEVICE_ID
#define XPAR_UARTNS550_1_BASEADDR (XPAR_OPB_UART16550_1_BASEADDR+0x1000)
#define XPAR_UARTNS550_1_HIGHADDR XPAR_OPB_UART16550_1_HIGHADDR
#define XPAR_UARTNS550_1_CLOCK_FREQ_HZ XPAR_XUARTNS550_CLOCK_HZ
#define XPAR_UARTNS550_1_DEVICE_ID XPAR_OPB_UART16550_1_DEVICE_ID
/******************************************************************/
#define XPAR_IIC_0_BASEADDR XPAR_OPB_IIC_0_BASEADDR
#define XPAR_IIC_0_HIGHADDR XPAR_OPB_IIC_0_HIGHADDR
#define XPAR_IIC_0_TEN_BIT_ADR XPAR_OPB_IIC_0_TEN_BIT_ADR
#define XPAR_IIC_0_DEVICE_ID XPAR_OPB_IIC_0_DEVICE_ID
/******************************************************************/
#define XPAR_EMAC_0_BASEADDR XPAR_OPB_ETHERNET_0_BASEADDR
#define XPAR_EMAC_0_HIGHADDR XPAR_OPB_ETHERNET_0_HIGHADDR
#define XPAR_EMAC_0_DMA_PRESENT XPAR_OPB_ETHERNET_0_DMA_PRESENT
#define XPAR_EMAC_0_MII_EXIST XPAR_OPB_ETHERNET_0_MII_EXIST
#define XPAR_EMAC_0_ERR_COUNT_EXIST XPAR_OPB_ETHERNET_0_ERR_COUNT_EXIST
#define XPAR_EMAC_0_DEVICE_ID XPAR_OPB_ETHERNET_0_DEVICE_ID
/******************************************************************/
#define XPAR_CORE_CLOCK_FREQ_HZ XPAR_CPU_PPC405_CORE_CLOCK_FREQ_HZ
/******************************************************************/
#define XPAR_PERSISTENT_0_IIC_0_BASEADDR 0x00000400
#define XPAR_PERSISTENT_0_IIC_0_HIGHADDR 0x000007FF
#define XPAR_PERSISTENT_0_IIC_0_EEPROMADDR 0xA0
/******************************************************************/
#define XPAR_XPCI_NUM_INSTANCES 1 #define XPAR_XPCI_NUM_INSTANCES 1
#define XPAR_XPCI_CLOCK_HZ 33333333 #define XPAR_XPCI_CLOCK_HZ 33333333
#define XPAR_OPB_PCI_REF_0_DEVICE_ID 0 #define XPAR_OPB_PCI_REF_0_DEVICE_ID 0
...@@ -181,36 +191,6 @@ ...@@ -181,36 +191,6 @@
/******************************************************************/ /******************************************************************/
#define STDIN_BASEADDRESS 0xA0000000
#define STDOUT_BASEADDRESS 0xA0000000
#define XPAR_CPU_PPC405_CORE_CLOCK_FREQ_HZ 300000000 #define XPAR_CPU_PPC405_CORE_CLOCK_FREQ_HZ 300000000
/******************************************************************/ /******************************************************************/
/* U-Boot Redefines */
/******************************************************************/
#define XPAR_UARTNS550_0_BASEADDR (XPAR_OPB_UART16550_0_BASEADDR+0x1000)
#define XPAR_UARTNS550_0_HIGHADDR XPAR_OPB_UART16550_0_HIGHADDR
#define XPAR_UARTNS550_0_CLOCK_FREQ_HZ XPAR_XUARTNS550_CLOCK_HZ
#define XPAR_UARTNS550_0_DEVICE_ID XPAR_OPB_UART16550_0_DEVICE_ID
#define XPAR_UARTNS550_1_BASEADDR (XPAR_OPB_UART16550_1_BASEADDR+0x1000)
#define XPAR_UARTNS550_1_HIGHADDR XPAR_OPB_UART16550_1_HIGHADDR
#define XPAR_UARTNS550_1_CLOCK_FREQ_HZ XPAR_XUARTNS550_CLOCK_HZ
#define XPAR_UARTNS550_1_DEVICE_ID XPAR_OPB_UART16550_1_DEVICE_ID
/******************************************************************/
#define XPAR_EMAC_0_BASEADDR XPAR_OPB_ETHERNET_0_BASEADDR
#define XPAR_EMAC_0_HIGHADDR XPAR_OPB_ETHERNET_0_HIGHADDR
#define XPAR_EMAC_0_DMA_PRESENT XPAR_OPB_ETHERNET_0_DMA_PRESENT
#define XPAR_EMAC_0_MII_EXIST XPAR_OPB_ETHERNET_0_MII_EXIST
#define XPAR_EMAC_0_ERR_COUNT_EXIST XPAR_OPB_ETHERNET_0_ERR_COUNT_EXIST
#define XPAR_EMAC_0_DEVICE_ID XPAR_OPB_ETHERNET_0_DEVICE_ID
/******************************************************************/
#define XPAR_CORE_CLOCK_FREQ_HZ XPAR_CPU_PPC405_CORE_CLOCK_FREQ_HZ
/******************************************************************/
...@@ -56,8 +56,10 @@ ...@@ -56,8 +56,10 @@
static XEmac Emac; static XEmac Emac;
static char etherrxbuff[PKTSIZE_ALIGN]; /* Receive buffer */ static char etherrxbuff[PKTSIZE_ALIGN]; /* Receive buffer */
/* hardcoded MAC address for the Xilinx EMAC Core */ /* hardcoded MAC address for the Xilinx EMAC Core when env is nowhere*/
#ifdef CFG_ENV_IS_NOWHERE
static u8 EMACAddr[ENET_ADDR_LENGTH] = { 0x00, 0x0a, 0x35, 0x00, 0x22, 0x01 }; static u8 EMACAddr[ENET_ADDR_LENGTH] = { 0x00, 0x0a, 0x35, 0x00, 0x22, 0x01 };
#endif
static int initialized = 0; static int initialized = 0;
...@@ -86,8 +88,11 @@ eth_init(bd_t * bis) ...@@ -86,8 +88,11 @@ eth_init(bd_t * bis)
/* make sure the Emac is stopped before it is started */ /* make sure the Emac is stopped before it is started */
(void) XEmac_Stop(&Emac); (void) XEmac_Stop(&Emac);
#ifdef CFG_ENV_IS_NOWHERE
memcpy(bis->bi_enetaddr, EMACAddr, 6); memcpy(bis->bi_enetaddr, EMACAddr, 6);
Result = XEmac_SetMacAddress(&Emac, EMACAddr); #endif
Result = XEmac_SetMacAddress(&Emac, bis->bi_enetaddr);
if (Result != XST_SUCCESS) { if (Result != XST_SUCCESS) {
return 0; return 0;
} }
......
/******************************************************************************
*
* Author: Xilinx, Inc.
*
*
* 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.
*
*
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
* XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
* FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
* ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
* WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
* CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE.
*
*
* Xilinx hardware products are not intended for use in life support
* appliances, devices, or systems. Use in such applications is
* expressly prohibited.
*
*
* (c) Copyright 2002-2004 Xilinx Inc.
* All rights reserved.
*
*
* 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.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*
******************************************************************************/
#include <common.h>
#include <environment.h>
#include <net.h>
#include <configs/ml300.h>
#include "xparameters.h"
#ifdef CFG_ENV_IS_IN_EEPROM
#include <i2c.h>
#include "xiic_l.h"
#define IIC_DELAY 5000
static u8 envStep = 0; /* 0 means crc has not been read */
const u8 hex[] = "0123456789ABCDEF"; /* lookup table for ML300 CRC */
/************************************************************************
* Use Xilinx provided driver to send data to EEPROM using iic bus.
*/
static void
send(u32 adr, u8 * data, u32 len)
{
u8 sendBuf[34]; /* first 2-bit is address and others are data */
u32 pos, wlen;
u32 ret;
wlen = 32;
for (pos = 0; pos < len; pos += 32) {
if ((len - pos) < 32)
wlen = len - pos;
/* Put address and data bits together */
sendBuf[0] = (u8) ((adr + pos) >> 8);
sendBuf[1] = (u8) (adr + pos);
memcpy(&sendBuf[2], &data[pos], wlen);
/* Send to EEPROM through iic bus */
ret = XIic_Send(XPAR_IIC_0_BASEADDR, CFG_I2C_EEPROM_ADDR >> 1,
sendBuf, wlen + 2);
udelay(IIC_DELAY);
}
}
/************************************************************************
* Use Xilinx provided driver to read data from EEPROM using the iic bus.
*/
static void
receive(u32 adr, u8 * data, u32 len)
{
u8 address[2];
u32 ret;
address[0] = (u8) (adr >> 8);
address[1] = (u8) adr;
/* Provide EEPROM address */
ret =
XIic_Send(XPAR_IIC_0_BASEADDR, CFG_I2C_EEPROM_ADDR >> 1, address,
2);
/* Receive data from EEPROM */
ret =
XIic_Recv(XPAR_IIC_0_BASEADDR, CFG_I2C_EEPROM_ADDR >> 1, data, len);
}
/************************************************************************
* Convert a hexadecimal string to its equivalent integer value.
*/
static u8
axtoi(u8 * hexStg)
{
u8 n; /* position in string */
u8 m; /* position in digit[] to shift */
u8 count; /* loop index */
u8 intValue; /* integer value of hex string */
u8 digit[2]; /* hold values to convert */
for (n = 0; n < 2; n++) {
if (hexStg[n] == '\0')
break;
if (hexStg[n] > 0x29 && hexStg[n] < 0x40)
digit[n] = hexStg[n] & 0x0f;
else if (hexStg[n] >= 'a' && hexStg[n] <= 'f')
digit[n] = (hexStg[n] & 0x0f) + 9;
else if (hexStg[n] >= 'A' && hexStg[n] <= 'F')
digit[n] = (hexStg[n] & 0x0f) + 9;
else
break;
}
intValue = 0;
count = n;
m = n - 1;
n = 0;
while (n < count) {
intValue = intValue | (digit[n] << (m << 2));
m--; /* adjust the position to set */
n++; /* next digit to process */
}
return (intValue);
}
/************************************************************************
* Convert an integer string to its equivalent value.
*/
static u8
atoi(uchar * string)
{
u8 res = 0;
while (*string >= '0' && *string <= '9') {
res *= 10;
res += *string - '0';
string++;
}
return res;
}
/************************************************************************
* Key-value pairs are separated by "=" sign.
*/
static void
findKey(uchar * buffer, int *loc, u8 len)
{
u32 i;
for (i = 0; i < len; i++)
if (buffer[i] == '=') {
*loc = i;
return;
}
/* return -1 is no "=" sign found */
*loc = -1;
}
/************************************************************************
* Compute a new ML300 CRC when user calls the saveenv command.
* Also update EEPROM with new CRC value.
*/
static u8
update_crc(u32 len, uchar * data)
{
uchar temp[6] = { 'C', '=', 0x00, 0x00, 0x00, 0x00 };
u32 crc; /* new crc value */
u32 i;
crc = 0;
/* calculate new CRC */
for (i = 0; i < len; i++)
crc += data[i];
/* CRC includes key for check sum */
crc += 'C' + '=';
/* compose new CRC to be updated */
temp[2] = hex[(crc >> 4) & 0xf];
temp[3] = hex[crc & 0xf];
/* check to see if env size exceeded */
if (len + 6 > ENV_SIZE) {
printf("ERROR: not enough space to store CRC on EEPROM");
return 1;
}
memcpy(data + len, temp, 6);
return 0;
}
/************************************************************************
* Read out ML300 CRC and compare it with a runtime calculated ML300 CRC.
* If equal, then pass back a u-boot CRC value, otherwise pass back
* junk to indicate CRC error.
*/
static void
read_crc(uchar * buffer, int len)
{
u32 addr, n;
u32 crc; /* runtime crc */
u8 old[2] = { 0xff, 0xff }; /* current CRC in EEPROM */
u8 stop; /* indication of end of env data */
u8 pre; /* previous EEPROM data bit */
int i, loc;
addr = CFG_ENV_OFFSET; /* start from first env address */
n = 0;
pre = 1;
stop = 1;
crc = 0;
/* calculate runtime CRC according to ML300 and read back
old CRC stored in the EEPROM */
while (n < CFG_ENV_SIZE) {
receive(addr, buffer, len);
/* found two null chars, end of env */
if ((pre || buffer[0]) == 0)
break;
findKey(buffer, &loc, len);
/* found old check sum, read and store old CRC */
if ((loc == 0 && pre == 'C')
|| (loc > 0 && buffer[loc - 1] == 'C'))
receive(addr + loc + 1, old, 2);
pre = buffer[len - 1];
/* calculate runtime ML300 CRC */
crc += buffer[0];
i = 1;
do {
crc += buffer[i];
stop = buffer[i] || buffer[i - 1];
i++;
} while (stop && (i < len));
if (stop == 0)
break;
n += len;
addr += len;
}
/* exclude old CRC from runtime calculation */
crc -= (old[0] + old[1]);
/* match CRC values, send back u-boot CRC */
if ((old[0] == hex[(crc >> 4) & 0xf])
&& (old[1] == hex[crc & 0xf])) {
crc = 0;
n = 0;
addr =
CFG_ENV_OFFSET - offsetof(env_t, crc) + offsetof(env_t,
data);
/* calculate u-boot crc */
while (n < ENV_SIZE) {
receive(addr, buffer, len);
crc = crc32(crc, buffer, len);
n += len;
addr += len;
}
memcpy(buffer, &crc, 4);
}
}
/************************************************************************
* Convert IP address to hexadecimals.
*/
static void
ip_ml300(uchar * s, uchar * res)
{
uchar temp[2];
u8 i;
res[0] = 0x00;
for (i = 0; i < 4; i++) {
sprintf(temp, "%02x", atoi(s));
s = strchr(s, '.') + 1;
strcat(res, temp);
}
}
/************************************************************************
* Change 0xff (255), a dummy null char to 0x00.
*/
static void
change_null(uchar * s)
{
if (s != NULL) {
change_null(strchr(s + 1, 255));
*(strchr(s, 255)) = '\0';
}
}
/************************************************************************
* Update environment variable name and values to u-boot standard.
*/
void
convert_env(void)
{
uchar *s; /* pointer to env value */
uchar temp[20]; /* temp storage for addresses */
/* E -> ethaddr */
s = getenv("E");
if (s != NULL) {
sprintf(temp, "%c%c.%c%c.%c%c.%c%c.%c%c.%c%c",
*s++, *s++, *s++, *s++, *s++, *s++,
*s++, *s++, *s++, *s++, *s++, *s);
setenv("ethaddr", temp);
setenv("E", NULL);
}
/* L -> serial# */
s = getenv("L");
if (s != NULL) {
setenv("serial#", s);
setenv("L", NULL);
}
/* I -> ipaddr */
s = getenv("I");
if (s != NULL) {
sprintf(temp, "%d.%d.%d.%d", axtoi(s), axtoi(s + 2),
axtoi(s + 4), axtoi(s + 6));
setenv("ipaddr", temp);
setenv("I", NULL);
}
/* S -> serverip */
s = getenv("S");
if (s != NULL) {
sprintf(temp, "%d.%d.%d.%d", axtoi(s), axtoi(s + 2),
axtoi(s + 4), axtoi(s + 6));
setenv("serverip", temp);
setenv("S", NULL);
}
/* A -> bootargs */
s = getenv("A");
if (s != NULL) {
setenv("bootargs", s);
setenv("A", NULL);
}
/* F -> bootfile */
s = getenv("F");
if (s != NULL) {
setenv("bootfile", s);
setenv("F", NULL);
}
/* M -> bootcmd */
s = getenv("M");
if (s != NULL) {
setenv("bootcmd", s);
setenv("M", NULL);
}
/* Don't include C (CRC) */
setenv("C", NULL);
}
/************************************************************************
* Save user modified environment values back to EEPROM.
*/
static void
save_env(void)
{
uchar eprom[ENV_SIZE]; /* buffer to be written back to EEPROM */
uchar *s, temp[20];
uchar ff[] = { 0xff, 0x00 }; /* dummy null value */
u32 len; /* length of env to be written to EEPROM */
eprom[0] = 0x00;
/* ethaddr -> E */
s = getenv("ethaddr");
if (s != NULL) {
strcat(eprom, "E=");
sprintf(temp, "%c%c%c%c%c%c%c%c%c%c%c%c",
*s, *(s + 1), *(s + 3), *(s + 4), *(s + 6), *(s + 7),
*(s + 9), *(s + 10), *(s + 12), *(s + 13), *(s + 15),
*(s + 16));
strcat(eprom, temp);
strcat(eprom, ff);
}
/* serial# -> L */
s = getenv("serial#");
if (s != NULL) {
strcat(eprom, "L=");
strcat(eprom, s);
strcat(eprom, ff);
}
/* ipaddr -> I */
s = getenv("ipaddr");
if (s != NULL) {
strcat(eprom, "I=");
ip_ml300(s, temp);
strcat(eprom, temp);
strcat(eprom, ff);
}
/* serverip -> S */
s = getenv("serverip");
if (s != NULL) {
strcat(eprom, "S=");
ip_ml300(s, temp);
strcat(eprom, temp);
strcat(eprom, ff);
}
/* bootargs -> A */
s = getenv("bootargs");
if (s != NULL) {
strcat(eprom, "A=");
strcat(eprom, s);
strcat(eprom, ff);
}
/* bootfile -> F */
s = getenv("bootfile");
if (s != NULL) {
strcat(eprom, "F=");
strcat(eprom, s);
strcat(eprom, ff);
}
/* bootcmd -> M */
s = getenv("bootcmd");
if (s != NULL) {
strcat(eprom, "M=");
strcat(eprom, s);
strcat(eprom, ff);
}
len = strlen(eprom); /* find env length without crc */
change_null(eprom); /* change 0xff to 0x00 */
/* update EEPROM env values if there is enough space */
if (update_crc(len, eprom) == 0)
send(CFG_ENV_OFFSET, eprom, len + 6);
}
/************************************************************************
* U-boot call for EEPROM read associated activities.
*/
int
i2c_read(uchar chip, uint addr, int alen, uchar * buffer, int len)
{
if (envStep == 0) {
/* first read call is for crc */
read_crc(buffer, len);
++envStep;
return 0;
} else if (envStep == 1) {
/* then read out EEPROM content for runtime u-boot CRC calculation */
receive(addr, buffer, len);
if (addr + len - CFG_ENV_OFFSET == CFG_ENV_SIZE)
/* end of runtime crc read */
++envStep;
return 0;
}
if (len < 2) {
/* when call getenv_r */
receive(addr, buffer, len);
} else if (addr + len < CFG_ENV_OFFSET + CFG_ENV_SIZE) {
/* calling env_relocate(), but don't read out
crc value from EEPROM */
receive(addr, buffer + 4, len);
} else {
receive(addr, buffer + 4, len - 4);
}
return 0;
}
/************************************************************************
* U-boot call for EEPROM write acativities.
*/
int
i2c_write(uchar chip, uint addr, int alen, uchar * buffer, int len)
{
/* save env on last page write called by u-boot */
if (addr + len >= CFG_ENV_OFFSET + CFG_ENV_SIZE)
save_env();
return 0;
}
/************************************************************************
* Dummy function.
*/
int
i2c_probe(uchar chip)
{
return 1;
}
#endif
/* $Id: xiic_l.c,v 1.2 2002/12/05 19:32:40 meinelte Exp $ */
/******************************************************************************
*
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
* AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
* SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE,
* OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
* APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
* THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
* AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
* FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY
* WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
* IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
* REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
* INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* (c) Copyright 2002 Xilinx Inc.
* All rights reserved.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xiic_l.c
*
* This file contains low-level driver functions that can be used to access the
* device. The user should refer to the hardware device specification for more
* details of the device operation.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- --- ------- -----------------------------------------------
* 1.01b jhl 5/13/02 First release
* 1.01b jhl 10/14/02 Corrected bug in the receive function, the setup of the
* interrupt status mask was not being done in the loop such
* that a read would sometimes fail on the last byte because
* the transmit error which should have been ignored was
* being used. This would leave an extra byte in the FIFO
* and the bus throttled such that the next operation would
* also fail. Also updated the receive function to not
* disable the device after the last byte until after the
* bus transitions to not busy which is more consistent
* with the expected behavior.
* 1.01c ecm 12/05/02 new rev
* </pre>
*
****************************************************************************/
/***************************** Include Files *******************************/
#include "xbasic_types.h"
#include "xio.h"
#include "xipif_v1_23_b.h"
#include "xiic_l.h"
/************************** Constant Definitions ***************************/
/**************************** Type Definitions *****************************/
/***************** Macros (Inline Functions) Definitions *******************/
/******************************************************************************
*
* This macro clears the specified interrupt in the IPIF interrupt status
* register. It is non-destructive in that the register is read and only the
* interrupt specified is cleared. Clearing an interrupt acknowledges it.
*
* @param BaseAddress contains the IPIF registers base address.
*
* @param InterruptMask contains the interrupts to be disabled
*
* @return
*
* None.
*
* @note
*
* Signature: void XIic_mClearIisr(u32 BaseAddress,
* u32 InterruptMask);
*
******************************************************************************/
#define XIic_mClearIisr(BaseAddress, InterruptMask) \
XIIF_V123B_WRITE_IISR((BaseAddress), \
XIIF_V123B_READ_IISR(BaseAddress) & (InterruptMask))
/******************************************************************************
*
* This macro sends the address for a 7 bit address during both read and write
* operations. It takes care of the details to format the address correctly.
* This macro is designed to be called internally to the drivers.
*
* @param SlaveAddress contains the address of the slave to send to.
*
* @param Operation indicates XIIC_READ_OPERATION or XIIC_WRITE_OPERATION
*
* @return
*
* None.
*
* @note
*
* Signature: void XIic_mSend7BitAddr(u16 SlaveAddress, u8 Operation);
*
******************************************************************************/
#define XIic_mSend7BitAddress(BaseAddress, SlaveAddress, Operation) \
{ \
u8 LocalAddr = (u8)(SlaveAddress << 1); \
LocalAddr = (LocalAddr & 0xFE) | (Operation); \
XIo_Out8(BaseAddress + XIIC_DTR_REG_OFFSET, LocalAddr); \
}
/************************** Function Prototypes ****************************/
static unsigned RecvData (u32 BaseAddress, u8 * BufferPtr,
unsigned ByteCount);
static unsigned SendData (u32 BaseAddress, u8 * BufferPtr,
unsigned ByteCount);
/************************** Variable Definitions **************************/
/****************************************************************************/
/**
* Receive data as a master on the IIC bus. This function receives the data
* using polled I/O and blocks until the data has been received. It only
* supports 7 bit addressing and non-repeated start modes of operation. The
* user is responsible for ensuring the bus is not busy if multiple masters
* are present on the bus.
*
* @param BaseAddress contains the base address of the IIC device.
* @param Address contains the 7 bit IIC address of the device to send the
* specified data to.
* @param BufferPtr points to the data to be sent.
* @param ByteCount is the number of bytes to be sent.
*
* @return
*
* The number of bytes received.
*
* @note
*
* None
*
******************************************************************************/
unsigned XIic_Recv (u32 BaseAddress, u8 Address,
u8 * BufferPtr, unsigned ByteCount)
{
u8 CntlReg;
unsigned RemainingByteCount;
/* Tx error is enabled incase the address (7 or 10) has no device to answer
* with Ack. When only one byte of data, must set NO ACK before address goes
* out therefore Tx error must not be enabled as it will go off immediately
* and the Rx full interrupt will be checked. If full, then the one byte
* was received and the Tx error will be disabled without sending an error
* callback msg.
*/
XIic_mClearIisr (BaseAddress,
XIIC_INTR_RX_FULL_MASK | XIIC_INTR_TX_ERROR_MASK |
XIIC_INTR_ARB_LOST_MASK);
/* Set receive FIFO occupancy depth for 1 byte (zero based)
*/
XIo_Out8 (BaseAddress + XIIC_RFD_REG_OFFSET, 0);
/* 7 bit slave address, send the address for a read operation
* and set the state to indicate the address has been sent
*/
XIic_mSend7BitAddress (BaseAddress, Address, XIIC_READ_OPERATION);
/* MSMS gets set after putting data in FIFO. Start the master receive
* operation by setting CR Bits MSMS to Master, if the buffer is only one
* byte, then it should not be acknowledged to indicate the end of data
*/
CntlReg = XIIC_CR_MSMS_MASK | XIIC_CR_ENABLE_DEVICE_MASK;
if (ByteCount == 1) {
CntlReg |= XIIC_CR_NO_ACK_MASK;
}
/* Write out the control register to start receiving data and call the
* function to receive each byte into the buffer
*/
XIo_Out8 (BaseAddress + XIIC_CR_REG_OFFSET, CntlReg);
/* Clear the latched interrupt status for the bus not busy bit which must
* be done while the bus is busy
*/
XIic_mClearIisr (BaseAddress, XIIC_INTR_BNB_MASK);
/* Try to receive the data from the IIC bus */
RemainingByteCount = RecvData (BaseAddress, BufferPtr, ByteCount);
/*
* The receive is complete, disable the IIC device and return the number of
* bytes that was received
*/
XIo_Out8 (BaseAddress + XIIC_CR_REG_OFFSET, 0);
/* Return the number of bytes that was received */
return ByteCount - RemainingByteCount;
}
/******************************************************************************
*
* Receive the specified data from the device that has been previously addressed
* on the IIC bus. This function assumes that the 7 bit address has been sent
* and it should wait for the transmit of the address to complete.
*
* @param BaseAddress contains the base address of the IIC device.
* @param BufferPtr points to the buffer to hold the data that is received.
* @param ByteCount is the number of bytes to be received.
*
* @return
*
* The number of bytes remaining to be received.
*
* @note
*
* This function does not take advantage of the receive FIFO because it is
* designed for minimal code space and complexity. It contains loops that
* that could cause the function not to return if the hardware is not working.
*
* This function assumes that the calling function will disable the IIC device
* after this function returns.
*
******************************************************************************/
static unsigned RecvData (u32 BaseAddress, u8 * BufferPtr, unsigned ByteCount)
{
u8 CntlReg;
u32 IntrStatusMask;
u32 IntrStatus;
/* Attempt to receive the specified number of bytes on the IIC bus */
while (ByteCount > 0) {
/* Setup the mask to use for checking errors because when receiving one
* byte OR the last byte of a multibyte message an error naturally
* occurs when the no ack is done to tell the slave the last byte
*/
if (ByteCount == 1) {
IntrStatusMask =
XIIC_INTR_ARB_LOST_MASK | XIIC_INTR_BNB_MASK;
} else {
IntrStatusMask =
XIIC_INTR_ARB_LOST_MASK |
XIIC_INTR_TX_ERROR_MASK | XIIC_INTR_BNB_MASK;
}
/* Wait for the previous transmit and the 1st receive to complete
* by checking the interrupt status register of the IPIF
*/
while (1) {
IntrStatus = XIIF_V123B_READ_IISR (BaseAddress);
if (IntrStatus & XIIC_INTR_RX_FULL_MASK) {
break;
}
/* Check the transmit error after the receive full because when
* sending only one byte transmit error will occur because of the
* no ack to indicate the end of the data
*/
if (IntrStatus & IntrStatusMask) {
return ByteCount;
}
}
CntlReg = XIo_In8 (BaseAddress + XIIC_CR_REG_OFFSET);
/* Special conditions exist for the last two bytes so check for them
* Note that the control register must be setup for these conditions
* before the data byte which was already received is read from the
* receive FIFO (while the bus is throttled
*/
if (ByteCount == 1) {
/* For the last data byte, it has already been read and no ack
* has been done, so clear MSMS while leaving the device enabled
* so it can get off the IIC bus appropriately with a stop.
*/
XIo_Out8 (BaseAddress + XIIC_CR_REG_OFFSET,
XIIC_CR_ENABLE_DEVICE_MASK);
}
/* Before the last byte is received, set NOACK to tell the slave IIC
* device that it is the end, this must be done before reading the byte
* from the FIFO
*/
if (ByteCount == 2) {
/* Write control reg with NO ACK allowing last byte to
* have the No ack set to indicate to slave last byte read.
*/
XIo_Out8 (BaseAddress + XIIC_CR_REG_OFFSET,
CntlReg | XIIC_CR_NO_ACK_MASK);
}
/* Read in data from the FIFO and unthrottle the bus such that the
* next byte is read from the IIC bus
*/
*BufferPtr++ = XIo_In8 (BaseAddress + XIIC_DRR_REG_OFFSET);
/* Clear the latched interrupt status so that it will be updated with
* the new state when it changes, this must be done after the receive
* register is read
*/
XIic_mClearIisr (BaseAddress, XIIC_INTR_RX_FULL_MASK |
XIIC_INTR_TX_ERROR_MASK |
XIIC_INTR_ARB_LOST_MASK);
ByteCount--;
}
/* Wait for the bus to transition to not busy before returning, the IIC
* device cannot be disabled until this occurs. It should transition as
* the MSMS bit of the control register was cleared before the last byte
* was read from the FIFO.
*/
while (1) {
if (XIIF_V123B_READ_IISR (BaseAddress) & XIIC_INTR_BNB_MASK) {
break;
}
}
return ByteCount;
}
/****************************************************************************/
/**
* Send data as a master on the IIC bus. This function sends the data
* using polled I/O and blocks until the data has been sent. It only supports
* 7 bit addressing and non-repeated start modes of operation. The user is
* responsible for ensuring the bus is not busy if multiple masters are present
* on the bus.
*
* @param BaseAddress contains the base address of the IIC device.
* @param Address contains the 7 bit IIC address of the device to send the
* specified data to.
* @param BufferPtr points to the data to be sent.
* @param ByteCount is the number of bytes to be sent.
*
* @return
*
* The number of bytes sent.
*
* @note
*
* None
*
******************************************************************************/
unsigned XIic_Send (u32 BaseAddress, u8 Address,
u8 * BufferPtr, unsigned ByteCount)
{
unsigned RemainingByteCount;
/* Put the address into the FIFO to be sent and indicate that the operation
* to be performed on the bus is a write operation
*/
XIic_mSend7BitAddress (BaseAddress, Address, XIIC_WRITE_OPERATION);
/* Clear the latched interrupt status so that it will be updated with the
* new state when it changes, this must be done after the address is put
* in the FIFO
*/
XIic_mClearIisr (BaseAddress, XIIC_INTR_TX_EMPTY_MASK |
XIIC_INTR_TX_ERROR_MASK | XIIC_INTR_ARB_LOST_MASK);
/* MSMS must be set after putting data into transmit FIFO, indicate the
* direction is transmit, this device is master and enable the IIC device
*/
XIo_Out8 (BaseAddress + XIIC_CR_REG_OFFSET,
XIIC_CR_MSMS_MASK | XIIC_CR_DIR_IS_TX_MASK |
XIIC_CR_ENABLE_DEVICE_MASK);
/* Clear the latched interrupt
* status for the bus not busy bit which must be done while the bus is busy
*/
XIic_mClearIisr (BaseAddress, XIIC_INTR_BNB_MASK);
/* Send the specified data to the device on the IIC bus specified by the
* the address
*/
RemainingByteCount = SendData (BaseAddress, BufferPtr, ByteCount);
/*
* The send is complete, disable the IIC device and return the number of
* bytes that was sent
*/
XIo_Out8 (BaseAddress + XIIC_CR_REG_OFFSET, 0);
return ByteCount - RemainingByteCount;
}
/******************************************************************************
*
* Send the specified buffer to the device that has been previously addressed
* on the IIC bus. This function assumes that the 7 bit address has been sent
* and it should wait for the transmit of the address to complete.
*
* @param BaseAddress contains the base address of the IIC device.
* @param BufferPtr points to the data to be sent.
* @param ByteCount is the number of bytes to be sent.
*
* @return
*
* The number of bytes remaining to be sent.
*
* @note
*
* This function does not take advantage of the transmit FIFO because it is
* designed for minimal code space and complexity. It contains loops that
* that could cause the function not to return if the hardware is not working.
*
******************************************************************************/
static unsigned SendData (u32 BaseAddress, u8 * BufferPtr, unsigned ByteCount)
{
u32 IntrStatus;
/* Send the specified number of bytes in the specified buffer by polling
* the device registers and blocking until complete
*/
while (ByteCount > 0) {
/* Wait for the transmit to be empty before sending any more data
* by polling the interrupt status register
*/
while (1) {
IntrStatus = XIIF_V123B_READ_IISR (BaseAddress);
if (IntrStatus & (XIIC_INTR_TX_ERROR_MASK |
XIIC_INTR_ARB_LOST_MASK |
XIIC_INTR_BNB_MASK)) {
return ByteCount;
}
if (IntrStatus & XIIC_INTR_TX_EMPTY_MASK) {
break;
}
}
/* If there is more than one byte to send then put the next byte to send
* into the transmit FIFO
*/
if (ByteCount > 1) {
XIo_Out8 (BaseAddress + XIIC_DTR_REG_OFFSET,
*BufferPtr++);
} else {
/* Set the stop condition before sending the last byte of data so that
* the stop condition will be generated immediately following the data
* This is done by clearing the MSMS bit in the control register.
*/
XIo_Out8 (BaseAddress + XIIC_CR_REG_OFFSET,
XIIC_CR_ENABLE_DEVICE_MASK |
XIIC_CR_DIR_IS_TX_MASK);
/* Put the last byte to send in the transmit FIFO */
XIo_Out8 (BaseAddress + XIIC_DTR_REG_OFFSET,
*BufferPtr++);
}
/* Clear the latched interrupt status register and this must be done after
* the transmit FIFO has been written to or it won't clear
*/
XIic_mClearIisr (BaseAddress, XIIC_INTR_TX_EMPTY_MASK);
/* Update the byte count to reflect the byte sent and clear the latched
* interrupt status so it will be updated for the new state
*/
ByteCount--;
}
/* Wait for the bus to transition to not busy before returning, the IIC
* device cannot be disabled until this occurs.
* Note that this is different from a receive operation because the stop
* condition causes the bus to go not busy.
*/
while (1) {
if (XIIF_V123B_READ_IISR (BaseAddress) & XIIC_INTR_BNB_MASK) {
break;
}
}
return ByteCount;
}
/* $Id: xiic_l.h,v 1.2 2002/12/05 19:32:40 meinelte Exp $ */
/*****************************************************************************
*
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
* AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
* SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE,
* OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
* APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
* THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
* AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
* FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY
* WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
* IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
* REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
* INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* (c) Copyright 2002 Xilinx Inc.
* All rights reserved.
*
*****************************************************************************/
/****************************************************************************/
/**
*
* @file xiic_l.h
*
* This header file contains identifiers and low-level driver functions (or
* macros) that can be used to access the device. High-level driver functions
* are defined in xiic.h.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00b jhl 05/07/02 First release
* 1.01c ecm 12/05/02 new rev
* </pre>
*
*****************************************************************************/
#ifndef XIIC_L_H /* prevent circular inclusions */
#define XIIC_L_H /* by using protection macros */
/***************************** Include Files ********************************/
#include "xbasic_types.h"
/************************** Constant Definitions ****************************/
#define XIIC_MSB_OFFSET 3
#define XIIC_REG_OFFSET 0x100 + XIIC_MSB_OFFSET
/*
* Register offsets in bytes from RegisterBase. Three is added to the
* base offset to access LSB (IBM style) of the word
*/
#define XIIC_CR_REG_OFFSET 0x00+XIIC_REG_OFFSET /* Control Register */
#define XIIC_SR_REG_OFFSET 0x04+XIIC_REG_OFFSET /* Status Register */
#define XIIC_DTR_REG_OFFSET 0x08+XIIC_REG_OFFSET /* Data Tx Register */
#define XIIC_DRR_REG_OFFSET 0x0C+XIIC_REG_OFFSET /* Data Rx Register */
#define XIIC_ADR_REG_OFFSET 0x10+XIIC_REG_OFFSET /* Address Register */
#define XIIC_TFO_REG_OFFSET 0x14+XIIC_REG_OFFSET /* Tx FIFO Occupancy */
#define XIIC_RFO_REG_OFFSET 0x18+XIIC_REG_OFFSET /* Rx FIFO Occupancy */
#define XIIC_TBA_REG_OFFSET 0x1C+XIIC_REG_OFFSET /* 10 Bit Address reg */
#define XIIC_RFD_REG_OFFSET 0x20+XIIC_REG_OFFSET /* Rx FIFO Depth reg */
/* Control Register masks */
#define XIIC_CR_ENABLE_DEVICE_MASK 0x01 /* Device enable = 1 */
#define XIIC_CR_TX_FIFO_RESET_MASK 0x02 /* Transmit FIFO reset=1 */
#define XIIC_CR_MSMS_MASK 0x04 /* Master starts Txing=1 */
#define XIIC_CR_DIR_IS_TX_MASK 0x08 /* Dir of tx. Txing=1 */
#define XIIC_CR_NO_ACK_MASK 0x10 /* Tx Ack. NO ack = 1 */
#define XIIC_CR_REPEATED_START_MASK 0x20 /* Repeated start = 1 */
#define XIIC_CR_GENERAL_CALL_MASK 0x40 /* Gen Call enabled = 1 */
/* Status Register masks */
#define XIIC_SR_GEN_CALL_MASK 0x01 /* 1=a mstr issued a GC */
#define XIIC_SR_ADDR_AS_SLAVE_MASK 0x02 /* 1=when addr as slave */
#define XIIC_SR_BUS_BUSY_MASK 0x04 /* 1 = bus is busy */
#define XIIC_SR_MSTR_RDING_SLAVE_MASK 0x08 /* 1=Dir: mstr <-- slave */
#define XIIC_SR_TX_FIFO_FULL_MASK 0x10 /* 1 = Tx FIFO full */
#define XIIC_SR_RX_FIFO_FULL_MASK 0x20 /* 1 = Rx FIFO full */
#define XIIC_SR_RX_FIFO_EMPTY_MASK 0x40 /* 1 = Rx FIFO empty */
/* IPIF Interrupt Status Register masks Interrupt occurs when... */
#define XIIC_INTR_ARB_LOST_MASK 0x01 /* 1 = arbitration lost */
#define XIIC_INTR_TX_ERROR_MASK 0x02 /* 1=Tx error/msg complete*/
#define XIIC_INTR_TX_EMPTY_MASK 0x04 /* 1 = Tx FIFO/reg empty */
#define XIIC_INTR_RX_FULL_MASK 0x08 /* 1=Rx FIFO/reg=OCY level*/
#define XIIC_INTR_BNB_MASK 0x10 /* 1 = Bus not busy */
#define XIIC_INTR_AAS_MASK 0x20 /* 1 = when addr as slave */
#define XIIC_INTR_NAAS_MASK 0x40 /* 1 = not addr as slave */
#define XIIC_INTR_TX_HALF_MASK 0x80 /* 1 = TX FIFO half empty */
/* IPIF Device Interrupt Register masks */
#define XIIC_IPIF_IIC_MASK 0x00000004UL /* 1=inter enabled */
#define XIIC_IPIF_ERROR_MASK 0x00000001UL /* 1=inter enabled */
#define XIIC_IPIF_INTER_ENABLE_MASK (XIIC_IPIF_IIC_MASK | \
XIIC_IPIF_ERROR_MASK)
#define XIIC_TX_ADDR_SENT 0x00
#define XIIC_TX_ADDR_MSTR_RECV_MASK 0x02
/* The following constants specify the depth of the FIFOs */
#define IIC_RX_FIFO_DEPTH 16 /* Rx fifo capacity */
#define IIC_TX_FIFO_DEPTH 16 /* Tx fifo capacity */
/* The following constants specify groups of interrupts that are typically
* enabled or disables at the same time
*/
#define XIIC_TX_INTERRUPTS \
(XIIC_INTR_TX_ERROR_MASK | XIIC_INTR_TX_EMPTY_MASK | \
XIIC_INTR_TX_HALF_MASK)
#define XIIC_TX_RX_INTERRUPTS (XIIC_INTR_RX_FULL_MASK | XIIC_TX_INTERRUPTS)
/* The following constants are used with the following macros to specify the
* operation, a read or write operation.
*/
#define XIIC_READ_OPERATION 1
#define XIIC_WRITE_OPERATION 0
/* The following constants are used with the transmit FIFO fill function to
* specify the role which the IIC device is acting as, a master or a slave.
*/
#define XIIC_MASTER_ROLE 1
#define XIIC_SLAVE_ROLE 0
/**************************** Type Definitions ******************************/
/***************** Macros (Inline Functions) Definitions ********************/
/************************** Function Prototypes *****************************/
unsigned XIic_Recv(u32 BaseAddress, u8 Address,
u8 *BufferPtr, unsigned ByteCount);
unsigned XIic_Send(u32 BaseAddress, u8 Address,
u8 *BufferPtr, unsigned ByteCount);
#endif /* end of protection macro */
...@@ -167,8 +167,6 @@ static void ppc_440x_eth_halt (struct eth_device *dev) ...@@ -167,8 +167,6 @@ static void ppc_440x_eth_halt (struct eth_device *dev)
/* EMAC RESET */ /* EMAC RESET */
out32 (EMAC_M0 + hw_p->hw_addr, EMAC_M0_SRST); out32 (EMAC_M0 + hw_p->hw_addr, EMAC_M0_SRST);
hw_p->print_speed = 1; /* print speed message again next time */
return; return;
} }
...@@ -241,11 +239,9 @@ int ppc_440x_eth_setup_bridge(int devnum, bd_t * bis) ...@@ -241,11 +239,9 @@ int ppc_440x_eth_setup_bridge(int devnum, bd_t * bis)
zmiifer |= ZMII_FER_SMII << ZMII_FER_V (0); zmiifer |= ZMII_FER_SMII << ZMII_FER_V (0);
zmiifer |= ZMII_FER_SMII << ZMII_FER_V (1); zmiifer |= ZMII_FER_SMII << ZMII_FER_V (1);
rmiifer |= RGMII_FER_RGMII << RGMII_FER_V(2); rmiifer |= RGMII_FER_RGMII << RGMII_FER_V(2);
rmiifer |= RGMII_FER_RGMII << RGMII_FER_V(3);
bis->bi_phymode[0] = BI_PHYMODE_ZMII; bis->bi_phymode[0] = BI_PHYMODE_ZMII;
bis->bi_phymode[1] = BI_PHYMODE_ZMII; bis->bi_phymode[1] = BI_PHYMODE_ZMII;
bis->bi_phymode[2] = BI_PHYMODE_RGMII; bis->bi_phymode[2] = BI_PHYMODE_RGMII;
bis->bi_phymode[3] = BI_PHYMODE_RGMII;
break; break;
case 0: case 0:
default: default:
...@@ -426,8 +422,12 @@ static int ppc_440x_eth_init (struct eth_device *dev, bd_t * bis) ...@@ -426,8 +422,12 @@ static int ppc_440x_eth_init (struct eth_device *dev, bd_t * bis)
bis->bi_phynum[devnum] = reg; bis->bi_phynum[devnum] = reg;
/* Reset the phy */ /*
miiphy_reset (reg); * Reset the phy, only if its the first time through
* otherwise, just check the speeds & feeds
*/
if (hw_p->first_init == 0) {
miiphy_reset (reg);
#if defined(CONFIG_440_GX) #if defined(CONFIG_440_GX)
#if defined(CONFIG_CIS8201_PHY) #if defined(CONFIG_CIS8201_PHY)
...@@ -456,9 +456,10 @@ static int ppc_440x_eth_init (struct eth_device *dev, bd_t * bis) ...@@ -456,9 +456,10 @@ static int ppc_440x_eth_init (struct eth_device *dev, bd_t * bis)
} }
#endif #endif
#endif #endif
/* Start/Restart autonegotiation */ /* Start/Restart autonegotiation */
phy_setup_aneg (reg); phy_setup_aneg (reg);
udelay (1000); udelay (1000);
}
miiphy_read (reg, PHY_BMSR, &reg_short); miiphy_read (reg, PHY_BMSR, &reg_short);
...@@ -1167,6 +1168,10 @@ int ppc_440x_eth_initialize (bd_t * bis) ...@@ -1167,6 +1168,10 @@ int ppc_440x_eth_initialize (bd_t * bis)
bis->bi_phymode[2] = 2; bis->bi_phymode[2] = 2;
bis->bi_phymode[3] = 2; bis->bi_phymode[3] = 2;
#if defined (CONFIG_440_GX)
ppc_440x_eth_setup_bridge(0, bis);
#endif
for (eth_num = 0; eth_num < EMAC_NUM_DEV; eth_num++) { for (eth_num = 0; eth_num < EMAC_NUM_DEV; eth_num++) {
/* See if we can actually bring up the interface, otherwise, skip it */ /* See if we can actually bring up the interface, otherwise, skip it */
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
* You should have received a copy of the GNU General Public License along * 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., * with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA. * 675 Mass Ave, Cambridge, MA 02139, USA.
* *
*/ */
#ifndef __CONFIG_H #ifndef __CONFIG_H
...@@ -56,9 +56,21 @@ ...@@ -56,9 +56,21 @@
#define CONFIG_4xx 1 /* ...member of PPC4xx family */ #define CONFIG_4xx 1 /* ...member of PPC4xx family */
#define CONFIG_XILINX_ML300 1 /* ...on a Xilinx ML300 board */ #define CONFIG_XILINX_ML300 1 /* ...on a Xilinx ML300 board */
#define CFG_ENV_IS_NOWHERE 1 /* environment is in RAM */ #define CFG_ENV_IS_IN_EEPROM 1 /* environment is in EEPROM */
/* following are used only if env is in EEPROM */
#ifdef CFG_ENV_IS_IN_EEPROM
#define CFG_I2C_EEPROM_ADDR XPAR_PERSISTENT_0_IIC_0_EEPROMADDR
#define CFG_I2C_EEPROM_ADDR_LEN 1
#define CFG_ENV_OFFSET XPAR_PERSISTENT_0_IIC_0_BASEADDR
#define CONFIG_MISC_INIT_R 1 /* used to call out convert_env() */
#define CONFIG_ENV_OVERWRITE 1 /* allow users to update ethaddr and serial# */
#endif
#include "../board/xilinx/ml300/xparameters.h"
#define CFG_NO_FLASH 1 /* no flash */ #define CFG_NO_FLASH 1 /* no flash */
#define CFG_ENV_SIZE 0x2000 #define CFG_ENV_SIZE XPAR_PERSISTENT_0_IIC_0_HIGHADDR - XPAR_PERSISTENT_0_IIC_0_BASEADDR + 1
#define CONFIG_BAUDRATE 9600 #define CONFIG_BAUDRATE 9600
#define CONFIG_BOOTDELAY 3 /* autoboot after 3 seconds */ #define CONFIG_BOOTDELAY 3 /* autoboot after 3 seconds */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment