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
October 2006
- 134 participants
- 267 discussions
I am having trouble getting Ethernet to work correctly on our Embedded Planet
EP82xxM board. Specifically, pings and TFTP transfers fail when the board is
populated with an MPC8250 or an MPC8270. However, when the board is populated
with an MPC8280 processor, Ethernet works. Any suggestions of things to try out
to resolve this would be greatly appreciated.
FCC2/3 port pins appear to be correctly configured.
PHY registers are able to be accessed and seem to show the correct configuration.
No packets are appearing on the wire when sniffed with Ethereal.
With ET_DEBUG turned on, pinging results in the following output:
ep82xxm=> ping 10.0.0.26
Using FCC3 ETHERNET device
sending ARP for 0a00001a
ARP broadcast 1
packet received
packet received
Receive from protocol 0x0
packet received
packet received
Receive from protocol 0x0
.
.
.
ARP broadcast 2
packet received
packet received
Receive from protocol 0x0
packet received
packet received
Receive from protocol 0x0
.
.
.
ping failed; host 10.0.0.26 is not alive
MII info and dump result in the following output:
ep82xxm=> mii info
PHY 0x00: OUI = 0x04DE, Model = 0x0E, Rev = 0x02, 100baseT, FDX
PHY 0x01: OUI = 0x04DE, Model = 0x0E, Rev = 0x02, 10baseT, HDX
ep82xxm=> mii dump 0 0-5
0. (3100) -- PHY control register --
(8000:0000) 0.15 = 0 reset
(4000:0000) 0.14 = 0 loopback
(2040:2000) 0. 6,13 = b01 speed selection = 100 Mbps
(1000:1000) 0.12 = 1 A/N enable
(0800:0000) 0.11 = 0 power-down
(0400:0000) 0.10 = 0 isolate
(0200:0000) 0. 9 = 0 restart A/N
(0100:0100) 0. 8 = 1 duplex = full
(0080:0000) 0. 7 = 0 collision test enable
(003f:0000) 0. 5- 0 = 0 (reserved)
1. (782d) -- PHY status register --
(8000:0000) 1.15 = 0 100BASE-T4 able
(4000:4000) 1.14 = 1 100BASE-X full duplex able
(2000:2000) 1.13 = 1 100BASE-X half duplex able
(1000:1000) 1.12 = 1 10 Mbps full duplex able
(0800:0800) 1.11 = 1 10 Mbps half duplex able
(0400:0000) 1.10 = 0 100BASE-T2 full duplex able
(0200:0000) 1. 9 = 0 100BASE-T2 half duplex able
(0100:0000) 1. 8 = 0 extended status
(0080:0000) 1. 7 = 0 (reserved)
(0040:0000) 1. 6 = 0 MF preamble suppression
(0020:0020) 1. 5 = 1 A/N complete
(0010:0000) 1. 4 = 0 remote fault
(0008:0008) 1. 3 = 1 A/N able
(0004:0004) 1. 2 = 1 link status
(0002:0000) 1. 1 = 0 jabber detect
(0001:0001) 1. 0 = 1 extended capabilities
2. (0013) -- PHY ID 1 register --
(ffff:0013) 2.15- 0 = 19 OUI portion
3. (78e2) -- PHY ID 2 register --
(fc00:7800) 3.15-10 = 30 OUI portion
(03f0:00e0) 3. 9- 4 = 14 manufacturer part number
(000f:0002) 3. 3- 0 = 2 manufacturer rev. number
4. (01e1) -- Autonegotiation advertisement register --
(8000:0000) 4.15 = 0 next page able
(4000:0000) 4.14 = 0 reserved
(2000:0000) 4.13 = 0 remote fault
(1000:0000) 4.12 = 0 reserved
(0800:0000) 4.11 = 0 asymmetric pause
(0400:0000) 4.10 = 0 pause enable
(0200:0000) 4. 9 = 0 100BASE-T4 able
(0100:0100) 4. 8 = 1 100BASE-TX full duplex able
(0080:0080) 4. 7 = 1 100BASE-TX able
(0040:0040) 4. 6 = 1 10BASE-T full duplex able
(0020:0020) 4. 5 = 1 10BASE-T able
(001f:0001) 4. 4- 0 = 1 selector = IEEE 802.3
5. (45e1) -- Autonegotiation partner abilities register --
(8000:0000) 5.15 = 0 next page able
(4000:4000) 5.14 = 1 acknowledge
(2000:0000) 5.13 = 0 remote fault
(1000:0000) 5.12 = 0 (reserved)
(0800:0000) 5.11 = 0 asymmetric pause able
(0400:0400) 5.10 = 1 pause able
(0200:0000) 5. 9 = 0 100BASE-T4 able
(0100:0100) 5. 8 = 1 100BASE-X full duplex able
(0080:0080) 5. 7 = 1 100BASE-TX able
(0040:0040) 5. 6 = 1 10BASE-T full duplex able
(0020:0020) 5. 5 = 1 10BASE-T able
(001f:0001) 5. 4- 0 = 1 selector = IEEE 802.3
My environment settings are as follows:
ep82xxm=> printenv
bootdelay=5
baudrate=115200
ethaddr=00:10:EC:00:88:66
eth1addr=00:10:EC:80:88:66
ipaddr=10.0.0.245
serverip=10.0.0.26
gatewayip=10.0.0.1
netmask=255.255.255.0
hostname=EP82xxM
ethprime=FCC3 ETHERNET
stdin=serial
stdout=serial
stderr=serial
ethact=FCC3 ETHERNET
Thanks for your help!
3
3

[U-Boot-Users] [PATCH 02/07 v2]: mpc7448hpc2 platform support (part 3/4 misc )
by Zang Roy-r61911 03 Nov '06
by Zang Roy-r61911 03 Nov '06
03 Nov '06
Add mpc7448hpc2 (mpc7448 + tsi108) board associated code support.
The original one is too big and divided into 4 parts for review.
Make ,config and link file for the board.
Signed-off-by: Alexandre Bounine <alexandreb(a)tundra.com>
Signed-off-by: Roy Zang <tie-fei.zang(a)freescale.com>
--
board/mpc7448hpc2/Makefile | 48 ++
board/mpc7448hpc2/config.mk | 28 +
board/mpc7448hpc2/u-boot.lds | 136 ++++++
3 files changed, 212 insertions(+), 0 deletions(-)
diff --git a/board/mpc7448hpc2/Makefile b/board/mpc7448hpc2/Makefile
new file mode 100644
index 0000000..d5ed01f
--- /dev/null
+++ b/board/mpc7448hpc2/Makefile
@@ -0,0 +1,48 @@
+#
+# (C) Copyright 2000
+# Wolfgang Denk, DENX Software Engineering, wd(a)denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = lib$(BOARD).a
+
+OBJS = $(BOARD).o tsi108_init.o
+
+SOBJS = asm_init.o
+
+$(LIB): .depend $(OBJS) $(SOBJS)
+ $(AR) crv $@ $(OBJS) $(SOBJS)
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak .depend
+
+#######################################################################
##
+
+.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
+ $(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#######################################################################
##
diff --git a/board/mpc7448hpc2/config.mk b/board/mpc7448hpc2/config.mk
new file mode 100644
index 0000000..9147a5c
--- /dev/null
+++ b/board/mpc7448hpc2/config.mk
@@ -0,0 +1,28 @@
+#
+# 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
+#
+
+# Flash address
+TEXT_BASE = 0xFFF00000
+# RAM address
+#TEXT_BASE = 0x00400000
+
+PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -maltivec -mabi=altivec
-msoft-float
diff --git a/board/mpc7448hpc2/u-boot.lds b/board/mpc7448hpc2/u-boot.lds
new file mode 100644
index 0000000..8f24213
--- /dev/null
+++ b/board/mpc7448hpc2/u-boot.lds
@@ -0,0 +1,136 @@
+/*
+ * (C) Copyright 2001
+ * Josh Huber <huber(a)mclx.com>, Mission Critical Linux, 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
+ */
+
+/*
+ * u-boot.lds - linker script for U-Boot on mpc7448hpc2 Board.
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib);
SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+ __DYNAMIC = 0; */
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = + SIZEOF_HEADERS;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) }
+ .plt : { *(.plt) }
+ .text :
+ {
+ cpu/74xx_7xx/start.o (.text)
+
+/* store the environment in a seperate sector in the boot flash */
+/* . = env_offset; */
+/* common/environment.o(.text) */
+
+ *(.text)
+ *(.fixup)
+ *(.got1)
+ }
+ _etext = .;
+ PROVIDE (etext = .);
+ .rodata :
+ {
+ *(.rodata)
+ *(.rodata1)
+ *(.rodata.str1.4)
+ }
+ .fini : { *(.fini) } =0
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+
+ /* Read-write section, merged into data segment: */
+ . = (. + 0x00FF) & 0xFFFFFF00;
+ _erotext = .;
+ PROVIDE (erotext = .);
+ .reloc :
+ {
+ *(.got)
+ _GOT2_TABLE_ = .;
+ *(.got2)
+ _FIXUP_TABLE_ = .;
+ *(.fixup)
+ }
+ __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+ __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.dynamic)
+ CONSTRUCTORS
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+
+ . = .;
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) }
+ __u_boot_cmd_end = .;
+
+ . = .;
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
+
+ . = ALIGN(256);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(256);
+ __init_end = .;
+
+ __bss_start = .;
+ .bss :
+ {
+ *(.sbss) *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ _end = . ;
+ PROVIDE (end = .);
+}
--
1.4.0
2
3

