[U-Boot] [PATCH] cpu_misc_init support for ARM architectures

This patch is required for Kirkwood support may be used by other ARM architectures
Signed-off-by: Prafulla Wadaskar prafulla@marvell.com --- include/asm-arm/u-boot-arm.h | 1 + lib_arm/board.c | 4 ++++ 2 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/include/asm-arm/u-boot-arm.h b/include/asm-arm/u-boot-arm.h index 76f1ffa..6d2f8bc 100644 --- a/include/asm-arm/u-boot-arm.h +++ b/include/asm-arm/u-boot-arm.h @@ -42,6 +42,7 @@ int cleanup_before_linux(void);
/* cpu/.../arch/cpu.c */ int arch_cpu_init(void); +int arch_misc_init(void);
/* board/.../... */ int board_init(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 ();

-----Original Message----- From: Mike Frysinger [mailto:vapier@gentoo.org] Sent: Friday, May 29, 2009 9:58 PM To: u-boot@lists.denx.de Cc: Prafulla Wadaskar; Manas Saksena; Ronen Shitrit; Nicolas Pitre; Ashish Karkare; Prabhanjan Sarnaik; Lennert Buijtenhek Subject: Re: [U-Boot] [PATCH] cpu_misc_init support for ARM architectures
On Friday 29 May 2009 15:43:30 Prafulla Wadaskar wrote:
+int arch_misc_init(void);
your subject line says cpu_xxx but the source says arch_xxx -mike
Hi Mike, Thanks.... I will correct this regards.. Prafulla . .

This patch is required for Kirkwood support may be used by other ARM architectures
Signed-off-by: Prafulla Wadaskar prafulla@marvell.com --- Change log: v2: Name of the patch corrected to arch_misc_init from cpu_misc_init
include/asm-arm/u-boot-arm.h | 1 + lib_arm/board.c | 4 ++++ 2 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/include/asm-arm/u-boot-arm.h b/include/asm-arm/u-boot-arm.h index 76f1ffa..6d2f8bc 100644 --- a/include/asm-arm/u-boot-arm.h +++ b/include/asm-arm/u-boot-arm.h @@ -42,6 +42,7 @@ int cleanup_before_linux(void);
/* cpu/.../arch/cpu.c */ int arch_cpu_init(void); +int arch_misc_init(void);
/* board/.../... */ int board_init(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 ();

On 16:12 Sat 30 May , Prafulla Wadaskar wrote:
This patch is required for Kirkwood support may be used by other ARM architectures
Signed-off-by: Prafulla Wadaskar prafulla@marvell.com
applied to arm/next
Best Regards, J.

This patch is required for Kirkwood SoC support may be used by other ARM architectures
Signed-off-by: Prafulla Wadaskar prafulla@marvell.com --- include/asm-arm/cache.h | 41 +++++++++++++++++++++++++++++++++++++++++ 1 files changed, 41 insertions(+), 0 deletions(-) create mode 100644 include/asm-arm/cache.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> + * Written-by: 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 */

Kirkwood family controllers are highly integrated SOCs based on Feroceon-88FR131/Sheeva-88SV131/arm926ejs 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) PCI Express port initialization 3) NS16550 driver support
Contributors: Yotam Admon yotam@marvell.com Michael Blostein <michaelbl@marvell.com
Reviewed-by: Ronen Shitrit rshitrit@marvell.com Acked-by: Stefan Rose sr@denx.de Signed-off-by: Prafulla Wadaskar prafulla@marvell.com --- cpu/arm926ejs/kirkwood/Makefile | 49 +++++ cpu/arm926ejs/kirkwood/cpu.c | 324 +++++++++++++++++++++++++++++ cpu/arm926ejs/kirkwood/dram.c | 58 +++++ cpu/arm926ejs/kirkwood/mpp.c | 80 +++++++ cpu/arm926ejs/kirkwood/timer.c | 168 +++++++++++++++ drivers/serial/serial.c | 3 + include/asm-arm/arch-kirkwood/cpu.h | 148 +++++++++++++ include/asm-arm/arch-kirkwood/kirkwood.h | 69 ++++++ include/asm-arm/arch-kirkwood/kw88f6192.h | 37 ++++ include/asm-arm/arch-kirkwood/kw88f6281.h | 37 ++++ include/asm-arm/arch-kirkwood/mpp.h | 303 +++++++++++++++++++++++++++ 11 files changed, 1276 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 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
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> +# Written-by: 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..62c4157 --- /dev/null +++ b/cpu/arm926ejs/kirkwood/cpu.c @@ -0,0 +1,324 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Written-by: 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 ones followed by + * sequence of zeros. The number of ones 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 */ + +#ifdef CONFIG_KIRKWOOD_EGIGA +int cpu_eth_init(bd_t *bis) +{ + kirkwood_egiga_initialize(bis); + return 0; +} +#endif 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> + * Written-by: Prafulla Wadaskar prafulla@marvell.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include <config.h> +#include <asm/arch/kirkwood.h> + +#define KW_REG_CPUCS_WIN_BAR(x) (KW_REGISTER(0x1500) + (x * 0x08)) +#define KW_REG_CPUCS_WIN_SZ(x) (KW_REGISTER(0x1504) + (x * 0x08)) +/* + * kw_sdram_bar - reads SDRAM Base Address Register + */ +u32 kw_sdram_bar(enum memory_bank bank) +{ + u32 result = 0; + u32 enable = 0x01 & readl(KW_REG_CPUCS_WIN_SZ(bank)); + + if ((!enable) || (bank > BANK3)) + return 0; + + result = readl(KW_REG_CPUCS_WIN_BAR(bank)); + return result; +} + +/* + * kw_sdram_bs - reads SDRAM Bank size + */ +u32 kw_sdram_bs(enum memory_bank bank) +{ + u32 result = 0; + u32 enable = 0x01 & readl(KW_REG_CPUCS_WIN_SZ(bank)); + + if ((!enable) || (bank > BANK3)) + return 0; + result = 0xff000000 & readl(KW_REG_CPUCS_WIN_SZ(bank)); + result += 0x01000000; + return result; +} diff --git a/cpu/arm926ejs/kirkwood/mpp.c b/cpu/arm926ejs/kirkwood/mpp.c new file mode 100644 index 0000000..b2f0ad5 --- /dev/null +++ b/cpu/arm926ejs/kirkwood/mpp.c @@ -0,0 +1,80 @@ +/* + * arch/arm/mach-kirkwood/mpp.c + * + * MPP functions for Marvell Kirkwood SoCs + * Referenced from Linux kernel source + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include <common.h> +#include <asm/arch/kirkwood.h> +#include <asm/arch/mpp.h> + +static u32 kirkwood_variant(void) +{ + switch (readl(KW_REG_DEVICE_ID) & 0x03) { + case 1: + return MPP_F6192_MASK; + case 2: + return MPP_F6281_MASK; + default: + debug("MPP setup: unknown kirkwood variant\n"); + return 0; + } +} + +#define MPP_CTRL(i) (KW_MPP_BASE + (i* 4)) +#define MPP_NR_REGS (1 + MPP_MAX/8) + +void kirkwood_mpp_conf(u32 *mpp_list) +{ + u32 mpp_ctrl[MPP_NR_REGS]; + unsigned int variant_mask; + int i; + + variant_mask = kirkwood_variant(); + if (!variant_mask) + return; + + debug( "initial MPP regs:"); + for (i = 0; i < MPP_NR_REGS; i++) { + mpp_ctrl[i] = readl(MPP_CTRL(i)); + debug(" %08x", mpp_ctrl[i]); + } + debug("\n"); + + + while (*mpp_list) { + unsigned int num = MPP_NUM(*mpp_list); + unsigned int sel = MPP_SEL(*mpp_list); + int shift; + + if (num > MPP_MAX) { + debug("kirkwood_mpp_conf: invalid MPP " + "number (%u)\n", num); + continue; + } + if (!(*mpp_list & variant_mask)) { + debug("kirkwood_mpp_conf: requested MPP%u config " + "unavailable on this hardware\n", num); + continue; + } + + shift = (num & 7) << 2; + mpp_ctrl[num / 8] &= ~(0xf << shift); + mpp_ctrl[num / 8] |= sel << shift; + + mpp_list++; + } + + debug(" final MPP regs:"); + for (i = 0; i < MPP_NR_REGS; i++) { + writel(mpp_ctrl[i], MPP_CTRL(i)); + debug(" %08x", mpp_ctrl[i]); + } + debug("\n"); + +} diff --git a/cpu/arm926ejs/kirkwood/timer.c b/cpu/arm926ejs/kirkwood/timer.c new file mode 100644 index 0000000..5c39ee8 --- /dev/null +++ b/cpu/arm926ejs/kirkwood/timer.c @@ -0,0 +1,168 @@ +/* + * Copyright (C) Marvell International Ltd. and its affiliates + * Written-by: 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/include/asm-arm/arch-kirkwood/cpu.h b/include/asm-arm/arch-kirkwood/cpu.h new file mode 100644 index 0000000..1e955f4 --- /dev/null +++ b/include/asm-arm/arch-kirkwood/cpu.h @@ -0,0 +1,148 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Written-by: 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(); +} + +/* + * MBus-L to Mbus Bridge Registers + * Ref: Datasheet sec:A.3 + */ +struct kwwin_registers { + u32 ctrl; + u32 base; + u32 remap_lo; + u32 remap_hi; +}; + +/* + * CPU control and status Registers + * Ref: Datasheet sec:A.3.2 + */ +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 */ +}; + +/* + * GPIO Registers + * Ref: Datasheet sec:A.19 + */ +struct kwgpio_registers { + u32 dout; + u32 oe; + u32 blink_en; + u32 din_pol; + u32 din; + u32 irq_cause; + u32 irq_mask; + u32 irq_level; +}; + +/* + * functions + */ +void reset_cpu(unsigned long ignored); +unsigned char get_random_hex(void); +unsigned int kw_sdram_bar(enum memory_bank bank); +unsigned int kw_sdram_bs(enum memory_bank bank); +int kw_config_adr_windows(void); +void kw_config_gpio(unsigned int gpp0_oe_val, unsigned int gpp1_oe_val, + unsigned int gpp0_oe, unsigned int gpp1_oe); +int kw_config_mpp(unsigned int mpp0_7, unsigned int mpp8_15, + unsigned int mpp16_23, unsigned int mpp24_31, + unsigned int mpp32_39, unsigned int mpp40_47, + unsigned int mpp48_55); +#endif /* __ASSEMBLY__ */ +#endif /* _KWCPU_H */ diff --git a/include/asm-arm/arch-kirkwood/kirkwood.h b/include/asm-arm/arch-kirkwood/kirkwood.h new file mode 100644 index 0000000..f026b9c --- /dev/null +++ b/include/asm-arm/arch-kirkwood/kirkwood.h @@ -0,0 +1,69 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Written-by: Prafulla Wadaskar prafulla@marvell.com + * + * Header file for the Marvell's Feroceon CPU core. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef _ASM_ARCH_KIRKWOOD_H +#define _ASM_ARCH_KIRKWOOD_H + +#ifndef __ASSEMBLY__ +#include <asm/types.h> +#include <asm/io.h> +#endif /* __ASSEMBLY__ */ + +#if defined (CONFIG_FEROCEON_88FR131) || defined (CONFIG_SHEEVA_88SV131) +#include <asm/arch/cpu.h> + +/* SOC specific definations */ +#define INTREG_BASE 0xd0000000 +#define KW_REGISTER(x) (KW_REGS_PHY_BASE + x) +#define KW_OFFSET_REG (INTREG_BASE + 0x20080) + +/* undocumented registers */ +#define KW_REG_UNDOC_0x1470 (KW_REGISTER(0x1470)) +#define KW_REG_UNDOC_0x1478 (KW_REGISTER(0x1478)) + +#define KW_UART0_BASE (KW_REGISTER(0x12000)) +#define KW_UART1_BASE (KW_REGISTER(0x13000)) +#define KW_MPP_BASE (KW_REGISTER(0x10000)) +#define KW_GPIO0_BASE (KW_REGISTER(0x10100)) +#define KW_GPIO1_BASE (KW_REGISTER(0x10140)) +#define KW_NANDF_BASE (KW_REGISTER(0x10418)) +#define KW_SPI_BASE (KW_REGISTER(0x10600)) +#define KW_CPU_WIN_BASE (KW_REGISTER(0x20000)) +#define KW_CPU_REG_BASE (KW_REGISTER(0x20100)) +#define KW_TIMER_BASE (KW_REGISTER(0x20300)) +#define KW_REG_PCIE_BASE (KW_REGISTER(0x40000)) +#define KW_EGIGA0_BASE (KW_REGISTER(0x72000)) +#define KW_EGIGA1_BASE (KW_REGISTER(0x76000)) + +#if defined (CONFIG_KW88F6281) +#include <asm/arch/kw88f6281.h> +#elif defined (CONFIG_KW88F6192) +#include <asm/arch/kw88f6192.h> +#else +#error "SOC Name not defined" +#endif /* CONFIG_KW88F6281 */ +#endif /* CONFIG_FEROCEON_88FR131 */ +#endif /* _ASM_ARCH_KIRKWOOD_H */ diff --git a/include/asm-arm/arch-kirkwood/kw88f6192.h b/include/asm-arm/arch-kirkwood/kw88f6192.h new file mode 100644 index 0000000..a2b1f96 --- /dev/null +++ b/include/asm-arm/arch-kirkwood/kw88f6192.h @@ -0,0 +1,37 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Written-by: 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> + * Written-by: 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

This patch adds a SPI driver for the Marvell Kirkwood SoC's.
Signed-off-by: Prafulla Wadaskar prafulla@marvell.com --- drivers/spi/Makefile | 1 + drivers/spi/kirkwood_spi.c | 185 +++++++++++++++++++++++++++++++++++ include/asm-arm/arch-kirkwood/spi.h | 56 +++++++++++ 3 files changed, 242 insertions(+), 0 deletions(-) create mode 100644 drivers/spi/kirkwood_spi.c create mode 100644 include/asm-arm/arch-kirkwood/spi.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> + * Written-by: 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/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> + * Written-by: 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__ */

This patch adds a NAND driver for the Marvell Kirkwood SoC's.
Acked-by: Stefan Roese sr@denx.de Signed-off-by: Prafulla Wadaskar prafulla@marvell.com --- drivers/mtd/nand/Makefile | 1 + drivers/mtd/nand/kirkwood_nand.c | 81 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 0 deletions(-) create mode 100644 drivers/mtd/nand/kirkwood_nand.c
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index 471cd6b..766c3f0 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -40,6 +40,7 @@ COBJS-$(CONFIG_DRIVER_NAND_BFIN) += bfin_nand.o COBJS-$(CONFIG_NAND_DAVINCI) += davinci_nand.o COBJS-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_nand.o COBJS-$(CONFIG_NAND_FSL_UPM) += fsl_upm.o +COBJS-$(CONFIG_NAND_KIRKWOOD) += kirkwood_nand.o COBJS-$(CONFIG_NAND_NOMADIK) += nomadik.o COBJS-$(CONFIG_NAND_S3C2410) += s3c2410_nand.c COBJS-$(CONFIG_NAND_S3C64XX) += s3c64xx.o diff --git a/drivers/mtd/nand/kirkwood_nand.c b/drivers/mtd/nand/kirkwood_nand.c new file mode 100644 index 0000000..a2551cd --- /dev/null +++ b/drivers/mtd/nand/kirkwood_nand.c @@ -0,0 +1,81 @@ +/* + * Copyright (C) Marvell International Ltd. and its affiliates + * Written-by: Prafulla Wadaskar prafulla@marvell.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/kirkwood.h> +#include <nand.h> + +/* NAND Flash Soc registers */ +struct kwnandf_registers { + u32 rd_params; /* 0x10418 */ + u32 wr_param; /* 0x1041c */ + u8 pag[0x10470 - 0x1041c -4]; + u32 ctrl; /* 0x10470 */ +}; + +static struct kwnandf_registers *nf_reg = + (struct kwnandf_registers *)KW_NANDF_BASE; + +/* + * hardware specific access to control-lines/bits + */ +#define NAND_ACTCEBOOT_BIT 0x02 + +static void kw_nand_hwcontrol(struct mtd_info *mtd, int cmd, + unsigned int ctrl) +{ + struct nand_chip *nc = mtd->priv; + u32 offs; + + if (cmd == NAND_CMD_NONE) + return; + + if (ctrl & NAND_CLE) + offs = (1 << 0); /* Commands with A[1:0] == 01 */ + else if (ctrl & NAND_ALE) + offs = (1 << 1); /* Addresses with A[1:0] == 10 */ + else + return; + + writeb(cmd, nc->IO_ADDR_W + offs); +} + +void kw_nand_select_chip(struct mtd_info *mtd, int chip) +{ + u32 data; + + data = readl(&nf_reg->ctrl); + data |= NAND_ACTCEBOOT_BIT; + writel(data, &nf_reg->ctrl); +} + +int board_nand_init(struct nand_chip *nand) +{ + nand->options = NAND_COPYBACK | NAND_CACHEPRG | NAND_NO_PADDING; + nand->ecc.mode = NAND_ECC_SOFT; + nand->cmd_ctrl = kw_nand_hwcontrol; + nand->chip_delay = 30; + nand->select_chip = kw_nand_select_chip; + return 0; +}

