U-Boot
Threads by month
- ----- 2025 -----
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2000 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
August 2006
- 279 discussions

02 Nov '06
This patch comes from Yuli's posted patch on 8/8/2006
about "CFI Driver Little-Endian write Issue".
If that patch applied, please discard this one.
Signed-off-by: Yuli Barcohen <yuli(a)arabellasw.com>
Signed-off-by: Roy Zang <tie-fei.zang(a)freescale.com>
---
drivers/cfi_flash.c | 32 ++++++++++++++++++++++++++------
1 files changed, 26 insertions(+), 6 deletions(-)
diff --git a/drivers/cfi_flash.c b/drivers/cfi_flash.c
index fd0a186..33a5822 100644
--- a/drivers/cfi_flash.c
+++ b/drivers/cfi_flash.c
@@ -2,9 +2,12 @@
* (C) Copyright 2002-2004
* Brad Kemp, Seranoa Networks, Brad.Kemp(a)seranoa.com
*
- * Copyright (C) 2003 Arabella Software Ltd.
+ * Copyright (C) 2003, 2006 Arabella Software Ltd.
* Yuli Barcohen <yuli(a)arabellasw.com>
* Modified to work with AMD flashes
+ * Added support for byte lanes swap
+ * Added support for 32-bit chips consisting of two 16-bit devices
+ * (for example, S70GL256M00)
*
* Copyright (C) 2004
* Ed Okerson
@@ -45,10 +48,13 @@
/* #define DEBUG */
#include <common.h>
+
+#ifdef CFG_FLASH_CFI_DRIVER
+
+#include <watchdog.h>
#include <asm/processor.h>
#include <asm/byteorder.h>
#include <environment.h>
-#ifdef CFG_FLASH_CFI_DRIVER
/*
* This file implements a Common Flash Interface (CFI) driver for
U-Boot.
@@ -71,6 +77,10 @@ #ifdef CFG_FLASH_CFI_DRIVER
* Verify erase and program timeouts.
*/
+#if defined(__LITTLE_ENDIAN) && !defined(CFG_FLASH_CFI_SWAP)
+#define CFG_FLASH_CFI_SWAP
+#endif
+
#ifndef CFG_FLASH_BANKS_LIST
#define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE }
#endif
@@ -268,7 +278,7 @@ inline uchar flash_read_uchar (flash_inf
uchar *cp;
cp = flash_make_addr (info, 0, offset);
-#if defined(__LITTLE_ENDIAN)
+#if defined(CFG_FLASH_CFI_SWAP)
return (cp[0]);
#else
return (cp[info->portwidth - 1]);
@@ -295,7 +305,7 @@ #ifdef DEBUG
debug ("addr[%x] = 0x%x\n", x, addr[x]);
}
#endif
-#if defined(__LITTLE_ENDIAN)
+#if defined(CFG_FLASH_CFI_SWAP)
retval = ((addr[(info->portwidth)] << 8) | addr[0]);
#else
retval = ((addr[(2 * info->portwidth) - 1] << 8) |
@@ -327,7 +337,7 @@ #ifdef DEBUG
debug ("addr[%x] = 0x%x\n", x, addr[x]);
}
#endif
-#if defined(__LITTLE_ENDIAN)
+#if defined(CFG_FLASH_CFI_SWAP)
retval = (addr[0] << 16) | (addr[(info->portwidth)] << 24) |
(addr[(2 * info->portwidth)]) | (addr[(3 *
info->portwidth)] << 8);
#else
@@ -892,12 +902,22 @@ static void flash_make_cmd (flash_info_t
int i;
uchar *cp = (uchar *) cmdbuf;
-#if defined(__LITTLE_ENDIAN)
+#if defined(CFG_FLASH_CFI_SWAP)
for (i = info->portwidth; i > 0; i--)
#else
for (i = 1; i <= info->portwidth; i++)
#endif
*cp++ = (i & (info->chipwidth - 1)) ? '\0' : cmd;
+#ifdef CFG_FLASH_CFI_2x16
+ if ((info->portwidth == FLASH_CFI_32BIT) && (info->chipwidth ==
FLASH_CFI_BY16))
+ {
+ uchar tmp;
+ cp = (uchar *) cmdbuf;
+ tmp = cp[1];
+ cp[1] = cp[2];
+ cp[2] = tmp;
+ }
+#endif /* CFG_FLASH_CFI_2x16 */
}
/*
--
1.4.0
1
1
tsi108 on chip i2c support.
The i2c Interface provides a master-only, serial interface
that can be used for initializing Tsi108/Tsi109 registers
from an EEPROM after a device reset.
Signed-off-by: Alexandre Bounine <alexandreb(a)tundra.com>
Signed-off-by: Roy Zang <tie-fei.zang(a)freescale.com>
---
drivers/tsi108_i2c.c | 295
++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 295 insertions(+), 0 deletions(-)
diff --git a/drivers/tsi108_i2c.c b/drivers/tsi108_i2c.c
new file mode 100644
index 0000000..bfa10d8
--- /dev/null
+++ b/drivers/tsi108_i2c.c
@@ -0,0 +1,295 @@
+/*
+ * (C) Copyright 2004 Tundra Semiconductor Corp.
+ * Author: Alex Bounine
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+#include <tsi108.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_I2C)
+
+#define I2C_DELAY 100000
+#undef DEBUG_I2C
+
+#ifdef DEBUG_I2C
+#define DPRINT(x) printf(x)
+#else
+#define DPRINT(x)
+#endif
+
+/* All functions assume that Tsi108 I2C block is the only master on the
bus */
+/* I2C read helper function */
+
+static int i2c_read_byte(
+ uint i2c_chan, /* I2C channel number: 0 - main, 1 - SDC
SPD */
+ uchar chip_addr,/* I2C device address on the bus */
+ uint byte_addr, /* Byte address within I2C device */
+ uchar * buffer /* pointer to data buffer */
+ )
+{
+ u32 temp;
+ u32 to_count = I2C_DELAY;
+ u32 op_status = TSI108_I2C_TIMEOUT_ERR;
+ u32 chan_offset = TSI108_I2C_OFFSET;
+
+ DPRINT(("I2C read_byte() %d 0x%02x 0x%02x\n",
+ i2c_chan, chip_addr, byte_addr));
+
+ if (0 != i2c_chan) {
+ chan_offset = TSI108_I2C_SDRAM_OFFSET;
+ }
+
+ /* Check if I2C operation is in progress */
+ temp = *(u32 *) (CFG_TSI108_CSR_BASE + chan_offset +
I2C_CNTRL2);
+
+ if (0 == (temp & (I2C_CNTRL2_RD_STATUS | I2C_CNTRL2_WR_STATUS |
+ I2C_CNTRL2_START))
+ ) {
+ /* Set device address and operation (read = 0) */
+ temp = (byte_addr << 16) | ((chip_addr & 0x07) << 8) |
+ ((chip_addr >> 3) & 0x0F);
+ *(u32 *) (CFG_TSI108_CSR_BASE + chan_offset +
I2C_CNTRL1) =
+ temp;
+
+ /* Issue the read command
+ * (at this moment all other parameters are 0
+ * (size = 1 byte, lane = 0)
+ */
+
+ *(u32 *) (CFG_TSI108_CSR_BASE + chan_offset +
I2C_CNTRL2) =
+ (I2C_CNTRL2_START);
+
+ /* Wait until operation completed */
+ do {
+ /* Read I2C operation status */
+ temp =
+ *(u32 *) (CFG_TSI108_CSR_BASE + chan_offset
+
+ I2C_CNTRL2);
+
+ if (0 ==
+ (temp & (I2C_CNTRL2_RD_STATUS |
I2C_CNTRL2_START)))
+ {
+ if (0 ==
+ (temp &
+ (I2C_CNTRL2_I2C_CFGERR |
+ I2C_CNTRL2_I2C_TO_ERR))
+ ) {
+ op_status = TSI108_I2C_SUCCESS;
+
+ temp = *(u32 *)
(CFG_TSI108_CSR_BASE +
+ chan_offset +
+ I2C_RD_DATA);
+
+ *buffer = (u8) (temp & 0xFF);
+ } else {
+ /* report HW error */
+ op_status = TSI108_I2C_IF_ERROR;
+
+ DPRINT(("I2C HW error reported:
0x%02x\n", temp));
+ }
+
+ break;
+ }
+ } while (to_count--);
+ } else {
+ op_status = TSI108_I2C_IF_BUSY;
+
+ DPRINT(("I2C Transaction start failed: 0x%02x\n",
temp));
+ }
+
+ DPRINT(("I2C read_byte() status: 0x%02x\n", op_status));
+ return op_status;
+}
+
+/*
+ * I2C Read interface as defined in "include/i2c.h" :
+ * chip_addr: I2C chip address, range 0..127
+ * (to read from SPD channel EEPROM use (0xD0 ...
0xD7)
+ * NOTE: The bit 7 in the chip_addr serves as a channel
select.
+ * This hack is for enabling "isdram" command on Tsi108
boards
+ * without changes to common code. Used for I2C reads
only.
+ * byte_addr: Memory or register address within the chip
+ * alen: Number of bytes to use for addr (typically 1, 2 for
larger
+ * memories, 0 for register type devices with only one
+ * register)
+ * buffer: Pointer to destination buffer for data to be read
+ * len: How many bytes to read
+ *
+ * Returns: 0 on success, not 0 on failure
+ */
+
+int i2c_read(uchar chip_addr, uint byte_addr, int alen, uchar * buffer,
int len)
+{
+ u32 op_status = TSI108_I2C_PARAM_ERR;
+ u32 i2c_if = 0;
+
+ /* Hack to support second (SPD) I2C controller (SPD EEPROM read
only).*/
+ if (0xD0 == (chip_addr & ~0x07)) {
+ i2c_if = 1;
+ chip_addr &= 0x7F;
+ }
+ /* Check for valid I2C address */
+ if (chip_addr <= 0x7F && (byte_addr + len) <= (0x01 << (alen *
8))) {
+ while (len--) {
+ op_status =
+ i2c_read_byte(i2c_if, chip_addr,
byte_addr++,
+ buffer++);
+
+ if (TSI108_I2C_SUCCESS != op_status) {
+ DPRINT(("I2C read_byte() failed: 0x%02x
(%d left)\n", op_status, len));
+
+ break;
+ }
+ }
+ }
+
+ DPRINT(("I2C read() status: 0x%02x\n", op_status));
+ return op_status;
+}
+
+/* I2C write helper function */
+
+static int i2c_write_byte(uchar chip_addr,/* I2C device address on the
bus */
+ uint byte_addr, /* Byte address within I2C
device */
+ uchar * buffer /* pointer to data buffer */
+ )
+{
+ u32 temp;
+ u32 to_count = I2C_DELAY;
+ u32 op_status = TSI108_I2C_TIMEOUT_ERR;
+
+ /* Check if I2C operation is in progress */
+ temp = *(u32 *) (CFG_TSI108_CSR_BASE + TSI108_I2C_OFFSET +
I2C_CNTRL2);
+
+ if (0 ==
+ (temp &
+ (I2C_CNTRL2_RD_STATUS | I2C_CNTRL2_WR_STATUS |
I2C_CNTRL2_START)))
+ {
+ /* Place data into the I2C Tx Register */
+ *(u32 *) (CFG_TSI108_CSR_BASE + TSI108_I2C_OFFSET +
+ I2C_TX_DATA) = (u32) * buffer;
+
+ /* Set device address and operation */
+ temp =
+ I2C_CNTRL1_I2CWRITE | (byte_addr << 16) |
+ ((chip_addr & 0x07) << 8) | ((chip_addr >> 3) &
0x0F);
+ *(u32 *) (CFG_TSI108_CSR_BASE + TSI108_I2C_OFFSET +
+ I2C_CNTRL1) = temp;
+
+ /* Issue the write command (at this moment all other
parameters
+ * are 0 (size = 1 byte, lane = 0)
+ */
+
+ *(u32 *) (CFG_TSI108_CSR_BASE + TSI108_I2C_OFFSET +
+ I2C_CNTRL2) = (I2C_CNTRL2_START);
+
+ op_status = TSI108_I2C_TIMEOUT_ERR;
+
+ /* Wait until operation completed */
+ do {
+ // Read I2C operation status
+ temp =
+ *(u32 *) (CFG_TSI108_CSR_BASE +
TSI108_I2C_OFFSET +
+ I2C_CNTRL2);
+
+ if (0 ==
+ (temp & (I2C_CNTRL2_WR_STATUS |
I2C_CNTRL2_START)))
+ {
+ if (0 ==
+ (temp &
+ (I2C_CNTRL2_I2C_CFGERR |
+ I2C_CNTRL2_I2C_TO_ERR))) {
+ op_status = TSI108_I2C_SUCCESS;
+ } else {
+ /* report detected HW error */
+ op_status = TSI108_I2C_IF_ERROR;
+
+ DPRINT(("I2C HW error reported:
0x%02x\n", temp));
+ }
+
+ break;
+ }
+
+ } while (to_count--);
+ } else {
+ op_status = TSI108_I2C_IF_BUSY;
+
+ DPRINT(("I2C Transaction start failed: 0x%02x\n",
temp));
+ }
+
+ return op_status;
+}
+
+/*
+ * I2C Write interface as defined in "include/i2c.h" :
+ * chip_addr: I2C chip address, range 0..127
+ * byte_addr: Memory or register address within the chip
+ * alen: Number of bytes to use for addr (typically 1, 2 for
larger
+ * memories, 0 for register type devices with only one
+ * register)
+ * buffer: Pointer to data to be written
+ * len: How many bytes to write
+ *
+ * Returns: 0 on success, not 0 on failure
+ */
+
+int i2c_write(uchar chip_addr, uint byte_addr, int alen, uchar *
buffer,
+ int len)
+{
+ u32 op_status = TSI108_I2C_PARAM_ERR;
+
+ /* Check for valid I2C address */
+ if (chip_addr <= 0x7F && (byte_addr + len) <= (0x01 << (alen *
8))) {
+ while (len--) {
+ op_status =
+ i2c_write_byte(chip_addr, byte_addr++,
buffer++);
+
+ if (TSI108_I2C_SUCCESS != op_status) {
+ DPRINT(("I2C write_byte() failed: 0x%02x
(%d left)\n", op_status, len));
+
+ break;
+ }
+ }
+ }
+
+ return op_status;
+}
+
+/*
+ * I2C interface function as defined in "include/i2c.h".
+ * Probe the given I2C chip address by reading single byte from offset
0.
+ * Returns 0 if a chip responded, not 0 on failure.
+ */
+
+int i2c_probe(uchar chip)
+{
+ u32 tmp;
+
+ /*
+ * Try to read the first location of the chip.
+ * The Tsi108 HW doesn't support sending just the chip address
+ * and checkong for an <ACK> back.
+ */
+ return i2c_read(chip, 0, 1, (char *)&tmp, 1);
+}
+
+#endif /* (CONFIG_COMMANDS & CFG_CMD_I2C) */
--
1.4.0
1
1

02 Nov '06
tsi108 on chip pci controller support.
If there is no pci card, the tsi108/109 pci configure read will cause a
machine check exception to the processor.
PCI error should also be cleared after the read.
Signed-off-by: Alexandre Bounine <alexandreb(a)tundra.com>
Signed-off-by: Roy Zang <tie-fei.zang(a)freescale.com>
---
drivers/tsi108_pci.c | 176
++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 176 insertions(+), 0 deletions(-)
diff --git a/drivers/tsi108_pci.c b/drivers/tsi108_pci.c
new file mode 100644
index 0000000..6043bec
--- /dev/null
+++ b/drivers/tsi108_pci.c
@@ -0,0 +1,176 @@
+/*
+ * (C) Copyright 2004 Tundra Semiconductor Corp.
+ * Alex Bounine <alexandreb(a)tundra.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * PCI initialisation for the Tsi108 EMU board.
+ */
+
+#include <common.h>
+#include <pci.h>
+#include <asm/io.h>
+#include <tsi108.h>
+
+#ifdef CONFIG_TSI108_PCI
+
+struct pci_controller local_hose;
+
+void tsi108_clear_pci_error(void)
+{
+ u32 err_stat, err_addr, pci_stat;
+
+ /*
+ * Quietly clear errors signalled as result of PCI/X
configuration read
+ * requests.
+ */
+ /* Read PB Error Log Registers */
+ err_stat = *(volatile u32 *)(CFG_TSI108_CSR_BASE +
+ TSI108_PB_REG_OFFSET + PB_ERRCS);
+ err_addr = *(volatile u32 *)(CFG_TSI108_CSR_BASE +
+ TSI108_PB_REG_OFFSET + PB_AERR);
+ if (err_stat & PB_ERRCS_ES) {
+ /* Clear PCI/X bus errors if applicable */
+ if ((err_addr & 0xFF000000) == CFG_PCI_CFG_BASE) {
+ /* Clear error flag */
+ *(u32 *) (CFG_TSI108_CSR_BASE +
+ TSI108_PB_REG_OFFSET + PB_ERRCS) =
+ PB_ERRCS_ES;
+
+ /* Clear read error reported in PB_ISR */
+ *(u32 *) (CFG_TSI108_CSR_BASE +
+ TSI108_PB_REG_OFFSET + PB_ISR) =
+ PB_ISR_PBS_RD_ERR;
+
+ /* Clear errors reported by PCI CSR (Normally Master
Abort) */
+ pci_stat = *(volatile u32 *)(CFG_TSI108_CSR_BASE
+
+
TSI108_PCI_REG_OFFSET +
+ PCI_CSR);
+ *(volatile u32 *)(CFG_TSI108_CSR_BASE +
+ TSI108_PCI_REG_OFFSET +
PCI_CSR) =
+ pci_stat;
+
+ *(volatile u32 *)(CFG_TSI108_CSR_BASE +
+ TSI108_PCI_REG_OFFSET +
+ PCI_IRP_STAT) =
PCI_IRP_STAT_P_CSR;
+ }
+ }
+
+ return;
+}
+
+unsigned int __get_pci_config_dword(u32 addr)
+{
+ unsigned int retval;
+
+ __asm__ __volatile__(" lwbrx %0,0,%1\n"
+ "1: eieio\n"
+ "2:\n"
+ ".section .fixup,\"ax\"\n"
+ "3: li %0,-1\n"
+ " b 2b\n"
+ ".section __ex_table,\"a\"\n"
+ " .align 2\n"
+ " .long 1b,3b\n"
+ ".text":"=r"(retval):"r"(addr));
+
+ return (retval);
+}
+
+static int tsi108_read_config_dword(struct pci_controller *hose,
+ pci_dev_t dev, int offset, u32 *
value)
+{
+ dev &= (CFG_PCI_CFG_SIZE - 1);
+ dev |= (CFG_PCI_CFG_BASE | (offset & 0xfc));
+ *value = __get_pci_config_dword(dev);
+ if (0xFFFFFFFF == *value)
+ tsi108_clear_pci_error();
+ return 0;
+}
+
+static int tsi108_write_config_dword(struct pci_controller *hose,
+ pci_dev_t dev, int offset, u32
value)
+{
+ dev &= (CFG_PCI_CFG_SIZE - 1);
+ dev |= (CFG_PCI_CFG_BASE | (offset & 0xfc));
+
+ out_le32((volatile unsigned *)dev, value);
+
+ return 0;
+}
+
+void pci_init_board(void)
+{
+ struct pci_controller *hose = (struct pci_controller
*)&local_hose;
+
+ hose->first_busno = 0;
+ hose->last_busno = 0xff;
+
+ pci_set_region(hose->regions + 0,
+ CFG_PCI_MEMORY_BUS,
+ CFG_PCI_MEMORY_PHYS,
+ CFG_PCI_MEMORY_SIZE, PCI_REGION_MEM |
PCI_REGION_MEMORY);
+
+ /* PCI memory space */
+ pci_set_region(hose->regions + 1,
+ CFG_PCI_MEM_BUS,
+ CFG_PCI_MEM_PHYS, CFG_PCI_MEM_SIZE,
PCI_REGION_MEM);
+
+ /* PCI I/O space */
+ pci_set_region(hose->regions + 2,
+ CFG_PCI_IO_BUS,
+ CFG_PCI_IO_PHYS, CFG_PCI_IO_SIZE, PCI_REGION_IO);
+
+ hose->region_count = 3;
+
+ pci_set_ops(hose,
+ pci_hose_read_config_byte_via_dword,
+ pci_hose_read_config_word_via_dword,
+ tsi108_read_config_dword,
+ pci_hose_write_config_byte_via_dword,
+ pci_hose_write_config_word_via_dword,
+ tsi108_write_config_dword);
+
+ pci_register_hose(hose);
+
+ hose->last_busno = pci_hose_scan(hose);
+
+ debug("Done PCI initialization\n");
+ return;
+}
+
+#ifdef CONFIG_OF_FLAT_TREE
+void
+ft_pci_setup(void *blob, bd_t *bd)
+{
+ u32 *p;
+ int len;
+
+ p = (u32 *)ft_get_prop(blob, "/" OF_TSI "/pci@1000/bus-range",
&len);
+ if (p != NULL) {
+ p[0] = local_hose.first_busno;
+ p[1] = local_hose.last_busno;
+ }
+
+}
+#endif
+
+#endif /* CONFIG_TSI108_PCI */
--
1.4.0
1
1

02 Nov '06
Tundra tsi108 on chip Ethernet controller support.
There are two Gitb Ethernet ports on tsi108 chip.
Signed-off-by: Alexandre Bounine <alexandreb(a)tundra.com>
Signed-off-by: Roy Zang <tie-fei.zang(a)freescale.com>
---
drivers/tsi108_eth.c | 1042
++++++++++++++++++++++++++++++++++++++++++++++++++
net/eth.c | 4
2 files changed, 1046 insertions(+), 0 deletions(-)
diff --git a/drivers/tsi108_eth.c b/drivers/tsi108_eth.c
new file mode 100644
index 0000000..196c4b4
--- /dev/null
+++ b/drivers/tsi108_eth.c
@@ -0,0 +1,1042 @@
+/**********************************************************************
*
+ *
+ * Copyright (c) 2005 Freescale Semiconductor, Inc.
+ *
+ * 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
+ *
+ * Description:
+ * Ethernet interface for Tundra TSI108 bridge chip
+ *
+
***********************************************************************/
+
+#include <common.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI) \
+ && defined(CONFIG_TSI108_ETH)
+
+#if !defined(CONFIG_TSI108_ETH_NUM_PORTS) ||
(CONFIG_TSI108_ETH_NUM_PORTS > 2)
+#error "CONFIG_TSI108_ETH_NUM_PORTS must be defined as 1 or 2"
+#endif
+
+#include <malloc.h>
+#include <net.h>
+#include <asm/cache.h>
+
+#ifdef DEBUG
+#define TSI108_ETH_DEBUG 7
+#else
+#define TSI108_ETH_DEBUG 0
+#endif
+
+#if TSI108_ETH_DEBUG > 0
+#define debug_lev(lev, fmt, args...) if (lev <= TSI108_ETH_DEBUG)
printf("%s %d: " fmt, __FUNCTION__, __LINE__, ##args)
+#else
+#define debug_lev(lev, fmt, args...) do{}while(0)
+#endif
+
+#define RX_PRINT_ERRORS
+#define TX_PRINT_ERRORS
+
+#define ETH_BASE (CFG_TSI108_CSR_BASE + 0x6000)
+
+#define ETH_PORT_OFFSET 0x400
+
+#define __REG32(base, offset) (*((volatile u32 *)((char *)(base) +
(offset))))
+
+#define reg_MAC_CONFIG_1(base) __REG32(base,
0x00000000)
+#define MAC_CONFIG_1_TX_ENABLE (0x00000001)
+#define MAC_CONFIG_1_SYNC_TX_ENABLE (0x00000002)
+#define MAC_CONFIG_1_RX_ENABLE (0x00000004)
+#define MAC_CONFIG_1_SYNC_RX_ENABLE (0x00000008)
+#define MAC_CONFIG_1_TX_FLOW_CONTROL (0x00000010)
+#define MAC_CONFIG_1_RX_FLOW_CONTROL (0x00000020)
+#define MAC_CONFIG_1_LOOP_BACK (0x00000100)
+#define MAC_CONFIG_1_RESET_TX_FUNCTION (0x00010000)
+#define MAC_CONFIG_1_RESET_RX_FUNCTION (0x00020000)
+#define MAC_CONFIG_1_RESET_TX_MAC (0x00040000)
+#define MAC_CONFIG_1_RESET_RX_MAC (0x00080000)
+#define MAC_CONFIG_1_SIM_RESET (0x40000000)
+#define MAC_CONFIG_1_SOFT_RESET (0x80000000)
+
+#define reg_MAC_CONFIG_2(base) __REG32(base,
0x00000004)
+#define MAC_CONFIG_2_FULL_DUPLEX (0x00000001)
+#define MAC_CONFIG_2_CRC_ENABLE (0x00000002)
+#define MAC_CONFIG_2_PAD_CRC (0x00000004)
+#define MAC_CONFIG_2_LENGTH_CHECK (0x00000010)
+#define MAC_CONFIG_2_HUGE_FRAME (0x00000020)
+#define MAC_CONFIG_2_INTERFACE_MODE(val) (((val) & 0x3) << 8)
+#define MAC_CONFIG_2_PREAMBLE_LENGTH(val) (((val) & 0xf) << 12)
+#define INTERFACE_MODE_NIBBLE 1 /* 10/100 Mb/s MII) */
+#define INTERFACE_MODE_BYTE 2 /* 1000 Mb/s GMII/TBI */
+
+#define reg_MAXIMUM_FRAME_LENGTH(base) __REG32(base,
0x00000010)
+
+#define reg_MII_MGMT_CONFIG(base) __REG32(base,
0x00000020)
+#define MII_MGMT_CONFIG_MGMT_CLOCK_SELECT(val) ((val) & 0x7)
+#define MII_MGMT_CONFIG_NO_PREAMBLE (0x00000010)
+#define MII_MGMT_CONFIG_SCAN_INCREMENT (0x00000020)
+#define MII_MGMT_CONFIG_RESET_MGMT (0x80000000)
+
+#define reg_MII_MGMT_COMMAND(base) __REG32(base,
0x00000024)
+#define MII_MGMT_COMMAND_READ_CYCLE (0x00000001)
+#define MII_MGMT_COMMAND_SCAN_CYCLE (0x00000002)
+
+#define reg_MII_MGMT_ADDRESS(base) __REG32(base,
0x00000028)
+#define reg_MII_MGMT_CONTROL(base) __REG32(base,
0x0000002c)
+#define reg_MII_MGMT_STATUS(base) __REG32(base,
0x00000030)
+
+#define reg_MII_MGMT_INDICATORS(base) __REG32(base,
0x00000034)
+#define MII_MGMT_INDICATORS_BUSY (0x00000001)
+#define MII_MGMT_INDICATORS_SCAN (0x00000002)
+#define MII_MGMT_INDICATORS_NOT_VALID (0x00000004)
+
+#define reg_INTERFACE_STATUS(base) __REG32(base,
0x0000003c)
+#define INTERFACE_STATUS_LINK_FAIL (0x00000008)
+#define INTERFACE_STATUS_EXCESS_DEFER (0x00000200)
+
+#define reg_STATION_ADDRESS_1(base) __REG32(base,
0x00000040)
+#define reg_STATION_ADDRESS_2(base) __REG32(base,
0x00000044)
+
+#define reg_PORT_CONTROL(base) __REG32(base,
0x00000200)
+#define PORT_CONTROL_PRI (0x00000001)
+#define PORT_CONTROL_BPT (0x00010000)
+#define PORT_CONTROL_SPD (0x00040000)
+#define PORT_CONTROL_RBC (0x00080000)
+#define PORT_CONTROL_PRB (0x00200000)
+#define PORT_CONTROL_DIS (0x00400000)
+#define PORT_CONTROL_TBI (0x00800000)
+#define PORT_CONTROL_STE (0x10000000)
+#define PORT_CONTROL_ZOR (0x20000000)
+#define PORT_CONTROL_CLR (0x40000000)
+#define PORT_CONTROL_SRT (0x80000000)
+
+#define reg_TX_CONFIG(base) __REG32(base,
0x00000220)
+#define TX_CONFIG_START_Q (0x00000003)
+#define TX_CONFIG_EHP (0x00400000)
+#define TX_CONFIG_CHP (0x00800000)
+#define TX_CONFIG_RST (0x80000000)
+
+#define reg_TX_CONTROL(base) __REG32(base,
0x00000224)
+#define TX_CONTROL_GO (0x00008000)
+#define TX_CONTROL_MP (0x01000000)
+#define TX_CONTROL_EAI (0x20000000)
+#define TX_CONTROL_ABT (0x40000000)
+#define TX_CONTROL_EII (0x80000000)
+
+#define reg_TX_STATUS(base) __REG32(base,
0x00000228)
+#define TX_STATUS_QUEUE_USABLE (0x0000000f)
+#define TX_STATUS_CURR_Q (0x00000300)
+#define TX_STATUS_ACT (0x00008000)
+#define TX_STATUS_QUEUE_IDLE (0x000f0000)
+#define TX_STATUS_EOQ_PENDING (0x0f000000)
+
+#define reg_TX_EXTENDED_STATUS(base) __REG32(base,
0x0000022c)
+#define TX_EXTENDED_STATUS_END_OF_QUEUE_CONDITION (0x0000000f)
+#define TX_EXTENDED_STATUS_END_OF_FRAME_CONDITION (0x00000f00)
+#define TX_EXTENDED_STATUS_DESCRIPTOR_INTERRUPT_CONDITION (0x000f0000)
+#define TX_EXTENDED_STATUS_ERROR_FLAG (0x0f000000)
+
+#define reg_TX_THRESHOLDS(base) __REG32(base,
0x00000230)
+
+#define reg_TX_DIAGNOSTIC_ADDR(base) __REG32(base,
0x00000270)
+#define TX_DIAGNOSTIC_ADDR_INDEX (0x0000007f)
+#define TX_DIAGNOSTIC_ADDR_DFR (0x40000000)
+#define TX_DIAGNOSTIC_ADDR_AI (0x80000000)
+
+#define reg_TX_DIAGNOSTIC_DATA(base) __REG32(base,
0x00000274)
+
+#define reg_TX_ERROR_STATUS(base) __REG32(base,
0x00000278)
+#define TX_ERROR_STATUS (0x00000278)
+#define TX_ERROR_STATUS_QUEUE_0_ERROR_RESPONSE (0x0000000f)
+#define TX_ERROR_STATUS_TEA_ON_QUEUE_0 (0x00000010)
+#define TX_ERROR_STATUS_RER_ON_QUEUE_0 (0x00000020)
+#define TX_ERROR_STATUS_TER_ON_QUEUE_0 (0x00000040)
+#define TX_ERROR_STATUS_DER_ON_QUEUE_0 (0x00000080)
+#define TX_ERROR_STATUS_QUEUE_1_ERROR_RESPONSE (0x00000f00)
+#define TX_ERROR_STATUS_TEA_ON_QUEUE_1 (0x00001000)
+#define TX_ERROR_STATUS_RER_ON_QUEUE_1 (0x00002000)
+#define TX_ERROR_STATUS_TER_ON_QUEUE_1 (0x00004000)
+#define TX_ERROR_STATUS_DER_ON_QUEUE_1 (0x00008000)
+#define TX_ERROR_STATUS_QUEUE_2_ERROR_RESPONSE (0x000f0000)
+#define TX_ERROR_STATUS_TEA_ON_QUEUE_2 (0x00100000)
+#define TX_ERROR_STATUS_RER_ON_QUEUE_2 (0x00200000)
+#define TX_ERROR_STATUS_TER_ON_QUEUE_2 (0x00400000)
+#define TX_ERROR_STATUS_DER_ON_QUEUE_2 (0x00800000)
+#define TX_ERROR_STATUS_QUEUE_3_ERROR_RESPONSE (0x0f000000)
+#define TX_ERROR_STATUS_TEA_ON_QUEUE_3 (0x10000000)
+#define TX_ERROR_STATUS_RER_ON_QUEUE_3 (0x20000000)
+#define TX_ERROR_STATUS_TER_ON_QUEUE_3 (0x40000000)
+#define TX_ERROR_STATUS_DER_ON_QUEUE_3 (0x80000000)
+
+#define reg_TX_QUEUE_0_CONFIG(base) __REG32(base,
0x00000280)
+#define TX_QUEUE_0_CONFIG_OCN_PORT (0x0000003f)
+#define TX_QUEUE_0_CONFIG_BSWP (0x00000400)
+#define TX_QUEUE_0_CONFIG_WSWP (0x00000800)
+#define TX_QUEUE_0_CONFIG_AM (0x00004000)
+#define TX_QUEUE_0_CONFIG_GVI (0x00008000)
+#define TX_QUEUE_0_CONFIG_EEI (0x00010000)
+#define TX_QUEUE_0_CONFIG_ELI (0x00020000)
+#define TX_QUEUE_0_CONFIG_ENI (0x00040000)
+#define TX_QUEUE_0_CONFIG_ESI (0x00080000)
+#define TX_QUEUE_0_CONFIG_EDI (0x00100000)
+
+#define reg_TX_QUEUE_0_BUF_CONFIG(base) __REG32(base,
0x00000284)
+#define TX_QUEUE_0_BUF_CONFIG_OCN_PORT (0x0000003f)
+#define TX_QUEUE_0_BUF_CONFIG_BURST (0x00000300)
+#define TX_QUEUE_0_BUF_CONFIG_BSWP (0x00000400)
+#define TX_QUEUE_0_BUF_CONFIG_WSWP (0x00000800)
+
+#define OCN_PORT_HLP 0 /* HLP Interface */
+#define OCN_PORT_PCI_X 1 /* PCI-X Interface */
+#define OCN_PORT_PROCESSOR_MASTER 2 /* Processor Interface
(master) */
+#define OCN_PORT_PROCESSOR_SLAVE 3 /* Processor Interface
(slave) */
+#define OCN_PORT_MEMORY 4 /* Memory Controller */
+#define OCN_PORT_DMA 5 /* DMA Controller */
+#define OCN_PORT_ETHERNET 6 /* Ethernet Controller
*/
+#define OCN_PORT_PRINT 7 /* Print Engine
Interface */
+
+#define reg_TX_QUEUE_0_PTR_LOW(base) __REG32(base,
0x00000288)
+
+#define reg_TX_QUEUE_0_PTR_HIGH(base) __REG32(base,
0x0000028c)
+#define TX_QUEUE_0_PTR_HIGH_VALID (0x80000000)
+
+#define reg_RX_CONFIG(base) __REG32(base,
0x00000320)
+#define RX_CONFIG_DEF_Q (0x00000003)
+#define RX_CONFIG_EMF (0x00000100)
+#define RX_CONFIG_EUF (0x00000200)
+#define RX_CONFIG_BFE (0x00000400)
+#define RX_CONFIG_MFE (0x00000800)
+#define RX_CONFIG_UFE (0x00001000)
+#define RX_CONFIG_SE (0x00002000)
+#define RX_CONFIG_ABF (0x00200000)
+#define RX_CONFIG_APE (0x00400000)
+#define RX_CONFIG_CHP (0x00800000)
+#define RX_CONFIG_RST (0x80000000)
+
+#define reg_RX_CONTROL(base) __REG32(base,
0x00000324)
+#define GE_E0_RX_CONTROL_QUEUE_ENABLES (0x0000000f)
+#define GE_E0_RX_CONTROL_GO (0x00008000)
+#define GE_E0_RX_CONTROL_EAI (0x20000000)
+#define GE_E0_RX_CONTROL_ABT (0x40000000)
+#define GE_E0_RX_CONTROL_EII (0x80000000)
+
+#define reg_RX_EXTENDED_STATUS(base) __REG32(base,
0x0000032c)
+#define RX_EXTENDED_STATUS (0x0000032c)
+#define RX_EXTENDED_STATUS_EOQ (0x0000000f)
+#define RX_EXTENDED_STATUS_EOQ_0 (0x00000001)
+#define RX_EXTENDED_STATUS_EOF (0x00000f00)
+#define RX_EXTENDED_STATUS_DESCRIPTOR_INTERRUPT_CONDITION (0x000f0000)
+#define RX_EXTENDED_STATUS_ERROR_FLAG (0x0f000000)
+
+#define reg_RX_THRESHOLDS(base) __REG32(base,
0x00000330)
+
+#define reg_RX_DIAGNOSTIC_ADDR(base) __REG32(base,
0x00000370)
+#define RX_DIAGNOSTIC_ADDR_INDEX (0x0000007f)
+#define RX_DIAGNOSTIC_ADDR_DFR (0x40000000)
+#define RX_DIAGNOSTIC_ADDR_AI (0x80000000)
+
+#define reg_RX_DIAGNOSTIC_DATA(base) __REG32(base,
0x00000374)
+
+#define reg_RX_QUEUE_0_CONFIG(base) __REG32(base,
0x00000380)
+#define RX_QUEUE_0_CONFIG_OCN_PORT (0x0000003f)
+#define RX_QUEUE_0_CONFIG_BSWP (0x00000400)
+#define RX_QUEUE_0_CONFIG_WSWP (0x00000800)
+#define RX_QUEUE_0_CONFIG_AM (0x00004000)
+#define RX_QUEUE_0_CONFIG_EEI (0x00010000)
+#define RX_QUEUE_0_CONFIG_ELI (0x00020000)
+#define RX_QUEUE_0_CONFIG_ENI (0x00040000)
+#define RX_QUEUE_0_CONFIG_ESI (0x00080000)
+#define RX_QUEUE_0_CONFIG_EDI (0x00100000)
+
+#define reg_RX_QUEUE_0_BUF_CONFIG(base) __REG32(base, 0x00000384)
+#define RX_QUEUE_0_BUF_CONFIG_OCN_PORT (0x0000003f)
+#define RX_QUEUE_0_BUF_CONFIG_BURST (0x00000300)
+#define RX_QUEUE_0_BUF_CONFIG_BSWP (0x00000400)
+#define RX_QUEUE_0_BUF_CONFIG_WSWP (0x00000800)
+
+#define reg_RX_QUEUE_0_PTR_LOW(base) __REG32(base,
0x00000388)
+
+#define reg_RX_QUEUE_0_PTR_HIGH(base) __REG32(base,
0x0000038c)
+#define RX_QUEUE_0_PTR_HIGH_VALID (0x80000000)
+
+/*
+ * PHY register definitions
+ */
+/* the first 15 PHY registers are standard. */
+#define PHY_CTRL_REG 0 /* Control Register */
+#define PHY_STATUS_REG 1 /* Status Regiser */
+#define PHY_ID1_REG 2 /* Phy Id Reg (word 1) */
+#define PHY_ID2_REG 3 /* Phy Id Reg (word 2) */
+#define PHY_AN_ADV_REG 4 /* Autoneg Advertisement */
+#define PHY_LP_ABILITY_REG 5 /* Link Partner Ability (Base
Page) */
+#define PHY_AUTONEG_EXP_REG 6 /* Autoneg Expansion Reg */
+#define PHY_NEXT_PAGE_TX_REG 7 /* Next Page TX */
+#define PHY_LP_NEXT_PAGE_REG 8 /* Link Partner Next Page */
+#define PHY_1000T_CTRL_REG 9 /* 1000Base-T Control Reg */
+#define PHY_1000T_STATUS_REG 10 /* 1000Base-T Status Reg */
+#define PHY_EXT_STATUS_REG 11 /* Extended Status Reg */
+
+/*
+ * PHY Register bit masks.
+ */
+#define PHY_CTRL_RESET (1 << 15)
+#define PHY_CTRL_LOOPBACK (1 << 14)
+#define PHY_CTRL_SPEED0 (1 << 13)
+#define PHY_CTRL_AN_EN (1 << 12)
+#define PHY_CTRL_PWR_DN (1 << 11)
+#define PHY_CTRL_ISOLATE (1 << 10)
+#define PHY_CTRL_RESTART_AN (1 << 9)
+#define PHY_CTRL_FULL_DUPLEX (1 << 8)
+#define PHY_CTRL_CT_EN (1 << 7)
+#define PHY_CTRL_SPEED1 (1 << 6)
+
+#define PHY_STAT_100BASE_T4 (1 << 15)
+#define PHY_STAT_100BASE_X_FD (1 << 14)
+#define PHY_STAT_100BASE_X_HD (1 << 13)
+#define PHY_STAT_10BASE_T_FD (1 << 12)
+#define PHY_STAT_10BASE_T_HD (1 << 11)
+#define PHY_STAT_100BASE_T2_FD (1 << 10)
+#define PHY_STAT_100BASE_T2_HD (1 << 9)
+#define PHY_STAT_EXT_STAT (1 << 8)
+#define PHY_STAT_RESERVED (1 << 7)
+#define PHY_STAT_MFPS (1 << 6) /* Management Frames
Preamble Suppression */
+#define PHY_STAT_AN_COMPLETE (1 << 5)
+#define PHY_STAT_REM_FAULT (1 << 4)
+#define PHY_STAT_AN_CAP (1 << 3)
+#define PHY_STAT_LINK_UP (1 << 2)
+#define PHY_STAT_JABBER (1 << 1)
+#define PHY_STAT_EXT_CAP (1 << 0)
+
+#define TBI_CONTROL_2 0x11
+#define TBI_CONTROL_2_ENABLE_COMMA_DETECT 0x0001
+#define TBI_CONTROL_2_ENABLE_WRAP 0x0002
+#define TBI_CONTROL_2_G_MII_MODE 0x0010
+#define TBI_CONTROL_2_RECEIVE_CLOCK_SELECT 0x0020
+#define TBI_CONTROL_2_AUTO_NEGOTIATION_SENSE 0x0100
+#define TBI_CONTROL_2_DISABLE_TRANSMIT_RUNNING_DISPARITY 0x1000
+#define TBI_CONTROL_2_DISABLE_RECEIVE_RUNNING_DISPARITY 0x2000
+#define TBI_CONTROL_2_SHORTCUT_LINK_TIMER 0x4000
+#define TBI_CONTROL_2_SOFT_RESET 0x8000
+
+/* marvel specific */
+#define MV1111_EXT_CTRL1_REG 16 /* PHY Specific Control Reg */
+#define MV1111_SPEC_STAT_REG 17 /* PHY Specific Status Reg */
+#define MV1111_EXT_CTRL2_REG 20 /* Extended PHY Specific Control
Reg */
+
+/*
+ * MARVELL 88E1111 PHY register bit masks
+ */
+/* PHY Specific Status Register (MV1111_EXT_CTRL1_REG) */
+
+#define SPEC_STAT_SPEED_MASK (3 << 14)
+#define SPEC_STAT_FULL_DUP (1 << 13)
+#define SPEC_STAT_PAGE_RCVD (1 << 12)
+#define SPEC_STAT_RESOLVED (1 << 11) /* Speed and Duplex
Resolved */
+#define SPEC_STAT_LINK_UP (1 << 10)
+#define SPEC_STAT_CABLE_LEN_MASK (7 << 7) /* Cable Length
(100/1000 modes only) */
+#define SPEC_STAT_MDIX (1 << 6)
+#define SPEC_STAT_POLARITY (1 << 1)
+#define SPEC_STAT_JABBER (1 << 0)
+
+#define SPEED_1000 (2 << 14)
+#define SPEED_100 (1 << 14)
+#define SPEED_10 (0 << 14)
+
+#define TBI_ADDR 0x1E /* Ten Bit Interface address */
+
+/* negotiated link parameters */
+#define LINK_SPEED_UNKNOWN 0
+#define LINK_SPEED_10 1
+#define LINK_SPEED_100 2
+#define LINK_SPEED_1000 3
+
+#define LINK_DUPLEX_UNKNOWN 0
+#define LINK_DUPLEX_HALF 1
+#define LINK_DUPLEX_FULL 2
+
+static unsigned int phy_address[] = { 8, 9 };
+
+#define vuint32 volatile u32
+
+/* TX/RX buffer descriptors. MUST be cache line aligned in memory. (32
byte)
+ * This structure is accessed by the ethernet DMA engine which means it
+ * MUST be in LITTLE ENDIAN format */
+struct dma_descriptor {
+ vuint32 start_addr0; /* buffer address, least significant
bytes. */
+ vuint32 start_addr1; /* buffer address, most significant
bytes. */
+ vuint32 next_descr_addr0;/* next descriptor address, least
significant bytes. Must be 64-bit aligned. */
+ vuint32 next_descr_addr1;/* next descriptor address, most
significant bytes. */
+ vuint32 vlan_byte_count;/* VLAN tag(top 2 bytes) and byte countt
(bottom 2 bytes). */
+ vuint32 config_status; /* Configuration/Status. */
+ vuint32 reserved1; /* reserved to make the descriptor cache
line aligned. */
+ vuint32 reserved2; /* reserved to make the descriptor cache
line aligned. */
+};
+
+/* last next descriptor address flag */
+#define DMA_DESCR_LAST (1 << 31)
+
+/* TX DMA descriptor config status bits */
+#define DMA_DESCR_TX_EOF (1 << 0) /* end of frame */
+#define DMA_DESCR_TX_SOF (1 << 1) /* start of frame */
+#define DMA_DESCR_TX_PFVLAN (1 << 2)
+#define DMA_DESCR_TX_HUGE (1 << 3)
+#define DMA_DESCR_TX_PAD (1 << 4)
+#define DMA_DESCR_TX_CRC (1 << 5)
+#define DMA_DESCR_TX_DESCR_INT (1 << 14)
+#define DMA_DESCR_TX_RETRY_COUNT 0x000F0000
+#define DMA_DESCR_TX_ONE_COLLISION (1 << 20)
+#define DMA_DESCR_TX_LATE_COLLISION (1 << 24)
+#define DMA_DESCR_TX_UNDERRUN (1 << 25)
+#define DMA_DESCR_TX_RETRY_LIMIT (1 << 26)
+#define DMA_DESCR_TX_OK (1 << 30)
+#define DMA_DESCR_TX_OWNER (1 << 31)
+
+/* RX DMA descriptor status bits */
+#define DMA_DESCR_RX_EOF (1 << 0)
+#define DMA_DESCR_RX_SOF (1 << 1)
+#define DMA_DESCR_RX_VTF (1 << 2)
+#define DMA_DESCR_RX_FRAME_IS_TYPE (1 << 3)
+#define DMA_DESCR_RX_SHORT_FRAME (1 << 4)
+#define DMA_DESCR_RX_HASH_MATCH (1 << 7)
+#define DMA_DESCR_RX_BAD_FRAME (1 << 8)
+#define DMA_DESCR_RX_OVERRUN (1 << 9)
+#define DMA_DESCR_RX_MAX_FRAME_LEN (1 << 11)
+#define DMA_DESCR_RX_CRC_ERROR (1 << 12)
+#define DMA_DESCR_RX_DESCR_INT (1 << 13)
+#define DMA_DESCR_RX_OWNER (1 << 15)
+
+#define RX_BUFFER_SIZE PKTSIZE
+#define NUM_RX_DESC PKTBUFSRX
+
+static struct dma_descriptor tx_descriptor __attribute__
((aligned(32)));
+
+static struct dma_descriptor rx_descr_array[NUM_RX_DESC]
+ __attribute__ ((aligned(32)));
+
+static struct dma_descriptor *rx_descr_current;
+
+static int tsi108_eth_probe(struct eth_device *dev, bd_t * bis);
+static int tsi108_eth_send(struct eth_device *dev,
+ volatile void *packet, int length);
+static int tsi108_eth_recv(struct eth_device *dev);
+static void tsi108_eth_halt(struct eth_device *dev);
+static unsigned int read_phy(unsigned int base,
+ unsigned int phy_addr, unsigned int
phy_reg);
+static void write_phy(unsigned int base,
+ unsigned int phy_addr,
+ unsigned int phy_reg, unsigned int phy_data);
+
+#if TSI108_ETH_DEBUG > 100
+/*
+ * print phy debug infomation
+ */
+static void dump_phy_regs(unsigned int phy_addr)
+{
+ int i;
+
+ printf("PHY %d registers\n", phy_addr);
+ for (i = 0; i <= 30; i++) {
+ printf("%2d 0x%04x\n", i, read_phy(ETH_BASE, phy_addr,
i));
+ }
+ printf("\n");
+
+}
+#else
+#define dump_phy_regs(base) do{}while(0)
+#endif
+
+#if TSI108_ETH_DEBUG > 100
+/*
+ * print debug infomation
+ */
+static void tx_diag_regs(unsigned int base)
+{
+ int i;
+ unsigned long dummy;
+
+ printf("TX diagnostics registers\n");
+ reg_TX_DIAGNOSTIC_ADDR(base) = 0x00 | TX_DIAGNOSTIC_ADDR_AI;
+ udelay(1000);
+ dummy = reg_TX_DIAGNOSTIC_DATA(base);
+ for (i = 0x00; i <= 0x05; i++) {
+ udelay(1000);
+ printf("0x%02x 0x%08x\n", i,
reg_TX_DIAGNOSTIC_DATA(base));
+ }
+ reg_TX_DIAGNOSTIC_ADDR(base) = 0x40 | TX_DIAGNOSTIC_ADDR_AI;
+ udelay(1000);
+ dummy = reg_TX_DIAGNOSTIC_DATA(base);
+ for (i = 0x40; i <= 0x47; i++) {
+ udelay(1000);
+ printf("0x%02x 0x%08x\n", i,
reg_TX_DIAGNOSTIC_DATA(base));
+ }
+ printf("\n");
+
+}
+#else
+#define tx_diag_regs(base) do{}while(0)
+#endif
+
+#if TSI108_ETH_DEBUG > 100
+/*
+ * print debug infomation
+ */
+static void rx_diag_regs(unsigned int base)
+{
+ int i;
+ unsigned long dummy;
+
+ printf("RX diagnostics registers\n");
+ reg_RX_DIAGNOSTIC_ADDR(base) = 0x00 | RX_DIAGNOSTIC_ADDR_AI;
+ udelay(1000);
+ dummy = reg_RX_DIAGNOSTIC_DATA(base);
+ for (i = 0x00; i <= 0x05; i++) {
+ udelay(1000);
+ printf("0x%02x 0x%08x\n", i,
reg_RX_DIAGNOSTIC_DATA(base));
+ }
+ reg_RX_DIAGNOSTIC_ADDR(base) = 0x40 | RX_DIAGNOSTIC_ADDR_AI;
+ udelay(1000);
+ dummy = reg_RX_DIAGNOSTIC_DATA(base);
+ for (i = 0x08; i <= 0x0a; i++) {
+ udelay(1000);
+ printf("0x%02x 0x%08x\n", i,
reg_RX_DIAGNOSTIC_DATA(base));
+ }
+ printf("\n");
+
+}
+#else
+#define rx_diag_regs(base) do{}while(0)
+#endif
+
+#if TSI108_ETH_DEBUG > 100
+/*
+ * print debug infomation
+ */
+static void debug_mii_regs(unsigned int base)
+{
+ printf("MII_MGMT_CONFIG 0x%08x\n",
reg_MII_MGMT_CONFIG(base));
+ printf("MII_MGMT_COMMAND 0x%08x\n",
reg_MII_MGMT_COMMAND(base));
+ printf("MII_MGMT_ADDRESS 0x%08x\n",
reg_MII_MGMT_ADDRESS(base));
+ printf("MII_MGMT_CONTROL 0x%08x\n",
reg_MII_MGMT_CONTROL(base));
+ printf("MII_MGMT_STATUS 0x%08x\n",
reg_MII_MGMT_STATUS(base));
+ printf("MII_MGMT_INDICATORS 0x%08x\n",
reg_MII_MGMT_INDICATORS(base));
+ printf("\n");
+
+}
+#else
+#define debug_mii_regs(base) do{}while(0)
+#endif
+
+/*
+ * Wait until the phy bus is non-busy
+ */
+static void phy_wait(unsigned int base, unsigned int condition)
+{
+ int timeout;
+
+ timeout = 0;
+ while (reg_MII_MGMT_INDICATORS(base) & condition) {
+ udelay(10);
+ if (++timeout > 10000) {
+ printf("ERROR: timeout waiting for phy bus
(%d)\n",
+ condition);
+ break;
+ }
+ }
+}
+
+/*
+ * read phy register
+ */
+static unsigned int read_phy(unsigned int base,
+ unsigned int phy_addr, unsigned int
phy_reg)
+{
+ unsigned int value;
+
+ phy_wait(base, MII_MGMT_INDICATORS_BUSY);
+
+ reg_MII_MGMT_ADDRESS(base) = (phy_addr << 8) | phy_reg;
+
+ /* Ensure that the Read Cycle bit is cleared prior to next read
cycle */
+ reg_MII_MGMT_COMMAND(base) = 0;
+
+ /* start the read */
+ reg_MII_MGMT_COMMAND(base) = MII_MGMT_COMMAND_READ_CYCLE;
+
+ /* wait for the read to complete */
+ phy_wait(base,
+ MII_MGMT_INDICATORS_NOT_VALID |
MII_MGMT_INDICATORS_BUSY);
+
+ value = reg_MII_MGMT_STATUS(base);
+
+ reg_MII_MGMT_COMMAND(base) = 0;
+
+ return value;
+}
+
+/*
+ * write phy register
+ */
+static void write_phy(unsigned int base,
+ unsigned int phy_addr,
+ unsigned int phy_reg, unsigned int phy_data)
+{
+ phy_wait(base, MII_MGMT_INDICATORS_BUSY);
+
+ reg_MII_MGMT_ADDRESS(base) = (phy_addr << 8) | phy_reg;
+
+ /* Ensure that the Read Cycle bit is cleared prior to next cycle
*/
+ reg_MII_MGMT_COMMAND(base) = 0;
+
+ /* start the write */
+ reg_MII_MGMT_CONTROL(base) = phy_data;
+}
+
+/*
+ * configure the marvell 88e1111 phy
+ */
+static int marvell_88e_phy_config(struct eth_device *dev, int *speed,
+ int *duplex)
+{
+ unsigned long base;
+ unsigned long phy_addr;
+ unsigned int phy_status;
+ unsigned int phy_spec_status;
+ int timeout;
+ int phy_speed;
+ int phy_duplex;
+ unsigned int value;
+
+ phy_speed = LINK_SPEED_UNKNOWN;
+ phy_duplex = LINK_DUPLEX_UNKNOWN;
+
+ base = dev->iobase;
+ phy_addr = (unsigned long)dev->priv;
+
+ /* Take the PHY out of reset. */
+ write_phy(ETH_BASE, phy_addr, PHY_CTRL_REG, PHY_CTRL_RESET);
+
+ /* Wait for the reset process to complete. */
+ udelay(10);
+ timeout = 0;
+ while ((phy_status =
+ read_phy(ETH_BASE, phy_addr, PHY_CTRL_REG)) &
PHY_CTRL_RESET) {
+ udelay(10);
+ if (++timeout > 10000) {
+ printf("ERROR: timeout waiting for phy
reset\n");
+ break;
+ }
+ }
+
+ /* TBI Configuration. */
+ write_phy(base, TBI_ADDR, TBI_CONTROL_2,
TBI_CONTROL_2_G_MII_MODE |
+ TBI_CONTROL_2_RECEIVE_CLOCK_SELECT);
+ /* Wait for the link to be established. */
+ timeout = 0;
+ do {
+ udelay(20000);
+ phy_status = read_phy(ETH_BASE, phy_addr,
PHY_STATUS_REG);
+ if (++timeout > 100) {
+ debug_lev(1, "ERROR: unable to establish
link!!!\n");
+ break;
+ }
+ } while ((phy_status & PHY_STAT_LINK_UP) == 0);
+
+ if ((phy_status & PHY_STAT_LINK_UP) == 0) {
+ return 0;
+ }
+
+ value = 0;
+ phy_spec_status = read_phy(ETH_BASE, phy_addr,
MV1111_SPEC_STAT_REG);
+ if (phy_spec_status & SPEC_STAT_RESOLVED) {
+ switch (phy_spec_status & SPEC_STAT_SPEED_MASK) {
+ case SPEED_1000:
+ phy_speed = LINK_SPEED_1000;
+ value |= PHY_CTRL_SPEED1;
+ break;
+ case SPEED_100:
+ phy_speed = LINK_SPEED_100;
+ value |= PHY_CTRL_SPEED0;
+ break;
+ case SPEED_10:
+ phy_speed = LINK_SPEED_10;
+ break;
+ }
+ if (phy_spec_status & SPEC_STAT_FULL_DUP) {
+ phy_duplex = LINK_DUPLEX_FULL;
+ value |= PHY_CTRL_FULL_DUPLEX;
+ } else {
+ phy_duplex = LINK_DUPLEX_HALF;
+ }
+ }
+ /* set TBI speed */
+ write_phy(base, TBI_ADDR, PHY_CTRL_REG, value);
+ write_phy(base, TBI_ADDR, PHY_AN_ADV_REG, 0x0060);
+
+#if TSI108_ETH_DEBUG > 0
+ printf("%s link is up", dev->name);
+ phy_spec_status = read_phy(ETH_BASE, phy_addr,
MV1111_SPEC_STAT_REG);
+ if (phy_spec_status & SPEC_STAT_RESOLVED) {
+ switch (phy_speed) {
+ case LINK_SPEED_1000:
+ printf(", 1000 Mbps");
+ break;
+ case LINK_SPEED_100:
+ printf(", 100 Mbps");
+ break;
+ case LINK_SPEED_10:
+ printf(", 10 Mbps");
+ break;
+ }
+ if (phy_duplex == LINK_DUPLEX_FULL) {
+ printf(", Full duplex");
+ } else {
+ printf(", Half duplex");
+ }
+ }
+ printf("\n");
+#endif
+
+ dump_phy_regs(TBI_ADDR);
+ if (speed) {
+ *speed = phy_speed;
+ }
+ if (duplex) {
+ *duplex = phy_duplex;
+ }
+
+ return 1;
+}
+
+/*
+ * External interface
+ *
+ * register the tsi108 ethernet controllers with the multi-ethernet
system
+ */
+int tsi108_eth_initialize(bd_t * bis)
+{
+ struct eth_device *dev;
+ int index;
+
+ for (index = 0; index < CONFIG_TSI108_ETH_NUM_PORTS; index++) {
+ dev = (struct eth_device *)malloc(sizeof(struct
eth_device));
+
+ sprintf(dev->name, "TSI108_eth%d", index);
+
+ dev->iobase = ETH_BASE + (index * ETH_PORT_OFFSET);
+ dev->priv = (void *)(phy_address[index]);
+ dev->init = tsi108_eth_probe;
+ dev->halt = tsi108_eth_halt;
+ dev->send = tsi108_eth_send;
+ dev->recv = tsi108_eth_recv;
+
+ eth_register(dev);
+ }
+ return index;
+}
+
+/*
+ * probe for and initialize a single ethernet interface
+ */
+static int tsi108_eth_probe(struct eth_device *dev, bd_t * bis)
+{
+ unsigned long base;
+ unsigned long value;
+ int index;
+ struct dma_descriptor *tx_descr;
+ struct dma_descriptor *rx_descr;
+ int speed;
+ int duplex;
+
+ base = dev->iobase;
+
+ reg_PORT_CONTROL(base) = PORT_CONTROL_STE | PORT_CONTROL_BPT;
+
+ /* Bring DMA/FIFO out of reset. */
+ reg_TX_CONFIG(base) = 0x00000000;
+ reg_RX_CONFIG(base) = 0x00000000;
+
+ reg_TX_THRESHOLDS(base) = (192 << 16) | 192;
+ reg_RX_THRESHOLDS(base) = (192 << 16) | 112;
+
+ /* Bring MAC out of reset. */
+ reg_MAC_CONFIG_1(base) = 0x00000000;
+
+ /* DMA MAC configuration. */
+ reg_MAC_CONFIG_1(base) =
+ MAC_CONFIG_1_RX_ENABLE | MAC_CONFIG_1_TX_ENABLE;
+
+ reg_MII_MGMT_CONFIG(base) = MII_MGMT_CONFIG_NO_PREAMBLE;
+ reg_MAXIMUM_FRAME_LENGTH(base) = RX_BUFFER_SIZE;
+
+ /* Note: Early tsi108 manual did not have correct byte order
+ * for the station address.*/
+ reg_STATION_ADDRESS_1(base) = (dev->enetaddr[5] << 24) |
+ (dev->enetaddr[4] << 16) |
+ (dev->enetaddr[3] << 8) | (dev->enetaddr[2] << 0);
+
+ reg_STATION_ADDRESS_2(base) = (dev->enetaddr[1] << 24) |
+ (dev->enetaddr[0] << 16);
+
+ if (marvell_88e_phy_config(dev, &speed, &duplex) == 0) {
+ return 0;
+ }
+
+ value =
+ MAC_CONFIG_2_PREAMBLE_LENGTH(7) | MAC_CONFIG_2_PAD_CRC |
+ MAC_CONFIG_2_CRC_ENABLE;
+ if (speed == LINK_SPEED_1000) {
+ value |=
MAC_CONFIG_2_INTERFACE_MODE(INTERFACE_MODE_BYTE);
+ } else {
+ value |=
MAC_CONFIG_2_INTERFACE_MODE(INTERFACE_MODE_NIBBLE);
+ reg_PORT_CONTROL(base) |= PORT_CONTROL_SPD;
+ }
+ if (duplex == LINK_DUPLEX_FULL) {
+ value |= MAC_CONFIG_2_FULL_DUPLEX;
+ reg_PORT_CONTROL(base) &= ~PORT_CONTROL_BPT;
+ } else {
+ reg_PORT_CONTROL(base) |= PORT_CONTROL_BPT;
+ }
+ reg_MAC_CONFIG_2(base) = value;
+
+ reg_RX_CONFIG(base) = RX_CONFIG_SE;
+ reg_RX_QUEUE_0_CONFIG(base) = OCN_PORT_MEMORY;
+ reg_RX_QUEUE_0_BUF_CONFIG(base) = OCN_PORT_MEMORY;
+
+ /* initialize the RX DMA descriptors */
+ rx_descr = &rx_descr_array[0];
+ rx_descr_current = rx_descr;
+ for (index = 0; index < NUM_RX_DESC; index++) {
+ /* make sure the receive buffers are not in cache */
+ invalidate_dcache_range((unsigned
long)NetRxPackets[index],
+ (unsigned
long)NetRxPackets[index] +
+ RX_BUFFER_SIZE);
+ rx_descr->start_addr0 =
+ cpu_to_le32((vuint32) NetRxPackets[index]);
+ rx_descr->start_addr1 = 0;
+ rx_descr->next_descr_addr0 =
+ cpu_to_le32((vuint32) (rx_descr + 1));
+ rx_descr->next_descr_addr1 = 0;
+ rx_descr->vlan_byte_count = 0;
+ rx_descr->config_status = cpu_to_le32((RX_BUFFER_SIZE <<
16) |
+
DMA_DESCR_RX_OWNER);
+ rx_descr++;
+ }
+ rx_descr--;
+ rx_descr->next_descr_addr0 = 0;
+ rx_descr->next_descr_addr1 = cpu_to_le32(DMA_DESCR_LAST);
+ /* Push the descriptors to RAM so the ethernet DMA can see them
*/
+ invalidate_dcache_range((unsigned long)rx_descr_array,
+ (unsigned long)rx_descr_array +
+ sizeof(rx_descr_array));
+
+ /* enable RX queue */
+ reg_RX_CONTROL(base) = TX_CONTROL_GO | 0x01;
+ reg_RX_QUEUE_0_PTR_LOW(base) = (u32) rx_descr_current;
+ /* enable receive DMA */
+ reg_RX_QUEUE_0_PTR_HIGH(base) = RX_QUEUE_0_PTR_HIGH_VALID;
+
+ reg_TX_QUEUE_0_CONFIG(base) = OCN_PORT_MEMORY;
+ reg_TX_QUEUE_0_BUF_CONFIG(base) = OCN_PORT_MEMORY;
+
+ /* initialize the TX DMA descriptor */
+ tx_descr = &tx_descriptor;
+
+ tx_descr->start_addr0 = 0;
+ tx_descr->start_addr1 = 0;
+ tx_descr->next_descr_addr0 = 0;
+ tx_descr->next_descr_addr1 = cpu_to_le32(DMA_DESCR_LAST);
+ tx_descr->vlan_byte_count = 0;
+ tx_descr->config_status = cpu_to_le32(DMA_DESCR_TX_OK |
+ DMA_DESCR_TX_SOF |
+ DMA_DESCR_TX_EOF);
+ /* enable TX queue */
+ reg_TX_CONTROL(base) = TX_CONTROL_GO | 0x01;
+
+ return 1;
+}
+
+/*
+ * send a packet
+ */
+static int tsi108_eth_send(struct eth_device *dev,
+ volatile void *packet, int length)
+{
+ unsigned long base;
+ int timeout;
+ struct dma_descriptor *tx_descr;
+ unsigned long status;
+
+ base = dev->iobase;
+ tx_descr = &tx_descriptor;
+
+ /* Wait until the last packet has been transmitted. */
+ timeout = 0;
+ do {
+ /* make sure we see the changes made by the DMA engine
*/
+ invalidate_dcache_range((unsigned long)tx_descr,
+ (unsigned long)tx_descr +
+ sizeof(struct dma_descriptor));
+
+ if (timeout != 0) {
+ udelay(15);
+ }
+ if (++timeout > 10000) {
+ tx_diag_regs(base);
+ debug_lev(1,
+ "ERROR: timeout waiting for last
transmit packet to be sent\n");
+ return 0;
+ }
+ } while (tx_descr->config_status &
cpu_to_le32(DMA_DESCR_TX_OWNER));
+
+ status = le32_to_cpu(tx_descr->config_status);
+ if ((status & DMA_DESCR_TX_OK) == 0) {
+#ifdef TX_PRINT_ERRORS
+ printf("TX packet error: 0x%08x\n %s%s%s%s\n",
status,
+ status & DMA_DESCR_TX_OK ? "tx error, " : "",
+ status & DMA_DESCR_TX_RETRY_LIMIT ?
+ "retry limit reached, " : "",
+ status & DMA_DESCR_TX_UNDERRUN ? "underrun, " :
"",
+ status & DMA_DESCR_TX_LATE_COLLISION ? "late
collision, "
+ : "");
+#endif
+ }
+
+ debug_lev(9, "sending packet %d\n", length);
+ tx_descr->start_addr0 = cpu_to_le32((vuint32) packet);
+ tx_descr->start_addr1 = 0;
+ tx_descr->next_descr_addr0 = 0;
+ tx_descr->next_descr_addr1 = cpu_to_le32(DMA_DESCR_LAST);
+ tx_descr->vlan_byte_count = cpu_to_le32(length);
+ tx_descr->config_status = cpu_to_le32(DMA_DESCR_TX_OWNER |
+ DMA_DESCR_TX_CRC |
+ DMA_DESCR_TX_PAD |
+ DMA_DESCR_TX_SOF |
+ DMA_DESCR_TX_EOF);
+
+ invalidate_dcache_range((unsigned long)tx_descr,
+ (unsigned long)tx_descr +
+ sizeof(struct dma_descriptor));
+
+ invalidate_dcache_range((unsigned long)packet,
+ (unsigned long)packet + length);
+
+ reg_TX_QUEUE_0_PTR_LOW(base) = (u32) tx_descr;
+ reg_TX_QUEUE_0_PTR_HIGH(base) = TX_QUEUE_0_PTR_HIGH_VALID;
+
+ return length;
+}
+
+/*
+ * Check for received packets and send them up the protocal stack
+ */
+static int tsi108_eth_recv(struct eth_device *dev)
+{
+ struct dma_descriptor *rx_descr;
+ unsigned long base;
+ int length = 0;
+ unsigned long status;
+ volatile uchar *buffer;
+
+ base = dev->iobase;
+
+ /* make sure we see the changes made by the DMA engine */
+ invalidate_dcache_range((unsigned long)rx_descr_array,
+ (unsigned long)rx_descr_array +
+ sizeof(rx_descr_array));
+
+ /* process all of the received packets */
+ rx_descr = rx_descr_current;
+ while ((rx_descr->config_status &
cpu_to_le32(DMA_DESCR_RX_OWNER)) == 0) {
+ /* check for error */
+ status = le32_to_cpu(rx_descr->config_status);
+ if (status & DMA_DESCR_RX_BAD_FRAME) {
+#ifdef RX_PRINT_ERRORS
+ printf("RX packet error: 0x%08x\n
%s%s%s%s%s%s\n",
+ status,
+ status & DMA_DESCR_RX_FRAME_IS_TYPE ?
"too big, "
+ : "",
+ status & DMA_DESCR_RX_SHORT_FRAME ? "too
short, "
+ : "",
+ status & DMA_DESCR_RX_BAD_FRAME ? "bad
frame, " :
+ "",
+ status & DMA_DESCR_RX_OVERRUN ? "overrun,
" : "",
+ status & DMA_DESCR_RX_MAX_FRAME_LEN ?
+ "max length, " : "",
+ status & DMA_DESCR_RX_CRC_ERROR ? "CRC
error, " :
+ "");
+#endif
+ } else {
+ length =
+ le32_to_cpu(rx_descr->vlan_byte_count) &
0xFFFF;
+
+ /*** process packet ***/
+ buffer =
+ (volatile uchar
+ *)(le32_to_cpu(rx_descr->start_addr0));
+ NetReceive(buffer, length);
+
+ invalidate_dcache_range((unsigned long)buffer,
+ (unsigned long)buffer +
+ RX_BUFFER_SIZE);
+ }
+ /* Give this buffer back to the DMA engine */
+ rx_descr->vlan_byte_count = 0;
+ rx_descr->config_status = cpu_to_le32((RX_BUFFER_SIZE <<
16) |
+
DMA_DESCR_RX_OWNER);
+ /* move descriptor pointer forward */
+ rx_descr =
+ (struct dma_descriptor
+ *)(le32_to_cpu(rx_descr->next_descr_addr0));
+ if (rx_descr == 0) {
+ rx_descr = &rx_descr_array[0];
+ }
+ }
+ /* remember where we are for next time */
+ rx_descr_current = rx_descr;
+
+ /* If the DMA engine has reached the end of the queue
+ * start over at the begining */
+ if (reg_RX_EXTENDED_STATUS(base) & RX_EXTENDED_STATUS_EOQ_0) {
+
+ reg_RX_EXTENDED_STATUS(base) = RX_EXTENDED_STATUS_EOQ_0;
+ reg_RX_QUEUE_0_PTR_LOW(base) = (u32) &
rx_descr_array[0];
+ reg_RX_QUEUE_0_PTR_HIGH(base) =
RX_QUEUE_0_PTR_HIGH_VALID;
+ }
+
+ return length;
+}
+
+/*
+ * disable an ethernet interface
+ */
+static void tsi108_eth_halt(struct eth_device *dev)
+{
+ unsigned long base;
+
+ base = dev->iobase;
+
+ /* Put DMA/FIFO into reset state. */
+ reg_TX_CONFIG(base) = TX_CONFIG_RST;
+ reg_RX_CONFIG(base) = RX_CONFIG_RST;
+
+ /* Put MAC into reset state. */
+ reg_MAC_CONFIG_1(base) = MAC_CONFIG_1_SOFT_RESET;
+}
+
+#endif
diff --git a/net/eth.c b/net/eth.c
index 6f48aac..cfc0232 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -52,6 +52,7 @@ extern int rtl8139_initialize(bd_t*);
extern int rtl8169_initialize(bd_t*);
extern int scc_initialize(bd_t*);
extern int skge_initialize(bd_t*);
+extern int tsi108_eth_initialize(bd_t*);
extern int tsec_initialize(bd_t*, int, char *);
extern int npe_initialize(bd_t *);
@@ -229,6 +230,9 @@ #endif
#ifdef CONFIG_NS8382X
ns8382x_initialize(bis);
#endif
+#if defined(CONFIG_TSI108_ETH)
+ tsi108_eth_initialize(bis);
+#endif
#if defined(CONFIG_RTL8139)
rtl8139_initialize(bis);
#endif
--
1.4.0
1
1
Tundra tsi108 header file.
Provided the macro define for tsi108 chip.
Signed-off-by: Alexandre Bounine <alexandreb(a)tundra.com>
Signed-off-by: Roy Zang <tie-fei.zang(a)freescale.com>
---
include/tsi108.h | 221
++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 221 insertions(+), 0 deletions(-)
diff --git a/include/tsi108.h b/include/tsi108.h
new file mode 100644
index 0000000..072daa0
--- /dev/null
+++ b/include/tsi108.h
@@ -0,0 +1,221 @@
+/**********************************************************************
*******
+ * (C) Copyright 2003; Tundra Semiconductor Corp.
+ * (C) Copyright 2006; Freescale Semiconductor Corp.
+ *
+ * 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
+
************************************************************************
*****/
+
+/*
+ * FILENAME: tsi108.h
+ *
+ * Originator: Alex Bounine
+ *
+ * DESCRIPTION:
+ * Common definitions for the Tundra Tsi108 bridge chip
+ *
+ */
+
+#ifndef _TSI108_H_
+#define _TSI108_H_
+
+#define TSI108_HLP_REG_OFFSET (0x0000)
+#define TSI108_PCI_REG_OFFSET (0x1000)
+#define TSI108_CLK_REG_OFFSET (0x2000)
+#define TSI108_PB_REG_OFFSET (0x3000)
+#define TSI108_SD_REG_OFFSET (0x4000)
+#define TSI108_MPIC_REG_OFFSET (0x7400)
+
+#define PB_ID (0x000)
+#define PB_RSR (0x004)
+#define PB_BUS_MS_SELECT (0x008)
+#define PB_ISR (0x00C)
+#define PB_ARB_CTRL (0x018)
+#define PB_PVT_CTRL2 (0x034)
+#define PB_SCR (0x400)
+#define PB_ERRCS (0x404)
+#define PB_AERR (0x408)
+#define PB_REG_BAR (0x410)
+#define PB_OCN_BAR1 (0x414)
+#define PB_OCN_BAR2 (0x418)
+#define PB_SDRAM_BAR1 (0x41C)
+#define PB_SDRAM_BAR2 (0x420)
+#define PB_MCR (0xC00)
+#define PB_MCMD (0xC04)
+
+#define HLP_B0_ADDR (0x000)
+#define HLP_B1_ADDR (0x010)
+#define HLP_B2_ADDR (0x020)
+#define HLP_B3_ADDR (0x030)
+
+#define HLP_B0_MASK (0x004)
+#define HLP_B1_MASK (0x014)
+#define HLP_B2_MASK (0x024)
+#define HLP_B3_MASK (0x034)
+
+#define HLP_B0_CTRL0 (0x008)
+#define HLP_B1_CTRL0 (0x018)
+#define HLP_B2_CTRL0 (0x028)
+#define HLP_B3_CTRL0 (0x038)
+
+#define HLP_B0_CTRL1 (0x00C)
+#define HLP_B1_CTRL1 (0x01C)
+#define HLP_B2_CTRL1 (0x02C)
+#define HLP_B3_CTRL1 (0x03C)
+
+#define PCI_CSR (0x004)
+#define PCI_P2O_BAR0 (0x010)
+#define PCI_P2O_BAR0_UPPER (0x014)
+#define PCI_P2O_BAR2 (0x018)
+#define PCI_P2O_BAR2_UPPER (0x01C)
+#define PCI_P2O_BAR3 (0x020)
+#define PCI_P2O_BAR3_UPPER (0x024)
+
+#define PCI_MISC_CSR (0x040)
+#define PCI_P2O_PAGE_SIZES (0x04C)
+
+#define PCI_PCIX_STAT (0x0F4)
+
+#define PCI_IRP_STAT (0x184)
+
+#define PCI_PFAB_BAR0 (0x204)
+#define PCI_PFAB_BAR0_UPPER (0x208)
+#define PCI_PFAB_IO (0x20C)
+#define PCI_PFAB_IO_UPPER (0x210)
+
+#define PCI_PFAB_MEM32 (0x214)
+#define PCI_PFAB_MEM32_REMAP (0x218)
+#define PCI_PFAB_MEM32_MASK (0x21C)
+
+#define CG_PLL0_CTRL0 (0x210)
+#define CG_PLL0_CTRL1 (0x214)
+#define CG_PLL1_CTRL0 (0x220)
+#define CG_PLL1_CTRL1 (0x224)
+#define CG_PWRUP_STATUS (0x234)
+
+#define MPIC_CSR(n) (0x30C + (n * 0x40))
+
+#define SD_CTRL (0x000)
+#define SD_STATUS (0x004)
+#define SD_TIMING (0x008)
+#define SD_REFRESH (0x00C)
+#define SD_INT_STATUS (0x010)
+#define SD_INT_ENABLE (0x014)
+#define SD_INT_SET (0x018)
+#define SD_D0_CTRL (0x020)
+#define SD_D1_CTRL (0x024)
+#define SD_D0_BAR (0x028)
+#define SD_D1_BAR (0x02C)
+#define SD_ECC_CTRL (0x040)
+#define SD_DLL_STATUS (0x250)
+
+#define TS_SD_CTRL_ENABLE (1 << 31)
+
+#define PB_ERRCS_ES (1 << 1)
+#define PB_ISR_PBS_RD_ERR (1 << 8)
+#define PCI_IRP_STAT_P_CSR (1 << 23)
+
+/*
+ * I2C : Register address offset definitions
+ */
+#define I2C_CNTRL1
(0x00000000)
+#define I2C_CNTRL2
(0x00000004)
+#define I2C_RD_DATA
(0x00000008)
+#define I2C_TX_DATA
(0x0000000c)
+
+/*
+ * I2C : Register Bit Masks and Reset Values
+ * definitions for every register
+ */
+
+/* I2C_CNTRL1 : Reset Value */
+#define I2C_CNTRL1_RESET_VALUE
(0x0000000a)
+
+/* I2C_CNTRL1 : Register Bits Masks Definitions */
+#define I2C_CNTRL1_DEVCODE
(0x0000000f)
+#define I2C_CNTRL1_PAGE
(0x00000700)
+#define I2C_CNTRL1_BYTADDR
(0x00ff0000)
+#define I2C_CNTRL1_I2CWRITE
(0x01000000)
+
+/* I2C_CNTRL1 : Read/Write Bit Mask Definition */
+#define I2C_CNTRL1_RWMASK
(0x01ff070f)
+
+/* I2C_CNTRL1 : Unused/Reserved bits Definition */
+#define I2C_CNTRL1_RESERVED
(0xfe00f8f0)
+
+/* I2C_CNTRL2 : Reset Value */
+#define I2C_CNTRL2_RESET_VALUE
(0x00000000)
+
+/* I2C_CNTRL2 : Register Bits Masks Definitions */
+#define I2C_CNTRL2_SIZE
(0x00000003)
+#define I2C_CNTRL2_LANE
(0x0000000c)
+#define I2C_CNTRL2_MULTIBYTE
(0x00000010)
+#define I2C_CNTRL2_START
(0x00000100)
+#define I2C_CNTRL2_WR_STATUS
(0x00010000)
+#define I2C_CNTRL2_RD_STATUS
(0x00020000)
+#define I2C_CNTRL2_I2C_TO_ERR
(0x04000000)
+#define I2C_CNTRL2_I2C_CFGERR
(0x08000000)
+#define I2C_CNTRL2_I2C_CMPLT
(0x10000000)
+
+/* I2C_CNTRL2 : Read/Write Bit Mask Definition */
+#define I2C_CNTRL2_RWMASK
(0x0000011f)
+
+/* I2C_CNTRL2 : Unused/Reserved bits Definition */
+#define I2C_CNTRL2_RESERVED
(0xe3fcfee0)
+
+/* I2C_RD_DATA : Reset Value */
+#define I2C_RD_DATA_RESET_VALUE
(0x00000000)
+
+/* I2C_RD_DATA : Register Bits Masks Definitions */
+#define I2C_RD_DATA_RBYTE0
(0x000000ff)
+#define I2C_RD_DATA_RBYTE1
(0x0000ff00)
+#define I2C_RD_DATA_RBYTE2
(0x00ff0000)
+#define I2C_RD_DATA_RBYTE3
(0xff000000)
+
+/* I2C_RD_DATA : Read/Write Bit Mask Definition */
+#define I2C_RD_DATA_RWMASK
(0x00000000)
+
+/* I2C_RD_DATA : Unused/Reserved bits Definition */
+#define I2C_RD_DATA_RESERVED
(0x00000000)
+
+/* I2C_TX_DATA : Reset Value */
+#define I2C_TX_DATA_RESET_VALUE
(0x00000000)
+
+/* I2C_TX_DATA : Register Bits Masks Definitions */
+#define I2C_TX_DATA_TBYTE0
(0x000000ff)
+#define I2C_TX_DATA_TBYTE1
(0x0000ff00)
+#define I2C_TX_DATA_TBYTE2
(0x00ff0000)
+#define I2C_TX_DATA_TBYTE3
(0xff000000)
+
+/* I2C_TX_DATA : Read/Write Bit Mask Definition */
+#define I2C_TX_DATA_RWMASK
(0xffffffff)
+
+/* I2C_TX_DATA : Unused/Reserved bits Definition */
+#define I2C_TX_DATA_RESERVED
(0x00000000)
+
+#define TSI108_I2C_OFFSET 0x7000 /* register block offset for
general use I2C channel */
+#define TSI108_I2C_SDRAM_OFFSET 0x4400 /* register block offset for SPD
I2C channel */
+
+#define I2C_EEPROM_DEVCODE 0xA /* standard I2C EEPROM device code */
+
+/* I2C status codes */
+
+#define TSI108_I2C_SUCCESS 0
+#define TSI108_I2C_PARAM_ERR 1
+#define TSI108_I2C_TIMEOUT_ERR 2
+#define TSI108_I2C_IF_BUSY 3
+#define TSI108_I2C_IF_ERROR 4
+
+#endif /* _TSI108_H_ */
--
1.4.0
1
1

[U-Boot-Users] [PATCH 02/07 v2]: mpc7448hpc2 platform support (part 4/4 mpc7448+tsi108)
by Zang Roy-r61911 02 Nov '06
by Zang Roy-r61911 02 Nov '06
02 Nov '06
Add mpc7448hpc2 (mpc7448 + tsi108) board associated code support.
The original one is too big and divided into 4 parts for review.
board support high level code:tsi108+mpc7448 .
---
board/mpc7448hpc2/mpc7448hpc2.c | 468 +++++++++++++++++++
board/mpc7448hpc2/tsi108_init.c | 662 +++++++++++++++++++++++++++
2 files changed, 1130 insertions(+), 0 deletions(-)
diff --git a/board/mpc7448hpc2/mpc7448hpc2.c
b/board/mpc7448hpc2/mpc7448hpc2.c
new file mode 100644
index 0000000..d0aa59c
--- /dev/null
+++ b/board/mpc7448hpc2/mpc7448hpc2.c
@@ -0,0 +1,468 @@
+/*
+ * (C) Copyright 2005 Freescale Semiconductor, Inc.
+ *
+ * Roy Zang <tie-fei.zang(a)freescale.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * modifications for the Tsi108 Emul Board by avb@Tundra
+ */
+
+/*
+ * board support/init functions for the
+ * Freescale MPC7448 HPC2 (High-Performance Computing 2 Platform).
+ */
+
+#include <common.h>
+#include <74xx_7xx.h>
+
+#undef DEBUG
+
+extern void flush_data_cache(void);
+extern void invalidate_l1_instruction_cache(void);
+extern void tsi108_init_f(void);
+
+int display_mem_map(void);
+
+void after_reloc(ulong dest_addr)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ /*
+ * Jump to the main U-Boot board init code
+ */
+ board_init_r((gd_t *) gd, dest_addr);
+ /* NOTREACHED */
+}
+
+/*
+ * Check Board Identity:
+ *
+ * report board type
+ */
+
+int checkboard(void)
+{
+ int l_type = 0;
+
+ printf("BOARD: %s\n", CFG_BOARD_NAME);
+ return (l_type);
+}
+
+/*
+ * Read Processor ID:
+ *
+ * report calling processor number
+ */
+
+int read_pid(void)
+{
+ return 0; /* we are on single CPU platform for a
while */
+}
+
+long int dram_size(int board_type)
+{
+ return 0x20000000; /* 256M bytes */
+}
+
+long int initdram(int board_type)
+{
+ return dram_size(board_type);
+}
+
+/* DRAM check routines copied from gw8260 */
+
+#if defined (CFG_DRAM_TEST)
+
+/*********************************************************************/
+/* NAME: move64() - moves a double word (64-bit) */
+/* */
+/* DESCRIPTION:
*/
+/* this function performs a double word move from the data at
*/
+/* the source pointer to the location at the destination pointer. */
+/* */
+/* INPUTS: */
+/* unsigned long long *src - pointer to data to move
*/
+/* */
+/* OUTPUTS: */
+/* unsigned long long *dest - pointer to locate to move data */
+/* */
+/* RETURNS: */
+/* None */
+/* */
+/* RESTRICTIONS/LIMITATIONS: */
+/* May cloober fr0. */
+/* */
+/*********************************************************************/
+static void move64(unsigned long long *src, unsigned long long *dest)
+{
+ asm("lfd 0, 0(3)\n\t" /* fpr0 = *scr */
+ "stfd 0, 0(4)" /* *dest = fpr0 */
+ : : :"fr0"); /* Clobbers fr0 */
+ return;
+}
+
+#if defined (CFG_DRAM_TEST_DATA)
+
+unsigned long long pattern[] = {
+ 0xaaaaaaaaaaaaaaaaULL,
+ 0xccccccccccccccccULL,
+ 0xf0f0f0f0f0f0f0f0ULL,
+ 0xff00ff00ff00ff00ULL,
+ 0xffff0000ffff0000ULL,
+ 0xffffffff00000000ULL,
+ 0x00000000ffffffffULL,
+ 0x0000ffff0000ffffULL,
+ 0x00ff00ff00ff00ffULL,
+ 0x0f0f0f0f0f0f0f0fULL,
+ 0x3333333333333333ULL,
+ 0x5555555555555555ULL
+};
+
+/*********************************************************************/
+/* NAME: mem_test_data() - test data lines for shorts and opens */
+/* */
+/* DESCRIPTION:
*/
+/* Tests data lines for shorts and opens by forcing adjacent data */
+/* to opposite states. Because the data lines could be routed in */
+/* an arbitrary manner the must ensure test patterns ensure that */
+/* every case is tested. By using the following series of binary */
+/* patterns every combination of adjacent bits is test regardless */
+/* of routing. */
+/* */
+/* ...101010101010101010101010 */
+/* ...110011001100110011001100 */
+/* ...111100001111000011110000 */
+/* ...111111110000000011111111 */
+/* */
+/* Carrying this out, gives us six hex patterns as follows: */
+/* */
+/* 0xaaaaaaaaaaaaaaaa */
+/* 0xcccccccccccccccc */
+/* 0xf0f0f0f0f0f0f0f0 */
+/* 0xff00ff00ff00ff00 */
+/* 0xffff0000ffff0000 */
+/* 0xffffffff00000000 */
+/* */
+/* The number test patterns will always be given by: */
+/* */
+/* log(base 2)(number data bits) = log2 (64) = 6 */
+/* */
+/* To test for short and opens to other signals on our boards. we */
+/* simply */
+/* test with the 1's complemnt of the paterns as well. */
+/* */
+/* OUTPUTS: */
+/* Displays failing test pattern */
+/* */
+/* RETURNS: */
+/* 0 - Passed test */
+/* 1 - Failed test */
+/* */
+/* RESTRICTIONS/LIMITATIONS: */
+/* Assumes only one one SDRAM bank */
+/* */
+/*********************************************************************/
+int mem_test_data(void)
+{
+ unsigned long long *pmem = (unsigned long long
*)CFG_MEMTEST_START;
+ unsigned long long temp64;
+ int num_patterns = sizeof(pattern) / sizeof(pattern[0]);
+ int i;
+ unsigned int hi, lo;
+
+ for (i = 0; i < num_patterns; i++) {
+ move64(&(pattern[i]), pmem);
+ move64(pmem, &temp64);
+
+ /* hi = (temp64>>32) & 0xffffffff; */
+ /* lo = temp64 & 0xffffffff; */
+ /* printf("\ntemp64 = 0x%08x%08x", hi, lo); */
+
+ hi = (pattern[i] >> 32) & 0xffffffff;
+ lo = pattern[i] & 0xffffffff;
+ /* printf("\npattern[%d] = 0x%08x%08x", i, hi, lo); */
+
+ if (temp64 != pattern[i]) {
+ printf("\n Data Test Failed, pattern
0x%08x%08x",
+ hi, lo);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+#endif /* CFG_DRAM_TEST_DATA */
+
+#if defined (CFG_DRAM_TEST_ADDRESS)
+/*********************************************************************/
+/* NAME: mem_test_address() - test address lines */
+/* */
+/* DESCRIPTION:
*/
+/* This function performs a test to verify that each word im */
+/* memory is uniquly addressable. The test sequence is as follows: */
+/* */
+/* 1) write the address of each word to each word. */
+/* 2) verify that each location equals its address */
+/* */
+/* OUTPUTS: */
+/* Displays failing test pattern and address */
+/* */
+/* RETURNS: */
+/* 0 - Passed test */
+/* 1 - Failed test */
+/* */
+/* RESTRICTIONS/LIMITATIONS: */
+/* */
+/* */
+/*********************************************************************/
+int mem_test_address(void)
+{
+ volatile unsigned int *pmem =
+ (volatile unsigned int *)CFG_MEMTEST_START;
+ const unsigned int size = (CFG_MEMTEST_END - CFG_MEMTEST_START)
/ 4;
+ unsigned int i;
+
+ /* write address to each location */
+ for (i = 0; i < size; i++) {
+ pmem[i] = i;
+ }
+
+ /* verify each loaction */
+ for (i = 0; i < size; i++) {
+ if (pmem[i] != i) {
+ printf("\n Address Test Failed at 0x%x", i);
+ return 1;
+ }
+ }
+ return 0;
+}
+#endif /* CFG_DRAM_TEST_ADDRESS */
+
+#if defined (CFG_DRAM_TEST_WALK)
+/*********************************************************************/
+/* NAME: mem_march() - memory march */
+/* */
+/* DESCRIPTION:
*/
+/* Marches up through memory. At each location verifies rmask if */
+/* read = 1. At each location write wmask if write = 1. Displays */
+/* failing address and pattern. */
+/* */
+/* INPUTS: */
+/* volatile unsigned long long * base - start address of test
*/
+/* unsigned int size - number of dwords(64-bit) to test */
+/* unsigned long long rmask - read verify mask */
+/* unsigned long long wmask - wrtie verify mask */
+/* short read - verifies rmask if read = 1 */
+/* short write - writes wmask if write = 1 */
+/* */
+/* OUTPUTS: */
+/* Displays failing test pattern and address */
+/* */
+/* RETURNS: */
+/* 0 - Passed test */
+/* 1 - Failed test */
+/* */
+/* RESTRICTIONS/LIMITATIONS: */
+/* */
+/* */
+/*********************************************************************/
+int mem_march(volatile unsigned long long *base,
+ unsigned int size,
+ unsigned long long rmask,
+ unsigned long long wmask, short read, short write)
+{
+ unsigned int i;
+ unsigned long long temp;
+ unsigned int hitemp, lotemp, himask, lomask;
+
+ for (i = 0; i < size; i++) {
+ if (read != 0) {
+ /* temp = base[i]; */
+ move64((unsigned long long *)&(base[i]), &temp);
+ if (rmask != temp) {
+ hitemp = (temp >> 32) & 0xffffffff;
+ lotemp = temp & 0xffffffff;
+ himask = (rmask >> 32) & 0xffffffff;
+ lomask = rmask & 0xffffffff;
+
+ printf("\n Walking one's test failed:
\
+ address = 0x%08x," "\n\texpected
\
+ 0x%08x%08x, found 0x%08x%08x", i
<< 3,\
+ himask, lomask, hitemp, lotemp);
+ return 1;
+ }
+ }
+ if (write != 0) {
+ /* base[i] = wmask; */
+ move64(&wmask, (unsigned long long
*)&(base[i]));
+ }
+ }
+ return 0;
+}
+#endif /* CFG_DRAM_TEST_WALK */
+
+/*********************************************************************/
+/* NAME: mem_test_walk() - a simple walking ones test */
+/* */
+/* DESCRIPTION:
*/
+/* Performs a walking ones through entire physical memory. The */
+/* test uses as series of memory marches, mem_march(), to verify */
+/* and write the test patterns to memory. The test sequence is as */
+/* follows: */
+/* 1) march writing 0000...0001 */
+/* 2) march verifying 0000...0001 , writing 0000...0010 */
+/* 3) repeat step 2 shifting masks left 1 bit each time unitl */
+/* the write mask equals 1000...0000 */
+/* 4) march verifying 1000...0000 */
+/* The test fails if any of the memory marches return a failure. */
+/* */
+/* OUTPUTS: */
+/* Displays which pass on the memory test is executing */
+/* */
+/* RETURNS: */
+/* 0 - Passed test */
+/* 1 - Failed test */
+/* */
+/* RESTRICTIONS/LIMITATIONS: */
+/* */
+/* */
+/*********************************************************************/
+int mem_test_walk(void)
+{
+ unsigned long long mask;
+ volatile unsigned long long *pmem =
+ (volatile unsigned long long *)CFG_MEMTEST_START;
+ const unsigned long size = (CFG_MEMTEST_END - CFG_MEMTEST_START)
/ 8;
+
+ unsigned int i;
+
+ mask = 0x01;
+
+ printf("Initial Pass");
+ mem_march(pmem, size, 0x0, 0x1, 0, 1);
+
+ printf("\b\b\b\b\b\b\b\b\b\b\b\b");
+ printf(" ");
+ printf(" ");
+ printf("\b\b\b\b\b\b\b\b\b\b\b\b");
+
+ for (i = 0; i < 63; i++) {
+ printf("Pass %2d", i + 2);
+ if (mem_march(pmem, size, mask, mask << 1, 1, 1) != 0) {
+ /*printf("mask: 0x%x, pass: %d, ", mask, i); */
+ return 1;
+ }
+ mask = mask << 1;
+ printf("\b\b\b\b\b\b\b");
+ }
+
+ printf("Last Pass");
+ if (mem_march(pmem, size, 0, mask, 0, 1) != 0) {
+ /* printf("mask: 0x%x", mask); */
+ return 1;
+ }
+ printf("\b\b\b\b\b\b\b\b\b");
+ printf(" ");
+ printf("\b\b\b\b\b\b\b\b\b");
+
+ return 0;
+}
+
+/*********************************************************************/
+/* NAME: testdram() - calls any enabled memory tests */
+/* */
+/* DESCRIPTION:
*/
+/* Runs memory tests if the environment test variables are set to */
+/* 'y'. */
+/* */
+/* INPUTS: */
+/* testdramdata - If set to 'y', data test is run.
*/
+/* testdramaddress - If set to 'y', address test is run. */
+/* testdramwalk - If set to 'y', walking ones test is run */
+/* */
+/* OUTPUTS: */
+/* None */
+/* */
+/* RETURNS: */
+/* 0 - Passed test */
+/* 1 - Failed test */
+/* */
+/* RESTRICTIONS/LIMITATIONS: */
+/* */
+/* */
+/*********************************************************************/
+int testdram(void)
+{
+ char *s;
+ int rundata, runaddress, runwalk;
+
+ s = getenv("testdramdata");
+ rundata = (s && (*s == 'y')) ? 1 : 0;
+ s = getenv("testdramaddress");
+ runaddress = (s && (*s == 'y')) ? 1 : 0;
+ s = getenv("testdramwalk");
+ runwalk = (s && (*s == 'y')) ? 1 : 0;
+
+/* rundata = 1; */
+/* runaddress = 0; */
+/* runwalk = 0; */
+
+ if ((rundata == 1) || (runaddress == 1) || (runwalk == 1)) {
+ printf("Testing RAM from 0x%08x to 0x%08x ... \
+ (don't panic... that will take a moment
!!!!)\n", \
+ CFG_MEMTEST_START, CFG_MEMTEST_END);
+ }
+#ifdef CFG_DRAM_TEST_DATA
+ if (rundata == 1) {
+ printf("Test DATA ... ");
+ if (mem_test_data () == 1) {
+ printf("failed \n");
+ return 1;
+ } else
+ printf("ok \n");
+ }
+#endif
+#ifdef CFG_DRAM_TEST_ADDRESS
+ if (runaddress == 1) {
+ printf("Test ADDRESS ... ");
+ if (mem_test_address () == 1) {
+ printf("failed \n");
+ return 1;
+ } else
+ printf("ok \n");
+ }
+#endif
+#ifdef CFG_DRAM_TEST_WALK
+ if (runwalk == 1) {
+ printf("Test WALKING ONEs ... ");
+ if (mem_test_walk() == 1) {
+ printf("failed \n");
+ return 1;
+ } else
+ printf("ok \n");
+ }
+#endif
+ if ((rundata == 1) || (runaddress == 1) || (runwalk == 1)) {
+ printf("passed\n");
+ }
+ return 0;
+
+}
+#endif /* CFG_DRAM_TEST */
diff --git a/board/mpc7448hpc2/tsi108_init.c
b/board/mpc7448hpc2/tsi108_init.c
new file mode 100644
index 0000000..6f517f5
--- /dev/null
+++ b/board/mpc7448hpc2/tsi108_init.c
@@ -0,0 +1,662 @@
+/**********************************************************************
*******
+ * (C) Copyright 2003; Tundra Semiconductor Corp.
+ *
+ * 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
+
************************************************************************
*****/
+
+/*---------------------------------------------------------------------
-------
+ * FILENAME: tsi108_init.c
+ *
+ * Originator: Alex Bounine
+ *
+ * DESCRIPTION:
+ * Initialization code for the Tundra Tsi108 bridge chip
+
*-----------------------------------------------------------------------
----*/
+
+#include <common.h>
+#include <74xx_7xx.h>
+#include <config.h>
+#include <version.h>
+#include <asm/processor.h>
+#include <tsi108.h>
+
+extern void mpicInit(int verbose);
+
+/*
+ * Configuration Options
+ */
+
+typedef struct {
+ ulong upper;
+ ulong lower;
+} PB2OCN_LUT_ENTRY;
+
+PB2OCN_LUT_ENTRY pb2ocn_lut1[32] = {
+ /* 0 - 7 */
+ {0x00000000, 0x00000201}, /* PBA=0xE000_0000 -> PCI/X
(Byte-Swap) */
+ {0x00000000, 0x00000201}, /* PBA=0xE100_0000 -> PCI/X
(Byte-Swap) */
+ {0x00000000, 0x00000201}, /* PBA=0xE200_0000 -> PCI/X
(Byte-Swap) */
+ {0x00000000, 0x00000201}, /* PBA=0xE300_0000 -> PCI/X
(Byte-Swap) */
+ {0x00000000, 0x00000201}, /* PBA=0xE400_0000 -> PCI/X
(Byte-Swap) */
+ {0x00000000, 0x00000201}, /* PBA=0xE500_0000 -> PCI/X
(Byte-Swap) */
+ {0x00000000, 0x00000201}, /* PBA=0xE600_0000 -> PCI/X
(Byte-Swap) */
+ {0x00000000, 0x00000201}, /* PBA=0xE700_0000 -> PCI/X
(Byte-Swap) */
+
+ /* 8 - 15 */
+ {0x00000000, 0x00000201}, /* PBA=0xE800_0000 -> PCI/X
(Byte-Swap) */
+ {0x00000000, 0x00000201}, /* PBA=0xE900_0000 -> PCI/X
(Byte-Swap) */
+ {0x00000000, 0x00000201}, /* PBA=0xEA00_0000 -> PCI/X
(Byte-Swap) */
+ {0x00000000, 0x00000201}, /* PBA=0xEB00_0000 -> PCI/X
(Byte-Swap) */
+ {0x00000000, 0x00000201}, /* PBA=0xEC00_0000 -> PCI/X
(Byte-Swap) */
+ {0x00000000, 0x00000201}, /* PBA=0xED00_0000 -> PCI/X
(Byte-Swap) */
+ {0x00000000, 0x00000201}, /* PBA=0xEE00_0000 -> PCI/X
(Byte-Swap) */
+ {0x00000000, 0x00000201}, /* PBA=0xEF00_0000 -> PCI/X
(Byte-Swap) */
+
+ /* 16 - 23 */
+ {0x00000000, 0x00000201}, /* PBA=0xF000_0000 -> PCI/X
(Byte-Swap) */
+ {0x00000000, 0x00000201}, /* PBA=0xF100_0000 -> PCI/X
(Byte-Swap) */
+ {0x00000000, 0x00000201}, /* PBA=0xF200_0000 -> PCI/X
(Byte-Swap) */
+ {0x00000000, 0x00000201}, /* PBA=0xF300_0000 -> PCI/X
(Byte-Swap) */
+ {0x00000000, 0x00000201}, /* PBA=0xF400_0000 -> PCI/X
(Byte-Swap) */
+ {0x00000000, 0x00000201}, /* PBA=0xF500_0000 -> PCI/X
(Byte-Swap) */
+ {0x00000000, 0x00000201}, /* PBA=0xF600_0000 -> PCI/X
(Byte-Swap) */
+ {0x00000000, 0x00000201}, /* PBA=0xF700_0000 -> PCI/X
(Byte-Swap) */
+ /* 24 - 31 */
+ {0x00000000, 0x00000201}, /* PBA=0xF800_0000 -> PCI/X
(Byte-Swap) */
+ {0x00000000, 0x00000201}, /* PBA=0xF900_0000 -> PCI/X
(Byte-Swap) */
+ {0x00000000, 0x00000201}, /* PBA=0xFA00_0000 -> PCI/X PCI I/O
(Byte-Swap) */
+ {0x00000000, 0x00000201}, /* PBA=0xFB00_0000 -> PCI/X PCI
Config (Byte-Swap) */
+
+ {0x00000000, 0x02000240}, /* PBA=0xFC00_0000 -> HLP */
+ {0x00000000, 0x01000240}, /* PBA=0xFD00_0000 -> HLP */
+ {0x00000000, 0x03000240}, /* PBA=0xFE00_0000 -> HLP */
+ {0x00000000, 0x00000240} /* PBA=0xFF00_0000 -> HLP :
(Translation Enabled + Byte-Swap)*/
+};
+
+#ifdef CFG_CLK_SPREAD
+typedef struct {
+ ulong ctrl0;
+ ulong ctrl1;
+} PLL_CTRL_SET;
+
+/*
+ * Clock Generator SPLL0 initialization values
+ * PLL0 configuration table for various PB_CLKO freq.
+ * Uses pre-calculated values for Fs = 30 kHz, D = 0.5%
+ * Fout depends on required PB_CLKO. Based on Fref = 33 MHz
+ */
+
+static PLL_CTRL_SET pll0_config[8] = {
+ {0x00000000, 0x00000000}, /* 0: bypass */
+ {0x00000000, 0x00000000}, /* 1: reserved */
+ {0x00430044, 0x00000043}, /* 2: CG_PB_CLKO = 183 MHz */
+ {0x005c0044, 0x00000039}, /* 3: CG_PB_CLKO = 100 MHz */
+ {0x005c0044, 0x00000039}, /* 4: CG_PB_CLKO = 133 MHz */
+ {0x004a0044, 0x00000040}, /* 5: CG_PB_CLKO = 167 MHz */
+ {0x005c0044, 0x00000039}, /* 6: CG_PB_CLKO = 200 MHz */
+ {0x004f0044, 0x0000003e} /* 7: CG_PB_CLKO = 233 MHz */
+};
+#endif /* CFG_CLK_SPREAD */
+
+/*
+ * Prosessor Bus Clock (in MHz) defined by CG_PB_SELECT
+ * (based on recommended Tsi108 reference clock 33MHz)
+ */
+static int pb_clk_sel[8] = { 0, 0, 183, 100, 133, 167, 200, 233 };
+
+/*
+ * get_board_bus_clk()
+ *
+ * returns the bus clock in Hz.
+ */
+unsigned long get_board_bus_clk(void)
+{
+ ulong i;
+
+ /* Detect PB clock freq. */
+ i = in32(CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET +
CG_PWRUP_STATUS);
+ i = (i >> 16) & 0x07; /* Get PB PLL multiplier */
+
+ return pb_clk_sel[i] * 1000000;
+}
+
+/*
+ * board_early_init_f()
+ *
+ * board-specific initialization executed from flash
+ */
+
+int board_early_init_f(void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ ulong i;
+
+ gd->mem_clk = 0;
+ i = in32(CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET +
CG_PWRUP_STATUS);
+ i = (i >> 20) & 0x07;
+ switch (i) {
+ case 0:
+ printf("Using external clock\n");
+ break;
+ case 1:
+ gd->mem_clk = gd->bus_clk;
+ break;
+ case 4:
+ case 5:
+ case 6:
+ gd->mem_clk = pb_clk_sel[i] * 1000000;
+ break;
+ default:
+ printf("Invalid DDR2 clock setting\n");
+ return -1;
+ }
+ printf("BUS! %d MHz\n", get_board_bus_clk() / 1000000);
+ printf("MEM! %d MHz\n", gd->mem_clk / 1000000);
+ return 0;
+}
+
+/*
+ * board_early_init_r() - Tsi108 initialization function executed right
after
+ * relocation. Contains code that cannot be executed from flash.
+ */
+
+int board_early_init_r(void)
+{
+ ulong temp, i;
+ ulong reg_val;
+ volatile ulong *reg_ptr;
+
+ reg_ptr =
+ (ulong *) (CFG_TSI108_CSR_BASE + TSI108_PB_REG_OFFSET +
0x900);
+
+ for (i = 0; i < 32; i++) {
+ *reg_ptr++ = 0x00000201; /* SWAP ENABLED */
+ *reg_ptr++ = 0x00;
+ }
+
+ __asm__ __volatile__("eieio");
+ __asm__ __volatile__("sync");
+
+ /* Setup PB_OCN_BAR2: size 256B + ENable @ 0x0_80000000 */
+
+ out32(CFG_TSI108_CSR_BASE + TSI108_PB_REG_OFFSET + PB_OCN_BAR2,
+ 0x80000001);
+ __asm__ __volatile__("sync");
+
+ /* Make sure that OCN_BAR2 decoder is set (to allow following
immediate
+ * read from SDRAM)
+ */
+
+ temp = in32(CFG_TSI108_CSR_BASE + TSI108_PB_REG_OFFSET +
PB_OCN_BAR2);
+ __asm__ __volatile__("sync");
+
+ /*
+ * Remap PB_OCN_BAR1 to accomodate PCI-bus aperture and EPROM
into the
+ * processor bus address space. Immediately after reset LUT and
address
+ * translation are disabled for this BAR. Now we have to
initialize LUT
+ * and switch from the BOOT mode to the normal operation mode.
+ *
+ * The aperture defined by PB_OCN_BAR1 startes at address
0xE0000000
+ * and covers 512MB of address space. To allow larger aperture
we also
+ * have to relocate register window of Tsi108
+ *
+ * Initialize LUT (32-entries) prior switching PB_OCN_BAR1 from
BOOT
+ * mode.
+ *
+ * initialize pointer to LUT associated with PB_OCN_BAR1
+ */
+ reg_ptr =
+ (ulong *) (CFG_TSI108_CSR_BASE + TSI108_PB_REG_OFFSET +
0x800);
+
+ for (i = 0; i < 32; i++) {
+ *reg_ptr++ = pb2ocn_lut1[i].lower;
+ *reg_ptr++ = pb2ocn_lut1[i].upper;
+ }
+
+ __asm__ __volatile__("sync");
+
+ /* Base addresses for Cs0, CS1, CS2, CS3 */
+
+ out32(CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B0_ADDR,
+ 0x00000000);
+ __asm__ __volatile__("sync");
+
+ out32(CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B1_ADDR,
+ 0x00100000);
+ __asm__ __volatile__("sync");
+
+ out32(CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B2_ADDR,
+ 0x00200000);
+ __asm__ __volatile__("sync");
+
+ out32(CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B3_ADDR,
+ 0x00300000);
+ __asm__ __volatile__("sync");
+
+ /* Masks for HLP banks */
+
+ out32(CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B0_MASK,
+ 0xFFF00000);
+ __asm__ __volatile__("sync");
+
+ out32(CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B1_MASK,
+ 0xFFF00000);
+ __asm__ __volatile__("sync");
+
+ out32(CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B2_MASK,
+ 0xFFF00000);
+ __asm__ __volatile__("sync");
+
+ out32(CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B3_MASK,
+ 0xFFF00000);
+ __asm__ __volatile__("sync");
+
+ /* Set CTRL0 values for banks */
+
+ out32(CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET +
HLP_B0_CTRL0,
+ 0x7FFC44C2);
+ __asm__ __volatile__("sync");
+
+ out32(CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET +
HLP_B1_CTRL0,
+ 0x7FFC44C0);
+ __asm__ __volatile__("sync");
+
+ out32(CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET +
HLP_B2_CTRL0,
+ 0x7FFC44C0);
+ __asm__ __volatile__("sync");
+
+ out32(CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET +
HLP_B3_CTRL0,
+ 0x7FFC44C2);
+ __asm__ __volatile__("sync");
+
+ /* Set banks to latched mode, enabled, and other default
settings */
+
+ out32(CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET +
HLP_B0_CTRL1,
+ 0x7C0F2000);
+ __asm__ __volatile__("sync");
+
+ out32(CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET +
HLP_B1_CTRL1,
+ 0x7C0F2000);
+ __asm__ __volatile__("sync");
+
+ out32(CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET +
HLP_B2_CTRL1,
+ 0x7C0F2000);
+ __asm__ __volatile__("sync");
+
+ out32(CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET +
HLP_B3_CTRL1,
+ 0x7C0F2000);
+ __asm__ __volatile__("sync");
+
+ /*
+ * Set new value for PB_OCN_BAR1: switch from BOOT to LUT mode.
+ * value for PB_OCN_BAR1: (BA-0xE000_0000 + size 512MB + ENable)
+ */
+ out32(CFG_TSI108_CSR_BASE + TSI108_PB_REG_OFFSET + PB_OCN_BAR1,
+ 0xE0000011);
+ __asm__ __volatile__("sync");
+
+ /* Make sure that OCN_BAR2 decoder is set (to allow following
+ * immediate read from SDRAM)
+ */
+
+ temp = in32(CFG_TSI108_CSR_BASE + TSI108_PB_REG_OFFSET +
PB_OCN_BAR1);
+ __asm__ __volatile__("sync");
+
+ /*
+ * SRI: At this point we have enabled the HLP banks. That means
we can
+ * now read from the NVRAM and initialize the environment
variables.
+ * We will over-ride the env_init called in board_init_f
+ * This is really a work-around because, the HLP bank 1
+ * where NVRAM resides is not visible during board_init_f
+ * (lib_ppc/board.c)
+ * Alternatively, we could use the I2C EEPROM at start-up to
configure
+ * and enable all HLP banks and not just HLP 0 as is being done
for
+ * Taiga Rev. 2.
+ */
+
+ env_init();
+
+#ifndef DISABLE_PBM
+
+ /*
+ * For IBM processors we have to set Address-Only commands
generated
+ * by PBM that are different from ones set after reset.
+ */
+
+ temp = get_cpu_type();
+
+ if ((CPU_750FX == temp) || (CPU_750GX == temp)) {
+ out32(CFG_TSI108_CSR_BASE + TSI108_PB_REG_OFFSET +
PB_MCMD,
+ 0x00009955);
+ }
+#endif /* DISABLE_PBM */
+
+#ifdef CONFIG_PCI
+ /*
+ * Initialize PCI/X block
+ */
+
+ /* Map PCI/X Configuration Space (16MB @ 0x0_FE000000) */
+ out32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET +
PCI_PFAB_BAR0_UPPER,
+ 0);
+ __asm__ __volatile__("sync");
+
+ out32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET +
PCI_PFAB_BAR0,
+ 0xFB000001);
+ __asm__ __volatile__("sync");
+
+ /* Set Bus Number for the attached PCI/X bus (we will use 0 for
NB) */
+
+ temp =
+ in32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET +
PCI_PCIX_STAT);
+
+ temp &= ~0xFF00; /* Clear the BUS_NUM field */
+
+ out32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET +
PCI_PCIX_STAT,
+ temp);
+
+ /* Map PCI/X IO Space (64KB @ 0x0_FD000000) takes one 16MB LUT
entry */
+
+ out32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET +
PCI_PFAB_IO_UPPER,
+ 0);
+ __asm__ __volatile__("sync");
+
+ /* This register is on the PCI side to interpret the address it
receives
+ * and maps it as a IO address.
+ */
+
+ out32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_PFAB_IO,
+ 0xFA000001);
+ __asm__ __volatile__("sync");
+
+ /*
+ * Map PCI/X Memory Space
+ *
+ * Transactions directed from OCM to PCI Memory Space are
directed
+ * from PB to PCI
+ * unchanged (as defined by PB_OCN_BAR1,2 and LUT settings).
+ * If address remapping is required the corresponding
PCI_PFAB_MEM32
+ * and PCI_PFAB_PFMx register groups have to be configured.
+ *
+ * Map the path from the PCI/X bus into the system memory
+ *
+ * The memory mapped window assotiated with PCI P2O_BAR2
provides
+ * access to the system memory without address remapping.
+ * All system memory is opened for accesses initiated by PCI/X
bus
+ * masters.
+ *
+ * Initialize LUT associated with PCI P2O_BAR2
+ *
+ * set pointer to LUT associated with PCI P2O_BAR2
+ */
+
+ reg_ptr =
+ (ulong *) (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET +
0x500);
+
+#ifdef DISABLE_PBM
+
+ /* In case when PBM is disabled (no HW supported cache snoopng
on PB)
+ * P2O_BAR2 is directly mapped into the system memory without
address
+ * translation.
+ */
+
+ reg_val = 0x00000004; /* SDRAM port + NO Addr_Translation */
+
+ for (i = 0; i < 32; i++) {
+ *reg_ptr++ = reg_val; /* P2O_BAR2_LUTx */
+ *reg_ptr++ = 0; /* P2O_BAR2_LUT_UPPERx */
+ }
+
+ /* value for PCI BAR2 (size = 512MB, Enabled, No Addr.
Translation) */
+ reg_val = 0x00007500;
+#else
+
+ reg_val = 0x00000002; /* Destination port = PBM */
+
+ for (i = 0; i < 32; i++) {
+ *reg_ptr++ = reg_val; /* P2O_BAR2_LUTx */
+/* P2O_BAR2_LUT_UPPERx : Set data swapping mode for PBM (byte swapping)
*/
+ *reg_ptr++ = 0x40000000;
+/* offset = 16MB, address translation is enabled to allow byte swapping
*/
+ reg_val += 0x01000000;
+ }
+
+/* value for PCI BAR2 (size = 512MB, Enabled, Address Translation
Enabled) */
+ reg_val = 0x00007100;
+#endif
+
+ __asm__ __volatile__("eieio");
+ __asm__ __volatile__("sync");
+
+ out32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET +
PCI_P2O_PAGE_SIZES,
+ reg_val);
+ __asm__ __volatile__("sync");
+
+ /* Set 64-bit PCI bus address for system memory
+ * ( 0 is the best choice for easy mapping)
+ */
+
+ out32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET +
PCI_P2O_BAR2,
+ 0x00000000);
+ out32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET +
PCI_P2O_BAR2_UPPER,
+ 0x00000000);
+ __asm__ __volatile__("sync");
+
+#ifndef DISABLE_PBM
+ /*
+ * The memory mapped window assotiated with PCI P2O_BAR3
provides
+ * access to the system memory using SDRAM OCN port and address
+ * translation. This is alternative way to access SDRAM from
PCI
+ * required for Tsi108 emulation testing.
+ * All system memory is opened for accesses initiated by
+ * PCI/X bus masters.
+ *
+ * Initialize LUT associated with PCI P2O_BAR3
+ *
+ * set pointer to LUT associated with PCI P2O_BAR3
+ */
+ reg_ptr =
+ (ulong *) (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET +
0x600);
+
+ reg_val = 0x00000004; /* Destination port = SDC */
+
+ for (i = 0; i < 32; i++) {
+ *reg_ptr++ = reg_val; /* P2O_BAR3_LUTx */
+
+/* P2O_BAR3_LUT_UPPERx : Set data swapping mode for PBM (byte swapping)
*/
+ *reg_ptr++ = 0;
+
+/* offset = 16MB, address translation is enabled to allow byte swapping
*/
+ reg_val += 0x01000000;
+ }
+
+ __asm__ __volatile__("eieio");
+ __asm__ __volatile__("sync");
+
+ /* Configure PCI P2O_BAR3 (size = 512MB, Enabled) */
+
+ reg_val =
+ in32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET +
+ PCI_P2O_PAGE_SIZES);
+ reg_val &= ~0x00FF;
+ reg_val |= 0x0071;
+ out32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET +
PCI_P2O_PAGE_SIZES,
+ reg_val);
+ __asm__ __volatile__("sync");
+
+ /* Set 64-bit base PCI bus address for window (0x20000000) */
+
+ out32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET +
PCI_P2O_BAR3_UPPER,
+ 0x00000000);
+ out32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET +
PCI_P2O_BAR3,
+ 0x20000000);
+ __asm__ __volatile__("sync");
+
+#endif /* !DISABLE_PBM */
+
+#ifdef ENABLE_PCI_CSR_BAR
+ /* open if required access to Tsi108 CSRs from the PCI/X bus */
+ /* enable BAR0 on the PCI/X bus */
+ reg_val =
+ in32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET +
PCI_MISC_CSR);
+ reg_val |= 0x02;
+ out32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET +
PCI_MISC_CSR,
+ reg_val);
+ __asm__ __volatile__("sync");
+
+ out32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET +
PCI_P2O_BAR0_UPPER,
+ 0x00000000);
+ out32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET +
PCI_P2O_BAR0,
+ CFG_TSI108_CSR_BASE);
+ __asm__ __volatile__("sync");
+
+#endif
+
+ /*
+ * Finally enable PCI/X Bus Master and Memory Space access
+ */
+
+ reg_val = in32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET +
PCI_CSR);
+ reg_val |= 0x06;
+ out32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_CSR,
reg_val);
+ __asm__ __volatile__("sync");
+
+#endif /* CONFIG_PCI */
+
+ /*
+ * Initialize MPIC outputs (interrupt pins):
+ * Interrupt routing on the Grendel Emul. Board:
+ * PB_INT[0] -> INT (CPU0)
+ * PB_INT[1] -> INT (CPU1)
+ * PB_INT[2] -> MCP (CPU0)
+ * PB_INT[3] -> MCP (CPU1)
+ * Set interrupt controller outputs as
Level_Sensitive/Active_Low
+ */
+ out32(CFG_TSI108_CSR_BASE + TSI108_MPIC_REG_OFFSET +
MPIC_CSR(0), 0x02);
+ out32(CFG_TSI108_CSR_BASE + TSI108_MPIC_REG_OFFSET +
MPIC_CSR(1), 0x02);
+ out32(CFG_TSI108_CSR_BASE + TSI108_MPIC_REG_OFFSET +
MPIC_CSR(2), 0x02);
+ out32(CFG_TSI108_CSR_BASE + TSI108_MPIC_REG_OFFSET +
MPIC_CSR(3), 0x02);
+ __asm__ __volatile__("sync");
+
+ /*
+ * Ensure that Machine Check exception is enabled
+ * We need it to support PCI Bus probing (configuration reads)
+ */
+
+ reg_val = mfmsr();
+ mtmsr(reg_val | MSR_ME);
+
+ return 0;
+}
+
+/*
+ * Needed to print out L2 cache info
+ * used in the misc_init_r function
+ */
+
+unsigned long get_l2cr(void)
+{
+ unsigned long l2controlreg;
+ asm volatile ("mfspr %0, 1017":"=r" (l2controlreg):);
+ return l2controlreg;
+}
+
+/*
+ * misc_init_r()
+ *
+ * various things to do after relocation
+ *
+ */
+
+int misc_init_r(void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+#ifdef CFG_CLK_SPREAD /* Initialize Spread-Spectrum Clock generation
*/
+ ulong i;
+
+ /* Ensure that Spread-Spectrum is disabled */
+ out32(CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET +
CG_PLL0_CTRL0, 0);
+ out32(CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET +
CG_PLL1_CTRL0, 0);
+
+ /* Initialize PLL1: CG_PCI_CLK , internal OCN_CLK
+ * Uses pre-calculated value for Fout = 800 MHz, Fs = 30 kHz, D
= 0.5%
+ */
+
+ out32(CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET +
CG_PLL1_CTRL0, 0x002e0044); /* D = 0.25% */
+ out32(CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET +
CG_PLL1_CTRL1, 0x00000039); /* BWADJ */
+
+ /* Initialize PLL0: CG_PB_CLKO */
+ /* Detect PB clock freq. */
+ i = in32(CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET +
CG_PWRUP_STATUS);
+ i = (i >> 16) & 0x07; /* Get PB PLL multiplier */
+
+ out32(CFG_TSI108_CSR_BASE +
+ TSI108_CLK_REG_OFFSET + CG_PLL0_CTRL0,
pll0_config[i].ctrl0);
+ out32(CFG_TSI108_CSR_BASE +
+ TSI108_CLK_REG_OFFSET + CG_PLL0_CTRL1,
pll0_config[i].ctrl1);
+
+ /* Wait and set SSEN for both PLL0 and 1 */
+ udelay(1000);
+ out32(CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET +
CG_PLL1_CTRL0, 0x802e0044); /* D=0.25% */
+ out32(CFG_TSI108_CSR_BASE +
+ TSI108_CLK_REG_OFFSET + CG_PLL0_CTRL0,
+ 0x80000000 | pll0_config[i].ctrl0);
+#endif /* CFG_CLK_SPREAD */
+
+#ifdef CFG_L2
+ l2cache_enable();
+#endif
+ printf("BUS: %d MHz\n", gd->bus_clk / 1000000);
+ printf("MEM: %d MHz\n", gd->mem_clk / 1000000);
+
+ /*
+ * All the information needed to print the cache details is
avaiblable
+ * at this point i.e. above call to l2cache_enable is the very
last
+ * thing done with regards to enabling diabling the cache.
+ * So this seems like a good place to print all this information
+ */
+
+ printf("CACHE: ");
+ switch (get_cpu_type()) {
+ case CPU_7447A:
+ printf("L1 Instruction cache - 32KB 8-way");
+ (get_hid0() & (1 << 15)) ? printf(" ENABLED\n") :
+ printf(" DISABLED\n");
+ printf(" L1 Data cache - 32KB 8-way");
+ (get_hid0() & (1 << 14)) ? printf(" ENABLED\n") :
+ printf(" DISABLED\n");
+ printf(" Unified L2 cache - 512KB 8-way");
+ (get_l2cr() & (1 << 31)) ? printf(" ENABLED\n") :
+ printf(" DISABLED\n");
+ printf("\n");
+ break;
+
+ case CPU_7448:
+ printf("L1 Instruction cache - 32KB 8-way");
+ (get_hid0() & (1 << 15)) ? printf(" ENABLED\n") :
+ printf(" DISABLED\n");
+ printf(" L1 Data cache - 32KB 8-way");
+ (get_hid0() & (1 << 14)) ? printf(" ENABLED\n") :
+ printf(" DISABLED\n");
+ printf(" Unified L2 cache - 1MB 8-way");
+ (get_l2cr() & (1 << 31)) ? printf(" ENABLED\n") :
+ printf(" DISABLED\n");
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
--
1.4.0
1
1

[U-Boot-Users] [PATCH 01/07 v2 ]: General code modification for mpc7448hpc2 board
by Zang Roy-r61911 02 Nov '06
by Zang Roy-r61911 02 Nov '06
02 Nov '06
General code modification for mpc7448hpc2 board support.
1. Add 7447A and 7448 processor support.
2. Add the following flags.
CFG_CONFIG_BUS_CLK : If the 74xx bus frequency can be configured
dynamically
(such as by switch on board), this flag should be set.
CFG_EXCEPTION_AFTER_RELOCATE: If an exception occurs after the u-boot
relocates to RAM, this flag should be set
CFG_SERIAL_HANG_IN_EXCEPTION: If the print out function will cause the
system hang in
exception, this flag should be set.
There is a design issue for tsi108/109 pci configure read.
When pci scan the slots, if there is no pci card, the tsi108/9
will cause a machine check exception for mpc7448 processor.
Signed-off-by: Alexandre Bounine <alexandreb(a)tundra.com>
Signed-off-by: Roy Zang <tie-fei.zang(a)freescale.com>
---
MAKEALL | 4 +--
Makefile | 3 ++
README | 22 ++++++++--------
cpu/74xx_7xx/cpu.c | 22 ++++++++++++++--
cpu/74xx_7xx/cpu_init.c | 2 +
cpu/74xx_7xx/speed.c | 55
++++++++++++++++++++++++++++++++++++++---
drivers/Makefile | 6 ++--
include/74xx_7xx.h | 1 +
include/asm-ppc/global_data.h | 3 ++
lib_ppc/extable.c | 10 +++++++
10 files changed, 105 insertions(+), 23 deletions(-)
diff --git a/MAKEALL b/MAKEALL
index 467a9be..2f41936 100755
--- a/MAKEALL
+++ b/MAKEALL
@@ -139,8 +139,8 @@ ## 74xx/7xx Systems
########################################################################
#
LIST_74xx=" \
- DB64360 DB64460 EVB64260 P3G4
\
- PCIPPC2 PCIPPC6 ZUMA
\
+ DB64360 DB64460 EVB64260 mpc7448hpc2
\
+ P3G4 PCIPPC2 PCIPPC6 ZUMA
\
"
LIST_7xx=" \
diff --git a/Makefile b/Makefile
index 128ae59..c910f39 100644
--- a/Makefile
+++ b/Makefile
@@ -1489,6 +1489,9 @@ EVB64260_config \
EVB64260_750CX_config: unconfig
@./mkconfig EVB64260 ppc 74xx_7xx evb64260
+mpc7448hpc2_config: unconfig
+ @./mkconfig $(@:_config=) ppc 74xx_7xx mpc7448hpc2
+
P3G4_config: unconfig
@./mkconfig $(@:_config=) ppc 74xx_7xx evb64260
diff --git a/README b/README
index e772c1a..f7f53d1 100644
--- a/README
+++ b/README
@@ -2289,17 +2289,17 @@ configurations; the following names are
csb272_config lwmon_config sbc8260_config
CU824_config MBX860T_config
sbc8560_33_config
DUET_ADS_config MBX_config
sbc8560_66_config
- EBONY_config MPC8260ADS_config SM850_config
- ELPT860_config MPC8540ADS_config SPD823TS_config
- ESTEEM192E_config MPC8540EVAL_config stxgp3_config
- ETX094_config MPC8560ADS_config SXNI855T_config
- FADS823_config NETVIA_config TQM823L_config
- FADS850SAR_config omap1510inn_config TQM850L_config
- FADS860T_config omap1610h2_config TQM855L_config
- FPS850L_config omap1610inn_config TQM860L_config
- omap5912osk_config walnut_config
- omap2420h4_config Yukon8220_config
- ZPC1900_config
+ EBONY_config mpc7448hpc2_config SM850_config
+ ELPT860_config MPC8260ADS_config SPD823TS_config
+ ESTEEM192E_config MPC8540ADS_config stxgp3_config
+ ETX094_config MPC8540EVAL_config SXNI855T_config
+ FADS823_config NMPC8560ADS_config TQM823L_config
+ FADS850SAR_config NETVIA_config TQM850L_config
+ FADS860T_config omap1510inn_config TQM855L_config
+ FPS850L_config omap1610h2_config TQM860L_config
+ omap1610inn_config walnut_config
+ omap5912osk_config Yukon8220_config
+ omap2420h4_config ZPC1900_config
Note: for some board special configuration names may exist; check if
additional information is available from the board vendor; for
diff --git a/cpu/74xx_7xx/cpu.c b/cpu/74xx_7xx/cpu.c
index ca45e17..f159557 100644
--- a/cpu/74xx_7xx/cpu.c
+++ b/cpu/74xx_7xx/cpu.c
@@ -101,6 +101,14 @@ get_cpu_type(void)
type = CPU_7457;
break;
+ case 0x8003:
+ type = CPU_7447A;
+ break;
+
+ case 0x8004:
+ type = CPU_7448;
+ break;
+
default:
break;
}
@@ -164,6 +172,14 @@ int checkcpu (void)
str = "MPC7457";
break;
+ case CPU_7447A:
+ str = "MPC7447A";
+ break;
+
+ case CPU_7448:
+ str = "MPC7448";
+ break;
+
default:
printf("Unknown CPU -- PVR: 0x%08x\n", pvr);
return -1;
@@ -256,18 +272,18 @@ #endif
/*
* For the 7400 the TB clock runs at 1/4 the cpu bus speed.
*/
-#ifdef CONFIG_AMIGAONEG3SE
+#if defined(CONFIG_AMIGAONEG3SE) || defined(CFG_CONFIG_BUS_CLK)
unsigned long get_tbclk(void)
{
return (gd->bus_clk / 4);
}
-#else /* ! CONFIG_AMIGAONEG3SE */
+#else /* ! CONFIG_AMIGAONEG3SE and !CFG_CONFIG_BUS_CLK*/
unsigned long get_tbclk (void)
{
return CFG_BUS_HZ / 4;
}
-#endif /* CONFIG_AMIGAONEG3SE */
+#endif /* CONFIG_AMIGAONEG3SE or CFG_CONFIG_BUS_CLK*/
/*
------------------------------------------------------------------------
- */
#if defined(CONFIG_WATCHDOG)
diff --git a/cpu/74xx_7xx/cpu_init.c b/cpu/74xx_7xx/cpu_init.c
index 93f180f..1dd1b2c 100644
--- a/cpu/74xx_7xx/cpu_init.c
+++ b/cpu/74xx_7xx/cpu_init.c
@@ -43,6 +43,8 @@ cpu_init_f (void)
case CPU_7450:
case CPU_7455:
case CPU_7457:
+ case CPU_7447A:
+ case CPU_7448:
/* enable the timebase bit in HID0 */
set_hid0(get_hid0() | 0x4000000);
break;
diff --git a/cpu/74xx_7xx/speed.c b/cpu/74xx_7xx/speed.c
index 2dc5107..d520794 100644
--- a/cpu/74xx_7xx/speed.c
+++ b/cpu/74xx_7xx/speed.c
@@ -31,6 +31,8 @@ #endif
DECLARE_GLOBAL_DATA_PTR;
+extern unsigned long get_board_bus_clk(void);
+
static const int hid1_multipliers_x_10[] = {
25, /* 0000 - 2.5x */
75, /* 0001 - 7.5x */
@@ -50,6 +52,41 @@ static const int hid1_multipliers_x_10[]
0 /* 1111 - off */
};
+static const int hid1_7447A_multipliers_x_10[] = {
+ 115, /* 00000 - 11.5x */
+ 170, /* 00001 - 17x */
+ 75, /* 00010 - 7.5x */
+ 150, /* 00011 - 15x */
+ 70, /* 00100 - 7x */
+ 180, /* 00101 - 18x */
+ 10, /* 00110 - bypass */
+ 200, /* 00111 - 20x */
+ 20, /* 01000 - 2x */
+ 210, /* 01001 - 21x */
+ 65, /* 01010 - 6.5x */
+ 130, /* 01011 - 13x */
+ 85, /* 01100 - 8.5x */
+ 240, /* 01101 - 13x */
+ 95, /* 01110 - 9.5x */
+ 90, /* 01111 - 9x */
+ 30, /* 10000 - 3x */
+ 105, /* 10001 - 10.5x */
+ 55, /* 10010 - 5.5x */
+ 110, /* 10011 - 11x */
+ 40, /* 10100 - 4x */
+ 100, /* 10101 - 10x */
+ 50, /* 10110 - 5x */
+ 120, /* 10111 - 12x */
+ 80, /* 11000 - 8x */
+ 140, /* 11001 - 14x */
+ 60, /* 11010 - 6x */
+ 160, /* 11011 - 16x */
+ 135, /* 11100 - 13.5x */
+ 280, /* 11101 - 28x */
+ 0, /* 11110 - off */
+ 125 /* 11111 - 12.5x */
+};
+
static const int hid1_fx_multipliers_x_10[] = {
00, /* 0000 - off */
00, /* 0001 - off */
@@ -89,8 +126,19 @@ int get_clocks (void)
{
ulong clock = 0;
+#ifdef CFG_CONFIG_BUS_CLK
+ gd->bus_clk = get_board_bus_clk();
+#else
+ gd->bus_clk = CFG_BUS_CLK;
+#endif
+
/* calculate the clock frequency based upon the CPU type */
switch (get_cpu_type()) {
+ case CPU_7447A:
+ case CPU_7448:
+ clock = (gd->bus_clk / 10) *
hid1_7447A_multipliers_x_10[(get_hid1 () >> 12) & 0x1F];
+ break;
+
case CPU_7455:
case CPU_7457:
/*
@@ -98,12 +146,12 @@ int get_clocks (void)
* Make sure division is done before multiplication to
prevent 32-bit
* arithmetic overflows which will cause a negative
number
*/
- clock = (CFG_BUS_CLK / 10) *
hid1_multipliers_x_10[(get_hid1 () >> 13) & 0xF];
+ clock = (gd->bus_clk / 10) *
hid1_multipliers_x_10[(get_hid1 () >> 13) & 0xF];
break;
case CPU_750GX:
case CPU_750FX:
- clock = CFG_BUS_CLK * hid1_fx_multipliers_x_10[get_hid1
() >> 27] / 10;
+ clock = gd->bus_clk * hid1_fx_multipliers_x_10[get_hid1
() >> 27] / 10;
break;
case CPU_7450:
@@ -120,7 +168,7 @@ int get_clocks (void)
* Make sure division is done before multiplication to
prevent 32-bit
* arithmetic overflows which will cause a negative
number
*/
- clock = (CFG_BUS_CLK / 10) *
hid1_multipliers_x_10[get_hid1 () >> 28];
+ clock = (gd->bus_clk / 10) *
hid1_multipliers_x_10[get_hid1 () >> 28];
break;
case CPU_UNKNOWN:
@@ -130,7 +178,6 @@ int get_clocks (void)
}
gd->cpu_clk = clock;
- gd->bus_clk = CFG_BUS_CLK;
return (0);
}
diff --git a/drivers/Makefile b/drivers/Makefile
index 9be95c7..8b18b37 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -35,8 +35,8 @@ OBJS = 3c589.o 5701rls.o ali512x.o \
lan91c96.o \
natsemi.o ne2000.o netarm_eth.o netconsole.o \
ns16550.o ns8382x.o ns87308.o ns7520_eth.o omap1510_i2c.o \
- omap24xx_i2c.o pci.o pci_auto.o pci_indirect.o \
- pcnet.o plb2800_eth.o \
+ omap24xx_i2c.o pci.o pci_auto.o pci_indirect.o tsi108_pci.o\
+ tsi108_i2c.o pcnet.o plb2800_eth.o \
ps2ser.o ps2mult.o pc_keyb.o \
rtl8019.o rtl8139.o rtl8169.o \
s3c4510b_eth.o s3c4510b_uart.o \
@@ -45,7 +45,7 @@ OBJS = 3c589.o 5701rls.o ali512x.o \
serial_pl010.o serial_pl011.o serial_xuartlite.o \
sl811_usb.o sm501.o smc91111.o smiLynxEM.o \
status_led.o sym53c8xx.o \
- ti_pci1410a.o tigon3.o tsec.o \
+ ti_pci1410a.o tigon3.o tsec.o tsi108_eth.o\
usbdcore.o usbdcore_ep0.o usbdcore_omap1510.o usbtty.o \
videomodes.o w83c553f.o \
ks8695eth.o \
diff --git a/include/74xx_7xx.h b/include/74xx_7xx.h
index a628798..7cd2f10 100644
--- a/include/74xx_7xx.h
+++ b/include/74xx_7xx.h
@@ -112,6 +112,7 @@ typedef enum __cpu_t {
CPU_7400,
CPU_7410,
CPU_7450, CPU_7455, CPU_7457,
+ CPU_7447A, CPU_7448,
CPU_UNKNOWN} cpu_t;
extern cpu_t get_cpu_type(void);
diff --git a/include/asm-ppc/global_data.h
b/include/asm-ppc/global_data.h
index b73af96..166afbe 100644
--- a/include/asm-ppc/global_data.h
+++ b/include/asm-ppc/global_data.h
@@ -49,6 +49,9 @@ #if defined(CONFIG_CPM2)
unsigned long scc_clk;
unsigned long brg_clk;
#endif
+#if defined(CONFIG_MPC7448HPC2)
+ unsigned long mem_clk;
+#endif
#if defined(CONFIG_MPC83XX)
/* There are other clocks in the MPC83XX */
u32 csb_clk;
diff --git a/lib_ppc/extable.c b/lib_ppc/extable.c
index d92f142..34b5d46 100644
--- a/lib_ppc/extable.c
+++ b/lib_ppc/extable.c
@@ -50,14 +50,22 @@ search_one_table(const struct exception_
const struct exception_table_entry *last,
unsigned long value)
{
+ DECLARE_GLOBAL_DATA_PTR;
+
while (first <= last) {
const struct exception_table_entry *mid;
long diff;
mid = (last - first) / 2 + first;
+#ifdef CFG_EXCEPTION_AFTER_RELOCATE
+ diff = (mid->insn + gd->reloc_off) - value;
+ if (diff == 0)
+ return (mid->fixup + gd->reloc_off);
+#else
diff = mid->insn - value;
if (diff == 0)
return mid->fixup;
+#endif
else if (diff < 0)
first = mid+1;
else
@@ -75,8 +83,10 @@ search_exception_table(unsigned long add
/* There is only the kernel to search. */
ret = search_one_table(__start___ex_table, __stop___ex_table-1,
addr);
+#if !defined(CFG_SERIAL_HANG_IN_EXCEPTION)
if (ex_tab_message)
printf("Bus Fault @ 0x%08lx, fixup 0x%08lx\n", addr,
ret);
+#endif
if (ret) return ret;
return 0;
--
1.4.0
1
1

29 Oct '06
Signed-off-by: Ladislav Michl <ladis(a)linux-mips.org>
CHANGELOG
* omap925.c - remove nowhere used functions
Patch by Ladislav Michl, 25 Jul 2006
diff --git a/include/arm925t.h b/include/arm925t.h
index ab343ea..3d767b3 100644
--- a/include/arm925t.h
+++ b/include/arm925t.h
@@ -6,10 +6,6 @@
#ifndef __ARM925T_H__
#define __ARM925T_H__
-void gpioreserve(ushort mask);
-void gpiosetdir(ushort mask, ushort in);
-void gpiosetout(ushort mask, ushort out);
-void gpioinit(void);
void archflashwp(void *archdata, int wp);
#endif /*__ARM925T_H__*/
diff --git a/cpu/arm925t/omap925.c b/cpu/arm925t/omap925.c
index ae62656..65dab9f 100644
--- a/cpu/arm925t/omap925.c
+++ b/cpu/arm925t/omap925.c
@@ -25,40 +25,6 @@ #include <common.h>
#include <command.h>
#include <arm925t.h>
-ushort gpioreserved;
-
-void gpioreserve(ushort mask)
-{
- gpioreserved |= mask;
-}
-
-void gpiosetdir(ushort mask, ushort in)
-{
- *(ushort *)GPIO_DIR_CONTROL_REG = (*(ushort *)GPIO_DIR_CONTROL_REG & ~mask) | (in & mask);
-}
-
-
-void gpiosetout(ushort mask, ushort out)
-{
- ushort *r_ptr, r_val;
-
- r_ptr = (ushort *)GPIO_DATA_OUTPUT_REG; /* set pointer */
- r_val = *r_ptr & ~mask; /* get previous val, clear bits we want to change */
- r_val |= (out & mask); /* set specified bits in value + plus origional ones */
- *r_ptr = r_val; /* write it out */
-/*
- * gcc screwed this one up :(.
- *
- * *(ushort *)GPIO_DATA_OUTPUT_REG = (*(ushort *)GPIO_DATA_OUTPUT_REG & ~mask) | (out & mask);
- */
-
-}
-
-void gpioinit(void)
-{
-}
-
-
#define MIF_CONFIG_REG 0xFFFECC0C
#define FLASH_GLOBAL_CTRL_NWP 1
2
1
Hi there.
I'm just trying to sync with U-Boot development and found a little
regresion in new mtdparts code. Previously I was using custom partition
function, which let me do precisely what I wanted.
mtd0 - U-Boot
mtd1 - env
mtd2 - r_env
mtd3 - rootfs0
mtd4 - rootfs1
... etc
In above scheme my custom part function allowed only chpart [34], so it
was not even possible to change partition to evn sector for example.
Moreover it was pretty easy to construct kernel command line this way:
setenv bootargs '$bootargs root=/dev/mtdblock$partition ro rootfstype=jffs2'
And everything worked nicely. That is no longer case and it's real pain
with both NOR and NAND devices used in system.
Prefered solution for me is to fix kernel to be able to mount root
filesystem from MTD device given by name (root=mtd:rootfs0) unless
someone has better idea :-). Something which would work also with 2.4
kernels would be appreciated.
ladis
6
14

24 Oct '06
In config.mk, -Wa,-gstabs is unconditionally appended to AFLAGS no
matter what the target's preferred debugging format is. The AVR32
toolchain doesn't support the stabs debugging format at all, so this
will obviously not work.
This patch simply replaces -gstabs with -g, so that the default
debugging format for the architecture is used.
Signed-off-by: Haavard Skinnemoen <hskinnemoen(a)atmel.com>
---
config.mk | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/config.mk b/config.mk
index b59667a..07ade42 100644
--- a/config.mk
+++ b/config.mk
@@ -143,7 +143,7 @@ CFLAGS := $(CPPFLAGS) -Wall -Wno-trigrap
endif
endif
-AFLAGS_DEBUG := -Wa,-gstabs
+AFLAGS_DEBUG := -Wa,-g
# turn jbsr into jsr for m68k
ifeq ($(ARCH),m68k)
--
1.4.1.1
2
1