[U-Boot-Users] [PATCH] Add a oftdump (open firmware flattened tree dump) command.
by Jerry Van Baren 02 Nov '06
by Jerry Van Baren 02 Nov '06
02 Nov '06
Add a oftdump (open firmware flattened tree dump) command.
Git repository:
<http://www.cideas.us/cgi-bin/gitweb.cgi?p=u-boot/u-boot-of-cmd.git;a=summary>
Branch: of-cmd
<http://www.cideas.us/cgi-bin/gitweb.cgi?p=u-boot/u-boot-of-cmd.git;a=shortl…>
Signed-off-by: Jerry Van Baren <vanbaren(a)cideas.com>
>From 20328071e132c40c662ffb2a07460144841b9e1a Mon Sep 17 00:00:00 2001
From: Jerry Van Baren <vanbaren(a)cideas.com>
Date: Mon, 30 Oct 2006 21:47:02 -0500
Subject: [PATCH] Add a oftdump (open firmware flattened tree dump) command.
---
common/Makefile | 2 +-
common/cmd_bootm.c | 2 --
common/cmd_oftdump.c | 58 +++++++++++++++++++++++++++++++++++++++++++++
common/ft_build.c | 65 ++++++++++++++++++++++++++++++++++++++++++--------
include/ft_build.h | 2 +-
5 files changed, 114 insertions(+), 15 deletions(-)
diff --git a/common/Makefile b/common/Makefile
index 07ddc95..477aadb 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -37,7 +37,7 @@ COBJS = main.o ACEX1K.o altera.o bedbug.
cmd_i2c.o cmd_ide.o cmd_immap.o cmd_itest.o cmd_jffs2.o \
cmd_load.o cmd_log.o \
cmd_mem.o cmd_mii.o cmd_misc.o cmd_mmc.o \
- cmd_nand.o cmd_net.o cmd_nvedit.o \
+ cmd_nand.o cmd_net.o cmd_nvedit.o cmd_oftdump.o \
cmd_pci.o cmd_pcmcia.o cmd_portio.o \
cmd_reginfo.o cmd_reiser.o cmd_scsi.o cmd_spi.o cmd_universe.o \
cmd_usb.o cmd_vfd.o \
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index 3091a58..1797328 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -950,7 +950,6 @@ #else /* CONFIG_OF_FLAT_TREE */
}
ft_setup(of_flat_tree, kbd, initrd_start, initrd_end);
- /* ft_dump_blob(of_flat_tree); */
#if defined(CFG_INIT_RAM_LOCK) && !defined(CONFIG_E500)
unlock_ram_in_cache();
@@ -968,7 +967,6 @@ #endif
cmd_start, cmd_end);
else {
ft_setup(of_flat_tree, kbd, initrd_start, initrd_end);
- /* ft_dump_blob(of_flat_tree); */
(*kernel) ((bd_t *)of_flat_tree, (ulong)kernel, 0, 0, 0);
}
#endif /* CONFIG_OF_FLAT_TREE */
diff --git a/common/cmd_oftdump.c b/common/cmd_oftdump.c
new file mode 100644
index 0000000..5cc1995
--- /dev/null
+++ b/common/cmd_oftdump.c
@@ -0,0 +1,58 @@
+/*
+ * (C) Copyright 2006
+ * Gerald Van Baren, Custom IDEAS, vanbaren(a)cideas.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
+ */
+
+/*
+ * Misc functions
+ */
+#include <common.h>
+#include <command.h>
+#include <ft_build.h>
+
+#ifdef CONFIG_OF_FLAT_TREE
+
+int do_oftdump (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ void *p = (void *)simple_strtoul(argv[1], NULL, 16);
+
+ if (argc < 2) {
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+ } else if (argc == 2) {
+ ft_dump_blob(p, "/");
+ } else {
+ ft_dump_blob(p, argv[2]);
+ }
+
+ return 0;
+}
+
+
+U_BOOT_CMD(
+ oftdump, 3, 0, do_oftdump,
+ "oftdump - Open Firmware flattened tree dump\n",
+ "oftdump <addr> - Dump the whole OF flattened tree\n"
+ "oftdump <addr> <prop> - Dump the given OF property\n"
+);
+
+#endif /* CONFIG_OF_FLAT_TREE */
+
diff --git a/common/ft_build.c b/common/ft_build.c
index 980e40f..4fbe34c 100644
--- a/common/ft_build.c
+++ b/common/ft_build.c
@@ -233,10 +233,19 @@ static void print_data(const void *data,
printf(" = <%04x>", be16_to_cpu(*(u16 *) data) & 0xffff);
break;
case 4: /* word */
- printf(" = <%x>", be32_to_cpu(*(u32 *) data) & 0xffffffffU);
+ printf(" = <%08x>", be32_to_cpu(*(u32 *) data) & 0xffffffffU);
break;
case 8: /* double-word */
- printf(" = <%qx>", be64_to_cpu(*(uint64_t *) data));
+ /*
+ * If 64 bit printing is supported, use it.
+ */
+#ifdef CFG_64BIT_VSPRINTF
+ printf(" = <%016llx>", be64_to_cpu(*(uint64_t *) data));
+#else
+ printf(" = <%08x", be32_to_cpu(*(u32 *) data) & 0xffffffffU);
+ data += sizeof(u32);
+ printf(" %08x>", be32_to_cpu(*(u32 *) data) & 0xffffffffU);
+#endif
break;
default: /* anything else... hexdump */
printf(" = [");
@@ -248,7 +257,12 @@ static void print_data(const void *data,
}
}
-void ft_dump_blob(const void *bphp)
+/*
+ * Used by ft_dump_blob() and ft_get_prop() to build up property names
+ */
+static char path[256], prop[256];
+
+void ft_dump_blob(const void *bphp, const char *propname)
{
const struct boot_param_header *bph = bphp;
const uint64_t *p_rsvmap = (const uint64_t *)
@@ -260,17 +274,22 @@ void ft_dump_blob(const void *bphp)
u32 tag;
const u32 *p;
const char *s, *t;
+ char *ss;
int depth, sz, shift;
+ int found;
int i;
uint64_t addr, size;
if (be32_to_cpu(bph->magic) != OF_DT_HEADER) {
/* not valid tree */
+ printf("Not a valid tree.\n");
return;
}
depth = 0;
shift = 4;
+ found = 0;
+ strcpy(path, "/");
for (i = 0;; i++) {
addr = be64_to_cpu(p_rsvmap[i * 2]);
@@ -290,7 +309,17 @@ void ft_dump_blob(const void *bphp)
s = (const char *)p;
p = (u32 *) _ALIGN((unsigned long)p + strlen(s) + 1, 4);
- printf("%*s%s {\n", depth * shift, "", s);
+ strcat(path, s);
+ if (found || (strcmp(path, propname) == 0)) {
+ found++;
+ if (depth == 0)
+ printf("/ {\n");
+ else
+ printf("%*s%s {\n", depth * shift, "", s);
+ }
+ /* The root path is already there as "/" */
+ if(depth != 0)
+ strcat(path, "/");
depth++;
continue;
@@ -299,7 +328,16 @@ void ft_dump_blob(const void *bphp)
if (tag == OF_DT_END_NODE) {
depth--;
- printf("%*s};\n", depth * shift, "");
+ path[strlen(path) - 1] = '\0';
+ ss = strrchr(path, '/');
+ if (ss != NULL)
+ ss[1] = '\0';
+
+ if(found) {
+ printf("%*s};\n", depth * shift, "");
+ if (found-- == 0)
+ return; /* request done */
+ }
continue;
}
@@ -317,9 +355,15 @@ void ft_dump_blob(const void *bphp)
s = (const char *)p_strings + be32_to_cpu(*p++);
t = (const char *)p;
p = (const u32 *)_ALIGN((unsigned long)p + sz, 4);
- printf("%*s%s", depth * shift, "", s);
- print_data(t, sz);
- printf(";\n");
+
+ strcpy(prop, path);
+ strcat(prop, s);
+
+ if(found || (strcmp(prop, propname) == 0)) {
+ printf("%*s%s", depth * shift, "", s);
+ print_data(t, sz);
+ printf(";\n");
+ }
}
}
@@ -349,7 +393,6 @@ void *ft_get_prop(void *bphp, const char
char *s, *t;
char *ss;
int sz;
- static char path[256], prop[256];
path[0] = '\0';
@@ -478,7 +521,7 @@ #endif
#ifdef DEBUG
printf ("recieved oftree\n");
- ft_dump_blob(blob);
+ ft_dump_blob(blob, "/");
#endif
ft_init_cxt(&cxt, blob);
@@ -585,7 +628,7 @@ #endif
#ifdef DEBUG
printf("final OF-tree\n");
- ft_dump_blob(blob);
+ ft_dump_blob(blob, "/");
#endif
}
#endif
diff --git a/include/ft_build.h b/include/ft_build.h
index 89c689c..5530122 100644
--- a/include/ft_build.h
+++ b/include/ft_build.h
@@ -58,7 +58,7 @@ void ft_add_rsvmap(struct ft_cxt *cxt, u
void ft_setup(void *blob, bd_t * bd, ulong initrd_start, ulong initrd_end);
-void ft_dump_blob(const void *bphp);
+void ft_dump_blob(const void *bphp, const char *propname);
void ft_merge_blob(struct ft_cxt *cxt, void *blob);
void *ft_get_prop(void *bphp, const char *propname, int *szp);
--
1.4.1.1
2
3

[U-Boot-Users] [PATCH] Use the open firmware flattened tree methodology for the PQ2FADS board.
by Jerry Van Baren 02 Nov '06
by Jerry Van Baren 02 Nov '06
02 Nov '06
Use the open firmware flattened tree methodology for the PQ2FADS board.
Git repository:
<http://www.cideas.us/cgi-bin/gitweb.cgi?p=u-boot/u-boot-of-cmd.git;a=summary>
Branch: pq2fads-of
<http://www.cideas.us/cgi-bin/gitweb.cgi?p=u-boot/u-boot-of-cmd.git;a=shortl…>
Signed-off-by: Jerry Van Baren <vanbaren(a)cideas.com>
>From 05dde92cf942f0cae7d731912824cc76c9a040d5 Mon Sep 17 00:00:00 2001
From: Jerry Van Baren <vanbaren(a)cideas.com>
Date: Mon, 30 Oct 2006 20:31:26 -0500
Subject: [PATCH] Use the open firmware flattened tree methodology for the PQ2FADS board.
---
include/configs/MPC8260ADS.h | 11 +++++++++++
1 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/include/configs/MPC8260ADS.h b/include/configs/MPC8260ADS.h
index 6195bca..12e9560 100644
--- a/include/configs/MPC8260ADS.h
+++ b/include/configs/MPC8260ADS.h
@@ -506,4 +506,15 @@ #if CONFIG_ADSTYPE == CFG_8272ADS
#define CONFIG_HAS_ETH1
#endif
+/* pass open firmware flat tree */
+#define CONFIG_OF_FLAT_TREE 1
+
+/* maximum size of the flat tree (8K) */
+#define OF_FLAT_TREE_MAX_SIZE 8192
+
+#define OF_CPU "PowerPC,MPC8272@0"
+#define OF_TBCLK (CONFIG_8260_CLKIN / 4)
+#define CONFIG_OF_HAS_BD_T 1
+#define CONFIG_OF_HAS_UBOOT_ENV 1
+
#endif /* __CONFIG_H */
--
1.4.1.1
2
1

[U-Boot-Users] [PATCH] Enhance vsprintf to handle "ll" long long specifier
by Jerry Van Baren 02 Nov '06
by Jerry Van Baren 02 Nov '06
02 Nov '06
Enhance vsprintf to handle "ll" long long specifier (it already
supported the deprecated "q" specifier).
Git repository:
<http://www.cideas.us/cgi-bin/gitweb.cgi?p=u-boot/u-boot-of-cmd.git;a=summary>
Branch: vsprintf-ll
<http://www.cideas.us/cgi-bin/gitweb.cgi?p=u-boot/u-boot-of-cmd.git;a=shortl…>
Signed-off-by: Jerry Van Baren <vanbaren(a)cideas.com>
>From 9ec9c50b5e9acbc97bf7c7fc023328b231772065 Mon Sep 17 00:00:00 2001
From: Jerry Van Baren <vanbaren(a)cideas.com>
Date: Mon, 30 Oct 2006 19:55:32 -0500
Subject: [PATCH] Enhance vsprintf to handle "ll" long long specifier (it already supported
the deprecated "q" specifier).
Signed-off-by: Jerry Van Baren <vanbaren(a)cideas.com>
---
lib_generic/vsprintf.c | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/lib_generic/vsprintf.c b/lib_generic/vsprintf.c
index 2740f2e..034c619 100644
--- a/lib_generic/vsprintf.c
+++ b/lib_generic/vsprintf.c
@@ -256,6 +256,13 @@ #endif
if (*fmt == 'h' || *fmt == 'l' || *fmt == 'q') {
qualifier = *fmt;
++fmt;
+#ifdef CFG_64BIT_VSPRINTF
+ /* parse ll (64 bit) and change to 'q' */
+ if (*fmt == 'l') {
+ qualifier = 'q';
+ ++fmt;
+ }
+#endif
}
/* default base */
--
1.4.1.1
2
1

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