On Sat, May 30, 2009 at 01:13:34AM +0530, Prafulla Wadaskar wrote:
This patch adds a NAND driver for the Marvell Kirkwood SoC's.
Acked-by: Stefan Roese sr@denx.de Signed-off-by: Prafulla Wadaskar prafulla@marvell.com
ACK, except for a typo:
+/* NAND Flash Soc registers */ +struct kwnandf_registers {
- u32 rd_params; /* 0x10418 */
- u32 wr_param; /* 0x1041c */
- u8 pag[0x10470 - 0x1041c -4];
s/pag/pad/, presumably. Also s/-4/- 4/.
-Scott

This patch adds a NAND driver for the Marvell Kirkwood SoC's.
Acked-by: Stefan Roese sr@denx.de Signed-off-by: Prafulla Wadaskar prafulla@marvell.com --- Change log: v2: Typos corrected
drivers/mtd/nand/Makefile | 1 + drivers/mtd/nand/kirkwood_nand.c | 81 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 0 deletions(-) create mode 100644 drivers/mtd/nand/kirkwood_nand.c
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index 471cd6b..766c3f0 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -40,6 +40,7 @@ COBJS-$(CONFIG_DRIVER_NAND_BFIN) += bfin_nand.o COBJS-$(CONFIG_NAND_DAVINCI) += davinci_nand.o COBJS-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_nand.o COBJS-$(CONFIG_NAND_FSL_UPM) += fsl_upm.o +COBJS-$(CONFIG_NAND_KIRKWOOD) += kirkwood_nand.o COBJS-$(CONFIG_NAND_NOMADIK) += nomadik.o COBJS-$(CONFIG_NAND_S3C2410) += s3c2410_nand.c COBJS-$(CONFIG_NAND_S3C64XX) += s3c64xx.o diff --git a/drivers/mtd/nand/kirkwood_nand.c b/drivers/mtd/nand/kirkwood_nand.c new file mode 100644 index 0000000..a2551cd --- /dev/null +++ b/drivers/mtd/nand/kirkwood_nand.c @@ -0,0 +1,81 @@ +/* + * Copyright (C) Marvell International Ltd. and its affiliates + * Written-by: Prafulla Wadaskar prafulla@marvell.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/kirkwood.h> +#include <nand.h> + +/* NAND Flash Soc registers */ +struct kwnandf_registers { + u32 rd_params; /* 0x10418 */ + u32 wr_param; /* 0x1041c */ + u8 pad[0x10470 - 0x1041c - 4]; + u32 ctrl; /* 0x10470 */ +}; + +static struct kwnandf_registers *nf_reg = + (struct kwnandf_registers *)KW_NANDF_BASE; + +/* + * hardware specific access to control-lines/bits + */ +#define NAND_ACTCEBOOT_BIT 0x02 + +static void kw_nand_hwcontrol(struct mtd_info *mtd, int cmd, + unsigned int ctrl) +{ + struct nand_chip *nc = mtd->priv; + u32 offs; + + if (cmd == NAND_CMD_NONE) + return; + + if (ctrl & NAND_CLE) + offs = (1 << 0); /* Commands with A[1:0] == 01 */ + else if (ctrl & NAND_ALE) + offs = (1 << 1); /* Addresses with A[1:0] == 10 */ + else + return; + + writeb(cmd, nc->IO_ADDR_W + offs); +} + +void kw_nand_select_chip(struct mtd_info *mtd, int chip) +{ + u32 data; + + data = readl(&nf_reg->ctrl); + data |= NAND_ACTCEBOOT_BIT; + writel(data, &nf_reg->ctrl); +} + +int board_nand_init(struct nand_chip *nand) +{ + nand->options = NAND_COPYBACK | NAND_CACHEPRG | NAND_NO_PADDING; + nand->ecc.mode = NAND_ECC_SOFT; + nand->cmd_ctrl = kw_nand_hwcontrol; + nand->chip_delay = 30; + nand->select_chip = kw_nand_select_chip; + return 0; +}

Hi Scott
I have already posted v2 patch for this change which has only cosmetic change suggested by you. Ref : http://lists.denx.de/pipermail/u-boot/2009-May/053485.html
Since Kirkwood Basic Soc support is pulled in, and if there are no issues pending with this driver. May I request you to pull this on nand/next? Followed by pull request to Wolfgang.
Regards.. Prafulla . .
-----Original Message----- From: Scott Wood [mailto:scottwood@freescale.com] Sent: Saturday, May 30, 2009 1:10 AM To: Prafulla Wadaskar Cc: u-boot@lists.denx.de; Manas Saksena; Ronen Shitrit; Nicolas Pitre; Ashish Karkare; Prabhanjan Sarnaik; Lennert Buijtenhek Subject: Re: [U-Boot] [PATCH] nand: Add Marvell Kirkwood NAND driver
On Sat, May 30, 2009 at 01:13:34AM +0530, Prafulla Wadaskar wrote:
This patch adds a NAND driver for the Marvell Kirkwood SoC's.
Acked-by: Stefan Roese sr@denx.de Signed-off-by: Prafulla Wadaskar prafulla@marvell.com
ACK, except for a typo:
+/* NAND Flash Soc registers */ +struct kwnandf_registers {
- u32 rd_params; /* 0x10418 */
- u32 wr_param; /* 0x1041c */
- u8 pag[0x10470 - 0x1041c -4];
s/pag/pad/, presumably. Also s/-4/- 4/.
-Scott

This patch adds a egiga driver for the Marvell Kirkwood SoC's.
Contributors: Yotam Admon yotam@marvell.com Michael Blostein <michaelbl@marvell.com
Reviewed-by: Ronen Shitrit rshitrit@marvell.com Acked-by: Stefan Rose sr@denx.de Signed-off-by: Prafulla Wadaskar prafulla@marvell.com --- drivers/net/Makefile | 1 + drivers/net/kirkwood_egiga.c | 674 ++++++++++++++++++++++++++++++++++++++++++ drivers/net/kirkwood_egiga.h | 561 +++++++++++++++++++++++++++++++++++ include/netdev.h | 1 + 4 files changed, 1237 insertions(+), 0 deletions(-) create mode 100644 drivers/net/kirkwood_egiga.c create mode 100644 drivers/net/kirkwood_egiga.h
diff --git a/drivers/net/Makefile b/drivers/net/Makefile index a360a50..f0c5654 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -40,6 +40,7 @@ COBJS-$(CONFIG_ENC28J60) += enc28j60.o COBJS-$(CONFIG_FSLDMAFEC) += fsl_mcdmafec.o mcfmii.o COBJS-$(CONFIG_GRETH) += greth.o COBJS-$(CONFIG_INCA_IP_SWITCH) += inca-ip_sw.o +COBJS-$(CONFIG_KIRKWOOD_EGIGA) += kirkwood_egiga.o COBJS-$(CONFIG_DRIVER_KS8695ETH) += ks8695eth.o COBJS-$(CONFIG_DRIVER_LAN91C96) += lan91c96.o COBJS-$(CONFIG_MACB) += macb.o diff --git a/drivers/net/kirkwood_egiga.c b/drivers/net/kirkwood_egiga.c new file mode 100644 index 0000000..9e26d2c --- /dev/null +++ b/drivers/net/kirkwood_egiga.c @@ -0,0 +1,674 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Written-by: Prafulla Wadaskar prafulla@marvell.com + * + * (C) Copyright 2003 + * Ingo Assmus ingo.assmus@keymile.com + * + * based on - Driver for MV64360X ethernet ports + * Copyright (C) 2002 rabeeh@galileo.co.il + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include <common.h> +#include <net.h> +#include <malloc.h> +#include <miiphy.h> +#include <asm/errno.h> +#include <asm/types.h> +#include <asm/byteorder.h> +#include <asm/arch/kirkwood.h> +#include "kirkwood_egiga.h" + +/* + * smi_reg_read - miiphy_read callback function. + * + * Returns 16bit phy register value, or 0xffff on error + */ +static int smi_reg_read(char *devname, u8 phy_adr, u8 reg_ofs, u16 * data) +{ + struct eth_device *dev = eth_get_dev_by_name(devname); + struct kwgbe_device *dkwgbe = to_dkwgbe(dev); + struct kwgbe_registers *regs = dkwgbe->regs; + u32 smi_reg; + volatile u32 timeout; + + /* Phyadr read */ + if (phy_adr == 0xEE && reg_ofs == 0xEE) { + *data = (u16) (KWGBEREG_RD(regs->phyadr) & 0x00ff); + return 0; + } + /* check parameters */ + if ((phy_adr << KWGBE_PHY_SMI_DEV_ADDR_OFFS) & + ~KWGBE_PHY_SMI_DEV_ADDR_MASK) { + printf("Illegal PHY device address %d\n", phy_adr); + return -EFAULT; + } + if ((reg_ofs << KWGBE_SMI_REG_ADDR_OFFS) & + ~KWGBE_SMI_REG_ADDR_MASK) { + printf("Illegal PHY register offset %d\n", reg_ofs); + return -EFAULT; + } + + timeout = KWGBE_PHY_SMI_TIMEOUT; + /* wait till the SMI is not busy */ + do { + /* read smi register */ + smi_reg = KWGBEREG_RD(regs->smi); + if (timeout-- == 0) { + printf("SMI busy timeout\n"); + return -EFAULT; + } + } while (smi_reg & KWGBE_PHY_SMI_BUSY_MASK); + + /* fill the phy address and regiser offset and read opcode */ + smi_reg = (phy_adr << KWGBE_PHY_SMI_DEV_ADDR_OFFS) + | (reg_ofs << KWGBE_SMI_REG_ADDR_OFFS) + | KWGBE_PHY_SMI_OPCODE_READ; + + /* write the smi register */ + KWGBEREG_WR(regs->smi, smi_reg); + + /*wait till readed value is ready */ + timeout = KWGBE_PHY_SMI_TIMEOUT; + do { + /* read smi register */ + smi_reg = KWGBEREG_RD(regs->smi); + if (timeout-- == 0) { + printf("SMI read-valid timeout\n"); + return -EFAULT; + } + } while (!(smi_reg & KWGBE_PHY_SMI_READ_VALID_MASK)); + + /* Wait for the data to update in the SMI register */ + for (timeout = 0; timeout < KWGBE_PHY_SMI_TIMEOUT; timeout++) ; + + *data = (u16) (KWGBEREG_RD(regs->smi) & KWGBE_PHY_SMI_DATA_MASK); + + debug("Reg(phyadr %d, off %d) Phy-value = %04x\n", phy_adr, + reg_ofs, *data); + + return 0; +} + +/* + * smi_reg_write - imiiphy_write callback function. + * + * Returns 0 if write succeed, -EINVAL on bad parameters + * -ETIME on timeout + */ +static int smi_reg_write(char *devname, u8 phy_adr, u8 reg_ofs, u16 data) +{ + struct eth_device *dev = eth_get_dev_by_name(devname); + struct kwgbe_device *dkwgbe = to_dkwgbe(dev); + struct kwgbe_registers *regs = dkwgbe->regs; + u32 smi_reg; + volatile u32 timeout; + + /* Phyadr write */ + if (phy_adr == 0xEE && reg_ofs == 0xEE) { + KWGBEREG_WR(regs->phyadr, data); + return 0; + } + + /* check parameters */ + if ((phy_adr << KWGBE_PHY_SMI_DEV_ADDR_OFFS) & + ~KWGBE_PHY_SMI_DEV_ADDR_MASK) { + printf("Illegal phy address\n"); + return -EINVAL; + } + if ((reg_ofs << KWGBE_SMI_REG_ADDR_OFFS) & + ~KWGBE_SMI_REG_ADDR_MASK) { + printf("Illegal register offset\n"); + return -EINVAL; + } + + /* wait till the SMI is not busy */ + timeout = KWGBE_PHY_SMI_TIMEOUT; + do { + /* read smi register */ + smi_reg = KWGBEREG_RD(regs->smi); + if (timeout-- == 0) { + printf("SMI busy timeout\n"); + return -ETIME; + } + } while (smi_reg & KWGBE_PHY_SMI_BUSY_MASK); + + /* fill the phy addr and reg offset and write opcode and data */ + smi_reg = (data << KWGBE_PHY_SMI_DATA_OFFS); + smi_reg |= (phy_adr << KWGBE_PHY_SMI_DEV_ADDR_OFFS) + | (reg_ofs << KWGBE_SMI_REG_ADDR_OFFS); + smi_reg &= ~KWGBE_PHY_SMI_OPCODE_READ; + + /* write the smi register */ + KWGBEREG_WR(regs->smi, smi_reg); + + return 0; +} + +/* Stop and checks all queues */ +static void stop_queue(u32 *qreg) +{ + u32 reg_data; + + reg_data = readl(qreg); + + if (reg_data & 0xFF) { + /* Issue stop command for active channels only */ + writel((reg_data << 8), qreg); + + /* Wait for all queue activity to terminate. */ + do { + /* + * Check port cause register that all queues + * are stopped + */ + reg_data = readl(qreg); + } + while (reg_data & 0xFF); + } +} + +/* + * set_access_control - Config address decode parameters for Ethernet unit + * + * This function configures the address decode parameters for the Gigabit + * Ethernet Controller according the given parameters struct. + * + * @regs Register struct pointer. + * @param Address decode parameter struct. + */ +static void set_access_control(struct kwgbe_registers *regs, + struct kwgbe_winparam *param) +{ + u32 access_prot_reg; + + /* Set access control register */ + access_prot_reg = KWGBEREG_RD(regs->epap); + /* clear window permission */ + access_prot_reg &= (~(3 << (param->win * 2))); + access_prot_reg |= (param->access_ctrl << (param->win * 2)); + KWGBEREG_WR(regs->epap, access_prot_reg); + + /* Set window Size reg (SR) */ + KWGBEREG_WR(regs->barsz[param->win].size, + (((param->size / 0x10000) - 1) << 16)); + + /* Set window Base address reg (BA) */ + KWGBEREG_WR(regs->barsz[param->win].bar, + (param->target | param->attrib | param->base_addr)); + /* High address remap reg (HARR) */ + if (param->win < 4) + KWGBEREG_WR(regs->ha_remap[param->win], param->high_addr); + + /* Base address enable reg (BARER) */ + if (param->enable == 1) + KWGBEREG_BITS_RESET(regs->bare, (1 << param->win)); + else + KWGBEREG_BITS_SET(regs->bare, (1 << param->win)); +} + +static void set_dram_access(struct kwgbe_registers *regs) +{ + struct kwgbe_winparam win_param; + int i; + + for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { + /* Set access parameters for DRAM bank i */ + win_param.win = i; /* Use Ethernet window i */ + /* Window target - DDR */ + win_param.target = KWGBE_TARGET_DRAM; + /* Enable full access */ + win_param.access_ctrl = EWIN_ACCESS_FULL; + win_param.high_addr = 0; + /* Get bank base */ + win_param.base_addr = kw_sdram_bar(i); + win_param.size = kw_sdram_bs(i); /* Get bank size */ + if (win_param.size == 0) + win_param.enable = 0; + else + win_param.enable = 1; /* Enable the access */ + + /* Enable DRAM bank */ + switch (i) { + case 0: + win_param.attrib = EBAR_DRAM_CS0; + break; + case 1: + win_param.attrib = EBAR_DRAM_CS1; + break; + case 2: + win_param.attrib = EBAR_DRAM_CS2; + break; + case 3: + win_param.attrib = EBAR_DRAM_CS3; + break; + default: + /* invalide bank, disable access */ + win_param.enable = 0; + win_param.attrib = 0; + break; + } +#ifdef CONFIG_SYS_COHERENT_CACHE + win_param.attrib |= EBAR_DRAM_CACHE_COHERENCY_WB; +#endif + /* Set the access control for address window(EPAPR) RD/WR */ + set_access_control(regs, &win_param); + } +} + +/* + * port_init_mac_tables - Clear all entrance in the UC, SMC and OMC tables + * + * Go through all the DA filter tables (Unicast, Special Multicast & Other + * Multicast) and set each entry to 0. + */ +static void port_init_mac_tables(struct kwgbe_registers *regs) +{ + int table_index; + + /* Clear DA filter unicast table (Ex_dFUT) */ + for (table_index = 0; table_index < 4; ++table_index) + KWGBEREG_WR(regs->dfut[table_index], 0); + + for (table_index = 0; table_index < 64; ++table_index) { + /* Clear DA filter special multicast table (Ex_dFSMT) */ + KWGBEREG_WR(regs->dfsmt[table_index], 0); + /* Clear DA filter other multicast table (Ex_dFOMT) */ + KWGBEREG_WR(regs->dfomt[table_index], 0); + } +} + +/* + * port_uc_addr - This function Set the port unicast address table + * + * This function locates the proper entry in the Unicast table for the + * specified MAC nibble and sets its properties according to function + * parameters. + * This function add/removes MAC addresses from the port unicast address + * table. + * + * @uc_nibble Unicast MAC Address last nibble. + * @option 0 = Add, 1 = remove address. + * + * RETURN: 1 if output succeeded. 0 if option parameter is invalid. + */ +static int port_uc_addr(struct kwgbe_registers *regs, u8 uc_nibble, + int option) +{ + u32 unicast_reg; + u32 tbl_offset; + u32 reg_offset; + + /* Locate the Unicast table entry */ + uc_nibble = (0xf & uc_nibble); + /* Register offset from unicast table base */ + tbl_offset = (uc_nibble / 4); + /* Entry offset within the above register */ + reg_offset = uc_nibble % 4; + + switch (option) { + case REJECT_MAC_ADDR: + /* + * Clear accepts frame bit at specified unicast + * DA table entry + */ + unicast_reg = KWGBEREG_RD(regs->dfut[tbl_offset]); + unicast_reg &= (0xFF << (8 * reg_offset)); + KWGBEREG_WR(regs->dfut[tbl_offset], unicast_reg); + break; + case ACCEPT_MAC_ADDR: + /* Set accepts frame bit at unicast DA filter table entry */ + unicast_reg = KWGBEREG_RD(regs->dfut[tbl_offset]); + unicast_reg &= (0xFF << (8 * reg_offset)); + unicast_reg |= ((0x01 | (RXUQ << 1)) << (8 * reg_offset)); + KWGBEREG_WR(regs->dfut[tbl_offset], unicast_reg); + break; + default: + return 0; + } + return 1; +} + +/* + * port_uc_addr_set - This function Set the port Unicast address. + */ +static void port_uc_addr_set(struct kwgbe_registers *regs, u8* p_addr) +{ + u32 mac_h; + u32 mac_l; + + mac_l = (p_addr[4] << 8) | (p_addr[5]); + mac_h = (p_addr[0] << 24) | (p_addr[1] << 16) | (p_addr[2] << 8) | + (p_addr[3] << 0); + + KWGBEREG_WR(regs->macal, mac_l); + KWGBEREG_WR(regs->macah, mac_h); + + /* Accept frames of this address */ + port_uc_addr(regs, p_addr[5], ACCEPT_MAC_ADDR); +} + +/* + * kwgbe_init_rx_desc_ring - Curve a Rx chain desc list and buffer in memory. + */ +static void kwgbe_init_rx_desc_ring(struct kwgbe_device *dkwgbe) +{ + volatile struct kwgbe_rxdesc *p_rx_desc; + int i; + + /* initialize the Rx descriptors ring */ + p_rx_desc = dkwgbe->p_rxdesc; + for (i = 0; i < RINGSZ; i++) { + p_rx_desc->cmd_sts = + KWGBE_BUFFER_OWNED_BY_DMA | KWGBE_RX_EN_INTERRUPT; + p_rx_desc->buf_size = PKTSIZE_ALIGN; + p_rx_desc->byte_cnt = 0x0000; + p_rx_desc->buf_ptr = dkwgbe->p_rxbuf + + i * PKTSIZE_ALIGN; + if (i == (RINGSZ -1) ) + p_rx_desc->nxtdesc_p = dkwgbe->p_rxdesc; + else { + p_rx_desc->nxtdesc_p = (struct kwgbe_rxdesc *) + ((u32) p_rx_desc + KW_RXQ_DESC_ALIGNED_SIZE); + p_rx_desc = p_rx_desc->nxtdesc_p; + } + D_CACHE_FLUSH_LINE(p_rx_desc, 0); + } + + dkwgbe->p_rxdesc_curr = dkwgbe->p_rxdesc; +} + +static int kwgbe_init(struct eth_device *dev) +{ + struct kwgbe_device *dkwgbe = to_dkwgbe(dev); + struct kwgbe_registers *regs = dkwgbe->regs; + + /* setup RX rings */ + kwgbe_init_rx_desc_ring(dkwgbe); + + /* Clear the ethernet port interrupts */ + KWGBEREG_WR(regs->ic, 0); + KWGBEREG_WR(regs->ice, 0); + /* Unmask RX buffer and TX end interrupt */ + KWGBEREG_WR(regs->pim, INT_CAUSE_UNMASK_ALL); + /* Unmask phy and link status changes interrupts */ + KWGBEREG_WR(regs->peim, INT_CAUSE_UNMASK_ALL_EXT); + + set_dram_access(regs); + port_init_mac_tables(regs); + port_uc_addr_set(regs, dkwgbe->dev.enetaddr); + + /* Assign port configuration and command. */ + KWGBEREG_WR(regs->pxc, PRT_CFG_VAL); + KWGBEREG_WR(regs->pxcx, PORT_CFG_EXTEND_VALUE); + KWGBEREG_WR(regs->psc0, PORT_SERIAL_CONTROL_VALUE); + KWGBEREG_BITS_SET(regs->psc0, KWGBE_SERIAL_PORT_EN); + + /* Assign port SDMA configuration */ + KWGBEREG_WR(regs->sdc, PORT_SDMA_CFG_VALUE); + KWGBEREG_WR(regs->tqx[0].qxttbc, 0x3fffffff); + KWGBEREG_WR(regs->tqx[0].tqxtbc, 0x03fffcff); + /* Turn off the port/RXUQ bandwidth limitation */ + KWGBEREG_WR(regs->pmtu, 0x0); + + /* Set maximum receive buffer to 9700 bytes */ + KWGBEREG_WR(regs->psc0, + (0x5 << 17) | (KWGBEREG_RD(regs->psc0) & 0xfff1ffff)); + + /* + * Set ethernet MTU for leaky bucket mechanism to 0 - this will + * disable the leaky bucket mechanism . + */ + KWGBEREG_WR(regs->pmtu, 0); + + /* Assignment of Rx CRDB of given RXUQ */ + KWGBEREG_WR(regs->rxcdp[RXUQ].rxcdp, (u32) dkwgbe->p_rxdesc_curr); + /* Enable port Rx. */ + KWGBEREG_WR(regs->rqc, (1 << RXUQ)); + +#if (defined (CONFIG_MII) || defined (CONFIG_CMD_MII)) \ + && defined (CONFIG_SYS_FAULT_ECHO_LINK_DOWN) + u16 phyadr; + miiphy_read(dev->name,0xEE,0xEE,&phyadr); + if (!miiphy_link(dev->name, phyadr)) { + printf("No link on %s\n", dev->name); + } +#endif + return 0; +} + +static int kwgbe_halt(struct eth_device *dev) +{ + struct kwgbe_device *dkwgbe = to_dkwgbe(dev); + struct kwgbe_registers *regs = dkwgbe->regs; + + /* Disable all gigE address decoder */ + KWGBEREG_WR(regs->bare, 0x3f); + + stop_queue(®s->tqc); + stop_queue(®s->rqc); + + /* Enable port in the Configuration Register */ + KWGBEREG_BITS_RESET(regs->psc0, KWGBE_SERIAL_PORT_EN); + /* Set port of active in the Configuration Register */ + KWGBEREG_BITS_RESET(regs->psc1, 1 << 4); +#ifdef CONFIG_SYS_MII_MODE + /* Set MMI interface up */ + KWGBEREG_BITS_RESET(regs->psc1, 1 << 3); +#endif + /* Disable ethernet port interrupts */ + KWGBEREG_WR(regs->ic, 0); + KWGBEREG_WR(regs->ice, 0); + /* Mask RX buffer and TX end interrupt */ + KWGBEREG_WR(regs->pim, 0); + /* Mask phy and link status changes interrupts */ + KWGBEREG_WR(regs->peim, 0); + + debug("Deallocating descriptor and buffer rings"); + + debug("Ethernet stopped ...\n"); + return 0; +} + +static int kwgbe_send(struct eth_device *dev, volatile void *dataptr, int datasize) +{ + struct kwgbe_device *dkwgbe = to_dkwgbe(dev); + struct kwgbe_registers *regs = dkwgbe->regs; + struct kwgbe_txdesc *p_txdesc = dkwgbe->p_txdesc; + + if ((u32)dataptr &0x07) { + printf("Err..xmit dataptr not 64bit aligned\n"); + return -1; + } + p_txdesc->cmd_sts = KWGBE_ZERO_PADDING | KWGBE_GEN_CRC; + p_txdesc->cmd_sts |= KWGBE_TX_FIRST_DESC | KWGBE_TX_LAST_DESC; + p_txdesc->cmd_sts |= KWGBE_BUFFER_OWNED_BY_DMA; + p_txdesc->cmd_sts |= KWGBE_TX_EN_INTERRUPT; + p_txdesc->buf_ptr = (u8 *) dataptr; + p_txdesc->byte_cnt = datasize; + + /* Flush CPU pipe */ + CPU_PIPE_FLUSH; + + /* Apply send command using zeroth RXUQ */ + KWGBEREG_WR(regs->tcqdp[TXUQ], (u32)p_txdesc); + KWGBEREG_WR(regs->tqc, (1 << TXUQ)); + + /* + * wait for packet xmit completion + */ + while (p_txdesc->cmd_sts & KWGBE_BUFFER_OWNED_BY_DMA) { + /* return fail if error is detected */ + if (p_txdesc->cmd_sts & (KWGBE_UR_ERROR | KWGBE_RL_ERROR)) { + printf("Err..in xmit packet\n"); + return -1; + } + }; + return 0; +} + +static int kwgbe_recv(struct eth_device *dev) +{ + volatile struct kwgbe_device *dkwgbe = to_dkwgbe(dev); + volatile struct kwgbe_rxdesc *p_rxdesc_curr= dkwgbe->p_rxdesc_curr; + + /* Sanity check */ + if (p_rxdesc_curr == NULL) { + printf("Err.. null ptr \n"); + return -1; + } + + /* wait untill rx packet available */ + while (p_rxdesc_curr->cmd_sts & KWGBE_BUFFER_OWNED_BY_DMA); + D_CACHE_FLUSH_LINE((u32) p_rxdesc_curr, 0); + + if (p_rxdesc_curr->byte_cnt != 0) { + debug("%s: Received %d byte Packet @ 0x%x (cmd_sts= %08x)\n", + __FUNCTION__, (u32) p_rxdesc_curr->byte_cnt, + (u32) p_rxdesc_curr->buf_ptr, + (u32) p_rxdesc_curr->cmd_sts); + } + + /* + * In case received a packet without first/last bits on + * OR the error summary bit is on, + * the packets needs to be dropeed. + */ + if (((p_rxdesc_curr->cmd_sts & + (KWGBE_RX_FIRST_DESC | KWGBE_RX_LAST_DESC)) + != (KWGBE_RX_FIRST_DESC | KWGBE_RX_LAST_DESC)) + || (p_rxdesc_curr->cmd_sts & KWGBE_ERROR_SUMMARY)) { + + printf("Received packet spread on"); + printf(" multiple descriptors or RxErr\n"); + + } else { + /* !!! call higher layer processing */ + debug("Now send it to upper layer "); + debug("protocol (NetReceive) ...\n"); + + /* let the upper layer handle the packet */ + NetReceive((p_rxdesc_curr->buf_ptr + RX_BUF_OFFSET), + (int)(p_rxdesc_curr->byte_cnt + - RX_BUF_OFFSET)); + } + /* + * free these descriptors and point next in the ring + */ + p_rxdesc_curr->cmd_sts = + KWGBE_BUFFER_OWNED_BY_DMA | KWGBE_RX_EN_INTERRUPT; + p_rxdesc_curr->buf_size = PKTSIZE_ALIGN; + p_rxdesc_curr->byte_cnt = 0x0000; + + dkwgbe->p_rxdesc_curr = p_rxdesc_curr->nxtdesc_p; + debug("Next rx_desc ptr = %08x, %08x\n", + (u32) p_rxdesc_curr, (u32) p_rxdesc_curr->nxtdesc_p); + + return 0; +} + +int kirkwood_egiga_initialize(bd_t *bis) +{ + struct kwgbe_device *dkwgbe; + struct eth_device *dev; + int devnum; + char *s, buf[64]; + u8 used_ports[MAX_KWGBE_DEVS] = CONFIG_KIRKWOOD_EGIGA_PORTS; + + for (devnum = 0; devnum < MAX_KWGBE_DEVS; devnum++) { + /*skip if port is configured not to use */ + if (used_ports[devnum] == 0) + continue; + + if (!(dkwgbe = malloc(sizeof(struct kwgbe_device)))) + goto error1; + + memset(dkwgbe, 0, sizeof(struct kwgbe_device)); + + if (!(dkwgbe->p_rxdesc = + (struct kwgbe_rxdesc *)memalign(PKTALIGN, + KW_RXQ_DESC_ALIGNED_SIZE * RINGSZ + 1))) + goto error2; + + if (!(dkwgbe->p_rxbuf = (u8 *)memalign(PKTALIGN, RINGSZ + * PKTSIZE_ALIGN + 1))) + goto error3; + + if (!(dkwgbe->p_txdesc = (struct kwgbe_txdesc *) + memalign(PKTALIGN, + sizeof(struct kwgbe_txdesc) + 1))) { + free(dkwgbe->p_rxbuf); +error3: + free(dkwgbe->p_rxdesc); +error2: + free(dkwgbe); +error1: + printf("Err.. %s Failed to allocate memory\n", + __FUNCTION__); + return -1; + } + + dev = &dkwgbe->dev; + + /* must be less than NAMESIZE (16) */ + sprintf(dev->name, "egiga%d", devnum); + debug("Initializing %s", dev->name); + + /* Extract the MAC address from the environment */ + switch (devnum) { + case 0: + dkwgbe->regs = (void *)KW_EGIGA0_BASE; + s = "ethaddr"; + break; + case 1: + dkwgbe->regs = (void *)KW_EGIGA1_BASE; + s = "eth1addr"; + break; + default: /* this should never happen */ + printf("%s: Invalid device number %d\n", + __FUNCTION__, devnum); + return -1; + } + + while (!eth_getenv_enetaddr(s, dev->enetaddr)) { + /* Generate Ramdom MAC addresses if not set */ + sprintf(buf, "00:50:43:%02x:%02x:%02x", + get_random_hex(), get_random_hex(), + get_random_hex()); + setenv(s, buf); + } + + dev->init = (void *)kwgbe_init; + dev->halt = (void *)kwgbe_halt; + dev->send = (void *)kwgbe_send; + dev->recv = (void *)kwgbe_recv; + + eth_register(dev); + +#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) + miiphy_register(dev->name, smi_reg_read, smi_reg_write); + /* Set phy address of the port */ + miiphy_write(dev->name, 0xEE, 0xEE, PHY_BASE_ADR + devnum); +#endif + } + return 0; +} diff --git a/drivers/net/kirkwood_egiga.h b/drivers/net/kirkwood_egiga.h new file mode 100644 index 0000000..d2f02a8 --- /dev/null +++ b/drivers/net/kirkwood_egiga.h @@ -0,0 +1,561 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Written-by: Prafulla Wadaskar prafulla@marvell.com + * + * based on - Driver for MV64360X ethernet ports + * Copyright (C) 2002 rabeeh@galileo.co.il + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef __EGIGA_H__ +#define __EGIGA_H__ + +#define MAX_KWGBE_DEVS 2 /*controller has two ports */ + +/* In case SRAM is cache coherent or non-cacheable */ +#ifndef CONFIG_SYS_COHERENT_CACHE +#define D_CACHE_FLUSH_LINE(addr, offset) ; +#define CPU_PIPE_FLUSH { __asm__ __volatile__ ("nop;nop;nop;nop;nop;nop");} +#else +#error "Cache coherent macros to be defined.." +#endif + +/* PHY_BASE_ADR is board specific and can be configured */ +#if defined (CONFIG_PHY_BASE_ADR) +#define PHY_BASE_ADR CONFIG_PHY_BASE_ADR +#else +#define PHY_BASE_ADR 0x08 /* default phy base addr */ +#endif + +/* Constants */ +#define INT_CAUSE_UNMASK_ALL 0x0007ffff +#define INT_CAUSE_UNMASK_ALL_EXT 0x0011ffff +#define RXUQ 0 /* Used Rx queue */ +#define TXUQ 0 /* Used Rx queue */ + +#define to_dkwgbe(_kd) container_of(_kd, struct kwgbe_device, dev) +#define KWGBEREG_WR(adr, val) writel(val, &adr) +#define KWGBEREG_RD(adr) readl(&adr) +#define KWGBEREG_BITS_RESET(adr, val) writel(readl(&adr) & ~(val), &adr) +#define KWGBEREG_BITS_SET(adr, val) writel(readl(&adr) | val, &adr) + +/* Default port configuration value */ +#define PRT_CFG_VAL ( \ + KWGBE_UCAST_MOD_NRML | \ + KWGBE_DFLT_RX_Q0 | \ + KWGBE_DFLT_RX_ARPQ0 | \ + KWGBE_RX_BC_IF_NOT_IP_OR_ARP | \ + KWGBE_RX_BC_IF_IP | \ + KWGBE_RX_BC_IF_ARP | \ + KWGBE_CPTR_TCP_FRMS_DIS | \ + KWGBE_CPTR_UDP_FRMS_DIS | \ + KWGBE_DFLT_RX_TCPQ0 | \ + KWGBE_DFLT_RX_UDPQ0 | \ + KWGBE_DFLT_RX_BPDU_Q_0) + +/* Default port extend configuration value */ +#define PORT_CFG_EXTEND_VALUE \ + KWGBE_SPAN_BPDU_PACKETS_AS_NORMAL | \ + KWGBE_PARTITION_DIS | \ + KWGBE_TX_CRC_GENERATION_EN + +/* Default sdma control value */ +#ifndef CONFIG_SYS_COHERENT_CACHE +#define PORT_SDMA_CFG_VALUE ( \ + KWGBE_RX_BURST_SIZE_16_64BIT | \ + KWGBE_BLM_RX_NO_SWAP | \ + KWGBE_BLM_TX_NO_SWAP | \ + GT_KWGBE_IPG_INT_RX(0) | \ + KWGBE_TX_BURST_SIZE_16_64BIT) +#else +#define PORT_SDMA_CFG_VALUE ( \ + KWGBE_RX_BURST_SIZE_4_64BIT | \ + GT_KWGBE_IPG_INT_RX(0) | \ + KWGBE_TX_BURST_SIZE_4_64BIT) +#endif + +#define GT_KWGBE_IPG_INT_RX(value) ((value & 0x3fff) << 8) + +/* Default port serial control value */ +#define PORT_SERIAL_CONTROL_VALUE_TMP ( \ + KWGBE_FORCE_LINK_PASS | \ + KWGBE_DIS_AUTO_NEG_FOR_DUPLX | \ + KWGBE_DIS_AUTO_NEG_FOR_FLOW_CTRL | \ + KWGBE_ADV_NO_FLOW_CTRL | \ + KWGBE_FORCE_FC_MODE_NO_PAUSE_DIS_TX | \ + KWGBE_FORCE_BP_MODE_NO_JAM | \ + (1 << 9) | \ + KWGBE_DO_NOT_FORCE_LINK_FAIL | \ + KWGBE_DIS_AUTO_NEG_SPEED_GMII | \ + KWGBE_DTE_ADV_0 | \ + KWGBE_MIIPHY_MAC_MODE | \ + KWGBE_AUTO_NEG_NO_CHANGE | \ + KWGBE_MAX_RX_PACKET_1552BYTE | \ + KWGBE_CLR_EXT_LOOPBACK | \ + KWGBE_SET_FULL_DUPLEX_MODE | \ + KWGBE_DIS_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX | \ + KWGBE_SET_MII_SPEED_TO_100) + +/* Speed will be configured to 10_100MBPS for MII mode of operation */ +#ifdef CONFIG_SYS_MII_MODE +#define PORT_SERIAL_CONTROL_VALUE ( \ + PORT_SERIAL_CONTROL_VALUE_TMP | \ + KWGBE_SET_GMII_SPEED_TO_10_100) +#else +#define PORT_SERIAL_CONTROL_VALUE ( \ + PORT_SERIAL_CONTROL_VALUE_TMP | \ + KWGBE_SET_GMII_SPEED_TO_1000) +#endif + +/* Tx WRR confoguration macros */ +#define PORT_MAX_TRAN_UNIT 0x24 /* MTU register (default) 9KByte */ +#define PORT_MAX_TOKEN_BUCKET_SIZE 0x_fFFF /* PMTBS reg (default) */ +#define PORT_TOKEN_RATE 1023 /* PTTBRC reg (default) */ +/* MAC accepet/reject macros */ +#define ACCEPT_MAC_ADDR 0 +#define REJECT_MAC_ADDR 1 +/* Size of a Tx/Rx descriptor used in chain list data structure */ +#define KW_RXQ_DESC_ALIGNED_SIZE \ + (((sizeof(struct kwgbe_rxdesc) / PKTALIGN) + 1) * PKTALIGN) +/* Buffer offset from buffer pointer */ +#define RX_BUF_OFFSET 0x2 + +/* Port serial status reg (PSR) */ +#define KWGBE_INTERFACE_GMII_MII 0 +#define KWGBE_INTERFACE_PCM 1 +#define KWGBE_LINK_IS_DOWN 0 +#define KWGBE_LINK_IS_UP (1 << 1) +#define KWGBE_PORT_AT_HALF_DUPLEX 0 +#define KWGBE_PORT_AT_FULL_DUPLEX (1 << 2) +#define KWGBE_RX_FLOW_CTRL_DISD 0 +#define KWGBE_RX_FLOW_CTRL_ENBALED (1 << 3) +#define KWGBE_GMII_SPEED_100_10 0 +#define KWGBE_GMII_SPEED_1000 (1 << 4) +#define KWGBE_MII_SPEED_10 0 +#define KWGBE_MII_SPEED_100 (1 << 5) +#define KWGBE_NO_TX 0 +#define KWGBE_TX_IN_PROGRESS (1 << 7) +#define KWGBE_BYPASS_NO_ACTIVE 0 +#define KWGBE_BYPASS_ACTIVE (1 << 8) +#define KWGBE_PORT_NOT_AT_PARTN_STT 0 +#define KWGBE_PORT_AT_PARTN_STT (1 << 9) +#define KWGBE_PORT_TX_FIFO_NOT_EMPTY 0 +#define KWGBE_PORT_TX_FIFO_EMPTY (1 << 10) + +/* These macros describes the Port configuration reg (Px_cR) bits */ +#define KWGBE_UCAST_MOD_NRML 0 +#define KWGBE_UNICAST_PROMISCUOUS_MODE 1 +#define KWGBE_DFLT_RX_Q0 0 +#define KWGBE_DFLT_RX_Q1 (1 << 1) +#define KWGBE_DFLT_RX_Q2 (1 << 2) +#define KWGBE_DFLT_RX_Q3 ((1 << 2) | (1 << 1)) +#define KWGBE_DFLT_RX_Q4 (1 << 3) +#define KWGBE_DFLT_RX_Q5 ((1 << 3) | (1 << 1)) +#define KWGBE_DFLT_RX_Q6 ((1 << 3) | (1 << 2)) +#define KWGBE_DFLT_RX_Q7 ((1 << 3) | (1 << 2) | (1 << 1)) +#define KWGBE_DFLT_RX_ARPQ0 0 +#define KWGBE_DFLT_RX_ARPQ1 (1 << 4) +#define KWGBE_DFLT_RX_ARPQ2 (1 << 5) +#define KWGBE_DFLT_RX_ARPQ3 ((1 << 5) | (1 << 4)) +#define KWGBE_DFLT_RX_ARPQ4 (1 << 6) +#define KWGBE_DFLT_RX_ARPQ5 ((1 << 6) | (1 << 4)) +#define KWGBE_DFLT_RX_ARPQ6 ((1 << 6) | (1 << 5)) +#define KWGBE_DFLT_RX_ARPQ7 ((1 << 6) | (1 << 5) | (1 << 4)) +#define KWGBE_RX_BC_IF_NOT_IP_OR_ARP 0 +#define KWGBE_REJECT_BC_IF_NOT_IP_OR_ARP (1 << 7) +#define KWGBE_RX_BC_IF_IP 0 +#define KWGBE_REJECT_BC_IF_IP (1 << 8) +#define KWGBE_RX_BC_IF_ARP 0 +#define KWGBE_REJECT_BC_IF_ARP (1 << 9) +#define KWGBE_TX_AM_NO_UPDATE_ERR_SMRY (1 << 12) +#define KWGBE_CPTR_TCP_FRMS_DIS 0 +#define KWGBE_CPTR_TCP_FRMS_EN (1 << 14) +#define KWGBE_CPTR_UDP_FRMS_DIS 0 +#define KWGBE_CPTR_UDP_FRMS_EN (1 << 15) +#define KWGBE_DFLT_RX_TCPQ0 0 +#define KWGBE_DFLT_RX_TCPQ1 (1 << 16) +#define KWGBE_DFLT_RX_TCPQ2 (1 << 17) +#define KWGBE_DFLT_RX_TCPQ3 ((1 << 17) | (1 << 16)) +#define KWGBE_DFLT_RX_TCPQ4 (1 << 18) +#define KWGBE_DFLT_RX_TCPQ5 ((1 << 18) | (1 << 16)) +#define KWGBE_DFLT_RX_TCPQ6 ((1 << 18) | (1 << 17)) +#define KWGBE_DFLT_RX_TCPQ7 ((1 << 18) | (1 << 17) | (1 << 16)) +#define KWGBE_DFLT_RX_UDPQ0 0 +#define KWGBE_DFLT_RX_UDPQ1 (1 << 19) +#define KWGBE_DFLT_RX_UDPQ2 (1 << 20) +#define KWGBE_DFLT_RX_UDPQ3 ((1 << 20) | (1 << 19)) +#define KWGBE_DFLT_RX_UDPQ4 (1 << 21) +#define KWGBE_DFLT_RX_UDPQ5 ((1 << 21) | (1 << 19)) +#define KWGBE_DFLT_RX_UDPQ6 ((1 << 21) | (1 << 20)) +#define KWGBE_DFLT_RX_UDPQ7 ((1 << 21) | (1 << 20) | (1 << 19)) +#define KWGBE_DFLT_RX_BPDU_Q_0 0 +#define KWGBE_DFLT_RX_BPDU_Q_1 (1 << 22) +#define KWGBE_DFLT_RX_BPDU_Q_2 (1 << 23) +#define KWGBE_DFLT_RX_BPDU_Q_3 ((1 << 23) | (1 << 22)) +#define KWGBE_DFLT_RX_BPDU_Q_4 (1 << 24) +#define KWGBE_DFLT_RX_BPDU_Q_5 ((1 << 24) | (1 << 22)) +#define KWGBE_DFLT_RX_BPDU_Q_6 ((1 << 24) | (1 << 23)) +#define KWGBE_DFLT_RX_BPDU_Q_7 ((1 << 24) | (1 << 23) | (1 << 22)) +#define KWGBE_DFLT_RX_TCP_CHKSUM_MODE (1 << 25) + +/* These macros describes the Port configuration extend reg (Px_cXR) bits*/ +#define KWGBE_CLASSIFY_EN 1 +#define KWGBE_SPAN_BPDU_PACKETS_AS_NORMAL 0 +#define KWGBE_SPAN_BPDU_PACKETS_TO_RX_Q7 (1 << 1) +#define KWGBE_PARTITION_DIS 0 +#define KWGBE_PARTITION_EN (1 << 2) +#define KWGBE_TX_CRC_GENERATION_EN 0 +#define KWGBE_TX_CRC_GENERATION_DIS (1 << 3) + +/* These macros describes the Port Sdma configuration reg (SDCR) bits */ +#define KWGBE_RIFB 1 +#define KWGBE_RX_BURST_SIZE_1_64BIT 0 +#define KWGBE_RX_BURST_SIZE_2_64BIT (1 << 1) +#define KWGBE_RX_BURST_SIZE_4_64BIT (1 << 2) +#define KWGBE_RX_BURST_SIZE_8_64BIT ((1 << 2) | (1 << 1)) +#define KWGBE_RX_BURST_SIZE_16_64BIT (1 << 3) +#define KWGBE_BLM_RX_NO_SWAP (1 << 4) +#define KWGBE_BLM_RX_BYTE_SWAP 0 +#define KWGBE_BLM_TX_NO_SWAP (1 << 5) +#define KWGBE_BLM_TX_BYTE_SWAP 0 +#define KWGBE_DESCRIPTORS_BYTE_SWAP (1 << 6) +#define KWGBE_DESCRIPTORS_NO_SWAP 0 +#define KWGBE_TX_BURST_SIZE_1_64BIT 0 +#define KWGBE_TX_BURST_SIZE_2_64BIT (1 << 22) +#define KWGBE_TX_BURST_SIZE_4_64BIT (1 << 23) +#define KWGBE_TX_BURST_SIZE_8_64BIT ((1 << 23) | (1 << 22)) +#define KWGBE_TX_BURST_SIZE_16_64BIT (1 << 24) + +/* These macros describes the Port serial control reg (PSCR) bits */ +#define KWGBE_SERIAL_PORT_DIS 0 +#define KWGBE_SERIAL_PORT_EN 1 +#define KWGBE_FORCE_LINK_PASS (1 << 1) +#define KWGBE_DO_NOT_FORCE_LINK_PASS 0 +#define KWGBE_EN_AUTO_NEG_FOR_DUPLX 0 +#define KWGBE_DIS_AUTO_NEG_FOR_DUPLX (1 << 2) +#define KWGBE_EN_AUTO_NEG_FOR_FLOW_CTRL 0 +#define KWGBE_DIS_AUTO_NEG_FOR_FLOW_CTRL (1 << 3) +#define KWGBE_ADV_NO_FLOW_CTRL 0 +#define KWGBE_ADV_SYMMETRIC_FLOW_CTRL (1 << 4) +#define KWGBE_FORCE_FC_MODE_NO_PAUSE_DIS_TX 0 +#define KWGBE_FORCE_FC_MODE_TX_PAUSE_DIS (1 << 5) +#define KWGBE_FORCE_BP_MODE_NO_JAM 0 +#define KWGBE_FORCE_BP_MODE_JAM_TX (1 << 7) +#define KWGBE_FORCE_BP_MODE_JAM_TX_ON_RX_ERR (1 << 8) +#define KWGBE_FORCE_LINK_FAIL 0 +#define KWGBE_DO_NOT_FORCE_LINK_FAIL (1 << 10) +#define KWGBE_DIS_AUTO_NEG_SPEED_GMII (1 << 13) +#define KWGBE_EN_AUTO_NEG_SPEED_GMII 0 +#define KWGBE_DTE_ADV_0 0 +#define KWGBE_DTE_ADV_1 (1 << 14) +#define KWGBE_MIIPHY_MAC_MODE 0 +#define KWGBE_MIIPHY_PHY_MODE (1 << 15) +#define KWGBE_AUTO_NEG_NO_CHANGE 0 +#define KWGBE_RESTART_AUTO_NEG (1 << 16) +#define KWGBE_MAX_RX_PACKET_1518BYTE 0 +#define KWGBE_MAX_RX_PACKET_1522BYTE (1 << 17) +#define KWGBE_MAX_RX_PACKET_1552BYTE (1 << 18) +#define KWGBE_MAX_RX_PACKET_9022BYTE ((1 << 18) | (1 << 17)) +#define KWGBE_MAX_RX_PACKET_9192BYTE (1 << 19) +#define KWGBE_MAX_RX_PACKET_9700BYTE ((1 << 19) | (1 << 17)) +#define KWGBE_SET_EXT_LOOPBACK (1 << 20) +#define KWGBE_CLR_EXT_LOOPBACK 0 +#define KWGBE_SET_FULL_DUPLEX_MODE (1 << 21) +#define KWGBE_SET_HALF_DUPLEX_MODE 0 +#define KWGBE_EN_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX (1 << 22) +#define KWGBE_DIS_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX 0 +#define KWGBE_SET_GMII_SPEED_TO_10_100 0 +#define KWGBE_SET_GMII_SPEED_TO_1000 (1 << 23) +#define KWGBE_SET_MII_SPEED_TO_10 0 +#define KWGBE_SET_MII_SPEED_TO_100 (1 << 24) + +/* SMI register fields (KWGBE_SMI_REG) */ +#define KWGBE_PHY_SMI_TIMEOUT 10000 +#define KWGBE_PHY_SMI_DATA_OFFS 0 /* Data */ +#define KWGBE_PHY_SMI_DATA_MASK (0xffff << KWGBE_PHY_SMI_DATA_OFFS) +#define KWGBE_PHY_SMI_DEV_ADDR_OFFS 16 /* PHY device address */ +#define KWGBE_PHY_SMI_DEV_ADDR_MASK (0x1f << KWGBE_PHY_SMI_DEV_ADDR_OFFS) +#define KWGBE_SMI_REG_ADDR_OFFS 21 /* PHY device reg addr */ +#define KWGBE_SMI_REG_ADDR_MASK (0x1f << KWGBE_SMI_REG_ADDR_OFFS) +#define KWGBE_PHY_SMI_OPCODE_OFFS 26 /* Write/Read opcode */ +#define KWGBE_PHY_SMI_OPCODE_MASK (3 << KWGBE_PHY_SMI_OPCODE_OFFS) +#define KWGBE_PHY_SMI_OPCODE_WRITE (0 << KWGBE_PHY_SMI_OPCODE_OFFS) +#define KWGBE_PHY_SMI_OPCODE_READ (1 << KWGBE_PHY_SMI_OPCODE_OFFS) +#define KWGBE_PHY_SMI_READ_VALID_MASK (1 << 27) /* Read Valid */ +#define KWGBE_PHY_SMI_BUSY_MASK (1 << 28) /* Busy */ + +/* SDMA command status fields macros */ +/* Tx & Rx descriptors status */ +#define KWGBE_ERROR_SUMMARY 1 + +/* Tx & Rx descriptors command */ +#define KWGBE_BUFFER_OWNED_BY_DMA (1 << 31) + +/* Tx descriptors status */ +#define KWGBE_LC_ERROR 0 +#define KWGBE_UR_ERROR (1 << 1) +#define KWGBE_RL_ERROR (1 << 2) +#define KWGBE_LLC_SNAP_FORMAT (1 << 9) + +/* Rx descriptors status */ +#define KWGBE_CRC_ERROR 0 +#define KWGBE_OVERRUN_ERROR (1 << 1) +#define KWGBE_MAX_FRAME_LENGTH_ERROR (1 << 2) +#define KWGBE_RESOURCE_ERROR ((1 << 2) | (1 << 1)) +#define KWGBE_VLAN_TAGGED (1 << 19) +#define KWGBE_BPDU_FRAME (1 << 20) +#define KWGBE_TCP_FRAME_OVER_IP_V_4 0 +#define KWGBE_UDP_FRAME_OVER_IP_V_4 (1 << 21) +#define KWGBE_OTHER_FRAME_TYPE (1 << 22) +#define KWGBE_LAYER_2_IS_KWGBE_V_2 (1 << 23) +#define KWGBE_FRAME_TYPE_IP_V_4 (1 << 24) +#define KWGBE_FRAME_HEADER_OK (1 << 25) +#define KWGBE_RX_LAST_DESC (1 << 26) +#define KWGBE_RX_FIRST_DESC (1 << 27) +#define KWGBE_UNKNOWN_DESTINATION_ADDR (1 << 28) +#define KWGBE_RX_EN_INTERRUPT (1 << 29) +#define KWGBE_LAYER_4_CHECKSUM_OK (1 << 30) + +/* Rx descriptors byte count */ +#define KWGBE_FRAME_FRAGMENTED (1 << 2) + +/* Tx descriptors command */ +#define KWGBE_LAYER_4_CHECKSUM_FIRST_DESC (1 << 10) +#define KWGBE_FRAME_SET_TO_VLAN (1 << 15) +#define KWGBE_TCP_FRAME 0 +#define KWGBE_UDP_FRAME (1 << 16) +#define KWGBE_GEN_TCP_UDP_CHECKSUM (1 << 17) +#define KWGBE_GEN_IP_V_4_CHECKSUM (1 << 18) +#define KWGBE_ZERO_PADDING (1 << 19) +#define KWGBE_TX_LAST_DESC (1 << 20) +#define KWGBE_TX_FIRST_DESC (1 << 21) +#define KWGBE_GEN_CRC (1 << 22) +#define KWGBE_TX_EN_INTERRUPT (1 << 23) +#define KWGBE_AUTO_MODE (1 << 30) + +/* Address decode parameters */ +/* Ethernet Base Address Register bits */ +#define EBAR_TARGET_DRAM 0x00000000 +#define EBAR_TARGET_DEVICE 0x00000001 +#define EBAR_TARGET_CBS 0x00000002 +#define EBAR_TARGET_PCI0 0x00000003 +#define EBAR_TARGET_PCI1 0x00000004 +#define EBAR_TARGET_CUNIT 0x00000005 +#define EBAR_TARGET_AUNIT 0x00000006 +#define EBAR_TARGET_GUNIT 0x00000007 + +/* Window attrib */ +#define EBAR_DRAM_CS0 0x00000E00 +#define EBAR_DRAM_CS1 0x00000D00 +#define EBAR_DRAM_CS2 0x00000B00 +#define EBAR_DRAM_CS3 0x00000700 + +/* DRAM Target interface */ +#define EBAR_DRAM_NO_CACHE_COHERENCY 0x00000000 +#define EBAR_DRAM_CACHE_COHERENCY_WT 0x00001000 +#define EBAR_DRAM_CACHE_COHERENCY_WB 0x00002000 + +/* Device Bus Target interface */ +#define EBAR_DEVICE_DEVCS0 0x00001E00 +#define EBAR_DEVICE_DEVCS1 0x00001D00 +#define EBAR_DEVICE_DEVCS2 0x00001B00 +#define EBAR_DEVICE_DEVCS3 0x00001700 +#define EBAR_DEVICE_BOOTCS3 0x00000F00 + +/* PCI Target interface */ +#define EBAR_PCI_BYTE_SWAP 0x00000000 +#define EBAR_PCI_NO_SWAP 0x00000100 +#define EBAR_PCI_BYTE_WORD_SWAP 0x00000200 +#define EBAR_PCI_WORD_SWAP 0x00000300 +#define EBAR_PCI_NO_SNOOP_NOT_ASSERT 0x00000000 +#define EBAR_PCI_NO_SNOOP_ASSERT 0x00000400 +#define EBAR_PCI_IO_SPACE 0x00000000 +#define EBAR_PCI_MEMORY_SPACE 0x00000800 +#define EBAR_PCI_REQ64_FORCE 0x00000000 +#define EBAR_PCI_REQ64_SIZE 0x00001000 + +/* Window access control */ +#define EWIN_ACCESS_NOT_ALLOWED 0 +#define EWIN_ACCESS_READ_ONLY 1 +#define EWIN_ACCESS_FULL ((1 << 1) | 1) + +/* structures represents Controller registers */ +struct kwgbe_barsz { + u32 bar; + u32 size; +}; + +struct kwgbe_rxcdp { + struct kwgbe_rxdesc *rxcdp; + u32 rxcdp_pad[3]; +}; + +struct kwgbe_tqx { + u32 qxttbc; + u32 tqxtbc; + u32 tqxac; + u32 tqxpad; +}; + +struct kwgbe_registers { + u32 phyadr; + u32 smi; + u32 euda; + u32 eudid; + u8 pad1[0x080 - 0x00c - 4]; + u32 euic; + u32 euim; + u8 pad2[0x094 - 0x084 - 4]; + u32 euea; + u32 euiae; + u8 pad3[0x0b0 - 0x098 - 4]; + u32 euc; + u8 pad3a[0x200 - 0x0b0 - 4]; + struct kwgbe_barsz barsz[6]; + u8 pad4[0x280 - 0x22c - 4]; + u32 ha_remap[4]; + u32 bare; + u32 epap; + u8 pad5[0x400 - 0x294 - 4]; + u32 pxc; + u32 pxcx; + u32 mii_ser_params; + u8 pad6[0x410 - 0x408 - 4]; + u32 evlane; + u32 macal; + u32 macah; + u32 sdc; + u32 dscp[7]; + u32 psc0; + u32 vpt2p; + u32 ps0; + u32 tqc; + u32 psc1; + u32 ps1; + u32 mrvl_header; + u8 pad7[0x460 - 0x454 - 4]; + u32 ic; + u32 ice; + u32 pim; + u32 peim; + u8 pad8[0x474 - 0x46c - 4]; + u32 pxtfut; + u32 pad9; + u32 pxmfs; + u32 pad10; + u32 pxdfc; + u32 pxofc; + u8 pad11[0x494 - 0x488 - 4]; + u32 peuiae; + u8 pad12[0x4bc - 0x494 - 4]; + u32 eth_type_prio; + u8 pad13[0x4dc - 0x4bc - 4]; + u32 tqfpc; + u32 pttbrc; + u32 tqc1; + u32 pmtu; + u32 pmtbs; + u8 pad14[0x60c - 0x4ec - 4]; + struct kwgbe_rxcdp rxcdp[7]; + u32 rxcdp7; + u32 rqc; + struct kwgbe_txdesc *tcsdp; + u8 pad15[0x6c0 - 0x684 - 4]; + struct kwgbe_txdesc *tcqdp[8]; + u8 pad16[0x700 - 0x6dc - 4]; + struct kwgbe_tqx tqx[8]; + u32 pttbc; + u8 pad17[0x7a8 - 0x780 - 4]; + u32 tqxipg0; + u32 pad18[3]; + u32 tqxipg1; + u8 pad19[0x7c0 - 0x7b8 - 4]; + u32 hitkninlopkt; + u32 hitkninasyncpkt; + u32 lotkninasyncpkt; + u32 pad20; + u32 ts; + u8 pad21[0x3000 - 0x27d0 - 4]; + u32 pad20_1[32]; /* mib counter registes */ + u8 pad22[0x3400 - 0x3000 - sizeof(u32) * 32]; + u32 dfsmt[64]; + u32 dfomt[64]; + u32 dfut[4]; + u8 pad23[0xe20c0 - 0x7360c - 4]; + u32 pmbus_top_arbiter; +}; + +/* structures/enums needed by driver */ +enum kwgbe_adrwin { + KWGBE_WIN0, + KWGBE_WIN1, + KWGBE_WIN2, + KWGBE_WIN3, + KWGBE_WIN4, + KWGBE_WIN5 +}; + +enum kwgbe_target { + KWGBE_TARGET_DRAM, + KWGBE_TARGET_DEV, + KWGBE_TARGET_CBS, + KWGBE_TARGET_PCI0, + KWGBE_TARGET_PCI1 +}; + +struct kwgbe_winparam { + enum kwgbe_adrwin win; /* Window number */ + enum kwgbe_target target; /* System targets */ + u16 attrib; /* BAR attrib. See above macros */ + u32 base_addr; /* Window base address in u32 form */ + u32 high_addr; /* Window high address in u32 form */ + u32 size; /* Size in MBytes. Must be % 64Kbyte. */ + int enable; /* Enable/disable access to the window. */ + u16 access_ctrl; /*Access ctrl register. see above macros */ +}; + +struct kwgbe_rxdesc { + u32 cmd_sts; /* Descriptor command status */ + u16 buf_size; /* Buffer size */ + u16 byte_cnt; /* Descriptor buffer byte count */ + u8 *buf_ptr; /* Descriptor buffer pointer */ + struct kwgbe_rxdesc *nxtdesc_p; /* Next descriptor pointer */ +}; + +struct kwgbe_txdesc { + u32 cmd_sts; /* Descriptor command status */ + u16 l4i_chk; /* CPU provided TCP Checksum */ + u16 byte_cnt; /* Descriptor buffer byte count */ + u8 *buf_ptr; /* Descriptor buffer ptr */ + struct kwgbe_txdesc *nxtdesc_p; /* Next descriptor ptr */ +}; + +/* port device data struct */ +struct kwgbe_device { + struct eth_device dev; + struct kwgbe_registers *regs; + struct kwgbe_txdesc *p_txdesc; + struct kwgbe_rxdesc *p_rxdesc; + struct kwgbe_rxdesc *p_rxdesc_curr; + u8 *p_rxbuf; +}; + +#endif /* __EGIGA_H__ */ diff --git a/include/netdev.h b/include/netdev.h index f37b6ae..3a59f4e 100644 --- a/include/netdev.h +++ b/include/netdev.h @@ -52,6 +52,7 @@ int fec_initialize (bd_t *bis); int greth_initialize(bd_t *bis); void gt6426x_eth_initialize(bd_t *bis); int inca_switch_initialize(bd_t *bis); +int kirkwood_egiga_initialize(bd_t *bis); int macb_eth_initialize(int id, void *regs, unsigned int phy_addr); int mcdmafec_initialize(bd_t *bis); int mcffec_initialize(bd_t *bis);

This is Marvell's 88F6281_A0 based custom board developed for wireless access point product
This patch is tested for- 1. Boot from DRAM/SPI flash/NFS 2. File transfer using tftp and loadb 3. SPI flash read/write/erase 4. Booting Linux kernel and RFS from SPI flash
Reviewed-by: Ronen Shitrit rshitrit@marvell.com Signed-off-by: Prafulla Wadaskar prafulla@marvell.com --- MAKEALL | 1 + Makefile | 3 + board/Marvell/mv88f6281gtw_ge/Makefile | 51 ++++++ board/Marvell/mv88f6281gtw_ge/config.mk | 25 +++ board/Marvell/mv88f6281gtw_ge/mv88f6281gtw_ge.c | 141 +++++++++++++++++ board/Marvell/mv88f6281gtw_ge/mv88f6281gtw_ge.h | 36 +++++ include/configs/mv88f6281gtw_ge.h | 188 +++++++++++++++++++++++ 7 files changed, 445 insertions(+), 0 deletions(-) create mode 100644 board/Marvell/mv88f6281gtw_ge/Makefile create mode 100644 board/Marvell/mv88f6281gtw_ge/config.mk create mode 100644 board/Marvell/mv88f6281gtw_ge/mv88f6281gtw_ge.c create mode 100644 board/Marvell/mv88f6281gtw_ge/mv88f6281gtw_ge.h create mode 100644 include/configs/mv88f6281gtw_ge.h
diff --git a/MAKEALL b/MAKEALL index c98d03a..6719d7b 100755 --- a/MAKEALL +++ b/MAKEALL @@ -505,6 +505,7 @@ LIST_ARM9=" \ cp946es \ cp966 \ lpd7a400 \ + mv88f6281gtw_ge \ mx1ads \ mx1fs2 \ netstar \ diff --git a/Makefile b/Makefile index 81a5cd0..8144ecd 100644 --- a/Makefile +++ b/Makefile @@ -2808,6 +2808,9 @@ lpd7a400_config \ lpd7a404_config: unconfig @$(MKCONFIG) $(@:_config=) arm lh7a40x lpd7a40x
+mv88f6281gtw_ge_config: unconfig + @$(MKCONFIG) $(@:_config=) arm arm926ejs $(@:_config=) Marvell kirkwood + mx1ads_config : unconfig @$(MKCONFIG) $(@:_config=) arm arm920t mx1ads NULL imx
diff --git a/board/Marvell/mv88f6281gtw_ge/Makefile b/board/Marvell/mv88f6281gtw_ge/Makefile new file mode 100644 index 0000000..8c49a3e --- /dev/null +++ b/board/Marvell/mv88f6281gtw_ge/Makefile @@ -0,0 +1,51 @@ +# +# (C) Copyright 2009 +# Marvell Semiconductor <www.marvell.com> +# Written-by: Prafulla Wadaskar prafulla@marvell.com +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(BOARD).a + +COBJS := mv88f6281gtw_ge.o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) +SOBJS := $(addprefix $(obj),$(SOBJS)) + +$(LIB): $(obj).depend $(OBJS) $(SOBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS) + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak .depend + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/Marvell/mv88f6281gtw_ge/config.mk b/board/Marvell/mv88f6281gtw_ge/config.mk new file mode 100644 index 0000000..fb29a1b --- /dev/null +++ b/board/Marvell/mv88f6281gtw_ge/config.mk @@ -0,0 +1,25 @@ +# +# (C) Copyright 2009 +# Marvell Semiconductor <www.marvell.com> +# Written-by: Prafulla Wadaskar prafulla@marvell.com +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301 USA +# + +TEXT_BASE = 0x00600000 diff --git a/board/Marvell/mv88f6281gtw_ge/mv88f6281gtw_ge.c b/board/Marvell/mv88f6281gtw_ge/mv88f6281gtw_ge.c new file mode 100644 index 0000000..7ea61be --- /dev/null +++ b/board/Marvell/mv88f6281gtw_ge/mv88f6281gtw_ge.c @@ -0,0 +1,141 @@ +/* + * Maintainer : Prafulla Wadaskar prafulla@marvell.com + * + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Written-by: Prafulla Wadaskar prafulla@marvell.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include <common.h> +#include <netdev.h> +#include <asm/arch/kirkwood.h> +#include <asm/arch/mpp.h> +#include "mv88f6281gtw_ge.h" + +DECLARE_GLOBAL_DATA_PTR; + +int board_init(void) +{ + /* + * default gpio configuration + * There are maximum 64 gpios controlled through 2 sets of registers + * the below configuration configures mainly initial LED status + */ + kw_config_gpio(MV88F6281GTW_GE_OE_VAL_LOW, + MV88F6281GTW_GE_OE_VAL_HIGH, + MV88F6281GTW_GE_OE_LOW, MV88F6281GTW_GE_OE_HIGH); + + /* Multi-Purpose Pins Functionality configuration */ + u32 kwmpp_config[] = { + MPP0_SPI_SCn, + MPP1_SPI_MOSI, + MPP2_SPI_SCK, + MPP3_SPI_MISO, + MPP4_GPIO, + MPP5_GPO, + MPP6_SYSRST_OUTn, + MPP7_SPI_SCn, + MPP8_TW_SDA, + MPP9_TW_SCK, + MPP10_UART0_TXD, + MPP11_UART0_RXD, + MPP12_GPO, + MPP13_GPIO, + MPP14_GPIO, + MPP15_GPIO, + MPP16_GPIO, + MPP17_GPIO, + MPP18_GPO, + MPP19_GPO, + MPP20_GPIO, + MPP21_GPIO, + MPP22_GPIO, + MPP23_GPIO, + MPP24_GPIO, + MPP25_GPIO, + MPP26_GPIO, + MPP27_GPIO, + MPP28_GPIO, + MPP29_GPIO, + MPP30_GPIO, + MPP31_GPIO, + MPP32_GPIO, + MPP33_GPIO, + MPP34_GPIO, + MPP35_GPIO, + MPP36_GPIO, + MPP37_GPIO, + MPP38_GPIO, + MPP39_GPIO, + MPP40_GPIO, + MPP41_GPIO, + MPP42_GPIO, + MPP43_GPIO, + MPP44_GPIO, + MPP45_GPIO, + MPP46_GPIO, + MPP47_GPIO, + MPP48_GPIO, + MPP49_GPIO, + 0 + }; + kirkwood_mpp_conf(kwmpp_config); + + /* + * arch number of board + */ + gd->bd->bi_arch_number = MACH_TYPE_MV88F6281GTW_GE; + + /* adress of boot parameters */ + gd->bd->bi_boot_params = kw_sdram_bar(0) + 0x100; + + return 0; +} + +int dram_init(void) +{ + int i; + + for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { + gd->bd->bi_dram[i].start = kw_sdram_bar(i); + gd->bd->bi_dram[i].size = kw_sdram_bs(i); + } + return 0; +} + +#ifdef CONFIG_MV88E61XX_SWITCH +void reset_phy(void) +{ + /* configure and initialize switch */ + struct mv88e61xx_config swcfg = { + .name = "egiga0", + .vlancfg = MV88E61XX_VLANCFG_ROUTER, + .rgmii_delay = MV88E61XX_RGMII_DELAY_EN, + .led_init = MV88E61XX_LED_INIT_EN, + .mdip = MV88E61XX_MDIP_REVERSE, + .portstate = MV88E61XX_PORTSTT_FORWARDING, + .cpuport = (1 << 5), + .ports_enabled = 0x3f + }; + + mv88e61xx_switch_initialize(&swcfg); +} +#endif /* CONFIG_MV88E61XX_SWITCH */ diff --git a/board/Marvell/mv88f6281gtw_ge/mv88f6281gtw_ge.h b/board/Marvell/mv88f6281gtw_ge/mv88f6281gtw_ge.h new file mode 100644 index 0000000..fb0e571 --- /dev/null +++ b/board/Marvell/mv88f6281gtw_ge/mv88f6281gtw_ge.h @@ -0,0 +1,36 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Written-by: Prafulla Wadaskar prafulla@marvell.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef __MV88F6281GTW_GE_H +#define __MV88F6281GTW_GE_H + +#define MV88F6281GTW_GE_OE_LOW (~((1 << 7) | (1 << 12) \ + |(1 << 20) | (1 << 21))) /*enable GLED,RLED */ +#define MV88F6281GTW_GE_OE_HIGH (~((1 << 4)|(1 << 6)|(1 << 7)|(1 << 12) \ + |(1 << 13)|(1 << 16)|(1 << 17))) +#define MV88F6281GTW_GE_OE_VAL_LOW (1 << 20) /*make GLED on */ +#define MV88F6281GTW_GE_OE_VAL_HIGH ((1 << 6)|(1 << 13)|(1 << 16)|(1 << 17)) + + +#endif /* __MV88F6281GTW_GE_H */ diff --git a/include/configs/mv88f6281gtw_ge.h b/include/configs/mv88f6281gtw_ge.h new file mode 100644 index 0000000..8735b9e --- /dev/null +++ b/include/configs/mv88f6281gtw_ge.h @@ -0,0 +1,188 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Written-by: Prafulla Wadaskar prafulla@marvell.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef _CONFIG_MV88F6281GTW_GE_H +#define _CONFIG_MV88F6281GTW_GE_H + +/* + * Version number information + */ +#define CONFIG_IDENT_STRING "\nMarvell-MV88F6281GTW_GE-A0" + +/* + * High Level Configuration Options (easy to change) + */ +#define CONFIG_MARVELL 1 +#define CONFIG_ARM926EJS 1 /* Basic Architecture */ +#define CONFIG_FEROCEON_88FR131 1 /* CPU Core subversion */ +#define CONFIG_KIRKWOOD 1 /* SOC Family Name */ +#define CONFIG_KW88F6281 1 /* SOC Name */ +#define CONFIG_MACH_MV88F6281GTW_GE /* Machine type */ + +#define CONFIG_MD5 /* get_random_hex on krikwood needs MD5 support */ +#define CONFIG_SKIP_LOWLEVEL_INIT /* disable board lowlevel_init */ +#define CONFIG_KIRKWOOD_EGIGA_INIT /* Enable GbePort0/1 for kernel */ +#define CONFIG_KIRKWOOD_PCIE_INIT /* Enable PCIE Port0 for kernel */ +#define CONFIG_KIRKWOOD_RGMII_PAD_1V8 /* Set RGMII Pad voltage to 1.8V */ + +/* + * CLKs configurations + */ +#define CONFIG_SYS_HZ 1000 + +/* + * NS16550 Configuration + */ +#define CONFIG_SYS_NS16550 +#define CONFIG_SYS_NS16550_SERIAL +#define CONFIG_SYS_NS16550_REG_SIZE (-4) +#define CONFIG_SYS_NS16550_CLK CONFIG_SYS_TCLK +#define CONFIG_SYS_NS16550_COM1 KW_UART0_BASE + +/* + * Serial Port configuration + * The following definitions let you select what serial you want to use + * for your console driver. + */ + +#define CONFIG_CONS_INDEX 1 /*Console on UART0 */ +#define CONFIG_BAUDRATE 115200 /* console baudrate */ +#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, \ + 115200,230400, 460800, 921600 } +/* auto boot */ +#define CONFIG_BOOTDELAY 3 /* default enable autoboot */ + +/* + * For booting Linux, the board info and command line data + * have to be in the first 8 MB of memory, since this is + * the maximum mapped by the Linux kernel during initialization. + */ +#define CONFIG_BOOTMAPSZ (8 << 20) /* Initial Memmap for Linux */ +#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */ +#define CONFIG_INITRD_TAG 1 /* enable INITRD tag */ +#define CONFIG_SETUP_MEMORY_TAGS 1 /* enable memory tag */ + +#define CONFIG_SYS_PROMPT "Marvell>> " /* Command Prompt */ +#define CONFIG_SYS_CBSIZE 1024 /* Console I/O Buff Size */ +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE \ + +sizeof(CONFIG_SYS_PROMPT) + 16) /* Print Buff */ +/* + * Commands configuration + */ +#define CONFIG_CMD_ENV +#define CONFIG_CMD_RUN +#define CONFIG_CMD_LOADB +#define CONFIG_CMD_NET +#define CONFIG_CMD_AUTOSCRIPT +#define CONFIG_CMD_MEMORY +#define CONFIG_CMD_BOOTD +#define CONFIG_CMD_SAVEENV +#define CONFIG_CMD_SF + +/* + * Flash configuration + */ +#ifdef CONFIG_CMD_SF +#define CONFIG_SYS_NO_FLASH 1 /* Declare no NOR flash */ +#define CONFIG_SPI_FLASH 1 +#define CONFIG_HARD_SPI 1 +#define CONFIG_KIRKWOOD_SPI 1 +#define CONFIG_SPI_FLASH_MACRONIX 1 +#define CONFIG_ENV_SPI_BUS 0 +#define CONFIG_ENV_SPI_CS 0 +#define CONFIG_ENV_SPI_MAX_HZ 50000000 /*50Mhz */ +#endif + +/* + * Environment variables configurations + */ +#ifdef CONFIG_SPI_FLASH +#define CONFIG_ENV_IS_IN_SPI_FLASH 1 +#define CONFIG_ENV_SECT_SIZE 0x10000 /* 64K */ +#else +#define CONFIG_ENV_IS_NOWHERE 1 /* if env in SDRAM */ +#endif +#define CONFIG_ENV_SIZE 0x1000 /* 4k */ +#define CONFIG_ENV_ADDR 0x20000 +#define CONFIG_ENV_OFFSET 0x20000 /* env starts here */ + +/* + * Default environment variables + */ +#define CONFIG_BOOTCOMMAND "${x_bootcmd_kernel}; " \ + "setenv bootargs ${x_bootargs} ${x_bootargs_root}; " \ + "bootm 0x6400000;" + +#define CONFIG_MTDPARTS "spi0.0:512k(uboot)," \ + "512k@512k(psm), 2m@1m(kernel),13m@3m(rootfs)\0" + +#define CONFIG_EXTRA_ENV_SETTINGS "x_bootargs=console" \ + "=ttyS0,115200 mtdparts="CONFIG_MTDPARTS \ + "x_bootcmd_kernel=cp.b 0xf8100000 0x6400000 0x200000\0" \ + "x_bootargs_root=root=/dev/mtdblock3 ro rootfstype=squashfs\0" + +/* + * Size of malloc() pool + */ +#define CONFIG_SYS_MALLOC_LEN (1024 * 128) /* 128kB for malloc() */ +/* size in bytes reserved for initial data */ +#define CONFIG_SYS_GBL_DATA_SIZE 128 + +/* + * Other required minimal configurations + */ +#define CONFIG_CONSOLE_INFO_QUIET /* some code reduction */ +#define CONFIG_ARCH_CPU_INIT /* call arch_cpu_init() */ +#define CONFIG_ARCH_MISC_INIT /* call arch_misc_init() */ +#define CONFIG_DISPLAY_CPUINFO /* Display cpu info */ +#define CONFIG_NR_DRAM_BANKS 4 +#define CONFIG_STACKSIZE 0x00100000 /* regular stack- 1M */ +#define CONFIG_SYS_LOAD_ADDR 0x00800000 /* default load adr- 8M */ +#define CONFIG_SYS_MEMTEST_START 0x00400000 /* 4M */ +#define CONFIG_SYS_MEMTEST_END 0x007fffff /*(_8M -1) */ +#define CONFIG_SYS_RESET_ADDRESS 0xffff0000 /* Rst Vector Adr */ +#define CONFIG_SYS_MAXARGS 16 /* max number of command args */ + +/* + * Ethernet Driver configuration + */ +#ifdef CONFIG_CMD_NET +#define CONFIG_CMD_DHCP +#define CONFIG_CMD_PING +#define CONFIG_NETCONSOLE /* include NetConsole support */ +#define CONFIG_NET_MULTI /* specify more that one ports available */ +#define CONFIG_MII /* expose smi ove miiphy interface */ +#define CONFIG_KIRKWOOD_EGIGA /* Enable kirkwood Gbe Controller Driver */ +#define CONFIG_SYS_FAULT_ECHO_LINK_DOWN /* detect link using phy */ +#define CONFIG_KIRKWOOD_EGIGA_PORTS {1,0} /* enable port 0 only */ +#define CONFIG_ENV_OVERWRITE /* ethaddr can be reprogrammed */ +#endif /* CONFIG_CMD_NET */ + +/* + * Marvell 88Exxxx Switch configurations + */ +#define CONFIG_RESET_PHY_R /* use reset_phy() to init phy/swtich */ +#define CONFIG_MV88E61XX_SWITCH /* Enable mv88e61xx switch driver */ + +#endif /* _CONFIG_MV88F6281GTW_GE_H */

Reference: http://plugcomputer.org/ http://openplug.org/plugwiki/index.php/Das_U-boot_plug_support
This patch is tested for- 1. Boot from DRAM/NAND flash 2. File transfer using tftp 3. NAND flash read/write/erase 4. Linux kernel and RFS Boot from NAND
Signed-off-by: Prafulla Wadaskar prafulla@marvell.com --- MAKEALL | 1 + Makefile | 4 +- board/Marvell/sheevaplug/Makefile | 51 +++++++++ board/Marvell/sheevaplug/config.mk | 25 +++++ board/Marvell/sheevaplug/sheevaplug.c | 135 +++++++++++++++++++++++ board/Marvell/sheevaplug/sheevaplug.h | 37 +++++++ include/configs/sheevaplug.h | 192 +++++++++++++++++++++++++++++++++ 7 files changed, 444 insertions(+), 1 deletions(-) create mode 100644 board/Marvell/sheevaplug/Makefile create mode 100644 board/Marvell/sheevaplug/config.mk create mode 100644 board/Marvell/sheevaplug/sheevaplug.c create mode 100644 board/Marvell/sheevaplug/sheevaplug.h create mode 100644 include/configs/sheevaplug.h
diff --git a/MAKEALL b/MAKEALL index 6719d7b..e3d33cb 100755 --- a/MAKEALL +++ b/MAKEALL @@ -144,6 +144,7 @@ LIST_8xx=" \ RPXlite \ RPXlite_DW \ RRvision \ + sheevaplug \ SM850 \ spc1920 \ SPD823TS \ diff --git a/Makefile b/Makefile index 8144ecd..39b3367 100644 --- a/Makefile +++ b/Makefile @@ -1122,6 +1122,9 @@ RRvision_LCD_config: unconfig @echo "#define CONFIG_SHARP_LQ104V7DS01" >>$(obj)include/config.h @$(MKCONFIG) -a RRvision ppc mpc8xx RRvision
+sheevaplug_config: unconfig + @$(MKCONFIG) $(@:_config=) arm arm926ejs $(@:_config=) Marvell kirkwood + SM850_config : unconfig @$(MKCONFIG) $(@:_config=) ppc mpc8xx tqm8xx tqc
@@ -3110,7 +3113,6 @@ omap2420h4_config : unconfig qong_config : unconfig @$(MKCONFIG) $(@:_config=) arm arm1136 qong davedenx mx31
- ######################################################################### ## ARM1176 Systems ######################################################################### diff --git a/board/Marvell/sheevaplug/Makefile b/board/Marvell/sheevaplug/Makefile new file mode 100644 index 0000000..7b6f0da --- /dev/null +++ b/board/Marvell/sheevaplug/Makefile @@ -0,0 +1,51 @@ +# +# (C) Copyright 2009 +# Marvell Semiconductor <www.marvell.com> +# Written-by: Prafulla Wadaskar prafulla@marvell.com +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(BOARD).a + +COBJS := sheevaplug.o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) +SOBJS := $(addprefix $(obj),$(SOBJS)) + +$(LIB): $(obj).depend $(OBJS) $(SOBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS) + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak .depend + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/Marvell/sheevaplug/config.mk b/board/Marvell/sheevaplug/config.mk new file mode 100644 index 0000000..fb29a1b --- /dev/null +++ b/board/Marvell/sheevaplug/config.mk @@ -0,0 +1,25 @@ +# +# (C) Copyright 2009 +# Marvell Semiconductor <www.marvell.com> +# Written-by: Prafulla Wadaskar prafulla@marvell.com +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301 USA +# + +TEXT_BASE = 0x00600000 diff --git a/board/Marvell/sheevaplug/sheevaplug.c b/board/Marvell/sheevaplug/sheevaplug.c new file mode 100644 index 0000000..b861c24 --- /dev/null +++ b/board/Marvell/sheevaplug/sheevaplug.c @@ -0,0 +1,135 @@ +/* + * Maintainer : Prafulla Wadaskar prafulla@marvell.com + * + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Written-by: Prafulla Wadaskar prafulla@marvell.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include <common.h> +#include <netdev.h> +#include <asm/arch/kirkwood.h> +#include <asm/arch/mpp.h> +#include "sheevaplug.h" + +DECLARE_GLOBAL_DATA_PTR; + +int board_init(void) +{ + /* + * default gpio configuration + * There are maximum 64 gpios controlled through 2 sets of registers + * the below configuration configures mainly initial LED status + */ + kw_config_gpio(SHEEVAPLUG_OE_VAL_LOW, + SHEEVAPLUG_OE_VAL_HIGH, + SHEEVAPLUG_OE_LOW, SHEEVAPLUG_OE_HIGH); + + /* Multi-Purpose Pins Functionality configuration */ + u32 kwmpp_config[] = { + MPP0_NF_IO2, + MPP1_NF_IO3, + MPP2_NF_IO4, + MPP3_NF_IO5, + MPP4_NF_IO6, + MPP5_NF_IO7, + MPP6_SYSRST_OUTn, + MPP7_GPO, + MPP8_UART0_RTS, + MPP9_UART0_CTS, + MPP10_UART0_TXD, + MPP11_UART0_RXD, + MPP12_SD_CLK, + MPP13_SD_CMD, + MPP14_SD_D0, + MPP15_SD_D1, + MPP16_SD_D2, + MPP17_SD_D3, + MPP18_NF_IO0, + MPP19_NF_IO1, + MPP20_GPIO, + MPP21_GPIO, + MPP22_GPIO, + MPP23_GPIO, + MPP24_GPIO, + MPP25_GPIO, + MPP26_GPIO, + MPP27_GPIO, + MPP28_GPIO, + MPP29_TSMP9, + MPP30_GPIO, + MPP31_GPIO, + MPP32_GPIO, + MPP33_GPIO, + MPP34_GPIO, + MPP35_GPIO, + MPP36_GPIO, + MPP37_GPIO, + MPP38_GPIO, + MPP39_GPIO, + MPP40_GPIO, + MPP41_GPIO, + MPP42_GPIO, + MPP43_GPIO, + MPP44_GPIO, + MPP45_GPIO, + MPP46_GPIO, + MPP47_GPIO, + MPP48_GPIO, + MPP49_GPIO, + 0 + }; + kirkwood_mpp_conf(kwmpp_config); + + /* + * arch number of board + */ + gd->bd->bi_arch_number = MACH_TYPE_SHEEVAPLUG; + + /* adress of boot parameters */ + gd->bd->bi_boot_params = kw_sdram_bar(0) + 0x100; + + return 0; +} + +int dram_init(void) +{ + int i; + + for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { + gd->bd->bi_dram[i].start = kw_sdram_bar(i); + gd->bd->bi_dram[i].size = kw_sdram_bs(i); + } + return 0; +} + +#ifdef CONFIG_MV88E1116_PHY +void reset_phy(void) +{ + /* configure and initialize phy */ + struct mv88e1116_config phycfg = { + .name = "egiga0", + .rgmii_delay = MV88E1116_RGMII_DELAY_EN, + .led_init = MV88E1116_LED_INIT_EN, + }; + mv88e1116_phy_initialize(&phycfg); +} +#endif /* CONFIG_MV88E1116_PHY */ diff --git a/board/Marvell/sheevaplug/sheevaplug.h b/board/Marvell/sheevaplug/sheevaplug.h new file mode 100644 index 0000000..45bfeca --- /dev/null +++ b/board/Marvell/sheevaplug/sheevaplug.h @@ -0,0 +1,37 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Written-by: Prafulla Wadaskar prafulla@marvell.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef __SHEEVAPLUG_H +#define __SHEEVAPLUG_H + +#ifndef MACH_TYPE_SHEEVAPLUG +#define MACH_TYPE_SHEEVAPLUG 2097 +#endif + +#define SHEEVAPLUG_OE_LOW (~(0)) +#define SHEEVAPLUG_OE_HIGH (~(0)) +#define SHEEVAPLUG_OE_VAL_LOW (1 << 29) /* USB_PWEN low */ +#define SHEEVAPLUG_OE_VAL_HIGH (1 << 17) /* LED pin high */ + +#endif /* __SHEEVAPLUG_H */ diff --git a/include/configs/sheevaplug.h b/include/configs/sheevaplug.h new file mode 100644 index 0000000..2bd7832 --- /dev/null +++ b/include/configs/sheevaplug.h @@ -0,0 +1,192 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Written-by: Prafulla Wadaskar prafulla@marvell.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef _CONFIG_SHEEVAPLUG_H +#define _CONFIG_SHEEVAPLUG_H + +/* + * Version number information + */ +#define CONFIG_IDENT_STRING "\nMarvell-Sheevaplug" + +/* + * High Level Configuration Options (easy to change) + */ +#define CONFIG_MARVELL 1 +#define CONFIG_ARM926EJS 1 /* Basic Architecture */ +#define CONFIG_FEROCEON_88FR131 1 /* CPU Core subversion */ +#define CONFIG_KIRKWOOD 1 /* SOC Family Name */ +#define CONFIG_KW88F6281 1 /* SOC Name */ +#define CONFIG_MACH_SHEEVAPLUG /* Machine type */ + +#define CONFIG_MD5 /* get_random_hex on krikwood needs MD5 support */ +#define CONFIG_SKIP_LOWLEVEL_INIT /* disable board lowlevel_init */ +#define CONFIG_KIRKWOOD_EGIGA_INIT /* Enable GbePort0/1 for kernel */ +#define CONFIG_KIRKWOOD_RGMII_PAD_1V8 /* Set RGMII Pad voltage to 1.8V */ + +/* + * CLKs configurations + */ +#define CONFIG_SYS_HZ 1000 + +/* + * NS16550 Configuration + */ +#define CONFIG_SYS_NS16550 +#define CONFIG_SYS_NS16550_SERIAL +#define CONFIG_SYS_NS16550_REG_SIZE (-4) +#define CONFIG_SYS_NS16550_CLK CONFIG_SYS_TCLK +#define CONFIG_SYS_NS16550_COM1 KW_UART0_BASE + +/* + * Serial Port configuration + * The following definitions let you select what serial you want to use + * for your console driver. + */ + +#define CONFIG_CONS_INDEX 1 /*Console on UART0 */ +#define CONFIG_BAUDRATE 115200 /* console baudrate */ +#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, \ + 115200,230400, 460800, 921600 } +/* auto boot */ +#define CONFIG_BOOTDELAY 3 /* default enable autoboot */ + +/* + * For booting Linux, the board info and command line data + * have to be in the first 8 MB of memory, since this is + * the maximum mapped by the Linux kernel during initialization. + */ +#define CONFIG_BOOTMAPSZ (8 << 20) /* Initial Memmap for Linux */ +#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */ +#define CONFIG_INITRD_TAG 1 /* enable INITRD tag */ +#define CONFIG_SETUP_MEMORY_TAGS 1 /* enable memory tag */ + +#define CONFIG_SYS_PROMPT "Marvell>> " /* Command Prompt */ +#define CONFIG_SYS_CBSIZE 1024 /* Console I/O Buff Size */ +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE \ + +sizeof(CONFIG_SYS_PROMPT) + 16) /* Print Buff */ +/* + * Commands configuration + */ +#define CONFIG_CMD_ENV +#define CONFIG_CMD_RUN +#define CONFIG_CMD_LOADB +#define CONFIG_CMD_NET +#define CONFIG_CMD_AUTOSCRIPT +#define CONFIG_CMD_MEMORY +#define CONFIG_CMD_BOOTD +#define CONFIG_CMD_SAVEENV +#define CONFIG_CMD_NAND + +/* + * Flash configuration + */ +#ifndef CONFIG_CMD_FLASH +#define CONFIG_SYS_NO_FLASH 1 /* Declare no flash (NOR/SPI) */ +#endif + +/* + * NAND configuration + */ +#ifdef CONFIG_CMD_NAND +#define CONFIG_NAND_KIRKWOOD +#define CONFIG_SYS_MAX_NAND_DEVICE 1 +#define NAND_MAX_CHIPS 1 +#define CONFIG_SYS_NAND_BASE 0xf9000000 +#define NAND_ALLOW_ERASE_ALL 1 +#endif + +/* + * Environment variables configurations + */ +#ifdef CONFIG_CMD_NAND +#define CONFIG_ENV_IS_IN_NAND 1 +#define CONFIG_ENV_SECT_SIZE 0x20000 /* 128K */ +#else +#define CONFIG_ENV_IS_NOWHERE 1 /* if env in SDRAM */ +#endif +#define CONFIG_ENV_SIZE 0x20000 /* 128k */ +#define CONFIG_ENV_ADDR 0x40000 +#define CONFIG_ENV_OFFSET 0x40000 /* env starts here */ + +/* + * Default environment variables + */ +#define CONFIG_BOOTCOMMAND "${x_bootcmd_kernel}; " \ + "setenv bootargs ${x_bootargs} ${x_bootargs_root}; " \ + "bootm 0x6400000;" + +#define CONFIG_MTDPARTS "orion_nand:512k(uboot)," \ + "1m@4m(psm), 3m@1m(kernel),13m@5m(rootfs) rw\0" + +#define CONFIG_EXTRA_ENV_SETTINGS "x_bootargs=console" \ + "=ttyS0,115200 mtdparts="CONFIG_MTDPARTS \ + "x_bootcmd_kernel=nand read 0x100000 0x6400000 0x300000\0" \ + "x_bootargs_root=root=/dev/mtdblock3 rw rootfstype=jffs2\0" + +/* + * Size of malloc() pool + */ +#define CONFIG_SYS_MALLOC_LEN (1024 * 128) /* 128kB for malloc() */ +/* size in bytes reserved for initial data */ +#define CONFIG_SYS_GBL_DATA_SIZE 128 + +/* + * Other required minimal configurations + */ +#define CONFIG_CONSOLE_INFO_QUIET /* some code reduction */ +#define CONFIG_ARCH_CPU_INIT /* call arch_cpu_init() */ +#define CONFIG_ARCH_MISC_INIT /* call arch_misc_init() */ +#define CONFIG_DISPLAY_CPUINFO /* Display cpu info */ +#define CONFIG_NR_DRAM_BANKS 4 +#define CONFIG_STACKSIZE 0x00100000 /* regular stack- 1M */ +#define CONFIG_SYS_LOAD_ADDR 0x00800000 /* default load adr- 8M */ +#define CONFIG_SYS_MEMTEST_START 0x00400000 /* 4M */ +#define CONFIG_SYS_MEMTEST_END 0x007fffff /*(_8M -1) */ +#define CONFIG_SYS_RESET_ADDRESS 0xffff0000 /* Rst Vector Adr */ +#define CONFIG_SYS_MAXARGS 16 /* max number of command args */ + +/* + * Ethernet Driver configuration + */ +#ifdef CONFIG_CMD_NET +#define CONFIG_CMD_DHCP +#define CONFIG_CMD_PING +#define CONFIG_NETCONSOLE /* include NetConsole support */ +#define CONFIG_NET_MULTI /* specify more that one ports available */ +#define CONFIG_MII /* expose smi ove miiphy interface */ +#define CONFIG_KIRKWOOD_EGIGA /* Enable kirkwood Gbe Controller Driver */ +#define CONFIG_SYS_FAULT_ECHO_LINK_DOWN /* detect link using phy */ +#define CONFIG_KIRKWOOD_EGIGA_PORTS {1,0} /* enable port 0 only */ +#define CONFIG_PHY_BASE_ADR 0 +#define CONFIG_ENV_OVERWRITE /* ethaddr can be reprogrammed */ +#endif /* CONFIG_CMD_NET */ + +/* + * Marvell 88E1116 PHY configurations + */ +#define CONFIG_RESET_PHY_R /* use reset_phy() to init phy/swtich */ +#define CONFIG_MV88E1116_PHY /* Enable mv88e61xx Phy driver */ + +#endif /* _CONFIG_SHEEVAPLUG_H */

Please do not review/accept this patch, I have send v2 for this. Sorry for inconvenience
Regards.. Prafulla . .
-----Original Message----- From: Prafulla Wadaskar [mailto:prafulla@marvell.com] Sent: Saturday, May 30, 2009 1:14 AM To: u-boot@lists.denx.de Cc: Nicolas Pitre; Manas Saksena; Lennert Buijtenhek; Prabhanjan Sarnaik; Ronen Shitrit; Ashish Karkare; Prafulla Wadaskar Subject: [PATCH] Marvell Sheevaplug Board support
Reference: http://plugcomputer.org/ http://openplug.org/plugwiki/index.php/Das_U-boot_plug_support
This patch is tested for-
- Boot from DRAM/NAND flash
- File transfer using tftp
- NAND flash read/write/erase
- Linux kernel and RFS Boot from NAND
Signed-off-by: Prafulla Wadaskar prafulla@marvell.com
MAKEALL | 1 + Makefile | 4 +- board/Marvell/sheevaplug/Makefile | 51 +++++++++ board/Marvell/sheevaplug/config.mk | 25 +++++ board/Marvell/sheevaplug/sheevaplug.c | 135 +++++++++++++++++++++++ board/Marvell/sheevaplug/sheevaplug.h | 37 +++++++ include/configs/sheevaplug.h | 192

Dear Prafulla Wadaskar,
In message 1243626217-9232-8-git-send-email-prafulla@marvell.com you wrote:
Reference: http://plugcomputer.org/ http://openplug.org/plugwiki/index.php/Das_U-boot_plug_support
This patch is tested for-
- Boot from DRAM/NAND flash
- File transfer using tftp
- NAND flash read/write/erase
- Linux kernel and RFS Boot from NAND
Signed-off-by: Prafulla Wadaskar prafulla@marvell.com
MAKEALL | 1 + Makefile | 4 +- board/Marvell/sheevaplug/Makefile | 51 +++++++++ board/Marvell/sheevaplug/config.mk | 25 +++++ board/Marvell/sheevaplug/sheevaplug.c | 135 +++++++++++++++++++++++ board/Marvell/sheevaplug/sheevaplug.h | 37 +++++++ include/configs/sheevaplug.h | 192 +++++++++++++++++++++++++++++++++ 7 files changed, 444 insertions(+), 1 deletions(-) create mode 100644 board/Marvell/sheevaplug/Makefile create mode 100644 board/Marvell/sheevaplug/config.mk create mode 100644 board/Marvell/sheevaplug/sheevaplug.c create mode 100644 board/Marvell/sheevaplug/sheevaplug.h create mode 100644 include/configs/sheevaplug.h
Entry in MAINTAINERS missing.
...
+/*
- Commands configuration
- */
+#define CONFIG_CMD_ENV +#define CONFIG_CMD_RUN +#define CONFIG_CMD_LOADB +#define CONFIG_CMD_NET +#define CONFIG_CMD_AUTOSCRIPT +#define CONFIG_CMD_MEMORY +#define CONFIG_CMD_BOOTD +#define CONFIG_CMD_SAVEENV +#define CONFIG_CMD_NAND
Please sort.
...
+#define CONFIG_MTDPARTS "orion_nand:512k(uboot)," \
- "1m@4m(psm), 3m@1m(kernel),13m@5m(rootfs) rw\0"
Do you really want to have such an unusal and unexpectad setup?
+/*
- Ethernet Driver configuration
- */
+#ifdef CONFIG_CMD_NET +#define CONFIG_CMD_DHCP +#define CONFIG_CMD_PING
I recommend to keep command definitions close together. Move up?
+#define CONFIG_NETCONSOLE /* include NetConsole support */ +#define CONFIG_NET_MULTI /* specify more that one ports available */ +#define CONFIG_MII /* expose smi ove miiphy interface */ +#define CONFIG_KIRKWOOD_EGIGA /* Enable kirkwood Gbe Controller Driver */ +#define CONFIG_SYS_FAULT_ECHO_LINK_DOWN /* detect link using phy */ +#define CONFIG_KIRKWOOD_EGIGA_PORTS {1,0} /* enable port 0 only */ +#define CONFIG_PHY_BASE_ADR 0 +#define CONFIG_ENV_OVERWRITE /* ethaddr can be reprogrammed */ +#endif /* CONFIG_CMD_NET */
Best regards,
Wolfgang Denk

Dear Prafulla Wadaskar,
In message 1243626217-9232-7-git-send-email-prafulla@marvell.com you wrote:
This is Marvell's 88F6281_A0 based custom board developed for wireless access point product
This patch is tested for-
- Boot from DRAM/SPI flash/NFS
- File transfer using tftp and loadb
- SPI flash read/write/erase
- Booting Linux kernel and RFS from SPI flash
Reviewed-by: Ronen Shitrit rshitrit@marvell.com Signed-off-by: Prafulla Wadaskar prafulla@marvell.com
MAKEALL | 1 + Makefile | 3 + board/Marvell/mv88f6281gtw_ge/Makefile | 51 ++++++ board/Marvell/mv88f6281gtw_ge/config.mk | 25 +++ board/Marvell/mv88f6281gtw_ge/mv88f6281gtw_ge.c | 141 +++++++++++++++++ board/Marvell/mv88f6281gtw_ge/mv88f6281gtw_ge.h | 36 +++++ include/configs/mv88f6281gtw_ge.h | 188 +++++++++++++++++++++++ 7 files changed, 445 insertions(+), 0 deletions(-) create mode 100644 board/Marvell/mv88f6281gtw_ge/Makefile create mode 100644 board/Marvell/mv88f6281gtw_ge/config.mk create mode 100644 board/Marvell/mv88f6281gtw_ge/mv88f6281gtw_ge.c create mode 100644 board/Marvell/mv88f6281gtw_ge/mv88f6281gtw_ge.h create mode 100644 include/configs/mv88f6281gtw_ge.h
Entry in MAINTAINERS file is missing.
diff --git a/include/configs/mv88f6281gtw_ge.h b/include/configs/mv88f6281gtw_ge.h new file mode 100644 index 0000000..8735b9e --- /dev/null +++ b/include/configs/mv88f6281gtw_ge.h
...
+/*
- Commands configuration
- */
+#define CONFIG_CMD_ENV +#define CONFIG_CMD_RUN +#define CONFIG_CMD_LOADB +#define CONFIG_CMD_NET +#define CONFIG_CMD_AUTOSCRIPT +#define CONFIG_CMD_MEMORY +#define CONFIG_CMD_BOOTD +#define CONFIG_CMD_SAVEENV +#define CONFIG_CMD_SF
Please sort such lists.
...
+#define CONFIG_MTDPARTS "spi0.0:512k(uboot)," \
- "512k@512k(psm), 2m@1m(kernel),13m@3m(rootfs)\0"
For readability, you might want to omit the redundant offet values here.
Best regards,
Wolfgang Denk

On 01:13 Sat 30 May , Prafulla Wadaskar wrote:
This patch adds a egiga driver for the Marvell Kirkwood SoC's.
Contributors: Yotam Admon yotam@marvell.com Michael Blostein <michaelbl@marvell.com
Reviewed-by: Ronen Shitrit rshitrit@marvell.com Acked-by: Stefan Rose sr@denx.de Signed-off-by: Prafulla Wadaskar prafulla@marvell.com
Ben if it's ok for you I'll apply with rest of the series
Best Regards, J.

Jean-Christophe PLAGNIOL-VILLARD wrote:
On 01:13 Sat 30 May , Prafulla Wadaskar wrote:
This patch adds a egiga driver for the Marvell Kirkwood SoC's.
Contributors: Yotam Admon yotam@marvell.com Michael Blostein <michaelbl@marvell.com
Reviewed-by: Ronen Shitrit rshitrit@marvell.com Acked-by: Stefan Rose sr@denx.de Signed-off-by: Prafulla Wadaskar prafulla@marvell.com
Ben if it's ok for you I'll apply with rest of the series
Best Regards, J.
I'll look at it this weekend.
regards, Ben

-----Original Message----- From: Ben Warren [mailto:biggerbadderben@gmail.com] Sent: Saturday, May 30, 2009 4:51 AM To: Jean-Christophe PLAGNIOL-VILLARD Cc: Prafulla Wadaskar; u-boot@lists.denx.de; Manas Saksena; Ronen Shitrit; Nicolas Pitre; Ashish Karkare; Prabhanjan Sarnaik; Lennert Buijtenhek Subject: Re: [U-Boot] [PATCH] net: Add Marvell Kirkwood gigabit ethernet driver
Jean-Christophe PLAGNIOL-VILLARD wrote:
On 01:13 Sat 30 May , Prafulla Wadaskar wrote:
This patch adds a egiga driver for the Marvell Kirkwood SoC's.
Contributors: Yotam Admon yotam@marvell.com Michael Blostein <michaelbl@marvell.com
Reviewed-by: Ronen Shitrit rshitrit@marvell.com Acked-by: Stefan Rose sr@denx.de Signed-off-by: Prafulla Wadaskar prafulla@marvell.com
Ben if it's ok for you I'll apply with rest of the series
Best Regards, J.
I'll look at it this weekend.
Hi Ben, I have put the huge efforts to tune it specially for code size reduction. Whereas I have lost only network statistics and packet info print debugging features. Now it looks more simpler and cleaner :-) Hopefully it will stand as per your suggestions.
See the difference New driver.. drivers/net/Makefile | 1 + drivers/net/kirkwood_egiga.c | 674 ++++++++++++++++++++++++++++++++++++++++++ drivers/net/kirkwood_egiga.h | 561 +++++++++++++++++++++++++++++++++++ include/netdev.h | 1 + 4 files changed, 1237 insertions(+), 0 deletions(-) create mode 100644
Old driver cpu/arm926ejs/kirkwood/cpu.c | 8 + drivers/net/Makefile | 1 + drivers/net/kirkwood_egiga.c | 1670 ++++++++++++++++++++++++++++++++++++++++++ drivers/net/kirkwood_egiga.h | 828 +++++++++++++++++++++ include/netdev.h | 1 + 5 files changed, 2508 insertions(+), 0 deletions(-) create mode 100644 drivers/net/kirkwood_egiga.c create mode 100644 drivers/net/kirkwood_egiga.h
Regards.. Prafulla .
regards, Ben

Prafulla Wadaskar wrote:
-----Original Message----- From: Ben Warren [mailto:biggerbadderben@gmail.com] Sent: Saturday, May 30, 2009 4:51 AM To: Jean-Christophe PLAGNIOL-VILLARD Cc: Prafulla Wadaskar; u-boot@lists.denx.de; Manas Saksena; Ronen Shitrit; Nicolas Pitre; Ashish Karkare; Prabhanjan Sarnaik; Lennert Buijtenhek Subject: Re: [U-Boot] [PATCH] net: Add Marvell Kirkwood gigabit ethernet driver
Jean-Christophe PLAGNIOL-VILLARD wrote:
On 01:13 Sat 30 May , Prafulla Wadaskar wrote:
This patch adds a egiga driver for the Marvell Kirkwood SoC's.
Contributors: Yotam Admon yotam@marvell.com Michael Blostein <michaelbl@marvell.com
Reviewed-by: Ronen Shitrit rshitrit@marvell.com Acked-by: Stefan Rose sr@denx.de Signed-off-by: Prafulla Wadaskar prafulla@marvell.com
Ben if it's ok for you I'll apply with rest of the series
Best Regards, J.
I'll look at it this weekend.
Hi Ben, I have put the huge efforts to tune it specially for code size reduction. Whereas I have lost only network statistics and packet info print debugging features. Now it looks more simpler and cleaner :-) Hopefully it will stand as per your suggestions.
Much appreciated! Thanks a lot. It looks really good - please just take care of Wolfgang's concerns about error messages and it'll be ready for inclusion.
regards, Ben

