* [U-Boot] [PATCH v2] Marvell Kirkwood family SOC support
@ 2009-04-08 12:03 Prafulla Wadaskar
2009-04-14 17:26 ` Prafulla Wadaskar
2009-04-17 9:22 ` Jean-Christophe PLAGNIOL-VILLARD
0 siblings, 2 replies; 11+ messages in thread
From: Prafulla Wadaskar @ 2009-04-08 12:03 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-Z0 define CONFIG_KW88F6281_Z0
2) 88F6281-A0 define CONFIG_KW88F6281_A0
3) 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>
---
Changelog:
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
board/Marvell/include/core.h | 4 +
cpu/arm926ejs/kirkwood/Makefile | 50 ++++++
cpu/arm926ejs/kirkwood/config.mk | 25 +++
cpu/arm926ejs/kirkwood/dram.c | 55 +++++++
cpu/arm926ejs/kirkwood/kwcore.c | 250 +++++++++++++++++++++++++++++
cpu/arm926ejs/kirkwood/kwcore.h | 47 ++++++
cpu/arm926ejs/kirkwood/lowlevel_init.S | 183 +++++++++++++++++++++
cpu/arm926ejs/kirkwood/timer.c | 165 +++++++++++++++++++
drivers/serial/Makefile | 1 +
drivers/serial/kirkwood_serial.c | 187 +++++++++++++++++++++
drivers/spi/Makefile | 1 +
drivers/spi/kirkwood_spi.c | 199 +++++++++++++++++++++++
include/asm-arm/arch-kirkwood/kirkwood.h | 142 ++++++++++++++++
include/asm-arm/arch-kirkwood/kw88f6192.h | 37 +++++
include/asm-arm/arch-kirkwood/kw88f6281.h | 43 +++++
include/asm-arm/config.h | 4 +
16 files changed, 1393 insertions(+), 0 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
diff --git a/board/Marvell/include/core.h b/board/Marvell/include/core.h
index c413439..ecc4682 100644
--- a/board/Marvell/include/core.h
+++ b/board/Marvell/include/core.h
@@ -12,9 +12,11 @@ space). The macros take care of Big/Little endian conversions.
#ifndef __INCcoreh
#define __INCcoreh
+#ifndef CONFIG_KIRKWOOD
#include "mv_gen_reg.h"
extern unsigned int INTERNAL_REG_BASE_ADDR;
+#endif /* CONFIG_KIRKWOOD */
/****************************************/
/* GENERAL Definitions */
@@ -91,10 +93,12 @@ extern unsigned int INTERNAL_REG_BASE_ADDR;
#define _1G 0x40000000
#define _2G 0x80000000
+#ifndef __ASSEMBLY__
#ifndef BOOL_WAS_DEFINED
#define BOOL_WAS_DEFINED
typedef enum _bool{false,true} bool;
#endif
+#endif
/* Little to Big endian conversion macros */
diff --git a/cpu/arm926ejs/kirkwood/Makefile b/cpu/arm926ejs/kirkwood/Makefile
new file mode 100644
index 0000000..c917f0d
--- /dev/null
+++ b/cpu/arm926ejs/kirkwood/Makefile
@@ -0,0 +1,50 @@
+#
+# (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 += 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@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..80e2b13
--- /dev/null
+++ b/cpu/arm926ejs/kirkwood/dram.c
@@ -0,0 +1,55 @@
+/*
+ * (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>
+
+/*
+ * kw_sdram_bar - reads SDRAM Base Address Register
+ */
+u32 kw_sdram_bar(MEMORY_BANK bank)
+{
+ u32 result = 0;
+ u32 enable = (0x01 & KW_REG_READ((0x1504 + bank * 8)));
+
+ if ((!enable) || (bank > BANK3))
+ return 0;
+
+ result = KW_REG_READ((0x1500 + bank * 8));
+ return result;
+}
+
+/*
+ * kw_sdram_bs - reads SDRAM Bank size
+ */
+u32 kw_sdram_bs(MEMORY_BANK bank)
+{
+ u32 result = 0;
+ u32 enable = (0x01 & KW_REG_READ((0x1504 + bank * 8)));
+
+ if ((!enable) || (bank > BANK3))
+ return 0;
+ result = (0xff000000 & KW_REG_READ((0x1504 + bank * 8)));
+ result += 0x01000000;
+ return result;
+}
diff --git a/cpu/arm926ejs/kirkwood/kwcore.c b/cpu/arm926ejs/kirkwood/kwcore.c
new file mode 100644
index 0000000..2e887d5
--- /dev/null
+++ b/cpu/arm926ejs/kirkwood/kwcore.c
@@ -0,0 +1,250 @@
+/*
+ * (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 <u-boot/md5.h>
+
+void reset_cpu(unsigned long ignored)
+{
+ KW_REG_BITS_SET(KW_REG_CPU_RSTOUTN_MASK, BIT2);
+ KW_REG_BITS_SET(KW_REG_CPU_SYS_SOFT_RST, BIT0);
+ 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];
+
+#if defined (CONFIG_KW88F6281_Z0)
+ KW_REG_BITS_SET(0x1478, BIT7);
+#elif defined (CONFIG_KW88F6281_A0) || defined (CONFIG_KW88F6192_A0)
+ /*
+ * in case of 88F6281/88F6192 A0,
+ * BIT7 need to reset to generate random values in 0x1470
+ */
+ KW_REG_BITS_RESET(0x1478, BIT7);
+#else
+#error Undefined SOC Revision
+#endif
+ for (i = 0; i < 16; i++) {
+ inbuf[i] = KW_REG_READ(0x1470);
+ }
+ md5((u8 *) inbuf, 64, outbuf);
+ return outbuf[outbuf[7] % 0x0f];
+}
+
+/*
+ * kw_window_ctrl_reg_init - Mbus-L to Mbus Bridge Registers init.
+ */
+int kw_window_ctrl_reg_init(void)
+{
+ KW_REG_WRITE(KW_REG_WIN_CTRL(0), 0x0fffe841);
+ KW_REG_WRITE(KW_REG_WIN_BASE(0), 0x90000000);
+ KW_REG_WRITE(KW_REG_WIN_REMAP_LOW(0), 0x90000000);
+ KW_REG_WRITE(KW_REG_WIN_REMAP_HIGH(0), 0x00000000);
+
+ KW_REG_WRITE(KW_REG_WIN_CTRL(1), 0x007f2f11);
+ KW_REG_WRITE(KW_REG_WIN_BASE(1), 0xF9000000);
+ KW_REG_WRITE(KW_REG_WIN_REMAP_LOW(1), 0xF9000000);
+ KW_REG_WRITE(KW_REG_WIN_REMAP_HIGH(1), 0x00000000);
+
+ KW_REG_WRITE(KW_REG_WIN_CTRL(2), 0x00ffe041);
+ KW_REG_WRITE(KW_REG_WIN_BASE(2), 0xF0000000);
+ KW_REG_WRITE(KW_REG_WIN_REMAP_LOW(2), 0xC0000000);
+ KW_REG_WRITE(KW_REG_WIN_REMAP_HIGH(2), 0x00000000);
+
+ KW_REG_WRITE(KW_REG_WIN_CTRL(3), 0x00ff1e11);
+ KW_REG_WRITE(KW_REG_WIN_BASE(3), 0xF8000000);
+ KW_REG_WRITE(KW_REG_WIN_REMAP_LOW(3), 0x00000000);
+ KW_REG_WRITE(KW_REG_WIN_REMAP_HIGH(3), 0x00000000);
+
+ KW_REG_WRITE(KW_REG_WIN_CTRL(4), 0x00ff1d11);
+ KW_REG_WRITE(KW_REG_WIN_BASE(4), 0xFF000000);
+ KW_REG_WRITE(KW_REG_WIN_REMAP_LOW(4), 0x00000000);
+ KW_REG_WRITE(KW_REG_WIN_REMAP_HIGH(4), 0x00000000);
+
+ KW_REG_WRITE(KW_REG_WIN_CTRL(5), 0x07ff1e10);
+ KW_REG_WRITE(KW_REG_WIN_BASE(5), 0xE8000000);
+ KW_REG_WRITE(KW_REG_WIN_REMAP_LOW(5), 0x00000000);
+ KW_REG_WRITE(KW_REG_WIN_REMAP_HIGH(5), 0x00000000);
+
+ KW_REG_WRITE(KW_REG_WIN_CTRL(6), 0x07ff1d10);
+ KW_REG_WRITE(KW_REG_WIN_BASE(6), 0xF0000000);
+ KW_REG_WRITE(KW_REG_WIN_REMAP_LOW(6), 0x00000000);
+ KW_REG_WRITE(KW_REG_WIN_REMAP_HIGH(6), 0x00000000);
+
+ KW_REG_WRITE(KW_REG_WIN_CTRL(7), 0x00000131);
+ KW_REG_WRITE(KW_REG_WIN_BASE(7), 0xFB000000);
+ KW_REG_WRITE(KW_REG_WIN_REMAP_LOW(7), 0x00000000);
+ KW_REG_WRITE(KW_REG_WIN_REMAP_HIGH(7), 0x00000000);
+
+ return KW_OK;
+}
+
+/*
+ * kw_gpio_init - Init gpios for default values
+ */
+void kw_gpio_init(u32 gpp0_oe_val, u32 gpp1_oe_val, u32 gpp0_oe, u32 gpp1_oe)
+{
+ /* Init GPIOS to default values as per board requirement */
+ KW_REG_WRITE(KW_REG_GPP0_DATA_OUT, gpp0_oe_val);
+ KW_REG_WRITE(KW_REG_GPP1_DATA_OUT, gpp1_oe_val);
+ KW_REG_WRITE(KW_REG_GPP0_DATA_OUT_EN, gpp0_oe);
+ KW_REG_WRITE(KW_REG_GPP1_DATA_OUT_EN, gpp1_oe);
+}
+
+/*
+ * kw_mpp_control_init - initialize mpp for board specific functionality
+ */
+int kw_mpp_control_init(u32 mpp0_7, u32 mpp8_15, u32 mpp16_23, u32 mpp24_31,
+ u32 mpp32_39, u32 mpp40_47, u32 mpp48_55)
+{
+ /* program mpp registers */
+ KW_REG_WRITE(KW_REG_MPP_CONTROL0, mpp0_7);
+ KW_REG_WRITE(KW_REG_MPP_CONTROL1, mpp8_15);
+ KW_REG_WRITE(KW_REG_MPP_CONTROL2, mpp16_23);
+ KW_REG_WRITE(KW_REG_MPP_CONTROL3, mpp24_31);
+ KW_REG_WRITE(KW_REG_MPP_CONTROL4, mpp32_39);
+ KW_REG_WRITE(KW_REG_MPP_CONTROL5, mpp40_47);
+ KW_REG_WRITE(KW_REG_MPP_CONTROL6, mpp48_55);
+ return KW_OK;
+}
+
+/*
+ * kw_misc_init_r - SOC specific misc init (mainly cache initialization)
+ */
+int kw_misc_init_r(void)
+{
+ char *env;
+ volatile unsigned int temp;
+
+ /*CPU streaming & write allocate */
+ env = getenv("enaWrAllo");
+ if (env && ((strcmp(env, "yes") == 0) || (strcmp(env, "Yes") == 0))) {
+ __asm__ __volatile__("mrc p15, 1, %0, c15, c1, 0":"=r"(temp));
+ temp |= BIT28;
+ __asm__ __volatile__("mcr p15, 1, %0, c15, c1, 0"::"r"(temp));
+
+ } else {
+ __asm__ __volatile__("mrc p15, 1, %0, c15, c1, 0":"=r"(temp));
+ temp &= ~BIT28;
+ __asm__ __volatile__("mcr p15, 1, %0, c15, c1, 0"::"r"(temp));
+ }
+
+ env = getenv("enaCpuStream");
+ if (!env || (strcmp(env, "no") == 0) || (strcmp(env, "No") == 0)) {
+ __asm__ __volatile__("mrc p15, 1, %0, c15, c1, 0":"=r"(temp));
+ temp &= ~BIT29;
+ __asm__ __volatile__("mcr p15, 1, %0, c15, c1, 0"::"r"(temp));
+ } else {
+ __asm__ __volatile__("mrc p15, 1, %0, c15, c1, 0":"=r"(temp));
+ temp |= BIT29;
+ __asm__ __volatile__("mcr p15, 1, %0, c15, c1, 0"::"r"(temp));
+ }
+
+ /* Verify write allocate and streaming */
+ printf("\n");
+ __asm__ __volatile__("mrc p15, 1, %0, c15, c1, 0":"=r"(temp));
+ if (temp & BIT29)
+ printf("Streaming enabled\n");
+ else
+ printf("Streaming disabled\n");
+ if (temp & BIT28)
+ printf("Write allocate enabled\n");
+ else
+ printf("Write allocate disabled\n");
+
+ /* DCache Pref */
+ env = getenv("enaDCPref");
+ if (env && ((strcmp(env, "yes") == 0) || (strcmp(env, "Yes") == 0))) {
+ temp = KW_REG_READ(KW_REG_CPU_CONFIG);
+ temp |= BIT17; /* Set CCR_DCACH_PREF_BUF_ENABLE */
+ KW_REG_WRITE(KW_REG_CPU_CONFIG, temp);
+ }
+
+ if (env && ((strcmp(env, "no") == 0) || (strcmp(env, "No") == 0))) {
+ temp = KW_REG_READ(KW_REG_CPU_CONFIG);
+ temp &= ~BIT17; /* Reset CCR_DCACH_PREF_BUF_ENABLE */
+ KW_REG_WRITE(KW_REG_CPU_CONFIG, temp);
+ }
+
+ /* ICache Pref */
+ env = getenv("enaICPref");
+ if (env && ((strcmp(env, "yes") == 0) || (strcmp(env, "Yes") == 0))) {
+ temp = KW_REG_READ(KW_REG_CPU_CONFIG);
+ temp |= BIT16; /* Set CCR_ICACH_PREF_BUF_ENABLE */
+ KW_REG_WRITE(KW_REG_CPU_CONFIG, temp);
+ }
+
+ if (env && ((strcmp(env, "no") == 0) || (strcmp(env, "No") == 0))) {
+ temp = KW_REG_READ(KW_REG_CPU_CONFIG);
+ temp &= ~BIT16; /* Reset CCR_ICACH_PREF_BUF_ENABLE */
+ KW_REG_WRITE(KW_REG_CPU_CONFIG, temp);
+ }
+ /* Set L2C WT mode - Set bit 4 */
+ temp = KW_REG_READ(KW_REG_CPU_L2_CONFIG);
+ env = getenv("setL2CacheWT");
+ if (!env || ((strcmp(env, "yes") == 0) || (strcmp(env, "Yes") == 0))) {
+ temp |= BIT4;
+ } else
+ temp &= ~BIT4;
+ KW_REG_WRITE(KW_REG_CPU_L2_CONFIG, temp);
+
+ /* L2Cache settings */
+ asm("mrc p15, 1, %0, c15, c1, 0":"=r"(temp));
+
+ /* Disable L2C pre fetch - Set bit 24 */
+ env = getenv("disL2Prefetch");
+ if (env && ((strcmp(env, "no") == 0) || (strcmp(env, "No") == 0)))
+ temp &= ~BIT24;
+ else
+ temp |= BIT24;
+
+ /* enable L2C - Set bit 22 */
+ env = getenv("disL2Cache");
+ if (!env || ((strcmp(env, "no") == 0) || (strcmp(env, "No") == 0)))
+ temp |= BIT22;
+ else
+ temp &= ~BIT22;
+
+ asm("mcr p15, 1, %0, c15, c1, 0": :"r"(temp));
+
+ /* Enable i cache */
+ asm("mrc p15, 0, %0, c1, c0, 0":"=r"(temp));
+ temp |= BIT12;
+ asm("mcr p15, 0, %0, c1, c0, 0": :"r"(temp));
+ /* Change reset vector to address 0x0 */
+ asm("mrc p15, 0, %0, c1, c0, 0":"=r"(temp));
+ temp &= ~BIT13;
+ asm("mcr p15, 0, %0, c1, c0, 0": :"r"(temp));
+
+ return (0);
+}
+
diff --git a/cpu/arm926ejs/kirkwood/kwcore.h b/cpu/arm926ejs/kirkwood/kwcore.h
new file mode 100644
index 0000000..8d2a8cc
--- /dev/null
+++ b/cpu/arm926ejs/kirkwood/kwcore.h
@@ -0,0 +1,47 @@
+/*
+ * (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 _KWCORE_H
+#define _KWCORE_H
+
+/*
+ * functions
+ */
+#ifndef __ASSEMBLY__
+void reset_cpu(unsigned long ignored);
+unsigned char get_random_hex(void);
+typedef enum _memory_bank { BANK0, BANK1, BANK2, BANK3 } MEMORY_BANK;
+unsigned int kw_sdram_bar(MEMORY_BANK bank);
+unsigned int kw_sdram_bs(MEMORY_BANK bank);
+int kw_window_ctrl_reg_init(void);
+void kw_gpio_init(unsigned int gpp0_oe_val, unsigned int gpp1_oe_val,
+ unsigned int gpp0_oe, unsigned int gpp1_oe);
+int kw_mpp_control_init(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);
+int kw_misc_init_r(void);
+#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..169e58b
--- /dev/null
+++ b/cpu/arm926ejs/kirkwood/lowlevel_init.S
@@ -0,0 +1,183 @@
+/*
+ * (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>
+
+#define CCR_CPU_2_MBUSL_TICK_DRV_OFFS 8
+#define CCR_CPU_2_MBUSL_TICK_DRV_MASK (0xF << CCR_CPU_2_MBUSL_TICK_DRV_OFFS)
+#define CCR_CPU_2_MBUSL_TICK_SMPL_OFFS 12
+#define CCR_CPU_2_MBUSL_TICK_SMPL_MASK (0xF << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS)
+
+#define MSAR_DDRCLCK_RTIO_OFFS 5
+#define MSAR_DDRCLCK_RTIO_MASK (0xF << MSAR_DDRCLCK_RTIO_OFFS)
+
+/* Ratio options for CPU to DDR for 6281/6192/6180 */
+#define CPU_2_DDR_CLK_1x2 2
+#define CPU_2_DDR_CLK_1x3 4
+#define CPU_2_DDR_CLK_1x4 6
+
+/* Default values for CPU to Mbus-L DDR Interface Tick Driver and */
+/* CPU to Mbus-L Tick Sample fields in CPU config register */
+
+#define TICK_DRV_1x1 0
+#define TICK_DRV_1x2 0
+#define TICK_DRV_1x3 1
+#define TICK_DRV_1x4 2
+#define TICK_SMPL_1x1 0
+#define TICK_SMPL_1x2 1
+#define TICK_SMPL_1x3 2
+#define TICK_SMPL_1x4 3
+#define CPU_2_MBUSL_DDR_CLK_1x2 \
+ ((TICK_DRV_1x2 << CCR_CPU_2_MBUSL_TICK_DRV_OFFS) | \
+ (TICK_SMPL_1x2 << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS))
+#define CPU_2_MBUSL_DDR_CLK_1x3 \
+ ((TICK_DRV_1x3 << CCR_CPU_2_MBUSL_TICK_DRV_OFFS) | \
+ (TICK_SMPL_1x3 << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS))
+#define CPU_2_MBUSL_DDR_CLK_1x4 \
+ ((TICK_DRV_1x4 << CCR_CPU_2_MBUSL_TICK_DRV_OFFS) | \
+ (TICK_SMPL_1x4 << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS))
+
+
+ .globl kw_cpu_if_pre_init
+kw_cpu_if_pre_init:
+
+ mov r11, LR /* Save link register */
+
+ /*
+ * Configures the I/O voltage of the pads connected to Egigabit
+ * Ethernet interface to 1.8V
+ * By defult it is set to 3.3V
+ */
+#ifdef CONFIG_KIRKWOOD_RGMII_PAD_1V8
+ KW_REG_READ_ASM (r7, r5, KW_REG_MPP_OUT_DRV_REG)
+ ldr r5, =BIT7
+ orr r7, r7, r5 /* Set RGMII PADS Voltage to 1.8V */
+ KW_REG_WRITE_ASM (r7, r5, KW_REG_MPP_OUT_DRV_REG)
+#endif
+ /*
+ * 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
+ */
+#ifdef CONFIG_KIRKWOOD_EGIGA_INIT
+ KW_REG_READ_ASM (r7, r5, KW_ETH_PORT_SERIAL_CONTROL1_REG(0))
+ ldr r5, =~(BIT4)
+ and r7, r7, r5 /* Clear PortReset Bit */
+ KW_REG_WRITE_ASM (r7, r5, KW_ETH_PORT_SERIAL_CONTROL1_REG(0))
+
+ KW_REG_READ_ASM (r7, r5, KW_ETH_PORT_SERIAL_CONTROL1_REG(1))
+ ldr r5, =~(BIT4)
+ and r7, r7, r5 /* Clear PortReset Bit */
+ KW_REG_WRITE_ASM (r7, r5, KW_ETH_PORT_SERIAL_CONTROL1_REG(1))
+#endif
+
+ /*
+ * Enable PCI Express Port0
+ */
+#ifdef CONFIG_KIRKWOOD_PCIE_INIT
+ KW_REG_READ_ASM (r7, r5, KW_REG_CPU_CTRL_STAT)
+ ldr r5, =BIT0
+ orr r7, r7, r5 /* Set PEX0En Bit */
+ KW_REG_WRITE_ASM (r7, r5, KW_REG_CPU_CTRL_STAT)
+#endif
+
+#ifdef CONFIG_KW88F6281_Z0
+ /* Get the "sample on reset" register */
+ KW_REG_READ_ASM (r4, r5, KW_REG_MPP_SMPL_AT_RST)
+ ldr r5, =MSAR_DDRCLCK_RTIO_MASK
+ and r5, r4, r5
+ mov r5, r5, lsr #MSAR_DDRCLCK_RTIO_OFFS
+
+ ldr r4, =CPU_2_MBUSL_DDR_CLK_1x2
+ cmp r5, #CPU_2_DDR_CLK_1x2
+ beq set_config_reg
+
+ ldr r4, =CPU_2_MBUSL_DDR_CLK_1x3
+ cmp r5, #CPU_2_DDR_CLK_1x3
+ beq set_config_reg
+
+ ldr r4, =CPU_2_MBUSL_DDR_CLK_1x4
+ cmp r5, #CPU_2_DDR_CLK_1x4
+ beq set_config_reg
+
+ ldr r4, =0
+
+set_config_reg:
+ /* Read CPU Config register */
+ KW_REG_READ_ASM (r7, r5, KW_REG_CPU_CONFIG)
+ ldr r5, =~(CCR_CPU_2_MBUSL_TICK_DRV_MASK | CCR_CPU_2_MBUSL_TICK_SMPL_MASK)
+ and r7, r7, r5 /* Clear register fields */
+ orr r7, r7, r4 /* Set the values according to the findings */
+ KW_REG_WRITE_ASM (r7, r5, KW_REG_CPU_CONFIG)
+
+done:
+#endif
+ mov PC, r11 /* r11 is saved link register */
+
+ .globl kw_enable_invalidate_l2_cache
+kw_enable_invalidate_l2_cache:
+ mov r11, LR /* Save link register */
+
+ /* Enable L2 cache in write through mode */
+ KW_REG_READ_ASM(r4, r1, KW_REG_CPU_L2_CONFIG)
+ orr r4, r4, #0x18
+ KW_REG_WRITE_ASM(r4, r1, KW_REG_CPU_L2_CONFIG)
+ /* Read operation to make sure the L2 bit is set */
+ KW_REG_READ_ASM(r4, r1, KW_REG_CPU_L2_CONFIG)
+
+ /* invalidate L2 cache */
+ mov r0, #0
+ mcr p15, 1, r0, c15, c11, 0
+
+ mov PC, r11 /* r11 is saved link register */
+
+ .globl lowlevel_init
+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]
+
+ /* save Link Registers */
+ mov r2, lr
+
+ /* Enable L2 cache in write through mode */
+ bl kw_enable_invalidate_l2_cache
+
+#ifdef CONFIG_BOARD_LOWLEVEL_INIT
+ /*
+ * if Kirkwood is configured not to use its internal bootROM
+ * This will be needed specially for DRAM configuration
+ */
+ bl board_lowlevel_init
+#endif
+
+ /*
+ * Initialize BUS-L to DDR configuration parameters
+ * Must be done prior to DDR operation
+ */
+ bl kw_cpu_if_pre_init
+ mov lr, r2
+ mov pc, lr
diff --git a/cpu/arm926ejs/kirkwood/timer.c b/cpu/arm926ejs/kirkwood/timer.c
new file mode 100644
index 0000000..4ab1a54
--- /dev/null
+++ b/cpu/arm926ejs/kirkwood/timer.c
@@ -0,0 +1,165 @@
+/*
+ * 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>
+
+#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) BIT1
+#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
+
+/* This enumerator describe counters\watchdog numbers */
+typedef enum _kwCntmrID {
+ TIMER0 = 0,
+ TIMER1,
+ WATCHDOG
+} KW_CNTMR_ID;
+
+#define READ_TIMER (KW_REG_READ(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 = KW_REG_READ(CNTMR_VAL_REG(UBOOT_CNTR));
+ delayticks = (usec * (CONFIG_SYS_TCLK / 1000000));
+
+ if (current < delayticks) {
+ delayticks -= current;
+ while (KW_REG_READ(CNTMR_VAL_REG(UBOOT_CNTR)) < current) ;
+ while ((TIMER_LOAD_VAL - delayticks) <
+ KW_REG_READ(CNTMR_VAL_REG(UBOOT_CNTR))) ;
+ } else {
+ while (KW_REG_READ(CNTMR_VAL_REG(UBOOT_CNTR)) >
+ (current - delayticks)) ;
+ }
+}
+
+/*
+ * init the counter
+ */
+int timer_init(void)
+{
+ unsigned int cntmrCtrl;
+
+ /* load value onto counter\timer */
+ KW_REG_WRITE(CNTMR_RELOAD_REG(UBOOT_CNTR), TIMER_LOAD_VAL);
+ KW_REG_WRITE(CNTMR_VAL_REG(UBOOT_CNTR), TIMER_LOAD_VAL);
+
+ /* set the counter to load in the first time */
+ KW_REG_WRITE(CNTMR_VAL_REG(UBOOT_CNTR), TIMER_LOAD_VAL);
+
+ /* set control for timer \ cunter and enable */
+ /* read control register */
+ cntmrCtrl = KW_REG_READ(CNTMR_CTRL_REG);
+ cntmrCtrl |= CTCR_ARM_TIMER_EN(UBOOT_CNTR); /* enable cnt\timer */
+ cntmrCtrl |= CTCR_ARM_TIMER_AUTO_EN(UBOOT_CNTR); /* Auto mode */
+
+ KW_REG_WRITE(CNTMR_CTRL_REG, cntmrCtrl);
+
+ /* init the timestamp and lastdec value */
+ reset_timer_masked();
+
+ return 0;
+}
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index bb99a34..dd59ff8 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) += 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..6422ab2
--- /dev/null
+++ b/drivers/serial/kirkwood_serial.c
@@ -0,0 +1,187 @@
+/*
+ * 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>
+
+/* registers feilds */
+#define FCR_FIFO_EN BIT0 /* fifo enable */
+#define FCR_RXSR BIT1 /* receiver soft reset */
+#define FCR_TXSR BIT2 /* transmitter soft reset */
+#define MCR_RTS BIT1 /* 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 BIT0 /* Data ready */
+#define LSR_OE BIT1 /* Overrun */
+#define LSR_PE BIT2 /* Parity error */
+#define LSR_FE BIT3 /* Framing error */
+#define LSR_BI BIT4 /* Break */
+#define LSR_THRE BIT5 /* Xmit holding register empty */
+#define LSR_TEMT BIT6 /* Xmitter empty */
+#define LSR_ERR BIT7 /* 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 */
+typedef struct kwUartPort {
+ 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];
+} kw_uart_port;
+
+/* aliases - for registers which has the same offsets */
+#define thr rbr
+#define iir fcr
+#define dll rbr
+#define dlm ier
+
+/* static variables */
+#if defined (CONFIG_CONS_INDEX) /* comes from board config */
+#if (CONFIG_CONS_INDEX == 0 )
+static volatile kw_uart_port *p_uart_port = (void *)KW_REGISTER(KW_UART0_BASE);
+#elif (CONFIG_CONS_INDEX == 1 )
+static volatile 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);
+}
+
+void kwUartPutc(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')
+ kwUartPutc('\r');
+
+ kwUartPutc(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..f0bc3a7
--- /dev/null
+++ b/drivers/spi/kirkwood_spi.c
@@ -0,0 +1,199 @@
+/*
+ * (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>
+
+/* SPI Registers on kirkwood SOC */
+#define KW_REG_SPI_CTRL (0x10600)
+#define KW_REG_SPI_CONFIG (0x10604)
+#define KW_REG_SPI_DATA_OUT (0x10608)
+#define KW_REG_SPI_DATA_IN (0x1060c)
+#define KW_REG_SPI_IRQ_CAUSE (0x10610)
+#define KW_REG_SPI_IRQ_MASK (0x10614)
+
+#define KW_SPI_TIMEOUT 10000
+
+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;
+
+ KW_REG_WRITE(KW_REG_SPI_CTRL, 0x00000002);
+ /* program spi clock prescaller using max_hz */
+ data = ((CONFIG_SYS_TCLK / 2) / max_hz) & 0x0000000f;
+ debug("data = 0x%08x \n", data);
+ KW_REG_WRITE(KW_REG_SPI_CONFIG, 0x00000210 | data);
+ KW_REG_WRITE(KW_REG_SPI_IRQ_CAUSE, 0x00000001);
+ KW_REG_WRITE(KW_REG_SPI_IRQ_MASK, 0x00000000);
+
+ /* program mpp registers to select SPI_CSn */
+ if (cs)
+ KW_REG_WRITE(KW_REG_MPP_CONTROL0,
+ ((KW_REG_READ(KW_REG_MPP_CONTROL0) & 0x0fffffff) |
+ 0x20000000));
+ else
+ KW_REG_WRITE(KW_REG_MPP_CONTROL0,
+ ((KW_REG_READ(KW_REG_MPP_CONTROL0) & 0xfffffff0) |
+ 0x00000002));
+
+ 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)
+{
+ KW_REG_BITS_SET(KW_REG_SPI_CTRL, BIT0);
+}
+
+void spi_cs_deactivate(struct spi_slave *slave)
+{
+ KW_REG_BITS_RESET(KW_REG_SPI_CTRL, BIT0);
+}
+
+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;
+ if (1) { //bitlen <= 8) {
+ /*1 byte xfer mode */
+ KW_REG_BITS_RESET(KW_REG_SPI_CONFIG, BIT5);
+ /* Shift data so it's msb-justified */
+ if (dout) {
+ tmpdout = *(u32 *) dout & 0x0ff;
+ }
+ } else {
+ /*2 byte xfer mode */
+ KW_REG_BITS_SET(KW_REG_SPI_CONFIG, BIT5);
+ /* Shift data so it's msb-justified */
+ if (dout) {
+ tmpdout = *(u32 *) dout & 0x0ffff;
+ }
+ }
+
+ KW_REG_WRITE(KW_REG_SPI_IRQ_CAUSE, 0x0); /* clear bit */
+ KW_REG_WRITE(KW_REG_SPI_DATA_OUT, tmpdout); /* 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 (KW_REG_READ(KW_REG_SPI_IRQ_CAUSE)) {
+ isRead = 1;
+ tmpdin = KW_REG_READ(KW_REG_SPI_DATA_IN);
+ debug
+ ("*** spi_xfer: din %08X ... %08x read\n",
+ din, tmpdin);
+
+ if (1) { //bitlen <= 8) {
+ if (din) {
+ *((u8 *) din) = (u8) tmpdin;
+ din += 1;
+ }
+ if (dout)
+ dout += 1;
+ bitlen -= 8;
+ } else {
+ if (din) {
+ *((u16 *) din) = (u16) tmpdin;
+ din += 1;
+ }
+ if (dout)
+ dout += 1;
+ bitlen -= 16;
+ }
+ }
+ 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..67d94dc
--- /dev/null
+++ b/include/asm-arm/arch-kirkwood/kirkwood.h
@@ -0,0 +1,142 @@
+/*
+ * (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-arm/types.h>
+#endif /* __ASSEMBLY__ */
+#include <../board/Marvell/include/core.h>
+
+#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)
+
+#define KW_UART0_BASE (0x12000) /* UArt 0 */
+#define KW_UART1_BASE (0x13000) /* UArt 1 */
+
+/* Controler environment registers offsets */
+#define KW_REG_MPP_CONTROL0 (0x10000)
+#define KW_REG_MPP_CONTROL1 (0x10004)
+#define KW_REG_MPP_CONTROL2 (0x10008)
+#define KW_REG_MPP_CONTROL3 (0x1000C)
+#define KW_REG_MPP_CONTROL4 (0x10010)
+#define KW_REG_MPP_CONTROL5 (0x10014)
+#define KW_REG_MPP_CONTROL6 (0x10018)
+#define KW_REG_MPP_SMPL_AT_RST (0x10030)
+#define KW_REG_CHIP_BOND (0x10034)
+#define KW_REG_MPP_OUT_DRV_REG (0x100E0)
+
+#define KW_REG_GPP0_DATA_OUT (0x10100)
+#define KW_REG_GPP0_DATA_OUT_EN (0x10104)
+#define KW_REG_GPP0_BLINK_EN (0x10108)
+#define KW_REG_GPP0_DATA_IN_POL (0x1010C)
+#define KW_REG_GPP0_DATA_IN (0x10110)
+#define KW_REG_GPP0_INT_CAUSE (0x10114)
+#define KW_REG_GPP0_INT_MASK (0x10118)
+#define KW_REG_GPP0_INT_LVL (0x1011c)
+
+#define KW_REG_GPP1_DATA_OUT (0x10140)
+#define KW_REG_GPP1_DATA_OUT_EN (0x10144)
+#define KW_REG_GPP1_BLINK_EN (0x10148)
+#define KW_REG_GPP1_DATA_IN_POL (0x1014C)
+#define KW_REG_GPP1_DATA_IN (0x10150)
+#define KW_REG_GPP1_INT_CAUSE (0x10154)
+#define KW_REG_GPP1_INT_MASK (0x10158)
+#define KW_REG_GPP1_INT_LVL (0x1015c)
+
+#define KW_REG_NAND_READ_PARAM (0x10418)
+#define KW_REG_NAND_WRITE_PARAM (0x1041c)
+#define KW_REG_NAND_CTRL (0x10470)
+
+#define KW_REG_WIN_CTRL(x) (0x20000+(x*0x10))
+#define KW_REG_WIN_BASE(x) (0x20004+(x*0x10))
+#define KW_REG_WIN_REMAP_LOW(x) (0x20008+(x*0x10))
+#define KW_REG_WIN_REMAP_HIGH(x) (0x2000c+(x*0x10))
+
+#define KW_REG_CPU_CONFIG (0x20100)
+#define KW_REG_CPU_CTRL_STAT (0x20104)
+#define KW_REG_CPU_RSTOUTN_MASK (0x20108)
+#define KW_REG_CPU_SYS_SOFT_RST (0x2010C)
+#define KW_REG_CPU_AHB_MBUS_CAUSE_INT (0x20110)
+#define KW_REG_CPU_AHB_MBUS_MASK_INT (0x20114)
+#define KW_REG_CPU_FTDLL_CONFIG (0x20120)
+#define KW_REG_CPU_L2_CONFIG (0x20128)
+#define KW_REG_L2_RAM_TIMING0 (0x20134)
+#define KW_REG_L2_RAM_TIMING1 (0x20138)
+
+#define KW_REG_TMR_CTRL (0x20300)
+#define KW_REG_TMR_RELOAD (0x20310)
+#define KW_REG_TMR_VAL (0x20314)
+
+/*
+ * Macros
+ * CPU architecture dependent I/O read/write
+ */
+#define KW_REG_WRITE(addr, data) \
+ ((*((volatile unsigned int*)(KW_REGISTER(addr)))) \
+ = ((unsigned int)WORD_SWAP((data))))
+
+#define KW_REG_READ(addr) \
+ WORD_SWAP(((*((volatile unsigned int*)(KW_REGISTER(addr))))))
+
+#define KW_REG_BITS_SET(adr, bits) (KW_REG_WRITE(adr, KW_REG_READ(adr)\
+ | ((unsigned int)WORD_SWAP(bits))))
+
+#define KW_REG_BITS_RESET(adr, bits) (KW_REG_WRITE(adr, KW_REG_READ(adr)\
+ & ~((unsigned int)WORD_SWAP(bits))))
+
+#define KW_REG_READ_ASM(toReg, tmpReg, regOffs) \
+ ldr tmpReg, =KW_REGISTER(regOffs); \
+ ldr toReg, [tmpReg]; \
+ /*WORD_SWAP_ASM(toReg,tmpReg) */
+
+#define KW_REG_WRITE_ASM(fromReg, tmpReg, regOffs) \
+ /*WORD_SWAP_ASM(fromReg,tmpReg)*/; \
+ ldr tmpReg, =KW_REGISTER(regOffs); \
+ str fromReg, [tmpReg]
+
+/*
+ * Error codes
+ */
+#define KW_ERROR (-1)
+#define KW_OK (0)
+
+#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@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..45098fb
--- /dev/null
+++ b/include/asm-arm/arch-kirkwood/kw88f6281.h
@@ -0,0 +1,43 @@
+/*
+ * (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*/
+#if defined (CONFIG_KW88F6281_Z0)
+#define CONFIG_SYS_TCLK 166000000 /* 166MHz */
+#elif defined (CONFIG_KW88F6281_A0)
+#define CONFIG_SYS_TCLK 200000000 /* 200MHz */
+#else
+#error "CONFIG_SYS_TCLK not defined"
+#endif
+
+#endif /* _ASM_ARCH_KW88F6281_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
--
1.5.3.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [U-Boot] [PATCH v2] Marvell Kirkwood family SOC support
2009-04-08 12:03 [U-Boot] [PATCH v2] Marvell Kirkwood family SOC support Prafulla Wadaskar
@ 2009-04-14 17:26 ` Prafulla Wadaskar
2009-04-17 9:22 ` Jean-Christophe PLAGNIOL-VILLARD
1 sibling, 0 replies; 11+ messages in thread
From: Prafulla Wadaskar @ 2009-04-14 17:26 UTC (permalink / raw)
To: u-boot
Hi all,
Any comments welcomed...
Or Shall I consider this patch is accepted ;-)
.....Shall I send it again ?
Regards..
Prafulla . .
> -----Original Message-----
> From: Prafulla Wadaskar [mailto:prafulla at marvell.com]
> Sent: Wednesday, April 08, 2009 5:33 PM
> To: u-boot at lists.denx.de
> Cc: Ronen Shitrit; Ashish Karkare; Prafulla Wadaskar
> Subject: [PATCH v2] Marvell Kirkwood family SOC support
>
> Kirkwood family controllers are highly integrated SOCs
> based on Feroceon-88FR131/Sheeva-88SV131 cpu core.
>
> SOC versions supported:-
> 1) 88F6281-Z0 define CONFIG_KW88F6281_Z0
> 2) 88F6281-A0 define CONFIG_KW88F6281_A0
> 3) 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>
> ---
> Changelog:
> 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
>
> board/Marvell/include/core.h | 4 +
> cpu/arm926ejs/kirkwood/Makefile | 50 ++++++
> cpu/arm926ejs/kirkwood/config.mk | 25 +++
> cpu/arm926ejs/kirkwood/dram.c | 55 +++++++
> cpu/arm926ejs/kirkwood/kwcore.c | 250
> +++++++++++++++++++++++++++++
> cpu/arm926ejs/kirkwood/kwcore.h | 47 ++++++
> cpu/arm926ejs/kirkwood/lowlevel_init.S | 183
> +++++++++++++++++++++
> cpu/arm926ejs/kirkwood/timer.c | 165 +++++++++++++++++++
> drivers/serial/Makefile | 1 +
> drivers/serial/kirkwood_serial.c | 187
> +++++++++++++++++++++
> drivers/spi/Makefile | 1 +
> drivers/spi/kirkwood_spi.c | 199
> +++++++++++++++++++++++
> include/asm-arm/arch-kirkwood/kirkwood.h | 142 ++++++++++++++++
> include/asm-arm/arch-kirkwood/kw88f6192.h | 37 +++++
> include/asm-arm/arch-kirkwood/kw88f6281.h | 43 +++++
> include/asm-arm/config.h | 4 +
> 16 files changed, 1393 insertions(+), 0 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
>
> diff --git a/board/Marvell/include/core.h
> b/board/Marvell/include/core.h
> index c413439..ecc4682 100644
> --- a/board/Marvell/include/core.h
> +++ b/board/Marvell/include/core.h
> @@ -12,9 +12,11 @@ space). The macros take care of Big/Little
> endian conversions.
> #ifndef __INCcoreh
> #define __INCcoreh
>
> +#ifndef CONFIG_KIRKWOOD
> #include "mv_gen_reg.h"
>
> extern unsigned int INTERNAL_REG_BASE_ADDR;
> +#endif /* CONFIG_KIRKWOOD */
>
> /****************************************/
> /* GENERAL Definitions */
> @@ -91,10 +93,12 @@ extern unsigned int INTERNAL_REG_BASE_ADDR;
> #define _1G 0x40000000
> #define _2G 0x80000000
>
> +#ifndef __ASSEMBLY__
> #ifndef BOOL_WAS_DEFINED
> #define BOOL_WAS_DEFINED
> typedef enum _bool{false,true} bool;
> #endif
> +#endif
>
> /* Little to Big endian conversion macros */
>
> diff --git a/cpu/arm926ejs/kirkwood/Makefile
> b/cpu/arm926ejs/kirkwood/Makefile
> new file mode 100644
> index 0000000..c917f0d
> --- /dev/null
> +++ b/cpu/arm926ejs/kirkwood/Makefile
> @@ -0,0 +1,50 @@
> +#
> +# (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 += 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@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..80e2b13
> --- /dev/null
> +++ b/cpu/arm926ejs/kirkwood/dram.c
> @@ -0,0 +1,55 @@
> +/*
> + * (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>
> +
> +/*
> + * kw_sdram_bar - reads SDRAM Base Address Register
> + */
> +u32 kw_sdram_bar(MEMORY_BANK bank)
> +{
> + u32 result = 0;
> + u32 enable = (0x01 & KW_REG_READ((0x1504 + bank * 8)));
> +
> + if ((!enable) || (bank > BANK3))
> + return 0;
> +
> + result = KW_REG_READ((0x1500 + bank * 8));
> + return result;
> +}
> +
> +/*
> + * kw_sdram_bs - reads SDRAM Bank size
> + */
> +u32 kw_sdram_bs(MEMORY_BANK bank)
> +{
> + u32 result = 0;
> + u32 enable = (0x01 & KW_REG_READ((0x1504 + bank * 8)));
> +
> + if ((!enable) || (bank > BANK3))
> + return 0;
> + result = (0xff000000 & KW_REG_READ((0x1504 + bank * 8)));
> + result += 0x01000000;
> + return result;
> +}
> diff --git a/cpu/arm926ejs/kirkwood/kwcore.c
> b/cpu/arm926ejs/kirkwood/kwcore.c
> new file mode 100644
> index 0000000..2e887d5
> --- /dev/null
> +++ b/cpu/arm926ejs/kirkwood/kwcore.c
> @@ -0,0 +1,250 @@
> +/*
> + * (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 <u-boot/md5.h>
> +
> +void reset_cpu(unsigned long ignored)
> +{
> + KW_REG_BITS_SET(KW_REG_CPU_RSTOUTN_MASK, BIT2);
> + KW_REG_BITS_SET(KW_REG_CPU_SYS_SOFT_RST, BIT0);
> + 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];
> +
> +#if defined (CONFIG_KW88F6281_Z0)
> + KW_REG_BITS_SET(0x1478, BIT7);
> +#elif defined (CONFIG_KW88F6281_A0) || defined (CONFIG_KW88F6192_A0)
> + /*
> + * in case of 88F6281/88F6192 A0,
> + * BIT7 need to reset to generate random values in 0x1470
> + */
> + KW_REG_BITS_RESET(0x1478, BIT7);
> +#else
> +#error Undefined SOC Revision
> +#endif
> + for (i = 0; i < 16; i++) {
> + inbuf[i] = KW_REG_READ(0x1470);
> + }
> + md5((u8 *) inbuf, 64, outbuf);
> + return outbuf[outbuf[7] % 0x0f];
> +}
> +
> +/*
> + * kw_window_ctrl_reg_init - Mbus-L to Mbus Bridge Registers init.
> + */
> +int kw_window_ctrl_reg_init(void)
> +{
> + KW_REG_WRITE(KW_REG_WIN_CTRL(0), 0x0fffe841);
> + KW_REG_WRITE(KW_REG_WIN_BASE(0), 0x90000000);
> + KW_REG_WRITE(KW_REG_WIN_REMAP_LOW(0), 0x90000000);
> + KW_REG_WRITE(KW_REG_WIN_REMAP_HIGH(0), 0x00000000);
> +
> + KW_REG_WRITE(KW_REG_WIN_CTRL(1), 0x007f2f11);
> + KW_REG_WRITE(KW_REG_WIN_BASE(1), 0xF9000000);
> + KW_REG_WRITE(KW_REG_WIN_REMAP_LOW(1), 0xF9000000);
> + KW_REG_WRITE(KW_REG_WIN_REMAP_HIGH(1), 0x00000000);
> +
> + KW_REG_WRITE(KW_REG_WIN_CTRL(2), 0x00ffe041);
> + KW_REG_WRITE(KW_REG_WIN_BASE(2), 0xF0000000);
> + KW_REG_WRITE(KW_REG_WIN_REMAP_LOW(2), 0xC0000000);
> + KW_REG_WRITE(KW_REG_WIN_REMAP_HIGH(2), 0x00000000);
> +
> + KW_REG_WRITE(KW_REG_WIN_CTRL(3), 0x00ff1e11);
> + KW_REG_WRITE(KW_REG_WIN_BASE(3), 0xF8000000);
> + KW_REG_WRITE(KW_REG_WIN_REMAP_LOW(3), 0x00000000);
> + KW_REG_WRITE(KW_REG_WIN_REMAP_HIGH(3), 0x00000000);
> +
> + KW_REG_WRITE(KW_REG_WIN_CTRL(4), 0x00ff1d11);
> + KW_REG_WRITE(KW_REG_WIN_BASE(4), 0xFF000000);
> + KW_REG_WRITE(KW_REG_WIN_REMAP_LOW(4), 0x00000000);
> + KW_REG_WRITE(KW_REG_WIN_REMAP_HIGH(4), 0x00000000);
> +
> + KW_REG_WRITE(KW_REG_WIN_CTRL(5), 0x07ff1e10);
> + KW_REG_WRITE(KW_REG_WIN_BASE(5), 0xE8000000);
> + KW_REG_WRITE(KW_REG_WIN_REMAP_LOW(5), 0x00000000);
> + KW_REG_WRITE(KW_REG_WIN_REMAP_HIGH(5), 0x00000000);
> +
> + KW_REG_WRITE(KW_REG_WIN_CTRL(6), 0x07ff1d10);
> + KW_REG_WRITE(KW_REG_WIN_BASE(6), 0xF0000000);
> + KW_REG_WRITE(KW_REG_WIN_REMAP_LOW(6), 0x00000000);
> + KW_REG_WRITE(KW_REG_WIN_REMAP_HIGH(6), 0x00000000);
> +
> + KW_REG_WRITE(KW_REG_WIN_CTRL(7), 0x00000131);
> + KW_REG_WRITE(KW_REG_WIN_BASE(7), 0xFB000000);
> + KW_REG_WRITE(KW_REG_WIN_REMAP_LOW(7), 0x00000000);
> + KW_REG_WRITE(KW_REG_WIN_REMAP_HIGH(7), 0x00000000);
> +
> + return KW_OK;
> +}
> +
> +/*
> + * kw_gpio_init - Init gpios for default values
> + */
> +void kw_gpio_init(u32 gpp0_oe_val, u32 gpp1_oe_val, u32
> gpp0_oe, u32 gpp1_oe)
> +{
> + /* Init GPIOS to default values as per board requirement */
> + KW_REG_WRITE(KW_REG_GPP0_DATA_OUT, gpp0_oe_val);
> + KW_REG_WRITE(KW_REG_GPP1_DATA_OUT, gpp1_oe_val);
> + KW_REG_WRITE(KW_REG_GPP0_DATA_OUT_EN, gpp0_oe);
> + KW_REG_WRITE(KW_REG_GPP1_DATA_OUT_EN, gpp1_oe);
> +}
> +
> +/*
> + * kw_mpp_control_init - initialize mpp for board specific
> functionality
> + */
> +int kw_mpp_control_init(u32 mpp0_7, u32 mpp8_15, u32
> mpp16_23, u32 mpp24_31,
> + u32 mpp32_39, u32 mpp40_47, u32 mpp48_55)
> +{
> + /* program mpp registers */
> + KW_REG_WRITE(KW_REG_MPP_CONTROL0, mpp0_7);
> + KW_REG_WRITE(KW_REG_MPP_CONTROL1, mpp8_15);
> + KW_REG_WRITE(KW_REG_MPP_CONTROL2, mpp16_23);
> + KW_REG_WRITE(KW_REG_MPP_CONTROL3, mpp24_31);
> + KW_REG_WRITE(KW_REG_MPP_CONTROL4, mpp32_39);
> + KW_REG_WRITE(KW_REG_MPP_CONTROL5, mpp40_47);
> + KW_REG_WRITE(KW_REG_MPP_CONTROL6, mpp48_55);
> + return KW_OK;
> +}
> +
> +/*
> + * kw_misc_init_r - SOC specific misc init (mainly cache
> initialization)
> + */
> +int kw_misc_init_r(void)
> +{
> + char *env;
> + volatile unsigned int temp;
> +
> + /*CPU streaming & write allocate */
> + env = getenv("enaWrAllo");
> + if (env && ((strcmp(env, "yes") == 0) || (strcmp(env,
> "Yes") == 0))) {
> + __asm__ __volatile__("mrc p15, 1, %0, c15, c1,
> 0":"=r"(temp));
> + temp |= BIT28;
> + __asm__ __volatile__("mcr p15, 1, %0, c15, c1,
> 0"::"r"(temp));
> +
> + } else {
> + __asm__ __volatile__("mrc p15, 1, %0, c15, c1,
> 0":"=r"(temp));
> + temp &= ~BIT28;
> + __asm__ __volatile__("mcr p15, 1, %0, c15, c1,
> 0"::"r"(temp));
> + }
> +
> + env = getenv("enaCpuStream");
> + if (!env || (strcmp(env, "no") == 0) || (strcmp(env,
> "No") == 0)) {
> + __asm__ __volatile__("mrc p15, 1, %0, c15, c1,
> 0":"=r"(temp));
> + temp &= ~BIT29;
> + __asm__ __volatile__("mcr p15, 1, %0, c15, c1,
> 0"::"r"(temp));
> + } else {
> + __asm__ __volatile__("mrc p15, 1, %0, c15, c1,
> 0":"=r"(temp));
> + temp |= BIT29;
> + __asm__ __volatile__("mcr p15, 1, %0, c15, c1,
> 0"::"r"(temp));
> + }
> +
> + /* Verify write allocate and streaming */
> + printf("\n");
> + __asm__ __volatile__("mrc p15, 1, %0, c15, c1, 0":"=r"(temp));
> + if (temp & BIT29)
> + printf("Streaming enabled\n");
> + else
> + printf("Streaming disabled\n");
> + if (temp & BIT28)
> + printf("Write allocate enabled\n");
> + else
> + printf("Write allocate disabled\n");
> +
> + /* DCache Pref */
> + env = getenv("enaDCPref");
> + if (env && ((strcmp(env, "yes") == 0) || (strcmp(env,
> "Yes") == 0))) {
> + temp = KW_REG_READ(KW_REG_CPU_CONFIG);
> + temp |= BIT17; /* Set CCR_DCACH_PREF_BUF_ENABLE */
> + KW_REG_WRITE(KW_REG_CPU_CONFIG, temp);
> + }
> +
> + if (env && ((strcmp(env, "no") == 0) || (strcmp(env,
> "No") == 0))) {
> + temp = KW_REG_READ(KW_REG_CPU_CONFIG);
> + temp &= ~BIT17; /* Reset CCR_DCACH_PREF_BUF_ENABLE */
> + KW_REG_WRITE(KW_REG_CPU_CONFIG, temp);
> + }
> +
> + /* ICache Pref */
> + env = getenv("enaICPref");
> + if (env && ((strcmp(env, "yes") == 0) || (strcmp(env,
> "Yes") == 0))) {
> + temp = KW_REG_READ(KW_REG_CPU_CONFIG);
> + temp |= BIT16; /* Set CCR_ICACH_PREF_BUF_ENABLE */
> + KW_REG_WRITE(KW_REG_CPU_CONFIG, temp);
> + }
> +
> + if (env && ((strcmp(env, "no") == 0) || (strcmp(env,
> "No") == 0))) {
> + temp = KW_REG_READ(KW_REG_CPU_CONFIG);
> + temp &= ~BIT16; /* Reset CCR_ICACH_PREF_BUF_ENABLE */
> + KW_REG_WRITE(KW_REG_CPU_CONFIG, temp);
> + }
> + /* Set L2C WT mode - Set bit 4 */
> + temp = KW_REG_READ(KW_REG_CPU_L2_CONFIG);
> + env = getenv("setL2CacheWT");
> + if (!env || ((strcmp(env, "yes") == 0) || (strcmp(env,
> "Yes") == 0))) {
> + temp |= BIT4;
> + } else
> + temp &= ~BIT4;
> + KW_REG_WRITE(KW_REG_CPU_L2_CONFIG, temp);
> +
> + /* L2Cache settings */
> + asm("mrc p15, 1, %0, c15, c1, 0":"=r"(temp));
> +
> + /* Disable L2C pre fetch - Set bit 24 */
> + env = getenv("disL2Prefetch");
> + if (env && ((strcmp(env, "no") == 0) || (strcmp(env,
> "No") == 0)))
> + temp &= ~BIT24;
> + else
> + temp |= BIT24;
> +
> + /* enable L2C - Set bit 22 */
> + env = getenv("disL2Cache");
> + if (!env || ((strcmp(env, "no") == 0) || (strcmp(env,
> "No") == 0)))
> + temp |= BIT22;
> + else
> + temp &= ~BIT22;
> +
> + asm("mcr p15, 1, %0, c15, c1, 0": :"r"(temp));
> +
> + /* Enable i cache */
> + asm("mrc p15, 0, %0, c1, c0, 0":"=r"(temp));
> + temp |= BIT12;
> + asm("mcr p15, 0, %0, c1, c0, 0": :"r"(temp));
> + /* Change reset vector to address 0x0 */
> + asm("mrc p15, 0, %0, c1, c0, 0":"=r"(temp));
> + temp &= ~BIT13;
> + asm("mcr p15, 0, %0, c1, c0, 0": :"r"(temp));
> +
> + return (0);
> +}
> +
> diff --git a/cpu/arm926ejs/kirkwood/kwcore.h
> b/cpu/arm926ejs/kirkwood/kwcore.h
> new file mode 100644
> index 0000000..8d2a8cc
> --- /dev/null
> +++ b/cpu/arm926ejs/kirkwood/kwcore.h
> @@ -0,0 +1,47 @@
> +/*
> + * (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 _KWCORE_H
> +#define _KWCORE_H
> +
> +/*
> + * functions
> + */
> +#ifndef __ASSEMBLY__
> +void reset_cpu(unsigned long ignored);
> +unsigned char get_random_hex(void);
> +typedef enum _memory_bank { BANK0, BANK1, BANK2, BANK3 } MEMORY_BANK;
> +unsigned int kw_sdram_bar(MEMORY_BANK bank);
> +unsigned int kw_sdram_bs(MEMORY_BANK bank);
> +int kw_window_ctrl_reg_init(void);
> +void kw_gpio_init(unsigned int gpp0_oe_val, unsigned int gpp1_oe_val,
> + unsigned int gpp0_oe, unsigned int gpp1_oe);
> +int kw_mpp_control_init(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);
> +int kw_misc_init_r(void);
> +#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..169e58b
> --- /dev/null
> +++ b/cpu/arm926ejs/kirkwood/lowlevel_init.S
> @@ -0,0 +1,183 @@
> +/*
> + * (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>
> +
> +#define CCR_CPU_2_MBUSL_TICK_DRV_OFFS 8
> +#define CCR_CPU_2_MBUSL_TICK_DRV_MASK (0xF <<
> CCR_CPU_2_MBUSL_TICK_DRV_OFFS)
> +#define CCR_CPU_2_MBUSL_TICK_SMPL_OFFS 12
> +#define CCR_CPU_2_MBUSL_TICK_SMPL_MASK (0xF <<
> CCR_CPU_2_MBUSL_TICK_SMPL_OFFS)
> +
> +#define MSAR_DDRCLCK_RTIO_OFFS 5
> +#define MSAR_DDRCLCK_RTIO_MASK (0xF <<
> MSAR_DDRCLCK_RTIO_OFFS)
> +
> +/* Ratio options for CPU to DDR for 6281/6192/6180 */
> +#define CPU_2_DDR_CLK_1x2 2
> +#define CPU_2_DDR_CLK_1x3 4
> +#define CPU_2_DDR_CLK_1x4 6
> +
> +/* Default values for CPU to Mbus-L DDR Interface Tick
> Driver and */
> +/* CPU to Mbus-L Tick Sample fields in CPU config register
> */
> +
> +#define TICK_DRV_1x1 0
> +#define TICK_DRV_1x2 0
> +#define TICK_DRV_1x3 1
> +#define TICK_DRV_1x4 2
> +#define TICK_SMPL_1x1 0
> +#define TICK_SMPL_1x2 1
> +#define TICK_SMPL_1x3 2
> +#define TICK_SMPL_1x4 3
> +#define CPU_2_MBUSL_DDR_CLK_1x2
> \
> + ((TICK_DRV_1x2 <<
> CCR_CPU_2_MBUSL_TICK_DRV_OFFS) | \
> + (TICK_SMPL_1x2 << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS))
> +#define CPU_2_MBUSL_DDR_CLK_1x3
> \
> + ((TICK_DRV_1x3 <<
> CCR_CPU_2_MBUSL_TICK_DRV_OFFS) | \
> + (TICK_SMPL_1x3 << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS))
> +#define CPU_2_MBUSL_DDR_CLK_1x4
> \
> + ((TICK_DRV_1x4 <<
> CCR_CPU_2_MBUSL_TICK_DRV_OFFS) | \
> + (TICK_SMPL_1x4 << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS))
> +
> +
> + .globl kw_cpu_if_pre_init
> +kw_cpu_if_pre_init:
> +
> + mov r11, LR /* Save link register */
> +
> + /*
> + * Configures the I/O voltage of the pads connected to Egigabit
> + * Ethernet interface to 1.8V
> + * By defult it is set to 3.3V
> + */
> +#ifdef CONFIG_KIRKWOOD_RGMII_PAD_1V8
> + KW_REG_READ_ASM (r7, r5, KW_REG_MPP_OUT_DRV_REG)
> + ldr r5, =BIT7
> + orr r7, r7, r5 /* Set RGMII PADS Voltage to 1.8V */
> + KW_REG_WRITE_ASM (r7, r5, KW_REG_MPP_OUT_DRV_REG)
> +#endif
> + /*
> + * 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
> + */
> +#ifdef CONFIG_KIRKWOOD_EGIGA_INIT
> + KW_REG_READ_ASM (r7, r5, KW_ETH_PORT_SERIAL_CONTROL1_REG(0))
> + ldr r5, =~(BIT4)
> + and r7, r7, r5 /* Clear PortReset Bit */
> + KW_REG_WRITE_ASM (r7, r5, KW_ETH_PORT_SERIAL_CONTROL1_REG(0))
> +
> + KW_REG_READ_ASM (r7, r5, KW_ETH_PORT_SERIAL_CONTROL1_REG(1))
> + ldr r5, =~(BIT4)
> + and r7, r7, r5 /* Clear PortReset Bit */
> + KW_REG_WRITE_ASM (r7, r5, KW_ETH_PORT_SERIAL_CONTROL1_REG(1))
> +#endif
> +
> + /*
> + * Enable PCI Express Port0
> + */
> +#ifdef CONFIG_KIRKWOOD_PCIE_INIT
> + KW_REG_READ_ASM (r7, r5, KW_REG_CPU_CTRL_STAT)
> + ldr r5, =BIT0
> + orr r7, r7, r5 /* Set PEX0En Bit */
> + KW_REG_WRITE_ASM (r7, r5, KW_REG_CPU_CTRL_STAT)
> +#endif
> +
> +#ifdef CONFIG_KW88F6281_Z0
> + /* Get the "sample on reset" register */
> + KW_REG_READ_ASM (r4, r5, KW_REG_MPP_SMPL_AT_RST)
> + ldr r5, =MSAR_DDRCLCK_RTIO_MASK
> + and r5, r4, r5
> + mov r5, r5, lsr #MSAR_DDRCLCK_RTIO_OFFS
> +
> + ldr r4, =CPU_2_MBUSL_DDR_CLK_1x2
> + cmp r5, #CPU_2_DDR_CLK_1x2
> + beq set_config_reg
> +
> + ldr r4, =CPU_2_MBUSL_DDR_CLK_1x3
> + cmp r5, #CPU_2_DDR_CLK_1x3
> + beq set_config_reg
> +
> + ldr r4, =CPU_2_MBUSL_DDR_CLK_1x4
> + cmp r5, #CPU_2_DDR_CLK_1x4
> + beq set_config_reg
> +
> + ldr r4, =0
> +
> +set_config_reg:
> + /* Read CPU Config register */
> + KW_REG_READ_ASM (r7, r5, KW_REG_CPU_CONFIG)
> + ldr r5, =~(CCR_CPU_2_MBUSL_TICK_DRV_MASK |
> CCR_CPU_2_MBUSL_TICK_SMPL_MASK)
> + and r7, r7, r5 /* Clear register fields */
> + orr r7, r7, r4 /* Set the values according
> to the findings */
> + KW_REG_WRITE_ASM (r7, r5, KW_REG_CPU_CONFIG)
> +
> +done:
> +#endif
> + mov PC, r11 /* r11 is saved link register */
> +
> + .globl kw_enable_invalidate_l2_cache
> +kw_enable_invalidate_l2_cache:
> + mov r11, LR /* Save link register */
> +
> + /* Enable L2 cache in write through mode */
> + KW_REG_READ_ASM(r4, r1, KW_REG_CPU_L2_CONFIG)
> + orr r4, r4, #0x18
> + KW_REG_WRITE_ASM(r4, r1, KW_REG_CPU_L2_CONFIG)
> + /* Read operation to make sure the L2 bit is set */
> + KW_REG_READ_ASM(r4, r1, KW_REG_CPU_L2_CONFIG)
> +
> + /* invalidate L2 cache */
> + mov r0, #0
> + mcr p15, 1, r0, c15, c11, 0
> +
> + mov PC, r11 /* r11 is saved link register */
> +
> + .globl lowlevel_init
> +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]
> +
> + /* save Link Registers */
> + mov r2, lr
> +
> + /* Enable L2 cache in write through mode */
> + bl kw_enable_invalidate_l2_cache
> +
> +#ifdef CONFIG_BOARD_LOWLEVEL_INIT
> + /*
> + * if Kirkwood is configured not to use its internal bootROM
> + * This will be needed specially for DRAM configuration
> + */
> + bl board_lowlevel_init
> +#endif
> +
> + /*
> + * Initialize BUS-L to DDR configuration parameters
> + * Must be done prior to DDR operation
> + */
> + bl kw_cpu_if_pre_init
> + mov lr, r2
> + mov pc, lr
> diff --git a/cpu/arm926ejs/kirkwood/timer.c
> b/cpu/arm926ejs/kirkwood/timer.c
> new file mode 100644
> index 0000000..4ab1a54
> --- /dev/null
> +++ b/cpu/arm926ejs/kirkwood/timer.c
> @@ -0,0 +1,165 @@
> +/*
> + * 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>
> +
> +#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) BIT1
> +#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
> +
> +/* This enumerator describe counters\watchdog numbers */
> +typedef enum _kwCntmrID {
> + TIMER0 = 0,
> + TIMER1,
> + WATCHDOG
> +} KW_CNTMR_ID;
> +
> +#define READ_TIMER
> (KW_REG_READ(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 = KW_REG_READ(CNTMR_VAL_REG(UBOOT_CNTR));
> + delayticks = (usec * (CONFIG_SYS_TCLK / 1000000));
> +
> + if (current < delayticks) {
> + delayticks -= current;
> + while (KW_REG_READ(CNTMR_VAL_REG(UBOOT_CNTR)) <
> current) ;
> + while ((TIMER_LOAD_VAL - delayticks) <
> + KW_REG_READ(CNTMR_VAL_REG(UBOOT_CNTR))) ;
> + } else {
> + while (KW_REG_READ(CNTMR_VAL_REG(UBOOT_CNTR)) >
> + (current - delayticks)) ;
> + }
> +}
> +
> +/*
> + * init the counter
> + */
> +int timer_init(void)
> +{
> + unsigned int cntmrCtrl;
> +
> + /* load value onto counter\timer */
> + KW_REG_WRITE(CNTMR_RELOAD_REG(UBOOT_CNTR), TIMER_LOAD_VAL);
> + KW_REG_WRITE(CNTMR_VAL_REG(UBOOT_CNTR), TIMER_LOAD_VAL);
> +
> + /* set the counter to load in the first time */
> + KW_REG_WRITE(CNTMR_VAL_REG(UBOOT_CNTR), TIMER_LOAD_VAL);
> +
> + /* set control for timer \ cunter and enable */
> + /* read control register */
> + cntmrCtrl = KW_REG_READ(CNTMR_CTRL_REG);
> + cntmrCtrl |= CTCR_ARM_TIMER_EN(UBOOT_CNTR); /*
> enable cnt\timer */
> + cntmrCtrl |= CTCR_ARM_TIMER_AUTO_EN(UBOOT_CNTR);
> /* Auto mode */
> +
> + KW_REG_WRITE(CNTMR_CTRL_REG, cntmrCtrl);
> +
> + /* init the timestamp and lastdec value */
> + reset_timer_masked();
> +
> + return 0;
> +}
> diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
> index bb99a34..dd59ff8 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) += 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..6422ab2
> --- /dev/null
> +++ b/drivers/serial/kirkwood_serial.c
> @@ -0,0 +1,187 @@
> +/*
> + * 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>
> +
> +/* registers feilds */
> +#define FCR_FIFO_EN BIT0 /* fifo enable */
> +#define FCR_RXSR BIT1 /* receiver soft reset */
> +#define FCR_TXSR BIT2 /* transmitter soft reset */
> +#define MCR_RTS BIT1 /* 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 BIT0 /* Data ready */
> +#define LSR_OE BIT1 /* Overrun */
> +#define LSR_PE BIT2 /* Parity error */
> +#define LSR_FE BIT3 /* Framing error */
> +#define LSR_BI BIT4 /* Break */
> +#define LSR_THRE BIT5 /* Xmit holding
> register empty */
> +#define LSR_TEMT BIT6 /* Xmitter empty */
> +#define LSR_ERR BIT7 /* 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 */
> +typedef struct kwUartPort {
> + 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];
> +} kw_uart_port;
> +
> +/* aliases - for registers which has the same offsets */
> +#define thr rbr
> +#define iir fcr
> +#define dll rbr
> +#define dlm ier
> +
> +/* static variables */
> +#if defined (CONFIG_CONS_INDEX) /* comes from board config */
> +#if (CONFIG_CONS_INDEX == 0 )
> +static volatile kw_uart_port *p_uart_port = (void
> *)KW_REGISTER(KW_UART0_BASE);
> +#elif (CONFIG_CONS_INDEX == 1 )
> +static volatile 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);
> +}
> +
> +void kwUartPutc(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')
> + kwUartPutc('\r');
> +
> + kwUartPutc(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..f0bc3a7
> --- /dev/null
> +++ b/drivers/spi/kirkwood_spi.c
> @@ -0,0 +1,199 @@
> +/*
> + * (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>
> +
> +/* SPI Registers on kirkwood SOC */
> +#define KW_REG_SPI_CTRL (0x10600)
> +#define KW_REG_SPI_CONFIG (0x10604)
> +#define KW_REG_SPI_DATA_OUT (0x10608)
> +#define KW_REG_SPI_DATA_IN (0x1060c)
> +#define KW_REG_SPI_IRQ_CAUSE (0x10610)
> +#define KW_REG_SPI_IRQ_MASK (0x10614)
> +
> +#define KW_SPI_TIMEOUT 10000
> +
> +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;
> +
> + KW_REG_WRITE(KW_REG_SPI_CTRL, 0x00000002);
> + /* program spi clock prescaller using max_hz */
> + data = ((CONFIG_SYS_TCLK / 2) / max_hz) & 0x0000000f;
> + debug("data = 0x%08x \n", data);
> + KW_REG_WRITE(KW_REG_SPI_CONFIG, 0x00000210 | data);
> + KW_REG_WRITE(KW_REG_SPI_IRQ_CAUSE, 0x00000001);
> + KW_REG_WRITE(KW_REG_SPI_IRQ_MASK, 0x00000000);
> +
> + /* program mpp registers to select SPI_CSn */
> + if (cs)
> + KW_REG_WRITE(KW_REG_MPP_CONTROL0,
> + ((KW_REG_READ(KW_REG_MPP_CONTROL0)
> & 0x0fffffff) |
> + 0x20000000));
> + else
> + KW_REG_WRITE(KW_REG_MPP_CONTROL0,
> + ((KW_REG_READ(KW_REG_MPP_CONTROL0)
> & 0xfffffff0) |
> + 0x00000002));
> +
> + 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)
> +{
> + KW_REG_BITS_SET(KW_REG_SPI_CTRL, BIT0);
> +}
> +
> +void spi_cs_deactivate(struct spi_slave *slave)
> +{
> + KW_REG_BITS_RESET(KW_REG_SPI_CTRL, BIT0);
> +}
> +
> +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;
> + if (1) { //bitlen <= 8) {
> + /*1 byte xfer mode */
> + KW_REG_BITS_RESET(KW_REG_SPI_CONFIG, BIT5);
> + /* Shift data so it's msb-justified */
> + if (dout) {
> + tmpdout = *(u32 *) dout & 0x0ff;
> + }
> + } else {
> + /*2 byte xfer mode */
> + KW_REG_BITS_SET(KW_REG_SPI_CONFIG, BIT5);
> + /* Shift data so it's msb-justified */
> + if (dout) {
> + tmpdout = *(u32 *) dout & 0x0ffff;
> + }
> + }
> +
> + KW_REG_WRITE(KW_REG_SPI_IRQ_CAUSE, 0x0);
> /* clear bit */
> + KW_REG_WRITE(KW_REG_SPI_DATA_OUT, tmpdout);
> /* 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 (KW_REG_READ(KW_REG_SPI_IRQ_CAUSE)) {
> + isRead = 1;
> + tmpdin =
> KW_REG_READ(KW_REG_SPI_DATA_IN);
> + debug
> + ("*** spi_xfer: din %08X
> ... %08x read\n",
> + din, tmpdin);
> +
> + if (1) { //bitlen <= 8) {
> + if (din) {
> + *((u8 *) din) =
> (u8) tmpdin;
> + din += 1;
> + }
> + if (dout)
> + dout += 1;
> + bitlen -= 8;
> + } else {
> + if (din) {
> + *((u16 *) din)
> = (u16) tmpdin;
> + din += 1;
> + }
> + if (dout)
> + dout += 1;
> + bitlen -= 16;
> + }
> + }
> + 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..67d94dc
> --- /dev/null
> +++ b/include/asm-arm/arch-kirkwood/kirkwood.h
> @@ -0,0 +1,142 @@
> +/*
> + * (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-arm/types.h>
> +#endif /* __ASSEMBLY__ */
> +#include <../board/Marvell/include/core.h>
> +
> +#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)
> +
> +#define KW_UART0_BASE (0x12000)
> /* UArt 0 */
> +#define KW_UART1_BASE (0x13000)
> /* UArt 1 */
> +
> +/* Controler environment registers offsets */
> +#define KW_REG_MPP_CONTROL0 (0x10000)
> +#define KW_REG_MPP_CONTROL1 (0x10004)
> +#define KW_REG_MPP_CONTROL2 (0x10008)
> +#define KW_REG_MPP_CONTROL3 (0x1000C)
> +#define KW_REG_MPP_CONTROL4 (0x10010)
> +#define KW_REG_MPP_CONTROL5 (0x10014)
> +#define KW_REG_MPP_CONTROL6 (0x10018)
> +#define KW_REG_MPP_SMPL_AT_RST (0x10030)
> +#define KW_REG_CHIP_BOND (0x10034)
> +#define KW_REG_MPP_OUT_DRV_REG (0x100E0)
> +
> +#define KW_REG_GPP0_DATA_OUT (0x10100)
> +#define KW_REG_GPP0_DATA_OUT_EN (0x10104)
> +#define KW_REG_GPP0_BLINK_EN (0x10108)
> +#define KW_REG_GPP0_DATA_IN_POL (0x1010C)
> +#define KW_REG_GPP0_DATA_IN (0x10110)
> +#define KW_REG_GPP0_INT_CAUSE (0x10114)
> +#define KW_REG_GPP0_INT_MASK (0x10118)
> +#define KW_REG_GPP0_INT_LVL (0x1011c)
> +
> +#define KW_REG_GPP1_DATA_OUT (0x10140)
> +#define KW_REG_GPP1_DATA_OUT_EN (0x10144)
> +#define KW_REG_GPP1_BLINK_EN (0x10148)
> +#define KW_REG_GPP1_DATA_IN_POL (0x1014C)
> +#define KW_REG_GPP1_DATA_IN (0x10150)
> +#define KW_REG_GPP1_INT_CAUSE (0x10154)
> +#define KW_REG_GPP1_INT_MASK (0x10158)
> +#define KW_REG_GPP1_INT_LVL (0x1015c)
> +
> +#define KW_REG_NAND_READ_PARAM (0x10418)
> +#define KW_REG_NAND_WRITE_PARAM (0x1041c)
> +#define KW_REG_NAND_CTRL (0x10470)
> +
> +#define KW_REG_WIN_CTRL(x) (0x20000+(x*0x10))
> +#define KW_REG_WIN_BASE(x) (0x20004+(x*0x10))
> +#define KW_REG_WIN_REMAP_LOW(x) (0x20008+(x*0x10))
> +#define KW_REG_WIN_REMAP_HIGH(x) (0x2000c+(x*0x10))
> +
> +#define KW_REG_CPU_CONFIG (0x20100)
> +#define KW_REG_CPU_CTRL_STAT (0x20104)
> +#define KW_REG_CPU_RSTOUTN_MASK (0x20108)
> +#define KW_REG_CPU_SYS_SOFT_RST (0x2010C)
> +#define KW_REG_CPU_AHB_MBUS_CAUSE_INT (0x20110)
> +#define KW_REG_CPU_AHB_MBUS_MASK_INT (0x20114)
> +#define KW_REG_CPU_FTDLL_CONFIG (0x20120)
> +#define KW_REG_CPU_L2_CONFIG (0x20128)
> +#define KW_REG_L2_RAM_TIMING0 (0x20134)
> +#define KW_REG_L2_RAM_TIMING1 (0x20138)
> +
> +#define KW_REG_TMR_CTRL (0x20300)
> +#define KW_REG_TMR_RELOAD (0x20310)
> +#define KW_REG_TMR_VAL (0x20314)
> +
> +/*
> + * Macros
> + * CPU architecture dependent I/O read/write
> + */
> +#define KW_REG_WRITE(addr, data) \
> + ((*((volatile unsigned int*)(KW_REGISTER(addr)))) \
> + = ((unsigned int)WORD_SWAP((data))))
> +
> +#define KW_REG_READ(addr) \
> + WORD_SWAP(((*((volatile unsigned int*)(KW_REGISTER(addr))))))
> +
> +#define KW_REG_BITS_SET(adr, bits) (KW_REG_WRITE(adr,
> KW_REG_READ(adr)\
> + | ((unsigned
> int)WORD_SWAP(bits))))
> +
> +#define KW_REG_BITS_RESET(adr, bits) (KW_REG_WRITE(adr,
> KW_REG_READ(adr)\
> + & ~((unsigned
> int)WORD_SWAP(bits))))
> +
> +#define KW_REG_READ_ASM(toReg, tmpReg, regOffs) \
> + ldr tmpReg, =KW_REGISTER(regOffs); \
> + ldr toReg, [tmpReg]; \
> + /*WORD_SWAP_ASM(toReg,tmpReg) */
> +
> +#define KW_REG_WRITE_ASM(fromReg, tmpReg, regOffs) \
> + /*WORD_SWAP_ASM(fromReg,tmpReg)*/; \
> + ldr tmpReg, =KW_REGISTER(regOffs); \
> + str fromReg, [tmpReg]
> +
> +/*
> + * Error codes
> + */
> +#define KW_ERROR (-1)
> +#define KW_OK (0)
> +
> +#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@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..45098fb
> --- /dev/null
> +++ b/include/asm-arm/arch-kirkwood/kw88f6281.h
> @@ -0,0 +1,43 @@
> +/*
> + * (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*/
> +#if defined (CONFIG_KW88F6281_Z0)
> +#define CONFIG_SYS_TCLK 166000000 /* 166MHz */
> +#elif defined (CONFIG_KW88F6281_A0)
> +#define CONFIG_SYS_TCLK 200000000 /* 200MHz */
> +#else
> +#error "CONFIG_SYS_TCLK not defined"
> +#endif
> +
> +#endif /* _ASM_ARCH_KW88F6281_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
> --
> 1.5.3.3
>
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* [U-Boot] [PATCH v2] Marvell Kirkwood family SOC support
2009-04-08 12:03 [U-Boot] [PATCH v2] Marvell Kirkwood family SOC support Prafulla Wadaskar
2009-04-14 17:26 ` Prafulla Wadaskar
@ 2009-04-17 9:22 ` Jean-Christophe PLAGNIOL-VILLARD
2009-04-18 6:44 ` Prafulla Wadaskar
1 sibling, 1 reply; 11+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2009-04-17 9:22 UTC (permalink / raw)
To: u-boot
On 17:33 Wed 08 Apr , Prafulla Wadaskar wrote:
> Kirkwood family controllers are highly integrated SOCs
> based on Feroceon-88FR131/Sheeva-88SV131 cpu core.
>
> SOC versions supported:-
> 1) 88F6281-Z0 define CONFIG_KW88F6281_Z0
> 2) 88F6281-A0 define CONFIG_KW88F6281_A0
> 3) 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>
> ---
> Changelog:
> 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
>
> board/Marvell/include/core.h | 4 +
> cpu/arm926ejs/kirkwood/Makefile | 50 ++++++
> cpu/arm926ejs/kirkwood/config.mk | 25 +++
> cpu/arm926ejs/kirkwood/dram.c | 55 +++++++
> cpu/arm926ejs/kirkwood/kwcore.c | 250 +++++++++++++++++++++++++++++
> cpu/arm926ejs/kirkwood/kwcore.h | 47 ++++++
> cpu/arm926ejs/kirkwood/lowlevel_init.S | 183 +++++++++++++++++++++
> cpu/arm926ejs/kirkwood/timer.c | 165 +++++++++++++++++++
> drivers/serial/Makefile | 1 +
> drivers/serial/kirkwood_serial.c | 187 +++++++++++++++++++++
> drivers/spi/Makefile | 1 +
> drivers/spi/kirkwood_spi.c | 199 +++++++++++++++++++++++
> include/asm-arm/arch-kirkwood/kirkwood.h | 142 ++++++++++++++++
> include/asm-arm/arch-kirkwood/kw88f6192.h | 37 +++++
> include/asm-arm/arch-kirkwood/kw88f6281.h | 43 +++++
> include/asm-arm/config.h | 4 +
> 16 files changed, 1393 insertions(+), 0 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
>
> diff --git a/board/Marvell/include/core.h b/board/Marvell/include/core.h
> index c413439..ecc4682 100644
> --- a/board/Marvell/include/core.h
> +++ b/board/Marvell/include/core.h
> @@ -12,9 +12,11 @@ space). The macros take care of Big/Little endian conversions.
> #ifndef __INCcoreh
> #define __INCcoreh
>
> +#ifndef CONFIG_KIRKWOOD
> #include "mv_gen_reg.h"
>
> extern unsigned int INTERNAL_REG_BASE_ADDR;
> +#endif /* CONFIG_KIRKWOOD */
>
> /****************************************/
> /* GENERAL Definitions */
> @@ -91,10 +93,12 @@ extern unsigned int INTERNAL_REG_BASE_ADDR;
> #define _1G 0x40000000
> #define _2G 0x80000000
>
> +#ifndef __ASSEMBLY__
> #ifndef BOOL_WAS_DEFINED
> #define BOOL_WAS_DEFINED
> typedef enum _bool{false,true} bool;
> #endif
> +#endif
>
> /* Little to Big endian conversion macros */
>
> diff --git a/cpu/arm926ejs/kirkwood/Makefile b/cpu/arm926ejs/kirkwood/Makefile
> new file mode 100644
> index 0000000..c917f0d
> --- /dev/null
> +++ b/cpu/arm926ejs/kirkwood/Makefile
> @@ -0,0 +1,50 @@
> +#
> +# (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 += 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@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..80e2b13
> --- /dev/null
> +++ b/cpu/arm926ejs/kirkwood/dram.c
> @@ -0,0 +1,55 @@
> +/*
> + * (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>
> +
> +/*
> + * kw_sdram_bar - reads SDRAM Base Address Register
> + */
> +u32 kw_sdram_bar(MEMORY_BANK bank)
> +{
> + u32 result = 0;
> + u32 enable = (0x01 & KW_REG_READ((0x1504 + bank * 8)));
please create macro for these registers
please use readx/writex (madatory)
> +
> + if ((!enable) || (bank > BANK3))
> + return 0;
> +
> + result = KW_REG_READ((0x1500 + bank * 8));
> + return result;
> +}
> +
> +/*
> + * kw_sdram_bs - reads SDRAM Bank size
> + */
> +u32 kw_sdram_bs(MEMORY_BANK bank)
> +{
> + u32 result = 0;
> + u32 enable = (0x01 & KW_REG_READ((0x1504 + bank * 8)));
> +
> + if ((!enable) || (bank > BANK3))
> + return 0;
> + result = (0xff000000 & KW_REG_READ((0x1504 + bank * 8)));
> + result += 0x01000000;
> + return result;
> +}
> diff --git a/cpu/arm926ejs/kirkwood/kwcore.c b/cpu/arm926ejs/kirkwood/kwcore.c
> new file mode 100644
> index 0000000..2e887d5
> --- /dev/null
> +++ b/cpu/arm926ejs/kirkwood/kwcore.c
> @@ -0,0 +1,250 @@
> +/*
> + * (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 <u-boot/md5.h>
> +
> +void reset_cpu(unsigned long ignored)
> +{
> + KW_REG_BITS_SET(KW_REG_CPU_RSTOUTN_MASK, BIT2);
> + KW_REG_BITS_SET(KW_REG_CPU_SYS_SOFT_RST, BIT0);
plase use readx/writex
everywhere
> + 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];
> +
> +#if defined (CONFIG_KW88F6281_Z0)
> + KW_REG_BITS_SET(0x1478, BIT7);
> +#elif defined (CONFIG_KW88F6281_A0) || defined (CONFIG_KW88F6192_A0)
could you detect it
> + /*
> + * in case of 88F6281/88F6192 A0,
> + * BIT7 need to reset to generate random values in 0x1470
> + */
> + KW_REG_BITS_RESET(0x1478, BIT7);
please use macro everywhere instead of hardcode value
> +#else
> +#error Undefined SOC Revision
> +#endif
> + for (i = 0; i < 16; i++) {
> + inbuf[i] = KW_REG_READ(0x1470);
> + }
> + md5((u8 *) inbuf, 64, outbuf);
> + return outbuf[outbuf[7] % 0x0f];
> +}
> +
> +/*
> + * kw_window_ctrl_reg_init - Mbus-L to Mbus Bridge Registers init.
> + */
> +int kw_window_ctrl_reg_init(void)
> +{
coudl explain a few more what you do and try use macro instead of hardcode
value
> + KW_REG_WRITE(KW_REG_WIN_CTRL(0), 0x0fffe841);
> + KW_REG_WRITE(KW_REG_WIN_BASE(0), 0x90000000);
> + KW_REG_WRITE(KW_REG_WIN_REMAP_LOW(0), 0x90000000);
> + KW_REG_WRITE(KW_REG_WIN_REMAP_HIGH(0), 0x00000000);
> +
> + KW_REG_WRITE(KW_REG_WIN_CTRL(1), 0x007f2f11);
> + KW_REG_WRITE(KW_REG_WIN_BASE(1), 0xF9000000);
> + KW_REG_WRITE(KW_REG_WIN_REMAP_LOW(1), 0xF9000000);
> + KW_REG_WRITE(KW_REG_WIN_REMAP_HIGH(1), 0x00000000);
> +
> + KW_REG_WRITE(KW_REG_WIN_CTRL(2), 0x00ffe041);
> + KW_REG_WRITE(KW_REG_WIN_BASE(2), 0xF0000000);
> + KW_REG_WRITE(KW_REG_WIN_REMAP_LOW(2), 0xC0000000);
> + KW_REG_WRITE(KW_REG_WIN_REMAP_HIGH(2), 0x00000000);
> +
> + KW_REG_WRITE(KW_REG_WIN_CTRL(3), 0x00ff1e11);
> + KW_REG_WRITE(KW_REG_WIN_BASE(3), 0xF8000000);
> + KW_REG_WRITE(KW_REG_WIN_REMAP_LOW(3), 0x00000000);
> + KW_REG_WRITE(KW_REG_WIN_REMAP_HIGH(3), 0x00000000);
> +
> + KW_REG_WRITE(KW_REG_WIN_CTRL(4), 0x00ff1d11);
> + KW_REG_WRITE(KW_REG_WIN_BASE(4), 0xFF000000);
> + KW_REG_WRITE(KW_REG_WIN_REMAP_LOW(4), 0x00000000);
> + KW_REG_WRITE(KW_REG_WIN_REMAP_HIGH(4), 0x00000000);
> +
> + KW_REG_WRITE(KW_REG_WIN_CTRL(5), 0x07ff1e10);
> + KW_REG_WRITE(KW_REG_WIN_BASE(5), 0xE8000000);
> + KW_REG_WRITE(KW_REG_WIN_REMAP_LOW(5), 0x00000000);
> + KW_REG_WRITE(KW_REG_WIN_REMAP_HIGH(5), 0x00000000);
> +
> + KW_REG_WRITE(KW_REG_WIN_CTRL(6), 0x07ff1d10);
> + KW_REG_WRITE(KW_REG_WIN_BASE(6), 0xF0000000);
> + KW_REG_WRITE(KW_REG_WIN_REMAP_LOW(6), 0x00000000);
> + KW_REG_WRITE(KW_REG_WIN_REMAP_HIGH(6), 0x00000000);
> +
> + KW_REG_WRITE(KW_REG_WIN_CTRL(7), 0x00000131);
> + KW_REG_WRITE(KW_REG_WIN_BASE(7), 0xFB000000);
> + KW_REG_WRITE(KW_REG_WIN_REMAP_LOW(7), 0x00000000);
> + KW_REG_WRITE(KW_REG_WIN_REMAP_HIGH(7), 0x00000000);
> +
> + return KW_OK;
> +}
> +
> +/*
> + * kw_gpio_init - Init gpios for default values
> + */
> +void kw_gpio_init(u32 gpp0_oe_val, u32 gpp1_oe_val, u32 gpp0_oe, u32 gpp1_oe)
> +{
> + /* Init GPIOS to default values as per board requirement */
> + KW_REG_WRITE(KW_REG_GPP0_DATA_OUT, gpp0_oe_val);
> + KW_REG_WRITE(KW_REG_GPP1_DATA_OUT, gpp1_oe_val);
> + KW_REG_WRITE(KW_REG_GPP0_DATA_OUT_EN, gpp0_oe);
> + KW_REG_WRITE(KW_REG_GPP1_DATA_OUT_EN, gpp1_oe);
> +}
> +
> +/*
> + * kw_mpp_control_init - initialize mpp for board specific functionality
> + */
> +int kw_mpp_control_init(u32 mpp0_7, u32 mpp8_15, u32 mpp16_23, u32 mpp24_31,
> + u32 mpp32_39, u32 mpp40_47, u32 mpp48_55)
> +{
> + /* program mpp registers */
> + KW_REG_WRITE(KW_REG_MPP_CONTROL0, mpp0_7);
> + KW_REG_WRITE(KW_REG_MPP_CONTROL1, mpp8_15);
> + KW_REG_WRITE(KW_REG_MPP_CONTROL2, mpp16_23);
> + KW_REG_WRITE(KW_REG_MPP_CONTROL3, mpp24_31);
> + KW_REG_WRITE(KW_REG_MPP_CONTROL4, mpp32_39);
> + KW_REG_WRITE(KW_REG_MPP_CONTROL5, mpp40_47);
> + KW_REG_WRITE(KW_REG_MPP_CONTROL6, mpp48_55);
> + return KW_OK;
> +}
> +
> +/*
> + * kw_misc_init_r - SOC specific misc init (mainly cache initialization)
> + */
> +int kw_misc_init_r(void)
> +{
> + char *env;
> + volatile unsigned int temp;
> +
> + /*CPU streaming & write allocate */
> + env = getenv("enaWrAllo");
> + if (env && ((strcmp(env, "yes") == 0) || (strcmp(env, "Yes") == 0))) {
> + __asm__ __volatile__("mrc p15, 1, %0, c15, c1, 0":"=r"(temp));
please cp15 api (the same as the kernel)
set_cr/get_cr
btw could explain why do you need to do it via env?
be aware that we have cache API
> + temp |= BIT28;
> + __asm__ __volatile__("mcr p15, 1, %0, c15, c1, 0"::"r"(temp));
> +
> + } else {
> + __asm__ __volatile__("mrc p15, 1, %0, c15, c1, 0":"=r"(temp));
> + temp &= ~BIT28;
> + __asm__ __volatile__("mcr p15, 1, %0, c15, c1, 0"::"r"(temp));
> + }
> +
<snip>
> +
> diff --git a/cpu/arm926ejs/kirkwood/kwcore.h b/cpu/arm926ejs/kirkwood/kwcore.h
> new file mode 100644
> index 0000000..8d2a8cc
> --- /dev/null
> +++ b/cpu/arm926ejs/kirkwood/kwcore.h
> @@ -0,0 +1,47 @@
> +/*
> + * (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 _KWCORE_H
> +#define _KWCORE_H
> +
> +/*
> + * functions
> + */
> +#ifndef __ASSEMBLY__
> +void reset_cpu(unsigned long ignored);
> +unsigned char get_random_hex(void);
> +typedef enum _memory_bank { BANK0, BANK1, BANK2, BANK3 } MEMORY_BANK;
please do not use upper case
> +unsigned int kw_sdram_bar(MEMORY_BANK bank);
> +unsigned int kw_sdram_bs(MEMORY_BANK bank);
> +int kw_window_ctrl_reg_init(void);
> +void kw_gpio_init(unsigned int gpp0_oe_val, unsigned int gpp1_oe_val,
> + unsigned int gpp0_oe, unsigned int gpp1_oe);
> +int kw_mpp_control_init(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);
> +int kw_misc_init_r(void);
> +#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..169e58b
> --- /dev/null
> +++ b/cpu/arm926ejs/kirkwood/lowlevel_init.S
> @@ -0,0 +1,183 @@
> +/*
> + * (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>
> +
> +#define CCR_CPU_2_MBUSL_TICK_DRV_OFFS 8
> +#define CCR_CPU_2_MBUSL_TICK_DRV_MASK (0xF << CCR_CPU_2_MBUSL_TICK_DRV_OFFS)
> +#define CCR_CPU_2_MBUSL_TICK_SMPL_OFFS 12
> +#define CCR_CPU_2_MBUSL_TICK_SMPL_MASK (0xF << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS)
> +
> +#define MSAR_DDRCLCK_RTIO_OFFS 5
> +#define MSAR_DDRCLCK_RTIO_MASK (0xF << MSAR_DDRCLCK_RTIO_OFFS)
> +
> +/* Ratio options for CPU to DDR for 6281/6192/6180 */
> +#define CPU_2_DDR_CLK_1x2 2
> +#define CPU_2_DDR_CLK_1x3 4
> +#define CPU_2_DDR_CLK_1x4 6
> +
> +/* Default values for CPU to Mbus-L DDR Interface Tick Driver and */
> +/* CPU to Mbus-L Tick Sample fields in CPU config register */
> +
> +#define TICK_DRV_1x1 0
> +#define TICK_DRV_1x2 0
> +#define TICK_DRV_1x3 1
> +#define TICK_DRV_1x4 2
> +#define TICK_SMPL_1x1 0
> +#define TICK_SMPL_1x2 1
> +#define TICK_SMPL_1x3 2
> +#define TICK_SMPL_1x4 3
> +#define CPU_2_MBUSL_DDR_CLK_1x2 \
> + ((TICK_DRV_1x2 << CCR_CPU_2_MBUSL_TICK_DRV_OFFS) | \
> + (TICK_SMPL_1x2 << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS))
> +#define CPU_2_MBUSL_DDR_CLK_1x3 \
> + ((TICK_DRV_1x3 << CCR_CPU_2_MBUSL_TICK_DRV_OFFS) | \
> + (TICK_SMPL_1x3 << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS))
> +#define CPU_2_MBUSL_DDR_CLK_1x4 \
> + ((TICK_DRV_1x4 << CCR_CPU_2_MBUSL_TICK_DRV_OFFS) | \
> + (TICK_SMPL_1x4 << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS))
> +
please move all this define to header corresponding of the functionallity/IP
> +
> + .globl kw_cpu_if_pre_init
> +kw_cpu_if_pre_init:
do you really need to do this before relocation
> +
> + mov r11, LR /* Save link register */
will you call a sub routine?
> +
> + /*
> + * Configures the I/O voltage of the pads connected to Egigabit
> + * Ethernet interface to 1.8V
> + * By defult it is set to 3.3V
> + */
> +#ifdef CONFIG_KIRKWOOD_RGMII_PAD_1V8
> + KW_REG_READ_ASM (r7, r5, KW_REG_MPP_OUT_DRV_REG)
> + ldr r5, =BIT7
> + orr r7, r7, r5 /* Set RGMII PADS Voltage to 1.8V */
> + KW_REG_WRITE_ASM (r7, r5, KW_REG_MPP_OUT_DRV_REG)
> +#endif
> + /*
> + * 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
> + */
> +#ifdef CONFIG_KIRKWOOD_EGIGA_INIT
> + KW_REG_READ_ASM (r7, r5, KW_ETH_PORT_SERIAL_CONTROL1_REG(0))
> + ldr r5, =~(BIT4)
> + and r7, r7, r5 /* Clear PortReset Bit */
> + KW_REG_WRITE_ASM (r7, r5, KW_ETH_PORT_SERIAL_CONTROL1_REG(0))
> +
> + KW_REG_READ_ASM (r7, r5, KW_ETH_PORT_SERIAL_CONTROL1_REG(1))
> + ldr r5, =~(BIT4)
> + and r7, r7, r5 /* Clear PortReset Bit */
> + KW_REG_WRITE_ASM (r7, r5, KW_ETH_PORT_SERIAL_CONTROL1_REG(1))
> +#endif
> +
> + /*
> + * Enable PCI Express Port0
> + */
> +#ifdef CONFIG_KIRKWOOD_PCIE_INIT
> + KW_REG_READ_ASM (r7, r5, KW_REG_CPU_CTRL_STAT)
> + ldr r5, =BIT0
> + orr r7, r7, r5 /* Set PEX0En Bit */
> + KW_REG_WRITE_ASM (r7, r5, KW_REG_CPU_CTRL_STAT)
> +#endif
> +
> +#ifdef CONFIG_KW88F6281_Z0
> + /* Get the "sample on reset" register */
> + KW_REG_READ_ASM (r4, r5, KW_REG_MPP_SMPL_AT_RST)
> + ldr r5, =MSAR_DDRCLCK_RTIO_MASK
> + and r5, r4, r5
> + mov r5, r5, lsr #MSAR_DDRCLCK_RTIO_OFFS
> +
> + ldr r4, =CPU_2_MBUSL_DDR_CLK_1x2
> + cmp r5, #CPU_2_DDR_CLK_1x2
> + beq set_config_reg
> +
> + ldr r4, =CPU_2_MBUSL_DDR_CLK_1x3
> + cmp r5, #CPU_2_DDR_CLK_1x3
> + beq set_config_reg
> +
> + ldr r4, =CPU_2_MBUSL_DDR_CLK_1x4
> + cmp r5, #CPU_2_DDR_CLK_1x4
> + beq set_config_reg
> +
> + ldr r4, =0
> +
> +set_config_reg:
> + /* Read CPU Config register */
> + KW_REG_READ_ASM (r7, r5, KW_REG_CPU_CONFIG)
> + ldr r5, =~(CCR_CPU_2_MBUSL_TICK_DRV_MASK | CCR_CPU_2_MBUSL_TICK_SMPL_MASK)
> + and r7, r7, r5 /* Clear register fields */
> + orr r7, r7, r4 /* Set the values according to the findings */
> + KW_REG_WRITE_ASM (r7, r5, KW_REG_CPU_CONFIG)
> +
> +done:
> +#endif
> + mov PC, r11 /* r11 is saved link register */
> +
> + .globl kw_enable_invalidate_l2_cache
> +kw_enable_invalidate_l2_cache:
> + mov r11, LR /* Save link register */
> +
> + /* Enable L2 cache in write through mode */
> + KW_REG_READ_ASM(r4, r1, KW_REG_CPU_L2_CONFIG)
please remove thhis KW_RED_READ_ASM
or do it via asm macro as we have done for sh2/3/4
> + orr r4, r4, #0x18
> + KW_REG_WRITE_ASM(r4, r1, KW_REG_CPU_L2_CONFIG)
> + /* Read operation to make sure the L2 bit is set */
> + KW_REG_READ_ASM(r4, r1, KW_REG_CPU_L2_CONFIG)
> +
> + /* invalidate L2 cache */
> + mov r0, #0
> + mcr p15, 1, r0, c15, c11, 0
please create a macro for this
> +
> + mov PC, r11 /* r11 is saved link register */
> +
> + .globl lowlevel_init
in this case call it arch_lowlevel_init
and update start.S to call it just be the lowlevel_init
which is board lowlevel init
> +lowlevel_init:
if you have multple sub call use the stack will be beter
> + /* Linux expects` the internal registers to be at 0xf1000000 */
> + ldr r1, = KW_OFFSET_REG
> + ldr r3, = KW_REGS_PHY_BASE
> + str r3,[r1]
> +
> + /* save Link Registers */
> + mov r2, lr
> +
> + /* Enable L2 cache in write through mode */
> + bl kw_enable_invalidate_l2_cache
> +
> +#ifdef CONFIG_BOARD_LOWLEVEL_INIT
> + /*
> + * if Kirkwood is configured not to use its internal bootROM
> + * This will be needed specially for DRAM configuration
> + */
> + bl board_lowlevel_init
> +#endif
> +
> + /*
> + * Initialize BUS-L to DDR configuration parameters
> + * Must be done prior to DDR operation
> + */
> + bl kw_cpu_if_pre_init
> + mov lr, r2
> + mov pc, lr
> diff --git a/cpu/arm926ejs/kirkwood/timer.c b/cpu/arm926ejs/kirkwood/timer.c
> new file mode 100644
> index 0000000..4ab1a54
> --- /dev/null
> +++ b/cpu/arm926ejs/kirkwood/timer.c
> @@ -0,0 +1,165 @@
> +/*
> + * 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>
> +
> +#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)
please no uppercase in the var name
> +
> +/*
> + * 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) BIT1
> +#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
please move all this define to a header
and nearly all precedent comment can be apply to the rest of the patch
Best Regards,
J.
^ permalink raw reply [flat|nested] 11+ messages in thread
* [U-Boot] [PATCH v2] Marvell Kirkwood family SOC support
2009-04-17 9:22 ` Jean-Christophe PLAGNIOL-VILLARD
@ 2009-04-18 6:44 ` Prafulla Wadaskar
2009-04-18 7:23 ` Jean-Christophe PLAGNIOL-VILLARD
0 siblings, 1 reply; 11+ messages in thread
From: Prafulla Wadaskar @ 2009-04-18 6:44 UTC (permalink / raw)
To: u-boot
Hi Jean
Thanks for your review comments.
> -----Original Message-----
> From: Jean-Christophe PLAGNIOL-VILLARD [mailto:plagnioj at jcrosoft.com]
> Sent: Friday, April 17, 2009 2:52 PM
> To: Prafulla Wadaskar
> Cc: u-boot at lists.denx.de; Ashish Karkare; Ronen Shitrit
> Subject: Re: [U-Boot] [PATCH v2] Marvell Kirkwood family SOC support
>
> On 17:33 Wed 08 Apr , Prafulla Wadaskar wrote:
> > Kirkwood family controllers are highly integrated SOCs based on
> > Feroceon-88FR131/Sheeva-88SV131 cpu core.
> >
> > SOC versions supported:-
> > 1) 88F6281-Z0 define CONFIG_KW88F6281_Z0
> > 2) 88F6281-A0 define CONFIG_KW88F6281_A0
> > 3) 88F6192-A0 define CONFIG_KW88F6192_A0
> >
> > Other supported features:-
> > 1) get_random_hex() fucntion
> > 2) SPI port controller driver
> > 3) PCI Express port initialization
> > +/*
> > + * kw_sdram_bar - reads SDRAM Base Address Register */
> > +u32 kw_sdram_bar(MEMORY_BANK bank)
> > +{
> > + u32 result = 0;
> > + u32 enable = (0x01 & KW_REG_READ((0x1504 + bank * 8)));
> please create macro for these registers
This will be taken care....
> please use readx/writex (madatory)
You mean instead of KW_REG_READ to be used readx() ?
> > +
> > +void reset_cpu(unsigned long ignored) {
> > + KW_REG_BITS_SET(KW_REG_CPU_RSTOUTN_MASK, BIT2);
> > + KW_REG_BITS_SET(KW_REG_CPU_SYS_SOFT_RST, BIT0);
> plase use readx/writex
> everywhere
Okay...
> > +
> > +#if defined (CONFIG_KW88F6281_Z0)
> > + KW_REG_BITS_SET(0x1478, BIT7);
> > +#elif defined (CONFIG_KW88F6281_A0) || defined
> (CONFIG_KW88F6192_A0)
> could you detect it
I should be able to detect it, I will check and update the same
> > + /*
> > + * in case of 88F6281/88F6192 A0,
> > + * BIT7 need to reset to generate random values in 0x1470
> > + */
> > + KW_REG_BITS_RESET(0x1478, BIT7);
> please use macro everywhere instead of hardcode value
Okay..
> > +
> > +/*
> > + * kw_window_ctrl_reg_init - Mbus-L to Mbus Bridge Registers init.
> > + */
> > +int kw_window_ctrl_reg_init(void)
> > +{
> coudl explain a few more what you do and try use macro
> instead of hardcode value
Macros will be used..
I will put the explaination in the comment for this function
> > + KW_REG_WRITE(KW_REG_WIN_CTRL(0), 0x0fffe841);
> > + KW_REG_WRITE(KW_REG_WIN_BASE(0), 0x90000000);
> > + KW_REG_WRITE(KW_REG_WIN_REMAP_LOW(0), 0x90000000);
> > + KW_REG_WRITE(KW_REG_WIN_REMAP_HIGH(0), 0x00000000);
> > +
> > +#ifndef __ASSEMBLY__
> > +void reset_cpu(unsigned long ignored); unsigned char
> > +get_random_hex(void); typedef enum _memory_bank { BANK0, BANK1,
> > +BANK2, BANK3 } MEMORY_BANK;
> please do not use upper case
You mean MEMORY_BANK, right? I will change it
> > + (TICK_SMPL_1x3 << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS))
> > +#define CPU_2_MBUSL_DDR_CLK_1x4
> \
> > + ((TICK_DRV_1x4 <<
> CCR_CPU_2_MBUSL_TICK_DRV_OFFS) | \
> > + (TICK_SMPL_1x4 << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS))
> > +
> please move all this define to header corresponding of the
> functionallity/IP
I thought these are only settings limited to this file only, any way I will create and move them to header file
> > +
> > + .globl kw_cpu_if_pre_init
> > +kw_cpu_if_pre_init:
> do you really need to do this before relocation
Yes..
> > +
> > + mov r11, LR /* Save link register */
> will you call a sub routine?
I will do it?
> > + .globl kw_enable_invalidate_l2_cache
> > +kw_enable_invalidate_l2_cache:
> > + mov r11, LR /* Save link register */
> > +
> > + /* Enable L2 cache in write through mode */
> > + KW_REG_READ_ASM(r4, r1, KW_REG_CPU_L2_CONFIG)
> please remove thhis KW_RED_READ_ASM
> or do it via asm macro as we have done for sh2/3/4
I will check this...
> > +
> > + /* invalidate L2 cache */
> > + mov r0, #0
> > + mcr p15, 1, r0, c15, c11, 0
> please create a macro for this
Okay...
> > +
> > + mov PC, r11 /* r11 is saved link register */
> > +
> > + .globl lowlevel_init
>
> in this case call it arch_lowlevel_init
>
> and update start.S to call it just be the lowlevel_init
You mean to add support for arch_lowlevel_init, using some CONFIG_ option ?
>
> which is board lowlevel init
>
> > +lowlevel_init:
> if you have multple sub call use the stack will be beter
That's good idea, I will do it
> > +/*
> > + * 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)
> please no uppercase in the var name
Okay..
> > +/*
> > + * 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
> please move all this define to a header
Okay...
Thanks and regards....
Prafulla . .
>
> and nearly all precedent comment can be apply to the rest of the patch
>
> Best Regards,
> J.
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* [U-Boot] [PATCH v2] Marvell Kirkwood family SOC support
2009-04-18 6:44 ` Prafulla Wadaskar
@ 2009-04-18 7:23 ` Jean-Christophe PLAGNIOL-VILLARD
2009-04-19 6:32 ` Prafulla Wadaskar
0 siblings, 1 reply; 11+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2009-04-18 7:23 UTC (permalink / raw)
To: u-boot
On 23:44 Fri 17 Apr , Prafulla Wadaskar wrote:
> Hi Jean
>
> Thanks for your review comments.
>
> > -----Original Message-----
> > From: Jean-Christophe PLAGNIOL-VILLARD [mailto:plagnioj at jcrosoft.com]
> > Sent: Friday, April 17, 2009 2:52 PM
> > To: Prafulla Wadaskar
> > Cc: u-boot at lists.denx.de; Ashish Karkare; Ronen Shitrit
> > Subject: Re: [U-Boot] [PATCH v2] Marvell Kirkwood family SOC support
> >
> > On 17:33 Wed 08 Apr , Prafulla Wadaskar wrote:
> > > Kirkwood family controllers are highly integrated SOCs based on
> > > Feroceon-88FR131/Sheeva-88SV131 cpu core.
> > >
> > > SOC versions supported:-
> > > 1) 88F6281-Z0 define CONFIG_KW88F6281_Z0
> > > 2) 88F6281-A0 define CONFIG_KW88F6281_A0
> > > 3) 88F6192-A0 define CONFIG_KW88F6192_A0
> > >
> > > Other supported features:-
> > > 1) get_random_hex() fucntion
> > > 2) SPI port controller driver
> > > 3) PCI Express port initialization
> > > +/*
> > > + * kw_sdram_bar - reads SDRAM Base Address Register */
> > > +u32 kw_sdram_bar(MEMORY_BANK bank)
> > > +{
> > > + u32 result = 0;
> > > + u32 enable = (0x01 & KW_REG_READ((0x1504 + bank * 8)));
> > please create macro for these registers
> This will be taken care....
> > please use readx/writex (madatory)
> You mean instead of KW_REG_READ to be used readx() ?
readl I guess
take a look in include/arm-asm/io.h
>
> > > +
> > > +void reset_cpu(unsigned long ignored) {
> > > + KW_REG_BITS_SET(KW_REG_CPU_RSTOUTN_MASK, BIT2);
> > > + KW_REG_BITS_SET(KW_REG_CPU_SYS_SOFT_RST, BIT0);
> > plase use readx/writex
> > everywhere
> Okay...
>
> > > +
> > > +#if defined (CONFIG_KW88F6281_Z0)
> > > + KW_REG_BITS_SET(0x1478, BIT7);
> > > +#elif defined (CONFIG_KW88F6281_A0) || defined
> > (CONFIG_KW88F6192_A0)
> > could you detect it
> I should be able to detect it, I will check and update the same
>
> > > + /*
> > > + * in case of 88F6281/88F6192 A0,
> > > + * BIT7 need to reset to generate random values in 0x1470
> > > + */
> > > + KW_REG_BITS_RESET(0x1478, BIT7);
> > please use macro everywhere instead of hardcode value
> Okay..
>
> > > +
> > > +/*
> > > + * kw_window_ctrl_reg_init - Mbus-L to Mbus Bridge Registers init.
> > > + */
> > > +int kw_window_ctrl_reg_init(void)
> > > +{
> > coudl explain a few more what you do and try use macro
> > instead of hardcode value
> Macros will be used..
> I will put the explaination in the comment for this function
>
> > > + KW_REG_WRITE(KW_REG_WIN_CTRL(0), 0x0fffe841);
> > > + KW_REG_WRITE(KW_REG_WIN_BASE(0), 0x90000000);
> > > + KW_REG_WRITE(KW_REG_WIN_REMAP_LOW(0), 0x90000000);
> > > + KW_REG_WRITE(KW_REG_WIN_REMAP_HIGH(0), 0x00000000);
> > > +
>
> > > +#ifndef __ASSEMBLY__
> > > +void reset_cpu(unsigned long ignored); unsigned char
> > > +get_random_hex(void); typedef enum _memory_bank { BANK0, BANK1,
> > > +BANK2, BANK3 } MEMORY_BANK;
> > please do not use upper case
> You mean MEMORY_BANK, right? I will change it
yes
>
>
> > > + (TICK_SMPL_1x3 << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS))
> > > +#define CPU_2_MBUSL_DDR_CLK_1x4
> > \
> > > + ((TICK_DRV_1x4 <<
> > CCR_CPU_2_MBUSL_TICK_DRV_OFFS) | \
> > > + (TICK_SMPL_1x4 << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS))
> > > +
> > please move all this define to header corresponding of the
> > functionallity/IP
> I thought these are only settings limited to this file only, any way I will create and move them to header file
>
> > > +
> > > + .globl kw_cpu_if_pre_init
> > > +kw_cpu_if_pre_init:
> > do you really need to do this before relocation
> Yes..
could add comment to explain why
>
> > > +
> > > + mov r11, LR /* Save link register */
> > will you call a sub routine?
> I will do it?
>
> > > + .globl kw_enable_invalidate_l2_cache
> > > +kw_enable_invalidate_l2_cache:
> > > + mov r11, LR /* Save link register */
> > > +
> > > + /* Enable L2 cache in write through mode */
> > > + KW_REG_READ_ASM(r4, r1, KW_REG_CPU_L2_CONFIG)
> > please remove thhis KW_RED_READ_ASM
> > or do it via asm macro as we have done for sh2/3/4
> I will check this...
attached a first version of macro.h file for arm
>
>
> > > +
> > > + /* invalidate L2 cache */
> > > + mov r0, #0
> > > + mcr p15, 1, r0, c15, c11, 0
> > please create a macro for this
> Okay...
>
> > > +
> > > + mov PC, r11 /* r11 is saved link register */
> > > +
> > > + .globl lowlevel_init
> >
> > in this case call it arch_lowlevel_init
> >
> > and update start.S to call it just be the lowlevel_init
> You mean to add support for arch_lowlevel_init, using some CONFIG_ option ?
yes
CONFIG_ARCH_LOWLEVEL_INIT
Best Regards,
J.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: macro.h
Type: text/x-chdr
Size: 1374 bytes
Desc: not available
Url : http://lists.denx.de/pipermail/u-boot/attachments/20090418/9678bb62/attachment-0001.h
^ permalink raw reply [flat|nested] 11+ messages in thread
* [U-Boot] [PATCH v2] Marvell Kirkwood family SOC support
2009-04-18 7:23 ` Jean-Christophe PLAGNIOL-VILLARD
@ 2009-04-19 6:32 ` Prafulla Wadaskar
2009-04-23 14:16 ` [U-Boot] [PATCH v3] " Prafulla Wadaskar
2009-04-23 14:19 ` [U-Boot] [PATCH v3] Marvell MV88F6281GTW_GE Board support Prafulla Wadaskar
0 siblings, 2 replies; 11+ messages in thread
From: Prafulla Wadaskar @ 2009-04-19 6:32 UTC (permalink / raw)
To: u-boot
> > > > + u32 enable = (0x01 & KW_REG_READ((0x1504 + bank * 8)));
> > > please create macro for these registers
> > This will be taken care....
> > > please use readx/writex (madatory)
> > You mean instead of KW_REG_READ to be used readx() ?
> readl I guess
>
> take a look in include/arm-asm/io.h
I understood... Thanks
> > > > +
> > > > + .globl kw_cpu_if_pre_init
> > > > +kw_cpu_if_pre_init:
> > > do you really need to do this before relocation
> > Yes..
> could add comment to explain why
Okay I will add..
> > > please remove thhis KW_RED_READ_ASM
> > > or do it via asm macro as we have done for sh2/3/4
> > I will check this...
> attached a first version of macro.h file for arm
Thanks ....
> > > and update start.S to call it just be the lowlevel_init
> > You mean to add support for arch_lowlevel_init, using some
> CONFIG_ option ?
> yes
> CONFIG_ARCH_LOWLEVEL_INIT
Okay, I will release a small separate patch for this because this will be generic to arm other SOCs too
Regards..
Prafulla . .
>
> Best Regards,
> J.
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* [U-Boot] [PATCH v3] Marvell Kirkwood family SOC support
2009-04-19 6:32 ` Prafulla Wadaskar
@ 2009-04-23 14:16 ` Prafulla Wadaskar
2009-04-23 16:21 ` Jean-Christophe PLAGNIOL-VILLARD
2009-04-23 14:19 ` [U-Boot] [PATCH v3] Marvell MV88F6281GTW_GE Board support Prafulla Wadaskar
1 sibling, 1 reply; 11+ messages in thread
From: Prafulla Wadaskar @ 2009-04-23 14:16 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() function
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 comments for v2
board/Marvell/include/core.h | 4 +
cpu/arm926ejs/kirkwood/Makefile | 49 +++++
cpu/arm926ejs/kirkwood/config.mk | 25 +++
cpu/arm926ejs/kirkwood/dram.c | 57 ++++++
cpu/arm926ejs/kirkwood/kwcore.c | 304 +++++++++++++++++++++++++++++
cpu/arm926ejs/kirkwood/kwcore.h | 112 +++++++++++
cpu/arm926ejs/kirkwood/lowlevel_init.c | 93 +++++++++
cpu/arm926ejs/kirkwood/timer.c | 165 ++++++++++++++++
cpu/arm926ejs/start.S | 7 +-
drivers/serial/Makefile | 1 +
drivers/serial/kirkwood_serial.c | 187 ++++++++++++++++++
drivers/spi/Makefile | 1 +
drivers/spi/kirkwood_spi.c | 199 +++++++++++++++++++
include/asm-arm/arch-kirkwood/kirkwood.h | 140 +++++++++++++
include/asm-arm/arch-kirkwood/kw88f6192.h | 37 ++++
include/asm-arm/arch-kirkwood/kw88f6281.h | 37 ++++
include/asm-arm/config.h | 4 +
17 files changed, 1421 insertions(+), 1 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.c
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
diff --git a/board/Marvell/include/core.h b/board/Marvell/include/core.h
index c413439..ecc4682 100644
--- a/board/Marvell/include/core.h
+++ b/board/Marvell/include/core.h
@@ -12,9 +12,11 @@ space). The macros take care of Big/Little endian conversions.
#ifndef __INCcoreh
#define __INCcoreh
+#ifndef CONFIG_KIRKWOOD
#include "mv_gen_reg.h"
extern unsigned int INTERNAL_REG_BASE_ADDR;
+#endif /* CONFIG_KIRKWOOD */
/****************************************/
/* GENERAL Definitions */
@@ -91,10 +93,12 @@ extern unsigned int INTERNAL_REG_BASE_ADDR;
#define _1G 0x40000000
#define _2G 0x80000000
+#ifndef __ASSEMBLY__
#ifndef BOOL_WAS_DEFINED
#define BOOL_WAS_DEFINED
typedef enum _bool{false,true} bool;
#endif
+#endif
/* Little to Big endian conversion macros */
diff --git a/cpu/arm926ejs/kirkwood/Makefile b/cpu/arm926ejs/kirkwood/Makefile
new file mode 100644
index 0000000..9f9aed2
--- /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 += kwcore.o
+COBJS-$(CONFIG_ARCH_LOWLEVEL_INIT) += lowlevel_init.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/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@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..03f3277
--- /dev/null
+++ b/cpu/arm926ejs/kirkwood/dram.c
@@ -0,0 +1,57 @@
+/*
+ * (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>
+
+#define KW_REG_CPUCS_WIN_BAR(x) (0x1500+ (x * 0x08))
+#define KW_REG_CPUCS_WIN_SZ(x) (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..df57f4c
--- /dev/null
+++ b/cpu/arm926ejs/kirkwood/kwcore.c
@@ -0,0 +1,304 @@
+/*
+ * (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 <u-boot/md5.h>
+
+void reset_cpu(unsigned long ignored)
+{
+ writel_set_bits(KW_REG_CPU_RSTOUTN_MASK, 1<<2);
+ writel_set_bits(KW_REG_CPU_SYS_SOFT_RST, 1<<0);
+ 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 0x1470
+ * Soc reg offsets 0x1470 and 0x1478 are reserved regs and
+ * Does not have names@this moment (no errata available)
+ */
+ writel_reset_bits(0x1478, 1<<7);
+ for (i = 0; i < 16; i++) {
+ inbuf[i] = readl(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?EUR(tm)s followed by
+ * sequence of 0?EUR(tm)s. The number of 1?EUR(tm)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_window_ctrl_reg_init - Mbus-L to Mbus Bridge Registers init.
+ *
+ * Ref: Sec 25.1 and 25.3 of Datasheet
+ * The CPU interfaces with the device units over the Mbus-L to Mbus bridge.
+ * This bridge forwards CPU transactions to the device units over the Mbus,
+ * and forwards read responses back from the units to the CPU.
+ *
+ * NOTE: If the remap function for this register is not used,
+ * the <Remap> field in the Window0 Remap Low Register must be set to same
+ * value as the <Base> field in this register
+ */
+int kw_window_ctrl_reg_init(void)
+{
+ writel(KW_REG_WIN_CTRL(0),
+ KWCPU_WIN_CTRL_DATA(0xc0000, KWCPU_TARGET_PCIE,
+ KWCPU_ATTR_PCIE_MEM, KWCPU_WIN_ENABLE));
+
+ writel(KW_REG_WIN_BASE(0), 0x90000000);
+ writel(KW_REG_WIN_REMAP_LOW(0), 0x90000000);
+ writel(KW_REG_WIN_REMAP_HIGH(0), 0x00000000);
+
+ writel(KW_REG_WIN_CTRL(1),
+ KWCPU_WIN_CTRL_DATA(0x70000, KWCPU_TARGET_MEMORY,
+ KWCPU_ATTR_NANDFLASH, KWCPU_WIN_ENABLE));
+ writel(KW_REG_WIN_BASE(1), 0xF9000000);
+ writel(KW_REG_WIN_REMAP_LOW(1), 0xF9000000);
+ writel(KW_REG_WIN_REMAP_HIGH(1), 0x00000000);
+
+ writel(KW_REG_WIN_CTRL(2),
+ KWCPU_WIN_CTRL_DATA(0x80000, KWCPU_TARGET_PCIE,
+ KWCPU_ATTR_PCIE_IO, KWCPU_WIN_ENABLE));
+ writel(KW_REG_WIN_BASE(2), 0xF0000000);
+ writel(KW_REG_WIN_REMAP_LOW(2), 0xC0000000);
+ writel(KW_REG_WIN_REMAP_HIGH(2), 0x00000000);
+
+ writel(KW_REG_WIN_CTRL(3),
+ KWCPU_WIN_CTRL_DATA(0x80000, KWCPU_TARGET_MEMORY,
+ KWCPU_ATTR_SPIFLASH, KWCPU_WIN_ENABLE));
+ writel(KW_REG_WIN_BASE(3), 0xF8000000);
+ writel(KW_REG_WIN_REMAP_LOW(3), 0x00000000);
+ writel(KW_REG_WIN_REMAP_HIGH(3), 0x00000000);
+
+ writel(KW_REG_WIN_CTRL(4),
+ KWCPU_WIN_CTRL_DATA(0x80000, KWCPU_TARGET_MEMORY,
+ KWCPU_ATTR_BOOTROM, KWCPU_WIN_ENABLE));
+ writel(KW_REG_WIN_BASE(4), 0xFF000000);
+ writel(KW_REG_WIN_REMAP_LOW(4), 0x00000000);
+ writel(KW_REG_WIN_REMAP_HIGH(4), 0x00000000);
+
+ writel(KW_REG_WIN_CTRL(5),
+ KWCPU_WIN_CTRL_DATA(0xb0000, KWCPU_TARGET_MEMORY,
+ KWCPU_ATTR_SPIFLASH, KWCPU_WIN_DISABLE));
+ writel(KW_REG_WIN_BASE(5), 0xE8000000);
+ writel(KW_REG_WIN_REMAP_LOW(5), 0x00000000);
+ writel(KW_REG_WIN_REMAP_HIGH(5), 0x00000000);
+
+ writel(KW_REG_WIN_CTRL(6),
+ KWCPU_WIN_CTRL_DATA(0xb0000, KWCPU_TARGET_MEMORY,
+ KWCPU_ATTR_BOOTROM, KWCPU_WIN_DISABLE));
+ writel(KW_REG_WIN_BASE(6), 0xF0000000);
+ writel(KW_REG_WIN_REMAP_LOW(6), 0x00000000);
+ writel(KW_REG_WIN_REMAP_HIGH(6), 0x00000000);
+
+ writel(KW_REG_WIN_CTRL(7),
+ KWCPU_WIN_CTRL_DATA(0x0, KWCPU_TARGET_SASRAM, KWCPU_ATTR_SASRAM,
+ KWCPU_WIN_ENABLE));
+ writel(KW_REG_WIN_BASE(7), 0xFB000000);
+ writel(KW_REG_WIN_REMAP_LOW(7), 0x00000000);
+ writel(KW_REG_WIN_REMAP_HIGH(7), 0x00000000);
+
+ return KW_OK;
+}
+
+/*
+ * kw_gpio_init - Init gpios for default values
+ */
+void kw_gpio_init(u32 gpp0_oe_val, u32 gpp1_oe_val, u32 gpp0_oe, u32 gpp1_oe)
+{
+ /* Init GPIOS to default values as per board requirement */
+ writel(KW_REG_GPP0_DATA_OUT, gpp0_oe_val);
+ writel(KW_REG_GPP1_DATA_OUT, gpp1_oe_val);
+ writel(KW_REG_GPP0_DATA_OUT_EN, gpp0_oe);
+ writel(KW_REG_GPP1_DATA_OUT_EN, gpp1_oe);
+}
+
+/*
+ * kw_mpp_control_init - initialize mpp for board specific functionality
+ */
+int kw_mpp_control_init(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(KW_REG_MPP_CONTROL0, mpp0_7);
+ writel(KW_REG_MPP_CONTROL1, mpp8_15);
+ writel(KW_REG_MPP_CONTROL2, mpp16_23);
+ writel(KW_REG_MPP_CONTROL3, mpp24_31);
+ writel(KW_REG_MPP_CONTROL4, mpp32_39);
+ writel(KW_REG_MPP_CONTROL5, mpp40_47);
+ writel(KW_REG_MPP_CONTROL6, mpp48_55);
+ return KW_OK;
+}
+
+char *kwsoc_name(void)
+{
+ switch (readl(KW_REG_DEVICE_ID) & 0x03) {
+ case 1:
+ return ("88F6192_A0");
+ break;
+ case 2:
+ return ("88F6281_A0");
+ break;
+ default:
+ return ("Unknown");
+ }
+}
+
+/*
+ * kw_misc_init_r - SOC specific misc init (mainly cache initialization)
+ */
+int kw_misc_init_r(void)
+{
+ char *env;
+ volatile unsigned int temp;
+
+ printf("SoC: %s\n", kwsoc_name());
+
+ /*CPU streaming & write allocate */
+ env = getenv("enaWrAllo");
+ temp = readfr_extra_feature_reg();
+ if (env && ((strcmp(env, "yes") == 0) || (strcmp(env, "Yes") == 0)))
+ temp |= 1<<28; /*Enable wr alloc */
+ else
+ temp &= ~1<<28; /*disable wr alloc */
+ writefr_extra_feature_reg(temp);
+
+ env = getenv("enaCpuStream");
+ temp = readfr_extra_feature_reg();
+ if (!env || (strcmp(env, "no") == 0) || (strcmp(env, "No") == 0))
+ temp &= ~1<<29; /* streaming disabled */
+ else
+ temp |= 1<<29; /*streaming enabled */
+ writefr_extra_feature_reg(temp);
+
+ /* Verify write allocate and streaming */
+ printf("\n");
+ temp = readfr_extra_feature_reg();
+ if (temp & 1<<29)
+ printf("Streaming enabled\n");
+ else
+ printf("Streaming disabled\n");
+ if (temp & 1<<28)
+ printf("Write allocate enabled\n");
+ else
+ printf("Write allocate disabled\n");
+
+ /* DCache Pref */
+ env = getenv("enaDCPref");
+ if (env && ((strcmp(env, "yes") == 0) || (strcmp(env, "Yes") == 0))) {
+ temp = readl(KW_REG_CPU_CONFIG);
+ temp |= 1<<17; /* Set CCR_DCACH_PREF_BUF_ENABLE */
+ writel(KW_REG_CPU_CONFIG, temp);
+ }
+
+ if (env && ((strcmp(env, "no") == 0) || (strcmp(env, "No") == 0))) {
+ temp = readl(KW_REG_CPU_CONFIG);
+ temp &= ~1<<17; /* Reset CCR_DCACH_PREF_BUF_ENABLE */
+ writel(KW_REG_CPU_CONFIG, temp);
+ }
+
+ /* ICache Pref */
+ env = getenv("enaICPref");
+ if (env && ((strcmp(env, "yes") == 0) || (strcmp(env, "Yes") == 0))) {
+ temp = readl(KW_REG_CPU_CONFIG);
+ temp |= 1<<16; /* Set CCR_ICACH_PREF_BUF_ENABLE */
+ writel(KW_REG_CPU_CONFIG, temp);
+ }
+
+ if (env && ((strcmp(env, "no") == 0) || (strcmp(env, "No") == 0))) {
+ temp = readl(KW_REG_CPU_CONFIG);
+ temp &= ~1<<16; /* Reset CCR_ICACH_PREF_BUF_ENABLE */
+ writel(KW_REG_CPU_CONFIG, temp);
+ }
+ /* Set L2C WT mode - Set bit 4 */
+ temp = readl(KW_REG_CPU_L2_CONFIG);
+ env = getenv("setL2CacheWT");
+ if (!env || ((strcmp(env, "yes") == 0) || (strcmp(env, "Yes") == 0))) {
+ temp |= 1<<4;
+ } else
+ temp &= ~1<<4;
+ writel(KW_REG_CPU_L2_CONFIG, temp);
+
+ /* L2Cache settings */
+ asm("mrc p15, 1, %0, c15, c1, 0":"=r"(temp));
+
+ /* Disable L2C pre fetch - Set bit 24 */
+ env = getenv("disL2Prefetch");
+ if (env && ((strcmp(env, "no") == 0) || (strcmp(env, "No") == 0)))
+ temp &= ~1<<24;
+ else
+ temp |= 1<<24;
+
+ /* enable L2C - Set bit 22 */
+ env = getenv("disL2Cache");
+ if (!env || ((strcmp(env, "no") == 0) || (strcmp(env, "No") == 0)))
+ temp |= 1<<22;
+ else
+ temp &= ~1<<22;
+
+ asm("mcr p15, 1, %0, c15, c1, 0": :"r"(temp));
+
+ /* Enable i cache */
+ asm("mrc p15, 0, %0, c1, c0, 0":"=r"(temp));
+ temp |= 1<<12;
+ asm("mcr p15, 0, %0, c1, c0, 0": :"r"(temp));
+ /* Change reset vector to address 0x0 */
+ asm("mrc p15, 0, %0, c1, c0, 0":"=r"(temp));
+ temp &= ~1<<13;
+ asm("mcr p15, 0, %0, c1, c0, 0": :"r"(temp));
+
+ return (0);
+}
+
diff --git a/cpu/arm926ejs/kirkwood/kwcore.h b/cpu/arm926ejs/kirkwood/kwcore.h
new file mode 100644
index 0000000..feec86b
--- /dev/null
+++ b/cpu/arm926ejs/kirkwood/kwcore.h
@@ -0,0 +1,112 @@
+/*
+ * (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 _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();
+}
+
+/*
+ * 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();
+}
+
+/*
+ * 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_window_ctrl_reg_init(void);
+void kw_gpio_init(unsigned int gpp0_oe_val, unsigned int gpp1_oe_val,
+ unsigned int gpp0_oe, unsigned int gpp1_oe);
+int kw_mpp_control_init(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);
+int kw_misc_init_r(void);
+#endif /* __ASSEMBLY__ */
+
+#endif /* _KWCORE_H */
diff --git a/cpu/arm926ejs/kirkwood/lowlevel_init.c b/cpu/arm926ejs/kirkwood/lowlevel_init.c
new file mode 100644
index 0000000..21bfc81
--- /dev/null
+++ b/cpu/arm926ejs/kirkwood/lowlevel_init.c
@@ -0,0 +1,93 @@
+/*
+ * (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>
+
+void kw_cpu_if_pre_init(void)
+{
+ u32 reg;
+
+#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(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((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((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(KW_REG_CPU_CTRL_STAT, ®);
+#endif
+}
+
+void kw_enable_invalidate_l2_cache(void)
+{
+ u32 reg;
+
+ /* Enable L2 cache in write through mode */
+ reg = readl(KW_REG_CPU_L2_CONFIG);
+ reg |= 0x18;
+ writel(KW_REG_CPU_L2_CONFIG, reg);
+ /* Read operation to make sure the L2 bit is set */
+ reg = readl(KW_REG_CPU_L2_CONFIG);
+
+ invalidate_l2_cache();
+}
+
+void arch_lowlevel_init(void)
+{
+ /* Linux expects` the internal registers to be at 0xf1000000 */
+ writel(KW_REGS_PHY_BASE, KW_OFFSET_REG);
+
+ /* Enable L2 cache in write through mode */
+ kw_enable_invalidate_l2_cache();
+
+ /*
+ * kw_cpu_if_pre_init contains
+ * Initialize BUS-L to DDR configuration parameters
+ * so must be done prior to DDR operation
+ */
+ kw_cpu_if_pre_init();
+}
diff --git a/cpu/arm926ejs/kirkwood/timer.c b/cpu/arm926ejs/kirkwood/timer.c
new file mode 100644
index 0000000..c6e1a26
--- /dev/null
+++ b/cpu/arm926ejs/kirkwood/timer.c
@@ -0,0 +1,165 @@
+/*
+ * 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>
+
+#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
+
+/* This enumerator describe counters\watchdog numbers */
+typedef enum _kwCntmrID {
+ TIMER0 = 0,
+ TIMER1,
+ WATCHDOG
+} KW_CNTMR_ID;
+
+#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(CNTMR_RELOAD_REG(UBOOT_CNTR), TIMER_LOAD_VAL);
+ writel(CNTMR_VAL_REG(UBOOT_CNTR), TIMER_LOAD_VAL);
+
+ /* set the counter to load in the first time */
+ writel(CNTMR_VAL_REG(UBOOT_CNTR), TIMER_LOAD_VAL);
+
+ /* 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(CNTMR_CTRL_REG, cntmrCtrl);
+
+ /* 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..520dcef 100644
--- a/cpu/arm926ejs/start.S
+++ b/cpu/arm926ejs/start.S
@@ -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..dd59ff8 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) += 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..6422ab2
--- /dev/null
+++ b/drivers/serial/kirkwood_serial.c
@@ -0,0 +1,187 @@
+/*
+ * 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>
+
+/* 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 */
+typedef struct kwUartPort {
+ 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];
+} kw_uart_port;
+
+/* aliases - for registers which has the same offsets */
+#define thr rbr
+#define iir fcr
+#define dll rbr
+#define dlm ier
+
+/* static variables */
+#if defined (CONFIG_CONS_INDEX) /* comes from board config */
+#if (CONFIG_CONS_INDEX == 0 )
+static volatile kw_uart_port *p_uart_port = (void *)KW_REGISTER(KW_UART0_BASE);
+#elif (CONFIG_CONS_INDEX == 1 )
+static volatile 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);
+}
+
+void kwUartPutc(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')
+ kwUartPutc('\r');
+
+ kwUartPutc(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..a884ac1
--- /dev/null
+++ b/drivers/spi/kirkwood_spi.c
@@ -0,0 +1,199 @@
+/*
+ * (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>
+
+/* SPI Registers on kirkwood SOC */
+#define KW_REG_SPI_CTRL (0x10600)
+#define KW_REG_SPI_CONFIG (0x10604)
+#define KW_REG_SPI_DATA_OUT (0x10608)
+#define KW_REG_SPI_DATA_IN (0x1060c)
+#define KW_REG_SPI_IRQ_CAUSE (0x10610)
+#define KW_REG_SPI_IRQ_MASK (0x10614)
+
+#define KW_SPI_TIMEOUT 10000
+
+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(KW_REG_SPI_CTRL, 0x00000002);
+ /* program spi clock prescaller using max_hz */
+ data = ((CONFIG_SYS_TCLK / 2) / max_hz) & 0x0000000f;
+ debug("data = 0x%08x \n", data);
+ writel(KW_REG_SPI_CONFIG, 0x00000210 | data);
+ writel(KW_REG_SPI_IRQ_CAUSE, 0x00000001);
+ writel(KW_REG_SPI_IRQ_MASK, 0x00000000);
+
+ /* program mpp registers to select SPI_CSn */
+ if (cs)
+ writel(KW_REG_MPP_CONTROL0,
+ ((readl(KW_REG_MPP_CONTROL0) & 0x0fffffff) |
+ 0x20000000));
+ else
+ writel(KW_REG_MPP_CONTROL0,
+ ((readl(KW_REG_MPP_CONTROL0) & 0xfffffff0) |
+ 0x00000002));
+
+ 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_set_bits(KW_REG_SPI_CTRL, 1<<0);
+}
+
+void spi_cs_deactivate(struct spi_slave *slave)
+{
+ writel_reset_bits(KW_REG_SPI_CTRL, 1<<0);
+}
+
+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;
+ if (1) { //bitlen <= 8) {
+ /*1 byte xfer mode */
+ writel_reset_bits(KW_REG_SPI_CONFIG, 1<<5);
+ /* Shift data so it's msb-justified */
+ if (dout) {
+ tmpdout = *(u32 *) dout & 0x0ff;
+ }
+ } else {
+ /*2 byte xfer mode */
+ writel_set_bits(KW_REG_SPI_CONFIG, 1<<5);
+ /* Shift data so it's msb-justified */
+ if (dout) {
+ tmpdout = *(u32 *) dout & 0x0ffff;
+ }
+ }
+
+ writel(KW_REG_SPI_IRQ_CAUSE, 0x0); /* clear bit */
+ writel(KW_REG_SPI_DATA_OUT, tmpdout); /* 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 (1) { //bitlen <= 8) {
+ if (din) {
+ *((u8 *) din) = (u8) tmpdin;
+ din += 1;
+ }
+ if (dout)
+ dout += 1;
+ bitlen -= 8;
+ } else {
+ if (din) {
+ *((u16 *) din) = (u16) tmpdin;
+ din += 1;
+ }
+ if (dout)
+ dout += 1;
+ bitlen -= 16;
+ }
+ }
+ 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..f07aa64
--- /dev/null
+++ b/include/asm-arm/arch-kirkwood/kirkwood.h
@@ -0,0 +1,140 @@
+/*
+ * (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
+
+#if defined (__ARMEL__)
+#define LE
+#else
+#define BE
+#endif /* __ARMEL__ */
+
+#ifndef __ASSEMBLY__
+#include <asm-arm/types.h>
+#endif /* __ASSEMBLY__ */
+#include <../board/Marvell/include/core.h>
+
+#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)
+
+#define KW_UART0_BASE (0x12000) /* UArt 0 */
+#define KW_UART1_BASE (0x13000) /* UArt 1 */
+
+/* Controler environment registers offsets */
+#define KW_REG_MPP_CONTROL0 (0x10000)
+#define KW_REG_MPP_CONTROL1 (0x10004)
+#define KW_REG_MPP_CONTROL2 (0x10008)
+#define KW_REG_MPP_CONTROL3 (0x1000C)
+#define KW_REG_MPP_CONTROL4 (0x10010)
+#define KW_REG_MPP_CONTROL5 (0x10014)
+#define KW_REG_MPP_CONTROL6 (0x10018)
+#define KW_REG_MPP_SMPL_AT_RST (0x10030)
+#define KW_REG_DEVICE_ID (0x10034)
+#define KW_REG_MPP_OUT_DRV_REG (0x100E0)
+
+#define KW_REG_GPP0_DATA_OUT (0x10100)
+#define KW_REG_GPP0_DATA_OUT_EN (0x10104)
+#define KW_REG_GPP0_BLINK_EN (0x10108)
+#define KW_REG_GPP0_DATA_IN_POL (0x1010C)
+#define KW_REG_GPP0_DATA_IN (0x10110)
+#define KW_REG_GPP0_INT_CAUSE (0x10114)
+#define KW_REG_GPP0_INT_MASK (0x10118)
+#define KW_REG_GPP0_INT_LVL (0x1011c)
+
+#define KW_REG_GPP1_DATA_OUT (0x10140)
+#define KW_REG_GPP1_DATA_OUT_EN (0x10144)
+#define KW_REG_GPP1_BLINK_EN (0x10148)
+#define KW_REG_GPP1_DATA_IN_POL (0x1014C)
+#define KW_REG_GPP1_DATA_IN (0x10150)
+#define KW_REG_GPP1_INT_CAUSE (0x10154)
+#define KW_REG_GPP1_INT_MASK (0x10158)
+#define KW_REG_GPP1_INT_LVL (0x1015c)
+
+#define KW_REG_NAND_READ_PARAM (0x10418)
+#define KW_REG_NAND_WRITE_PARAM (0x1041c)
+#define KW_REG_NAND_CTRL (0x10470)
+
+#define KW_REG_WIN_CTRL(x) (0x20000+(x*0x10))
+#define KW_REG_WIN_BASE(x) (0x20004+(x*0x10))
+#define KW_REG_WIN_REMAP_LOW(x) (0x20008+(x*0x10))
+#define KW_REG_WIN_REMAP_HIGH(x) (0x2000c+(x*0x10))
+
+#define KW_REG_CPU_CONFIG (0x20100)
+#define KW_REG_CPU_CTRL_STAT (0x20104)
+#define KW_REG_CPU_RSTOUTN_MASK (0x20108)
+#define KW_REG_CPU_SYS_SOFT_RST (0x2010C)
+#define KW_REG_CPU_AHB_MBUS_CAUSE_INT (0x20110)
+#define KW_REG_CPU_AHB_MBUS_MASK_INT (0x20114)
+#define KW_REG_CPU_FTDLL_CONFIG (0x20120)
+#define KW_REG_CPU_L2_CONFIG (0x20128)
+#define KW_REG_L2_RAM_TIMING0 (0x20134)
+#define KW_REG_L2_RAM_TIMING1 (0x20138)
+
+#define KW_REG_TMR_CTRL (0x20300)
+#define KW_REG_TMR_RELOAD (0x20310)
+#define KW_REG_TMR_VAL (0x20314)
+
+#define KW_REG_PCIE_BASE (0x40000)
+
+/*
+ * Macros
+ * CPU architecture dependent I/O read/write
+ */
+#define writel(addr, data) \
+ (*((volatile unsigned int*)(KW_REGISTER(addr))) \
+ = (unsigned int)WORD_SWAP((data)))
+
+#define readl(addr) \
+ (WORD_SWAP(*((volatile unsigned int*)(KW_REGISTER(addr)))))
+
+#define writel_set_bits(adr, bits) (writel(adr, readl(adr)\
+ | ((unsigned int)WORD_SWAP(bits))))
+
+#define writel_reset_bits(adr, bits) (writel(adr, readl(adr)\
+ & ~((unsigned int)WORD_SWAP(bits))))
+
+/*
+ * Error codes
+ */
+#define KW_ERROR (-1)
+#define KW_OK (0)
+
+#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@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@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/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
--
1.5.3.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [U-Boot] [PATCH v3] Marvell MV88F6281GTW_GE Board support
2009-04-19 6:32 ` Prafulla Wadaskar
2009-04-23 14:16 ` [U-Boot] [PATCH v3] " Prafulla Wadaskar
@ 2009-04-23 14:19 ` Prafulla Wadaskar
2009-04-26 22:36 ` Jean-Christophe PLAGNIOL-VILLARD
1 sibling, 1 reply; 11+ messages in thread
From: Prafulla Wadaskar @ 2009-04-23 14:19 UTC (permalink / raw)
To: u-boot
This is Marvell's 88F6281_A0 based custom board developed
for wireless access point product
This patch is tested for-
1. Boot from DRAM/SPI flash/NFS
2. File transfer using tftp and loadb
3. SPI flash read/write/erase
4. Booting Linux kernel and RFS from SPI flash
Reviewed-by: Ronen Shitrit <rshitrit@marvell.com>
Signed-off-by: Prafulla Wadaskar <prafulla@marvell.com>
---
Change log
v2: updated as per first review comments
debug_prints updated to debug
v3: updated as per review comments for v2
added mv88f6281gtw_ge.h file
removed BITxx macros
MAKEALL | 1 +
Makefile | 3 +
board/Marvell/mv88f6281gtw_ge/Makefile | 51 +++++++
board/Marvell/mv88f6281gtw_ge/config.mk | 25 ++++
board/Marvell/mv88f6281gtw_ge/mv88f6281gtw_ge.c | 102 +++++++++++++
board/Marvell/mv88f6281gtw_ge/mv88f6281gtw_ge.h | 46 ++++++
board/Marvell/mv88f6281gtw_ge/u-boot.lds | 53 +++++++
include/configs/mv88f6281gtw_ge.h | 175 +++++++++++++++++++++++
8 files changed, 456 insertions(+), 0 deletions(-)
create mode 100644 board/Marvell/mv88f6281gtw_ge/Makefile
create mode 100644 board/Marvell/mv88f6281gtw_ge/config.mk
create mode 100644 board/Marvell/mv88f6281gtw_ge/mv88f6281gtw_ge.c
create mode 100644 board/Marvell/mv88f6281gtw_ge/mv88f6281gtw_ge.h
create mode 100644 board/Marvell/mv88f6281gtw_ge/u-boot.lds
create mode 100644 include/configs/mv88f6281gtw_ge.h
diff --git a/MAKEALL b/MAKEALL
index e4eb42b..1caf81d 100755
--- a/MAKEALL
+++ b/MAKEALL
@@ -504,6 +504,7 @@ LIST_ARM9=" \
cp946es \
cp966 \
lpd7a400 \
+ mv88f6281gtw_ge \
mx1ads \
mx1fs2 \
netstar \
diff --git a/Makefile b/Makefile
index d2c7c3f..709e4be 100644
--- a/Makefile
+++ b/Makefile
@@ -2792,6 +2792,9 @@ 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
diff --git a/board/Marvell/mv88f6281gtw_ge/Makefile b/board/Marvell/mv88f6281gtw_ge/Makefile
new file mode 100644
index 0000000..8c49a3e
--- /dev/null
+++ b/board/Marvell/mv88f6281gtw_ge/Makefile
@@ -0,0 +1,51 @@
+#
+# (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 := mv88f6281gtw_ge.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/mv88f6281gtw_ge/config.mk b/board/Marvell/mv88f6281gtw_ge/config.mk
new file mode 100644
index 0000000..fb29a1b
--- /dev/null
+++ b/board/Marvell/mv88f6281gtw_ge/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/mv88f6281gtw_ge/mv88f6281gtw_ge.c b/board/Marvell/mv88f6281gtw_ge/mv88f6281gtw_ge.c
new file mode 100644
index 0000000..2e789a9
--- /dev/null
+++ b/board/Marvell/mv88f6281gtw_ge/mv88f6281gtw_ge.c
@@ -0,0 +1,102 @@
+/*
+ * (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 <../drivers/net/phy/mv88e61xx.h>
+#include <netdev.h>
+#include "mv88f6281gtw_ge.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int board_init(void)
+{
+ /* Board Parameters initializations */
+ kw_window_ctrl_reg_init();
+ kw_gpio_init(MV88F6281GTW_GE_OE_VAL_LOW,
+ MV88F6281GTW_GE_OE_VAL_HIGH,
+ MV88F6281GTW_GE_OE_LOW, MV88F6281GTW_GE_OE_HIGH);
+
+ kw_mpp_control_init(MV88F6281GTW_GE_MPP0_7,
+ MV88F6281GTW_GE_MPP8_15,
+ MV88F6281GTW_GE_MPP16_23,
+ MV88F6281GTW_GE_MPP24_31,
+ MV88F6281GTW_GE_MPP32_39,
+ MV88F6281GTW_GE_MPP40_47, MV88F6281GTW_GE_MPP48_55);
+
+ /* serial config */
+ gd->baudrate = CONFIG_BAUDRATE;
+ gd->have_console = 1;
+ /*
+ * arch number of USED SOC
+ */
+ gd->bd->bi_arch_number = MACH_TYPE_MV88F6281GTW_GE;
+
+ /* adress of boot parameters */
+ gd->bd->bi_boot_params = 0x00000100;
+
+ 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;
+}
+
+int last_stage_init(void)
+{
+ return 0;
+}
+
+#if defined(CONFIG_MISC_INIT_R)
+/* miscellaneous platform dependent init */
+int misc_init_r(void)
+{
+ return kw_misc_init_r();
+}
+
+void reset_phy(void)
+{
+#ifdef CONFIG_MV88E61XX_SWITCH
+ /* configure and initialize switch */
+ struct mv88e61xx_config swcfg = {
+ .name = "egiga0",
+ .vlancfg = MV88E61XX_VLANCFG_ROUTER,
+ .rgmii_delay = MV88E61XX_RGMII_DELAY_EN,
+ .portstate = MV88E61XX_PORTSTT_FORWARDING,
+ .cpuport = 5,
+ .ports_enabled = (PORT(0) | PORT(1) | PORT(2)
+ | PORT(3) | PORT(4) | PORT(5))
+ };
+
+ mv88e61xx_switch_initialize(&swcfg);
+#endif
+}
+
+#endif /* CONFIG_MISC_INIT_R */
diff --git a/board/Marvell/mv88f6281gtw_ge/mv88f6281gtw_ge.h b/board/Marvell/mv88f6281gtw_ge/mv88f6281gtw_ge.h
new file mode 100644
index 0000000..6e91c25
--- /dev/null
+++ b/board/Marvell/mv88f6281gtw_ge/mv88f6281gtw_ge.h
@@ -0,0 +1,46 @@
+/*
+ * (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 __MV88F6281GTW_GE_H
+#define __MV88F6281GTW_GE_H
+
+#define MV88F6281GTW_GE_OE_LOW (~((1<<7) | (1<<20) \
+ |(1<<21))) /*enable GLED,RLED */
+#define MV88F6281GTW_GE_OE_HIGH (~((1<<4)|(1<<6)|(1<<7)|(1<<12) \
+ |(1<<13)|(1<<16)|(1<<17)))
+#define MV88F6281GTW_GE_OE_VAL_LOW (1<<20) /*make GLED on */
+#define MV88F6281GTW_GE_OE_VAL_HIGH ((1<<6)|(1<<13)|(1<<16)|(1<<17))
+
+/*
+ * Default values for MPP registers
+ */
+#define MV88F6281GTW_GE_MPP0_7 0x01112222
+#define MV88F6281GTW_GE_MPP8_15 0x11103311
+#define MV88F6281GTW_GE_MPP16_23 0x00001111
+#define MV88F6281GTW_GE_MPP24_31 0x22222222
+#define MV88F6281GTW_GE_MPP32_39 0x40440222
+#define MV88F6281GTW_GE_MPP40_47 0x00004444
+#define MV88F6281GTW_GE_MPP48_55 0x00000000
+
+#endif /* __MV88F6281GTW_GE_H */
diff --git a/board/Marvell/mv88f6281gtw_ge/u-boot.lds b/board/Marvell/mv88f6281gtw_ge/u-boot.lds
new file mode 100644
index 0000000..9695f3f
--- /dev/null
+++ b/board/Marvell/mv88f6281gtw_ge/u-boot.lds
@@ -0,0 +1,53 @@
+/*
+ * (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
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ . = _start;
+ . = ALIGN(4);
+ .text :
+ {
+ cpu/arm926ejs/start.o (.text)
+ *(.text)
+ }
+ .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata))) }
+ . = ALIGN(4);
+ .data : { *(.data) }
+ . = ALIGN(4);
+ .got : { *(.got) }
+
+ . = .;
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) }
+ __u_boot_cmd_end = .;
+
+ . = ALIGN(4);
+ __bss_start = .;
+ .bss (NOLOAD) : { *(.bss) . = ALIGN(4); }
+ _end = .;
+}
+
diff --git a/include/configs/mv88f6281gtw_ge.h b/include/configs/mv88f6281gtw_ge.h
new file mode 100644
index 0000000..10f213f
--- /dev/null
+++ b/include/configs/mv88f6281gtw_ge.h
@@ -0,0 +1,175 @@
+/*
+ * (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_MV88F6281GTW_GE_H
+#define _CONFIG_MV88F6281GTW_GE_H
+
+/*
+ * Version number information
+ */
+#define CONFIG_IDENT_STRING "\nMarvell-MV88F6281GTW_GE-A0"
+
+/*
+ * 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 */
+
+#ifdef CONFIG_KIRKWOOD
+#define CONFIG_MD5 /* get_random_hex on krikwood needs MD5 support */
+#define CONFIG_ARCH_LOWLEVEL_INIT /* enable arch_lowlevel_init */
+#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 */
+#endif
+
+/*
+ * CLKs configurations
+ */
+#define CONFIG_SYS_HZ 1000
+
+/*
+ * Serial Port configuration
+ * The following definitions let you select what serial you want to use
+ * for your console driver.
+ */
+#define CONFIG_KW_SERIAL
+#define CONFIG_CONS_INDEX 0 /*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_SF
+
+/*
+ * Flash configuration
+ */
+#ifdef CONFIG_CMD_SF
+#define CONFIG_SYS_NO_FLASH 1 /* Declare no NOR flash */
+#define CONFIG_SPI_FLASH 1
+#define CONFIG_HARD_SPI 1
+#define CONFIG_KIRKWOOD_SPI 1
+#define CONFIG_SPI_FLASH_MACRONIX 1
+#define CONFIG_ENV_SPI_BUS 0
+#define CONFIG_ENV_SPI_CS 0
+#define CONFIG_ENV_SPI_MAX_HZ 50000000 /*50Mhz */
+#endif
+
+/*
+ * Environment variables configurations
+ */
+#ifdef CONFIG_SPI_FLASH
+#define CONFIG_ENV_IS_IN_SPI_FLASH 1
+#define CONFIG_ENV_SIZE 0x10000 /* spi flash block (64k) */
+#define CONFIG_ENV_SECT_SIZE 0x10000 /* _64K */
+#else
+#define CONFIG_ENV_IS_NOWHERE 1 /* if env in SDRAM */
+#define CONFIG_ENV_SIZE 0x20000 /* default 128k */
+#endif
+#define CONFIG_ENV_ADDR 0x20000
+#define CONFIG_ENV_OFFSET 0x20000 /* env starts here */
+
+/*
+ * Default environment variables
+ */
+#define CONFIG_BOOTCOMMAND "$(x_bootcmd_kernel); setenv bootargs " \
+ "$(x_bootargs) $(x_bootargs_root); bootm 0x6400000;"
+#define CONFIG_EXTRA_ENV_SETTINGS "x_bootargs=console=ttyS0,115200 " \
+ "mtdparts=spi0.0:512k(uboot),512k at 512k(psm),2m at 1m(kernel),13m at 3m(rootfs)\0" \
+ "x_bootcmd_kernel=cp.b 0xf8100000 0x6400000 0x200000\0" \
+ "x_bootargs_root=root=/dev/mtdblock3 ro rootfstype=squashfs\0"
+
+/*
+ * Size of malloc() pool
+ */
+#define CONFIG_SYS_MALLOC_LEN 0x00400000 /* 4M */
+/* 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_MISC_INIT_R 1 /* call misc_init_r() */
+#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 {TRUE,FALSE} /* enable port 0 only */
+#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_MV88E61XX_SWITCH /* Enable mv88e61xx switch driver */
+
+#endif /* _CONFIG_MV88F6281GTW_GE_H */
--
1.5.3.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [U-Boot] [PATCH v3] Marvell Kirkwood family SOC support
2009-04-23 14:16 ` [U-Boot] [PATCH v3] " Prafulla Wadaskar
@ 2009-04-23 16:21 ` Jean-Christophe PLAGNIOL-VILLARD
0 siblings, 0 replies; 11+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2009-04-23 16:21 UTC (permalink / raw)
To: u-boot
On 07:16 Thu 23 Apr , 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() function
> 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>
a general comment please sue tab for indentation not space
> ---
> 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 comments for v2
>
> board/Marvell/include/core.h | 4 +
> cpu/arm926ejs/kirkwood/Makefile | 49 +++++
> cpu/arm926ejs/kirkwood/config.mk | 25 +++
> cpu/arm926ejs/kirkwood/dram.c | 57 ++++++
> cpu/arm926ejs/kirkwood/kwcore.c | 304 +++++++++++++++++++++++++++++
> cpu/arm926ejs/kirkwood/kwcore.h | 112 +++++++++++
> cpu/arm926ejs/kirkwood/lowlevel_init.c | 93 +++++++++
> cpu/arm926ejs/kirkwood/timer.c | 165 ++++++++++++++++
> cpu/arm926ejs/start.S | 7 +-
> drivers/serial/kirkwood_serial.c | 187 ++++++++++++++++++
> drivers/spi/Makefile | 1 +
> drivers/spi/kirkwood_spi.c | 199 +++++++++++++++++++
> include/asm-arm/arch-kirkwood/kirkwood.h | 140 +++++++++++++
> include/asm-arm/arch-kirkwood/kw88f6192.h | 37 ++++
> include/asm-arm/arch-kirkwood/kw88f6281.h | 37 ++++
> + } else
> + temp &= ~1<<4;
> + writel(KW_REG_CPU_L2_CONFIG, temp);
> +
> + /* L2Cache settings */
> + asm("mrc p15, 1, %0, c15, c1, 0":"=r"(temp));
> +
> + /* Disable L2C pre fetch - Set bit 24 */
> + env = getenv("disL2Prefetch");
sorry I've forget about it precedently btw please add a doc about all this env
var
> + if (env && ((strcmp(env, "no") == 0) || (strcmp(env, "No") == 0)))
> + temp &= ~1<<24;
> + else
> + temp |= 1<<24;
> +
> + /* enable L2C - Set bit 22 */
> + env = getenv("disL2Cache");
> + if (!env || ((strcmp(env, "no") == 0) || (strcmp(env, "No") == 0)))
> + temp |= 1<<22;
> + else
> + temp &= ~1<<22;
> +
> + asm("mcr p15, 1, %0, c15, c1, 0": :"r"(temp));
please use set/get_cr
> +
> + /* Enable i cache */
we have a cache management framework now
please take a look on the lib_arm/cache-cp15.c
> + asm("mrc p15, 0, %0, c1, c0, 0":"=r"(temp));
> + temp |= 1<<12;
> + asm("mcr p15, 0, %0, c1, c0, 0": :"r"(temp));
> + /* Change reset vector to address 0x0 */
> + asm("mrc p15, 0, %0, c1, c0, 0":"=r"(temp));
> + temp &= ~1<<13;
> + asm("mcr p15, 0, %0, c1, c0, 0": :"r"(temp));
> +
> + return (0);
> +}
> +
> diff --git a/cpu/arm926ejs/kirkwood/kwcore.h b/cpu/arm926ejs/kirkwood/kwcore.h
> new file mode 100644
> index 0000000..feec86b
> --- /dev/null
> +++ b/cpu/arm926ejs/kirkwood/kwcore.h
> + asm volatile("mcr p15, 1, %0, c15, c1, 0 @ writefr exfr"
> + : : "r" (val) : "cc");
> + isb();
> +}
> +
> +/*
> + * Invalidate L2 Cache using co-proc instruction
> + */
> +static inline void invalidate_l2_cache(void)
we need to have the same api for l2_cache management so please add it in
include/asm-arm/cache.h
> +{
> + unsigned int val=0;
> +
> + asm volatile("mcr p15, 1, %0, c15, c11, 0 @ invl l2 cache"
> + : : "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_window_ctrl_reg_init(void);
> +void kw_gpio_init(unsigned int gpp0_oe_val, unsigned int gpp1_oe_val,
> + unsigned int gpp0_oe, unsigned int gpp1_oe);
> +int kw_mpp_control_init(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);
> +int kw_misc_init_r(void);
> +#endif /* __ASSEMBLY__ */
> +
> +#endif /* _KWCORE_H */
> diff --git a/cpu/arm926ejs/kirkwood/lowlevel_init.c b/cpu/arm926ejs/kirkwood/lowlevel_init.c
> new file mode 100644
> index 0000000..21bfc81
> --- /dev/null
> +++ b/cpu/arm926ejs/kirkwood/lowlevel_init.c
> @@ -0,0 +1,93 @@
> +/*
> + * (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
> + */
> +
I'm not a fan of c init but if you prefer ok
> +#include <config.h>
> +
> +void kw_cpu_if_pre_init(void)
> +{
> + u32 reg;
> +
> +#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(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((KW_EGIGA0_BASE + 0x44c), ®); /* PORT_SERIAL_CONTROL1_REG */
> + * so must be done prior to DDR operation
> + */
> + kw_cpu_if_pre_init();
> +}
> diff --git a/cpu/arm926ejs/kirkwood/timer.c b/cpu/arm926ejs/kirkwood/timer.c
> new file mode 100644
> index 0000000..c6e1a26
> --- /dev/null
> +++ b/cpu/arm926ejs/kirkwood/timer.c
> @@ -0,0 +1,165 @@
as I've ask for the ARM925T timer update please provice
the precision and resolution on you timer in the code
> +/*
> + * 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>
> +
> +#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)
please add a space before and after the '*'
and so on
> +#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
> +
> +/* This enumerator describe counters\watchdog numbers */
> +typedef enum _kwCntmrID {
please no Uppercase
> + TIMER0 = 0,
> + TIMER1,
> + WATCHDOG
> +} KW_CNTMR_ID;
> +
> +#define READ_TIMER (readl(CNTMR_VAL_REG(UBOOT_CNTR))/(CONFIG_SYS_TCLK/1000))
please add a space before and after the '/'
> +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));
> +}
> diff --git a/cpu/arm926ejs/start.S b/cpu/arm926ejs/start.S
> index ed4932a..520dcef 100644
> --- a/cpu/arm926ejs/start.S
> +++ b/cpu/arm926ejs/start.S
> @@ -201,7 +201,7 @@ _start_armboot:
> *
> *************************************************************************
> */
> -#ifndef CONFIG_SKIP_LOWLEVEL_INIT
> +#if !defined (CONFIG_SKIP_LOWLEVEL_INIT) || defined (CONFIG_ARCH_LOWLEVEL_INIT)
we will call the ARCH_LOWLEVEL_INIT only if we do not skip the the 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..dd59ff8 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) += kirkwood_serial.o
please use the same CONFIG_ as the kernel
> 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..6422ab2
> --- /dev/null
> +++ b/drivers/serial/kirkwood_serial.c
> @@ -0,0 +1,187 @@
> +/*
> + * 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>
> +
> +/* 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
please move this macro to a header
as include/asm/arch/serial.h as example
> +
> +/* This structure describes the registers offsets for one UART port/channel */
> +typedef struct kwUartPort {
> + 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];
> +} kw_uart_port;
> +
> +/* aliases - for registers which has the same offsets */
> +#define thr rbr
> +#define iir fcr
> +#define dll rbr
> +#define dlm ier
> +
> +/* static variables */
> +#if defined (CONFIG_CONS_INDEX) /* comes from board config */
> +#if (CONFIG_CONS_INDEX == 0 )
> +static volatile kw_uart_port *p_uart_port = (void *)KW_REGISTER(KW_UART0_BASE);
> +#elif (CONFIG_CONS_INDEX == 1 )
> +static volatile 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);
> +}
> +
> +void kwUartPutc(u8 c)
please no upper case
and please add static, this function is not use outside
> +{
> + while ((p_uart_port->lsr & LSR_THRE) == 0) ;
> + p_uart_port->thr = c;
> + return;
> +}
> +
> +void serial_putc(const char c)
> +{
> + if (c == '\n')
> + kwUartPutc('\r');
> +
> + kwUartPutc(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);
> +}
> +
> + * 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>
> +
> +/* SPI Registers on kirkwood SOC */
> +#define KW_REG_SPI_CTRL (0x10600)
> +#define KW_REG_SPI_CONFIG (0x10604)
> +#define KW_REG_SPI_DATA_OUT (0x10608)
> +#define KW_REG_SPI_DATA_IN (0x1060c)
> +#define KW_REG_SPI_IRQ_CAUSE (0x10610)
> +#define KW_REG_SPI_IRQ_MASK (0x10614)
please move this to a header
include/asm/arch/spi.h as example
> +
> +#define KW_SPI_TIMEOUT 10000
> +
> +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(KW_REG_SPI_CTRL, 0x00000002);
> + /* program spi clock prescaller using max_hz */
> + data = ((CONFIG_SYS_TCLK / 2) / max_hz) & 0x0000000f;
> + debug("data = 0x%08x \n", data);
> + writel(KW_REG_SPI_CONFIG, 0x00000210 | data);
> + writel(KW_REG_SPI_IRQ_CAUSE, 0x00000001);
> + writel(KW_REG_SPI_IRQ_MASK, 0x00000000);
> +
> + /* program mpp registers to select SPI_CSn */
> + if (cs)
> + writel(KW_REG_MPP_CONTROL0,
> + ((readl(KW_REG_MPP_CONTROL0) & 0x0fffffff) |
> + 0x20000000));
> + else
> + writel(KW_REG_MPP_CONTROL0,
> + ((readl(KW_REG_MPP_CONTROL0) & 0xfffffff0) |
> + 0x00000002));
> +
> + 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_set_bits(KW_REG_SPI_CTRL, 1<<0);
I prefer writel(t, readl(t) |?1);
> +}
> +
> +void spi_cs_deactivate(struct spi_slave *slave)
> +{
> + writel_reset_bits(KW_REG_SPI_CTRL, 1<<0);
please add a space before and after '<<'
> +}
> +
> +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;
please no upper case
> +
> + 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;
> + if (1) { //bitlen <= 8) {
please no dead code
> + /*1 byte xfer mode */
> + writel_reset_bits(KW_REG_SPI_CONFIG, 1<<5);
> + /* Shift data so it's msb-justified */
> + if (dout) {
> + tmpdout = *(u32 *) dout & 0x0ff;
> + }
> + } else {
> + /*2 byte xfer mode */
> + writel_set_bits(KW_REG_SPI_CONFIG, 1<<5);
> + /* Shift data so it's msb-justified */
> + if (dout) {
> + tmpdout = *(u32 *) dout & 0x0ffff;
> + }
> + }
> +
> + writel(KW_REG_SPI_IRQ_CAUSE, 0x0); /* clear bit */
> + writel(KW_REG_SPI_DATA_OUT, tmpdout); /* 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 (1) { //bitlen <= 8) {
> + if (din) {
> + *((u8 *) din) = (u8) tmpdin;
> + din += 1;
> + }
> + if (dout)
> + dout += 1;
> + bitlen -= 8;
> + } else {
> + if (din) {
> + *((u16 *) din) = (u16) tmpdin;
> + din += 1;
> + * 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
> +
> +#if defined (__ARMEL__)
> +#define LE
> +#else
> +#define BE
> +#endif /* __ARMEL__ */
no need please remove
> +
> +#ifndef __ASSEMBLY__
> +#include <asm-arm/types.h>
> +#endif /* __ASSEMBLY__ */
> +#include <../board/Marvell/include/core.h>
> +
> +#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)
> +
> +#define KW_UART0_BASE (0x12000) /* UArt 0 */
> +#define KW_UART1_BASE (0x13000) /* UArt 1 */
> +
> +/* Controler environment registers offsets */
> +#define KW_REG_MPP_CONTROL0 (0x10000)
> +#define KW_REG_MPP_CONTROL1 (0x10004)
> +#define KW_REG_MPP_CONTROL2 (0x10008)
> +#define KW_REG_MPP_CONTROL3 (0x1000C)
> +#define KW_REG_MPP_CONTROL4 (0x10010)
> +#define KW_REG_MPP_CONTROL5 (0x10014)
> +#define KW_REG_MPP_CONTROL6 (0x10018)
> +#define KW_REG_MPP_SMPL_AT_RST (0x10030)
> +#define KW_REG_DEVICE_ID (0x10034)
> +#define KW_REG_MPP_OUT_DRV_REG (0x100E0)
> +
> +#define KW_REG_GPP0_DATA_OUT (0x10100)
> +#define KW_REG_GPP0_DATA_OUT_EN (0x10104)
> +#define KW_REG_GPP0_BLINK_EN (0x10108)
> +#define KW_REG_GPP0_DATA_IN_POL (0x1010C)
> +#define KW_REG_GPP0_DATA_IN (0x10110)
> +#define KW_REG_GPP0_INT_CAUSE (0x10114)
> +#define KW_REG_GPP0_INT_MASK (0x10118)
> +#define KW_REG_GPP0_INT_LVL (0x1011c)
> +
> +#define KW_REG_GPP1_DATA_OUT (0x10140)
> +#define KW_REG_GPP1_DATA_OUT_EN (0x10144)
> +#define KW_REG_GPP1_BLINK_EN (0x10148)
> +#define KW_REG_GPP1_DATA_IN_POL (0x1014C)
> +#define KW_REG_GPP1_DATA_IN (0x10150)
> +#define KW_REG_GPP1_INT_CAUSE (0x10154)
> +#define KW_REG_GPP1_INT_MASK (0x10158)
> +#define KW_REG_GPP1_INT_LVL (0x1015c)
> +
> +#define KW_REG_NAND_READ_PARAM (0x10418)
> +#define KW_REG_NAND_WRITE_PARAM (0x1041c)
> +#define KW_REG_NAND_CTRL (0x10470)
> +
> +#define KW_REG_WIN_CTRL(x) (0x20000+(x*0x10))
please add a space before and after '+' '*'
> +#define KW_REG_WIN_BASE(x) (0x20004+(x*0x10))
> +#define KW_REG_WIN_REMAP_LOW(x) (0x20008+(x*0x10))
> +#define KW_REG_WIN_REMAP_HIGH(x) (0x2000c+(x*0x10))
> +
> +#define KW_REG_CPU_CONFIG (0x20100)
> +#define KW_REG_CPU_CTRL_STAT (0x20104)
> +#define KW_REG_CPU_RSTOUTN_MASK (0x20108)
> +#define KW_REG_CPU_SYS_SOFT_RST (0x2010C)
> +#define KW_REG_CPU_AHB_MBUS_CAUSE_INT (0x20110)
> +#define KW_REG_CPU_AHB_MBUS_MASK_INT (0x20114)
> +#define KW_REG_CPU_FTDLL_CONFIG (0x20120)
> +#define KW_REG_CPU_L2_CONFIG (0x20128)
> +#define KW_REG_L2_RAM_TIMING0 (0x20134)
> +#define KW_REG_L2_RAM_TIMING1 (0x20138)
> +
> +#define KW_REG_TMR_CTRL (0x20300)
> +#define KW_REG_TMR_RELOAD (0x20310)
> +#define KW_REG_TMR_VAL (0x20314)
> +
> +#define KW_REG_PCIE_BASE (0x40000)
> +
> +/*
> + * Macros
> + * CPU architecture dependent I/O read/write
> + */
> +#define writel(addr, data) \
> + (*((volatile unsigned int*)(KW_REGISTER(addr))) \
> + = (unsigned int)WORD_SWAP((data)))
no need please use generic arm/io.h (mandatory)
> +
> +#define readl(addr) \
> + (WORD_SWAP(*((volatile unsigned int*)(KW_REGISTER(addr)))))
> +
> +#define writel_set_bits(adr, bits) (writel(adr, readl(adr)\
> + | ((unsigned int)WORD_SWAP(bits))))
> +
> +#define writel_reset_bits(adr, bits) (writel(adr, readl(adr)\
> + & ~((unsigned int)WORD_SWAP(bits))))
> +
> +/*
> + * Error codes
> + */
> +#define KW_ERROR (-1)
> +#define KW_OK (0)
no need please remove
> +
Best Regards,
J.
^ permalink raw reply [flat|nested] 11+ messages in thread
* [U-Boot] [PATCH v3] Marvell MV88F6281GTW_GE Board support
2009-04-23 14:19 ` [U-Boot] [PATCH v3] Marvell MV88F6281GTW_GE Board support Prafulla Wadaskar
@ 2009-04-26 22:36 ` Jean-Christophe PLAGNIOL-VILLARD
2009-04-27 6:45 ` Prafulla Wadaskar
0 siblings, 1 reply; 11+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2009-04-26 22:36 UTC (permalink / raw)
To: u-boot
On 07:19 Thu 23 Apr , Prafulla Wadaskar wrote:
> This is Marvell's 88F6281_A0 based custom board developed
> for wireless access point product
>
> This patch is tested for-
> 1. Boot from DRAM/SPI flash/NFS
> 2. File transfer using tftp and loadb
> 3. SPI flash read/write/erase
> 4. Booting Linux kernel and RFS from SPI flash
>
> Reviewed-by: Ronen Shitrit <rshitrit@marvell.com>
> Signed-off-by: Prafulla Wadaskar <prafulla@marvell.com>
> ---
> Change log
> v2: updated as per first review comments
> debug_prints updated to debug
>
> v3: updated as per review comments for v2
> added mv88f6281gtw_ge.h file
> removed BITxx macros
first a general comment
I do not known if it's your mailer but all tab are converted in whitespace
please fix it
>
> MAKEALL | 1 +
> Makefile | 3 +
> board/Marvell/mv88f6281gtw_ge/Makefile | 51 +++++++
> board/Marvell/mv88f6281gtw_ge/config.mk | 25 ++++
> board/Marvell/mv88f6281gtw_ge/mv88f6281gtw_ge.c | 102 +++++++++++++
> board/Marvell/mv88f6281gtw_ge/mv88f6281gtw_ge.h | 46 ++++++
> board/Marvell/mv88f6281gtw_ge/u-boot.lds | 53 +++++++
> include/configs/mv88f6281gtw_ge.h | 175 +++++++++++++++++++++++
> 8 files changed, 456 insertions(+), 0 deletions(-)
> create mode 100644 board/Marvell/mv88f6281gtw_ge/Makefile
> create mode 100644 board/Marvell/mv88f6281gtw_ge/config.mk
> create mode 100644 board/Marvell/mv88f6281gtw_ge/mv88f6281gtw_ge.c
> create mode 100644 board/Marvell/mv88f6281gtw_ge/mv88f6281gtw_ge.h
> create mode 100644 board/Marvell/mv88f6281gtw_ge/u-boot.lds
> create mode 100644 include/configs/mv88f6281gtw_ge.h
>
> diff --git a/MAKEALL b/MAKEALL
> index e4eb42b..1caf81d 100755
> --- a/MAKEALL
> +++ b/MAKEALL
> @@ -504,6 +504,7 @@ LIST_ARM9=" \
> cp946es \
> cp966 \
> lpd7a400 \
> + mv88f6281gtw_ge \
> mx1ads \
> mx1fs2 \
> netstar \
> + * 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 <../drivers/net/phy/mv88e61xx.h>
> +#include <netdev.h>
> +#include "mv88f6281gtw_ge.h"
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +int board_init(void)
> +{
> + /* Board Parameters initializations */
could explain what you do a few more?
> + kw_window_ctrl_reg_init();
> + kw_gpio_init(MV88F6281GTW_GE_OE_VAL_LOW,
> + MV88F6281GTW_GE_OE_VAL_HIGH,
> + MV88F6281GTW_GE_OE_LOW, MV88F6281GTW_GE_OE_HIGH);
> +
> + kw_mpp_control_init(MV88F6281GTW_GE_MPP0_7,
> + MV88F6281GTW_GE_MPP8_15,
> + MV88F6281GTW_GE_MPP16_23,
> + MV88F6281GTW_GE_MPP24_31,
> + MV88F6281GTW_GE_MPP32_39,
> + MV88F6281GTW_GE_MPP40_47, MV88F6281GTW_GE_MPP48_55);
> +
from
> + /* serial config */
> + gd->baudrate = CONFIG_BAUDRATE;
> + gd->have_console = 1;
no need please remove
> + /*
> + * arch number of USED SOC
> + */
> + gd->bd->bi_arch_number = MACH_TYPE_MV88F6281GTW_GE;
> +
> + /* adress of boot parameters */
> + gd->bd->bi_boot_params = 0x00000100;
please be more consistant with the other arm boards
RAM_BASE + 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;
> +}
> +
> +int last_stage_init(void)
> +{
> + return 0;
> +}
no need please remove
> +
> +#if defined(CONFIG_MISC_INIT_R)
> +/* miscellaneous platform dependent init */
> +int misc_init_r(void)
> +{
> + return kw_misc_init_r();
> +}
if it's really arch late init please create a generic function like
arch_late_init or arch_misc_init
and call it from lib_arm/board.c
> +
> +void reset_phy(void)
> +{
> +#ifdef CONFIG_MV88E61XX_SWITCH
> + /* configure and initialize switch */
> + struct mv88e61xx_config swcfg = {
> + .name = "egiga0",
> + .vlancfg = MV88E61XX_VLANCFG_ROUTER,
> + .rgmii_delay = MV88E61XX_RGMII_DELAY_EN,
> + .portstate = MV88E61XX_PORTSTT_FORWARDING,
> + .cpuport = 5,
> + .ports_enabled = (PORT(0) | PORT(1) | PORT(2)
> + | PORT(3) | PORT(4) | PORT(5))
> + };
> +
> + mv88e61xx_switch_initialize(&swcfg);
> +#endif
> +}
please only call reset_phy when the SWITCH is enable. it will reduce the size
of u-boot whenyou do not use the switch
> +
> +#endif /* CONFIG_MISC_INIT_R */
> diff --git a/board/Marvell/mv88f6281gtw_ge/mv88f6281gtw_ge.h b/board/Marvell/mv88f6281gtw_ge/mv88f6281gtw_ge.h
> new file mode 100644
> index 0000000..6e91c25
> --- /dev/null
> +++ b/board/Marvell/mv88f6281gtw_ge/mv88f6281gtw_ge.h
> @@ -0,0 +1,46 @@
> +/*
> + * (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 __MV88F6281GTW_GE_H
> +#define __MV88F6281GTW_GE_H
> +
> +#define MV88F6281GTW_GE_OE_LOW (~((1<<7) | (1<<20) \
> + |(1<<21))) /*enable GLED,RLED */
> +#define MV88F6281GTW_GE_OE_HIGH (~((1<<4)|(1<<6)|(1<<7)|(1<<12) \
> + |(1<<13)|(1<<16)|(1<<17)))
> +#define MV88F6281GTW_GE_OE_VAL_LOW (1<<20) /*make GLED on */
> +#define MV88F6281GTW_GE_OE_VAL_HIGH ((1<<6)|(1<<13)|(1<<16)|(1<<17))
> +
> +/*
> + * Default values for MPP registers
> + */
> +#define MV88F6281GTW_GE_MPP0_7 0x01112222
> +#define MV88F6281GTW_GE_MPP8_15 0x11103311
> +#define MV88F6281GTW_GE_MPP16_23 0x00001111
> +#define MV88F6281GTW_GE_MPP24_31 0x22222222
> +#define MV88F6281GTW_GE_MPP32_39 0x40440222
> +#define MV88F6281GTW_GE_MPP40_47 0x00004444
> +#define MV88F6281GTW_GE_MPP48_55 0x00000000
could explain a few more these value
> +
> +#endif /* __MV88F6281GTW_GE_H */
> diff --git a/board/Marvell/mv88f6281gtw_ge/u-boot.lds b/board/Marvell/mv88f6281gtw_ge/u-boot.lds
> new file mode 100644
> index 0000000..9695f3f
> --- /dev/null
> + *
> + * 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_MV88F6281GTW_GE_H
> +#define _CONFIG_MV88F6281GTW_GE_H
> +
> +/*
> + * Version number information
> + */
> +#define CONFIG_IDENT_STRING "\nMarvell-MV88F6281GTW_GE-A0"
> +
> +/*
> + * 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 */
> +
> +#ifdef CONFIG_KIRKWOOD
> +#define CONFIG_MD5 /* get_random_hex on krikwood needs MD5 support */
> +#define CONFIG_ARCH_LOWLEVEL_INIT /* enable arch_lowlevel_init */
> +#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 */
> +#endif
why?
this boards is not a KIRWOOD?
> +
> +/*
> + * CLKs configurations
> + */
> +#define CONFIG_SYS_HZ 1000
> +
> +/*
> + * Serial Port configuration
> + * The following definitions let you select what serial you want to use
> + * for your console driver.
> + */
> + * Default environment variables
> + */
> +#define CONFIG_BOOTCOMMAND "$(x_bootcmd_kernel); setenv bootargs " \
IIRC please use ${} instead of $()
> + "$(x_bootargs) $(x_bootargs_root); bootm 0x6400000;"
> +#define CONFIG_EXTRA_ENV_SETTINGS "x_bootargs=console=ttyS0,115200 " \
> + "mtdparts=spi0.0:512k(uboot),512k at 512k(psm),2m at 1m(kernel),13m at 3m(rootfs)\0" \
he could be usefull to use CONFIG_MTDPARTS
> + "x_bootcmd_kernel=cp.b 0xf8100000 0x6400000 0x200000\0" \
> + "x_bootargs_root=root=/dev/mtdblock3 ro rootfstype=squashfs\0"
> +
Best Regards,
J.
^ permalink raw reply [flat|nested] 11+ messages in thread
* [U-Boot] [PATCH v3] Marvell MV88F6281GTW_GE Board support
2009-04-26 22:36 ` Jean-Christophe PLAGNIOL-VILLARD
@ 2009-04-27 6:45 ` Prafulla Wadaskar
0 siblings, 0 replies; 11+ messages in thread
From: Prafulla Wadaskar @ 2009-04-27 6:45 UTC (permalink / raw)
To: u-boot
Hi Jean
Thanks for your review feedback
Pls see my in lined comments
> -----Original Message-----
> From: Jean-Christophe PLAGNIOL-VILLARD [mailto:plagnioj at jcrosoft.com]
> Sent: Monday, April 27, 2009 4:06 AM
> To: Prafulla Wadaskar
> Cc: u-boot at lists.denx.de; Ashish Karkare; Ronen Shitrit;
> Prabhanjan Sarnaik
> Subject: Re: [PATCH v3] Marvell MV88F6281GTW_GE Board support
>
> On 07:19 Thu 23 Apr , Prafulla Wadaskar wrote:
> > This is Marvell's 88F6281_A0 based custom board developed
> for wireless
> > access point product
> > v3: updated as per review comments for v2 added
> mv88f6281gtw_ge.h file
> > removed BITxx macros
> first a general comment
> I do not known if it's your mailer but all tab are converted
> in whitespace please fix it
This should be mailer problem, I will fix it for all next patch send
> > +DECLARE_GLOBAL_DATA_PTR;
> > +
> > +int board_init(void)
> > +{
> > + /* Board Parameters initializations */
> could explain what you do a few more?
This is explained in detail in Kirkwood support file (i.e. cpu/arm926ejs/kirkwood/kwcore.c) in Kirkwood SOC support patch
I will put some explanation here too for each init call
> > + kw_window_ctrl_reg_init();
> > + kw_gpio_init(MV88F6281GTW_GE_OE_VAL_LOW,
> > + MV88F6281GTW_GE_OE_VAL_HIGH,
> > + MV88F6281GTW_GE_OE_LOW,
> MV88F6281GTW_GE_OE_HIGH);
> > +
> > + kw_mpp_control_init(MV88F6281GTW_GE_MPP0_7,
> > + MV88F6281GTW_GE_MPP8_15,
> > + MV88F6281GTW_GE_MPP16_23,
> > + MV88F6281GTW_GE_MPP24_31,
> > + MV88F6281GTW_GE_MPP32_39,
> > + MV88F6281GTW_GE_MPP40_47,
> > + MV88F6281GTW_GE_MPP48_55);
> > +
> from
> > + /* serial config */
> > + gd->baudrate = CONFIG_BAUDRATE;
> > + gd->have_console = 1;
> no need please remove
Okay I will remove this
> > + /*
> > + * arch number of USED SOC
> > + */
> > + gd->bd->bi_arch_number = MACH_TYPE_MV88F6281GTW_GE;
> > +
> > + /* adress of boot parameters */
> > + gd->bd->bi_boot_params = 0x00000100;
> please be more consistant with the other arm boards RAM_BASE + 0x100
Okay..
> > +
> > + 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;
> > +}
> > +
> > +int last_stage_init(void)
> > +{
> > + return 0;
> > +}
> no need please remove
Okay
> > +
> > +#if defined(CONFIG_MISC_INIT_R)
> > +/* miscellaneous platform dependent init */ int misc_init_r(void) {
> > + return kw_misc_init_r();
> > +}
> if it's really arch late init please create a generic
> function like arch_late_init or arch_misc_init and call it
> from lib_arm/board.c
> > +
> > +void reset_phy(void)
> > +{
> > +#ifdef CONFIG_MV88E61XX_SWITCH
> > + /* configure and initialize switch */
> > + struct mv88e61xx_config swcfg = {
> > + .name = "egiga0",
> > + .vlancfg = MV88E61XX_VLANCFG_ROUTER,
> > + .rgmii_delay = MV88E61XX_RGMII_DELAY_EN,
> > + .portstate = MV88E61XX_PORTSTT_FORWARDING,
> > + .cpuport = 5,
> > + .ports_enabled = (PORT(0) | PORT(1) | PORT(2)
> > + | PORT(3) | PORT(4) | PORT(5))
> > + };
> > +
> > + mv88e61xx_switch_initialize(&swcfg);
> > +#endif
> > +}
> please only call reset_phy when the SWITCH is enable. it will
> reduce the size of u-boot whenyou do not use the switch
Yes... I will do it
> > +/*
> > + * Default values for MPP registers
> > + */
> > +#define MV88F6281GTW_GE_MPP0_7 0x01112222
> > +#define MV88F6281GTW_GE_MPP8_15 0x11103311
> > +#define MV88F6281GTW_GE_MPP16_23 0x00001111
> > +#define MV88F6281GTW_GE_MPP24_31 0x22222222
> > +#define MV88F6281GTW_GE_MPP32_39 0x40440222
> > +#define MV88F6281GTW_GE_MPP40_47 0x00004444
> > +#define MV88F6281GTW_GE_MPP48_55 0x00000000
> could explain a few more these value
I will put explanation for this
> 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 */ #endif
> why?
> this boards is not a KIRWOOD?
No, This board is MV88F6281GTW_GE which uses 88F6281 belongs to kirkwood family of SoCs.
Soc has provision to configure RGMII pad voltages to 1.8 or 3.3 Volts connected to Gbe interface (i.e. switch used on this board).
Also kernel switch and Gbe controller driver does not take care of this since they are generic.
> > +#define CONFIG_BOOTCOMMAND
> "$(x_bootcmd_kernel); setenv bootargs " \
> IIRC please use ${} instead of $()
Okay
> > + "$(x_bootargs) $(x_bootargs_root); bootm 0x6400000;"
> > +#define CONFIG_EXTRA_ENV_SETTINGS
> "x_bootargs=console=ttyS0,115200 " \
> > +
> >
> +"mtdparts=spi0.0:512k(uboot),512k at 512k(psm),2m at 1m(kernel),13m at 3m(root
> > +fs)\0" \
> he could be usefull to use CONFIG_MTDPARTS
I will check this and use it
Regards..
Prafulla . .
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2009-04-27 6:45 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-04-08 12:03 [U-Boot] [PATCH v2] Marvell Kirkwood family SOC support Prafulla Wadaskar
2009-04-14 17:26 ` Prafulla Wadaskar
2009-04-17 9:22 ` Jean-Christophe PLAGNIOL-VILLARD
2009-04-18 6:44 ` Prafulla Wadaskar
2009-04-18 7:23 ` Jean-Christophe PLAGNIOL-VILLARD
2009-04-19 6:32 ` Prafulla Wadaskar
2009-04-23 14:16 ` [U-Boot] [PATCH v3] " Prafulla Wadaskar
2009-04-23 16:21 ` Jean-Christophe PLAGNIOL-VILLARD
2009-04-23 14:19 ` [U-Boot] [PATCH v3] Marvell MV88F6281GTW_GE Board support Prafulla Wadaskar
2009-04-26 22:36 ` Jean-Christophe PLAGNIOL-VILLARD
2009-04-27 6:45 ` Prafulla Wadaskar
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox