All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v10] Marvell Kirkwood family SOC support
@ 2009-05-21 20:24 Prafulla Wadaskar
  2009-05-21 20:24 ` [U-Boot] [PATCH] Marvell Sheevaplug Board support Prafulla Wadaskar
                   ` (2 more replies)
  0 siblings, 3 replies; 18+ messages in thread
From: Prafulla Wadaskar @ 2009-05-21 20:24 UTC (permalink / raw)
  To: u-boot

Kirkwood family controllers are highly integrated SOCs
based on Feroceon-88FR131/Sheeva-88SV131 cpu core.

SOC versions supported:-
1) 88F6281-A0       define CONFIG_KW88F6281_A0
2) 88F6192-A0       define CONFIG_KW88F6192_A0

Other supported features:-
1) get_random_hex() fucntion
2) SPI port controller driver
3) PCI Express port initialization

Contributors:
Yotam Admon <yotam@marvell.com>
Michael Blostein <michaelbl at marvell.com

Reviewed-by: Ronen Shitrit <rshitrit@marvell.com>
Signed-off-by: Prafulla Wadaskar <prafulla@marvell.com>
---
Change log:
v2: crated arch-kirkwood and moved some header files there
renamed and moved spi.c to drivers/spi/
renamed and moved serial.c to drivers/serial/
doimage utility removed
soc_init.S renamed as lowlevel_init.S
debug prints removed

v3: lowlevel_init.S converted to lowlevel_init.c
removed BITxx macros, removed entire assembly code
Added CONFIG_ARCH_LOWLEVE_INIT support for arm926ejs core
updated as per review commens for v2

v4: updated as per review comments for v3
print_cpuinfo used to display Soc info
arch_misc_init support created and used for lib_arm
mandatory readl/write macros used
asm/cache.h asm/arch/spi.h asm//arch/serial.h created and used

v5: updated as per review comments for v4
cosmetic updates, arch_misc_init and arch_cpu_init used
start.S updated to call arch_lowlevel_init in case if lowlevl_init is skipped
bug fix in cpu.c

v6: lowlevel_init.S removed code moved under arch_cpu_init

v7: include <asm/arch/kirkwood.h> added to each c file
reference removed from include/asm/config.h
arch_misc_init defination kept as it is in include/common.h
bugfixed in get_random_hex function

v7.1: u-boot.lds moved from board specific to kirkwood

v8: mpp configuration added
u-boot.lsd and config.mk removed
serial driver removed and used ns16550
register offsets replaced by c struct 
updated as per review comments for v7

v9: updated as per v8 review comments
removed all (u32) typecasts
spi driver bugfix and magic constants removed
tabs used for all indentation

v10: struct for nand flash registers added

 cpu/arm926ejs/kirkwood/Makefile           |   49 +++++
 cpu/arm926ejs/kirkwood/cpu.c              |  316 +++++++++++++++++++++++++++++
 cpu/arm926ejs/kirkwood/dram.c             |   58 ++++++
 cpu/arm926ejs/kirkwood/mpp.c              |   80 ++++++++
 cpu/arm926ejs/kirkwood/timer.c            |  168 +++++++++++++++
 drivers/serial/serial.c                   |    3 +
 drivers/spi/Makefile                      |    1 +
 drivers/spi/kirkwood_spi.c                |  185 +++++++++++++++++
 include/asm-arm/arch-kirkwood/cpu.h       |  149 ++++++++++++++
 include/asm-arm/arch-kirkwood/kirkwood.h  |   69 +++++++
 include/asm-arm/arch-kirkwood/kw88f6192.h |   37 ++++
 include/asm-arm/arch-kirkwood/kw88f6281.h |   37 ++++
 include/asm-arm/arch-kirkwood/mpp.h       |  303 +++++++++++++++++++++++++++
 include/asm-arm/arch-kirkwood/spi.h       |   56 +++++
 include/asm-arm/cache.h                   |   41 ++++
 include/common.h                          |    1 +
 lib_arm/board.c                           |    4 +
 17 files changed, 1557 insertions(+), 0 deletions(-)
 create mode 100644 cpu/arm926ejs/kirkwood/Makefile
 create mode 100644 cpu/arm926ejs/kirkwood/cpu.c
 create mode 100644 cpu/arm926ejs/kirkwood/dram.c
 create mode 100644 cpu/arm926ejs/kirkwood/mpp.c
 create mode 100644 cpu/arm926ejs/kirkwood/timer.c
 create mode 100644 drivers/spi/kirkwood_spi.c
 create mode 100644 include/asm-arm/arch-kirkwood/cpu.h
 create mode 100644 include/asm-arm/arch-kirkwood/kirkwood.h
 create mode 100644 include/asm-arm/arch-kirkwood/kw88f6192.h
 create mode 100644 include/asm-arm/arch-kirkwood/kw88f6281.h
 create mode 100644 include/asm-arm/arch-kirkwood/mpp.h
 create mode 100644 include/asm-arm/arch-kirkwood/spi.h
 create mode 100644 include/asm-arm/cache.h

diff --git a/cpu/arm926ejs/kirkwood/Makefile b/cpu/arm926ejs/kirkwood/Makefile
new file mode 100644
index 0000000..b966ea1
--- /dev/null
+++ b/cpu/arm926ejs/kirkwood/Makefile
@@ -0,0 +1,49 @@
+#
+# (C) Copyright 2009
+# Marvell Semiconductor <www.marvell.com>
+# Prafulla Wadaskar <prafulla@marvell.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., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(SOC).a
+
+COBJS-y	= dram.o
+COBJS-y	+= cpu.o
+COBJS-y	+= mpp.o
+COBJS-y	+= timer.o
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS-y))
+
+all:	$(obj).depend $(LIB)
+
+$(LIB):	$(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/cpu/arm926ejs/kirkwood/cpu.c b/cpu/arm926ejs/kirkwood/cpu.c
new file mode 100644
index 0000000..1286cac
--- /dev/null
+++ b/cpu/arm926ejs/kirkwood/cpu.c
@@ -0,0 +1,316 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Prafulla Wadaskar <prafulla@marvell.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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <common.h>
+#include <netdev.h>
+#include <asm/cache.h>
+#include <u-boot/md5.h>
+#include <asm/arch/kirkwood.h>
+
+#define BUFLEN	16
+
+void reset_cpu(unsigned long ignored)
+{
+	struct kwcpu_registers *cpureg =
+	    (struct kwcpu_registers *)KW_CPU_REG_BASE;
+
+	writel(readl(&cpureg->rstoutn_mask) | (1 << 2),
+		&cpureg->rstoutn_mask);
+	writel(readl(&cpureg->sys_soft_rst) | 1,
+		&cpureg->sys_soft_rst);
+	while (1) ;
+}
+
+/*
+ * Generates Ramdom hex number reading some time varient system registers
+ * and using md5 algorithm
+ */
+unsigned char get_random_hex(void)
+{
+	int i;
+	u32 inbuf[BUFLEN];
+	u8 outbuf[BUFLEN];
+
+	/*
+	 * in case of 88F6281/88F6192 A0,
+	 * Bit7 need to reset to generate random values in KW_REG_UNDOC_0x1470
+	 * Soc reg offsets KW_REG_UNDOC_0x1470 and KW_REG_UNDOC_0x1478 are reserved regs and
+	 * Does not have names at this moment (no errata available)
+	 */
+	writel(readl(KW_REG_UNDOC_0x1478) & ~(1 << 7), KW_REG_UNDOC_0x1478);
+	for (i = 0; i < BUFLEN; i++) {
+		inbuf[i] = readl(KW_REG_UNDOC_0x1470);
+	}
+	md5((u8 *) inbuf, (BUFLEN * sizeof(u32)), outbuf);
+	return outbuf[outbuf[7] % 0x0f];
+}
+
+/*
+ * Window Size
+ * Used with the Base register to set the address window size and location.
+ * Must be programmed from LSB to MSB as sequence of 1???s followed by
+ * sequence of 0???s. The number of 1???s specifies the size of the window in
+ * 64 KByte granularity (e.g., a value of 0x00FF specifies 256 = 16 MByte).
+ * NOTE: A value of 0x0 specifies 64-KByte size.
+ */
+static unsigned int kw_winctrl_calcsize(unsigned int sizeval)
+{
+	int i;
+	unsigned int j = 0;
+
+	for (i = 0; i < (sizeval / 0x10000); i++)
+		j |= (1 << i);
+
+	return (0x0000ffff & j);
+}
+
+/* prepares data to be loaded in win_Ctrl register */
+#define KWCPU_WIN_CTRL_DATA(size, target, attr, en)	(en | (target << 4)	\
+			| (attr << 8) | (kw_winctrl_calcsize(size) << 16))
+
+/*
+ * kw_config_adr_windows - Configure address Windows
+ *
+ * There are 7 address windows supported by Kirkwood Soc to addess different
+ * devices. Each window can be configured for size, BAR and remap addr
+ * Below configuration is standard for most of the cases
+ *
+ * Reference Documentation:
+ * Mbus-L to Mbus Bridge Registers Configuration.
+ * (Sec 25.1 and 25.3 of Datasheet)
+ */
+int kw_config_adr_windows(void)
+{
+	struct kwwin_registers *winregs =
+		(struct kwwin_registers *)KW_CPU_WIN_BASE;
+
+	writel(KWCPU_WIN_CTRL_DATA(0xc0000, KWCPU_TARGET_PCIE,
+				KWCPU_ATTR_PCIE_MEM, KWCPU_WIN_ENABLE),
+		&winregs[0].ctrl);
+
+	writel(0x90000000, &winregs[0].base);
+	writel(0x90000000, &winregs[0].remap_lo);
+	writel(0x00000000, &winregs[0].remap_hi);
+
+	writel(KWCPU_WIN_CTRL_DATA(0x70000, KWCPU_TARGET_MEMORY,
+				KWCPU_ATTR_NANDFLASH, KWCPU_WIN_ENABLE),
+		&winregs[1].ctrl);
+	writel(0xF9000000, &winregs[1].base);
+	writel(0xF9000000, &winregs[1].remap_lo);
+	writel(0x00000000, &winregs[1].remap_hi);
+
+	writel(KWCPU_WIN_CTRL_DATA(0x80000, KWCPU_TARGET_PCIE,
+				KWCPU_ATTR_PCIE_IO, KWCPU_WIN_ENABLE),
+		&winregs[2].ctrl);
+	writel(0xF0000000, &winregs[2].base);
+	writel(0xC0000000, &winregs[2].remap_lo);
+	writel(0x00000000, &winregs[2].remap_hi);
+
+	writel(KWCPU_WIN_CTRL_DATA(0x80000, KWCPU_TARGET_MEMORY,
+				KWCPU_ATTR_SPIFLASH, KWCPU_WIN_ENABLE),
+		&winregs[3].ctrl);
+	writel(0xF8000000, &winregs[3].base);
+	writel(0x00000000, &winregs[3].remap_lo);
+	writel(0x00000000, &winregs[3].remap_hi);
+
+	writel(KWCPU_WIN_CTRL_DATA(0x80000, KWCPU_TARGET_MEMORY,
+				KWCPU_ATTR_BOOTROM, KWCPU_WIN_ENABLE),
+		&winregs[4].ctrl);
+	writel(0xFF000000, &winregs[4].base);
+	writel(0x00000000, &winregs[4].remap_lo);
+	writel(0x00000000, &winregs[4].remap_hi);
+
+	writel(KWCPU_WIN_CTRL_DATA(0xb0000, KWCPU_TARGET_MEMORY,
+				KWCPU_ATTR_SPIFLASH, KWCPU_WIN_DISABLE),
+	&winregs[5].ctrl);
+	writel(0xE8000000, &winregs[5].base);
+	writel(0x00000000, &winregs[5].remap_lo);
+	writel(0x00000000, &winregs[5].remap_hi);
+
+	writel(KWCPU_WIN_CTRL_DATA(0xb0000, KWCPU_TARGET_MEMORY,
+				KWCPU_ATTR_BOOTROM, KWCPU_WIN_DISABLE),
+		&winregs[6].ctrl);
+	writel(0xF0000000, &winregs[6].base);
+	writel(0x00000000, &winregs[6].remap_lo);
+	writel(0x00000000, &winregs[6].remap_hi);
+
+	writel(KWCPU_WIN_CTRL_DATA(0x0, KWCPU_TARGET_SASRAM, KWCPU_ATTR_SASRAM,
+				KWCPU_WIN_ENABLE), &winregs[7].ctrl);
+	writel(0xFB000000, &winregs[7].base);
+	writel(0x00000000, &winregs[7].remap_lo);
+	writel(0x00000000, &winregs[7].remap_hi);
+
+	return 0;
+}
+
+/*
+ * kw_config_gpio - GPIO configuration
+ */
+void kw_config_gpio(u32 gpp0_oe_val, u32 gpp1_oe_val, u32 gpp0_oe, u32 gpp1_oe)
+{
+	struct kwgpio_registers *gpio0reg =
+		(struct kwgpio_registers *)KW_GPIO0_BASE;
+	struct kwgpio_registers *gpio1reg =
+		(struct kwgpio_registers *)KW_GPIO1_BASE;
+
+	/* Init GPIOS to default values as per board requirement */
+	writel(gpp0_oe_val, &gpio0reg->dout);
+	writel(gpp1_oe_val, &gpio1reg->dout);
+	writel(gpp0_oe, &gpio0reg->oe);
+	writel(gpp1_oe, &gpio1reg->oe);
+}
+
+/*
+ * kw_config_mpp - Multi-Purpose Pins Functionality configuration
+ *
+ * Each MPP can be configured to different functionality through
+ * MPP control register, ref (sec 6.1 of kirkwood h/w specification)
+ *
+ * There are maximum 64 Multi-Pourpose Pins on Kirkwood
+ * Each MPP functionality can be configuration by a 4bit value
+ * of MPP control reg, the value and associated functionality depends
+ * upon used SoC varient
+ */
+int kw_config_mpp(u32 mpp0_7, u32 mpp8_15, u32 mpp16_23, u32 mpp24_31,
+		u32 mpp32_39, u32 mpp40_47, u32 mpp48_55)
+{
+	u32 *mppreg = (u32 *) KW_MPP_BASE;
+
+	/* program mpp registers */
+	writel(mpp0_7, &mppreg[0]);
+	writel(mpp8_15, &mppreg[1]);
+	writel(mpp16_23, &mppreg[2]);
+	writel(mpp24_31, &mppreg[3]);
+	writel(mpp32_39, &mppreg[4]);
+	writel(mpp40_47, &mppreg[5]);
+	writel(mpp48_55, &mppreg[6]);
+	return 0;
+}
+
+#if defined(CONFIG_DISPLAY_CPUINFO)
+int print_cpuinfo(void)
+{
+	char *name = "Unknown";
+
+	switch (readl(KW_REG_DEVICE_ID) & 0x03) {
+	case 1:
+		name = "88F6192_A0";
+		break;
+	case 2:
+		name = "88F6281_A0";
+		break;
+	default:
+		printf("SoC:   Unsupported Kirkwood\n");
+		return -1;
+	}
+	printf("SoC:   Kirkwood %s\n", name);
+	return 0;
+}
+#endif /* CONFIG_DISPLAY_CPUINFO */
+
+#ifdef CONFIG_ARCH_CPU_INIT
+int arch_cpu_init(void)
+{
+	u32 reg;
+	struct kwcpu_registers *cpureg =
+		(struct kwcpu_registers *)KW_CPU_REG_BASE;
+
+	/* Linux expects` the internal registers to be at 0xf1000000 */
+	writel(KW_REGS_PHY_BASE, KW_OFFSET_REG);
+
+	/* Enable and invalidate L2 cache in write through mode */
+	writel(readl(&cpureg->l2_cfg) | 0x18, &cpureg->l2_cfg);
+	invalidate_l2_cache();
+
+	kw_config_adr_windows();
+
+#ifdef CONFIG_KIRKWOOD_RGMII_PAD_1V8
+	/*
+	 * Configures the I/O voltage of the pads connected to Egigabit
+	 * Ethernet interface to 1.8V
+	 * By defult it is set to 3.3V
+	 */
+	reg = readl(KW_REG_MPP_OUT_DRV_REG);
+	reg |= (1 << 7);
+	writel(reg, KW_REG_MPP_OUT_DRV_REG);
+#endif
+#ifdef CONFIG_KIRKWOOD_EGIGA_INIT
+	/*
+	 * Set egiga port0/1 in normal functional mode
+	 * This is required becasue on kirkwood by default ports are in reset mode
+	 * OS egiga driver may not have provision to set them in normal mode
+	 * and if u-boot is build without network support, network may fail@OS level
+	 */
+	reg = readl(KWGBE_PORT_SERIAL_CONTROL1_REG(0));
+	reg &= ~(1 << 4);	/* Clear PortReset Bit */
+	writel(reg, (KWGBE_PORT_SERIAL_CONTROL1_REG(0)));
+	reg = readl(KWGBE_PORT_SERIAL_CONTROL1_REG(1));
+	reg &= ~(1 << 4);	/* Clear PortReset Bit */
+	writel(reg, (KWGBE_PORT_SERIAL_CONTROL1_REG(1)));
+#endif
+#ifdef CONFIG_KIRKWOOD_PCIE_INIT
+	/*
+	 * Enable PCI Express Port0
+	 */
+	reg = readl(&cpureg->ctrl_stat);
+	reg |= (1 << 0);	/* Set PEX0En Bit */
+	writel(reg, &cpureg->ctrl_stat);
+#endif
+	return 0;
+}
+#endif /* CONFIG_ARCH_CPU_INIT */
+
+/*
+ * SOC specific misc init
+ */
+#if defined(CONFIG_ARCH_MISC_INIT)
+int arch_misc_init(void)
+{
+	volatile u32 temp;
+
+	/*CPU streaming & write allocate */
+	temp = readfr_extra_feature_reg();
+	temp &= ~(1 << 28);	/* disable wr alloc */
+	writefr_extra_feature_reg(temp);
+
+	temp = readfr_extra_feature_reg();
+	temp &= ~(1 << 29);	/* streaming disabled */
+	writefr_extra_feature_reg(temp);
+
+	/* L2Cache settings */
+	temp = readfr_extra_feature_reg();
+	/* Disable L2C pre fetch - Set bit 24 */
+	temp |= (1 << 24);
+	/* enable L2C - Set bit 22 */
+	temp |= (1 << 22);
+	writefr_extra_feature_reg(temp);
+
+	icache_enable();
+	/* Change reset vector to address 0x0 */
+	temp = get_cr();
+	set_cr(temp & ~CR_V);
+
+	return 0;
+}
+#endif /* CONFIG_ARCH_MISC_INIT */
diff --git a/cpu/arm926ejs/kirkwood/dram.c b/cpu/arm926ejs/kirkwood/dram.c
new file mode 100644
index 0000000..3ec0548
--- /dev/null
+++ b/cpu/arm926ejs/kirkwood/dram.c
@@ -0,0 +1,58 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Prafulla Wadaskar <prafulla@marvell.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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <config.h>
+#include <asm/arch/kirkwood.h>
+
+#define KW_REG_CPUCS_WIN_BAR(x)		(KW_REGISTER(0x1500) + (x * 0x08))
+#define KW_REG_CPUCS_WIN_SZ(x)		(KW_REGISTER(0x1504) + (x * 0x08))
+/*
+ * kw_sdram_bar - reads SDRAM Base Address Register
+ */
+u32 kw_sdram_bar(enum memory_bank bank)
+{
+	u32 result = 0;
+	u32 enable = 0x01 & readl(KW_REG_CPUCS_WIN_SZ(bank));
+
+	if ((!enable) || (bank > BANK3))
+		return 0;
+
+	result = readl(KW_REG_CPUCS_WIN_BAR(bank));
+	return result;
+}
+
+/*
+ * kw_sdram_bs - reads SDRAM Bank size
+ */
+u32 kw_sdram_bs(enum memory_bank bank)
+{
+	u32 result = 0;
+	u32 enable = 0x01 & readl(KW_REG_CPUCS_WIN_SZ(bank));
+
+	if ((!enable) || (bank > BANK3))
+		return 0;
+	result = 0xff000000 & readl(KW_REG_CPUCS_WIN_SZ(bank));
+	result += 0x01000000;
+	return result;
+}
diff --git a/cpu/arm926ejs/kirkwood/mpp.c b/cpu/arm926ejs/kirkwood/mpp.c
new file mode 100644
index 0000000..b2f0ad5
--- /dev/null
+++ b/cpu/arm926ejs/kirkwood/mpp.c
@@ -0,0 +1,80 @@
+/*
+ * arch/arm/mach-kirkwood/mpp.c
+ *
+ * MPP functions for Marvell Kirkwood SoCs
+ * Referenced from Linux kernel source
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <common.h>
+#include <asm/arch/kirkwood.h>
+#include <asm/arch/mpp.h>
+
+static u32 kirkwood_variant(void)
+{
+	switch (readl(KW_REG_DEVICE_ID) & 0x03) {
+	case 1:
+		return MPP_F6192_MASK;
+	case 2:
+		return MPP_F6281_MASK;
+	default:
+		debug("MPP setup: unknown kirkwood variant\n");
+		return 0;
+	}
+}
+
+#define MPP_CTRL(i)	(KW_MPP_BASE + (i* 4))
+#define MPP_NR_REGS	(1 + MPP_MAX/8)
+
+void kirkwood_mpp_conf(u32 *mpp_list)
+{
+	u32 mpp_ctrl[MPP_NR_REGS];
+	unsigned int variant_mask;
+	int i;
+
+	variant_mask = kirkwood_variant();
+	if (!variant_mask)
+		return;
+
+	debug( "initial MPP regs:");
+	for (i = 0; i < MPP_NR_REGS; i++) {
+		mpp_ctrl[i] = readl(MPP_CTRL(i));
+		debug(" %08x", mpp_ctrl[i]);
+	}
+	debug("\n");
+
+
+	while (*mpp_list) {
+		unsigned int num = MPP_NUM(*mpp_list);
+		unsigned int sel = MPP_SEL(*mpp_list);
+		int shift;
+
+		if (num > MPP_MAX) {
+			debug("kirkwood_mpp_conf: invalid MPP "
+					"number (%u)\n", num);
+			continue;
+		}
+		if (!(*mpp_list & variant_mask)) {
+			debug("kirkwood_mpp_conf: requested MPP%u config "
+				"unavailable on this hardware\n", num);
+			continue;
+		}
+
+		shift = (num & 7) << 2;
+		mpp_ctrl[num / 8] &= ~(0xf << shift);
+		mpp_ctrl[num / 8] |= sel << shift;
+
+		mpp_list++;
+	}
+
+	debug("  final MPP regs:");
+	for (i = 0; i < MPP_NR_REGS; i++) {
+		writel(mpp_ctrl[i], MPP_CTRL(i));
+		debug(" %08x", mpp_ctrl[i]);
+	}
+	debug("\n");
+
+}
diff --git a/cpu/arm926ejs/kirkwood/timer.c b/cpu/arm926ejs/kirkwood/timer.c
new file mode 100644
index 0000000..5c39ee8
--- /dev/null
+++ b/cpu/arm926ejs/kirkwood/timer.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ * Prafulla Wadaskar <prafulla@marvell.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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <common.h>
+#include <asm/arch/kirkwood.h>
+
+#define UBOOT_CNTR	0	/* counter to use for uboot timer */
+
+/* Timer reload and current value registers */
+struct kwtmr_val {
+	u32 reload;	/* Timer reload reg */
+	u32 val;	/* Timer value reg */
+};
+
+/* Timer registers */
+struct kwtmr_registers {
+	u32 ctrl;	/* Timer control reg */
+	u32 pad[3];
+	struct kwtmr_val tmr[2];
+	u32 wdt_reload;
+	u32 wdt_val;
+};
+
+struct kwtmr_registers *kwtmr_regs = (struct kwtmr_registers *)KW_TIMER_BASE;
+
+/*
+ * ARM Timers Registers Map
+ */
+#define CNTMR_CTRL_REG			&kwtmr_regs->ctrl
+#define CNTMR_RELOAD_REG(tmrnum)	&kwtmr_regs->tmr[tmrnum].reload
+#define CNTMR_VAL_REG(tmrnum)		&kwtmr_regs->tmr[tmrnum].val
+
+/*
+ * ARM Timers Control Register
+ * CPU_TIMERS_CTRL_REG (CTCR)
+ */
+#define CTCR_ARM_TIMER_EN_OFFS(cntr)	(cntr * 2)
+#define CTCR_ARM_TIMER_EN_MASK(cntr)	(1 << CTCR_ARM_TIMER_EN_OFFS)
+#define CTCR_ARM_TIMER_EN(cntr)		(1 << CTCR_ARM_TIMER_EN_OFFS(cntr))
+#define CTCR_ARM_TIMER_DIS(cntr)	(0 << CTCR_ARM_TIMER_EN_OFFS(cntr))
+
+#define CTCR_ARM_TIMER_AUTO_OFFS(cntr)	((cntr * 2) + 1)
+#define CTCR_ARM_TIMER_AUTO_MASK(cntr)	(1 << 1)
+#define CTCR_ARM_TIMER_AUTO_EN(cntr)	(1 << CTCR_ARM_TIMER_AUTO_OFFS(cntr))
+#define CTCR_ARM_TIMER_AUTO_DIS(cntr)	(0 << CTCR_ARM_TIMER_AUTO_OFFS(cntr))
+
+/*
+ * ARM Timer\Watchdog Reload Register
+ * CNTMR_RELOAD_REG (TRR)
+ */
+#define TRG_ARM_TIMER_REL_OFFS		0
+#define TRG_ARM_TIMER_REL_MASK		0xffffffff
+
+/*
+ * ARM Timer\Watchdog Register
+ * CNTMR_VAL_REG (TVRG)
+ */
+#define TVR_ARM_TIMER_OFFS		0
+#define TVR_ARM_TIMER_MASK		0xffffffff
+#define TVR_ARM_TIMER_MAX		0xffffffff
+#define TIMER_LOAD_VAL 			0xffffffff
+
+#define READ_TIMER			(readl(CNTMR_VAL_REG(UBOOT_CNTR)) /	\
+					 (CONFIG_SYS_TCLK / 1000))
+
+static ulong timestamp;
+static ulong lastdec;
+
+void reset_timer_masked(void)
+{
+	/* reset time */
+	lastdec = READ_TIMER;
+	timestamp = 0;
+}
+
+ulong get_timer_masked(void)
+{
+	ulong now = READ_TIMER;
+
+	if (lastdec >= now) {
+		/* normal mode */
+		timestamp += lastdec - now;
+	} else {
+		/* we have an overflow ... */
+		timestamp += lastdec +
+			(TIMER_LOAD_VAL / (CONFIG_SYS_TCLK / 1000)) - now;
+	}
+	lastdec = now;
+
+	return timestamp;
+}
+
+void reset_timer(void)
+{
+	reset_timer_masked();
+}
+
+ulong get_timer(ulong base)
+{
+	return get_timer_masked() - base;
+}
+
+void set_timer(ulong t)
+{
+	timestamp = t;
+}
+
+void udelay(unsigned long usec)
+{
+	uint current;
+	ulong delayticks;
+
+	current = readl(CNTMR_VAL_REG(UBOOT_CNTR));
+	delayticks = (usec * (CONFIG_SYS_TCLK / 1000000));
+
+	if (current < delayticks) {
+		delayticks -= current;
+		while (readl(CNTMR_VAL_REG(UBOOT_CNTR)) < current) ;
+		while ((TIMER_LOAD_VAL - delayticks) <
+			readl(CNTMR_VAL_REG(UBOOT_CNTR))) ;
+	} else {
+		while (readl(CNTMR_VAL_REG(UBOOT_CNTR)) >
+			(current - delayticks)) ;
+	}
+}
+
+/*
+ * init the counter
+ */
+int timer_init(void)
+{
+	unsigned int cntmrctrl;
+
+	/* load value into timer */
+	writel(TIMER_LOAD_VAL, CNTMR_RELOAD_REG(UBOOT_CNTR));
+	writel(TIMER_LOAD_VAL, CNTMR_VAL_REG(UBOOT_CNTR));
+
+	/* enable timer in auto reload mode */
+	cntmrctrl = readl(CNTMR_CTRL_REG);
+	cntmrctrl |= CTCR_ARM_TIMER_EN(UBOOT_CNTR);
+	cntmrctrl |= CTCR_ARM_TIMER_AUTO_EN(UBOOT_CNTR);
+	writel(cntmrctrl, CNTMR_CTRL_REG);
+
+	/* init the timestamp and lastdec value */
+	reset_timer_masked();
+
+	return 0;
+}
diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c
index 966df9a..dd5f332 100644
--- a/drivers/serial/serial.c
+++ b/drivers/serial/serial.c
@@ -27,6 +27,9 @@
 #ifdef CONFIG_NS87308
 #include <ns87308.h>
 #endif
+#ifdef CONFIG_KIRKWOOD
+#include <asm/arch/kirkwood.h>
+#endif
 
 #if defined (CONFIG_SERIAL_MULTI)
 #include <serial.h>
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 1350f3e..7ffa47d 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -28,6 +28,7 @@ LIB	:= $(obj)libspi.a
 COBJS-$(CONFIG_ATMEL_DATAFLASH_SPI) += atmel_dataflash_spi.o
 COBJS-$(CONFIG_ATMEL_SPI) += atmel_spi.o
 COBJS-$(CONFIG_BFIN_SPI) += bfin_spi.o
+COBJS-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o
 COBJS-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o
 COBJS-$(CONFIG_MXC_SPI) += mxc_spi.o
 COBJS-$(CONFIG_SOFT_SPI) += soft_spi.o
