[U-Boot] [PATCH v4] Marvell Kirkwood family SOC support

Prafulla Wadaskar prafulla at marvell.com
Wed Apr 29 18:57:35 CEST 2009


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 at marvell.com>
Michael Blostein <michaelbl at marvell.com

Reviewed-by: Ronen Shitrit <rshitrit at marvell.com>
Signed-off-by: Prafulla Wadaskar <prafulla at 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

 cpu/arm926ejs/kirkwood/Makefile           |   50 +++++
 cpu/arm926ejs/kirkwood/config.mk          |   25 +++
 cpu/arm926ejs/kirkwood/dram.c             |   57 ++++++
 cpu/arm926ejs/kirkwood/kwcore.c           |  284 +++++++++++++++++++++++++++++
 cpu/arm926ejs/kirkwood/kwcore.h           |   99 ++++++++++
 cpu/arm926ejs/kirkwood/lowlevel_init.S    |   43 +++++
 cpu/arm926ejs/kirkwood/timer.c            |  159 ++++++++++++++++
 cpu/arm926ejs/start.S                     |    9 +-
 drivers/serial/Makefile                   |    1 +
 drivers/serial/kirkwood_serial.c          |  128 +++++++++++++
 drivers/spi/Makefile                      |    1 +
 drivers/spi/kirkwood_spi.c                |  167 +++++++++++++++++
 include/asm-arm/arch-kirkwood/kirkwood.h  |  118 ++++++++++++
 include/asm-arm/arch-kirkwood/kw88f6192.h |   37 ++++
 include/asm-arm/arch-kirkwood/kw88f6281.h |   37 ++++
 include/asm-arm/arch-kirkwood/serial.h    |   89 +++++++++
 include/asm-arm/arch-kirkwood/spi.h       |   39 ++++
 include/asm-arm/cache.h                   |   49 +++++
 include/asm-arm/config.h                  |    4 +
 include/common.h                          |    1 +
 lib_arm/board.c                           |    4 +
 21 files changed, 1399 insertions(+), 2 deletions(-)
 create mode 100644 cpu/arm926ejs/kirkwood/Makefile
 create mode 100644 cpu/arm926ejs/kirkwood/config.mk
 create mode 100644 cpu/arm926ejs/kirkwood/dram.c
 create mode 100644 cpu/arm926ejs/kirkwood/kwcore.c
 create mode 100644 cpu/arm926ejs/kirkwood/kwcore.h
 create mode 100644 cpu/arm926ejs/kirkwood/lowlevel_init.S
 create mode 100644 cpu/arm926ejs/kirkwood/timer.c
 create mode 100644 drivers/serial/kirkwood_serial.c
 create mode 100644 drivers/spi/kirkwood_spi.c
 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/serial.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..781a3c6
