[U-Boot] [PATCH v6] 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-A0 define CONFIG_KW88F6281_A0 2) 88F6192-A0 define CONFIG_KW88F6192_A0
Other supported features:- 1) get_random_hex() fucntion 2) SPI port controller driver 3) PCI Express port initialization
Contributors: Yotam Admon yotam@marvell.com Michael Blostein <michaelbl@marvell.com
Reviewed-by: Ronen Shitrit rshitrit@marvell.com Signed-off-by: Prafulla Wadaskar prafulla@marvell.com --- Change log: v2: crated arch-kirkwood and moved some header files there renamed and moved spi.c to drivers/spi/ renamed and moved serial.c to drivers/serial/ doimage utility removed soc_init.S renamed as lowlevel_init.S debug prints removed
v3: lowlevel_init.S converted to lowlevel_init.c removed BITxx macros, removed entire assembly code Added CONFIG_ARCH_LOWLEVE_INIT support for arm926ejs core updated as per review commens for v2
v4: updated as per review comments for v3 print_cpuinfo used to display Soc info arch_misc_init support created and used for lib_arm mandatory readl/write macros used asm/cache.h asm/arch/spi.h asm//arch/serial.h created and used
v5: updated as per review comments for v4 cosmetic updates, arch_misc_init and arch_cpu_init used start.S updated to call arch_lowlevel_init in case if lowlevl_init is skipped bug fix in cpu.c
v6: lowlevel_init.S removed code moved under arch_cpu_init
cpu/arm926ejs/kirkwood/Makefile | 48 +++++ cpu/arm926ejs/kirkwood/config.mk | 25 +++ cpu/arm926ejs/kirkwood/cpu.c | 295 +++++++++++++++++++++++++++++ cpu/arm926ejs/kirkwood/cpu.h | 99 ++++++++++ cpu/arm926ejs/kirkwood/dram.c | 57 ++++++ cpu/arm926ejs/kirkwood/timer.c | 159 ++++++++++++++++ drivers/serial/Makefile | 1 + drivers/serial/kirkwood_serial.c | 128 +++++++++++++ drivers/spi/Makefile | 1 + drivers/spi/kirkwood_spi.c | 167 ++++++++++++++++ include/asm-arm/arch-kirkwood/kirkwood.h | 118 ++++++++++++ include/asm-arm/arch-kirkwood/kw88f6192.h | 37 ++++ include/asm-arm/arch-kirkwood/kw88f6281.h | 37 ++++ include/asm-arm/arch-kirkwood/serial.h | 89 +++++++++ include/asm-arm/arch-kirkwood/spi.h | 39 ++++ include/asm-arm/cache.h | 41 ++++ include/asm-arm/config.h | 4 + include/common.h | 1 + lib_arm/board.c | 4 + 19 files changed, 1350 insertions(+), 0 deletions(-) create mode 100644 cpu/arm926ejs/kirkwood/Makefile create mode 100644 cpu/arm926ejs/kirkwood/config.mk create mode 100644 cpu/arm926ejs/kirkwood/cpu.c create mode 100644 cpu/arm926ejs/kirkwood/cpu.h create mode 100644 cpu/arm926ejs/kirkwood/dram.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 create mode 100644 include/asm-arm/arch-kirkwood/serial.h create mode 100644 include/asm-arm/arch-kirkwood/spi.h create mode 100644 include/asm-arm/cache.h
diff --git a/cpu/arm926ejs/kirkwood/Makefile b/cpu/arm926ejs/kirkwood/Makefile new file mode 100644 index 0000000..ef1176e --- /dev/null +++ b/cpu/arm926ejs/kirkwood/Makefile @@ -0,0 +1,48 @@ +# +# (C) Copyright 2009 +# Marvell Semiconductor <www.marvell.com> +# Prafulla Wadaskar prafulla@marvell.com +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).a + +COBJS-y = dram.o +COBJS-y += cpu.o +COBJS-y += 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/cpu.c b/cpu/arm926ejs/kirkwood/cpu.c new file mode 100644 index 0000000..bfbbe05 --- /dev/null +++ b/cpu/arm926ejs/kirkwood/cpu.c @@ -0,0 +1,295 @@ +/* + * (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 <asm/cache.h> +#include <u-boot/md5.h> + +void reset_cpu(unsigned long ignored) +{ + writel(readl(KW_REG_CPU_RSTOUTN_MASK) | (1 << 2), + KW_REG_CPU_RSTOUTN_MASK); + writel(readl(KW_REG_CPU_SYS_SOFT_RST) | 1, KW_REG_CPU_SYS_SOFT_RST); + while (1) ; +} + +/* + * Generates Ramdom hex number reading some time varient system registers + * and using md5 algorithm + */ +unsigned char get_random_hex(void) +{ + int i; + u32 inbuf[16]; + u8 outbuf[16]; + + /* + * in case of 88F6281/88F6192 A0, + * Bit7 need to reset to generate random values in KW_REG_UNDOC_0x1470 + * Soc reg offsets KW_REG_UNDOC_0x1470 and KW_REG_UNDOC_0x1478 are reserved regs and + * Does not have names at this moment (no errata available) + */ + writel(readl(KW_REG_UNDOC_0x1478) | (1 << 7), KW_REG_UNDOC_0x1478); + for (i = 0; i < 16; i++) { + inbuf[i] = readl(KW_REG_UNDOC_0x1470); + } + md5((u8 *) inbuf, 64, outbuf); + return outbuf[outbuf[7] % 0x0f]; +} + +/* + * Window Size + * Used with the Base register to set the address window size and location. + * Must be programmed from LSB to MSB as sequence of 1’s followed by + * sequence of 0’s. The number of 1’s specifies the size of the window in + * 64 KByte granularity (e.g., a value of 0x00FF specifies 256 = 16 MByte). + * NOTE: A value of 0x0 specifies 64-KByte size. + */ +static unsigned int kw_winctrl_calcsize(unsigned int sizeval) +{ + int i; + unsigned int j = 0; + + for (i = 0; i < (sizeval / 0x10000); i++) { + j |= (1 << i); + } + return (0x0000ffff & j); +} + +/* prepares data to be loaded in win_Ctrl register */ +#define KWCPU_WIN_CTRL_DATA(size, target, attr, en) (en | (target << 4) \ + | (attr << 8) | (kw_winctrl_calcsize(size) << 16)) + +/* + * kw_config_adr_windows - Configure address Windows + * + * There are 7 address windows supported by Kirkwood Soc to addess different + * devices. Each window can be configured for size, BAR and remap addr + * Below configuration is standard for most of the cases + * + * Reference Documentation: + * Mbus-L to Mbus Bridge Registers Configuration. + * (Sec 25.1 and 25.3 of Datasheet) + */ +int kw_config_adr_windows(void) +{ + writel(KWCPU_WIN_CTRL_DATA(0xc0000, KWCPU_TARGET_PCIE, + KWCPU_ATTR_PCIE_MEM, KWCPU_WIN_ENABLE), + KW_REG_WIN_CTRL(0)); + + writel(0x90000000, KW_REG_WIN_BASE(0)); + writel(0x90000000, KW_REG_WIN_REMAP_LOW(0)); + writel(0x00000000, KW_REG_WIN_REMAP_HIGH(0)); + + writel(KWCPU_WIN_CTRL_DATA(0x70000, KWCPU_TARGET_MEMORY, + KWCPU_ATTR_NANDFLASH, KWCPU_WIN_ENABLE), + KW_REG_WIN_CTRL(1)); + writel(0xF9000000, KW_REG_WIN_BASE(1)); + writel(0xF9000000, KW_REG_WIN_REMAP_LOW(1)); + writel(0x00000000, KW_REG_WIN_REMAP_HIGH(1)); + + writel(KWCPU_WIN_CTRL_DATA(0x80000, KWCPU_TARGET_PCIE, + KWCPU_ATTR_PCIE_IO, KWCPU_WIN_ENABLE), + KW_REG_WIN_CTRL(2)); + writel(0xF0000000, KW_REG_WIN_BASE(2)); + writel(0xC0000000, KW_REG_WIN_REMAP_LOW(2)); + writel(0x00000000, KW_REG_WIN_REMAP_HIGH(2)); + + writel(KWCPU_WIN_CTRL_DATA(0x80000, KWCPU_TARGET_MEMORY, + KWCPU_ATTR_SPIFLASH, KWCPU_WIN_ENABLE), + KW_REG_WIN_CTRL(3)); + writel(0xF8000000, KW_REG_WIN_BASE(3)); + writel(0x00000000, KW_REG_WIN_REMAP_LOW(3)); + writel(0x00000000, KW_REG_WIN_REMAP_HIGH(3)); + + writel(KWCPU_WIN_CTRL_DATA(0x80000, KWCPU_TARGET_MEMORY, + KWCPU_ATTR_BOOTROM, KWCPU_WIN_ENABLE), + KW_REG_WIN_CTRL(4)); + writel(0xFF000000, KW_REG_WIN_BASE(4)); + writel(0x00000000, KW_REG_WIN_REMAP_LOW(4)); + writel(0x00000000, KW_REG_WIN_REMAP_HIGH(4)); + + writel(KWCPU_WIN_CTRL_DATA(0xb0000, KWCPU_TARGET_MEMORY, + KWCPU_ATTR_SPIFLASH, KWCPU_WIN_DISABLE), + KW_REG_WIN_CTRL(5)); + writel(0xE8000000, KW_REG_WIN_BASE(5)); + writel(0x00000000, KW_REG_WIN_REMAP_LOW(5)); + writel(0x00000000, KW_REG_WIN_REMAP_HIGH(5)); + + writel(KWCPU_WIN_CTRL_DATA(0xb0000, KWCPU_TARGET_MEMORY, + KWCPU_ATTR_BOOTROM, KWCPU_WIN_DISABLE), + KW_REG_WIN_CTRL(6)); + writel(0xF0000000, KW_REG_WIN_BASE(6)); + writel(0x00000000, KW_REG_WIN_REMAP_LOW(6)); + writel(0x00000000, KW_REG_WIN_REMAP_HIGH(6)); + + writel(KWCPU_WIN_CTRL_DATA(0x0, KWCPU_TARGET_SASRAM, KWCPU_ATTR_SASRAM, + KWCPU_WIN_ENABLE), KW_REG_WIN_CTRL(7)); + writel(0xFB000000, KW_REG_WIN_BASE(7)); + writel(0x00000000, KW_REG_WIN_REMAP_LOW(7)); + writel(0x00000000, KW_REG_WIN_REMAP_HIGH(7)); + + return 0; +} + +/* + * kw_config_gpio - GPIO configuration + */ +void kw_config_gpio(u32 gpp0_oe_val, u32 gpp1_oe_val, u32 gpp0_oe, u32 gpp1_oe) +{ + /* Init GPIOS to default values as per board requirement */ + writel(gpp0_oe_val, KW_REG_GPP0_DATA_OUT); + writel(gpp1_oe_val, KW_REG_GPP1_DATA_OUT); + writel(gpp0_oe, KW_REG_GPP0_DATA_OUT_EN); + writel(gpp1_oe, KW_REG_GPP1_DATA_OUT_EN); +} + +/* + * kw_config_mpp - Multi-Purpose Pins Functionality configuration + * + * Each MPP can be configured to different functionality through + * MPP control register, ref (sec 6.1 of kirkwood h/w specification) + * + * There are maximum 64 Multi-Pourpose Pins on Kirkwood + * Each MPP functionality can be configuration by a 4bit value + * of MPP control reg, the value and associated functionality depends + * upon used SoC varient + */ +int kw_config_mpp(u32 mpp0_7, u32 mpp8_15, u32 mpp16_23, u32 mpp24_31, + u32 mpp32_39, u32 mpp40_47, u32 mpp48_55) +{ + /* program mpp registers */ + writel(mpp0_7, KW_REG_MPP_CONTROL0); + writel(mpp8_15, KW_REG_MPP_CONTROL1); + writel(mpp16_23, KW_REG_MPP_CONTROL2); + writel(mpp24_31, KW_REG_MPP_CONTROL3); + writel(mpp32_39, KW_REG_MPP_CONTROL4); + writel(mpp40_47, KW_REG_MPP_CONTROL5); + writel(mpp48_55, KW_REG_MPP_CONTROL6); + return 0; +} + +#if defined(CONFIG_DISPLAY_CPUINFO) +int print_cpuinfo(void) +{ + char *name = "Unknown"; + + switch (readl(KW_REG_DEVICE_ID) & 0x03) { + case 1: + name = "88F6192_A0"; + break; + case 2: + name = "88F6281_A0"; + break; + default: + break; + } + printf("SoC: Kirkwood %s\n", name); + return 0; +} +#endif /* CONFIG_DISPLAY_CPUINFO */ + +#ifdef CONFIG_ARCH_CPU_INIT +int arch_cpu_init(void) +{ + u32 reg; + + /* Linux expects` the internal registers to be at 0xf1000000 */ + writel(KW_REGS_PHY_BASE, KW_OFFSET_REG); + + /* Enable and invalidate L2 cache in write through mode */ + writel(readl(KW_REG_CPU_L2_CONFIG) | 0x18, KW_REG_CPU_L2_CONFIG); + invalidate_l2_cache(); + + kw_config_adr_windows(); + +#ifdef CONFIG_KIRKWOOD_RGMII_PAD_1V8 + /* + * Configures the I/O voltage of the pads connected to Egigabit + * Ethernet interface to 1.8V + * By defult it is set to 3.3V + */ + reg = readl(KW_REG_MPP_OUT_DRV_REG); + reg |= (1 << 7); + writel(reg, KW_REG_MPP_OUT_DRV_REG); +#endif +#ifdef CONFIG_KIRKWOOD_EGIGA_INIT + /* + * Set egiga port0/1 in normal functional mode + * This is required becasue on kirkwood by default ports are in reset mode + * OS egiga driver may not have provision to set them in normal mode + * and if u-boot is build without network support, network may fail at OS level + */ + reg = readl((KW_EGIGA0_BASE + 0x44c)); /* PORT_SERIAL_CONTROL1_REG */ + reg &= ~(1 << 4); /* Clear PortReset Bit */ + writel(reg, (KW_EGIGA0_BASE + 0x44c)); /* PORT_SERIAL_CONTROL1_REG */ + reg = readl((KW_EGIGA1_BASE + 0x44c)); /* PORT_SERIAL_CONTROL1_REG */ + reg &= ~(1 << 4); /* Clear PortReset Bit */ + writel(reg, (KW_EGIGA1_BASE + 0x44c)); /* PORT_SERIAL_CONTROL1_REG */ +#endif +#ifdef CONFIG_KIRKWOOD_PCIE_INIT + /* + * Enable PCI Express Port0 + */ + reg = readl(KW_REG_CPU_CTRL_STAT); + reg |= (1 << 0); /* Set PEX0En Bit */ + writel(reg, KW_REG_CPU_CTRL_STAT); +#endif + return 0; +} +#endif /* CONFIG_ARCH_CPU_INIT */ + +/* + * SOC specific misc init + */ +#if defined(CONFIG_ARCH_MISC_INIT) +int arch_misc_init(void) +{ + volatile u32 temp; + + /*CPU streaming & write allocate */ + temp = readfr_extra_feature_reg(); + temp &= ~(1 << 28); /* disable wr alloc */ + writefr_extra_feature_reg(temp); + + temp = readfr_extra_feature_reg(); + temp &= ~(1 << 29); /* streaming disabled */ + writefr_extra_feature_reg(temp); + + /* L2Cache settings */ + temp = readfr_extra_feature_reg(); + /* Disable L2C pre fetch - Set bit 24 */ + temp |= (1 << 24); + /* enable L2C - Set bit 22 */ + temp |= (1 << 22); + writefr_extra_feature_reg(temp); + + icache_enable(); + /* Change reset vector to address 0x0 */ + temp = get_cr(); + set_cr(temp & ~CR_V); + + return 0; +} +#endif /* CONFIG_ARCH_MISC_INIT */ diff --git a/cpu/arm926ejs/kirkwood/cpu.h b/cpu/arm926ejs/kirkwood/cpu.h new file mode 100644 index 0000000..6cdf8b8 --- /dev/null +++ b/cpu/arm926ejs/kirkwood/cpu.h @@ -0,0 +1,99 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Prafulla Wadaskar prafulla@marvell.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef _KWCPU_H +#define _KWCPU_H + +#include <asm/system.h> + +#ifndef __ASSEMBLY__ +enum memory_bank { + BANK0, + BANK1, + BANK2, + BANK3 +}; + +enum kwcpu_winen { + KWCPU_WIN_DISABLE, + KWCPU_WIN_ENABLE +}; + +enum kwcpu_target { + KWCPU_TARGET_RESERVED, + KWCPU_TARGET_MEMORY, + KWCPU_TARGET_1RESERVED, + KWCPU_TARGET_SASRAM, + KWCPU_TARGET_PCIE +}; + +enum kwcpu_attrib { + KWCPU_ATTR_SASRAM = 0x01, + KWCPU_ATTR_NANDFLASH = 0x2f, + KWCPU_ATTR_SPIFLASH = 0x1e, + KWCPU_ATTR_BOOTROM = 0x1d, + KWCPU_ATTR_PCIE_IO = 0xe0, + KWCPU_ATTR_PCIE_MEM = 0xe8 +}; + +/* + * read feroceon/sheeva core extra feature register + * using co-proc instruction + */ +static inline unsigned int readfr_extra_feature_reg(void) +{ + unsigned int val; + asm volatile ("mrc p15, 1, %0, c15, c1, 0 @ readfr exfr":"=r" + (val)::"cc"); + return val; +} + +/* + * write feroceon/sheeva core extra feature register + * using co-proc instruction + */ +static inline void writefr_extra_feature_reg(unsigned int val) +{ + asm volatile ("mcr p15, 1, %0, c15, c1, 0 @ writefr exfr"::"r" + (val):"cc"); + isb(); +} + +/* + * functions + */ +void reset_cpu(unsigned long ignored); +unsigned char get_random_hex(void); +unsigned int kw_sdram_bar(enum memory_bank bank); +unsigned int kw_sdram_bs(enum memory_bank bank); +int kw_config_adr_windows(void); +void kw_config_gpio(unsigned int gpp0_oe_val, unsigned int gpp1_oe_val, + unsigned int gpp0_oe, unsigned int gpp1_oe); +int kw_config_mpp(unsigned int mpp0_7, unsigned int mpp8_15, + unsigned int mpp16_23, unsigned int mpp24_31, + unsigned int mpp32_39, unsigned int mpp40_47, + unsigned int mpp48_55); +#endif /* __ASSEMBLY__ */ + +#endif /* _KWCPU_H */ diff --git a/cpu/arm926ejs/kirkwood/dram.c b/cpu/arm926ejs/kirkwood/dram.c new file mode 100644 index 0000000..9abdca2 --- /dev/null +++ b/cpu/arm926ejs/kirkwood/dram.c @@ -0,0 +1,57 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Prafulla Wadaskar prafulla@marvell.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include <config.h> + +#define KW_REG_CPUCS_WIN_BAR(x) (KW_REGISTER(0x1500) + (x * 0x08)) +#define KW_REG_CPUCS_WIN_SZ(x) (KW_REGISTER(0x1504) + (x * 0x08)) +/* + * kw_sdram_bar - reads SDRAM Base Address Register + */ +u32 kw_sdram_bar(enum memory_bank bank) +{ + u32 result = 0; + u32 enable = 0x01 & readl(KW_REG_CPUCS_WIN_SZ(bank)); + + if ((!enable) || (bank > BANK3)) + return 0; + + result = readl(KW_REG_CPUCS_WIN_BAR(bank)); + return result; +} + +/* + * kw_sdram_bs - reads SDRAM Bank size + */ +u32 kw_sdram_bs(enum memory_bank bank) +{ + u32 result = 0; + u32 enable = 0x01 & readl(KW_REG_CPUCS_WIN_SZ(bank)); + + if ((!enable) || (bank > BANK3)) + return 0; + result = 0xff000000 & readl(KW_REG_CPUCS_WIN_SZ(bank)); + result += 0x01000000; + return result; +} diff --git a/cpu/arm926ejs/kirkwood/timer.c b/cpu/arm926ejs/kirkwood/timer.c new file mode 100644 index 0000000..034acb9 --- /dev/null +++ b/cpu/arm926ejs/kirkwood/timer.c @@ -0,0 +1,159 @@ +/* + * 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 + +#define READ_TIMER (readl(CNTMR_VAL_REG(UBOOT_CNTR)) / \ + (CONFIG_SYS_TCLK / 1000)) + +static ulong timestamp; +static ulong lastdec; + +void reset_timer_masked(void) +{ + /* reset time */ + lastdec = READ_TIMER; + timestamp = 0; +} + +ulong get_timer_masked(void) +{ + ulong now = READ_TIMER; + + if (lastdec >= now) { + /* normal mode */ + timestamp += lastdec - now; + } else { + /* we have an overflow ... */ + timestamp += + lastdec + (TIMER_LOAD_VAL / (CONFIG_SYS_TCLK / 1000)) - now; + } + lastdec = now; + + return timestamp; +} + +void reset_timer(void) +{ + reset_timer_masked(); +} + +ulong get_timer(ulong base) +{ + return get_timer_masked() - base; +} + +void set_timer(ulong t) +{ + timestamp = t; +} + +void udelay(unsigned long usec) +{ + uint current; + ulong delayticks; + + current = readl(CNTMR_VAL_REG(UBOOT_CNTR)); + delayticks = (usec * (CONFIG_SYS_TCLK / 1000000)); + + if (current < delayticks) { + delayticks -= current; + while (readl(CNTMR_VAL_REG(UBOOT_CNTR)) < current) ; + while ((TIMER_LOAD_VAL - delayticks) < + readl(CNTMR_VAL_REG(UBOOT_CNTR))) ; + } else { + while (readl(CNTMR_VAL_REG(UBOOT_CNTR)) > + (current - delayticks)) ; + } +} + +/* + * init the counter + */ +int timer_init(void) +{ + unsigned int cntmrCtrl; + + /* load value onto counter\timer */ + writel(TIMER_LOAD_VAL, CNTMR_RELOAD_REG(UBOOT_CNTR)); + writel(TIMER_LOAD_VAL, CNTMR_VAL_REG(UBOOT_CNTR)); + + /* set the counter to load in the first time */ + writel(TIMER_LOAD_VAL, CNTMR_VAL_REG(UBOOT_CNTR)); + + /* set control for timer \ cunter and enable */ + /* read control register */ + cntmrCtrl = readl(CNTMR_CTRL_REG); + cntmrCtrl |= CTCR_ARM_TIMER_EN(UBOOT_CNTR); /* enable cnt\timer */ + cntmrCtrl |= CTCR_ARM_TIMER_AUTO_EN(UBOOT_CNTR); /* Auto mode */ + + writel(cntmrCtrl, CNTMR_CTRL_REG); + + /* init the timestamp and lastdec value */ + reset_timer_masked(); + + return 0; +} diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 14c818d..9174ec6 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -28,6 +28,7 @@ LIB := $(obj)libserial.a COBJS-$(CONFIG_ARM_DCC) += arm_dcc.o COBJS-$(CONFIG_AT91RM9200_USART) += at91rm9200_usart.o COBJS-$(CONFIG_ATMEL_USART) += atmel_usart.o +COBJS-$(CONFIG_KIRKWOOD_SERIAL) += kirkwood_serial.o COBJS-$(CONFIG_MCFUART) += mcfuart.o COBJS-$(CONFIG_NS9750_UART) += ns9750_serial.o COBJS-$(CONFIG_SYS_NS16550) += ns16550.o diff --git a/drivers/serial/kirkwood_serial.c b/drivers/serial/kirkwood_serial.c new file mode 100644 index 0000000..2f79d59 --- /dev/null +++ b/drivers/serial/kirkwood_serial.c @@ -0,0 +1,128 @@ +/* + * Copyright (C) Marvell International Ltd. and its affiliates + * Prafulla Wadaskar prafulla@marvell.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include <common.h> +#include <asm/arch/serial.h> + +/* static variables */ +#if defined (CONFIG_CONS_INDEX) /* comes from board config */ +#if (CONFIG_CONS_INDEX == 0 ) +static volatile struct kw_uart_port *p_uart_port = + (void *)KW_REGISTER(KW_UART0_BASE); +#elif (CONFIG_CONS_INDEX == 1 ) +static volatile struct kw_uart_port *p_uart_port = + (void *)KW_REGISTER(KW_UART1_BASE); +#endif +#else +#error CONFIG_CONS_INDEX not defined correctly +#endif + +#define CONFIG_KW_UART_PORTS { (void *)KW_UART0_BASE, \ + (void *)KW_UART1_BASE } + +/* + * Serial init banner is kept simplest one + * if required can be created good one + */ +int serial_init(void) +{ + serial_setbrg(); + printf + ("\n*************************************************************"); + return (0); +} + +static void kw_uart_putc(u8 c) +{ + while ((p_uart_port->lsr & LSR_THRE) == 0) ; + p_uart_port->thr = c; + return; +} + +void serial_putc(const char c) +{ + if (c == '\n') + kw_uart_putc('\r'); + + kw_uart_putc(c); +} + +int serial_getc(void) +{ + while ((p_uart_port->lsr & LSR_DR) == 0) ; + return (p_uart_port->rbr); +} + +int serial_tstc(void) +{ + return ((p_uart_port->lsr & LSR_DR) != 0); +} + +void serial_setbrg(void) +{ + DECLARE_GLOBAL_DATA_PTR; + + int clock_divisor = (CONFIG_SYS_TCLK / 16) / gd->baudrate; + + p_uart_port->ier = 0x00; + p_uart_port->lcr = LCR_DIVL_EN; /* Access baud rate */ + p_uart_port->dll = clock_divisor & 0xff; /* 9600 baud */ + p_uart_port->dlm = (clock_divisor >> 8) & 0xff; + p_uart_port->lcr = LCR_8N1; /* 8 data, 1 stop, no parity */ + /* Clear & enable FIFOs */ + p_uart_port->fcr = FCR_FIFO_EN | FCR_RXSR | FCR_TXSR; + return; +} + +void serial_puts(const char *s) +{ + while (*s) { + serial_putc(*s++); + } +} + +#ifdef CONFIG_CMD_KGDB +void kgdb_serial_init(void) +{ +} + +void putDebugChar(int c) +{ + serial_putc(c); +} + +void putDebugStr(const char *str) +{ + serial_puts(str); +} + +int getDebugChar(void) +{ + return serial_getc(); +} + +void kgdb_interruptible(int yes) +{ + return; +} +#endif /* CONFIG_CMD_KGDB */ diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 1350f3e..7ffa47d 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -28,6 +28,7 @@ LIB := $(obj)libspi.a COBJS-$(CONFIG_ATMEL_DATAFLASH_SPI) += atmel_dataflash_spi.o COBJS-$(CONFIG_ATMEL_SPI) += atmel_spi.o COBJS-$(CONFIG_BFIN_SPI) += bfin_spi.o +COBJS-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o COBJS-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o COBJS-$(CONFIG_MXC_SPI) += mxc_spi.o COBJS-$(CONFIG_SOFT_SPI) += soft_spi.o diff --git a/drivers/spi/kirkwood_spi.c b/drivers/spi/kirkwood_spi.c new file mode 100644 index 0000000..f7a70ce --- /dev/null +++ b/drivers/spi/kirkwood_spi.c @@ -0,0 +1,167 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Prafulla Wadaskar prafulla@marvell.com + * + * Derived from drivers/spi/mpc8xxx_spi.c + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include <common.h> +#include <malloc.h> +#include <spi.h> +#include <asm/arch/spi.h> + +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, + unsigned int max_hz, unsigned int mode) +{ + struct spi_slave *slave; + u32 data; + + if (!spi_cs_is_valid(bus, cs)) + return NULL; + + slave = malloc(sizeof(struct spi_slave)); + if (!slave) + return NULL; + + slave->bus = bus; + slave->cs = cs; + + writel(0x00000002, KW_REG_SPI_CTRL); + /* program spi clock prescaller using max_hz */ + data = ((CONFIG_SYS_TCLK / 2) / max_hz) & 0x0000000f; + debug("data = 0x%08x \n", data); + writel(0x00000210 | data, KW_REG_SPI_CONFIG); + writel(0x00000001, KW_REG_SPI_IRQ_CAUSE); + writel(0x00000000, KW_REG_SPI_IRQ_MASK); + + /* program mpp registers to select SPI_CSn */ + if (cs) + writel((readl(KW_REG_MPP_CONTROL0) & 0x0fffffff) | + 0x20000000, KW_REG_MPP_CONTROL0); + else + writel((readl(KW_REG_MPP_CONTROL0) & 0xfffffff0) | + 0x00000002, KW_REG_MPP_CONTROL0); + + return slave; +} + +void spi_free_slave(struct spi_slave *slave) +{ + free(slave); +} + +int spi_claim_bus(struct spi_slave *slave) +{ + return 0; +} + +void spi_release_bus(struct spi_slave *slave) +{ +} + +#ifndef CONFIG_SPI_CS_IS_VALID +/* + * you can define this function board specific + * define above CONFIG in board specific config file and + * provide the function in board specific src file + */ +int spi_cs_is_valid(unsigned int bus, unsigned int cs) +{ + return (bus == 0 && (cs == 0 || cs == 1)); +} +#endif + +void spi_cs_activate(struct spi_slave *slave) +{ + writel(readl(KW_REG_SPI_CTRL) | 1, KW_REG_SPI_CTRL); +} + +void spi_cs_deactivate(struct spi_slave *slave) +{ + writel(readl(KW_REG_SPI_CTRL) & ~1, KW_REG_SPI_CTRL); +} + +int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, + void *din, unsigned long flags) +{ + unsigned int tmpdout, tmpdin; + int tm, isread = 0; + + debug("spi_xfer: slave %u:%u dout %08X din %08X bitlen %u\n", + slave->bus, slave->cs, dout, din, bitlen); + + if (flags & SPI_XFER_BEGIN) + spi_cs_activate(slave); + + /* + * handle data in 8-bit chunks + * TBD: 2byte xfer mode to be enabled + */ + while (bitlen > 4) { + debug("loopstart bitlen %d\n", bitlen); + tmpdout = 0; + /*1 byte xfer mode */ + writel(readl(KW_REG_SPI_CONFIG) & ~(1 << 5), KW_REG_SPI_CONFIG); + /* Shift data so it's msb-justified */ + if (dout) + tmpdout = *(u32 *) dout & 0x0ff; + + writel(0x0, KW_REG_SPI_IRQ_CAUSE); /* clear bit */ + writel(tmpdout, KW_REG_SPI_DATA_OUT); /* Write the data out */ + debug("*** spi_xfer: ... %08x written, bitlen %d\n", + tmpdout, bitlen); + + /* + * Wait for SPI transmit to get out + * or time out (1 second = 1000 ms) + * The NE event must be read and cleared first + */ + for (tm = 0, isread = 0; tm < KW_SPI_TIMEOUT; ++tm) { + if (readl(KW_REG_SPI_IRQ_CAUSE)) { + isread = 1; + tmpdin = readl(KW_REG_SPI_DATA_IN); + debug + ("*** spi_xfer: din %08X ... %08x read\n", + din, tmpdin); + + if (din) { + *((u8 *) din) = (u8) tmpdin; + din += 1; + } + if (dout) + dout += 1; + bitlen -= 8; + } + if (isread) + break; + } + if (tm >= KW_SPI_TIMEOUT) + printf("*** spi_xfer: Time out during SPI transfer\n"); + + debug("loopend bitlen %d\n", bitlen); + } + + if (flags & SPI_XFER_END) + spi_cs_deactivate(slave); + + return 0; +} diff --git a/include/asm-arm/arch-kirkwood/kirkwood.h b/include/asm-arm/arch-kirkwood/kirkwood.h new file mode 100644 index 0000000..d06ec35 --- /dev/null +++ b/include/asm-arm/arch-kirkwood/kirkwood.h @@ -0,0 +1,118 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Prafulla Wadaskar prafulla@marvell.com + * + * Header file for the Marvell's Feroceon CPU core. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef _ASM_ARCH_KIRKWOOD_H +#define _ASM_ARCH_KIRKWOOD_H + +#ifndef __ASSEMBLY__ +#include <asm/types.h> +#include <asm/io.h> +#endif /* __ASSEMBLY__ */ + +#if defined (CONFIG_FEROCEON_88FR131) || defined (CONFIG_SHEEVA_88SV131) +#if defined (CONFIG_KIRKWOOD) +#include <../cpu/arm926ejs/kirkwood/cpu.h> + +/* SOC specific definations */ +#define INTREG_BASE 0xd0000000 +#define KW_REGISTER(x) (KW_REGS_PHY_BASE | x) +#define KW_OFFSET_REG (INTREG_BASE | 0x20080) + +/* undocumented registers */ +#define KW_REG_UNDOC_0x1470 (KW_REGISTER(0x1470)) +#define KW_REG_UNDOC_0x1478 (KW_REGISTER(0x1478)) + +#define KW_UART0_BASE (KW_REGISTER(0x12000)) /* UArt 0 */ +#define KW_UART1_BASE (KW_REGISTER(0x13000)) /* UArt 1 */ + +/* Controler environment registers offsets */ +#define KW_REG_MPP_CONTROL0 (KW_REGISTER(0x10000)) +#define KW_REG_MPP_CONTROL1 (KW_REGISTER(0x10004)) +#define KW_REG_MPP_CONTROL2 (KW_REGISTER(0x10008)) +#define KW_REG_MPP_CONTROL3 (KW_REGISTER(0x1000C)) +#define KW_REG_MPP_CONTROL4 (KW_REGISTER(0x10010)) +#define KW_REG_MPP_CONTROL5 (KW_REGISTER(0x10014)) +#define KW_REG_MPP_CONTROL6 (KW_REGISTER(0x10018)) +#define KW_REG_MPP_SMPL_AT_RST (KW_REGISTER(0x10030)) +#define KW_REG_DEVICE_ID (KW_REGISTER(0x10034)) +#define KW_REG_MPP_OUT_DRV_REG (KW_REGISTER(0x100E0)) + +#define KW_REG_GPP0_DATA_OUT (KW_REGISTER(0x10100)) +#define KW_REG_GPP0_DATA_OUT_EN (KW_REGISTER(0x10104)) +#define KW_REG_GPP0_BLINK_EN (KW_REGISTER(0x10108)) +#define KW_REG_GPP0_DATA_IN_POL (KW_REGISTER(0x1010C)) +#define KW_REG_GPP0_DATA_IN (KW_REGISTER(0x10110)) +#define KW_REG_GPP0_INT_CAUSE (KW_REGISTER(0x10114)) +#define KW_REG_GPP0_INT_MASK (KW_REGISTER(0x10118)) +#define KW_REG_GPP0_INT_LVL (KW_REGISTER(0x1011c)) + +#define KW_REG_GPP1_DATA_OUT (KW_REGISTER(0x10140)) +#define KW_REG_GPP1_DATA_OUT_EN (KW_REGISTER(0x10144)) +#define KW_REG_GPP1_BLINK_EN (KW_REGISTER(0x10148)) +#define KW_REG_GPP1_DATA_IN_POL (KW_REGISTER(0x1014C)) +#define KW_REG_GPP1_DATA_IN (KW_REGISTER(0x10150)) +#define KW_REG_GPP1_INT_CAUSE (KW_REGISTER(0x10154)) +#define KW_REG_GPP1_INT_MASK (KW_REGISTER(0x10158)) +#define KW_REG_GPP1_INT_LVL (KW_REGISTER(0x1015c)) + +#define KW_REG_NAND_READ_PARAM (KW_REGISTER(0x10418)) +#define KW_REG_NAND_WRITE_PARAM (KW_REGISTER(0x1041c)) +#define KW_REG_NAND_CTRL (KW_REGISTER(0x10470)) + +#define KW_REG_WIN_CTRL(x) (KW_REGISTER((0x20000 + (x * 0x10)))) +#define KW_REG_WIN_BASE(x) (KW_REGISTER((0x20004 + (x * 0x10)))) +#define KW_REG_WIN_REMAP_LOW(x) (KW_REGISTER((0x20008 + (x * 0x10)))) +#define KW_REG_WIN_REMAP_HIGH(x) (KW_REGISTER((0x2000c + (x * 0x10)))) + +#define KW_REG_CPU_CONFIG (KW_REGISTER(0x20100)) +#define KW_REG_CPU_CTRL_STAT (KW_REGISTER(0x20104)) +#define KW_REG_CPU_RSTOUTN_MASK (KW_REGISTER(0x20108)) +#define KW_REG_CPU_SYS_SOFT_RST (KW_REGISTER(0x2010C)) +#define KW_REG_CPU_AHB_MBUS_CAUSE_INT (KW_REGISTER(0x20110)) +#define KW_REG_CPU_AHB_MBUS_MASK_INT (KW_REGISTER(0x20114)) +#define KW_REG_CPU_FTDLL_CONFIG (KW_REGISTER(0x20120)) +#define KW_REG_CPU_L2_CONFIG (KW_REGISTER(0x20128)) +#define KW_REG_L2_RAM_TIMING0 (KW_REGISTER(0x20134)) +#define KW_REG_L2_RAM_TIMING1 (KW_REGISTER(0x20138)) + +#define KW_REG_TMR_CTRL (KW_REGISTER(0x20300)) +#define KW_REG_TMR_RELOAD (KW_REGISTER(0x20310)) +#define KW_REG_TMR_VAL (KW_REGISTER(0x20314)) + +#define KW_REG_PCIE_BASE (KW_REGISTER(0x40000)) + +#define KW_EGIGA0_BASE (KW_REGISTER(0x72000)) +#define KW_EGIGA1_BASE (KW_REGISTER(0x76000)) + +#if defined (CONFIG_KW88F6281) +#include "kw88f6281.h" +#endif /* CONFIG_KW88F6281 */ +#if defined (CONFIG_KW88F6192) +#include "kw88f6192.h" +#endif /* CONFIG_KW88F6192 */ +#endif /* CONFIG_KIRKWOOD */ +#endif /* CONFIG_FEROCEON_88FR131 */ +#endif /* _ASM_ARCH_KIRKWOOD_H */ diff --git a/include/asm-arm/arch-kirkwood/kw88f6192.h b/include/asm-arm/arch-kirkwood/kw88f6192.h new file mode 100644 index 0000000..000fc16 --- /dev/null +++ b/include/asm-arm/arch-kirkwood/kw88f6192.h @@ -0,0 +1,37 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Prafulla Wadaskar prafulla@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/arch-kirkwood/serial.h b/include/asm-arm/arch-kirkwood/serial.h new file mode 100644 index 0000000..5fd3b31 --- /dev/null +++ b/include/asm-arm/arch-kirkwood/serial.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) Marvell International Ltd. and its affiliates + * Prafulla Wadaskar prafulla@marvell.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef __KW_SERIAL_H__ +#define __KW_SERIAL_H__ + +/* registers feilds */ +#define FCR_FIFO_EN (1 << 0) /* fifo enable */ +#define FCR_RXSR (1 << 1) /* receiver soft reset */ +#define FCR_TXSR (1 << 2) /* transmitter soft reset */ +#define MCR_RTS (1 << 1) /* ready to send */ + +#define LCR_WLS_OFFS 0 +#define LCR_WLS_MASK (0x3 << LCR_WLS_OFFS) /* character length mask */ +#define LCR_WLS_5 (0x0 << LCR_WLS_OFFS) /* 5 bit character length */ +#define LCR_WLS_6 (0x1 << LCR_WLS_OFFS) /* 6 bit character length */ +#define LCR_WLS_7 (0x2 << LCR_WLS_OFFS) /* 7 bit character length */ +#define LCR_WLS_8 (0x3 << LCR_WLS_OFFS) /* 8 bit character length */ +#define LCR_STP_OFFS 2 +#define LCR_1_STB (0x0 << LCR_STP_OFFS) /* Number of stop Bits */ +#define LCR_2_STB (0x1 << LCR_STP_OFFS) /* Number of stop Bits */ +#define LCR_PEN 0x8 /* Parity enable */ +#define LCR_PS_OFFS 4 +#define LCR_EPS (0x1 << LCR_PS_OFFS) /* Even Parity Select */ +#define LCR_OPS (0x0 << LCR_PS_OFFS) /* Odd Parity Select */ +#define LCR_SBRK_OFFS 0x6 +#define LCR_SBRK (0x1 << LCR_SBRK_OFFS) /* Set Break */ +#define LCR_DIVL_OFFS 7 +#define LCR_DIVL_EN (0x1 << LCR_DIVL_OFFS) /* Divisior latch enable */ + +#define LSR_DR (1 << 0) /* Data ready */ +#define LSR_OE (1 << 1) /* Overrun */ +#define LSR_PE (1 << 2) /* Parity error */ +#define LSR_FE (1 << 3) /* Framing error */ +#define LSR_BI (1 << 4) /* Break */ +#define LSR_THRE (1 << 5) /* Xmit holding register empty */ +#define LSR_TEMT (1 << 6) /* Xmitter empty */ +#define LSR_ERR (1 << 7) /* Error */ + +/* useful defaults for LCR*/ +#define LCR_8N1 LCR_WLS_8 | LCR_1_STB + +/* This structure describes the registers offsets for one UART port/channel */ +struct kw_uart_port { + u8 rbr; /* 0 = 0-3 */ + u8 pad1[3]; + u8 ier; /* 1 = 4-7 */ + u8 pad2[3]; + u8 fcr; /* 2 = 8-b */ + u8 pad3[3]; + u8 lcr; /* 3 = c-f */ + u8 pad4[3]; + u8 mcr; /* 4 = 10-13 */ + u8 pad5[3]; + u8 lsr; /* 5 = 14-17 */ + u8 pad6[3]; + u8 msr; /* 6 =18-1b */ + u8 pad7[3]; + u8 scr; /* 7 =1c-1f */ + u8 pad8[3]; +}; + +/* aliases - for registers which has the same offsets */ +#define thr rbr +#define iir fcr +#define dll rbr +#define dlm ier + +#endif /* __KW_SERIAL_H__ */ diff --git a/include/asm-arm/arch-kirkwood/spi.h b/include/asm-arm/arch-kirkwood/spi.h new file mode 100644 index 0000000..0fd9131 --- /dev/null +++ b/include/asm-arm/arch-kirkwood/spi.h @@ -0,0 +1,39 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Prafulla Wadaskar prafulla@marvell.com + * + * Derived from drivers/spi/mpc8xxx_spi.c + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef __KW_SPI_H__ +#define __KW_SPI_H__ + +/* SPI Registers on kirkwood SOC */ +#define KW_REG_SPI_CTRL KW_REGISTER(0x10600) +#define KW_REG_SPI_CONFIG KW_REGISTER(0x10604) +#define KW_REG_SPI_DATA_OUT KW_REGISTER(0x10608) +#define KW_REG_SPI_DATA_IN KW_REGISTER(0x1060c) +#define KW_REG_SPI_IRQ_CAUSE KW_REGISTER(0x10610) +#define KW_REG_SPI_IRQ_MASK KW_REGISTER(0x10614) + +#define KW_SPI_TIMEOUT 10000 +#endif __KW_SPI_H__ diff --git a/include/asm-arm/cache.h b/include/asm-arm/cache.h new file mode 100644 index 0000000..2f0ea29 --- /dev/null +++ b/include/asm-arm/cache.h @@ -0,0 +1,41 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Prafulla Wadaskar prafulla@marvell.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef _ASM_CACHE_H +#define _ASM_CACHE_H + +#include <asm/system.h> + +/* + * Invalidate L2 Cache using co-proc instruction + */ +static inline void invalidate_l2_cache(void) +{ + unsigned int val=0; + + asm volatile("mcr p15, 1, %0, c15, c11, 0 @ invl l2 cache" + : : "r" (val) : "cc"); + isb(); +} +#endif /* _ASM_CACHE_H */ diff --git a/include/asm-arm/config.h b/include/asm-arm/config.h index 049c44e..5d52f15 100644 --- a/include/asm-arm/config.h +++ b/include/asm-arm/config.h @@ -21,4 +21,8 @@ #ifndef _ASM_CONFIG_H_ #define _ASM_CONFIG_H_
+#if defined (CONFIG_KIRKWOOD) +#include <asm-arm/arch-kirkwood/kirkwood.h> +#endif /* CONFIG_KIRKWOOD */ + #endif diff --git a/include/common.h b/include/common.h index 30fff7d..9e4b859 100644 --- a/include/common.h +++ b/include/common.h @@ -294,6 +294,7 @@ void pciinfo (int, int); #endif #endif
+int arch_misc_init (void); int misc_init_f (void); int misc_init_r (void);
diff --git a/lib_arm/board.c b/lib_arm/board.c index 5d05d9b..b8db60d 100644 --- a/lib_arm/board.c +++ b/lib_arm/board.c @@ -393,6 +393,10 @@ void start_armboot (void)
console_init_r (); /* fully init console as a device */
+#if defined(CONFIG_ARCH_MISC_INIT) + /* miscellaneous arch dependent initialisations */ + arch_misc_init (); +#endif #if defined(CONFIG_MISC_INIT_R) /* miscellaneous platform dependent initialisations */ misc_init_r ();