diff --git a/drivers/spi/kirkwood_spi.c b/drivers/spi/kirkwood_spi.c
new file mode 100644
index 0000000..9d16e9b
--- /dev/null
+++ b/drivers/spi/kirkwood_spi.c
@@ -0,0 +1,185 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Prafulla Wadaskar <prafulla@marvell.com>
+ *
+ * Derived from drivers/spi/mpc8xxx_spi.c
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <spi.h>
+#include <asm/arch/kirkwood.h>
+#include <asm/arch/spi.h>
+#include <asm/arch/mpp.h>
+
+static struct kwspi_registers *spireg = (struct kwspi_registers *)KW_SPI_BASE;
+
+struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
+				unsigned int max_hz, unsigned int mode)
+{
+	struct spi_slave *slave;
+	u32 data;
+	u32 kwspi_mpp_config[] = {
+		MPP0_GPIO,
+		MPP7_SPI_SCn,
+		0
+	};
+
+	if (!spi_cs_is_valid(bus, cs))
+		return NULL;
+
+	slave = malloc(sizeof(struct spi_slave));
+	if (!slave)
+		return NULL;
+
+	slave->bus = bus;
+	slave->cs = cs;
+
+	writel(~KWSPI_CSN_ACT | KWSPI_SMEMRDY, &spireg->ctrl);
+
+	/* calculate spi clock prescaller using max_hz */
+	data = ((CONFIG_SYS_TCLK / 2) / max_hz) & KWSPI_CLKPRESCL_MASK;
+	data |= 0x10;
+
+	/* program spi clock prescaller using max_hz */
+	writel(KWSPI_ADRLEN_3BYTE | data, &spireg->cfg);
+	debug("data = 0x%08x \n", data);
+
+	writel(KWSPI_SMEMRDIRQ, &spireg->irq_cause);
+	writel(KWSPI_IRQMASK, spireg->irq_mask);
+
+	/* program mpp registers to select  SPI_CSn */
+	if (cs) {
+		kwspi_mpp_config[0] = MPP0_GPIO;
+		kwspi_mpp_config[1] = MPP7_SPI_SCn;
+	} else {
+		kwspi_mpp_config[0] = MPP0_SPI_SCn;
+		kwspi_mpp_config[1] = MPP7_GPO;
+	}
+	kirkwood_mpp_conf(kwspi_mpp_config);
+
+	return slave;
+}
+
+void spi_free_slave(struct spi_slave *slave)
+{
+	free(slave);
+}
+
+int spi_claim_bus(struct spi_slave *slave)
+{
+	return 0;
+}
+
+void spi_release_bus(struct spi_slave *slave)
+{
+}
+
+#ifndef CONFIG_SPI_CS_IS_VALID
+/*
+ * you can define this function board specific
+ * define above CONFIG in board specific config file and
+ * provide the function in board specific src file
+ */
+int spi_cs_is_valid(unsigned int bus, unsigned int cs)
+{
+	return (bus == 0 && (cs == 0 || cs == 1));
+}
+#endif
+
+void spi_cs_activate(struct spi_slave *slave)
+{
+	writel(readl(&spireg->ctrl) | KWSPI_IRQUNMASK, &spireg->ctrl);
+}
+
+void spi_cs_deactivate(struct spi_slave *slave)
+{
+	writel(readl(&spireg->ctrl) & KWSPI_IRQMASK, &spireg->ctrl);
+}
+
+int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
+	     void *din, unsigned long flags)
+{
+	unsigned int tmpdout, tmpdin;
+	int tm, isread = 0;
+
+	debug("spi_xfer: slave %u:%u dout %08X din %08X bitlen %u\n",
+	      slave->bus, slave->cs, dout, din, bitlen);
+
+	if (flags & SPI_XFER_BEGIN)
+		spi_cs_activate(slave);
+
+	/*
+	 * handle data in 8-bit chunks
+	 * TBD: 2byte xfer mode to be enabled
+	 */
+	writel(((readl(&spireg->cfg) & ~KWSPI_XFERLEN_MASK) |
+		KWSPI_XFERLEN_1BYTE), &spireg->cfg);
+
+	while (bitlen > 4) {
+		debug("loopstart bitlen %d\n", bitlen);
+		tmpdout = 0;
+
+		/* Shift data so it's msb-justified */
+		if (dout)
+			tmpdout = *(u32 *) dout & 0x0ff;
+
+		writel(~KWSPI_SMEMRDIRQ, &spireg->irq_cause);
+		writel(tmpdout, &spireg->dout);	/* Write the data out */
+		debug("*** spi_xfer: ... %08x written, bitlen %d\n",
+		      tmpdout, bitlen);
+
+		/*
+		 * Wait for SPI transmit to get out
+		 * or time out (1 second = 1000 ms)
+		 * The NE event must be read and cleared first
+		 */
+		for (tm = 0, isread = 0; tm < KWSPI_TIMEOUT; ++tm) {
+			if (readl(&spireg->irq_cause) & KWSPI_SMEMRDIRQ) {
+				isread = 1;
+				tmpdin = readl(&spireg->din);
+				debug
+					("spi_xfer: din %08x..%08x read\n",
+					din, tmpdin);
+
+				if (din) {
+					*((u8 *) din) = (u8) tmpdin;
+					din += 1;
+				}
+				if (dout)
+					dout += 1;
+				bitlen -= 8;
+			}
+			if (isread)
+				break;
+		}
+		if (tm >= KWSPI_TIMEOUT)
+			printf("*** spi_xfer: Time out during SPI transfer\n");
+
+		debug("loopend bitlen %d\n", bitlen);
+	}
+
+	if (flags & SPI_XFER_END)
+		spi_cs_deactivate(slave);
+
+	return 0;
+}
diff --git a/include/asm-arm/arch-kirkwood/cpu.h b/include/asm-arm/arch-kirkwood/cpu.h
new file mode 100644
index 0000000..635bd8f
--- /dev/null
+++ b/include/asm-arm/arch-kirkwood/cpu.h
@@ -0,0 +1,149 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Prafulla Wadaskar <prafulla@marvell.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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#ifndef _KWCPU_H
+#define _KWCPU_H
+
+#include <asm/system.h>
+
+#ifndef __ASSEMBLY__
+
+#define KWGBE_PORT_SERIAL_CONTROL1_REG(_x)	\
+		((_x ? KW_EGIGA0_BASE : KW_EGIGA1_BASE) + 0x44c)
+
+#define KW_REG_DEVICE_ID		(KW_MPP_BASE + 0x34)
+#define KW_REG_MPP_OUT_DRV_REG		(KW_MPP_BASE + 0xE0)
+
+enum memory_bank {
+	BANK0,
+	BANK1,
+	BANK2,
+	BANK3
+};
+
+enum kwcpu_winen {
+	KWCPU_WIN_DISABLE,
+	KWCPU_WIN_ENABLE
+};
+
+enum kwcpu_target {
+	KWCPU_TARGET_RESERVED,
+	KWCPU_TARGET_MEMORY,
+	KWCPU_TARGET_1RESERVED,
+	KWCPU_TARGET_SASRAM,
+	KWCPU_TARGET_PCIE
+};
+
+enum kwcpu_attrib {
+	KWCPU_ATTR_SASRAM = 0x01,
+	KWCPU_ATTR_NANDFLASH = 0x2f,
+	KWCPU_ATTR_SPIFLASH = 0x1e,
+	KWCPU_ATTR_BOOTROM = 0x1d,
+	KWCPU_ATTR_PCIE_IO = 0xe0,
+	KWCPU_ATTR_PCIE_MEM = 0xe8
+};
+
+/*
+ * read feroceon/sheeva core extra feature register
+ * using co-proc instruction
+ */
+static inline unsigned int readfr_extra_feature_reg(void)
+{
+	unsigned int val;
+	asm volatile ("mrc p15, 1, %0, c15, c1, 0 @ readfr exfr":"=r"
+			(val)::"cc");
+	return val;
+}
+
+/*
+ * write feroceon/sheeva core extra feature register
+ * using co-proc instruction
+ */
+static inline void writefr_extra_feature_reg(unsigned int val)
+{
+	asm volatile ("mcr p15, 1, %0, c15, c1, 0 @ writefr exfr"::"r"
+			(val):"cc");
+	isb();
+}
+
+/*
+ * Register structures
+ */
+struct kwgpio_registers {
+	u32 dout;
+	u32 oe;
+	u32 blink_en;
+	u32 din_pol;
+	u32 din;
+	u32 irq_cause;
+	u32 irq_mask;
+	u32 irq_level;
+};
+
+struct kwwin_registers {
+	u32 ctrl;
+	u32 base;
+	u32 remap_lo;
+	u32 remap_hi;
+};
+
+/* CPU control and status registers */
+struct kwcpu_registers {
+	u32 config;	/*0x20100 */
+	u32 ctrl_stat;	/*0x20104 */
+	u32 rstoutn_mask; /* 0x20108 */
+	u32 sys_soft_rst; /* 0x2010C */
+	u32 ahb_mbus_cause_irq; /* 0x20110 */
+	u32 ahb_mbus_mask_irq; /* 0x20114 */
+	u32 pad1[2];
+	u32 ftdll_config; /* 0x20120 */
+	u32 pad2;
+	u32 l2_cfg;	/* 0x20128 */
+};
+
+/* NAND flash registers */
+struct kwnandf_registers {
+	u32 rd_params;	/* 0x10418 */
+	u32 wr_param;	/* 0x1041c */
+	u8  pag[0x10470 - 0x1041c -4];
+	u32 ctrl;	/* 0x10470 */
+};
+
+/*
+ * functions
+ */
+void reset_cpu(unsigned long ignored);
+unsigned char get_random_hex(void);
+unsigned int kw_sdram_bar(enum memory_bank bank);
+unsigned int kw_sdram_bs(enum memory_bank bank);
+int kw_config_adr_windows(void);
+void kw_config_gpio(unsigned int gpp0_oe_val, unsigned int gpp1_oe_val,
+		unsigned int gpp0_oe, unsigned int gpp1_oe);
+int kw_config_mpp(unsigned int mpp0_7, unsigned int mpp8_15,
+		unsigned int mpp16_23, unsigned int mpp24_31,
+		unsigned int mpp32_39, unsigned int mpp40_47,
+		unsigned int mpp48_55);
+#endif /* __ASSEMBLY__ */
+
+#endif /* _KWCPU_H */
diff --git a/include/asm-arm/arch-kirkwood/kirkwood.h b/include/asm-arm/arch-kirkwood/kirkwood.h
new file mode 100644
index 0000000..f026b9c
--- /dev/null
+++ b/include/asm-arm/arch-kirkwood/kirkwood.h
@@ -0,0 +1,69 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Prafulla Wadaskar <prafulla@marvell.com>
+ *
+ * Header file for the Marvell's Feroceon CPU core.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#ifndef _ASM_ARCH_KIRKWOOD_H
+#define _ASM_ARCH_KIRKWOOD_H
+
+#ifndef __ASSEMBLY__
+#include <asm/types.h>
+#include <asm/io.h>
+#endif /* __ASSEMBLY__ */
+
+#if defined (CONFIG_FEROCEON_88FR131) || defined (CONFIG_SHEEVA_88SV131)
+#include <asm/arch/cpu.h>
+
+/* SOC specific definations */
+#define INTREG_BASE			0xd0000000
+#define KW_REGISTER(x)			(KW_REGS_PHY_BASE + x)
+#define KW_OFFSET_REG			(INTREG_BASE + 0x20080)
+
+/* undocumented registers */
+#define KW_REG_UNDOC_0x1470		(KW_REGISTER(0x1470))
+#define KW_REG_UNDOC_0x1478		(KW_REGISTER(0x1478))
+
+#define KW_UART0_BASE			(KW_REGISTER(0x12000))
+#define KW_UART1_BASE			(KW_REGISTER(0x13000))
+#define KW_MPP_BASE			(KW_REGISTER(0x10000))
+#define KW_GPIO0_BASE			(KW_REGISTER(0x10100))
+#define KW_GPIO1_BASE			(KW_REGISTER(0x10140))
+#define KW_NANDF_BASE			(KW_REGISTER(0x10418))
+#define KW_SPI_BASE			(KW_REGISTER(0x10600))
+#define KW_CPU_WIN_BASE			(KW_REGISTER(0x20000))
+#define KW_CPU_REG_BASE			(KW_REGISTER(0x20100))
+#define KW_TIMER_BASE			(KW_REGISTER(0x20300))
+#define KW_REG_PCIE_BASE		(KW_REGISTER(0x40000))
+#define KW_EGIGA0_BASE			(KW_REGISTER(0x72000))
+#define KW_EGIGA1_BASE			(KW_REGISTER(0x76000))
+
+#if defined (CONFIG_KW88F6281)
+#include <asm/arch/kw88f6281.h>
+#elif defined (CONFIG_KW88F6192)
+#include <asm/arch/kw88f6192.h>
+#else
+#error "SOC Name not defined"
+#endif /* CONFIG_KW88F6281 */
+#endif /* CONFIG_FEROCEON_88FR131 */
+#endif /* _ASM_ARCH_KIRKWOOD_H */
diff --git a/include/asm-arm/arch-kirkwood/kw88f6192.h b/include/asm-arm/arch-kirkwood/kw88f6192.h
new file mode 100644
index 0000000..a2b1f96
--- /dev/null
+++ b/include/asm-arm/arch-kirkwood/kw88f6192.h
@@ -0,0 +1,37 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Prafulla Wadaskar <prafulla@marvell.com>
+ *
+ * Header file for Feroceon CPU core 88FR131 Based KW88F6192 SOC.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#ifndef _CONFIG_KW88F6192_H
+#define _CONFIG_KW88F6192_H
+
+/* SOC specific definations */
+#define KW88F6192_REGS_PHYS_BASE	0xf1000000
+#define KW_REGS_PHY_BASE		KW88F6192_REGS_PHYS_BASE
+
+/* TCLK Core Clock defination */
+#define CONFIG_SYS_TCLK	  166000000 /* 166MHz */
+
+#endif /* _CONFIG_KW88F6192_H */
diff --git a/include/asm-arm/arch-kirkwood/kw88f6281.h b/include/asm-arm/arch-kirkwood/kw88f6281.h
new file mode 100644
index 0000000..9b89b93
--- /dev/null
+++ b/include/asm-arm/arch-kirkwood/kw88f6281.h
@@ -0,0 +1,37 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Prafulla Wadaskar <prafulla@marvell.com>
+ *
+ * Header file for Feroceon CPU core 88FR131 Based KW88F6281 SOC.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#ifndef _ASM_ARCH_KW88F6281_H
+#define _ASM_ARCH_KW88F6281_H
+
+/* SOC specific definations */
+#define KW88F6281_REGS_PHYS_BASE	0xf1000000
+#define KW_REGS_PHY_BASE		KW88F6281_REGS_PHYS_BASE
+
+/* TCLK Core Clock defination*/
+#define CONFIG_SYS_TCLK	  200000000 /* 200MHz */
+
+#endif /* _ASM_ARCH_KW88F6281_H */
diff --git a/include/asm-arm/arch-kirkwood/mpp.h b/include/asm-arm/arch-kirkwood/mpp.h
new file mode 100644
index 0000000..e021a80
--- /dev/null
+++ b/include/asm-arm/arch-kirkwood/mpp.h
@@ -0,0 +1,303 @@
+/*
+ * linux/arch/arm/mach-kirkwood/mpp.h -- Multi Purpose Pins
+ *
+ * Copyright 2009: Marvell Technology Group Ltd.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __KIRKWOOD_MPP_H
+#define __KIRKWOOD_MPP_H
+
+#define MPP(_num, _sel, _in, _out, _F6180, _F6190, _F6192, _F6281) ( \
+	/* MPP number */		((_num) & 0xff) | \
+	/* MPP select value */		(((_sel) & 0xf) << 8) | \
+	/* may be input signal */	((!!(_in)) << 12) | \
+	/* may be output signal */	((!!(_out)) << 13) | \
+	/* available on F6180 */	((!!(_F6180)) << 14) | \
+	/* available on F6190 */	((!!(_F6190)) << 15) | \
+	/* available on F6192 */	((!!(_F6192)) << 16) | \
+	/* available on F6281 */	((!!(_F6281)) << 17))
+
+#define MPP_NUM(x)	((x) & 0xff)
+#define MPP_SEL(x)	(((x) >> 8) & 0xf)
+
+				/*   num sel  i  o  6180 6190 6192 6281 */
+
+#define MPP_INPUT_MASK		MPP(  0, 0x0, 1, 0, 0,   0,   0,   0    )
+#define MPP_OUTPUT_MASK		MPP(  0, 0x0, 0, 1, 0,   0,   0,   0    )
+
+#define MPP_F6180_MASK		MPP(  0, 0x0, 0, 0, 1,   0,   0,   0    )
+#define MPP_F6190_MASK		MPP(  0, 0x0, 0, 0, 0,   1,   0,   0    )
+#define MPP_F6192_MASK		MPP(  0, 0x0, 0, 0, 0,   0,   1,   0    )
+#define MPP_F6281_MASK		MPP(  0, 0x0, 0, 0, 0,   0,   0,   1    )
+
+#define MPP0_GPIO		MPP(  0, 0x0, 1, 1, 1,   1,   1,   1    )
+#define MPP0_NF_IO2		MPP(  0, 0x1, 1, 1, 1,   1,   1,   1    )
+#define MPP0_SPI_SCn		MPP(  0, 0x2, 0, 1, 1,   1,   1,   1    )
+
+#define MPP1_GPO		MPP(  1, 0x0, 0, 1, 1,   1,   1,   1    )
+#define MPP1_NF_IO3		MPP(  1, 0x1, 1, 1, 1,   1,   1,   1    )
+#define MPP1_SPI_MOSI		MPP(  1, 0x2, 0, 1, 1,   1,   1,   1    )
+
+#define MPP2_GPO		MPP(  2, 0x0, 0, 1, 1,   1,   1,   1    )
+#define MPP2_NF_IO4		MPP(  2, 0x1, 1, 1, 1,   1,   1,   1    )
+#define MPP2_SPI_SCK		MPP(  2, 0x2, 0, 1, 1,   1,   1,   1    )
+
+#define MPP3_GPO		MPP(  3, 0x0, 0, 1, 1,   1,   1,   1    )
+#define MPP3_NF_IO5		MPP(  3, 0x1, 1, 1, 1,   1,   1,   1    )
+#define MPP3_SPI_MISO		MPP(  3, 0x2, 1, 0, 1,   1,   1,   1    )
+
+#define MPP4_GPIO		MPP(  4, 0x0, 1, 1, 1,   1,   1,   1    )
+#define MPP4_NF_IO6		MPP(  4, 0x1, 1, 1, 1,   1,   1,   1    )
+#define MPP4_UART0_RXD		MPP(  4, 0x2, 1, 0, 1,   1,   1,   1    )
+#define MPP4_SATA1_ACTn		MPP(  4, 0x5, 0, 1, 0,   0,   1,   1    )
+#define MPP4_PTP_CLK		MPP(  4, 0xd, 1, 0, 1,   1,   1,   1    )
+
+#define MPP5_GPO		MPP(  5, 0x0, 0, 1, 1,   1,   1,   1    )
+#define MPP5_NF_IO7		MPP(  5, 0x1, 1, 1, 1,   1,   1,   1    )
+#define MPP5_UART0_TXD		MPP(  5, 0x2, 0, 1, 1,   1,   1,   1    )
+#define MPP5_PTP_TRIG_GEN	MPP(  5, 0x4, 0, 1, 1,   1,   1,   1    )
+#define MPP5_SATA0_ACTn		MPP(  5, 0x5, 0, 1, 0,   1,   1,   1    )
+
+#define MPP6_SYSRST_OUTn	MPP(  6, 0x1, 0, 1, 1,   1,   1,   1    )
+#define MPP6_SPI_MOSI		MPP(  6, 0x2, 0, 1, 1,   1,   1,   1    )
+#define MPP6_PTP_TRIG_GEN	MPP(  6, 0x3, 0, 1, 1,   1,   1,   1    )
+
+#define MPP7_GPO		MPP(  7, 0x0, 0, 1, 1,   1,   1,   1    )
+#define MPP7_PEX_RST_OUTn	MPP(  7, 0x1, 0, 1, 1,   1,   1,   1    )
+#define MPP7_SPI_SCn		MPP(  7, 0x2, 0, 1, 1,   1,   1,   1    )
+#define MPP7_PTP_TRIG_GEN	MPP(  7, 0x3, 0, 1, 1,   1,   1,   1    )
+
+#define MPP8_GPIO		MPP(  8, 0x0, 1, 1, 1,    1,  1,   1    )
+#define MPP8_TW_SDA		MPP(  8, 0x1, 1, 1, 1,   1,   1,   1    )
+#define MPP8_UART0_RTS		MPP(  8, 0x2, 0, 1, 1,   1,   1,   1    )
+#define MPP8_UART1_RTS		MPP(  8, 0x3, 0, 1, 1,   1,   1,   1    )
+#define MPP8_MII0_RXERR		MPP(  8, 0x4, 1, 0, 0,   1,   1,   1    )
+#define MPP8_SATA1_PRESENTn	MPP(  8, 0x5, 0, 1, 0,   0,   1,   1    )
+#define MPP8_PTP_CLK		MPP(  8, 0xc, 1, 0, 1,   1,   1,   1    )
+#define MPP8_MII0_COL		MPP(  8, 0xd, 1, 0, 1,   1,   1,   1    )
+
+#define MPP9_GPIO		MPP(  9, 0x0, 1, 1, 1,   1,   1,   1    )
+#define MPP9_TW_SCK		MPP(  9, 0x1, 1, 1, 1,   1,   1,   1    )
+#define MPP9_UART0_CTS		MPP(  9, 0x2, 1, 0, 1,   1,   1,   1    )
+#define MPP9_UART1_CTS		MPP(  9, 0x3, 1, 0, 1,   1,   1,   1    )
+#define MPP9_SATA0_PRESENTn	MPP(  9, 0x5, 0, 1, 0,   1,   1,   1    )
+#define MPP9_PTP_EVENT_REQ	MPP(  9, 0xc, 1, 0, 1,   1,   1,   1    )
+#define MPP9_MII0_CRS		MPP(  9, 0xd, 1, 0, 1,   1,   1,   1    )
+
+#define MPP10_GPO		MPP( 10, 0x0, 0, 1, 1,   1,   1,   1    )
+#define MPP10_SPI_SCK		MPP( 10, 0x2, 0, 1, 1,   1,   1,   1    )
+#define MPP10_UART0_TXD		MPP( 10, 0X3, 0, 1, 1,   1,   1,   1    )
+#define MPP10_SATA1_ACTn	MPP( 10, 0x5, 0, 1, 0,   0,   1,   1    )
+#define MPP10_PTP_TRIG_GEN	MPP( 10, 0xc, 0, 1, 1,   1,   1,   1    )
+
+#define MPP11_GPIO		MPP( 11, 0x0, 1, 1, 1,   1,   1,   1    )
+#define MPP11_SPI_MISO		MPP( 11, 0x2, 1, 0, 1,   1,   1,   1    )
+#define MPP11_UART0_RXD		MPP( 11, 0x3, 1, 0, 1,   1,   1,   1    )
+#define MPP11_PTP_EVENT_REQ	MPP( 11, 0x4, 1, 0, 1,   1,   1,   1    )
+#define MPP11_PTP_TRIG_GEN	MPP( 11, 0xc, 0, 1, 1,   1,   1,   1    )
+#define MPP11_PTP_CLK		MPP( 11, 0xd, 1, 0, 1,   1,   1,   1    )
+#define MPP11_SATA0_ACTn	MPP( 11, 0x5, 0, 1, 0,   1,   1,   1    )
+
+#define MPP12_GPO		MPP( 12, 0x0, 0, 1, 1,   1,   1,   1    )
+#define MPP12_SD_CLK		MPP( 12, 0x1, 0, 1, 1,   1,   1,   1    )
+
+#define MPP13_GPIO		MPP( 13, 0x0, 1, 1, 1,   1,   1,   1    )
+#define MPP13_SD_CMD		MPP( 13, 0x1, 1, 1, 1,   1,   1,   1    )
+#define MPP13_UART1_TXD		MPP( 13, 0x3, 0, 1, 1,   1,   1,   1    )
+
+#define MPP14_GPIO		MPP( 14, 0x0, 1, 1, 1,   1,   1,   1    )
+#define MPP14_SD_D0		MPP( 14, 0x1, 1, 1, 1,   1,   1,   1    )
+#define MPP14_UART1_RXD		MPP( 14, 0x3, 1, 0, 1,   1,   1,   1    )
+#define MPP14_SATA1_PRESENTn	MPP( 14, 0x4, 0, 1, 0,   0,   1,   1    )
+#define MPP14_MII0_COL		MPP( 14, 0xd, 1, 0, 1,   1,   1,   1    )
+
+#define MPP15_GPIO		MPP( 15, 0x0, 1, 1, 1,   1,   1,   1    )
+#define MPP15_SD_D1		MPP( 15, 0x1, 1, 1, 1,   1,   1,   1    )
+#define MPP15_UART0_RTS		MPP( 15, 0x2, 0, 1, 1,   1,   1,   1    )
+#define MPP15_UART1_TXD		MPP( 15, 0x3, 0, 1, 1,   1,   1,   1    )
+#define MPP15_SATA0_ACTn	MPP( 15, 0x4, 0, 1, 0,   1,   1,   1    )
+
+#define MPP16_GPIO		MPP( 16, 0x0, 1, 1, 1,   1,   1,   1    )
+#define MPP16_SD_D2		MPP( 16, 0x1, 1, 1, 1,   1,   1,   1    )
+#define MPP16_UART0_CTS		MPP( 16, 0x2, 1, 0, 1,   1,   1,   1    )
+#define MPP16_UART1_RXD		MPP( 16, 0x3, 1, 0, 1,   1,   1,   1    )
+#define MPP16_SATA1_ACTn	MPP( 16, 0x4, 0, 1, 0,   0,   1,   1    )
+#define MPP16_MII0_CRS		MPP( 16, 0xd, 1, 0, 1,   1,   1,   1    )
+
+#define MPP17_GPIO		MPP( 17, 0x0, 1, 1, 1,   1,   1,   1    )
+#define MPP17_SD_D3		MPP( 17, 0x1, 1, 1, 1,   1,   1,   1    )
+#define MPP17_SATA0_PRESENTn	MPP( 17, 0x4, 0, 1, 0,   1,   1,   1    )
+
+#define MPP18_GPO		MPP( 18, 0x0, 0, 1, 1,   1,   1,   1    )
+#define MPP18_NF_IO0		MPP( 18, 0x1, 1, 1, 1,   1,   1,   1    )
+
+#define MPP19_GPO		MPP( 19, 0x0, 0, 1, 1,   1,   1,   1    )
+#define MPP19_NF_IO1		MPP( 19, 0x1, 1, 1, 1,   1,   1,   1    )
+
+#define MPP20_GPIO		MPP( 20, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP20_TSMP0		MPP( 20, 0x1, 1, 1, 0,   0,   1,   1    )
+#define MPP20_TDM_CH0_TX_QL	MPP( 20, 0x2, 0, 1, 0,   0,   1,   1    )
+#define MPP20_GE1_0		MPP( 20, 0x3, 0, 0, 0,   1,   1,   1    )
+#define MPP20_AUDIO_SPDIFI	MPP( 20, 0x4, 1, 0, 0,   0,   1,   1    )
+#define MPP20_SATA1_ACTn	MPP( 20, 0x5, 0, 1, 0,   0,   1,   1    )
+
+#define MPP21_GPIO		MPP( 21, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP21_TSMP1		MPP( 21, 0x1, 1, 1, 0,   0,   1,   1    )
+#define MPP21_TDM_CH0_RX_QL	MPP( 21, 0x2, 0, 1, 0,   0,   1,   1    )
+#define MPP21_GE1_1		MPP( 21, 0x3, 0, 0, 0,   1,   1,   1    )
+#define MPP21_AUDIO_SPDIFO	MPP( 21, 0x4, 0, 1, 0,   0,   1,   1    )
+#define MPP21_SATA0_ACTn	MPP( 21, 0x5, 0, 1, 0,   1,   1,   1    )
+
+#define MPP22_GPIO		MPP( 22, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP22_TSMP2		MPP( 22, 0x1, 1, 1, 0,   0,   1,   1    )
+#define MPP22_TDM_CH2_TX_QL	MPP( 22, 0x2, 0, 1, 0,   0,   1,   1    )
+#define MPP22_GE1_2		MPP( 22, 0x3, 0, 0, 0,   1,   1,   1    )
+#define MPP22_AUDIO_SPDIFRMKCLK	MPP( 22, 0x4, 0, 1, 0,   0,   1,   1    )
+#define MPP22_SATA1_PRESENTn	MPP( 22, 0x5, 0, 1, 0,   0,   1,   1    )
+
+#define MPP23_GPIO		MPP( 23, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP23_TSMP3		MPP( 23, 0x1, 1, 1, 0,   0,   1,   1    )
+#define MPP23_TDM_CH2_RX_QL	MPP( 23, 0x2, 1, 0, 0,   0,   1,   1    )
+#define MPP23_GE1_3		MPP( 23, 0x3, 0, 0, 0,   1,   1,   1    )
+#define MPP23_AUDIO_I2SBCLK	MPP( 23, 0x4, 0, 1, 0,   0,   1,   1    )
+#define MPP23_SATA0_PRESENTn	MPP( 23, 0x5, 0, 1, 0,   1,   1,   1    )
+
+#define MPP24_GPIO		MPP( 24, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP24_TSMP4		MPP( 24, 0x1, 1, 1, 0,   0,   1,   1    )
+#define MPP24_TDM_SPI_CS0	DEV( 24, 0x2, 0, 1, 0,   0,   1,   1    )
+#define MPP24_GE1_4		MPP( 24, 0x3, 0, 0, 0,   1,   1,   1    )
+#define MPP24_AUDIO_I2SDO	MPP( 24, 0x4, 0, 1, 0,   0,   1,   1    )
+
+#define MPP25_GPIO		MPP( 25, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP25_TSMP5		MPP( 25, 0x1, 1, 1, 0,   0,   1,   1    )
+#define MPP25_TDM_SPI_SCK	MPP( 25, 0x2, 0, 1, 0,   0,   1,   1    )
+#define MPP25_GE1_5		MPP( 25, 0x3, 0, 0, 0,   1,   1,   1    )
+#define MPP25_AUDIO_I2SLRCLK	MPP( 25, 0x4, 0, 1, 0,   0,   1,   1    )
+
+#define MPP26_GPIO		MPP( 26, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP26_TSMP6		MPP( 26, 0x1, 1, 1, 0,   0,   1,   1    )
+#define MPP26_TDM_SPI_MISO	MPP( 26, 0x2, 1, 0, 0,   0,   1,   1    )
+#define MPP26_GE1_6		MPP( 26, 0x3, 0, 0, 0,   1,   1,   1    )
+#define MPP26_AUDIO_I2SMCLK	MPP( 26, 0x4, 0, 1, 0,   0,   1,   1    )
+
+#define MPP27_GPIO		MPP( 27, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP27_TSMP7		MPP( 27, 0x1, 1, 1, 0,   0,   1,   1    )
+#define MPP27_TDM_SPI_MOSI	MPP( 27, 0x2, 0, 1, 0,   0,   1,   1    )
+#define MPP27_GE1_7		MPP( 27, 0x3, 0, 0, 0,   1,   1,   1    )
+#define MPP27_AUDIO_I2SDI	MPP( 27, 0x4, 1, 0, 0,   0,   1,   1    )
+
+#define MPP28_GPIO		MPP( 28, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP28_TSMP8		MPP( 28, 0x1, 1, 1, 0,   0,   1,   1    )
+#define MPP28_TDM_CODEC_INTn	MPP( 28, 0x2, 0, 0, 0,   0,   1,   1    )
+#define MPP28_GE1_8		MPP( 28, 0x3, 0, 0, 0,   1,   1,   1    )
+#define MPP28_AUDIO_EXTCLK	MPP( 28, 0x4, 1, 0, 0,   0,   1,   1    )
+
+#define MPP29_GPIO		MPP( 29, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP29_TSMP9		MPP( 29, 0x1, 1, 1, 0,   0,   1,   1    )
+#define MPP29_TDM_CODEC_RSTn	MPP( 29, 0x2, 0, 0, 0,   0,   1,   1    )
+#define MPP29_GE1_9		MPP( 29, 0x3, 0, 0, 0,   1,   1,   1    )
+
+#define MPP30_GPIO		MPP( 30, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP30_TSMP10		MPP( 30, 0x1, 1, 1, 0,   0,   1,   1    )
+#define MPP30_TDM_PCLK		MPP( 30, 0x2, 1, 1, 0,   0,   1,   1    )
+#define MPP30_GE1_10		MPP( 30, 0x3, 0, 0, 0,   1,   1,   1    )
+
+#define MPP31_GPIO		MPP( 31, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP31_TSMP11		MPP( 31, 0x1, 1, 1, 0,   0,   1,   1    )
+#define MPP31_TDM_FS		MPP( 31, 0x2, 1, 1, 0,   0,   1,   1    )
+#define MPP31_GE1_11		MPP( 31, 0x3, 0, 0, 0,   1,   1,   1    )
+
+#define MPP32_GPIO		MPP( 32, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP32_TSMP12		MPP( 32, 0x1, 1, 1, 0,   0,   1,   1    )
+#define MPP32_TDM_DRX		MPP( 32, 0x2, 1, 0, 0,   0,   1,   1    )
+#define MPP32_GE1_12		MPP( 32, 0x3, 0, 0, 0,   1,   1,   1    )
+
+#define MPP33_GPIO		MPP( 33, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP33_TDM_DTX		MPP( 33, 0x2, 0, 1, 0,   0,   1,   1    )
+#define MPP33_GE1_13		MPP( 33, 0x3, 0, 0, 0,   1,   1,   1    )
+
+#define MPP34_GPIO		MPP( 34, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP34_TDM_SPI_CS1	MPP( 34, 0x2, 0, 1, 0,   0,   1,   1    )
+#define MPP34_GE1_14		MPP( 34, 0x3, 0, 0, 0,   1,   1,   1    )
+
+#define MPP35_GPIO		MPP( 35, 0x0, 1, 1, 1,   1,   1,   1    )
+#define MPP35_TDM_CH0_TX_QL	MPP( 35, 0x2, 0, 1, 0,   0,   1,   1    )
+#define MPP35_GE1_15		MPP( 35, 0x3, 0, 0, 0,   1,   1,   1    )
+#define MPP35_SATA0_ACTn	MPP( 35, 0x5, 0, 1, 0,   1,   1,   1    )
+#define MPP35_MII0_RXERR	MPP( 35, 0xc, 1, 0, 1,   1,   1,   1    )
+
+#define MPP36_GPIO		MPP( 36, 0x0, 1, 1, 1,   0,   0,   1    )
+#define MPP36_TSMP0		MPP( 36, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP36_TDM_SPI_CS1	MPP( 36, 0x2, 0, 1, 0,   0,   0,   1    )
+#define MPP36_AUDIO_SPDIFI	MPP( 36, 0x4, 1, 0, 1,   0,   0,   1    )
+
+#define MPP37_GPIO		MPP( 37, 0x0, 1, 1, 1,   0,   0,   1    )
+#define MPP37_TSMP1		MPP( 37, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP37_TDM_CH2_TX_QL	MPP( 37, 0x2, 0, 1, 0,   0,   0,   1    )
+#define MPP37_AUDIO_SPDIFO	MPP( 37, 0x4, 0, 1, 1,   0,   0,   1    )
+
+#define MPP38_GPIO		MPP( 38, 0x0, 1, 1, 1,   0,   0,   1    )
+#define MPP38_TSMP2		MPP( 38, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP38_TDM_CH2_RX_QL	MPP( 38, 0x2, 0, 1, 0,   0,   0,   1    )
+#define MPP38_AUDIO_SPDIFRMLCLK	MPP( 38, 0x4, 0, 1, 1,   0,   0,   1    )
+
+#define MPP39_GPIO		MPP( 39, 0x0, 1, 1, 1,   0,   0,   1    )
+#define MPP39_TSMP3		MPP( 39, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP39_TDM_SPI_CS0	MPP( 39, 0x2, 0, 1, 0,   0,   0,   1    )
+#define MPP39_AUDIO_I2SBCLK	MPP( 39, 0x4, 0, 1, 1,   0,   0,   1    )
+
+#define MPP40_GPIO		MPP( 40, 0x0, 1, 1, 1,   0,   0,   1    )
+#define MPP40_TSMP4		MPP( 40, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP40_TDM_SPI_SCK	MPP( 40, 0x2, 0, 1, 0,   0,   0,   1    )
+#define MPP40_AUDIO_I2SDO	MPP( 40, 0x4, 0, 1, 1,   0,   0,   1    )
+
+#define MPP41_GPIO		MPP( 41, 0x0, 1, 1, 1,   0,   0,   1    )
+#define MPP41_TSMP5		MPP( 41, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP41_TDM_SPI_MISO	MPP( 41, 0x2, 1, 0, 0,   0,   0,   1    )
+#define MPP41_AUDIO_I2SLRC	MPP( 41, 0x4, 0, 1, 1,   0,   0,   1    )
+
+#define MPP42_GPIO		MPP( 42, 0x0, 1, 1, 1,   0,   0,   1    )
+#define MPP42_TSMP6		MPP( 42, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP42_TDM_SPI_MOSI	MPP( 42, 0x2, 0, 1, 0,   0,   0,   1    )
+#define MPP42_AUDIO_I2SMCLK	MPP( 42, 0x4, 0, 1, 1,   0,   0,   1    )
+
+#define MPP43_GPIO		MPP( 43, 0x0, 1, 1, 1,   0,   0,   1    )
+#define MPP43_TSMP7		MPP( 43, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP43_TDM_CODEC_INTn	MPP( 43, 0x2, 0, 0, 0,   0,   0,   1    )
+#define MPP43_AUDIO_I2SDI	MPP( 43, 0x4, 1, 0, 1,   0,   0,   1    )
+
+#define MPP44_GPIO		MPP( 44, 0x0, 1, 1, 1,   0,   0,   1    )
+#define MPP44_TSMP8		MPP( 44, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP44_TDM_CODEC_RSTn	MPP( 44, 0x2, 0, 0, 0,   0,   0,   1    )
+#define MPP44_AUDIO_EXTCLK	MPP( 44, 0x4, 1, 0, 1,   0,   0,   1    )
+
+#define MPP45_GPIO		MPP( 45, 0x0, 1, 1, 0,   0,   0,   1    )
+#define MPP45_TSMP9		MPP( 45, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP45_TDM_PCLK		MPP( 45, 0x2, 1, 1, 0,   0,   0,   1    )
+
+#define MPP46_GPIO		MPP( 46, 0x0, 1, 1, 0,   0,   0,   1    )
+#define MPP46_TSMP10		MPP( 46, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP46_TDM_FS		MPP( 46, 0x2, 1, 1, 0,   0,   0,   1    )
+
+#define MPP47_GPIO		MPP( 47, 0x0, 1, 1, 0,   0,   0,   1    )
+#define MPP47_TSMP11		MPP( 47, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP47_TDM_DRX		MPP( 47, 0x2, 1, 0, 0,   0,   0,   1    )
+
+#define MPP48_GPIO		MPP( 48, 0x0, 1, 1, 0,   0,   0,   1    )
+#define MPP48_TSMP12		MPP( 48, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP48_TDM_DTX		MPP( 48. 0x2, 0, 1, 0,   0,   0,   1    )
+
+#define MPP49_GPIO		MPP( 49, 0x0, 1, 1, 0,   0,   0,   1    )
+#define MPP49_TSMP9		MPP( 49, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP49_TDM_CH0_RX_QL	MPP( 49, 0x2, 0, 1, 0,   0,   0,   1    )
+#define MPP49_PTP_CLK		MPP( 49, 0x5, 1, 0, 0,   0,   0,   1    )
+
+#define MPP_MAX			49
+
+void kirkwood_mpp_conf(unsigned int *mpp_list);
+
+#endif
diff --git a/include/asm-arm/arch-kirkwood/spi.h b/include/asm-arm/arch-kirkwood/spi.h
new file mode 100644
index 0000000..8719279
--- /dev/null
+++ b/include/asm-arm/arch-kirkwood/spi.h
@@ -0,0 +1,56 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Prafulla Wadaskar <prafulla@marvell.com>
+ *
+ * Derived from drivers/spi/mpc8xxx_spi.c
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#ifndef __KW_SPI_H__
+#define __KW_SPI_H__
+
+/* SPI Registers on kirkwood SOC */
+struct kwspi_registers {
+	u32 ctrl;	/* 0x10600 */
+	u32 cfg;	/* 0x10604 */
+	u32 dout;	/* 0x10608 */
+	u32 din;	/* 0x1060c */
+	u32 irq_cause;	/* 0x10610 */
+	u32 irq_mask;	/* 0x10614 */
+};
+
+#define KWSPI_CLKPRESCL_MASK	0x1f
+#define KWSPI_CSN_ACT		1 /* Activates serial memory interface */
+#define KWSPI_SMEMRDY		(1 << 1) /* SerMem Data xfer ready */
+#define KWSPI_IRQUNMASK		1 /* unmask SPI interrupt */
+#define KWSPI_IRQMASK		0 /* mask SPI interrupt */
+#define KWSPI_SMEMRDIRQ		1 /* SerMem data xfer ready irq */
+#define KWSPI_XFERLEN_1BYTE	0
+#define KWSPI_XFERLEN_2BYTE	(1 << 5)
+#define KWSPI_XFERLEN_MASK	(1 << 5)
+#define KWSPI_ADRLEN_1BYTE	0
+#define KWSPI_ADRLEN_2BYTE	1 << 8
+#define KWSPI_ADRLEN_3BYTE	2 << 8
+#define KWSPI_ADRLEN_4BYTE	3 << 8
+#define KWSPI_ADRLEN_MASK	3 << 8
+#define KWSPI_TIMEOUT		10000
+
+#endif /* __KW_SPI_H__ */
diff --git a/include/asm-arm/cache.h b/include/asm-arm/cache.h
new file mode 100644
index 0000000..205b5da
--- /dev/null
+++ b/include/asm-arm/cache.h
@@ -0,0 +1,41 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Prafulla Wadaskar <prafulla@marvell.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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#ifndef _ASM_CACHE_H
+#define _ASM_CACHE_H
+
+#include <asm/system.h>
+
+/*
+ * Invalidate L2 Cache using co-proc instruction
+ */
+static inline void invalidate_l2_cache(void)
+{
+	unsigned int val=0;
+
+	asm volatile("mcr p15, 1, %0, c15, c11, 0 @ invl l2 cache"
+		: : "r" (val) : "cc");
+	isb();
+}
+#endif /* _ASM_CACHE_H */
diff --git a/include/common.h b/include/common.h
index 30fff7d..9e4b859 100644
--- a/include/common.h
+++ b/include/common.h
@@ -294,6 +294,7 @@ void	pciinfo	      (int, int);
 #endif
 #endif
 