--- /dev/null
+++ b/cpu/arm926ejs/kirkwood/Makefile
@@ -0,0 +1,50 @@
+#
+# (C) Copyright 2009
+# Marvell Semiconductor <www.marvell.com>
+# Prafulla Wadaskar <prafulla at 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	+= kwcore.o
+COBJS-y	+= timer.o
+
+SOBJS	= lowlevel_init.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/config.mk b/cpu/arm926ejs/kirkwood/config.mk
new file mode 100644
index 0000000..000eeb4
--- /dev/null
+++ b/cpu/arm926ejs/kirkwood/config.mk
@@ -0,0 +1,25 @@
+#
+# (C) Copyright 2009
+# Marvell Semiconductor <www.marvell.com>
+# Prafulla Wadaskar <prafulla at 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
+#
+
+PLATFORM_CPPFLAGS += -march=armv5te
diff --git a/cpu/arm926ejs/kirkwood/dram.c b/cpu/arm926ejs/kirkwood/dram.c
new file mode 100644
index 0000000..9abdca2
--- /dev/null
+++ b/cpu/arm926ejs/kirkwood/dram.c
@@ -0,0 +1,57 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Prafulla Wadaskar <prafulla at 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>
+
+#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/kwcore.c b/cpu/arm926ejs/kirkwood/kwcore.c
new file mode 100644
index 0000000..9eaaab6
--- /dev/null
+++ b/cpu/arm926ejs/kirkwood/kwcore.c
@@ -0,0 +1,284 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Prafulla Wadaskar <prafulla at 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 <u-boot/md5.h>
+
+void reset_cpu(unsigned long ignored)
+{
+	writel(readl(KW_REG_CPU_RSTOUTN_MASK) | 1 << 2,
+	       KW_REG_CPU_RSTOUTN_MASK);
+	writel(readl(KW_REG_CPU_SYS_SOFT_RST) | 1, KW_REG_CPU_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[16];
+	u8 outbuf[16];
+
+	/*
+	 * in case of 88F6281/88F6192 A0,
+	 * 1<<7 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 < 16; i++) {
+		inbuf[i] = readl(KW_REG_UNDOC_0x1470);
+	}
+	md5((u8 *) inbuf, 64, 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)
+{
+	writel(KWCPU_WIN_CTRL_DATA(0xc0000, KWCPU_TARGET_PCIE,
+				   KWCPU_ATTR_PCIE_MEM, KWCPU_WIN_ENABLE),
+	       KW_REG_WIN_CTRL(0));
+
+	writel(0x90000000, KW_REG_WIN_BASE(0));
+	writel(0x90000000, KW_REG_WIN_REMAP_LOW(0));
+	writel(0x00000000, KW_REG_WIN_REMAP_HIGH(0));
+
+	writel(KWCPU_WIN_CTRL_DATA(0x70000, KWCPU_TARGET_MEMORY,
+				   KWCPU_ATTR_NANDFLASH, KWCPU_WIN_ENABLE),
+	       KW_REG_WIN_CTRL(1));
+	writel(0xF9000000, KW_REG_WIN_BASE(1));
+	writel(0xF9000000, KW_REG_WIN_REMAP_LOW(1));
+	writel(0x00000000, KW_REG_WIN_REMAP_HIGH(1));
+
+	writel(KWCPU_WIN_CTRL_DATA(0x80000, KWCPU_TARGET_PCIE,
+				   KWCPU_ATTR_PCIE_IO, KWCPU_WIN_ENABLE),
+	       KW_REG_WIN_CTRL(2));
+	writel(0xF0000000, KW_REG_WIN_BASE(2));
+	writel(0xC0000000, KW_REG_WIN_REMAP_LOW(2));
+	writel(0x00000000, KW_REG_WIN_REMAP_HIGH(2));
+
+	writel(KWCPU_WIN_CTRL_DATA(0x80000, KWCPU_TARGET_MEMORY,
+				   KWCPU_ATTR_SPIFLASH, KWCPU_WIN_ENABLE),
+	       KW_REG_WIN_CTRL(3));
+	writel(0xF8000000, KW_REG_WIN_BASE(3));
+	writel(0x00000000, KW_REG_WIN_REMAP_LOW(3));
+	writel(0x00000000, KW_REG_WIN_REMAP_HIGH(3));
+
+	writel(KWCPU_WIN_CTRL_DATA(0x80000, KWCPU_TARGET_MEMORY,
+				   KWCPU_ATTR_BOOTROM, KWCPU_WIN_ENABLE),
+	       KW_REG_WIN_CTRL(4));
+	writel(0xFF000000, KW_REG_WIN_BASE(4));
+	writel(0x00000000, KW_REG_WIN_REMAP_LOW(4));
+	writel(0x00000000, KW_REG_WIN_REMAP_HIGH(4));
+
+	writel(KWCPU_WIN_CTRL_DATA(0xb0000, KWCPU_TARGET_MEMORY,
+				   KWCPU_ATTR_SPIFLASH, KWCPU_WIN_DISABLE),
+	       KW_REG_WIN_CTRL(5));
+	writel(0xE8000000, KW_REG_WIN_BASE(5));
+	writel(0x00000000, KW_REG_WIN_REMAP_LOW(5));
+	writel(0x00000000, KW_REG_WIN_REMAP_HIGH(5));
+
+	writel(KWCPU_WIN_CTRL_DATA(0xb0000, KWCPU_TARGET_MEMORY,
+				   KWCPU_ATTR_BOOTROM, KWCPU_WIN_DISABLE),
+	       KW_REG_WIN_CTRL(6));
+	writel(0xF0000000, KW_REG_WIN_BASE(6));
+	writel(0x00000000, KW_REG_WIN_REMAP_LOW(6));
+	writel(0x00000000, KW_REG_WIN_REMAP_HIGH(6));
+
+	writel(KWCPU_WIN_CTRL_DATA(0x0, KWCPU_TARGET_SASRAM, KWCPU_ATTR_SASRAM,
+				   KWCPU_WIN_ENABLE), KW_REG_WIN_CTRL(7));
+	writel(0xFB000000, KW_REG_WIN_BASE(7));
+	writel(0x00000000, KW_REG_WIN_REMAP_LOW(7));
+	writel(0x00000000, KW_REG_WIN_REMAP_HIGH(7));
+
+	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)
+{
+	/* Init GPIOS to default values as per board requirement */
+	writel(gpp0_oe_val, KW_REG_GPP0_DATA_OUT);
+	writel(gpp1_oe_val, KW_REG_GPP1_DATA_OUT);
+	writel(gpp0_oe, KW_REG_GPP0_DATA_OUT_EN);
+	writel(gpp1_oe, KW_REG_GPP1_DATA_OUT_EN);
+}
+
+/*
+ * 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)
+{
+	/* program mpp registers */
+	writel(mpp0_7, KW_REG_MPP_CONTROL0);
+	writel(mpp8_15, KW_REG_MPP_CONTROL1);
+	writel(mpp16_23, KW_REG_MPP_CONTROL2);
+	writel(mpp24_31, KW_REG_MPP_CONTROL3);
+	writel(mpp32_39, KW_REG_MPP_CONTROL4);
+	writel(mpp40_47, KW_REG_MPP_CONTROL5);
+	writel(mpp48_55, KW_REG_MPP_CONTROL6);
+	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:
+		break;
+	}
+	printf("SoC:   Kirkwood %s\n", name);
+	return 0;
+}
+#endif /* CONFIG_DISPLAY_CPUINFO */
+
+static void kw_basic_init(void)
+{
+	u32 reg;
+
+	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((u32) & 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 at OS level
+	 */
+	reg = readl((KW_EGIGA0_BASE + 0x44c));	/* PORT_SERIAL_CONTROL1_REG */
+	reg &= ~(1 << 4);	/* Clear PortReset Bit */
+	writel((u32) & reg, (KW_EGIGA0_BASE + 0x44c));	/* PORT_SERIAL_CONTROL1_REG */
+	reg = readl((KW_EGIGA1_BASE + 0x44c));	/* PORT_SERIAL_CONTROL1_REG */
+	reg &= ~(1 << 4);	/* Clear PortReset Bit */
+	writel((u32) & reg, (KW_EGIGA1_BASE + 0x44c));	/* PORT_SERIAL_CONTROL1_REG */
+#endif
+#ifdef CONFIG_KIRKWOOD_PCIE_INIT
+	/*
+	 * Enable PCI Express Port0
+	 */
+	reg = readl(KW_REG_CPU_CTRL_STAT);
+	reg |= 1 << 0;		/* Set PEX0En Bit */
+	writel((u32) & reg, KW_REG_CPU_CTRL_STAT);
+#endif
+}
+
+/*
+ * SOC specific misc init
+ */
+int arch_misc_init(void)
+{
+	volatile u32 temp;
+
+	kw_basic_init();
+
+	/*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);
+}
diff --git a/cpu/arm926ejs/kirkwood/kwcore.h b/cpu/arm926ejs/kirkwood/kwcore.h
new file mode 100644
index 0000000..fae769d
--- /dev/null
+++ b/cpu/arm926ejs/kirkwood/kwcore.h
@@ -0,0 +1,99 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Prafulla Wadaskar <prafulla at 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 _KWCORE_H
+#define _KWCORE_H
+
+#include <asm/system.h>
+
+#ifndef __ASSEMBLY__
+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();
+}
+
+/*
+ * 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 /* _KWCORE_H */
diff --git a/cpu/arm926ejs/kirkwood/lowlevel_init.S b/cpu/arm926ejs/kirkwood/lowlevel_init.S
new file mode 100644
index 0000000..d81ad05
--- /dev/null
+++ b/cpu/arm926ejs/kirkwood/lowlevel_init.S
@@ -0,0 +1,43 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Prafulla Wadaskar <prafulla at 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/cache.h>
+
+        .globl arch_lowlevel_init
+arch_lowlevel_init:
+        /* Linux expects` the internal registers to be at 0xf1000000 */
+        ldr r1, = KW_OFFSET_REG
+        ldr r3, = KW_REGS_PHY_BASE
+        str r3,[r1]
+
+	/* Enable L2 cache in write through mode */
+	ldr r1, = KW_REG_CPU_L2_CONFIG
+	ldr r2, [r1]
+	orr r2, r2, #0x18
+	str r2, [r1]
+
+	asm_invalidate_l2_cache
+
+        mov pc, lr
diff --git a/cpu/arm926ejs/kirkwood/timer.c b/cpu/arm926ejs/kirkwood/timer.c
new file mode 100644
index 0000000..40b9aa0
--- /dev/null
+++ b/cpu/arm926ejs/kirkwood/timer.c
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ * Prafulla Wadaskar <prafulla at 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>
+
+#define UBOOT_CNTR	0	/* counter to use for uboot timer */
+
+/*
+ * ARM Timers Registers Map
+ */
+#define CNTMR_CTRL_REG			KW_REG_TMR_CTRL
+#define CNTMR_RELOAD_REG(tmrnum)	(KW_REG_TMR_RELOAD + tmrnum*8)
+#define CNTMR_VAL_REG(tmrnum)		(KW_REG_TMR_VAL + tmrnum*8)
+
+/*
+ * ARM Timers Control Register
+ * CPU_TIMERS_CTRL_REG (CTCR)
+ */
+#define TIMER0_NUM			0
+#define TIMER1_NUM			1
+#define WATCHDOG_NUM			2
+
+#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 onto counter\timer */
+	writel(TIMER_LOAD_VAL, CNTMR_RELOAD_REG(UBOOT_CNTR));
+	writel(TIMER_LOAD_VAL, CNTMR_VAL_REG(UBOOT_CNTR));
+
+	/* set the counter to load in the first time */
+	writel(TIMER_LOAD_VAL, CNTMR_VAL_REG(UBOOT_CNTR));
+
+	/* set control for timer \ cunter and enable */
+	/* read control register */
+	cntmrCtrl = readl(CNTMR_CTRL_REG);
+	cntmrCtrl |= CTCR_ARM_TIMER_EN(UBOOT_CNTR);	/* enable cnt\timer */
+	cntmrCtrl |= CTCR_ARM_TIMER_AUTO_EN(UBOOT_CNTR);	/* Auto mode */
+
+	writel(cntmrCtrl, CNTMR_CTRL_REG);
+
+	/* init the timestamp and lastdec value */
+	reset_timer_masked();
+
+	return 0;
+}
diff --git a/cpu/arm926ejs/start.S b/cpu/arm926ejs/start.S
index ed4932a..bdbb7e0 100644
--- a/cpu/arm926ejs/start.S
+++ b/cpu/arm926ejs/start.S
@@ -139,7 +139,7 @@ reset:
 	 * we do sys-critical inits only at reboot,
 	 * not when booting from ram!
 	 */
-#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+#if !defined (CONFIG_SKIP_LOWLEVEL_INIT) || defined (CONFIG_ARCH_LOWLEVEL_INIT)
 	bl	cpu_init_crit
 #endif
 
@@ -201,7 +201,7 @@ _start_armboot:
  *
  *************************************************************************
  */
-#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+#if !defined (CONFIG_SKIP_LOWLEVEL_INIT) || defined (CONFIG_ARCH_LOWLEVEL_INIT)
 cpu_init_crit:
 	/*
 	 * flush v4 I/D caches
@@ -224,7 +224,12 @@ cpu_init_crit:
 	 * Go setup Memory and board specific bits prior to relocation.
 	 */
 	mov	ip, lr		/* perserve link reg across call */
+#ifdef CONFIG_ARCH_LOWLEVEL_INIT
+	bl	arch_lowlevel_init	/* go setup arch specific init */
+#endif /* CONFIG_ARCH_LOWLEVEL_INIT */
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
 	bl	lowlevel_init	/* go setup pll,mux,memory */
+#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
 	mov	lr, ip		/* restore link */
 	mov	pc, lr		/* back to my caller */
 #endif /* CONFIG_SKIP_LOWLEVEL_INIT */
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index bb99a34..8003447 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -28,6 +28,7 @@ LIB	:= $(obj)libserial.a
 COBJS-$(CONFIG_ARM_DCC) += arm_dcc.o
 COBJS-$(CONFIG_AT91RM9200_USART) += at91rm9200_usart.o
 COBJS-$(CONFIG_ATMEL_USART) += atmel_usart.o
+COBJS-$(CONFIG_KIRKWOOD_SERIAL) += kirkwood_serial.o
 COBJS-$(CONFIG_MCFUART) += mcfuart.o
 COBJS-$(CONFIG_NS9750_UART) += ns9750_serial.o
 COBJS-$(CONFIG_SYS_NS16550) += ns16550.o
diff --git a/drivers/serial/kirkwood_serial.c b/drivers/serial/kirkwood_serial.c
new file mode 100644
index 0000000..2f79d59
--- /dev/null
+++ b/drivers/serial/kirkwood_serial.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ * Prafulla Wadaskar <prafulla at 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/serial.h>
+
+/* static variables */
+#if defined (CONFIG_CONS_INDEX)	/* comes from board config */
+#if (CONFIG_CONS_INDEX == 0 )
+static volatile struct kw_uart_port *p_uart_port =
+    (void *)KW_REGISTER(KW_UART0_BASE);
+#elif (CONFIG_CONS_INDEX == 1 )
+static volatile struct kw_uart_port *p_uart_port =
+    (void *)KW_REGISTER(KW_UART1_BASE);
+#endif
+#else
+#error CONFIG_CONS_INDEX not defined correctly
+#endif
+
+#define CONFIG_KW_UART_PORTS	{ (void *)KW_UART0_BASE, \
+				  (void *)KW_UART1_BASE }
+
+/*
+ * Serial init banner is kept simplest one
+ * if required can be created good one
+ */
+int serial_init(void)
+{
+	serial_setbrg();
+	printf
+	    ("\n*************************************************************");
+	return (0);
+}
+
+static void kw_uart_putc(u8 c)
+{
+	while ((p_uart_port->lsr & LSR_THRE) == 0) ;
+	p_uart_port->thr = c;
+	return;
+}
+
+void serial_putc(const char c)
+{
+	if (c == '\n')
+		kw_uart_putc('\r');
+
+	kw_uart_putc(c);
+}
+
+int serial_getc(void)
+{
+	while ((p_uart_port->lsr & LSR_DR) == 0) ;
+	return (p_uart_port->rbr);
+}
+
+int serial_tstc(void)
+{
+	return ((p_uart_port->lsr & LSR_DR) != 0);
+}
+
+void serial_setbrg(void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	int clock_divisor = (CONFIG_SYS_TCLK / 16) / gd->baudrate;
+
+	p_uart_port->ier = 0x00;
+	p_uart_port->lcr = LCR_DIVL_EN;	/* Access baud rate */
+	p_uart_port->dll = clock_divisor & 0xff;	/* 9600 baud */
+	p_uart_port->dlm = (clock_divisor >> 8) & 0xff;
+	p_uart_port->lcr = LCR_8N1;	/* 8 data, 1 stop, no parity */
+	/* Clear & enable FIFOs */
+	p_uart_port->fcr = FCR_FIFO_EN | FCR_RXSR | FCR_TXSR;
+	return;
+}
+
+void serial_puts(const char *s)
+{
+	while (*s) {
+		serial_putc(*s++);
+	}
+}
+
+#ifdef CONFIG_CMD_KGDB
+void kgdb_serial_init(void)
+{
+}
+
+void putDebugChar(int c)
+{
+	serial_putc(c);
+}
+
+void putDebugStr(const char *str)
+{
+	serial_puts(str);
+}
+
+int getDebugChar(void)
+{
+	return serial_getc();
+}
+
+void kgdb_interruptible(int yes)
+{
+	return;
+}
+#endif /* CONFIG_CMD_KGDB */
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..f7a70ce
--- /dev/null
+++ b/drivers/spi/kirkwood_spi.c
@@ -0,0 +1,167 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Prafulla Wadaskar <prafulla at 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/spi.h>
+
+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;
+
+	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(0x00000002, KW_REG_SPI_CTRL);
+	/* program spi clock prescaller using max_hz */
+	data = ((CONFIG_SYS_TCLK / 2) / max_hz) & 0x0000000f;
+	debug("data = 0x%08x \n", data);
+	writel(0x00000210 | data, KW_REG_SPI_CONFIG);
+	writel(0x00000001, KW_REG_SPI_IRQ_CAUSE);
+	writel(0x00000000, KW_REG_SPI_IRQ_MASK);
+
+	/* program mpp registers to select  SPI_CSn */
+	if (cs)
+		writel((readl(KW_REG_MPP_CONTROL0) & 0x0fffffff) |
+		       0x20000000, KW_REG_MPP_CONTROL0);
+	else
+		writel((readl(KW_REG_MPP_CONTROL0) & 0xfffffff0) |
+		       0x00000002, KW_REG_MPP_CONTROL0);
+
+	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(KW_REG_SPI_CTRL) | 1, KW_REG_SPI_CTRL);
+}
+
+void spi_cs_deactivate(struct spi_slave *slave)
+{
+	writel(readl(KW_REG_SPI_CTRL) & ~1, KW_REG_SPI_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
+	 */
+	while (bitlen > 4) {
+		debug("loopstart bitlen %d\n", bitlen);
+		tmpdout = 0;
+		/*1 byte xfer mode */
+		writel(readl(KW_REG_SPI_CONFIG) & ~(1 << 5), KW_REG_SPI_CONFIG);
+		/* Shift data so it's msb-justified */
+		if (dout)
+			tmpdout = *(u32 *) dout & 0x0ff;
+
+		writel(0x0, KW_REG_SPI_IRQ_CAUSE);	/* clear bit */
+		writel(tmpdout, KW_REG_SPI_DATA_OUT);	/* 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 < KW_SPI_TIMEOUT; ++tm) {
+			if (readl(KW_REG_SPI_IRQ_CAUSE)) {
+				isread = 1;
+				tmpdin = readl(KW_REG_SPI_DATA_IN);
+				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 >= KW_SPI_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/kirkwood.h b/include/asm-arm/arch-kirkwood/kirkwood.h
new file mode 100644
index 0000000..b94c6cd
--- /dev/null
+++ b/include/asm-arm/arch-kirkwood/kirkwood.h
@@ -0,0 +1,118 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Prafulla Wadaskar <prafulla at 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)
+#if defined (CONFIG_KIRKWOOD)
+#include <../cpu/arm926ejs/kirkwood/kwcore.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))	/* UArt 0 */
+#define KW_UART1_BASE			(KW_REGISTER(0x13000))	/* UArt 1 */
+
+/* Controler environment registers offsets */
+#define KW_REG_MPP_CONTROL0		(KW_REGISTER(0x10000))
+#define KW_REG_MPP_CONTROL1		(KW_REGISTER(0x10004))
+#define KW_REG_MPP_CONTROL2		(KW_REGISTER(0x10008))
+#define KW_REG_MPP_CONTROL3		(KW_REGISTER(0x1000C))
+#define KW_REG_MPP_CONTROL4		(KW_REGISTER(0x10010))
+#define KW_REG_MPP_CONTROL5		(KW_REGISTER(0x10014))
+#define KW_REG_MPP_CONTROL6		(KW_REGISTER(0x10018))
+#define KW_REG_MPP_SMPL_AT_RST		(KW_REGISTER(0x10030))
+#define KW_REG_DEVICE_ID		(KW_REGISTER(0x10034))
+#define KW_REG_MPP_OUT_DRV_REG		(KW_REGISTER(0x100E0))
+
+#define KW_REG_GPP0_DATA_OUT		(KW_REGISTER(0x10100))
+#define KW_REG_GPP0_DATA_OUT_EN		(KW_REGISTER(0x10104))
+#define KW_REG_GPP0_BLINK_EN		(KW_REGISTER(0x10108))
+#define KW_REG_GPP0_DATA_IN_POL		(KW_REGISTER(0x1010C))
+#define KW_REG_GPP0_DATA_IN		(KW_REGISTER(0x10110))
+#define KW_REG_GPP0_INT_CAUSE		(KW_REGISTER(0x10114))
+#define KW_REG_GPP0_INT_MASK		(KW_REGISTER(0x10118))
+#define KW_REG_GPP0_INT_LVL		(KW_REGISTER(0x1011c))
+
+#define KW_REG_GPP1_DATA_OUT		(KW_REGISTER(0x10140))
+#define KW_REG_GPP1_DATA_OUT_EN		(KW_REGISTER(0x10144))
+#define KW_REG_GPP1_BLINK_EN		(KW_REGISTER(0x10148))
+#define KW_REG_GPP1_DATA_IN_POL		(KW_REGISTER(0x1014C))
+#define KW_REG_GPP1_DATA_IN		(KW_REGISTER(0x10150))
+#define KW_REG_GPP1_INT_CAUSE		(KW_REGISTER(0x10154))
+#define KW_REG_GPP1_INT_MASK		(KW_REGISTER(0x10158))
+#define KW_REG_GPP1_INT_LVL		(KW_REGISTER(0x1015c))
+
+#define KW_REG_NAND_READ_PARAM		(KW_REGISTER(0x10418))
+#define KW_REG_NAND_WRITE_PARAM		(KW_REGISTER(0x1041c))
+#define KW_REG_NAND_CTRL		(KW_REGISTER(0x10470))
+
+#define KW_REG_WIN_CTRL(x)		(KW_REGISTER((0x20000 + (x * 0x10))))
+#define KW_REG_WIN_BASE(x)		(KW_REGISTER((0x20004 + (x * 0x10))))
+#define KW_REG_WIN_REMAP_LOW(x)		(KW_REGISTER((0x20008 + (x * 0x10))))
+#define KW_REG_WIN_REMAP_HIGH(x)	(KW_REGISTER((0x2000c + (x * 0x10))))
+
+#define KW_REG_CPU_CONFIG		(KW_REGISTER(0x20100))
+#define KW_REG_CPU_CTRL_STAT		(KW_REGISTER(0x20104))
+#define KW_REG_CPU_RSTOUTN_MASK		(KW_REGISTER(0x20108))
+#define KW_REG_CPU_SYS_SOFT_RST		(KW_REGISTER(0x2010C))
+#define KW_REG_CPU_AHB_MBUS_CAUSE_INT	(KW_REGISTER(0x20110))
+#define KW_REG_CPU_AHB_MBUS_MASK_INT	(KW_REGISTER(0x20114))
+#define KW_REG_CPU_FTDLL_CONFIG		(KW_REGISTER(0x20120))
+#define KW_REG_CPU_L2_CONFIG		(KW_REGISTER(0x20128))
+#define KW_REG_L2_RAM_TIMING0		(KW_REGISTER(0x20134))
+#define KW_REG_L2_RAM_TIMING1		(KW_REGISTER(0x20138))
+
+#define KW_REG_TMR_CTRL			(KW_REGISTER(0x20300))
+#define KW_REG_TMR_RELOAD		(KW_REGISTER(0x20310))
+#define KW_REG_TMR_VAL			(KW_REGISTER(0x20314))
+
+#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 "kw88f6281.h"
+#endif /* CONFIG_KW88F6281 */
+#if defined (CONFIG_KW88F6192)
+#include "kw88f6192.h"
+#endif /* CONFIG_KW88F6192 */
+#endif /* CONFIG_KIRKWOOD */
+#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..000fc16
--- /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 at 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..270d931
--- /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 at 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/serial.h b/include/asm-arm/arch-kirkwood/serial.h
new file mode 100644
index 0000000..59fe56f
--- /dev/null
+++ b/include/asm-arm/arch-kirkwood/serial.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ * Prafulla Wadaskar <prafulla at 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 __KW_SERIAL_H__
+#define __KW_SERIAL_H__
+
+/* registers feilds */
+#define FCR_FIFO_EN		1<<0	/* fifo enable */
+#define FCR_RXSR		1<<1	/* receiver soft reset */
+#define FCR_TXSR		1<<2	/* transmitter soft reset */
+#define MCR_RTS		1<<1	/* ready to send */
+
+#define LCR_WLS_OFFS		0
+#define LCR_WLS_MASK		0x3 << LCR_WLS_OFFS	/* character length mask  */
+#define LCR_WLS_5		0x0 << LCR_WLS_OFFS	/* 5 bit character length */
+#define LCR_WLS_6		0x1 << LCR_WLS_OFFS	/* 6 bit character length */
+#define LCR_WLS_7		0x2 << LCR_WLS_OFFS	/* 7 bit character length */
+#define LCR_WLS_8		0x3 << LCR_WLS_OFFS	/* 8 bit character length */
+#define LCR_STP_OFFS		2
+#define LCR_1_STB		0x0 << LCR_STP_OFFS	/* Number of stop Bits */
+#define LCR_2_STB		0x1 << LCR_STP_OFFS	/* Number of stop Bits */
+#define LCR_PEN		0x8	/* Parity enable */
+#define LCR_PS_OFFS		4
+#define LCR_EPS		0x1 << LCR_PS_OFFS	/* Even Parity Select */
+#define LCR_OPS		0x0 << LCR_PS_OFFS	/* Odd Parity Select */
+#define LCR_SBRK_OFFS		0x6
+#define LCR_SBRK		0x1 << LCR_SBRK_OFFS	/* Set Break */
+#define LCR_DIVL_OFFS		7
+#define LCR_DIVL_EN		0x1 << LCR_DIVL_OFFS	/* Divisior latch enable */
+
+#define LSR_DR			1<<0	/* Data ready */
+#define LSR_OE			1<<1	/* Overrun */
+#define LSR_PE			1<<2	/* Parity error */
+#define LSR_FE			1<<3	/* Framing error */
+#define LSR_BI			1<<4	/* Break */
+#define LSR_THRE		1<<5	/* Xmit holding register empty */
+#define LSR_TEMT		1<<6	/* Xmitter empty */
+#define LSR_ERR		1<<7	/* Error */
+
+/* useful defaults for LCR*/
+#define LCR_8N1		LCR_WLS_8 | LCR_1_STB
+
+/* This structure describes the registers offsets for one UART port/channel */
+struct kw_uart_port {
+	u8 rbr;			/* 0 = 0-3 */
+	u8 pad1[3];
+	u8 ier;			/* 1 = 4-7 */
+	u8 pad2[3];
+	u8 fcr;			/* 2 = 8-b */
+	u8 pad3[3];
+	u8 lcr;			/* 3 = c-f */
+	u8 pad4[3];
+	u8 mcr;			/* 4 = 10-13 */
+	u8 pad5[3];
+	u8 lsr;			/* 5 = 14-17 */
+	u8 pad6[3];
+	u8 msr;			/* 6 =18-1b */
+	u8 pad7[3];
+	u8 scr;			/* 7 =1c-1f */
+	u8 pad8[3];
+};
+
+/* aliases - for registers which has the same offsets */
+#define thr rbr
+#define iir fcr
+#define dll rbr
+#define dlm ier
+
+#endif /* __KW_SERIAL_H__ */
diff --git a/include/asm-arm/arch-kirkwood/spi.h b/include/asm-arm/arch-kirkwood/spi.h
new file mode 100644
index 0000000..0fd9131
--- /dev/null
+++ b/include/asm-arm/arch-kirkwood/spi.h
@@ -0,0 +1,39 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Prafulla Wadaskar <prafulla at 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 */
+#define KW_REG_SPI_CTRL		KW_REGISTER(0x10600)
+#define KW_REG_SPI_CONFIG	KW_REGISTER(0x10604)
+#define KW_REG_SPI_DATA_OUT	KW_REGISTER(0x10608)
+#define KW_REG_SPI_DATA_IN	KW_REGISTER(0x1060c)
+#define KW_REG_SPI_IRQ_CAUSE	KW_REGISTER(0x10610)
+#define KW_REG_SPI_IRQ_MASK	KW_REGISTER(0x10614)
+
+#define KW_SPI_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..07eef4c
--- /dev/null
+++ b/include/asm-arm/cache.h
@@ -0,0 +1,49 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Prafulla Wadaskar <prafulla at 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
+
+#ifndef __ASSEMBLY__
+#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();
+}
+#else
+.macro asm_invalidate_l2_cache
+	mov	r0, #0
+	mcr	p15, 1, r0, c15, c11, 0
+.endm
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_CACHE_H */
diff --git a/include/asm-arm/config.h b/include/asm-arm/config.h
index 049c44e..5d52f15 100644
--- a/include/asm-arm/config.h
+++ b/include/asm-arm/config.h
@@ -21,4 +21,8 @@
 #ifndef _ASM_CONFIG_H_
 #define _ASM_CONFIG_H_
 
+#if defined (CONFIG_KIRKWOOD)
+#include <asm-arm/arch-kirkwood/kirkwood.h>
+#endif /* CONFIG_KIRKWOOD */
+
 #endif
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 3dfaec0..7f7c28d 100644
--- a/lib_arm/board.c
+++ b/lib_arm/board.c
@@ -390,6 +390,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



More information about the U-Boot mailing list