+#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 */
so please define it and use it
- reg &= ~(1 << 4); /* Clear PortReset Bit */
- writel(reg, (KW_EGIGA0_BASE + 0x44c)); /* PORT_SERIAL_CONTROL1_REG */
- reg = readl((KW_EGIGA1_BASE + 0x44c)); /* PORT_SERIAL_CONTROL1_REG */
- reg &= ~(1 << 4); /* Clear PortReset Bit */
- writel(reg, (KW_EGIGA1_BASE + 0x44c)); /* PORT_SERIAL_CONTROL1_REG */
+#endif +#ifdef CONFIG_KIRKWOOD_PCIE_INIT
- /*
* Enable PCI Express Port0
*/
- reg = readl(KW_REG_CPU_CTRL_STAT);
- reg |= (1 << 0); /* Set PEX0En Bit */
- writel(reg, KW_REG_CPU_CTRL_STAT);
+#endif
- return 0;
+} +#endif /* CONFIG_ARCH_CPU_INIT */ 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 */
a header must only be include in the file that need it please remove from here
#endif diff --git a/include/common.h b/include/common.h index 30fff7d..9e4b859 100644 --- a/include/common.h +++ b/include/common.h @@ -294,6 +294,7 @@ void pciinfo (int, int); #endif #endif
+int arch_misc_init (void);
please move to include/asm-arm/u-boot-arm.h
Best Regards, J.