This patch adds a egiga driver for the Marvell Kirkwood SoC's.
Contributors: Yotam Admon yotam@marvell.com Michael Blostein <michaelbl@marvell.com
Reviewed-by: Ronen Shitrit rshitrit@marvell.com Acked-by: Stefan Rose sr@denx.de Signed-off-by: Prafulla Wadaskar prafulla@marvell.com --- Change log: v2: updated all print messages to provide helpful info
drivers/net/Makefile | 1 + drivers/net/kirkwood_egiga.c | 664 ++++++++++++++++++++++++++++++++++++++++++ drivers/net/kirkwood_egiga.h | 561 +++++++++++++++++++++++++++++++++++ include/netdev.h | 1 + 4 files changed, 1227 insertions(+), 0 deletions(-) create mode 100644 drivers/net/kirkwood_egiga.c create mode 100644 drivers/net/kirkwood_egiga.h
diff --git a/drivers/net/Makefile b/drivers/net/Makefile index a360a50..f0c5654 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -40,6 +40,7 @@ COBJS-$(CONFIG_ENC28J60) += enc28j60.o COBJS-$(CONFIG_FSLDMAFEC) += fsl_mcdmafec.o mcfmii.o COBJS-$(CONFIG_GRETH) += greth.o COBJS-$(CONFIG_INCA_IP_SWITCH) += inca-ip_sw.o +COBJS-$(CONFIG_KIRKWOOD_EGIGA) += kirkwood_egiga.o COBJS-$(CONFIG_DRIVER_KS8695ETH) += ks8695eth.o COBJS-$(CONFIG_DRIVER_LAN91C96) += lan91c96.o COBJS-$(CONFIG_MACB) += macb.o diff --git a/drivers/net/kirkwood_egiga.c b/drivers/net/kirkwood_egiga.c new file mode 100644 index 0000000..85cacdb --- /dev/null +++ b/drivers/net/kirkwood_egiga.c @@ -0,0 +1,664 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Written-by: Prafulla Wadaskar prafulla@marvell.com + * + * (C) Copyright 2003 + * Ingo Assmus ingo.assmus@keymile.com + * + * based on - Driver for MV64360X ethernet ports + * Copyright (C) 2002 rabeeh@galileo.co.il + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include <common.h> +#include <net.h> +#include <malloc.h> +#include <miiphy.h> +#include <asm/errno.h> +#include <asm/types.h> +#include <asm/byteorder.h> +#include <asm/arch/kirkwood.h> +#include "kirkwood_egiga.h" + +/* + * smi_reg_read - miiphy_read callback function. + * + * Returns 16bit phy register value, or 0xffff on error + */ +static int smi_reg_read(char *devname, u8 phy_adr, u8 reg_ofs, u16 * data) +{ + struct eth_device *dev = eth_get_dev_by_name(devname); + struct kwgbe_device *dkwgbe = to_dkwgbe(dev); + struct kwgbe_registers *regs = dkwgbe->regs; + u32 smi_reg; + volatile u32 timeout; + + /* Phyadr read request */ + if (phy_adr == 0xEE && reg_ofs == 0xEE) { + *data = (u16) (KWGBEREG_RD(regs->phyadr) & 0x00ff); + return 0; + } + /* check parameters */ + if (phy_adr > 0x1f) { + printf("Err..(%s) Invalid PHY address %d\n", + __FUNCTION__, phy_adr); + return -EFAULT; + } + if (reg_ofs > 0x1f) { + printf("Err..(%s) Invalid register offset %d\n", + __FUNCTION__, reg_ofs); + return -EFAULT; + } + + timeout = KWGBE_PHY_SMI_TIMEOUT; + /* wait till the SMI is not busy */ + do { + /* read smi register */ + smi_reg = KWGBEREG_RD(regs->smi); + if (timeout-- == 0) { + printf("Err..(%s) SMI busy timeout\n", __FUNCTION__); + return -EFAULT; + } + } while (smi_reg & KWGBE_PHY_SMI_BUSY_MASK); + + /* fill the phy address and regiser offset and read opcode */ + smi_reg = (phy_adr << KWGBE_PHY_SMI_DEV_ADDR_OFFS) + | (reg_ofs << KWGBE_SMI_REG_ADDR_OFFS) + | KWGBE_PHY_SMI_OPCODE_READ; + + /* write the smi register */ + KWGBEREG_WR(regs->smi, smi_reg); + + /*wait till read value is ready */ + timeout = KWGBE_PHY_SMI_TIMEOUT; + do { + /* read smi register */ + smi_reg = KWGBEREG_RD(regs->smi); + if (timeout-- == 0) { + printf("Err..(%s) SMI read ready timeout\n", + __FUNCTION__); + return -EFAULT; + } + } while (!(smi_reg & KWGBE_PHY_SMI_READ_VALID_MASK)); + + /* Wait for the data to update in the SMI register */ + for (timeout = 0; timeout < KWGBE_PHY_SMI_TIMEOUT; timeout++) ; + + *data = (u16) (KWGBEREG_RD(regs->smi) & KWGBE_PHY_SMI_DATA_MASK); + + debug("%s:(adr %d, off %d) value= %04x\n", __FUNCTION__, phy_adr, + reg_ofs, *data); + + return 0; +} + +/* + * smi_reg_write - imiiphy_write callback function. + * + * Returns 0 if write succeed, -EINVAL on bad parameters + * -ETIME on timeout + */ +static int smi_reg_write(char *devname, u8 phy_adr, u8 reg_ofs, u16 data) +{ + struct eth_device *dev = eth_get_dev_by_name(devname); + struct kwgbe_device *dkwgbe = to_dkwgbe(dev); + struct kwgbe_registers *regs = dkwgbe->regs; + u32 smi_reg; + volatile u32 timeout; + + /* Phyadr write request*/ + if (phy_adr == 0xEE && reg_ofs == 0xEE) { + KWGBEREG_WR(regs->phyadr, data); + return 0; + } + + /* check parameters */ + if (phy_adr > 0x1f) { + printf("Err..(%s) Invalid phy address\n", __FUNCTION__); + return -EINVAL; + } + if (reg_ofs > 0x1f) { + printf("Err..(%s) Invalid register offset\n", __FUNCTION__); + return -EINVAL; + } + + /* wait till the SMI is not busy */ + timeout = KWGBE_PHY_SMI_TIMEOUT; + do { + /* read smi register */ + smi_reg = KWGBEREG_RD(regs->smi); + if (timeout-- == 0) { + printf("Err..(%s) SMI busy timeout\n", __FUNCTION__); + return -ETIME; + } + } while (smi_reg & KWGBE_PHY_SMI_BUSY_MASK); + + /* fill the phy addr and reg offset and write opcode and data */ + smi_reg = (data << KWGBE_PHY_SMI_DATA_OFFS); + smi_reg |= (phy_adr << KWGBE_PHY_SMI_DEV_ADDR_OFFS) + | (reg_ofs << KWGBE_SMI_REG_ADDR_OFFS); + smi_reg &= ~KWGBE_PHY_SMI_OPCODE_READ; + + /* write the smi register */ + KWGBEREG_WR(regs->smi, smi_reg); + + return 0; +} + +/* Stop and checks all queues */ +static void stop_queue(u32 * qreg) +{ + u32 reg_data; + + reg_data = readl(qreg); + + if (reg_data & 0xFF) { + /* Issue stop command for active channels only */ + writel((reg_data << 8), qreg); + + /* Wait for all queue activity to terminate. */ + do { + /* + * Check port cause register that all queues + * are stopped + */ + reg_data = readl(qreg); + } + while (reg_data & 0xFF); + } +} + +/* + * set_access_control - Config address decode parameters for Ethernet unit + * + * This function configures the address decode parameters for the Gigabit + * Ethernet Controller according the given parameters struct. + * + * @regs Register struct pointer. + * @param Address decode parameter struct. + */ +static void set_access_control(struct kwgbe_registers *regs, + struct kwgbe_winparam *param) +{ + u32 access_prot_reg; + + /* Set access control register */ + access_prot_reg = KWGBEREG_RD(regs->epap); + /* clear window permission */ + access_prot_reg &= (~(3 << (param->win * 2))); + access_prot_reg |= (param->access_ctrl << (param->win * 2)); + KWGBEREG_WR(regs->epap, access_prot_reg); + + /* Set window Size reg (SR) */ + KWGBEREG_WR(regs->barsz[param->win].size, + (((param->size / 0x10000) - 1) << 16)); + + /* Set window Base address reg (BA) */ + KWGBEREG_WR(regs->barsz[param->win].bar, + (param->target | param->attrib | param->base_addr)); + /* High address remap reg (HARR) */ + if (param->win < 4) + KWGBEREG_WR(regs->ha_remap[param->win], param->high_addr); + + /* Base address enable reg (BARER) */ + if (param->enable == 1) + KWGBEREG_BITS_RESET(regs->bare, (1 << param->win)); + else + KWGBEREG_BITS_SET(regs->bare, (1 << param->win)); +} + +static void set_dram_access(struct kwgbe_registers *regs) +{ + struct kwgbe_winparam win_param; + int i; + + for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { + /* Set access parameters for DRAM bank i */ + win_param.win = i; /* Use Ethernet window i */ + /* Window target - DDR */ + win_param.target = KWGBE_TARGET_DRAM; + /* Enable full access */ + win_param.access_ctrl = EWIN_ACCESS_FULL; + win_param.high_addr = 0; + /* Get bank base */ + win_param.base_addr = kw_sdram_bar(i); + win_param.size = kw_sdram_bs(i); /* Get bank size */ + if (win_param.size == 0) + win_param.enable = 0; + else + win_param.enable = 1; /* Enable the access */ + + /* Enable DRAM bank */ + switch (i) { + case 0: + win_param.attrib = EBAR_DRAM_CS0; + break; + case 1: + win_param.attrib = EBAR_DRAM_CS1; + break; + case 2: + win_param.attrib = EBAR_DRAM_CS2; + break; + case 3: + win_param.attrib = EBAR_DRAM_CS3; + break; + default: + /* invalide bank, disable access */ + win_param.enable = 0; + win_param.attrib = 0; + break; + } +#ifdef CONFIG_SYS_COHERENT_CACHE + win_param.attrib |= EBAR_DRAM_CACHE_COHERENCY_WB; +#endif + /* Set the access control for address window(EPAPR) RD/WR */ + set_access_control(regs, &win_param); + } +} + +/* + * port_init_mac_tables - Clear all entrance in the UC, SMC and OMC tables + * + * Go through all the DA filter tables (Unicast, Special Multicast & Other + * Multicast) and set each entry to 0. + */ +static void port_init_mac_tables(struct kwgbe_registers *regs) +{ + int table_index; + + /* Clear DA filter unicast table (Ex_dFUT) */ + for (table_index = 0; table_index < 4; ++table_index) + KWGBEREG_WR(regs->dfut[table_index], 0); + + for (table_index = 0; table_index < 64; ++table_index) { + /* Clear DA filter special multicast table (Ex_dFSMT) */ + KWGBEREG_WR(regs->dfsmt[table_index], 0); + /* Clear DA filter other multicast table (Ex_dFOMT) */ + KWGBEREG_WR(regs->dfomt[table_index], 0); + } +} + +/* + * port_uc_addr - This function Set the port unicast address table + * + * This function locates the proper entry in the Unicast table for the + * specified MAC nibble and sets its properties according to function + * parameters. + * This function add/removes MAC addresses from the port unicast address + * table. + * + * @uc_nibble Unicast MAC Address last nibble. + * @option 0 = Add, 1 = remove address. + * + * RETURN: 1 if output succeeded. 0 if option parameter is invalid. + */ +static int port_uc_addr(struct kwgbe_registers *regs, u8 uc_nibble, + int option) +{ + u32 unicast_reg; + u32 tbl_offset; + u32 reg_offset; + + /* Locate the Unicast table entry */ + uc_nibble = (0xf & uc_nibble); + /* Register offset from unicast table base */ + tbl_offset = (uc_nibble / 4); + /* Entry offset within the above register */ + reg_offset = uc_nibble % 4; + + switch (option) { + case REJECT_MAC_ADDR: + /* + * Clear accepts frame bit at specified unicast + * DA table entry + */ + unicast_reg = KWGBEREG_RD(regs->dfut[tbl_offset]); + unicast_reg &= (0xFF << (8 * reg_offset)); + KWGBEREG_WR(regs->dfut[tbl_offset], unicast_reg); + break; + case ACCEPT_MAC_ADDR: + /* Set accepts frame bit at unicast DA filter table entry */ + unicast_reg = KWGBEREG_RD(regs->dfut[tbl_offset]); + unicast_reg &= (0xFF << (8 * reg_offset)); + unicast_reg |= ((0x01 | (RXUQ << 1)) << (8 * reg_offset)); + KWGBEREG_WR(regs->dfut[tbl_offset], unicast_reg); + break; + default: + return 0; + } + return 1; +} + +/* + * port_uc_addr_set - This function Set the port Unicast address. + */ +static void port_uc_addr_set(struct kwgbe_registers *regs, u8 * p_addr) +{ + u32 mac_h; + u32 mac_l; + + mac_l = (p_addr[4] << 8) | (p_addr[5]); + mac_h = (p_addr[0] << 24) | (p_addr[1] << 16) | (p_addr[2] << 8) | + (p_addr[3] << 0); + + KWGBEREG_WR(regs->macal, mac_l); + KWGBEREG_WR(regs->macah, mac_h); + + /* Accept frames of this address */ + port_uc_addr(regs, p_addr[5], ACCEPT_MAC_ADDR); +} + +/* + * kwgbe_init_rx_desc_ring - Curve a Rx chain desc list and buffer in memory. + */ +static void kwgbe_init_rx_desc_ring(struct kwgbe_device *dkwgbe) +{ + volatile struct kwgbe_rxdesc *p_rx_desc; + int i; + + /* initialize the Rx descriptors ring */ + p_rx_desc = dkwgbe->p_rxdesc; + for (i = 0; i < RINGSZ; i++) { + p_rx_desc->cmd_sts = + KWGBE_BUFFER_OWNED_BY_DMA | KWGBE_RX_EN_INTERRUPT; + p_rx_desc->buf_size = PKTSIZE_ALIGN; + p_rx_desc->byte_cnt = 0x0000; + p_rx_desc->buf_ptr = dkwgbe->p_rxbuf + i * PKTSIZE_ALIGN; + if (i == (RINGSZ - 1)) + p_rx_desc->nxtdesc_p = dkwgbe->p_rxdesc; + else { + p_rx_desc->nxtdesc_p = (struct kwgbe_rxdesc *) + ((u32) p_rx_desc + KW_RXQ_DESC_ALIGNED_SIZE); + p_rx_desc = p_rx_desc->nxtdesc_p; + } + D_CACHE_FLUSH_LINE(p_rx_desc, 0); + } + + dkwgbe->p_rxdesc_curr = dkwgbe->p_rxdesc; +} + +static int kwgbe_init(struct eth_device *dev) +{ + struct kwgbe_device *dkwgbe = to_dkwgbe(dev); + struct kwgbe_registers *regs = dkwgbe->regs; + + /* setup RX rings */ + kwgbe_init_rx_desc_ring(dkwgbe); + + /* Clear the ethernet port interrupts */ + KWGBEREG_WR(regs->ic, 0); + KWGBEREG_WR(regs->ice, 0); + /* Unmask RX buffer and TX end interrupt */ + KWGBEREG_WR(regs->pim, INT_CAUSE_UNMASK_ALL); + /* Unmask phy and link status changes interrupts */ + KWGBEREG_WR(regs->peim, INT_CAUSE_UNMASK_ALL_EXT); + + set_dram_access(regs); + port_init_mac_tables(regs); + port_uc_addr_set(regs, dkwgbe->dev.enetaddr); + + /* Assign port configuration and command. */ + KWGBEREG_WR(regs->pxc, PRT_CFG_VAL); + KWGBEREG_WR(regs->pxcx, PORT_CFG_EXTEND_VALUE); + KWGBEREG_WR(regs->psc0, PORT_SERIAL_CONTROL_VALUE); + KWGBEREG_BITS_SET(regs->psc0, KWGBE_SERIAL_PORT_EN); + + /* Assign port SDMA configuration */ + KWGBEREG_WR(regs->sdc, PORT_SDMA_CFG_VALUE); + KWGBEREG_WR(regs->tqx[0].qxttbc, 0x3fffffff); + KWGBEREG_WR(regs->tqx[0].tqxtbc, 0x03fffcff); + /* Turn off the port/RXUQ bandwidth limitation */ + KWGBEREG_WR(regs->pmtu, 0x0); + + /* Set maximum receive buffer to 9700 bytes */ + KWGBEREG_WR(regs->psc0, + (0x5 << 17) | (KWGBEREG_RD(regs->psc0) & 0xfff1ffff)); + + /* + * Set ethernet MTU for leaky bucket mechanism to 0 - this will + * disable the leaky bucket mechanism . + */ + KWGBEREG_WR(regs->pmtu, 0); + + /* Assignment of Rx CRDB of given RXUQ */ + KWGBEREG_WR(regs->rxcdp[RXUQ].rxcdp, (u32) dkwgbe->p_rxdesc_curr); + /* Enable port Rx. */ + KWGBEREG_WR(regs->rqc, (1 << RXUQ)); + +#if (defined (CONFIG_MII) || defined (CONFIG_CMD_MII)) \ + && defined (CONFIG_SYS_FAULT_ECHO_LINK_DOWN) + u16 phyadr; + miiphy_read(dev->name, 0xEE, 0xEE, &phyadr); + if (!miiphy_link(dev->name, phyadr)) { + printf("%s: No link on %s\n", __FUNCTION__, dev->name); + } +#endif + return 0; +} + +static int kwgbe_halt(struct eth_device *dev) +{ + struct kwgbe_device *dkwgbe = to_dkwgbe(dev); + struct kwgbe_registers *regs = dkwgbe->regs; + + /* Disable all gigE address decoder */ + KWGBEREG_WR(regs->bare, 0x3f); + + stop_queue(®s->tqc); + stop_queue(®s->rqc); + + /* Enable port in the Configuration Register */ + KWGBEREG_BITS_RESET(regs->psc0, KWGBE_SERIAL_PORT_EN); + /* Set port of active in the Configuration Register */ + KWGBEREG_BITS_RESET(regs->psc1, 1 << 4); +#ifdef CONFIG_SYS_MII_MODE + /* Set MMI interface up */ + KWGBEREG_BITS_RESET(regs->psc1, 1 << 3); +#endif + /* Disable ethernet port interrupts */ + KWGBEREG_WR(regs->ic, 0); + KWGBEREG_WR(regs->ice, 0); + /* Mask RX buffer and TX end interrupt */ + KWGBEREG_WR(regs->pim, 0); + /* Mask phy and link status changes interrupts */ + KWGBEREG_WR(regs->peim, 0); + + return 0; +} + +static int kwgbe_send(struct eth_device *dev, volatile void *dataptr, + int datasize) +{ + struct kwgbe_device *dkwgbe = to_dkwgbe(dev); + struct kwgbe_registers *regs = dkwgbe->regs; + struct kwgbe_txdesc *p_txdesc = dkwgbe->p_txdesc; + + if ((u32) dataptr & 0x07) { + printf("Err..(%s) xmit dataptr not 64bit aligned\n", + __FUNCTION__); + return -1; + } + p_txdesc->cmd_sts = KWGBE_ZERO_PADDING | KWGBE_GEN_CRC; + p_txdesc->cmd_sts |= KWGBE_TX_FIRST_DESC | KWGBE_TX_LAST_DESC; + p_txdesc->cmd_sts |= KWGBE_BUFFER_OWNED_BY_DMA; + p_txdesc->cmd_sts |= KWGBE_TX_EN_INTERRUPT; + p_txdesc->buf_ptr = (u8 *) dataptr; + p_txdesc->byte_cnt = datasize; + + /* Flush CPU pipe */ + CPU_PIPE_FLUSH; + + /* Apply send command using zeroth RXUQ */ + KWGBEREG_WR(regs->tcqdp[TXUQ], (u32) p_txdesc); + KWGBEREG_WR(regs->tqc, (1 << TXUQ)); + + /* + * wait for packet xmit completion + */ + while (p_txdesc->cmd_sts & KWGBE_BUFFER_OWNED_BY_DMA) { + /* return fail if error is detected */ + if (p_txdesc->cmd_sts & 0x06) { + printf("Err..(%s) in xmit packet\n", __FUNCTION__); + return -1; + } + }; + return 0; +} + +static int kwgbe_recv(struct eth_device *dev) +{ + volatile struct kwgbe_device *dkwgbe = to_dkwgbe(dev); + volatile struct kwgbe_rxdesc *p_rxdesc_curr = dkwgbe->p_rxdesc_curr; + + /* wait untill rx packet available */ + while (p_rxdesc_curr->cmd_sts & KWGBE_BUFFER_OWNED_BY_DMA) ; + D_CACHE_FLUSH_LINE((u32) p_rxdesc_curr, 0); + + if (p_rxdesc_curr->byte_cnt != 0) { + debug("%s: Received %d byte Packet @ 0x%x (cmd_sts= %08x)\n", + __FUNCTION__, (u32) p_rxdesc_curr->byte_cnt, + (u32) p_rxdesc_curr->buf_ptr, + (u32) p_rxdesc_curr->cmd_sts); + } + + /* + * In case received a packet without first/last bits on + * OR the error summary bit is on, + * the packets needs to be dropeed. + */ + if ((p_rxdesc_curr->cmd_sts & + (KWGBE_RX_FIRST_DESC | KWGBE_RX_LAST_DESC)) + != (KWGBE_RX_FIRST_DESC | KWGBE_RX_LAST_DESC)) { + + printf("Err..(%s) Dropping packet spread on" + " multiple descriptors\n", __FUNCTION__); + + } else if (p_rxdesc_curr->cmd_sts & KWGBE_ERROR_SUMMARY) { + + printf("Err..(%s) Dropping packet with errors\n", + __FUNCTION__); + + } else { + /* !!! call higher layer processing */ + debug("%s: Sending Received packet to" + " upper layer (NetReceive)\n", __FUNCTION__); + + /* let the upper layer handle the packet */ + NetReceive((p_rxdesc_curr->buf_ptr + RX_BUF_OFFSET), + (int)(p_rxdesc_curr->byte_cnt - RX_BUF_OFFSET)); + } + /* + * free these descriptors and point next in the ring + */ + p_rxdesc_curr->cmd_sts = + KWGBE_BUFFER_OWNED_BY_DMA | KWGBE_RX_EN_INTERRUPT; + p_rxdesc_curr->buf_size = PKTSIZE_ALIGN; + p_rxdesc_curr->byte_cnt = 0x0000; + + dkwgbe->p_rxdesc_curr = p_rxdesc_curr->nxtdesc_p; + return 0; +} + +int kirkwood_egiga_initialize(bd_t * bis) +{ + struct kwgbe_device *dkwgbe; + struct eth_device *dev; + int devnum; + char *s, buf[64]; + u8 used_ports[MAX_KWGBE_DEVS] = CONFIG_KIRKWOOD_EGIGA_PORTS; + + for (devnum = 0; devnum < MAX_KWGBE_DEVS; devnum++) { + /*skip if port is configured not to use */ + if (used_ports[devnum] == 0) + continue; + + if (!(dkwgbe = malloc(sizeof(struct kwgbe_device)))) + goto error1; + + memset(dkwgbe, 0, sizeof(struct kwgbe_device)); + + if (!(dkwgbe->p_rxdesc = + (struct kwgbe_rxdesc *)memalign(PKTALIGN, + KW_RXQ_DESC_ALIGNED_SIZE + * RINGSZ + 1))) + goto error2; + + if (!(dkwgbe->p_rxbuf = (u8 *) memalign(PKTALIGN, RINGSZ + * PKTSIZE_ALIGN + 1))) + goto error3; + + if (!(dkwgbe->p_txdesc = (struct kwgbe_txdesc *) + memalign(PKTALIGN, sizeof(struct kwgbe_txdesc) + 1))) { + free(dkwgbe->p_rxbuf); + error3: + free(dkwgbe->p_rxdesc); + error2: + free(dkwgbe); + error1: + printf("Err.. %s Failed to allocate memory\n", + __FUNCTION__); + return -1; + } + + dev = &dkwgbe->dev; + + /* must be less than NAMESIZE (16) */ + sprintf(dev->name, "egiga%d", devnum); + + /* Extract the MAC address from the environment */ + switch (devnum) { + case 0: + dkwgbe->regs = (void *)KW_EGIGA0_BASE; + s = "ethaddr"; + break; + case 1: + dkwgbe->regs = (void *)KW_EGIGA1_BASE; + s = "eth1addr"; + break; + default: /* this should never happen */ + printf("Err..(%s) Invalid device number %d\n", + __FUNCTION__, devnum); + return -1; + } + + while (!eth_getenv_enetaddr(s, dev->enetaddr)) { + /* Generate Ramdom MAC addresses if not set */ + sprintf(buf, "00:50:43:%02x:%02x:%02x", + get_random_hex(), get_random_hex(), + get_random_hex()); + setenv(s, buf); + } + + dev->init = (void *)kwgbe_init; + dev->halt = (void *)kwgbe_halt; + dev->send = (void *)kwgbe_send; + dev->recv = (void *)kwgbe_recv; + + eth_register(dev); + +#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) + miiphy_register(dev->name, smi_reg_read, smi_reg_write); + /* Set phy address of the port */ + miiphy_write(dev->name, 0xEE, 0xEE, PHY_BASE_ADR + devnum); +#endif + } + return 0; +} diff --git a/drivers/net/kirkwood_egiga.h b/drivers/net/kirkwood_egiga.h new file mode 100644 index 0000000..1d818f9 --- /dev/null +++ b/drivers/net/kirkwood_egiga.h @@ -0,0 +1,561 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Written-by: Prafulla Wadaskar prafulla@marvell.com + * + * based on - Driver for MV64360X ethernet ports + * Copyright (C) 2002 rabeeh@galileo.co.il + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef __EGIGA_H__ +#define __EGIGA_H__ + +#define MAX_KWGBE_DEVS 2 /*controller has two ports */ + +/* In case SRAM is cache coherent or non-cacheable */ +#ifndef CONFIG_SYS_COHERENT_CACHE +#define D_CACHE_FLUSH_LINE(addr, offset) ; +#define CPU_PIPE_FLUSH { __asm__ __volatile__ ("nop;nop;nop;nop;nop;nop");} +#else +#error "Cache coherent macros to be defined.." +#endif + +/* PHY_BASE_ADR is board specific and can be configured */ +#if defined (CONFIG_PHY_BASE_ADR) +#define PHY_BASE_ADR CONFIG_PHY_BASE_ADR +#else +#define PHY_BASE_ADR 0x08 /* default phy base addr */ +#endif + +/* Constants */ +#define INT_CAUSE_UNMASK_ALL 0x0007ffff +#define INT_CAUSE_UNMASK_ALL_EXT 0x0011ffff +#define RXUQ 0 /* Used Rx queue */ +#define TXUQ 0 /* Used Rx queue */ + +#define to_dkwgbe(_kd) container_of(_kd, struct kwgbe_device, dev) +#define KWGBEREG_WR(adr, val) writel(val, &adr) +#define KWGBEREG_RD(adr) readl(&adr) +#define KWGBEREG_BITS_RESET(adr, val) writel(readl(&adr) & ~(val), &adr) +#define KWGBEREG_BITS_SET(adr, val) writel(readl(&adr) | val, &adr) + +/* Default port configuration value */ +#define PRT_CFG_VAL ( \ + KWGBE_UCAST_MOD_NRML | \ + KWGBE_DFLT_RX_Q0 | \ + KWGBE_DFLT_RX_ARPQ0 | \ + KWGBE_RX_BC_IF_NOT_IP_OR_ARP | \ + KWGBE_RX_BC_IF_IP | \ + KWGBE_RX_BC_IF_ARP | \ + KWGBE_CPTR_TCP_FRMS_DIS | \ + KWGBE_CPTR_UDP_FRMS_DIS | \ + KWGBE_DFLT_RX_TCPQ0 | \ + KWGBE_DFLT_RX_UDPQ0 | \ + KWGBE_DFLT_RX_BPDU_Q_0) + +/* Default port extend configuration value */ +#define PORT_CFG_EXTEND_VALUE \ + KWGBE_SPAN_BPDU_PACKETS_AS_NORMAL | \ + KWGBE_PARTITION_DIS | \ + KWGBE_TX_CRC_GENERATION_EN + +/* Default sdma control value */ +#ifndef CONFIG_SYS_COHERENT_CACHE +#define PORT_SDMA_CFG_VALUE ( \ + KWGBE_RX_BURST_SIZE_16_64BIT | \ + KWGBE_BLM_RX_NO_SWAP | \ + KWGBE_BLM_TX_NO_SWAP | \ + GT_KWGBE_IPG_INT_RX(0) | \ + KWGBE_TX_BURST_SIZE_16_64BIT) +#else +#define PORT_SDMA_CFG_VALUE ( \ + KWGBE_RX_BURST_SIZE_4_64BIT | \ + GT_KWGBE_IPG_INT_RX(0) | \ + KWGBE_TX_BURST_SIZE_4_64BIT) +#endif + +#define GT_KWGBE_IPG_INT_RX(value) ((value & 0x3fff) << 8) + +/* Default port serial control value */ +#define PORT_SERIAL_CONTROL_VALUE_TMP ( \ + KWGBE_FORCE_LINK_PASS | \ + KWGBE_DIS_AUTO_NEG_FOR_DUPLX | \ + KWGBE_DIS_AUTO_NEG_FOR_FLOW_CTRL | \ + KWGBE_ADV_NO_FLOW_CTRL | \ + KWGBE_FORCE_FC_MODE_NO_PAUSE_DIS_TX | \ + KWGBE_FORCE_BP_MODE_NO_JAM | \ + (1 << 9) | \ + KWGBE_DO_NOT_FORCE_LINK_FAIL | \ + KWGBE_DIS_AUTO_NEG_SPEED_GMII | \ + KWGBE_DTE_ADV_0 | \ + KWGBE_MIIPHY_MAC_MODE | \ + KWGBE_AUTO_NEG_NO_CHANGE | \ + KWGBE_MAX_RX_PACKET_1552BYTE | \ + KWGBE_CLR_EXT_LOOPBACK | \ + KWGBE_SET_FULL_DUPLEX_MODE | \ + KWGBE_DIS_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX | \ + KWGBE_SET_MII_SPEED_TO_100) + +/* Speed will be configured to 10_100MBPS for MII mode of operation */ +#ifdef CONFIG_SYS_MII_MODE +#define PORT_SERIAL_CONTROL_VALUE ( \ + PORT_SERIAL_CONTROL_VALUE_TMP | \ + KWGBE_SET_GMII_SPEED_TO_10_100) +#else +#define PORT_SERIAL_CONTROL_VALUE ( \ + PORT_SERIAL_CONTROL_VALUE_TMP | \ + KWGBE_SET_GMII_SPEED_TO_1000) +#endif + +/* Tx WRR confoguration macros */ +#define PORT_MAX_TRAN_UNIT 0x24 /* MTU register (default) 9KByte */ +#define PORT_MAX_TOKEN_BUCKET_SIZE 0x_fFFF /* PMTBS reg (default) */ +#define PORT_TOKEN_RATE 1023 /* PTTBRC reg (default) */ +/* MAC accepet/reject macros */ +#define ACCEPT_MAC_ADDR 0 +#define REJECT_MAC_ADDR 1 +/* Size of a Tx/Rx descriptor used in chain list data structure */ +#define KW_RXQ_DESC_ALIGNED_SIZE \ + (((sizeof(struct kwgbe_rxdesc) / PKTALIGN) + 1) * PKTALIGN) +/* Buffer offset from buffer pointer */ +#define RX_BUF_OFFSET 0x2 + +/* Port serial status reg (PSR) */ +#define KWGBE_INTERFACE_GMII_MII 0 +#define KWGBE_INTERFACE_PCM 1 +#define KWGBE_LINK_IS_DOWN 0 +#define KWGBE_LINK_IS_UP (1 << 1) +#define KWGBE_PORT_AT_HALF_DUPLEX 0 +#define KWGBE_PORT_AT_FULL_DUPLEX (1 << 2) +#define KWGBE_RX_FLOW_CTRL_DISD 0 +#define KWGBE_RX_FLOW_CTRL_ENBALED (1 << 3) +#define KWGBE_GMII_SPEED_100_10 0 +#define KWGBE_GMII_SPEED_1000 (1 << 4) +#define KWGBE_MII_SPEED_10 0 +#define KWGBE_MII_SPEED_100 (1 << 5) +#define KWGBE_NO_TX 0 +#define KWGBE_TX_IN_PROGRESS (1 << 7) +#define KWGBE_BYPASS_NO_ACTIVE 0 +#define KWGBE_BYPASS_ACTIVE (1 << 8) +#define KWGBE_PORT_NOT_AT_PARTN_STT 0 +#define KWGBE_PORT_AT_PARTN_STT (1 << 9) +#define KWGBE_PORT_TX_FIFO_NOT_EMPTY 0 +#define KWGBE_PORT_TX_FIFO_EMPTY (1 << 10) + +/* These macros describes the Port configuration reg (Px_cR) bits */ +#define KWGBE_UCAST_MOD_NRML 0 +#define KWGBE_UNICAST_PROMISCUOUS_MODE 1 +#define KWGBE_DFLT_RX_Q0 0 +#define KWGBE_DFLT_RX_Q1 (1 << 1) +#define KWGBE_DFLT_RX_Q2 (1 << 2) +#define KWGBE_DFLT_RX_Q3 ((1 << 2) | (1 << 1)) +#define KWGBE_DFLT_RX_Q4 (1 << 3) +#define KWGBE_DFLT_RX_Q5 ((1 << 3) | (1 << 1)) +#define KWGBE_DFLT_RX_Q6 ((1 << 3) | (1 << 2)) +#define KWGBE_DFLT_RX_Q7 ((1 << 3) | (1 << 2) | (1 << 1)) +#define KWGBE_DFLT_RX_ARPQ0 0 +#define KWGBE_DFLT_RX_ARPQ1 (1 << 4) +#define KWGBE_DFLT_RX_ARPQ2 (1 << 5) +#define KWGBE_DFLT_RX_ARPQ3 ((1 << 5) | (1 << 4)) +#define KWGBE_DFLT_RX_ARPQ4 (1 << 6) +#define KWGBE_DFLT_RX_ARPQ5 ((1 << 6) | (1 << 4)) +#define KWGBE_DFLT_RX_ARPQ6 ((1 << 6) | (1 << 5)) +#define KWGBE_DFLT_RX_ARPQ7 ((1 << 6) | (1 << 5) | (1 << 4)) +#define KWGBE_RX_BC_IF_NOT_IP_OR_ARP 0 +#define KWGBE_REJECT_BC_IF_NOT_IP_OR_ARP (1 << 7) +#define KWGBE_RX_BC_IF_IP 0 +#define KWGBE_REJECT_BC_IF_IP (1 << 8) +#define KWGBE_RX_BC_IF_ARP 0 +#define KWGBE_REJECT_BC_IF_ARP (1 << 9) +#define KWGBE_TX_AM_NO_UPDATE_ERR_SMRY (1 << 12) +#define KWGBE_CPTR_TCP_FRMS_DIS 0 +#define KWGBE_CPTR_TCP_FRMS_EN (1 << 14) +#define KWGBE_CPTR_UDP_FRMS_DIS 0 +#define KWGBE_CPTR_UDP_FRMS_EN (1 << 15) +#define KWGBE_DFLT_RX_TCPQ0 0 +#define KWGBE_DFLT_RX_TCPQ1 (1 << 16) +#define KWGBE_DFLT_RX_TCPQ2 (1 << 17) +#define KWGBE_DFLT_RX_TCPQ3 ((1 << 17) | (1 << 16)) +#define KWGBE_DFLT_RX_TCPQ4 (1 << 18) +#define KWGBE_DFLT_RX_TCPQ5 ((1 << 18) | (1 << 16)) +#define KWGBE_DFLT_RX_TCPQ6 ((1 << 18) | (1 << 17)) +#define KWGBE_DFLT_RX_TCPQ7 ((1 << 18) | (1 << 17) | (1 << 16)) +#define KWGBE_DFLT_RX_UDPQ0 0 +#define KWGBE_DFLT_RX_UDPQ1 (1 << 19) +#define KWGBE_DFLT_RX_UDPQ2 (1 << 20) +#define KWGBE_DFLT_RX_UDPQ3 ((1 << 20) | (1 << 19)) +#define KWGBE_DFLT_RX_UDPQ4 (1 << 21) +#define KWGBE_DFLT_RX_UDPQ5 ((1 << 21) | (1 << 19)) +#define KWGBE_DFLT_RX_UDPQ6 ((1 << 21) | (1 << 20)) +#define KWGBE_DFLT_RX_UDPQ7 ((1 << 21) | (1 << 20) | (1 << 19)) +#define KWGBE_DFLT_RX_BPDU_Q_0 0 +#define KWGBE_DFLT_RX_BPDU_Q_1 (1 << 22) +#define KWGBE_DFLT_RX_BPDU_Q_2 (1 << 23) +#define KWGBE_DFLT_RX_BPDU_Q_3 ((1 << 23) | (1 << 22)) +#define KWGBE_DFLT_RX_BPDU_Q_4 (1 << 24) +#define KWGBE_DFLT_RX_BPDU_Q_5 ((1 << 24) | (1 << 22)) +#define KWGBE_DFLT_RX_BPDU_Q_6 ((1 << 24) | (1 << 23)) +#define KWGBE_DFLT_RX_BPDU_Q_7 ((1 << 24) | (1 << 23) | (1 << 22)) +#define KWGBE_DFLT_RX_TCP_CHKSUM_MODE (1 << 25) + +/* These macros describes the Port configuration extend reg (Px_cXR) bits*/ +#define KWGBE_CLASSIFY_EN 1 +#define KWGBE_SPAN_BPDU_PACKETS_AS_NORMAL 0 +#define KWGBE_SPAN_BPDU_PACKETS_TO_RX_Q7 (1 << 1) +#define KWGBE_PARTITION_DIS 0 +#define KWGBE_PARTITION_EN (1 << 2) +#define KWGBE_TX_CRC_GENERATION_EN 0 +#define KWGBE_TX_CRC_GENERATION_DIS (1 << 3) + +/* These macros describes the Port Sdma configuration reg (SDCR) bits */ +#define KWGBE_RIFB 1 +#define KWGBE_RX_BURST_SIZE_1_64BIT 0 +#define KWGBE_RX_BURST_SIZE_2_64BIT (1 << 1) +#define KWGBE_RX_BURST_SIZE_4_64BIT (1 << 2) +#define KWGBE_RX_BURST_SIZE_8_64BIT ((1 << 2) | (1 << 1)) +#define KWGBE_RX_BURST_SIZE_16_64BIT (1 << 3) +#define KWGBE_BLM_RX_NO_SWAP (1 << 4) +#define KWGBE_BLM_RX_BYTE_SWAP 0 +#define KWGBE_BLM_TX_NO_SWAP (1 << 5) +#define KWGBE_BLM_TX_BYTE_SWAP 0 +#define KWGBE_DESCRIPTORS_BYTE_SWAP (1 << 6) +#define KWGBE_DESCRIPTORS_NO_SWAP 0 +#define KWGBE_TX_BURST_SIZE_1_64BIT 0 +#define KWGBE_TX_BURST_SIZE_2_64BIT (1 << 22) +#define KWGBE_TX_BURST_SIZE_4_64BIT (1 << 23) +#define KWGBE_TX_BURST_SIZE_8_64BIT ((1 << 23) | (1 << 22)) +#define KWGBE_TX_BURST_SIZE_16_64BIT (1 << 24) + +/* These macros describes the Port serial control reg (PSCR) bits */ +#define KWGBE_SERIAL_PORT_DIS 0 +#define KWGBE_SERIAL_PORT_EN 1 +#define KWGBE_FORCE_LINK_PASS (1 << 1) +#define KWGBE_DO_NOT_FORCE_LINK_PASS 0 +#define KWGBE_EN_AUTO_NEG_FOR_DUPLX 0 +#define KWGBE_DIS_AUTO_NEG_FOR_DUPLX (1 << 2) +#define KWGBE_EN_AUTO_NEG_FOR_FLOW_CTRL 0 +#define KWGBE_DIS_AUTO_NEG_FOR_FLOW_CTRL (1 << 3) +#define KWGBE_ADV_NO_FLOW_CTRL 0 +#define KWGBE_ADV_SYMMETRIC_FLOW_CTRL (1 << 4) +#define KWGBE_FORCE_FC_MODE_NO_PAUSE_DIS_TX 0 +#define KWGBE_FORCE_FC_MODE_TX_PAUSE_DIS (1 << 5) +#define KWGBE_FORCE_BP_MODE_NO_JAM 0 +#define KWGBE_FORCE_BP_MODE_JAM_TX (1 << 7) +#define KWGBE_FORCE_BP_MODE_JAM_TX_ON_RX_ERR (1 << 8) +#define KWGBE_FORCE_LINK_FAIL 0 +#define KWGBE_DO_NOT_FORCE_LINK_FAIL (1 << 10) +#define KWGBE_DIS_AUTO_NEG_SPEED_GMII (1 << 13) +#define KWGBE_EN_AUTO_NEG_SPEED_GMII 0 +#define KWGBE_DTE_ADV_0 0 +#define KWGBE_DTE_ADV_1 (1 << 14) +#define KWGBE_MIIPHY_MAC_MODE 0 +#define KWGBE_MIIPHY_PHY_MODE (1 << 15) +#define KWGBE_AUTO_NEG_NO_CHANGE 0 +#define KWGBE_RESTART_AUTO_NEG (1 << 16) +#define KWGBE_MAX_RX_PACKET_1518BYTE 0 +#define KWGBE_MAX_RX_PACKET_1522BYTE (1 << 17) +#define KWGBE_MAX_RX_PACKET_1552BYTE (1 << 18) +#define KWGBE_MAX_RX_PACKET_9022BYTE ((1 << 18) | (1 << 17)) +#define KWGBE_MAX_RX_PACKET_9192BYTE (1 << 19) +#define KWGBE_MAX_RX_PACKET_9700BYTE ((1 << 19) | (1 << 17)) +#define KWGBE_SET_EXT_LOOPBACK (1 << 20) +#define KWGBE_CLR_EXT_LOOPBACK 0 +#define KWGBE_SET_FULL_DUPLEX_MODE (1 << 21) +#define KWGBE_SET_HALF_DUPLEX_MODE 0 +#define KWGBE_EN_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX (1 << 22) +#define KWGBE_DIS_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX 0 +#define KWGBE_SET_GMII_SPEED_TO_10_100 0 +#define KWGBE_SET_GMII_SPEED_TO_1000 (1 << 23) +#define KWGBE_SET_MII_SPEED_TO_10 0 +#define KWGBE_SET_MII_SPEED_TO_100 (1 << 24) + +/* SMI register fields (KWGBE_SMI_REG) */ +#define KWGBE_PHY_SMI_TIMEOUT 10000 +#define KWGBE_PHY_SMI_DATA_OFFS 0 /* Data */ +#define KWGBE_PHY_SMI_DATA_MASK (0xffff << KWGBE_PHY_SMI_DATA_OFFS) +#define KWGBE_PHY_SMI_DEV_ADDR_OFFS 16 /* PHY device address */ +#define KWGBE_PHY_SMI_DEV_ADDR_MASK (0x1f << KWGBE_PHY_SMI_DEV_ADDR_OFFS) +#define KWGBE_SMI_REG_ADDR_OFFS 21 /* PHY device reg addr */ +#define KWGBE_SMI_REG_ADDR_MASK (0x1f << KWGBE_SMI_REG_ADDR_OFFS) +#define KWGBE_PHY_SMI_OPCODE_OFFS 26 /* Write/Read opcode */ +#define KWGBE_PHY_SMI_OPCODE_MASK (3 << KWGBE_PHY_SMI_OPCODE_OFFS) +#define KWGBE_PHY_SMI_OPCODE_WRITE (0 << KWGBE_PHY_SMI_OPCODE_OFFS) +#define KWGBE_PHY_SMI_OPCODE_READ (1 << KWGBE_PHY_SMI_OPCODE_OFFS) +#define KWGBE_PHY_SMI_READ_VALID_MASK (1 << 27) /* Read Valid */ +#define KWGBE_PHY_SMI_BUSY_MASK (1 << 28) /* Busy */ + +/* SDMA command status fields macros */ +/* Tx & Rx descriptors status */ +#define KWGBE_ERROR_SUMMARY 1 + +/* Tx & Rx descriptors command */ +#define KWGBE_BUFFER_OWNED_BY_DMA (1 << 31) + +/* Tx descriptors status */ +#define KWGBE_LC_ERROR 0 +#define KWGBE_UR_ERROR (1 << 1) +#define KWGBE_RL_ERROR (1 << 2) +#define KWGBE_LLC_SNAP_FORMAT (1 << 9) + +/* Rx descriptors status */ +#define KWGBE_CRC_ERROR 0 +#define KWGBE_OVERRUN_ERROR (1 << 1) +#define KWGBE_MAX_FRAME_LENGTH_ERROR (1 << 2) +#define KWGBE_RESOURCE_ERROR ((1 << 2) | (1 << 1)) +#define KWGBE_VLAN_TAGGED (1 << 19) +#define KWGBE_BPDU_FRAME (1 << 20) +#define KWGBE_TCP_FRAME_OVER_IP_V_4 0 +#define KWGBE_UDP_FRAME_OVER_IP_V_4 (1 << 21) +#define KWGBE_OTHER_FRAME_TYPE (1 << 22) +#define KWGBE_LAYER_2_IS_KWGBE_V_2 (1 << 23) +#define KWGBE_FRAME_TYPE_IP_V_4 (1 << 24) +#define KWGBE_FRAME_HEADER_OK (1 << 25) +#define KWGBE_RX_LAST_DESC (1 << 26) +#define KWGBE_RX_FIRST_DESC (1 << 27) +#define KWGBE_UNKNOWN_DESTINATION_ADDR (1 << 28) +#define KWGBE_RX_EN_INTERRUPT (1 << 29) +#define KWGBE_LAYER_4_CHECKSUM_OK (1 << 30) + +/* Rx descriptors byte count */ +#define KWGBE_FRAME_FRAGMENTED (1 << 2) + +/* Tx descriptors command */ +#define KWGBE_LAYER_4_CHECKSUM_FIRST_DESC (1 << 10) +#define KWGBE_FRAME_SET_TO_VLAN (1 << 15) +#define KWGBE_TCP_FRAME 0 +#define KWGBE_UDP_FRAME (1 << 16) +#define KWGBE_GEN_TCP_UDP_CHECKSUM (1 << 17) +#define KWGBE_GEN_IP_V_4_CHECKSUM (1 << 18) +#define KWGBE_ZERO_PADDING (1 << 19) +#define KWGBE_TX_LAST_DESC (1 << 20) +#define KWGBE_TX_FIRST_DESC (1 << 21) +#define KWGBE_GEN_CRC (1 << 22) +#define KWGBE_TX_EN_INTERRUPT (1 << 23) +#define KWGBE_AUTO_MODE (1 << 30) + +/* Address decode parameters */ +/* Ethernet Base Address Register bits */ +#define EBAR_TARGET_DRAM 0x00000000 +#define EBAR_TARGET_DEVICE 0x00000001 +#define EBAR_TARGET_CBS 0x00000002 +#define EBAR_TARGET_PCI0 0x00000003 +#define EBAR_TARGET_PCI1 0x00000004 +#define EBAR_TARGET_CUNIT 0x00000005 +#define EBAR_TARGET_AUNIT 0x00000006 +#define EBAR_TARGET_GUNIT 0x00000007 + +/* Window attrib */ +#define EBAR_DRAM_CS0 0x00000E00 +#define EBAR_DRAM_CS1 0x00000D00 +#define EBAR_DRAM_CS2 0x00000B00 +#define EBAR_DRAM_CS3 0x00000700 + +/* DRAM Target interface */ +#define EBAR_DRAM_NO_CACHE_COHERENCY 0x00000000 +#define EBAR_DRAM_CACHE_COHERENCY_WT 0x00001000 +#define EBAR_DRAM_CACHE_COHERENCY_WB 0x00002000 + +/* Device Bus Target interface */ +#define EBAR_DEVICE_DEVCS0 0x00001E00 +#define EBAR_DEVICE_DEVCS1 0x00001D00 +#define EBAR_DEVICE_DEVCS2 0x00001B00 +#define EBAR_DEVICE_DEVCS3 0x00001700 +#define EBAR_DEVICE_BOOTCS3 0x00000F00 + +/* PCI Target interface */ +#define EBAR_PCI_BYTE_SWAP 0x00000000 +#define EBAR_PCI_NO_SWAP 0x00000100 +#define EBAR_PCI_BYTE_WORD_SWAP 0x00000200 +#define EBAR_PCI_WORD_SWAP 0x00000300 +#define EBAR_PCI_NO_SNOOP_NOT_ASSERT 0x00000000 +#define EBAR_PCI_NO_SNOOP_ASSERT 0x00000400 +#define EBAR_PCI_IO_SPACE 0x00000000 +#define EBAR_PCI_MEMORY_SPACE 0x00000800 +#define EBAR_PCI_REQ64_FORCE 0x00000000 +#define EBAR_PCI_REQ64_SIZE 0x00001000 + +/* Window access control */ +#define EWIN_ACCESS_NOT_ALLOWED 0 +#define EWIN_ACCESS_READ_ONLY 1 +#define EWIN_ACCESS_FULL ((1 << 1) | 1) + +/* structures represents Controller registers */ +struct kwgbe_barsz { + u32 bar; + u32 size; +}; + +struct kwgbe_rxcdp { + struct kwgbe_rxdesc *rxcdp; + u32 rxcdp_pad[3]; +}; + +struct kwgbe_tqx { + u32 qxttbc; + u32 tqxtbc; + u32 tqxac; + u32 tqxpad; +}; + +struct kwgbe_registers { + u32 phyadr; + u32 smi; + u32 euda; + u32 eudid; + u8 pad1[0x080 - 0x00c - 4]; + u32 euic; + u32 euim; + u8 pad2[0x094 - 0x084 - 4]; + u32 euea; + u32 euiae; + u8 pad3[0x0b0 - 0x098 - 4]; + u32 euc; + u8 pad3a[0x200 - 0x0b0 - 4]; + struct kwgbe_barsz barsz[6]; + u8 pad4[0x280 - 0x22c - 4]; + u32 ha_remap[4]; + u32 bare; + u32 epap; + u8 pad5[0x400 - 0x294 - 4]; + u32 pxc; + u32 pxcx; + u32 mii_ser_params; + u8 pad6[0x410 - 0x408 - 4]; + u32 evlane; + u32 macal; + u32 macah; + u32 sdc; + u32 dscp[7]; + u32 psc0; + u32 vpt2p; + u32 ps0; + u32 tqc; + u32 psc1; + u32 ps1; + u32 mrvl_header; + u8 pad7[0x460 - 0x454 - 4]; + u32 ic; + u32 ice; + u32 pim; + u32 peim; + u8 pad8[0x474 - 0x46c - 4]; + u32 pxtfut; + u32 pad9; + u32 pxmfs; + u32 pad10; + u32 pxdfc; + u32 pxofc; + u8 pad11[0x494 - 0x488 - 4]; + u32 peuiae; + u8 pad12[0x4bc - 0x494 - 4]; + u32 eth_type_prio; + u8 pad13[0x4dc - 0x4bc - 4]; + u32 tqfpc; + u32 pttbrc; + u32 tqc1; + u32 pmtu; + u32 pmtbs; + u8 pad14[0x60c - 0x4ec - 4]; + struct kwgbe_rxcdp rxcdp[7]; + u32 rxcdp7; + u32 rqc; + struct kwgbe_txdesc *tcsdp; + u8 pad15[0x6c0 - 0x684 - 4]; + struct kwgbe_txdesc *tcqdp[8]; + u8 pad16[0x700 - 0x6dc - 4]; + struct kwgbe_tqx tqx[8]; + u32 pttbc; + u8 pad17[0x7a8 - 0x780 - 4]; + u32 tqxipg0; + u32 pad18[3]; + u32 tqxipg1; + u8 pad19[0x7c0 - 0x7b8 - 4]; + u32 hitkninlopkt; + u32 hitkninasyncpkt; + u32 lotkninasyncpkt; + u32 pad20; + u32 ts; + u8 pad21[0x3000 - 0x27d0 - 4]; + u32 pad20_1[32]; /* mib counter registes */ + u8 pad22[0x3400 - 0x3000 - sizeof(u32) * 32]; + u32 dfsmt[64]; + u32 dfomt[64]; + u32 dfut[4]; + u8 pad23[0xe20c0 - 0x7360c - 4]; + u32 pmbus_top_arbiter; +}; + +/* structures/enums needed by driver */ +enum kwgbe_adrwin { + KWGBE_WIN0, + KWGBE_WIN1, + KWGBE_WIN2, + KWGBE_WIN3, + KWGBE_WIN4, + KWGBE_WIN5 +}; + +enum kwgbe_target { + KWGBE_TARGET_DRAM, + KWGBE_TARGET_DEV, + KWGBE_TARGET_CBS, + KWGBE_TARGET_PCI0, + KWGBE_TARGET_PCI1 +}; + +struct kwgbe_winparam { + enum kwgbe_adrwin win; /* Window number */ + enum kwgbe_target target; /* System targets */ + u16 attrib; /* BAR attrib. See above macros */ + u32 base_addr; /* Window base address in u32 form */ + u32 high_addr; /* Window high address in u32 form */ + u32 size; /* Size in MBytes. Must be % 64Kbyte. */ + int enable; /* Enable/disable access to the window. */ + u16 access_ctrl; /*Access ctrl register. see above macros */ +}; + +struct kwgbe_rxdesc { + u32 cmd_sts; /* Descriptor command status */ + u16 buf_size; /* Buffer size */ + u16 byte_cnt; /* Descriptor buffer byte count */ + u8 *buf_ptr; /* Descriptor buffer pointer */ + struct kwgbe_rxdesc *nxtdesc_p; /* Next descriptor pointer */ +}; + +struct kwgbe_txdesc { + u32 cmd_sts; /* Descriptor command status */ + u16 l4i_chk; /* CPU provided TCP Checksum */ + u16 byte_cnt; /* Descriptor buffer byte count */ + u8 *buf_ptr; /* Descriptor buffer ptr */ + struct kwgbe_txdesc *nxtdesc_p; /* Next descriptor ptr */ +}; + +/* port device data struct */ +struct kwgbe_device { + struct eth_device dev; + struct kwgbe_registers *regs; + struct kwgbe_txdesc *p_txdesc; + struct kwgbe_rxdesc *p_rxdesc; + struct kwgbe_rxdesc *p_rxdesc_curr; + u8 *p_rxbuf; +}; + +#endif /* __EGIGA_H__ */ diff --git a/include/netdev.h b/include/netdev.h index f37b6ae..3a59f4e 100644 --- a/include/netdev.h +++ b/include/netdev.h @@ -52,6 +52,7 @@ int fec_initialize (bd_t *bis); int greth_initialize(bd_t *bis); void gt6426x_eth_initialize(bd_t *bis); int inca_switch_initialize(bd_t *bis); +int kirkwood_egiga_initialize(bd_t *bis); int macb_eth_initialize(int id, void *regs, unsigned int phy_addr); int mcdmafec_initialize(bd_t *bis); int mcffec_initialize(bd_t *bis);

