
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@marvell.com] Sent: Wednesday, April 08, 2009 5:33 PM To: u-boot@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:-
- 88F6281-Z0 define CONFIG_KW88F6281_Z0
- 88F6281-A0 define CONFIG_KW88F6281_A0
- 88F6192-A0 define CONFIG_KW88F6192_A0
Other supported features:-
- get_random_hex() fucntion
- SPI port controller driver
- 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