Dear Jean-Christophe PLAGNIOL-VILLARD,
In message 20090504220837.GB13923@game.jcrosoft.org you wrote:
diff --git a/include/common.h b/include/common.h index 30fff7d..9e4b859 100644 --- a/include/common.h +++ b/include/common.h @@ -294,6 +294,7 @@ void pciinfo (int, int); #endif #endif
+int arch_misc_init (void);
please move to include/asm-arm/u-boot-arm.h
This change request makes no sense to me. Please leave as is.
Best regards,
Wolfgang Denk

On 00:38 Tue 05 May , Wolfgang Denk wrote:
Dear Jean-Christophe PLAGNIOL-VILLARD,
In message 20090504220837.GB13923@game.jcrosoft.org you wrote:
diff --git a/include/common.h b/include/common.h index 30fff7d..9e4b859 100644 --- a/include/common.h +++ b/include/common.h @@ -294,6 +294,7 @@ void pciinfo (int, int); #endif #endif
+int arch_misc_init (void);
please move to include/asm-arm/u-boot-arm.h
This change request makes no sense to me. Please leave as is.
all other arm specific init are already store there so for me it's make sense to have them all store at the same place
Best Regards, J.

Dear Jean-Christophe PLAGNIOL-VILLARD,
In message 20090504223746.GE13923@game.jcrosoft.org you wrote:
please move to include/asm-arm/u-boot-arm.h
This change request makes no sense to me. Please leave as is.
all other arm specific init are already store there so for me it's make sense to have them all store at the same place
arch_misc_init() is not exactly ARM specific. It might as well be used by other architectures (ievenif this is currently not the case).
Best regards,
Wolfgang Denk

-----Original Message----- From: Wolfgang Denk [mailto:wd@denx.de] Sent: Tuesday, May 05, 2009 4:21 AM To: Jean-Christophe PLAGNIOL-VILLARD Cc: Prafulla Wadaskar; u-boot@lists.denx.de; Ashish Karkare; Prabhanjan Sarnaik; Ronen Shitrit Subject: Re: [U-Boot] [PATCH v6] Marvell Kirkwood family SOC support
Dear Jean-Christophe PLAGNIOL-VILLARD,
In message 20090504223746.GE13923@game.jcrosoft.org you wrote:
please move to include/asm-arm/u-boot-arm.h
This change request makes no sense to me. Please leave as is.
all other arm specific init are already store there so for me it's make sense to have them all store at the same place
arch_misc_init() is not exactly ARM specific. It might as well be used by other architectures (ievenif this is currently not the case).
I agree with Wolfgang on this. arch_misc_init() can be used by any architecture. It may not be currently used by other architectures. Same applies for arch_cpu_init() too
Regards.. Prafulla . .

-----Original Message----- From: u-boot-bounces@lists.denx.de [mailto:u-boot-bounces@lists.denx.de] On Behalf Of Prafulla Wadaskar Sent: Tuesday, May 05, 2009 11:41 AM To: Wolfgang Denk; Jean-Christophe PLAGNIOL-VILLARD Cc: u-boot@lists.denx.de; Ashish Karkare; Prabhanjan Sarnaik; Ronen Shitrit Subject: Re: [U-Boot] [PATCH v6] Marvell Kirkwood family SOC support
-----Original Message----- From: Wolfgang Denk [mailto:wd@denx.de] Sent: Tuesday, May 05, 2009 4:21 AM To: Jean-Christophe PLAGNIOL-VILLARD Cc: Prafulla Wadaskar; u-boot@lists.denx.de; Ashish Karkare; Prabhanjan Sarnaik; Ronen Shitrit Subject: Re: [U-Boot] [PATCH v6] Marvell Kirkwood family SOC support
Dear Jean-Christophe PLAGNIOL-VILLARD,
In message 20090504223746.GE13923@game.jcrosoft.org you wrote:
please move to include/asm-arm/u-boot-arm.h
This change request makes no sense to me. Please leave as is.
all other arm specific init are already store there so
for me it's
make sense to have them all store at the same place
arch_misc_init() is not exactly ARM specific. It might as
well be used
by other architectures (ievenif this is currently not the case).
I agree with Wolfgang on this. arch_misc_init() can be used by any architecture. It may not be currently used by other architectures. Same applies for arch_cpu_init() too
Hi Jean, For my next patch I am not changing for arch_misc_init(), i.e. keeping it in common.h There are other architectures (non ARM too) using cpu_init() declared in their respective headers. It make more sense to move them to common.h along with newly defined arch_cpu_init(). Shall I do this as a part of this patch? Or separate patch?
Regards.. Prafulla . .
Regards.. Prafulla . .
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