Dear Prafulla Wadaskar,
In message 1243626217-9232-6-git-send-email-prafulla@marvell.com you wrote:
This patch adds a egiga driver for the Marvell Kirkwood SoC's.
...
- /* check parameters */
- if ((phy_adr << KWGBE_PHY_SMI_DEV_ADDR_OFFS) &
~KWGBE_PHY_SMI_DEV_ADDR_MASK) {
printf("Illegal phy address\n");
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
return -EINVAL;
- }
- if ((reg_ofs << KWGBE_SMI_REG_ADDR_OFFS) &
~KWGBE_SMI_REG_ADDR_MASK) {
printf("Illegal register offset\n");
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If you priont an error message, please print a helpful one, i. e. provide the information what failed the test, and why.
+static int kwgbe_send(struct eth_device *dev, volatile void *dataptr, int datasize) +{
- struct kwgbe_device *dkwgbe = to_dkwgbe(dev);
- struct kwgbe_registers *regs = dkwgbe->regs;
- struct kwgbe_txdesc *p_txdesc = dkwgbe->p_txdesc;
- if ((u32)dataptr &0x07) {
printf("Err..xmit dataptr not 64bit aligned\n");
Ditto. The user does not even know which driver this is coming from.
Also, please write "dataptr & 0x07".
- while (p_txdesc->cmd_sts & KWGBE_BUFFER_OWNED_BY_DMA) {
/* return fail if error is detected */
if (p_txdesc->cmd_sts & (KWGBE_UR_ERROR | KWGBE_RL_ERROR)) {
printf("Err..in xmit packet\n");
Ditto.
+static int kwgbe_recv(struct eth_device *dev) +{
- volatile struct kwgbe_device *dkwgbe = to_dkwgbe(dev);
- volatile struct kwgbe_rxdesc *p_rxdesc_curr= dkwgbe->p_rxdesc_curr;
- /* Sanity check */
- if (p_rxdesc_curr == NULL) {
printf("Err.. null ptr \n");
Please do not print trailing white space.
Also, this error message could be more helpful if you printed where it happened, and which pointer was unexpectedly NULL.
And so on - please check rest of this file, and all other files for _helpful_ error messages.
Best regards,
Wolfgang Denk

On 01:13 Sat 30 May , Prafulla Wadaskar wrote:
This patch adds a SPI driver for the Marvell Kirkwood SoC's.
Signed-off-by: Prafulla Wadaskar prafulla@marvell.com
Looks fine
Andy fot you?
Best Regards, J.

...My first pass says this patch doesn't touch on my domain. Is there something I'm missing?
On Fri, May 29, 2009 at 5:24 PM, Jean-Christophe PLAGNIOL-VILLARD < plagnioj@jcrosoft.com> wrote:
On 01:13 Sat 30 May , Prafulla Wadaskar wrote:
This patch adds a SPI driver for the Marvell Kirkwood SoC's.
Signed-off-by: Prafulla Wadaskar prafulla@marvell.com
Looks fine
Andy fot you?
Best Regards, J. _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

Dear Prafulla Wadaskar,
In message 1243626217-9232-4-git-send-email-prafulla@marvell.com you wrote:
This patch adds a SPI driver for the Marvell Kirkwood SoC's.
- /* program spi clock prescaller using max_hz */
- writel(KWSPI_ADRLEN_3BYTE | data, &spireg->cfg);
- debug("data = 0x%08x \n", data);
Please do not print trailing white space.
Best regards,
Wolfgang Denk

This patch adds a SPI driver for the Marvell Kirkwood SoC's.
Signed-off-by: Prafulla Wadaskar prafulla@marvell.com --- Change log: v2: White space in debug print removed
drivers/spi/Makefile | 1 + drivers/spi/kirkwood_spi.c | 185 +++++++++++++++++++++++++++++++++++ include/asm-arm/arch-kirkwood/spi.h | 56 +++++++++++ 3 files changed, 242 insertions(+), 0 deletions(-) create mode 100644 drivers/spi/kirkwood_spi.c create mode 100644 include/asm-arm/arch-kirkwood/spi.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..a1c3070 --- /dev/null +++ b/drivers/spi/kirkwood_spi.c @@ -0,0 +1,185 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Written-by: 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/spi.h b/include/asm-arm/arch-kirkwood/spi.h new file mode 100644 index 0000000..1d5043f --- /dev/null +++ b/include/asm-arm/arch-kirkwood/spi.h @@ -0,0 +1,56 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Written-by: 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__ */

On 01:13 Sat 30 May , Prafulla Wadaskar wrote:
This patch adds a SPI driver for the Marvell Kirkwood SoC's.
Signed-off-by: Prafulla Wadaskar prafulla@marvell.com
drivers/spi/Makefile | 1 + drivers/spi/kirkwood_spi.c | 185 +++++++++++++++++++++++++++++++++++ include/asm-arm/arch-kirkwood/spi.h | 56 +++++++++++ 3 files changed, 242 insertions(+), 0 deletions(-) create mode 100644 drivers/spi/kirkwood_spi.c create mode 100644 include/asm-arm/arch-kirkwood/spi.h
applied to u-boot-arm
Best Regards, J.

Thanks Jean...
Regards.. Prafulla . .
-----Original Message----- From: Jean-Christophe PLAGNIOL-VILLARD [mailto:plagnioj@jcrosoft.com] Sent: Friday, June 26, 2009 4:30 AM To: Prafulla Wadaskar Cc: u-boot@lists.denx.de; Manas Saksena; Ronen Shitrit; Nicolas Pitre; Ashish Karkare; Prabhanjan Sarnaik; Lennert Buijtenhek Subject: Re: [U-Boot] [PATCH] spi: Add Marvell Kirkwood SPI driver
On 01:13 Sat 30 May , Prafulla Wadaskar wrote:
This patch adds a SPI driver for the Marvell Kirkwood SoC's.
Signed-off-by: Prafulla Wadaskar prafulla@marvell.com
drivers/spi/Makefile | 1 + drivers/spi/kirkwood_spi.c | 185
+++++++++++++++++++++++++++++++++++
include/asm-arm/arch-kirkwood/spi.h | 56 +++++++++++ 3 files changed, 242 insertions(+), 0 deletions(-) create mode 100644 drivers/spi/kirkwood_spi.c create mode 100644 include/asm-arm/arch-kirkwood/spi.h
applied to u-boot-arm
Best Regards, J.

-----Original Message----- From: u-boot-bounces@lists.denx.de [mailto:u-boot-bounces@lists.denx.de] On Behalf Of Prafulla Wadaskar Sent: Friday, June 26, 2009 11:28 AM To: Jean-Christophe PLAGNIOL-VILLARD Cc: Manas Saksena; Ronen Shitrit; Nicolas Pitre; u-boot@lists.denx.de; Ashish Karkare; Prabhanjan Sarnaik; Lennert Buijtenhek Subject: Re: [U-Boot] [PATCH] spi: Add Marvell Kirkwood SPI driver
Thanks Jean...
Regards.. Prafulla . .
-----Original Message----- From: Jean-Christophe PLAGNIOL-VILLARD
[mailto:plagnioj@jcrosoft.com]
Sent: Friday, June 26, 2009 4:30 AM To: Prafulla Wadaskar Cc: u-boot@lists.denx.de; Manas Saksena; Ronen Shitrit;
Nicolas Pitre;
Ashish Karkare; Prabhanjan Sarnaik; Lennert Buijtenhek Subject: Re: [U-Boot] [PATCH] spi: Add Marvell Kirkwood SPI driver
On 01:13 Sat 30 May , Prafulla Wadaskar wrote:
This patch adds a SPI driver for the Marvell Kirkwood SoC's.
Signed-off-by: Prafulla Wadaskar prafulla@marvell.com
drivers/spi/Makefile | 1 + drivers/spi/kirkwood_spi.c | 185
+++++++++++++++++++++++++++++++++++
include/asm-arm/arch-kirkwood/spi.h | 56 +++++++++++ 3 files changed, 242 insertions(+), 0 deletions(-) create mode 100644 drivers/spi/kirkwood_spi.c create mode 100644 include/asm-arm/arch-kirkwood/spi.h
applied to u-boot-arm
Hi Jean,
On which branch it is applied?, I could not find it on arm/next...
Regards.. Prafulla . . .
Best Regards, J.
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

On 20:52 Fri 26 Jun , Prafulla Wadaskar wrote:
-----Original Message----- From: u-boot-bounces@lists.denx.de [mailto:u-boot-bounces@lists.denx.de] On Behalf Of Prafulla Wadaskar Sent: Friday, June 26, 2009 11:28 AM To: Jean-Christophe PLAGNIOL-VILLARD Cc: Manas Saksena; Ronen Shitrit; Nicolas Pitre; u-boot@lists.denx.de; Ashish Karkare; Prabhanjan Sarnaik; Lennert Buijtenhek Subject: Re: [U-Boot] [PATCH] spi: Add Marvell Kirkwood SPI driver
Thanks Jean...
Regards.. Prafulla . .
-----Original Message----- From: Jean-Christophe PLAGNIOL-VILLARD
[mailto:plagnioj@jcrosoft.com]
Sent: Friday, June 26, 2009 4:30 AM To: Prafulla Wadaskar Cc: u-boot@lists.denx.de; Manas Saksena; Ronen Shitrit;
Nicolas Pitre;
Ashish Karkare; Prabhanjan Sarnaik; Lennert Buijtenhek Subject: Re: [U-Boot] [PATCH] spi: Add Marvell Kirkwood SPI driver
On 01:13 Sat 30 May , Prafulla Wadaskar wrote:
This patch adds a SPI driver for the Marvell Kirkwood SoC's.
Signed-off-by: Prafulla Wadaskar prafulla@marvell.com
drivers/spi/Makefile | 1 + drivers/spi/kirkwood_spi.c | 185
+++++++++++++++++++++++++++++++++++
include/asm-arm/arch-kirkwood/spi.h | 56 +++++++++++ 3 files changed, 242 insertions(+), 0 deletions(-) create mode 100644 drivers/spi/kirkwood_spi.c create mode 100644 include/asm-arm/arch-kirkwood/spi.h
applied to u-boot-arm
Hi Jean,
On which branch it is applied?, I could not find it on arm/next...
master
next or testing is still for dev as the master will not build for mtd stuff
Best Regards, J.

Prafulla Wadaskar
Sent: Friday, June 26, 2009 11:28 AM To: Jean-Christophe PLAGNIOL-VILLARD Cc: Manas Saksena; Ronen Shitrit; Nicolas Pitre; u-boot@lists.denx.de; Ashish Karkare; Prabhanjan Sarnaik; Lennert Buijtenhek Subject: Re: [U-Boot] [PATCH] spi: Add Marvell Kirkwood SPI driver
applied to u-boot-arm
Hi Jean,
On which branch it is applied?, I could not find it on arm/next...
master
next or testing is still for dev as the master will not build for mtd stuff
Thanks jean I could see it now :)
Regards.. Prafulla . .

- 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);
any chance to have some macro for the 0x90000000 & co...
other fine
Best Regards, J.

-----Original Message----- From: Jean-Christophe PLAGNIOL-VILLARD [mailto:plagnioj@jcrosoft.com] Sent: Saturday, May 30, 2009 3:52 AM To: Prafulla Wadaskar Cc: u-boot@lists.denx.de; Manas Saksena; Ronen Shitrit; Nicolas Pitre; Ashish Karkare; Prabhanjan Sarnaik; Lennert Buijtenhek Subject: Re: [U-Boot] [PATCH] arm: Kirkwood: Basic SOCs support
- 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);
any chance to have some macro for the 0x90000000 & co...
Hi Jean, Base address, remap address high, remap address low are the registers need to be programmed with some address value. Making it macro will not make much sense since the code line itself is readable for objective
other fine
Please make it everything fine :-) Waiting eagerly for acceptance
Regards.. Prafulla ..
Best Regards, J.

On 00:16 Sat 30 May , Prafulla Wadaskar wrote:
-----Original Message----- From: Jean-Christophe PLAGNIOL-VILLARD [mailto:plagnioj@jcrosoft.com] Sent: Saturday, May 30, 2009 3:52 AM To: Prafulla Wadaskar Cc: u-boot@lists.denx.de; Manas Saksena; Ronen Shitrit; Nicolas Pitre; Ashish Karkare; Prabhanjan Sarnaik; Lennert Buijtenhek Subject: Re: [U-Boot] [PATCH] arm: Kirkwood: Basic SOCs support
- 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);
any chance to have some macro for the 0x90000000 & co...
Hi Jean, Base address, remap address high, remap address low are the registers need to be programmed with some address value. Making it macro will not make much sense since the code line itself is readable for objective
so please explain this in the code
Best Regards, J.

Kirkwood family controllers are highly integrated SOCs based on Feroceon-88FR131/Sheeva-88SV131/arm926ejs 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) PCI Express port initialization 3) NS16550 driver support
Contributors: Yotam Admon yotam@marvell.com Michael Blostein <michaelbl@marvell.com
Reviewed-by: Ronen Shitrit rshitrit@marvell.com Acked-by: Stefan Rose sr@denx.de Signed-off-by: Prafulla Wadaskar prafulla@marvell.com --- Change log: v2: explained cpu winregs programming, defined macros too.
cpu/arm926ejs/kirkwood/Makefile | 49 +++++ cpu/arm926ejs/kirkwood/cpu.c | 315 +++++++++++++++++++++++++++++ cpu/arm926ejs/kirkwood/dram.c | 58 ++++++ cpu/arm926ejs/kirkwood/mpp.c | 80 ++++++++ cpu/arm926ejs/kirkwood/timer.c | 168 +++++++++++++++ drivers/serial/serial.c | 3 + include/asm-arm/arch-kirkwood/cpu.h | 159 +++++++++++++++ include/asm-arm/arch-kirkwood/kirkwood.h | 69 +++++++ include/asm-arm/arch-kirkwood/kw88f6192.h | 37 ++++ include/asm-arm/arch-kirkwood/kw88f6281.h | 37 ++++ include/asm-arm/arch-kirkwood/mpp.h | 303 +++++++++++++++++++++++++++ 11 files changed, 1278 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 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
diff --git a/cpu/arm926ejs/kirkwood/Makefile b/cpu/arm926ejs/kirkwood/Makefile new file mode 100644 index 0000000..d73e210 --- /dev/null +++ b/cpu/arm926ejs/kirkwood/Makefile @@ -0,0 +1,49 @@ +# +# (C) Copyright 2009 +# Marvell Semiconductor <www.marvell.com> +# Written-by: 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..32e95d2 --- /dev/null +++ b/cpu/arm926ejs/kirkwood/cpu.c @@ -0,0 +1,315 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Written-by: 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 ones followed by + * sequence of zeros. The number of ones 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; + u32 val = sizeval >> 1; + + for (i = 0; val > 0x10000; i++) { + j |= (1 << i); + val = val >> 1; + } + 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 8 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 + * + * If remap function not used, remap_lo must be set as base + * + * 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; + + /* Window 0: PCIE MEM address space */ + writel(KWCPU_WIN_CTRL_DATA(1024 * 1024 * 256, KWCPU_TARGET_PCIE, + KWCPU_ATTR_PCIE_MEM, KWCPU_WIN_ENABLE), &winregs[0].ctrl); + + writel(KW_DEFADR_PCI_MEM, &winregs[0].base); + writel(KW_DEFADR_PCI_MEM, &winregs[0].remap_lo); + writel(0x0, &winregs[0].remap_hi); + + /* Window 1: PCIE IO address space */ + writel(KWCPU_WIN_CTRL_DATA(1024 * 64, KWCPU_TARGET_PCIE, + KWCPU_ATTR_PCIE_IO, KWCPU_WIN_ENABLE), &winregs[1].ctrl); + writel(KW_DEFADR_PCI_IO, &winregs[1].base); + writel(KW_DEFADR_PCI_IO_REMAP, &winregs[1].remap_lo); + writel(0x0, &winregs[1].remap_hi); + + /* Window 2: NAND Flash address space */ + writel(KWCPU_WIN_CTRL_DATA(1024 * 1024 * 128, KWCPU_TARGET_MEMORY, + KWCPU_ATTR_NANDFLASH, KWCPU_WIN_ENABLE), &winregs[2].ctrl); + writel(KW_DEFADR_NANDF, &winregs[2].base); + writel(KW_DEFADR_NANDF, &winregs[2].remap_lo); + writel(0x0, &winregs[2].remap_hi); + + /* Window 3: SPI Flash address space */ + writel(KWCPU_WIN_CTRL_DATA(1024 * 1024 * 128, KWCPU_TARGET_MEMORY, + KWCPU_ATTR_SPIFLASH, KWCPU_WIN_ENABLE), &winregs[3].ctrl); + writel(KW_DEFADR_SPIF, &winregs[3].base); + writel(KW_DEFADR_SPIF, &winregs[3].remap_lo); + writel(0x0, &winregs[3].remap_hi); + + /* Window 4: BOOT Memory address space */ + writel(KWCPU_WIN_CTRL_DATA(1024 * 1024 * 128, KWCPU_TARGET_MEMORY, + KWCPU_ATTR_BOOTROM, KWCPU_WIN_ENABLE), &winregs[4].ctrl); + writel(KW_DEFADR_BOOTROM, &winregs[4].base); + + /* Window 5: Security SRAM address space */ + writel(KWCPU_WIN_CTRL_DATA(1024 * 64, KWCPU_TARGET_SASRAM, + KWCPU_ATTR_SASRAM, KWCPU_WIN_ENABLE), &winregs[5].ctrl); + writel(KW_DEFADR_SASRAM, &winregs[5].base); + + /* Window 6-7: Disabled */ + writel(KWCPU_WIN_DISABLE, &winregs[6].ctrl); + writel(KWCPU_WIN_DISABLE, &winregs[7].ctrl); + + 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 */ + +#ifdef CONFIG_KIRKWOOD_EGIGA +int cpu_eth_init(bd_t *bis) +{ + kirkwood_egiga_initialize(bis); + return 0; +} +#endif diff --git a/cpu/arm926ejs/kirkwood/dram.c b/cpu/arm926ejs/kirkwood/dram.c new file mode 100644 index 0000000..8f2a18a --- /dev/null +++ b/cpu/arm926ejs/kirkwood/dram.c @@ -0,0 +1,58 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Written-by: 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..817ff42 --- /dev/null +++ b/cpu/arm926ejs/kirkwood/timer.c @@ -0,0 +1,168 @@ +/* + * Copyright (C) Marvell International Ltd. and its affiliates + * Written-by: 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/include/asm-arm/arch-kirkwood/cpu.h b/include/asm-arm/arch-kirkwood/cpu.h new file mode 100644 index 0000000..e3b96a8 --- /dev/null +++ b/include/asm-arm/arch-kirkwood/cpu.h @@ -0,0 +1,159 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Written-by: 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 +}; + +/* + * Default Device Address MAP BAR values + */ +#define KW_DEFADR_PCI_MEM 0x90000000 +#define KW_DEFADR_PCI_IO 0xC0000000 +#define KW_DEFADR_PCI_IO_REMAP 0xC0000000 +#define KW_DEFADR_SASRAM 0xC8010000 +#define KW_DEFADR_NANDF 0xD8000000 +#define KW_DEFADR_SPIF 0xE8000000 +#define KW_DEFADR_BOOTROM 0xF8000000 + +/* + * 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(); +} + +/* + * MBus-L to Mbus Bridge Registers + * Ref: Datasheet sec:A.3 + */ +struct kwwin_registers { + u32 ctrl; + u32 base; + u32 remap_lo; + u32 remap_hi; +}; + +/* + * CPU control and status Registers + * Ref: Datasheet sec:A.3.2 + */ +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 */ +}; + +/* + * GPIO Registers + * Ref: Datasheet sec:A.19 + */ +struct kwgpio_registers { + u32 dout; + u32 oe; + u32 blink_en; + u32 din_pol; + u32 din; + u32 irq_cause; + u32 irq_mask; + u32 irq_level; +}; + +/* + * 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..d5f25f9 --- /dev/null +++ b/include/asm-arm/arch-kirkwood/kirkwood.h @@ -0,0 +1,69 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Written-by: Prafulla Wadaskar prafulla@marvell.com + * + * Header file for the Marvell's Feroceon CPU core. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef _ASM_ARCH_KIRKWOOD_H +#define _ASM_ARCH_KIRKWOOD_H + +#ifndef __ASSEMBLY__ +#include <asm/types.h> +#include <asm/io.h> +#endif /* __ASSEMBLY__ */ + +#if defined (CONFIG_FEROCEON_88FR131) || defined (CONFIG_SHEEVA_88SV131) +#include <asm/arch/cpu.h> + +/* SOC specific definations */ +#define INTREG_BASE 0xd0000000 +#define KW_REGISTER(x) (KW_REGS_PHY_BASE + x) +#define KW_OFFSET_REG (INTREG_BASE + 0x20080) + +/* undocumented registers */ +#define KW_REG_UNDOC_0x1470 (KW_REGISTER(0x1470)) +#define KW_REG_UNDOC_0x1478 (KW_REGISTER(0x1478)) + +#define KW_UART0_BASE (KW_REGISTER(0x12000)) +#define KW_UART1_BASE (KW_REGISTER(0x13000)) +#define KW_MPP_BASE (KW_REGISTER(0x10000)) +#define KW_GPIO0_BASE (KW_REGISTER(0x10100)) +#define KW_GPIO1_BASE (KW_REGISTER(0x10140)) +#define KW_NANDF_BASE (KW_REGISTER(0x10418)) +#define KW_SPI_BASE (KW_REGISTER(0x10600)) +#define KW_CPU_WIN_BASE (KW_REGISTER(0x20000)) +#define KW_CPU_REG_BASE (KW_REGISTER(0x20100)) +#define KW_TIMER_BASE (KW_REGISTER(0x20300)) +#define KW_REG_PCIE_BASE (KW_REGISTER(0x40000)) +#define KW_EGIGA0_BASE (KW_REGISTER(0x72000)) +#define KW_EGIGA1_BASE (KW_REGISTER(0x76000)) + +#if defined (CONFIG_KW88F6281) +#include <asm/arch/kw88f6281.h> +#elif defined (CONFIG_KW88F6192) +#include <asm/arch/kw88f6192.h> +#else +#error "SOC Name not defined" +#endif /* CONFIG_KW88F6281 */ +#endif /* CONFIG_FEROCEON_88FR131 */ +#endif /* _ASM_ARCH_KIRKWOOD_H */ diff --git a/include/asm-arm/arch-kirkwood/kw88f6192.h b/include/asm-arm/arch-kirkwood/kw88f6192.h new file mode 100644 index 0000000..bbb7cee --- /dev/null +++ b/include/asm-arm/arch-kirkwood/kw88f6192.h @@ -0,0 +1,37 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Written-by: 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..80723ea --- /dev/null +++ b/include/asm-arm/arch-kirkwood/kw88f6281.h @@ -0,0 +1,37 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Written-by: 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