+int	arch_misc_init (void);
 int	misc_init_f   (void);
 int	misc_init_r   (void);
 
diff --git a/lib_arm/board.c b/lib_arm/board.c
index e081fbc..5c3bfec 100644
--- a/lib_arm/board.c
+++ b/lib_arm/board.c
@@ -399,6 +399,10 @@ void start_armboot (void)
 
 	console_init_r ();	/* fully init console as a device */
 
+#if defined(CONFIG_ARCH_MISC_INIT)
+	/* miscellaneous arch dependent initialisations */
+	arch_misc_init ();
+#endif
 #if defined(CONFIG_MISC_INIT_R)
 	/* miscellaneous platform dependent initialisations */
 	misc_init_r ();
-- 
1.5.3.3

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [U-Boot] [PATCH] Marvell Sheevaplug Board support
  2009-05-21 20:24 [U-Boot] [PATCH v10] Marvell Kirkwood family SOC support Prafulla Wadaskar
@ 2009-05-21 20:24 ` Prafulla Wadaskar
  2009-05-21 20:24   ` [U-Boot] [PATCH] Marvell MV88E1116 PHY Driver support Prafulla Wadaskar
                     ` (2 more replies)
  2009-05-25  4:56 ` [U-Boot] [PATCH v10] Marvell Kirkwood family SOC support Prafulla Wadaskar
  2009-05-25  7:11 ` Stefan Roese
  2 siblings, 3 replies; 18+ messages in thread
From: Prafulla Wadaskar @ 2009-05-21 20:24 UTC (permalink / raw)
  To: u-boot

References: http://plugcomputer.org/
Serial console Setup
http://openplug.org/plugwiki/index.php/Serial_terminal_program#Linux
OpenOCD Setup
http://openplug.org/plugwiki/index.php/Setting_Up_OpenOCD_Under_Linux

This patch is tested for-
1. Boot from DRAM/NAND flash
2. File transfer using tftp
3. NAND flash read/write/erase

Signed-off-by: Prafulla Wadaskar <prafulla@marvell.com>
---
 MAKEALL                               |    1 +
 Makefile                              |    8 +-
 board/Marvell/sheevaplug/Makefile     |   52 +++++++++
 board/Marvell/sheevaplug/config.mk    |   25 +++++
 board/Marvell/sheevaplug/nand.c       |   80 ++++++++++++++
 board/Marvell/sheevaplug/sheevaplug.c |  135 +++++++++++++++++++++++
 board/Marvell/sheevaplug/sheevaplug.h |   37 +++++++
 include/configs/sheevaplug.h          |  191 +++++++++++++++++++++++++++++++++
 8 files changed, 526 insertions(+), 3 deletions(-)
 create mode 100644 board/Marvell/sheevaplug/Makefile
 create mode 100644 board/Marvell/sheevaplug/config.mk
 create mode 100644 board/Marvell/sheevaplug/nand.c
 create mode 100644 board/Marvell/sheevaplug/sheevaplug.c
 create mode 100644 board/Marvell/sheevaplug/sheevaplug.h
 create mode 100644 include/configs/sheevaplug.h

diff --git a/MAKEALL b/MAKEALL
index 6719d7b..e3d33cb 100755
--- a/MAKEALL
+++ b/MAKEALL
@@ -144,6 +144,7 @@ LIST_8xx="		\
 	RPXlite		\
 	RPXlite_DW	\
 	RRvision	\
+	sheevaplug	\
 	SM850		\
 	spc1920		\
 	SPD823TS	\
diff --git a/Makefile b/Makefile
index 8144ecd..34a863b 100644
--- a/Makefile
+++ b/Makefile
@@ -1122,6 +1122,9 @@ RRvision_LCD_config:	unconfig
 	@echo "#define CONFIG_SHARP_LQ104V7DS01" >>$(obj)include/config.h
 	@$(MKCONFIG) -a RRvision ppc mpc8xx RRvision
 
+sheevaplug_config: unconfig
+	@$(MKCONFIG) $(@:_config=) arm arm926ejs $(@:_config=) Marvell kirkwood
+
 SM850_config	:	unconfig
 	@$(MKCONFIG) $(@:_config=) ppc mpc8xx tqm8xx tqc
 
@@ -2808,9 +2811,6 @@ lpd7a400_config \
 lpd7a404_config:	unconfig
 	@$(MKCONFIG) $(@:_config=) arm lh7a40x lpd7a40x
 
-mv88f6281gtw_ge_config: unconfig
-	@$(MKCONFIG) $(@:_config=) arm arm926ejs $(@:_config=) Marvell kirkwood
-
 mx1ads_config	:	unconfig
 	@$(MKCONFIG) $(@:_config=) arm arm920t mx1ads NULL imx
 
@@ -3110,6 +3110,8 @@ omap2420h4_config	: unconfig
 qong_config		: unconfig
 	@$(MKCONFIG) $(@:_config=) arm arm1136 qong davedenx mx31
 
+sheevapluge_config: unconfig
+	@$(MKCONFIG) $(@:_config=) arm arm926ejs $(@:_config=) Marvell kirkwood
 
 #########################################################################
 ## ARM1176 Systems
diff --git a/board/Marvell/sheevaplug/Makefile b/board/Marvell/sheevaplug/Makefile
new file mode 100644
index 0000000..6520776
--- /dev/null
+++ b/board/Marvell/sheevaplug/Makefile
@@ -0,0 +1,52 @@
+#
+# (C) Copyright 2009
+# Marvell Semiconductor <www.marvell.com>
+# Prafulla Wadaskar <prafulla@marvell.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., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(BOARD).a
+
+COBJS	:= sheevaplug.o
+COBJS	+= nand.o
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+SOBJS	:= $(addprefix $(obj),$(SOBJS))
+
+$(LIB):	$(obj).depend $(OBJS) $(SOBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
+
+clean:
+	rm -f $(SOBJS) $(OBJS)
+
+distclean:	clean
+	rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/Marvell/sheevaplug/config.mk b/board/Marvell/sheevaplug/config.mk
new file mode 100644
index 0000000..fb29a1b
--- /dev/null
+++ b/board/Marvell/sheevaplug/config.mk
@@ -0,0 +1,25 @@
+#
+# (C) Copyright 2009
+# Marvell Semiconductor <www.marvell.com>
+# Prafulla Wadaskar <prafulla@marvell.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., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301 USA
+#
+
+TEXT_BASE = 0x00600000
diff --git a/board/Marvell/sheevaplug/nand.c b/board/Marvell/sheevaplug/nand.c
new file mode 100644
index 0000000..ddaf8c5
--- /dev/null
+++ b/board/Marvell/sheevaplug/nand.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ * Prafulla Wadaskar <prafulla@marvell.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
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/kirkwood.h>
+#ifdef CONFIG_CMD_NAND
+#include <nand.h>
+
+static struct kwnandf_registers *nf_reg =
+		(struct kwnandf_registers *)KW_NANDF_BASE;
+
+/*
+ *	hardware specific access to control-lines/bits
+ */
+#define	MASK_CLE			0x01
+#define	MASK_ALE			0x02
+#define NAND_ACTCEBOOT_BIT		0x02
+
+static void kw_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+	struct nand_chip *this = mtd->priv;
+	ulong IO_ADDR_W = (ulong) this->IO_ADDR_W;
+
+	if (ctrl & NAND_CTRL_CHANGE) {
+		if (ctrl & NAND_CLE)
+			IO_ADDR_W |= MASK_CLE;
+		else
+			IO_ADDR_W &= ~MASK_CLE;
+
+		if (ctrl & NAND_ALE)
+			IO_ADDR_W |= MASK_ALE;
+		else
+			IO_ADDR_W &= ~MASK_ALE;
+
+		this->IO_ADDR_W = (void __iomem *)IO_ADDR_W;
+	}
+	if (cmd != NAND_CMD_NONE)
+		writeb(cmd, this->IO_ADDR_W);
+}
+
+void kw_nand_select_chip(struct mtd_info *mtd, int chip)
+{
+	u32 data;
+
+	data = readl(&nf_reg->ctrl);
+	data |= NAND_ACTCEBOOT_BIT;
+	writel(data, &nf_reg->ctrl);
+}
+
+int board_nand_init(struct nand_chip *nand)
+{
+	nand->options = NAND_SAMSUNG_LP_OPTIONS;
+	nand->ecc.mode = NAND_ECC_SOFT;
+	nand->cmd_ctrl = kw_nand_hwcontrol;
+	nand->chip_delay = 30;
+	nand->select_chip = kw_nand_select_chip;
+	return 0;
+}
+#endif /* CONFIG_CMD_NAND */
diff --git a/board/Marvell/sheevaplug/sheevaplug.c b/board/Marvell/sheevaplug/sheevaplug.c
new file mode 100644
index 0000000..b861c24
--- /dev/null
+++ b/board/Marvell/sheevaplug/sheevaplug.c
@@ -0,0 +1,135 @@
+/*
+ * Maintainer : Prafulla Wadaskar <prafulla@marvell.com>
+ *
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Prafulla Wadaskar <prafulla@marvell.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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <common.h>
+#include <netdev.h>
+#include <asm/arch/kirkwood.h>
+#include <asm/arch/mpp.h>
+#include "sheevaplug.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int board_init(void)
+{
+	/*
+	 * default gpio configuration
+	 * There are maximum 64 gpios controlled through 2 sets of registers
+	 * the  below configuration configures mainly initial LED status
+	 */
+	kw_config_gpio(SHEEVAPLUG_OE_VAL_LOW,
+			SHEEVAPLUG_OE_VAL_HIGH,
+			SHEEVAPLUG_OE_LOW, SHEEVAPLUG_OE_HIGH);
+
+	/* Multi-Purpose Pins Functionality configuration */
+	u32 kwmpp_config[] = {
+		MPP0_NF_IO2,
+		MPP1_NF_IO3,
+		MPP2_NF_IO4,
+		MPP3_NF_IO5,
+		MPP4_NF_IO6,
+		MPP5_NF_IO7,
+		MPP6_SYSRST_OUTn,
+		MPP7_GPO,
+		MPP8_UART0_RTS,
+		MPP9_UART0_CTS,
+		MPP10_UART0_TXD,
+		MPP11_UART0_RXD,
+		MPP12_SD_CLK,
+		MPP13_SD_CMD,
+		MPP14_SD_D0,
+		MPP15_SD_D1,
+		MPP16_SD_D2,
+		MPP17_SD_D3,
+		MPP18_NF_IO0,
+		MPP19_NF_IO1,
+		MPP20_GPIO,
+		MPP21_GPIO,
+		MPP22_GPIO,
+		MPP23_GPIO,
+		MPP24_GPIO,
+		MPP25_GPIO,
+		MPP26_GPIO,
+		MPP27_GPIO,
+		MPP28_GPIO,
+		MPP29_TSMP9,
+		MPP30_GPIO,
+		MPP31_GPIO,
+		MPP32_GPIO,
+		MPP33_GPIO,
+		MPP34_GPIO,
+		MPP35_GPIO,
+		MPP36_GPIO,
+		MPP37_GPIO,
+		MPP38_GPIO,
+		MPP39_GPIO,
+		MPP40_GPIO,
+		MPP41_GPIO,
+		MPP42_GPIO,
+		MPP43_GPIO,
+		MPP44_GPIO,
+		MPP45_GPIO,
+		MPP46_GPIO,
+		MPP47_GPIO,
+		MPP48_GPIO,
+		MPP49_GPIO,
+		0
+	};
+	kirkwood_mpp_conf(kwmpp_config);
+
+	/*
+	 * arch number of board
+	 */
+	gd->bd->bi_arch_number = MACH_TYPE_SHEEVAPLUG;
+
+	/* adress of boot parameters */
+	gd->bd->bi_boot_params = kw_sdram_bar(0) + 0x100;
+
+	return 0;
+}
+
+int dram_init(void)
+{
+	int i;
+
+	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+		gd->bd->bi_dram[i].start = kw_sdram_bar(i);
+		gd->bd->bi_dram[i].size = kw_sdram_bs(i);
+	}
+	return 0;
+}
+
+#ifdef CONFIG_MV88E1116_PHY
+void reset_phy(void)
+{
+	/* configure and initialize phy */
+	struct mv88e1116_config phycfg = {
+		.name = "egiga0",
+		.rgmii_delay = MV88E1116_RGMII_DELAY_EN,
+		.led_init = MV88E1116_LED_INIT_EN,
+	};
+	mv88e1116_phy_initialize(&phycfg);
+}
+#endif /* CONFIG_MV88E1116_PHY */
diff --git a/board/Marvell/sheevaplug/sheevaplug.h b/board/Marvell/sheevaplug/sheevaplug.h
new file mode 100644
index 0000000..45bfeca
--- /dev/null
+++ b/board/Marvell/sheevaplug/sheevaplug.h
@@ -0,0 +1,37 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Prafulla Wadaskar <prafulla@marvell.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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#ifndef __SHEEVAPLUG_H
+#define __SHEEVAPLUG_H
+
+#ifndef MACH_TYPE_SHEEVAPLUG
+#define MACH_TYPE_SHEEVAPLUG	2097
+#endif
+
+#define SHEEVAPLUG_OE_LOW		(~(0))
+#define SHEEVAPLUG_OE_HIGH		(~(0))
+#define SHEEVAPLUG_OE_VAL_LOW		(1 << 29)	/* USB_PWEN low */
+#define SHEEVAPLUG_OE_VAL_HIGH		(1 << 17)	/* LED pin high */
+
+#endif /* __SHEEVAPLUG_H */
diff --git a/include/configs/sheevaplug.h b/include/configs/sheevaplug.h
new file mode 100644
index 0000000..671bab6
--- /dev/null
+++ b/include/configs/sheevaplug.h
@@ -0,0 +1,191 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Prafulla Wadaskar <prafulla@marvell.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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#ifndef _CONFIG_SHEEVAPLUG_H
+#define _CONFIG_SHEEVAPLUG_H
+
+/*
+ * Version number information
+ */
+#define CONFIG_IDENT_STRING	"\nMarvell-Sheevaplug"
+
+/*
+ * High Level Configuration Options (easy to change)
+ */
+#define CONFIG_MARVELL		1
+#define CONFIG_ARM926EJS	1	/* Basic Architecture */
+#define CONFIG_FEROCEON_88FR131	1	/* CPU Core subversion */
+#define CONFIG_KIRKWOOD		1	/* SOC Family Name */
+#define CONFIG_KW88F6281	1	/* SOC Name */
+#define CONFIG_MACH_SHEEVAPLUG	/* Machine type */
+
+#define CONFIG_MD5	/* get_random_hex on krikwood needs MD5 support */
+#define CONFIG_SKIP_LOWLEVEL_INIT	/* disable board lowlevel_init */
+#define CONFIG_KIRKWOOD_EGIGA_INIT	/* Enable GbePort0/1 for kernel */
+#define CONFIG_KIRKWOOD_PCIE_INIT	/* Enable PCIE Port0 for kernel */
+#define CONFIG_KIRKWOOD_RGMII_PAD_1V8	/* Set RGMII Pad voltage to 1.8V */
+
+/*
+ * CLKs configurations
+ */
+#define CONFIG_SYS_HZ		1000
+
+/*
+ * NS16550 Configuration
+ */
+#define CONFIG_SYS_NS16550
+#define CONFIG_SYS_NS16550_SERIAL
+#define CONFIG_SYS_NS16550_REG_SIZE	(-4)
+#define CONFIG_SYS_NS16550_CLK		CONFIG_SYS_TCLK
+#define CONFIG_SYS_NS16550_COM1		KW_UART0_BASE
+
+/*
+ * Serial Port configuration
+ * The following definitions let you select what serial you want to use
+ * for your console driver.
+ */
+
+#define CONFIG_CONS_INDEX	1	/*Console on UART0 */
+#define CONFIG_BAUDRATE			115200	/* console baudrate */
+#define CONFIG_SYS_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, \
+					  115200,230400, 460800, 921600 }
+/* auto boot */
+#define CONFIG_BOOTDELAY	3	/* default enable autoboot */
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 8 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define	CONFIG_BOOTMAPSZ	(8 << 20)	/* Initial Memmap for Linux */
+#define CONFIG_CMDLINE_TAG	1	/* enable passing of ATAGs  */
+#define CONFIG_INITRD_TAG	1	/* enable INITRD tag */
+#define CONFIG_SETUP_MEMORY_TAGS 1	/* enable memory tag */
+
+#define	CONFIG_SYS_PROMPT	"Marvell>> "	/* Command Prompt */
+#define	CONFIG_SYS_CBSIZE	1024	/* Console I/O Buff Size */
+#define	CONFIG_SYS_PBSIZE	(CONFIG_SYS_CBSIZE \
+		+sizeof(CONFIG_SYS_PROMPT) + 16)	/* Print Buff */
+/*
+ * Commands configuration
+ */
+#define CONFIG_CMD_ENV
+#define CONFIG_CMD_RUN
+#define CONFIG_CMD_LOADB
+#define CONFIG_CMD_NET
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_AUTOSCRIPT
+#define CONFIG_CMD_MEMORY
+#define CONFIG_CMD_BOOTD
+#define CONFIG_CMD_SAVEENV
+#define CONFIG_CMD_NAND
+
+/*
+ * Flash configuration
+ */
+#ifndef CONFIG_CMD_FLASH
+#define CONFIG_SYS_NO_FLASH		1	/* Declare no flash (NOR/SPI) */
+#endif
+
+/*
+ * NAND configuration
+ */
+#ifdef CONFIG_CMD_NAND
+#define CONFIG_SYS_MAX_NAND_DEVICE	1
+#define NAND_MAX_CHIPS			1
+#define CONFIG_SYS_NAND_BASE		0xf9000000
+#define NAND_ALLOW_ERASE_ALL		1
+#endif
+
+/*
+ *  Environment variables configurations
+ */
+#ifdef CONFIG_CMD_NAND
+#define CONFIG_ENV_IS_IN_NAND		1
+#define CONFIG_ENV_SECT_SIZE		0x20000	/* 128K */
+#else
+#define CONFIG_ENV_IS_NOWHERE		1	/* if env in SDRAM */
+#endif
+#define CONFIG_ENV_SIZE			0x20000	/* 128k */
+#define CONFIG_ENV_ADDR			0x40000
+#define CONFIG_ENV_OFFSET		0x40000	/* env starts here */
+
+/*
+ * Default environment variables
+ */
+#define CONFIG_BOOTCOMMAND		"${x_bootcmd_kernel}; "	\
+	"setenv bootargs ${x_bootargs} ${x_bootargs_root}; "	\
+	"bootm 0x6400000;"
+
+#define CONFIG_MTDPARTS			"orion_nand:512k(uboot),"	\
+	"1m at 4m(psm), 3m at 1m(kernel),13m at 5m(rootfs) rw\0"
+
+#define CONFIG_EXTRA_ENV_SETTINGS	"x_bootargs=console"	\
+	"=ttyS0,115200 mtdparts="CONFIG_MTDPARTS	\
+	"x_bootcmd_kernel=nand read 0x100000 0x6400000 0x300000\0" \
+	"x_bootargs_root=root=/dev/mtdblock3 rw rootfstype=jffs2\0"
+
+/*
+ * Size of malloc() pool
+ */
+#define CONFIG_SYS_MALLOC_LEN	(1024 * 128) /* 128kB for malloc() */
+/* size in bytes reserved for initial data */
+#define CONFIG_SYS_GBL_DATA_SIZE	128
+
+/*
+ * Other required minimal configurations
+ */
+#define CONFIG_CONSOLE_INFO_QUIET	/* some code reduction */
+#define CONFIG_ARCH_CPU_INIT	/* call arch_cpu_init() */
+#define CONFIG_ARCH_MISC_INIT	/* call arch_misc_init() */
+#define CONFIG_DISPLAY_CPUINFO	/* Display cpu info */
+#define CONFIG_NR_DRAM_BANKS	4
+#define CONFIG_STACKSIZE	0x00100000	/* regular stack- 1M */
+#define CONFIG_SYS_LOAD_ADDR	0x00800000	/* default load adr- 8M */
+#define CONFIG_SYS_MEMTEST_START 0x00400000	/* 4M */
+#define CONFIG_SYS_MEMTEST_END	0x007fffff	/*(_8M -1) */
+#define CONFIG_SYS_RESET_ADDRESS 0xffff0000	/* Rst Vector Adr */
+#define CONFIG_SYS_MAXARGS	16	/* max number of command args */
+
+/*
+ * Ethernet Driver configuration
+ */
+#ifdef CONFIG_CMD_NET
+#define CONFIG_NETCONSOLE	/* include NetConsole support   */
+#define CONFIG_NET_MULTI	/* specify more that one ports available */
+#define	CONFIG_MII		/* expose smi ove miiphy interface */
+#define CONFIG_KIRKWOOD_EGIGA	/* Enable kirkwood Gbe Controller Driver */
+#define CONFIG_SYS_FAULT_ECHO_LINK_DOWN	/* detect link using phy */
+#define CONFIG_KIRKWOOD_EGIGA_PORTS	{1,0}	/* enable port 0 only */
+#define CONFIG_PHY_BASE_ADR	0
+#define CONFIG_ENV_OVERWRITE	/* ethaddr can be reprogrammed */
+#endif /* CONFIG_CMD_NET */
+
+/*
+ * Marvell 88Exxxx Switch configurations
+ */
+#define CONFIG_RESET_PHY_R	/* use reset_phy() to init phy/swtich */
+#define CONFIG_MV88E1116_PHY	/* Enable mv88e61xx switch driver */
+
+#endif /* _CONFIG_SHEEVAPLUG_H */
-- 
1.5.3.3

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [U-Boot] [PATCH] Marvell MV88E1116 PHY Driver support
  2009-05-21 20:24 ` [U-Boot] [PATCH] Marvell Sheevaplug Board support Prafulla Wadaskar
@ 2009-05-21 20:24   ` Prafulla Wadaskar
  2009-05-21 20:24     ` [U-Boot] [PATCH v4] Gbe Controller driver support for kirkwood SOCs Prafulla Wadaskar
       [not found]     ` <73173D32E9439E4ABB5151606C3E19E201CFBDC5A1@SC-VEXCH1.marvell.com>
  2009-05-22  8:21   ` [U-Boot] [PATCH] Marvell Sheevaplug Board support Stefan Roese
  2009-05-22 11:02   ` Wolfgang Denk
  2 siblings, 2 replies; 18+ messages in thread
From: Prafulla Wadaskar @ 2009-05-21 20:24 UTC (permalink / raw)
  To: u-boot

Suports Basic PHY init (i.e. PHY reset)
optional supported configurations:
led_init, mdipn_reverse, rgmii_delay config

This driver is tested with sheevaplug board

Signed-off-by: Prafulla Wadaskar <prafulla@marvell.com>
---
 drivers/net/phy/Makefile    |    1 +
 drivers/net/phy/mv88e1116.c |   90 +++++++++++++++++++++++++++++++++++++++++++
 drivers/net/phy/mv88e1116.h |   38 ++++++++++++++++++
 include/netdev.h            |   31 +++++++++++++++
 4 files changed, 160 insertions(+), 0 deletions(-)
 create mode 100644 drivers/net/phy/mv88e1116.c
 create mode 100644 drivers/net/phy/mv88e1116.h

diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 3b92614..ed624b4 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -26,6 +26,7 @@ include $(TOPDIR)/config.mk
 LIB	:= $(obj)libphy.a
 
 COBJS-$(CONFIG_BITBANGMII) += miiphybb.o
+COBJS-$(CONFIG_MV88E1116_PHY) += mv88e1116.o
 COBJS-$(CONFIG_MV88E61XX_SWITCH) += mv88e61xx.o
 
 COBJS	:= $(COBJS-y)
diff --git a/drivers/net/phy/mv88e1116.c b/drivers/net/phy/mv88e1116.c
new file mode 100644
index 0000000..bd210f6
--- /dev/null
+++ b/drivers/net/phy/mv88e1116.c
@@ -0,0 +1,90 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Prafulla Wadaskar <prafulla@marvell.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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <common.h>
+#include <netdev.h>
+#include "mv88e1116.h"
+
+/*
+ * Marvell 88E61XX PHY initialization
+ */
+int mv88e1116_phy_initialize(struct mv88e1116_config *phycfg)
+{
+	char *name = phycfg->name;
+	u16 reg;
+	u16 devadr;
+
+	if (miiphy_set_current_dev(name)) {
+		printf("%s failed\n", __FUNCTION__);
+		return -1;
+	}
+
+	/* command to read PHY dev address */
+	if (miiphy_read(name, 0xEE, 0xEE, (u16 *) &devadr)) {
+		printf("Error..could not read PHY dev address\n");
+		return -1;
+	}
+
+	/*
+	 * Leds link and activity
+	 * LED[0] On-Link, Blink-Activity, Off-NoLink
+	 */
+	if (phycfg->led_init == MV88E1116_LED_INIT_EN) {
+		miiphy_write(name, devadr, MV88E1116_PGADR_REG, 0x3);
+		miiphy_read(name, devadr, MV88E1116_LED_FCTRL_REG, &reg);
+		reg &= ~0xf;
+		reg |= 0x1;
+		miiphy_write(name, devadr, MV88E1116_LED_FCTRL_REG, reg);
+		miiphy_write(name, devadr, MV88E1116_PGADR_REG, 0);
+	}
+
+	/*
+	 * Enable RGMII delay on Tx and Rx for CPU port
+	 * Ref: sec 4.7.2 of chip datasheet
+	 */
+	if (phycfg->rgmii_delay == MV88E1116_RGMII_DELAY_EN) {
+		miiphy_write(name, devadr, MV88E1116_PGADR_REG, 2);
+		miiphy_read(name, devadr, 21, &reg);
+		reg |= (MV88E1116_RGMII_RXTM_CTRL | MV88E1116_RGMII_TXTM_CTRL);
+		miiphy_write(name, devadr, 21, reg);
+		miiphy_write(name, devadr, MV88E1116_PGADR_REG, 0);
+	}
+
+	/*
+	 * Reverse Transmit polarity for Media Dependent Interface
+	 * Pins (MDIP) bits in Copper Specific Control Register 3
+	 * Reference: table 53 chip datasheet
+	 */
+	if (phycfg->mdip == MV88E1116_MDIP_REVERSE) {
+		miiphy_read(name, devadr, MV88E1116_CPRSP_CR3_REG, &reg);
+		reg |= 0xf;
+		miiphy_write(name, devadr, MV88E1116_CPRSP_CR3_REG, reg);
+	}
+
+	/* reset the phy */
+	miiphy_reset(name, devadr);
+
+	printf("88E1116 Initialized on %s\n", name);
+	return 0;
+}
diff --git a/drivers/net/phy/mv88e1116.h b/drivers/net/phy/mv88e1116.h
new file mode 100644
index 0000000..b12be22
--- /dev/null
+++ b/drivers/net/phy/mv88e1116.h
@@ -0,0 +1,38 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Prafulla Wadaskar <prafulla@marvell.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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#ifndef _MV88E1116_H
+#define _MV88E1116_H
+
+#include <miiphy.h>
+
+#define MV88E1116_LED_FCTRL_REG		10
+#define MV88E1116_CPRSP_CR3_REG		21
+#define MV88E1116_MAC_CTRL_REG		21
+#define MV88E1116_PGADR_REG		22
+
+#define MV88E1116_RGMII_TXTM_CTRL	(1 << 4)
+#define MV88E1116_RGMII_RXTM_CTRL	(1 << 5)
+
+#endif /* _MV88E1116_H */
diff --git a/include/netdev.h b/include/netdev.h
index 4f2b23a..f37b6ae 100644
--- a/include/netdev.h
+++ b/include/netdev.h
@@ -163,4 +163,35 @@ struct mv88e61xx_config {
 int mv88e61xx_switch_initialize(struct mv88e61xx_config *swconfig);
 #endif /* CONFIG_MV88E61XX_SWITCH */
 
+/*
+ * Boards with mv88e1116 PHY can use this by defining
+ * CONFIG_MV88E1116_PHY in respective board config header file
+ * the stuct and enums here are used to specify switch config params
+ */
+#if defined(CONFIG_MV88E1116_PHY)
+enum mv88e1116_cfg_mdip {
+	MV88E1116_MDIP_NOCHANGE,
+	MV88E1116_MDIP_REVERSE
+};
+
+enum mv88e1116_cfg_ledinit {
+	MV88E1116_LED_INIT_DIS,
+	MV88E1116_LED_INIT_EN
+};
+
+enum mv88e1116_cfg_rgmiid {
+	MV88E1116_RGMII_DELAY_DIS,
+	MV88E1116_RGMII_DELAY_EN
+};
+
+struct mv88e1116_config {
+	char *name;
+	enum mv88e1116_cfg_rgmiid rgmii_delay;
+	enum mv88e1116_cfg_ledinit led_init;
+	enum mv88e1116_cfg_mdip mdip;
+};
+
+int mv88e1116_phy_initialize(struct mv88e1116_config *phycfg);
+#endif /* CONFIG_MV88E1116_PHY */
+
 #endif /* _NETDEV_H_ */
-- 
1.5.3.3

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [U-Boot] [PATCH v4] Gbe Controller driver support for kirkwood SOCs
  2009-05-21 20:24   ` [U-Boot] [PATCH] Marvell MV88E1116 PHY Driver support Prafulla Wadaskar
@ 2009-05-21 20:24     ` Prafulla Wadaskar
  2009-05-26  6:34       ` Ben Warren
  2009-05-26 14:56       ` Stefan Roese
       [not found]     ` <73173D32E9439E4ABB5151606C3E19E201CFBDC5A1@SC-VEXCH1.marvell.com>
  1 sibling, 2 replies; 18+ messages in thread
From: Prafulla Wadaskar @ 2009-05-21 20:24 UTC (permalink / raw)
  To: u-boot

Contributors:
Yotam Admon <yotam@marvell.com>
Michael Blostein <michaelbl at marvell.com

Reviewed by: Ronen Shitrit <rshitrit@marvell.com>
Signed-off-by: Prafulla Wadaskar <prafulla@marvell.com>
---
Change log:
v2: entire rewrite/restructure of v1
used small names for variable/function names
readl/writel used to access SoC registers
Soc registers accssed using pointers through net device struct
miiphy registration done for external smi read/write access
miiphy_link used to detect phy link presence
cleaned for cosmetic changes

v3: asm/arch/kirkwood.h included in c file

v4: bugfix for phy address read

 cpu/arm926ejs/kirkwood/cpu.c |    8 +
 drivers/net/Makefile         |    1 +
 drivers/net/kirkwood_egiga.c | 1670 ++++++++++++++++++++++++++++++++++++++++++
 drivers/net/kirkwood_egiga.h |  828 +++++++++++++++++++++
 include/netdev.h             |    1 +
 5 files changed, 2508 insertions(+), 0 deletions(-)
 create mode 100644 drivers/net/kirkwood_egiga.c
 create mode 100644 drivers/net/kirkwood_egiga.h

diff --git a/cpu/arm926ejs/kirkwood/cpu.c b/cpu/arm926ejs/kirkwood/cpu.c
index 1286cac..d37c2e2 100644
--- a/cpu/arm926ejs/kirkwood/cpu.c
+++ b/cpu/arm926ejs/kirkwood/cpu.c
@@ -314,3 +314,11 @@ int arch_misc_init(void)
 	return 0;
 }
 #endif /* CONFIG_ARCH_MISC_INIT */
+
+#ifdef CONFIG_KIRKWOOD_EGIGA
+int cpu_eth_init(bd_t *bis)
+{
+	kirkwood_egiga_initialize(bis);
+	return 0;
+}
+#endif
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index a360a50..f0c5654 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -40,6 +40,7 @@ COBJS-$(CONFIG_ENC28J60) += enc28j60.o
 COBJS-$(CONFIG_FSLDMAFEC) += fsl_mcdmafec.o mcfmii.o
 COBJS-$(CONFIG_GRETH) += greth.o
 COBJS-$(CONFIG_INCA_IP_SWITCH) += inca-ip_sw.o
+COBJS-$(CONFIG_KIRKWOOD_EGIGA) += kirkwood_egiga.o
 COBJS-$(CONFIG_DRIVER_KS8695ETH) += ks8695eth.o
 COBJS-$(CONFIG_DRIVER_LAN91C96) += lan91c96.o
 COBJS-$(CONFIG_MACB) += macb.o