Kirkwood family controllers are highly integrated SOCs based on Feroceon-88FR131/Sheeva-88SV131 cpu core.
SOC versions supported:- 1) 88F6281-A0 define CONFIG_KW88F6281_A0 2) 88F6192-A0 define CONFIG_KW88F6192_A0
Other supported features:- 1) get_random_hex() fucntion 2) SPI port controller driver 3) PCI Express port initialization
Contributors: Yotam Admon yotam@marvell.com Michael Blostein <michaelbl@marvell.com
Reviewed-by: Ronen Shitrit rshitrit@marvell.com Signed-off-by: Prafulla Wadaskar prafulla@marvell.com --- Change log: v2: crated arch-kirkwood and moved some header files there renamed and moved spi.c to drivers/spi/ renamed and moved serial.c to drivers/serial/ doimage utility removed soc_init.S renamed as lowlevel_init.S debug prints removed
v3: lowlevel_init.S converted to lowlevel_init.c removed BITxx macros, removed entire assembly code Added CONFIG_ARCH_LOWLEVE_INIT support for arm926ejs core updated as per review commens for v2
v4: updated as per review comments for v3 print_cpuinfo used to display Soc info arch_misc_init support created and used for lib_arm mandatory readl/write macros used asm/cache.h asm/arch/spi.h asm//arch/serial.h created and used
v5: updated as per review comments for v4 cosmetic updates, arch_misc_init and arch_cpu_init used start.S updated to call arch_lowlevel_init in case if lowlevl_init is skipped bug fix in cpu.c
v6: lowlevel_init.S removed code moved under arch_cpu_init
v7: include <asm/arch/kirkwood.h> added to each c file reference removed from include/asm/config.h arch_misc_init defination kept as it is in include/common.h bugfixed in get_random_hex function
cpu/arm926ejs/kirkwood/Makefile | 48 +++++ cpu/arm926ejs/kirkwood/config.mk | 25 +++ cpu/arm926ejs/kirkwood/cpu.c | 297 +++++++++++++++++++++++++++++ cpu/arm926ejs/kirkwood/cpu.h | 103 ++++++++++ cpu/arm926ejs/kirkwood/dram.c | 58 ++++++ cpu/arm926ejs/kirkwood/timer.c | 160 ++++++++++++++++ drivers/serial/Makefile | 1 + drivers/serial/kirkwood_serial.c | 129 +++++++++++++ drivers/spi/Makefile | 1 + drivers/spi/kirkwood_spi.c | 168 ++++++++++++++++ include/asm-arm/arch-kirkwood/kirkwood.h | 117 +++++++++++ include/asm-arm/arch-kirkwood/kw88f6192.h | 37 ++++ include/asm-arm/arch-kirkwood/kw88f6281.h | 37 ++++ include/asm-arm/arch-kirkwood/serial.h | 89 +++++++++ include/asm-arm/arch-kirkwood/spi.h | 39 ++++ include/asm-arm/cache.h | 41 ++++ include/common.h | 1 + lib_arm/board.c | 4 + 18 files changed, 1355 insertions(+), 0 deletions(-) create mode 100644 cpu/arm926ejs/kirkwood/Makefile create mode 100644 cpu/arm926ejs/kirkwood/config.mk create mode 100644 cpu/arm926ejs/kirkwood/cpu.c create mode 100644 cpu/arm926ejs/kirkwood/cpu.h create mode 100644 cpu/arm926ejs/kirkwood/dram.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 create mode 100644 include/asm-arm/arch-kirkwood/serial.h create mode 100644 include/asm-arm/arch-kirkwood/spi.h create mode 100644 include/asm-arm/cache.h
diff --git a/cpu/arm926ejs/kirkwood/Makefile b/cpu/arm926ejs/kirkwood/Makefile new file mode 100644 index 0000000..ef1176e --- /dev/null +++ b/cpu/arm926ejs/kirkwood/Makefile @@ -0,0 +1,48 @@ +# +# (C) Copyright 2009 +# Marvell Semiconductor <www.marvell.com> +# Prafulla Wadaskar prafulla@marvell.com +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).a + +COBJS-y = dram.o +COBJS-y += cpu.o +COBJS-y += 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/cpu.c b/cpu/arm926ejs/kirkwood/cpu.c new file mode 100644 index 0000000..c1e9146 --- /dev/null +++ b/cpu/arm926ejs/kirkwood/cpu.c @@ -0,0 +1,297 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Prafulla Wadaskar prafulla@marvell.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include <common.h> +#include <netdev.h> +#include <asm/cache.h> +#include <u-boot/md5.h> +#include <asm/arch/kirkwood.h> + +void reset_cpu(unsigned long ignored) +{ + writel(readl(KW_REG_CPU_RSTOUTN_MASK) | (1 << 2), + KW_REG_CPU_RSTOUTN_MASK); + writel(readl(KW_REG_CPU_SYS_SOFT_RST) | 1, KW_REG_CPU_SYS_SOFT_RST); + while (1) ; +} + +/* + * Generates Ramdom hex number reading some time varient system registers + * and using md5 algorithm + */ +unsigned char get_random_hex(void) +{ + int i; + u32 inbuf[16]; + u8 outbuf[16]; + + /* + * in case of 88F6281/88F6192 A0, + * Bit7 need to reset to generate random values in KW_REG_UNDOC_0x1470 + * Soc reg offsets KW_REG_UNDOC_0x1470 and KW_REG_UNDOC_0x1478 are reserved regs and + * Does not have names at this moment (no errata available) + */ + writel(readl(KW_REG_UNDOC_0x1478) & ~(1 << 7), KW_REG_UNDOC_0x1478); + for (i = 0; i < 16; i++) { + inbuf[i] = readl(KW_REG_UNDOC_0x1470); + } + md5((u8 *) inbuf, 64, outbuf); + return outbuf[outbuf[7] % 0x0f]; +} + +/* + * Window Size + * Used with the Base register to set the address window size and location. + * Must be programmed from LSB to MSB as sequence of 1’s followed by + * sequence of 0’s. The number of 1’s specifies the size of the window in + * 64 KByte granularity (e.g., a value of 0x00FF specifies 256 = 16 MByte). + * NOTE: A value of 0x0 specifies 64-KByte size. + */ +static unsigned int kw_winctrl_calcsize(unsigned int sizeval) +{ + int i; + unsigned int j = 0; + + for (i = 0; i < (sizeval / 0x10000); i++) { + j |= (1 << i); + } + return (0x0000ffff & j); +} + +/* prepares data to be loaded in win_Ctrl register */ +#define KWCPU_WIN_CTRL_DATA(size, target, attr, en) (en | (target << 4) \ + | (attr << 8) | (kw_winctrl_calcsize(size) << 16)) + +/* + * kw_config_adr_windows - Configure address Windows + * + * There are 7 address windows supported by Kirkwood Soc to addess different + * devices. Each window can be configured for size, BAR and remap addr + * Below configuration is standard for most of the cases + * + * Reference Documentation: + * Mbus-L to Mbus Bridge Registers Configuration. + * (Sec 25.1 and 25.3 of Datasheet) + */ +int kw_config_adr_windows(void) +{ + writel(KWCPU_WIN_CTRL_DATA(0xc0000, KWCPU_TARGET_PCIE, + KWCPU_ATTR_PCIE_MEM, KWCPU_WIN_ENABLE), + KW_REG_WIN_CTRL(0)); + + writel(0x90000000, KW_REG_WIN_BASE(0)); + writel(0x90000000, KW_REG_WIN_REMAP_LOW(0)); + writel(0x00000000, KW_REG_WIN_REMAP_HIGH(0)); + + writel(KWCPU_WIN_CTRL_DATA(0x70000, KWCPU_TARGET_MEMORY, + KWCPU_ATTR_NANDFLASH, KWCPU_WIN_ENABLE), + KW_REG_WIN_CTRL(1)); + writel(0xF9000000, KW_REG_WIN_BASE(1)); + writel(0xF9000000, KW_REG_WIN_REMAP_LOW(1)); + writel(0x00000000, KW_REG_WIN_REMAP_HIGH(1)); + + writel(KWCPU_WIN_CTRL_DATA(0x80000, KWCPU_TARGET_PCIE, + KWCPU_ATTR_PCIE_IO, KWCPU_WIN_ENABLE), + KW_REG_WIN_CTRL(2)); + writel(0xF0000000, KW_REG_WIN_BASE(2)); + writel(0xC0000000, KW_REG_WIN_REMAP_LOW(2)); + writel(0x00000000, KW_REG_WIN_REMAP_HIGH(2)); + + writel(KWCPU_WIN_CTRL_DATA(0x80000, KWCPU_TARGET_MEMORY, + KWCPU_ATTR_SPIFLASH, KWCPU_WIN_ENABLE), + KW_REG_WIN_CTRL(3)); + writel(0xF8000000, KW_REG_WIN_BASE(3)); + writel(0x00000000, KW_REG_WIN_REMAP_LOW(3)); + writel(0x00000000, KW_REG_WIN_REMAP_HIGH(3)); + + writel(KWCPU_WIN_CTRL_DATA(0x80000, KWCPU_TARGET_MEMORY, + KWCPU_ATTR_BOOTROM, KWCPU_WIN_ENABLE), + KW_REG_WIN_CTRL(4)); + writel(0xFF000000, KW_REG_WIN_BASE(4)); + writel(0x00000000, KW_REG_WIN_REMAP_LOW(4)); + writel(0x00000000, KW_REG_WIN_REMAP_HIGH(4)); + + writel(KWCPU_WIN_CTRL_DATA(0xb0000, KWCPU_TARGET_MEMORY, + KWCPU_ATTR_SPIFLASH, KWCPU_WIN_DISABLE), + KW_REG_WIN_CTRL(5)); + writel(0xE8000000, KW_REG_WIN_BASE(5)); + writel(0x00000000, KW_REG_WIN_REMAP_LOW(5)); + writel(0x00000000, KW_REG_WIN_REMAP_HIGH(5)); + + writel(KWCPU_WIN_CTRL_DATA(0xb0000, KWCPU_TARGET_MEMORY, + KWCPU_ATTR_BOOTROM, KWCPU_WIN_DISABLE), + KW_REG_WIN_CTRL(6)); + writel(0xF0000000, KW_REG_WIN_BASE(6)); + writel(0x00000000, KW_REG_WIN_REMAP_LOW(6)); + writel(0x00000000, KW_REG_WIN_REMAP_HIGH(6)); + + writel(KWCPU_WIN_CTRL_DATA(0x0, KWCPU_TARGET_SASRAM, KWCPU_ATTR_SASRAM, + KWCPU_WIN_ENABLE), KW_REG_WIN_CTRL(7)); + writel(0xFB000000, KW_REG_WIN_BASE(7)); + writel(0x00000000, KW_REG_WIN_REMAP_LOW(7)); + writel(0x00000000, KW_REG_WIN_REMAP_HIGH(7)); + + return 0; +} + +/* + * kw_config_gpio - GPIO configuration + */ +void kw_config_gpio(u32 gpp0_oe_val, u32 gpp1_oe_val, u32 gpp0_oe, u32 gpp1_oe) +{ + /* Init GPIOS to default values as per board requirement */ + writel(gpp0_oe_val, KW_REG_GPP0_DATA_OUT); + writel(gpp1_oe_val, KW_REG_GPP1_DATA_OUT); + writel(gpp0_oe, KW_REG_GPP0_DATA_OUT_EN); + writel(gpp1_oe, KW_REG_GPP1_DATA_OUT_EN); +} + +/* + * kw_config_mpp - Multi-Purpose Pins Functionality configuration + * + * Each MPP can be configured to different functionality through + * MPP control register, ref (sec 6.1 of kirkwood h/w specification) + * + * There are maximum 64 Multi-Pourpose Pins on Kirkwood + * Each MPP functionality can be configuration by a 4bit value + * of MPP control reg, the value and associated functionality depends + * upon used SoC varient + */ +int kw_config_mpp(u32 mpp0_7, u32 mpp8_15, u32 mpp16_23, u32 mpp24_31, + u32 mpp32_39, u32 mpp40_47, u32 mpp48_55) +{ + /* program mpp registers */ + writel(mpp0_7, KW_REG_MPP_CONTROL0); + writel(mpp8_15, KW_REG_MPP_CONTROL1); + writel(mpp16_23, KW_REG_MPP_CONTROL2); + writel(mpp24_31, KW_REG_MPP_CONTROL3); + writel(mpp32_39, KW_REG_MPP_CONTROL4); + writel(mpp40_47, KW_REG_MPP_CONTROL5); + writel(mpp48_55, KW_REG_MPP_CONTROL6); + return 0; +} + +#if defined(CONFIG_DISPLAY_CPUINFO) +int print_cpuinfo(void) +{ + char *name = "Unknown"; + + switch (readl(KW_REG_DEVICE_ID) & 0x03) { + case 1: + name = "88F6192_A0"; + break; + case 2: + name = "88F6281_A0"; + break; + default: + break; + } + printf("SoC: Kirkwood %s\n", name); + return 0; +} +#endif /* CONFIG_DISPLAY_CPUINFO */ + +#ifdef CONFIG_ARCH_CPU_INIT +int arch_cpu_init(void) +{ + u32 reg; + + /* Linux expects` the internal registers to be at 0xf1000000 */ + writel(KW_REGS_PHY_BASE, KW_OFFSET_REG); + + /* Enable and invalidate L2 cache in write through mode */ + writel(readl(KW_REG_CPU_L2_CONFIG) | 0x18, KW_REG_CPU_L2_CONFIG); + invalidate_l2_cache(); + + kw_config_adr_windows(); + +#ifdef CONFIG_KIRKWOOD_RGMII_PAD_1V8 + /* + * Configures the I/O voltage of the pads connected to Egigabit + * Ethernet interface to 1.8V + * By defult it is set to 3.3V + */ + reg = readl(KW_REG_MPP_OUT_DRV_REG); + reg |= (1 << 7); + writel(reg, KW_REG_MPP_OUT_DRV_REG); +#endif +#ifdef CONFIG_KIRKWOOD_EGIGA_INIT + /* + * Set egiga port0/1 in normal functional mode + * This is required becasue on kirkwood by default ports are in reset mode + * OS egiga driver may not have provision to set them in normal mode + * and if u-boot is build without network support, network may fail at OS level + */ + reg = readl(KWGBE_PORT_SERIAL_CONTROL1_REG(0)); + reg &= ~(1 << 4); /* Clear PortReset Bit */ + writel(reg, (KWGBE_PORT_SERIAL_CONTROL1_REG(0))); + reg = readl(KWGBE_PORT_SERIAL_CONTROL1_REG(1)); + reg &= ~(1 << 4); /* Clear PortReset Bit */ + writel(reg, (KWGBE_PORT_SERIAL_CONTROL1_REG(1))); +#endif +#ifdef CONFIG_KIRKWOOD_PCIE_INIT + /* + * Enable PCI Express Port0 + */ + reg = readl(KW_REG_CPU_CTRL_STAT); + reg |= (1 << 0); /* Set PEX0En Bit */ + writel(reg, KW_REG_CPU_CTRL_STAT); +#endif + return 0; +} +#endif /* CONFIG_ARCH_CPU_INIT */ + +/* + * SOC specific misc init + */ +#if defined(CONFIG_ARCH_MISC_INIT) +int arch_misc_init(void) +{ + volatile u32 temp; + + /*CPU streaming & write allocate */ + temp = readfr_extra_feature_reg(); + temp &= ~(1 << 28); /* disable wr alloc */ + writefr_extra_feature_reg(temp); + + temp = readfr_extra_feature_reg(); + temp &= ~(1 << 29); /* streaming disabled */ + writefr_extra_feature_reg(temp); + + /* L2Cache settings */ + temp = readfr_extra_feature_reg(); + /* Disable L2C pre fetch - Set bit 24 */ + temp |= (1 << 24); + /* enable L2C - Set bit 22 */ + temp |= (1 << 22); + writefr_extra_feature_reg(temp); + + icache_enable(); + /* Change reset vector to address 0x0 */ + temp = get_cr(); + set_cr(temp & ~CR_V); + + return 0; +} +#endif /* CONFIG_ARCH_MISC_INIT */ diff --git a/cpu/arm926ejs/kirkwood/cpu.h b/cpu/arm926ejs/kirkwood/cpu.h new file mode 100644 index 0000000..d36835b --- /dev/null +++ b/cpu/arm926ejs/kirkwood/cpu.h @@ -0,0 +1,103 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Prafulla Wadaskar prafulla@marvell.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef _KWCPU_H +#define _KWCPU_H + +#include <asm/system.h> + +#ifndef __ASSEMBLY__ + +#define KWGBE_PORT_SERIAL_CONTROL1_REG(_x) \ + ((_x ? KW_EGIGA0_BASE : KW_EGIGA1_BASE) + 0x44c) + +enum memory_bank { + BANK0, + BANK1, + BANK2, + BANK3 +}; + +enum kwcpu_winen { + KWCPU_WIN_DISABLE, + KWCPU_WIN_ENABLE +}; + +enum kwcpu_target { + KWCPU_TARGET_RESERVED, + KWCPU_TARGET_MEMORY, + KWCPU_TARGET_1RESERVED, + KWCPU_TARGET_SASRAM, + KWCPU_TARGET_PCIE +}; + +enum kwcpu_attrib { + KWCPU_ATTR_SASRAM = 0x01, + KWCPU_ATTR_NANDFLASH = 0x2f, + KWCPU_ATTR_SPIFLASH = 0x1e, + KWCPU_ATTR_BOOTROM = 0x1d, + KWCPU_ATTR_PCIE_IO = 0xe0, + KWCPU_ATTR_PCIE_MEM = 0xe8 +}; + +/* + * read feroceon/sheeva core extra feature register + * using co-proc instruction + */ +static inline unsigned int readfr_extra_feature_reg(void) +{ + unsigned int val; + asm volatile ("mrc p15, 1, %0, c15, c1, 0 @ readfr exfr":"=r" + (val)::"cc"); + return val; +} + +/* + * write feroceon/sheeva core extra feature register + * using co-proc instruction + */ +static inline void writefr_extra_feature_reg(unsigned int val) +{ + asm volatile ("mcr p15, 1, %0, c15, c1, 0 @ writefr exfr"::"r" + (val):"cc"); + isb(); +} + +/* + * functions + */ +void reset_cpu(unsigned long ignored); +unsigned char get_random_hex(void); +unsigned int kw_sdram_bar(enum memory_bank bank); +unsigned int kw_sdram_bs(enum memory_bank bank); +int kw_config_adr_windows(void); +void kw_config_gpio(unsigned int gpp0_oe_val, unsigned int gpp1_oe_val, + unsigned int gpp0_oe, unsigned int gpp1_oe); +int kw_config_mpp(unsigned int mpp0_7, unsigned int mpp8_15, + unsigned int mpp16_23, unsigned int mpp24_31, + unsigned int mpp32_39, unsigned int mpp40_47, + unsigned int mpp48_55); +#endif /* __ASSEMBLY__ */ + +#endif /* _KWCPU_H */ diff --git a/cpu/arm926ejs/kirkwood/dram.c b/cpu/arm926ejs/kirkwood/dram.c new file mode 100644 index 0000000..3ec0548 --- /dev/null +++ b/cpu/arm926ejs/kirkwood/dram.c @@ -0,0 +1,58 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Prafulla Wadaskar prafulla@marvell.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include <config.h> +#include <asm/arch/kirkwood.h> + +#define KW_REG_CPUCS_WIN_BAR(x) (KW_REGISTER(0x1500) + (x * 0x08)) +#define KW_REG_CPUCS_WIN_SZ(x) (KW_REGISTER(0x1504) + (x * 0x08)) +/* + * kw_sdram_bar - reads SDRAM Base Address Register + */ +u32 kw_sdram_bar(enum memory_bank bank) +{ + u32 result = 0; + u32 enable = 0x01 & readl(KW_REG_CPUCS_WIN_SZ(bank)); + + if ((!enable) || (bank > BANK3)) + return 0; + + result = readl(KW_REG_CPUCS_WIN_BAR(bank)); + return result; +} + +/* + * kw_sdram_bs - reads SDRAM Bank size + */ +u32 kw_sdram_bs(enum memory_bank bank) +{ + u32 result = 0; + u32 enable = 0x01 & readl(KW_REG_CPUCS_WIN_SZ(bank)); + + if ((!enable) || (bank > BANK3)) + return 0; + result = 0xff000000 & readl(KW_REG_CPUCS_WIN_SZ(bank)); + result += 0x01000000; + return result; +} diff --git a/cpu/arm926ejs/kirkwood/timer.c b/cpu/arm926ejs/kirkwood/timer.c new file mode 100644 index 0000000..51661a0 --- /dev/null +++ b/cpu/arm926ejs/kirkwood/timer.c @@ -0,0 +1,160 @@ +/* + * Copyright (C) Marvell International Ltd. and its affiliates + * Prafulla Wadaskar prafulla@marvell.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include <common.h> +#include <asm/arch/kirkwood.h> + +#define UBOOT_CNTR 0 /* counter to use for uboot timer */ + +/* + * ARM Timers Registers Map + */ +#define CNTMR_CTRL_REG KW_REG_TMR_CTRL +#define CNTMR_RELOAD_REG(tmrnum) (KW_REG_TMR_RELOAD + tmrnum*8) +#define CNTMR_VAL_REG(tmrnum) (KW_REG_TMR_VAL + tmrnum*8) + +/* + * ARM Timers Control Register + * CPU_TIMERS_CTRL_REG (CTCR) + */ +#define TIMER0_NUM 0 +#define TIMER1_NUM 1 +#define WATCHDOG_NUM 2 + +#define CTCR_ARM_TIMER_EN_OFFS(cntr) (cntr * 2) +#define CTCR_ARM_TIMER_EN_MASK(cntr) (1 << CTCR_ARM_TIMER_EN_OFFS) +#define CTCR_ARM_TIMER_EN(cntr) (1 << CTCR_ARM_TIMER_EN_OFFS(cntr)) +#define CTCR_ARM_TIMER_DIS(cntr) (0 << CTCR_ARM_TIMER_EN_OFFS(cntr)) + +#define CTCR_ARM_TIMER_AUTO_OFFS(cntr) ((cntr * 2) + 1) +#define CTCR_ARM_TIMER_AUTO_MASK(cntr) (1 << 1) +#define CTCR_ARM_TIMER_AUTO_EN(cntr) (1 << CTCR_ARM_TIMER_AUTO_OFFS(cntr)) +#define CTCR_ARM_TIMER_AUTO_DIS(cntr) (0 << CTCR_ARM_TIMER_AUTO_OFFS(cntr)) + +/* + * ARM Timer\Watchdog Reload Register + * CNTMR_RELOAD_REG (TRR) + */ +#define TRG_ARM_TIMER_REL_OFFS 0 +#define TRG_ARM_TIMER_REL_MASK 0xffffffff + +/* + * ARM Timer\Watchdog Register + * CNTMR_VAL_REG (TVRG) + */ +#define TVR_ARM_TIMER_OFFS 0 +#define TVR_ARM_TIMER_MASK 0xffffffff +#define TVR_ARM_TIMER_MAX 0xffffffff +#define TIMER_LOAD_VAL 0xffffffff + +#define READ_TIMER (readl(CNTMR_VAL_REG(UBOOT_CNTR)) / \ + (CONFIG_SYS_TCLK / 1000)) + +static ulong timestamp; +static ulong lastdec; + +void reset_timer_masked(void) +{ + /* reset time */ + lastdec = READ_TIMER; + timestamp = 0; +} + +ulong get_timer_masked(void) +{ + ulong now = READ_TIMER; + + if (lastdec >= now) { + /* normal mode */ + timestamp += lastdec - now; + } else { + /* we have an overflow ... */ + timestamp += + lastdec + (TIMER_LOAD_VAL / (CONFIG_SYS_TCLK / 1000)) - now; + } + lastdec = now; + + return timestamp; +} + +void reset_timer(void) +{ + reset_timer_masked(); +} + +ulong get_timer(ulong base) +{ + return get_timer_masked() - base; +} + +void set_timer(ulong t) +{ + timestamp = t; +} + +void udelay(unsigned long usec) +{ + uint current; + ulong delayticks; + + current = readl(CNTMR_VAL_REG(UBOOT_CNTR)); + delayticks = (usec * (CONFIG_SYS_TCLK / 1000000)); + + if (current < delayticks) { + delayticks -= current; + while (readl(CNTMR_VAL_REG(UBOOT_CNTR)) < current) ; + while ((TIMER_LOAD_VAL - delayticks) < + readl(CNTMR_VAL_REG(UBOOT_CNTR))) ; + } else { + while (readl(CNTMR_VAL_REG(UBOOT_CNTR)) > + (current - delayticks)) ; + } +} + +/* + * init the counter + */ +int timer_init(void) +{ + unsigned int cntmrCtrl; + + /* load value onto counter\timer */ + writel(TIMER_LOAD_VAL, CNTMR_RELOAD_REG(UBOOT_CNTR)); + writel(TIMER_LOAD_VAL, CNTMR_VAL_REG(UBOOT_CNTR)); + + /* set the counter to load in the first time */ + writel(TIMER_LOAD_VAL, CNTMR_VAL_REG(UBOOT_CNTR)); + + /* set control for timer \ cunter and enable */ + /* read control register */ + cntmrCtrl = readl(CNTMR_CTRL_REG); + cntmrCtrl |= CTCR_ARM_TIMER_EN(UBOOT_CNTR); /* enable cnt\timer */ + cntmrCtrl |= CTCR_ARM_TIMER_AUTO_EN(UBOOT_CNTR); /* Auto mode */ + + writel(cntmrCtrl, CNTMR_CTRL_REG); + + /* init the timestamp and lastdec value */ + reset_timer_masked(); + + return 0; +} diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 14c818d..9174ec6 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -28,6 +28,7 @@ LIB := $(obj)libserial.a COBJS-$(CONFIG_ARM_DCC) += arm_dcc.o COBJS-$(CONFIG_AT91RM9200_USART) += at91rm9200_usart.o COBJS-$(CONFIG_ATMEL_USART) += atmel_usart.o +COBJS-$(CONFIG_KIRKWOOD_SERIAL) += kirkwood_serial.o COBJS-$(CONFIG_MCFUART) += mcfuart.o COBJS-$(CONFIG_NS9750_UART) += ns9750_serial.o COBJS-$(CONFIG_SYS_NS16550) += ns16550.o diff --git a/drivers/serial/kirkwood_serial.c b/drivers/serial/kirkwood_serial.c new file mode 100644 index 0000000..4a2c88c --- /dev/null +++ b/drivers/serial/kirkwood_serial.c @@ -0,0 +1,129 @@ +/* + * Copyright (C) Marvell International Ltd. and its affiliates + * Prafulla Wadaskar prafulla@marvell.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include <common.h> +#include <asm/arch/kirkwood.h> +#include <asm/arch/serial.h> + +/* static variables */ +#if defined (CONFIG_CONS_INDEX) /* comes from board config */ +#if (CONFIG_CONS_INDEX == 0 ) +static volatile struct kw_uart_port *p_uart_port = + (void *)KW_REGISTER(KW_UART0_BASE); +#elif (CONFIG_CONS_INDEX == 1 ) +static volatile struct kw_uart_port *p_uart_port = + (void *)KW_REGISTER(KW_UART1_BASE); +#endif +#else +#error CONFIG_CONS_INDEX not defined correctly +#endif + +#define CONFIG_KW_UART_PORTS { (void *)KW_UART0_BASE, \ + (void *)KW_UART1_BASE } + +/* + * Serial init banner is kept simplest one + * if required can be created good one + */ +int serial_init(void) +{ + serial_setbrg(); + printf + ("\n*************************************************************"); + return (0); +} + +static void kw_uart_putc(u8 c) +{ + while ((p_uart_port->lsr & LSR_THRE) == 0) ; + p_uart_port->thr = c; + return; +} + +void serial_putc(const char c) +{ + if (c == '\n') + kw_uart_putc('\r'); + + kw_uart_putc(c); +} + +int serial_getc(void) +{ + while ((p_uart_port->lsr & LSR_DR) == 0) ; + return (p_uart_port->rbr); +} + +int serial_tstc(void) +{ + return ((p_uart_port->lsr & LSR_DR) != 0); +} + +void serial_setbrg(void) +{ + DECLARE_GLOBAL_DATA_PTR; + + int clock_divisor = (CONFIG_SYS_TCLK / 16) / gd->baudrate; + + p_uart_port->ier = 0x00; + p_uart_port->lcr = LCR_DIVL_EN; /* Access baud rate */ + p_uart_port->dll = clock_divisor & 0xff; /* 9600 baud */ + p_uart_port->dlm = (clock_divisor >> 8) & 0xff; + p_uart_port->lcr = LCR_8N1; /* 8 data, 1 stop, no parity */ + /* Clear & enable FIFOs */ + p_uart_port->fcr = FCR_FIFO_EN | FCR_RXSR | FCR_TXSR; + return; +} + +void serial_puts(const char *s) +{ + while (*s) { + serial_putc(*s++); + } +} + +#ifdef CONFIG_CMD_KGDB +void kgdb_serial_init(void) +{ +} + +void putDebugChar(int c) +{ + serial_putc(c); +} + +void putDebugStr(const char *str) +{ + serial_puts(str); +} + +int getDebugChar(void) +{ + return serial_getc(); +} + +void kgdb_interruptible(int yes) +{ + return; +} +#endif /* CONFIG_CMD_KGDB */ diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 1350f3e..7ffa47d 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -28,6 +28,7 @@ LIB := $(obj)libspi.a COBJS-$(CONFIG_ATMEL_DATAFLASH_SPI) += atmel_dataflash_spi.o COBJS-$(CONFIG_ATMEL_SPI) += atmel_spi.o COBJS-$(CONFIG_BFIN_SPI) += bfin_spi.o +COBJS-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o COBJS-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o COBJS-$(CONFIG_MXC_SPI) += mxc_spi.o COBJS-$(CONFIG_SOFT_SPI) += soft_spi.o diff --git a/drivers/spi/kirkwood_spi.c b/drivers/spi/kirkwood_spi.c new file mode 100644 index 0000000..2881ccb --- /dev/null +++ b/drivers/spi/kirkwood_spi.c @@ -0,0 +1,168 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Prafulla Wadaskar prafulla@marvell.com + * + * Derived from drivers/spi/mpc8xxx_spi.c + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include <common.h> +#include <malloc.h> +#include <spi.h> +#include <asm/arch/kirkwood.h> +#include <asm/arch/spi.h> + +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, + unsigned int max_hz, unsigned int mode) +{ + struct spi_slave *slave; + u32 data; + + if (!spi_cs_is_valid(bus, cs)) + return NULL; + + slave = malloc(sizeof(struct spi_slave)); + if (!slave) + return NULL; + + slave->bus = bus; + slave->cs = cs; + + writel(0x00000002, KW_REG_SPI_CTRL); + /* program spi clock prescaller using max_hz */ + data = ((CONFIG_SYS_TCLK / 2) / max_hz) & 0x0000000f; + debug("data = 0x%08x \n", data); + writel(0x00000210 | data, KW_REG_SPI_CONFIG); + writel(0x00000001, KW_REG_SPI_IRQ_CAUSE); + writel(0x00000000, KW_REG_SPI_IRQ_MASK); + + /* program mpp registers to select SPI_CSn */ + if (cs) + writel((readl(KW_REG_MPP_CONTROL0) & 0x0fffffff) | + 0x20000000, KW_REG_MPP_CONTROL0); + else + writel((readl(KW_REG_MPP_CONTROL0) & 0xfffffff0) | + 0x00000002, KW_REG_MPP_CONTROL0); + + return slave; +} + +void spi_free_slave(struct spi_slave *slave) +{ + free(slave); +} + +int spi_claim_bus(struct spi_slave *slave) +{ + return 0; +} + +void spi_release_bus(struct spi_slave *slave) +{ +} + +#ifndef CONFIG_SPI_CS_IS_VALID +/* + * you can define this function board specific + * define above CONFIG in board specific config file and + * provide the function in board specific src file + */ +int spi_cs_is_valid(unsigned int bus, unsigned int cs) +{ + return (bus == 0 && (cs == 0 || cs == 1)); +} +#endif + +void spi_cs_activate(struct spi_slave *slave) +{ + writel(readl(KW_REG_SPI_CTRL) | 1, KW_REG_SPI_CTRL); +} + +void spi_cs_deactivate(struct spi_slave *slave) +{ + writel(readl(KW_REG_SPI_CTRL) & ~1, KW_REG_SPI_CTRL); +} + +int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, + void *din, unsigned long flags) +{ + unsigned int tmpdout, tmpdin; + int tm, isread = 0; + + debug("spi_xfer: slave %u:%u dout %08X din %08X bitlen %u\n", + slave->bus, slave->cs, dout, din, bitlen); + + if (flags & SPI_XFER_BEGIN) + spi_cs_activate(slave); + + /* + * handle data in 8-bit chunks + * TBD: 2byte xfer mode to be enabled + */ + while (bitlen > 4) { + debug("loopstart bitlen %d\n", bitlen); + tmpdout = 0; + /*1 byte xfer mode */ + writel(readl(KW_REG_SPI_CONFIG) & ~(1 << 5), KW_REG_SPI_CONFIG); + /* Shift data so it's msb-justified */ + if (dout) + tmpdout = *(u32 *) dout & 0x0ff; + + writel(0x0, KW_REG_SPI_IRQ_CAUSE); /* clear bit */ + writel(tmpdout, KW_REG_SPI_DATA_OUT); /* Write the data out */ + debug("*** spi_xfer: ... %08x written, bitlen %d\n", + tmpdout, bitlen); + + /* + * Wait for SPI transmit to get out + * or time out (1 second = 1000 ms) + * The NE event must be read and cleared first + */ + for (tm = 0, isread = 0; tm < KW_SPI_TIMEOUT; ++tm) { + if (readl(KW_REG_SPI_IRQ_CAUSE)) { + isread = 1; + tmpdin = readl(KW_REG_SPI_DATA_IN); + debug + ("*** spi_xfer: din %08X ... %08x read\n", + din, tmpdin); + + if (din) { + *((u8 *) din) = (u8) tmpdin; + din += 1; + } + if (dout) + dout += 1; + bitlen -= 8; + } + if (isread) + break; + } + if (tm >= KW_SPI_TIMEOUT) + printf("*** spi_xfer: Time out during SPI transfer\n"); + + debug("loopend bitlen %d\n", bitlen); + } + + if (flags & SPI_XFER_END) + spi_cs_deactivate(slave); + + return 0; +} diff --git a/include/asm-arm/arch-kirkwood/kirkwood.h b/include/asm-arm/arch-kirkwood/kirkwood.h new file mode 100644 index 0000000..0e6e0be --- /dev/null +++ b/include/asm-arm/arch-kirkwood/kirkwood.h @@ -0,0 +1,117 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Prafulla Wadaskar prafulla@marvell.com + * + * Header file for the Marvell's Feroceon CPU core. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef _ASM_ARCH_KIRKWOOD_H +#define _ASM_ARCH_KIRKWOOD_H + +#ifndef __ASSEMBLY__ +#include <asm/types.h> +#include <asm/io.h> +#endif /* __ASSEMBLY__ */ + +#if defined (CONFIG_FEROCEON_88FR131) || defined (CONFIG_SHEEVA_88SV131) +#include <../cpu/arm926ejs/kirkwood/cpu.h> + +/* SOC specific definations */ +#define INTREG_BASE 0xd0000000 +#define KW_REGISTER(x) (KW_REGS_PHY_BASE | x) +#define KW_OFFSET_REG (INTREG_BASE | 0x20080) + +/* undocumented registers */ +#define KW_REG_UNDOC_0x1470 (KW_REGISTER(0x1470)) +#define KW_REG_UNDOC_0x1478 (KW_REGISTER(0x1478)) + +#define KW_UART0_BASE (KW_REGISTER(0x12000)) /* UArt 0 */ +#define KW_UART1_BASE (KW_REGISTER(0x13000)) /* UArt 1 */ + +/* Controler environment registers offsets */ +#define KW_REG_MPP_CONTROL0 (KW_REGISTER(0x10000)) +#define KW_REG_MPP_CONTROL1 (KW_REGISTER(0x10004)) +#define KW_REG_MPP_CONTROL2 (KW_REGISTER(0x10008)) +#define KW_REG_MPP_CONTROL3 (KW_REGISTER(0x1000C)) +#define KW_REG_MPP_CONTROL4 (KW_REGISTER(0x10010)) +#define KW_REG_MPP_CONTROL5 (KW_REGISTER(0x10014)) +#define KW_REG_MPP_CONTROL6 (KW_REGISTER(0x10018)) +#define KW_REG_MPP_SMPL_AT_RST (KW_REGISTER(0x10030)) +#define KW_REG_DEVICE_ID (KW_REGISTER(0x10034)) +#define KW_REG_MPP_OUT_DRV_REG (KW_REGISTER(0x100E0)) + +#define KW_REG_GPP0_DATA_OUT (KW_REGISTER(0x10100)) +#define KW_REG_GPP0_DATA_OUT_EN (KW_REGISTER(0x10104)) +#define KW_REG_GPP0_BLINK_EN (KW_REGISTER(0x10108)) +#define KW_REG_GPP0_DATA_IN_POL (KW_REGISTER(0x1010C)) +#define KW_REG_GPP0_DATA_IN (KW_REGISTER(0x10110)) +#define KW_REG_GPP0_INT_CAUSE (KW_REGISTER(0x10114)) +#define KW_REG_GPP0_INT_MASK (KW_REGISTER(0x10118)) +#define KW_REG_GPP0_INT_LVL (KW_REGISTER(0x1011c)) + +#define KW_REG_GPP1_DATA_OUT (KW_REGISTER(0x10140)) +#define KW_REG_GPP1_DATA_OUT_EN (KW_REGISTER(0x10144)) +#define KW_REG_GPP1_BLINK_EN (KW_REGISTER(0x10148)) +#define KW_REG_GPP1_DATA_IN_POL (KW_REGISTER(0x1014C)) +#define KW_REG_GPP1_DATA_IN (KW_REGISTER(0x10150)) +#define KW_REG_GPP1_INT_CAUSE (KW_REGISTER(0x10154)) +#define KW_REG_GPP1_INT_MASK (KW_REGISTER(0x10158)) +#define KW_REG_GPP1_INT_LVL (KW_REGISTER(0x1015c)) + +#define KW_REG_NAND_READ_PARAM (KW_REGISTER(0x10418)) +#define KW_REG_NAND_WRITE_PARAM (KW_REGISTER(0x1041c)) +#define KW_REG_NAND_CTRL (KW_REGISTER(0x10470)) + +#define KW_REG_WIN_CTRL(x) (KW_REGISTER((0x20000 + (x * 0x10)))) +#define KW_REG_WIN_BASE(x) (KW_REGISTER((0x20004 + (x * 0x10)))) +#define KW_REG_WIN_REMAP_LOW(x) (KW_REGISTER((0x20008 + (x * 0x10)))) +#define KW_REG_WIN_REMAP_HIGH(x) (KW_REGISTER((0x2000c + (x * 0x10)))) + +#define KW_REG_CPU_CONFIG (KW_REGISTER(0x20100)) +#define KW_REG_CPU_CTRL_STAT (KW_REGISTER(0x20104)) +#define KW_REG_CPU_RSTOUTN_MASK (KW_REGISTER(0x20108)) +#define KW_REG_CPU_SYS_SOFT_RST (KW_REGISTER(0x2010C)) +#define KW_REG_CPU_AHB_MBUS_CAUSE_INT (KW_REGISTER(0x20110)) +#define KW_REG_CPU_AHB_MBUS_MASK_INT (KW_REGISTER(0x20114)) +#define KW_REG_CPU_FTDLL_CONFIG (KW_REGISTER(0x20120)) +#define KW_REG_CPU_L2_CONFIG (KW_REGISTER(0x20128)) +#define KW_REG_L2_RAM_TIMING0 (KW_REGISTER(0x20134)) +#define KW_REG_L2_RAM_TIMING1 (KW_REGISTER(0x20138)) + +#define KW_REG_TMR_CTRL (KW_REGISTER(0x20300)) +#define KW_REG_TMR_RELOAD (KW_REGISTER(0x20310)) +#define KW_REG_TMR_VAL (KW_REGISTER(0x20314)) + +#define KW_REG_PCIE_BASE (KW_REGISTER(0x40000)) + +#define KW_EGIGA0_BASE (KW_REGISTER(0x72000)) +#define KW_EGIGA1_BASE (KW_REGISTER(0x76000)) + +#if defined (CONFIG_KW88F6281) +#include "kw88f6281.h" +#endif /* CONFIG_KW88F6281 */ +#if defined (CONFIG_KW88F6192) +#include "kw88f6192.h" +#endif /* CONFIG_KW88F6192 */ + +#endif /* CONFIG_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/arch-kirkwood/serial.h b/include/asm-arm/arch-kirkwood/serial.h new file mode 100644 index 0000000..5fd3b31 --- /dev/null +++ b/include/asm-arm/arch-kirkwood/serial.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) Marvell International Ltd. and its affiliates + * Prafulla Wadaskar prafulla@marvell.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef __KW_SERIAL_H__ +#define __KW_SERIAL_H__ + +/* registers feilds */ +#define FCR_FIFO_EN (1 << 0) /* fifo enable */ +#define FCR_RXSR (1 << 1) /* receiver soft reset */ +#define FCR_TXSR (1 << 2) /* transmitter soft reset */ +#define MCR_RTS (1 << 1) /* ready to send */ + +#define LCR_WLS_OFFS 0 +#define LCR_WLS_MASK (0x3 << LCR_WLS_OFFS) /* character length mask */ +#define LCR_WLS_5 (0x0 << LCR_WLS_OFFS) /* 5 bit character length */ +#define LCR_WLS_6 (0x1 << LCR_WLS_OFFS) /* 6 bit character length */ +#define LCR_WLS_7 (0x2 << LCR_WLS_OFFS) /* 7 bit character length */ +#define LCR_WLS_8 (0x3 << LCR_WLS_OFFS) /* 8 bit character length */ +#define LCR_STP_OFFS 2 +#define LCR_1_STB (0x0 << LCR_STP_OFFS) /* Number of stop Bits */ +#define LCR_2_STB (0x1 << LCR_STP_OFFS) /* Number of stop Bits */ +#define LCR_PEN 0x8 /* Parity enable */ +#define LCR_PS_OFFS 4 +#define LCR_EPS (0x1 << LCR_PS_OFFS) /* Even Parity Select */ +#define LCR_OPS (0x0 << LCR_PS_OFFS) /* Odd Parity Select */ +#define LCR_SBRK_OFFS 0x6 +#define LCR_SBRK (0x1 << LCR_SBRK_OFFS) /* Set Break */ +#define LCR_DIVL_OFFS 7 +#define LCR_DIVL_EN (0x1 << LCR_DIVL_OFFS) /* Divisior latch enable */ + +#define LSR_DR (1 << 0) /* Data ready */ +#define LSR_OE (1 << 1) /* Overrun */ +#define LSR_PE (1 << 2) /* Parity error */ +#define LSR_FE (1 << 3) /* Framing error */ +#define LSR_BI (1 << 4) /* Break */ +#define LSR_THRE (1 << 5) /* Xmit holding register empty */ +#define LSR_TEMT (1 << 6) /* Xmitter empty */ +#define LSR_ERR (1 << 7) /* Error */ + +/* useful defaults for LCR*/ +#define LCR_8N1 LCR_WLS_8 | LCR_1_STB + +/* This structure describes the registers offsets for one UART port/channel */ +struct kw_uart_port { + u8 rbr; /* 0 = 0-3 */ + u8 pad1[3]; + u8 ier; /* 1 = 4-7 */ + u8 pad2[3]; + u8 fcr; /* 2 = 8-b */ + u8 pad3[3]; + u8 lcr; /* 3 = c-f */ + u8 pad4[3]; + u8 mcr; /* 4 = 10-13 */ + u8 pad5[3]; + u8 lsr; /* 5 = 14-17 */ + u8 pad6[3]; + u8 msr; /* 6 =18-1b */ + u8 pad7[3]; + u8 scr; /* 7 =1c-1f */ + u8 pad8[3]; +}; + +/* aliases - for registers which has the same offsets */ +#define thr rbr +#define iir fcr +#define dll rbr +#define dlm ier + +#endif /* __KW_SERIAL_H__ */ diff --git a/include/asm-arm/arch-kirkwood/spi.h b/include/asm-arm/arch-kirkwood/spi.h new file mode 100644 index 0000000..d8fcb86 --- /dev/null +++ b/include/asm-arm/arch-kirkwood/spi.h @@ -0,0 +1,39 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Prafulla Wadaskar prafulla@marvell.com + * + * Derived from drivers/spi/mpc8xxx_spi.c + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef __KW_SPI_H__ +#define __KW_SPI_H__ + +/* SPI Registers on kirkwood SOC */ +#define KW_REG_SPI_CTRL KW_REGISTER(0x10600) +#define KW_REG_SPI_CONFIG KW_REGISTER(0x10604) +#define KW_REG_SPI_DATA_OUT KW_REGISTER(0x10608) +#define KW_REG_SPI_DATA_IN KW_REGISTER(0x1060c) +#define KW_REG_SPI_IRQ_CAUSE KW_REGISTER(0x10610) +#define KW_REG_SPI_IRQ_MASK KW_REGISTER(0x10614) + +#define KW_SPI_TIMEOUT 10000 +#endif /* __KW_SPI_H__ */ diff --git a/include/asm-arm/cache.h b/include/asm-arm/cache.h new file mode 100644 index 0000000..2f0ea29 --- /dev/null +++ b/include/asm-arm/cache.h @@ -0,0 +1,41 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Prafulla Wadaskar prafulla@marvell.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef _ASM_CACHE_H +#define _ASM_CACHE_H + +#include <asm/system.h> + +/* + * Invalidate L2 Cache using co-proc instruction + */ +static inline void invalidate_l2_cache(void) +{ + unsigned int val=0; + + asm volatile("mcr p15, 1, %0, c15, c11, 0 @ invl l2 cache" + : : "r" (val) : "cc"); + isb(); +} +#endif /* _ASM_CACHE_H */ diff --git a/include/common.h b/include/common.h index 30fff7d..9e4b859 100644 --- a/include/common.h +++ b/include/common.h @@ -294,6 +294,7 @@ void pciinfo (int, int); #endif #endif
+int arch_misc_init (void); int misc_init_f (void); int misc_init_r (void);
diff --git a/lib_arm/board.c b/lib_arm/board.c index 5d05d9b..b8db60d 100644 --- a/lib_arm/board.c +++ b/lib_arm/board.c @@ -393,6 +393,10 @@ void start_armboot (void)
console_init_r (); /* fully init console as a device */
+#if defined(CONFIG_ARCH_MISC_INIT) + /* miscellaneous arch dependent initialisations */ + arch_misc_init (); +#endif #if defined(CONFIG_MISC_INIT_R) /* miscellaneous platform dependent initialisations */ misc_init_r ();