Hi Jean
I have added macros and put some comments in kw_config_adr_windows() for better readability Also I have given references from datasheet too.
This was the only feedback from the last patch. I Hope this patch is clean to apply So please kindly review and apply the same
Regards.. Prafulla . .
-----Original Message----- From: Prafulla Wadaskar [mailto:prafulla@marvell.com] Sent: Tuesday, June 02, 2009 3:17 PM To: u-boot@lists.denx.de Cc: Nicolas Pitre; Manas Saksena; Lennert Buijtenhek; Prabhanjan Sarnaik; Ronen Shitrit; Ashish Karkare; Prafulla Wadaskar Subject: [PATCH v1] arm: Kirkwood: Basic SOCs support
Kirkwood family controllers are highly integrated SOCs based on Feroceon-88FR131/Sheeva-88SV131/arm926ejs cpu core.
SOC versions supported:-
- 88F6281-A0 define CONFIG_KW88F6281_A0
- 88F6192-A0 define CONFIG_KW88F6192_A0
Other supported features:-
- get_random_hex() fucntion
- PCI Express port initialization
- NS16550 driver support
Contributors: Yotam Admon yotam@marvell.com Michael Blostein <michaelbl@marvell.com
Reviewed-by: Ronen Shitrit rshitrit@marvell.com Acked-by: Stefan Rose sr@denx.de Signed-off-by: Prafulla Wadaskar prafulla@marvell.com
Change log: v2: explained cpu winregs programming, defined macros too.

On 15:16 Tue 02 Jun , Prafulla Wadaskar wrote:
Kirkwood family controllers are highly integrated SOCs based on Feroceon-88FR131/Sheeva-88SV131/arm926ejs cpu core.
SOC versions supported:-
- 88F6281-A0 define CONFIG_KW88F6281_A0
- 88F6192-A0 define CONFIG_KW88F6192_A0
Other supported features:-
- get_random_hex() fucntion
- PCI Express port initialization
- NS16550 driver support
Contributors: Yotam Admon yotam@marvell.com Michael Blostein <michaelbl@marvell.com
Reviewed-by: Ronen Shitrit rshitrit@marvell.com Acked-by: Stefan Rose sr@denx.de Signed-off-by: Prafulla Wadaskar prafulla@marvell.com
Change log: v2: explained cpu winregs programming, defined macros too.
cpu/arm926ejs/kirkwood/Makefile | 49 +++++ cpu/arm926ejs/kirkwood/cpu.c | 315 +++++++++++++++++++++++++++++ cpu/arm926ejs/kirkwood/dram.c | 58 ++++++ cpu/arm926ejs/kirkwood/mpp.c | 80 ++++++++ cpu/arm926ejs/kirkwood/timer.c | 168 +++++++++++++++ drivers/serial/serial.c | 3 + include/asm-arm/arch-kirkwood/cpu.h | 159 +++++++++++++++ include/asm-arm/arch-kirkwood/kirkwood.h | 69 +++++++ include/asm-arm/arch-kirkwood/kw88f6192.h | 37 ++++ include/asm-arm/arch-kirkwood/kw88f6281.h | 37 ++++ include/asm-arm/arch-kirkwood/mpp.h | 303 +++++++++++++++++++++++++++ 11 files changed, 1278 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 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
applied to arm/next
Best Regards, J.

-----Original Message----- From: Jean-Christophe PLAGNIOL-VILLARD [mailto:plagnioj@jcrosoft.com] Sent: Sunday, June 07, 2009 5:27 PM To: Prafulla Wadaskar Cc: u-boot@lists.denx.de; Manas Saksena; Ronen Shitrit; Nicolas Pitre; Ashish Karkare; Prabhanjan Sarnaik; Lennert Buijtenhek Subject: Re: [U-Boot] [PATCH v1] arm: Kirkwood: Basic SOCs support
On 15:16 Tue 02 Jun , Prafulla Wadaskar wrote:
Kirkwood family controllers are highly integrated SOCs based on Feroceon-88FR131/Sheeva-88SV131/arm926ejs cpu core.
applied to arm/next
Thanks Jean.
Regards.. Prafulla . .

Hi Jean Thanks for accepting my earlier patch "arch_misc_init support for ARM architectures" Can you please re-think for this patch too. This patch is nothing but outcome of our earlier discussion/abstraction to create Generic Cache header for ARM
Also kirkwood Soc support patches are almost done (I think so :-) ) Kirkwood users are very keen to use them right from next release
How I can assist you to get them through? Shall I resubmit them with the dependency follow-up as suggested by Wolfgang? Reference : http://lists.denx.de/pipermail/u-boot/2009-May/053509.html
Regards.. Prafulla . .
-----Original Message----- From: Prafulla Wadaskar [mailto:prafulla@marvell.com] Sent: Saturday, May 30, 2009 1:14 AM To: u-boot@lists.denx.de Cc: Nicolas Pitre; Manas Saksena; Lennert Buijtenhek; Prabhanjan Sarnaik; Ronen Shitrit; Ashish Karkare; Prafulla Wadaskar Subject: [PATCH] arm: generic cache.h for ARM architectures
This patch is required for Kirkwood SoC support may be used by other ARM architectures
Signed-off-by: Prafulla Wadaskar prafulla@marvell.com
include/asm-arm/cache.h | 41 +++++++++++++++++++++++++++++++++++++++++ 1 files changed, 41 insertions(+), 0 deletions(-) create mode 100644 include/asm-arm/cache.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>
- Written-by: 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 */
1.5.3.3

On 01:13 Sat 30 May , Prafulla Wadaskar wrote:
This patch is required for Kirkwood SoC support may be used by other ARM architectures
Signed-off-by: Prafulla Wadaskar prafulla@marvell.com
applied to arm/next
Best Regards, J.

Dear Prafulla Wadaskar,
In message 1243626217-9232-1-git-send-email-prafulla@marvell.com you wrote:
This patch is required for Kirkwood support may be used by other ARM architectures
I see some (8 ?) patches posted as follow-up - are these supposed to be a series, i. e. do they in any way depend on each other, or need to be applied in a specific order? If so, then please post as numbered patches.
Best regards,
Wolfgang Denk
participants (7)
-
Andy Fleming
-
Ben Warren
-
Jean-Christophe PLAGNIOL-VILLARD
-
Mike Frysinger
-
Prafulla Wadaskar
-
Scott Wood
-
Wolfgang Denk