diff --git a/drivers/net/kirkwood_egiga.c b/drivers/net/kirkwood_egiga.c
new file mode 100644
index 0000000..b4a8117
--- /dev/null
+++ b/drivers/net/kirkwood_egiga.c
@@ -0,0 +1,1670 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Prafulla Wadaskar <prafulla@marvell.com>
+ *
+ * (C) Copyright 2003
+ * Ingo Assmus <ingo.assmus@keymile.com>
+ *
+ * based on - Driver for MV64360X ethernet ports
+ * Copyright (C) 2002 rabeeh at galileo.co.il
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <common.h>
+#include <net.h>
+#include <malloc.h>
+#include <miiphy.h>
+#include <asm/errno.h>
+#include <asm/types.h>
+#include <asm/byteorder.h>
+#include <asm/arch/kirkwood.h>
+
+/* In case SRAM is cache coherent or non-cacheable */
+#define CONFIG_NOT_COHERENT_CACHE
+#define D_CACHE_FLUSH_LINE(addr, offset) ;
+#define CPU_PIPE_FLUSH	{ __asm__ __volatile__ ("nop;nop;nop;nop;nop;nop;nop");}
+
+#include "kirkwood_egiga.h"
+
+/*
+ * smi_reg_read - Read from ethernet phy register.
+ *
+ * INPUT:
+ * @phy_adr - Phy address.
+ * @reg_ofs - Phy register offset.
+ *
+ * This function reads ethernet phy register.
+ * REturns 16bit phy register value, or 0xffff on error
+ */
+int smi_reg_read(char *devname, u8 phy_adr, u8 reg_ofs, u16 * data)
+{
+	struct eth_device *dev = eth_get_dev_by_name(devname);
+	struct kwgbe_device *dkwgbe = to_dkwgbe(dev);
+	struct kwgbe_registers *regs = dkwgbe->regs;
+	u32 smi_reg;
+	volatile u32 timeout;
+
+	/* check to read parameters */
+	if (phy_adr == 0xEE && reg_ofs == 0xEE) {
+		*data = (u16) (KWGBEREG_RD(regs->phyadr) & 0x00ff);
+		return 0;
+	}
+	/* check parameters */
+	if ((phy_adr << KWGBE_PHY_SMI_DEV_ADDR_OFFS) &
+	    ~KWGBE_PHY_SMI_DEV_ADDR_MASK) {
+		printf("Illegal PHY device address %d\n", phy_adr);
+		return -EFAULT;
+	}
+	if ((reg_ofs << KWGBE_SMI_REG_ADDR_OFFS) & ~KWGBE_SMI_REG_ADDR_MASK) {
+		printf("Illegal PHY register offset %d\n", reg_ofs);
+		return -EFAULT;
+	}
+
+	timeout = KWGBE_PHY_SMI_TIMEOUT;
+	/* wait till the SMI is not busy */
+	do {
+		/* read smi register */
+		smi_reg = KWGBEREG_RD(regs->smi);
+		if (timeout-- == 0) {
+			printf("SMI busy timeout\n");
+			return -EFAULT;
+		}
+	} while (smi_reg & KWGBE_PHY_SMI_BUSY_MASK);
+
+	/* fill the phy address and regiser offset and read opcode */
+	smi_reg =
+	    (phy_adr << KWGBE_PHY_SMI_DEV_ADDR_OFFS) | (reg_ofs <<
+							KWGBE_SMI_REG_ADDR_OFFS)
+	    | KWGBE_PHY_SMI_OPCODE_READ;
+
+	/* write the smi register */
+	KWGBEREG_WR(regs->smi, smi_reg);
+
+	/*wait till readed value is ready */
+	timeout = KWGBE_PHY_SMI_TIMEOUT;
+	do {
+		/* read smi register */
+		smi_reg = KWGBEREG_RD(regs->smi);
+		if (timeout-- == 0) {
+			printf("SMI read-valid timeout\n");
+			return -EFAULT;
+		}
+	} while (!(smi_reg & KWGBE_PHY_SMI_READ_VALID_MASK));
+
+	/* Wait for the data to update in the SMI register */
+	for (timeout = 0; timeout < KWGBE_PHY_SMI_TIMEOUT; timeout++) ;
+
+	*data = (u16) (KWGBEREG_RD(regs->smi) & KWGBE_PHY_SMI_DATA_MASK);
+
+	debug("Reg(phyadr %d, off %d) Phy-value = %04x\n", phy_adr,
+	      reg_ofs, *data);
+
+	return 0;
+}
+
+/*
+ * smi_reg_write - Write to ethernet phy register.
+ *
+ * @phy_adr - Phy address.
+ * @reg_ofs - Phy register offset.
+ * @data    - 16bit data.
+ *
+ * This function write to ethernet phy register.
+ * Returns 0 if write succeed, -EINVAL on bad parameters , MV_ERROR on error .
+ * -ETIME on timeout
+ */
+int smi_reg_write(char *devname, u8 phy_adr, u8 reg_ofs, u16 data)
+{
+	struct eth_device *dev = eth_get_dev_by_name(devname);
+	struct kwgbe_device *dkwgbe = to_dkwgbe(dev);
+	struct kwgbe_registers *regs = dkwgbe->regs;
+	u32 smi_reg;
+	volatile u32 timeout;
+
+	/* check parameters */
+	if ((phy_adr << KWGBE_PHY_SMI_DEV_ADDR_OFFS) &
+	    ~KWGBE_PHY_SMI_DEV_ADDR_MASK) {
+		printf("Illegal phy address\n");
+		return -EINVAL;
+	}
+	if ((reg_ofs << KWGBE_SMI_REG_ADDR_OFFS) & ~KWGBE_SMI_REG_ADDR_MASK) {
+		printf("Illegal register offset\n");
+		return -EINVAL;
+	}
+
+	/* wait till the SMI is not busy */
+	timeout = KWGBE_PHY_SMI_TIMEOUT;
+	do {
+		/* read smi register */
+		smi_reg = KWGBEREG_RD(regs->smi);
+		if (timeout-- == 0) {
+			printf("SMI busy timeout\n");
+			return -ETIME;
+		}
+	} while (smi_reg & KWGBE_PHY_SMI_BUSY_MASK);
+
+	/* fill the phy address and regiser offset and write opcode and data */
+	smi_reg = (data << KWGBE_PHY_SMI_DATA_OFFS);
+	smi_reg |=
+	    (phy_adr << KWGBE_PHY_SMI_DEV_ADDR_OFFS) | (reg_ofs <<
+							KWGBE_SMI_REG_ADDR_OFFS);
+	smi_reg &= ~KWGBE_PHY_SMI_OPCODE_READ;
+
+	/* write the smi register */
+	KWGBEREG_WR(regs->smi, smi_reg);
+
+	return 0;
+}
+
+static int egiga_free_tx_rings(struct eth_device *dev)
+{
+	struct kwgbe_device *dkwgbe = to_dkwgbe(dev);
+	struct kwgbe_portinfo *portinfo = &dkwgbe->portinfo;
+	struct kwgbe_registers *regs = dkwgbe->regs;
+
+	u32 queue;
+	volatile struct kwgbe_tx_dscr *p_tx_curr_desc;
+
+	/* Stop Tx Queues */
+	KWGBEREG_WR(regs->tqc, 0x0000ff00);
+
+	/* Free TX rings */
+	debug("Clearing previously allocated TX queues... \n");
+	for (queue = 0; queue < KW_TXQ_NO; queue++) {
+		/* Free on TX rings */
+		for (p_tx_curr_desc = portinfo->p_tx_desc_area_base[queue];
+		     ((u32) p_tx_curr_desc <=
+		      (u32) portinfo->p_tx_desc_area_base[queue] +
+		      portinfo->tx_desc_area_size[queue]);
+		     p_tx_curr_desc =
+		     (struct kwgbe_tx_dscr *)((u32) p_tx_curr_desc +
+					      TX_DESC_ALIGNED_SIZE)) {
+			/* this is inside for loop */
+			if (p_tx_curr_desc->retinfo != 0) {
+				p_tx_curr_desc->retinfo = 0;
+				debug("freed\n");
+			}
+		}
+		debug("Done\n");
+	}
+	return 0;
+}
+
+static int egiga_free_rx_rings(struct eth_device *dev)
+{
+	struct kwgbe_device *dkwgbe = to_dkwgbe(dev);
+	struct kwgbe_portinfo *portinfo = &dkwgbe->portinfo;
+	struct kwgbe_registers *regs = dkwgbe->regs;
+
+	u32 queue;
+	volatile struct kwgbe_rx_dscr *p_rx_curr_desc;
+
+	/* Stop RX Queues */
+	KWGBEREG_WR(regs->rqc, 0x0000ff00);
+
+	/* Free RX rings */
+	debug("Clearing previously allocated RX queues...\n");
+	for (queue = 0; queue < KW_RXQ_NO; queue++) {
+		/* Free preallocated skb's on RX rings */
+		for (p_rx_curr_desc = portinfo->p_rx_desc_area_base[queue];
+		     (((u32) p_rx_curr_desc <
+		       ((u32) portinfo->p_rx_desc_area_base[queue] +
+			portinfo->rx_desc_area_size[queue])));
+		     p_rx_curr_desc =
+		     (struct kwgbe_rx_dscr *)((u32) p_rx_curr_desc +
+					      RX_DESC_ALIGNED_SIZE)) {
+			if (p_rx_curr_desc->retinfo != 0) {
+				p_rx_curr_desc->retinfo = 0;
+				debug("freed\n");
+			}
+		}
+		debug("Done\n");
+	}
+	return 0;
+}
+
+static void phy_set_addr(struct kwgbe_registers *regs, int phy_addr)
+{
+	KWGBEREG_WR(regs->phyadr, phy_addr);
+}
+
+#ifdef  UPDATE_STATS_BY_SOFTWARE
+/*
+ * egiga_print_stat
+ *
+ * Update the statistics structure in the private data structure
+ *
+ * Input : pointer to ethernet interface network device structure
+ * Output : N/A
+ */
+static void egiga_print_stat(struct eth_device *dev)
+{
+	struct kwgbe_device *dkwgbe = to_dkwgbe(dev);
+	struct egiga_priv *portpriv = &dkwgbe->portpriv;
+	struct net_device_stats *stats = &portpriv->stats;
+
+	/* These are false updates */
+	printf("\n### Network statistics: ###\n");
+	printf("--------------------------\n");
+	printf(" Packets received:		%d\n", stats->rx_packets);
+	printf(" Packets send:			%d\n", stats->tx_packets);
+	printf(" Received bytes:		%lld\n", stats->rx_bytes);
+	printf(" Send bytes:			%lld\n", stats->tx_bytes);
+	if (stats->rx_errors != 0)
+		printf(" Rx Errors:			%d\n",
+		       stats->rx_errors);
+	if (stats->rx_dropped != 0)
+		printf(" Rx dropped (CRC Errors):	%d\n",
+		       stats->rx_dropped);
+	if (stats->multicast != 0)
+		printf(" Rx mulicast frames:		%d\n",
+		       stats->multicast);
+	if (stats->collisions != 0)
+		printf(" No. of collisions:		%d\n",
+		       stats->collisions);
+	if (stats->rx_length_errors != 0)
+		printf(" Rx length errors:		%d\n",
+		       stats->rx_length_errors);
+}
+#endif
+
+/*
+ * kwgbe_stop
+ *
+ * This function is used when closing the network device.
+ * It updates the hardware,
+ * release all memory that holds buffers and descriptors and release the IRQ.
+ * Input : a pointer to the device structure
+ * Output : zero if success , nonzero if fails
+ */
+int kwgbe_stop(struct eth_device *dev)
+{
+	struct kwgbe_device *dkwgbe = to_dkwgbe(dev);
+	struct kwgbe_registers *regs = dkwgbe->regs;
+
+	/* Disable all gigE address decoder */
+	KWGBEREG_WR(regs->bare, 0x3f);
+
+	egiga_free_tx_rings(dev);
+	egiga_free_rx_rings(dev);
+
+	port_reset(regs);
+	/* Disable ethernet port interrupts */
+	KWGBEREG_WR(regs->ic, 0);
+	KWGBEREG_WR(regs->ice, 0);
+	/* Mask RX buffer and TX end interrupt */
+	KWGBEREG_WR(regs->pim, 0);
+	/* Mask phy and link status changes interrupts */
+	KWGBEREG_WR(regs->peim, 0);
+
+	/* Print Network statistics */
+#ifdef  UPDATE_STATS_BY_SOFTWARE
+	struct egiga_priv *portpriv = &dkwgbe->portpriv;
+	/*
+	 * Print statistics (only if ethernet is running),
+	 * then zero all the stats fields in memory
+	 */
+	if (portpriv->running == MAGIC_KWGBE_RUNNING) {
+		portpriv->running = 0;
+		egiga_print_stat(dev);
+	}
+	memset(&portpriv->stats, 0, sizeof(struct net_device_stats));
+#endif
+	debug("Ethernet stopped ...\n");
+	return 0;
+}
+
+/*
+ * clear_mib_counters - Clear all MIB counters
+ *
+ * This function clears all MIB counters of a specific ethernet port.
+ * A read from the MIB counter will reset the counter.
+ *
+ * OUTPUT: After reading all MIB counters, the counters resets.
+ * RETURN: MIB counter value.
+ */
+static void clear_mib_counters(u32 mibc)
+{
+	u32 i = mibc + 0x80;
+	u32 dummy;
+
+	/* Perform dummy reads from MIB counters */
+	for (; mibc < i; mibc += 4) {
+		dummy = readl(mibc);
+	}
+}
+
+/*
+ * egiga_update_stat
+ *
+ * Update the statistics structure in the private data structure
+ *
+ * Input : pointer to ethernet interface network device structure
+ * Output : N/A
+ */
+static void egiga_update_stat(struct eth_device *dev)
+{
+	struct kwgbe_device *dkwgbe = to_dkwgbe(dev);
+	struct egiga_priv *portpriv = &dkwgbe->portpriv;
+	struct net_device_stats *stats = &portpriv->stats;
+	struct mib_counters *mibc = &dkwgbe->regs->mibc;
+
+	/* These are false updates */
+	stats->rx_packets += KWGBEREG_RD(mibc->good_frames_received);
+	stats->tx_packets += KWGBEREG_RD(mibc->good_frames_sent);
+	stats->rx_bytes += KWGBEREG_RD(mibc->good_octets_received);
+	stats->tx_bytes += KWGBEREG_RD(mibc->good_octets_sent);
+	stats->rx_errors += KWGBEREG_RD(mibc->mac_receive_error);
+	/* Rx dropped is for received packet with CRC error */
+	stats->rx_dropped += KWGBEREG_RD(mibc->bad_crc_event);
+	stats->multicast += KWGBEREG_RD(mibc->multicast_frames_received);
+	stats->collisions +=
+	    KWGBEREG_RD(mibc->collision) + KWGBEREG_RD(mibc->late_collision);
+	stats->rx_length_errors +=
+	    KWGBEREG_RD(mibc->undersize_received) +
+	    KWGBEREG_RD(mibc->oversize_received);
+}
+
+/*
+ * egiga_get_stats
+ *
+ * Returns a pointer to the interface statistics.
+ *
+ * Input : dev - a pointer to the required interface
+ * Output : a pointer to the interface's statistics
+ */
+static struct net_device_stats *egiga_get_stats(struct eth_device *dev)
+{
+	struct kwgbe_device *dkwgbe = to_dkwgbe(dev);
+	struct egiga_priv *portpriv = &dkwgbe->portpriv;
+
+	egiga_update_stat(dev);
+	return &portpriv->stats;
+}
+
+/*
+ * set_access_control - Config address decode parameters for Ethernet unit
+ *
+ * This function configures the address decode parameters for the Gigabit
+ * Ethernet Controller according the given parameters struct.
+ *
+ * @regs	Register struct pointer.
+ * @param	Address decode parameter struct.
+ */
+static void set_access_control(struct kwgbe_registers *regs,
+			       struct kwgbe_winparam *param)
+{
+	u32 access_prot_reg;
+
+	/* Set access control register */
+	access_prot_reg = KWGBEREG_RD(regs->epap);
+	access_prot_reg &= (~(3 << (param->win * 2)));	/* clear window permission */
+	access_prot_reg |= (param->access_ctrl << (param->win * 2));
+	KWGBEREG_WR(regs->epap, access_prot_reg);
+
+	/* Set window Size reg (SR) */
+	KWGBEREG_WR(regs->barsz[param->win].size,
+		    (((param->size / 0x10000) - 1) << 16));
+
+	/* Set window Base address reg (BA) */
+	KWGBEREG_WR(regs->barsz[param->win].bar,
+		    (param->target | param->attrib | param->base_addr));
+	/* High address remap reg (HARR) */
+	if (param->win < 4)
+		KWGBEREG_WR(regs->ha_remap[param->win], param->high_addr);
+
+	/* Base address enable reg (BARER) */
+	if (param->enable == 1)
+		KWGBEREG_BITS_RESET(regs->bare, (1 << param->win));
+	else
+		KWGBEREG_BITS_SET(regs->bare, (1 << param->win));
+}
+
+static void set_dram_access(struct kwgbe_registers *regs)
+{
+	struct kwgbe_winparam win_param;
+	int i;
+
+	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+		/* Set access parameters for DRAM bank i */
+		win_param.win = i;	/* Use Ethernet window i */
+		win_param.target = KWGBE_TARGET_DRAM;	/* Window target - DDR  */
+		win_param.access_ctrl = EWIN_ACCESS_FULL;	/* Enable full access */
+		win_param.high_addr = 0;
+		/* Get bank base */
+		win_param.base_addr = kw_sdram_bar(i);
+		win_param.size = kw_sdram_bs(i);	/* Get bank size */
+		if (win_param.size == 0)
+			win_param.enable = 0;
+		else
+			win_param.enable = 1;	/* Enable the access */
+		switch (i) {
+		case 0:
+			/* Enable DRAM bank 0  */
+			win_param.attrib = EBAR_ATTR_DRAM_CS0;
+			break;
+		case 1:
+			/* Enable DRAM bank 1  */
+			win_param.attrib = EBAR_ATTR_DRAM_CS1;
+			break;
+		case 2:
+			/* Enable DRAM bank 2  */
+			win_param.attrib = EBAR_ATTR_DRAM_CS2;
+			break;
+		case 3:
+			/* Enable DRAM bank 3  */
+			win_param.attrib = EBAR_ATTR_DRAM_CS3;
+			break;
+		default:
+			/* invalide bank, disable access */
+			win_param.enable = 0;
+			win_param.attrib = 0;
+			break;
+		}
+#ifndef CONFIG_NOT_COHERENT_CACHE
+		win_param.attrib |= EBAR_ATTR_DRAM_CACHE_COHERENCY_WB;
+#endif
+		/* Set the access control for address window (EPAPR) READ & WRITE */
+		set_access_control(regs, &win_param);
+	}
+}
+
+/*
+ * port_init_mac_tables - Clear all entrance in the UC, SMC and OMC tables
+ *
+ * Go through all the DA filter tables (Unicast, Special Multicast & Other
+ * Multicast) and set each entry to 0.
+ *
+ */
+static void port_init_mac_tables(struct kwgbe_registers *regs)
+{
+	int table_index;
+
+	/* Clear DA filter unicast table (Ex_dFUT) */
+	for (table_index = 0; table_index < 4; ++table_index)
+		KWGBEREG_WR(regs->dfut[table_index], 0);
+
+	for (table_index = 0; table_index < 64; ++table_index) {
+		/* Clear DA filter special multicast table (Ex_dFSMT) */
+		KWGBEREG_WR(regs->dfsmt[table_index], 0);
+		/* Clear DA filter other multicast table (Ex_dFOMT) */
+		KWGBEREG_WR(regs->dfomt[table_index], 0);
+	}
+}
+
+/*
+ * port_init - Initialize the Ethernet port driver
+ *
+ * @p_gbe_pctrl - ptr to Ethernet port control struct
+ *
+ * This function prepares the ethernet port to start its activity:
+ * 1) Completes the ethernet port driver struct initialization toward port
+ *     start routine.
+ * 2) Resets the device to a quiescent state in case of warm reboot.
+ * 3) Enable SDMA access to all four DRAM banks as well as internal SRAM.
+ * 4) Clean MAC tables. The reset status of those tables is unknown.
+ * 5) Set PHY address.
+ * Note: Call this routine prior to port_start routine and after setting
+ *  user values in the user fields of Ethernet port control struct (i.e.
+ *  port_phy_addr).
+ *
+ */
+static void port_init(struct kwgbe_device *dkwgbe)
+{
+	struct kwgbe_portinfo *p_gbe_pctrl = &dkwgbe->portinfo;
+	struct kwgbe_registers *regs = dkwgbe->regs;
+	int queue;
+
+	p_gbe_pctrl->port_config = PRT_CFG_VAL;
+	p_gbe_pctrl->port_config_extend = PORT_CFG_EXTEND_VALUE;
+	p_gbe_pctrl->port_sdma_config = PORT_SDMA_CFG_VALUE;
+	p_gbe_pctrl->port_serial_control = PORT_SERIAL_CONTROL_VALUE;
+
+	p_gbe_pctrl->port_rx_queue_command = 0;
+	p_gbe_pctrl->port_tx_queue_command = 0;
+
+	/* Stop RX Queues */
+	KWGBEREG_WR(regs->rqc, 0x0000ff00);
+
+	/* Clear the ethernet port interrupts */
+	KWGBEREG_WR(regs->ic, 0);
+	KWGBEREG_WR(regs->ice, 0);
+
+	/* Unmask RX buffer and TX end interrupt */
+	KWGBEREG_WR(regs->pim, INT_CAUSE_UNMASK_ALL);
+
+	/* Unmask phy and link status changes interrupts */
+	KWGBEREG_WR(regs->peim, INT_CAUSE_UNMASK_ALL_EXT);
+
+	/* Zero out SW structs */
+	for (queue = 0; queue < MAX_RXQ_NO; queue++) {
+		CURR_RFD_SET((struct kwgbe_rx_dscr *)0x00000000, queue);
+		USED_RFD_SET((struct kwgbe_rx_dscr *)0x00000000, queue);
+		p_gbe_pctrl->rx_resource_err[queue] = 0;
+	}
+
+	for (queue = 0; queue < MAX_TXQ_NO; queue++) {
+		CURR_TFD_SET((struct kwgbe_tx_dscr *)0x00000000, queue);
+		USED_TFD_SET((struct kwgbe_tx_dscr *)0x00000000, queue);
+		FIRST_TFD_SET((struct kwgbe_tx_dscr *)0x00000000, queue);
+		p_gbe_pctrl->tx_resource_err[queue] = 0;
+	}
+
+	port_reset(regs);
+	set_dram_access(regs);
+	port_init_mac_tables(regs);
+}
+
+/*
+ * port_start - Start the Ethernet port activity.
+ *
+ * This routine prepares the Ethernet port for Rx and Tx activity:
+ * 1. Initialize Tx and Rx Current Descriptor Pointer for each queue that
+ *     has been initialized a descriptor's ring (using kwgbe_init_tx_desc_ring
+ *     for Tx and kwgbe_init_rx_desc_ring for Rx)
+ * 2. Initialize and enable the Ethernet configuration port by writing to
+ *     the port's configuration and command registers.
+ * 3. Initialize and enable the SDMA by writing to the SDMA's
+ * configuration and command registers.
+ * After completing these steps, the ethernet port SDMA can starts to
+ * perform Rx and Tx activities.
+ *
+ * Note: Each Rx and Tx queue descriptor's list must be initialized prior
+ * to calling this function (use kwgbe_init_tx_desc_ring for Tx queues and
+ * kwgbe_init_rx_desc_ring for Rx queues).
+ *
+ * OUTPUT: Ethernet port is ready to receive and transmit.
+ *
+ * RETURN: 0 if the port PHY is not up. 1 otherwise.
+ */
+static void port_start(struct kwgbe_device *dkwgbe)
+{
+	struct kwgbe_portinfo *p_gbe_pctrl = &dkwgbe->portinfo;
+	struct kwgbe_registers *regs = dkwgbe->regs;
+	int queue;
+	volatile struct kwgbe_tx_dscr *p_tx_curr_desc;
+	volatile struct kwgbe_rx_dscr *p_rx_curr_desc;
+
+	/* Assignment of Tx CTRP of given queue */
+	for (queue = 0; queue < MAX_TXQ_NO; queue++) {
+		CURR_TFD_GET(p_tx_curr_desc, queue);
+		KWGBEREG_WR(regs->tcqdp[queue], (u32) p_tx_curr_desc);
+	}
+
+	/* Assignment of Rx CRDB of given queue */
+	for (queue = 0; queue < MAX_RXQ_NO; queue++) {
+		CURR_RFD_GET(p_rx_curr_desc, queue);
+		KWGBEREG_WR(regs->crdp[queue], (u32) p_rx_curr_desc);
+
+		if (p_rx_curr_desc != NULL)
+			/* Add the assigned Ethernet address to the port's address table */
+			port_uc_addr_set(regs, p_gbe_pctrl->port_mac_addr,
+					 queue);
+	}
+
+	/* Assign port configuration and command. */
+	KWGBEREG_WR(regs->pxc, p_gbe_pctrl->port_config);
+	KWGBEREG_WR(regs->pxcx, p_gbe_pctrl->port_config_extend);
+	KWGBEREG_WR(regs->psc0, p_gbe_pctrl->port_serial_control);
+	KWGBEREG_BITS_SET(regs->psc0, KWGBE_SERIAL_PORT_EN);
+
+	/* Assign port SDMA configuration */
+	KWGBEREG_WR(regs->sdc, p_gbe_pctrl->port_sdma_config);
+	KWGBEREG_WR(regs->tqx[0].qxttbc, 0x3fffffff);
+	KWGBEREG_WR(regs->tqx[0].tqxtbc, 0x03fffcff);
+	/* Turn off the port/queue bandwidth limitation */
+	KWGBEREG_WR(regs->pmtu, 0x0);
+
+	/* Enable port Rx. */
+	KWGBEREG_WR(regs->rqc, p_gbe_pctrl->port_rx_queue_command);
+
+	/* Set maximum receive buffer to 9700 bytes */
+	KWGBEREG_WR(regs->psc0,
+		    (0x5 << 17) | (KWGBEREG_RD(regs->psc0) & 0xfff1ffff));
+
+	/*
+	 * Set ethernet MTU for leaky bucket mechanism to 0 - this will
+	 * disable the leaky bucket mechanism .
+	 */
+	KWGBEREG_WR(regs->pmtu, 0);
+}
+
+/*
+ * port_uc_addr - This function Set the port unicast address table
+ *
+ * This function locates the proper entry in the Unicast table for the
+ * specified MAC nibble and sets its properties according to function
+ * parameters.
+ * This function add/removes MAC addresses from the port unicast address
+ * table.
+ *
+ * @uc_nibble	Unicast MAC Address last nibble.
+ * @queue	Rx queue number for this MAC address.
+ * @option      0 = Add, 1 = remove address.
+ *
+ * RETURN: 1 if output succeeded. 0 if option parameter is invalid.
+ */
+static int port_uc_addr(struct kwgbe_registers *regs, u8 uc_nibble,
+			enum kwgbe_q queue, int option)
+{
+	u32 unicast_reg;
+	u32 tbl_offset;
+	u32 reg_offset;
+
+	/* Locate the Unicast table entry */
+	uc_nibble = (0xf & uc_nibble);
+	tbl_offset = (uc_nibble / 4);	/* Register offset from unicast table base */
+	reg_offset = uc_nibble % 4;	/* Entry offset within the above register */
+
+	switch (option) {
+	case REJECT_MAC_ADDR:
+		/* Clear accepts frame bit at specified unicast DA table entry */
+		unicast_reg = KWGBEREG_RD(regs->dfut[tbl_offset]);
+		unicast_reg &= (0xFF << (8 * reg_offset));
+		KWGBEREG_WR(regs->dfut[tbl_offset], unicast_reg);
+		break;
+	case ACCEPT_MAC_ADDR:
+		/* Set accepts frame bit at unicast DA filter table entry */
+		unicast_reg = KWGBEREG_RD(regs->dfut[tbl_offset]);
+		unicast_reg &= (0xFF << (8 * reg_offset));
+		unicast_reg |= ((0x01 | (queue << 1)) << (8 * reg_offset));
+		KWGBEREG_WR(regs->dfut[tbl_offset], unicast_reg);
+		break;
+	default:
+		return 0;
+	}
+	return 1;
+}
+
+/*
+ * port_uc_addr_set - This function Set the port Unicast address.
+ *
+ * This function Set the port Ethernet MAC address.
+ *
+ * @p_addr	Address to be set
+ * @queue	Rx queue number for this MAC address.
+ *
+ * OUTPUT: Set MAC address low and high registers. also calls
+ * port_uc_addr() To set the unicast table with the proper info.
+ */
+static void port_uc_addr_set(struct kwgbe_registers *regs, u8 * p_addr,
+			     enum kwgbe_q queue)
+{
+	u32 mac_h;
+	u32 mac_l;
+
+	mac_l = (p_addr[4] << 8) | (p_addr[5]);
+	mac_h =
+	    (p_addr[0] << 24) | (p_addr[1] << 16) | (p_addr[2] << 8) |
+	    (p_addr[3] << 0);
+
+	KWGBEREG_WR(regs->macal, mac_l);
+	KWGBEREG_WR(regs->macah, mac_h);
+
+	/* Accept frames of this address */
+	port_uc_addr(regs, p_addr[5], queue, ACCEPT_MAC_ADDR);
+}
+
+/*
+ * port_reset - Reset Ethernet port
+ *
+ * This routine resets the chip by aborting any SDMA engine activity and
+ * clearing the MIB counters. The Receiver and the Transmit unit are in
+ * idle state after this command is performed and the port is disabled.
+ *
+ */
+static void port_reset(struct kwgbe_registers *regs)
+{
+	u32 reg_data, i;
+
+	/* Stop Tx port activity. Check port Tx activity. */
+	reg_data = KWGBEREG_RD(regs->tqc);
+
+	if (reg_data & 0xFF) {
+		/* Issue stop command for active channels only */
+		KWGBEREG_WR(regs->tqc, (reg_data << 8));
+
+		/* Wait for all Tx activity to terminate. */
+		do {
+			/* Check port cause register that all Tx queues are stopped */
+			reg_data = KWGBEREG_RD(regs->tqc);
+		}
+		while (reg_data & 0xFF);
+	}
+
+	/* Stop Rx port activity. Check port Rx activity. */
+	reg_data = KWGBEREG_RD(regs->rqc);
+
+	if (reg_data & 0xFF) {
+		/* Issue stop command for active channels only */
+		KWGBEREG_WR(regs->rqc, (reg_data << 8));
+
+		/* Wait for all Rx activity to terminate. */
+		do {
+			/* Check port cause register that all Rx queues are stopped */
+			reg_data = KWGBEREG_RD(regs->rqc);
+		}
+		while (reg_data & 0xFF);
+	}
+
+	/* Clear all MIB counters */
+	clear_mib_counters((u32) &regs->mibc);
+
+	/* Enable port in the Configuration Register */
+	KWGBEREG_BITS_RESET(regs->psc0, KWGBE_SERIAL_PORT_EN);
+	/* Set port of active in the Configuration Register */
+	KWGBEREG_BITS_RESET(regs->psc1, 1 << 4);
+#ifdef CONFIG_SYS_MII_MODE
+	/* Set MMI interface up */
+	KWGBEREG_BITS_RESET(regs->psc1, 1 << 3);
+#endif
+	for (i = 0; i < 4000; i++) ;
+	return;
+}
+
+/*
+ * kwgbe_init_rx_desc_ring - Curve a Rx chain desc list and buffer in memory.
+ *
+ * This function prepares a Rx chained list of descriptors and packet
+ * buffers in a form of a ring. The routine must be called after port
+ * initialization routine and before port start routine.
+ * The Ethernet SDMA engine uses CPU bus addresses to access the various
+ * devices in the system (i.e. DRAM). This function uses the ethernet
+ * struct 'virtual to physical' routine (set by the user) to set the ring
+ * with physical addresses.
+ *
+ * @rx_queue		Number of Rx queue.
+ * @rx_desc_num		Number of Rx descriptors
+ * @rx_buff_size	Size of Rx buffer
+ * @rx_desc_base_addr	Rx descriptors memory area base addr.
+ * @rx_buff_base_addr	Rx buffer memory area base addr.
+ *
+ * The routine updates the Ethernet port control struct with information
+ * regarding the Rx descriptors and buffers.
+ *
+ * RETURN:
+ * 0 if the given descriptors memory area is not aligned according to
+ * Ethernet SDMA specifications.
+ * 1 otherwise.
+ */
+static int kwgbe_init_rx_desc_ring(struct kwgbe_device *dkwgbe,
+				   enum kwgbe_q rx_queue,
+				   int rx_desc_num,
+				   int rx_buff_size,
+				   u32 rx_desc_base_addr, u32 rx_buff_base_addr)
+{
+	struct kwgbe_portinfo *p_gbe_pctrl = &dkwgbe->portinfo;
+	struct kwgbe_rx_dscr *p_rx_desc;
+	/* pointer to link with the last descriptor */
+	struct kwgbe_rx_dscr *p_rx_prev_desc;
+	u32 buffer_addr;
+	int ix;			/* a counter */
+
+	p_rx_desc = (struct kwgbe_rx_dscr *)rx_desc_base_addr;
+	p_rx_prev_desc = p_rx_desc;
+	buffer_addr = rx_buff_base_addr;
+
+	/* Rx desc Must be 4LW aligned (i.e. Descriptor_Address[3:0]=0000). */
+	if (rx_buff_base_addr & 0xF)
+		return 0;
+
+	/* Rx buffers are limited to 64K bytes and Minimum size is 8 bytes  */
+	if ((rx_buff_size < 8) || (rx_buff_size > RX_BUF_MXSZ))
+		return 0;
+
+	/* Rx buffers must be 64-bit aligned.       */
+	if ((rx_buff_base_addr + rx_buff_size) & 0x7)
+		return 0;
+
+	/* initialize the Rx descriptors ring */
+	for (ix = 0; ix < rx_desc_num; ix++) {
+		p_rx_desc->buf_size = rx_buff_size;
+		p_rx_desc->byte_cnt = 0x0000;
+		p_rx_desc->cmd_sts =
+		    KWGBE_BUFFER_OWNED_BY_DMA | KWGBE_RX_EN_INTERRUPT;
+		p_rx_desc->nxtdesc_p = ((u32) p_rx_desc) + RX_DESC_ALIGNED_SIZE;
+		p_rx_desc->buf_ptr = buffer_addr;
+		p_rx_desc->retinfo = 0x00000000;
+		D_CACHE_FLUSH_LINE(p_rx_desc, 0);
+		buffer_addr += rx_buff_size;
+		p_rx_prev_desc = p_rx_desc;
+		p_rx_desc = (struct kwgbe_rx_dscr *)
+		    ((u32) p_rx_desc + RX_DESC_ALIGNED_SIZE);
+	}
+
+	/* Closing Rx descriptors ring */
+	p_rx_prev_desc->nxtdesc_p = (rx_desc_base_addr);
+	D_CACHE_FLUSH_LINE(p_rx_prev_desc, 0);
+
+	/* Save Rx desc pointer to driver struct. */
+	CURR_RFD_SET((struct kwgbe_rx_dscr *)rx_desc_base_addr, rx_queue);
+	USED_RFD_SET((struct kwgbe_rx_dscr *)rx_desc_base_addr, rx_queue);
+
+	p_gbe_pctrl->p_rx_desc_area_base[rx_queue] =
+	    (struct kwgbe_rx_dscr *)rx_desc_base_addr;
+	p_gbe_pctrl->rx_desc_area_size[rx_queue] =
+	    rx_desc_num * RX_DESC_ALIGNED_SIZE;
+
+	p_gbe_pctrl->port_rx_queue_command |= (1 << rx_queue);
+
+	return 1;
+}
+
+/*
+ * kwgbe_init_tx_desc_ring - Curve a Tx chain desc list and buffer in memory.
+ *
+ * This function prepares a Tx chained list of descriptors and packet
+ * buffers in a form of a ring. The routine must be called after port
+ * initialization routine and before port start routine.
+ * The Ethernet SDMA engine uses CPU bus addresses to access the various
+ * devices in the system (i.e. DRAM). This function uses the ethernet
+ * struct 'virtual to physical' routine (set by the user) to set the ring
+ * with physical addresses.
+ *
+ * @p_gbe_pctrl		Ethernet Port Control srtuct ptr.
+ * @tx_queue		Number of Tx queue.
+ * @tx_desc_num		Number of Tx descriptors
+ * @tx_buff_size	Size of Tx buffer
+ * @tx_desc_base_addr	Tx descriptors memory area base addr.
+ * @tx_buff_base_addr	Tx buffer memory area base addr.
+ *
+ * The routine updates the Ethernet port control struct with information
+ * regarding the Tx descriptors and buffers.
+ *
+ * RETURN:
+ * 0 if the given descriptors memory area is not aligned according to
+ * Ethernet SDMA specifications.
+ * 1 otherwise.
+ */
+static int kwgbe_init_tx_desc_ring(struct kwgbe_device *dkwgbe,
+				   enum kwgbe_q tx_queue,
+				   int tx_desc_num,
+				   int tx_buff_size,
+				   u32 tx_desc_base_addr, u32 tx_buff_base_addr)
+{
+	struct kwgbe_portinfo *p_gbe_pctrl = &dkwgbe->portinfo;
+	struct kwgbe_tx_dscr *p_tx_desc;
+	struct kwgbe_tx_dscr *p_tx_prev_desc;
+	u32 buffer_addr;
+	int ix;			/* a counter */
+
+	/* save the first desc pointer to link with the last descriptor */
+	p_tx_desc = (struct kwgbe_tx_dscr *)tx_desc_base_addr;
+	p_tx_prev_desc = p_tx_desc;
+	buffer_addr = tx_buff_base_addr;
+
+	/* Tx desc Must be 4LW aligned (i.e. Descriptor_Address[3:0]=0000). */
+	if (tx_buff_base_addr & 0xF)
+		return 0;
+
+	/* Tx buffers are limited to 64K bytes and Minimum size is 8 bytes  */
+	if ((tx_buff_size > TX_BUF_MXSZ)
+	    || (tx_buff_size < TX_BUF_MNSZ))
+		return 0;
+
+	/* Initialize the Tx descriptors ring */
+	for (ix = 0; ix < tx_desc_num; ix++) {
+		p_tx_desc->byte_cnt = 0x0000;
+		p_tx_desc->l4i_chk = 0x0000;
+		p_tx_desc->cmd_sts = 0x00000000;
+		p_tx_desc->nxtdesc_p = ((u32) p_tx_desc) + TX_DESC_ALIGNED_SIZE;
+
+		p_tx_desc->buf_ptr = buffer_addr;
+		p_tx_desc->retinfo = 0x00000000;
+		D_CACHE_FLUSH_LINE(p_tx_desc, 0);
+		buffer_addr += tx_buff_size;
+		p_tx_prev_desc = p_tx_desc;
+		p_tx_desc = (struct kwgbe_tx_dscr *)
+		    ((u32) p_tx_desc + TX_DESC_ALIGNED_SIZE);
+
+	}
+	/* Closing Tx descriptors ring */
+	p_tx_prev_desc->nxtdesc_p = tx_desc_base_addr;
+	D_CACHE_FLUSH_LINE(p_tx_prev_desc, 0);
+	/* Set Tx desc pointer in driver struct. */
+	CURR_TFD_SET((struct kwgbe_tx_dscr *)tx_desc_base_addr, tx_queue);
+	USED_TFD_SET((struct kwgbe_tx_dscr *)tx_desc_base_addr, tx_queue);
+
+	/* Init Tx ring base and size parameters */
+	p_gbe_pctrl->p_tx_desc_area_base[tx_queue] =
+	    (struct kwgbe_tx_dscr *)tx_desc_base_addr;
+	p_gbe_pctrl->tx_desc_area_size[tx_queue] =
+	    (tx_desc_num * TX_DESC_ALIGNED_SIZE);
+
+	/* Add the queue to the list of Tx queues of this port */
+	p_gbe_pctrl->port_tx_queue_command |= (1 << tx_queue);
+
+	return 1;
+}
+
+/*
+ * b_copy - Copy bytes from source to destination
+ *
+ * This function supports the eight bytes limitation on Tx buffer size.
+ * The routine will zero eight bytes starting from the destination address
+ * followed by copying bytes from the source address to the destination.
+ *
+ * @src_addr		32 bit source address.
+ * @dst_add		32 bit destination address.
+ * @byte_count		Number of bytes to copy.
+ */
+static void b_copy(u32 src_addr, u32 dst_addr, int byte_count)
+{
+	/* Zero the dst_addr area */
+	*(u32 *) dst_addr = 0x0;
+
+	while (byte_count != 0) {
+		*(char *)dst_addr = *(char *)src_addr;
+		dst_addr++;
+		src_addr++;
+		byte_count--;
+	}
+}
+
+/*
+ * port_send - Send an Ethernet packet
+ *
+ * This routine send a given packet described by p_pktinfo parameter. It
+ * supports transmitting of a packet spaned over multiple buffers. The
+ * routine updates 'curr' and 'first' indexes according to the packet
+ * segment passed to the routine. In case the packet segment is first,
+ * the 'first' index is update. In any case, the 'curr' index is updated.
+ * If the routine get into Tx resource error it assigns 'curr' index as
+ * 'first'. This way the function can abort Tx process of multiple
+ * descriptors per packet.
+ *
+ * @tx_queue		Number of Tx queue.
+ * @p_pkt_info		User packet buffer ptr.
+ *
+ * OUTPUT: Tx ring 'curr' and 'first' indexes are updated.
+ *
+ * RETURN:
+ * KWGBE_QFULL in case of Tx resource error.
+ * KWGBE_ERROR in case the routine can not access Tx desc ring.
+ * KWGBE_QLAST_RESO if the routine uses the last Tx resource.
+ * KWGBE_OK otherwise.
+ */
+static enum kwgbe_fret_sts port_send(struct kwgbe_device *dkwgbe,
+				     enum kwgbe_q tx_queue,
+				     struct kwgbe_pktinf *p_pkt_info)
+{
+	struct kwgbe_portinfo *p_gbe_pctrl = &dkwgbe->portinfo;
+	struct kwgbe_registers *regs = dkwgbe->regs;
+	volatile struct kwgbe_tx_dscr *p_tx_desc_first;
+	volatile struct kwgbe_tx_dscr *p_tx_desc_curr;
+	volatile struct kwgbe_tx_dscr *p_tx_next_desc_curr;
+	volatile struct kwgbe_tx_dscr *p_tx_desc_used;
+	u32 command_status;
+
+#ifdef CONFIG_TX_PKT_DISPLAY
+	{
+		u16 pcnt = p_pkt_info->byte_cnt;
+		u8 *prnt = (u8 *) p_pkt_info->buf_ptr;
+		printf("cnt=%d,", pcnt);
+		while (pcnt) {
+			printf("%02x,", prnt[0]);
+			prnt++;
+			pcnt--;
+		}
+		printf(" pckend\n");
+	}
+#endif
+	/* Do not process Tx ring in case of Tx ring resource error */
+	if (p_gbe_pctrl->tx_resource_err[tx_queue] == 1)
+		return KWGBE_QFULL;
+
+	/* Get the Tx Desc ring indexes */
+	CURR_TFD_GET(p_tx_desc_curr, tx_queue);
+	USED_TFD_GET(p_tx_desc_used, tx_queue);
+
+	if (p_tx_desc_curr == NULL)
+		return KWGBE_ERROR;
+
+	/* The following parameters are used to save readings from memory */
+	p_tx_next_desc_curr = TX_NEXT_DESC_PTR(p_tx_desc_curr, tx_queue);
+	command_status =
+	    p_pkt_info->cmd_sts | KWGBE_ZERO_PADDING | KWGBE_GEN_CRC;
+
+	if (command_status & (KWGBE_TX_FIRST_DESC)) {
+		/* Update first desc */
+		FIRST_TFD_SET(p_tx_desc_curr, tx_queue);
+		p_tx_desc_first = p_tx_desc_curr;
+	} else {
+		FIRST_TFD_GET(p_tx_desc_first, tx_queue);
+		command_status |= KWGBE_BUFFER_OWNED_BY_DMA;
+	}
+
+	/*
+	 * Buffers with a payload smaller than 8 bytes must be aligned to 64-bit
+	 * boundary. We use the memory allocated for Tx descriptor. This memory
+	 * located in TX_BUF_OFFSET_IN_DESC offset within the Tx descriptor.
+	 */
+	if (p_pkt_info->byte_cnt <= 8) {
+		printf("You have failed in the < 8 bytes errata - fixme\n");
+		return KWGBE_ERROR;
+
+		p_tx_desc_curr->buf_ptr =
+		    (u32) p_tx_desc_curr + TX_BUF_OFFSET_IN_DESC;
+		b_copy(p_pkt_info->buf_ptr, p_tx_desc_curr->buf_ptr,
+		       p_pkt_info->byte_cnt);
+	} else
+		p_tx_desc_curr->buf_ptr = p_pkt_info->buf_ptr;
+
+	p_tx_desc_curr->byte_cnt = p_pkt_info->byte_cnt;
+	p_tx_desc_curr->retinfo = p_pkt_info->retinfo;
+
+	if (p_pkt_info->cmd_sts & (KWGBE_TX_LAST_DESC)) {
+		/* Set last desc with DMA ownership and interrupt enable. */
+		p_tx_desc_curr->cmd_sts = command_status |
+		    KWGBE_BUFFER_OWNED_BY_DMA | KWGBE_TX_EN_INTERRUPT;
+
+		if (p_tx_desc_curr != p_tx_desc_first)
+			p_tx_desc_first->cmd_sts |= KWGBE_BUFFER_OWNED_BY_DMA;
+
+		/* Flush CPU pipe */
+		D_CACHE_FLUSH_LINE((u32) p_tx_desc_curr, 0);
+		D_CACHE_FLUSH_LINE((u32) p_tx_desc_first, 0);
+		CPU_PIPE_FLUSH;
+
+		/* Apply send command */
+		KWGBEREG_WR(regs->tqc, (1 << tx_queue));
+		debug("packet xmitted\n");
+
+		/*
+		 * Finish Tx packet.
+		 * Update first desc in case of Tx resource error
+		 */
+		p_tx_desc_first = p_tx_next_desc_curr;
+		FIRST_TFD_SET(p_tx_desc_first, tx_queue);
+
+	} else {
+		p_tx_desc_curr->cmd_sts = command_status;
+		D_CACHE_FLUSH_LINE((u32) p_tx_desc_curr, 0);
+	}
+
+	/* Check for ring index overlap in the Tx desc ring */
+	if (p_tx_next_desc_curr == p_tx_desc_used) {
+		/* Update the current descriptor */
+		CURR_TFD_SET(p_tx_desc_first, tx_queue);
+
+		p_gbe_pctrl->tx_resource_err[tx_queue] = 1;
+		return KWGBE_QLAST_RESO;
+	} else {
+		/* Update the current descriptor */
+		CURR_TFD_SET(p_tx_next_desc_curr, tx_queue);
+		return KWGBE_OK;
+	}
+}
+
+/*
+ * tx_return_desc - Free all used Tx descriptors
+ *
+ * This routine returns the transmitted packet information to the caller.
+ * It uses the 'first' index to support Tx desc return in case a transmit
+ * of a packet spanned over multiple buffer still in process.
+ * In case the Tx queue was in "resource error" condition, where there are
+ * no available Tx resources, the function resets the resource error flag.
+ *
+ * @p_gbe_pctrl		Ethernet Port Control srtuct ptr.
+ * @tx_queue		Number of Tx queue.
+ * @p_pkt_info		User packet buffer ptr.
+ *
+ * OUTPUT:Tx ring 'first' and 'used' indexes are updated.
+ *
+ * RETURN:
+ * KWGBE_ERROR in case the routine can not access Tx desc ring.
+ * KWGBE_RETRY in case there is transmission in process.
+ * KWGBE_END_OF_JOB if the routine has nothing to release.
+ * KWGBE_OK otherwise.
+ */
+static enum kwgbe_fret_sts tx_return_desc(struct kwgbe_device *dkwgbe,
+					  enum kwgbe_q tx_queue,
+					  struct kwgbe_pktinf *p_pkt_info)
+{
+	struct kwgbe_portinfo *p_gbe_pctrl = &dkwgbe->portinfo;
+	volatile struct kwgbe_tx_dscr *p_tx_desc_used = NULL;
+	volatile struct kwgbe_tx_dscr *p_tx_desc_first = NULL;
+	u32 command_status;
+
+	/* Get the Tx Desc ring indexes */
+	USED_TFD_GET(p_tx_desc_used, tx_queue);
+	FIRST_TFD_GET(p_tx_desc_first, tx_queue);
+
+	/* Sanity check */
+	if (p_tx_desc_used == NULL)
+		return KWGBE_ERROR;
+
+	command_status = p_tx_desc_used->cmd_sts;
+
+	/* Still transmitting... */
+	if (command_status & (KWGBE_BUFFER_OWNED_BY_DMA)) {
+		D_CACHE_FLUSH_LINE((u32) p_tx_desc_used, 0);
+		return KWGBE_RETRY;
+	}
+
+	/* Stop release. About to overlap the current available Tx descriptor */
+	if ((p_tx_desc_used == p_tx_desc_first) &&
+	    (p_gbe_pctrl->tx_resource_err[tx_queue] == 0)) {
+		D_CACHE_FLUSH_LINE((u32) p_tx_desc_used, 0);
+		return KWGBE_END_OF_JOB;
+	}
+
+	/* Pass the packet information to the caller */
+	p_pkt_info->cmd_sts = command_status;
+	p_pkt_info->retinfo = p_tx_desc_used->retinfo;
+	p_tx_desc_used->retinfo = 0;
+
+	/* Update the next descriptor to release. */
+	USED_TFD_SET(TX_NEXT_DESC_PTR(p_tx_desc_used, tx_queue), tx_queue);
+
+	/* Any Tx return cancels the Tx resource error status */
+	if (p_gbe_pctrl->tx_resource_err[tx_queue] == 1)
+		p_gbe_pctrl->tx_resource_err[tx_queue] = 0;
+
+	D_CACHE_FLUSH_LINE((u32) p_tx_desc_used, 0);
+
+	return KWGBE_OK;
+}
+
+/*
+ * port_receive - Get received information from Rx ring.
+ *
+ * This routine returns the received data to the caller. There is no
+ * data copying during routine operation. All information is returned
+ * using pointer to packet information struct passed from the caller.
+ * If the routine exhausts	Rx ring resources then the resource error flag
+ * is set.
+ *
+ * @p_gbe_pctrl		Ethernet Port Control srtuct ptr.
+ * @rx_queue		Number of Rx queue.
+ * @p_pkt_info		User packet buffer.
+ *
+ * OUTPUT: Rx ring current and used indexes are updated.
+ *
+ * RETURN:
+ * KWGBE_ERROR in case the routine can not access Rx desc ring.
+ * KWGBE_QFULL if Rx ring resources are exhausted.
+ * KWGBE_END_OF_JOB if there is no received data.
+ * KWGBE_OK otherwise.
+ */
+static enum kwgbe_fret_sts port_receive(struct kwgbe_device *dkwgbe,
+					enum kwgbe_q rx_queue,
+					struct kwgbe_pktinf *p_pkt_info)
+{
+	struct kwgbe_portinfo *p_gbe_pctrl = &dkwgbe->portinfo;
+	volatile struct kwgbe_rx_dscr *p_rx_curr_desc;
+	volatile struct kwgbe_rx_dscr *p_rx_next_curr_desc;
+	volatile struct kwgbe_rx_dscr *p_rx_used_desc;
+	u32 command_status;
+
+	/* Do not process Rx ring in case of Rx ring resource error */
+	if (p_gbe_pctrl->rx_resource_err[rx_queue] == 1) {
+		printf("Rx Queue is full ...\n");
+		return KWGBE_QFULL;
+	}
+
+	/* Get the Rx Desc ring 'curr and 'used' indexes */
+	CURR_RFD_GET(p_rx_curr_desc, rx_queue);
+	USED_RFD_GET(p_rx_used_desc, rx_queue);
+
+	/* Sanity check */
+	if (p_rx_curr_desc == NULL)
+		return KWGBE_ERROR;
+
+	/* The following parameters are used to save readings from memory */
+	p_rx_next_curr_desc = RX_NEXT_DESC_PTR(p_rx_curr_desc, rx_queue);
+	command_status = p_rx_curr_desc->cmd_sts;
+
+	/* Nothing to receive... */
+	if (command_status & (KWGBE_BUFFER_OWNED_BY_DMA)) {
+		/*debug("Rx: command_status: %08x\n", command_status); */
+		D_CACHE_FLUSH_LINE((u32) p_rx_curr_desc, 0);
+		/*debug("KWGBE_END_OF_JOB ...\n"); */
+		return KWGBE_END_OF_JOB;
+	}
+
+	p_pkt_info->byte_cnt = (p_rx_curr_desc->byte_cnt) - RX_BUF_OFFSET;
+	p_pkt_info->cmd_sts = command_status;
+	p_pkt_info->buf_ptr = (p_rx_curr_desc->buf_ptr) + RX_BUF_OFFSET;
+	p_pkt_info->retinfo = p_rx_curr_desc->retinfo;
+	p_pkt_info->l4i_chk = p_rx_curr_desc->buf_size;	/* IP fragment indicator */
+
+	/* Clean the return info field to indicate that the packet has been */
+	/* moved to the upper layers                                        */
+	p_rx_curr_desc->retinfo = 0;
+
+	/* Update 'curr' in data structure */
+	CURR_RFD_SET(p_rx_next_curr_desc, rx_queue);
+
+	/* Rx descriptors resource exhausted. Set the Rx ring resource error flag */
+	if (p_rx_next_curr_desc == p_rx_used_desc)
+		p_gbe_pctrl->rx_resource_err[rx_queue] = 1;
+
+	D_CACHE_FLUSH_LINE((u32) p_rx_curr_desc, 0);
+	CPU_PIPE_FLUSH;
+	return KWGBE_OK;
+}
+
+/*
+ * rx_return_buff - Returns a Rx buffer back to the Rx ring.
+ *
+ * This routine returns a Rx buffer back to the Rx ring. It retrieves the
+ * next 'used' descriptor and attached the returned buffer to it.
+ * In case the Rx ring was in "resource error" condition, where there are
+ * no available Rx resources, the function resets the resource error flag.
+ *
+ * @p_gbe_pctrl		Ethernet Port Control srtuct ptr.
+ * @rx_queue		Number of Rx queue.
+ * @p_pkt_info		Information on the returned buffer ptr.
+ *
+ * OUTPUT: New available Rx resource in Rx descriptor ring.
+ *
+ * RETURN:
+ * KWGBE_ERROR in case the routine can not access Rx desc ring.
+ * KWGBE_OK otherwise.
+ */
+static enum kwgbe_fret_sts rx_return_buff(struct kwgbe_device *dkwgbe,
+					  enum kwgbe_q rx_queue,
+					  struct kwgbe_pktinf *p_pkt_info)
+{
+	struct kwgbe_portinfo *p_gbe_pctrl = &dkwgbe->portinfo;
+	volatile struct kwgbe_rx_dscr *p_used_rx_desc;	/* Where to return Rx resource */
+
+	/* Get 'used' Rx descriptor */
+	USED_RFD_GET(p_used_rx_desc, rx_queue);
+
+	/* Sanity check */
+	if (p_used_rx_desc == NULL)
+		return KWGBE_ERROR;
+
+	p_used_rx_desc->buf_ptr = p_pkt_info->buf_ptr;
+	p_used_rx_desc->retinfo = p_pkt_info->retinfo;
+	p_used_rx_desc->byte_cnt = p_pkt_info->byte_cnt;
+	p_used_rx_desc->buf_size = KW_RX_BUF_SZ;	/* Reset Buffer size */
+
+	/* Flush the write pipe */
+	CPU_PIPE_FLUSH;
+
+	/* Return the descriptor to DMA ownership */
+	p_used_rx_desc->cmd_sts =
+	    KWGBE_BUFFER_OWNED_BY_DMA | KWGBE_RX_EN_INTERRUPT;
+
+	/* Flush descriptor and CPU pipe */
+	D_CACHE_FLUSH_LINE((u32) p_used_rx_desc, 0);
+	CPU_PIPE_FLUSH;
+
+	/* Move the used descriptor pointer to the next descriptor */
+	USED_RFD_SET(RX_NEXT_DESC_PTR(p_used_rx_desc, rx_queue), rx_queue);
+
+	/* Any Rx return cancels the Rx resource error status */
+	if (p_gbe_pctrl->rx_resource_err[rx_queue] == 1)
+		p_gbe_pctrl->rx_resource_err[rx_queue] = 0;
+
+	return KWGBE_OK;
+}
+
+/*
+ * init function
+ */
+static int kwgbe_init(struct eth_device *dev)
+{
+	struct kwgbe_device *dkwgbe = to_dkwgbe(dev);
+	struct kwgbe_portinfo *portinfo = &dkwgbe->portinfo;
+	struct egiga_priv *portpriv = &dkwgbe->portpriv;
+
+	u32 queue;
+
+	/*
+	 * ronen - when we update the MAC env params we only update dev->enetaddr
+	 * see ./net/eth.c set_enetaddr()
+	 */
+	memcpy(portinfo->port_mac_addr, dev->enetaddr, 6);
+
+	/* Activate the DMA channels etc */
+	port_init(dkwgbe);
+
+	/* "Allocate" setup TX rings */
+	for (queue = 0; queue < KW_TXQ_NO; queue++) {
+		u32 size;
+
+		portpriv->tx_ring_size[queue] = KW_TXQ_SZ;
+		/*size = no of DESCs times DESC-size */
+		size = (portpriv->tx_ring_size[queue] * TX_DESC_ALIGNED_SIZE);
+		portinfo->tx_desc_area_size[queue] = size;
+
+		/* first clear desc area completely */
+		memset((void *)portinfo->p_tx_desc_area_base[queue],
+		       0, portinfo->tx_desc_area_size[queue]);
+
+		/* initialize tx desc ring with low level driver */
+		if (kwgbe_init_tx_desc_ring
+		    (dkwgbe, KWGBE_Q0,
+		     portpriv->tx_ring_size[queue],
+		     KW_TX_BUF_SZ /* Each Buffer is 1600 Byte */ ,
+		     (u32) portinfo->
+		     p_tx_desc_area_base[queue],
+		     (u32) portinfo->p_tx_buffer_base[queue]) == 0)
+			printf("### initializing TX Ring\n");
+	}
+
+	/* "Allocate" setup RX rings */
+	for (queue = 0; queue < KW_RXQ_NO; queue++) {
+		u32 size;
+
+		/* Meantime RX Ring are fixed - but must be configurable by user */
+		portpriv->rx_ring_size[queue] = KW_RXQ_SZ;
+		size = (portpriv->rx_ring_size[queue] * RX_DESC_ALIGNED_SIZE);
+		portinfo->rx_desc_area_size[queue] = size;
+
+		/* first clear desc area completely */
+		memset((void *)portinfo->p_rx_desc_area_base[queue],
+		       0, portinfo->rx_desc_area_size[queue]);
+		if ((kwgbe_init_rx_desc_ring
+		     (dkwgbe, KWGBE_Q0,
+		      portpriv->rx_ring_size[queue],
+		      KW_RX_BUF_SZ /* Each Buffer is 1600 Byte */ ,
+		      (u32) portinfo->
+		      p_rx_desc_area_base[queue],
+		      (u32) portinfo->p_rx_buffer_base[queue])) == 0)
+			printf("### initializing RX Ring\n");
+	}
+
+	port_start(dkwgbe);
+
+#if (defined (CONFIG_MII) || defined (CONFIG_CMD_MII)) \
+	 && defined (CONFIG_SYS_FAULT_ECHO_LINK_DOWN)
+	if (!miiphy_link(dev->name, portinfo->port_phy_addr)) {
+		printf("No link on %s\n", dev->name);
+		return 0;
+	}
+#endif
+	portpriv->running = MAGIC_KWGBE_RUNNING;
+	return 1;
+}
+
+/*
+ * egiga_start_xmit
+ *
+ * This function is queues a packet in the Tx descriptor for
+ * required port.
+ *
+ * Output : zero upon success
+ */
+int kwgbe_xmit(struct eth_device *dev, volatile void *dataPtr, int dataSize)
+{
+	struct kwgbe_device *dkwgbe = to_dkwgbe(dev);
+	struct egiga_priv *portpriv = &dkwgbe->portpriv;
+	struct net_device_stats *stats = &portpriv->stats;
+
+	struct kwgbe_pktinf pkt_info;
+	enum kwgbe_fret_sts status;
+	enum kwgbe_fret_sts release_result;
+
+	/* Update packet info data structure */
+	pkt_info.cmd_sts = KWGBE_TX_FIRST_DESC | KWGBE_TX_LAST_DESC;	/* first last */
+	pkt_info.cmd_sts |= KWGBE_BUFFER_OWNED_BY_DMA;	/* DMA owned */
+
+	pkt_info.byte_cnt = dataSize;
+	pkt_info.buf_ptr = (u32) dataPtr;
+	pkt_info.retinfo = 0;
+
+	status = port_send(dkwgbe, KWGBE_Q0, &pkt_info);
+	if ((status == KWGBE_ERROR) || (status == KWGBE_QFULL)) {
+		printf("On transmitting packet ..\n");
+		if (status == KWGBE_QFULL)
+			printf("ETH Queue is full.\n");
+		if (status == KWGBE_QLAST_RESO)
+			printf("ETH Queue: using last available resource.\n");
+		goto error;
+	}
+
+	/* Update statistics and start of transmittion time */
+	stats->tx_bytes += dataSize;
+	stats->tx_packets++;
+
+	/* Check if packet(s) is(are) transmitted correctly (release everything) */
+	do {
+		release_result = tx_return_desc(dkwgbe, KWGBE_Q0, &pkt_info);
+		switch (release_result) {
+		case KWGBE_OK:
+			debug("descriptor released\n");
+			if (pkt_info.cmd_sts & 1) {
+				printf("in TX\n");
+				stats->tx_errors++;
+			}
+			break;
+		case KWGBE_RETRY:
+			debug("transmission still in process\n");
+			break;
+		case KWGBE_ERROR:
+			printf("routine can not access Tx desc ring\n");
+			break;
+		case KWGBE_END_OF_JOB:
+			debug("the routine has nothing to release\n");
+			break;
+		default:	/* should not happen */
+			break;
+		}
+	} while (release_result == KWGBE_OK);
+
+	return 0;		/* success */
+      error:
+	return 1;		/* Failed - higher layers will free the skb */
+}
+
+/*
+ * kwgbe_receive
+ *
+ * This function is forward packets that are received from the port's
+ * queues toward kernel core or FastRoute them to another interface.
+ *
+ * @dev		a pointer to the required interface
+ *
+ * Output : number of served packets
+ */
+int kwgbe_receive(struct eth_device *dev)
+{
+	struct kwgbe_device *dkwgbe = to_dkwgbe(dev);
+	struct egiga_priv *portpriv = &dkwgbe->portpriv;
+	struct net_device_stats *stats = &portpriv->stats;
+	struct kwgbe_pktinf pkt_info;
+
+	while ((port_receive(dkwgbe, KWGBE_Q0, &pkt_info) == KWGBE_OK)) {
+
+		if (pkt_info.byte_cnt != 0) {
+			debug("%s: Received %d byte Packet @ 0x%x",
+			      __FUNCTION__, pkt_info.byte_cnt,
+			      pkt_info.buf_ptr);
+		}
+		/* Update statistics. Note byte count includes 4 byte CRC count */
+		stats->rx_packets++;
+		stats->rx_bytes += pkt_info.byte_cnt;
+
+		/*
+		 * In case received a packet without first / last bits on OR the error
+		 * summary bit is on, the packets needs to be dropeed.
+		 */
+		if (((pkt_info.
+		      cmd_sts & (KWGBE_RX_FIRST_DESC | KWGBE_RX_LAST_DESC)) !=
+		     (KWGBE_RX_FIRST_DESC | KWGBE_RX_LAST_DESC))
+		    || (pkt_info.cmd_sts & KWGBE_ERROR_SUMMARY)) {
+			stats->rx_dropped++;
+
+			printf
+			    ("Received packet spread on multiple descriptors\n");
+
+			/* Is this caused by an error ? */
+			if (pkt_info.cmd_sts & KWGBE_ERROR_SUMMARY) {
+				stats->rx_errors++;
+			}
+
+			/* free these descriptors again without forwarding them to the higher layers */
+			pkt_info.buf_ptr &= ~0x7;	/* realign buffer again */
+			pkt_info.byte_cnt = 0x0000;	/* Reset Byte count */
+
+			if (rx_return_buff(dkwgbe, KWGBE_Q0, &pkt_info) !=
+			    KWGBE_OK) {
+				printf
+				    ("Error while returning the RX Desc to Ring\n");
+			} else {
+				debug("RX Desc returned to Ring");
+			}
+			/* /free these descriptors again */
+		} else {
+			/* !!! call higher layer processing */
+			debug
+			    ("\nNow send it to upper layer protocols (NetReceive) ...");
+
+			/* let the upper layer handle the packet */
+			NetReceive((uchar *) pkt_info.buf_ptr,
+				   (int)pkt_info.byte_cnt);
+
+			/* free descriptor  */
+			pkt_info.buf_ptr &= ~0x7;	/* realign buffer again */
+			pkt_info.byte_cnt = 0x0000;	/* Reset Byte count */
+			debug("RX: pkt_info.buf_ptr = %x", pkt_info.buf_ptr);
+			if (rx_return_buff(dkwgbe, KWGBE_Q0, &pkt_info) !=
+			    KWGBE_OK) {
+				printf("while returning the RX Desc to Ring");
+			} else {
+				debug("RX Desc returned to Ring");
+			}
+			/* free descriptor code end  */
+		}
+	}
+	egiga_get_stats(dev);	/* update statistics */
+	return 1;
+}
+
+/*
+ * Called from net/eth.c
+ */
+int kirkwood_egiga_initialize(bd_t * bis)
+{
+	struct kwgbe_device *dkwgbe;
+	struct eth_device *dev;
+	struct kwgbe_portinfo *portinfo;
+	struct egiga_priv *portpriv;
+	int devnum, x, temp;
+	char *s, *e, buf[64];
+	u8 used_ports[MAX_KWGBE_DEVS] = CONFIG_KIRKWOOD_EGIGA_PORTS;
+
+	for (devnum = 0; devnum < MAX_KWGBE_DEVS; devnum++) {
+		/*skip if port is configured not to use */
+		if (used_ports[devnum] == 0)
+			continue;
+
+		dkwgbe = malloc(sizeof(struct kwgbe_device));
+		if (!dkwgbe) {
+			printf("Error: Failed to allocate memory for kwgbe%d\n",
+			       devnum);
+			return -1;
+		}
+		memset(dkwgbe, 0, sizeof(struct kwgbe_device));
+
+		dev = &dkwgbe->dev;
+		portinfo = &dkwgbe->portinfo;
+		portpriv = &dkwgbe->portpriv;
+
+		/* must be less than NAMESIZE (16) */
+		sprintf(dev->name, "egiga%d", devnum);
+		debug("Initializing %s", dev->name);
+
+		/* Extract the MAC address from the environment */
+		switch (devnum) {
+		case 0:
+			dkwgbe->regs = (void *)KW_EGIGA0_BASE;
+			s = "ethaddr";
+			break;
+		case 1:
+			dkwgbe->regs = (void *)KW_EGIGA1_BASE;
+			s = "eth1addr";
+			break;
+		default:	/* this should never happen */
+			printf("%s: Invalid device number %d\n",
+			       __FUNCTION__, devnum);
+			return -1;
+		}
+
+		e = getenv(s);
+		if (!e) {
+			/* Generate Ramdom MAC addresses if not set */
+			sprintf(buf, "00:50:43:%02x:%02x:%02x",
+				get_random_hex(), get_random_hex(),
+				get_random_hex());
+			setenv(s, buf);
+		}
+
+		temp = getenv_r(s, buf, sizeof(buf));
+		s = (temp > 0) ? buf : NULL;
+
+		debug("Setting MAC %d to %s", devnum, s);
+		/* on POR port is pre-powered up, so assume it is up */
+
+		for (x = 0; x < 6; ++x) {
+			dev->enetaddr[x] = s ? simple_strtoul(s, &e, 16) : 0;
+			if (s)
+				s = (*e) ? e + 1 : e;
+		}
+		/* set the MAC addr in the HW */
+		memcpy(portinfo->port_mac_addr, dev->enetaddr, 6);
+		port_uc_addr_set(dkwgbe->regs, dev->enetaddr, 0);
+
+		dev->init = (void *)kwgbe_init;
+		dev->halt = (void *)kwgbe_stop;
+		dev->send = (void *)kwgbe_xmit;
+		dev->recv = (void *)kwgbe_receive;
+
+		/*
+		 * Read MIB counter on the GT in order to reset them,
+		 * then zero all the stats fields in memory
+		 */
+		egiga_update_stat(dev);
+		memset(&portpriv->stats, 0, sizeof(struct net_device_stats));
+
+		debug("Allocating descriptor and buffer rings");
+
+		portinfo->p_rx_desc_area_base[0] =
+		    (struct kwgbe_rx_dscr *)memalign(16,
+						     RX_DESC_ALIGNED_SIZE *
+						     KW_RXQ_SZ + 1);
+		portinfo->p_tx_desc_area_base[0] =
+		    (struct kwgbe_tx_dscr *)memalign(16,
+						     TX_DESC_ALIGNED_SIZE *
+						     KW_TXQ_SZ + 1);
+
+		portinfo->p_rx_buffer_base[0] =
+		    (char *)memalign(16, KW_RXQ_SZ * KW_TX_BUF_SZ + 1);
+		portinfo->p_tx_buffer_base[0] =
+		    (char *)memalign(16, KW_RXQ_SZ * KW_TX_BUF_SZ + 1);
+
+		eth_register(dev);
+
+		/* Set phy address of the port */
+		portinfo->port_phy_addr = PHY_BASE_ADR + devnum;
+		phy_set_addr(dkwgbe->regs, portinfo->port_phy_addr);
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+		miiphy_register(dev->name, smi_reg_read, smi_reg_write);
+#endif
+	}
+	return 0;
+}
diff --git a/drivers/net/kirkwood_egiga.h b/drivers/net/kirkwood_egiga.h
new file mode 100644
index 0000000..9f3908e
--- /dev/null
+++ b/drivers/net/kirkwood_egiga.h
@@ -0,0 +1,828 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Prafulla Wadaskar <prafulla@marvell.com>
+ *
+ * based on - Driver for MV64360X ethernet ports
+ * Copyright (C) 2002 rabeeh at galileo.co.il
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#ifndef __EGIGA_H__
+#define __EGIGA_H__
+
+#define MAX_KWGBE_DEVS	2	/*controller has two ports */
+
+/* PHY_BASE_ADR is board specific and can be configured */
+#if defined (CONFIG_PHY_BASE_ADR)
+#define PHY_BASE_ADR		CONFIG_PHY_BASE_ADR
+#else
+#define PHY_BASE_ADR		0x08	/* default phy base addr */
+#endif
+
+/* Egiga driver statistics can be displayed optionally */
+#ifdef CONFIG_EGIGA_STATS_BY_SOFTWARE
+#define UPDATE_STATS_BY_SOFTWARE
+#else
+#undef UPDATE_STATS_BY_SOFTWARE
+#endif
+
+/* Constants */
+#define MAGIC_KWGBE_RUNNING		8031971
+#define INT_CAUSE_UNMASK_ALL		0x0007ffff
+#define INT_CAUSE_UNMASK_ALL_EXT	0x0011ffff
+
+/* Port attrib */
+/* Max queue number is 8 for controller but here configured 1 */
+#define MAX_RXQ_NO	1
+#define MAX_TXQ_NO	1
+/* Use one TX queue and one RX queue */
+#define KW_TXQ_NO 	1
+#define KW_RXQ_NO 	1
+
+/*
+ * Number of RX / TX descriptors on RX / TX rings.
+ * Note that allocating RX descriptors is done by allocating the RX
+ * ring AND a preallocated RX buffers (skb's) for each descriptor.
+ * The TX descriptors only allocates the TX descriptors ring,
+ * with no pre allocated TX buffers (skb's are allocated by higher layers.
+ */
+
+/* TX/RX parameters can be passed externally */
+#ifdef CONFIG_KWGBE_TXQ_SZ
+#define KW_TXQ_SZ CONFIG_KWGBE_TXQ_SZ
+#else
+#define KW_TXQ_SZ 4
+#endif
+
+#ifdef	CONFIG_KWGBE_RXQ_SZ
+#define KW_RXQ_SZ CONFIG_KWGBE_RXQ_SZ
+#else
+#define KW_RXQ_SZ 4
+#endif
+
+#ifdef CONFIG_KWGBE_RXBUF_SZ
+#define KW_RX_BUF_SZ CONFIG_KWGBE_RXBUF_SZ
+#else
+#define KW_RX_BUF_SZ 1600
+#endif
+
+#ifdef CONFIG_KWGBE_TXBUF_SZ
+#define KW_TX_BUF_SZ CONFIG_KWGBE_TXBUF_SZ
+#else
+#define KW_TX_BUF_SZ 1600
+#endif
+
+#define RX_BUF_MXSZ  0xFFFF
+#define TX_BUF_MXSZ  0xFFFF	/* Buffers are limited to 64k */
+#define RX_BUF_MNSZ  0x8
+#define TX_BUF_MNSZ  0x8
+
+/*
+ *	Network device statistics. Akin to the 2.0 ether stats but
+ *	with byte counters.
+ */
+struct net_device_stats {
+	u32 rx_packets;		/* total packets received       */
+	u32 tx_packets;		/* total packets transmitted    */
+	u64 rx_bytes;		/* total bytes received         */
+	u64 tx_bytes;		/* total bytes transmitted      */
+	u32 rx_errors;		/* bad packets received         */
+	u32 tx_errors;		/* packet transmit problems     */
+	u32 rx_dropped;		/* no space in linux buffers    */
+	u32 tx_dropped;		/* no space available in linux  */
+	u32 multicast;		/* multicast packets received   */
+	u32 collisions;
+	/* detailed rx_errors: */
+	u32 rx_length_errors;
+	u32 rx_over_errors;	/* receiver ring buff overflow  */
+	u32 rx_crc_errors;	/* recved pkt with crc error    */
+	u32 rx_frame_errors;	/* recv'd frame alignment error */
+	u32 rx_fifo_errors;	/* recv'r fifo overrun          */
+	u32 rx_missed_errors;	/* receiver missed packet       */
+	/* detailed tx_errors */
+	u32 tx_aborted_errors;
+	u32 tx_carrier_errors;
+	u32 tx_fifo_errors;
+	u32 tx_heartbeat_errors;
+	u32 tx_window_errors;
+	/* for cslip etc */
+	u32 rx_compressed;
+	u32 tx_compressed;
+};
+
+/* Private data structure used for ethernet device */
+struct egiga_priv {
+	struct net_device_stats stats;
+	/* to buffer area aligned */
+	char *p_tx_buffer[KW_TXQ_SZ + 1];
+	char *p_rx_buffer[KW_RXQ_SZ + 1];
+	/* Size of Tx Ring per queue */
+	u32 tx_ring_size[MAX_TXQ_NO];
+	/* Size of Rx Ring per queue */
+	u32 rx_ring_size[MAX_RXQ_NO];
+	/* Magic Number for Ethernet running */
+	u32 running;
+};
+
+/* Chip Registers Structures */
+struct mib_counters {
+	u64 good_octets_received;
+	u32 bad_octets_received;
+	u32 internal_mac_transmit_err;
+	u32 good_frames_received;
+	u32 bad_frames_received;
+	u32 broadcast_frames_received;
+	u32 multicast_frames_received;
+	u32 frames_64_octets;
+	u32 frames_65_to_127_octets;
+	u32 frames_128_to_255_octets;
+	u32 frames_256_to_511_octets;
+	u32 frames_512_to_1023_octets;
+	u32 frames_1024_to_max_octets;
+	u64 good_octets_sent;
+	u32 good_frames_sent;
+	u32 excessive_collision;
+	u32 multicast_frames_sent;
+	u32 broadcast_frames_sent;
+	u32 unrec_mac_control_received;
+	u32 fc_sent;
+	u32 good_fc_received;
+	u32 bad_fc_received;
+	u32 undersize_received;
+	u32 fragments_received;
+	u32 oversize_received;
+	u32 jabber_received;
+	u32 mac_receive_error;
+	u32 bad_crc_event;
+	u32 collision;
+	u32 late_collision;
+};
+
+struct kwgbe_barsz {
+	u32 bar;
+	u32 size;
+};
+
+struct kwgbe_crdp {
+	u32 crdp;
+	u32 crdp_pad[3];
+};
+
+struct kwgbe_tqx {
+	u32 qxttbc;
+	u32 tqxtbc;
+	u32 tqxac;
+	u32 tqxpad;
+};
+
+struct kwgbe_registers {
+	u32 phyadr;
+	u32 smi;
+	u32 euda;
+	u32 eudid;
+	u8 pad1[0x080 - 0x00c - 4];
+	u32 euic;
+	u32 euim;
+	u8 pad2[0x094 - 0x084 - 4];
+	u32 euea;
+	u32 euiae;
+	u8 pad3[0x0b0 - 0x098 - 4];
+	u32 euc;
+	u8 pad3a[0x200 - 0x0b0 - 4];
+	struct kwgbe_barsz barsz[6];
+	u8 pad4[0x280 - 0x22c - 4];
+	u32 ha_remap[4];
+	u32 bare;
+	u32 epap;
+	u8 pad5[0x400 - 0x294 - 4];
+	u32 pxc;
+	u32 pxcx;
+	u32 mii_ser_params;
+	u8 pad6[0x410 - 0x408 - 4];
+	u32 evlane;
+	u32 macal;
+	u32 macah;
+	u32 sdc;
+	u32 dscp[7];
+	u32 psc0;
+	u32 vpt2p;
+	u32 ps0;
+	u32 tqc;
+	u32 psc1;
+	u32 ps1;
+	u32 mrvl_header;
+	u8 pad7[0x460 - 0x454 - 4];
+	u32 ic;
+	u32 ice;
+	u32 pim;
+	u32 peim;
+	u8 pad8[0x474 - 0x46c - 4];
+	u32 pxtfut;
+	u32 pad9;
+	u32 pxmfs;
+	u32 pad10;
+	u32 pxdfc;
+	u32 pxofc;
+	u8 pad11[0x494 - 0x488 - 4];
+	u32 peuiae;
+	u8 pad12[0x4bc - 0x494 - 4];
+	u32 eth_type_prio;
+	u8 pad13[0x4dc - 0x4bc - 4];
+	u32 tqfpc;
+	u32 pttbrc;
+	u32 tqc1;
+	u32 pmtu;
+	u32 pmtbs;
+	u8 pad14[0x60c - 0x4ec - 4];
+	struct kwgbe_crdp crdp[7];
+	u32 crdp7;
+	u32 rqc;
+	u32 cur_servd_dscr_ptr;
+	u8 pad15[0x6c0 - 0x684 - 4];
+	u32 tcqdp[8];
+	u8 pad16[0x700 - 0x6dc - 4];
+	struct kwgbe_tqx tqx[8];
+	u32 pttbc;
+	u8 pad17[0x7a8 - 0x780 - 4];
+	u32 tqxipg0;
+	u32 pad18[3];
+	u32 tqxipg1;
+	u8 pad19[0x7c0 - 0x7b8 - 4];
+	u32 hitkninlopkt;
+	u32 hitkninasyncpkt;
+	u32 lotkninasyncpkt;
+	u32 pad20;
+	u32 ts;
+	u8 pad21[0x3000 - 0x27d0 - 4];
+	struct mib_counters mibc;
+	u8 pad22[0x3400 - 0x3000 - sizeof(struct mib_counters)];
+	u32 dfsmt[64];
+	u32 dfomt[64];
+	u32 dfut[4];
+	u8 pad23[0xe20c0 - 0x7360c - 4];
+	u32 pmbus_top_arbiter;
+};
+
+#define to_dkwgbe(_kd) container_of(_kd, struct kwgbe_device, dev)
+#define KWGBEREG_WR(adr, val)		writel(val, &adr)
+#define KWGBEREG_RD(adr)		readl(&adr)
+#define KWGBEREG_BITS_RESET(adr, val)	writel(readl(&adr) & ~(val), &adr)
+#define KWGBEREG_BITS_SET(adr, val)	writel(readl(&adr) | val, &adr)
+
+/* Default port configuration value */
+#define PRT_CFG_VAL			\
+	KWGBE_UCAST_MOD_NRML		| \
+	KWGBE_DFLT_RX_Q0		| \
+	KWGBE_DFLT_RX_ARPQ0		| \
+	KWGBE_RX_BC_IF_NOT_IP_OR_ARP	| \
+	KWGBE_RX_BC_IF_IP		| \
+	KWGBE_RX_BC_IF_ARP		| \
+	KWGBE_CPTR_TCP_FRMS_DIS		| \
+	KWGBE_CPTR_UDP_FRMS_DIS		| \
+	KWGBE_DFLT_RX_TCPQ0		| \
+	KWGBE_DFLT_RX_UDPQ0		| \
+	KWGBE_DFLT_RX_BPDU_Q_0
+
+/* Default port extend configuration value */
+#define PORT_CFG_EXTEND_VALUE		\
+     KWGBE_SPAN_BPDU_PACKETS_AS_NORMAL	| \
+     KWGBE_PARTITION_DIS		| \
+	KWGBE_TX_CRC_GENERATION_EN
+
+/* Default sdma control value */
+#ifdef CONFIG_NOT_COHERENT_CACHE
+#define PORT_SDMA_CFG_VALUE		\
+	KWGBE_RX_BURST_SIZE_16_64BIT	| \
+	KWGBE_BLM_RX_NO_SWAP		| \
+	KWGBE_BLM_TX_NO_SWAP		| \
+	GT_KWGBE_IPG_INT_RX(0)		| \
+	KWGBE_TX_BURST_SIZE_16_64BIT;
+#else
+#define PORT_SDMA_CFG_VALUE		\
+	KWGBE_RX_BURST_SIZE_4_64BIT	| \
+	GT_KWGBE_IPG_INT_RX(0)		| \
+	KWGBE_TX_BURST_SIZE_4_64BIT;
+#endif
+
+#define GT_KWGBE_IPG_INT_RX(value)	((value & 0x3fff) << 8)
+
+/* Default port serial control value */
+#define PORT_SERIAL_CONTROL_VALUE_TMP		  \
+	KWGBE_FORCE_LINK_PASS			| \
+	KWGBE_DIS_AUTO_NEG_FOR_DUPLX		| \
+	KWGBE_DIS_AUTO_NEG_FOR_FLOW_CTRL	| \
+	KWGBE_ADV_NO_FLOW_CTRL			| \
+	KWGBE_FORCE_FC_MODE_NO_PAUSE_DIS_TX	| \
+	KWGBE_FORCE_BP_MODE_NO_JAM		| \
+	(1 << 9)					| \
+	KWGBE_DO_NOT_FORCE_LINK_FAIL		| \
+	KWGBE_DIS_AUTO_NEG_SPEED_GMII		| \
+	KWGBE_DTE_ADV_0				| \
+	KWGBE_MIIPHY_MAC_MODE			| \
+	KWGBE_AUTO_NEG_NO_CHANGE			| \
+	KWGBE_MAX_RX_PACKET_1552BYTE		| \
+	KWGBE_CLR_EXT_LOOPBACK			| \
+	KWGBE_SET_FULL_DUPLEX_MODE		| \
+	KWGBE_DIS_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX | \
+	KWGBE_SET_MII_SPEED_TO_100
+
+#ifdef CONFIG_SYS_MII_MODE
+#define PORT_SERIAL_CONTROL_VALUE	\
+	PORT_SERIAL_CONTROL_VALUE_TMP |	\
+	KWGBE_SET_GMII_SPEED_TO_10_100
+#else
+#define PORT_SERIAL_CONTROL_VALUE	\
+	PORT_SERIAL_CONTROL_VALUE_TMP |	\
+	KWGBE_SET_GMII_SPEED_TO_1000
+#endif
+
+/* Tx WRR confoguration macros */
+#define PORT_MAX_TRAN_UNIT	0x24	/* MTU register (default) 9KByte */
+#define PORT_MAX_TOKEN_BUCKET_SIZE	0x_fFFF	/* PMTBS reg (default) */
+#define PORT_TOKEN_RATE		    1023	/* PTTBRC reg (default) */
+/* MAC accepet/reject macros */
+#define ACCEPT_MAC_ADDR		0
+#define REJECT_MAC_ADDR		1
+/* Size of a Tx/Rx descriptor used in chain list data structure */
+#define RX_DESC_ALIGNED_SIZE	0x20
+#define TX_DESC_ALIGNED_SIZE	0x20
+/* An offest in Tx descriptors to store data for buffers less than 8 Bytes */
+#define TX_BUF_OFFSET_IN_DESC	0x18
+/* Buffer offset from buffer pointer */
+#define RX_BUF_OFFSET		0x2
+
+/* Port serial status reg (PSR) */
+#define KWGBE_INTERFACE_GMII_MII	0
+#define KWGBE_INTERFACE_PCM		1
+#define KWGBE_LINK_IS_DOWN		0
+#define KWGBE_LINK_IS_UP		(1 << 1)
+#define KWGBE_PORT_AT_HALF_DUPLEX	0
+#define KWGBE_PORT_AT_FULL_DUPLEX	(1 << 2)
+#define KWGBE_RX_FLOW_CTRL_DISD		0
+#define KWGBE_RX_FLOW_CTRL_ENBALED	(1 << 3)
+#define KWGBE_GMII_SPEED_100_10		0
+#define KWGBE_GMII_SPEED_1000		(1 << 4)
+#define KWGBE_MII_SPEED_10		0
+#define KWGBE_MII_SPEED_100		(1 << 5)
+#define KWGBE_NO_TX			0
+#define KWGBE_TX_IN_PROGRESS		(1 << 7)
+#define KWGBE_BYPASS_NO_ACTIVE		0
+#define KWGBE_BYPASS_ACTIVE		(1 << 8)
+#define KWGBE_PORT_NOT_AT_PARTN_STT	0
+#define KWGBE_PORT_AT_PARTN_STT		(1 << 9)
+#define KWGBE_PORT_TX_FIFO_NOT_EMPTY	0
+#define KWGBE_PORT_TX_FIFO_EMPTY	(1 << 10)
+
+/* These macros describes the Port configuration reg (Px_cR) bits */
+#define KWGBE_UCAST_MOD_NRML		0
+#define KWGBE_UNICAST_PROMISCUOUS_MODE	1
+#define KWGBE_DFLT_RX_Q0		0
+#define KWGBE_DFLT_RX_Q1		(1 << 1)
+#define KWGBE_DFLT_RX_Q2		(1 << 2)
+#define KWGBE_DFLT_RX_Q3		((1 << 2) | (1 << 1))
+#define KWGBE_DFLT_RX_Q4		(1 << 3)
+#define KWGBE_DFLT_RX_Q5		((1 << 3) | (1 << 1))
+#define KWGBE_DFLT_RX_Q6		((1 << 3) | (1 << 2))
+#define KWGBE_DFLT_RX_Q7		((1 << 3) | (1 << 2) | (1 << 1))
+#define KWGBE_DFLT_RX_ARPQ0		0
+#define KWGBE_DFLT_RX_ARPQ1		(1 << 4)
+#define KWGBE_DFLT_RX_ARPQ2		(1 << 5)
+#define KWGBE_DFLT_RX_ARPQ3		((1 << 5) | (1 << 4))
+#define KWGBE_DFLT_RX_ARPQ4		(1 << 6)
+#define KWGBE_DFLT_RX_ARPQ5		((1 << 6) | (1 << 4))
+#define KWGBE_DFLT_RX_ARPQ6		((1 << 6) | (1 << 5))
+#define KWGBE_DFLT_RX_ARPQ7		((1 << 6) | (1 << 5) | (1 << 4))
+#define KWGBE_RX_BC_IF_NOT_IP_OR_ARP	0
+#define KWGBE_REJECT_BC_IF_NOT_IP_OR_ARP (1 << 7)
+#define KWGBE_RX_BC_IF_IP		0
+#define KWGBE_REJECT_BC_IF_IP		(1 << 8)
+#define KWGBE_RX_BC_IF_ARP		0
+#define KWGBE_REJECT_BC_IF_ARP		(1 << 9)
+#define KWGBE_TX_AM_NO_UPDATE_ERR_SMRY	(1 << 12)
+#define KWGBE_CPTR_TCP_FRMS_DIS		0
+#define KWGBE_CPTR_TCP_FRMS_EN		(1 << 14)
+#define KWGBE_CPTR_UDP_FRMS_DIS		0
+#define KWGBE_CPTR_UDP_FRMS_EN		(1 << 15)
+#define KWGBE_DFLT_RX_TCPQ0		0
+#define KWGBE_DFLT_RX_TCPQ1		(1 << 16)
+#define KWGBE_DFLT_RX_TCPQ2		(1 << 17)
+#define KWGBE_DFLT_RX_TCPQ3		((1 << 17) | (1 << 16))
+#define KWGBE_DFLT_RX_TCPQ4		(1 << 18)
+#define KWGBE_DFLT_RX_TCPQ5		((1 << 18) | (1 << 16))
+#define KWGBE_DFLT_RX_TCPQ6		((1 << 18) | (1 << 17))
+#define KWGBE_DFLT_RX_TCPQ7		((1 << 18) | (1 << 17) | (1 << 16))
+#define KWGBE_DFLT_RX_UDPQ0		0
+#define KWGBE_DFLT_RX_UDPQ1		(1 << 19)
+#define KWGBE_DFLT_RX_UDPQ2		(1 << 20)
+#define KWGBE_DFLT_RX_UDPQ3		((1 << 20) | (1 << 19))
+#define KWGBE_DFLT_RX_UDPQ4		(1 << 21)
+#define KWGBE_DFLT_RX_UDPQ5		((1 << 21) | (1 << 19))
+#define KWGBE_DFLT_RX_UDPQ6		((1 << 21) | (1 << 20))
+#define KWGBE_DFLT_RX_UDPQ7		((1 << 21) | (1 << 20) | (1 << 19))
+#define KWGBE_DFLT_RX_BPDU_Q_0		 0
+#define KWGBE_DFLT_RX_BPDU_Q_1		(1 << 22)
+#define KWGBE_DFLT_RX_BPDU_Q_2		(1 << 23)
+#define KWGBE_DFLT_RX_BPDU_Q_3		((1 << 23) | (1 << 22))
+#define KWGBE_DFLT_RX_BPDU_Q_4		(1 << 24)
+#define KWGBE_DFLT_RX_BPDU_Q_5		((1 << 24) | (1 << 22))
+#define KWGBE_DFLT_RX_BPDU_Q_6		((1 << 24) | (1 << 23))
+#define KWGBE_DFLT_RX_BPDU_Q_7		((1 << 24) | (1 << 23) | (1 << 22))
+#define KWGBE_DFLT_RX_TCP_CHKSUM_MODE	(1 << 25)
+
+/* These macros describes the Port configuration extend reg (Px_cXR) bits*/
+#define KWGBE_CLASSIFY_EN			1
+#define KWGBE_SPAN_BPDU_PACKETS_AS_NORMAL	0
+#define KWGBE_SPAN_BPDU_PACKETS_TO_RX_Q7	(1 << 1)
+#define KWGBE_PARTITION_DIS			0
+#define KWGBE_PARTITION_EN			(1 << 2)
+#define KWGBE_TX_CRC_GENERATION_EN		0
+#define KWGBE_TX_CRC_GENERATION_DIS		(1 << 3)
+
+/* Tx/Rx queue command reg (RQCR/TQCR)*/
+#define KWGBE_Q_0_EN				1
+#define KWGBE_Q_1_EN				(1 << 1)
+#define KWGBE_Q_2_EN				(1 << 2)
+#define KWGBE_Q_3_EN				(1 << 3)
+#define KWGBE_Q_4_EN				(1 << 4)
+#define KWGBE_Q_5_EN				(1 << 5)
+#define KWGBE_Q_6_EN				(1 << 6)
+#define KWGBE_Q_7_EN				(1 << 7)
+#define KWGBE_Q_0_DIS				(1 << 8)
+#define KWGBE_Q_1_DIS				(1 << 9)
+#define KWGBE_Q_2_DIS				(1 << 10)
+#define KWGBE_Q_3_DIS				(1 << 11)
+#define KWGBE_Q_4_DIS				(1 << 12)
+#define KWGBE_Q_5_DIS				(1 << 13)
+#define KWGBE_Q_6_DIS				(1 << 14)
+#define KWGBE_Q_7_DIS				(1 << 15)
+
+/* These macros describes the Port Sdma configuration reg (SDCR) bits */
+#define KWGBE_RIFB				1
+#define KWGBE_RX_BURST_SIZE_1_64BIT		0
+#define KWGBE_RX_BURST_SIZE_2_64BIT		(1 << 1)
+#define KWGBE_RX_BURST_SIZE_4_64BIT		(1 << 2)
+#define KWGBE_RX_BURST_SIZE_8_64BIT		((1 << 2) | (1 << 1))
+#define KWGBE_RX_BURST_SIZE_16_64BIT		(1 << 3)
+#define KWGBE_BLM_RX_NO_SWAP			(1 << 4)
+#define KWGBE_BLM_RX_BYTE_SWAP			0
+#define KWGBE_BLM_TX_NO_SWAP			(1 << 5)
+#define KWGBE_BLM_TX_BYTE_SWAP			0
+#define KWGBE_DESCRIPTORS_BYTE_SWAP		(1 << 6)
+#define KWGBE_DESCRIPTORS_NO_SWAP		0
+#define KWGBE_TX_BURST_SIZE_1_64BIT		0
+#define KWGBE_TX_BURST_SIZE_2_64BIT		(1 << 22)
+#define KWGBE_TX_BURST_SIZE_4_64BIT		(1 << 23)
+#define KWGBE_TX_BURST_SIZE_8_64BIT		((1 << 23) | (1 << 22))
+#define KWGBE_TX_BURST_SIZE_16_64BIT		(1 << 24)
+
+/* These macros describes the Port serial control reg (PSCR) bits */
+#define KWGBE_SERIAL_PORT_DIS			0
+#define KWGBE_SERIAL_PORT_EN			1
+#define KWGBE_FORCE_LINK_PASS			(1 << 1)
+#define KWGBE_DO_NOT_FORCE_LINK_PASS		0
+#define KWGBE_EN_AUTO_NEG_FOR_DUPLX		0
+#define KWGBE_DIS_AUTO_NEG_FOR_DUPLX		(1 << 2)
+#define KWGBE_EN_AUTO_NEG_FOR_FLOW_CTRL		0
+#define KWGBE_DIS_AUTO_NEG_FOR_FLOW_CTRL	(1 << 3)
+#define KWGBE_ADV_NO_FLOW_CTRL			0
+#define KWGBE_ADV_SYMMETRIC_FLOW_CTRL		(1 << 4)
+#define KWGBE_FORCE_FC_MODE_NO_PAUSE_DIS_TX	0
+#define KWGBE_FORCE_FC_MODE_TX_PAUSE_DIS	(1 << 5)
+#define KWGBE_FORCE_BP_MODE_NO_JAM		0
+#define KWGBE_FORCE_BP_MODE_JAM_TX		(1 << 7)
+#define KWGBE_FORCE_BP_MODE_JAM_TX_ON_RX_ERR	(1 << 8)
+#define KWGBE_FORCE_LINK_FAIL			0
+#define KWGBE_DO_NOT_FORCE_LINK_FAIL		(1 << 10)
+#define KWGBE_DIS_AUTO_NEG_SPEED_GMII		(1 << 13)
+#define KWGBE_EN_AUTO_NEG_SPEED_GMII		0
+#define KWGBE_DTE_ADV_0				0
+#define KWGBE_DTE_ADV_1				(1 << 14)
+#define KWGBE_MIIPHY_MAC_MODE			0
+#define KWGBE_MIIPHY_PHY_MODE			(1 << 15)
+#define KWGBE_AUTO_NEG_NO_CHANGE		0
+#define KWGBE_RESTART_AUTO_NEG			(1 << 16)
+#define KWGBE_MAX_RX_PACKET_1518BYTE		0
+#define KWGBE_MAX_RX_PACKET_1522BYTE		(1 << 17)
+#define KWGBE_MAX_RX_PACKET_1552BYTE		(1 << 18)
+#define KWGBE_MAX_RX_PACKET_9022BYTE		((1 << 18) | (1 << 17))
+#define KWGBE_MAX_RX_PACKET_9192BYTE		(1 << 19)
+#define KWGBE_MAX_RX_PACKET_9700BYTE		((1 << 19) | (1 << 17))
+#define KWGBE_SET_EXT_LOOPBACK			(1 << 20)
+#define KWGBE_CLR_EXT_LOOPBACK			0
+#define KWGBE_SET_FULL_DUPLEX_MODE		(1 << 21)
+#define KWGBE_SET_HALF_DUPLEX_MODE		0
+#define KWGBE_EN_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX	(1 << 22)
+#define KWGBE_DIS_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX 0
+#define KWGBE_SET_GMII_SPEED_TO_10_100		0
+#define KWGBE_SET_GMII_SPEED_TO_1000		(1 << 23)
+#define KWGBE_SET_MII_SPEED_TO_10		0
+#define KWGBE_SET_MII_SPEED_TO_100		(1 << 24)
+
+/* SMI register fields (KWGBE_SMI_REG) */
+#define KWGBE_PHY_SMI_TIMEOUT		10000
+#define KWGBE_PHY_SMI_DATA_OFFS        	0	/* Data */
+#define KWGBE_PHY_SMI_DATA_MASK	       	(0xffff << KWGBE_PHY_SMI_DATA_OFFS)
+#define KWGBE_PHY_SMI_DEV_ADDR_OFFS	16	/* PHY device address */
+#define KWGBE_PHY_SMI_DEV_ADDR_MASK    	(0x1f << KWGBE_PHY_SMI_DEV_ADDR_OFFS)
+#define KWGBE_SMI_REG_ADDR_OFFS		21	/* PHY device register address */
+#define KWGBE_SMI_REG_ADDR_MASK		(0x1f << KWGBE_SMI_REG_ADDR_OFFS)
+#define KWGBE_PHY_SMI_OPCODE_OFFS	26	/* Write/Read opcode */
+#define KWGBE_PHY_SMI_OPCODE_MASK	(3 << KWGBE_PHY_SMI_OPCODE_OFFS)
+#define KWGBE_PHY_SMI_OPCODE_WRITE	(0 << KWGBE_PHY_SMI_OPCODE_OFFS)
+#define KWGBE_PHY_SMI_OPCODE_READ	(1 << KWGBE_PHY_SMI_OPCODE_OFFS)
+#define KWGBE_PHY_SMI_READ_VALID_MASK	(1 << 27)	/* Read Valid  */
+#define KWGBE_PHY_SMI_BUSY_MASK		(1 << 28)	/* Busy */
+
+/* SDMA command status fields macros */
+/* Tx & Rx descriptors status */
+#define KWGBE_ERROR_SUMMARY		1
+
+/* Tx & Rx descriptors command */
+#define KWGBE_BUFFER_OWNED_BY_DMA	(1 << 31)
+
+/* Tx descriptors status */
+#define KWGBE_LC_ERROR			0
+#define KWGBE_UR_ERROR			(1 << 1)
+#define KWGBE_RL_ERROR			(1 << 2)
+#define KWGBE_LLC_SNAP_FORMAT		(1 << 9)
+
+/* Rx descriptors status */
+#define KWGBE_CRC_ERROR			0
+#define KWGBE_OVERRUN_ERROR		(1 << 1)
+#define KWGBE_MAX_FRAME_LENGTH_ERROR	(1 << 2)
+#define KWGBE_RESOURCE_ERROR		((1 << 2) | (1 << 1))
+#define KWGBE_VLAN_TAGGED		(1 << 19)
+#define KWGBE_BPDU_FRAME		(1 << 20)
+#define KWGBE_TCP_FRAME_OVER_IP_V_4	0
+#define KWGBE_UDP_FRAME_OVER_IP_V_4	(1 << 21)
+#define KWGBE_OTHER_FRAME_TYPE		(1 << 22)
+#define KWGBE_LAYER_2_IS_KWGBE_V_2	(1 << 23)
+#define KWGBE_FRAME_TYPE_IP_V_4		(1 << 24)
+#define KWGBE_FRAME_HEADER_OK		(1 << 25)
+#define KWGBE_RX_LAST_DESC		(1 << 26)
+#define KWGBE_RX_FIRST_DESC		(1 << 27)
+#define KWGBE_UNKNOWN_DESTINATION_ADDR	(1 << 28)
+#define KWGBE_RX_EN_INTERRUPT		(1 << 29)
+#define KWGBE_LAYER_4_CHECKSUM_OK	(1 << 30)
+
+/* Rx descriptors byte count */
+#define KWGBE_FRAME_FRAGMENTED		(1 << 2)
+
+/* Tx descriptors command */
+#define KWGBE_LAYER_4_CHECKSUM_FIRST_DESC	(1 << 10)
+#define KWGBE_FRAME_SET_TO_VLAN			(1 << 15)
+#define KWGBE_TCP_FRAME				0
+#define KWGBE_UDP_FRAME				(1 << 16)
+#define KWGBE_GEN_TCP_UDP_CHECKSUM		(1 << 17)
+#define KWGBE_GEN_IP_V_4_CHECKSUM		(1 << 18)
+#define KWGBE_ZERO_PADDING			(1 << 19)
+#define KWGBE_TX_LAST_DESC			(1 << 20)
+#define KWGBE_TX_FIRST_DESC			(1 << 21)
+#define KWGBE_GEN_CRC				(1 << 22)
+#define KWGBE_TX_EN_INTERRUPT			(1 << 23)
+#define KWGBE_AUTO_MODE				(1 << 30)
+
+/* Address decode parameters */
+/* Ethernet Base Address Register bits */
+#define EBAR_TARGET_DRAM			0x00000000
+#define EBAR_TARGET_DEVICE			0x00000001
+#define EBAR_TARGET_CBS				0x00000002
+#define EBAR_TARGET_PCI0			0x00000003
+#define EBAR_TARGET_PCI1			0x00000004
+#define EBAR_TARGET_CUNIT			0x00000005
+#define EBAR_TARGET_AUNIT			0x00000006
+#define EBAR_TARGET_GUNIT			0x00000007
+
+/* Window attrib */
+#define EBAR_ATTR_DRAM_CS0			0x00000E00
+#define EBAR_ATTR_DRAM_CS1			0x00000D00
+#define EBAR_ATTR_DRAM_CS2			0x00000B00
+#define EBAR_ATTR_DRAM_CS3			0x00000700
+
+/* DRAM Target interface */
+#define EBAR_ATTR_DRAM_NO_CACHE_COHERENCY	0x00000000
+#define EBAR_ATTR_DRAM_CACHE_COHERENCY_WT	0x00001000
+#define EBAR_ATTR_DRAM_CACHE_COHERENCY_WB	0x00002000
+
+/* Device Bus Target interface */
+#define EBAR_ATTR_DEVICE_DEVCS0			0x00001E00
+#define EBAR_ATTR_DEVICE_DEVCS1			0x00001D00
+#define EBAR_ATTR_DEVICE_DEVCS2			0x00001B00
+#define EBAR_ATTR_DEVICE_DEVCS3			0x00001700
+#define EBAR_ATTR_DEVICE_BOOTCS3		0x00000F00
+
+/* PCI Target interface */
+#define EBAR_ATTR_PCI_BYTE_SWAP			0x00000000
+#define EBAR_ATTR_PCI_NO_SWAP			0x00000100
+#define EBAR_ATTR_PCI_BYTE_WORD_SWAP		0x00000200
+#define EBAR_ATTR_PCI_WORD_SWAP			0x00000300
+#define EBAR_ATTR_PCI_NO_SNOOP_NOT_ASSERT	0x00000000
+#define EBAR_ATTR_PCI_NO_SNOOP_ASSERT		0x00000400
+#define EBAR_ATTR_PCI_IO_SPACE			0x00000000
+#define EBAR_ATTR_PCI_MEMORY_SPACE		0x00000800
+#define EBAR_ATTR_PCI_REQ64_FORCE		0x00000000
+#define EBAR_ATTR_PCI_REQ64_SIZE		0x00001000
+
+/* Window access control */
+#define EWIN_ACCESS_NOT_ALLOWED 0
+#define EWIN_ACCESS_READ_ONLY	1
+#define EWIN_ACCESS_FULL	((1 << 1) | 1)
+
+/* SDMA command macros */
+#define CURR_RFD_GET(p_curr_desc, queue) \
+ ((p_curr_desc) = p_gbe_pctrl->p_rx_curr_desc_q[queue])
+
+#define CURR_RFD_SET(p_curr_desc, queue) \
+ (p_gbe_pctrl->p_rx_curr_desc_q[queue] = (p_curr_desc))
+
+#define USED_RFD_GET(p_used_desc, queue) \
+ ((p_used_desc) = p_gbe_pctrl->p_rx_used_desc_q[queue])
+
+#define USED_RFD_SET(p_used_desc, queue)\
+(p_gbe_pctrl->p_rx_used_desc_q[queue] = (p_used_desc))
+
+#define CURR_TFD_GET(p_curr_desc, queue) \
+ ((p_curr_desc) = p_gbe_pctrl->p_tx_curr_desc_q[queue])
+
+#define CURR_TFD_SET(p_curr_desc, queue) \
+ (p_gbe_pctrl->p_tx_curr_desc_q[queue] = (p_curr_desc))
+
+#define USED_TFD_GET(p_used_desc, queue) \
+ ((p_used_desc) = p_gbe_pctrl->p_tx_used_desc_q[queue])
+
+#define USED_TFD_SET(p_used_desc, queue) \
+ (p_gbe_pctrl->p_tx_used_desc_q[queue] = (p_used_desc))
+
+#define FIRST_TFD_GET(p_first_desc, queue) \
+ ((p_first_desc) = p_gbe_pctrl->p_tx_first_desc_q[queue])
+
+#define FIRST_TFD_SET(p_first_desc, queue) \
+ (p_gbe_pctrl->p_tx_first_desc_q[queue] = (p_first_desc))
+
+/* Macros that save access to desc in order to find next desc pointer  */
+#define RX_NEXT_DESC_PTR(p_rx_desc, queue) 	( \
+	struct kwgbe_rx_dscr*)(((((u32)p_rx_desc - \
+	(u32)p_gbe_pctrl->p_rx_desc_area_base[queue]) + \
+	RX_DESC_ALIGNED_SIZE) % p_gbe_pctrl->rx_desc_area_size[queue]) + \
+	(u32)p_gbe_pctrl->p_rx_desc_area_base[queue])
+
+#define TX_NEXT_DESC_PTR(p_tx_desc, queue) 	( \
+	struct kwgbe_tx_dscr*)(((((u32)p_tx_desc - \
+	(u32)p_gbe_pctrl->p_tx_desc_area_base[queue]) + \
+	TX_DESC_ALIGNED_SIZE) % p_gbe_pctrl->tx_desc_area_size[queue]) + \
+	(u32)p_gbe_pctrl->p_tx_desc_area_base[queue])
+
+enum kwgbe_fret_sts {
+	KWGBE_OK,		/* Returned as expected. */
+	KWGBE_ERROR,		/* Fundamental error. */
+	KWGBE_RETRY,		/* Could not process request. Try later. */
+	KWGBE_END_OF_JOB,	/* Ring has nothing to process. */
+	KWGBE_QFULL,		/* Ring resource error. */
+	KWGBE_QLAST_RESO	/* Ring resources about to exhaust. */
+};
+
+enum kwgbe_q {
+	KWGBE_Q0 = 0,
+	KWGBE_Q1 = 1,
+	KWGBE_Q2 = 2,
+	KWGBE_Q3 = 3,
+	KWGBE_Q4 = 4,
+	KWGBE_Q5 = 5,
+	KWGBE_Q6 = 6,
+	KWGBE_Q7 = 7
+};
+
+enum kwgbe_adrwin {
+	KWGBE_WIN0,
+	KWGBE_WIN1,
+	KWGBE_WIN2,
+	KWGBE_WIN3,
+	KWGBE_WIN4,
+	KWGBE_WIN5
+};
+
+enum kwgbe_target {
+	KWGBE_TARGET_DRAM,
+	KWGBE_TARGET_DEV,
+	KWGBE_TARGET_CBS,
+	KWGBE_TARGET_PCI0,
+	KWGBE_TARGET_PCI1
+};
+
+struct kwgbe_rx_dscr {
+	u32 cmd_sts;		/* Descriptor command status */
+	u16 buf_size;		/* Buffer size */
+	u16 byte_cnt;		/* Descriptor buffer byte count */
+	u32 buf_ptr;		/* Descriptor buffer pointer */
+	u32 nxtdesc_p;		/* Next descriptor pointer */
+	u32 retinfo;		/* User resource return information */
+};
+
+struct kwgbe_tx_dscr {
+	u32 cmd_sts;		/* Descriptor command status */
+	u16 l4i_chk;		/* CPU provided TCP Checksum */
+	u16 byte_cnt;		/* Descriptor buffer byte count */
+	u32 buf_ptr;		/* Descriptor buffer pointer */
+	u32 nxtdesc_p;		/* Next descriptor pointer */
+	u32 retinfo;		/* User resource return information */
+};
+
+/*
+ * Unified struct for Rx and Tx operations. The user is not required to
+ * be familier with neither Tx nor Rx descriptors.
+ */
+struct kwgbe_pktinf {
+	u32 cmd_sts;		/* Descriptor command status */
+	u16 byte_cnt;		/* Descriptor buffer byte count */
+	u16 l4i_chk;		/* Tx CPU provided TCP Checksum */
+	u32 buf_ptr;		/* Descriptor buffer pointer */
+	u32 retinfo;		/* User resource return information */
+};
+
+struct kwgbe_winparam {
+	enum kwgbe_adrwin win;	/* Window number */
+	enum kwgbe_target target;	/* System targets */
+	u16 attrib;		/* BAR attrib. See above macros */
+	u32 base_addr;		/* Window base address in u32 form */
+	u32 high_addr;		/* Window high address in u32 form */
+	u32 size;		/* Size in MBytes. Must be % 64Kbyte. */
+	int enable;		/* Enable/disable access to the window. */
+	u16 access_ctrl;	/*Access ctrl register. see above macros */
+};
+
+/* Ethernet port specific infomation */
+struct kwgbe_portinfo {
+	int port_phy_addr;	/* User phy address of Ethrnet port */
+	u8 port_mac_addr[6];	/* User defined port MAC address. */
+	u32 port_config;	/* User port configuration value */
+	u32 port_config_extend;	/* User port config extend value */
+	u32 port_sdma_config;	/* User port SDMA config value */
+	u32 port_serial_control;	/* User port serial control value */
+	u32 port_tx_queue_command;	/* Port active Tx queues summary */
+	u32 port_rx_queue_command;	/* Port active Rx queues summary */
+
+	/* User function to cast virtual address to CPU bus address */
+	 u32(*port_virt_to_phys) (u32 addr);
+	/* User scratch pad for user specific data structures */
+	void *port_private;
+
+	int rx_resource_err[MAX_RXQ_NO];	/* Rx ring resource err flag */
+	int tx_resource_err[MAX_TXQ_NO];	/* Tx ring resource err flag */
+
+	/* Tx/Rx rings managment indexes fields. For driver use */
+
+	/* Next available Rx resource */
+	volatile struct kwgbe_rx_dscr *p_rx_curr_desc_q[MAX_RXQ_NO];
+	/* Returning Rx resource */
+	volatile struct kwgbe_rx_dscr *p_rx_used_desc_q[MAX_RXQ_NO];
+
+	/* Next available Tx resource */
+	volatile struct kwgbe_tx_dscr *p_tx_curr_desc_q[MAX_TXQ_NO];
+	/* Returning Tx resource */
+	volatile struct kwgbe_tx_dscr *p_tx_used_desc_q[MAX_TXQ_NO];
+	/* An extra Tx index to support txmt of multiple buffs per packet */
+	volatile struct kwgbe_tx_dscr *p_tx_first_desc_q[MAX_TXQ_NO];
+
+	/* Tx/Rx rings size and base variables fields. For driver use */
+
+	volatile struct kwgbe_rx_dscr *p_rx_desc_area_base[MAX_RXQ_NO];
+	u32 rx_desc_area_size[MAX_RXQ_NO];
+	char *p_rx_buffer_base[MAX_RXQ_NO];
+
+	volatile struct kwgbe_tx_dscr *p_tx_desc_area_base[MAX_TXQ_NO];
+	u32 tx_desc_area_size[MAX_TXQ_NO];
+	char *p_tx_buffer_base[MAX_TXQ_NO];
+};
+
+/* port device data struct */
+struct kwgbe_device {
+	struct eth_device dev;
+	struct kwgbe_portinfo portinfo;
+	struct egiga_priv portpriv;
+	struct kwgbe_registers *regs;
+};
+
+/* functions */
+static void port_uc_addr_set(struct kwgbe_registers *regs, u8 * p_addr,
+			     enum kwgbe_q queue);
+static void port_reset(struct kwgbe_registers *regs);
+
+#endif /* __EGIGA_H__ */
diff --git a/include/netdev.h b/include/netdev.h
index f37b6ae..3a59f4e 100644
--- a/include/netdev.h
+++ b/include/netdev.h
@@ -52,6 +52,7 @@ int fec_initialize (bd_t *bis);
 int greth_initialize(bd_t *bis);
 void gt6426x_eth_initialize(bd_t *bis);
 int inca_switch_initialize(bd_t *bis);
+int kirkwood_egiga_initialize(bd_t *bis);
 int macb_eth_initialize(int id, void *regs, unsigned int phy_addr);
 int mcdmafec_initialize(bd_t *bis);
 int mcffec_initialize(bd_t *bis);
-- 
1.5.3.3

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [U-Boot] [PATCH] Marvell Sheevaplug Board support
  2009-05-21 20:24 ` [U-Boot] [PATCH] Marvell Sheevaplug Board support Prafulla Wadaskar
  2009-05-21 20:24   ` [U-Boot] [PATCH] Marvell MV88E1116 PHY Driver support Prafulla Wadaskar
@ 2009-05-22  8:21   ` Stefan Roese
  2009-05-22 11:02   ` Wolfgang Denk
  2 siblings, 0 replies; 18+ messages in thread
From: Stefan Roese @ 2009-05-22  8:21 UTC (permalink / raw)
  To: u-boot

Hi Prafulla,

On Thursday 21 May 2009 22:24:30 Prafulla Wadaskar wrote:
> References: http://plugcomputer.org/
> Serial console Setup
> http://openplug.org/plugwiki/index.php/Serial_terminal_program#Linux
> OpenOCD Setup
> http://openplug.org/plugwiki/index.php/Setting_Up_OpenOCD_Under_Linux
>
> This patch is tested for-
> 1. Boot from DRAM/NAND flash
> 2. File transfer using tftp
> 3. NAND flash read/write/erase
>
> Signed-off-by: Prafulla Wadaskar <prafulla@marvell.com>
> ---
>  MAKEALL                               |    1 +
>  Makefile                              |    8 +-
>  board/Marvell/sheevaplug/Makefile     |   52 +++++++++
>  board/Marvell/sheevaplug/config.mk    |   25 +++++
>  board/Marvell/sheevaplug/nand.c       |   80 ++++++++++++++
>  board/Marvell/sheevaplug/sheevaplug.c |  135 +++++++++++++++++++++++
>  board/Marvell/sheevaplug/sheevaplug.h |   37 +++++++
>  include/configs/sheevaplug.h          |  191
> +++++++++++++++++++++++++++++++++ 8 files changed, 526 insertions(+), 3
> deletions(-)
>  create mode 100644 board/Marvell/sheevaplug/Makefile
>  create mode 100644 board/Marvell/sheevaplug/config.mk
>  create mode 100644 board/Marvell/sheevaplug/nand.c
>  create mode 100644 board/Marvell/sheevaplug/sheevaplug.c
>  create mode 100644 board/Marvell/sheevaplug/sheevaplug.h
>  create mode 100644 include/configs/sheevaplug.h