- icache_enable();
- /* Change reset vector to address 0x0 */
- temp = get_cr();
- set_cr(temp & ~CR_V);
- return 0;
+} +#endif /* CONFIG_ARCH_MISC_INIT */ diff --git a/cpu/arm926ejs/kirkwood/cpu.h b/cpu/arm926ejs/kirkwood/cpu.h
please move to include/asm-arm/arch-kirkwood/
new file mode 100644 index 0000000..d36835b --- /dev/null +++ b/cpu/arm926ejs/kirkwood/cpu.h @@ -0,0 +1,103 @@ +/*
- (C) Copyright 2009
- Marvell Semiconductor <www.marvell.com>
- Prafulla Wadaskar prafulla@marvell.com
- See file CREDITS for list of people who contributed to this
- project.
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of
- the License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- MA 02110-1301 USA
- */
+#ifndef _KWCPU_H +#define _KWCPU_H
+#include <asm/system.h>
+#ifndef __ASSEMBLY__
+#define KWGBE_PORT_SERIAL_CONTROL1_REG(_x) \
((_x ? KW_EGIGA0_BASE : KW_EGIGA1_BASE) + 0x44c)
+enum memory_bank {
- BANK0,
....
+void serial_putc(const char c) +{
- if (c == '\n')
kw_uart_putc('\r');
- kw_uart_putc(c);
+}
+int serial_getc(void) +{
- while ((p_uart_port->lsr & LSR_DR) == 0) ;
while(!serial_tstc());
- 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 */
no need please remove the KGBD support as the does not support it
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/include/asm-arm/arch-kirkwood/kirkwood.h b/include/asm-arm/arch-kirkwood/kirkwood.h new file mode 100644 index 0000000..0e6e0be --- /dev/null +++ b/include/asm-arm/arch-kirkwood/kirkwood.h @@ -0,0 +1,117 @@ +/*
- (C) Copyright 2009
- Marvell Semiconductor <www.marvell.com>
- Prafulla Wadaskar prafulla@marvell.com
- Header file for the Marvell's Feroceon CPU core.
- See file CREDITS for list of people who contributed to this
- project.
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of
- the License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- MA 02110-1301 USA
- */
+#ifndef _ASM_ARCH_KIRKWOOD_H +#define _ASM_ARCH_KIRKWOOD_H
+#ifndef __ASSEMBLY__ +#include <asm/types.h> +#include <asm/io.h> +#endif /* __ASSEMBLY__ */
+#if defined (CONFIG_FEROCEON_88FR131) || defined (CONFIG_SHEEVA_88SV131) +#include <../cpu/arm926ejs/kirkwood/cpu.h>
as mention upper include/asm/arch/cpu.h
+#if defined (CONFIG_KW88F6281) +#include "kw88f6281.h"
please use <include/asm/arch/kw88f6281.h>
+#endif /* CONFIG_KW88F6281 */ +#if defined (CONFIG_KW88F6192)
please use elif as they will not be include together
+#include "kw88f6192.h"
please use <include/asm/arch/kw88f6192.h>
+#endif /* CONFIG_KW88F6192 */
+#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
Best Regards, J.

Dear Prafulla Wadaskar,
+unsigned char get_random_hex(void) +{
- int i;
- u32 inbuf[16];
- u8 outbuf[16];
- /*
* in case of 88F6281/88F6192 A0,
* Bit7 need to reset to generate random values in KW_REG_UNDOC_0x1470
* Soc reg offsets KW_REG_UNDOC_0x1470 and KW_REG_UNDOC_0x1478 are reserved regs and
* Does not have names at this moment (no errata available)
*/
- writel(readl(KW_REG_UNDOC_0x1478) & ~(1 << 7), KW_REG_UNDOC_0x1478);
- for (i = 0; i < 16; i++) {
either use a #define'd name instead of the repeated 16, or use sizeof(inbuf), but don't hard-code the same constant in multiple places. This is calling for inconsistency.
--- /dev/null +++ b/drivers/serial/kirkwood_serial.c @@ -0,0 +1,129 @@
... ...
+static void kw_uart_putc(u8 c) +{
- while ((p_uart_port->lsr & LSR_THRE) == 0) ;
- p_uart_port->thr = c;
- return;
+}
+void serial_putc(const char c) +{
- if (c == '\n')
kw_uart_putc('\r');
- kw_uart_putc(c);
+}
+int serial_getc(void) +{
- while ((p_uart_port->lsr & LSR_DR) == 0) ;
- return (p_uart_port->rbr);
+}
+int serial_tstc(void) +{
- return ((p_uart_port->lsr & LSR_DR) != 0);
+}
+void serial_setbrg(void) +{
- DECLARE_GLOBAL_DATA_PTR;
- int clock_divisor = (CONFIG_SYS_TCLK / 16) / gd->baudrate;
- p_uart_port->ier = 0x00;
- p_uart_port->lcr = LCR_DIVL_EN; /* Access baud rate */
- p_uart_port->dll = clock_divisor & 0xff; /* 9600 baud */
- p_uart_port->dlm = (clock_divisor >> 8) & 0xff;
- p_uart_port->lcr = LCR_8N1; /* 8 data, 1 stop, no parity */
- /* Clear & enable FIFOs */
- p_uart_port->fcr = FCR_FIFO_EN | FCR_RXSR | FCR_TXSR;
- return;
Please use I/O accessors instead of all trhese raw register accesses.
+/* SOC specific definations */ +#define INTREG_BASE 0xd0000000 +#define KW_REGISTER(x) (KW_REGS_PHY_BASE | x) +#define KW_OFFSET_REG (INTREG_BASE | 0x20080)
You want to perform a "base + offset" addition, so please write this as an addition and not as a logical operation! But...
+/* undocumented registers */ +#define KW_REG_UNDOC_0x1470 (KW_REGISTER(0x1470)) +#define KW_REG_UNDOC_0x1478 (KW_REGISTER(0x1478))
+#define KW_UART0_BASE (KW_REGISTER(0x12000)) /* UArt 0 */ +#define KW_UART1_BASE (KW_REGISTER(0x13000)) /* UArt 1 */
+/* Controler environment registers offsets */ +#define KW_REG_MPP_CONTROL0 (KW_REGISTER(0x10000)) +#define KW_REG_MPP_CONTROL1 (KW_REGISTER(0x10004)) +#define KW_REG_MPP_CONTROL2 (KW_REGISTER(0x10008)) +#define KW_REG_MPP_CONTROL3 (KW_REGISTER(0x1000C)) +#define KW_REG_MPP_CONTROL4 (KW_REGISTER(0x10010)) +#define KW_REG_MPP_CONTROL5 (KW_REGISTER(0x10014)) +#define KW_REG_MPP_CONTROL6 (KW_REGISTER(0x10018)) +#define KW_REG_MPP_SMPL_AT_RST (KW_REGISTER(0x10030)) +#define KW_REG_DEVICE_ID (KW_REGISTER(0x10034)) +#define KW_REG_MPP_OUT_DRV_REG (KW_REGISTER(0x100E0))
+#define KW_REG_GPP0_DATA_OUT (KW_REGISTER(0x10100)) +#define KW_REG_GPP0_DATA_OUT_EN (KW_REGISTER(0x10104)) +#define KW_REG_GPP0_BLINK_EN (KW_REGISTER(0x10108)) +#define KW_REG_GPP0_DATA_IN_POL (KW_REGISTER(0x1010C)) +#define KW_REG_GPP0_DATA_IN (KW_REGISTER(0x10110)) +#define KW_REG_GPP0_INT_CAUSE (KW_REGISTER(0x10114)) +#define KW_REG_GPP0_INT_MASK (KW_REGISTER(0x10118)) +#define KW_REG_GPP0_INT_LVL (KW_REGISTER(0x1011c))
+#define KW_REG_GPP1_DATA_OUT (KW_REGISTER(0x10140)) +#define KW_REG_GPP1_DATA_OUT_EN (KW_REGISTER(0x10144)) +#define KW_REG_GPP1_BLINK_EN (KW_REGISTER(0x10148)) +#define KW_REG_GPP1_DATA_IN_POL (KW_REGISTER(0x1014C)) +#define KW_REG_GPP1_DATA_IN (KW_REGISTER(0x10150)) +#define KW_REG_GPP1_INT_CAUSE (KW_REGISTER(0x10154)) +#define KW_REG_GPP1_INT_MASK (KW_REGISTER(0x10158)) +#define KW_REG_GPP1_INT_LVL (KW_REGISTER(0x1015c))
+#define KW_REG_NAND_READ_PARAM (KW_REGISTER(0x10418)) +#define KW_REG_NAND_WRITE_PARAM (KW_REGISTER(0x1041c)) +#define KW_REG_NAND_CTRL (KW_REGISTER(0x10470))
+#define KW_REG_WIN_CTRL(x) (KW_REGISTER((0x20000 + (x * 0x10)))) +#define KW_REG_WIN_BASE(x) (KW_REGISTER((0x20004 + (x * 0x10)))) +#define KW_REG_WIN_REMAP_LOW(x) (KW_REGISTER((0x20008 + (x * 0x10)))) +#define KW_REG_WIN_REMAP_HIGH(x) (KW_REGISTER((0x2000c + (x * 0x10))))
+#define KW_REG_CPU_CONFIG (KW_REGISTER(0x20100)) +#define KW_REG_CPU_CTRL_STAT (KW_REGISTER(0x20104)) +#define KW_REG_CPU_RSTOUTN_MASK (KW_REGISTER(0x20108)) +#define KW_REG_CPU_SYS_SOFT_RST (KW_REGISTER(0x2010C)) +#define KW_REG_CPU_AHB_MBUS_CAUSE_INT (KW_REGISTER(0x20110)) +#define KW_REG_CPU_AHB_MBUS_MASK_INT (KW_REGISTER(0x20114)) +#define KW_REG_CPU_FTDLL_CONFIG (KW_REGISTER(0x20120)) +#define KW_REG_CPU_L2_CONFIG (KW_REGISTER(0x20128)) +#define KW_REG_L2_RAM_TIMING0 (KW_REGISTER(0x20134)) +#define KW_REG_L2_RAM_TIMING1 (KW_REGISTER(0x20138))
+#define KW_REG_TMR_CTRL (KW_REGISTER(0x20300)) +#define KW_REG_TMR_RELOAD (KW_REGISTER(0x20310)) +#define KW_REG_TMR_VAL (KW_REGISTER(0x20314))
+#define KW_REG_PCIE_BASE (KW_REGISTER(0x40000))
+#define KW_EGIGA0_BASE (KW_REGISTER(0x72000)) +#define KW_EGIGA1_BASE (KW_REGISTER(0x76000))
... please get rid of all these register offsets and use C structs instead, as has been discussed here a couple of times recently.
...
+++ b/include/asm-arm/arch-kirkwood/serial.h @@ -0,0 +1,89 @@
...
+/* This structure describes the registers offsets for one UART port/channel */ +struct kw_uart_port {
- u8 rbr; /* 0 = 0-3 */
- u8 pad1[3];
- u8 ier; /* 1 = 4-7 */
- u8 pad2[3];
- u8 fcr; /* 2 = 8-b */
- u8 pad3[3];
- u8 lcr; /* 3 = c-f */
- u8 pad4[3];
- u8 mcr; /* 4 = 10-13 */
- u8 pad5[3];
- u8 lsr; /* 5 = 14-17 */
- u8 pad6[3];
- u8 msr; /* 6 =18-1b */
- u8 pad7[3];
- u8 scr; /* 7 =1c-1f */
- u8 pad8[3];
+};
Come on. Why does this have to be a separate header file? Does this not look very much the same like a zillion of other UARTs Why cannot you simply use "include/ns16550.h" instead?
Heck. Why do you need your own serial driver at all? I bet the standard 16550 driver just works fine for you, too.
Best regards,
Wolfgang Denk

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

Dear Prafulla Wadaskar,
In message 1242763678-13724-1-git-send-email-prafulla@marvell.com you wrote:
Kirkwood family controllers are highly integrated SOCs based on Feroceon-88FR131/Sheeva-88SV131 cpu core.
...
+/*
- Window Size
- Used with the Base register to set the address window size and location.
- Must be programmed from LSB to MSB as sequence of 1âs followed by
- sequence of 0âs. The number of 1âs specifies the size of the window in
- 64 KByte granularity (e.g., a value of 0x00FF specifies 256 = 16 MByte).
- NOTE: A value of 0x0 specifies 64-KByte size.
- */
You have a number of strange special characters here. Please try and restrict yourself to plain ASCII text in normal C comments.
- for (i = 0; i < (sizeval / 0x10000); i++) {
j |= (1 << i);
- }
No curly braces for single line statements, please.
+}
+/* prepares data to be loaded in win_Ctrl register */ +#define KWCPU_WIN_CTRL_DATA(size, target, attr, en) (en | (target << 4) \
| (attr << 8) | (kw_winctrl_calcsize(size) << 16))
+/*
- kw_config_adr_windows - Configure address Windows
- There are 7 address windows supported by Kirkwood Soc to addess different
- devices. Each window can be configured for size, BAR and remap addr
- Below configuration is standard for most of the cases
- Reference Documentation:
- Mbus-L to Mbus Bridge Registers Configuration.
- (Sec 25.1 and 25.3 of Datasheet)
- */
+int kw_config_adr_windows(void) +{
- struct kwwin_registers *winregs = (struct kwwin_registers *)KW_CPU_WIN_BASE;
Line too long.
+/*
- kw_config_gpio - GPIO configuration
- */
+void kw_config_gpio(u32 gpp0_oe_val, u32 gpp1_oe_val, u32 gpp0_oe, u32 gpp1_oe) +{
- struct kwgpio_registers *gpio0reg = (struct kwgpio_registers *)KW_GPIO0_BASE;
- struct kwgpio_registers *gpio1reg = (struct kwgpio_registers *)KW_GPIO1_BASE;
More too long lines. Pleasse check everywhere.
- /* Init GPIOS to default values as per board requirement */
- writel(gpp0_oe_val, (u32)&gpio0reg->dout);
- writel(gpp1_oe_val, (u32)&gpio1reg->dout);
- writel(gpp0_oe, (u32)&gpio0reg->oe);
- writel(gpp1_oe, (u32)&gpio1reg->oe);
Why are you using these casts here? The whole purpose of using a C struct to access device registers is to enable type checking by the C compiler, but you sabotage this with these casts. Please don't do that.
Why are you using these casts here? The whole purpose of using a C struct to access device registers is to enable type checking by the C compiler, but you sabotage this with these casts. Please don't do that. This comment applies to the whole patch.
...
- cntmrctrl = readl(CNTMR_CTRL_REG);
- cntmrctrl |= CTCR_ARM_TIMER_EN(UBOOT_CNTR); /* enable cnt\timer */
Are you sure you want to have a TAB character in this comment? What's "cnt imer" ? :-)
diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c index 966df9a..dd5f332 100644 --- a/drivers/serial/serial.c +++ b/drivers/serial/serial.c @@ -27,6 +27,9 @@ #ifdef CONFIG_NS87308 #include <ns87308.h> #endif +#ifdef CONFIG_KIRKWOOD +#include <asm/arch/kirkwood.h> +#endif
What exactly is this needed for?
#if defined (CONFIG_SERIAL_MULTI) #include <serial.h> diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 1350f3e..7ffa47d 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -28,6 +28,7 @@ LIB := $(obj)libspi.a COBJS-$(CONFIG_ATMEL_DATAFLASH_SPI) += atmel_dataflash_spi.o COBJS-$(CONFIG_ATMEL_SPI) += atmel_spi.o COBJS-$(CONFIG_BFIN_SPI) += bfin_spi.o +COBJS-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o COBJS-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o COBJS-$(CONFIG_MXC_SPI) += mxc_spi.o COBJS-$(CONFIG_SOFT_SPI) += soft_spi.o diff --git a/drivers/spi/kirkwood_spi.c b/drivers/spi/kirkwood_spi.c new file mode 100644 index 0000000..e0c4f0a --- /dev/null +++ b/drivers/spi/kirkwood_spi.c @@ -0,0 +1,169 @@ +/*
- (C) Copyright 2009
- Marvell Semiconductor <www.marvell.com>
- Prafulla Wadaskar prafulla@marvell.com
- Derived from drivers/spi/mpc8xxx_spi.c
- See file CREDITS for list of people who contributed to this
- project.
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of
- the License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- MA 02110-1301 USA
- */
+#include <common.h> +#include <malloc.h> +#include <spi.h> +#include <asm/arch/kirkwood.h> +#include <asm/arch/spi.h>
+struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
unsigned int max_hz, unsigned int mode)
+{
- struct spi_slave *slave;
- u32 data;
- u32 *mppreg = (u32 *)KW_MPP_BASE;
- if (!spi_cs_is_valid(bus, cs))
return NULL;
- slave = malloc(sizeof(struct spi_slave));
- if (!slave)
return NULL;
- slave->bus = bus;
- slave->cs = cs;
- writel(0x00000002, KW_REG_SPI_CTRL);
- /* program spi clock prescaller using max_hz */
- data = ((CONFIG_SYS_TCLK / 2) / max_hz) & 0x0000000f;
- debug("data = 0x%08x \n", data);
- writel(0x00000210 | data, KW_REG_SPI_CONFIG);
- writel(0x00000001, KW_REG_SPI_IRQ_CAUSE);
- writel(0x00000000, KW_REG_SPI_IRQ_MASK);
What does these magic constants mean?
- /* program mpp registers to select SPI_CSn */
- if (cs)
writel((readl((u32)&mppreg[0]) & 0x0fffffff) |
0x20000000, (u32)&mppreg[0]);
- else
writel((readl((u32)&mppreg[0]) & 0xfffffff0) |
0x00000002, (u32)&mppreg[0]);
Ot these?
+int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
void *din, unsigned long flags)
...
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);
Indentation by TABs only, please.
+#define INTREG_BASE 0xd0000000 +#define KW_REGISTER(x) (KW_REGS_PHY_BASE + x) +#define KW_OFFSET_REG (INTREG_BASE + 0x20080)
+/* undocumented registers */ +#define KW_REG_UNDOC_0x1470 (KW_REGISTER(0x1470)) +#define KW_REG_UNDOC_0x1478 (KW_REGISTER(0x1478))
+#define KW_UART0_BASE (KW_REGISTER(0x12000)) +#define KW_UART1_BASE (KW_REGISTER(0x13000)) +#define KW_MPP_BASE (KW_REGISTER(0x10000)) +#define KW_GPIO0_BASE (KW_REGISTER(0x10100)) +#define KW_GPIO1_BASE (KW_REGISTER(0x10140)) +#define KW_CPU_WIN_BASE (KW_REGISTER(0x20000)) +#define KW_CPU_REG_BASE (KW_REGISTER(0x20100)) +#define KW_TIMER_BASE (KW_REGISTER(0x20300)) +#define KW_REG_PCIE_BASE (KW_REGISTER(0x40000)) +#define KW_EGIGA0_BASE (KW_REGISTER(0x72000)) +#define KW_EGIGA1_BASE (KW_REGISTER(0x76000))
Use a C struct?
Best regards,
Wolfgang Denk

Dear Wolfgand Denk
Thanks for your review comments
-----Original Message----- From: Wolfgang Denk [mailto:wd@denx.de] Sent: Wednesday, May 20, 2009 3:29 AM To: Prafulla Wadaskar Cc: u-boot@lists.denx.de; Ashish Karkare; Prabhanjan Sarnaik; Ronen Shitrit Subject: Re: [U-Boot] [PATCH v8] Marvell Kirkwood family SOC support
Dear Prafulla Wadaskar,
In message 1242763678-13724-1-git-send-email-prafulla@marvell.com you wrote:
Kirkwood family controllers are highly integrated SOCs based on Feroceon-88FR131/Sheeva-88SV131 cpu core.
...
+/*
- Window Size
- Used with the Base register to set the address window
size and location.
- Must be programmed from LSB to MSB as sequence of 1’s
followed
+by
- sequence of 0’s. The number of 1’s specifies the
size of the
+window in
- 64 KByte granularity (e.g., a value of 0x00FF specifies
256 = 16 MByte).
- NOTE: A value of 0x0 specifies 64-KByte size.
- */
You have a number of strange special characters here. Please try and restrict yourself to plain ASCII text in normal C comments.
I checked the patch that I send across and associated source code too. I didn’t find the above special chars in it I am using git-send-email to send the patches and vim as my editor I wonder how these special characters appeared in the patch !!!! I will check this issue with my system admin
- for (i = 0; i < (sizeval / 0x10000); i++) {
j |= (1 << i);
- }
No curly braces for single line statements, please.
Sorry missed this one, corrected..
- struct kwwin_registers *winregs = (struct kwwin_registers
+*)KW_CPU_WIN_BASE;
Line too long.
+/*
- kw_config_gpio - GPIO configuration */ void kw_config_gpio(u32
+gpp0_oe_val, u32 gpp1_oe_val, u32 gpp0_oe, u32 gpp1_oe) {
- struct kwgpio_registers *gpio0reg = (struct
kwgpio_registers *)KW_GPIO0_BASE;
- struct kwgpio_registers *gpio1reg = (struct kwgpio_registers
+*)KW_GPIO1_BASE;
More too long lines. Pleasse check everywhere.
Generally I execute Lindent, I missed it this time, I will do it
- writel(gpp0_oe, (u32)&gpio0reg->oe);
- writel(gpp1_oe, (u32)&gpio1reg->oe);
Why are you using these casts here? The whole purpose of using a C struct to access device registers is to enable type checking by the C compiler, but you sabotage this with these casts. Please don't do that. This comment applies to the whole patch.
This was done to remove build warnings in some context I will remove them
...
- cntmrctrl = readl(CNTMR_CTRL_REG);
- cntmrctrl |= CTCR_ARM_TIMER_EN(UBOOT_CNTR); /*
enable cnt\timer */
Are you sure you want to have a TAB character in this comment? What's "cnt imer" ? :-)
Not really :-) it was for counter/timer, slash was a confusion. Removed....
diff --git a/drivers/serial/serial.c
b/drivers/serial/serial.c index
966df9a..dd5f332 100644 --- a/drivers/serial/serial.c +++ b/drivers/serial/serial.c @@ -27,6 +27,9 @@ #ifdef CONFIG_NS87308 #include <ns87308.h> #endif +#ifdef CONFIG_KIRKWOOD +#include <asm/arch/kirkwood.h> +#endif
What exactly is this needed for?
CONFIG_SYS_NS16550_CLK is defined as CONFIG_SYS_TCLK which defined in the soc specific header file
In my earlier versions I had included arch specific header file in board_config header file But in the review comments it has asked to remove Hence above include is done
- writel(0x00000002, KW_REG_SPI_CTRL);
- /* program spi clock prescaller using max_hz */
- data = ((CONFIG_SYS_TCLK / 2) / max_hz) & 0x0000000f;
- debug("data = 0x%08x \n", data);
- writel(0x00000210 | data, KW_REG_SPI_CONFIG);
- writel(0x00000001, KW_REG_SPI_IRQ_CAUSE);
- writel(0x00000000, KW_REG_SPI_IRQ_MASK);
What does these magic constants mean?
- /* program mpp registers to select SPI_CSn */
- if (cs)
writel((readl((u32)&mppreg[0]) & 0x0fffffff) |
0x20000000, (u32)&mppreg[0]);
- else
writel((readl((u32)&mppreg[0]) & 0xfffffff0) |
0x00000002, (u32)&mppreg[0]);
Ot these?
I will provide definitions for magic numbers
+int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
const void *dout,
void *din, unsigned long flags)
...
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);
Indentation by TABs only, please.
Indentation is done by Lindent. Do you mean to do it manually?
+#define INTREG_BASE 0xd0000000 +#define KW_REGISTER(x) (KW_REGS_PHY_BASE + x) +#define KW_OFFSET_REG (INTREG_BASE + 0x20080)
+/* undocumented registers */ +#define KW_REG_UNDOC_0x1470 (KW_REGISTER(0x1470)) +#define KW_REG_UNDOC_0x1478 (KW_REGISTER(0x1478))
+#define KW_UART0_BASE (KW_REGISTER(0x12000)) +#define KW_UART1_BASE (KW_REGISTER(0x13000)) +#define KW_MPP_BASE (KW_REGISTER(0x10000)) +#define KW_GPIO0_BASE (KW_REGISTER(0x10100)) +#define KW_GPIO1_BASE (KW_REGISTER(0x10140)) +#define KW_CPU_WIN_BASE (KW_REGISTER(0x20000)) +#define KW_CPU_REG_BASE (KW_REGISTER(0x20100)) +#define KW_TIMER_BASE (KW_REGISTER(0x20300)) +#define KW_REG_PCIE_BASE (KW_REGISTER(0x40000)) +#define KW_EGIGA0_BASE (KW_REGISTER(0x72000)) +#define KW_EGIGA1_BASE (KW_REGISTER(0x76000))
Use a C struct?
These are the Base address referred by register structures. Generally this type of declaration used for other cpu/socs. May you point any reference for this?
Regards.. Prafulla . .
Best regards,
Wolfgang Denk
-- DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de "One lawyer can steal more than a hundred men with guns."
- The Godfather

+#define INTREG_BASE 0xd0000000 +#define KW_REGISTER(x) (KW_REGS_PHY_BASE + x) +#define KW_OFFSET_REG (INTREG_BASE + 0x20080)
+/* undocumented registers */ +#define KW_REG_UNDOC_0x1470 (KW_REGISTER(0x1470)) +#define KW_REG_UNDOC_0x1478 (KW_REGISTER(0x1478))
+#define KW_UART0_BASE (KW_REGISTER(0x12000)) +#define KW_UART1_BASE (KW_REGISTER(0x13000)) +#define KW_MPP_BASE (KW_REGISTER(0x10000)) +#define KW_GPIO0_BASE (KW_REGISTER(0x10100)) +#define KW_GPIO1_BASE (KW_REGISTER(0x10140)) +#define KW_CPU_WIN_BASE (KW_REGISTER(0x20000)) +#define KW_CPU_REG_BASE (KW_REGISTER(0x20100)) +#define KW_TIMER_BASE (KW_REGISTER(0x20300)) +#define KW_REG_PCIE_BASE (KW_REGISTER(0x40000)) +#define KW_EGIGA0_BASE (KW_REGISTER(0x72000)) +#define KW_EGIGA1_BASE (KW_REGISTER(0x76000))
Use a C struct?
These are the Base address referred by register structures. Generally this type of declaration used for other cpu/socs. May you point any reference for this?
Hi Wolfgang Denk I have almost done with other changes except this one Do this really need to be converted C struct? I will have to put some efforts to get it done :-(.
Regards.. Prafulla . .

Dear Prafulla,
In message 73173D32E9439E4ABB5151606C3E19E201CF9E64AE@SC-VEXCH1.marvell.com you wrote:
...
+#define KW_EGIGA0_BASE (KW_REGISTER(0x72000)) +#define KW_EGIGA1_BASE (KW_REGISTER(0x76000))
Use a C struct?
These are the Base address referred by register structures.
I am aware of this.
Generally this type of declaration used for other cpu/socs.
Well, "generally" is a weak argument - you find examples for both. Coming from the PowerPC world, and haveing been using the code these sinde > 10 years, I'm more accustomed to see something like a big IMMR sturcture here.
I have almost done with other changes except this one Do this really need to be converted C struct?
No, you do not *have* to. That's why I asked it as a question. If I had to write the code, I would use a C struct, and I think it would be easier to read.
But I don't insist on such a change. You can find arguments for both solutions, so decide what deems best for you.
I will have to put some efforts to get it done :-(.
Well, changing it would actually be trivial. But as mentioned above: I don't insist. It's largely a matter of taste, I think.
Best regards,
Wolfgang Denk

...
+#define KW_EGIGA0_BASE
(KW_REGISTER(0x72000))
+#define KW_EGIGA1_BASE
(KW_REGISTER(0x76000))
Use a C struct?
These are the Base address referred by register structures.
I am aware of this.
Generally this type of declaration used for other cpu/socs.
Well, "generally" is a weak argument - you find examples for both. Coming from the PowerPC world, and haveing been using the code these sinde > 10 years, I'm more accustomed to see something like a big IMMR sturcture here.
I have almost done with other changes except this one Do
this really
need to be converted C struct?
No, you do not *have* to. That's why I asked it as a question. If I had to write the code, I would use a C struct, and I think it would be easier to read.
But I don't insist on such a change. You can find arguments for both solutions, so decide what deems best for you.
Hi Wolfgang There is always scope for improvements and one should do it. Just to sync current kirkwood code with other arm architectures, I will keep the registers offset definitions as it is.
I appreciate your suggestions, I will take care for future coding
Thanks and regards... Prafulla . .

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

Dear Prafulla Wadaskar,
In message 73173D32E9439E4ABB5151606C3E19E201CF9E63DE@SC-VEXCH1.marvell.com you wrote:
tmpdin = readl(KW_REG_SPI_DATA_IN);
debug
("*** spi_xfer: din %08X
... %08x read\n",
din, tmpdin);
Indentation by TABs only, please.
Indentation is done by Lindent. Do you mean to do it manually?
Yes, please, if Lindent does it wrong ...
Best regards,
Wolfgang Denk

-----Original Message----- From: u-boot-bounces@lists.denx.de [mailto:u-boot-bounces@lists.denx.de] On Behalf Of Prafulla Wadaskar Sent: Wednesday, May 20, 2009 2:30 PM To: Wolfgang Denk Cc: u-boot@lists.denx.de; Ashish Karkare; Prabhanjan Sarnaik; Ronen Shitrit Subject: Re: [U-Boot] [PATCH v8] Marvell Kirkwood family SOC support
Dear Wolfgand Denk
Thanks for your review comments
-----Original Message----- From: Wolfgang Denk [mailto:wd@denx.de] Sent: Wednesday, May 20, 2009 3:29 AM To: Prafulla Wadaskar Cc: u-boot@lists.denx.de; Ashish Karkare; Prabhanjan Sarnaik; Ronen Shitrit Subject: Re: [U-Boot] [PATCH v8] Marvell Kirkwood family SOC support
Dear Prafulla Wadaskar,
In message 1242763678-13724-1-git-send-email-prafulla@marvell.com you wrote:
Kirkwood family controllers are highly integrated SOCs based on Feroceon-88FR131/Sheeva-88SV131 cpu core.
...
+/*
- Window Size
- Used with the Base register to set the address window
size and location.
- Must be programmed from LSB to MSB as sequence of 1’s
followed
+by
- sequence of 0’s. The number of 1’s specifies the
size of the
+window in
- 64 KByte granularity (e.g., a value of 0x00FF specifies
256 = 16 MByte).
- NOTE: A value of 0x0 specifies 64-KByte size.
- */
You have a number of strange special characters here.
Please try and
restrict yourself to plain ASCII text in normal C comments.
I checked the patch that I send across and associated source code too. I didn’t find the above special chars in it I am using git-send-email to send the patches and vim as my editor I wonder how these special characters appeared in the patch !!!! I will check this issue with my system admin
Hi Wolfgang Denk We have discovered the root cause of this problem I was using apostrophes, those were getting converted to weird characters by the mailer software (just a guess). I have replaced then with strings (i.e. "1's" with "ones" and "0's" with "zeros") Of course I will not release a new patch (V11) for this :-) but I have corrected at my end and will reflect in next patch after review feedback for V10
Thanks for pointing this...
Regards.. Prafulla . .

Hi Prafulla,
On Tuesday 19 May 2009 22:07:58 Prafulla Wadaskar wrote:
Kirkwood family controllers are highly integrated SOCs based on Feroceon-88FR131/Sheeva-88SV131 cpu core.
I would like to give your Kirkwood support a try and start compiling the latest version before trying to port a custom board. Now I'm failing to compile the latest version posted on the list. Most likely I missed some patches or applied them to the wrong git repository.
I tried it on u-boot/next and on u-boot-arm/next. Both failed. I applied those patches:
[PATCH v8] Marvell Kirkwood family SOC support [PATCH v9] Marvell MV88F6281GTW_GE Board support [PATCH v3] Gbe Controller driver support for kirkwood SOCs
It would be great if you could tell me what I am missing here (additional patches or wrong repository?).
Here the error messages from building with those 3 patches on top of u-boot- arm/next:
[stefan@stefan-desktop u-boot-arm (kirkwood)]$ ./MAKEALL mv88f6281gtw_ge Configuring for mv88f6281gtw_ge board... mpp.c: In function 'kirkwood_mpp_conf': mpp.c:53: warning: unused variable 'gpio_mode' kirkwood_egiga.c: In function 'smi_reg_read': kirkwood_egiga.c:66: warning: implicit declaration of function 'readl' kirkwood_egiga.c:98: warning: implicit declaration of function 'writel' kirkwood_egiga.c: In function 'set_dram_access': kirkwood_egiga.c:451: warning: implicit declaration of function 'kw_sdram_bar' kirkwood_egiga.c:452: warning: implicit declaration of function 'kw_sdram_bs' kirkwood_egiga.c: In function 'kirkwood_egiga_initialize': kirkwood_egiga.c:1593: error: 'KW_EGIGA0_BASE' undeclared (first use in this function) kirkwood_egiga.c:1593: error: (Each undeclared identifier is reported only once kirkwood_egiga.c:1593: error: for each function it appears in.) kirkwood_egiga.c:1597: error: 'KW_EGIGA1_BASE' undeclared (first use in this function) kirkwood_egiga.c:1610: warning: implicit declaration of function 'get_random_hex'
Thanks.
Best regards, Stefan
===================================================================== DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office@denx.de =====================================================================

-----Original Message----- From: Stefan Roese [mailto:sr@denx.de] Sent: Wednesday, May 20, 2009 5:40 PM To: u-boot@lists.denx.de Cc: Prafulla Wadaskar; Ashish Karkare; Prabhanjan Sarnaik; Ronen Shitrit Subject: Re: [U-Boot] [PATCH v8] Marvell Kirkwood family SOC support
Hi Prafulla,
On Tuesday 19 May 2009 22:07:58 Prafulla Wadaskar wrote:
Kirkwood family controllers are highly integrated SOCs based on Feroceon-88FR131/Sheeva-88SV131 cpu core.
I would like to give your Kirkwood support a try and start compiling the latest version before trying to port a custom board. Now I'm failing to compile the latest version posted on the list. Most likely I missed some patches or applied them to the wrong git repository.
Thanks Stefan, your efforts will help me a lot
I tried it on u-boot/next and on u-boot-arm/next. Both
I have used u-boot-arm/next pls use the same.
failed. I applied those patches:
[PATCH v8] Marvell Kirkwood family SOC support [PATCH v9] Marvell MV88F6281GTW_GE Board support [PATCH v3] Gbe Controller driver support for kirkwood SOCs
It would be great if you could tell me what I am missing here (additional patches or wrong repository?).
You will need additional two patches as mentioned below http://git.denx.de/?p=u-boot/u-boot-blackfin.git;a=commit;h=12cedeb9589ef120... http://lists.denx.de/pipermail/u-boot/2009-May/052905.html
Apart from this pls add below line to drivers/net/kirkwood_egiga.c remove below mentioned errors #include <asm/arch/kirkwood.h>
I hope build will be through... Best of Luck
Regards.. Prafulla . .
Here the error messages from building with those 3 patches on top of u-boot- arm/next:
[stefan@stefan-desktop u-boot-arm (kirkwood)]$ ./MAKEALL mv88f6281gtw_ge Configuring for mv88f6281gtw_ge board... mpp.c: In function 'kirkwood_mpp_conf': mpp.c:53: warning: unused variable 'gpio_mode' kirkwood_egiga.c: In function 'smi_reg_read': kirkwood_egiga.c:66: warning: implicit declaration of function 'readl' kirkwood_egiga.c:98: warning: implicit declaration of function 'writel' kirkwood_egiga.c: In function 'set_dram_access': kirkwood_egiga.c:451: warning: implicit declaration of function 'kw_sdram_bar' kirkwood_egiga.c:452: warning: implicit declaration of function 'kw_sdram_bs' kirkwood_egiga.c: In function 'kirkwood_egiga_initialize': kirkwood_egiga.c:1593: error: 'KW_EGIGA0_BASE' undeclared (first use in this function) kirkwood_egiga.c:1593: error: (Each undeclared identifier is reported only once kirkwood_egiga.c:1593: error: for each function it appears in.) kirkwood_egiga.c:1597: error: 'KW_EGIGA1_BASE' undeclared (first use in this function) kirkwood_egiga.c:1610: warning: implicit declaration of function 'get_random_hex'
Thanks.
Best regards, Stefan
===================================================================== DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office@denx.de =====================================================================

On Wednesday 20 May 2009 15:40:00 Prafulla Wadaskar wrote:
I would like to give your Kirkwood support a try and start compiling the latest version before trying to port a custom board. Now I'm failing to compile the latest version posted on the list. Most likely I missed some patches or applied them to the wrong git repository.
Thanks Stefan, your efforts will help me a lot
Sure. I'll try to help out if possible. But I'm only starting into this project right now. So please don't expect any "real output" soon. But I definitely can give some feedback...
I tried it on u-boot/next and on u-boot-arm/next. Both
I have used u-boot-arm/next pls use the same.
OK, understood.
failed. I applied those patches:
[PATCH v8] Marvell Kirkwood family SOC support [PATCH v9] Marvell MV88F6281GTW_GE Board support [PATCH v3] Gbe Controller driver support for kirkwood SOCs
It would be great if you could tell me what I am missing here (additional patches or wrong repository?).
You will need additional two patches as mentioned below http://git.denx.de/?p=u-boot/u-boot-blackfin.git;a=commit;h=12cedeb9589ef12 03e3308e80b11e5ee73261ced http://lists.denx.de/pipermail/u-boot/2009-May/052905.html
Apart from this pls add below line to drivers/net/kirkwood_egiga.c remove below mentioned errors #include <asm/arch/kirkwood.h>
I hope build will be through... Best of Luck
Yes, this works. Thanks a lot.
Best regards, Stefan
===================================================================== DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office@denx.de =====================================================================

Kirkwood family controllers are highly integrated SOCs based on Feroceon-88FR131/Sheeva-88SV131 cpu core.
SOC versions supported:- 1) 88F6281-A0 define CONFIG_KW88F6281_A0 2) 88F6192-A0 define CONFIG_KW88F6192_A0
Other supported features:- 1) get_random_hex() fucntion 2) SPI port controller driver 3) PCI Express port initialization
Contributors: Yotam Admon yotam@marvell.com Michael Blostein <michaelbl@marvell.com
Reviewed-by: Ronen Shitrit rshitrit@marvell.com Signed-off-by: Prafulla Wadaskar prafulla@marvell.com --- Change log: v2: crated arch-kirkwood and moved some header files there renamed and moved spi.c to drivers/spi/ renamed and moved serial.c to drivers/serial/ doimage utility removed soc_init.S renamed as lowlevel_init.S debug prints removed
v3: lowlevel_init.S converted to lowlevel_init.c removed BITxx macros, removed entire assembly code Added CONFIG_ARCH_LOWLEVE_INIT support for arm926ejs core updated as per review commens for v2
v4: updated as per review comments for v3 print_cpuinfo used to display Soc info arch_misc_init support created and used for lib_arm mandatory readl/write macros used asm/cache.h asm/arch/spi.h asm//arch/serial.h created and used
v5: updated as per review comments for v4 cosmetic updates, arch_misc_init and arch_cpu_init used start.S updated to call arch_lowlevel_init in case if lowlevl_init is skipped bug fix in cpu.c
v6: lowlevel_init.S removed code moved under arch_cpu_init
v7: include <asm/arch/kirkwood.h> added to each c file reference removed from include/asm/config.h arch_misc_init defination kept as it is in include/common.h bugfixed in get_random_hex function
v7.1: u-boot.lds moved from board specific to kirkwood
cpu/arm926ejs/kirkwood/Makefile | 48 +++++ cpu/arm926ejs/kirkwood/config.mk | 2 + cpu/arm926ejs/kirkwood/cpu.c | 297 +++++++++++++++++++++++++++++ cpu/arm926ejs/kirkwood/cpu.h | 103 ++++++++++ cpu/arm926ejs/kirkwood/dram.c | 58 ++++++ cpu/arm926ejs/kirkwood/timer.c | 160 ++++++++++++++++ cpu/arm926ejs/kirkwood/u-boot.lds | 51 +++++ drivers/serial/Makefile | 1 + drivers/serial/kirkwood_serial.c | 129 +++++++++++++ drivers/spi/Makefile | 1 + drivers/spi/kirkwood_spi.c | 168 ++++++++++++++++ include/asm-arm/arch-kirkwood/kirkwood.h | 117 +++++++++++ include/asm-arm/arch-kirkwood/kw88f6192.h | 37 ++++ include/asm-arm/arch-kirkwood/kw88f6281.h | 37 ++++ include/asm-arm/arch-kirkwood/serial.h | 89 +++++++++ include/asm-arm/arch-kirkwood/spi.h | 39 ++++ include/asm-arm/cache.h | 41 ++++ include/common.h | 1 + lib_arm/board.c | 4 + 19 files changed, 1383 insertions(+), 0 deletions(-) create mode 100644 cpu/arm926ejs/kirkwood/Makefile create mode 100644 cpu/arm926ejs/kirkwood/config.mk create mode 100644 cpu/arm926ejs/kirkwood/cpu.c create mode 100644 cpu/arm926ejs/kirkwood/cpu.h create mode 100644 cpu/arm926ejs/kirkwood/dram.c create mode 100644 cpu/arm926ejs/kirkwood/timer.c create mode 100644 cpu/arm926ejs/kirkwood/u-boot.lds create mode 100644 drivers/serial/kirkwood_serial.c create mode 100644 drivers/spi/kirkwood_spi.c create mode 100644 include/asm-arm/arch-kirkwood/kirkwood.h create mode 100644 include/asm-arm/arch-kirkwood/kw88f6192.h create mode 100644 include/asm-arm/arch-kirkwood/kw88f6281.h create mode 100644 include/asm-arm/arch-kirkwood/serial.h create mode 100644 include/asm-arm/arch-kirkwood/spi.h create mode 100644 include/asm-arm/cache.h
diff --git a/cpu/arm926ejs/kirkwood/Makefile b/cpu/arm926ejs/kirkwood/Makefile new file mode 100644 index 0000000..ef1176e --- /dev/null +++ b/cpu/arm926ejs/kirkwood/Makefile @@ -0,0 +1,48 @@ +# +# (C) Copyright 2009 +# Marvell Semiconductor <www.marvell.com> +# Prafulla Wadaskar prafulla@marvell.com +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).a + +COBJS-y = dram.o +COBJS-y += cpu.o +COBJS-y += 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..b8d9824 --- /dev/null +++ b/cpu/arm926ejs/kirkwood/config.mk @@ -0,0 +1,2 @@ +PLATFORM_CPPFLAGS += -march=armv5te +LDSCRIPT := $(SRCTREE)/cpu/arm926ejs/kirkwood/u-boot.lds diff --git a/cpu/arm926ejs/kirkwood/cpu.c b/cpu/arm926ejs/kirkwood/cpu.c new file mode 100644 index 0000000..c1e9146 --- /dev/null +++ b/cpu/arm926ejs/kirkwood/cpu.c @@ -0,0 +1,297 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Prafulla Wadaskar prafulla@marvell.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include <common.h> +#include <netdev.h> +#include <asm/cache.h> +#include <u-boot/md5.h> +#include <asm/arch/kirkwood.h> + +void reset_cpu(unsigned long ignored) +{ + writel(readl(KW_REG_CPU_RSTOUTN_MASK) | (1 << 2), + KW_REG_CPU_RSTOUTN_MASK); + writel(readl(KW_REG_CPU_SYS_SOFT_RST) | 1, KW_REG_CPU_SYS_SOFT_RST); + while (1) ; +} + +/* + * Generates Ramdom hex number reading some time varient system registers + * and using md5 algorithm + */ +unsigned char get_random_hex(void) +{ + int i; + u32 inbuf[16]; + u8 outbuf[16]; + + /* + * in case of 88F6281/88F6192 A0, + * Bit7 need to reset to generate random values in KW_REG_UNDOC_0x1470 + * Soc reg offsets KW_REG_UNDOC_0x1470 and KW_REG_UNDOC_0x1478 are reserved regs and + * Does not have names at this moment (no errata available) + */ + writel(readl(KW_REG_UNDOC_0x1478) & ~(1 << 7), KW_REG_UNDOC_0x1478); + for (i = 0; i < 16; i++) { + inbuf[i] = readl(KW_REG_UNDOC_0x1470); + } + md5((u8 *) inbuf, 64, outbuf); + return outbuf[outbuf[7] % 0x0f]; +} + +/* + * Window Size + * Used with the Base register to set the address window size and location. + * Must be programmed from LSB to MSB as sequence of 1’s followed by + * sequence of 0’s. The number of 1’s specifies the size of the window in + * 64 KByte granularity (e.g., a value of 0x00FF specifies 256 = 16 MByte). + * NOTE: A value of 0x0 specifies 64-KByte size. + */ +static unsigned int kw_winctrl_calcsize(unsigned int sizeval) +{ + int i; + unsigned int j = 0; + + for (i = 0; i < (sizeval / 0x10000); i++) { + j |= (1 << i); + } + return (0x0000ffff & j); +} + +/* prepares data to be loaded in win_Ctrl register */ +#define KWCPU_WIN_CTRL_DATA(size, target, attr, en) (en | (target << 4) \ + | (attr << 8) | (kw_winctrl_calcsize(size) << 16)) + +/* + * kw_config_adr_windows - Configure address Windows + * + * There are 7 address windows supported by Kirkwood Soc to addess different + * devices. Each window can be configured for size, BAR and remap addr + * Below configuration is standard for most of the cases + * + * Reference Documentation: + * Mbus-L to Mbus Bridge Registers Configuration. + * (Sec 25.1 and 25.3 of Datasheet) + */ +int kw_config_adr_windows(void) +{ + writel(KWCPU_WIN_CTRL_DATA(0xc0000, KWCPU_TARGET_PCIE, + KWCPU_ATTR_PCIE_MEM, KWCPU_WIN_ENABLE), + KW_REG_WIN_CTRL(0)); + + writel(0x90000000, KW_REG_WIN_BASE(0)); + writel(0x90000000, KW_REG_WIN_REMAP_LOW(0)); + writel(0x00000000, KW_REG_WIN_REMAP_HIGH(0)); + + writel(KWCPU_WIN_CTRL_DATA(0x70000, KWCPU_TARGET_MEMORY, + KWCPU_ATTR_NANDFLASH, KWCPU_WIN_ENABLE), + KW_REG_WIN_CTRL(1)); + writel(0xF9000000, KW_REG_WIN_BASE(1)); + writel(0xF9000000, KW_REG_WIN_REMAP_LOW(1)); + writel(0x00000000, KW_REG_WIN_REMAP_HIGH(1)); + + writel(KWCPU_WIN_CTRL_DATA(0x80000, KWCPU_TARGET_PCIE, + KWCPU_ATTR_PCIE_IO, KWCPU_WIN_ENABLE), + KW_REG_WIN_CTRL(2)); + writel(0xF0000000, KW_REG_WIN_BASE(2)); + writel(0xC0000000, KW_REG_WIN_REMAP_LOW(2)); + writel(0x00000000, KW_REG_WIN_REMAP_HIGH(2)); + + writel(KWCPU_WIN_CTRL_DATA(0x80000, KWCPU_TARGET_MEMORY, + KWCPU_ATTR_SPIFLASH, KWCPU_WIN_ENABLE), + KW_REG_WIN_CTRL(3)); + writel(0xF8000000, KW_REG_WIN_BASE(3)); + writel(0x00000000, KW_REG_WIN_REMAP_LOW(3)); + writel(0x00000000, KW_REG_WIN_REMAP_HIGH(3)); + + writel(KWCPU_WIN_CTRL_DATA(0x80000, KWCPU_TARGET_MEMORY, + KWCPU_ATTR_BOOTROM, KWCPU_WIN_ENABLE), + KW_REG_WIN_CTRL(4)); + writel(0xFF000000, KW_REG_WIN_BASE(4)); + writel(0x00000000, KW_REG_WIN_REMAP_LOW(4)); + writel(0x00000000, KW_REG_WIN_REMAP_HIGH(4)); + + writel(KWCPU_WIN_CTRL_DATA(0xb0000, KWCPU_TARGET_MEMORY, + KWCPU_ATTR_SPIFLASH, KWCPU_WIN_DISABLE), + KW_REG_WIN_CTRL(5)); + writel(0xE8000000, KW_REG_WIN_BASE(5)); + writel(0x00000000, KW_REG_WIN_REMAP_LOW(5)); + writel(0x00000000, KW_REG_WIN_REMAP_HIGH(5)); + + writel(KWCPU_WIN_CTRL_DATA(0xb0000, KWCPU_TARGET_MEMORY, + KWCPU_ATTR_BOOTROM, KWCPU_WIN_DISABLE), + KW_REG_WIN_CTRL(6)); + writel(0xF0000000, KW_REG_WIN_BASE(6)); + writel(0x00000000, KW_REG_WIN_REMAP_LOW(6)); + writel(0x00000000, KW_REG_WIN_REMAP_HIGH(6)); + + writel(KWCPU_WIN_CTRL_DATA(0x0, KWCPU_TARGET_SASRAM, KWCPU_ATTR_SASRAM, + KWCPU_WIN_ENABLE), KW_REG_WIN_CTRL(7)); + writel(0xFB000000, KW_REG_WIN_BASE(7)); + writel(0x00000000, KW_REG_WIN_REMAP_LOW(7)); + writel(0x00000000, KW_REG_WIN_REMAP_HIGH(7)); + + return 0; +} + +/* + * kw_config_gpio - GPIO configuration + */ +void kw_config_gpio(u32 gpp0_oe_val, u32 gpp1_oe_val, u32 gpp0_oe, u32 gpp1_oe) +{ + /* Init GPIOS to default values as per board requirement */ + writel(gpp0_oe_val, KW_REG_GPP0_DATA_OUT); + writel(gpp1_oe_val, KW_REG_GPP1_DATA_OUT); + writel(gpp0_oe, KW_REG_GPP0_DATA_OUT_EN); + writel(gpp1_oe, KW_REG_GPP1_DATA_OUT_EN); +} + +/* + * kw_config_mpp - Multi-Purpose Pins Functionality configuration + * + * Each MPP can be configured to different functionality through + * MPP control register, ref (sec 6.1 of kirkwood h/w specification) + * + * There are maximum 64 Multi-Pourpose Pins on Kirkwood + * Each MPP functionality can be configuration by a 4bit value + * of MPP control reg, the value and associated functionality depends + * upon used SoC varient + */ +int kw_config_mpp(u32 mpp0_7, u32 mpp8_15, u32 mpp16_23, u32 mpp24_31, + u32 mpp32_39, u32 mpp40_47, u32 mpp48_55) +{ + /* program mpp registers */ + writel(mpp0_7, KW_REG_MPP_CONTROL0); + writel(mpp8_15, KW_REG_MPP_CONTROL1); + writel(mpp16_23, KW_REG_MPP_CONTROL2); + writel(mpp24_31, KW_REG_MPP_CONTROL3); + writel(mpp32_39, KW_REG_MPP_CONTROL4); + writel(mpp40_47, KW_REG_MPP_CONTROL5); + writel(mpp48_55, KW_REG_MPP_CONTROL6); + return 0; +} + +#if defined(CONFIG_DISPLAY_CPUINFO) +int print_cpuinfo(void) +{ + char *name = "Unknown"; + + switch (readl(KW_REG_DEVICE_ID) & 0x03) { + case 1: + name = "88F6192_A0"; + break; + case 2: + name = "88F6281_A0"; + break; + default: + break; + } + printf("SoC: Kirkwood %s\n", name); + return 0; +} +#endif /* CONFIG_DISPLAY_CPUINFO */ + +#ifdef CONFIG_ARCH_CPU_INIT +int arch_cpu_init(void) +{ + u32 reg; + + /* Linux expects` the internal registers to be at 0xf1000000 */ + writel(KW_REGS_PHY_BASE, KW_OFFSET_REG); + + /* Enable and invalidate L2 cache in write through mode */ + writel(readl(KW_REG_CPU_L2_CONFIG) | 0x18, KW_REG_CPU_L2_CONFIG); + invalidate_l2_cache(); + + kw_config_adr_windows(); + +#ifdef CONFIG_KIRKWOOD_RGMII_PAD_1V8 + /* + * Configures the I/O voltage of the pads connected to Egigabit + * Ethernet interface to 1.8V + * By defult it is set to 3.3V + */ + reg = readl(KW_REG_MPP_OUT_DRV_REG); + reg |= (1 << 7); + writel(reg, KW_REG_MPP_OUT_DRV_REG); +#endif +#ifdef CONFIG_KIRKWOOD_EGIGA_INIT + /* + * Set egiga port0/1 in normal functional mode + * This is required becasue on kirkwood by default ports are in reset mode + * OS egiga driver may not have provision to set them in normal mode + * and if u-boot is build without network support, network may fail at OS level + */ + reg = readl(KWGBE_PORT_SERIAL_CONTROL1_REG(0)); + reg &= ~(1 << 4); /* Clear PortReset Bit */ + writel(reg, (KWGBE_PORT_SERIAL_CONTROL1_REG(0))); + reg = readl(KWGBE_PORT_SERIAL_CONTROL1_REG(1)); + reg &= ~(1 << 4); /* Clear PortReset Bit */ + writel(reg, (KWGBE_PORT_SERIAL_CONTROL1_REG(1))); +#endif +#ifdef CONFIG_KIRKWOOD_PCIE_INIT + /* + * Enable PCI Express Port0 + */ + reg = readl(KW_REG_CPU_CTRL_STAT); + reg |= (1 << 0); /* Set PEX0En Bit */ + writel(reg, KW_REG_CPU_CTRL_STAT); +#endif + return 0; +} +#endif /* CONFIG_ARCH_CPU_INIT */ + +/* + * SOC specific misc init + */ +#if defined(CONFIG_ARCH_MISC_INIT) +int arch_misc_init(void) +{ + volatile u32 temp; + + /*CPU streaming & write allocate */ + temp = readfr_extra_feature_reg(); + temp &= ~(1 << 28); /* disable wr alloc */ + writefr_extra_feature_reg(temp); + + temp = readfr_extra_feature_reg(); + temp &= ~(1 << 29); /* streaming disabled */ + writefr_extra_feature_reg(temp); + + /* L2Cache settings */ + temp = readfr_extra_feature_reg(); + /* Disable L2C pre fetch - Set bit 24 */ + temp |= (1 << 24); + /* enable L2C - Set bit 22 */ + temp |= (1 << 22); + writefr_extra_feature_reg(temp); + + icache_enable(); + /* Change reset vector to address 0x0 */ + temp = get_cr(); + set_cr(temp & ~CR_V); + + return 0; +} +#endif /* CONFIG_ARCH_MISC_INIT */ diff --git a/cpu/arm926ejs/kirkwood/cpu.h b/cpu/arm926ejs/kirkwood/cpu.h new file mode 100644 index 0000000..d36835b --- /dev/null +++ b/cpu/arm926ejs/kirkwood/cpu.h @@ -0,0 +1,103 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Prafulla Wadaskar prafulla@marvell.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef _KWCPU_H +#define _KWCPU_H + +#include <asm/system.h> + +#ifndef __ASSEMBLY__ + +#define KWGBE_PORT_SERIAL_CONTROL1_REG(_x) \ + ((_x ? KW_EGIGA0_BASE : KW_EGIGA1_BASE) + 0x44c) + +enum memory_bank { + BANK0, + BANK1, + BANK2, + BANK3 +}; + +enum kwcpu_winen { + KWCPU_WIN_DISABLE, + KWCPU_WIN_ENABLE +}; + +enum kwcpu_target { + KWCPU_TARGET_RESERVED, + KWCPU_TARGET_MEMORY, + KWCPU_TARGET_1RESERVED, + KWCPU_TARGET_SASRAM, + KWCPU_TARGET_PCIE +}; + +enum kwcpu_attrib { + KWCPU_ATTR_SASRAM = 0x01, + KWCPU_ATTR_NANDFLASH = 0x2f, + KWCPU_ATTR_SPIFLASH = 0x1e, + KWCPU_ATTR_BOOTROM = 0x1d, + KWCPU_ATTR_PCIE_IO = 0xe0, + KWCPU_ATTR_PCIE_MEM = 0xe8 +}; + +/* + * read feroceon/sheeva core extra feature register + * using co-proc instruction + */ +static inline unsigned int readfr_extra_feature_reg(void) +{ + unsigned int val; + asm volatile ("mrc p15, 1, %0, c15, c1, 0 @ readfr exfr":"=r" + (val)::"cc"); + return val; +} + +/* + * write feroceon/sheeva core extra feature register + * using co-proc instruction + */ +static inline void writefr_extra_feature_reg(unsigned int val) +{ + asm volatile ("mcr p15, 1, %0, c15, c1, 0 @ writefr exfr"::"r" + (val):"cc"); + isb(); +} + +/* + * functions + */ +void reset_cpu(unsigned long ignored); +unsigned char get_random_hex(void); +unsigned int kw_sdram_bar(enum memory_bank bank); +unsigned int kw_sdram_bs(enum memory_bank bank); +int kw_config_adr_windows(void); +void kw_config_gpio(unsigned int gpp0_oe_val, unsigned int gpp1_oe_val, + unsigned int gpp0_oe, unsigned int gpp1_oe); +int kw_config_mpp(unsigned int mpp0_7, unsigned int mpp8_15, + unsigned int mpp16_23, unsigned int mpp24_31, + unsigned int mpp32_39, unsigned int mpp40_47, + unsigned int mpp48_55); +#endif /* __ASSEMBLY__ */ + +#endif /* _KWCPU_H */ diff --git a/cpu/arm926ejs/kirkwood/dram.c b/cpu/arm926ejs/kirkwood/dram.c new file mode 100644 index 0000000..3ec0548 --- /dev/null +++ b/cpu/arm926ejs/kirkwood/dram.c @@ -0,0 +1,58 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Prafulla Wadaskar prafulla@marvell.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include <config.h> +#include <asm/arch/kirkwood.h> + +#define KW_REG_CPUCS_WIN_BAR(x) (KW_REGISTER(0x1500) + (x * 0x08)) +#define KW_REG_CPUCS_WIN_SZ(x) (KW_REGISTER(0x1504) + (x * 0x08)) +/* + * kw_sdram_bar - reads SDRAM Base Address Register + */ +u32 kw_sdram_bar(enum memory_bank bank) +{ + u32 result = 0; + u32 enable = 0x01 & readl(KW_REG_CPUCS_WIN_SZ(bank)); + + if ((!enable) || (bank > BANK3)) + return 0; + + result = readl(KW_REG_CPUCS_WIN_BAR(bank)); + return result; +} + +/* + * kw_sdram_bs - reads SDRAM Bank size + */ +u32 kw_sdram_bs(enum memory_bank bank) +{ + u32 result = 0; + u32 enable = 0x01 & readl(KW_REG_CPUCS_WIN_SZ(bank)); + + if ((!enable) || (bank > BANK3)) + return 0; + result = 0xff000000 & readl(KW_REG_CPUCS_WIN_SZ(bank)); + result += 0x01000000; + return result; +} diff --git a/cpu/arm926ejs/kirkwood/timer.c b/cpu/arm926ejs/kirkwood/timer.c new file mode 100644 index 0000000..51661a0 --- /dev/null +++ b/cpu/arm926ejs/kirkwood/timer.c @@ -0,0 +1,160 @@ +/* + * Copyright (C) Marvell International Ltd. and its affiliates + * Prafulla Wadaskar prafulla@marvell.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include <common.h> +#include <asm/arch/kirkwood.h> + +#define UBOOT_CNTR 0 /* counter to use for uboot timer */ + +/* + * ARM Timers Registers Map + */ +#define CNTMR_CTRL_REG KW_REG_TMR_CTRL +#define CNTMR_RELOAD_REG(tmrnum) (KW_REG_TMR_RELOAD + tmrnum*8) +#define CNTMR_VAL_REG(tmrnum) (KW_REG_TMR_VAL + tmrnum*8) + +/* + * ARM Timers Control Register + * CPU_TIMERS_CTRL_REG (CTCR) + */ +#define TIMER0_NUM 0 +#define TIMER1_NUM 1 +#define WATCHDOG_NUM 2 + +#define CTCR_ARM_TIMER_EN_OFFS(cntr) (cntr * 2) +#define CTCR_ARM_TIMER_EN_MASK(cntr) (1 << CTCR_ARM_TIMER_EN_OFFS) +#define CTCR_ARM_TIMER_EN(cntr) (1 << CTCR_ARM_TIMER_EN_OFFS(cntr)) +#define CTCR_ARM_TIMER_DIS(cntr) (0 << CTCR_ARM_TIMER_EN_OFFS(cntr)) + +#define CTCR_ARM_TIMER_AUTO_OFFS(cntr) ((cntr * 2) + 1) +#define CTCR_ARM_TIMER_AUTO_MASK(cntr) (1 << 1) +#define CTCR_ARM_TIMER_AUTO_EN(cntr) (1 << CTCR_ARM_TIMER_AUTO_OFFS(cntr)) +#define CTCR_ARM_TIMER_AUTO_DIS(cntr) (0 << CTCR_ARM_TIMER_AUTO_OFFS(cntr)) + +/* + * ARM Timer\Watchdog Reload Register + * CNTMR_RELOAD_REG (TRR) + */ +#define TRG_ARM_TIMER_REL_OFFS 0 +#define TRG_ARM_TIMER_REL_MASK 0xffffffff + +/* + * ARM Timer\Watchdog Register + * CNTMR_VAL_REG (TVRG) + */ +#define TVR_ARM_TIMER_OFFS 0 +#define TVR_ARM_TIMER_MASK 0xffffffff +#define TVR_ARM_TIMER_MAX 0xffffffff +#define TIMER_LOAD_VAL 0xffffffff + +#define READ_TIMER (readl(CNTMR_VAL_REG(UBOOT_CNTR)) / \ + (CONFIG_SYS_TCLK / 1000)) + +static ulong timestamp; +static ulong lastdec; + +void reset_timer_masked(void) +{ + /* reset time */ + lastdec = READ_TIMER; + timestamp = 0; +} + +ulong get_timer_masked(void) +{ + ulong now = READ_TIMER; + + if (lastdec >= now) { + /* normal mode */ + timestamp += lastdec - now; + } else { + /* we have an overflow ... */ + timestamp += + lastdec + (TIMER_LOAD_VAL / (CONFIG_SYS_TCLK / 1000)) - now; + } + lastdec = now; + + return timestamp; +} + +void reset_timer(void) +{ + reset_timer_masked(); +} + +ulong get_timer(ulong base) +{ + return get_timer_masked() - base; +} + +void set_timer(ulong t) +{ + timestamp = t; +} + +void udelay(unsigned long usec) +{ + uint current; + ulong delayticks; + + current = readl(CNTMR_VAL_REG(UBOOT_CNTR)); + delayticks = (usec * (CONFIG_SYS_TCLK / 1000000)); + + if (current < delayticks) { + delayticks -= current; + while (readl(CNTMR_VAL_REG(UBOOT_CNTR)) < current) ; + while ((TIMER_LOAD_VAL - delayticks) < + readl(CNTMR_VAL_REG(UBOOT_CNTR))) ; + } else { + while (readl(CNTMR_VAL_REG(UBOOT_CNTR)) > + (current - delayticks)) ; + } +} + +/* + * init the counter + */ +int timer_init(void) +{ + unsigned int cntmrCtrl; + + /* load value onto counter\timer */ + writel(TIMER_LOAD_VAL, CNTMR_RELOAD_REG(UBOOT_CNTR)); + writel(TIMER_LOAD_VAL, CNTMR_VAL_REG(UBOOT_CNTR)); + + /* set the counter to load in the first time */ + writel(TIMER_LOAD_VAL, CNTMR_VAL_REG(UBOOT_CNTR)); + + /* set control for timer \ cunter and enable */ + /* read control register */ + cntmrCtrl = readl(CNTMR_CTRL_REG); + cntmrCtrl |= CTCR_ARM_TIMER_EN(UBOOT_CNTR); /* enable cnt\timer */ + cntmrCtrl |= CTCR_ARM_TIMER_AUTO_EN(UBOOT_CNTR); /* Auto mode */ + + writel(cntmrCtrl, CNTMR_CTRL_REG); + + /* init the timestamp and lastdec value */ + reset_timer_masked(); + + return 0; +} diff --git a/cpu/arm926ejs/kirkwood/u-boot.lds b/cpu/arm926ejs/kirkwood/u-boot.lds new file mode 100644 index 0000000..96168d6 --- /dev/null +++ b/cpu/arm926ejs/kirkwood/u-boot.lds @@ -0,0 +1,51 @@ +/* + * 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/drivers/serial/Makefile b/drivers/serial/Makefile index 14c818d..9174ec6 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -28,6 +28,7 @@ LIB := $(obj)libserial.a COBJS-$(CONFIG_ARM_DCC) += arm_dcc.o COBJS-$(CONFIG_AT91RM9200_USART) += at91rm9200_usart.o COBJS-$(CONFIG_ATMEL_USART) += atmel_usart.o +COBJS-$(CONFIG_KIRKWOOD_SERIAL) += kirkwood_serial.o COBJS-$(CONFIG_MCFUART) += mcfuart.o COBJS-$(CONFIG_NS9750_UART) += ns9750_serial.o COBJS-$(CONFIG_SYS_NS16550) += ns16550.o diff --git a/drivers/serial/kirkwood_serial.c b/drivers/serial/kirkwood_serial.c new file mode 100644 index 0000000..4a2c88c --- /dev/null +++ b/drivers/serial/kirkwood_serial.c @@ -0,0 +1,129 @@ +/* + * Copyright (C) Marvell International Ltd. and its affiliates + * Prafulla Wadaskar prafulla@marvell.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include <common.h> +#include <asm/arch/kirkwood.h> +#include <asm/arch/serial.h> + +/* static variables */ +#if defined (CONFIG_CONS_INDEX) /* comes from board config */ +#if (CONFIG_CONS_INDEX == 0 ) +static volatile struct kw_uart_port *p_uart_port = + (void *)KW_REGISTER(KW_UART0_BASE); +#elif (CONFIG_CONS_INDEX == 1 ) +static volatile struct kw_uart_port *p_uart_port = + (void *)KW_REGISTER(KW_UART1_BASE); +#endif +#else +#error CONFIG_CONS_INDEX not defined correctly +#endif + +#define CONFIG_KW_UART_PORTS { (void *)KW_UART0_BASE, \ + (void *)KW_UART1_BASE } + +/* + * Serial init banner is kept simplest one + * if required can be created good one + */ +int serial_init(void) +{ + serial_setbrg(); + printf + ("\n*************************************************************"); + return (0); +} + +static void kw_uart_putc(u8 c) +{ + while ((p_uart_port->lsr & LSR_THRE) == 0) ; + p_uart_port->thr = c; + return; +} + +void serial_putc(const char c) +{ + if (c == '\n') + kw_uart_putc('\r'); + + kw_uart_putc(c); +} + +int serial_getc(void) +{ + while ((p_uart_port->lsr & LSR_DR) == 0) ; + return (p_uart_port->rbr); +} + +int serial_tstc(void) +{ + return ((p_uart_port->lsr & LSR_DR) != 0); +} + +void serial_setbrg(void) +{ + DECLARE_GLOBAL_DATA_PTR; + + int clock_divisor = (CONFIG_SYS_TCLK / 16) / gd->baudrate; + + p_uart_port->ier = 0x00; + p_uart_port->lcr = LCR_DIVL_EN; /* Access baud rate */ + p_uart_port->dll = clock_divisor & 0xff; /* 9600 baud */ + p_uart_port->dlm = (clock_divisor >> 8) & 0xff; + p_uart_port->lcr = LCR_8N1; /* 8 data, 1 stop, no parity */ + /* Clear & enable FIFOs */ + p_uart_port->fcr = FCR_FIFO_EN | FCR_RXSR | FCR_TXSR; + return; +} + +void serial_puts(const char *s) +{ + while (*s) { + serial_putc(*s++); + } +} + +#ifdef CONFIG_CMD_KGDB +void kgdb_serial_init(void) +{ +} + +void putDebugChar(int c) +{ + serial_putc(c); +} + +void putDebugStr(const char *str) +{ + serial_puts(str); +} + +int getDebugChar(void) +{ + return serial_getc(); +} + +void kgdb_interruptible(int yes) +{ + return; +} +#endif /* CONFIG_CMD_KGDB */ diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 1350f3e..7ffa47d 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -28,6 +28,7 @@ LIB := $(obj)libspi.a COBJS-$(CONFIG_ATMEL_DATAFLASH_SPI) += atmel_dataflash_spi.o COBJS-$(CONFIG_ATMEL_SPI) += atmel_spi.o COBJS-$(CONFIG_BFIN_SPI) += bfin_spi.o +COBJS-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o COBJS-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o COBJS-$(CONFIG_MXC_SPI) += mxc_spi.o COBJS-$(CONFIG_SOFT_SPI) += soft_spi.o diff --git a/drivers/spi/kirkwood_spi.c b/drivers/spi/kirkwood_spi.c new file mode 100644 index 0000000..2881ccb --- /dev/null +++ b/drivers/spi/kirkwood_spi.c @@ -0,0 +1,168 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Prafulla Wadaskar prafulla@marvell.com + * + * Derived from drivers/spi/mpc8xxx_spi.c + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include <common.h> +#include <malloc.h> +#include <spi.h> +#include <asm/arch/kirkwood.h> +#include <asm/arch/spi.h> + +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, + unsigned int max_hz, unsigned int mode) +{ + struct spi_slave *slave; + u32 data; + + if (!spi_cs_is_valid(bus, cs)) + return NULL; + + slave = malloc(sizeof(struct spi_slave)); + if (!slave) + return NULL; + + slave->bus = bus; + slave->cs = cs; + + writel(0x00000002, KW_REG_SPI_CTRL); + /* program spi clock prescaller using max_hz */ + data = ((CONFIG_SYS_TCLK / 2) / max_hz) & 0x0000000f; + debug("data = 0x%08x \n", data); + writel(0x00000210 | data, KW_REG_SPI_CONFIG); + writel(0x00000001, KW_REG_SPI_IRQ_CAUSE); + writel(0x00000000, KW_REG_SPI_IRQ_MASK); + + /* program mpp registers to select SPI_CSn */ + if (cs) + writel((readl(KW_REG_MPP_CONTROL0) & 0x0fffffff) | + 0x20000000, KW_REG_MPP_CONTROL0); + else + writel((readl(KW_REG_MPP_CONTROL0) & 0xfffffff0) | + 0x00000002, KW_REG_MPP_CONTROL0); + + return slave; +} + +void spi_free_slave(struct spi_slave *slave) +{ + free(slave); +} + +int spi_claim_bus(struct spi_slave *slave) +{ + return 0; +} + +void spi_release_bus(struct spi_slave *slave) +{ +} + +#ifndef CONFIG_SPI_CS_IS_VALID +/* + * you can define this function board specific + * define above CONFIG in board specific config file and + * provide the function in board specific src file + */ +int spi_cs_is_valid(unsigned int bus, unsigned int cs) +{ + return (bus == 0 && (cs == 0 || cs == 1)); +} +#endif + +void spi_cs_activate(struct spi_slave *slave) +{ + writel(readl(KW_REG_SPI_CTRL) | 1, KW_REG_SPI_CTRL); +} + +void spi_cs_deactivate(struct spi_slave *slave) +{ + writel(readl(KW_REG_SPI_CTRL) & ~1, KW_REG_SPI_CTRL); +} + +int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, + void *din, unsigned long flags) +{ + unsigned int tmpdout, tmpdin; + int tm, isread = 0; + + debug("spi_xfer: slave %u:%u dout %08X din %08X bitlen %u\n", + slave->bus, slave->cs, dout, din, bitlen); + + if (flags & SPI_XFER_BEGIN) + spi_cs_activate(slave); + + /* + * handle data in 8-bit chunks + * TBD: 2byte xfer mode to be enabled + */ + while (bitlen > 4) { + debug("loopstart bitlen %d\n", bitlen); + tmpdout = 0; + /*1 byte xfer mode */ + writel(readl(KW_REG_SPI_CONFIG) & ~(1 << 5), KW_REG_SPI_CONFIG); + /* Shift data so it's msb-justified */ + if (dout) + tmpdout = *(u32 *) dout & 0x0ff; + + writel(0x0, KW_REG_SPI_IRQ_CAUSE); /* clear bit */ + writel(tmpdout, KW_REG_SPI_DATA_OUT); /* Write the data out */ + debug("*** spi_xfer: ... %08x written, bitlen %d\n", + tmpdout, bitlen); + + /* + * Wait for SPI transmit to get out + * or time out (1 second = 1000 ms) + * The NE event must be read and cleared first + */ + for (tm = 0, isread = 0; tm < KW_SPI_TIMEOUT; ++tm) { + if (readl(KW_REG_SPI_IRQ_CAUSE)) { + isread = 1; + tmpdin = readl(KW_REG_SPI_DATA_IN); + debug + ("*** spi_xfer: din %08X ... %08x read\n", + din, tmpdin); + + if (din) { + *((u8 *) din) = (u8) tmpdin; + din += 1; + } + if (dout) + dout += 1; + bitlen -= 8; + } + if (isread) + break; + } + if (tm >= KW_SPI_TIMEOUT) + printf("*** spi_xfer: Time out during SPI transfer\n"); + + debug("loopend bitlen %d\n", bitlen); + } + + if (flags & SPI_XFER_END) + spi_cs_deactivate(slave); + + return 0; +} diff --git a/include/asm-arm/arch-kirkwood/kirkwood.h b/include/asm-arm/arch-kirkwood/kirkwood.h new file mode 100644 index 0000000..0e6e0be --- /dev/null +++ b/include/asm-arm/arch-kirkwood/kirkwood.h @@ -0,0 +1,117 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Prafulla Wadaskar prafulla@marvell.com + * + * Header file for the Marvell's Feroceon CPU core. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef _ASM_ARCH_KIRKWOOD_H +#define _ASM_ARCH_KIRKWOOD_H + +#ifndef __ASSEMBLY__ +#include <asm/types.h> +#include <asm/io.h> +#endif /* __ASSEMBLY__ */ + +#if defined (CONFIG_FEROCEON_88FR131) || defined (CONFIG_SHEEVA_88SV131) +#include <../cpu/arm926ejs/kirkwood/cpu.h> + +/* SOC specific definations */ +#define INTREG_BASE 0xd0000000 +#define KW_REGISTER(x) (KW_REGS_PHY_BASE | x) +#define KW_OFFSET_REG (INTREG_BASE | 0x20080) + +/* undocumented registers */ +#define KW_REG_UNDOC_0x1470 (KW_REGISTER(0x1470)) +#define KW_REG_UNDOC_0x1478 (KW_REGISTER(0x1478)) + +#define KW_UART0_BASE (KW_REGISTER(0x12000)) /* UArt 0 */ +#define KW_UART1_BASE (KW_REGISTER(0x13000)) /* UArt 1 */ + +/* Controler environment registers offsets */ +#define KW_REG_MPP_CONTROL0 (KW_REGISTER(0x10000)) +#define KW_REG_MPP_CONTROL1 (KW_REGISTER(0x10004)) +#define KW_REG_MPP_CONTROL2 (KW_REGISTER(0x10008)) +#define KW_REG_MPP_CONTROL3 (KW_REGISTER(0x1000C)) +#define KW_REG_MPP_CONTROL4 (KW_REGISTER(0x10010)) +#define KW_REG_MPP_CONTROL5 (KW_REGISTER(0x10014)) +#define KW_REG_MPP_CONTROL6 (KW_REGISTER(0x10018)) +#define KW_REG_MPP_SMPL_AT_RST (KW_REGISTER(0x10030)) +#define KW_REG_DEVICE_ID (KW_REGISTER(0x10034)) +#define KW_REG_MPP_OUT_DRV_REG (KW_REGISTER(0x100E0)) + +#define KW_REG_GPP0_DATA_OUT (KW_REGISTER(0x10100)) +#define KW_REG_GPP0_DATA_OUT_EN (KW_REGISTER(0x10104)) +#define KW_REG_GPP0_BLINK_EN (KW_REGISTER(0x10108)) +#define KW_REG_GPP0_DATA_IN_POL (KW_REGISTER(0x1010C)) +#define KW_REG_GPP0_DATA_IN (KW_REGISTER(0x10110)) +#define KW_REG_GPP0_INT_CAUSE (KW_REGISTER(0x10114)) +#define KW_REG_GPP0_INT_MASK (KW_REGISTER(0x10118)) +#define KW_REG_GPP0_INT_LVL (KW_REGISTER(0x1011c)) + +#define KW_REG_GPP1_DATA_OUT (KW_REGISTER(0x10140)) +#define KW_REG_GPP1_DATA_OUT_EN (KW_REGISTER(0x10144)) +#define KW_REG_GPP1_BLINK_EN (KW_REGISTER(0x10148)) +#define KW_REG_GPP1_DATA_IN_POL (KW_REGISTER(0x1014C)) +#define KW_REG_GPP1_DATA_IN (KW_REGISTER(0x10150)) +#define KW_REG_GPP1_INT_CAUSE (KW_REGISTER(0x10154)) +#define KW_REG_GPP1_INT_MASK (KW_REGISTER(0x10158)) +#define KW_REG_GPP1_INT_LVL (KW_REGISTER(0x1015c)) + +#define KW_REG_NAND_READ_PARAM (KW_REGISTER(0x10418)) +#define KW_REG_NAND_WRITE_PARAM (KW_REGISTER(0x1041c)) +#define KW_REG_NAND_CTRL (KW_REGISTER(0x10470)) + +#define KW_REG_WIN_CTRL(x) (KW_REGISTER((0x20000 + (x * 0x10)))) +#define KW_REG_WIN_BASE(x) (KW_REGISTER((0x20004 + (x * 0x10)))) +#define KW_REG_WIN_REMAP_LOW(x) (KW_REGISTER((0x20008 + (x * 0x10)))) +#define KW_REG_WIN_REMAP_HIGH(x) (KW_REGISTER((0x2000c + (x * 0x10)))) + +#define KW_REG_CPU_CONFIG (KW_REGISTER(0x20100)) +#define KW_REG_CPU_CTRL_STAT (KW_REGISTER(0x20104)) +#define KW_REG_CPU_RSTOUTN_MASK (KW_REGISTER(0x20108)) +#define KW_REG_CPU_SYS_SOFT_RST (KW_REGISTER(0x2010C)) +#define KW_REG_CPU_AHB_MBUS_CAUSE_INT (KW_REGISTER(0x20110)) +#define KW_REG_CPU_AHB_MBUS_MASK_INT (KW_REGISTER(0x20114)) +#define KW_REG_CPU_FTDLL_CONFIG (KW_REGISTER(0x20120)) +#define KW_REG_CPU_L2_CONFIG (KW_REGISTER(0x20128)) +#define KW_REG_L2_RAM_TIMING0 (KW_REGISTER(0x20134)) +#define KW_REG_L2_RAM_TIMING1 (KW_REGISTER(0x20138)) + +#define KW_REG_TMR_CTRL (KW_REGISTER(0x20300)) +#define KW_REG_TMR_RELOAD (KW_REGISTER(0x20310)) +#define KW_REG_TMR_VAL (KW_REGISTER(0x20314)) + +#define KW_REG_PCIE_BASE (KW_REGISTER(0x40000)) + +#define KW_EGIGA0_BASE (KW_REGISTER(0x72000)) +#define KW_EGIGA1_BASE (KW_REGISTER(0x76000)) + +#if defined (CONFIG_KW88F6281) +#include "kw88f6281.h" +#endif /* CONFIG_KW88F6281 */ +#if defined (CONFIG_KW88F6192) +#include "kw88f6192.h" +#endif /* CONFIG_KW88F6192 */ + +#endif /* CONFIG_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/arch-kirkwood/serial.h b/include/asm-arm/arch-kirkwood/serial.h new file mode 100644 index 0000000..5fd3b31 --- /dev/null +++ b/include/asm-arm/arch-kirkwood/serial.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) Marvell International Ltd. and its affiliates + * Prafulla Wadaskar prafulla@marvell.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef __KW_SERIAL_H__ +#define __KW_SERIAL_H__ + +/* registers feilds */ +#define FCR_FIFO_EN (1 << 0) /* fifo enable */ +#define FCR_RXSR (1 << 1) /* receiver soft reset */ +#define FCR_TXSR (1 << 2) /* transmitter soft reset */ +#define MCR_RTS (1 << 1) /* ready to send */ + +#define LCR_WLS_OFFS 0 +#define LCR_WLS_MASK (0x3 << LCR_WLS_OFFS) /* character length mask */ +#define LCR_WLS_5 (0x0 << LCR_WLS_OFFS) /* 5 bit character length */ +#define LCR_WLS_6 (0x1 << LCR_WLS_OFFS) /* 6 bit character length */ +#define LCR_WLS_7 (0x2 << LCR_WLS_OFFS) /* 7 bit character length */ +#define LCR_WLS_8 (0x3 << LCR_WLS_OFFS) /* 8 bit character length */ +#define LCR_STP_OFFS 2 +#define LCR_1_STB (0x0 << LCR_STP_OFFS) /* Number of stop Bits */ +#define LCR_2_STB (0x1 << LCR_STP_OFFS) /* Number of stop Bits */ +#define LCR_PEN 0x8 /* Parity enable */ +#define LCR_PS_OFFS 4 +#define LCR_EPS (0x1 << LCR_PS_OFFS) /* Even Parity Select */ +#define LCR_OPS (0x0 << LCR_PS_OFFS) /* Odd Parity Select */ +#define LCR_SBRK_OFFS 0x6 +#define LCR_SBRK (0x1 << LCR_SBRK_OFFS) /* Set Break */ +#define LCR_DIVL_OFFS 7 +#define LCR_DIVL_EN (0x1 << LCR_DIVL_OFFS) /* Divisior latch enable */ + +#define LSR_DR (1 << 0) /* Data ready */ +#define LSR_OE (1 << 1) /* Overrun */ +#define LSR_PE (1 << 2) /* Parity error */ +#define LSR_FE (1 << 3) /* Framing error */ +#define LSR_BI (1 << 4) /* Break */ +#define LSR_THRE (1 << 5) /* Xmit holding register empty */ +#define LSR_TEMT (1 << 6) /* Xmitter empty */ +#define LSR_ERR (1 << 7) /* Error */ + +/* useful defaults for LCR*/ +#define LCR_8N1 LCR_WLS_8 | LCR_1_STB + +/* This structure describes the registers offsets for one UART port/channel */ +struct kw_uart_port { + u8 rbr; /* 0 = 0-3 */ + u8 pad1[3]; + u8 ier; /* 1 = 4-7 */ + u8 pad2[3]; + u8 fcr; /* 2 = 8-b */ + u8 pad3[3]; + u8 lcr; /* 3 = c-f */ + u8 pad4[3]; + u8 mcr; /* 4 = 10-13 */ + u8 pad5[3]; + u8 lsr; /* 5 = 14-17 */ + u8 pad6[3]; + u8 msr; /* 6 =18-1b */ + u8 pad7[3]; + u8 scr; /* 7 =1c-1f */ + u8 pad8[3]; +}; + +/* aliases - for registers which has the same offsets */ +#define thr rbr +#define iir fcr +#define dll rbr +#define dlm ier + +#endif /* __KW_SERIAL_H__ */ diff --git a/include/asm-arm/arch-kirkwood/spi.h b/include/asm-arm/arch-kirkwood/spi.h new file mode 100644 index 0000000..d8fcb86 --- /dev/null +++ b/include/asm-arm/arch-kirkwood/spi.h @@ -0,0 +1,39 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Prafulla Wadaskar prafulla@marvell.com + * + * Derived from drivers/spi/mpc8xxx_spi.c + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef __KW_SPI_H__ +#define __KW_SPI_H__ + +/* SPI Registers on kirkwood SOC */ +#define KW_REG_SPI_CTRL KW_REGISTER(0x10600) +#define KW_REG_SPI_CONFIG KW_REGISTER(0x10604) +#define KW_REG_SPI_DATA_OUT KW_REGISTER(0x10608) +#define KW_REG_SPI_DATA_IN KW_REGISTER(0x1060c) +#define KW_REG_SPI_IRQ_CAUSE KW_REGISTER(0x10610) +#define KW_REG_SPI_IRQ_MASK KW_REGISTER(0x10614) + +#define KW_SPI_TIMEOUT 10000 +#endif /* __KW_SPI_H__ */ diff --git a/include/asm-arm/cache.h b/include/asm-arm/cache.h new file mode 100644 index 0000000..2f0ea29 --- /dev/null +++ b/include/asm-arm/cache.h @@ -0,0 +1,41 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Prafulla Wadaskar prafulla@marvell.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef _ASM_CACHE_H +#define _ASM_CACHE_H + +#include <asm/system.h> + +/* + * Invalidate L2 Cache using co-proc instruction + */ +static inline void invalidate_l2_cache(void) +{ + unsigned int val=0; + + asm volatile("mcr p15, 1, %0, c15, c11, 0 @ invl l2 cache" + : : "r" (val) : "cc"); + isb(); +} +#endif /* _ASM_CACHE_H */ diff --git a/include/common.h b/include/common.h index 30fff7d..9e4b859 100644 --- a/include/common.h +++ b/include/common.h @@ -294,6 +294,7 @@ void pciinfo (int, int); #endif #endif
+int arch_misc_init (void); int misc_init_f (void); int misc_init_r (void);
diff --git a/lib_arm/board.c b/lib_arm/board.c index 5d05d9b..b8db60d 100644 --- a/lib_arm/board.c +++ b/lib_arm/board.c @@ -393,6 +393,10 @@ void start_armboot (void)
console_init_r (); /* fully init console as a device */
+#if defined(CONFIG_ARCH_MISC_INIT) + /* miscellaneous arch dependent initialisations */ + arch_misc_init (); +#endif #if defined(CONFIG_MISC_INIT_R) /* miscellaneous platform dependent initialisations */ misc_init_r ();

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 */
a header must only be include in the file that need it please remove from here
asm/config.h is included in include/common.h which is automatically generated by make It makes no sense to keep include/asm-arm/config.h empty.
Regards.. Prafulla . .
participants (4)
-
Jean-Christophe PLAGNIOL-VILLARD
-
Prafulla Wadaskar
-
Stefan Roese
-
Wolfgang Denk