You didn't add a maintainer for this new board to MAINTAINERS. Please add this 
in your next patch version. And for the MV88F6281GTW_GE board as well.

> diff --git a/MAKEALL b/MAKEALL
> index 6719d7b..e3d33cb 100755
> --- a/MAKEALL
> +++ b/MAKEALL
> @@ -144,6 +144,7 @@ LIST_8xx="		\
>  	RPXlite		\
>  	RPXlite_DW	\
>  	RRvision	\
> +	sheevaplug	\
>  	SM850		\
>  	spc1920		\
>  	SPD823TS	\
> diff --git a/Makefile b/Makefile
> index 8144ecd..34a863b 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -1122,6 +1122,9 @@ RRvision_LCD_config:	unconfig
>  	@echo "#define CONFIG_SHARP_LQ104V7DS01" >>$(obj)include/config.h
>  	@$(MKCONFIG) -a RRvision ppc mpc8xx RRvision
>
> +sheevaplug_config: unconfig
> +	@$(MKCONFIG) $(@:_config=) arm arm926ejs $(@:_config=) Marvell kirkwood
> +
>  SM850_config	:	unconfig
>  	@$(MKCONFIG) $(@:_config=) ppc mpc8xx tqm8xx tqc
>
> @@ -2808,9 +2811,6 @@ lpd7a400_config \
>  lpd7a404_config:	unconfig
>  	@$(MKCONFIG) $(@:_config=) arm lh7a40x lpd7a40x
>
> -mv88f6281gtw_ge_config: unconfig
> -	@$(MKCONFIG) $(@:_config=) arm arm926ejs $(@:_config=) Marvell kirkwood
> -

Why do you remove this board here?

>  mx1ads_config	:	unconfig
>  	@$(MKCONFIG) $(@:_config=) arm arm920t mx1ads NULL imx
>
> @@ -3110,6 +3110,8 @@ omap2420h4_config	: unconfig
>  qong_config		: unconfig
>  	@$(MKCONFIG) $(@:_config=) arm arm1136 qong davedenx mx31
>
> +sheevapluge_config: unconfig
> +	@$(MKCONFIG) $(@:_config=) arm arm926ejs $(@:_config=) Marvell kirkwood


"sheevapluge" here and "sheevaplug" a few lines above? This probably just 
slipped in.

Thanks.

Best regards,
Stefan

=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80  Email: office at denx.de
=====================================================================

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [U-Boot] [PATCH] Marvell Sheevaplug Board support
  2009-05-21 20:24 ` [U-Boot] [PATCH] Marvell Sheevaplug Board support Prafulla Wadaskar
  2009-05-21 20:24   ` [U-Boot] [PATCH] Marvell MV88E1116 PHY Driver support Prafulla Wadaskar
  2009-05-22  8:21   ` [U-Boot] [PATCH] Marvell Sheevaplug Board support Stefan Roese
@ 2009-05-22 11:02   ` Wolfgang Denk
  2009-05-22 12:08     ` Prafulla Wadaskar
  2 siblings, 1 reply; 18+ messages in thread
From: Wolfgang Denk @ 2009-05-22 11:02 UTC (permalink / raw)
  To: u-boot

Dear Prafulla Wadaskar,

In message <1242937472-30778-2-git-send-email-prafulla@marvell.com> you wrote:
> References: http://plugcomputer.org/
> Serial console Setup
> http://openplug.org/plugwiki/index.php/Serial_terminal_program#Linux
> OpenOCD Setup
> http://openplug.org/plugwiki/index.php/Setting_Up_OpenOCD_Under_Linux
> 
> This patch is tested for-
> 1. Boot from DRAM/NAND flash
> 2. File transfer using tftp
> 3. NAND flash read/write/erase
...

> diff --git a/MAKEALL b/MAKEALL
> index 6719d7b..e3d33cb 100755
> --- a/MAKEALL
> +++ b/MAKEALL
> @@ -144,6 +144,7 @@ LIST_8xx="		\
>  	RPXlite		\
>  	RPXlite_DW	\
>  	RRvision	\
> +	sheevaplug	\
>  	SM850		\

Why do you add an ARM board right in the middle of MPC8xx PowerPC
boards? You obviously never tested this.

Please do not submit untested code!!!

> @@ -1122,6 +1122,9 @@ RRvision_LCD_config:	unconfig
>  	@echo "#define CONFIG_SHARP_LQ104V7DS01" >>$(obj)include/config.h
>  	@$(MKCONFIG) -a RRvision ppc mpc8xx RRvision
>  
> +sheevaplug_config: unconfig
> +	@$(MKCONFIG) $(@:_config=) arm arm926ejs $(@:_config=) Marvell kirkwood
> +
>  SM850_config	:	unconfig
>  	@$(MKCONFIG) $(@:_config=) ppc mpc8xx tqm8xx tqc

Why do you add an ARM board right in the middle of MPC8xx PowerPC
boards?

> @@ -2808,9 +2811,6 @@ lpd7a400_config \
>  lpd7a404_config:	unconfig
>  	@$(MKCONFIG) $(@:_config=) arm lh7a40x lpd7a40x
>  
> -mv88f6281gtw_ge_config: unconfig
> -	@$(MKCONFIG) $(@:_config=) arm arm926ejs $(@:_config=) Marvell kirkwood
> -

Why do you delete other boards?

> @@ -3110,6 +3110,8 @@ omap2420h4_config	: unconfig
>  qong_config		: unconfig
>  	@$(MKCONFIG) $(@:_config=) arm arm1136 qong davedenx mx31
>  
> +sheevapluge_config: unconfig
> +	@$(MKCONFIG) $(@:_config=) arm arm926ejs $(@:_config=) Marvell kirkwood

Why do you add the baord twice?

> +# (C) Copyright 2009
> +# Marvell Semiconductor <www.marvell.com>
> +# Prafulla Wadaskar <prafulla@marvell.com>

This makes no sense. Either Marvell holds the Copyright, or you do.
Same in other files.


> +/*
> + * For booting Linux, the board info and command line data
> + * have to be in the first 8 MB of memory, since this is
> + * the maximum mapped by the Linux kernel during initialization.
> + */
> +#define	CONFIG_BOOTMAPSZ	(8 << 20)	/* Initial Memmap for Linux */

Line too long.

> +#define CONFIG_MTDPARTS			"orion_nand:512k(uboot),"	\
> +	"1m at 4m(psm), 3m at 1m(kernel),13m at 5m(rootfs) rw\0"

This will not work. The embedded space is not allowed.

> +#ifdef CONFIG_CMD_NET
> +#define CONFIG_NETCONSOLE	/* include NetConsole support   */
> +#define CONFIG_NET_MULTI	/* specify more that one ports available */
> +#define	CONFIG_MII		/* expose smi ove miiphy interface */
> +#define CONFIG_KIRKWOOD_EGIGA	/* Enable kirkwood Gbe Controller Driver */

Line too long.


Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Marriage is the triumph  of  imagination  over  intelligence.  Second
marriage is the triumph of hope over experience.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [U-Boot] [PATCH] Marvell Sheevaplug Board support
  2009-05-22 11:02   ` Wolfgang Denk
@ 2009-05-22 12:08     ` Prafulla Wadaskar
  2009-05-22 12:17       ` Prafulla Wadaskar
  2009-05-22 15:22       ` Wolfgang Denk
  0 siblings, 2 replies; 18+ messages in thread
From: Prafulla Wadaskar @ 2009-05-22 12:08 UTC (permalink / raw)
  To: u-boot

> 
> > +#define CONFIG_MTDPARTS			
> "orion_nand:512k(uboot),"	\
> > +	"1m at 4m(psm), 3m at 1m(kernel),13m at 5m(rootfs) rw\0"
> 
> This will not work. The embedded space is not allowed.
These are the parameters will be passed to the kernel
I didn't understand what will not work.
Can you pls explain this?

Regards...
Prafulla . .

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [U-Boot] [PATCH] Marvell Sheevaplug Board support
  2009-05-22 12:08     ` Prafulla Wadaskar
@ 2009-05-22 12:17       ` Prafulla Wadaskar
  2009-05-22 15:22       ` Wolfgang Denk
  1 sibling, 0 replies; 18+ messages in thread
From: Prafulla Wadaskar @ 2009-05-22 12:17 UTC (permalink / raw)
  To: u-boot

 

> -----Original Message-----
> From: u-boot-bounces at lists.denx.de 
> [mailto:u-boot-bounces at lists.denx.de] On Behalf Of Prafulla Wadaskar
> Sent: Friday, May 22, 2009 5:38 PM
> To: Wolfgang Denk
> Cc: Manas Saksena; Ronen Shitrit; Nicolas Pitre; 
> u-boot at lists.denx.de; Ashish Karkare; Prabhanjan Sarnaik; 
> Lennert Buijtenhek
> Subject: Re: [U-Boot] [PATCH] Marvell Sheevaplug Board support
> 
> > 
> > > +#define CONFIG_MTDPARTS			
> > "orion_nand:512k(uboot),"	\
> > > +	"1m at 4m(psm), 3m at 1m(kernel),13m at 5m(rootfs) rw\0"
> > 
> > This will not work. The embedded space is not allowed.
> These are the parameters will be passed to the kernel I 
> didn't understand what will not work.
> Can you pls explain this?
Hi I got it.... ;-( sorry....
Regards..
Prafulla . .

> 
> Regards...
> Prafulla . .
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
> 

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [U-Boot] [PATCH] Marvell Sheevaplug Board support
  2009-05-22 12:08     ` Prafulla Wadaskar
  2009-05-22 12:17       ` Prafulla Wadaskar
@ 2009-05-22 15:22       ` Wolfgang Denk
  1 sibling, 0 replies; 18+ messages in thread
From: Wolfgang Denk @ 2009-05-22 15:22 UTC (permalink / raw)
  To: u-boot

Dear Prafulla Wadaskar,

In message <73173D32E9439E4ABB5151606C3E19E201CF9E688B@SC-VEXCH1.marvell.com> you wrote:
> > 
> > > +#define CONFIG_MTDPARTS			
> > "orion_nand:512k(uboot),"	\
> > > +	"1m at 4m(psm), 3m at 1m(kernel),13m at 5m(rootfs) rw\0"
> > 
> > This will not work. The embedded space is not allowed.
> These are the parameters will be passed to the kernel
> I didn't understand what will not work.

The Linux kernel will not be able to parse this.

> Can you pls explain this?

Please remove the space before "3m at 1m(kernel)", i. e. write:

	"1m at 4m(psm),3m at 1m(kernel),13m at 5m(rootfs) rw\0"

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
The high cost of living hasn't affected its popularity.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [U-Boot] [PATCH v10] Marvell Kirkwood family SOC support
  2009-05-21 20:24 [U-Boot] [PATCH v10] Marvell Kirkwood family SOC support Prafulla Wadaskar
  2009-05-21 20:24 ` [U-Boot] [PATCH] Marvell Sheevaplug Board support Prafulla Wadaskar
@ 2009-05-25  4:56 ` Prafulla Wadaskar
  2009-05-25  7:11 ` Stefan Roese
  2 siblings, 0 replies; 18+ messages in thread
From: Prafulla Wadaskar @ 2009-05-25  4:56 UTC (permalink / raw)
  To: u-boot

Dear Jean and Wolfgang

May you kindly provide your valued comments on this patch since this in important patch to be mainlined FIRST.
It might have skipped from your queue :-)

Shall I resend it?

Regards..
Prafulla . .

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [U-Boot] [PATCH v10] Marvell Kirkwood family SOC support
  2009-05-21 20:24 [U-Boot] [PATCH v10] Marvell Kirkwood family SOC support Prafulla Wadaskar
  2009-05-21 20:24 ` [U-Boot] [PATCH] Marvell Sheevaplug Board support Prafulla Wadaskar
  2009-05-25  4:56 ` [U-Boot] [PATCH v10] Marvell Kirkwood family SOC support Prafulla Wadaskar
@ 2009-05-25  7:11 ` Stefan Roese
  2 siblings, 0 replies; 18+ messages in thread
From: Stefan Roese @ 2009-05-25  7:11 UTC (permalink / raw)
  To: u-boot

On Thursday 21 May 2009 22:24:29 Prafulla Wadaskar wrote:
> Kirkwood family controllers are highly integrated SOCs
> based on Feroceon-88FR131/Sheeva-88SV131 cpu core.
>
> SOC versions supported:-
> 1) 88F6281-A0       define CONFIG_KW88F6281_A0
> 2) 88F6192-A0       define CONFIG_KW88F6192_A0
>
> Other supported features:-
> 1) get_random_hex() fucntion
> 2) SPI port controller driver
> 3) PCI Express port initialization
>
> Contributors:
> Yotam Admon <yotam@marvell.com>
> Michael Blostein <michaelbl@marvell.com
>
> Reviewed-by: Ronen Shitrit <rshitrit@marvell.com>
> Signed-off-by: Prafulla Wadaskar <prafulla@marvell.com>

Acked-by: Stefan Roese <sr@denx.de>

Thanks.

Best regards,
Stefan

=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80  Email: office at denx.de
=====================================================================

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [U-Boot] [PATCH v4] Gbe Controller driver support for kirkwood SOCs
  2009-05-21 20:24     ` [U-Boot] [PATCH v4] Gbe Controller driver support for kirkwood SOCs Prafulla Wadaskar
@ 2009-05-26  6:34       ` Ben Warren
  2009-05-26  6:54         ` Prafulla Wadaskar
  2009-05-26 14:56       ` Stefan Roese
  1 sibling, 1 reply; 18+ messages in thread
From: Ben Warren @ 2009-05-26  6:34 UTC (permalink / raw)
  To: u-boot

Hi Prafulla,

Prafulla Wadaskar wrote:
> Contributors:
> Yotam Admon <yotam@marvell.com>
> Michael Blostein <michaelbl@marvell.com
>
> Reviewed by: Ronen Shitrit <rshitrit@marvell.com>
> Signed-off-by: Prafulla Wadaskar <prafulla@marvell.com>
> ---
> Change log:
> v2: entire rewrite/restructure of v1
> used small names for variable/function names
> readl/writel used to access SoC registers
> Soc registers accssed using pointers through net device struct
> miiphy registration done for external smi read/write access
> miiphy_link used to detect phy link presence
> cleaned for cosmetic changes
>
> v3: asm/arch/kirkwood.h included in c file
>
> v4: bugfix for phy address read
>
>  cpu/arm926ejs/kirkwood/cpu.c |    8 +
>  drivers/net/Makefile         |    1 +
>  drivers/net/kirkwood_egiga.c | 1670 ++++++++++++++++++++++++++++++++++++++++++
>  drivers/net/kirkwood_egiga.h |  828 +++++++++++++++++++++
>  include/netdev.h             |    1 +
>  5 files changed, 2508 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/net/kirkwood_egiga.c
>  create mode 100644 drivers/net/kirkwood_egiga.h
>
> diff --git a/cpu/arm926ejs/kirkwood/cpu.c b/cpu/arm926ejs/kirkwood/cpu.c
> index 1286cac..d37c2e2 100644
> --- a/cpu/arm926ejs/kirkwood/cpu.c
> +++ b/cpu/arm926ejs/kirkwood/cpu.c
> @@ -314,3 +314,11 @@ int arch_misc_init(void)
>  	return 0;
>  }
>  #endif /* CONFIG_ARCH_MISC_INIT */
> +
> +#ifdef CONFIG_KIRKWOOD_EGIGA
> +int cpu_eth_init(bd_t *bis)
> +{
> +	kirkwood_egiga_initialize(bis);
> +	return 0;
> +}
> +#endif
>   
Please move this part (cpu.c) to a different patch.  This one should 
only include the driver itself, and I can't apply it since the cpu.c 
file doesn't exist yet...

I don't have any technical problems with this patch, but please consider 
the following:

1. Statistics are great to have, but most people won't look at them and 
all the associated logic makes the driver very big.  Please 
conditionally compile that stuff in.

2. Please ensure that all lines are <= 78 characters long (80 minus the 
initial character that diff puts in)

regards,
Ben

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [U-Boot] [PATCH v4] Gbe Controller driver support for kirkwood SOCs
  2009-05-26  6:34       ` Ben Warren
@ 2009-05-26  6:54         ` Prafulla Wadaskar
  0 siblings, 0 replies; 18+ messages in thread
From: Prafulla Wadaskar @ 2009-05-26  6:54 UTC (permalink / raw)
  To: u-boot

Hi Ben

Thanks...
> > diff --git a/cpu/arm926ejs/kirkwood/cpu.c 
> > b/cpu/arm926ejs/kirkwood/cpu.c index 1286cac..d37c2e2 100644
> > --- a/cpu/arm926ejs/kirkwood/cpu.c
> > +++ b/cpu/arm926ejs/kirkwood/cpu.c
> > @@ -314,3 +314,11 @@ int arch_misc_init(void)
> >  	return 0;
> >  }
> >  #endif /* CONFIG_ARCH_MISC_INIT */
> > +
> > +#ifdef CONFIG_KIRKWOOD_EGIGA
> > +int cpu_eth_init(bd_t *bis)
> > +{
> > +	kirkwood_egiga_initialize(bis);
> > +	return 0;
> > +}
> > +#endif
> >   
> Please move this part (cpu.c) to a different patch.  This one 
> should only include the driver itself, and I can't apply it 
> since the cpu.c file doesn't exist yet...
Cool..I will provide separate Kirwood SOC Support patch for this

> 
> I don't have any technical problems with this patch, but 
> please consider the following:
> 
> 1. Statistics are great to have, but most people won't look 
> at them and all the associated logic makes the driver very 
As I said earlier I am removing this stuff, this will make code smaller
> big.  Please conditionally compile that stuff in.
Probably in latter phase I will submit a patch to support statistics
 
> 
> 2. Please ensure that all lines are <= 78 characters long (80 
> minus the initial character that diff puts in)
Yes. this was a problem with Wolfgang(I think) some lines in the code are 79/80 chars long
I will correct them.

Regards..
Prafulla . .

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [U-Boot] [PATCH v4] Gbe Controller driver support for kirkwood SOCs
  2009-05-21 20:24     ` [U-Boot] [PATCH v4] Gbe Controller driver support for kirkwood SOCs Prafulla Wadaskar
  2009-05-26  6:34       ` Ben Warren
@ 2009-05-26 14:56       ` Stefan Roese
  2009-05-27  5:26         ` Prafulla Wadaskar
  1 sibling, 1 reply; 18+ messages in thread
From: Stefan Roese @ 2009-05-26 14:56 UTC (permalink / raw)
  To: u-boot

Hi Prafulla,

On Thursday 21 May 2009 22:24:32 Prafulla Wadaskar wrote:
> Contributors:
> Yotam Admon <yotam@marvell.com>
> Michael Blostein <michaelbl@marvell.com
>
> Reviewed by: Ronen Shitrit <rshitrit@marvell.com>
> Signed-off-by: Prafulla Wadaskar <prafulla@marvell.com>
> ---
> Change log:
> v2: entire rewrite/restructure of v1
> used small names for variable/function names
> readl/writel used to access SoC registers
> Soc registers accssed using pointers through net device struct
> miiphy registration done for external smi read/write access
> miiphy_link used to detect phy link presence
> cleaned for cosmetic changes

Please find a comment below.

> diff --git a/drivers/net/kirkwood_egiga.h b/drivers/net/kirkwood_egiga.h
> new file mode 100644
> index 0000000..9f3908e
> --- /dev/null
> +++ b/drivers/net/kirkwood_egiga.h
> @@ -0,0 +1,828 @@
> +/*
> + * (C) Copyright 2009
> + * Marvell Semiconductor <www.marvell.com>
> + * Prafulla Wadaskar <prafulla@marvell.com>
> + *
> + * based on - Driver for MV64360X ethernet ports
> + * Copyright (C) 2002 rabeeh at galileo.co.il
> + *
> + * 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., 51 Franklin Street, Fifth Floor, Boston,
> + * MA 02110-1301 USA
> + */
> +
> +#ifndef __EGIGA_H__
> +#define __EGIGA_H__
> +
> +#define MAX_KWGBE_DEVS	2	/*controller has two ports */

<snip>

> +/* Default port serial control value */
> +#define PORT_SERIAL_CONTROL_VALUE_TMP		  \
> +	KWGBE_FORCE_LINK_PASS			| \
> +	KWGBE_DIS_AUTO_NEG_FOR_DUPLX		| \
> +	KWGBE_DIS_AUTO_NEG_FOR_FLOW_CTRL	| \
> +	KWGBE_ADV_NO_FLOW_CTRL			| \
> +	KWGBE_FORCE_FC_MODE_NO_PAUSE_DIS_TX	| \
> +	KWGBE_FORCE_BP_MODE_NO_JAM		| \
> +	(1 << 9)					| \
> +	KWGBE_DO_NOT_FORCE_LINK_FAIL		| \
> +	KWGBE_DIS_AUTO_NEG_SPEED_GMII		| \

You disable speed auto-negotiation here. Why are you doing this? Using auto-
negotiation should be the default operation mode from my point of view.

> +	KWGBE_DTE_ADV_0				| \
> +	KWGBE_MIIPHY_MAC_MODE			| \
> +	KWGBE_AUTO_NEG_NO_CHANGE			| \
> +	KWGBE_MAX_RX_PACKET_1552BYTE		| \
> +	KWGBE_CLR_EXT_LOOPBACK			| \
> +	KWGBE_SET_FULL_DUPLEX_MODE		| \
> +	KWGBE_DIS_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX | \
> +	KWGBE_SET_MII_SPEED_TO_100
> +
> +#ifdef CONFIG_SYS_MII_MODE
> +#define PORT_SERIAL_CONTROL_VALUE	\
> +	PORT_SERIAL_CONTROL_VALUE_TMP |	\
> +	KWGBE_SET_GMII_SPEED_TO_10_100
> +#else
> +#define PORT_SERIAL_CONTROL_VALUE	\
> +	PORT_SERIAL_CONTROL_VALUE_TMP |	\
> +	KWGBE_SET_GMII_SPEED_TO_1000
> +#endif

If you need a fixed link speed configuration we should perhaps add a 
configuration option for this. What do you think?

Best regards,
Stefan

=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80  Email: office at denx.de
=====================================================================

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [U-Boot] [PATCH v4] Gbe Controller driver support for kirkwood SOCs
  2009-05-26 14:56       ` Stefan Roese
@ 2009-05-27  5:26         ` Prafulla Wadaskar
  2009-05-27  7:10           ` Stefan Roese
  0 siblings, 1 reply; 18+ messages in thread
From: Prafulla Wadaskar @ 2009-05-27  5:26 UTC (permalink / raw)
  To: u-boot

Thanks a lot Stefan for your review feedback...
You are thinking more similar to Linux Implementation :-)

I will try to address your suggestions, it provides more flexibility and readability.
On the other hand I am currently putting my efforts to reduce patch size cutting some features.
I will do it step-by-step.

Regards..
Prafulla . . .

> -----Original Message-----
> From: Stefan Roese [mailto:sr at denx.de] 
> Sent: Tuesday, May 26, 2009 8:26 PM
> To: u-boot at lists.denx.de
> Cc: Prafulla Wadaskar; Manas Saksena; Ronen Shitrit; Nicolas 
> Pitre; Ashish Karkare; Prabhanjan Sarnaik; Lennert Buijtenhek
> Subject: Re: [U-Boot] [PATCH v4] Gbe Controller driver 
> support for kirkwood SOCs
> 
> Hi Prafulla,
> 
> On Thursday 21 May 2009 22:24:32 Prafulla Wadaskar wrote:
> > Contributors:
> > Yotam Admon <yotam@marvell.com>
> > Michael Blostein <michaelbl@marvell.com
> >
> > Reviewed by: Ronen Shitrit <rshitrit@marvell.com>
> > Signed-off-by: Prafulla Wadaskar <prafulla@marvell.com>
> > ---
> > Change log:
> > v2: entire rewrite/restructure of v1
> > used small names for variable/function names readl/writel used to 
> > access SoC registers Soc registers accssed using pointers 
> through net 
> > device struct miiphy registration done for external smi read/write 
> > access miiphy_link used to detect phy link presence cleaned for 
> > cosmetic changes
> 
> Please find a comment below.
> 
> > diff --git a/drivers/net/kirkwood_egiga.h 
> > b/drivers/net/kirkwood_egiga.h new file mode 100644 index 
> > 0000000..9f3908e
> > --- /dev/null
> > +++ b/drivers/net/kirkwood_egiga.h
> > @@ -0,0 +1,828 @@
> > +/*
> > + * (C) Copyright 2009
> > + * Marvell Semiconductor <www.marvell.com>
> > + * Prafulla Wadaskar <prafulla@marvell.com>
> > + *
> > + * based on - Driver for MV64360X ethernet ports
> > + * Copyright (C) 2002 rabeeh at galileo.co.il
> > + *
> > + * 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., 51 Franklin Street, Fifth Floor, Boston,
> > + * MA 02110-1301 USA
> > + */
> > +
> > +#ifndef __EGIGA_H__
> > +#define __EGIGA_H__
> > +
> > +#define MAX_KWGBE_DEVS	2	/*controller has two ports */
> 
> <snip>
> 
> > +/* Default port serial control value */
> > +#define PORT_SERIAL_CONTROL_VALUE_TMP		  \
> > +	KWGBE_FORCE_LINK_PASS			| \
> > +	KWGBE_DIS_AUTO_NEG_FOR_DUPLX		| \
> > +	KWGBE_DIS_AUTO_NEG_FOR_FLOW_CTRL	| \
> > +	KWGBE_ADV_NO_FLOW_CTRL			| \
> > +	KWGBE_FORCE_FC_MODE_NO_PAUSE_DIS_TX	| \
> > +	KWGBE_FORCE_BP_MODE_NO_JAM		| \
> > +	(1 << 9)					| \
> > +	KWGBE_DO_NOT_FORCE_LINK_FAIL		| \
> > +	KWGBE_DIS_AUTO_NEG_SPEED_GMII		| \
> 
> You disable speed auto-negotiation here. Why are you doing 
> this? Using auto- negotiation should be the default operation 
> mode from my point of view.
> 
> > +	KWGBE_DTE_ADV_0				| \
> > +	KWGBE_MIIPHY_MAC_MODE			| \
> > +	KWGBE_AUTO_NEG_NO_CHANGE			| \
> > +	KWGBE_MAX_RX_PACKET_1552BYTE		| \
> > +	KWGBE_CLR_EXT_LOOPBACK			| \
> > +	KWGBE_SET_FULL_DUPLEX_MODE		| \
> > +	KWGBE_DIS_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX | \
> > +	KWGBE_SET_MII_SPEED_TO_100
> > +
> > +#ifdef CONFIG_SYS_MII_MODE
> > +#define PORT_SERIAL_CONTROL_VALUE	\
> > +	PORT_SERIAL_CONTROL_VALUE_TMP |	\
> > +	KWGBE_SET_GMII_SPEED_TO_10_100
> > +#else
> > +#define PORT_SERIAL_CONTROL_VALUE	\
> > +	PORT_SERIAL_CONTROL_VALUE_TMP |	\
> > +	KWGBE_SET_GMII_SPEED_TO_1000
> > +#endif
> 
> If you need a fixed link speed configuration we should 
> perhaps add a configuration option for this. What do you think?
> 
> Best regards,
> Stefan
> 
> =====================================================================
> DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
> HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
> Phone: +49-8142-66989-0 Fax: +49-8142-66989-80  Email: 
> office at denx.de 
> =====================================================================
> 

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [U-Boot] [PATCH v4] Gbe Controller driver support for kirkwood SOCs
  2009-05-27  5:26         ` Prafulla Wadaskar
@ 2009-05-27  7:10           ` Stefan Roese
  0 siblings, 0 replies; 18+ messages in thread
From: Stefan Roese @ 2009-05-27  7:10 UTC (permalink / raw)
  To: u-boot

On Wednesday 27 May 2009 07:26:13 Prafulla Wadaskar wrote:
> Thanks a lot Stefan for your review feedback...
> You are thinking more similar to Linux Implementation :-)
>
> I will try to address your suggestions, it provides more flexibility and
> readability. On the other hand I am currently putting my efforts to reduce
> patch size cutting some features. I will do it step-by-step.

Understood. We can always fine-tune the code after it's accepted upstream. So 
please add my:

Acked-by: Stefan Roese <sr@denx.de>

Thanks.

Best regards,
Stefan

=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80  Email: office at denx.de
=====================================================================

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [U-Boot] [PATCH] Marvell MV88E1116 PHY Driver support
       [not found]     ` <73173D32E9439E4ABB5151606C3E19E201CFBDC5A1@SC-VEXCH1.marvell.com>
@ 2009-05-30 16:06       ` Ben Warren
  2009-06-02 11:22         ` Prafulla Wadaskar
  0 siblings, 1 reply; 18+ messages in thread
From: Ben Warren @ 2009-05-30 16:06 UTC (permalink / raw)
  To: u-boot

Hi Prafulla,

On Fri, May 29, 2009 at 11:34 PM, Prafulla Wadaskar <prafulla@marvell.com>wrote:

> Hi Ben
> Thanks for accepting MV88E61xx driver code.
> Ping for mv88f1116 driver....... :-)
> This is dependency for sheevaplug board support.

I've already commented on this one.  We don't currently have a framework for
PHYs and I don't want to add PHY support ad-hoc.  For now, PHY support needs
to go in whatever ethernet driver uses it.

regards,
Ben

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [U-Boot] [PATCH] Marvell MV88E1116 PHY Driver support
  2009-05-30 16:06       ` [U-Boot] [PATCH] Marvell MV88E1116 PHY Driver support Ben Warren
@ 2009-06-02 11:22         ` Prafulla Wadaskar
  0 siblings, 0 replies; 18+ messages in thread
From: Prafulla Wadaskar @ 2009-06-02 11:22 UTC (permalink / raw)
  To: u-boot

> -----Original Message-----
> From: Ben Warren [mailto:biggerbadderben at gmail.com] 
> Sent: Saturday, May 30, 2009 9:36 PM
> To: Prafulla Wadaskar
> Cc: u-boot at lists.denx.de
> Subject: Re: [PATCH] Marvell MV88E1116 PHY Driver support
> 
> Hi Prafulla,
> 
> 
> On Fri, May 29, 2009 at 11:34 PM, Prafulla Wadaskar 
> <prafulla@marvell.com> wrote:
> 
> 
> 	Hi Ben
> 	Thanks for accepting MV88E61xx driver code.
> 	Ping for mv88f1116 driver....... :-)
> 	This is dependency for sheevaplug board support.
> 
> I've already commented on this one.  We don't currently have 
> a framework for PHYs and I don't want to add PHY support 
> ad-hoc.  For now, PHY support needs to go in whatever 
> ethernet driver uses it.
Hi Ben

Don't you think keeping phy support in Ethernet driver will harm to keep it's generic approach?
through development and reviews we always try to keep any driver generic so that it can be used by others.

As of now apart from switch mv88e61xx, there is no phy support in driver/net/phy/.
Being this first one- May I take this opportunity to help you to create a framework for PHYs?

Regards..
Prafulla . .

> 
> regards,
> Ben

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2009-06-02 11:22 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-05-21 20:24 [U-Boot] [PATCH v10] Marvell Kirkwood family SOC support Prafulla Wadaskar
2009-05-21 20:24 ` [U-Boot] [PATCH] Marvell Sheevaplug Board support Prafulla Wadaskar
2009-05-21 20:24   ` [U-Boot] [PATCH] Marvell MV88E1116 PHY Driver support Prafulla Wadaskar
2009-05-21 20:24     ` [U-Boot] [PATCH v4] Gbe Controller driver support for kirkwood SOCs Prafulla Wadaskar
2009-05-26  6:34       ` Ben Warren
2009-05-26  6:54         ` Prafulla Wadaskar
2009-05-26 14:56       ` Stefan Roese
2009-05-27  5:26         ` Prafulla Wadaskar
2009-05-27  7:10           ` Stefan Roese
     [not found]     ` <73173D32E9439E4ABB5151606C3E19E201CFBDC5A1@SC-VEXCH1.marvell.com>
2009-05-30 16:06       ` [U-Boot] [PATCH] Marvell MV88E1116 PHY Driver support Ben Warren
2009-06-02 11:22         ` Prafulla Wadaskar
2009-05-22  8:21   ` [U-Boot] [PATCH] Marvell Sheevaplug Board support Stefan Roese
2009-05-22 11:02   ` Wolfgang Denk
2009-05-22 12:08     ` Prafulla Wadaskar
2009-05-22 12:17       ` Prafulla Wadaskar
2009-05-22 15:22       ` Wolfgang Denk
2009-05-25  4:56 ` [U-Boot] [PATCH v10] Marvell Kirkwood family SOC support Prafulla Wadaskar
2009-05-25  7:11 ` Stefan Roese

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.