From 74d47c78ff59fe0520e602031957328be0db5061 Mon Sep 17 00:00:00 2001 From: Sipke Vriend Date: Fri, 5 Jul 2013 13:51:50 +1000 Subject: u-boot: Add yocto u-boot plus patches. Provide u-boot_v2013.01.01 with Xilinx specific patches for xilinx-v2013.01 Required small changes to common include files so they can be shared between u-boot and u-boot-xlnx. Signed-off-by: Sipke Vriend --- recipes-bsp/u-boot/u-boot-extra.inc | 8 +- recipes-bsp/u-boot/u-boot-xlnx.inc | 7 +- .../0001-Xilinx-modifications-to-arch.patch | 1131 +++ .../0002-Xilinx-modifications-to-boards.patch | 3559 ++++++++++ .../0003-Xilinx-modifications-to-commmon.patch | 522 ++ .../0004-Xilinx-modifications-to-drivers.patch | 7367 ++++++++++++++++++++ .../0005-Xilinx-modifications-to-configs.patch | 2333 +++++++ recipes-bsp/u-boot/u-boot_2013.01.01.bbappend | 15 + 8 files changed, 14934 insertions(+), 8 deletions(-) create mode 100644 recipes-bsp/u-boot/u-boot/xilinx-v2013.01/0001-Xilinx-modifications-to-arch.patch create mode 100644 recipes-bsp/u-boot/u-boot/xilinx-v2013.01/0002-Xilinx-modifications-to-boards.patch create mode 100644 recipes-bsp/u-boot/u-boot/xilinx-v2013.01/0003-Xilinx-modifications-to-commmon.patch create mode 100644 recipes-bsp/u-boot/u-boot/xilinx-v2013.01/0004-Xilinx-modifications-to-drivers.patch create mode 100644 recipes-bsp/u-boot/u-boot/xilinx-v2013.01/0005-Xilinx-modifications-to-configs.patch create mode 100644 recipes-bsp/u-boot/u-boot_2013.01.01.bbappend diff --git a/recipes-bsp/u-boot/u-boot-extra.inc b/recipes-bsp/u-boot/u-boot-extra.inc index f07284a5..44271bec 100644 --- a/recipes-bsp/u-boot/u-boot-extra.inc +++ b/recipes-bsp/u-boot/u-boot-extra.inc @@ -1,8 +1,12 @@ +S = "${WORKDIR}/git" +PACKAGE_ARCH = "${MACHINE_ARCH}" + # Also deploy u-boot elf file with same file format as bin file +UBOOTXTENSION ?= "${XILINX_EXTENSION}-${MACHINE}" SRC_ELF ?= "u-boot" -DEST_ELF ?= "u-boot-${MACHINE}-${PV}-${PR}.elf" -ELF_SYMLINK ?= "u-boot-${MACHINE}.elf" +DEST_ELF ?= "u-boot${UBOOTXTENSION}-${PV}-${PR}.elf" +ELF_SYMLINK ?= "u-boot${UBOOTXTENSION}.elf" do_deploy_append() { install ${S}/${SRC_ELF} ${DEPLOYDIR}/${DEST_ELF} diff --git a/recipes-bsp/u-boot/u-boot-xlnx.inc b/recipes-bsp/u-boot/u-boot-xlnx.inc index 038f764d..130e047a 100644 --- a/recipes-bsp/u-boot/u-boot-xlnx.inc +++ b/recipes-bsp/u-boot/u-boot-xlnx.inc @@ -3,8 +3,7 @@ require recipes-bsp/u-boot/u-boot.inc LICENSE = "GPLv2+" LIC_FILES_CHKSUM = "file://COPYING;md5=1707d6db1d42237583f50183a5651ecb" -# move this to common include? -XILINX_EXTENSION = "-xlnx" +XILINX_EXTENSION = "-xilinx" FILESEXTRAPATHS += "${THISDIR}/u-boot-xlnx:" SRC_URI = " \ @@ -14,8 +13,4 @@ SRC_URI = " \ file://microblaze_Fix_coding_style_for_bootb.patch \ " -S = "${WORKDIR}/git" - -PACKAGE_ARCH = "${MACHINE_ARCH}" - include u-boot-extra.inc diff --git a/recipes-bsp/u-boot/u-boot/xilinx-v2013.01/0001-Xilinx-modifications-to-arch.patch b/recipes-bsp/u-boot/u-boot/xilinx-v2013.01/0001-Xilinx-modifications-to-arch.patch new file mode 100644 index 00000000..0842ade4 --- /dev/null +++ b/recipes-bsp/u-boot/u-boot/xilinx-v2013.01/0001-Xilinx-modifications-to-arch.patch @@ -0,0 +1,1131 @@ +From f111a3294585ca536b2db2d19d1cbd6d1ec2b39a Mon Sep 17 00:00:00 2001 +From: Sipke Vriend +Date: Tue, 21 May 2013 07:19:12 +1000 +Subject: [PATCH 1/5] Xilinx modifications to arch + +Signed-off-by: Sipke Vriend +--- + arch/arm/cpu/armv7/zynq/Makefile | 1 + + arch/arm/cpu/armv7/zynq/config.mk | 25 +++ + arch/arm/cpu/armv7/zynq/cpu.c | 28 +++- + arch/arm/cpu/armv7/zynq/slcr.c | 240 ++++++++++++++++++++++++ + arch/arm/include/asm/arch-zynq/hardware.h | 96 ++++++++++ + arch/arm/include/asm/arch-zynq/mmc.h | 37 ++++ + arch/arm/include/asm/arch-zynq/nand.h | 25 +++ + arch/arm/include/asm/arch-zynq/sys_proto.h | 36 ++++ + arch/arm/lib/board.c | 2 +- + arch/arm/lib/bootm.c | 15 +-- + arch/microblaze/include/asm/icap.h | 279 ++++++++++++++++++++++++++++ + arch/microblaze/include/asm/processor.h | 4 + + arch/microblaze/lib/Makefile | 1 + + arch/microblaze/lib/board.c | 3 + + arch/microblaze/lib/bootm.c | 63 +++++++ + arch/microblaze/lib/muldi3.c | 91 +++++++++ + 16 files changed, 930 insertions(+), 16 deletions(-) + create mode 100644 arch/arm/cpu/armv7/zynq/config.mk + create mode 100644 arch/arm/cpu/armv7/zynq/slcr.c + create mode 100644 arch/arm/include/asm/arch-zynq/hardware.h + create mode 100644 arch/arm/include/asm/arch-zynq/mmc.h + create mode 100644 arch/arm/include/asm/arch-zynq/nand.h + create mode 100644 arch/arm/include/asm/arch-zynq/sys_proto.h + create mode 100644 arch/microblaze/include/asm/icap.h + create mode 100644 arch/microblaze/lib/muldi3.c + +diff --git a/arch/arm/cpu/armv7/zynq/Makefile b/arch/arm/cpu/armv7/zynq/Makefile +index 499ace4..388085d 100644 +--- a/arch/arm/cpu/armv7/zynq/Makefile ++++ b/arch/arm/cpu/armv7/zynq/Makefile +@@ -30,6 +30,7 @@ LIB = $(obj)lib$(SOC).o + + COBJS-y := timer.o + COBJS-y += cpu.o ++COBJS-y += slcr.o + + COBJS := $(COBJS-y) + +diff --git a/arch/arm/cpu/armv7/zynq/config.mk b/arch/arm/cpu/armv7/zynq/config.mk +new file mode 100644 +index 0000000..85996f3 +--- /dev/null ++++ b/arch/arm/cpu/armv7/zynq/config.mk +@@ -0,0 +1,25 @@ ++# ++# (C) Copyright 2002 ++# Gary Jennejohn, DENX Software Engineering, ++# ++# 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 ++# ++PLATFORM_RELFLAGS += -fno-strict-aliasing ++# Xilinx, added to prevent unaligned accesses which started happening # with GCC 4.5.2 tools ++PLATFORM_RELFLAGS += -mno-unaligned-access +diff --git a/arch/arm/cpu/armv7/zynq/cpu.c b/arch/arm/cpu/armv7/zynq/cpu.c +index ab615cc..e8f4c19 100644 +--- a/arch/arm/cpu/armv7/zynq/cpu.c ++++ b/arch/arm/cpu/armv7/zynq/cpu.c +@@ -21,11 +21,37 @@ + * MA 02111-1307 USA + */ + #include ++#include ++#include ++#include + +-inline void lowlevel_init(void) {} ++void lowlevel_init(void) ++{ ++ zynq_slcr_unlock(); ++ /* remap DDR to zero, FILTERSTART */ ++ writel(0, &scu_base->filter_start); ++ ++ /* Device config APB, unlock the PCAP */ ++ writel(0x757BDF0D, &devcfg_base->unlock); ++ writel(0xFFFFFFFF, &devcfg_base->rom_shadow); ++ ++ /* OCM_CFG, Mask out the ROM, map ram into upper addresses */ ++ writel(0x1F, &slcr_base->ocm_cfg); ++ /* FPGA_RST_CTRL, clear resets on AXI fabric ports */ ++ writel(0x0, &slcr_base->fpga_rst_ctrl); ++ /* TZ_DDR_RAM, Set DDR trust zone non-secure */ ++ writel(0xFFFFFFFF, &slcr_base->trust_zone); ++ /* Set urgent bits with register */ ++ writel(0x0, &slcr_base->ddr_urgent_sel); ++ /* Urgent write, ports S2/S3 */ ++ writel(0xC, &slcr_base->ddr_urgent); ++ ++ zynq_slcr_lock(); ++} + + void reset_cpu(ulong addr) + { ++ zynq_slcr_cpu_reset(); + while (1) + ; + } +diff --git a/arch/arm/cpu/armv7/zynq/slcr.c b/arch/arm/cpu/armv7/zynq/slcr.c +new file mode 100644 +index 0000000..e5f710d +--- /dev/null ++++ b/arch/arm/cpu/armv7/zynq/slcr.c +@@ -0,0 +1,240 @@ ++/* ++ * Copyright (c) 2013 Xilinx Inc. ++ * ++ * 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 ++#include ++#include ++#include ++ ++#define SLCR_LOCK_MAGIC 0x767B ++#define SLCR_UNLOCK_MAGIC 0xDF0D ++ ++#define SLCR_QSPI_ENABLE 0x02 ++#define SLCR_QSPI_ENABLE_MASK 0x03 ++#define SLCR_NAND_L2_SEL 0x10 ++#define SLCR_NAND_L2_SEL_MASK 0x1F ++ ++#define SLCR_IDCODE_MASK 0x1F000 ++#define SLCR_IDCODE_SHIFT 12 ++ ++/* ++ * zynq_slcr_mio_get_status - Get the status of MIO peripheral. ++ * ++ * @peri_name: Name of the peripheral for checking MIO status ++ * @get_pins: Pointer to array of get pin for this peripheral ++ * @num_pins: Number of pins for this peripheral ++ * @mask: Mask value ++ * @check_val: Required check value to get the status of periph ++ */ ++struct zynq_slcr_mio_get_status { ++ const char *peri_name; ++ const int *get_pins; ++ int num_pins; ++ u32 mask; ++ u32 check_val; ++}; ++ ++static const int qspi0_pins[] = { ++ 1, 2, 3, 4, 5, 6 ++}; ++ ++static const int qspi1_cs_pin[] = { ++ 0 ++}; ++ ++static const int qspi1_pins[] = { ++ 9, 10, 11, 12, 13 ++}; ++ ++static const int nand8_pins[] = { ++ 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 ++}; ++ ++static const int nand16_pins[] = { ++ 16, 17, 18, 19, 20, 21, 22, 23 ++}; ++ ++static const struct zynq_slcr_mio_get_status mio_periphs[] = { ++ { ++ "qspi0", ++ qspi0_pins, ++ ARRAY_SIZE(qspi0_pins), ++ SLCR_QSPI_ENABLE_MASK, ++ SLCR_QSPI_ENABLE, ++ }, ++ { ++ "qspi1_cs", ++ qspi1_cs_pin, ++ ARRAY_SIZE(qspi1_cs_pin), ++ SLCR_QSPI_ENABLE_MASK, ++ SLCR_QSPI_ENABLE, ++ }, ++ { ++ "qspi1", ++ qspi1_pins, ++ ARRAY_SIZE(qspi1_pins), ++ SLCR_QSPI_ENABLE_MASK, ++ SLCR_QSPI_ENABLE, ++ }, ++ { ++ "nand8", ++ nand8_pins, ++ ARRAY_SIZE(nand8_pins), ++ SLCR_NAND_L2_SEL_MASK, ++ SLCR_NAND_L2_SEL, ++ }, ++ { ++ "nand16", ++ nand16_pins, ++ ARRAY_SIZE(nand16_pins), ++ SLCR_NAND_L2_SEL_MASK, ++ SLCR_NAND_L2_SEL, ++ }, ++}; ++ ++static int slcr_lock = 1; /* 1 means locked, 0 means unlocked */ ++ ++void zynq_slcr_lock(void) ++{ ++ if (!slcr_lock) ++ writel(SLCR_LOCK_MAGIC, &slcr_base->slcr_lock); ++} ++ ++void zynq_slcr_unlock(void) ++{ ++ if (slcr_lock) ++ writel(SLCR_UNLOCK_MAGIC, &slcr_base->slcr_unlock); ++} ++ ++/* Reset the entire system */ ++void zynq_slcr_cpu_reset(void) ++{ ++ /* ++ * Unlock the SLCR then reset the system. ++ * Note that this seems to require raw i/o ++ * functions or there's a lockup? ++ */ ++ zynq_slcr_unlock(); ++ ++ /* ++ * Clear 0x0F000000 bits of reboot status register to workaround ++ * the FSBL not loading the bitstream after soft-reboot ++ * This is a temporary solution until we know more. ++ */ ++ clrbits_le32(&slcr_base->reboot_status, 0xF000000); ++ ++ writel(1, &slcr_base->pss_rst_ctrl); ++} ++ ++/* Setup clk for network */ ++void zynq_slcr_gem_clk_setup(u32 gem_id, u32 rclk, u32 clk) ++{ ++ zynq_slcr_unlock(); ++ ++ if (gem_id > 1) { ++ printf("Non existing GEM id %d\n", gem_id); ++ goto out; ++ } ++ ++ if (gem_id) { ++ /* Set divisors for appropriate frequency in GEM_CLK_CTRL */ ++ writel(clk, &slcr_base->gem1_clk_ctrl); ++ /* Configure GEM_RCLK_CTRL */ ++ writel(rclk, &slcr_base->gem1_rclk_ctrl); ++ } else { ++ /* Set divisors for appropriate frequency in GEM_CLK_CTRL */ ++ writel(clk, &slcr_base->gem0_clk_ctrl); ++ /* Configure GEM_RCLK_CTRL */ ++ writel(rclk, &slcr_base->gem0_rclk_ctrl); ++ } ++ ++out: ++ zynq_slcr_lock(); ++} ++ ++void zynq_slcr_devcfg_disable(void) ++{ ++ zynq_slcr_unlock(); ++ ++ /* Disable AXI interface */ ++ writel(0xFFFFFFFF, &slcr_base->fpga_rst_ctrl); ++ ++ /* Set Level Shifters DT618760 */ ++ writel(0xA, &slcr_base->lvl_shftr_en); ++ ++ zynq_slcr_lock(); ++} ++ ++void zynq_slcr_devcfg_enable(void) ++{ ++ zynq_slcr_unlock(); ++ ++ /* Set Level Shifters DT618760 */ ++ writel(0xF, &slcr_base->lvl_shftr_en); ++ ++ /* Disable AXI interface */ ++ writel(0x0, &slcr_base->fpga_rst_ctrl); ++ ++ zynq_slcr_lock(); ++} ++ ++u32 zynq_slcr_get_boot_mode(void) ++{ ++ /* Get the bootmode register value */ ++ return readl(&slcr_base->boot_mode); ++} ++ ++u32 zynq_slcr_get_idcode(void) ++{ ++ return (readl(&slcr_base->pss_idcode) & SLCR_IDCODE_MASK) >> ++ SLCR_IDCODE_SHIFT; ++} ++ ++/* ++ * zynq_slcr_get_mio_pin_status - Get the MIO pin status of peripheral. ++ * ++ * @periph: Name of the peripheral ++ * ++ * Returns count to indicate the number of pins configured for the ++ * given @periph. ++ */ ++int zynq_slcr_get_mio_pin_status(const char *periph) ++{ ++ const struct zynq_slcr_mio_get_status *mio_ptr; ++ int val, i, j; ++ int mio = 0; ++ ++ for (i = 0; i < ARRAY_SIZE(mio_periphs); i++) { ++ if (strcmp(periph, mio_periphs[i].peri_name) == 0) { ++ mio_ptr = &mio_periphs[i]; ++ for (j = 0; j < mio_ptr->num_pins; j++) { ++ val = readl(&slcr_base->mio_pin ++ [mio_ptr->get_pins[j]]); ++ if ((val & mio_ptr->mask) == mio_ptr->check_val) ++ mio++; ++ } ++ break; ++ } ++ } ++ ++ return mio; ++} +diff --git a/arch/arm/include/asm/arch-zynq/hardware.h b/arch/arm/include/asm/arch-zynq/hardware.h +new file mode 100644 +index 0000000..3fd980a +--- /dev/null ++++ b/arch/arm/include/asm/arch-zynq/hardware.h +@@ -0,0 +1,96 @@ ++/* ++ * Copyright (c) 2013 Xilinx Inc. ++ * ++ * 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 ++ */ ++ ++#ifndef _ASM_ARCH_HARDWARE_H ++#define _ASM_ARCH_HARDWARE_H ++ ++#define XPSS_SYS_CTRL_BASEADDR 0xF8000000 ++#define XPSS_DEV_CFG_APB_BASEADDR 0xF8007000 ++#define XPSS_SCU_BASEADDR 0xF8F00000 ++ ++/* Reflect slcr offsets */ ++struct slcr_regs { ++ u32 scl; /* 0x0 */ ++ u32 slcr_lock; /* 0x4 */ ++ u32 slcr_unlock; /* 0x8 */ ++ u32 reserved0[75]; ++ u32 gem0_rclk_ctrl; /* 0x138 */ ++ u32 gem1_rclk_ctrl; /* 0x13c */ ++ u32 gem0_clk_ctrl; /* 0x140 */ ++ u32 gem1_clk_ctrl; /* 0x144 */ ++ u32 reserved1[46]; ++ u32 pss_rst_ctrl; /* 0x200 */ ++ u32 reserved2[15]; ++ u32 fpga_rst_ctrl; /* 0x240 */ ++ u32 reserved3[5]; ++ u32 reboot_status; /* 0x258 */ ++ u32 boot_mode; /* 0x25c */ ++ u32 reserved4[116]; ++ u32 trust_zone; /* 0x430 */ /* FIXME */ ++ u32 reserved5_1[63]; ++ u32 pss_idcode; /* 0x530 */ ++ u32 reserved5_2[51]; ++ u32 ddr_urgent; /* 0x600 */ ++ u32 reserved6[6]; ++ u32 ddr_urgent_sel; /* 0x61c */ ++ u32 reserved7[56]; ++ u32 mio_pin[54]; /* 0x700 - 0x7D4 */ ++ u32 reserved8[74]; ++ u32 lvl_shftr_en; /* 0x900 */ ++ u32 reserved9[3]; ++ u32 ocm_cfg; /* 0x910 */ ++}; ++ ++#define slcr_base ((struct slcr_regs *) XPSS_SYS_CTRL_BASEADDR) ++ ++struct devcfg_regs { ++ u32 ctrl; /* 0x0 */ ++ u32 lock; /* 0x4 */ ++ u32 cfg; /* 0x8 */ ++ u32 int_sts; /* 0xc */ ++ u32 int_mask; /* 0x10 */ ++ u32 status; /* 0x14 */ ++ u32 dma_src_addr; /* 0x18 */ ++ u32 dma_dst_addr; /* 0x1c */ ++ u32 dma_src_len; /* 0x20 */ ++ u32 dma_dst_len; /* 0x24 */ ++ u32 rom_shadow; /* 0x28 */ ++ u32 reserved1[2]; ++ u32 unlock; /* 0x34 */ ++ u32 reserved2[18]; ++ u32 mctrl; /* 0x80 */ ++ u32 reserved3; ++ u32 write_count; /* 0x88 */ ++ u32 read_count; /* 0x8c */ ++}; ++ ++#define devcfg_base ((struct devcfg_regs *) XPSS_DEV_CFG_APB_BASEADDR) ++ ++struct scu_regs { ++ u32 reserved1[16]; ++ u32 filter_start; /* 0x40 */ ++ u32 filter_end; /* 0x44 */ ++}; ++ ++#define scu_base ((struct scu_regs *) XPSS_SCU_BASEADDR) ++ ++#endif /* _ASM_ARCH_HARDWARE_H */ +diff --git a/arch/arm/include/asm/arch-zynq/mmc.h b/arch/arm/include/asm/arch-zynq/mmc.h +new file mode 100644 +index 0000000..18dd036 +--- /dev/null ++++ b/arch/arm/include/asm/arch-zynq/mmc.h +@@ -0,0 +1,37 @@ ++/* ++ * Copyright 2012 Joe Hershberger ++ * ++ * 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 ++ */ ++ ++#ifndef __ASM_ARCH_MMC_H_ ++#define __ASM_ARCH_MMC_H_ ++ ++#include ++ ++int zynq_sdhci_init(u32 regbase, u32 max_clk, u32 min_clk); ++ ++static inline int zynq_mmc_init(bd_t *bd) ++{ ++ u32 regbase = (u32) SD_BASEADDR; ++ ++ return zynq_sdhci_init(regbase, 52000000, 52000000 >> 9); ++} ++ ++#endif /* __ASM_ARCH_MMC_H_ */ +diff --git a/arch/arm/include/asm/arch-zynq/nand.h b/arch/arm/include/asm/arch-zynq/nand.h +new file mode 100644 +index 0000000..33a7d20 +--- /dev/null ++++ b/arch/arm/include/asm/arch-zynq/nand.h +@@ -0,0 +1,25 @@ ++/* ++ * Copyright 2012 Joe Hershberger ++ * ++ * 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 ++ ++extern int zynq_nand_init(struct nand_chip *nand_chip); +diff --git a/arch/arm/include/asm/arch-zynq/sys_proto.h b/arch/arm/include/asm/arch-zynq/sys_proto.h +new file mode 100644 +index 0000000..411589e +--- /dev/null ++++ b/arch/arm/include/asm/arch-zynq/sys_proto.h +@@ -0,0 +1,36 @@ ++/* ++ * Copyright (c) 2013 Xilinx Inc. ++ * ++ * 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 ++ */ ++ ++#ifndef _SYS_PROTO_H_ ++#define _SYS_PROTO_H_ ++ ++extern void zynq_slcr_lock(void); ++extern void zynq_slcr_unlock(void); ++extern void zynq_slcr_cpu_reset(void); ++extern void zynq_slcr_gem_clk_setup(u32 gem_id, u32 rclk, u32 clk); ++extern void zynq_slcr_devcfg_disable(void); ++extern void zynq_slcr_devcfg_enable(void); ++extern u32 zynq_slcr_get_boot_mode(void); ++extern u32 zynq_slcr_get_idcode(void); ++extern int zynq_slcr_get_mio_pin_status(const char *periph); ++ ++#endif /* _SYS_PROTO_H_ */ +diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c +index 9f861cc..cfe32cc 100644 +--- a/arch/arm/lib/board.c ++++ b/arch/arm/lib/board.c +@@ -488,7 +488,7 @@ static char *failed = "*** failed ***\n"; + static int should_load_env(void) + { + #ifdef CONFIG_OF_CONTROL +- return fdtdec_get_config_int(gd->fdt_blob, "load-environment", 1); ++ return fdtdec_get_config_int(gd->fdt_blob, "load-environment", 0); + #elif defined CONFIG_DELAY_ENVIRONMENT + return 0; + #else +diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c +index 1bd2730..28420e3 100644 +--- a/arch/arm/lib/bootm.c ++++ b/arch/arm/lib/bootm.c +@@ -79,17 +79,7 @@ void arch_lmb_reserve(struct lmb *lmb) + #ifdef CONFIG_OF_LIBFDT + static int fixup_memory_node(void *blob) + { +- bd_t *bd = gd->bd; +- int bank; +- u64 start[CONFIG_NR_DRAM_BANKS]; +- u64 size[CONFIG_NR_DRAM_BANKS]; +- +- for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) { +- start[bank] = bd->bi_dram[bank].start; +- size[bank] = bd->bi_dram[bank].size; +- } +- +- return fdt_fixup_memory_banks(blob, start, size, CONFIG_NR_DRAM_BANKS); ++ return 0; + } + #endif + +@@ -315,9 +305,6 @@ static void boot_prep_linux(bootm_headers_t *images) + #endif + setup_board_tags(¶ms); + setup_end_tag(gd->bd); +-#else /* all tags */ +- printf("FDT and ATAGS support not compiled in - hanging\n"); +- hang(); + #endif /* all tags */ + } + } +diff --git a/arch/microblaze/include/asm/icap.h b/arch/microblaze/include/asm/icap.h +new file mode 100644 +index 0000000..8d4fe79 +--- /dev/null ++++ b/arch/microblaze/include/asm/icap.h +@@ -0,0 +1,279 @@ ++#include ++ ++#define XHwIcap_In32 readl ++ ++#define XHwIcap_Out32(a,b) writel(b,a) /* switch address & data */ ++ ++/* Packet Types */ ++#define XHI_SYNC_PACKET 0xAA995566 ++#define XHI_DUMMY_PACKET 0xFFFFFFFF ++#define XHI_DEVICE_ID_READ 0x28018001 ++#define XHI_NOOP_PACKET 0x20000000 ++ ++/* Command types */ ++#define XHI_TYPE_1 1 ++ ++/* Command Direction */ ++#define XHI_OP_READ 1 ++ ++/* Register Programming Offsets */ ++#define XHI_TYPE_SHIFT 29 ++#define XHI_REGISTER_SHIFT 13 ++#define XHI_OP_SHIFT 27 ++ ++/* Register Offsets */ ++#define XHI_WBSTAR 16 ++ ++/* Register offsets for the XHwIcap device. */ ++#define XHI_GIER_OFFSET 0x1C /**< Device Global Interrupt Enable Reg */ ++#define XHI_IPISR_OFFSET 0x20 /**< Interrupt Status Register */ ++#define XHI_IPIER_OFFSET 0x28 /**< Interrupt Enable Register */ ++#define XHI_WF_OFFSET 0x100 /**< Write FIFO */ ++#define XHI_RF_OFFSET 0x104 /**< Read FIFO */ ++#define XHI_SZ_OFFSET 0x108 /**< Size Register */ ++#define XHI_CR_OFFSET 0x10C /**< Control Register */ ++#define XHI_SR_OFFSET 0x110 /**< Status Register */ ++#define XHI_WFV_OFFSET 0x114 /**< Write FIFO Vacancy Register */ ++#define XHI_RFO_OFFSET 0x118 /**< Read FIFO Occupancy Register */ ++ ++/* Control Register Contents */ ++#define XHI_CR_READ_MASK 0x00000002 /**< Read from ICAP to FIFO */ ++#define XHI_CR_WRITE_MASK 0x00000001 /**< Write from FIFO to ICAP */ ++ ++/* Status Register Contents */ ++#define XHI_SR_DONE_MASK 0x00000001 /**< Done bit Mask */ ++ ++/* Number of times to poll the Status Register */ ++#define XHI_MAX_RETRIES 1000 ++ ++/* Program Command */ ++#define XHI_CMD_IPROG 15 ++ ++ ++/****************************************************************************/ ++/** ++* ++* Read from the specified HwIcap device register. ++* ++* @param BaseAddress contains the base address of the device. ++* @param RegOffset contains the offset from the 1st register of the ++* device to select the specific register. ++* ++* @return The value read from the register. ++* ++* @note C-Style signature: ++* u32 XHwIcap_ReadReg(u32 BaseAddress, u32 RegOffset); ++* ++******************************************************************************/ ++#define XHwIcap_ReadReg(BaseAddress, RegOffset) \ ++ XHwIcap_In32((BaseAddress) + (RegOffset)) ++ ++/***************************************************************************/ ++/** ++* ++* Write to the specified HwIcap device register. ++* ++* @param BaseAddress contains the base address of the device. ++* @param RegOffset contains the offset from the 1st register of the ++* device to select the specific register. ++* @param RegisterValue is the value to be written to the register. ++* ++* @return None. ++* ++* @note C-Style signature: ++* void XHwIcap_WriteReg(u32 BaseAddress, u32 RegOffset, ++* u32 RegisterValue); ++******************************************************************************/ ++#define XHwIcap_WriteReg(BaseAddress, RegOffset, RegisterValue) \ ++ XHwIcap_Out32((BaseAddress) + (RegOffset), (RegisterValue)) ++ ++/****************************************************************************/ ++/** ++* ++* Write data to the Write FIFO. ++* ++* @param BaseAddress contains the base address of the device. ++* @param Data is the 32-bit value to be written to the FIFO. ++* ++* @return None. ++* ++* @note C-style Signature: ++* void XHwIcap_FifoWrite(u32 BaseAddress, u32 Data); ++* ++*****************************************************************************/ ++#define XHwIcap_FifoWrite(BaseAddress,Data) \ ++ (XHwIcap_WriteReg(BaseAddress, XHI_WF_OFFSET, (Data))) ++ ++/****************************************************************************/ ++/** ++* ++* Read data from the Read FIFO. ++* ++* @param BaseAddress contains the base address of the device. ++* ++* @return The 32-bit Data read from the FIFO. ++* ++* @note C-style Signature: ++* u32 XHwIcap_FifoRead(u32 BaseAddress); ++* ++*****************************************************************************/ ++#define XHwIcap_FifoRead(BaseAddress) \ ++(XHwIcap_ReadReg(BaseAddress, XHI_RF_OFFSET)) ++ ++/****************************************************************************/ ++/** ++* ++* Get the contents of the Control register. ++* ++* @param BaseAddress contains the base address of the device. ++* ++* @return A 32-bit value representing the contents of the Control ++* register. ++* ++* @note u32 XHwIcap_GetControlReg(u32 BaseAddress); ++* ++*****************************************************************************/ ++#define XHwIcap_GetControlReg(BaseAddress) \ ++ (XHwIcap_ReadReg(BaseAddress, XHI_CR_OFFSET)) ++ ++ ++/****************************************************************************/ ++/** ++* ++* Set the Control Register to initiate a configuration (write) to the device. ++* ++* @param BaseAddress contains the base address of the device. ++* ++* @return None. ++* ++* @note C-style Signature: ++* void XHwIcap_StartConfig(u32 BaseAddress); ++* ++*****************************************************************************/ ++#define XHwIcap_StartConfig(BaseAddress) \ ++ (XHwIcap_WriteReg(BaseAddress, XHI_CR_OFFSET, (XHwIcap_GetControlReg(BaseAddress) & \ ++ (~ XHI_CR_READ_MASK)) | XHI_CR_WRITE_MASK)) ++ ++/******************************************************************************/ ++/** ++* ++* This macro returns the vacancy of the Write FIFO. This indicates the ++* number of words that can be written to the Write FIFO before it becomes ++* full. ++* ++* @param BaseAddress contains the base address of the device. ++* ++* @return The contents read from the Write FIFO Vacancy Register. ++* ++* @note C-Style signature: ++* u32 XHwIcap_GetWrFifoVacancy(u32 BaseAddress) ++* ++******************************************************************************/ ++#define XHwIcap_GetWrFifoVacancy(BaseAddress) \ ++ XHwIcap_ReadReg(BaseAddress, XHI_WFV_OFFSET) ++ ++/******************************************************************************/ ++/** ++* ++* This macro returns the occupancy of the Read FIFO. ++* ++* @param BaseAddress contains the base address of the device. ++* ++* @return The contents read from the Read FIFO Occupancy Register. ++* ++* @note C-Style signature: ++* u32 XHwIcap_GetRdFifoOccupancy(u32 BaseAddress) ++* ++******************************************************************************/ ++#define XHwIcap_GetRdFifoOccupancy(BaseAddress) \ ++ XHwIcap_ReadReg(BaseAddress, XHI_RFO_OFFSET) ++ ++/****************************************************************************/ ++/** ++* ++* Get the contents of the status register. ++* ++* @param BaseAddress contains the base address of the device. ++* ++* @return A 32-bit value representing the contents of the status register. ++* ++* @note u32 XHwIcap_GetStatusReg(u32 BaseAddress); ++* ++*****************************************************************************/ ++#define XHwIcap_GetStatusReg(BaseAddress) \ ++(XHwIcap_ReadReg(BaseAddress, XHI_SR_OFFSET)) ++ ++/****************************************************************************/ ++/** ++* ++* This macro checks if the last Read/Write to the ICAP device in the FPGA ++* is completed. ++* ++* @param BaseAddress contains the base address of the device. ++* ++* @return ++* - 1 if the last Read/Write(Config) to the ICAP is NOT ++* completed. ++* - 0 if the Read/Write(Config) to the ICAP is completed.. ++* ++* @note C-Style signature: ++* int XHwIcap_IsDeviceBusy(u32 BaseAddress); ++* ++*****************************************************************************/ ++#define XHwIcap_IsDeviceBusy(BaseAddress) \ ++ ((XHwIcap_GetStatusReg(BaseAddress) & XHI_SR_DONE_MASK) ? 0 : 1) ++ ++/****************************************************************************/ ++/** ++* ++* Set the number of words to be read from the Icap in the Size register. ++* ++* The Size Register holds the number of 32 bit words to transfer from the ++* the Icap to the Read FIFO of the HwIcap device. ++* ++* @param BaseAddress contains the base address of the device. ++* @param Data is the size in words. ++* ++* @return None. ++* ++* @note C-style Signature: ++* void XHwIcap_SetSizeReg(u32 BaseAddress, u32 Data); ++* ++*****************************************************************************/ ++#define XHwIcap_SetSizeReg(BaseAddress, Data) \ ++ (XHwIcap_WriteReg(BaseAddress, XHI_SZ_OFFSET, (Data))) ++ ++/****************************************************************************/ ++/** ++* ++* Set the Control Register to initiate a ReadBack from the device. ++* ++* @param BaseAddress contains the base address of the device. ++* ++* @return None. ++* ++* @note C-style Signature: ++* void XHwIcap_StartReadBack(u32 BaseAddress); ++* ++*****************************************************************************/ ++#define XHwIcap_StartReadBack(BaseAddress) \ ++ (XHwIcap_WriteReg(BaseAddress, XHI_CR_OFFSET, (XHwIcap_GetControlReg(BaseAddress) & \ ++ (~ XHI_CR_WRITE_MASK)) | XHI_CR_READ_MASK)) ++ ++/****************************************************************************/ ++/** ++* ++* Generates a Type 1 packet header that reads back the requested Configuration ++* register. ++* ++* @param Register is the address of the register to be read back. ++* ++* @return Type 1 packet header to read the specified register ++* ++* @note None. ++* ++*****************************************************************************/ ++#define XHwIcap_Type1Read(Register) \ ++ ( (XHI_TYPE_1 << XHI_TYPE_SHIFT) | (Register << XHI_REGISTER_SHIFT) | \ ++ (XHI_OP_READ << XHI_OP_SHIFT) ) ++ +diff --git a/arch/microblaze/include/asm/processor.h b/arch/microblaze/include/asm/processor.h +index 2c4d5ff..9d19dda 100644 +--- a/arch/microblaze/include/asm/processor.h ++++ b/arch/microblaze/include/asm/processor.h +@@ -31,4 +31,8 @@ extern char __text_start[]; + /* Microblaze board initialization function */ + void board_init(void); + ++/* Watchdog functions */ ++int hw_watchdog_init(void); ++void hw_watchdog_disable(void); ++ + #endif /* __ASM_MICROBLAZE_PROCESSOR_H */ +diff --git a/arch/microblaze/lib/Makefile b/arch/microblaze/lib/Makefile +index 7730695..8d7febd 100644 +--- a/arch/microblaze/lib/Makefile ++++ b/arch/microblaze/lib/Makefile +@@ -29,6 +29,7 @@ SOBJS-y += + + COBJS-y += board.o + COBJS-y += bootm.o ++COBJS-y += muldi3.o + + SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) + OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) +diff --git a/arch/microblaze/lib/board.c b/arch/microblaze/lib/board.c +index a7c2f76..815fb5a 100644 +--- a/arch/microblaze/lib/board.c ++++ b/arch/microblaze/lib/board.c +@@ -61,6 +61,9 @@ init_fnc_t *init_sequence[] = { + serial_init, + console_init_f, + interrupts_init, ++#ifdef CONFIG_XILINX_TB_WATCHDOG ++ hw_watchdog_init, ++#endif + timer_init, + NULL, + }; +diff --git a/arch/microblaze/lib/bootm.c b/arch/microblaze/lib/bootm.c +index 66d21f4..7da683d 100644 +--- a/arch/microblaze/lib/bootm.c ++++ b/arch/microblaze/lib/bootm.c +@@ -30,6 +30,10 @@ + #include + #include + ++#if defined(CONFIG_CMD_BOOTB) ++#include ++#endif ++ + DECLARE_GLOBAL_DATA_PTR; + + int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *images) +@@ -83,3 +87,62 @@ int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *ima + + return 1; + } ++ ++#if defined(CONFIG_CMD_BOOTB) ++int do_bootb_kintex7(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) ++{ ++ u32 FrameBuffer[8]; ++ u32 BootAddress = simple_strtoul(argv[1], NULL, 16); ++ u32 Index = 0; ++ u32 Count; ++ ++ if (argc < 2) ++ return -1; ++ ++ if ((BootAddress < CONFIG_SYS_FLASH_BASE) || (BootAddress > (CONFIG_SYS_FLASH_BASE + CONFIG_SYS_FLASH_SIZE))) ++ { ++ return -1; ++ } ++ ++ /* ++ * Create the data to be written to the ICAP. ++ */ ++ FrameBuffer[Index++] = XHI_DUMMY_PACKET; ++ FrameBuffer[Index++] = XHI_SYNC_PACKET; ++ FrameBuffer[Index++] = XHI_NOOP_PACKET; ++ FrameBuffer[Index++] = 0x30020001; /* Type 1 write to WBSTAR */ ++ FrameBuffer[Index++] = BootAddress; ++ FrameBuffer[Index++] = 0x30008001; /* Type 1 Write to CMD */ ++ FrameBuffer[Index++] = XHI_CMD_IPROG; ++ FrameBuffer[Index++] = XHI_NOOP_PACKET; ++ ++ /* ++ * Fill the FIFO with as many words as it will take (or as many as we have to send). ++ */ ++ while(Index > XHwIcap_GetWrFifoVacancy(HWICAP_BASEADDR)); ++ for (Count = 0; Count < Index; Count++) ++ { ++ XHwIcap_FifoWrite(HWICAP_BASEADDR, FrameBuffer[Count]); ++ } ++ ++ /* ++ * Start the transfer of the data from the FIFO to the ICAP device. ++ */ ++ XHwIcap_StartConfig(HWICAP_BASEADDR); ++ ++ while ((XHwIcap_ReadReg(HWICAP_BASEADDR,XHI_CR_OFFSET)) & XHI_CR_WRITE_MASK); ++ ++ while (XHwIcap_IsDeviceBusy(HWICAP_BASEADDR) != 0); ++ while (XHwIcap_ReadReg(HWICAP_BASEADDR, XHI_CR_OFFSET) & XHI_CR_WRITE_MASK); ++ ++ /* The code should never get here sice the FPGA should reset */ ++ return -1; ++} ++ ++U_BOOT_CMD( ++ bootb, 2, 1, do_bootb_kintex7, ++ "reprogram the fpga with a new image", ++ "
- Program the FPGA with the data starting at the given address" ++); ++ ++#endif +diff --git a/arch/microblaze/lib/muldi3.c b/arch/microblaze/lib/muldi3.c +new file mode 100644 +index 0000000..76d7590 +--- /dev/null ++++ b/arch/microblaze/lib/muldi3.c +@@ -0,0 +1,91 @@ ++/* ++ * U-boot - muldi3.c contains routines for mult and div ++ * ++ * ++ * 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 St, Fifth Floor, Boston, ++ * MA 02110-1301 USA ++ */ ++ ++/* Generic function got from GNU gcc package, libgcc2.c */ ++#ifndef SI_TYPE_SIZE ++#define SI_TYPE_SIZE 32 ++#endif ++#define __ll_B (1L << (SI_TYPE_SIZE / 2)) ++#define __ll_lowpart(t) ((USItype) (t) % __ll_B) ++#define __ll_highpart(t) ((USItype) (t) / __ll_B) ++#define BITS_PER_UNIT 8 ++ ++#if !defined(umul_ppmm) ++#define umul_ppmm(w1, w0, u, v) \ ++ do { \ ++ USItype __x0, __x1, __x2, __x3; \ ++ USItype __ul, __vl, __uh, __vh; \ ++ \ ++ __ul = __ll_lowpart(u); \ ++ __uh = __ll_highpart(u); \ ++ __vl = __ll_lowpart(v); \ ++ __vh = __ll_highpart(v); \ ++ \ ++ __x0 = (USItype) __ul * __vl; \ ++ __x1 = (USItype) __ul * __vh; \ ++ __x2 = (USItype) __uh * __vl; \ ++ __x3 = (USItype) __uh * __vh; \ ++ \ ++ __x1 += __ll_highpart(__x0); /* this can't give carry */\ ++ __x1 += __x2; /* but this indeed can */ \ ++ if (__x1 < __x2) /* did we get it? */ \ ++ __x3 += __ll_B; /* yes, add it in the proper pos. */ \ ++ \ ++ (w1) = __x3 + __ll_highpart(__x1); \ ++ (w0) = __ll_lowpart(__x1) * __ll_B + __ll_lowpart(__x0);\ ++ } while (0) ++#endif ++ ++#if !defined(__umulsidi3) ++#define __umulsidi3(u, v) \ ++ ({DIunion __w; \ ++ umul_ppmm(__w.s.high, __w.s.low, u, v); \ ++ __w.ll; }) ++#endif ++ ++typedef unsigned int USItype __attribute__ ((mode(SI))); ++typedef int SItype __attribute__ ((mode(SI))); ++typedef int DItype __attribute__ ((mode(DI))); ++typedef int word_type __attribute__ ((mode(__word__))); ++ ++struct DIstruct { ++ SItype low, high; ++}; ++typedef union { ++ struct DIstruct s; ++ DItype ll; ++} DIunion; ++ ++DItype __muldi3(DItype u, DItype v) ++{ ++ DIunion w; ++ DIunion uu, vv; ++ ++ uu.ll = u, vv.ll = v; ++ /* panic("kernel panic for __muldi3"); */ ++ w.ll = __umulsidi3(uu.s.low, vv.s.low); ++ w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high ++ + (USItype) uu.s.high * (USItype) vv.s.low); ++ ++ return w.ll; ++} +-- +1.7.5.4 + diff --git a/recipes-bsp/u-boot/u-boot/xilinx-v2013.01/0002-Xilinx-modifications-to-boards.patch b/recipes-bsp/u-boot/u-boot/xilinx-v2013.01/0002-Xilinx-modifications-to-boards.patch new file mode 100644 index 00000000..abae958c --- /dev/null +++ b/recipes-bsp/u-boot/u-boot/xilinx-v2013.01/0002-Xilinx-modifications-to-boards.patch @@ -0,0 +1,3559 @@ +From 06c1083022cf78385ca85edb0e7ccf679c8cb40a Mon Sep 17 00:00:00 2001 +From: Sipke Vriend +Date: Tue, 21 May 2013 07:19:12 +1000 +Subject: [PATCH 2/5] Xilinx modifications to boards + +Signed-off-by: Sipke Vriend +--- + board/avnet/fx12mm/.gitignore | 1 - + board/avnet/fx12mm/Makefile | 27 -- + board/avnet/fx12mm/fx12mm.c | 51 -- + board/avnet/fx12mm/xparameters.h | 51 -- + board/avnet/v5fx30teval/.gitignore | 1 - + board/avnet/v5fx30teval/Makefile | 27 -- + board/avnet/v5fx30teval/v5fx30teval.c | 28 -- + board/avnet/v5fx30teval/xparameters.h | 33 -- + board/xilinx/common/xbasic_types.c | 88 ++--- + board/xilinx/common/xbasic_types.h | 271 ++++++----- + board/xilinx/common/xstatus.h | 489 ++++++++++++-------- + board/xilinx/microblaze-generic/.gitignore | 5 + + board/xilinx/microblaze-generic/Makefile | 2 +- + board/xilinx/microblaze-generic/config.mk | 34 -- + .../xilinx/microblaze-generic/microblaze-generic.c | 77 +--- + board/xilinx/microblaze-generic/xparameters.h | 79 ---- + board/xilinx/ml507/.gitignore | 1 - + board/xilinx/ml507/Makefile | 27 -- + board/xilinx/ml507/ml507.c | 28 -- + board/xilinx/ml507/xparameters.h | 34 -- + board/xilinx/ppc405-generic/.gitignore | 6 +- + board/xilinx/ppc405-generic/Makefile | 11 +- + board/xilinx/ppc405-generic/ppc405-generic.c | 104 +++++ + board/xilinx/ppc405-generic/u-boot.lds | 132 ++++++ + .../xilinx/ppc405-generic/xilinx_ppc405_generic.c | 59 --- + board/xilinx/ppc405-generic/xparameters.h | 36 -- + board/xilinx/ppc440-generic/.gitignore | 6 +- + board/xilinx/ppc440-generic/Makefile | 13 +- + board/xilinx/ppc440-generic/ppc440-generic.c | 104 +++++ + board/xilinx/ppc440-generic/u-boot.lds | 104 +++++ + .../xilinx/ppc440-generic/xilinx_ppc440_generic.c | 52 -- + board/xilinx/ppc440-generic/xparameters.h | 34 -- + board/xilinx/xilinx_iic/xiic_l.c | 484 ------------------- + board/xilinx/xilinx_iic/xiic_l.h | 150 ------ + board/xilinx/zynq/Makefile | 8 +- + board/xilinx/zynq/board.c | 127 +++++- + boards.cfg | 23 +- + 37 files changed, 1079 insertions(+), 1728 deletions(-) + delete mode 100644 board/avnet/fx12mm/.gitignore + delete mode 100644 board/avnet/fx12mm/Makefile + delete mode 100644 board/avnet/fx12mm/fx12mm.c + delete mode 100644 board/avnet/fx12mm/xparameters.h + delete mode 100644 board/avnet/v5fx30teval/.gitignore + delete mode 100644 board/avnet/v5fx30teval/Makefile + delete mode 100644 board/avnet/v5fx30teval/v5fx30teval.c + delete mode 100644 board/avnet/v5fx30teval/xparameters.h + create mode 100644 board/xilinx/microblaze-generic/.gitignore + delete mode 100644 board/xilinx/microblaze-generic/config.mk + delete mode 100644 board/xilinx/microblaze-generic/xparameters.h + delete mode 100644 board/xilinx/ml507/.gitignore + delete mode 100644 board/xilinx/ml507/Makefile + delete mode 100644 board/xilinx/ml507/ml507.c + delete mode 100644 board/xilinx/ml507/xparameters.h + create mode 100644 board/xilinx/ppc405-generic/ppc405-generic.c + create mode 100644 board/xilinx/ppc405-generic/u-boot.lds + delete mode 100644 board/xilinx/ppc405-generic/xilinx_ppc405_generic.c + delete mode 100644 board/xilinx/ppc405-generic/xparameters.h + create mode 100644 board/xilinx/ppc440-generic/ppc440-generic.c + create mode 100644 board/xilinx/ppc440-generic/u-boot.lds + delete mode 100644 board/xilinx/ppc440-generic/xilinx_ppc440_generic.c + delete mode 100644 board/xilinx/ppc440-generic/xparameters.h + delete mode 100644 board/xilinx/xilinx_iic/xiic_l.c + delete mode 100644 board/xilinx/xilinx_iic/xiic_l.h + +diff --git a/board/avnet/fx12mm/.gitignore b/board/avnet/fx12mm/.gitignore +deleted file mode 100644 +index b644f59..0000000 +--- a/board/avnet/fx12mm/.gitignore ++++ /dev/null +@@ -1 +0,0 @@ +-config.tmp +diff --git a/board/avnet/fx12mm/Makefile b/board/avnet/fx12mm/Makefile +deleted file mode 100644 +index f943781..0000000 +--- a/board/avnet/fx12mm/Makefile ++++ /dev/null +@@ -1,27 +0,0 @@ +-# +-# (C) Copyright 2008 +-# Ricardo Ribalda,Universidad Autonoma de Madrid, ricardo.ribalda@uam.es +-# This work has been supported by: Qtechnology http://qtec.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 +-# +- +-COBJS += $(BOARD).o +- +-include $(SRCTREE)/board/xilinx/ppc405-generic/Makefile +diff --git a/board/avnet/fx12mm/fx12mm.c b/board/avnet/fx12mm/fx12mm.c +deleted file mode 100644 +index c975efa..0000000 +--- a/board/avnet/fx12mm/fx12mm.c ++++ /dev/null +@@ -1,51 +0,0 @@ +-/* +- * (C) Copyright 2008 +- * +- * Author: Xilinx Inc. +- * +- * Modified by: +- * Georg Schardt +- * +- * 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 +-#include +-#include +- +-int checkboard(void) +-{ +- char buf[64]; +- int i; +- int l = getenv_f("serial#", buf, sizeof(buf)); +- +- if (l < 0) { +- printf("Avnet Virtex4 FX12 with no serial #"); +- } else { +- printf("Avnet Virtex4 FX12 Minimodul # "); +- for (i = 0; i < l; ++i) { +- if (buf[i] == ' ') +- break; +- putc(buf[i]); +- } +- } +- putc('\n'); +- return 0; +-} +diff --git a/board/avnet/fx12mm/xparameters.h b/board/avnet/fx12mm/xparameters.h +deleted file mode 100644 +index 4410f19..0000000 +--- a/board/avnet/fx12mm/xparameters.h ++++ /dev/null +@@ -1,51 +0,0 @@ +-/* +- * (C) Copyright 2008 +- * +- * Georg Schardt +- * +- * 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 +- * +- * CAUTION: This file is based on the xparameters.h automatically +- * generated by libgen. Version: Xilinx EDK 10.1.02 Build EDK_K_SP2.5 +- */ +- +-#ifndef __XPARAMETER_H__ +-#define __XPARAMETER_H__ +- +-/* RS232 */ +-#define XPAR_UARTNS550_0_CLOCK_FREQ_HZ 100000000 +-#define XPAR_UARTNS550_0_BASEADDR 0x83E00000 +- +- +-/* INT_C */ +-#define XPAR_XPS_INTC_0_DEVICE_ID 0 +-#define XPAR_XPS_INTC_0_BASEADDR 0x81800000 +-#define XPAR_INTC_MAX_NUM_INTR_INPUTS 2 +- +-/* CPU core clock */ +-#define XPAR_CORE_CLOCK_FREQ_HZ 300000000 +-#define XPAR_PLB_CLOCK_FREQ_HZ 100000000 +- +-/* RAM */ +-#define XPAR_DDR2_SDRAM_MEM_BASEADDR 0x00000000 +- +-/* FLASH */ +-#define XPAR_FLASH_MEM0_BASEADDR 0xFFC00000 +- +-#endif +diff --git a/board/avnet/v5fx30teval/.gitignore b/board/avnet/v5fx30teval/.gitignore +deleted file mode 100644 +index f6418a0..0000000 +--- a/board/avnet/v5fx30teval/.gitignore ++++ /dev/null +@@ -1 +0,0 @@ +-/config.tmp +diff --git a/board/avnet/v5fx30teval/Makefile b/board/avnet/v5fx30teval/Makefile +deleted file mode 100644 +index de23f29..0000000 +--- a/board/avnet/v5fx30teval/Makefile ++++ /dev/null +@@ -1,27 +0,0 @@ +-# +-# (C) Copyright 2008 +-# Ricardo Ribalda,Universidad Autonoma de Madrid, ricardo.ribalda@uam.es +-# This work has been supported by: Qtechnology http://qtec.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 +-# +- +-COBJS += $(BOARD).o +- +-include $(SRCTREE)/board/xilinx/ppc440-generic/Makefile +diff --git a/board/avnet/v5fx30teval/v5fx30teval.c b/board/avnet/v5fx30teval/v5fx30teval.c +deleted file mode 100644 +index 14a1d5d..0000000 +--- a/board/avnet/v5fx30teval/v5fx30teval.c ++++ /dev/null +@@ -1,28 +0,0 @@ +-/* +- * (C) Copyright 2008 +- * Ricado Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es +- * This work has been supported by: QTechnology http://qtec.com/ +- * 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, see . +-*/ +- +-#include +-#include +-#include +- +- +-int checkboard(void) +-{ +- puts("Avnet Virtex 5 FX30 Evaluation Board\n"); +- return 0; +-} +diff --git a/board/avnet/v5fx30teval/xparameters.h b/board/avnet/v5fx30teval/xparameters.h +deleted file mode 100644 +index bb657fc..0000000 +--- a/board/avnet/v5fx30teval/xparameters.h ++++ /dev/null +@@ -1,33 +0,0 @@ +-/* +- * (C) Copyright 2008 +- * Ricado Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es +- * This work has been supported by: QTechnology http://qtec.com/ +- * based on xparameters.h by Xilinx +- * +- * 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, see . +-*/ +- +-#ifndef XPARAMETER_H +-#define XPARAMETER_H +- +-#define XPAR_DDR2_SDRAM_MEM_BASEADDR 0x00000000 +-#define XPAR_INTC_0_BASEADDR 0x81800000 +-#define XPAR_UARTLITE_0_BASEADDR 0x84000000 +-#define XPAR_FLASH_MEM0_BASEADDR 0xFF000000 +-#define XPAR_PLB_CLOCK_FREQ_HZ 100000000 +-#define XPAR_CORE_CLOCK_FREQ_HZ 400000000 +-#define XPAR_INTC_MAX_NUM_INTR_INPUTS 13 +-#define XPAR_UARTLITE_0_BAUDRATE 9600 +- +-#endif +diff --git a/board/xilinx/common/xbasic_types.c b/board/xilinx/common/xbasic_types.c +index c3a171a..7a80347 100644 +--- a/board/xilinx/common/xbasic_types.c ++++ b/board/xilinx/common/xbasic_types.c +@@ -1,39 +1,22 @@ ++/* $Id $ */ + /****************************************************************************** + * +-* Author: Xilinx, Inc. +-* +-* +-* 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. +-* +-* +-* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A +-* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS +-* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD, +-* XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE +-* FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING +-* ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION. +-* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO +-* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY +-* WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM +-* CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND +-* FITNESS FOR A PARTICULAR PURPOSE. +-* +-* +-* Xilinx hardware products are not intended for use in life support +-* appliances, devices, or systems. Use in such applications is +-* expressly prohibited. +-* +-* +-* (c) Copyright 2002-2004 Xilinx Inc. +-* All rights reserved. +-* +- * +-* 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., +-* 675 Mass Ave, Cambridge, MA 02139, USA. ++* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" ++* AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND ++* SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, ++* OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, ++* APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION ++* THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, ++* AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE ++* FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY ++* WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE ++* IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR ++* REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF ++* INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ++* FOR A PARTICULAR PURPOSE. ++* ++* (c) Copyright 2002-2003 Xilinx Inc. ++* All rights reserved. + * + ******************************************************************************/ + /*****************************************************************************/ +@@ -49,6 +32,7 @@ + * Ver Who Date Changes + * ----- ---- -------- ------------------------------------------------------- + * 1.00a rpm 11/07/03 Added XNullHandler function as a stub interrupt handler ++* 1.00a xd 11/03/04 Improved support for doxygen. + * + * + ******************************************************************************/ +@@ -77,7 +61,7 @@ unsigned int XAssertStatus; + * such that it does not wait infinitely. Use the debugger to disable the + * waiting during testing of asserts. + */ +-u32 XWaitInAssert = TRUE; ++int XWaitInAssert = TRUE; + + /* The callback function to be invoked when an assert is taken */ + static XAssertCallback XAssertCallbackRoutine = (XAssertCallback) NULL; +@@ -94,17 +78,12 @@ static XAssertCallback XAssertCallbackRoutine = (XAssertCallback) NULL; + * @param File is the name of the filename of the source + * @param Line is the linenumber within File + * +-* @return +-* +-* None. ++* @return None. + * +-* @note +-* +-* None. ++* @note None. + * + ******************************************************************************/ +-void +-XAssert(char *File, int Line) ++void XAssert(char *File, int Line) + { + /* if the callback has been set then invoke it */ + if (XAssertCallbackRoutine != NULL) { +@@ -126,21 +105,17 @@ XAssert(char *File, int Line) + * + * @param Routine is the callback to be invoked when an assert is taken + * +-* @return +-* +-* None. ++* @return None. + * +-* @note +-* +-* This function has no effect if NDEBUG is set ++* @note This function has no effect if NDEBUG is set + * + ******************************************************************************/ +-void +-XAssertSetCallback(XAssertCallback Routine) ++void XAssertSetCallback(XAssertCallback Routine) + { + XAssertCallbackRoutine = Routine; + } + ++ + /*****************************************************************************/ + /** + * +@@ -150,16 +125,11 @@ XAssertSetCallback(XAssertCallback Routine) + * + * @param NullParameter is an arbitrary void pointer and not used. + * +-* @return +-* +-* None. +-* +-* @note ++* @return None. + * +-* None. ++* @note None. + * + ******************************************************************************/ +-void +-XNullHandler(void *NullParameter) ++void XNullHandler(void *NullParameter) + { + } +diff --git a/board/xilinx/common/xbasic_types.h b/board/xilinx/common/xbasic_types.h +index ef0b7c2..dd118be 100644 +--- a/board/xilinx/common/xbasic_types.h ++++ b/board/xilinx/common/xbasic_types.h +@@ -1,39 +1,22 @@ ++/* $Id: xbasic_types.h,v 1.1.2.1 2009/05/19 14:56:55 meinelte Exp $ */ + /****************************************************************************** + * +-* Author: Xilinx, Inc. +-* +-* +-* 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. +-* +-* +-* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A +-* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS +-* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD, +-* XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE +-* FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING +-* ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION. +-* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO +-* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY +-* WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM +-* CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND +-* FITNESS FOR A PARTICULAR PURPOSE. +-* +-* +-* Xilinx hardware products are not intended for use in life support +-* appliances, devices, or systems. Use in such applications is +-* expressly prohibited. +-* +-* +-* (c) Copyright 2002-2004 Xilinx Inc. +-* All rights reserved. +-* +-* +-* 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., +-* 675 Mass Ave, Cambridge, MA 02139, USA. ++* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" ++* AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND ++* SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, ++* OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, ++* APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION ++* THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, ++* AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE ++* FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY ++* WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE ++* IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR ++* REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF ++* INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ++* FOR A PARTICULAR PURPOSE. ++* ++* (c) Copyright 2002-2007 Xilinx Inc. ++* All rights reserved. + * + ******************************************************************************/ + /*****************************************************************************/ +@@ -52,45 +35,61 @@ + *
+ * MODIFICATION HISTORY:
+ *
+-* Ver	Who    Date   Changes
++* Ver   Who    Date   Changes
+ * ----- ---- -------- -------------------------------------------------------
+ * 1.00a rmm  12/14/01 First release
+-*	rmm  05/09/03 Added "xassert always" macros to rid ourselves of diab
+-*		      compiler warnings
++*       rmm  05/09/03 Added "xassert always" macros to rid ourselves of diab
++*                     compiler warnings
+ * 1.00a rpm  11/07/03 Added XNullHandler function as a stub interrupt handler
++* 1.00a rpm  07/21/04 Added XExceptionHandler typedef for processor exceptions
++* 1.00a xd   11/03/04 Improved support for doxygen.
++* 1.00a wre  01/25/07 Added Linux style data types u32, u16, u8, TRUE, FALSE
++* 1.00a rpm  04/02/07 Added ifndef KERNEL around u32, u16, u8 data types
+ * 
+ * + ******************************************************************************/ + +-#ifndef XBASIC_TYPES_H /* prevent circular inclusions */ +-#define XBASIC_TYPES_H /* by using protection macros */ ++#ifndef XBASIC_TYPES_H /* prevent circular inclusions */ ++#define XBASIC_TYPES_H /* by using protection macros */ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ + + /***************************** Include Files *********************************/ + ++ + /************************** Constant Definitions *****************************/ + + #ifndef TRUE +-#define TRUE 1 ++# define TRUE 1 + #endif ++ + #ifndef FALSE +-#define FALSE 0 ++# define FALSE 0 + #endif + + #ifndef NULL +-#define NULL 0 ++#define NULL 0 + #endif +-/** Null */ + +-#define XCOMPONENT_IS_READY 0x11111111 /* component has been initialized */ +-#define XCOMPONENT_IS_STARTED 0x22222222 /* component has been started */ ++/** Xilinx NULL, TRUE and FALSE legacy support. Deprecated. */ ++#define XNULL NULL ++#define XTRUE TRUE ++#define XFALSE FALSE ++ ++ ++#define XCOMPONENT_IS_READY 0x11111111 /**< component has been initialized */ ++#define XCOMPONENT_IS_STARTED 0x22222222 /**< component has been started */ + + /* the following constants and declarations are for unit test purposes and are + * designed to be used in test applications. + */ +-#define XTEST_PASSED 0 +-#define XTEST_FAILED 1 ++#define XTEST_PASSED 0 ++#define XTEST_FAILED 1 + +-#define XASSERT_NONE 0 ++#define XASSERT_NONE 0 + #define XASSERT_OCCURRED 1 + + extern unsigned int XAssertStatus; +@@ -98,18 +97,38 @@ extern void XAssert(char *, int); + + /**************************** Type Definitions *******************************/ + +-/** @name Primitive types +- * These primitive types are created for transportability. +- * They are dependent upon the target architecture. ++/** @name Legacy types ++ * Deprecated legacy types. + * @{ + */ +-#include ++typedef unsigned char Xuint8; /**< unsigned 8-bit */ ++typedef char Xint8; /**< signed 8-bit */ ++typedef unsigned short Xuint16; /**< unsigned 16-bit */ ++typedef short Xint16; /**< signed 16-bit */ ++typedef unsigned long Xuint32; /**< unsigned 32-bit */ ++typedef long Xint32; /**< signed 32-bit */ ++typedef float Xfloat32; /**< 32-bit floating point */ ++typedef double Xfloat64; /**< 64-bit double precision FP */ ++typedef unsigned long Xboolean; /**< boolean (XTRUE or XFALSE) */ + +-typedef struct { +- u32 Upper; +- u32 Lower; ++typedef struct ++{ ++ Xuint32 Upper; ++ Xuint32 Lower; + } Xuint64; + ++/** @name New types ++ * New simple types. ++ * @{ ++ */ ++#ifndef __KERNEL__ ++typedef Xuint32 u32; ++typedef Xuint16 u16; ++typedef Xuint8 u8; ++#else ++#include ++#endif ++ + /*@}*/ + + /** +@@ -119,6 +138,12 @@ typedef struct { + typedef void (*XInterruptHandler) (void *InstancePtr); + + /** ++ * This data type defines an exception handler for a processor. ++ * The argument points to the instance of the component ++ */ ++typedef void (*XExceptionHandler) (void *InstancePtr); ++ ++/** + * This data type defines a callback to be invoked when an + * assert occurs. The callback is invoked only when asserts are enabled + */ +@@ -130,15 +155,11 @@ typedef void (*XAssertCallback) (char *FilenamePtr, int LineNumber); + /** + * Return the most significant half of the 64 bit data type. + * +-* @param x is the 64 bit word. ++* @param x is the 64 bit word. + * +-* @return ++* @return The upper 32 bits of the 64 bit word. + * +-* The upper 32 bits of the 64 bit word. +-* +-* @note +-* +-* None. ++* @note None. + * + ******************************************************************************/ + #define XUINT64_MSW(x) ((x).Upper) +@@ -147,19 +168,16 @@ typedef void (*XAssertCallback) (char *FilenamePtr, int LineNumber); + /** + * Return the least significant half of the 64 bit data type. + * +-* @param x is the 64 bit word. +-* +-* @return ++* @param x is the 64 bit word. + * +-* The lower 32 bits of the 64 bit word. ++* @return The lower 32 bits of the 64 bit word. + * +-* @note +-* +-* None. ++* @note None. + * + ******************************************************************************/ + #define XUINT64_LSW(x) ((x).Lower) + ++ + #ifndef NDEBUG + + /*****************************************************************************/ +@@ -168,28 +186,27 @@ typedef void (*XAssertCallback) (char *FilenamePtr, int LineNumber); + * (void). This in conjunction with the XWaitInAssert boolean can be used to + * accomodate tests so that asserts which fail allow execution to continue. + * +-* @param expression is the expression to evaluate. If it evaluates to false, +-* the assert occurs. +-* +-* @return ++* @param expression is the expression to evaluate. If it evaluates to ++* false, the assert occurs. + * +-* Returns void unless the XWaitInAssert variable is true, in which case +-* no return is made and an infinite loop is entered. ++* @return Returns void unless the XWaitInAssert variable is true, in which ++* case no return is made and an infinite loop is entered. + * +-* @note +-* +-* None. ++* @note None. + * + ******************************************************************************/ +-#define XASSERT_VOID(expression) \ +-{ \ +- if (expression) { \ +- XAssertStatus = XASSERT_NONE; \ +- } else { \ +- XAssert(__FILE__, __LINE__); \ +- XAssertStatus = XASSERT_OCCURRED; \ +- return; \ +- } \ ++#define XASSERT_VOID(expression) \ ++{ \ ++ if (expression) \ ++ { \ ++ XAssertStatus = XASSERT_NONE; \ ++ } \ ++ else \ ++ { \ ++ XAssert(__FILE__, __LINE__); \ ++ XAssertStatus = XASSERT_OCCURRED; \ ++ return; \ ++ } \ + } + + /*****************************************************************************/ +@@ -198,28 +215,27 @@ typedef void (*XAssertCallback) (char *FilenamePtr, int LineNumber); + * conjunction with the XWaitInAssert boolean can be used to accomodate tests so + * that asserts which fail allow execution to continue. + * +-* @param expression is the expression to evaluate. If it evaluates to false, +-* the assert occurs. ++* @param expression is the expression to evaluate. If it evaluates to false, ++* the assert occurs. + * +-* @return ++* @return Returns 0 unless the XWaitInAssert variable is true, in which case ++* no return is made and an infinite loop is entered. + * +-* Returns 0 unless the XWaitInAssert variable is true, in which case +-* no return is made and an infinite loop is entered. +-* +-* @note +-* +-* None. ++* @note None. + * + ******************************************************************************/ +-#define XASSERT_NONVOID(expression) \ +-{ \ +- if (expression) { \ +- XAssertStatus = XASSERT_NONE; \ +- } else { \ +- XAssert(__FILE__, __LINE__); \ +- XAssertStatus = XASSERT_OCCURRED; \ +- return 0; \ +- } \ ++#define XASSERT_NONVOID(expression) \ ++{ \ ++ if (expression) \ ++ { \ ++ XAssertStatus = XASSERT_NONE; \ ++ } \ ++ else \ ++ { \ ++ XAssert(__FILE__, __LINE__); \ ++ XAssertStatus = XASSERT_OCCURRED; \ ++ return 0; \ ++ } \ + } + + /*****************************************************************************/ +@@ -228,21 +244,17 @@ typedef void (*XAssertCallback) (char *FilenamePtr, int LineNumber); + * return anything (void). Use for instances where an assert should always + * occur. + * +-* @return +-* +-* Returns void unless the XWaitInAssert variable is true, in which case +-* no return is made and an infinite loop is entered. ++* @return Returns void unless the XWaitInAssert variable is true, in which case ++* no return is made and an infinite loop is entered. + * +-* @note +-* +-* None. ++* @note None. + * + ******************************************************************************/ +-#define XASSERT_VOID_ALWAYS() \ +-{ \ +- XAssert(__FILE__, __LINE__); \ +- XAssertStatus = XASSERT_OCCURRED; \ +- return; \ ++#define XASSERT_VOID_ALWAYS() \ ++{ \ ++ XAssert(__FILE__, __LINE__); \ ++ XAssertStatus = XASSERT_OCCURRED; \ ++ return; \ + } + + /*****************************************************************************/ +@@ -250,23 +262,20 @@ typedef void (*XAssertCallback) (char *FilenamePtr, int LineNumber); + * Always assert. This assert macro is to be used for functions that do return + * a value. Use for instances where an assert should always occur. + * +-* @return +-* +-* Returns void unless the XWaitInAssert variable is true, in which case +-* no return is made and an infinite loop is entered. ++* @return Returns void unless the XWaitInAssert variable is true, in which case ++* no return is made and an infinite loop is entered. + * +-* @note +-* +-* None. ++* @note None. + * + ******************************************************************************/ +-#define XASSERT_NONVOID_ALWAYS() \ +-{ \ +- XAssert(__FILE__, __LINE__); \ +- XAssertStatus = XASSERT_OCCURRED; \ +- return 0; \ ++#define XASSERT_NONVOID_ALWAYS() \ ++{ \ ++ XAssert(__FILE__, __LINE__); \ ++ XAssertStatus = XASSERT_OCCURRED; \ ++ return 0; \ + } + ++ + #else + + #define XASSERT_VOID(expression) +@@ -280,4 +289,8 @@ typedef void (*XAssertCallback) (char *FilenamePtr, int LineNumber); + void XAssertSetCallback(XAssertCallback Routine); + void XNullHandler(void *NullParameter); + ++#ifdef __cplusplus ++} ++#endif ++ + #endif /* end of protection macro */ +diff --git a/board/xilinx/common/xstatus.h b/board/xilinx/common/xstatus.h +index ffda4d7..6808afc 100644 +--- a/board/xilinx/common/xstatus.h ++++ b/board/xilinx/common/xstatus.h +@@ -1,39 +1,42 @@ ++/* $Id: xstatus.h,v 1.1.2.1 2010/01/07 06:11:50 sadanan Exp $ */ + /****************************************************************************** + * +-* Author: Xilinx, Inc. ++* (c) Copyright 2002-2009 Xilinx, Inc. All rights reserved. + * ++* This file contains confidential and proprietary information of Xilinx, Inc. ++* and is protected under U.S. and international copyright and other ++* intellectual property laws. + * +-* 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. ++* DISCLAIMER ++* This disclaimer is not a license and does not grant any rights to the ++* materials distributed herewith. Except as otherwise provided in a valid ++* license issued to you by Xilinx, and to the maximum extent permitted by ++* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL ++* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, ++* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF ++* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; ++* and (2) Xilinx shall not be liable (whether in contract or tort, including ++* negligence, or under any other theory of liability) for any loss or damage ++* of any kind or nature related to, arising under or in connection with these ++* materials, including for any direct, or any indirect, special, incidental, ++* or consequential loss or damage (including loss of data, profits, goodwill, ++* or any type of loss or damage suffered as a result of any action brought by ++* a third party) even if such damage or loss was reasonably foreseeable or ++* Xilinx had been advised of the possibility of the same. + * ++* CRITICAL APPLICATIONS ++* Xilinx products are not designed or intended to be fail-safe, or for use in ++* any application requiring fail-safe performance, such as life-support or ++* safety devices or systems, Class III medical devices, nuclear facilities, ++* applications related to the deployment of airbags, or any other applications ++* that could lead to death, personal injury, or severe property or ++* environmental damage (individually and collectively, "Critical ++* Applications"). Customer assumes the sole risk and liability of any use of ++* Xilinx products in Critical Applications, subject only to applicable laws ++* and regulations governing limitations on product liability. + * +-* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A +-* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS +-* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD, +-* XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE +-* FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING +-* ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION. +-* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO +-* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY +-* WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM +-* CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND +-* FITNESS FOR A PARTICULAR PURPOSE. +-* +-* +-* Xilinx hardware products are not intended for use in life support +-* appliances, devices, or systems. Use in such applications is +-* expressly prohibited. +-* +-* +-* (c) Copyright 2002-2004 Xilinx Inc. +-* All rights reserved. +-* +-* +-* 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., +-* 675 Mass Ave, Cambridge, MA 02139, USA. ++* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE ++* AT ALL TIMES. + * + ******************************************************************************/ + /*****************************************************************************/ +@@ -42,7 +45,7 @@ + * @file xstatus.h + * + * This file contains Xilinx software status codes. Status codes have their +-* own data type called XStatus. These codes are used throughout the Xilinx ++* own data type called int. These codes are used throughout the Xilinx + * device drivers. + * + ******************************************************************************/ +@@ -50,298 +53,376 @@ + #ifndef XSTATUS_H /* prevent circular inclusions */ + #define XSTATUS_H /* by using protection macros */ + ++#ifdef __cplusplus ++extern "C" { ++#endif ++ + /***************************** Include Files *********************************/ + ++#ifdef NOTNOW ++#include "xil_types.h" ++#include "xil_assert.h" ++#else + #include "xbasic_types.h" ++#endif + + /************************** Constant Definitions *****************************/ + + /*********************** Common statuses 0 - 500 *****************************/ + +-#define XST_SUCCESS 0L +-#define XST_FAILURE 1L +-#define XST_DEVICE_NOT_FOUND 2L +-#define XST_DEVICE_BLOCK_NOT_FOUND 3L +-#define XST_INVALID_VERSION 4L +-#define XST_DEVICE_IS_STARTED 5L +-#define XST_DEVICE_IS_STOPPED 6L +-#define XST_FIFO_ERROR 7L /* an error occurred during an ++#define XST_SUCCESS 0L ++#define XST_FAILURE 1L ++#define XST_DEVICE_NOT_FOUND 2L ++#define XST_DEVICE_BLOCK_NOT_FOUND 3L ++#define XST_INVALID_VERSION 4L ++#define XST_DEVICE_IS_STARTED 5L ++#define XST_DEVICE_IS_STOPPED 6L ++#define XST_FIFO_ERROR 7L /* an error occurred during an + operation with a FIFO such as + an underrun or overrun, this + error requires the device to + be reset */ +-#define XST_RESET_ERROR 8L /* an error occurred which requires +- the device to be reset */ +-#define XST_DMA_ERROR 9L /* a DMA error occurred, this error +- typically requires the device +- using the DMA to be reset */ +-#define XST_NOT_POLLED 10L /* the device is not configured for +- polled mode operation */ +-#define XST_FIFO_NO_ROOM 11L /* a FIFO did not have room to put +- the specified data into */ +-#define XST_BUFFER_TOO_SMALL 12L /* the buffer is not large enough +- to hold the expected data */ +-#define XST_NO_DATA 13L /* there was no data available */ +-#define XST_REGISTER_ERROR 14L /* a register did not contain the +- expected value */ +-#define XST_INVALID_PARAM 15L /* an invalid parameter was passed +- into the function */ +-#define XST_NOT_SGDMA 16L /* the device is not configured for +- scatter-gather DMA operation */ +-#define XST_LOOPBACK_ERROR 17L /* a loopback test failed */ +-#define XST_NO_CALLBACK 18L /* a callback has not yet been +- * registered */ +-#define XST_NO_FEATURE 19L /* device is not configured with +- * the requested feature */ +-#define XST_NOT_INTERRUPT 20L /* device is not configured for +- * interrupt mode operation */ +-#define XST_DEVICE_BUSY 21L /* device is busy */ +-#define XST_ERROR_COUNT_MAX 22L /* the error counters of a device +- * have maxed out */ +-#define XST_IS_STARTED 23L /* used when part of device is +- * already started i.e. +- * sub channel */ +-#define XST_IS_STOPPED 24L /* used when part of device is +- * already stopped i.e. +- * sub channel */ ++#define XST_RESET_ERROR 8L /* an error occurred which ++ requires the device to be ++ reset */ ++#define XST_DMA_ERROR 9L /* a DMA error occurred, this ++ error typically requires the ++ device using the DMA to be ++ reset */ ++#define XST_NOT_POLLED 10L /* the device is not configured ++ for polled mode operation */ ++#define XST_FIFO_NO_ROOM 11L /* a FIFO did not have room to ++ put the specified data into ++ */ ++#define XST_BUFFER_TOO_SMALL 12L /* the buffer is not large ++ enough to hold the expected ++ data */ ++#define XST_NO_DATA 13L /* there was no data available ++ */ ++#define XST_REGISTER_ERROR 14L /* a register did not contain ++ the expected value */ ++#define XST_INVALID_PARAM 15L /* an invalid parameter was ++ passed into the function */ ++#define XST_NOT_SGDMA 16L /* the device is not configured ++ for scatter-gather DMA ++ operation */ ++#define XST_LOOPBACK_ERROR 17L /* a loopback test failed */ ++#define XST_NO_CALLBACK 18L /* a callback has not yet been ++ registered */ ++#define XST_NO_FEATURE 19L /* device is not configured with ++ the requested feature */ ++#define XST_NOT_INTERRUPT 20L /* device is not configured for ++ interrupt mode operation */ ++#define XST_DEVICE_BUSY 21L /* device is busy */ ++#define XST_ERROR_COUNT_MAX 22L /* the error counters of a ++ device have maxed out */ ++#define XST_IS_STARTED 23L /* used when part of device is ++ already started i.e. ++ sub channel */ ++#define XST_IS_STOPPED 24L /* used when part of device is ++ already stopped i.e. ++ sub channel */ ++#define XST_DATA_LOST 26L /* driver defined error */ ++#define XST_RECV_ERROR 27L /* generic receive error */ ++#define XST_SEND_ERROR 28L /* generic transmit error */ ++#define XST_NOT_ENABLED 29L /* a requested service is not ++ available because it has not ++ been enabled */ + + /***************** Utility Component statuses 401 - 500 *********************/ + +-#define XST_MEMTEST_FAILED 401L /* memory test failed */ ++#define XST_MEMTEST_FAILED 401L /* memory test failed */ + + /***************** Common Components statuses 501 - 1000 *********************/ + + /********************* Packet Fifo statuses 501 - 510 ************************/ + +-#define XST_PFIFO_LACK_OF_DATA 501L /* not enough data in FIFO */ +-#define XST_PFIFO_NO_ROOM 502L /* not enough room in FIFO */ +-#define XST_PFIFO_BAD_REG_VALUE 503L /* self test, a register value ++#define XST_PFIFO_LACK_OF_DATA 501L /* not enough data in FIFO */ ++#define XST_PFIFO_NO_ROOM 502L /* not enough room in FIFO */ ++#define XST_PFIFO_BAD_REG_VALUE 503L /* self test, a register value + was invalid after reset */ ++#define XST_PFIFO_ERROR 504L /* generic packet FIFO error */ ++#define XST_PFIFO_DEADLOCK 505L /* packet FIFO is reporting ++ * empty and full simultaneously ++ */ + + /************************** DMA statuses 511 - 530 ***************************/ + +-#define XST_DMA_TRANSFER_ERROR 511L /* self test, DMA transfer ++#define XST_DMA_TRANSFER_ERROR 511L /* self test, DMA transfer + failed */ +-#define XST_DMA_RESET_REGISTER_ERROR 512L /* self test, a register value ++#define XST_DMA_RESET_REGISTER_ERROR 512L /* self test, a register value + was invalid after reset */ +-#define XST_DMA_SG_LIST_EMPTY 513L /* scatter gather list contains ++#define XST_DMA_SG_LIST_EMPTY 513L /* scatter gather list contains + no buffer descriptors ready + to be processed */ +-#define XST_DMA_SG_IS_STARTED 514L /* scatter gather not stopped */ +-#define XST_DMA_SG_IS_STOPPED 515L /* scatter gather not running */ +-#define XST_DMA_SG_LIST_FULL 517L /* all the buffer desciptors of ++#define XST_DMA_SG_IS_STARTED 514L /* scatter gather not stopped */ ++#define XST_DMA_SG_IS_STOPPED 515L /* scatter gather not running */ ++#define XST_DMA_SG_LIST_FULL 517L /* all the buffer desciptors of + the scatter gather list are + being used */ +-#define XST_DMA_SG_BD_LOCKED 518L /* the scatter gather buffer ++#define XST_DMA_SG_BD_LOCKED 518L /* the scatter gather buffer + descriptor which is to be + copied over in the scatter + list is locked */ +-#define XST_DMA_SG_NOTHING_TO_COMMIT 519L /* no buffer descriptors have been +- put into the scatter gather +- list to be commited */ +-#define XST_DMA_SG_COUNT_EXCEEDED 521L /* the packet count threshold ++#define XST_DMA_SG_NOTHING_TO_COMMIT 519L /* no buffer descriptors have ++ been put into the scatter ++ gather list to be commited */ ++#define XST_DMA_SG_COUNT_EXCEEDED 521L /* the packet count threshold + specified was larger than the + total # of buffer descriptors + in the scatter gather list */ +-#define XST_DMA_SG_LIST_EXISTS 522L /* the scatter gather list has ++#define XST_DMA_SG_LIST_EXISTS 522L /* the scatter gather list has + already been created */ +-#define XST_DMA_SG_NO_LIST 523L /* no scatter gather list has ++#define XST_DMA_SG_NO_LIST 523L /* no scatter gather list has + been created */ +-#define XST_DMA_SG_BD_NOT_COMMITTED 524L /* the buffer descriptor which was +- being started was not committed +- to the list */ +-#define XST_DMA_SG_NO_DATA 525L /* the buffer descriptor to start +- has already been used by the +- hardware so it can't be reused +- */ ++#define XST_DMA_SG_BD_NOT_COMMITTED 524L /* the buffer descriptor which ++ was being started was not ++ committed to the list */ ++#define XST_DMA_SG_NO_DATA 525L /* the buffer descriptor to ++ start has already been used ++ by the hardware so it can't ++ be reused */ ++#define XST_DMA_SG_LIST_ERROR 526L /* general purpose list access ++ error */ ++#define XST_DMA_BD_ERROR 527L /* general buffer descriptor ++ error */ + + /************************** IPIF statuses 531 - 550 ***************************/ + +-#define XST_IPIF_REG_WIDTH_ERROR 531L /* an invalid register width ++#define XST_IPIF_REG_WIDTH_ERROR 531L /* an invalid register width + was passed into the function */ +-#define XST_IPIF_RESET_REGISTER_ERROR 532L /* the value of a register at ++#define XST_IPIF_RESET_REGISTER_ERROR 532L /* the value of a register at + reset was not valid */ +-#define XST_IPIF_DEVICE_STATUS_ERROR 533L /* a write to the device interrupt ++#define XST_IPIF_DEVICE_STATUS_ERROR 533L /* a write to the device intr + status register did not read + back correctly */ +-#define XST_IPIF_DEVICE_ACK_ERROR 534L /* the device interrupt status ++#define XST_IPIF_DEVICE_ACK_ERROR 534L /* the device interrupt status + register did not reset when + acked */ +-#define XST_IPIF_DEVICE_ENABLE_ERROR 535L /* the device interrupt enable ++#define XST_IPIF_DEVICE_ENABLE_ERROR 535L /* the device interrupt enable + register was not updated when + other registers changed */ +-#define XST_IPIF_IP_STATUS_ERROR 536L /* a write to the IP interrupt ++#define XST_IPIF_IP_STATUS_ERROR 536L /* a write to the IP interrupt + status register did not read + back correctly */ +-#define XST_IPIF_IP_ACK_ERROR 537L /* the IP interrupt status register +- did not reset when acked */ +-#define XST_IPIF_IP_ENABLE_ERROR 538L /* IP interrupt enable register was +- not updated correctly when other +- registers changed */ +-#define XST_IPIF_DEVICE_PENDING_ERROR 539L /* The device interrupt pending ++#define XST_IPIF_IP_ACK_ERROR 537L /* the IP interrupt status ++ register did not reset when ++ acked */ ++#define XST_IPIF_IP_ENABLE_ERROR 538L /* IP interrupt enable register ++ was not updated correctly ++ when other registers changed ++ */ ++#define XST_IPIF_DEVICE_PENDING_ERROR 539L /* The device interrupt pending ++ register did not indicate the ++ expected value */ ++#define XST_IPIF_DEVICE_ID_ERROR 540L /* The device interrupt ID + register did not indicate the + expected value */ +-#define XST_IPIF_DEVICE_ID_ERROR 540L /* The device interrupt ID register +- did not indicate the expected +- value */ ++#define XST_IPIF_ERROR 541L /* generic ipif error */ + + /****************** Device specific statuses 1001 - 4095 *********************/ + + /********************* Ethernet statuses 1001 - 1050 *************************/ + +-#define XST_EMAC_MEMORY_SIZE_ERROR 1001L /* Memory space is not big enough +- * to hold the minimum number of +- * buffers or descriptors */ +-#define XST_EMAC_MEMORY_ALLOC_ERROR 1002L /* Memory allocation failed */ +-#define XST_EMAC_MII_READ_ERROR 1003L /* MII read error */ +-#define XST_EMAC_MII_BUSY 1004L /* An MII operation is in progress */ +-#define XST_EMAC_OUT_OF_BUFFERS 1005L /* Adapter is out of buffers */ +-#define XST_EMAC_PARSE_ERROR 1006L /* Invalid adapter init string */ +-#define XST_EMAC_COLLISION_ERROR 1007L /* Excess deferral or late ++#define XST_EMAC_MEMORY_SIZE_ERROR 1001L /* Memory space is not big ++ * enough to hold the minimum ++ * number of buffers or ++ * descriptors */ ++#define XST_EMAC_MEMORY_ALLOC_ERROR 1002L /* Memory allocation failed */ ++#define XST_EMAC_MII_READ_ERROR 1003L /* MII read error */ ++#define XST_EMAC_MII_BUSY 1004L /* An MII operation is in ++ * progress */ ++#define XST_EMAC_OUT_OF_BUFFERS 1005L /* Driver is out of buffers */ ++#define XST_EMAC_PARSE_ERROR 1006L /* Invalid driver init string */ ++#define XST_EMAC_COLLISION_ERROR 1007L /* Excess deferral or late + * collision on polled send */ + + /*********************** UART statuses 1051 - 1075 ***************************/ + #define XST_UART + +-#define XST_UART_INIT_ERROR 1051L +-#define XST_UART_START_ERROR 1052L +-#define XST_UART_CONFIG_ERROR 1053L +-#define XST_UART_TEST_FAIL 1054L +-#define XST_UART_BAUD_ERROR 1055L +-#define XST_UART_BAUD_RANGE 1056L ++#define XST_UART_INIT_ERROR 1051L ++#define XST_UART_START_ERROR 1052L ++#define XST_UART_CONFIG_ERROR 1053L ++#define XST_UART_TEST_FAIL 1054L ++#define XST_UART_BAUD_ERROR 1055L ++#define XST_UART_BAUD_RANGE 1056L + + /************************ IIC statuses 1076 - 1100 ***************************/ + +-#define XST_IIC_SELFTEST_FAILED 1076 /* self test failed */ +-#define XST_IIC_BUS_BUSY 1077 /* bus found busy */ +-#define XST_IIC_GENERAL_CALL_ADDRESS 1078 /* mastersend attempted with */ +- /* general call address */ +-#define XST_IIC_STAND_REG_RESET_ERROR 1079 /* A non parameterizable reg */ +- /* value after reset not valid */ +-#define XST_IIC_TX_FIFO_REG_RESET_ERROR 1080 /* Tx fifo included in design */ +- /* value after reset not valid */ +-#define XST_IIC_RX_FIFO_REG_RESET_ERROR 1081 /* Rx fifo included in design */ +- /* value after reset not valid */ +-#define XST_IIC_TBA_REG_RESET_ERROR 1082 /* 10 bit addr incl in design */ +- /* value after reset not valid */ +-#define XST_IIC_CR_READBACK_ERROR 1083 /* Read of the control register */ +- /* didn't return value written */ +-#define XST_IIC_DTR_READBACK_ERROR 1084 /* Read of the data Tx reg */ +- /* didn't return value written */ +-#define XST_IIC_DRR_READBACK_ERROR 1085 /* Read of the data Receive reg */ +- /* didn't return value written */ +-#define XST_IIC_ADR_READBACK_ERROR 1086 /* Read of the data Tx reg */ +- /* didn't return value written */ +-#define XST_IIC_TBA_READBACK_ERROR 1087 /* Read of the 10 bit addr reg */ +- /* didn't return written value */ +-#define XST_IIC_NOT_SLAVE 1088 /* The device isn't a slave */ ++#define XST_IIC_SELFTEST_FAILED 1076 /* self test failed */ ++#define XST_IIC_BUS_BUSY 1077 /* bus found busy */ ++#define XST_IIC_GENERAL_CALL_ADDRESS 1078 /* mastersend attempted with ++ * general call address */ ++#define XST_IIC_STAND_REG_RESET_ERROR 1079 /* A non parameterizable reg ++ * value after reset not valid ++ */ ++#define XST_IIC_TX_FIFO_REG_RESET_ERROR 1080 /* Tx fifo included in design ++ * value after reset not valid ++ */ ++#define XST_IIC_RX_FIFO_REG_RESET_ERROR 1081 /* Rx fifo included in design ++ * value after reset not valid ++ */ ++#define XST_IIC_TBA_REG_RESET_ERROR 1082 /* 10 bit addr incl in design ++ * value after reset not valid ++ */ ++#define XST_IIC_CR_READBACK_ERROR 1083 /* Read of the control register ++ * didn't return value written ++ */ ++#define XST_IIC_DTR_READBACK_ERROR 1084 /* Read of the data Tx reg ++ * didn't return value written ++ */ ++#define XST_IIC_DRR_READBACK_ERROR 1085 /* Read of the data Receive reg ++ * didn't return value written ++ */ ++#define XST_IIC_ADR_READBACK_ERROR 1086 /* Read of the data Tx reg ++ * didn't return value written ++ */ ++#define XST_IIC_TBA_READBACK_ERROR 1087 /* Read of the 10 bit addr reg ++ * didn't return written value ++ */ ++#define XST_IIC_NOT_SLAVE 1088 /* The device isn't a slave */ + + /*********************** ATMC statuses 1101 - 1125 ***************************/ + +-#define XST_ATMC_ERROR_COUNT_MAX 1101L /* the error counters in the ATM ++#define XST_ATMC_ERROR_COUNT_MAX 1101L /* the error counters in the ATM + controller hit the max value + which requires the statistics + to be cleared */ + + /*********************** Flash statuses 1126 - 1150 **************************/ + +-#define XST_FLASH_BUSY 1126L /* Flash is erasing or programming */ +-#define XST_FLASH_READY 1127L /* Flash is ready for commands */ +-#define XST_FLASH_ERROR 1128L /* Flash had detected an internal +- error. Use XFlash_DeviceControl ++#define XST_FLASH_BUSY 1126L /* Flash is erasing or ++ programming */ ++#define XST_FLASH_READY 1127L /* Flash is ready for commands ++ */ ++#define XST_FLASH_ERROR 1128L /* Flash had detected an ++ internal error. Use ++ XFlash_DeviceControl + to retrieve device specific codes */ +-#define XST_FLASH_ERASE_SUSPENDED 1129L /* Flash is in suspended erase state */ +-#define XST_FLASH_WRITE_SUSPENDED 1130L /* Flash is in suspended write state */ +-#define XST_FLASH_PART_NOT_SUPPORTED 1131L /* Flash type not supported by ++#define XST_FLASH_ERASE_SUSPENDED 1129L /* Flash is in suspended erase ++ state */ ++#define XST_FLASH_WRITE_SUSPENDED 1130L /* Flash is in suspended write ++ state */ ++#define XST_FLASH_PART_NOT_SUPPORTED 1131L /* Flash type not supported by + driver */ +-#define XST_FLASH_NOT_SUPPORTED 1132L /* Operation not supported */ +-#define XST_FLASH_TOO_MANY_REGIONS 1133L /* Too many erase regions */ +-#define XST_FLASH_TIMEOUT_ERROR 1134L /* Programming or erase operation +- aborted due to a timeout */ +-#define XST_FLASH_ADDRESS_ERROR 1135L /* Accessed flash outside its ++#define XST_FLASH_NOT_SUPPORTED 1132L /* Operation not supported */ ++#define XST_FLASH_TOO_MANY_REGIONS 1133L /* Too many erase regions */ ++#define XST_FLASH_TIMEOUT_ERROR 1134L /* Programming or erase ++ operation aborted due to a ++ timeout */ ++#define XST_FLASH_ADDRESS_ERROR 1135L /* Accessed flash outside its + addressible range */ +-#define XST_FLASH_ALIGNMENT_ERROR 1136L /* Write alignment error */ +-#define XST_FLASH_BLOCKING_CALL_ERROR 1137L /* Couldn't return immediately from +- write/erase function with +- XFL_NON_BLOCKING_WRITE/ERASE +- option cleared */ +-#define XST_FLASH_CFI_QUERY_ERROR 1138L /* Failed to query the device */ ++#define XST_FLASH_ALIGNMENT_ERROR 1136L /* Write alignment error */ ++#define XST_FLASH_BLOCKING_CALL_ERROR 1137L /* Couldn't return immediately ++ from write/erase function ++ with XFL_NON_BLOCKING_WRITE/ ++ ERASE option cleared */ ++#define XST_FLASH_CFI_QUERY_ERROR 1138L /* Failed to query the device */ + + /*********************** SPI statuses 1151 - 1175 ****************************/ + +-#define XST_SPI_MODE_FAULT 1151 /* master was selected as slave */ +-#define XST_SPI_TRANSFER_DONE 1152 /* data transfer is complete */ +-#define XST_SPI_TRANSMIT_UNDERRUN 1153 /* slave underruns transmit register */ +-#define XST_SPI_RECEIVE_OVERRUN 1154 /* device overruns receive register */ +-#define XST_SPI_NO_SLAVE 1155 /* no slave has been selected yet */ +-#define XST_SPI_TOO_MANY_SLAVES 1156 /* more than one slave is being ++#define XST_SPI_MODE_FAULT 1151 /* master was selected as slave ++ */ ++#define XST_SPI_TRANSFER_DONE 1152 /* data transfer is complete */ ++#define XST_SPI_TRANSMIT_UNDERRUN 1153 /* slave underruns transmit ++ * register */ ++#define XST_SPI_RECEIVE_OVERRUN 1154 /* device overruns receive ++ * register */ ++#define XST_SPI_NO_SLAVE 1155 /* no slave has been selected ++ * yet */ ++#define XST_SPI_TOO_MANY_SLAVES 1156 /* more than one slave is being + * selected */ +-#define XST_SPI_NOT_MASTER 1157 /* operation is valid only as master */ +-#define XST_SPI_SLAVE_ONLY 1158 /* device is configured as slave-only */ +-#define XST_SPI_SLAVE_MODE_FAULT 1159 /* slave was selected while disabled */ ++#define XST_SPI_NOT_MASTER 1157 /* operation is valid only as ++ * master */ ++#define XST_SPI_SLAVE_ONLY 1158 /* device is configured as ++ * slave-only */ ++#define XST_SPI_SLAVE_MODE_FAULT 1159 /* slave was selected while ++ * disabled */ + + /********************** OPB Arbiter statuses 1176 - 1200 *********************/ + +-#define XST_OPBARB_INVALID_PRIORITY 1176 /* the priority registers have either +- * one master assigned to two or more +- * priorities, or one master not +- * assigned to any priority ++#define XST_OPBARB_INVALID_PRIORITY 1176 /* the priority registers have ++ either one master assigned to ++ * two or more priorities, or ++ * one master not assigned ++ * to any priority + */ +-#define XST_OPBARB_NOT_SUSPENDED 1177 /* an attempt was made to modify the +- * priority levels without first +- * suspending the use of priority +- * levels ++#define XST_OPBARB_NOT_SUSPENDED 1177 /* an attempt was made to modify ++ * the priority levels without ++ * first suspending the use of ++ * priority levels + */ +-#define XST_OPBARB_PARK_NOT_ENABLED 1178 /* bus parking by id was enabled but +- * bus parking was not enabled +- */ +-#define XST_OPBARB_NOT_FIXED_PRIORITY 1179 /* the arbiter must be in fixed ++#define XST_OPBARB_PARK_NOT_ENABLED 1178 /* bus parking by id was enabled ++ * but bus parking was not ++ * enabled */ ++#define XST_OPBARB_NOT_FIXED_PRIORITY 1179 /* the arbiter must be in fixed + * priority mode to allow the + * priorities to be changed + */ + + /************************ Intc statuses 1201 - 1225 **************************/ + +-#define XST_INTC_FAIL_SELFTEST 1201 /* self test failed */ +-#define XST_INTC_CONNECT_ERROR 1202 /* interrupt already in use */ ++#define XST_INTC_FAIL_SELFTEST 1201 /* self test failed */ ++#define XST_INTC_CONNECT_ERROR 1202 /* interrupt already in use */ + + /********************** TmrCtr statuses 1226 - 1250 **************************/ + +-#define XST_TMRCTR_TIMER_FAILED 1226 /* self test failed */ ++#define XST_TMRCTR_TIMER_FAILED 1226 /* self test failed */ + + /********************** WdtTb statuses 1251 - 1275 ***************************/ + +-#define XST_WDTTB_TIMER_FAILED 1251L ++#define XST_WDTTB_TIMER_FAILED 1251L + + /********************** PlbArb statuses 1276 - 1300 **************************/ + +-#define XST_PLBARB_FAIL_SELFTEST 1276L ++#define XST_PLBARB_FAIL_SELFTEST 1276L + + /********************** Plb2Opb statuses 1301 - 1325 *************************/ + +-#define XST_PLB2OPB_FAIL_SELFTEST 1301L ++#define XST_PLB2OPB_FAIL_SELFTEST 1301L + + /********************** Opb2Plb statuses 1326 - 1350 *************************/ + +-#define XST_OPB2PLB_FAIL_SELFTEST 1326L ++#define XST_OPB2PLB_FAIL_SELFTEST 1326L + + /********************** SysAce statuses 1351 - 1360 **************************/ + +-#define XST_SYSACE_NO_LOCK 1351L /* No MPU lock has been granted */ ++#define XST_SYSACE_NO_LOCK 1351L /* No MPU lock has been granted ++ */ + + /********************** PCI Bridge statuses 1361 - 1375 **********************/ + +-#define XST_PCI_INVALID_ADDRESS 1361L ++#define XST_PCI_INVALID_ADDRESS 1361L ++ ++/********************** FlexRay constants 1400 - 1409 *************************/ ++ ++#define XST_FR_TX_ERROR 1400 ++#define XST_FR_TX_BUSY 1401 ++#define XST_FR_BUF_LOCKED 1402 ++#define XST_FR_NO_BUF 1403 ++ ++/****************** USB constants 1410 - 1420 *******************************/ ++ ++#define XST_USB_ALREADY_CONFIGURED 1410 ++#define XST_USB_BUF_ALIGN_ERROR 1411 ++#define XST_USB_NO_DESC_AVAILABLE 1412 ++#define XST_USB_BUF_TOO_BIG 1413 ++#define XST_USB_NO_BUF 1414 ++ ++/****************** HWICAP constants 1421 - 1430 *****************************/ ++ ++#define XST_HWICAP_WRITE_DONE 1421 + + /**************************** Type Definitions *******************************/ + +-/** +- * The status typedef. +- */ +-typedef u32 XStatus; ++typedef int XStatus; + + /***************** Macros (Inline Functions) Definitions *********************/ + + /************************** Function Prototypes ******************************/ + +-#endif /* end of protection macro */ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* end of protection macro */ +diff --git a/board/xilinx/microblaze-generic/.gitignore b/board/xilinx/microblaze-generic/.gitignore +new file mode 100644 +index 0000000..739c63e +--- /dev/null ++++ b/board/xilinx/microblaze-generic/.gitignore +@@ -0,0 +1,5 @@ ++config.mk ++dts ++Makefile ++microblaze-generic.c ++xparameters.h +diff --git a/board/xilinx/microblaze-generic/Makefile b/board/xilinx/microblaze-generic/Makefile +index 761203d..d4d1169 100644 +--- a/board/xilinx/microblaze-generic/Makefile ++++ b/board/xilinx/microblaze-generic/Makefile +@@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk + + LIB = $(obj)lib$(BOARD).o + +-COBJS = $(BOARD).o ++COBJS = microblaze-generic.o + + SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) + OBJS := $(addprefix $(obj),$(COBJS)) +diff --git a/board/xilinx/microblaze-generic/config.mk b/board/xilinx/microblaze-generic/config.mk +deleted file mode 100644 +index 9fd1015..0000000 +--- a/board/xilinx/microblaze-generic/config.mk ++++ /dev/null +@@ -1,34 +0,0 @@ +-# +-# (C) Copyright 2007 Michal Simek +-# +-# Michal SIMEK +-# +-# 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 +-# +-# CAUTION: This file is a faked configuration !!! +-# There is no real target for the microblaze-generic +-# configuration. You have to replace this file with +-# the generated file from your Xilinx design flow. +-# +- +-CONFIG_SYS_TEXT_BASE = 0x29000000 +- +-PLATFORM_CPPFLAGS += -mno-xl-soft-mul +-PLATFORM_CPPFLAGS += -mno-xl-soft-div +-PLATFORM_CPPFLAGS += -mxl-barrel-shift +diff --git a/board/xilinx/microblaze-generic/microblaze-generic.c b/board/xilinx/microblaze-generic/microblaze-generic.c +index b75e62c..81b2881 100644 +--- a/board/xilinx/microblaze-generic/microblaze-generic.c ++++ b/board/xilinx/microblaze-generic/microblaze-generic.c +@@ -35,13 +35,18 @@ + int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) + { + #ifdef CONFIG_SYS_GPIO_0 +- *((unsigned long *)(CONFIG_SYS_GPIO_0_ADDR)) = +- ++(*((unsigned long *)(CONFIG_SYS_GPIO_0_ADDR))); ++ *((u32 volatile *)(CONFIG_SYS_GPIO_0_ADDR)) = ++ ++(*((u32 volatile *)(CONFIG_SYS_GPIO_0_ADDR))); + #endif +-#ifdef CONFIG_SYS_RESET_ADDRESS +- puts ("Reseting board\n"); +- asm ("bra r0"); ++ ++#ifdef CONFIG_XILINX_TB_WATCHDOG ++ hw_watchdog_disable(); + #endif ++ ++ puts ("Reseting board\n"); ++ __asm__ __volatile__ (" mts rmsr, r0;" \ ++ "bra r0"); ++ + return 0; + } + +@@ -53,29 +58,9 @@ int gpio_init (void) + return 0; + } + +-#ifdef CONFIG_SYS_FSL_2 +-void fsl_isr2 (void *arg) { +- volatile int num; +- *((unsigned int *)(CONFIG_SYS_GPIO_0_ADDR + 0x4)) = +- ++(*((unsigned int *)(CONFIG_SYS_GPIO_0_ADDR + 0x4))); +- GET (num, 2); +- NGET (num, 2); +- puts("*"); +-} +- +-int fsl_init2 (void) { +- puts("fsl_init2\n"); +- install_interrupt_handler (FSL_INTR_2, fsl_isr2, NULL); +- return 0; +-} +-#endif +- + void board_init(void) + { + gpio_init(); +-#ifdef CONFIG_SYS_FSL_2 +- fsl_init2(); +-#endif + } + + int board_eth_init(bd_t *bis) +@@ -99,41 +84,19 @@ int board_eth_init(bd_t *bis) + ret |= xilinx_emaclite_initialize(bis, XILINX_EMACLITE_BASEADDR, + txpp, rxpp); + #endif +- + #ifdef CONFIG_XILINX_LL_TEMAC +-# ifdef XILINX_LLTEMAC_BASEADDR +-# ifdef XILINX_LLTEMAC_FIFO_BASEADDR +- ret |= xilinx_ll_temac_eth_init(bis, XILINX_LLTEMAC_BASEADDR, +- XILINX_LL_TEMAC_M_FIFO, XILINX_LLTEMAC_FIFO_BASEADDR); +-# elif XILINX_LLTEMAC_SDMA_CTRL_BASEADDR +-# if XILINX_LLTEMAC_SDMA_USE_DCR == 1 +- ret |= xilinx_ll_temac_eth_init(bis, XILINX_LLTEMAC_BASEADDR, +- XILINX_LL_TEMAC_M_SDMA_DCR, +- XILINX_LLTEMAC_SDMA_CTRL_BASEADDR); +-# else +- ret |= xilinx_ll_temac_eth_init(bis, XILINX_LLTEMAC_BASEADDR, +- XILINX_LL_TEMAC_M_SDMA_PLB, +- XILINX_LLTEMAC_SDMA_CTRL_BASEADDR); +-# endif +-# endif +-# endif +-# ifdef XILINX_LLTEMAC_BASEADDR1 +-# ifdef XILINX_LLTEMAC_FIFO_BASEADDR1 +- ret |= xilinx_ll_temac_eth_init(bis, XILINX_LLTEMAC_BASEADDR1, +- XILINX_LL_TEMAC_M_FIFO, XILINX_LLTEMAC_FIFO_BASEADDR1); +-# elif XILINX_LLTEMAC_SDMA_CTRL_BASEADDR1 +-# if XILINX_LLTEMAC_SDMA_USE_DCR == 1 +- ret |= xilinx_ll_temac_eth_init(bis, XILINX_LLTEMAC_BASEADDR1, +- XILINX_LL_TEMAC_M_SDMA_DCR, +- XILINX_LLTEMAC_SDMA_CTRL_BASEADDR1); +-# else +- ret |= xilinx_ll_temac_eth_init(bis, XILINX_LLTEMAC_BASEADDR1, +- XILINX_LL_TEMAC_M_SDMA_PLB, +- XILINX_LLTEMAC_SDMA_CTRL_BASEADDR1); +-# endif ++# ifdef XILINX_LLTEMAC_FIFO_BASEADDR ++ ret |= xilinx_ll_temac_initialize(bis, XILINX_LLTEMAC_BASEADDR, 0, ++ XILINX_LLTEMAC_FIFO_BASEADDR); ++# elif XILINX_LLTEMAC_SDMA_CTRL_BASEADDR ++# if XILINX_LLTEMAC_SDMA_USE_DCR == 1 ++ ret |= xilinx_ll_temac_initialize(bis, XILINX_LLTEMAC_BASEADDR, 3, ++ XILINX_LLTEMAC_SDMA_CTRL_BASEADDR); ++# else ++ ret |= xilinx_ll_temac_initialize(bis, XILINX_LLTEMAC_BASEADDR, 1, ++ XILINX_LLTEMAC_SDMA_CTRL_BASEADDR); + # endif + # endif + #endif +- + return ret; + } +diff --git a/board/xilinx/microblaze-generic/xparameters.h b/board/xilinx/microblaze-generic/xparameters.h +deleted file mode 100644 +index 50a82d9..0000000 +--- a/board/xilinx/microblaze-generic/xparameters.h ++++ /dev/null +@@ -1,79 +0,0 @@ +-/* +- * (C) Copyright 2007 Michal Simek +- * +- * Michal SIMEK +- * +- * 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 +- * +- * CAUTION: This file is a faked configuration !!! +- * There is no real target for the microblaze-generic +- * configuration. You have to replace this file with +- * the generated file from your Xilinx design flow. +- */ +- +-#define XILINX_BOARD_NAME microblaze-generic +- +-/* System Clock Frequency */ +-#define XILINX_CLOCK_FREQ 100000000 +- +-/* Microblaze is microblaze_0 */ +-#define XILINX_USE_MSR_INSTR 1 +-#define XILINX_FSL_NUMBER 3 +- +-/* Interrupt controller is opb_intc_0 */ +-#define XILINX_INTC_BASEADDR 0x41200000 +-#define XILINX_INTC_NUM_INTR_INPUTS 6 +- +-/* Timer pheriphery is opb_timer_1 */ +-#define XILINX_TIMER_BASEADDR 0x41c00000 +-#define XILINX_TIMER_IRQ 0 +- +-/* Uart pheriphery is RS232_Uart */ +-#define XILINX_UARTLITE_BASEADDR 0x40600000 +-#define XILINX_UARTLITE_BAUDRATE 115200 +- +-/* IIC pheriphery is IIC_EEPROM */ +-#define XILINX_IIC_0_BASEADDR 0x40800000 +-#define XILINX_IIC_0_FREQ 100000 +-#define XILINX_IIC_0_BIT 0 +- +-/* GPIO is LEDs_4Bit*/ +-#define XILINX_GPIO_BASEADDR 0x40000000 +- +-/* Flash Memory is FLASH_2Mx32 */ +-#define XILINX_FLASH_START 0x2c000000 +-#define XILINX_FLASH_SIZE 0x00800000 +- +-/* Main Memory is DDR_SDRAM_64Mx32 */ +-#define XILINX_RAM_START 0x28000000 +-#define XILINX_RAM_SIZE 0x04000000 +- +-/* Sysace Controller is SysACE_CompactFlash */ +-#define XILINX_SYSACE_BASEADDR 0x41800000 +-#define XILINX_SYSACE_HIGHADDR 0x4180ffff +-#define XILINX_SYSACE_MEM_WIDTH 16 +- +-/* Ethernet controller is Ethernet_MAC */ +-#define XILINX_EMACLITE_BASEADDR 0x40C00000 +- +-/* LL_TEMAC Ethernet controller */ +-#define XILINX_LLTEMAC_BASEADDR 0x44000000 +-#define XILINX_LLTEMAC_SDMA_CTRL_BASEADDR 0x42000180 +-#define XILINX_LLTEMAC_BASEADDR1 0x44200000 +-#define XILINX_LLTEMAC_FIFO_BASEADDR1 0x42100000 +diff --git a/board/xilinx/ml507/.gitignore b/board/xilinx/ml507/.gitignore +deleted file mode 100644 +index f6418a0..0000000 +--- a/board/xilinx/ml507/.gitignore ++++ /dev/null +@@ -1 +0,0 @@ +-/config.tmp +diff --git a/board/xilinx/ml507/Makefile b/board/xilinx/ml507/Makefile +deleted file mode 100644 +index de23f29..0000000 +--- a/board/xilinx/ml507/Makefile ++++ /dev/null +@@ -1,27 +0,0 @@ +-# +-# (C) Copyright 2008 +-# Ricardo Ribalda,Universidad Autonoma de Madrid, ricardo.ribalda@uam.es +-# This work has been supported by: Qtechnology http://qtec.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 +-# +- +-COBJS += $(BOARD).o +- +-include $(SRCTREE)/board/xilinx/ppc440-generic/Makefile +diff --git a/board/xilinx/ml507/ml507.c b/board/xilinx/ml507/ml507.c +deleted file mode 100644 +index f9789cf..0000000 +--- a/board/xilinx/ml507/ml507.c ++++ /dev/null +@@ -1,28 +0,0 @@ +-/* +- * (C) Copyright 2008 +- * Ricado Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es +- * This work has been supported by: QTechnology http://qtec.com/ +- * 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, see . +-*/ +- +-#include +-#include +-#include +- +- +-int checkboard(void) +-{ +- puts("Xilinx ML507 Board\n"); +- return 0; +-} +diff --git a/board/xilinx/ml507/xparameters.h b/board/xilinx/ml507/xparameters.h +deleted file mode 100644 +index 1992fff..0000000 +--- a/board/xilinx/ml507/xparameters.h ++++ /dev/null +@@ -1,34 +0,0 @@ +-/* +- * (C) Copyright 2008 +- * Ricado Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es +- * This work has been supported by: QTechnology http://qtec.com/ +- * based on xparameters-ml507.h by Xilinx +- * +- * 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, see . +-*/ +- +-#ifndef XPARAMETER_H +-#define XPARAMETER_H +- +-#define XPAR_DDR2_SDRAM_MEM_BASEADDR 0x00000000 +-#define XPAR_IIC_EEPROM_BASEADDR 0x81600000 +-#define XPAR_INTC_0_BASEADDR 0x81800000 +-#define XPAR_UARTLITE_0_BASEADDR 0x84000000 +-#define XPAR_FLASH_MEM0_BASEADDR 0xFE000000 +-#define XPAR_PLB_CLOCK_FREQ_HZ 100000000 +-#define XPAR_CORE_CLOCK_FREQ_HZ 400000000 +-#define XPAR_INTC_MAX_NUM_INTR_INPUTS 13 +-#define XPAR_UARTLITE_0_BAUDRATE 9600 +- +-#endif +diff --git a/board/xilinx/ppc405-generic/.gitignore b/board/xilinx/ppc405-generic/.gitignore +index b644f59..739c63e 100644 +--- a/board/xilinx/ppc405-generic/.gitignore ++++ b/board/xilinx/ppc405-generic/.gitignore +@@ -1 +1,5 @@ +-config.tmp ++config.mk ++dts ++Makefile ++microblaze-generic.c ++xparameters.h +diff --git a/board/xilinx/ppc405-generic/Makefile b/board/xilinx/ppc405-generic/Makefile +index 73d5145..9557159 100644 +--- a/board/xilinx/ppc405-generic/Makefile ++++ b/board/xilinx/ppc405-generic/Makefile +@@ -2,10 +2,6 @@ + # (C) Copyright 2000-2006 + # Wolfgang Denk, DENX Software Engineering, wd@denx.de. + # +-# (C) Copyright 2008 +-# Ricardo Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es +-# Work supported by Qtechnology http://www.qtec.com +-# + # See file CREDITS for list of people who contributed to this + # project. + # +@@ -26,20 +22,17 @@ + # + + include $(TOPDIR)/config.mk +-ifneq ($(OBJTREE),$(SRCTREE)) +-$(shell mkdir -p $(obj)../../xilinx/ppc405-generic) +-endif + + LIB = $(obj)lib$(BOARD).o + +-COBJS += ../../xilinx/ppc405-generic/xilinx_ppc405_generic.o ++COBJS = ppc405-generic.o + + SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) + OBJS := $(addprefix $(obj),$(COBJS)) + SOBJS := $(addprefix $(obj),$(SOBJS)) + + $(LIB): $(obj).depend $(OBJS) $(SOBJS) +- $(call cmd_link_o_target, $(OBJS)) ++ $(call cmd_link_o_target, $(OBJS) $(SOBJS)) + + ######################################################################### + +diff --git a/board/xilinx/ppc405-generic/ppc405-generic.c b/board/xilinx/ppc405-generic/ppc405-generic.c +new file mode 100644 +index 0000000..31e635c +--- /dev/null ++++ b/board/xilinx/ppc405-generic/ppc405-generic.c +@@ -0,0 +1,104 @@ ++/* ++ * (C) Copyright 2007 Michal Simek ++ * ++ * Michal SIMEK ++ * ++ * 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 ++ */ ++ ++/* This is a board specific file. It's OK to include board specific ++ * header files */ ++ ++#include ++#include ++#include ++ ++ulong __get_PCI_freq(void) ++{ ++ return 0; ++} ++ ++ulong get_PCI_freq(void) __attribute__((weak, alias("__get_PCI_freq"))); ++ ++phys_size_t __initdram(int board_type) ++{ ++ return get_ram_size(XILINX_RAM_START, XILINX_RAM_SIZE); ++} ++phys_size_t initdram(int) __attribute__((weak, alias("__initdram"))); ++ ++void __get_sys_info(sys_info_t *sysInfo) ++{ ++ /* FIXME */ ++ sysInfo->freqProcessor = XILINX_CLOCK_FREQ; ++ sysInfo->freqPLB = XILINX_CLOCK_FREQ; ++ sysInfo->freqPCI = 0; ++ ++ return; ++} ++ ++void get_sys_info(sys_info_t *) __attribute__((weak, alias("__get_sys_info"))); ++ ++int __checkboard(void) ++{ ++ puts(__stringify(XILINX_BOARD_NAME) "\n"); ++ return 0; ++} ++int checkboard(void) __attribute__((weak, alias("__checkboard"))); ++ ++ ++int gpio_init (void) ++{ ++#ifdef CONFIG_SYS_GPIO_0 ++ *((unsigned long *)(CONFIG_SYS_GPIO_0_ADDR)) = 0xFFFFFFFF; ++#endif ++ return 0; ++} ++ ++int board_eth_init(bd_t *bis) ++{ ++ int ret = 0; ++ ++#ifdef CONFIG_XILINX_EMACLITE ++ u32 txpp = 0; ++ u32 rxpp = 0; ++# ifdef CONFIG_XILINX_EMACLITE_TX_PING_PONG ++ txpp = 1; ++# endif ++# ifdef CONFIG_XILINX_EMACLITE_RX_PING_PONG ++ rxpp = 1; ++# endif ++ ret |= xilinx_emaclite_initialize(bis, XILINX_EMACLITE_BASEADDR, ++ txpp, rxpp); ++#endif ++#ifdef CONFIG_XILINX_LL_TEMAC ++# ifdef XILINX_LLTEMAC_FIFO_BASEADDR ++ ret |= xilinx_ll_temac_initialize(bis, XILINX_LLTEMAC_BASEADDR, 0, ++ XILINX_LLTEMAC_FIFO_BASEADDR); ++# elif XILINX_LLTEMAC_SDMA_CTRL_BASEADDR ++# if XILINX_LLTEMAC_SDMA_USE_DCR == 1 ++ ret |= xilinx_ll_temac_initialize(bis, XILINX_LLTEMAC_BASEADDR, 3, ++ XILINX_LLTEMAC_SDMA_CTRL_BASEADDR); ++# else ++ ret |= xilinx_ll_temac_initialize(bis, XILINX_LLTEMAC_BASEADDR, 1, ++ XILINX_LLTEMAC_SDMA_CTRL_BASEADDR); ++# endif ++# endif ++#endif ++ return ret; ++} +diff --git a/board/xilinx/ppc405-generic/u-boot.lds b/board/xilinx/ppc405-generic/u-boot.lds +new file mode 100644 +index 0000000..7fbbca6 +--- /dev/null ++++ b/board/xilinx/ppc405-generic/u-boot.lds +@@ -0,0 +1,132 @@ ++/* ++ * (C) Copyright 2000-2004 ++ * Wolfgang Denk, DENX Software Engineering, wd@denx.de. ++ * ++ * 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 ++ */ ++ ++OUTPUT_ARCH(powerpc) ++ENTRY(_start) ++ ++SECTIONS ++{ ++ /* Read-only sections, merged into text segment: */ ++ . = + SIZEOF_HEADERS; ++ .interp : { *(.interp) } ++ .hash : { *(.hash) } ++ .dynsym : { *(.dynsym) } ++ .dynstr : { *(.dynstr) } ++ .rel.text : { *(.rel.text) } ++ .rela.text : { *(.rela.text) } ++ .rel.data : { *(.rel.data) } ++ .rela.data : { *(.rela.data) } ++ .rel.rodata : { *(.rel.rodata) } ++ .rela.rodata : { *(.rela.rodata) } ++ .rel.got : { *(.rel.got) } ++ .rela.got : { *(.rela.got) } ++ .rel.ctors : { *(.rel.ctors) } ++ .rela.ctors : { *(.rela.ctors) } ++ .rel.dtors : { *(.rel.dtors) } ++ .rela.dtors : { *(.rela.dtors) } ++ .rel.bss : { *(.rel.bss) } ++ .rela.bss : { *(.rela.bss) } ++ .rel.plt : { *(.rel.plt) } ++ .rela.plt : { *(.rela.plt) } ++ .init : { *(.init) } ++ .plt : { *(.plt) } ++ .text : ++ { ++ /* WARNING - the following is hand-optimized to fit within */ ++ /* the sector layout of our flash chips! XXX FIXME XXX */ ++ ++ ++ *(.text) ++ *(.fixup) ++ *(.got1) ++ } ++ _etext = .; ++ PROVIDE (etext = .); ++ .rodata : ++ { ++ *(.eh_frame) ++ *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) ++ } ++ .fini : { *(.fini) } =0 ++ .ctors : { *(.ctors) } ++ .dtors : { *(.dtors) } ++ ++ /* Read-write section, merged into data segment: */ ++ . = (. + 0x00FF) & 0xFFFFFF00; ++ _erotext = .; ++ PROVIDE (erotext = .); ++ .reloc : ++ { ++ *(.got) ++ _GOT2_TABLE_ = .; ++ *(.got2) ++ _FIXUP_TABLE_ = .; ++ *(.fixup) ++ } ++ __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; ++ __fixup_entries = (. - _FIXUP_TABLE_)>>2; ++ ++ .data : ++ { ++ *(.data) ++ *(.data1) ++ *(.sdata) ++ *(.sdata2) ++ *(.dynamic) ++ CONSTRUCTORS ++ } ++ _edata = .; ++ PROVIDE (edata = .); ++ ++ . = .; ++ . = ALIGN(4); ++ .u_boot_list : { ++ #include ++ } ++ ++ . = .; ++ __start___ex_table = .; ++ __ex_table : { *(__ex_table) } ++ __stop___ex_table = .; ++ ++ . = ALIGN(256); ++ __init_begin = .; ++ .text.init : { *(.text.init) } ++ .data.init : { *(.data.init) } ++ . = ALIGN(256); ++ __init_end = .; ++ ++ __bss_start = .; ++ .bss (NOLOAD) : ++ { ++ *(.sbss) *(.scommon) ++ *(.dynbss) ++ *(.bss) ++ *(COMMON) ++ } ++ __bss_end__ = .; ++ ppcenv_assert = ASSERT(. < 0xFFFFB000, ".bss section too big, overlaps .ppcenv section. Please update your configuration: CONFIG_SYS_MONITOR_BASE, CONFIG_SYS_MONITOR_LEN and TEXT_BASE may need to be modified."); ++ ++ _end = . ; ++ PROVIDE (end = .); ++} +diff --git a/board/xilinx/ppc405-generic/xilinx_ppc405_generic.c b/board/xilinx/ppc405-generic/xilinx_ppc405_generic.c +deleted file mode 100644 +index 9bd1770..0000000 +--- a/board/xilinx/ppc405-generic/xilinx_ppc405_generic.c ++++ /dev/null +@@ -1,59 +0,0 @@ +-/* +- * (C) Copyright 2008 +- * Ricado Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es +- * This work has been supported by: QTechnology http://qtec.com/ +- * +- * 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, see . +-*/ +- +-#include +-#include +-#include +- +-ulong __get_PCI_freq(void) +-{ +- return 0; +-} +- +-ulong get_PCI_freq(void) __attribute__((weak, alias("__get_PCI_freq"))); +- +-int __board_pre_init(void) +-{ +- return 0; +-} +-int board_pre_init(void) __attribute__((weak, alias("__board_pre_init"))); +- +-int __checkboard(void) +-{ +- puts("Xilinx PPC405 Generic Board\n"); +- return 0; +-} +-int checkboard(void) __attribute__((weak, alias("__checkboard"))); +- +-phys_size_t __initdram(int board_type) +-{ +- return get_ram_size(XPAR_DDR2_SDRAM_MEM_BASEADDR, +- CONFIG_SYS_SDRAM_SIZE_MB * 1024 * 1024); +-} +-phys_size_t initdram(int) __attribute__((weak, alias("__initdram"))); +- +-void __get_sys_info(sys_info_t *sysInfo) +-{ +- sysInfo->freqProcessor = XPAR_CORE_CLOCK_FREQ_HZ; +- sysInfo->freqPLB = XPAR_PLB_CLOCK_FREQ_HZ; +- sysInfo->freqPCI = 0; +- +- return; +-} +-void get_sys_info(sys_info_t *) __attribute__((weak, alias("__get_sys_info"))); +diff --git a/board/xilinx/ppc405-generic/xparameters.h b/board/xilinx/ppc405-generic/xparameters.h +deleted file mode 100644 +index e8e8ced..0000000 +--- a/board/xilinx/ppc405-generic/xparameters.h ++++ /dev/null +@@ -1,36 +0,0 @@ +-/* +- * (C) Copyright 2008 +- * Ricado Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es +- * This work has been supported by: QTechnology http://qtec.com/ +- * based on xparameters-ml507.h by Xilinx +- * +- * 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, see . +-*/ +- +-#ifndef XPARAMETER_H +-#define XPARAMETER_H +- +-#define XPAR_DDR2_SDRAM_MEM_BASEADDR 0x00000000 +-#define XPAR_IIC_EEPROM_BASEADDR 0x81600000 +-#define XPAR_INTC_0_BASEADDR 0x81800000 +-#define XPAR_SPI_0_BASEADDR 0x83400000 +-#define XPAR_UARTLITE_0_BASEADDR 0x84000000 +-#define XPAR_FLASH_MEM0_BASEADDR 0xFE000000 +-#define XPAR_PLB_CLOCK_FREQ_HZ 100000000 +-#define XPAR_CORE_CLOCK_FREQ_HZ 400000000 +-#define XPAR_INTC_MAX_NUM_INTR_INPUTS 13 +-#define XPAR_UARTLITE_0_BAUDRATE 9600 +-#define XPAR_SPI_0_NUM_TRANSFER_BITS 8 +- +-#endif +diff --git a/board/xilinx/ppc440-generic/.gitignore b/board/xilinx/ppc440-generic/.gitignore +index f6418a0..739c63e 100644 +--- a/board/xilinx/ppc440-generic/.gitignore ++++ b/board/xilinx/ppc440-generic/.gitignore +@@ -1 +1,5 @@ +-/config.tmp ++config.mk ++dts ++Makefile ++microblaze-generic.c ++xparameters.h +diff --git a/board/xilinx/ppc440-generic/Makefile b/board/xilinx/ppc440-generic/Makefile +index 5d2848d..80b34b5 100644 +--- a/board/xilinx/ppc440-generic/Makefile ++++ b/board/xilinx/ppc440-generic/Makefile +@@ -2,10 +2,6 @@ + # (C) Copyright 2000-2006 + # Wolfgang Denk, DENX Software Engineering, wd@denx.de. + # +-# (C) Copyright 2008 +-# Ricardo Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es +-# Work supported by Qtechnology http://www.qtec.com +-# + # See file CREDITS for list of people who contributed to this + # project. + # +@@ -26,21 +22,18 @@ + # + + include $(TOPDIR)/config.mk +-ifneq ($(OBJTREE),$(SRCTREE)) +-$(shell mkdir -p $(obj)../../xilinx/ppc440-generic) +-endif + + LIB = $(obj)lib$(BOARD).o + +-COBJS += ../../xilinx/ppc440-generic/xilinx_ppc440_generic.o +-SOBJS += ../../xilinx/ppc440-generic/init.o ++COBJS = ppc440-generic.o ++SOBJS = init.o + + SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) + OBJS := $(addprefix $(obj),$(COBJS)) + SOBJS := $(addprefix $(obj),$(SOBJS)) + + $(LIB): $(obj).depend $(OBJS) $(SOBJS) +- $(call cmd_link_o_target, $(OBJS)) ++ $(call cmd_link_o_target, $(OBJS) $(SOBJS)) + + ######################################################################### + +diff --git a/board/xilinx/ppc440-generic/ppc440-generic.c b/board/xilinx/ppc440-generic/ppc440-generic.c +new file mode 100644 +index 0000000..b7cd251 +--- /dev/null ++++ b/board/xilinx/ppc440-generic/ppc440-generic.c +@@ -0,0 +1,104 @@ ++/* ++ * (C) Copyright 2007 Michal Simek ++ * ++ * Michal SIMEK ++ * ++ * 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 ++ */ ++ ++/* This is a board specific file. It's OK to include board specific ++ * header files */ ++ ++#include ++#include ++#include ++ ++ulong __get_PCI_freq(void) ++{ ++ return 0; ++} ++ ++ulong get_PCI_freq(void) __attribute__((weak, alias("__get_PCI_freq"))); ++ ++phys_size_t __initdram(int board_type) ++{ ++ return get_ram_size(XILINX_RAM_START, XILINX_RAM_SIZE); ++} ++phys_size_t initdram(int) __attribute__((weak, alias("__initdram"))); ++ ++void __get_sys_info(sys_info_t *sysInfo) ++{ ++ /* FIXME */ ++ sysInfo->freqProcessor = XILINX_CLOCK_FREQ; ++ sysInfo->freqPLB = XILINX_CLOCK_FREQ; ++ sysInfo->freqPCI = 0; ++ ++ return; ++} ++ ++void get_sys_info(sys_info_t *) __attribute__((weak, alias("__get_sys_info"))); ++ ++int __checkboard(void) ++{ ++ /*puts(__stringify(XILINX_BOARD_NAME) "\n");*/ ++ return 0; ++} ++int checkboard(void) __attribute__((weak, alias("__checkboard"))); ++ ++ ++int gpio_init (void) ++{ ++#ifdef CONFIG_SYS_GPIO_0 ++ *((unsigned long *)(CONFIG_SYS_GPIO_0_ADDR)) = 0xFFFFFFFF; ++#endif ++ return 0; ++} ++ ++int board_eth_init(bd_t *bis) ++{ ++ int ret = 0; ++ ++#ifdef CONFIG_XILINX_EMACLITE ++ u32 txpp = 0; ++ u32 rxpp = 0; ++# ifdef CONFIG_XILINX_EMACLITE_TX_PING_PONG ++ txpp = 1; ++# endif ++# ifdef CONFIG_XILINX_EMACLITE_RX_PING_PONG ++ rxpp = 1; ++# endif ++ ret |= xilinx_emaclite_initialize(bis, XILINX_EMACLITE_BASEADDR, ++ txpp, rxpp); ++#endif ++#ifdef CONFIG_XILINX_LL_TEMAC ++# ifdef XILINX_LLTEMAC_FIFO_BASEADDR ++ ret |= xilinx_ll_temac_initialize(bis, XILINX_LLTEMAC_BASEADDR, 0, ++ XILINX_LLTEMAC_FIFO_BASEADDR); ++# elif XILINX_LLTEMAC_SDMA_CTRL_BASEADDR ++# if XILINX_LLTEMAC_SDMA_USE_DCR == 1 ++ ret |= xilinx_ll_temac_initialize(bis, XILINX_LLTEMAC_BASEADDR, 3, ++ XILINX_LLTEMAC_SDMA_CTRL_BASEADDR); ++# else ++ ret |= xilinx_ll_temac_initialize(bis, XILINX_LLTEMAC_BASEADDR, 1, ++ XILINX_LLTEMAC_SDMA_CTRL_BASEADDR); ++# endif ++# endif ++#endif ++ return ret; ++} +diff --git a/board/xilinx/ppc440-generic/u-boot.lds b/board/xilinx/ppc440-generic/u-boot.lds +new file mode 100644 +index 0000000..023324d +--- /dev/null ++++ b/board/xilinx/ppc440-generic/u-boot.lds +@@ -0,0 +1,104 @@ ++/* ++ * (C) Copyright 2000-2004 ++ * Wolfgang Denk, DENX Software Engineering, wd@denx.de. ++ * ++ * 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 ++ */ ++ ++OUTPUT_ARCH(powerpc) ++ENTRY(_start_440) ++ ++ ++PHDRS ++{ ++ text PT_LOAD; ++ bss PT_LOAD; ++} ++ ++SECTIONS ++{ ++ /* Read-only sections, merged into text segment: */ ++ . = + SIZEOF_HEADERS; ++ .text : ++ { ++ *(.text*) ++ } :text ++ _etext = .; ++ PROVIDE (etext = .); ++ .rodata : ++ { ++ *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) ++ } :text ++ ++ ++ /* Read-write section, merged into data segment: */ ++ . = (. + 0x00FF) & 0xFFFFFF00; ++ _erotext = .; ++ PROVIDE (erotext = .); ++ .reloc : ++ { ++ _GOT2_TABLE_ = .; ++ KEEP(*(.got2)) ++ KEEP(*(.got)) ++ PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4); ++ _FIXUP_TABLE_ = .; ++ KEEP(*(.fixup)) ++ } ++ __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1; ++ __fixup_entries = (. - _FIXUP_TABLE_) >> 2; ++ ++ .data : ++ { ++ *(.data*) ++ *(.sdata*) ++ } ++ _edata = .; ++ PROVIDE (edata = .); ++ ++ . = .; ++ . = ALIGN(4); ++ .u_boot_list : { ++ #include ++ } ++ ++ . = .; ++ __start___ex_table = .; ++ __ex_table : { *(__ex_table) } ++ __stop___ex_table = .; ++ ++ . = ALIGN(256); ++ __init_begin = .; ++ .text.init : { *(.text.init) } ++ .data.init : { *(.data.init) } ++ . = ALIGN(256); ++ __init_end = .; ++ ++ __bss_start = .; ++ .bss (NOLOAD) : ++ { ++ *(.bss*) ++ *(.sbss*) ++ *(COMMON) ++ } :bss ++ . = ALIGN(4); ++ __bss_end__ = .; ++ ppcenv_assert = ASSERT(. < 0xFFFFB000, ".bss section too big, overlaps .ppcenv section. Please update your confguration: CONFIG_SYS_MONITOR_BASE, CONFIG_SYS_MONITOR_LEN and TEXT_BASE may need to be modified."); ++ ++ PROVIDE (end = .); ++} +diff --git a/board/xilinx/ppc440-generic/xilinx_ppc440_generic.c b/board/xilinx/ppc440-generic/xilinx_ppc440_generic.c +deleted file mode 100644 +index 0c3d667..0000000 +--- a/board/xilinx/ppc440-generic/xilinx_ppc440_generic.c ++++ /dev/null +@@ -1,52 +0,0 @@ +-/* +- * (C) Copyright 2008 +- * Ricado Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es +- * This work has been supported by: QTechnology http://qtec.com/ +- * +- * 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, see . +-*/ +- +-#include +-#include +-#include +- +-int __board_pre_init(void) +-{ +- return 0; +-} +-int board_pre_init(void) __attribute__((weak, alias("__board_pre_init"))); +- +-int __checkboard(void) +-{ +- puts("Xilinx PPC440 Generic Board\n"); +- return 0; +-} +-int checkboard(void) __attribute__((weak, alias("__checkboard"))); +- +-phys_size_t __initdram(int board_type) +-{ +- return get_ram_size(XPAR_DDR2_SDRAM_MEM_BASEADDR, +- CONFIG_SYS_SDRAM_SIZE_MB * 1024 * 1024); +-} +-phys_size_t initdram(int) __attribute__((weak, alias("__initdram"))); +- +-void __get_sys_info(sys_info_t *sysInfo) +-{ +- sysInfo->freqProcessor = XPAR_CORE_CLOCK_FREQ_HZ; +- sysInfo->freqPLB = XPAR_PLB_CLOCK_FREQ_HZ; +- sysInfo->freqPCI = 0; +- +- return; +-} +-void get_sys_info(sys_info_t *) __attribute__((weak, alias("__get_sys_info"))); +diff --git a/board/xilinx/ppc440-generic/xparameters.h b/board/xilinx/ppc440-generic/xparameters.h +deleted file mode 100644 +index 1992fff..0000000 +--- a/board/xilinx/ppc440-generic/xparameters.h ++++ /dev/null +@@ -1,34 +0,0 @@ +-/* +- * (C) Copyright 2008 +- * Ricado Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es +- * This work has been supported by: QTechnology http://qtec.com/ +- * based on xparameters-ml507.h by Xilinx +- * +- * 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, see . +-*/ +- +-#ifndef XPARAMETER_H +-#define XPARAMETER_H +- +-#define XPAR_DDR2_SDRAM_MEM_BASEADDR 0x00000000 +-#define XPAR_IIC_EEPROM_BASEADDR 0x81600000 +-#define XPAR_INTC_0_BASEADDR 0x81800000 +-#define XPAR_UARTLITE_0_BASEADDR 0x84000000 +-#define XPAR_FLASH_MEM0_BASEADDR 0xFE000000 +-#define XPAR_PLB_CLOCK_FREQ_HZ 100000000 +-#define XPAR_CORE_CLOCK_FREQ_HZ 400000000 +-#define XPAR_INTC_MAX_NUM_INTR_INPUTS 13 +-#define XPAR_UARTLITE_0_BAUDRATE 9600 +- +-#endif +diff --git a/board/xilinx/xilinx_iic/xiic_l.c b/board/xilinx/xilinx_iic/xiic_l.c +deleted file mode 100644 +index 6b78163..0000000 +--- a/board/xilinx/xilinx_iic/xiic_l.c ++++ /dev/null +@@ -1,484 +0,0 @@ +-/* $Id: xiic_l.c,v 1.2 2002/12/05 19:32:40 meinelte Exp $ */ +-/****************************************************************************** +-* +-* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" +-* AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND +-* SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, +-* OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, +-* APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION +-* THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, +-* AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE +-* FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY +-* WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE +-* IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR +-* REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF +-* INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +-* FOR A PARTICULAR PURPOSE. +-* +-* (c) Copyright 2002 Xilinx Inc. +-* All rights reserved. +-* +-******************************************************************************/ +-/*****************************************************************************/ +-/** +-* +-* @file xiic_l.c +-* +-* This file contains low-level driver functions that can be used to access the +-* device. The user should refer to the hardware device specification for more +-* details of the device operation. +-* +-*
+-* MODIFICATION HISTORY:
+-*
+-* Ver	Who  Date     Changes
+-* ----- --- -------  -----------------------------------------------
+-* 1.01b jhl 5/13/02  First release
+-* 1.01b jhl 10/14/02 Corrected bug in the receive function, the setup of the
+-*		     interrupt status mask was not being done in the loop such
+-*		     that a read would sometimes fail on the last byte because
+-*		     the transmit error which should have been ignored was
+-*		     being used.  This would leave an extra byte in the FIFO
+-*		     and the bus throttled such that the next operation would
+-*		     also fail.	 Also updated the receive function to not
+-*		     disable the device after the last byte until after the
+-*		     bus transitions to not busy which is more consistent
+-*		     with the expected behavior.
+-* 1.01c ecm 12/05/02 new rev
+-* 
+-* +-****************************************************************************/ +- +-/***************************** Include Files *******************************/ +- +-#include "xbasic_types.h" +-#include "xio.h" +-#include "xipif_v1_23_b.h" +-#include "xiic_l.h" +- +-/************************** Constant Definitions ***************************/ +- +-/**************************** Type Definitions *****************************/ +- +- +-/***************** Macros (Inline Functions) Definitions *******************/ +- +- +-/****************************************************************************** +-* +-* This macro clears the specified interrupt in the IPIF interrupt status +-* register. It is non-destructive in that the register is read and only the +-* interrupt specified is cleared. Clearing an interrupt acknowledges it. +-* +-* @param BaseAddress contains the IPIF registers base address. +-* +-* @param InterruptMask contains the interrupts to be disabled +-* +-* @return +-* +-* None. +-* +-* @note +-* +-* Signature: void XIic_mClearIisr(u32 BaseAddress, +-* u32 InterruptMask); +-* +-******************************************************************************/ +-#define XIic_mClearIisr(BaseAddress, InterruptMask) \ +- XIIF_V123B_WRITE_IISR((BaseAddress), \ +- XIIF_V123B_READ_IISR(BaseAddress) & (InterruptMask)) +- +-/****************************************************************************** +-* +-* This macro sends the address for a 7 bit address during both read and write +-* operations. It takes care of the details to format the address correctly. +-* This macro is designed to be called internally to the drivers. +-* +-* @param SlaveAddress contains the address of the slave to send to. +-* +-* @param Operation indicates XIIC_READ_OPERATION or XIIC_WRITE_OPERATION +-* +-* @return +-* +-* None. +-* +-* @note +-* +-* Signature: void XIic_mSend7BitAddr(u16 SlaveAddress, u8 Operation); +-* +-******************************************************************************/ +-#define XIic_mSend7BitAddress(BaseAddress, SlaveAddress, Operation) \ +-{ \ +- u8 LocalAddr = (u8)(SlaveAddress << 1); \ +- LocalAddr = (LocalAddr & 0xFE) | (Operation); \ +- XIo_Out8(BaseAddress + XIIC_DTR_REG_OFFSET, LocalAddr); \ +-} +- +-/************************** Function Prototypes ****************************/ +- +-static unsigned RecvData (u32 BaseAddress, u8 * BufferPtr, +- unsigned ByteCount); +-static unsigned SendData (u32 BaseAddress, u8 * BufferPtr, +- unsigned ByteCount); +- +-/************************** Variable Definitions **************************/ +- +- +-/****************************************************************************/ +-/** +-* Receive data as a master on the IIC bus. This function receives the data +-* using polled I/O and blocks until the data has been received. It only +-* supports 7 bit addressing and non-repeated start modes of operation. The +-* user is responsible for ensuring the bus is not busy if multiple masters +-* are present on the bus. +-* +-* @param BaseAddress contains the base address of the IIC device. +-* @param Address contains the 7 bit IIC address of the device to send the +-* specified data to. +-* @param BufferPtr points to the data to be sent. +-* @param ByteCount is the number of bytes to be sent. +-* +-* @return +-* +-* The number of bytes received. +-* +-* @note +-* +-* None +-* +-******************************************************************************/ +-unsigned XIic_Recv (u32 BaseAddress, u8 Address, +- u8 * BufferPtr, unsigned ByteCount) +-{ +- u8 CntlReg; +- unsigned RemainingByteCount; +- +- /* Tx error is enabled incase the address (7 or 10) has no device to answer +- * with Ack. When only one byte of data, must set NO ACK before address goes +- * out therefore Tx error must not be enabled as it will go off immediately +- * and the Rx full interrupt will be checked. If full, then the one byte +- * was received and the Tx error will be disabled without sending an error +- * callback msg. +- */ +- XIic_mClearIisr (BaseAddress, +- XIIC_INTR_RX_FULL_MASK | XIIC_INTR_TX_ERROR_MASK | +- XIIC_INTR_ARB_LOST_MASK); +- +- /* Set receive FIFO occupancy depth for 1 byte (zero based) +- */ +- XIo_Out8 (BaseAddress + XIIC_RFD_REG_OFFSET, 0); +- +- /* 7 bit slave address, send the address for a read operation +- * and set the state to indicate the address has been sent +- */ +- XIic_mSend7BitAddress (BaseAddress, Address, XIIC_READ_OPERATION); +- +- /* MSMS gets set after putting data in FIFO. Start the master receive +- * operation by setting CR Bits MSMS to Master, if the buffer is only one +- * byte, then it should not be acknowledged to indicate the end of data +- */ +- CntlReg = XIIC_CR_MSMS_MASK | XIIC_CR_ENABLE_DEVICE_MASK; +- if (ByteCount == 1) { +- CntlReg |= XIIC_CR_NO_ACK_MASK; +- } +- +- /* Write out the control register to start receiving data and call the +- * function to receive each byte into the buffer +- */ +- XIo_Out8 (BaseAddress + XIIC_CR_REG_OFFSET, CntlReg); +- +- /* Clear the latched interrupt status for the bus not busy bit which must +- * be done while the bus is busy +- */ +- XIic_mClearIisr (BaseAddress, XIIC_INTR_BNB_MASK); +- +- /* Try to receive the data from the IIC bus */ +- +- RemainingByteCount = RecvData (BaseAddress, BufferPtr, ByteCount); +- /* +- * The receive is complete, disable the IIC device and return the number of +- * bytes that was received +- */ +- XIo_Out8 (BaseAddress + XIIC_CR_REG_OFFSET, 0); +- +- /* Return the number of bytes that was received */ +- +- return ByteCount - RemainingByteCount; +-} +- +-/****************************************************************************** +-* +-* Receive the specified data from the device that has been previously addressed +-* on the IIC bus. This function assumes that the 7 bit address has been sent +-* and it should wait for the transmit of the address to complete. +-* +-* @param BaseAddress contains the base address of the IIC device. +-* @param BufferPtr points to the buffer to hold the data that is received. +-* @param ByteCount is the number of bytes to be received. +-* +-* @return +-* +-* The number of bytes remaining to be received. +-* +-* @note +-* +-* This function does not take advantage of the receive FIFO because it is +-* designed for minimal code space and complexity. It contains loops that +-* that could cause the function not to return if the hardware is not working. +-* +-* This function assumes that the calling function will disable the IIC device +-* after this function returns. +-* +-******************************************************************************/ +-static unsigned RecvData (u32 BaseAddress, u8 * BufferPtr, unsigned ByteCount) +-{ +- u8 CntlReg; +- u32 IntrStatusMask; +- u32 IntrStatus; +- +- /* Attempt to receive the specified number of bytes on the IIC bus */ +- +- while (ByteCount > 0) { +- /* Setup the mask to use for checking errors because when receiving one +- * byte OR the last byte of a multibyte message an error naturally +- * occurs when the no ack is done to tell the slave the last byte +- */ +- if (ByteCount == 1) { +- IntrStatusMask = +- XIIC_INTR_ARB_LOST_MASK | XIIC_INTR_BNB_MASK; +- } else { +- IntrStatusMask = +- XIIC_INTR_ARB_LOST_MASK | +- XIIC_INTR_TX_ERROR_MASK | XIIC_INTR_BNB_MASK; +- } +- +- /* Wait for the previous transmit and the 1st receive to complete +- * by checking the interrupt status register of the IPIF +- */ +- while (1) { +- IntrStatus = XIIF_V123B_READ_IISR (BaseAddress); +- if (IntrStatus & XIIC_INTR_RX_FULL_MASK) { +- break; +- } +- /* Check the transmit error after the receive full because when +- * sending only one byte transmit error will occur because of the +- * no ack to indicate the end of the data +- */ +- if (IntrStatus & IntrStatusMask) { +- return ByteCount; +- } +- } +- +- CntlReg = XIo_In8 (BaseAddress + XIIC_CR_REG_OFFSET); +- +- /* Special conditions exist for the last two bytes so check for them +- * Note that the control register must be setup for these conditions +- * before the data byte which was already received is read from the +- * receive FIFO (while the bus is throttled +- */ +- if (ByteCount == 1) { +- /* For the last data byte, it has already been read and no ack +- * has been done, so clear MSMS while leaving the device enabled +- * so it can get off the IIC bus appropriately with a stop. +- */ +- XIo_Out8 (BaseAddress + XIIC_CR_REG_OFFSET, +- XIIC_CR_ENABLE_DEVICE_MASK); +- } +- +- /* Before the last byte is received, set NOACK to tell the slave IIC +- * device that it is the end, this must be done before reading the byte +- * from the FIFO +- */ +- if (ByteCount == 2) { +- /* Write control reg with NO ACK allowing last byte to +- * have the No ack set to indicate to slave last byte read. +- */ +- XIo_Out8 (BaseAddress + XIIC_CR_REG_OFFSET, +- CntlReg | XIIC_CR_NO_ACK_MASK); +- } +- +- /* Read in data from the FIFO and unthrottle the bus such that the +- * next byte is read from the IIC bus +- */ +- *BufferPtr++ = XIo_In8 (BaseAddress + XIIC_DRR_REG_OFFSET); +- +- /* Clear the latched interrupt status so that it will be updated with +- * the new state when it changes, this must be done after the receive +- * register is read +- */ +- XIic_mClearIisr (BaseAddress, XIIC_INTR_RX_FULL_MASK | +- XIIC_INTR_TX_ERROR_MASK | +- XIIC_INTR_ARB_LOST_MASK); +- ByteCount--; +- } +- +- /* Wait for the bus to transition to not busy before returning, the IIC +- * device cannot be disabled until this occurs. It should transition as +- * the MSMS bit of the control register was cleared before the last byte +- * was read from the FIFO. +- */ +- while (1) { +- if (XIIF_V123B_READ_IISR (BaseAddress) & XIIC_INTR_BNB_MASK) { +- break; +- } +- } +- +- return ByteCount; +-} +- +-/****************************************************************************/ +-/** +-* Send data as a master on the IIC bus. This function sends the data +-* using polled I/O and blocks until the data has been sent. It only supports +-* 7 bit addressing and non-repeated start modes of operation. The user is +-* responsible for ensuring the bus is not busy if multiple masters are present +-* on the bus. +-* +-* @param BaseAddress contains the base address of the IIC device. +-* @param Address contains the 7 bit IIC address of the device to send the +-* specified data to. +-* @param BufferPtr points to the data to be sent. +-* @param ByteCount is the number of bytes to be sent. +-* +-* @return +-* +-* The number of bytes sent. +-* +-* @note +-* +-* None +-* +-******************************************************************************/ +-unsigned XIic_Send (u32 BaseAddress, u8 Address, +- u8 * BufferPtr, unsigned ByteCount) +-{ +- unsigned RemainingByteCount; +- +- /* Put the address into the FIFO to be sent and indicate that the operation +- * to be performed on the bus is a write operation +- */ +- XIic_mSend7BitAddress (BaseAddress, Address, XIIC_WRITE_OPERATION); +- +- /* Clear the latched interrupt status so that it will be updated with the +- * new state when it changes, this must be done after the address is put +- * in the FIFO +- */ +- XIic_mClearIisr (BaseAddress, XIIC_INTR_TX_EMPTY_MASK | +- XIIC_INTR_TX_ERROR_MASK | XIIC_INTR_ARB_LOST_MASK); +- +- /* MSMS must be set after putting data into transmit FIFO, indicate the +- * direction is transmit, this device is master and enable the IIC device +- */ +- XIo_Out8 (BaseAddress + XIIC_CR_REG_OFFSET, +- XIIC_CR_MSMS_MASK | XIIC_CR_DIR_IS_TX_MASK | +- XIIC_CR_ENABLE_DEVICE_MASK); +- +- /* Clear the latched interrupt +- * status for the bus not busy bit which must be done while the bus is busy +- */ +- XIic_mClearIisr (BaseAddress, XIIC_INTR_BNB_MASK); +- +- /* Send the specified data to the device on the IIC bus specified by the +- * the address +- */ +- RemainingByteCount = SendData (BaseAddress, BufferPtr, ByteCount); +- +- /* +- * The send is complete, disable the IIC device and return the number of +- * bytes that was sent +- */ +- XIo_Out8 (BaseAddress + XIIC_CR_REG_OFFSET, 0); +- +- return ByteCount - RemainingByteCount; +-} +- +-/****************************************************************************** +-* +-* Send the specified buffer to the device that has been previously addressed +-* on the IIC bus. This function assumes that the 7 bit address has been sent +-* and it should wait for the transmit of the address to complete. +-* +-* @param BaseAddress contains the base address of the IIC device. +-* @param BufferPtr points to the data to be sent. +-* @param ByteCount is the number of bytes to be sent. +-* +-* @return +-* +-* The number of bytes remaining to be sent. +-* +-* @note +-* +-* This function does not take advantage of the transmit FIFO because it is +-* designed for minimal code space and complexity. It contains loops that +-* that could cause the function not to return if the hardware is not working. +-* +-******************************************************************************/ +-static unsigned SendData (u32 BaseAddress, u8 * BufferPtr, unsigned ByteCount) +-{ +- u32 IntrStatus; +- +- /* Send the specified number of bytes in the specified buffer by polling +- * the device registers and blocking until complete +- */ +- while (ByteCount > 0) { +- /* Wait for the transmit to be empty before sending any more data +- * by polling the interrupt status register +- */ +- while (1) { +- IntrStatus = XIIF_V123B_READ_IISR (BaseAddress); +- +- if (IntrStatus & (XIIC_INTR_TX_ERROR_MASK | +- XIIC_INTR_ARB_LOST_MASK | +- XIIC_INTR_BNB_MASK)) { +- return ByteCount; +- } +- +- if (IntrStatus & XIIC_INTR_TX_EMPTY_MASK) { +- break; +- } +- } +- /* If there is more than one byte to send then put the next byte to send +- * into the transmit FIFO +- */ +- if (ByteCount > 1) { +- XIo_Out8 (BaseAddress + XIIC_DTR_REG_OFFSET, +- *BufferPtr++); +- } else { +- /* Set the stop condition before sending the last byte of data so that +- * the stop condition will be generated immediately following the data +- * This is done by clearing the MSMS bit in the control register. +- */ +- XIo_Out8 (BaseAddress + XIIC_CR_REG_OFFSET, +- XIIC_CR_ENABLE_DEVICE_MASK | +- XIIC_CR_DIR_IS_TX_MASK); +- +- /* Put the last byte to send in the transmit FIFO */ +- +- XIo_Out8 (BaseAddress + XIIC_DTR_REG_OFFSET, +- *BufferPtr++); +- } +- +- /* Clear the latched interrupt status register and this must be done after +- * the transmit FIFO has been written to or it won't clear +- */ +- XIic_mClearIisr (BaseAddress, XIIC_INTR_TX_EMPTY_MASK); +- +- /* Update the byte count to reflect the byte sent and clear the latched +- * interrupt status so it will be updated for the new state +- */ +- ByteCount--; +- } +- +- /* Wait for the bus to transition to not busy before returning, the IIC +- * device cannot be disabled until this occurs. +- * Note that this is different from a receive operation because the stop +- * condition causes the bus to go not busy. +- */ +- while (1) { +- if (XIIF_V123B_READ_IISR (BaseAddress) & XIIC_INTR_BNB_MASK) { +- break; +- } +- } +- +- return ByteCount; +-} +diff --git a/board/xilinx/xilinx_iic/xiic_l.h b/board/xilinx/xilinx_iic/xiic_l.h +deleted file mode 100644 +index a2c4c49..0000000 +--- a/board/xilinx/xilinx_iic/xiic_l.h ++++ /dev/null +@@ -1,150 +0,0 @@ +-/* $Id: xiic_l.h,v 1.2 2002/12/05 19:32:40 meinelte Exp $ */ +-/***************************************************************************** +-* +-* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" +-* AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND +-* SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, +-* OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, +-* APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION +-* THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, +-* AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE +-* FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY +-* WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE +-* IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR +-* REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF +-* INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +-* FOR A PARTICULAR PURPOSE. +-* +-* (c) Copyright 2002 Xilinx Inc. +-* All rights reserved. +-* +-*****************************************************************************/ +-/****************************************************************************/ +-/** +-* +-* @file xiic_l.h +-* +-* This header file contains identifiers and low-level driver functions (or +-* macros) that can be used to access the device. High-level driver functions +-* are defined in xiic.h. +-* +-*
+-* MODIFICATION HISTORY:
+-*
+-* Ver	Who  Date     Changes
+-* ----- ---- -------- -----------------------------------------------
+-* 1.00b jhl  05/07/02 First release
+-* 1.01c ecm  12/05/02 new rev
+-* 
+-* +-*****************************************************************************/ +- +-#ifndef XIIC_L_H /* prevent circular inclusions */ +-#define XIIC_L_H /* by using protection macros */ +- +-/***************************** Include Files ********************************/ +- +-#include "xbasic_types.h" +- +-/************************** Constant Definitions ****************************/ +- +-#define XIIC_MSB_OFFSET 3 +- +-#define XIIC_REG_OFFSET 0x100 + XIIC_MSB_OFFSET +- +-/* +- * Register offsets in bytes from RegisterBase. Three is added to the +- * base offset to access LSB (IBM style) of the word +- */ +-#define XIIC_CR_REG_OFFSET 0x00+XIIC_REG_OFFSET /* Control Register */ +-#define XIIC_SR_REG_OFFSET 0x04+XIIC_REG_OFFSET /* Status Register */ +-#define XIIC_DTR_REG_OFFSET 0x08+XIIC_REG_OFFSET /* Data Tx Register */ +-#define XIIC_DRR_REG_OFFSET 0x0C+XIIC_REG_OFFSET /* Data Rx Register */ +-#define XIIC_ADR_REG_OFFSET 0x10+XIIC_REG_OFFSET /* Address Register */ +-#define XIIC_TFO_REG_OFFSET 0x14+XIIC_REG_OFFSET /* Tx FIFO Occupancy */ +-#define XIIC_RFO_REG_OFFSET 0x18+XIIC_REG_OFFSET /* Rx FIFO Occupancy */ +-#define XIIC_TBA_REG_OFFSET 0x1C+XIIC_REG_OFFSET /* 10 Bit Address reg */ +-#define XIIC_RFD_REG_OFFSET 0x20+XIIC_REG_OFFSET /* Rx FIFO Depth reg */ +- +-/* Control Register masks */ +- +-#define XIIC_CR_ENABLE_DEVICE_MASK 0x01 /* Device enable = 1 */ +-#define XIIC_CR_TX_FIFO_RESET_MASK 0x02 /* Transmit FIFO reset=1 */ +-#define XIIC_CR_MSMS_MASK 0x04 /* Master starts Txing=1 */ +-#define XIIC_CR_DIR_IS_TX_MASK 0x08 /* Dir of tx. Txing=1 */ +-#define XIIC_CR_NO_ACK_MASK 0x10 /* Tx Ack. NO ack = 1 */ +-#define XIIC_CR_REPEATED_START_MASK 0x20 /* Repeated start = 1 */ +-#define XIIC_CR_GENERAL_CALL_MASK 0x40 /* Gen Call enabled = 1 */ +- +-/* Status Register masks */ +- +-#define XIIC_SR_GEN_CALL_MASK 0x01 /* 1=a mstr issued a GC */ +-#define XIIC_SR_ADDR_AS_SLAVE_MASK 0x02 /* 1=when addr as slave */ +-#define XIIC_SR_BUS_BUSY_MASK 0x04 /* 1 = bus is busy */ +-#define XIIC_SR_MSTR_RDING_SLAVE_MASK 0x08 /* 1=Dir: mstr <-- slave */ +-#define XIIC_SR_TX_FIFO_FULL_MASK 0x10 /* 1 = Tx FIFO full */ +-#define XIIC_SR_RX_FIFO_FULL_MASK 0x20 /* 1 = Rx FIFO full */ +-#define XIIC_SR_RX_FIFO_EMPTY_MASK 0x40 /* 1 = Rx FIFO empty */ +- +-/* IPIF Interrupt Status Register masks Interrupt occurs when... */ +- +-#define XIIC_INTR_ARB_LOST_MASK 0x01 /* 1 = arbitration lost */ +-#define XIIC_INTR_TX_ERROR_MASK 0x02 /* 1=Tx error/msg complete*/ +-#define XIIC_INTR_TX_EMPTY_MASK 0x04 /* 1 = Tx FIFO/reg empty */ +-#define XIIC_INTR_RX_FULL_MASK 0x08 /* 1=Rx FIFO/reg=OCY level*/ +-#define XIIC_INTR_BNB_MASK 0x10 /* 1 = Bus not busy */ +-#define XIIC_INTR_AAS_MASK 0x20 /* 1 = when addr as slave */ +-#define XIIC_INTR_NAAS_MASK 0x40 /* 1 = not addr as slave */ +-#define XIIC_INTR_TX_HALF_MASK 0x80 /* 1 = TX FIFO half empty */ +- +-/* IPIF Device Interrupt Register masks */ +- +-#define XIIC_IPIF_IIC_MASK 0x00000004UL /* 1=inter enabled */ +-#define XIIC_IPIF_ERROR_MASK 0x00000001UL /* 1=inter enabled */ +-#define XIIC_IPIF_INTER_ENABLE_MASK (XIIC_IPIF_IIC_MASK | \ +- XIIC_IPIF_ERROR_MASK) +- +-#define XIIC_TX_ADDR_SENT 0x00 +-#define XIIC_TX_ADDR_MSTR_RECV_MASK 0x02 +- +-/* The following constants specify the depth of the FIFOs */ +- +-#define IIC_RX_FIFO_DEPTH 16 /* Rx fifo capacity */ +-#define IIC_TX_FIFO_DEPTH 16 /* Tx fifo capacity */ +- +-/* The following constants specify groups of interrupts that are typically +- * enabled or disables at the same time +- */ +-#define XIIC_TX_INTERRUPTS \ +- (XIIC_INTR_TX_ERROR_MASK | XIIC_INTR_TX_EMPTY_MASK | \ +- XIIC_INTR_TX_HALF_MASK) +- +-#define XIIC_TX_RX_INTERRUPTS (XIIC_INTR_RX_FULL_MASK | XIIC_TX_INTERRUPTS) +- +-/* The following constants are used with the following macros to specify the +- * operation, a read or write operation. +- */ +-#define XIIC_READ_OPERATION 1 +-#define XIIC_WRITE_OPERATION 0 +- +-/* The following constants are used with the transmit FIFO fill function to +- * specify the role which the IIC device is acting as, a master or a slave. +- */ +-#define XIIC_MASTER_ROLE 1 +-#define XIIC_SLAVE_ROLE 0 +- +-/**************************** Type Definitions ******************************/ +- +- +-/***************** Macros (Inline Functions) Definitions ********************/ +- +- +-/************************** Function Prototypes *****************************/ +- +-unsigned XIic_Recv(u32 BaseAddress, u8 Address, +- u8 *BufferPtr, unsigned ByteCount); +- +-unsigned XIic_Send(u32 BaseAddress, u8 Address, +- u8 *BufferPtr, unsigned ByteCount); +- +-#endif /* end of protection macro */ +diff --git a/board/xilinx/zynq/Makefile b/board/xilinx/zynq/Makefile +index ef4faa1..d4814d1 100644 +--- a/board/xilinx/zynq/Makefile ++++ b/board/xilinx/zynq/Makefile +@@ -28,7 +28,7 @@ endif + + LIB = $(obj)lib$(BOARD).o + +-COBJS-y := board.o ++COBJS-y := board.o ../../xilinx/common/xbasic_types.o + + COBJS := $(sort $(COBJS-y)) + +@@ -38,12 +38,6 @@ OBJS := $(addprefix $(obj),$(COBJS)) + $(LIB): $(obj).depend $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +-clean: +- rm -f $(OBJS) +- +-distclean: clean +- rm -f $(LIB) core *.bak $(obj).depend +- + ######################################################################### + + # defines $(obj).depend target +diff --git a/board/xilinx/zynq/board.c b/board/xilinx/zynq/board.c +index 8ed75c3..3bb90f5 100644 +--- a/board/xilinx/zynq/board.c ++++ b/board/xilinx/zynq/board.c +@@ -21,31 +21,154 @@ + */ + + #include ++#include ++#include ++#include + #include ++#include ++#include + + DECLARE_GLOBAL_DATA_PTR; + ++/* Bootmode setting values */ ++#define BOOT_MODES_MASK 0x0000000F ++#define QSPI_MODE 0x00000001 ++#define NOR_FLASH_MODE 0x00000002 ++#define NAND_FLASH_MODE 0x00000004 ++#define SD_MODE 0x00000005 ++#define JTAG_MODE 0x00000000 ++ ++#ifdef CONFIG_FPGA ++Xilinx_desc fpga; ++ ++/* It can be done differently */ ++Xilinx_desc fpga010 = XILINX_XC7Z010_DESC(0x10); ++Xilinx_desc fpga020 = XILINX_XC7Z020_DESC(0x20); ++Xilinx_desc fpga030 = XILINX_XC7Z030_DESC(0x30); ++Xilinx_desc fpga045 = XILINX_XC7Z045_DESC(0x45); ++#endif ++ + int board_init(void) + { ++#ifdef CONFIG_FPGA ++ u32 idcode; ++ ++ idcode = zynq_slcr_get_idcode(); ++ ++ switch (idcode) { ++ case XILINX_ZYNQ_7010: ++ fpga = fpga010; ++ break; ++ case XILINX_ZYNQ_7020: ++ fpga = fpga020; ++ break; ++ case XILINX_ZYNQ_7030: ++ fpga = fpga030; ++ break; ++ case XILINX_ZYNQ_7045: ++ fpga = fpga045; ++ break; ++ } ++#endif ++ ++ /* temporary hack to clear pending irqs before Linux as it ++ * will hang Linux ++ */ ++ writel(0x26d, 0xe0001014); ++ ++ /* temporary hack to take USB out of reset til the is fixed ++ * in Linux ++ */ ++ writel(0x80, 0xe000a204); ++ writel(0x80, 0xe000a208); ++ writel(0x80, 0xe000a040); ++ writel(0x00, 0xe000a040); ++ writel(0x80, 0xe000a040); ++ + icache_enable(); + ++#ifdef CONFIG_FPGA ++ fpga_init(); ++ fpga_add(fpga_xilinx, &fpga); ++#endif ++ + return 0; + } + ++int board_late_init(void) ++{ ++ switch ((zynq_slcr_get_boot_mode()) & BOOT_MODES_MASK) { ++ case QSPI_MODE: ++ setenv("modeboot", "qspiboot"); ++ break; ++ case NAND_FLASH_MODE: ++ setenv("modeboot", "nandboot"); ++ break; ++ case NOR_FLASH_MODE: ++ setenv("modeboot", "norboot"); ++ break; ++ case SD_MODE: ++ setenv("modeboot", "sdboot"); ++ break; ++ case JTAG_MODE: ++ setenv("modeboot", "jtagboot"); ++ break; ++ default: ++ setenv("modeboot", ""); ++ break; ++ } ++ ++ return 0; ++} + + #ifdef CONFIG_CMD_NET + int board_eth_init(bd_t *bis) + { + u32 ret = 0; + +-#if defined(CONFIG_ZYNQ_GEM) && defined(CONFIG_ZYNQ_GEM_BASEADDR0) +- ret = zynq_gem_initialize(bis, CONFIG_ZYNQ_GEM_BASEADDR0); ++#ifdef CONFIG_XILINX_AXIEMAC ++ ret |= xilinx_axiemac_initialize(bis, XILINX_AXIEMAC_BASEADDR, ++ XILINX_AXIDMA_BASEADDR); ++#endif ++#ifdef CONFIG_XILINX_EMACLITE ++ u32 txpp = 0; ++ u32 rxpp = 0; ++# ifdef CONFIG_XILINX_EMACLITE_TX_PING_PONG ++ txpp = 1; ++# endif ++# ifdef CONFIG_XILINX_EMACLITE_RX_PING_PONG ++ rxpp = 1; ++# endif ++ ret |= xilinx_emaclite_initialize(bis, XILINX_EMACLITE_BASEADDR, ++ txpp, rxpp); + #endif + ++#if defined(CONFIG_ZYNQ_GEM) ++# if defined(CONFIG_ZYNQ_GEM_BASEADDR0) ++ ret |= zynq_gem_initialize(bis, CONFIG_ZYNQ_GEM_BASEADDR0); ++# endif ++# if defined(CONFIG_ZYNQ_GEM_BASEADDR1) ++ ret |= zynq_gem_initialize(bis, CONFIG_ZYNQ_GEM_BASEADDR1); ++# endif ++#endif + return ret; + } + #endif + ++#ifdef CONFIG_CMD_MMC ++int board_mmc_init(bd_t *bd) ++{ ++ return zynq_mmc_init(bd); ++} ++#endif ++ ++#ifdef CONFIG_CMD_NAND ++int board_nand_init(struct nand_chip *nand_chip) ++{ ++ return zynq_nand_init(nand_chip); ++} ++#endif ++ + int dram_init(void) + { + gd->ram_size = CONFIG_SYS_SDRAM_SIZE; +diff --git a/boards.cfg b/boards.cfg +index e4b0d44..f75a139 100644 +--- a/boards.cfg ++++ b/boards.cfg +@@ -278,6 +278,16 @@ twister arm armv7 twister technex + nokia_rx51 arm armv7 rx51 nokia omap3 + omap4_panda arm armv7 panda ti omap4 + omap4_sdp4430 arm armv7 sdp4430 ti omap4 ++zynq_zc770_XM010 arm armv7 zynq xilinx zynq zynq_zc770:ZC770_XM010 ++zynq_zc770_XM011 arm armv7 zynq xilinx zynq zynq_zc770:ZC770_XM011 ++zynq_zc770_XM012 arm armv7 zynq xilinx zynq zynq_zc770:ZC770_XM012 ++zynq_zc770_XM013 arm armv7 zynq xilinx zynq zynq_zc770:ZC770_XM013 ++zynq_afx_nor arm armv7 zynq xilinx zynq zynq_afx:AFX_NOR ++zynq_afx_qspi arm armv7 zynq xilinx zynq zynq_afx:AFX_QSPI ++zynq_afx_nand arm armv7 zynq xilinx zynq zynq_afx:AFX_NAND ++zynq_zc70x arm armv7 zynq xilinx zynq ++zynq_cseflash arm armv7 zynq xilinx zynq ++zynq_zed arm armv7 zynq xilinx zynq + omap5_evm arm armv7 omap5_evm ti omap5 + s5p_goni arm armv7 goni samsung s5pc1xx + smdkc100 arm armv7 smdkc100 samsung s5pc1xx +@@ -295,7 +305,6 @@ u8500_href arm armv7 u8500 st-eric + snowball arm armv7 snowball st-ericsson u8500 + kzm9g arm armv7 kzm9g kmc rmobile + armadillo-800eva arm armv7 armadillo-800eva atmark-techno rmobile +-zynq arm armv7 zynq xilinx zynq + socfpga_cyclone5 arm armv7 socfpga_cyclone5 altera socfpga + actux1_4_16 arm ixp actux1 - - actux1:FLASH2X2 + actux1_4_32 arm ixp actux1 - - actux1:FLASH2X2,RAM_32MB +@@ -1014,10 +1023,6 @@ walnut powerpc ppc4xx walnut amcc + yellowstone powerpc ppc4xx yosemite amcc - yosemite:YELLOWSTONE + yosemite powerpc ppc4xx yosemite amcc - yosemite:YOSEMITE + yucca powerpc ppc4xx - amcc +-fx12mm powerpc ppc4xx fx12mm avnet - fx12mm:SYS_TEXT_BASE=0x04000000,RESET_VECTOR_ADDRESS=0x04100000,INIT_TLB=board/xilinx/ppc405-generic/init.o +-fx12mm_flash powerpc ppc4xx fx12mm avnet - fx12mm:SYS_TEXT_BASE=0xF7F60000,RESET_VECTOR_ADDRESS=0xF7FFFFFC,INIT_TLB=board/xilinx/ppc405-generic/init.o +-v5fx30teval powerpc ppc4xx v5fx30teval avnet - v5fx30teval:SYS_TEXT_BASE=0x04000000,RESET_VECTOR_ADDRESS=0x04100000,BOOT_FROM_XMD=1,INIT_TLB=board/xilinx/ppc440-generic/init.o +-v5fx30teval_flash powerpc ppc4xx v5fx30teval avnet - v5fx30teval:SYS_TEXT_BASE=0xF7F60000,RESET_VECTOR_ADDRESS=0xF7FFFFFC,INIT_TLB=board/xilinx/ppc440-generic/init.o + CRAYL1 powerpc ppc4xx L1 cray + CATcenter powerpc ppc4xx PPChameleonEVB dave - CATcenter:PPCHAMELEON_MODULE_MODEL=1 + CATcenter_25 powerpc ppc4xx PPChameleonEVB dave - CATcenter:PPCHAMELEON_MODULE_MODEL=1,PPCHAMELEON_CLK_25 +@@ -1072,12 +1077,8 @@ p3p440 powerpc ppc4xx - prodriv + KAREF powerpc ppc4xx karef sandburst + METROBOX powerpc ppc4xx metrobox sandburst + xpedite1000 powerpc ppc4xx - xes +-ml507 powerpc ppc4xx ml507 xilinx - ml507:SYS_TEXT_BASE=0x04000000,RESET_VECTOR_ADDRESS=0x04100000,BOOT_FROM_XMD=1,INIT_TLB=board/xilinx/ppc440-generic/init.o +-ml507_flash powerpc ppc4xx ml507 xilinx - ml507:SYS_TEXT_BASE=0xF7F60000,RESET_VECTOR_ADDRESS=0xF7FFFFFC,INIT_TLB=board/xilinx/ppc440-generic/init.o +-xilinx-ppc405-generic powerpc ppc4xx ppc405-generic xilinx - xilinx-ppc405-generic:SYS_TEXT_BASE=0x04000000,RESET_VECTOR_ADDRESS=0x04100000 +-xilinx-ppc405-generic_flash powerpc ppc4xx ppc405-generic xilinx - xilinx-ppc405-generic:SYS_TEXT_BASE=0xF7F60000,RESET_VECTOR_ADDRESS=0xF7FFFFFC +-xilinx-ppc440-generic powerpc ppc4xx ppc440-generic xilinx - xilinx-ppc440-generic:SYS_TEXT_BASE=0x04000000,RESET_VECTOR_ADDRESS=0x04100000,BOOT_FROM_XMD=1 +-xilinx-ppc440-generic_flash powerpc ppc4xx ppc440-generic xilinx - xilinx-ppc440-generic:SYS_TEXT_BASE=0xF7F60000,RESET_VECTOR_ADDRESS=0xF7FFFFFC ++xilinx-ppc405-generic powerpc ppc4xx ppc405-generic xilinx - ++xilinx-ppc440-generic powerpc ppc4xx ppc440-generic xilinx - + sandbox sandbox sandbox sandbox sandbox - + rsk7203 sh sh2 rsk7203 renesas - + rsk7264 sh sh2 rsk7264 renesas - +-- +1.7.5.4 + diff --git a/recipes-bsp/u-boot/u-boot/xilinx-v2013.01/0003-Xilinx-modifications-to-commmon.patch b/recipes-bsp/u-boot/u-boot/xilinx-v2013.01/0003-Xilinx-modifications-to-commmon.patch new file mode 100644 index 00000000..0b1dc671 --- /dev/null +++ b/recipes-bsp/u-boot/u-boot/xilinx-v2013.01/0003-Xilinx-modifications-to-commmon.patch @@ -0,0 +1,522 @@ +From cc18c64aaa0a3cfb82ca490fe7e7e7d1a554b739 Mon Sep 17 00:00:00 2001 +From: Sipke Vriend +Date: Tue, 21 May 2013 07:19:12 +1000 +Subject: [PATCH 3/5] Xilinx modifications to commmon + +Signed-off-by: Sipke Vriend +--- + Makefile | 2 +- + common/Makefile | 1 - + common/cmd_bdinfo.c | 27 +++- + common/cmd_mfsl.c | 404 --------------------------------------------------- + common/stdio.c | 2 +- + 5 files changed, 24 insertions(+), 412 deletions(-) + mode change 100644 => 100755 Makefile + delete mode 100644 common/cmd_mfsl.c + +diff --git a/Makefile b/Makefile +old mode 100644 +new mode 100755 +index 8dd09a5..3305e8c +--- a/Makefile ++++ b/Makefile +@@ -23,7 +23,7 @@ + + VERSION = 2013 + PATCHLEVEL = 01 +-SUBLEVEL = 01 ++SUBLEVEL = + EXTRAVERSION = + ifneq "$(SUBLEVEL)" "" + U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) +diff --git a/common/Makefile b/common/Makefile +index 54fcc81..45c7afc 100644 +--- a/common/Makefile ++++ b/common/Makefile +@@ -125,7 +125,6 @@ COBJS-$(CONFIG_ID_EEPROM) += cmd_mac.o + COBJS-$(CONFIG_CMD_MD5SUM) += cmd_md5sum.o + COBJS-$(CONFIG_CMD_MEMORY) += cmd_mem.o + COBJS-$(CONFIG_CMD_IO) += cmd_io.o +-COBJS-$(CONFIG_CMD_MFSL) += cmd_mfsl.o + COBJS-$(CONFIG_MII) += miiphyutil.o + COBJS-$(CONFIG_CMD_MII) += miiphyutil.o + COBJS-$(CONFIG_PHYLIB) += miiphyutil.o +diff --git a/common/cmd_bdinfo.c b/common/cmd_bdinfo.c +index 48cdd16..28b5241 100644 +--- a/common/cmd_bdinfo.c ++++ b/common/cmd_bdinfo.c +@@ -51,6 +51,25 @@ static void print_eth(int idx) + } + + __maybe_unused ++static void print_eths(void) ++{ ++ struct eth_device *dev; ++ int i = 0; ++ ++ do { ++ dev = eth_get_dev_by_index(i); ++ if (dev) { ++ printf("eth%dname = %s\n", i, dev->name); ++ print_eth(i); ++ i++; ++ } ++ } while (dev); ++ ++ printf("current eth = %s\n", eth_get_name()); ++ printf("ip_addr = %s\n", getenv("ipaddr")); ++} ++ ++__maybe_unused + static void print_lnum(const char *name, unsigned long long value) + { + printf("%-12s= 0x%.8llX\n", name, value); +@@ -195,10 +214,9 @@ int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) + print_num("sram size ", (ulong)bd->bi_sramsize); + #endif + #if defined(CONFIG_CMD_NET) +- print_eth(0); +- printf("ip_addr = %s\n", getenv("ipaddr")); ++ print_eths(); + #endif +- printf("baudrate = %u bps\n", (ulong)bd->bi_baudrate); ++ printf("baudrate = %u bps\n", bd->bi_baudrate); + return 0; + } + +@@ -366,8 +384,7 @@ int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) + } + + #if defined(CONFIG_CMD_NET) +- print_eth(0); +- printf("ip_addr = %s\n", getenv("ipaddr")); ++ print_eths(); + #endif + printf("baudrate = %u bps\n", bd->bi_baudrate); + #if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) +diff --git a/common/cmd_mfsl.c b/common/cmd_mfsl.c +deleted file mode 100644 +index ddf80d7..0000000 +--- a/common/cmd_mfsl.c ++++ /dev/null +@@ -1,404 +0,0 @@ +-/* +- * (C) Copyright 2007 Michal Simek +- * +- * Michal SIMEK +- * +- * 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 +- */ +- +-/* +- * Microblaze FSL support +- */ +- +-#include +-#include +-#include +-#include +- +-int do_frd (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) +-{ +- unsigned int fslnum; +- unsigned int num; +- unsigned int blocking; +- +- if (argc < 2) +- return CMD_RET_USAGE; +- +- fslnum = (unsigned int)simple_strtoul (argv[1], NULL, 16); +- blocking = (unsigned int)simple_strtoul (argv[2], NULL, 16); +- if (fslnum < 0 || fslnum >= XILINX_FSL_NUMBER) { +- puts ("Bad number of FSL\n"); +- return CMD_RET_USAGE; +- } +- +- switch (fslnum) { +-#if (XILINX_FSL_NUMBER > 0) +- case 0: +- switch (blocking) { +- case 0: NGET (num, 0); +- break; +- case 1: NCGET (num, 0); +- break; +- case 2: GET (num, 0); +- break; +- case 3: CGET (num, 0); +- break; +- default: +- return 2; +- } +- break; +-#endif +-#if (XILINX_FSL_NUMBER > 1) +- case 1: +- switch (blocking) { +- case 0: NGET (num, 1); +- break; +- case 1: NCGET (num, 1); +- break; +- case 2: GET (num, 1); +- break; +- case 3: CGET (num, 1); +- break; +- default: +- return 2; +- } +- break; +-#endif +-#if (XILINX_FSL_NUMBER > 2) +- case 2: +- switch (blocking) { +- case 0: NGET (num, 2); +- break; +- case 1: NCGET (num, 2); +- break; +- case 2: GET (num, 2); +- break; +- case 3: CGET (num, 2); +- break; +- default: +- return 2; +- } +- break; +-#endif +-#if (XILINX_FSL_NUMBER > 3) +- case 3: +- switch (blocking) { +- case 0: NGET (num, 3); +- break; +- case 1: NCGET (num, 3); +- break; +- case 2: GET (num, 3); +- break; +- case 3: CGET (num, 3); +- break; +- default: +- return 2; +- } +- break; +-#endif +-#if (XILINX_FSL_NUMBER > 4) +- case 4: +- switch (blocking) { +- case 0: NGET (num, 4); +- break; +- case 1: NCGET (num, 4); +- break; +- case 2: GET (num, 4); +- break; +- case 3: CGET (num, 4); +- break; +- default: +- return 2; +- } +- break; +-#endif +-#if (XILINX_FSL_NUMBER > 5) +- case 5: +- switch (blocking) { +- case 0: NGET (num, 5); +- break; +- case 1: NCGET (num, 5); +- break; +- case 2: GET (num, 5); +- break; +- case 3: CGET (num, 5); +- break; +- default: +- return 2; +- } +- break; +-#endif +-#if (XILINX_FSL_NUMBER > 6) +- case 6: +- switch (blocking) { +- case 0: NGET (num, 6); +- break; +- case 1: NCGET (num, 6); +- break; +- case 2: GET (num, 6); +- break; +- case 3: CGET (num, 6); +- break; +- default: +- return 2; +- } +- break; +-#endif +-#if (XILINX_FSL_NUMBER > 7) +- case 7: +- switch (blocking) { +- case 0: NGET (num, 7); +- break; +- case 1: NCGET (num, 7); +- break; +- case 2: GET (num, 7); +- break; +- case 3: CGET (num, 7); +- break; +- default: +- return 2; +- } +- break; +-#endif +- default: +- return 1; +- } +- +- printf ("%01x: 0x%08x - %s %s read\n", fslnum, num, +- blocking < 2 ? "non blocking" : "blocking", +- ((blocking == 1) || (blocking == 3)) ? "control" : "data" ); +- return 0; +-} +- +-int do_fwr (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) +-{ +- unsigned int fslnum; +- unsigned int num; +- unsigned int blocking; +- +- if (argc < 3) +- return CMD_RET_USAGE; +- +- fslnum = (unsigned int)simple_strtoul (argv[1], NULL, 16); +- num = (unsigned int)simple_strtoul (argv[2], NULL, 16); +- blocking = (unsigned int)simple_strtoul (argv[3], NULL, 16); +- if (fslnum < 0 || fslnum >= XILINX_FSL_NUMBER) +- return CMD_RET_USAGE; +- +- switch (fslnum) { +-#if (XILINX_FSL_NUMBER > 0) +- case 0: +- switch (blocking) { +- case 0: NPUT (num, 0); +- break; +- case 1: NCPUT (num, 0); +- break; +- case 2: PUT (num, 0); +- break; +- case 3: CPUT (num, 0); +- break; +- default: +- return 2; +- } +- break; +-#endif +-#if (XILINX_FSL_NUMBER > 1) +- case 1: +- switch (blocking) { +- case 0: NPUT (num, 1); +- break; +- case 1: NCPUT (num, 1); +- break; +- case 2: PUT (num, 1); +- break; +- case 3: CPUT (num, 1); +- break; +- default: +- return 2; +- } +- break; +-#endif +-#if (XILINX_FSL_NUMBER > 2) +- case 2: +- switch (blocking) { +- case 0: NPUT (num, 2); +- break; +- case 1: NCPUT (num, 2); +- break; +- case 2: PUT (num, 2); +- break; +- case 3: CPUT (num, 2); +- break; +- default: +- return 2; +- } +- break; +-#endif +-#if (XILINX_FSL_NUMBER > 3) +- case 3: +- switch (blocking) { +- case 0: NPUT (num, 3); +- break; +- case 1: NCPUT (num, 3); +- break; +- case 2: PUT (num, 3); +- break; +- case 3: CPUT (num, 3); +- break; +- default: +- return 2; +- } +- break; +-#endif +-#if (XILINX_FSL_NUMBER > 4) +- case 4: +- switch (blocking) { +- case 0: NPUT (num, 4); +- break; +- case 1: NCPUT (num, 4); +- break; +- case 2: PUT (num, 4); +- break; +- case 3: CPUT (num, 4); +- break; +- default: +- return 2; +- } +- break; +-#endif +-#if (XILINX_FSL_NUMBER > 5) +- case 5: +- switch (blocking) { +- case 0: NPUT (num, 5); +- break; +- case 1: NCPUT (num, 5); +- break; +- case 2: PUT (num, 5); +- break; +- case 3: CPUT (num, 5); +- break; +- default: +- return 2; +- } +- break; +-#endif +-#if (XILINX_FSL_NUMBER > 6) +- case 6: +- switch (blocking) { +- case 0: NPUT (num, 6); +- break; +- case 1: NCPUT (num, 6); +- break; +- case 2: PUT (num, 6); +- break; +- case 3: CPUT (num, 6); +- break; +- default: +- return 2; +- } +- break; +-#endif +-#if (XILINX_FSL_NUMBER > 7) +- case 7: +- switch (blocking) { +- case 0: NPUT (num, 7); +- break; +- case 1: NCPUT (num, 7); +- break; +- case 2: PUT (num, 7); +- break; +- case 3: CPUT (num, 7); +- break; +- default: +- return 2; +- } +- break; +-#endif +- default: +- return 1; +- } +- +- printf ("%01x: 0x%08x - %s %s write\n", fslnum, num, +- blocking < 2 ? "non blocking" : "blocking", +- ((blocking == 1) || (blocking == 3)) ? "control" : "data" ); +- return 0; +- +-} +- +-int do_rspr (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) +-{ +- unsigned int reg = 0; +- unsigned int val = 0; +- +- if (argc < 2) +- return CMD_RET_USAGE; +- +- reg = (unsigned int)simple_strtoul (argv[1], NULL, 16); +- val = (unsigned int)simple_strtoul (argv[2], NULL, 16); +- switch (reg) { +- case 0x1: +- if (argc > 2) { +- MTS (val, rmsr); +- NOP; +- MFS (val, rmsr); +- } else { +- MFS (val, rmsr); +- } +- puts ("MSR"); +- break; +- case 0x3: +- MFS (val, rear); +- puts ("EAR"); +- break; +- case 0x5: +- MFS (val, resr); +- puts ("ESR"); +- break; +- default: +- puts ("Unsupported register\n"); +- return 1; +- } +- printf (": 0x%08x\n", val); +- return 0; +-} +- +-/***************************************************/ +- +-U_BOOT_CMD (frd, 3, 1, do_frd, +- "read data from FSL", +- "- [fslnum [0|1|2|3]]\n" +- " 0 - non blocking data read\n" +- " 1 - non blocking control read\n" +- " 2 - blocking data read\n" +- " 3 - blocking control read"); +- +-U_BOOT_CMD (fwr, 4, 1, do_fwr, +- "write data to FSL", +- "- [fslnum [0|1|2|3]]\n" +- " 0 - non blocking data write\n" +- " 1 - non blocking control write\n" +- " 2 - blocking data write\n" +- " 3 - blocking control write"); +- +-U_BOOT_CMD (rspr, 3, 1, do_rspr, +- "read/write special purpose register", +- "- reg_num [write value] read/write special purpose register\n" +- " 1 - MSR - Machine status register\n" +- " 3 - EAR - Exception address register\n" +- " 5 - ESR - Exception status register"); +diff --git a/common/stdio.c b/common/stdio.c +index 97ff9cf..5d5117c 100644 +--- a/common/stdio.c ++++ b/common/stdio.c +@@ -207,7 +207,7 @@ int stdio_init (void) + /* Initialize the list */ + INIT_LIST_HEAD(&(devs.list)); + +-#ifdef CONFIG_ARM_DCC_MULTI ++#ifdef CONFIG_ARM_DCC + drv_arm_dcc_init (); + #endif + #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C) +-- +1.7.5.4 + diff --git a/recipes-bsp/u-boot/u-boot/xilinx-v2013.01/0004-Xilinx-modifications-to-drivers.patch b/recipes-bsp/u-boot/u-boot/xilinx-v2013.01/0004-Xilinx-modifications-to-drivers.patch new file mode 100644 index 00000000..08a001e6 --- /dev/null +++ b/recipes-bsp/u-boot/u-boot/xilinx-v2013.01/0004-Xilinx-modifications-to-drivers.patch @@ -0,0 +1,7367 @@ +From bc707e15987263fe5db08a452fe373401c7c359f Mon Sep 17 00:00:00 2001 +From: Sipke Vriend +Date: Tue, 21 May 2013 07:19:13 +1000 +Subject: [PATCH 4/5] Xilinx modifications to drivers + +Signed-off-by: Sipke Vriend +--- + doc/README.watchdog | 3 + + drivers/block/systemace.c | 4 +- + drivers/fpga/Makefile | 1 + + drivers/fpga/xilinx.c | 35 + + drivers/fpga/zynqpl.c | 193 ++++++ + drivers/i2c/Makefile | 1 + + drivers/i2c/zynq_i2c.c | 303 +++++++++ + drivers/mmc/Makefile | 1 + + drivers/mmc/zynq_sdhci.c | 40 ++ + drivers/mtd/nand/Makefile | 1 + + drivers/mtd/nand/nand_base.c | 5 + + drivers/mtd/nand/zynq_nand.c | 1240 ++++++++++++++++++++++++++++++++++ + drivers/mtd/spi/spansion.c | 18 +- + drivers/mtd/spi/spi_flash.c | 172 +++++- + drivers/mtd/spi/spi_flash_internal.h | 19 + + drivers/mtd/spi/stmicro.c | 40 ++- + drivers/mtd/spi/winbond.c | 15 +- + drivers/net/Makefile | 3 +- + drivers/net/phy/marvell.c | 11 + + drivers/net/xilinx_axi_emac.c | 124 +++- + drivers/net/xilinx_emaclite.c | 281 +++++++- + drivers/net/xilinx_ll_temac.c | 885 +++++++++++++++++-------- + drivers/net/xilinx_ll_temac.h | 310 --------- + drivers/net/xilinx_ll_temac_fifo.c | 142 ---- + drivers/net/xilinx_ll_temac_fifo.h | 121 ---- + drivers/net/xilinx_ll_temac_mdio.c | 180 ----- + drivers/net/xilinx_ll_temac_mdio.h | 53 -- + drivers/net/xilinx_ll_temac_sdma.c | 369 ---------- + drivers/net/xilinx_ll_temac_sdma.h | 280 -------- + drivers/net/zynq_gem.c | 251 ++++++-- + drivers/serial/arm_dcc.c | 21 +- + drivers/spi/Makefile | 1 + + drivers/spi/xilinx_spi.c | 2 + + drivers/spi/xilinx_spi.h | 3 + + drivers/spi/zynq_qspips.c | 1056 +++++++++++++++++++++++++++++ + drivers/watchdog/Makefile | 1 + + drivers/watchdog/xilinx_tb_wdt.c | 87 +++ + include/netdev.h | 4 +- + include/spi.h | 2 + + include/spi_flash.h | 2 + + include/stdio_dev.h | 2 +- + include/xilinx.h | 4 + + 42 files changed, 4405 insertions(+), 1881 deletions(-) + create mode 100644 drivers/fpga/zynqpl.c + create mode 100644 drivers/i2c/zynq_i2c.c + create mode 100644 drivers/mmc/zynq_sdhci.c + create mode 100644 drivers/mtd/nand/zynq_nand.c + delete mode 100644 drivers/net/xilinx_ll_temac.h + delete mode 100644 drivers/net/xilinx_ll_temac_fifo.c + delete mode 100644 drivers/net/xilinx_ll_temac_fifo.h + delete mode 100644 drivers/net/xilinx_ll_temac_mdio.c + delete mode 100644 drivers/net/xilinx_ll_temac_mdio.h + delete mode 100644 drivers/net/xilinx_ll_temac_sdma.c + delete mode 100644 drivers/net/xilinx_ll_temac_sdma.h + create mode 100644 drivers/spi/zynq_qspips.c + create mode 100644 drivers/watchdog/xilinx_tb_wdt.c + +diff --git a/doc/README.watchdog b/doc/README.watchdog +index ee65008..33f31c2 100644 +--- a/doc/README.watchdog ++++ b/doc/README.watchdog +@@ -27,3 +27,6 @@ CONFIG_IMX_WATCHDOG + Available for i.mx31/35/5x/6x to service the watchdog. This is not + automatically set because some boards (vision2) still need to define + their own hw_watchdog_reset routine. ++ ++CONFIG_XILINX_TB_WATCHDOG ++ Available for Xilinx Axi platforms to service timebase watchdog timer. +diff --git a/drivers/block/systemace.c b/drivers/block/systemace.c +index 247cf06..b1a3914 100644 +--- a/drivers/block/systemace.c ++++ b/drivers/block/systemace.c +@@ -65,8 +65,8 @@ static void ace_writew(u16 val, unsigned off) + writeb(val, base + off); + writeb(val >> 8, base + off + 1); + #endif +- } +- out16(base + off, val); ++ } else ++ out16(base + off, val); + } + + static u16 ace_readw(unsigned off) +diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile +index b48f623..0b51dcd 100644 +--- a/drivers/fpga/Makefile ++++ b/drivers/fpga/Makefile +@@ -30,6 +30,7 @@ COBJS-y += fpga.o + COBJS-$(CONFIG_FPGA_SPARTAN2) += spartan2.o + COBJS-$(CONFIG_FPGA_SPARTAN3) += spartan3.o + COBJS-$(CONFIG_FPGA_VIRTEX2) += virtex2.o ++COBJS-$(CONFIG_FPGA_ZYNQPL) += zynqpl.o + COBJS-$(CONFIG_FPGA_XILINX) += xilinx.o + COBJS-$(CONFIG_FPGA_LATTICE) += ivm_core.o lattice.o + ifdef CONFIG_FPGA_ALTERA +diff --git a/drivers/fpga/xilinx.c b/drivers/fpga/xilinx.c +index 4072cb4..9ec0263 100644 +--- a/drivers/fpga/xilinx.c ++++ b/drivers/fpga/xilinx.c +@@ -31,6 +31,7 @@ + #include + #include + #include ++#include + + #if 0 + #define FPGA_DEBUG +@@ -86,6 +87,16 @@ int xilinx_load(Xilinx_desc *desc, const void *buf, size_t bsize) + __FUNCTION__); + #endif + break; ++ case Xilinx_Zynq: ++#if defined(CONFIG_FPGA_ZYNQPL) ++ PRINTF("%s: Launching the Zynq PL Loader...\n", ++ __func__); ++ ret_val = zynq_load(desc, buf, bsize); ++#else ++ printf("%s: No support for Zynq devices.\n", ++ __func__); ++#endif ++ break; + + default: + printf ("%s: Unsupported family type, %d\n", +@@ -133,6 +144,16 @@ int xilinx_dump(Xilinx_desc *desc, const void *buf, size_t bsize) + __FUNCTION__); + #endif + break; ++ case Xilinx_Zynq: ++#if defined(CONFIG_FPGA_ZYNQPL) ++ PRINTF("%s: Launching the Zynq PL Reader...\n", ++ __func__); ++ ret_val = zynq_dump(desc, buf, bsize); ++#else ++ printf("%s: No support for Zynq devices.\n", ++ __func__); ++#endif ++ break; + + default: + printf ("%s: Unsupported family type, %d\n", +@@ -158,6 +179,9 @@ int xilinx_info (Xilinx_desc * desc) + case Xilinx_Virtex2: + printf ("Virtex-II\n"); + break; ++ case Xilinx_Zynq: ++ printf("Zynq PL\n"); ++ break; + /* Add new family types here */ + default: + printf ("Unknown family type, %d\n", desc->family); +@@ -183,6 +207,9 @@ int xilinx_info (Xilinx_desc * desc) + case master_selectmap: + printf ("Master SelectMap Mode\n"); + break; ++ case devcfg: ++ printf("Device configuration interface (Zynq)\n"); ++ break; + /* Add new interface types here */ + default: + printf ("Unsupported interface type, %d\n", desc->iface); +@@ -222,6 +249,14 @@ int xilinx_info (Xilinx_desc * desc) + __FUNCTION__); + #endif + break; ++ case Xilinx_Zynq: ++#if defined(CONFIG_FPGA_ZYNQPL) ++ zynq_info(desc); ++#else ++ /* just in case */ ++ printf("%s: No support for Zynq devices.\n", ++ __func__); ++#endif + /* Add new family types here */ + default: + /* we don't need a message here - we give one up above */ +diff --git a/drivers/fpga/zynqpl.c b/drivers/fpga/zynqpl.c +new file mode 100644 +index 0000000..17cccf9 +--- /dev/null ++++ b/drivers/fpga/zynqpl.c +@@ -0,0 +1,193 @@ ++/* ++ * (C) Copyright 2012 ++ * Joe Hershberger ++ * ++ * 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 ++#include ++#include ++#include ++#include ++ ++#define DEVCFG_CTRL_PCFG_PROG_B 0x40000000 ++#define DEVCFG_ISR_FATAL_ERROR_MASK 0x00740040 ++#define DEVCFG_ISR_ERROR_FLAGS_MASK 0x00340840 ++#define DEVCFG_ISR_RX_FIFO_OV 0x00040000 ++#define DEVCFG_ISR_DMA_DONE 0x00002000 ++#define DEVCFG_ISR_PCFG_DONE 0x00000004 ++#define DEVCFG_STATUS_DMA_CMD_Q_F 0x80000000 ++#define DEVCFG_STATUS_DMA_CMD_Q_E 0x40000000 ++#define DEVCFG_STATUS_DMA_DONE_CNT_MASK 0x30000000 ++#define DEVCFG_STATUS_PCFG_INIT 0x00000010 ++#define DEVCFG_MCTRL_RFIFO_FLUSH 0x00000002 ++#define DEVCFG_MCTRL_WFIFO_FLUSH 0x00000001 ++ ++#ifndef CONFIG_SYS_FPGA_WAIT ++#define CONFIG_SYS_FPGA_WAIT CONFIG_SYS_HZ/100 /* 10 ms */ ++#endif ++ ++#ifndef CONFIG_SYS_FPGA_PROG_TIME ++#define CONFIG_SYS_FPGA_PROG_TIME CONFIG_SYS_HZ /* 1 s */ ++#endif ++ ++int zynq_info(Xilinx_desc *desc) ++{ ++ return FPGA_SUCCESS; ++} ++ ++int zynq_load(Xilinx_desc *desc, const void *buf, size_t bsize) ++{ ++ unsigned long ts; /* Timestamp */ ++ u32 control; ++ u32 isr_status; ++ u32 status; ++ ++ /* FIXME Add checking that passing bin is not a bitstream */ ++ ++ zynq_slcr_devcfg_disable(); ++ ++ /* Setting PCFG_PROG_B signal to high */ ++ control = readl(&devcfg_base->ctrl); ++ writel(control | DEVCFG_CTRL_PCFG_PROG_B, &devcfg_base->ctrl); ++ /* Setting PCFG_PROG_B signal to low */ ++ writel(control & ~DEVCFG_CTRL_PCFG_PROG_B, &devcfg_base->ctrl); ++ ++ /* Polling the PCAP_INIT status for Reset */ ++ ts = get_timer(0); ++ while (readl(&devcfg_base->status) & DEVCFG_STATUS_PCFG_INIT) { ++ if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT) { ++ puts("Error: Timeout waiting for INIT to clear.\n"); ++ return FPGA_FAIL; ++ } ++ } ++ ++ /* Setting PCFG_PROG_B signal to high */ ++ writel(control | DEVCFG_CTRL_PCFG_PROG_B, &devcfg_base->ctrl); ++ ++ /* Polling the PCAP_INIT status for Set */ ++ ts = get_timer(0); ++ while (!(readl(&devcfg_base->status) & DEVCFG_STATUS_PCFG_INIT)) { ++ if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT) { ++ puts("Error: Timeout waiting for INIT to set.\n"); ++ return FPGA_FAIL; ++ } ++ } ++ ++ isr_status = readl(&devcfg_base->int_sts); ++ ++ /* Clear it all, so if Boot ROM comes back, it can proceed */ ++ writel(0xFFFFFFFF, &devcfg_base->int_sts); ++ ++ if (isr_status & DEVCFG_ISR_FATAL_ERROR_MASK) { ++ debug("Fatal errors in PCAP 0x%X\n", isr_status); ++ ++ /* If RX FIFO overflow, need to flush RX FIFO first */ ++ if (isr_status & DEVCFG_ISR_RX_FIFO_OV) { ++ writel(DEVCFG_MCTRL_RFIFO_FLUSH, &devcfg_base->mctrl); ++ writel(0xFFFFFFFF, &devcfg_base->int_sts); ++ } ++ return FPGA_FAIL; ++ } ++ ++ status = readl(&devcfg_base->status); ++ ++ debug("status = 0x%08X\n", status); ++ ++ if (status & DEVCFG_STATUS_DMA_CMD_Q_F) { ++ debug("Error: device busy\n"); ++ return FPGA_FAIL; ++ } ++ ++ debug("device ready\n"); ++ ++ if (!(status & DEVCFG_STATUS_DMA_CMD_Q_E)) { ++ if (!(readl(&devcfg_base->int_sts) & DEVCFG_ISR_DMA_DONE)) { ++ /* Error state, transfer cannot occur */ ++ debug("isr indicates error\n"); ++ return FPGA_FAIL; ++ } else { ++ /* Clear out the status */ ++ writel(DEVCFG_ISR_DMA_DONE, &devcfg_base->int_sts); ++ } ++ } ++ ++ if (status & DEVCFG_STATUS_DMA_DONE_CNT_MASK) { ++ /* Clear the count of completed DMA transfers */ ++ writel(DEVCFG_STATUS_DMA_DONE_CNT_MASK, &devcfg_base->status); ++ } ++ ++ debug("Source = 0x%08X\n", (u32)buf); ++ debug("Size = %zu\n", bsize); ++ ++ /* Set up the transfer */ ++ writel((u32)buf | 1, &devcfg_base->dma_src_addr); ++ writel(0xFFFFFFFF, &devcfg_base->dma_dst_addr); ++ writel(bsize >> 2, &devcfg_base->dma_src_len); ++ writel(0, &devcfg_base->dma_dst_len); ++ ++ isr_status = readl(&devcfg_base->int_sts); ++ ++ /* Polling the PCAP_INIT status for Set */ ++ ts = get_timer(0); ++ while (!(isr_status & DEVCFG_ISR_DMA_DONE)) { ++ if (isr_status & DEVCFG_ISR_ERROR_FLAGS_MASK) { ++ debug("Error: isr = 0x%08X\n", isr_status); ++ debug("Write count = 0x%08X\n", ++ readl(&devcfg_base->write_count)); ++ debug("Read count = 0x%08X\n", ++ readl(&devcfg_base->read_count)); ++ ++ return FPGA_FAIL; ++ } ++ if (get_timer(ts) > CONFIG_SYS_FPGA_PROG_TIME) { ++ puts("Error: Timeout waiting for DMA to complete.\n"); ++ return FPGA_FAIL; ++ } ++ isr_status = readl(&devcfg_base->int_sts); ++ } ++ ++ debug("DMA transfer is done\n"); ++ ++ /* Check FPGA configuration completion */ ++ ts = get_timer(0); ++ while (!(isr_status & DEVCFG_ISR_PCFG_DONE)) { ++ if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT) { ++ puts("Error: Timeout waiting for FPGA to config.\n"); ++ return FPGA_FAIL; ++ } ++ isr_status = readl(&devcfg_base->int_sts); ++ } ++ ++ debug("FPGA config done\n"); ++ ++ /* Clear out the DMA status */ ++ writel(DEVCFG_ISR_DMA_DONE, &devcfg_base->int_sts); ++ ++ zynq_slcr_devcfg_enable(); ++ ++ return FPGA_SUCCESS; ++} ++ ++int zynq_dump(Xilinx_desc *desc, const void *buf, size_t bsize) ++{ ++ return FPGA_FAIL; ++} +diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile +index 5dbdbe3..72e85a3 100644 +--- a/drivers/i2c/Makefile ++++ b/drivers/i2c/Makefile +@@ -46,6 +46,7 @@ COBJS-$(CONFIG_TSI108_I2C) += tsi108_i2c.o + COBJS-$(CONFIG_U8500_I2C) += u8500_i2c.o + COBJS-$(CONFIG_SH_I2C) += sh_i2c.o + COBJS-$(CONFIG_SH_SH7734_I2C) += sh_sh7734_i2c.o ++COBJS-$(CONFIG_ZYNQ_I2C) += zynq_i2c.o + + COBJS := $(COBJS-y) + SRCS := $(COBJS:.o=.c) +diff --git a/drivers/i2c/zynq_i2c.c b/drivers/i2c/zynq_i2c.c +new file mode 100644 +index 0000000..14ca163 +--- /dev/null ++++ b/drivers/i2c/zynq_i2c.c +@@ -0,0 +1,303 @@ ++/* ++ * Driver for the Zynq-7000 PSS I2C controller ++ * IP from Cadence (ID T-CS-PE-0007-100, Version R1p10f2) ++ * ++ * Author: Joe Hershberger ++ * Copyright (c) 2012 Joe Hershberger. ++ * ++ * 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 ++#include ++#include ++#include ++ ++/* i2c register set */ ++struct zynq_i2c_registers { ++ u32 control; ++ u32 status; ++ u32 address; ++ u32 data; ++ u32 interrupt_status; ++ u32 transfer_size; ++ u32 slave_mon_pause; ++ u32 time_out; ++ u32 interrupt_mask; ++ u32 interrupt_enable; ++ u32 interrupt_disable; ++}; ++ ++/* Control register fields */ ++#define ZYNQ_I2C_CONTROL_RW 0x00000001 ++#define ZYNQ_I2C_CONTROL_MS 0x00000002 ++#define ZYNQ_I2C_CONTROL_NEA 0x00000004 ++#define ZYNQ_I2C_CONTROL_ACKEN 0x00000008 ++#define ZYNQ_I2C_CONTROL_HOLD 0x00000010 ++#define ZYNQ_I2C_CONTROL_SLVMON 0x00000020 ++#define ZYNQ_I2C_CONTROL_CLR_FIFO 0x00000040 ++#define ZYNQ_I2C_CONTROL_DIV_B_SHIFT 8 ++#define ZYNQ_I2C_CONTROL_DIV_B_MASK 0x00003F00 ++#define ZYNQ_I2C_CONTROL_DIV_A_SHIFT 14 ++#define ZYNQ_I2C_CONTROL_DIV_A_MASK 0x0000C000 ++ ++/* Status register values */ ++#define ZYNQ_I2C_STATUS_RXDV 0x00000020 ++#define ZYNQ_I2C_STATUS_TXDV 0x00000040 ++#define ZYNQ_I2C_STATUS_RXOVF 0x00000080 ++#define ZYNQ_I2C_STATUS_BA 0x00000100 ++ ++/* Interrupt register fields */ ++#define ZYNQ_I2C_INTERRUPT_COMP 0x00000001 ++#define ZYNQ_I2C_INTERRUPT_DATA 0x00000002 ++#define ZYNQ_I2C_INTERRUPT_NACK 0x00000004 ++#define ZYNQ_I2C_INTERRUPT_TO 0x00000008 ++#define ZYNQ_I2C_INTERRUPT_SLVRDY 0x00000010 ++#define ZYNQ_I2C_INTERRUPT_RXOVF 0x00000020 ++#define ZYNQ_I2C_INTERRUPT_TXOVF 0x00000040 ++#define ZYNQ_I2C_INTERRUPT_RXUNF 0x00000080 ++#define ZYNQ_I2C_INTERRUPT_ARBLOST 0x00000200 ++ ++#if defined(CONFIG_ZYNQ_I2C_CTLR_0) ++#define ZYNQ_I2C_BASE 0xE0004000 ++#if defined(CONFIG_ZYNQ_I2C_CTLR_1) ++#warning Only CONFIG_ZYNQ_I2C_CTLR_0 will be accessible ++#endif ++#elif defined(CONFIG_ZYNQ_I2C_CTLR_1) ++#define ZYNQ_I2C_BASE 0xE0005000 ++#else ++#error You must select CONFIG_ZYNQ_I2C_CTLR_0 or CONFIG_ZYNQ_I2C_CTLR_1 ++#endif ++ ++#define ZYNQ_I2C_FIFO_DEPTH 16 ++#define ZYNQ_I2C_TRANSFERT_SIZE_MAX 255 /* Controller transfer limit */ ++ ++static struct zynq_i2c_registers *zynq_i2c = ++ (struct zynq_i2c_registers *) ZYNQ_I2C_BASE; ++ ++/* I2C init called by cmd_i2c when doing 'i2c reset'. */ ++void i2c_init(int requested_speed, int slaveadd) ++{ ++ /* 111MHz / ( (3 * 17) * 22 ) = ~100KHz */ ++ writel((16 << ZYNQ_I2C_CONTROL_DIV_B_SHIFT) | ++ (2 << ZYNQ_I2C_CONTROL_DIV_A_SHIFT), &zynq_i2c->control); ++ ++ /* Enable master mode, ack, and 7-bit addressing */ ++ setbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_MS | ++ ZYNQ_I2C_CONTROL_ACKEN | ZYNQ_I2C_CONTROL_NEA); ++} ++ ++#ifdef DEBUG ++static void zynq_i2c_debug_status(void) ++{ ++ int int_status; ++ int status; ++ int_status = readl(&zynq_i2c->interrupt_status); ++ status = readl(&zynq_i2c->status); ++ if (int_status || status) { ++ debug("Status: "); ++ if (int_status & ZYNQ_I2C_INTERRUPT_COMP) ++ debug("COMP "); ++ if (int_status & ZYNQ_I2C_INTERRUPT_DATA) ++ debug("DATA "); ++ if (int_status & ZYNQ_I2C_INTERRUPT_NACK) ++ debug("NACK "); ++ if (int_status & ZYNQ_I2C_INTERRUPT_TO) ++ debug("TO "); ++ if (int_status & ZYNQ_I2C_INTERRUPT_SLVRDY) ++ debug("SLVRDY "); ++ if (int_status & ZYNQ_I2C_INTERRUPT_RXOVF) ++ debug("RXOVF "); ++ if (int_status & ZYNQ_I2C_INTERRUPT_TXOVF) ++ debug("TXOVF "); ++ if (int_status & ZYNQ_I2C_INTERRUPT_RXUNF) ++ debug("RXUNF "); ++ if (int_status & ZYNQ_I2C_INTERRUPT_ARBLOST) ++ debug("ARBLOST "); ++ if (status & ZYNQ_I2C_STATUS_RXDV) ++ debug("RXDV "); ++ if (status & ZYNQ_I2C_STATUS_TXDV) ++ debug("TXDV "); ++ if (status & ZYNQ_I2C_STATUS_RXOVF) ++ debug("RXOVF "); ++ if (status & ZYNQ_I2C_STATUS_BA) ++ debug("BA "); ++ debug("TS%d ", readl(&zynq_i2c->transfer_size)); ++ debug("\n"); ++ } ++} ++#endif ++ ++/* Wait for an interrupt */ ++static u32 zynq_i2c_wait(u32 mask) ++{ ++ int timeout, int_status; ++ for (timeout = 0; timeout < 100; timeout++) { ++ udelay(100); ++ int_status = readl(&zynq_i2c->interrupt_status); ++ if (int_status & mask) ++ break; ++ } ++#ifdef DEBUG ++ zynq_i2c_debug_status(); ++#endif ++ /* Clear interrupt status flags */ ++ writel(int_status & mask, &zynq_i2c->interrupt_status); ++ return int_status & mask; ++} ++ ++/* ++ * I2C probe called by cmd_i2c when doing 'i2c probe'. ++ * Begin read, nak data byte, end. ++ */ ++int i2c_probe(u8 dev) ++{ ++ /* Attempt to read a byte */ ++ setbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_CLR_FIFO | ++ ZYNQ_I2C_CONTROL_RW); ++ clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD); ++ writel(0xFF, &zynq_i2c->interrupt_status); ++ writel(dev, &zynq_i2c->address); ++ writel(1, &zynq_i2c->transfer_size); ++ ++ return (zynq_i2c_wait(ZYNQ_I2C_INTERRUPT_COMP | ++ ZYNQ_I2C_INTERRUPT_NACK) & ++ ZYNQ_I2C_INTERRUPT_COMP) ? 0 : -ETIMEDOUT; ++} ++ ++/* ++ * I2C read called by cmd_i2c when doing 'i2c read' and by cmd_eeprom.c ++ * Begin write, send address byte(s), begin read, receive data bytes, end. ++ */ ++int i2c_read(u8 dev, uint addr, int alen, u8 *data, int length) ++{ ++ u32 status; ++ u32 i = 0; ++ u8 *cur_data = data; ++ ++ /* check the hardware can handle the requested bytes */ ++ if ((length < 0) || (length > ZYNQ_I2C_TRANSFERT_SIZE_MAX)) ++ return -EINVAL; ++ ++ /* Write the register address */ ++ setbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_CLR_FIFO | ++ ZYNQ_I2C_CONTROL_HOLD); ++ /* Temporarily disable restart (by clearing hold)... */ ++ /* It doesn't seem to work. */ ++ clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_RW | ++ ZYNQ_I2C_CONTROL_HOLD); ++ writel(0xFF, &zynq_i2c->interrupt_status); ++ while (alen--) ++ writel(addr >> (8*alen), &zynq_i2c->data); ++ writel(dev, &zynq_i2c->address); ++ ++ /* wait for the address to be sent */ ++ if (!zynq_i2c_wait(ZYNQ_I2C_INTERRUPT_COMP)) { ++ /* Release the bus */ ++ clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD); ++ return -ETIMEDOUT; ++ } ++ debug("Device acked address\n"); ++ ++ setbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_CLR_FIFO | ++ ZYNQ_I2C_CONTROL_RW); ++ /* Start reading data */ ++ writel(dev, &zynq_i2c->address); ++ writel(length, &zynq_i2c->transfer_size); ++ ++ /* wait for data */ ++ do { ++ status = zynq_i2c_wait(ZYNQ_I2C_INTERRUPT_COMP | ++ ZYNQ_I2C_INTERRUPT_DATA); ++ if (!status) { ++ /* Release the bus */ ++ clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD); ++ return -ETIMEDOUT; ++ } ++ debug("Read %d bytes\n", ++ length - readl(&zynq_i2c->transfer_size)); ++ for (; i < length - readl(&zynq_i2c->transfer_size); i++) ++ *(cur_data++) = readl(&zynq_i2c->data); ++ } while (readl(&zynq_i2c->transfer_size) != 0); ++ /* All done... release the bus */ ++ clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD); ++ ++#ifdef DEBUG ++ zynq_i2c_debug_status(); ++#endif ++ return 0; ++} ++ ++/* ++ * I2C write called by cmd_i2c when doing 'i2c write' and by cmd_eeprom.c ++ * Begin write, send address byte(s), send data bytes, end. ++ */ ++int i2c_write(u8 dev, uint addr, int alen, u8 *data, int length) ++{ ++ u8 *cur_data = data; ++ ++ /* Write the register address */ ++ setbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_CLR_FIFO | ++ ZYNQ_I2C_CONTROL_HOLD); ++ clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_RW); ++ writel(0xFF, &zynq_i2c->interrupt_status); ++ while (alen--) ++ writel(addr >> (8*alen), &zynq_i2c->data); ++ /* Start the tranfer */ ++ writel(dev, &zynq_i2c->address); ++ if (!zynq_i2c_wait(ZYNQ_I2C_INTERRUPT_COMP)) { ++ /* Release the bus */ ++ clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD); ++ return -ETIMEDOUT; ++ } ++ ++ debug("Device acked address\n"); ++ while (length--) { ++ writel(*(cur_data++), &zynq_i2c->data); ++ if (readl(&zynq_i2c->transfer_size) == ZYNQ_I2C_FIFO_DEPTH) { ++ if (!zynq_i2c_wait(ZYNQ_I2C_INTERRUPT_COMP)) { ++ /* Release the bus */ ++ clrbits_le32(&zynq_i2c->control, ++ ZYNQ_I2C_CONTROL_HOLD); ++ return -ETIMEDOUT; ++ } ++ } ++ } ++ ++ /* All done... release the bus */ ++ clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD); ++ /* wait for the address and data to be sent */ ++ if (!zynq_i2c_wait(ZYNQ_I2C_INTERRUPT_COMP)) ++ return -ETIMEDOUT; ++ return 0; ++} ++ ++int i2c_set_bus_num(unsigned int bus) ++{ ++ /* Only support bus 0 */ ++ if (bus > 0) ++ return -1; ++ return 0; ++} ++ ++unsigned int i2c_get_bus_num(void) ++{ ++ /* Only support bus 0 */ ++ return 0; ++} +diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile +index 65791aa..692a2f7 100644 +--- a/drivers/mmc/Makefile ++++ b/drivers/mmc/Makefile +@@ -48,6 +48,7 @@ COBJS-$(CONFIG_SH_MMCIF) += sh_mmcif.o + COBJS-$(CONFIG_TEGRA_MMC) += tegra_mmc.o + COBJS-$(CONFIG_DWMMC) += dw_mmc.o + COBJS-$(CONFIG_EXYNOS_DWMMC) += exynos_dw_mmc.o ++COBJS-$(CONFIG_ZYNQ_SDHCI) += zynq_sdhci.o + + COBJS := $(COBJS-y) + SRCS := $(COBJS:.o=.c) +diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c +new file mode 100644 +index 0000000..340c098 +--- /dev/null ++++ b/drivers/mmc/zynq_sdhci.c +@@ -0,0 +1,40 @@ ++/* ++ * (C) Copyright 2013 Inc. ++ * ++ * Xilinx Zynq SD Host Controller Interface ++ * ++ * This program is free software; you can redistribute it and/or modify it under ++ * the terms of the GNU General Public License version 2 as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * 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 ++#include ++#include ++#include ++ ++int zynq_sdhci_init(u32 regbase, u32 max_clk, u32 min_clk) ++{ ++ struct sdhci_host *host = NULL; ++ ++ host = (struct sdhci_host *)malloc(sizeof(struct sdhci_host)); ++ if (!host) { ++ printf("zynq_sdhci_init: sdhci_host malloc fail\n"); ++ return 1; ++ } ++ ++ host->name = "zynq_sdhci"; ++ host->ioaddr = (void *) regbase; ++ host->quirks = SDHCI_QUIRK_NO_CD | SDHCI_QUIRK_WAIT_SEND_CMD; ++ host->version = sdhci_readw(host, SDHCI_HOST_VERSION); ++ ++ host->host_caps = MMC_MODE_HC; ++ ++ add_sdhci(host, max_clk, min_clk); ++ return 0; ++} +diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile +index c77c0c4..76d7168 100644 +--- a/drivers/mtd/nand/Makefile ++++ b/drivers/mtd/nand/Makefile +@@ -78,6 +78,7 @@ COBJS-$(CONFIG_NAND_SPEAR) += spr_nand.o + COBJS-$(CONFIG_TEGRA_NAND) += tegra_nand.o + COBJS-$(CONFIG_NAND_OMAP_GPMC) += omap_gpmc.o + COBJS-$(CONFIG_NAND_PLAT) += nand_plat.o ++COBJS-$(CONFIG_NAND_ZYNQ) += zynq_nand.o + + else # minimal SPL drivers + +diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c +index a2d06be..280e8f2 100644 +--- a/drivers/mtd/nand/nand_base.c ++++ b/drivers/mtd/nand/nand_base.c +@@ -786,13 +786,18 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip) + return 0x01; + } + ++/* HACK FIXME BHILL */ ++#ifndef CONFIG_ZYNQ + if (chip->dev_ready) { + if (chip->dev_ready(mtd)) + break; + } else { ++#endif + if (chip->read_byte(mtd) & NAND_STATUS_READY) + break; ++#ifndef CONFIG_ZYNQ + } ++#endif + } + #ifdef PPCHAMELON_NAND_TIMER_HACK + time_start = get_timer(0); +diff --git a/drivers/mtd/nand/zynq_nand.c b/drivers/mtd/nand/zynq_nand.c +new file mode 100644 +index 0000000..7ab5909 +--- /dev/null ++++ b/drivers/mtd/nand/zynq_nand.c +@@ -0,0 +1,1240 @@ ++/* ++ * Xilinx PS NAND Flash Controller Driver ++ * This driver is based on plat_nand.c and mxc_nand.c drivers ++ * ++ * Copyright (C) 2009 Xilinx, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify it under ++ * the terms of the GNU General Public License version 2 as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* The NAND flash driver defines */ ++#define XNANDPS_CMD_PHASE 1 /* End command valid in command phase */ ++#define XNANDPS_DATA_PHASE 2 /* End command valid in data phase */ ++#define XNANDPS_ECC_SIZE 512 /* Size of data for ECC operation */ ++ ++/* Flash memory controller operating parameters */ ++#define XNANDPS_CLR_CONFIG ((0x1 << 1) | /* Disable interrupt */ \ ++ (0x1 << 4) | /* Clear interrupt */ \ ++ (0x1 << 6)) /* Disable ECC interrupt */ ++ ++/* Assuming 50MHz clock (20ns cycle time) and 3V operation */ ++#define XNANDPS_SET_CYCLES ((0x2 << 20) | /* t_rr from nand_cycles */ \ ++ (0x2 << 17) | /* t_ar from nand_cycles */ \ ++ (0x1 << 14) | /* t_clr from nand_cycles */ \ ++ (0x3 << 11) | /* t_wp from nand_cycles */ \ ++ (0x2 << 8) | /* t_rea from nand_cycles */ \ ++ (0x5 << 4) | /* t_wc from nand_cycles */ \ ++ (0x5 << 0)) /* t_rc from nand_cycles */ ++ ++#define XNANDPS_SET_OPMODE 0x0 ++ ++#define XNANDPS_DIRECT_CMD ((0x4 << 23) | /* Chip 0 from interface 1 */ \ ++ (0x2 << 21)) /* UpdateRegs operation */ ++ ++#define XNANDPS_ECC_CONFIG ((0x1 << 2) | /* ECC available on APB */ \ ++ (0x1 << 4) | /* ECC read at end of page */ \ ++ (0x0 << 5)) /* No Jumping */ ++ ++#define XNANDPS_ECC_CMD1 ((0x80) | /* Write command */ \ ++ (0x00 << 8) | /* Read command */ \ ++ (0x30 << 16) | /* Read End command */ \ ++ (0x1 << 24)) /* Read End command calid */ ++ ++#define XNANDPS_ECC_CMD2 ((0x85) | /* Write col change cmd */ \ ++ (0x05 << 8) | /* Read col change cmd */ \ ++ (0xE0 << 16) | /* Read col change end cmd */ \ ++ (0x1 << 24)) /* Read col change ++ end cmd valid */ ++/* AXI Address definitions */ ++#define START_CMD_SHIFT 3 ++#define END_CMD_SHIFT 11 ++#define END_CMD_VALID_SHIFT 20 ++#define ADDR_CYCLES_SHIFT 21 ++#define CLEAR_CS_SHIFT 21 ++#define ECC_LAST_SHIFT 10 ++#define COMMAND_PHASE (0 << 19) ++#define DATA_PHASE (1 << 19) ++ ++#define XNANDPS_ECC_LAST (1 << ECC_LAST_SHIFT) /* Set ECC_Last */ ++#define XNANDPS_CLEAR_CS (1 << CLEAR_CS_SHIFT) /* Clear chip select */ ++ ++/* ECC block registers bit position and bit mask */ ++#define XNANDPS_ECC_BUSY (1 << 6) /* ECC block is busy */ ++#define XNANDPS_ECC_MASK 0x00FFFFFF /* ECC value mask */ ++ ++/* NAND MIO buswidth count*/ ++#define XNANDPS_MIO_NUM_NAND_8BIT 13 ++#define XNANDPS_MIO_NUM_NAND_16BIT 8 ++ ++/* NAND buswidth */ ++enum xnandps_bus_width { ++ NAND_BW_UNKNOWN = -1, ++ NAND_BW_8BIT, ++ NAND_BW_16BIT, ++}; ++ ++/* SMC register set */ ++struct xnandps_smc_regs { ++ u32 csr; /* 0x00 */ ++ u32 reserved0[2]; ++ u32 cfr; /* 0x0C */ ++ u32 dcr; /* 0x10 */ ++ u32 scr; /* 0x14 */ ++ u32 sor; /* 0x18 */ ++ u32 reserved1[249]; ++ u32 esr; /* 0x400 */ ++ u32 emcr; /* 0x404 */ ++ u32 emcmd1r; /* 0x408 */ ++ u32 emcmd2r; /* 0x40C */ ++ u32 reserved2[2]; ++ u32 eval0r; /* 0x418 */ ++}; ++ ++#define xnandps_smc_base \ ++ ((struct xnandps_smc_regs *) XPSS_CRTL_PARPORT_BASEADDR) ++ ++/* ++ * struct xnandps_command_format - Defines NAND flash command format ++ * @start_cmd: First cycle command (Start command) ++ * @end_cmd: Second cycle command (Last command) ++ * @addr_cycles: Number of address cycles required to send the address ++ * @end_cmd_valid: The second cycle command is valid for cmd or data phase ++ */ ++struct xnandps_command_format { ++ int start_cmd; ++ int end_cmd; ++ u8 addr_cycles; ++ u8 end_cmd_valid; ++}; ++ ++/* ++ * struct xnandps_info - Defines the NAND flash driver instance ++ * @parts: Pointer to the mtd_partition structure ++ * @nand_base: Virtual address of the NAND flash device ++ * @end_cmd_pending: End command is pending ++ * @end_cmd: End command ++ */ ++struct xnandps_info { ++#ifdef CONFIG_MTD_PARTITIONS ++ struct mtd_partition *parts; ++#endif ++ void __iomem *nand_base; ++ unsigned long end_cmd_pending; ++ unsigned long end_cmd; ++}; ++ ++#define NAND_CMD_GET_FEATURES 0xEE ++#define NAND_CMD_SET_FEATURES 0xEF ++#define ONDIE_ECC_FEATURE_ADDR 0x90 ++ ++/* The NAND flash operations command format */ ++static const struct xnandps_command_format xnandps_commands[] = { ++ {NAND_CMD_READ0, NAND_CMD_READSTART, 5, XNANDPS_CMD_PHASE}, ++ {NAND_CMD_RNDOUT, NAND_CMD_RNDOUTSTART, 2, XNANDPS_CMD_PHASE}, ++ {NAND_CMD_READID, NAND_CMD_NONE, 1, NAND_CMD_NONE}, ++ {NAND_CMD_STATUS, NAND_CMD_NONE, 0, NAND_CMD_NONE}, ++ {NAND_CMD_SEQIN, NAND_CMD_PAGEPROG, 5, XNANDPS_DATA_PHASE}, ++ {NAND_CMD_RNDIN, NAND_CMD_NONE, 2, NAND_CMD_NONE}, ++ {NAND_CMD_ERASE1, NAND_CMD_ERASE2, 3, XNANDPS_CMD_PHASE}, ++ {NAND_CMD_RESET, NAND_CMD_NONE, 0, NAND_CMD_NONE}, ++ {NAND_CMD_PARAM, NAND_CMD_NONE, 1, NAND_CMD_NONE}, ++ {NAND_CMD_GET_FEATURES, NAND_CMD_NONE, 1, NAND_CMD_NONE}, ++ {NAND_CMD_SET_FEATURES, NAND_CMD_NONE, 1, NAND_CMD_NONE}, ++ {NAND_CMD_NONE, NAND_CMD_NONE, 0, 0}, ++ /* Add all the flash commands supported by the flash device and Linux ++ * The cache program command is not supported by driver because driver ++ * cant differentiate between page program and cached page program from ++ * start command, these commands can be differentiated through end ++ * command, which doesn't fit in to the driver design. The cache program ++ * command is not supported by NAND subsystem also, look at 1612 line ++ * number (in nand_write_page function) of nand_base.c file. ++ * {NAND_CMD_SEQIN, NAND_CMD_CACHEDPROG, 5, XNANDPS_YES} ++ */ ++}; ++ ++/* Define default oob placement schemes for large and small page devices */ ++static struct nand_ecclayout nand_oob_16 = { ++ .eccbytes = 3, ++ .eccpos = {13, 14, 15}, ++ .oobfree = { ++ {.offset = 0, ++ . length = 12} } ++}; ++ ++static struct nand_ecclayout nand_oob_64 = { ++ .eccbytes = 12, ++ .eccpos = { ++ 52, 53, 54, 55, 56, 57, ++ 58, 59, 60, 61, 62, 63}, ++ .oobfree = { ++ {.offset = 2, ++ .length = 50} } ++}; ++ ++static struct nand_ecclayout ondie_nand_oob_64 = { ++ .eccbytes = 32, ++ ++ .eccpos = { ++ 8, 9, 10, 11, 12, 13, 14, 15, ++ 24, 25, 26, 27, 28, 29, 30, 31, ++ 40, 41, 42, 43, 44, 45, 46, 47, ++ 56, 57, 58, 59, 60, 61, 62, 63 ++ }, ++ ++ .oobfree = { ++ { .offset = 4, .length = 4 }, ++ { .offset = 20, .length = 4 }, ++ { .offset = 36, .length = 4 }, ++ { .offset = 52, .length = 4 } ++ } ++}; ++ ++/* Generic flash bbt decriptors */ ++static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' }; ++static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' }; ++ ++static struct nand_bbt_descr bbt_main_descr = { ++ .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE | ++ NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, ++ .offs = 4, ++ .len = 4, ++ .veroffs = 20, ++ .maxblocks = 4, ++ .pattern = bbt_pattern ++}; ++ ++static struct nand_bbt_descr bbt_mirror_descr = { ++ .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE | ++ NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, ++ .offs = 4, ++ .len = 4, ++ .veroffs = 20, ++ .maxblocks = 4, ++ .pattern = mirror_pattern ++}; ++ ++/* ++ * xnandps_waitfor_ecc_completion - Wait for ECC completion ++ * ++ * returns: status for command completion, -1 for Timeout ++ */ ++static int xnandps_waitfor_ecc_completion(void) ++{ ++ unsigned long timeout; ++ u32 status; ++ ++ /* Wait max 10ms */ ++ timeout = 10; ++ status = readl(&xnandps_smc_base->esr); ++ while (status & XNANDPS_ECC_BUSY) { ++ status = readl(&xnandps_smc_base->esr); ++ if (timeout == 0) ++ return -1; ++ timeout--; ++ udelay(1); ++ } ++ ++ return status; ++} ++ ++/* ++ * xnandps_init_nand_flash - Initialize NAND controller ++ * @option: Device property flags ++ * ++ * This function initializes the NAND flash interface on the NAND controller. ++ * ++ * returns: 0 on success or error value on failure ++ */ ++static int xnandps_init_nand_flash(int option) ++{ ++ u32 status; ++ ++ /* disable interrupts */ ++ writel(XNANDPS_CLR_CONFIG, &xnandps_smc_base->cfr); ++ /* Initialize the NAND interface by setting cycles and operation mode */ ++ writel(XNANDPS_SET_CYCLES, &xnandps_smc_base->scr); ++ if (option & NAND_BUSWIDTH_16) ++ writel((XNANDPS_SET_OPMODE | 0x1), &xnandps_smc_base->sor); ++ else ++ writel(XNANDPS_SET_OPMODE, &xnandps_smc_base->sor); ++ ++ writel(XNANDPS_DIRECT_CMD, &xnandps_smc_base->dcr); ++ ++ /* Wait till the ECC operation is complete */ ++ status = xnandps_waitfor_ecc_completion(); ++ if (status < 0) { ++ printf("xnandps_init_nand_flash: Timeout\n"); ++ return status; ++ } ++ ++ /* Set the command1 and command2 register */ ++ writel(XNANDPS_ECC_CMD1, &xnandps_smc_base->emcmd1r); ++ writel(XNANDPS_ECC_CMD2, &xnandps_smc_base->emcmd2r); ++ ++ return 0; ++} ++ ++/* ++ * xnandps_calculate_hwecc - Calculate Hardware ECC ++ * @mtd: Pointer to the mtd_info structure ++ * @data: Pointer to the page data ++ * @ecc_code: Pointer to the ECC buffer where ECC data needs to be stored ++ * ++ * This function retrieves the Hardware ECC data from the controller and returns ++ * ECC data back to the MTD subsystem. ++ * ++ * returns: 0 on success or error value on failure ++ */ ++static int xnandps_calculate_hwecc(struct mtd_info *mtd, const u8 *data, ++ u8 *ecc_code) ++{ ++ u32 ecc_value = 0; ++ u8 ecc_reg, ecc_byte; ++ u32 ecc_status; ++ ++ /* Wait till the ECC operation is complete */ ++ ecc_status = xnandps_waitfor_ecc_completion(); ++ if (ecc_status < 0) { ++ printf("xnandps_calculate_hwecc: Timeout\n"); ++ return ecc_status; ++ } ++ ++ for (ecc_reg = 0; ecc_reg < 4; ecc_reg++) { ++ /* Read ECC value for each block */ ++ ecc_value = readl(&xnandps_smc_base->eval0r + ecc_reg); ++ ecc_status = (ecc_value >> 24) & 0xFF; ++ /* ECC value valid */ ++ if (ecc_status & 0x40) { ++ for (ecc_byte = 0; ecc_byte < 3; ecc_byte++) { ++ /* Copy ECC bytes to MTD buffer */ ++ *ecc_code = ecc_value & 0xFF; ++ ecc_value = ecc_value >> 8; ++ ecc_code++; ++ } ++ } else { ++ debug("xnandps_calculate_hwecc: ecc status failed\n"); ++ } ++ } ++ return 0; ++} ++ ++/* ++ * onehot - onehot function ++ * @value: value to check for onehot ++ * ++ * This function checks whether a value is onehot or not. ++ * onehot is if and only if onebit is set. ++ * ++ */ ++static int onehot(unsigned short value) ++{ ++ return ((value & (value-1)) == 0); ++} ++ ++/* ++ * xnandps_correct_data - ECC correction function ++ * @mtd: Pointer to the mtd_info structure ++ * @buf: Pointer to the page data ++ * @read_ecc: Pointer to the ECC value read from spare data area ++ * @calc_ecc: Pointer to the calculated ECC value ++ * ++ * This function corrects the ECC single bit errors & detects 2-bit errors. ++ * ++ * returns: 0 if no ECC errors found ++ * 1 if single bit error found and corrected. ++ * -1 if multiple ECC errors found. ++ */ ++static int xnandps_correct_data(struct mtd_info *mtd, unsigned char *buf, ++ unsigned char *read_ecc, unsigned char *calc_ecc) ++{ ++ unsigned char bit_addr; ++ unsigned int byte_addr; ++ unsigned short ecc_odd, ecc_even; ++ unsigned short read_ecc_lower, read_ecc_upper; ++ unsigned short calc_ecc_lower, calc_ecc_upper; ++ ++ read_ecc_lower = (read_ecc[0] | (read_ecc[1] << 8)) & 0xfff; ++ read_ecc_upper = ((read_ecc[1] >> 4) | (read_ecc[2] << 4)) & 0xfff; ++ ++ calc_ecc_lower = (calc_ecc[0] | (calc_ecc[1] << 8)) & 0xfff; ++ calc_ecc_upper = ((calc_ecc[1] >> 4) | (calc_ecc[2] << 4)) & 0xfff; ++ ++ ecc_odd = read_ecc_lower ^ calc_ecc_lower; ++ ecc_even = read_ecc_upper ^ calc_ecc_upper; ++ ++ if ((ecc_odd == 0) && (ecc_even == 0)) ++ return 0; /* no error */ ++ else if (ecc_odd == (~ecc_even & 0xfff)) { ++ /* bits [11:3] of error code is byte offset */ ++ byte_addr = (ecc_odd >> 3) & 0x1ff; ++ /* bits [2:0] of error code is bit offset */ ++ bit_addr = ecc_odd & 0x7; ++ /* Toggling error bit */ ++ buf[byte_addr] ^= (1 << bit_addr); ++ return 1; ++ } else if (onehot(ecc_odd | ecc_even) == 1) { ++ return 1; /* one error in parity */ ++ } else { ++ return -1; /* Uncorrectable error */ ++ } ++} ++ ++/* ++ * xnandps_read_oob - [REPLACABLE] the most common OOB data read function ++ * @mtd: mtd info structure ++ * @chip: nand chip info structure ++ * @page: page number to read ++ * @sndcmd: flag whether to issue read command or not ++ */ ++static int xnandps_read_oob(struct mtd_info *mtd, struct nand_chip *chip, ++ int page, int sndcmd) ++{ ++ unsigned long data_width = 4; ++ unsigned long data_phase_addr = 0; ++ uint8_t *p; ++ ++ if (sndcmd) { ++ chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page); ++ sndcmd = 0; ++ } ++ ++ p = chip->oob_poi; ++ chip->read_buf(mtd, p, (mtd->oobsize - data_width)); ++ p += (mtd->oobsize - data_width); ++ ++ data_phase_addr = (unsigned long)chip->IO_ADDR_R; ++ data_phase_addr |= XNANDPS_CLEAR_CS; ++ chip->IO_ADDR_R = (void __iomem *)data_phase_addr; ++ chip->read_buf(mtd, p, data_width); ++ ++ return sndcmd; ++} ++ ++/* ++ * xnandps_write_oob - [REPLACABLE] the most common OOB data write function ++ * @mtd: mtd info structure ++ * @chip: nand chip info structure ++ * @page: page number to write ++ */ ++static int xnandps_write_oob(struct mtd_info *mtd, struct nand_chip *chip, ++ int page) ++{ ++ int status = 0; ++ const uint8_t *buf = chip->oob_poi; ++ unsigned long data_width = 4; ++ unsigned long data_phase_addr = 0; ++ ++ chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize, page); ++ ++ chip->write_buf(mtd, buf, (mtd->oobsize - data_width)); ++ buf += (mtd->oobsize - data_width); ++ ++ data_phase_addr = (unsigned long) chip->IO_ADDR_W; ++ data_phase_addr |= XNANDPS_CLEAR_CS; ++ data_phase_addr |= (1 << END_CMD_VALID_SHIFT); ++ chip->IO_ADDR_W = (void __iomem *) data_phase_addr; ++ chip->write_buf(mtd, buf, data_width); ++ ++ /* Send command to program the OOB data */ ++ chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); ++ status = chip->waitfunc(mtd, chip); ++ if (status) ++ return NAND_STATUS_FAIL; ++ ++ return status; ++} ++ ++/* ++ * xnandps_read_page_raw - [Intern] read raw page data without ecc ++ * @mtd: mtd info structure ++ * @chip: nand chip info structure ++ * @buf: buffer to store read data ++ * @page: page number to read ++ */ ++static int xnandps_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, ++ uint8_t *buf, int page) ++{ ++ unsigned long data_width = 4; ++ unsigned long data_phase_addr = 0; ++ uint8_t *p; ++ ++ chip->read_buf(mtd, buf, mtd->writesize); ++ ++ p = chip->oob_poi; ++ chip->read_buf(mtd, p, (mtd->oobsize - data_width)); ++ p += (mtd->oobsize - data_width); ++ ++ data_phase_addr = (unsigned long) chip->IO_ADDR_R; ++ data_phase_addr |= XNANDPS_CLEAR_CS; ++ chip->IO_ADDR_R = (void __iomem *) data_phase_addr; ++ ++ chip->read_buf(mtd, p, data_width); ++ return 0; ++} ++ ++static int xnandps_read_page_raw_nooob(struct mtd_info *mtd, ++ struct nand_chip *chip, uint8_t *buf, int page) ++{ ++ chip->read_buf(mtd, buf, mtd->writesize); ++ return 0; ++} ++ ++static int xnandps_read_subpage_raw(struct mtd_info *mtd, ++ struct nand_chip *chip, uint32_t data_offs, ++ uint32_t readlen, uint8_t *buf) ++{ ++ if (data_offs != 0) { ++ chip->cmdfunc(mtd, NAND_CMD_RNDOUT, data_offs, -1); ++ buf += data_offs; ++ } ++ ++ chip->read_buf(mtd, buf, readlen); ++ return 0; ++} ++ ++/* ++ * xnandps_write_page_raw - [Intern] raw page write function ++ * @mtd: mtd info structure ++ * @chip: nand chip info structure ++ * @buf: data buffer ++ */ ++static void xnandps_write_page_raw(struct mtd_info *mtd, ++ struct nand_chip *chip, const uint8_t *buf) ++{ ++ unsigned long data_width = 4; ++ unsigned long data_phase_addr = 0; ++ uint8_t *p; ++ ++ chip->write_buf(mtd, buf, mtd->writesize); ++ ++ p = chip->oob_poi; ++ chip->write_buf(mtd, p, (mtd->oobsize - data_width)); ++ p += (mtd->oobsize - data_width); ++ ++ data_phase_addr = (unsigned long) chip->IO_ADDR_W; ++ data_phase_addr |= XNANDPS_CLEAR_CS; ++ data_phase_addr |= (1 << END_CMD_VALID_SHIFT); ++ chip->IO_ADDR_W = (void __iomem *) data_phase_addr; ++ ++ chip->write_buf(mtd, p, data_width); ++} ++ ++/* ++ * nand_write_page_hwecc - Hardware ECC based page write function ++ * @mtd: Pointer to the mtd info structure ++ * @chip: Pointer to the NAND chip info structure ++ * @buf: Pointer to the data buffer ++ * ++ * This functions writes data and hardware generated ECC values in to the page. ++ */ ++static void xnandps_write_page_hwecc(struct mtd_info *mtd, ++ struct nand_chip *chip, const uint8_t *buf) ++{ ++ int i, eccsize = chip->ecc.size; ++ int eccsteps = chip->ecc.steps; ++ uint8_t *ecc_calc = chip->buffers->ecccalc; ++ const uint8_t *p = buf; ++ uint32_t *eccpos = chip->ecc.layout->eccpos; ++ unsigned long data_phase_addr = 0; ++ unsigned long data_width = 4; ++ uint8_t *oob_ptr; ++ ++ for ( ; (eccsteps - 1); eccsteps--) { ++ chip->write_buf(mtd, p, eccsize); ++ p += eccsize; ++ } ++ chip->write_buf(mtd, p, (eccsize - data_width)); ++ p += (eccsize - data_width); ++ ++ /* Set ECC Last bit to 1 */ ++ data_phase_addr = (unsigned long) chip->IO_ADDR_W; ++ data_phase_addr |= XNANDPS_ECC_LAST; ++ chip->IO_ADDR_W = (void __iomem *) data_phase_addr; ++ chip->write_buf(mtd, p, data_width); ++ ++ /* Wait for ECC to be calculated and read the error values */ ++ p = buf; ++ chip->ecc.calculate(mtd, p, &ecc_calc[0]); ++ ++ for (i = 0; i < chip->ecc.total; i++) ++ chip->oob_poi[eccpos[i]] = ~(ecc_calc[i]); ++ ++ /* Clear ECC last bit */ ++ data_phase_addr = (unsigned long)chip->IO_ADDR_W; ++ data_phase_addr &= ~XNANDPS_ECC_LAST; ++ chip->IO_ADDR_W = (void __iomem *)data_phase_addr; ++ ++ /* Write the spare area with ECC bytes */ ++ oob_ptr = chip->oob_poi; ++ chip->write_buf(mtd, oob_ptr, (mtd->oobsize - data_width)); ++ ++ data_phase_addr = (unsigned long)chip->IO_ADDR_W; ++ data_phase_addr |= XNANDPS_CLEAR_CS; ++ data_phase_addr |= (1 << END_CMD_VALID_SHIFT); ++ chip->IO_ADDR_W = (void __iomem *)data_phase_addr; ++ oob_ptr += (mtd->oobsize - data_width); ++ chip->write_buf(mtd, oob_ptr, data_width); ++} ++ ++/* ++ * xnandps_write_page_swecc - [REPLACABLE] software ecc based page ++ * write function ++ * @mtd: mtd info structure ++ * @chip: nand chip info structure ++ * @buf: data buffer ++ */ ++static void xnandps_write_page_swecc(struct mtd_info *mtd, ++ struct nand_chip *chip, const uint8_t *buf) ++{ ++ int i, eccsize = chip->ecc.size; ++ int eccbytes = chip->ecc.bytes; ++ int eccsteps = chip->ecc.steps; ++ uint8_t *ecc_calc = chip->buffers->ecccalc; ++ const uint8_t *p = buf; ++ uint32_t *eccpos = chip->ecc.layout->eccpos; ++ ++ /* Software ecc calculation */ ++ for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) ++ chip->ecc.calculate(mtd, p, &ecc_calc[i]); ++ ++ for (i = 0; i < chip->ecc.total; i++) ++ chip->oob_poi[eccpos[i]] = ecc_calc[i]; ++ ++ chip->ecc.write_page_raw(mtd, chip, buf); ++} ++ ++/* ++ * nand_read_page_hwecc - Hardware ECC based page read function ++ * @mtd: Pointer to the mtd info structure ++ * @chip: Pointer to the NAND chip info structure ++ * @buf: Pointer to the buffer to store read data ++ * @page: page number to read ++ * ++ * This functions reads data and checks the data integrity by comparing hardware ++ * generated ECC values and read ECC values from spare area. ++ * ++ * returns: 0 always and updates ECC operation status in to MTD structure ++ */ ++static int xnandps_read_page_hwecc(struct mtd_info *mtd, ++ struct nand_chip *chip, uint8_t *buf, int page) ++{ ++ int i, stat, eccsize = chip->ecc.size; ++ int eccbytes = chip->ecc.bytes; ++ int eccsteps = chip->ecc.steps; ++ uint8_t *p = buf; ++ uint8_t *ecc_calc = chip->buffers->ecccalc; ++ uint8_t *ecc_code = chip->buffers->ecccode; ++ uint32_t *eccpos = chip->ecc.layout->eccpos; ++ unsigned long data_phase_addr = 0; ++ unsigned long data_width = 4; ++ uint8_t *oob_ptr; ++ ++ for ( ; (eccsteps - 1); eccsteps--) { ++ chip->read_buf(mtd, p, eccsize); ++ p += eccsize; ++ } ++ chip->read_buf(mtd, p, (eccsize - data_width)); ++ p += (eccsize - data_width); ++ ++ /* Set ECC Last bit to 1 */ ++ data_phase_addr = (unsigned long)chip->IO_ADDR_R; ++ data_phase_addr |= XNANDPS_ECC_LAST; ++ chip->IO_ADDR_R = (void __iomem *)data_phase_addr; ++ chip->read_buf(mtd, p, data_width); ++ ++ /* Read the calculated ECC value */ ++ p = buf; ++ chip->ecc.calculate(mtd, p, &ecc_calc[0]); ++ ++ /* Clear ECC last bit */ ++ data_phase_addr = (unsigned long)chip->IO_ADDR_R; ++ data_phase_addr &= ~XNANDPS_ECC_LAST; ++ chip->IO_ADDR_R = (void __iomem *)data_phase_addr; ++ ++ /* Read the stored ECC value */ ++ oob_ptr = chip->oob_poi; ++ chip->read_buf(mtd, oob_ptr, (mtd->oobsize - data_width)); ++ ++ /* de-assert chip select */ ++ data_phase_addr = (unsigned long)chip->IO_ADDR_R; ++ data_phase_addr |= XNANDPS_CLEAR_CS; ++ chip->IO_ADDR_R = (void __iomem *)data_phase_addr; ++ ++ oob_ptr += (mtd->oobsize - data_width); ++ chip->read_buf(mtd, oob_ptr, data_width); ++ ++ for (i = 0; i < chip->ecc.total; i++) ++ ecc_code[i] = ~(chip->oob_poi[eccpos[i]]); ++ ++ eccsteps = chip->ecc.steps; ++ p = buf; ++ ++ /* Check ECC error for all blocks and correct if it is correctable */ ++ for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { ++ stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]); ++ if (stat < 0) ++ mtd->ecc_stats.failed++; ++ else ++ mtd->ecc_stats.corrected += stat; ++ } ++ return 0; ++} ++ ++/* ++ * xnandps_read_page_swecc - [REPLACABLE] software ecc based page ++ * read function ++ * @mtd: mtd info structure ++ * @chip: nand chip info structure ++ * @buf: buffer to store read data ++ * @page: page number to read ++ */ ++static int xnandps_read_page_swecc(struct mtd_info *mtd, ++ struct nand_chip *chip, uint8_t *buf, int page) ++{ ++ int i, eccsize = chip->ecc.size; ++ int eccbytes = chip->ecc.bytes; ++ int eccsteps = chip->ecc.steps; ++ uint8_t *p = buf; ++ uint8_t *ecc_calc = chip->buffers->ecccalc; ++ uint8_t *ecc_code = chip->buffers->ecccode; ++ uint32_t *eccpos = chip->ecc.layout->eccpos; ++ ++ chip->ecc.read_page_raw(mtd, chip, buf, page); ++ ++ for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) ++ chip->ecc.calculate(mtd, p, &ecc_calc[i]); ++ ++ for (i = 0; i < chip->ecc.total; i++) ++ ecc_code[i] = chip->oob_poi[eccpos[i]]; ++ ++ eccsteps = chip->ecc.steps; ++ p = buf; ++ ++ for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { ++ int stat; ++ ++ stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]); ++ if (stat < 0) ++ mtd->ecc_stats.failed++; ++ else ++ mtd->ecc_stats.corrected += stat; ++ } ++ return 0; ++} ++ ++/* ++ * xnandps_select_chip - Select the flash device ++ * @mtd: Pointer to the mtd_info structure ++ * @chip: Chip number to be selected ++ * ++ * This function is empty as the NAND controller handles chip select line ++ * internally based on the chip address passed in command and data phase. ++ */ ++static void xnandps_select_chip(struct mtd_info *mtd, int chip) ++{ ++ return; ++} ++ ++/* ++ * xnandps_cmd_function - Send command to NAND device ++ * @mtd: Pointer to the mtd_info structure ++ * @command: The command to be sent to the flash device ++ * @column: The column address for this command, -1 if none ++ * @page_addr: The page address for this command, -1 if none ++ */ ++static void xnandps_cmd_function(struct mtd_info *mtd, unsigned int command, ++ int column, int page_addr) ++{ ++ struct nand_chip *chip = mtd->priv; ++ const struct xnandps_command_format *curr_cmd = NULL; ++ struct xnandps_info *xnand; ++ void *cmd_addr; ++ unsigned long cmd_data = 0; ++ unsigned long cmd_phase_addr = 0; ++ unsigned long data_phase_addr = 0; ++ unsigned long end_cmd = 0; ++ unsigned long end_cmd_valid = 0; ++ unsigned long i; ++ ++ xnand = (struct xnandps_info *)chip->priv; ++ if (xnand->end_cmd_pending) { ++ /* Check for end command if this command request is same as the ++ * pending command then return ++ */ ++ if (xnand->end_cmd == command) { ++ xnand->end_cmd = 0; ++ xnand->end_cmd_pending = 0; ++ return; ++ } ++ } ++ ++ /* Emulate NAND_CMD_READOOB for large page device */ ++ if ((mtd->writesize > XNANDPS_ECC_SIZE) && ++ (command == NAND_CMD_READOOB)) { ++ column += mtd->writesize; ++ command = NAND_CMD_READ0; ++ } ++ ++ /* Get the command format */ ++ for (i = 0; (xnandps_commands[i].start_cmd != NAND_CMD_NONE || ++ xnandps_commands[i].end_cmd != NAND_CMD_NONE); i++) { ++ if (command == xnandps_commands[i].start_cmd) ++ curr_cmd = &xnandps_commands[i]; ++ } ++ if (curr_cmd == NULL) ++ return; ++ ++ /* Clear interrupt */ ++ writel((1 << 4), &xnandps_smc_base->cfr); ++ ++ /* Get the command phase address */ ++ if (curr_cmd->end_cmd_valid == XNANDPS_CMD_PHASE) ++ end_cmd_valid = 1; ++ ++ if (curr_cmd->end_cmd == NAND_CMD_NONE) ++ end_cmd = 0x0; ++ else ++ end_cmd = curr_cmd->end_cmd; ++ ++ cmd_phase_addr = (unsigned long)xnand->nand_base | ++ (curr_cmd->addr_cycles << ADDR_CYCLES_SHIFT) | ++ (end_cmd_valid << END_CMD_VALID_SHIFT) | ++ (COMMAND_PHASE) | ++ (end_cmd << END_CMD_SHIFT) | ++ (curr_cmd->start_cmd << START_CMD_SHIFT); ++ ++ cmd_addr = (void __iomem *)cmd_phase_addr; ++ ++ /* Get the data phase address */ ++ end_cmd_valid = 0; ++ ++ data_phase_addr = (unsigned long)xnand->nand_base | ++ (0x0 << CLEAR_CS_SHIFT) | ++ (end_cmd_valid << END_CMD_VALID_SHIFT) | ++ (DATA_PHASE) | ++ (end_cmd << END_CMD_SHIFT) | ++ (0x0 << ECC_LAST_SHIFT); ++ ++ chip->IO_ADDR_R = (void __iomem *)data_phase_addr; ++ chip->IO_ADDR_W = chip->IO_ADDR_R; ++ ++ /* Command phase AXI Read & Write */ ++ if (column != -1 && page_addr != -1) { ++ /* Adjust columns for 16 bit bus width */ ++ if (chip->options & NAND_BUSWIDTH_16) ++ column >>= 1; ++ cmd_data = column; ++ if (mtd->writesize > XNANDPS_ECC_SIZE) { ++ cmd_data |= page_addr << 16; ++ /* Another address cycle for devices > 128MiB */ ++ if (chip->chipsize > (128 << 20)) { ++ writel(cmd_data, cmd_addr); ++ cmd_data = (page_addr >> 16); ++ } ++ } else ++ cmd_data |= page_addr << 8; ++ } ++ /* Erase */ ++ else if (page_addr != -1) ++ cmd_data = page_addr; ++ /* Change read/write column, read id etc */ ++ else if (column != -1) { ++ /* Adjust columns for 16 bit bus width */ ++ if ((chip->options & NAND_BUSWIDTH_16) && ++ ((command == NAND_CMD_READ0) || ++ (command == NAND_CMD_SEQIN) || ++ (command == NAND_CMD_RNDOUT) || ++ (command == NAND_CMD_RNDIN))) ++ column >>= 1; ++ cmd_data = column; ++ } else ++ ; ++ ++ writel(cmd_data, cmd_addr); ++ ++ if (curr_cmd->end_cmd_valid) { ++ xnand->end_cmd = curr_cmd->end_cmd; ++ xnand->end_cmd_pending = 1; ++ } ++ ++ ndelay(100); ++ ++ if ((command == NAND_CMD_READ0) || ++ (command == NAND_CMD_ERASE1) || ++ (command == NAND_CMD_RESET) || ++ (command == NAND_CMD_PARAM) || ++ (command == NAND_CMD_GET_FEATURES)) { ++ while (!chip->dev_ready(mtd)) ++ ; ++ return; ++ } ++} ++ ++/* ++ * xnandps_read_buf - read chip data into buffer ++ * @mtd: MTD device structure ++ * @buf: buffer to store date ++ * @len: number of bytes to read ++ */ ++static void xnandps_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) ++{ ++ struct nand_chip *chip = mtd->priv; ++ const u32 *nand = chip->IO_ADDR_R; ++ ++ /* Make sure that buf is 32 bit aligned */ ++ if (((int)buf & 0x3) != 0) { ++ if (((int)buf & 0x1) != 0) { ++ if (len) { ++ *buf = readb(nand); ++ buf += 1; ++ len--; ++ } ++ } ++ ++ if (((int)buf & 0x3) != 0) { ++ if (len >= 2) { ++ *(u16 *)buf = readw(nand); ++ buf += 2; ++ len -= 2; ++ } ++ } ++ } ++ ++ /* copy aligned data */ ++ while (len >= 4) { ++ *(u32 *)buf = readl(nand); ++ buf += 4; ++ len -= 4; ++ } ++ ++ /* mop up any remaining bytes */ ++ if (len) { ++ if (len >= 2) { ++ *(u16 *)buf = readw(nand); ++ buf += 2; ++ len -= 2; ++ } ++ ++ if (len) ++ *buf = readb(nand); ++ } ++} ++ ++/* ++ * xnandps_write_buf - write buffer to chip ++ * @mtd: MTD device structure ++ * @buf: data buffer ++ * @len: number of bytes to write ++ */ ++static void xnandps_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) ++{ ++ struct nand_chip *chip = mtd->priv; ++ const u32 *nand = chip->IO_ADDR_W; ++ ++ /* Make sure that buf is 32 bit aligned */ ++ if (((int)buf & 0x3) != 0) { ++ if (((int)buf & 0x1) != 0) { ++ if (len) { ++ writeb(*buf, nand); ++ buf += 1; ++ len--; ++ } ++ } ++ ++ if (((int)buf & 0x3) != 0) { ++ if (len >= 2) { ++ writew(*(u16 *)buf, nand); ++ buf += 2; ++ len -= 2; ++ } ++ } ++ } ++ ++ /* copy aligned data */ ++ while (len >= 4) { ++ writel(*(u32 *)buf, nand); ++ buf += 4; ++ len -= 4; ++ } ++ ++ /* mop up any remaining bytes */ ++ if (len) { ++ if (len >= 2) { ++ writew(*(u16 *)buf, nand); ++ buf += 2; ++ len -= 2; ++ } ++ ++ if (len) ++ writeb(*buf, nand); ++ } ++} ++ ++/* ++ * xnandps_device_ready - Check device ready/busy line ++ * @mtd: Pointer to the mtd_info structure ++ * ++ * returns: 0 on busy or 1 on ready state ++ */ ++static int xnandps_device_ready(struct mtd_info *mtd) ++{ ++ /* Check the raw_int_status1 bit */ ++ if ((readl(&xnandps_smc_base->csr)) & 0x40) { ++ /* Clear the interrupt condition */ ++ writel((1<<4), &xnandps_smc_base->cfr); ++ return 1; ++ } ++ return 0; ++} ++ ++/* ++ * xnandps_check_is_16bit_bw_flash - checking for 16 or 8 bit buswidth nand ++ * ++ * This function will check nand buswidth whether it supports 16 or 8 bit ++ * based on the MIO configuration done by FSBL. ++ * ++ * User needs to correctly configure the MIO's based on the ++ * buswidth supported by the nand flash which is present on the board. ++ * ++ * function will return -1, if there is no MIO configuration for ++ * nand flash. ++ */ ++static int xnandps_check_is_16bit_bw_flash(void) ++{ ++ int is_16bit_bw = NAND_BW_UNKNOWN; ++ int mio_num_8bit = 0, mio_num_16bit = 0; ++ ++ mio_num_8bit = zynq_slcr_get_mio_pin_status("nand8"); ++ if (mio_num_8bit == XNANDPS_MIO_NUM_NAND_8BIT) ++ is_16bit_bw = NAND_BW_8BIT; ++ ++ mio_num_16bit = zynq_slcr_get_mio_pin_status("nand16"); ++ if ((mio_num_8bit == XNANDPS_MIO_NUM_NAND_8BIT) && ++ (mio_num_16bit == XNANDPS_MIO_NUM_NAND_16BIT)) ++ is_16bit_bw = NAND_BW_16BIT; ++ ++ return is_16bit_bw; ++} ++ ++int zynq_nand_init(struct nand_chip *nand_chip) ++{ ++ struct xnandps_info *xnand; ++ struct mtd_info *mtd; ++ unsigned long ecc_page_size; ++ int err = -1; ++ u8 maf_id, dev_id, i; ++ u8 get_feature[4]; ++ u8 set_feature[4] = {0x08, 0x00, 0x00, 0x00}; ++ unsigned long ecc_cfg; ++ int ondie_ecc_enabled = 0; ++ int is_16bit_bw; ++ ++ xnand = malloc(sizeof(struct xnandps_info)); ++ memset(xnand, 0, sizeof(struct xnandps_info)); ++ if (!xnand) { ++ printf("zynq_nand_init: failed to allocate\n"); ++ goto free; ++ } ++ ++ xnand->nand_base = (void *)XPSS_NAND_BASEADDR; ++ mtd = &nand_info[0]; ++ ++ nand_chip->priv = xnand; ++ mtd->priv = nand_chip; ++ ++ /* Set address of NAND IO lines */ ++ nand_chip->IO_ADDR_R = xnand->nand_base; ++ nand_chip->IO_ADDR_W = xnand->nand_base; ++ ++ /* Set the driver entry points for MTD */ ++ nand_chip->cmdfunc = xnandps_cmd_function; ++ nand_chip->dev_ready = xnandps_device_ready; ++ nand_chip->select_chip = xnandps_select_chip; ++ ++ /* If we don't set this delay driver sets 20us by default */ ++ nand_chip->chip_delay = 30; ++ ++ /* Buffer read/write routines */ ++ nand_chip->read_buf = xnandps_read_buf; ++ nand_chip->write_buf = xnandps_write_buf; ++ ++ /* Check the NAND buswidth */ ++ is_16bit_bw = xnandps_check_is_16bit_bw_flash(); ++ if (is_16bit_bw == NAND_BW_UNKNOWN) { ++ printf("zynq_nand_init: Unable detect NAND based on" ++ " MIO settings\n"); ++ goto free; ++ } else if (is_16bit_bw == NAND_BW_8BIT) ++ nand_chip->options = NAND_NO_AUTOINCR | NAND_USE_FLASH_BBT; ++ else if (is_16bit_bw == NAND_BW_16BIT) ++ nand_chip->options = NAND_BUSWIDTH_16; ++ ++ /* Initialize the NAND flash interface on NAND controller */ ++ if (xnandps_init_nand_flash(nand_chip->options) < 0) { ++ printf("zynq_nand_init: nand flash init failed\n"); ++ goto free; ++ } ++ ++ /* first scan to find the device and get the page size */ ++ if (nand_scan_ident(mtd, 1, NULL)) { ++ printf("zynq_nand_init: nand_scan_ident failed\n"); ++ goto fail; ++ } ++ ++ /* Send the command for reading device ID */ ++ nand_chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); ++ nand_chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); ++ ++ /* Read manufacturer and device IDs */ ++ maf_id = nand_chip->read_byte(mtd); ++ dev_id = nand_chip->read_byte(mtd); ++ ++ if ((maf_id == 0x2c) && ((dev_id == 0xf1) || ++ (dev_id == 0xa1) || (dev_id == 0xb1) || ++ (dev_id == 0xaa) || (dev_id == 0xba) || ++ (dev_id == 0xda) || (dev_id == 0xca) || ++ (dev_id == 0xac) || (dev_id == 0xbc) || ++ (dev_id == 0xdc) || (dev_id == 0xcc) || ++ (dev_id == 0xa3) || (dev_id == 0xb3) || ++ (dev_id == 0xd3) || (dev_id == 0xc3))) { ++ nand_chip->cmdfunc(mtd, NAND_CMD_SET_FEATURES, ++ ONDIE_ECC_FEATURE_ADDR, -1); ++ ++ for (i = 0; i < 4; i++) ++ writeb(set_feature[i], nand_chip->IO_ADDR_W); ++ ++ /* wait for 1us after writing data with SET_FEATURES command */ ++ ndelay(1000); ++ ++ nand_chip->cmdfunc(mtd, NAND_CMD_GET_FEATURES, ++ ONDIE_ECC_FEATURE_ADDR, -1); ++ nand_chip->read_buf(mtd, get_feature, 4); ++ ++ if (get_feature[0] & 0x08) { ++ debug("zynq_nand_init: OnDie ECC flash\n"); ++ ondie_ecc_enabled = 1; ++ } else ++ printf("zynq_nand_init: Unable to detect OnDie ECC\n"); ++ } ++ ++ if (ondie_ecc_enabled) { ++ /* bypass the controller ECC block */ ++ ecc_cfg = readl(&xnandps_smc_base->emcr); ++ ecc_cfg &= ~0xc; ++ writel(ecc_cfg, &xnandps_smc_base->emcr); ++ ++ /* The software ECC routines won't work ++ * with the SMC controller ++ */ ++ nand_chip->ecc.mode = NAND_ECC_HW; ++ nand_chip->ecc.read_page = xnandps_read_page_raw_nooob; ++ nand_chip->ecc.read_subpage = xnandps_read_subpage_raw; ++ nand_chip->ecc.write_page = xnandps_write_page_raw; ++ nand_chip->ecc.read_page_raw = xnandps_read_page_raw; ++ nand_chip->ecc.write_page_raw = xnandps_write_page_raw; ++ nand_chip->ecc.read_oob = xnandps_read_oob; ++ nand_chip->ecc.write_oob = xnandps_write_oob; ++ nand_chip->ecc.size = mtd->writesize; ++ nand_chip->ecc.bytes = 0; ++ ++ /* NAND with on-die ECC supports subpage reads */ ++ nand_chip->options |= NAND_SUBPAGE_READ; ++ ++ /* On-Die ECC spare bytes offset 8 is used for ECC codes */ ++ if (ondie_ecc_enabled) { ++ nand_chip->ecc.layout = &ondie_nand_oob_64; ++ /* Use the BBT pattern descriptors */ ++ nand_chip->bbt_td = &bbt_main_descr; ++ nand_chip->bbt_md = &bbt_mirror_descr; ++ } ++ } else { ++ /* Hardware ECC generates 3 bytes ECC code for each 512 bytes */ ++ nand_chip->ecc.mode = NAND_ECC_HW; ++ nand_chip->ecc.size = XNANDPS_ECC_SIZE; ++ nand_chip->ecc.bytes = 3; ++ nand_chip->ecc.calculate = xnandps_calculate_hwecc; ++ nand_chip->ecc.correct = xnandps_correct_data; ++ nand_chip->ecc.hwctl = NULL; ++ nand_chip->ecc.read_page = xnandps_read_page_hwecc; ++ nand_chip->ecc.write_page = xnandps_write_page_hwecc; ++ nand_chip->ecc.read_page_raw = xnandps_read_page_raw; ++ nand_chip->ecc.write_page_raw = xnandps_write_page_raw; ++ nand_chip->ecc.read_oob = xnandps_read_oob; ++ nand_chip->ecc.write_oob = xnandps_write_oob; ++ ++ switch (mtd->writesize) { ++ case 512: ++ ecc_page_size = 0x1; ++ /* Set the ECC memory config register */ ++ writel((XNANDPS_ECC_CONFIG | ecc_page_size), ++ &xnandps_smc_base->emcr); ++ break; ++ case 1024: ++ ecc_page_size = 0x2; ++ /* Set the ECC memory config register */ ++ writel((XNANDPS_ECC_CONFIG | ecc_page_size), ++ &xnandps_smc_base->emcr); ++ break; ++ case 2048: ++ ecc_page_size = 0x3; ++ /* Set the ECC memory config register */ ++ writel((XNANDPS_ECC_CONFIG | ecc_page_size), ++ &xnandps_smc_base->emcr); ++ break; ++ default: ++ /* The software ECC routines won't work with ++ * the SMC controller ++ */ ++ nand_chip->ecc.mode = NAND_ECC_HW; ++ nand_chip->ecc.calculate = nand_calculate_ecc; ++ nand_chip->ecc.correct = nand_correct_data; ++ nand_chip->ecc.read_page = xnandps_read_page_swecc; ++ /* nand_chip->ecc.read_subpage = nand_read_subpage; */ ++ nand_chip->ecc.write_page = xnandps_write_page_swecc; ++ nand_chip->ecc.read_page_raw = xnandps_read_page_raw; ++ nand_chip->ecc.write_page_raw = xnandps_write_page_raw; ++ nand_chip->ecc.read_oob = xnandps_read_oob; ++ nand_chip->ecc.write_oob = xnandps_write_oob; ++ nand_chip->ecc.size = 256; ++ nand_chip->ecc.bytes = 3; ++ break; ++ } ++ ++ if (mtd->oobsize == 16) ++ nand_chip->ecc.layout = &nand_oob_16; ++ else if (mtd->oobsize == 64) ++ nand_chip->ecc.layout = &nand_oob_64; ++ else ++ ; ++ } ++ ++ /* second phase scan */ ++ if (nand_scan_tail(mtd)) { ++ printf("zynq_nand_init: nand_scan_tailfailed\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ nand_release(mtd); ++free: ++ kfree(xnand); ++ return err; ++} +diff --git a/drivers/mtd/spi/spansion.c b/drivers/mtd/spi/spansion.c +index 32b76e0..4f19ee0 100644 +--- a/drivers/mtd/spi/spansion.c ++++ b/drivers/mtd/spi/spansion.c +@@ -31,6 +31,12 @@ + + #include "spi_flash_internal.h" + ++/* S25FLxx-specific commands */ ++#define CMD_S25FLXX_SE 0xd8 /* Sector Erase */ ++#define CMD_S25FLXX_BE 0xc7 /* Bulk Erase */ ++#define CMD_S25FLXX_DP 0xb9 /* Deep Power-down */ ++#define CMD_S25FLXX_RES 0xab /* Release from DP, and Read Signature */ ++ + struct spansion_spi_flash_params { + u16 idcode1; + u16 idcode2; +@@ -97,7 +103,7 @@ static const struct spansion_spi_flash_params spansion_spi_flash_table[] = { + .name = "S25FL129P_64K", + }, + { +- .idcode1 = 0x2019, ++ .idcode1 = 0x0219, + .idcode2 = 0x4d01, + .pages_per_sector = 256, + .nr_sectors = 512, +@@ -142,7 +148,15 @@ struct spi_flash *spi_flash_probe_spansion(struct spi_slave *spi, u8 *idcode) + flash->read = spi_flash_cmd_read_fast; + flash->page_size = 256; + flash->sector_size = 256 * params->pages_per_sector; +- flash->size = flash->sector_size * params->nr_sectors; ++ ++ /* address width is 4 for dual and 3 for single qspi */ ++ if (flash->spi->is_dual == 1) { ++ flash->addr_width = 4; ++ flash->size = flash->sector_size * (2 * params->nr_sectors); ++ } else { ++ flash->addr_width = 3; ++ flash->size = flash->sector_size * params->nr_sectors; ++ } + + return flash; + } +diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c +index 00aece9..44e2b61 100644 +--- a/drivers/mtd/spi/spi_flash.c ++++ b/drivers/mtd/spi/spi_flash.c +@@ -15,12 +15,44 @@ + + #include "spi_flash_internal.h" + +-static void spi_flash_addr(u32 addr, u8 *cmd) ++static void spi_flash_addr(struct spi_flash *flash, ++ unsigned long page_addr, unsigned long byte_addr, u8 *cmd) + { + /* cmd[0] is actual command */ +- cmd[1] = addr >> 16; +- cmd[2] = addr >> 8; +- cmd[3] = addr >> 0; ++ if (flash->addr_width == 4) { ++ cmd[1] = page_addr >> 16; ++ cmd[2] = page_addr >> 8; ++ cmd[3] = page_addr; ++ cmd[4] = byte_addr; ++ } else { ++ cmd[1] = page_addr >> 8; ++ cmd[2] = page_addr; ++ cmd[3] = byte_addr; ++ } ++} ++ ++static int spi_flash_check_bankaddr_access(struct spi_flash *flash, u32 *offset) ++{ ++ int ret; ++ ++ if (*offset >= 0x1000000) { ++ ret = spi_flash_bankaddr_access(flash, STATUS_BANKADDR_ENABLE); ++ if (ret) { ++ debug("SF: fail to %s bank addr bit\n", ++ STATUS_BANKADDR_ENABLE ? "set" : "reset"); ++ return ret; ++ } ++ *offset -= 0x1000000; ++ } else { ++ ret = spi_flash_bankaddr_access(flash, STATUS_BANKADDR_DISABLE); ++ if (ret) { ++ debug("SF: fail to %s bank addr bit\n", ++ STATUS_BANKADDR_DISABLE ? "set" : "reset"); ++ return ret; ++ } ++ } ++ ++ return ret; + } + + static int spi_flash_read_write(struct spi_slave *spi, +@@ -71,7 +103,15 @@ int spi_flash_cmd_write_multi(struct spi_flash *flash, u32 offset, + unsigned long page_addr, byte_addr, page_size; + size_t chunk_len, actual; + int ret; +- u8 cmd[4]; ++ u8 cmd[flash->addr_width+1]; ++ ++ if ((flash->size > 0x1000000) && (flash->addr_width == 3)) { ++ ret = spi_flash_check_bankaddr_access(flash, &offset); ++ if (ret) { ++ debug("SF: fail to acess bank_addr\n"); ++ return ret; ++ } ++ } + + page_size = flash->page_size; + page_addr = offset / page_size; +@@ -87,12 +127,11 @@ int spi_flash_cmd_write_multi(struct spi_flash *flash, u32 offset, + for (actual = 0; actual < len; actual += chunk_len) { + chunk_len = min(len - actual, page_size - byte_addr); + +- cmd[1] = page_addr >> 8; +- cmd[2] = page_addr; +- cmd[3] = byte_addr; ++ spi_flash_addr(flash, page_addr, byte_addr, cmd); + +- debug("PP: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %zu\n", +- buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len); ++ debug("PP: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x0x%02x } \ ++ chunk_len = %zu\n", buf + actual, cmd[0], cmd[1], ++ cmd[2], cmd[3], cmd[4], chunk_len); + + ret = spi_flash_cmd_write_enable(flash); + if (ret < 0) { +@@ -100,7 +139,7 @@ int spi_flash_cmd_write_multi(struct spi_flash *flash, u32 offset, + break; + } + +- ret = spi_flash_cmd_write(flash->spi, cmd, 4, ++ ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd), + buf + actual, chunk_len); + if (ret < 0) { + debug("SF: write failed\n"); +@@ -115,7 +154,7 @@ int spi_flash_cmd_write_multi(struct spi_flash *flash, u32 offset, + byte_addr = 0; + } + +- debug("SF: program %s %zu bytes @ %#x\n", ++ printf("SF: program %s %zu bytes @ %#x\n", + ret ? "failure" : "success", len, offset); + + spi_release_bus(flash->spi); +@@ -138,11 +177,27 @@ int spi_flash_read_common(struct spi_flash *flash, const u8 *cmd, + int spi_flash_cmd_read_fast(struct spi_flash *flash, u32 offset, + size_t len, void *data) + { +- u8 cmd[5]; ++ unsigned long page_addr; ++ unsigned long page_size; ++ unsigned long byte_addr; ++ u8 cmd[flash->addr_width+2]; ++ int ret; ++ ++ if ((flash->size > 0x1000000) && (flash->addr_width == 3)) { ++ ret = spi_flash_check_bankaddr_access(flash, &offset); ++ if (ret) { ++ debug("SF: fail to acess bank_addr\n"); ++ return ret; ++ } ++ } ++ ++ page_size = flash->page_size; ++ page_addr = offset / page_size; ++ byte_addr = offset % page_size; + + cmd[0] = CMD_READ_ARRAY_FAST; +- spi_flash_addr(offset, cmd); +- cmd[4] = 0x00; ++ spi_flash_addr(flash, page_addr, byte_addr, cmd); ++ cmd[sizeof(cmd)-1] = 0x00; + + return spi_flash_read_common(flash, cmd, sizeof(cmd), data, len); + } +@@ -194,7 +249,16 @@ int spi_flash_cmd_erase(struct spi_flash *flash, u32 offset, size_t len) + { + u32 start, end, erase_size; + int ret; +- u8 cmd[4]; ++ unsigned long page_addr; ++ u8 cmd[flash->addr_width+1]; ++ ++ if ((flash->size > 0x1000000) && (flash->addr_width == 3)) { ++ ret = spi_flash_check_bankaddr_access(flash, &offset); ++ if (ret) { ++ debug("SF: fail to acess bank_addr\n"); ++ return ret; ++ } ++ } + + erase_size = flash->sector_size; + if (offset % erase_size || len % erase_size) { +@@ -216,11 +280,12 @@ int spi_flash_cmd_erase(struct spi_flash *flash, u32 offset, size_t len) + end = start + len; + + while (offset < end) { +- spi_flash_addr(offset, cmd); ++ page_addr = offset / flash->page_size; ++ spi_flash_addr(flash, page_addr, 0, cmd); + offset += erase_size; + +- debug("SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1], +- cmd[2], cmd[3], offset); ++ debug("SF: erase %2x %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1], ++ cmd[2], cmd[3], cmd[4], offset); + + ret = spi_flash_cmd_write_enable(flash); + if (ret) +@@ -235,7 +300,7 @@ int spi_flash_cmd_erase(struct spi_flash *flash, u32 offset, size_t len) + goto out; + } + +- debug("SF: Successfully erased %zu bytes @ %#x\n", len, start); ++ printf("SF: Successfully erased %zu bytes @ %#x\n", len, start); + + out: + spi_release_bus(flash->spi); +@@ -269,6 +334,73 @@ int spi_flash_cmd_write_status(struct spi_flash *flash, u8 sr) + return 0; + } + ++int spi_flash_cmd_bankaddr_write(struct spi_flash *flash, u8 ear) ++{ ++ u8 cmd; ++ int ret; ++ ++ ret = spi_flash_cmd_write_enable(flash); ++ if (ret < 0) { ++ debug("SF: enabling write failed\n"); ++ return ret; ++ } ++ ++ cmd = CMD_BANKADDR_BRWR; ++ ret = spi_flash_cmd_write(flash->spi, &cmd, 1, &ear, 1); ++ if (ret) { ++ debug("SF: fail to write bank addr register\n"); ++ return ret; ++ } ++ ++ ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT); ++ if (ret < 0) { ++ debug("SF: write config register timed out\n"); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++int spi_flash_cmd_bankaddr_read(struct spi_flash *flash, void *data) ++{ ++ u8 cmd; ++ ++ cmd = CMD_BANKADDR_BRRD; ++ return spi_flash_read_common(flash, &cmd, 1, data, 1); ++} ++ ++int spi_flash_bankaddr_access(struct spi_flash *flash, u8 status) ++{ ++ int ret, pass; ++ u8 data = 0, write_done = 0; ++ ++ for (pass = 0; pass < 2; pass++) { ++ ret = spi_flash_cmd_bankaddr_read(flash, (void *)&data); ++ if (ret < 0) { ++ debug("SF: fail to read bank addr register\n"); ++ return ret; ++ } ++ ++ if ((data != status) & !write_done) { ++ debug("SF: need to %s bank addr bit\n", ++ status ? "set" : "reset"); ++ ++ write_done = 1; ++ ret = spi_flash_cmd_bankaddr_write(flash, status); ++ if (ret < 0) { ++ debug("SF: fail to write bank addr bit\n"); ++ return ret; ++ } ++ } else { ++ debug("SF: bank addr bit is %s.\n", ++ status ? "set" : "reset"); ++ return ret; ++ } ++ } ++ ++ return -1; ++} ++ + /* + * The following table holds all device probe functions + * +diff --git a/drivers/mtd/spi/spi_flash_internal.h b/drivers/mtd/spi/spi_flash_internal.h +index 141cfa8..dc411e5 100644 +--- a/drivers/mtd/spi/spi_flash_internal.h ++++ b/drivers/mtd/spi/spi_flash_internal.h +@@ -28,8 +28,14 @@ + #define CMD_ERASE_64K 0xd8 + #define CMD_ERASE_CHIP 0xc7 + ++/* Bank addr acess commands */ ++#define CMD_BANKADDR_BRWR 0x17 ++#define CMD_BANKADDR_BRRD 0x16 ++ + /* Common status */ + #define STATUS_WIP 0x01 ++#define STATUS_BANKADDR_ENABLE 0x01 ++#define STATUS_BANKADDR_DISABLE 0x00 + + /* Send a single-byte command to the device and read the response */ + int spi_flash_cmd(struct spi_slave *spi, u8 cmd, void *response, size_t len); +@@ -77,6 +83,19 @@ static inline int spi_flash_cmd_write_disable(struct spi_flash *flash) + /* Program the status register. */ + int spi_flash_cmd_write_status(struct spi_flash *flash, u8 sr); + ++/* Program the bank address register */ ++int spi_flash_cmd_bankaddr_write(struct spi_flash *flash, u8 ear); ++ ++/* Read the bank address register */ ++int spi_flash_cmd_bankaddr_read(struct spi_flash *flash, void *data); ++ ++/* ++ * Bank address access ++ * access 4th byte address in 3-byte addessing mode for flashes ++ * which has an actual size of > 16MB. ++ */ ++int spi_flash_bankaddr_access(struct spi_flash *flash, u8 status); ++ + /* + * Same as spi_flash_cmd_read() except it also claims/releases the SPI + * bus. Used as common part of the ->read() operation. +diff --git a/drivers/mtd/spi/stmicro.c b/drivers/mtd/spi/stmicro.c +index 30b626a..13c1971 100644 +--- a/drivers/mtd/spi/stmicro.c ++++ b/drivers/mtd/spi/stmicro.c +@@ -93,6 +93,30 @@ static const struct stmicro_spi_flash_params stmicro_spi_flash_table[] = { + .name = "M25P128", + }, + { ++ .id = 0xba16, ++ .pages_per_sector = 256, ++ .nr_sectors = 64, ++ .name = "N25Q32", ++ }, ++ { ++ .id = 0xbb16, ++ .pages_per_sector = 256, ++ .nr_sectors = 64, ++ .name = "N25Q32A", ++ }, ++ { ++ .id = 0xba17, ++ .pages_per_sector = 256, ++ .nr_sectors = 128, ++ .name = "N25Q64", ++ }, ++ { ++ .id = 0xbb17, ++ .pages_per_sector = 256, ++ .nr_sectors = 128, ++ .name = "N25Q64A", ++ }, ++ { + .id = 0xba18, + .pages_per_sector = 256, + .nr_sectors = 256, +@@ -110,6 +134,12 @@ static const struct stmicro_spi_flash_params stmicro_spi_flash_table[] = { + .nr_sectors = 512, + .name = "N25Q256", + }, ++ { ++ .id = 0xbb19, ++ .pages_per_sector = 256, ++ .nr_sectors = 512, ++ .name = "N25Q256A", ++ }, + }; + + struct spi_flash *spi_flash_probe_stmicro(struct spi_slave *spi, u8 * idcode) +@@ -160,7 +190,15 @@ struct spi_flash *spi_flash_probe_stmicro(struct spi_slave *spi, u8 * idcode) + flash->read = spi_flash_cmd_read_fast; + flash->page_size = 256; + flash->sector_size = 256 * params->pages_per_sector; +- flash->size = flash->sector_size * params->nr_sectors; ++ ++ /* address width is 4 for dual and 3 for single qspi */ ++ if (flash->spi->is_dual == 1) { ++ flash->addr_width = 4; ++ flash->size = flash->sector_size * (2 * params->nr_sectors); ++ } else { ++ flash->addr_width = 3; ++ flash->size = flash->sector_size * params->nr_sectors; ++ } + + return flash; + } +diff --git a/drivers/mtd/spi/winbond.c b/drivers/mtd/spi/winbond.c +index f6aab3d..3ddd057 100644 +--- a/drivers/mtd/spi/winbond.c ++++ b/drivers/mtd/spi/winbond.c +@@ -67,6 +67,11 @@ static const struct winbond_spi_flash_params winbond_spi_flash_table[] = { + .nr_blocks = 128, + .name = "W25Q80", + }, ++ { ++ .id = 0x6017, ++ .nr_blocks = 128, ++ .name = "W25Q64DW", ++ }, + }; + + struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode) +@@ -101,7 +106,15 @@ struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode) + flash->read = spi_flash_cmd_read_fast; + flash->page_size = 256; + flash->sector_size = 4096; +- flash->size = 4096 * 16 * params->nr_blocks; ++ ++ /* address width is 4 for dual and 3 for single qspi */ ++ if (flash->spi->is_dual == 1) { ++ flash->addr_width = 4; ++ flash->size = 4096 * 16 * (2 * params->nr_blocks); ++ } else { ++ flash->addr_width = 3; ++ flash->size = 4096 * 16 * params->nr_blocks; ++ } + + return flash; + } +diff --git a/drivers/net/Makefile b/drivers/net/Makefile +index 786a656..0ff814f 100644 +--- a/drivers/net/Makefile ++++ b/drivers/net/Makefile +@@ -77,8 +77,7 @@ COBJS-$(CONFIG_ULI526X) += uli526x.o + COBJS-$(CONFIG_VSC7385_ENET) += vsc7385.o + COBJS-$(CONFIG_XILINX_AXIEMAC) += xilinx_axi_emac.o + COBJS-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o +-COBJS-$(CONFIG_XILINX_LL_TEMAC) += xilinx_ll_temac.o xilinx_ll_temac_mdio.o \ +- xilinx_ll_temac_fifo.o xilinx_ll_temac_sdma.o ++COBJS-$(CONFIG_XILINX_LL_TEMAC) += xilinx_ll_temac.o + COBJS-$(CONFIG_ZYNQ_GEM) += zynq_gem.o + + COBJS := $(sort $(COBJS-y)) +diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c +index 4b27198..46801c7 100644 +--- a/drivers/net/phy/marvell.c ++++ b/drivers/net/phy/marvell.c +@@ -465,6 +465,16 @@ static struct phy_driver M88E1149S_driver = { + .shutdown = &genphy_shutdown, + }; + ++static struct phy_driver M88E1518_driver = { ++ .name = "Marvell 88E1518", ++ .uid = 0x1410dd1, ++ .mask = 0xffffff0, ++ .features = PHY_GBIT_FEATURES, ++ .config = &m88e1111s_config, ++ .startup = &m88e1011s_startup, ++ .shutdown = &genphy_shutdown, ++}; ++ + int phy_marvell_init(void) + { + phy_register(&M88E1149S_driver); +@@ -474,6 +484,7 @@ int phy_marvell_init(void) + phy_register(&M88E1118R_driver); + phy_register(&M88E1111S_driver); + phy_register(&M88E1011S_driver); ++ phy_register(&M88E1518_driver); + + return 0; + } +diff --git a/drivers/net/xilinx_axi_emac.c b/drivers/net/xilinx_axi_emac.c +index d777144..1ff9abf 100644 +--- a/drivers/net/xilinx_axi_emac.c ++++ b/drivers/net/xilinx_axi_emac.c +@@ -30,10 +30,6 @@ + #include + #include + +-#if !defined(CONFIG_PHYLIB) +-# error AXI_ETHERNET requires PHYLIB +-#endif +- + /* Link setup */ + #define XAE_EMMC_LINKSPEED_MASK 0xC0000000 /* Link speed */ + #define XAE_EMMC_LINKSPD_10 0x00000000 /* Link Speed mask for 10 Mbit */ +@@ -234,11 +230,47 @@ static u32 phywrite(struct eth_device *dev, u32 phyaddress, u32 registernum, + return 0; + } + ++static void phy_detection(struct eth_device *dev) ++{ ++ int i; ++ u16 phyreg; ++ struct axidma_priv *priv = dev->priv; ++ ++ if (priv->phyaddr != -1 ) { ++ phyread(dev, priv->phyaddr, PHY_DETECT_REG, &phyreg); ++ if ((phyreg != 0xFFFF) && ++ ((phyreg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) { ++ /* Found a valid PHY address */ ++ debug("Default phy address %d is valid\n", priv->phyaddr); ++ return; ++ } else { ++ debug("PHY address is not setup correctly %d\n", priv->phyaddr); ++ priv->phyaddr = -1; ++ } ++ } ++ ++ debug("detecting phy address\n"); ++ if (priv->phyaddr == -1 ) { ++ /* detect the PHY address */ ++ for (i = 31; i >= 0; i--) { ++ phyread(dev, i, PHY_DETECT_REG, &phyreg); ++ if ((phyreg != 0xFFFF) && ++ ((phyreg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) { ++ /* Found a valid PHY address */ ++ priv->phyaddr = i; ++ debug("Found valid phy address, %d\n", i); ++ return; ++ } ++ } ++ } ++ printf("PHY is not detected\n"); ++} ++ + /* Setting axi emac and phy to proper setting */ + static int setup_phy(struct eth_device *dev) + { +- u16 phyreg; +- u32 i, speed, emmc_reg, ret; ++#ifdef CONFIG_PHYLIB ++ u32 speed, emmc_reg; + struct axidma_priv *priv = dev->priv; + struct axi_regs *regs = (struct axi_regs *)dev->iobase; + struct phy_device *phydev; +@@ -250,20 +282,7 @@ static int setup_phy(struct eth_device *dev) + SUPPORTED_1000baseT_Half | + SUPPORTED_1000baseT_Full; + +- if (priv->phyaddr == -1) { +- /* Detect the PHY address */ +- for (i = 31; i >= 0; i--) { +- ret = phyread(dev, i, PHY_DETECT_REG, &phyreg); +- if (!ret && (phyreg != 0xFFFF) && +- ((phyreg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) { +- /* Found a valid PHY address */ +- priv->phyaddr = i; +- debug("axiemac: Found valid phy address, %x\n", +- phyreg); +- break; +- } +- } +- } ++ phy_detection(dev); + + /* Interface - look at tsec */ + phydev = phy_connect(priv->bus, priv->phyaddr, dev, 0); +@@ -308,6 +327,65 @@ static int setup_phy(struct eth_device *dev) + udelay(1); + + return 1; ++#else ++ int i; ++ struct axidma_priv *priv = dev->priv; ++ struct axi_regs *regs = (struct axi_regs *)dev->iobase; ++ unsigned retries = 100; ++ u16 phyreg; ++ u32 emmc_reg; ++ ++ ++ debug("waiting for the phy to be up\n"); ++ ++ /* wait for link up and autonegotiation completed */ ++ phyread(dev, priv->phyaddr, PHY_DETECT_REG, &phyreg); ++ while (retries-- && ((phyreg & 0x24) != 0x24)) ++ phyread(dev, priv->phyaddr, PHY_DETECT_REG, &phyreg); ++ ++ phy_detection(dev); ++ ++ /* get PHY id */ ++ phyread(dev, priv->phyaddr, 2, &phyreg); ++ i = phyreg << 16; ++ phyread(dev, priv->phyaddr, 3, &phyreg); ++ i |= phyreg; ++ debug("axiemac: Phy ID 0x%x\n", i); ++ ++ /* Marwell 88e1111 id - ml50x/sp605 */ ++ if (i == 0x1410cc2) { ++ debug("Marvell PHY recognized\n"); ++ ++ /* Setup the emac for the phy speed */ ++ emmc_reg = in_be32(®s->emmc); ++ emmc_reg &= ~XAE_EMMC_LINKSPEED_MASK; ++ ++ phyread(dev, priv->phyaddr, 17, &phyreg); ++ ++ if ((phyreg & 0x8000) == 0x8000) { ++ emmc_reg |= XAE_EMMC_LINKSPD_1000; ++ printf("1000BASE-T\n"); ++ } else if ((phyreg & 0x4000) == 0x4000) { ++ printf("100BASE-T\n"); ++ emmc_reg |= XAE_EMMC_LINKSPD_100; ++ } else { ++ printf("10BASE-T\n"); ++ emmc_reg |= XAE_EMMC_LINKSPD_10; ++ } ++ ++ /* Write new speed setting out to Axi Ethernet */ ++ out_be32(®s->emmc, emmc_reg); ++ ++ /* ++ * Setting the operating speed of the MAC needs a delay. There ++ * doesn't seem to be register to poll, so please consider this ++ * during your application design. ++ */ ++ udelay(1); ++ return 1; ++ } ++ return 0; ++#endif + } + + /* STOP DMA transfers */ +@@ -400,8 +478,8 @@ static void axi_dma_init(struct eth_device *dev) + while (timeout--) { + /* Check transmit/receive channel */ + /* Reset is done when the reset bit is low */ +- if (!(in_be32(&priv->dmatx->control) | +- in_be32(&priv->dmarx->control)) ++ if ((!(in_be32(&priv->dmatx->control) | ++ in_be32(&priv->dmarx->control))) + & XAXIDMA_CR_RESET_MASK) { + break; + } +@@ -510,7 +588,7 @@ static int axiemac_send(struct eth_device *dev, void *ptr, int len) + /* Wait for transmission to complete */ + debug("axiemac: Waiting for tx to be done\n"); + timeout = 200; +- while (timeout && (!in_be32(&priv->dmatx->status) & ++ while (timeout && ((!in_be32(&priv->dmatx->status)) & + (XAXIDMA_IRQ_DELAY_MASK | XAXIDMA_IRQ_IOC_MASK))) { + timeout--; + udelay(1); +diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c +index d890d60..f78ce0c 100644 +--- a/drivers/net/xilinx_emaclite.c ++++ b/drivers/net/xilinx_emaclite.c +@@ -28,6 +28,8 @@ + #include + #include + #include ++#include ++#include + #include + + DECLARE_GLOBAL_DATA_PTR; +@@ -64,11 +66,37 @@ DECLARE_GLOBAL_DATA_PTR; + /* Recv interrupt enable bit */ + #define XEL_RSR_RECV_IE_MASK 0x00000008UL + ++/* MDIO */ ++#define XEL_MDIOADDR_OFFSET 0x07E4 /* MDIO Address Register */ ++#define XEL_MDIOWR_OFFSET 0x07E8 /* MDIO Write Data Register */ ++#define XEL_MDIORD_OFFSET 0x07EC /* MDIO Read Data Register */ ++#define XEL_MDIOCTRL_OFFSET 0x07F0 /* MDIO Control Register */ ++ ++/* MDIO Address Register Bit Masks */ ++#define XEL_MDIOADDR_REGADR_MASK 0x0000001F /* Register Address */ ++#define XEL_MDIOADDR_PHYADR_MASK 0x000003E0 /* PHY Address */ ++#define XEL_MDIOADDR_PHYADR_SHIFT 5 ++#define XEL_MDIOADDR_OP_MASK 0x00000400 /* RD/WR Operation */ ++ ++/* MDIO Write Data Register Bit Masks */ ++#define XEL_MDIOWR_WRDATA_MASK 0x0000FFFF /* Data to be Written */ ++ ++/* MDIO Read Data Register Bit Masks */ ++#define XEL_MDIORD_RDDATA_MASK 0x0000FFFF /* Data to be Read */ ++ ++/* MDIO Control Register Bit Masks */ ++#define XEL_MDIOCTRL_MDIOSTS_MASK 0x00000001 /* MDIO Status Mask */ ++#define XEL_MDIOCTRL_MDIOEN_MASK 0x00000008 /* MDIO Enable */ ++ + struct xemaclite { + u32 nexttxbuffertouse; /* Next TX buffer to write to */ + u32 nextrxbuffertouse; /* Next RX buffer to read from */ + u32 txpp; /* TX ping pong buffer */ + u32 rxpp; /* RX ping pong buffer */ ++ int phyaddr; ++ ++ struct phy_device *phydev; ++ struct mii_dev *bus; + }; + + static u32 etherrxbuff[PKTSIZE_ALIGN/4]; /* Receive buffer */ +@@ -125,42 +153,181 @@ static void xemaclite_alignedwrite(void *srcptr, u32 destptr, u32 bytecount) + *to32ptr++ = alignbuffer; + } + ++#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB) ++static int mdio_wait(struct eth_device *dev) ++{ ++ u32 timeout = 200; ++ ++ /* Wait till MDIO interface is ready to accept a new transaction. */ ++ while (timeout && in_be32(dev->iobase + XEL_MDIOCTRL_OFFSET) ++ & XEL_MDIOCTRL_MDIOSTS_MASK) ++ timeout--; ++ ++ if (!timeout) { ++ printf("%s: Timeout\n", __func__); ++ return 1; ++ } ++ return 0; ++} ++ ++static u32 phyread(struct eth_device *dev, u32 phyaddress, u32 registernum, ++ u16 *data) ++{ ++ if (mdio_wait(dev)) ++ return 1; ++ ++ u32 ctrl_reg = in_be32(dev->iobase + XEL_MDIOCTRL_OFFSET); ++ out_be32(dev->iobase + XEL_MDIOADDR_OFFSET, ++ XEL_MDIOADDR_OP_MASK | ++ ((phyaddress << XEL_MDIOADDR_PHYADR_SHIFT) | registernum)); ++ out_be32(dev->iobase + XEL_MDIOCTRL_OFFSET, ++ ctrl_reg | XEL_MDIOCTRL_MDIOSTS_MASK); ++ ++ if (mdio_wait(dev)) ++ return 1; ++ ++ /* Read data */ ++ *data = in_be32(dev->iobase + XEL_MDIORD_OFFSET); ++ return 0; ++} ++ ++static u32 phywrite(struct eth_device *dev, u32 phyaddress, u32 registernum, ++ u16 data) ++{ ++ if (mdio_wait(dev)) ++ return 1; ++ ++ /* ++ * Write the PHY address, register number and clear the OP bit in the ++ * MDIO Address register and then write the value into the MDIO Write ++ * Data register. Finally, set the Status bit in the MDIO Control ++ * register to start a MDIO write transaction. ++ */ ++ u32 ctrl_reg = in_be32(dev->iobase + XEL_MDIOCTRL_OFFSET); ++ out_be32(dev->iobase + XEL_MDIOADDR_OFFSET, ++ ~XEL_MDIOADDR_OP_MASK & ++ ((phyaddress << XEL_MDIOADDR_PHYADR_SHIFT) | registernum)); ++ out_be32(dev->iobase + XEL_MDIOWR_OFFSET, data); ++ out_be32(dev->iobase + XEL_MDIOCTRL_OFFSET, ++ ctrl_reg | XEL_MDIOCTRL_MDIOSTS_MASK); ++ ++ if (mdio_wait(dev)) ++ return 1; ++ ++ return 0; ++} ++#endif ++ + static void emaclite_halt(struct eth_device *dev) + { + debug("eth_halt\n"); + } + ++/* Use MII register 1 (MII status register) to detect PHY */ ++#define PHY_DETECT_REG 1 ++ ++/* Mask used to verify certain PHY features (or register contents) ++ * in the register above: ++ * 0x1000: 10Mbps full duplex support ++ * 0x0800: 10Mbps half duplex support ++ * 0x0008: Auto-negotiation support ++ */ ++#define PHY_DETECT_MASK 0x1808 ++ ++#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB) ++static int setup_phy(struct eth_device *dev) ++{ ++ int i; ++ u16 phyreg; ++ struct xemaclite *emaclite = dev->priv; ++ struct phy_device *phydev; ++ ++ u32 supported = SUPPORTED_10baseT_Half | ++ SUPPORTED_10baseT_Full | ++ SUPPORTED_100baseT_Half | ++ SUPPORTED_100baseT_Full; ++ ++ if (emaclite->phyaddr != -1 ) { ++ phyread(dev, emaclite->phyaddr, PHY_DETECT_REG, &phyreg); ++ if ((phyreg != 0xFFFF) && ++ ((phyreg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) { ++ /* Found a valid PHY address */ ++ debug("Default phy address %d is valid\n", emaclite->phyaddr); ++ } else { ++ debug("PHY address is not setup correctly %d\n", emaclite->phyaddr); ++ emaclite->phyaddr = -1; ++ } ++ } ++ ++ if (emaclite->phyaddr == -1) { ++ /* detect the PHY address */ ++ for (i = 31; i >= 0; i--) { ++ phyread(dev, i, PHY_DETECT_REG, &phyreg); ++ if ((phyreg != 0xFFFF) && ++ ((phyreg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) { ++ /* Found a valid PHY address */ ++ emaclite->phyaddr = i; ++ debug("emaclite: Found valid phy address, %d\n", ++ phyreg); ++ break; ++ } ++ } ++ } ++ ++ /* interface - look at tsec */ ++ phydev = phy_connect(emaclite->bus, emaclite->phyaddr, dev, 0); ++ /* ++ * Phy can support 1000baseT but device NOT that's why phydev->supported ++ * must be setup for 1000baseT. phydev->advertising setups what speeds ++ * will be used for autonegotiation where 1000baseT must be disabled. ++ */ ++ phydev->supported = supported | SUPPORTED_1000baseT_Half | ++ SUPPORTED_1000baseT_Full; ++ phydev->advertising = supported; ++ emaclite->phydev = phydev; ++ phy_config(phydev); ++ phy_startup(phydev); ++ ++ /* Do not setup anything */ ++ return 1; ++} ++#endif ++ + static int emaclite_init(struct eth_device *dev, bd_t *bis) + { + struct xemaclite *emaclite = dev->priv; +- debug("EmacLite Initialization Started\n"); ++#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB) ++ u32 temp; ++#endif ++ ++ debug("EmacLite: Initialization Started\n"); + + /* + * TX - TX_PING & TX_PONG initialization + */ + /* Restart PING TX */ +- out_be32 (dev->iobase + XEL_TSR_OFFSET, 0); ++ out_be32 ((u32 *)(dev->iobase + XEL_TSR_OFFSET), 0); + /* Copy MAC address */ + xemaclite_alignedwrite(dev->enetaddr, dev->iobase, ENET_ADDR_LENGTH); + /* Set the length */ +- out_be32 (dev->iobase + XEL_TPLR_OFFSET, ENET_ADDR_LENGTH); ++ out_be32 ((u32 *)(dev->iobase + XEL_TPLR_OFFSET), ENET_ADDR_LENGTH); + /* Update the MAC address in the EMAC Lite */ +- out_be32 (dev->iobase + XEL_TSR_OFFSET, XEL_TSR_PROG_MAC_ADDR); ++ out_be32 ((u32 *)(dev->iobase + XEL_TSR_OFFSET), XEL_TSR_PROG_MAC_ADDR); + /* Wait for EMAC Lite to finish with the MAC address update */ +- while ((in_be32 (dev->iobase + XEL_TSR_OFFSET) & ++ while ((in_be32 ((u32 *)(dev->iobase + XEL_TSR_OFFSET)) & + XEL_TSR_PROG_MAC_ADDR) != 0) + ; + + if (emaclite->txpp) { + /* The same operation with PONG TX */ +- out_be32 (dev->iobase + XEL_TSR_OFFSET + XEL_BUFFER_OFFSET, 0); ++ out_be32 ((u32 *)(dev->iobase + XEL_TSR_OFFSET + XEL_BUFFER_OFFSET), 0); + xemaclite_alignedwrite(dev->enetaddr, dev->iobase + + XEL_BUFFER_OFFSET, ENET_ADDR_LENGTH); +- out_be32 (dev->iobase + XEL_TPLR_OFFSET, ENET_ADDR_LENGTH); +- out_be32 (dev->iobase + XEL_TSR_OFFSET + XEL_BUFFER_OFFSET, ++ out_be32 ((u32 *)(dev->iobase + XEL_TPLR_OFFSET), ENET_ADDR_LENGTH); ++ out_be32 ((u32 *)(dev->iobase + XEL_TSR_OFFSET + XEL_BUFFER_OFFSET), + XEL_TSR_PROG_MAC_ADDR); +- while ((in_be32 (dev->iobase + XEL_TSR_OFFSET + +- XEL_BUFFER_OFFSET) & XEL_TSR_PROG_MAC_ADDR) != 0) ++ while ((in_be32 ((u32 *)(dev->iobase + XEL_TSR_OFFSET + ++ XEL_BUFFER_OFFSET)) & XEL_TSR_PROG_MAC_ADDR) != 0) + ; + } + +@@ -168,12 +335,21 @@ static int emaclite_init(struct eth_device *dev, bd_t *bis) + * RX - RX_PING & RX_PONG initialization + */ + /* Write out the value to flush the RX buffer */ +- out_be32 (dev->iobase + XEL_RSR_OFFSET, XEL_RSR_RECV_IE_MASK); ++ out_be32 ((u32 *)(dev->iobase + XEL_RSR_OFFSET), XEL_RSR_RECV_IE_MASK); + + if (emaclite->rxpp) +- out_be32 (dev->iobase + XEL_RSR_OFFSET + XEL_BUFFER_OFFSET, ++ out_be32 ((u32 *)(dev->iobase + XEL_RSR_OFFSET + XEL_BUFFER_OFFSET), + XEL_RSR_RECV_IE_MASK); + ++#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB) ++ /* Enable MII PHY */ ++ /* Enable MII PHY */ ++ out_be32((u32 *)(dev->iobase + XEL_MDIOCTRL_OFFSET), XEL_MDIOCTRL_MDIOEN_MASK); ++ temp = in_be32((u32 *)(dev->iobase + XEL_MDIOCTRL_OFFSET)); ++ if (temp & XEL_MDIOCTRL_MDIOEN_MASK) ++ setup_phy(dev); ++#endif ++ + debug("EmacLite Initialization complete\n"); + return 0; + } +@@ -189,13 +365,13 @@ static int xemaclite_txbufferavailable(struct eth_device *dev) + * Read the other buffer register + * and determine if the other buffer is available + */ +- reg = in_be32 (dev->iobase + +- emaclite->nexttxbuffertouse + 0); ++ reg = in_be32 ((u32 *)(dev->iobase + ++ emaclite->nexttxbuffertouse + 0)); + txpingbusy = ((reg & XEL_TSR_XMIT_BUSY_MASK) == + XEL_TSR_XMIT_BUSY_MASK); + +- reg = in_be32 (dev->iobase + +- (emaclite->nexttxbuffertouse ^ XEL_TSR_OFFSET) + 0); ++ reg = in_be32 ((u32 *)(dev->iobase + ++ (emaclite->nexttxbuffertouse ^ XEL_TSR_OFFSET) + 0)); + txpongbusy = ((reg & XEL_TSR_XMIT_BUSY_MASK) == + XEL_TSR_XMIT_BUSY_MASK); + +@@ -221,10 +397,10 @@ static int emaclite_send(struct eth_device *dev, void *ptr, int len) + if (!maxtry) { + printf("Error: Timeout waiting for ethernet TX buffer\n"); + /* Restart PING TX */ +- out_be32 (dev->iobase + XEL_TSR_OFFSET, 0); ++ out_be32 ((u32 *)(dev->iobase + XEL_TSR_OFFSET), 0); + if (emaclite->txpp) { +- out_be32 (dev->iobase + XEL_TSR_OFFSET + +- XEL_BUFFER_OFFSET, 0); ++ out_be32 ((u32 *)(dev->iobase + XEL_TSR_OFFSET + ++ XEL_BUFFER_OFFSET), 0); + } + return -1; + } +@@ -233,9 +409,9 @@ static int emaclite_send(struct eth_device *dev, void *ptr, int len) + baseaddress = (dev->iobase + emaclite->nexttxbuffertouse); + + /* Determine if the expected buffer address is empty */ +- reg = in_be32 (baseaddress + XEL_TSR_OFFSET); ++ reg = in_be32 ((u32 *)(baseaddress + XEL_TSR_OFFSET)); + if (((reg & XEL_TSR_XMIT_BUSY_MASK) == 0) +- && ((in_be32 ((baseaddress) + XEL_TSR_OFFSET) ++ && ((in_be32 (((u32 *)(baseaddress) + XEL_TSR_OFFSET)) + & XEL_TSR_XMIT_ACTIVE_MASK) == 0)) { + + if (emaclite->txpp) +@@ -244,13 +420,13 @@ static int emaclite_send(struct eth_device *dev, void *ptr, int len) + debug("Send packet from 0x%x\n", baseaddress); + /* Write the frame to the buffer */ + xemaclite_alignedwrite(ptr, baseaddress, len); +- out_be32 (baseaddress + XEL_TPLR_OFFSET,(len & ++ out_be32 ((u32 *)(baseaddress + XEL_TPLR_OFFSET), (len & + (XEL_TPLR_LENGTH_MASK_HI | XEL_TPLR_LENGTH_MASK_LO))); +- reg = in_be32 (baseaddress + XEL_TSR_OFFSET); ++ reg = in_be32 ((u32 *)(baseaddress + XEL_TSR_OFFSET)); + reg |= XEL_TSR_XMIT_BUSY_MASK; + if ((reg & XEL_TSR_XMIT_IE_MASK) != 0) + reg |= XEL_TSR_XMIT_ACTIVE_MASK; +- out_be32 (baseaddress + XEL_TSR_OFFSET, reg); ++ out_be32 ((u32 *)(baseaddress + XEL_TSR_OFFSET), reg); + return 0; + } + +@@ -258,21 +434,21 @@ static int emaclite_send(struct eth_device *dev, void *ptr, int len) + /* Switch to second buffer */ + baseaddress ^= XEL_BUFFER_OFFSET; + /* Determine if the expected buffer address is empty */ +- reg = in_be32 (baseaddress + XEL_TSR_OFFSET); ++ reg = in_be32 ((u32 *)(baseaddress + XEL_TSR_OFFSET)); + if (((reg & XEL_TSR_XMIT_BUSY_MASK) == 0) +- && ((in_be32 ((baseaddress) + XEL_TSR_OFFSET) ++ && ((in_be32 ((u32 *)(baseaddress + XEL_TSR_OFFSET)) + & XEL_TSR_XMIT_ACTIVE_MASK) == 0)) { + debug("Send packet from 0x%x\n", baseaddress); + /* Write the frame to the buffer */ + xemaclite_alignedwrite(ptr, baseaddress, len); +- out_be32 (baseaddress + XEL_TPLR_OFFSET, (len & ++ out_be32 ((u32 *)(baseaddress + XEL_TPLR_OFFSET), (len & + (XEL_TPLR_LENGTH_MASK_HI | + XEL_TPLR_LENGTH_MASK_LO))); +- reg = in_be32 (baseaddress + XEL_TSR_OFFSET); ++ reg = in_be32 ((u32 *)(baseaddress + XEL_TSR_OFFSET)); + reg |= XEL_TSR_XMIT_BUSY_MASK; + if ((reg & XEL_TSR_XMIT_IE_MASK) != 0) + reg |= XEL_TSR_XMIT_ACTIVE_MASK; +- out_be32 (baseaddress + XEL_TSR_OFFSET, reg); ++ out_be32 ((u32 *)(baseaddress + XEL_TSR_OFFSET), reg); + return 0; + } + } +@@ -289,7 +465,7 @@ static int emaclite_recv(struct eth_device *dev) + struct xemaclite *emaclite = dev->priv; + + baseaddress = dev->iobase + emaclite->nextrxbuffertouse; +- reg = in_be32 (baseaddress + XEL_RSR_OFFSET); ++ reg = in_be32 ((u32 *)(baseaddress + XEL_RSR_OFFSET)); + debug("Testing data at address 0x%x\n", baseaddress); + if ((reg & XEL_RSR_RECV_DONE_MASK) == XEL_RSR_RECV_DONE_MASK) { + if (emaclite->rxpp) +@@ -302,7 +478,7 @@ static int emaclite_recv(struct eth_device *dev) + return 0; + } else { + baseaddress ^= XEL_BUFFER_OFFSET; +- reg = in_be32 (baseaddress + XEL_RSR_OFFSET); ++ reg = in_be32 ((u32 *)(baseaddress + XEL_RSR_OFFSET)); + if ((reg & XEL_RSR_RECV_DONE_MASK) != + XEL_RSR_RECV_DONE_MASK) { + debug("No data was available - address 0x%x\n", +@@ -312,7 +488,7 @@ static int emaclite_recv(struct eth_device *dev) + } + } + /* Get the length of the frame that arrived */ +- switch(((ntohl(in_be32 (baseaddress + XEL_RXBUFF_OFFSET + 0xC))) & ++ switch(((ntohl(in_be32 ((u32 *)(baseaddress + XEL_RXBUFF_OFFSET + 0xC)))) & + 0xFFFF0000 ) >> 16) { + case 0x806: + length = 42 + 20; /* FIXME size of ARP */ +@@ -320,8 +496,8 @@ static int emaclite_recv(struct eth_device *dev) + break; + case 0x800: + length = 14 + 14 + +- (((ntohl(in_be32 (baseaddress + XEL_RXBUFF_OFFSET + +- 0x10))) & 0xFFFF0000) >> 16); ++ (((ntohl(in_be32 ((u32 *)(baseaddress + XEL_RXBUFF_OFFSET + ++ 0x10)))) & 0xFFFF0000) >> 16); + /* FIXME size of IP packet */ + debug ("IP Packet\n"); + break; +@@ -335,9 +511,9 @@ static int emaclite_recv(struct eth_device *dev) + etherrxbuff, length); + + /* Acknowledge the frame */ +- reg = in_be32 (baseaddress + XEL_RSR_OFFSET); ++ reg = in_be32 ((u32 *)(baseaddress + XEL_RSR_OFFSET)); + reg &= ~XEL_RSR_RECV_DONE_MASK; +- out_be32 (baseaddress + XEL_RSR_OFFSET, reg); ++ out_be32 ((u32 *)(baseaddress + XEL_RSR_OFFSET), reg); + + debug("Packet receive from 0x%x, length %dB\n", baseaddress, length); + NetReceive((uchar *) etherrxbuff, length); +@@ -345,6 +521,28 @@ static int emaclite_recv(struct eth_device *dev) + + } + ++#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB) ++static int emaclite_miiphy_read(const char *devname, uchar addr, ++ uchar reg, ushort *val) ++{ ++ u32 ret; ++ struct eth_device *dev = eth_get_dev(); ++ ++ ret = phyread(dev, addr, reg, val); ++ debug("emaclite: Read MII 0x%x, 0x%x, 0x%x\n", addr, reg, *val); ++ return ret; ++} ++ ++static int emaclite_miiphy_write(const char *devname, uchar addr, ++ uchar reg, ushort val) ++{ ++ struct eth_device *dev = eth_get_dev(); ++ ++ debug("emaclite: Write MII 0x%x, 0x%x, 0x%x\n", addr, reg, val); ++ return phywrite(dev, addr, reg, val); ++} ++#endif ++ + int xilinx_emaclite_initialize(bd_t *bis, unsigned long base_addr, + int txpp, int rxpp) + { +@@ -374,8 +572,19 @@ int xilinx_emaclite_initialize(bd_t *bis, unsigned long base_addr, + dev->send = emaclite_send; + dev->recv = emaclite_recv; + ++#ifdef CONFIG_PHY_ADDR ++ emaclite->phyaddr = CONFIG_PHY_ADDR; ++#else ++ emaclite->phyaddr = -1; ++#endif ++ + eth_register(dev); + ++#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB) ++ miiphy_register(dev->name, emaclite_miiphy_read, emaclite_miiphy_write); ++ emaclite->bus = miiphy_get_dev_by_name(dev->name); ++#endif ++ + return 1; + } + +diff --git a/drivers/net/xilinx_ll_temac.c b/drivers/net/xilinx_ll_temac.c +index b67153b..5f8fc9c 100644 +--- a/drivers/net/xilinx_ll_temac.c ++++ b/drivers/net/xilinx_ll_temac.c +@@ -1,9 +1,6 @@ + /* + * Xilinx xps_ll_temac ethernet driver for u-boot + * +- * supports SDMA or FIFO access and MDIO bus communication +- * +- * Copyright (C) 2011 - 2012 Stephan Linz + * Copyright (C) 2008 - 2011 Michal Simek + * Copyright (C) 2008 - 2011 PetaLogix + * +@@ -15,391 +12,749 @@ + * 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. +- * +- * [0]: http://www.xilinx.com/support/documentation +- * +- * [S]: [0]/ip_documentation/xps_ll_temac.pdf +- * [A]: [0]/application_notes/xapp1041.pdf + */ + + #include + #include + #include +-#include + #include ++#include + #include ++#include + #include + +-#include "xilinx_ll_temac.h" +-#include "xilinx_ll_temac_fifo.h" +-#include "xilinx_ll_temac_sdma.h" +-#include "xilinx_ll_temac_mdio.h" ++#undef ETH_HALTING ++ ++#define XTE_EMMC_LINKSPEED_MASK 0xC0000000 /* Link speed */ ++/* XTE_EMCFG_LINKSPD_MASK */ ++#define XTE_EMMC_LINKSPD_10 0x00000000 /* for 10 Mbit */ ++#define XTE_EMMC_LINKSPD_100 0x40000000 /* for 100 Mbit */ ++#define XTE_EMMC_LINKSPD_1000 0x80000000 /* forr 1000 Mbit */ ++ ++#define XTE_RSE_MIIM_RR_MASK 0x0002 ++#define XTE_RSE_MIIM_WR_MASK 0x0004 ++#define XTE_RSE_CFG_RR_MASK 0x0020 ++#define XTE_RSE_CFG_WR_MASK 0x0040 ++ ++/* XPS_LL_TEMAC indirect registers offset definition */ ++#define RCW1 0x240 ++#define TC 0x280 ++#define EMMC 0x300 ++#define MC 0x340 ++#define UAW0 0x380 ++#define UAW1 0x384 ++#define AFM 0x390 ++#define MIIMWD 0x3b0 ++#define MIIMAI 0x3b4 ++ ++#define CNTLREG_WRITE_ENABLE_MASK 0x8000 ++ ++#define MDIO_ENABLE_MASK 0x40 ++#define MDIO_CLOCK_DIV_100MHz 0x28 ++ ++/* XPS_LL_TEMAC SDMA registers definition */ ++#define TX_CURDESC_PTR 0x03 ++#define TX_TAILDESC_PTR 0x04 ++#define TX_CHNL_CTRL 0x05 ++#define TX_IRQ_REG 0x06 ++#define TX_CHNL_STS 0x07 ++#define RX_NXTDESC_PTR 0x08 ++#define RX_CURDESC_PTR 0x0b ++#define RX_TAILDESC_PTR 0x0c ++#define RX_CHNL_CTRL 0x0d ++#define RX_IRQ_REG 0x0e ++#define RX_CHNL_STS 0x0f ++#define DMA_CONTROL_REG 0x10 ++ ++/* DMA control bit */ ++#define DMA_CONTROL_RESET 0x1 ++ ++/* CDMAC descriptor status bit definitions */ ++# define BDSTAT_STOP_ON_END_MASK 0x20 ++# define BDSTAT_COMPLETED_MASK 0x10 ++# define BDSTAT_SOP_MASK 0x08 ++# define BDSTAT_EOP_MASK 0x04 ++ ++# define CHNL_STS_ERROR_MASK 0x80 ++ ++/* All interrupt enable bits */ ++#define XLLDMA_CR_IRQ_ALL_EN_MASK 0x00000087 ++/* All interrupt bits */ ++#define XLLDMA_IRQ_ALL_MASK 0x0000001F ++/* Disable error when 2 or 4 bit coalesce counter overflows */ ++#define XLLDMA_DMACR_RX_OVERFLOW_ERR_DIS_MASK 0x00000010 ++/* Disable error when 2 or 4 bit coalesce counter overflows */ ++#define XLLDMA_DMACR_TX_OVERFLOW_ERR_DIS_MASK 0x00000008 ++/* Enable use of tail pointer register */ ++#define XLLDMA_DMACR_TAIL_PTR_EN_MASK 0x00000004 ++ ++#define LL_FIFO_ISR_RC_COMPLETE 0x04000000 ++ ++#define SDMA_BIT 1 ++#define DCR_BIT 2 ++ ++#define DMAALIGN 32 ++ ++/* SDMA Buffer Descriptor */ ++struct cdmac_bd_t { ++ struct cdmac_bd_t *next_p; ++ unsigned char *phys_buf_p; ++ unsigned long buf_len; ++ unsigned char stat; ++ unsigned char app1_1; ++ unsigned short app1_2; ++ unsigned long app2; ++ unsigned long app3; ++ unsigned long app4; ++ unsigned long app5; ++}; ++ ++static struct cdmac_bd_t tx_bd __attribute((aligned(DMAALIGN))); ++static struct cdmac_bd_t rx_bd __attribute((aligned(DMAALIGN))); ++ ++struct ll_fifo_s { ++ u32 isr; /* Interrupt Status Register 0x0 */ ++ u32 ier; /* Interrupt Enable Register 0x4 */ ++ u32 tdfr; /* Transmit data FIFO reset 0x8 */ ++ u32 tdfv; /* Transmit data FIFO Vacancy 0xC */ ++ u32 tdfd; /* Transmit data FIFO 32bit wide data write port 0x10 */ ++ u32 tlf; /* Write Transmit Length FIFO 0x14 */ ++ u32 rdfr; /* Read Receive data FIFO reset 0x18 */ ++ u32 rdfo; /* Receive data FIFO Occupancy 0x1C */ ++ u32 rdfd; /* Read Receive data FIFO 32bit wide data read port 0x20 */ ++ u32 rlf; /* Read Receive Length FIFO 0x24 */ ++ u32 llr; /* Read LocalLink reset 0x28 */ ++}; ++ ++static u8 tx_buffer[PKTSIZE_ALIGN] __attribute((aligned(DMAALIGN))); ++static u8 rx_buffer[PKTSIZE_ALIGN] __attribute((aligned(DMAALIGN))); + +-#if !defined(CONFIG_MII) +-# error "LL_TEMAC requires MII -- missing CONFIG_MII" ++struct temac_reg { ++ u32 reserved[8]; ++ u32 msw; /* Hard TEMAC MSW Data Register */ ++ u32 lsw; /* Hard TEMAC LSW Data Register */ ++ u32 ctl; /* Hard TEMAC Control Register */ ++ u32 rdy; /* Hard TEMAC Ready Status */ ++}; ++ ++struct ll_priv { ++ u32 ctrl; ++ u32 mode; ++ int phyaddr; ++ ++ struct phy_device *phydev; ++ struct mii_dev *bus; ++}; ++ ++#define XILINX_INDIRECT_DCR_ADDRESS_REG 0 ++#define XILINX_INDIRECT_DCR_ACCESS_REG 1 ++ ++static void mtdcr_local(u32 reg, u32 val) ++{ ++#if defined(CONFIG_XILINX_440) ++ mtdcr(XILINX_INDIRECT_DCR_ADDRESS_REG, reg); ++ mtdcr(XILINX_INDIRECT_DCR_ACCESS_REG, val); + #endif ++} + +-#if !defined(CONFIG_PHYLIB) +-# error "LL_TEMAC requires PHYLIB -- missing CONFIG_PHYLIB" ++static u32 mfdcr_local(u32 reg) ++{ ++ u32 val = 0; ++#if defined(CONFIG_XILINX_440) ++ mtdcr(XILINX_INDIRECT_DCR_ADDRESS_REG, reg); ++ val = mfdcr(XILINX_INDIRECT_DCR_ACCESS_REG); + #endif ++ return val; ++} + +-struct ll_temac_info { +- int flags; +- unsigned long base_addr; +- unsigned long ctrl_addr; +- char *devname; +- unsigned int phyaddr; +- char *mdio_busname; +-}; ++static void sdma_out_be32(struct ll_priv *priv, u32 offset, u32 val) ++{ ++ if (priv->mode & DCR_BIT) ++ mtdcr_local(priv->ctrl + offset, val); ++ else ++ out_be32((u32 *)(priv->ctrl + offset * 4), val); ++} + +-/* Ethernet interface ready status */ +-int ll_temac_check_status(struct temac_reg *regs, u32 mask) ++static u32 sdma_in_be32(struct ll_priv *priv, u32 offset) + { +- unsigned timeout = 50; /* 1usec * 50 = 50usec */ ++ if (priv->mode & DCR_BIT) ++ return mfdcr_local(priv->ctrl + offset); ++ ++ return in_be32((u32 *)(priv->ctrl + offset * 4)); ++} ++ ++static void xps_ll_temac_check_status(struct temac_reg *regs, int mask) ++{ ++ u32 timeout = 2000; + +- /* +- * Quote from LL TEMAC documentation: The bits in the RDY +- * register are asserted when there is no access in progress. +- * When an access is in progress, a bit corresponding to the +- * type of access is automatically de-asserted. The bit is +- * automatically re-asserted when the access is complete. +- */ + while (timeout && (!(in_be32(®s->rdy) & mask))) { + timeout--; + udelay(1); + } + +- if (!timeout) { +- printf("%s: Timeout on 0x%08x @%p\n", __func__, +- mask, ®s->rdy); +- return 1; +- } +- +- return 0; ++ if (!timeout) ++ printf("%s: Timeout\n", __func__); + } + +-/* +- * Indirect write to ll_temac. +- * +- * http://www.xilinx.com/support/documentation/ip_documentation/xps_ll_temac.pdf +- * page 23, second paragraph, The use of CTL0 register or CTL1 register +- */ +-int ll_temac_indirect_set(struct temac_reg *regs, u16 regn, u32 reg_data) ++/* undirect hostif write to ll_temac */ ++static void xps_ll_temac_hostif_set(struct eth_device *dev, int emac, ++ int phy_addr, int reg_addr, int phy_data) + { +- out_be32(®s->lsw, (reg_data & MLSW_MASK)); +- out_be32(®s->ctl, CTL_WEN | (regn & CTL_ADDR_MASK)); +- +- if (ll_temac_check_status(regs, RSE_CFG_WR)) +- return 0; ++ struct temac_reg *regs = (struct temac_reg *)dev->iobase; + +- return 1; ++ out_be32(®s->lsw, phy_data); ++ out_be32(®s->ctl, CNTLREG_WRITE_ENABLE_MASK | MIIMWD); ++ out_be32(®s->lsw, (phy_addr << 5) | reg_addr); ++ out_be32(®s->ctl, CNTLREG_WRITE_ENABLE_MASK | MIIMAI | (emac << 10)); ++ xps_ll_temac_check_status(regs, XTE_RSE_MIIM_WR_MASK); + } + +-/* +- * Indirect read from ll_temac. +- * +- * http://www.xilinx.com/support/documentation/ip_documentation/xps_ll_temac.pdf +- * page 23, second paragraph, The use of CTL0 register or CTL1 register +- */ +-int ll_temac_indirect_get(struct temac_reg *regs, u16 regn, u32* reg_data) ++/* undirect hostif read from ll_temac */ ++static unsigned int xps_ll_temac_hostif_get(struct eth_device *dev, ++ int emac, int phy_addr, int reg_addr) + { +- out_be32(®s->ctl, (regn & CTL_ADDR_MASK)); ++ struct temac_reg *regs = (struct temac_reg *)dev->iobase; + +- if (ll_temac_check_status(regs, RSE_CFG_RR)) +- return 0; ++ out_be32(®s->lsw, (phy_addr << 5) | reg_addr); ++ out_be32(®s->ctl, MIIMAI | (emac << 10)); ++ xps_ll_temac_check_status(regs, XTE_RSE_MIIM_RR_MASK); ++ return in_be32(®s->lsw); ++} + +- *reg_data = in_be32(®s->lsw) & MLSW_MASK; +- return 1; ++/* undirect write to ll_temac */ ++static void xps_ll_temac_indirect_set(struct eth_device *dev, ++ int emac, int reg_offset, int reg_data) ++{ ++ struct temac_reg *regs = (struct temac_reg *)dev->iobase; ++ ++ out_be32(®s->lsw, reg_data); ++ out_be32(®s->ctl, ++ CNTLREG_WRITE_ENABLE_MASK | (emac << 10) | reg_offset); ++ xps_ll_temac_check_status(regs, XTE_RSE_CFG_WR_MASK); + } + +-/* setting sub-controller and ll_temac to proper setting */ +-static int ll_temac_setup_ctrl(struct eth_device *dev) ++/* undirect read from ll_temac */ ++static int xps_ll_temac_indirect_get(struct eth_device *dev, ++ int emac, int reg_offset) + { +- struct ll_temac *ll_temac = dev->priv; + struct temac_reg *regs = (struct temac_reg *)dev->iobase; + +- if (ll_temac->ctrlreset && ll_temac->ctrlreset(dev)) +- return 0; ++ out_be32(®s->ctl, (emac << 10) | reg_offset); ++ xps_ll_temac_check_status(regs, XTE_RSE_CFG_RR_MASK); ++ return in_be32(®s->lsw); ++} + +- if (ll_temac->ctrlinit && ll_temac->ctrlinit(dev)) +- return 0; ++#ifdef DEBUG ++/* read from phy */ ++static void read_phy_reg(struct eth_device *dev, int phy_addr) ++{ ++ int j, result; + +- /* Promiscuous mode disable */ +- if (!ll_temac_indirect_set(regs, TEMAC_AFM, 0)) +- return 0; ++ debug("phy%d ", phy_addr); ++ for (j = 0; j < 32; j++) { ++ result = xps_ll_temac_hostif_get(dev, 0, phy_addr, j); ++ debug("%d: 0x%x ", j, result); ++ } ++ debug("\n"); ++} ++#endif + +- /* Enable Receiver - RX bit */ +- if (!ll_temac_indirect_set(regs, TEMAC_RCW1, RCW1_RX)) +- return 0; ++static void phy_detection(struct eth_device *dev) ++{ + +- /* Enable Transmitter - TX bit */ +- if (!ll_temac_indirect_set(regs, TEMAC_TC, TC_TX)) +- return 0; ++ int i; ++ struct ll_priv *priv = dev->priv; ++ unsigned int phyreg = 0; + +- return 1; ++ ++ if (priv->phyaddr != -1 ) { ++ phyreg = xps_ll_temac_hostif_get(dev, 0, priv->phyaddr, 1); ++ if ((phyreg & 0x0ffff) != 0x0ffff) { ++ /* Found a valid PHY address */ ++ debug("Default phy address %d is valid\n", priv->phyaddr); ++ } else { ++ debug("PHY address is not setup correctly %d\n", priv->phyaddr); ++ priv->phyaddr = -1; ++ } ++ } ++ ++ /* try out if have ever found the right phy? */ ++ if (priv->phyaddr == -1) { ++ for (i = 31; i >= 0; i--) { ++ phyreg = xps_ll_temac_hostif_get(dev, 0, i, 1); ++ if ((phyreg & 0x0ffff) != 0x0ffff) { ++ debug("phy %x result %x\n", i, phyreg); ++ priv->phyaddr = i; ++ break; ++ } ++ } ++ } + } + +-/* +- * Configure ll_temac based on negotiated speed and duplex +- * reported by PHY handling code +- */ +-static int ll_temac_adjust_link(struct eth_device *dev) ++/* setting ll_temac and phy to proper setting */ ++static int xps_ll_temac_phy_ctrl(struct eth_device *dev) + { +- unsigned int speed, emmc_reg; +- struct temac_reg *regs = (struct temac_reg *)dev->iobase; +- struct ll_temac *ll_temac = dev->priv; +- struct phy_device *phydev = ll_temac->phydev; ++#ifdef CONFIG_PHYLIB ++ unsigned int temp, speed; ++ struct ll_priv *priv = dev->priv; ++ struct phy_device *phydev; + +- if (!phydev->link) { +- printf("%s: No link.\n", phydev->dev->name); +- return 0; +- } ++ u32 supported = SUPPORTED_10baseT_Half | ++ SUPPORTED_10baseT_Full | ++ SUPPORTED_100baseT_Half | ++ SUPPORTED_100baseT_Full | ++ SUPPORTED_1000baseT_Half | ++ SUPPORTED_1000baseT_Full; ++ ++ phy_detection(dev); ++ ++ /* interface - look at tsec */ ++ phydev = phy_connect(priv->bus, priv->phyaddr, dev, 0); ++ ++ phydev->supported &= supported; ++ phydev->advertising = phydev->supported; ++ priv->phydev = phydev; ++ phy_config(phydev); ++ phy_startup(phydev); + + switch (phydev->speed) { + case 1000: +- speed = EMMC_LSPD_1000; ++ speed = XTE_EMMC_LINKSPD_1000; + break; + case 100: +- speed = EMMC_LSPD_100; ++ speed = XTE_EMMC_LINKSPD_100; + break; + case 10: +- speed = EMMC_LSPD_10; ++ speed = XTE_EMMC_LINKSPD_10; + break; + default: + return 0; + } + +- if (!ll_temac_indirect_get(regs, TEMAC_EMMC, &emmc_reg)) +- return 0; ++ temp = xps_ll_temac_indirect_get(dev, 0, EMMC); ++ temp &= ~XTE_EMMC_LINKSPEED_MASK; ++ temp |= speed; ++ xps_ll_temac_indirect_set(dev, 0, EMMC, temp); ++ ++ return 1; + +- emmc_reg &= ~EMMC_LSPD_MASK; +- emmc_reg |= speed; ++#else ++ int i; ++ unsigned int result; ++ struct ll_priv *priv = dev->priv; ++ unsigned retries = 10; ++ unsigned int phyreg = 0; + +- if (!ll_temac_indirect_set(regs, TEMAC_EMMC, emmc_reg)) +- return 0; ++ phy_detection(dev); + +- printf("%s: PHY is %s with %dbase%s, %s%s\n", +- dev->name, phydev->drv->name, +- phydev->speed, (phydev->port == PORT_TP) ? "T" : "X", +- (phydev->duplex) ? "FDX" : "HDX", +- (phydev->port == PORT_OTHER) ? ", unkown mode" : ""); ++#ifdef DEBUG ++ read_phy_reg(dev, priv->phyaddr); ++#endif ++ ++ /* wait for link up */ ++ puts("Waiting for link ... "); ++ retries = 20000; ++ while (retries-- && ++ ((xps_ll_temac_hostif_get(dev, 0, priv->phyaddr, 1) ++ & 0x04) != 0x04)) { ++ udelay(100); ++ } ++ ++ phyreg = xps_ll_temac_indirect_get(dev, 0, EMMC) & ++ (~XTE_EMMC_LINKSPEED_MASK); ++ ++ /* get PHY id */ ++ i = (xps_ll_temac_hostif_get(dev, 0, priv->phyaddr, 2) << 16) | ++ xps_ll_temac_hostif_get(dev, 0, priv->phyaddr, 3); ++ debug("LL_TEMAC: Phy ID 0x%x\n", i); ++ ++ /* FIXME this part will be replaced by PHY lib */ ++ /* s3e boards */ ++ if (i == 0x7c0a3) { ++ /* 100BASE-T/FD */ ++ xps_ll_temac_indirect_set(dev, 0, EMMC, ++ (phyreg | XTE_EMMC_LINKSPD_100)); ++ return 1; ++ } ++ ++#if 0 ++ /* Support for Xilinx 1000BASE-X PCS/PMA core */ ++ if (i == 0x0) { ++ /* 1000BASE-X/FD */ ++ xps_ll_temac_indirect_set(dev, 0, EMMC, 0x80000000); ++ /* Clear the Isolate bit from PHY control register */ ++ xps_ll_temac_hostif_set(dev, 0, phy_addr, 0, 0x1140); ++ link = 1; ++ return 1; ++ } ++#endif ++ ++ result = xps_ll_temac_hostif_get(dev, 0, priv->phyaddr, 5); ++ if ((result & 0x8000) == 0x8000) { ++ xps_ll_temac_indirect_set(dev, 0, EMMC, ++ (phyreg | XTE_EMMC_LINKSPD_1000)); ++ printf("1000BASE-T/FD\n"); ++ } else if ((result & 0x4000) == 0x4000) { ++ xps_ll_temac_indirect_set(dev, 0, EMMC, ++ (phyreg | XTE_EMMC_LINKSPD_100)); ++ printf("100BASE-T/FD\n"); ++ } else { ++ /* unsupported mode or auto-negotiation failed */ ++ puts("Unsupported mode or auto-negotiation failed\n"); ++ } + + return 1; ++#endif ++} ++ ++static inline int xps_ll_temac_dma_error(struct eth_device *dev) ++{ ++ int err; ++ struct ll_priv *priv = dev->priv; ++ ++ /* Check for TX and RX channel errrors. */ ++ err = sdma_in_be32(priv, TX_CHNL_STS) & CHNL_STS_ERROR_MASK; ++ err |= sdma_in_be32(priv, RX_CHNL_STS) & CHNL_STS_ERROR_MASK; ++ return err; ++} ++ ++static void xps_ll_temac_reset_dma(struct eth_device *dev) ++{ ++ u32 r; ++ struct ll_priv *priv = dev->priv; ++ ++ /* Soft reset the DMA. */ ++ sdma_out_be32(priv, DMA_CONTROL_REG, DMA_CONTROL_RESET); ++ while (sdma_in_be32(priv, DMA_CONTROL_REG) & DMA_CONTROL_RESET) ++ ; ++ ++ /* Now clear the interrupts. */ ++ r = sdma_in_be32(priv, TX_CHNL_CTRL); ++ r &= ~XLLDMA_CR_IRQ_ALL_EN_MASK; ++ sdma_out_be32(priv, TX_CHNL_CTRL, r); ++ ++ r = sdma_in_be32(priv, RX_CHNL_CTRL); ++ r &= ~XLLDMA_CR_IRQ_ALL_EN_MASK; ++ sdma_out_be32(priv, RX_CHNL_CTRL, r); ++ ++ /* Now ACK pending IRQs. */ ++ sdma_out_be32(priv, TX_IRQ_REG, XLLDMA_IRQ_ALL_MASK); ++ sdma_out_be32(priv, RX_IRQ_REG, XLLDMA_IRQ_ALL_MASK); ++ ++ /* Set tail-ptr mode, disable errors for both channels. */ ++ sdma_out_be32(priv, DMA_CONTROL_REG, ++ XLLDMA_DMACR_TAIL_PTR_EN_MASK | ++ XLLDMA_DMACR_RX_OVERFLOW_ERR_DIS_MASK | ++ XLLDMA_DMACR_TX_OVERFLOW_ERR_DIS_MASK); ++} ++ ++/* bd init */ ++static void xps_ll_temac_bd_init(struct eth_device *dev) ++{ ++ struct ll_priv *priv = dev->priv; ++ ++ memset(&tx_bd, 0, sizeof(tx_bd)); ++ memset(&rx_bd, 0, sizeof(rx_bd)); ++ ++ rx_bd.phys_buf_p = rx_buffer; ++ rx_bd.next_p = &rx_bd; ++ rx_bd.buf_len = PKTSIZE_ALIGN; ++ flush_cache((u32)&rx_bd, sizeof(tx_bd)); ++ flush_cache((u32)rx_bd.phys_buf_p, PKTSIZE_ALIGN); ++ ++ sdma_out_be32(priv, RX_CURDESC_PTR, (u32)&rx_bd); ++ sdma_out_be32(priv, RX_TAILDESC_PTR, (u32)&rx_bd); ++ sdma_out_be32(priv, RX_NXTDESC_PTR, (u32)&rx_bd); /* setup first fd */ ++ ++ tx_bd.phys_buf_p = tx_buffer; ++ tx_bd.next_p = &tx_bd; ++ ++ flush_cache((u32)&tx_bd, sizeof(tx_bd)); ++ sdma_out_be32(priv, TX_CURDESC_PTR, (u32)&tx_bd); ++} ++ ++static int ll_temac_send_sdma(struct eth_device *dev, ++ void *buffer, int length) ++{ ++ struct ll_priv *priv = dev->priv; ++ ++ if (xps_ll_temac_dma_error(dev)) { ++ xps_ll_temac_reset_dma(dev); ++ xps_ll_temac_bd_init(dev); ++ } ++ ++ memcpy(tx_buffer, (void *)buffer, length); ++ flush_cache((u32)tx_buffer, length); ++ ++ tx_bd.stat = BDSTAT_SOP_MASK | BDSTAT_EOP_MASK | ++ BDSTAT_STOP_ON_END_MASK; ++ tx_bd.buf_len = length; ++ flush_cache((u32)&tx_bd, sizeof(tx_bd)); ++ ++ sdma_out_be32(priv, TX_CURDESC_PTR, (u32)&tx_bd); ++ sdma_out_be32(priv, TX_TAILDESC_PTR, (u32)&tx_bd); /* DMA start */ ++ ++ do { ++ flush_cache((u32)&tx_bd, sizeof(tx_bd)); ++ } while (!(tx_bd.stat & BDSTAT_COMPLETED_MASK)); ++ ++ return 0; ++} ++ ++static int ll_temac_recv_sdma(struct eth_device *dev) ++{ ++ int length; ++ struct ll_priv *priv = dev->priv; ++ ++ if (xps_ll_temac_dma_error(dev)) { ++ xps_ll_temac_reset_dma(dev); ++ xps_ll_temac_bd_init(dev); ++ } ++ ++ flush_cache((u32)&rx_bd, sizeof(rx_bd)); ++ ++ if (!(rx_bd.stat & BDSTAT_COMPLETED_MASK)) ++ return 0; ++ ++ /* ++ * Read out the packet info and start the DMA ++ * onto the second buffer to enable the ethernet rx ++ * path to run in parallel with sw processing ++ * packets. ++ */ ++ length = rx_bd.app5 & 0x3FFF; /* max length mask */ ++ if (length > 0) ++ NetReceive(rx_bd.phys_buf_p, length); ++ ++ /* flip the buffer and re-enable the DMA. */ ++ flush_cache((u32)rx_bd.phys_buf_p, length); ++ ++ rx_bd.buf_len = PKTSIZE_ALIGN; ++ rx_bd.stat = 0; ++ rx_bd.app5 = 0; ++ ++ flush_cache((u32)&rx_bd, sizeof(rx_bd)); ++ sdma_out_be32(priv, RX_TAILDESC_PTR, (u32)&rx_bd); ++ ++ return length; ++} ++ ++#ifdef DEBUG ++static void debugll(struct eth_device *dev, int count) ++{ ++ struct ll_priv *priv = dev->priv; ++ struct ll_fifo_s *ll_fifo = (void *)priv->ctrl; ++ ++ printf("%d fifo isr 0x%08x, fifo_ier 0x%08x, fifo_rdfr 0x%08x, " ++ "fifo_rdfo 0x%08x fifo_rlr 0x%08x\n", count, ++ in_be32(&ll_fifo->isr), in_be32(&ll_fifo->ier), ++ in_be32(&ll_fifo->rdfr), in_be32(&ll_fifo->rdfo), ++ in_be32(&ll_fifo->rlf)); ++} ++#endif ++ ++static int ll_temac_send_fifo(struct eth_device *dev, ++ void *buffer, int length) ++{ ++ struct ll_priv *priv = dev->priv; ++ struct ll_fifo_s *ll_fifo = (void *)priv->ctrl; ++ u32 *buf = (u32 *)buffer; ++ u32 i; ++ ++ for (i = 0; i < length; i += 4) ++ out_be32(&ll_fifo->tdfd, *buf++); ++ ++ out_be32(&ll_fifo->tlf, length); ++ return 0; ++} ++ ++static int ll_temac_recv_fifo(struct eth_device *dev) ++{ ++ struct ll_priv *priv = dev->priv; ++ struct ll_fifo_s *ll_fifo = (void *)priv->ctrl; ++ u32 i, len = 0; ++ u32 *buf = (u32 *)&rx_buffer; ++ ++ if (in_be32(&ll_fifo->isr) & LL_FIFO_ISR_RC_COMPLETE) { ++ out_be32(&ll_fifo->isr, 0xffffffff); /* reset isr */ ++ ++ len = in_be32(&ll_fifo->rlf) & 0x7FF; ++ ++ for (i = 0; i < len; i += 4) ++ *buf++ = in_be32(&ll_fifo->rdfd); ++ ++#ifdef DEBUG ++ debugll(dev, 1); ++#endif ++ NetReceive((uchar *)&rx_buffer, len); ++ } ++ return len; + } + + /* setup mac addr */ +-static int ll_temac_setup_mac_addr(struct eth_device *dev) ++static int ll_temac_addr_setup(struct eth_device *dev) + { +- struct temac_reg *regs = (struct temac_reg *)dev->iobase; +- u32 val; ++ int val; + + /* set up unicast MAC address filter */ + val = ((dev->enetaddr[3] << 24) | (dev->enetaddr[2] << 16) | +- (dev->enetaddr[1] << 8) | (dev->enetaddr[0])); +- val &= UAW0_UADDR_MASK; ++ (dev->enetaddr[1] << 8) | (dev->enetaddr[0])); ++ xps_ll_temac_indirect_set(dev, 0, UAW0, val); ++ val = (dev->enetaddr[5] << 8) | dev->enetaddr[4] ; ++ xps_ll_temac_indirect_set(dev, 0, UAW1, val); + +- if (!ll_temac_indirect_set(regs, TEMAC_UAW0, val)) +- return 1; ++ return 0; ++} + +- val = ((dev->enetaddr[5] << 8) | dev->enetaddr[4]); +- val &= UAW1_UADDR_MASK; ++static int xps_ll_temac_init(struct eth_device *dev, bd_t *bis) ++{ ++ struct ll_priv *priv = dev->priv; ++ struct ll_fifo_s *ll_fifo = (void *)priv->ctrl; + +- if (!ll_temac_indirect_set(regs, TEMAC_UAW1, val)) +- return 1; ++ if (priv->mode & SDMA_BIT) { ++ xps_ll_temac_reset_dma(dev); ++ xps_ll_temac_bd_init(dev); ++ } else { ++ out_be32(&ll_fifo->tdfr, 0x000000a5); /* Fifo reset key */ ++ out_be32(&ll_fifo->rdfr, 0x000000a5); /* Fifo reset key */ ++ out_be32(&ll_fifo->isr, 0xFFFFFFFF); /* Reset status register */ ++ out_be32(&ll_fifo->ier, 0); /* Disable all IRQs */ ++ } + ++ xps_ll_temac_indirect_set(dev, 0, MC, ++ MDIO_ENABLE_MASK | MDIO_CLOCK_DIV_100MHz); ++ ++ /* Promiscuous mode disable */ ++ xps_ll_temac_indirect_set(dev, 0, AFM, 0); ++ /* Enable Receiver - RX bit */ ++ xps_ll_temac_indirect_set(dev, 0, RCW1, 0x10000000); ++ /* Enable Transmitter - TX bit */ ++ xps_ll_temac_indirect_set(dev, 0, TC, 0x10000000); + return 0; + } + + /* halt device */ + static void ll_temac_halt(struct eth_device *dev) + { +- struct ll_temac *ll_temac = dev->priv; +- struct temac_reg *regs = (struct temac_reg *)dev->iobase; ++#ifdef ETH_HALTING ++ struct ll_priv *priv = dev->priv; + + /* Disable Receiver */ +- ll_temac_indirect_set(regs, TEMAC_RCW0, 0); +- ++ xps_ll_temac_indirect_set(dev, 0, RCW1, 0); + /* Disable Transmitter */ +- ll_temac_indirect_set(regs, TEMAC_TC, 0); +- +- if (ll_temac->ctrlhalt) +- ll_temac->ctrlhalt(dev); ++ xps_ll_temac_indirect_set(dev, 0, TC, 0); + +- /* Shut down the PHY, as needed */ +- phy_shutdown(ll_temac->phydev); ++ if (priv->mode & SDMA_BIT) { ++ sdma_out_be32(priv->ctrl, DMA_CONTROL_REG, DMA_CONTROL_RESET); ++ while (sdma_in_be32(priv->ctrl, DMA_CONTROL_REG) ++ & DMA_CONTROL_RESET) ++ ; ++ } ++#endif + } + + static int ll_temac_init(struct eth_device *dev, bd_t *bis) + { +- struct ll_temac *ll_temac = dev->priv; +- int ret; ++#if DEBUG ++ int i; ++#endif ++ xps_ll_temac_init(dev, bis); + + printf("%s: Xilinx XPS LocalLink Tri-Mode Ether MAC #%d at 0x%08X.\n", +- dev->name, dev->index, dev->iobase); +- +- if (!ll_temac_setup_ctrl(dev)) +- return -1; ++ dev->name, 0, dev->iobase); + +- /* Start up the PHY */ +- ret = phy_startup(ll_temac->phydev); +- if (ret) { +- printf("%s: Could not initialize PHY %s\n", +- dev->name, ll_temac->phydev->dev->name); +- return ret; +- } ++#if DEBUG ++ for (i = 0; i < 32; i++) ++ read_phy_reg(dev, i); ++#endif + +- if (!ll_temac_adjust_link(dev)) { ++ if (!xps_ll_temac_phy_ctrl(dev)) { + ll_temac_halt(dev); + return -1; + } + +- /* If there's no link, fail */ +- return ll_temac->phydev->link ? 0 : -1; ++ return 0; + } + +-/* +- * Discover which PHY is attached to the device, and configure it +- * properly. If the PHY is not recognized, then return 0 +- * (failure). Otherwise, return 1 +- */ +-static int ll_temac_phy_init(struct eth_device *dev) ++static int ll_temac_miiphy_read(const char *devname, uchar addr, ++ uchar reg, ushort *val) + { +- struct ll_temac *ll_temac = dev->priv; +- struct phy_device *phydev; +- unsigned int supported = PHY_GBIT_FEATURES; ++ struct eth_device *dev = eth_get_dev(); + +- /* interface - look at driver/net/tsec.c */ +- phydev = phy_connect(ll_temac->bus, ll_temac->phyaddr, +- dev, PHY_INTERFACE_MODE_NONE); ++ *val = xps_ll_temac_hostif_get(dev, 0, addr, reg); /* emac = 0 */ + +- phydev->supported &= supported; +- phydev->advertising = phydev->supported; ++ debug("%s 0x%x, 0x%x, 0x%x\n", __func__, addr, reg, *val); ++ return 0; ++} + +- ll_temac->phydev = phydev; ++static int ll_temac_miiphy_write(const char *devname, uchar addr, ++ uchar reg, ushort val) ++{ ++ struct eth_device *dev = eth_get_dev(); + +- phy_config(phydev); ++ debug("%s 0x%x, 0x%x, 0x%x\n", __func__, addr, reg, val); + +- return 1; ++ xps_ll_temac_hostif_set(dev, 0, addr, reg, val); ++ ++ return 0; + } + +-/* +- * Initialize a single ll_temac devices +- * +- * Returns the result of ll_temac phy interface that were initialized +- */ +-int xilinx_ll_temac_initialize(bd_t *bis, struct ll_temac_info *devinf) ++static int ll_temac_bus_reset(struct mii_dev *bus) ++{ ++ debug("Just bus reset\n"); ++ return 0; ++} ++ ++/* mode bits: 0bit - fifo(0)/sdma(1):SDMA_BIT, 1bit - no dcr(0)/dcr(1):DCR_BIT ++ * ctrl - control address for file/sdma */ ++int xilinx_ll_temac_initialize(bd_t *bis, unsigned long base_addr, ++ int mode, unsigned long ctrl) + { + struct eth_device *dev; +- struct ll_temac *ll_temac; ++ struct ll_priv *priv; + + dev = calloc(1, sizeof(*dev)); + if (dev == NULL) +- return 0; ++ return -1; + +- ll_temac = calloc(1, sizeof(struct ll_temac)); +- if (ll_temac == NULL) { ++ dev->priv = calloc(1, sizeof(struct ll_priv)); ++ if (dev->priv == NULL) { + free(dev); +- return 0; ++ return -1; + } + +- /* use given name or generate its own unique name */ +- if (devinf->devname) { +- strncpy(dev->name, devinf->devname, sizeof(dev->name)); +- } else { +- snprintf(dev->name, sizeof(dev->name), "lltemac.%lx", devinf->base_addr); +- devinf->devname = dev->name; +- } ++ priv = dev->priv; + +- dev->iobase = devinf->base_addr; ++ sprintf(dev->name, "Xlltem.%lx", base_addr); ++ ++ dev->iobase = base_addr; ++ priv->ctrl = ctrl; ++ priv->mode = mode; ++ ++#ifdef CONFIG_PHY_ADDR ++ priv->phyaddr = CONFIG_PHY_ADDR; ++#else ++ priv->phyaddr = -1; ++#endif + +- dev->priv = ll_temac; + dev->init = ll_temac_init; + dev->halt = ll_temac_halt; +- dev->write_hwaddr = ll_temac_setup_mac_addr; +- +- ll_temac->ctrladdr = devinf->ctrl_addr; +- if (devinf->flags & XILINX_LL_TEMAC_M_SDMA_PLB) { +-#if defined(CONFIG_XILINX_440) || defined(CONFIG_XILINX_405) +- if (devinf->flags & XILINX_LL_TEMAC_M_SDMA_DCR) { +- ll_temac_collect_xldcr_sdma_reg_addr(dev); +- ll_temac->in32 = ll_temac_xldcr_in32; +- ll_temac->out32 = ll_temac_xldcr_out32; +- } else +-#endif +- { +- ll_temac_collect_xlplb_sdma_reg_addr(dev); +- ll_temac->in32 = ll_temac_xlplb_in32; +- ll_temac->out32 = ll_temac_xlplb_out32; +- } +- ll_temac->ctrlinit = ll_temac_init_sdma; +- ll_temac->ctrlhalt = ll_temac_halt_sdma; +- ll_temac->ctrlreset = ll_temac_reset_sdma; +- dev->recv = ll_temac_recv_sdma; ++ dev->write_hwaddr = ll_temac_addr_setup; ++ ++ if (priv->mode & SDMA_BIT) { + dev->send = ll_temac_send_sdma; ++ dev->recv = ll_temac_recv_sdma; + } else { +- ll_temac->in32 = NULL; +- ll_temac->out32 = NULL; +- ll_temac->ctrlinit = NULL; +- ll_temac->ctrlhalt = NULL; +- ll_temac->ctrlreset = ll_temac_reset_fifo; +- dev->recv = ll_temac_recv_fifo; + dev->send = ll_temac_send_fifo; ++ dev->recv = ll_temac_recv_fifo; + } + +- /* Link to specified MDIO bus */ +- strncpy(ll_temac->mdio_busname, devinf->mdio_busname, MDIO_NAME_LEN); +- ll_temac->bus = miiphy_get_dev_by_name(ll_temac->mdio_busname); +- +- /* Looking for a valid PHY address if it is not yet set */ +- if (devinf->phyaddr == -1) +- ll_temac->phyaddr = ll_temac_phy_addr(ll_temac->bus); +- else +- ll_temac->phyaddr = devinf->phyaddr; +- + eth_register(dev); + +- /* Try to initialize PHY here, and return */ +- return ll_temac_phy_init(dev); +-} +- +-/* +- * Initialize a single ll_temac device with its mdio bus behind ll_temac +- * +- * Returns 1 if the ll_temac device and the mdio bus were initialized +- * otherwise returns 0 +- */ +-int xilinx_ll_temac_eth_init(bd_t *bis, unsigned long base_addr, int flags, +- unsigned long ctrl_addr) +-{ +- struct ll_temac_info devinf; +- struct ll_temac_mdio_info mdioinf; +- int ret; +- +- /* prepare the internal driver informations */ +- devinf.flags = flags; +- devinf.base_addr = base_addr; +- devinf.ctrl_addr = ctrl_addr; +- devinf.devname = NULL; +- devinf.phyaddr = -1; +- +- mdioinf.name = devinf.mdio_busname = NULL; +- mdioinf.regs = (struct temac_reg *)devinf.base_addr; +- +- ret = xilinx_ll_temac_mdio_initialize(bis, &mdioinf); +- if (ret >= 0) { +- +- /* +- * If there was no MDIO bus name then take over the +- * new automaticaly generated by the MDIO init code. +- */ +- if (mdioinf.name != devinf.mdio_busname) +- devinf.mdio_busname = mdioinf.name; +- +- ret = xilinx_ll_temac_initialize(bis, &devinf); +- if (ret > 0) +- return 1; +- +- } +- +- return 0; ++#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB) ++ miiphy_register(dev->name, ll_temac_miiphy_read, ll_temac_miiphy_write); ++ priv->bus = miiphy_get_dev_by_name(dev->name); ++ priv->bus->reset = ll_temac_bus_reset; ++#endif ++ return 1; + } +diff --git a/drivers/net/xilinx_ll_temac.h b/drivers/net/xilinx_ll_temac.h +deleted file mode 100644 +index ece3b60..0000000 +--- a/drivers/net/xilinx_ll_temac.h ++++ /dev/null +@@ -1,310 +0,0 @@ +-/* +- * Xilinx xps_ll_temac ethernet driver for u-boot +- * +- * LL_TEMAC interface +- * +- * Copyright (C) 2011 - 2012 Stephan Linz +- * Copyright (C) 2008 - 2011 Michal Simek +- * Copyright (C) 2008 - 2011 PetaLogix +- * +- * Based on Yoshio Kashiwagi kashiwagi@co-nss.co.jp driver +- * Copyright (C) 2008 Nissin Systems Co.,Ltd. +- * March 2008 created +- * +- * 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. +- * +- * [0]: http://www.xilinx.com/support/documentation +- * +- * [S]: [0]/ip_documentation/xps_ll_temac.pdf +- * [A]: [0]/application_notes/xapp1041.pdf +- */ +-#ifndef _XILINX_LL_TEMAC_ +-#define _XILINX_LL_TEMAC_ +- +-#include +-#include +-#include +-#include +- +-#include +-#include +- +-#include "xilinx_ll_temac_sdma.h" +- +-#if !defined(__BIG_ENDIAN) +-# error LL_TEMAC requires big endianess +-#endif +- +-/* +- * TEMAC Memory and Register Definition +- * +- * [1]: [0]/ip_documentation/xps_ll_temac.pdf +- * page 19, Memory and Register Descriptions +- */ +-struct temac_reg { +- /* direct soft registers (low part) */ +- u32 raf; /* Reset and Address Filter */ +- u32 tpf; /* Transmit Pause Frame */ +- u32 ifgp; /* Transmit Inter Frame Gap Adjustment */ +- u32 is; /* Interrupt Status */ +- u32 ip; /* Interrupt Pending */ +- u32 ie; /* Interrupt Enable */ +- u32 ttag; /* Transmit VLAN Tag */ +- u32 rtag; /* Receive VLAN Tag */ +- /* hard TEMAC registers */ +- u32 msw; /* Most Significant Word Data */ +- u32 lsw; /* Least Significant Word Data */ +- u32 ctl; /* Control */ +- u32 rdy; /* Ready Status */ +- /* direct soft registers (high part) */ +- u32 uawl; /* Unicast Address Word Lower */ +- u32 uawu; /* Unicast Address Word Upper */ +- u32 tpid0; /* VLAN TPID Word 0 */ +- u32 tpid1; /* VLAN TPID Word 1 */ +-}; +- +-/* Reset and Address Filter Registers (raf), [1] p25 */ +-#define RAF_SR (1 << 13) +-#define RAF_EMFE (1 << 12) +-#define RAF_NFE (1 << 11) +-#define RAF_RVSTM_POS 9 +-#define RAF_RVSTM_MASK (3 << RAF_RVSTM_POS) +-#define RAF_TVSTM_POS 7 +-#define RAF_TVSTM_MASK (3 << RAF_TVSTM_POS) +-#define RAF_RVTM_POS 5 +-#define RAF_RVTM_MASK (3 << RAF_RVTM_POS) +-#define RAF_TVTM_POS 3 +-#define RAF_TVTM_MASK (3 << RAF_TVTM_POS) +-#define RAF_BCREJ (1 << 2) +-#define RAF_MCREJ (1 << 1) +-#define RAF_HTRST (1 << 0) +- +-/* Transmit Pause Frame Registers (tpf), [1] p28 */ +-#define TPF_TPFV_POS 0 +-#define TPF_TPFV_MASK (0xFFFF << TPF_TPFV_POS) +- +-/* Transmit Inter Frame Gap Adjustment Registers (ifgp), [1] p28 */ +-#define IFGP_POS 0 +-#define IFGP_MASK (0xFF << IFGP_POS) +- +-/* Interrupt Status, Pending, Enable Registers (is, ip, ie), [1] p29-33 */ +-#define ISPE_MR (1 << 7) +-#define ISPE_RDL (1 << 6) +-#define ISPE_TC (1 << 5) +-#define ISPE_RFO (1 << 4) +-#define ISPE_RR (1 << 3) +-#define ISPE_RC (1 << 2) +-#define ISPE_AN (1 << 1) +-#define ISPE_HAC (1 << 0) +- +-/* Transmit, Receive VLAN Tag Registers (ttag, rtag), [1] p34-35 */ +-#define TRTAG_TPID_POS 16 +-#define TRTAG_TPID_MASK (0xFFFF << TRTAG_TPID_POS) +-#define TRTAG_PRIO_POS 13 +-#define TRTAG_PRIO_MASK (7 << TRTAG_PRIO_POS) +-#define TRTAG_CFI (1 << 12) +-#define TRTAG_VID_POS 0 +-#define TRTAG_VID_MASK (0xFFF << TRTAG_VID_POS) +- +-/* Most, Least Significant Word Data Register (msw, lsw), [1] p46 */ +-#define MLSW_POS 0 +-#define MLSW_MASK (~0UL << MLSW_POS) +- +-/* LSW Data Register for PHY addresses (lsw), [1] p66 */ +-#define LSW_REGAD_POS 0 +-#define LSW_REGAD_MASK (0x1F << LSW_REGAD_POS) +-#define LSW_PHYAD_POS 5 +-#define LSW_PHYAD_MASK (0x1F << LSW_PHYAD_POS) +- +-/* LSW Data Register for PHY data (lsw), [1] p66 */ +-#define LSW_REGDAT_POS 0 +-#define LSW_REGDAT_MASK (0xFFFF << LSW_REGDAT_POS) +- +-/* Control Register (ctl), [1] p47 */ +-#define CTL_WEN (1 << 15) +-#define CTL_ADDR_POS 0 +-#define CTL_ADDR_MASK (0x3FF << CTL_ADDR_POS) +- +-/* Ready Status Register Ethernet (rdy), [1] p48 */ +-#define RSE_HACS_RDY (1 << 14) +-#define RSE_CFG_WR (1 << 6) +-#define RSE_CFG_RR (1 << 5) +-#define RSE_AF_WR (1 << 4) +-#define RSE_AF_RR (1 << 3) +-#define RSE_MIIM_WR (1 << 2) +-#define RSE_MIIM_RR (1 << 1) +-#define RSE_FABR_RR (1 << 0) +- +-/* Unicast Address Word Lower, Upper Registers (uawl, uawu), [1] p35-36 */ +-#define UAWL_UADDR_POS 0 +-#define UAWL_UADDR_MASK (~0UL << UAWL_UADDR_POS) +-#define UAWU_UADDR_POS 0 +-#define UAWU_UADDR_MASK (0xFFFF << UAWU_UADDR_POS) +- +-/* VLAN TPID Word 0, 1 Registers (tpid0, tpid1), [1] p37 */ +-#define TPID0_V0_POS 0 +-#define TPID0_V0_MASK (0xFFFF << TPID0_V0_POS) +-#define TPID0_V1_POS 16 +-#define TPID0_V1_MASK (0xFFFF << TPID0_V1_POS) +-#define TPID1_V2_POS 0 +-#define TPID1_V2_MASK (0xFFFF << TPID1_V2_POS) +-#define TPID1_V3_POS 16 +-#define TPID1_V3_MASK (0xFFFF << TPID1_V3_POS) +- +-/* +- * TEMAC Indirectly Addressable Register Index Enumeration +- * +- * [0]: http://www.xilinx.com/support/documentation +- * +- * [1]: [0]/ip_documentation/xps_ll_temac.pdf +- * page 23, PLB Indirectly Addressable TEMAC Registers +- */ +-enum temac_ctrl { +- TEMAC_RCW0 = 0x200, +- TEMAC_RCW1 = 0x240, +- TEMAC_TC = 0x280, +- TEMAC_FCC = 0x2C0, +- TEMAC_EMMC = 0x300, +- TEMAC_PHYC = 0x320, +- TEMAC_MC = 0x340, +- TEMAC_UAW0 = 0x380, +- TEMAC_UAW1 = 0x384, +- TEMAC_MAW0 = 0x388, +- TEMAC_MAW1 = 0x38C, +- TEMAC_AFM = 0x390, +- TEMAC_TIS = 0x3A0, +- TEMAC_TIE = 0x3A4, +- TEMAC_MIIMWD = 0x3B0, +- TEMAC_MIIMAI = 0x3B4 +-}; +- +-/* Receive Configuration Word 0, 1 Registers (RCW0, RCW1), [1] p50-51 */ +-#define RCW0_PADDR_POS 0 +-#define RCW0_PADDR_MASK (~0UL << RCW_PADDR_POS) +-#define RCW1_RST (1 << 31) +-#define RCW1_JUM (1 << 30) +-#define RCW1_FCS (1 << 29) +-#define RCW1_RX (1 << 28) +-#define RCW1_VLAN (1 << 27) +-#define RCW1_HD (1 << 26) +-#define RCW1_LT_DIS (1 << 25) +-#define RCW1_PADDR_POS 0 +-#define RCW1_PADDR_MASK (0xFFFF << RCW_PADDR_POS) +- +-/* Transmit Configuration Registers (TC), [1] p52 */ +-#define TC_RST (1 << 31) +-#define TC_JUM (1 << 30) +-#define TC_FCS (1 << 29) +-#define TC_TX (1 << 28) +-#define TC_VLAN (1 << 27) +-#define TC_HD (1 << 26) +-#define TC_IFG (1 << 25) +- +-/* Flow Control Configuration Registers (FCC), [1] p54 */ +-#define FCC_FCTX (1 << 30) +-#define FCC_FCRX (1 << 29) +- +-/* Ethernet MAC Mode Configuration Registers (EMMC), [1] p54 */ +-#define EMMC_LSPD_POS 30 +-#define EMMC_LSPD_MASK (3 << EMMC_LSPD_POS) +-#define EMMC_LSPD_1000 (2 << EMMC_LSPD_POS) +-#define EMMC_LSPD_100 (1 << EMMC_LSPD_POS) +-#define EMMC_LSPD_10 0 +-#define EMMC_RGMII (1 << 29) +-#define EMMC_SGMII (1 << 28) +-#define EMMC_GPCS (1 << 27) +-#define EMMC_HOST (1 << 26) +-#define EMMC_TX16 (1 << 25) +-#define EMMC_RX16 (1 << 24) +- +-/* RGMII/SGMII Configuration Registers (PHYC), [1] p56 */ +-#define PHYC_SLSPD_POS 30 +-#define PHYC_SLSPD_MASK (3 << EMMC_SLSPD_POS) +-#define PHYC_SLSPD_1000 (2 << EMMC_SLSPD_POS) +-#define PHYC_SLSPD_100 (1 << EMMC_SLSPD_POS) +-#define PHYC_SLSPD_10 0 +-#define PHYC_RLSPD_POS 2 +-#define PHYC_RLSPD_MASK (3 << EMMC_RLSPD_POS) +-#define PHYC_RLSPD_1000 (2 << EMMC_RLSPD_POS) +-#define PHYC_RLSPD_100 (1 << EMMC_RLSPD_POS) +-#define PHYC_RLSPD_10 0 +-#define PHYC_RGMII_HD (1 << 1) +-#define PHYC_RGMII_LINK (1 << 0) +- +-/* Management Configuration Registers (MC), [1] p57 */ +-#define MC_MDIOEN (1 << 6) +-#define MC_CLKDIV_POS 0 +-#define MC_CLKDIV_MASK (0x3F << MC_CLKDIV_POS) +- +-/* +- * fHOSTCLK fMDC = fHOSTCLK +- * fMDC = ------------------- ---------> MC_CLKDIV = -------- - 1 +- * (1 + MC_CLKDIV) * 2 2.5 MHz 5MHz +- */ +-#define MC_CLKDIV(f, m) ((f / (2 * m)) - 1) +-#define MC_CLKDIV_25(f) MC_CLKDIV(f, 2500000) +-#define MC_CLKDIV_20(f) MC_CLKDIV(f, 2000000) +-#define MC_CLKDIV_15(f) MC_CLKDIV(f, 1500000) +-#define MC_CLKDIV_10(f) MC_CLKDIV(f, 1000000) +- +-/* Unicast Address Word 0, 1 Registers (UAW0, UAW1), [1] p58-59 */ +-#define UAW0_UADDR_POS 0 +-#define UAW0_UADDR_MASK (~0UL << UAW0_UADDR_POS) +-#define UAW1_UADDR_POS 0 +-#define UAW1_UADDR_MASK (0xFFFF << UAW1_UADDR_POS) +- +-/* Multicast Address Word 0, 1 Registers (MAW0, MAW1), [1] p60 */ +-#define MAW0_MADDR_POS 0 +-#define MAW0_MADDR_MASK (~0UL << MAW0_MADDR_POS) +-#define MAW1_RNW (1 << 23) +-#define MAW1_MAIDX_POS 16 +-#define MAW1_MAIDX_MASK (3 << MAW1_MAIDX_POS) +-#define MAW1_MADDR_POS 0 +-#define MAW1_MADDR_MASK (0xFFFF << MAW1_MADDR_POS) +- +-/* Address Filter Mode Registers (AFM), [1] p63 */ +-#define AFM_PM (1 << 31) +- +-/* Interrupt Status, Enable Registers (TIS, TIE), [1] p63-65 */ +-#define TISE_CFG_W (1 << 6) +-#define TISE_CFG_R (1 << 5) +-#define TISE_AF_W (1 << 4) +-#define TISE_AF_R (1 << 3) +-#define TISE_MIIM_W (1 << 2) +-#define TISE_MIIM_R (1 << 1) +-#define TISE_FABR_R (1 << 0) +- +-/* MII Management Write Data Registers (MIIMWD), [1] p66 */ +-#define MIIMWD_DATA_POS 0 +-#define MIIMWD_DATA_MASK (0xFFFF << MIIMWD_DATA_POS) +- +-/* Ethernet interface ready status */ +-int ll_temac_check_status(struct temac_reg *regs, u32 mask); +- +-/* Indirect write to ll_temac. */ +-int ll_temac_indirect_set(struct temac_reg *regs, u16 regn, u32 reg_data); +- +-/* Indirect read from ll_temac. */ +-int ll_temac_indirect_get(struct temac_reg *regs, u16 regn, u32* reg_data); +- +-struct ll_temac { +- phys_addr_t ctrladdr; +- phys_addr_t sdma_reg_addr[SDMA_CTRL_REGNUMS]; +- +- unsigned (*in32)(phys_addr_t); +- void (*out32)(phys_addr_t, unsigned); +- +- int (*ctrlinit) (struct eth_device *); +- int (*ctrlhalt) (struct eth_device *); +- int (*ctrlreset) (struct eth_device *); +- +- int phyaddr; +- struct phy_device *phydev; +- struct mii_dev *bus; +- char mdio_busname[MDIO_NAME_LEN]; +-}; +- +-#endif /* _XILINX_LL_TEMAC_ */ +diff --git a/drivers/net/xilinx_ll_temac_fifo.c b/drivers/net/xilinx_ll_temac_fifo.c +deleted file mode 100644 +index d7fd989..0000000 +--- a/drivers/net/xilinx_ll_temac_fifo.c ++++ /dev/null +@@ -1,142 +0,0 @@ +-/* +- * Xilinx xps_ll_temac ethernet driver for u-boot +- * +- * FIFO sub-controller +- * +- * Copyright (C) 2011 - 2012 Stephan Linz +- * Copyright (C) 2008 - 2011 Michal Simek +- * Copyright (C) 2008 - 2011 PetaLogix +- * +- * Based on Yoshio Kashiwagi kashiwagi@co-nss.co.jp driver +- * Copyright (C) 2008 Nissin Systems Co.,Ltd. +- * March 2008 created +- * +- * CREDITS: tsec driver +- * +- * 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. +- * +- * [0]: http://www.xilinx.com/support/documentation +- * +- * [F]: [0]/ip_documentation/xps_ll_fifo.pdf +- * [S]: [0]/ip_documentation/xps_ll_temac.pdf +- * [A]: [0]/application_notes/xapp1041.pdf +- */ +- +-#include +-#include +-#include +- +-#include +-#include +- +-#include "xilinx_ll_temac.h" +-#include "xilinx_ll_temac_fifo.h" +- +-int ll_temac_reset_fifo(struct eth_device *dev) +-{ +- struct ll_temac *ll_temac = dev->priv; +- struct fifo_ctrl *fifo_ctrl = (void *)ll_temac->ctrladdr; +- +- out_be32(&fifo_ctrl->tdfr, LL_FIFO_TDFR_KEY); +- out_be32(&fifo_ctrl->rdfr, LL_FIFO_RDFR_KEY); +- out_be32(&fifo_ctrl->isr, ~0UL); +- out_be32(&fifo_ctrl->ier, 0); +- +- return 0; +-} +- +-int ll_temac_recv_fifo(struct eth_device *dev) +-{ +- int i, length = 0; +- u32 *buf = (u32 *)NetRxPackets[0]; +- struct ll_temac *ll_temac = dev->priv; +- struct fifo_ctrl *fifo_ctrl = (void *)ll_temac->ctrladdr; +- +- if (in_be32(&fifo_ctrl->isr) & LL_FIFO_ISR_RC) { +- +- /* reset isr */ +- out_be32(&fifo_ctrl->isr, ~0UL); +- +- /* +- * MAYBE here: +- * while (fifo_ctrl->isr); +- */ +- +- /* +- * The length is written (into RLR) by the XPS LL FIFO +- * when the packet is received across the RX LocalLink +- * interface and the receive data FIFO had enough +- * locations that all of the packet data has been saved. +- * The RLR should only be read when a receive packet is +- * available for processing (the receive occupancy is +- * not zero). Once the RLR is read, the receive packet +- * data should be read from the receive data FIFO before +- * the RLR is read again. +- * +- * [F] page 17, Receive Length Register (RLR) +- */ +- if (in_be32(&fifo_ctrl->rdfo) & LL_FIFO_RDFO_MASK) { +- length = in_be32(&fifo_ctrl->rlf) & LL_FIFO_RLF_MASK; +- } else { +- printf("%s: Got error, no receive occupancy\n", +- __func__); +- return -1; +- } +- +- if (length > PKTSIZE_ALIGN) { +- printf("%s: Got error, receive package too big (%i)\n", +- __func__, length); +- ll_temac_reset_fifo(dev); +- return -1; +- } +- +- for (i = 0; i < length; i += 4) +- *buf++ = in_be32(&fifo_ctrl->rdfd); +- +- NetReceive(NetRxPackets[0], length); +- } +- +- return 0; +-} +- +-int ll_temac_send_fifo(struct eth_device *dev, void *packet, int length) +-{ +- int i; +- u32 *buf = (u32 *)packet; +- struct ll_temac *ll_temac = dev->priv; +- struct fifo_ctrl *fifo_ctrl = (void *)ll_temac->ctrladdr; +- +- if (length < LL_FIFO_TLF_MIN) { +- printf("%s: Got error, transmit package too small (%i)\n", +- __func__, length); +- return -1; +- } +- +- if (length > LL_FIFO_TLF_MAX) { +- printf("%s: Got error, transmit package too big (%i)\n", +- __func__, length); +- return -1; +- } +- +- for (i = 0; i < length; i += 4) +- out_be32(&fifo_ctrl->tdfd, *buf++); +- +- /* +- * Once the packet length is written to the TLR it is +- * automatically moved to the transmit data FIFO with +- * the packet data freeing up the TLR for another value. +- * The packet length must be written to the TLR after +- * the packet data is written to the transmit data FIFO. +- * It is not valid to write data for multiple packets +- * to the transmit data FIFO before writing the packet +- * length values. +- * +- * [F] page 17, Transmit Length Register (TLR) +- */ +- out_be32(&fifo_ctrl->tlf, length); +- +- return 0; +-} +diff --git a/drivers/net/xilinx_ll_temac_fifo.h b/drivers/net/xilinx_ll_temac_fifo.h +deleted file mode 100644 +index e5b4be9..0000000 +--- a/drivers/net/xilinx_ll_temac_fifo.h ++++ /dev/null +@@ -1,121 +0,0 @@ +-/* +- * Xilinx xps_ll_temac ethernet driver for u-boot +- * +- * FIFO sub-controller interface +- * +- * Copyright (C) 2011 - 2012 Stephan Linz +- * Copyright (C) 2008 - 2011 Michal Simek +- * Copyright (C) 2008 - 2011 PetaLogix +- * +- * Based on Yoshio Kashiwagi kashiwagi@co-nss.co.jp driver +- * Copyright (C) 2008 Nissin Systems Co.,Ltd. +- * March 2008 created +- * +- * 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. +- * +- * [0]: http://www.xilinx.com/support/documentation +- * +- * [S]: [0]/ip_documentation/xps_ll_temac.pdf +- * [A]: [0]/application_notes/xapp1041.pdf +- */ +-#ifndef _XILINX_LL_TEMAC_FIFO_ +-#define _XILINX_LL_TEMAC_FIFO_ +- +-#include +- +-#include +-#include +- +-#if !defined(__BIG_ENDIAN) +-# error LL_TEMAC requires big endianess +-#endif +- +-/* +- * FIFO Register Definition +- * +- * Used for memory mapped access from and to (Rd/Td) the LocalLink (LL) +- * Tri-Mode Ether MAC (TEMAC) via the 2 kb full duplex FIFO Controller, +- * one for each. +- * +- * [1]: [0]/ip_documentation/xps_ll_fifo.pdf +- * page 10, Registers Definition +- */ +-struct fifo_ctrl { +- u32 isr; /* Interrupt Status Register (RW) */ +- u32 ier; /* Interrupt Enable Register (RW) */ +- u32 tdfr; /* Transmit Data FIFO Reset (WO) */ +- u32 tdfv; /* Transmit Data FIFO Vacancy (RO) */ +- u32 tdfd; /* Transmit Data FIFO 32bit wide Data write port (WO) */ +- u32 tlf; /* Transmit Length FIFO (WO) */ +- u32 rdfr; /* Receive Data FIFO Reset (WO) */ +- u32 rdfo; /* Receive Data FIFO Occupancy (RO) */ +- u32 rdfd; /* Receive Data FIFO 32bit wide Data read port (RO) */ +- u32 rlf; /* Receive Length FIFO (RO) */ +- u32 llr; /* LocalLink Reset (WO) */ +-}; +- +-/* Interrupt Status Register (ISR), [1] p11 */ +-#define LL_FIFO_ISR_RPURE (1 << 31) /* Receive Packet Underrun Read Err */ +-#define LL_FIFO_ISR_RPORE (1 << 30) /* Receive Packet Overrun Read Err */ +-#define LL_FIFO_ISR_RPUE (1 << 29) /* Receive Packet Underrun Error */ +-#define LL_FIFO_ISR_TPOE (1 << 28) /* Transmit Packet Overrun Error */ +-#define LL_FIFO_ISR_TC (1 << 27) /* Transmit Complete */ +-#define LL_FIFO_ISR_RC (1 << 26) /* Receive Complete */ +-#define LL_FIFO_ISR_TSE (1 << 25) /* Transmit Size Error */ +-#define LL_FIFO_ISR_TRC (1 << 24) /* Transmit Reset Complete */ +-#define LL_FIFO_ISR_RRC (1 << 23) /* Receive Reset Complete */ +- +-/* Interrupt Enable Register (IER), [1] p12/p13 */ +-#define LL_FIFO_IER_RPURE (1 << 31) /* Receive Packet Underrun Read Err */ +-#define LL_FIFO_IER_RPORE (1 << 30) /* Receive Packet Overrun Read Err */ +-#define LL_FIFO_IER_RPUE (1 << 29) /* Receive Packet Underrun Error */ +-#define LL_FIFO_IER_TPOE (1 << 28) /* Transmit Packet Overrun Error */ +-#define LL_FIFO_IER_TC (1 << 27) /* Transmit Complete */ +-#define LL_FIFO_IER_RC (1 << 26) /* Receive Complete */ +-#define LL_FIFO_IER_TSE (1 << 25) /* Transmit Size Error */ +-#define LL_FIFO_IER_TRC (1 << 24) /* Transmit Reset Complete */ +-#define LL_FIFO_IER_RRC (1 << 23) /* Receive Reset Complete */ +- +-/* Transmit Data FIFO Reset (TDFR), [1] p13/p14 */ +-#define LL_FIFO_TDFR_KEY 0x000000A5UL +- +-/* Transmit Data FIFO Vacancy (TDFV), [1] p14 */ +-#define LL_FIFO_TDFV_POS 0 +-#define LL_FIFO_TDFV_MASK (0x000001FFUL << LL_FIFO_TDFV_POS) +- +-/* Transmit Length FIFO (TLF), [1] p16/p17 */ +-#define LL_FIFO_TLF_POS 0 +-#define LL_FIFO_TLF_MASK (0x000007FFUL << LL_FIFO_TLF_POS) +-#define LL_FIFO_TLF_MIN ((4 * sizeof(u32)) & LL_FIFO_TLF_MASK) +-#define LL_FIFO_TLF_MAX ((510 * sizeof(u32)) & LL_FIFO_TLF_MASK) +- +-/* Receive Data FIFO Reset (RDFR), [1] p15 */ +-#define LL_FIFO_RDFR_KEY 0x000000A5UL +- +-/* Receive Data FIFO Occupancy (RDFO), [1] p16 */ +-#define LL_FIFO_RDFO_POS 0 +-#define LL_FIFO_RDFO_MASK (0x000001FFUL << LL_FIFO_RDFO_POS) +- +-/* Receive Length FIFO (RLF), [1] p17/p18 */ +-#define LL_FIFO_RLF_POS 0 +-#define LL_FIFO_RLF_MASK (0x000007FFUL << LL_FIFO_RLF_POS) +-#define LL_FIFO_RLF_MIN ((4 * sizeof(uint32)) & LL_FIFO_RLF_MASK) +-#define LL_FIFO_RLF_MAX ((510 * sizeof(uint32)) & LL_FIFO_RLF_MASK) +- +-/* LocalLink Reset (LLR), [1] p18 */ +-#define LL_FIFO_LLR_KEY 0x000000A5UL +- +- +-/* reset FIFO and IRQ, disable interrupts */ +-int ll_temac_reset_fifo(struct eth_device *dev); +- +-/* receive buffered data from FIFO (polling ISR) */ +-int ll_temac_recv_fifo(struct eth_device *dev); +- +-/* send buffered data to FIFO */ +-int ll_temac_send_fifo(struct eth_device *dev, void *packet, int length); +- +-#endif /* _XILINX_LL_TEMAC_FIFO_ */ +diff --git a/drivers/net/xilinx_ll_temac_mdio.c b/drivers/net/xilinx_ll_temac_mdio.c +deleted file mode 100644 +index c56ff48..0000000 +--- a/drivers/net/xilinx_ll_temac_mdio.c ++++ /dev/null +@@ -1,180 +0,0 @@ +-/* +- * Xilinx xps_ll_temac ethernet driver for u-boot +- * +- * MDIO bus access +- * +- * Copyright (C) 2011 - 2012 Stephan Linz +- * Copyright (C) 2008 - 2011 Michal Simek +- * Copyright (C) 2008 - 2011 PetaLogix +- * +- * Based on Yoshio Kashiwagi kashiwagi@co-nss.co.jp driver +- * Copyright (C) 2008 Nissin Systems Co.,Ltd. +- * March 2008 created +- * +- * CREDITS: tsec driver +- * +- * 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. +- * +- * [0]: http://www.xilinx.com/support/documentation +- * +- * [S]: [0]/ip_documentation/xps_ll_temac.pdf +- * [A]: [0]/application_notes/xapp1041.pdf +- */ +- +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include "xilinx_ll_temac.h" +-#include "xilinx_ll_temac_mdio.h" +- +-#if !defined(CONFIG_MII) +-# error "LL_TEMAC requires MII -- missing CONFIG_MII" +-#endif +- +-#if !defined(CONFIG_PHYLIB) +-# error "LL_TEMAC requires PHYLIB -- missing CONFIG_PHYLIB" +-#endif +- +-/* +- * Prior to PHY access, the MDIO clock must be setup. This driver will set a +- * safe default that should work with PLB bus speeds of up to 150 MHz and keep +- * the MDIO clock below 2.5 MHz. If the user wishes faster access to the PHY +- * then the clock divisor can be set to a different value by setting the +- * correct bus speed value with CONFIG_XILINX_LL_TEMAC_CLK. +- */ +-#if !defined(CONFIG_XILINX_LL_TEMAC_CLK) +-#define MDIO_CLOCK_DIV MC_CLKDIV_10(150000000) +-#else +-#define MDIO_CLOCK_DIV MC_CLKDIV_25(CONFIG_XILINX_LL_TEMAC_CLK) +-#endif +- +-static int ll_temac_mdio_setup(struct mii_dev *bus) +-{ +- struct temac_reg *regs = (struct temac_reg *)bus->priv; +- +- /* setup MDIO clock */ +- ll_temac_indirect_set(regs, TEMAC_MC, +- MC_MDIOEN | (MDIO_CLOCK_DIV & MC_CLKDIV_MASK)); +- +- return 0; +-} +- +-/* +- * Indirect MII PHY read via ll_temac. +- * +- * http://www.xilinx.com/support/documentation/ip_documentation/xps_ll_temac.pdf +- * page 67, Using the MII Management to Access PHY Registers +- */ +-int ll_temac_local_mdio_read(struct temac_reg *regs, int addr, int devad, +- int regnum) +-{ +- out_be32(®s->lsw, +- ((addr << LSW_PHYAD_POS) & LSW_PHYAD_MASK) | +- (regnum & LSW_REGAD_MASK)); +- out_be32(®s->ctl, TEMAC_MIIMAI); +- +- ll_temac_check_status(regs, RSE_MIIM_RR); +- +- return in_be32(®s->lsw) & LSW_REGDAT_MASK; +-} +- +-/* +- * Indirect MII PHY write via ll_temac. +- * +- * http://www.xilinx.com/support/documentation/ip_documentation/xps_ll_temac.pdf +- * page 67, Using the MII Management to Access PHY Registers +- */ +-void ll_temac_local_mdio_write(struct temac_reg *regs, int addr, int devad, +- int regnum, u16 value) +-{ +- out_be32(®s->lsw, (value & LSW_REGDAT_MASK)); +- out_be32(®s->ctl, CTL_WEN | TEMAC_MIIMWD); +- +- out_be32(®s->lsw, +- ((addr << LSW_PHYAD_POS) & LSW_PHYAD_MASK) | +- (regnum & LSW_REGAD_MASK)); +- out_be32(®s->ctl, CTL_WEN | TEMAC_MIIMAI); +- +- ll_temac_check_status(regs, RSE_MIIM_WR); +-} +- +-int ll_temac_phy_read(struct mii_dev *bus, int addr, int devad, int regnum) +-{ +- struct temac_reg *regs = (struct temac_reg *)bus->priv; +- +- return ll_temac_local_mdio_read(regs, addr, devad, regnum); +-} +- +-int ll_temac_phy_write(struct mii_dev *bus, int addr, int devad, int regnum, +- u16 value) +-{ +- struct temac_reg *regs = (struct temac_reg *)bus->priv; +- +- ll_temac_local_mdio_write(regs, addr, devad, regnum, value); +- +- return 0; +-} +- +-/* +- * Use MII register 1 (MII status register) to detect PHY +- * +- * A Mask used to verify certain PHY features (register content) +- * in the PHY detection register: +- * Auto-negotiation support, 10Mbps half/full duplex support +- */ +-#define PHY_DETECT_REG MII_BMSR +-#define PHY_DETECT_MASK (BMSR_10FULL | BMSR_10HALF | BMSR_ANEGCAPABLE) +- +-/* Looking for a valid PHY address */ +-int ll_temac_phy_addr(struct mii_dev *bus) +-{ +- struct temac_reg *regs = (struct temac_reg *)bus->priv; +- unsigned short val; +- unsigned int phy; +- +- for (phy = PHY_MAX_ADDR; phy >= 0; phy--) { +- val = ll_temac_local_mdio_read(regs, phy, 0, PHY_DETECT_REG); +- if ((val != 0xFFFF) && +- ((val & PHY_DETECT_MASK) == PHY_DETECT_MASK)) { +- /* Found a valid PHY address */ +- return phy; +- } +- } +- +- return -1; +-} +- +-int xilinx_ll_temac_mdio_initialize(bd_t *bis, struct ll_temac_mdio_info *info) +-{ +- struct mii_dev *bus = mdio_alloc(); +- +- if (!bus) { +- printf("Failed to allocate LL_TEMAC MDIO bus: %s\n", +- info->name); +- return -1; +- } +- +- bus->read = ll_temac_phy_read; +- bus->write = ll_temac_phy_write; +- bus->reset = NULL; +- +- /* use given name or generate its own unique name */ +- if (info->name) { +- strncpy(bus->name, info->name, MDIO_NAME_LEN); +- } else { +- snprintf(bus->name, MDIO_NAME_LEN, "lltemii.%p", info->regs); +- info->name = bus->name; +- } +- +- bus->priv = info->regs; +- +- ll_temac_mdio_setup(bus); +- return mdio_register(bus); +-} +diff --git a/drivers/net/xilinx_ll_temac_mdio.h b/drivers/net/xilinx_ll_temac_mdio.h +deleted file mode 100644 +index 8d8fabd..0000000 +--- a/drivers/net/xilinx_ll_temac_mdio.h ++++ /dev/null +@@ -1,53 +0,0 @@ +-/* +- * Xilinx xps_ll_temac ethernet driver for u-boot +- * +- * MDIO bus access interface +- * +- * Copyright (C) 2011 - 2012 Stephan Linz +- * Copyright (C) 2008 - 2011 Michal Simek +- * Copyright (C) 2008 - 2011 PetaLogix +- * +- * Based on Yoshio Kashiwagi kashiwagi@co-nss.co.jp driver +- * Copyright (C) 2008 Nissin Systems Co.,Ltd. +- * March 2008 created +- * +- * 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. +- * +- * [0]: http://www.xilinx.com/support/documentation +- * +- * [S]: [0]/ip_documentation/xps_ll_temac.pdf +- * [A]: [0]/application_notes/xapp1041.pdf +- */ +-#ifndef _XILINX_LL_TEMAC_MDIO_ +-#define _XILINX_LL_TEMAC_MDIO_ +- +-#include +-#include +- +-#include +-#include +- +-#include "xilinx_ll_temac.h" +- +-int ll_temac_local_mdio_read(struct temac_reg *regs, int addr, int devad, +- int regnum); +-void ll_temac_local_mdio_write(struct temac_reg *regs, int addr, int devad, +- int regnum, u16 value); +- +-int ll_temac_phy_read(struct mii_dev *bus, int addr, int devad, int regnum); +-int ll_temac_phy_write(struct mii_dev *bus, int addr, int devad, int regnum, +- u16 value); +- +-int ll_temac_phy_addr(struct mii_dev *bus); +- +-struct ll_temac_mdio_info { +- struct temac_reg *regs; +- char *name; +-}; +- +-int xilinx_ll_temac_mdio_initialize(bd_t *bis, struct ll_temac_mdio_info *info); +- +-#endif /* _XILINX_LL_TEMAC_MDIO_ */ +diff --git a/drivers/net/xilinx_ll_temac_sdma.c b/drivers/net/xilinx_ll_temac_sdma.c +deleted file mode 100644 +index 8637a6b..0000000 +--- a/drivers/net/xilinx_ll_temac_sdma.c ++++ /dev/null +@@ -1,369 +0,0 @@ +-/* +- * Xilinx xps_ll_temac ethernet driver for u-boot +- * +- * SDMA sub-controller +- * +- * Copyright (C) 2011 - 2012 Stephan Linz +- * Copyright (C) 2008 - 2011 Michal Simek +- * Copyright (C) 2008 - 2011 PetaLogix +- * +- * Based on Yoshio Kashiwagi kashiwagi@co-nss.co.jp driver +- * Copyright (C) 2008 Nissin Systems Co.,Ltd. +- * March 2008 created +- * +- * CREDITS: tsec driver +- * +- * 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. +- * +- * [0]: http://www.xilinx.com/support/documentation +- * +- * [M]: [0]/ip_documentation/mpmc.pdf +- * [S]: [0]/ip_documentation/xps_ll_temac.pdf +- * [A]: [0]/application_notes/xapp1041.pdf +- */ +- +-#include +-#include +-#include +- +-#include +-#include +- +-#include "xilinx_ll_temac.h" +-#include "xilinx_ll_temac_sdma.h" +- +-#define TX_BUF_CNT 2 +- +-static unsigned int rx_idx; /* index of the current RX buffer */ +-static unsigned int tx_idx; /* index of the current TX buffer */ +- +-struct rtx_cdmac_bd { +- struct cdmac_bd rx[PKTBUFSRX]; +- struct cdmac_bd tx[TX_BUF_CNT]; +-}; +- +-/* +- * DMA Buffer Descriptor alignment +- * +- * If the address contained in the Next Descriptor Pointer register is not +- * 8-word aligned or reaches beyond the range of available memory, the SDMA +- * halts processing and sets the CDMAC_BD_STCTRL_ERROR bit in the respective +- * status register (tx_chnl_sts or rx_chnl_sts). +- * +- * [1]: [0]/ip_documentation/mpmc.pdf +- * page 161, Next Descriptor Pointer +- */ +-static struct rtx_cdmac_bd cdmac_bd __aligned(32); +- +-#if defined(CONFIG_XILINX_440) || defined(CONFIG_XILINX_405) +- +-/* +- * Indirect DCR access operations mi{ft}dcr_xilinx() espacialy +- * for Xilinx PowerPC implementations on FPGA. +- * +- * FIXME: This part should go up to arch/powerpc -- but where? +- */ +-#include +-#define XILINX_INDIRECT_DCR_ADDRESS_REG 0 +-#define XILINX_INDIRECT_DCR_ACCESS_REG 1 +-inline unsigned mifdcr_xilinx(const unsigned dcrn) +-{ +- mtdcr(XILINX_INDIRECT_DCR_ADDRESS_REG, dcrn); +- return mfdcr(XILINX_INDIRECT_DCR_ACCESS_REG); +-} +-inline void mitdcr_xilinx(const unsigned dcrn, int val) +-{ +- mtdcr(XILINX_INDIRECT_DCR_ADDRESS_REG, dcrn); +- mtdcr(XILINX_INDIRECT_DCR_ACCESS_REG, val); +-} +- +-/* Xilinx Device Control Register (DCR) in/out accessors */ +-inline unsigned ll_temac_xldcr_in32(phys_addr_t addr) +-{ +- return mifdcr_xilinx((const unsigned)addr); +-} +-inline void ll_temac_xldcr_out32(phys_addr_t addr, unsigned value) +-{ +- mitdcr_xilinx((const unsigned)addr, value); +-} +- +-void ll_temac_collect_xldcr_sdma_reg_addr(struct eth_device *dev) +-{ +- struct ll_temac *ll_temac = dev->priv; +- phys_addr_t dmac_ctrl = ll_temac->ctrladdr; +- phys_addr_t *ra = ll_temac->sdma_reg_addr; +- +- ra[TX_NXTDESC_PTR] = dmac_ctrl + TX_NXTDESC_PTR; +- ra[TX_CURBUF_ADDR] = dmac_ctrl + TX_CURBUF_ADDR; +- ra[TX_CURBUF_LENGTH] = dmac_ctrl + TX_CURBUF_LENGTH; +- ra[TX_CURDESC_PTR] = dmac_ctrl + TX_CURDESC_PTR; +- ra[TX_TAILDESC_PTR] = dmac_ctrl + TX_TAILDESC_PTR; +- ra[TX_CHNL_CTRL] = dmac_ctrl + TX_CHNL_CTRL; +- ra[TX_IRQ_REG] = dmac_ctrl + TX_IRQ_REG; +- ra[TX_CHNL_STS] = dmac_ctrl + TX_CHNL_STS; +- ra[RX_NXTDESC_PTR] = dmac_ctrl + RX_NXTDESC_PTR; +- ra[RX_CURBUF_ADDR] = dmac_ctrl + RX_CURBUF_ADDR; +- ra[RX_CURBUF_LENGTH] = dmac_ctrl + RX_CURBUF_LENGTH; +- ra[RX_CURDESC_PTR] = dmac_ctrl + RX_CURDESC_PTR; +- ra[RX_TAILDESC_PTR] = dmac_ctrl + RX_TAILDESC_PTR; +- ra[RX_CHNL_CTRL] = dmac_ctrl + RX_CHNL_CTRL; +- ra[RX_IRQ_REG] = dmac_ctrl + RX_IRQ_REG; +- ra[RX_CHNL_STS] = dmac_ctrl + RX_CHNL_STS; +- ra[DMA_CONTROL_REG] = dmac_ctrl + DMA_CONTROL_REG; +-} +- +-#endif /* CONFIG_XILINX_440 || ONFIG_XILINX_405 */ +- +-/* Xilinx Processor Local Bus (PLB) in/out accessors */ +-inline unsigned ll_temac_xlplb_in32(phys_addr_t addr) +-{ +- return in_be32((void *)addr); +-} +-inline void ll_temac_xlplb_out32(phys_addr_t addr, unsigned value) +-{ +- out_be32((void *)addr, value); +-} +- +-/* collect all register addresses for Xilinx PLB in/out accessors */ +-void ll_temac_collect_xlplb_sdma_reg_addr(struct eth_device *dev) +-{ +- struct ll_temac *ll_temac = dev->priv; +- struct sdma_ctrl *sdma_ctrl = (void *)ll_temac->ctrladdr; +- phys_addr_t *ra = ll_temac->sdma_reg_addr; +- +- ra[TX_NXTDESC_PTR] = (phys_addr_t)&sdma_ctrl->tx_nxtdesc_ptr; +- ra[TX_CURBUF_ADDR] = (phys_addr_t)&sdma_ctrl->tx_curbuf_addr; +- ra[TX_CURBUF_LENGTH] = (phys_addr_t)&sdma_ctrl->tx_curbuf_length; +- ra[TX_CURDESC_PTR] = (phys_addr_t)&sdma_ctrl->tx_curdesc_ptr; +- ra[TX_TAILDESC_PTR] = (phys_addr_t)&sdma_ctrl->tx_taildesc_ptr; +- ra[TX_CHNL_CTRL] = (phys_addr_t)&sdma_ctrl->tx_chnl_ctrl; +- ra[TX_IRQ_REG] = (phys_addr_t)&sdma_ctrl->tx_irq_reg; +- ra[TX_CHNL_STS] = (phys_addr_t)&sdma_ctrl->tx_chnl_sts; +- ra[RX_NXTDESC_PTR] = (phys_addr_t)&sdma_ctrl->rx_nxtdesc_ptr; +- ra[RX_CURBUF_ADDR] = (phys_addr_t)&sdma_ctrl->rx_curbuf_addr; +- ra[RX_CURBUF_LENGTH] = (phys_addr_t)&sdma_ctrl->rx_curbuf_length; +- ra[RX_CURDESC_PTR] = (phys_addr_t)&sdma_ctrl->rx_curdesc_ptr; +- ra[RX_TAILDESC_PTR] = (phys_addr_t)&sdma_ctrl->rx_taildesc_ptr; +- ra[RX_CHNL_CTRL] = (phys_addr_t)&sdma_ctrl->rx_chnl_ctrl; +- ra[RX_IRQ_REG] = (phys_addr_t)&sdma_ctrl->rx_irq_reg; +- ra[RX_CHNL_STS] = (phys_addr_t)&sdma_ctrl->rx_chnl_sts; +- ra[DMA_CONTROL_REG] = (phys_addr_t)&sdma_ctrl->dma_control_reg; +-} +- +-/* Check for TX and RX channel errors. */ +-static inline int ll_temac_sdma_error(struct eth_device *dev) +-{ +- int err; +- struct ll_temac *ll_temac = dev->priv; +- phys_addr_t *ra = ll_temac->sdma_reg_addr; +- +- err = ll_temac->in32(ra[TX_CHNL_STS]) & CHNL_STS_ERROR; +- err |= ll_temac->in32(ra[RX_CHNL_STS]) & CHNL_STS_ERROR; +- +- return err; +-} +- +-int ll_temac_init_sdma(struct eth_device *dev) +-{ +- struct ll_temac *ll_temac = dev->priv; +- struct cdmac_bd *rx_dp; +- struct cdmac_bd *tx_dp; +- phys_addr_t *ra = ll_temac->sdma_reg_addr; +- int i; +- +- printf("%s: SDMA: %d Rx buffers, %d Tx buffers\n", +- dev->name, PKTBUFSRX, TX_BUF_CNT); +- +- /* Initialize the Rx Buffer descriptors */ +- for (i = 0; i < PKTBUFSRX; i++) { +- rx_dp = &cdmac_bd.rx[i]; +- memset(rx_dp, 0, sizeof(*rx_dp)); +- rx_dp->next_p = rx_dp; +- rx_dp->buf_len = PKTSIZE_ALIGN; +- rx_dp->phys_buf_p = (u8 *)NetRxPackets[i]; +- flush_cache((u32)rx_dp->phys_buf_p, PKTSIZE_ALIGN); +- } +- flush_cache((u32)cdmac_bd.rx, sizeof(cdmac_bd.rx)); +- +- /* Initialize the TX Buffer Descriptors */ +- for (i = 0; i < TX_BUF_CNT; i++) { +- tx_dp = &cdmac_bd.tx[i]; +- memset(tx_dp, 0, sizeof(*tx_dp)); +- tx_dp->next_p = tx_dp; +- } +- flush_cache((u32)cdmac_bd.tx, sizeof(cdmac_bd.tx)); +- +- /* Reset index counter to the Rx and Tx Buffer descriptors */ +- rx_idx = tx_idx = 0; +- +- /* initial Rx DMA start by writing to respective TAILDESC_PTR */ +- ll_temac->out32(ra[RX_CURDESC_PTR], (int)&cdmac_bd.rx[rx_idx]); +- ll_temac->out32(ra[RX_TAILDESC_PTR], (int)&cdmac_bd.rx[rx_idx]); +- +- return 0; +-} +- +-int ll_temac_halt_sdma(struct eth_device *dev) +-{ +- unsigned timeout = 50; /* 1usec * 50 = 50usec */ +- struct ll_temac *ll_temac = dev->priv; +- phys_addr_t *ra = ll_temac->sdma_reg_addr; +- +- /* +- * Soft reset the DMA +- * +- * Quote from MPMC documentation: Writing a 1 to this field +- * forces the DMA engine to shutdown and reset itself. After +- * setting this bit, software must poll it until the bit is +- * cleared by the DMA. This indicates that the reset process +- * is done and the pipeline has been flushed. +- */ +- ll_temac->out32(ra[DMA_CONTROL_REG], DMA_CONTROL_RESET); +- while (timeout && (ll_temac->in32(ra[DMA_CONTROL_REG]) +- & DMA_CONTROL_RESET)) { +- timeout--; +- udelay(1); +- } +- +- if (!timeout) { +- printf("%s: Timeout\n", __func__); +- return -1; +- } +- +- return 0; +-} +- +-int ll_temac_reset_sdma(struct eth_device *dev) +-{ +- u32 r; +- struct ll_temac *ll_temac = dev->priv; +- phys_addr_t *ra = ll_temac->sdma_reg_addr; +- +- /* Soft reset the DMA. */ +- if (ll_temac_halt_sdma(dev)) +- return -1; +- +- /* Now clear the interrupts. */ +- r = ll_temac->in32(ra[TX_CHNL_CTRL]); +- r &= ~CHNL_CTRL_IRQ_MASK; +- ll_temac->out32(ra[TX_CHNL_CTRL], r); +- +- r = ll_temac->in32(ra[RX_CHNL_CTRL]); +- r &= ~CHNL_CTRL_IRQ_MASK; +- ll_temac->out32(ra[RX_CHNL_CTRL], r); +- +- /* Now ACK pending IRQs. */ +- ll_temac->out32(ra[TX_IRQ_REG], IRQ_REG_IRQ_MASK); +- ll_temac->out32(ra[RX_IRQ_REG], IRQ_REG_IRQ_MASK); +- +- /* Set tail-ptr mode, disable errors for both channels. */ +- ll_temac->out32(ra[DMA_CONTROL_REG], +- /* Enable use of tail pointer register */ +- DMA_CONTROL_TPE | +- /* Disable error when 2 or 4 bit coalesce cnt overfl */ +- DMA_CONTROL_RXOCEID | +- /* Disable error when 2 or 4 bit coalesce cnt overfl */ +- DMA_CONTROL_TXOCEID); +- +- return 0; +-} +- +-int ll_temac_recv_sdma(struct eth_device *dev) +-{ +- int length, pb_idx; +- struct cdmac_bd *rx_dp = &cdmac_bd.rx[rx_idx]; +- struct ll_temac *ll_temac = dev->priv; +- phys_addr_t *ra = ll_temac->sdma_reg_addr; +- +- if (ll_temac_sdma_error(dev)) { +- +- if (ll_temac_reset_sdma(dev)) +- return -1; +- +- ll_temac_init_sdma(dev); +- } +- +- flush_cache((u32)rx_dp, sizeof(*rx_dp)); +- +- if (!(rx_dp->sca.stctrl & CDMAC_BD_STCTRL_COMPLETED)) +- return 0; +- +- if (rx_dp->sca.stctrl & (CDMAC_BD_STCTRL_SOP | CDMAC_BD_STCTRL_EOP)) { +- pb_idx = rx_idx; +- length = rx_dp->sca.app[4] & CDMAC_BD_APP4_RXBYTECNT_MASK; +- } else { +- pb_idx = -1; +- length = 0; +- printf("%s: Got part of package, unsupported (%x)\n", +- __func__, rx_dp->sca.stctrl); +- } +- +- /* flip the buffer */ +- flush_cache((u32)rx_dp->phys_buf_p, length); +- +- /* reset the current descriptor */ +- rx_dp->sca.stctrl = 0; +- rx_dp->sca.app[4] = 0; +- flush_cache((u32)rx_dp, sizeof(*rx_dp)); +- +- /* Find next empty buffer descriptor, preparation for next iteration */ +- rx_idx = (rx_idx + 1) % PKTBUFSRX; +- rx_dp = &cdmac_bd.rx[rx_idx]; +- flush_cache((u32)rx_dp, sizeof(*rx_dp)); +- +- /* DMA start by writing to respective TAILDESC_PTR */ +- ll_temac->out32(ra[RX_CURDESC_PTR], (int)&cdmac_bd.rx[rx_idx]); +- ll_temac->out32(ra[RX_TAILDESC_PTR], (int)&cdmac_bd.rx[rx_idx]); +- +- if (length > 0 && pb_idx != -1) +- NetReceive(NetRxPackets[pb_idx], length); +- +- return 0; +-} +- +-int ll_temac_send_sdma(struct eth_device *dev, void *packet, int length) +-{ +- unsigned timeout = 50; /* 1usec * 50 = 50usec */ +- struct cdmac_bd *tx_dp = &cdmac_bd.tx[tx_idx]; +- struct ll_temac *ll_temac = dev->priv; +- phys_addr_t *ra = ll_temac->sdma_reg_addr; +- +- if (ll_temac_sdma_error(dev)) { +- +- if (ll_temac_reset_sdma(dev)) +- return -1; +- +- ll_temac_init_sdma(dev); +- } +- +- tx_dp->phys_buf_p = (u8 *)packet; +- tx_dp->buf_len = length; +- tx_dp->sca.stctrl = CDMAC_BD_STCTRL_SOP | CDMAC_BD_STCTRL_EOP | +- CDMAC_BD_STCTRL_STOP_ON_END; +- +- flush_cache((u32)packet, length); +- flush_cache((u32)tx_dp, sizeof(*tx_dp)); +- +- /* DMA start by writing to respective TAILDESC_PTR */ +- ll_temac->out32(ra[TX_CURDESC_PTR], (int)tx_dp); +- ll_temac->out32(ra[TX_TAILDESC_PTR], (int)tx_dp); +- +- /* Find next empty buffer descriptor, preparation for next iteration */ +- tx_idx = (tx_idx + 1) % TX_BUF_CNT; +- tx_dp = &cdmac_bd.tx[tx_idx]; +- +- do { +- flush_cache((u32)tx_dp, sizeof(*tx_dp)); +- udelay(1); +- } while (timeout-- && !(tx_dp->sca.stctrl & CDMAC_BD_STCTRL_COMPLETED)); +- +- if (!timeout) { +- printf("%s: Timeout\n", __func__); +- return -1; +- } +- +- return 0; +-} +diff --git a/drivers/net/xilinx_ll_temac_sdma.h b/drivers/net/xilinx_ll_temac_sdma.h +deleted file mode 100644 +index db00a57..0000000 +--- a/drivers/net/xilinx_ll_temac_sdma.h ++++ /dev/null +@@ -1,280 +0,0 @@ +-/* +- * Xilinx xps_ll_temac ethernet driver for u-boot +- * +- * SDMA sub-controller interface +- * +- * Copyright (C) 2011 - 2012 Stephan Linz +- * Copyright (C) 2008 - 2011 Michal Simek +- * Copyright (C) 2008 - 2011 PetaLogix +- * +- * Based on Yoshio Kashiwagi kashiwagi@co-nss.co.jp driver +- * Copyright (C) 2008 Nissin Systems Co.,Ltd. +- * March 2008 created +- * +- * 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. +- * +- * [0]: http://www.xilinx.com/support/documentation +- * +- * [S]: [0]/ip_documentation/xps_ll_temac.pdf +- * [A]: [0]/application_notes/xapp1041.pdf +- */ +-#ifndef _XILINX_LL_TEMAC_SDMA_ +-#define _XILINX_LL_TEMAC_SDMA_ +- +-#include +- +-#include +-#include +- +-#include +- +-#if !defined(__BIG_ENDIAN) +-# error LL_TEMAC requires big endianess +-#endif +- +-/* +- * DMA Buffer Descriptor for CDMAC +- * +- * Used for data connection from and to (Rx/Tx) the LocalLink (LL) TEMAC via +- * the Communications Direct Memory Access Controller (CDMAC) -- one for each. +- * +- * overview: +- * ftp://ftp.xilinx.com/pub/documentation/misc/mpmc_getting_started.pdf +- * +- * [1]: [0]/ip_documentation/mpmc.pdf +- * page 140, DMA Operation Descriptors +- * +- * [2]: [0]/user_guides/ug200.pdf +- * page 229, DMA Controller -- Descriptor Format +- * +- * [3]: [0]/ip_documentation/xps_ll_temac.pdf +- * page 72, Transmit LocalLink Frame Format +- * page 73, Receive LocalLink Frame Format +- */ +-struct cdmac_bd { +- struct cdmac_bd *next_p; /* Next Descriptor Pointer */ +- u8 *phys_buf_p; /* Buffer Address */ +- u32 buf_len; /* Buffer Length */ +- union { +- u8 stctrl; /* Status/Control the DMA transfer */ +- u32 app[5]; /* application specific data */ +- } __packed __aligned(1) sca; +-}; +- +-/* CDMAC Descriptor Status and Control (stctrl), [1] p140, [2] p230 */ +-#define CDMAC_BD_STCTRL_ERROR (1 << 7) +-#define CDMAC_BD_STCTRL_IRQ_ON_END (1 << 6) +-#define CDMAC_BD_STCTRL_STOP_ON_END (1 << 5) +-#define CDMAC_BD_STCTRL_COMPLETED (1 << 4) +-#define CDMAC_BD_STCTRL_SOP (1 << 3) +-#define CDMAC_BD_STCTRL_EOP (1 << 2) +-#define CDMAC_BD_STCTRL_DMACHBUSY (1 << 1) +- +-/* CDMAC Descriptor APP0: Transmit LocalLink Footer Word 3, [3] p72 */ +-#define CDMAC_BD_APP0_TXCSCNTRL (1 << 0) +- +-/* CDMAC Descriptor APP1: Transmit LocalLink Footer Word 4, [3] p73 */ +-#define CDMAC_BD_APP1_TXCSBEGIN_POS 16 +-#define CDMAC_BD_APP1_TXCSBEGIN_MASK (0xFFFF << CDMAC_BD_APP1_TXCSBEGIN_POS) +-#define CDMAC_BD_APP1_TXCSINSERT_POS 0 +-#define CDMAC_BD_APP1_TXCSINSERT_MASK (0xFFFF << CDMAC_BD_APP1_TXCSINSERT_POS) +- +-/* CDMAC Descriptor APP2: Transmit LocalLink Footer Word 5, [3] p73 */ +-#define CDMAC_BD_APP2_TXCSINIT_POS 0 +-#define CDMAC_BD_APP2_TXCSINIT_MASK (0xFFFF << CDMAC_BD_APP2_TXCSINIT_POS) +- +-/* CDMAC Descriptor APP0: Receive LocalLink Footer Word 3, [3] p73 */ +-#define CDMAC_BD_APP0_MADDRU_POS 0 +-#define CDMAC_BD_APP0_MADDRU_MASK (0xFFFF << CDMAC_BD_APP0_MADDRU_POS) +- +-/* CDMAC Descriptor APP1: Receive LocalLink Footer Word 4, [3] p74 */ +-#define CDMAC_BD_APP1_MADDRL_POS 0 +-#define CDMAC_BD_APP1_MADDRL_MASK (~0UL << CDMAC_BD_APP1_MADDRL_POS) +- +-/* CDMAC Descriptor APP2: Receive LocalLink Footer Word 5, [3] p74 */ +-#define CDMAC_BD_APP2_BCAST_FRAME (1 << 2) +-#define CDMAC_BD_APP2_IPC_MCAST_FRAME (1 << 1) +-#define CDMAC_BD_APP2_MAC_MCAST_FRAME (1 << 0) +- +-/* CDMAC Descriptor APP3: Receive LocalLink Footer Word 6, [3] p74 */ +-#define CDMAC_BD_APP3_TLTPID_POS 16 +-#define CDMAC_BD_APP3_TLTPID_MASK (0xFFFF << CDMAC_BD_APP3_TLTPID_POS) +-#define CDMAC_BD_APP3_RXCSRAW_POS 0 +-#define CDMAC_BD_APP3_RXCSRAW_MASK (0xFFFF << CDMAC_BD_APP3_RXCSRAW_POS) +- +-/* CDMAC Descriptor APP4: Receive LocalLink Footer Word 7, [3] p74 */ +-#define CDMAC_BD_APP4_VLANTAG_POS 16 +-#define CDMAC_BD_APP4_VLANTAG_MASK (0xFFFF << CDMAC_BD_APP4_VLANTAG_POS) +-#define CDMAC_BD_APP4_RXBYTECNT_POS 0 +-#define CDMAC_BD_APP4_RXBYTECNT_MASK (0x3FFF << CDMAC_BD_APP4_RXBYTECNT_POS) +- +-/* +- * SDMA Register Definition +- * +- * [0]: http://www.xilinx.com/support/documentation +- * +- * [1]: [0]/ip_documentation/mpmc.pdf +- * page 54, SDMA Register Summary +- * page 160, SDMA Registers +- * +- * [2]: [0]/user_guides/ug200.pdf +- * page 244, DMA Controller -- Programming Interface and Registers +- */ +-#define SDMA_CTRL_REGTYPE u32 +-#define SDMA_CTRL_REGSIZE sizeof(SDMA_CTRL_REGTYPE) +-struct sdma_ctrl { +- /* Transmit Registers */ +- SDMA_CTRL_REGTYPE tx_nxtdesc_ptr; /* TX Next Description Pointer */ +- SDMA_CTRL_REGTYPE tx_curbuf_addr; /* TX Current Buffer Address */ +- SDMA_CTRL_REGTYPE tx_curbuf_length; /* TX Current Buffer Length */ +- SDMA_CTRL_REGTYPE tx_curdesc_ptr; /* TX Current Descriptor Pointer */ +- SDMA_CTRL_REGTYPE tx_taildesc_ptr; /* TX Tail Descriptor Pointer */ +- SDMA_CTRL_REGTYPE tx_chnl_ctrl; /* TX Channel Control */ +- SDMA_CTRL_REGTYPE tx_irq_reg; /* TX Interrupt Register */ +- SDMA_CTRL_REGTYPE tx_chnl_sts; /* TX Status Register */ +- /* Receive Registers */ +- SDMA_CTRL_REGTYPE rx_nxtdesc_ptr; /* RX Next Descriptor Pointer */ +- SDMA_CTRL_REGTYPE rx_curbuf_addr; /* RX Current Buffer Address */ +- SDMA_CTRL_REGTYPE rx_curbuf_length; /* RX Current Buffer Length */ +- SDMA_CTRL_REGTYPE rx_curdesc_ptr; /* RX Current Descriptor Pointer */ +- SDMA_CTRL_REGTYPE rx_taildesc_ptr; /* RX Tail Descriptor Pointer */ +- SDMA_CTRL_REGTYPE rx_chnl_ctrl; /* RX Channel Control */ +- SDMA_CTRL_REGTYPE rx_irq_reg; /* RX Interrupt Register */ +- SDMA_CTRL_REGTYPE rx_chnl_sts; /* RX Status Register */ +- /* Control Registers */ +- SDMA_CTRL_REGTYPE dma_control_reg; /* DMA Control Register */ +-}; +- +-#define SDMA_CTRL_REGNUMS sizeof(struct sdma_ctrl)/SDMA_CTRL_REGSIZE +- +-/* +- * DMAC Register Index Enumeration +- * +- * [2]: http://www.xilinx.com/support/documentation/user_guides/ug200.pdf +- * page 244, DMA Controller -- Programming Interface and Registers +- */ +-enum dmac_ctrl { +- /* Transmit Registers */ +- TX_NXTDESC_PTR = 0, /* TX Next Description Pointer */ +- TX_CURBUF_ADDR, /* TX Current Buffer Address */ +- TX_CURBUF_LENGTH, /* TX Current Buffer Length */ +- TX_CURDESC_PTR, /* TX Current Descriptor Pointer */ +- TX_TAILDESC_PTR, /* TX Tail Descriptor Pointer */ +- TX_CHNL_CTRL, /* TX Channel Control */ +- TX_IRQ_REG, /* TX Interrupt Register */ +- TX_CHNL_STS, /* TX Status Register */ +- /* Receive Registers */ +- RX_NXTDESC_PTR, /* RX Next Descriptor Pointer */ +- RX_CURBUF_ADDR, /* RX Current Buffer Address */ +- RX_CURBUF_LENGTH, /* RX Current Buffer Length */ +- RX_CURDESC_PTR, /* RX Current Descriptor Pointer */ +- RX_TAILDESC_PTR, /* RX Tail Descriptor Pointer */ +- RX_CHNL_CTRL, /* RX Channel Control */ +- RX_IRQ_REG, /* RX Interrupt Register */ +- RX_CHNL_STS, /* RX Status Register */ +- /* Control Registers */ +- DMA_CONTROL_REG /* DMA Control Register */ +-}; +- +-/* Rx/Tx Channel Control Register (*_chnl_ctrl), [1] p163, [2] p246/p252 */ +-#define CHNL_CTRL_ITO_POS 24 +-#define CHNL_CTRL_ITO_MASK (0xFF << CHNL_CTRL_ITO_POS) +-#define CHNL_CTRL_IC_POS 16 +-#define CHNL_CTRL_IC_MASK (0xFF << CHNL_CTRL_IC_POS) +-#define CHNL_CTRL_MSBADDR_POS 12 +-#define CHNL_CTRL_MSBADDR_MASK (0xF << CHNL_CTRL_MSBADDR_POS) +-#define CHNL_CTRL_AME (1 << 11) +-#define CHNL_CTRL_OBWC (1 << 10) +-#define CHNL_CTRL_IOE (1 << 9) +-#define CHNL_CTRL_LIC (1 << 8) +-#define CHNL_CTRL_IE (1 << 7) +-#define CHNL_CTRL_IEE (1 << 2) +-#define CHNL_CTRL_IDE (1 << 1) +-#define CHNL_CTRL_ICE (1 << 0) +- +-/* All interrupt enable bits */ +-#define CHNL_CTRL_IRQ_MASK (CHNL_CTRL_IE | \ +- CHNL_CTRL_IEE | \ +- CHNL_CTRL_IDE | \ +- CHNL_CTRL_ICE) +- +-/* Rx/Tx Interrupt Status Register (*_irq_reg), [1] p164, [2] p247/p253 */ +-#define IRQ_REG_DTV_POS 24 +-#define IRQ_REG_DTV_MASK (0xFF << IRQ_REG_DTV_POS) +-#define IRQ_REG_CCV_POS 16 +-#define IRQ_REG_CCV_MASK (0xFF << IRQ_REG_CCV_POS) +-#define IRQ_REG_WRCQ_EMPTY (1 << 14) +-#define IRQ_REG_CIC_POS 10 +-#define IRQ_REG_CIC_MASK (0xF << IRQ_REG_CIC_POS) +-#define IRQ_REG_DIC_POS 8 +-#define IRQ_REG_DIC_MASK (3 << 8) +-#define IRQ_REG_PLB_RD_NMI (1 << 4) +-#define IRQ_REG_PLB_WR_NMI (1 << 3) +-#define IRQ_REG_EI (1 << 2) +-#define IRQ_REG_DI (1 << 1) +-#define IRQ_REG_CI (1 << 0) +- +-/* All interrupt bits */ +-#define IRQ_REG_IRQ_MASK (IRQ_REG_PLB_RD_NMI | \ +- IRQ_REG_PLB_WR_NMI | \ +- IRQ_REG_EI | IRQ_REG_DI | IRQ_REG_CI) +- +-/* Rx/Tx Channel Status Register (*_chnl_sts), [1] p165, [2] p249/p255 */ +-#define CHNL_STS_ERROR_TAIL (1 << 21) +-#define CHNL_STS_ERROR_CMP (1 << 20) +-#define CHNL_STS_ERROR_ADDR (1 << 19) +-#define CHNL_STS_ERROR_NXTP (1 << 18) +-#define CHNL_STS_ERROR_CURP (1 << 17) +-#define CHNL_STS_ERROR_BSYWR (1 << 16) +-#define CHNL_STS_ERROR (1 << 7) +-#define CHNL_STS_IOE (1 << 6) +-#define CHNL_STS_SOE (1 << 5) +-#define CHNL_STS_CMPLT (1 << 4) +-#define CHNL_STS_SOP (1 << 3) +-#define CHNL_STS_EOP (1 << 2) +-#define CHNL_STS_EBUSY (1 << 1) +- +-/* DMA Control Register (dma_control_reg), [1] p166, [2] p256 */ +-#define DMA_CONTROL_PLBED (1 << 5) +-#define DMA_CONTROL_RXOCEID (1 << 4) +-#define DMA_CONTROL_TXOCEID (1 << 3) +-#define DMA_CONTROL_TPE (1 << 2) +-#define DMA_CONTROL_RESET (1 << 0) +- +-#if defined(CONFIG_XILINX_440) || defined(CONFIG_XILINX_405) +- +-/* Xilinx Device Control Register (DCR) in/out accessors */ +-unsigned ll_temac_xldcr_in32(phys_addr_t addr); +-void ll_temac_xldcr_out32(phys_addr_t addr, unsigned value); +- +-/* collect all register addresses for Xilinx DCR in/out accessors */ +-void ll_temac_collect_xldcr_sdma_reg_addr(struct eth_device *dev); +- +-#endif /* CONFIG_XILINX_440 || CONFIG_XILINX_405 */ +- +-/* Xilinx Processor Local Bus (PLB) in/out accessors */ +-unsigned ll_temac_xlplb_in32(phys_addr_t base); +-void ll_temac_xlplb_out32(phys_addr_t base, unsigned value); +- +-/* collect all register addresses for Xilinx PLB in/out accessors */ +-void ll_temac_collect_xlplb_sdma_reg_addr(struct eth_device *dev); +- +-/* initialize both Rx/Tx buffer descriptors */ +-int ll_temac_init_sdma(struct eth_device *dev); +- +-/* halt both Rx/Tx transfers */ +-int ll_temac_halt_sdma(struct eth_device *dev); +- +-/* reset SDMA and IRQ, disable interrupts and errors */ +-int ll_temac_reset_sdma(struct eth_device *dev); +- +-/* receive buffered data from SDMA (polling ISR) */ +-int ll_temac_recv_sdma(struct eth_device *dev); +- +-/* send buffered data to SDMA */ +-int ll_temac_send_sdma(struct eth_device *dev, void *packet, int length); +- +-#endif /* _XILINX_LL_TEMAC_SDMA_ */ +diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c +index 3596065..bd1c8c0 100644 +--- a/drivers/net/zynq_gem.c ++++ b/drivers/net/zynq_gem.c +@@ -33,10 +33,7 @@ + #include + #include + #include +- +-#if !defined(CONFIG_PHYLIB) +-# error XILINX_GEM_ETHERNET requires PHYLIB +-#endif ++#include + + /* Bit/mask specification */ + #define ZYNQ_GEM_PHYMNTNC_OP_MASK 0x40020000 /* operation mask bits */ +@@ -67,13 +64,14 @@ + #define ZYNQ_GEM_NWCTRL_MDEN_MASK 0x00000010 /* Enable MDIO port */ + #define ZYNQ_GEM_NWCTRL_STARTTX_MASK 0x00000200 /* Start tx (tx_go) */ + +-#define ZYNQ_GEM_NWCFG_SPEED 0x00000001 /* 100 Mbps operation */ +-#define ZYNQ_GEM_NWCFG_FDEN 0x00000002 /* Full Duplex mode */ +-#define ZYNQ_GEM_NWCFG_FSREM 0x00020000 /* FCS removal */ ++#define ZYNQ_GEM_NWCFG_SPEED100 0x000000001 /* 100 Mbps operation */ ++#define ZYNQ_GEM_NWCFG_SPEED1000 0x000000400 /* 1Gbps operation */ ++#define ZYNQ_GEM_NWCFG_FDEN 0x000000002 /* Full Duplex mode */ ++#define ZYNQ_GEM_NWCFG_FSREM 0x000020000 /* FCS removal */ + #define ZYNQ_GEM_NWCFG_MDCCLKDIV 0x000080000 /* Div pclk by 32, 80MHz */ ++#define ZYNQ_GEM_NWCFG_MDCCLKDIV2 0x0000c0000 /* Div pclk by 48, 120MHz */ + +-#define ZYNQ_GEM_NWCFG_INIT (ZYNQ_GEM_NWCFG_SPEED | \ +- ZYNQ_GEM_NWCFG_FDEN | \ ++#define ZYNQ_GEM_NWCFG_INIT (ZYNQ_GEM_NWCFG_FDEN | \ + ZYNQ_GEM_NWCFG_FSREM | \ + ZYNQ_GEM_NWCFG_MDCCLKDIV) + +@@ -92,6 +90,17 @@ + ZYNQ_GEM_DMACR_TXSIZE | \ + ZYNQ_GEM_DMACR_RXBUF) + ++/* Use MII register 1 (MII status register) to detect PHY */ ++#define PHY_DETECT_REG 1 ++ ++/* Mask used to verify certain PHY features (or register contents) ++ * in the register above: ++ * 0x1000: 10Mbps full duplex support ++ * 0x0800: 10Mbps half duplex support ++ * 0x0008: Auto-negotiation support ++ */ ++#define PHY_DETECT_MASK 0x1808 ++ + /* Device registers */ + struct zynq_gem_regs { + u32 nwctrl; /* Network Control reg */ +@@ -134,6 +143,7 @@ struct zynq_gem_priv { + u32 rxbd_current; + u32 rx_first_buf; + int phyaddr; ++ int init; + struct phy_device *phydev; + struct mii_dev *bus; + }; +@@ -141,7 +151,7 @@ struct zynq_gem_priv { + static inline int mdio_wait(struct eth_device *dev) + { + struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; +- u32 timeout = 200; ++ u32 timeout = 20000; + + /* Wait till MDIO interface is ready to accept a new transaction. */ + while (--timeout) { +@@ -196,6 +206,65 @@ static u32 phywrite(struct eth_device *dev, u32 phy_addr, u32 regnum, u16 data) + ZYNQ_GEM_PHYMNTNC_OP_W_MASK, &data); + } + ++#ifndef CONFIG_PHYLIB ++static int phy_rst(struct eth_device *dev) ++{ ++ struct zynq_gem_priv *priv = dev->priv; ++ u16 tmp; ++ ++ puts("Resetting PHY...\n"); ++ phyread(dev, priv->phyaddr, 0, &tmp); ++ tmp |= 0x8000; ++ phywrite(dev, priv->phyaddr, 0, tmp); ++ ++ phyread(dev, priv->phyaddr, 0, &tmp); ++ while (tmp & 0x8000) { ++ putc('.'); ++ if (ctrlc()) ++ return 1; ++ phyread(dev, priv->phyaddr, 0, &tmp); ++ } ++ puts("\nPHY reset complete.\n"); ++ return 0; ++} ++#endif ++ ++static void phy_detection(struct eth_device *dev) ++{ ++ int i; ++ u16 phyreg; ++ struct zynq_gem_priv *priv = dev->priv; ++ ++ if (priv->phyaddr != -1 ) { ++ phyread(dev, priv->phyaddr, PHY_DETECT_REG, &phyreg); ++ if ((phyreg != 0xFFFF) && ++ ((phyreg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) { ++ /* Found a valid PHY address */ ++ debug("Default phy address %d is valid\n", priv->phyaddr); ++ return; ++ } else { ++ debug("PHY address is not setup correctly %d\n", priv->phyaddr); ++ priv->phyaddr = -1; ++ } ++ } ++ ++ debug("detecting phy address\n"); ++ if (priv->phyaddr == -1 ) { ++ /* detect the PHY address */ ++ for (i = 31; i >= 0; i--) { ++ phyread(dev, i, PHY_DETECT_REG, &phyreg); ++ if ((phyreg != 0xFFFF) && ++ ((phyreg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) { ++ /* Found a valid PHY address */ ++ priv->phyaddr = i; ++ debug("Found valid phy address, %d\n", i); ++ return; ++ } ++ } ++ } ++ printf("PHY is not detected\n"); ++} ++ + static int zynq_gem_setup_mac(struct eth_device *dev) + { + u32 i, macaddrlow, macaddrhigh; +@@ -239,59 +308,132 @@ static int zynq_gem_init(struct eth_device *dev, bd_t * bis) + SUPPORTED_1000baseT_Half | + SUPPORTED_1000baseT_Full; + +- /* Disable all interrupts */ +- writel(0xFFFFFFFF, ®s->idr); +- +- /* Disable the receiver & transmitter */ +- writel(0, ®s->nwctrl); +- writel(0, ®s->txsr); +- writel(0, ®s->rxsr); +- writel(0, ®s->phymntnc); +- +- /* Clear the Hash registers for the mac address pointed by AddressPtr */ +- writel(0x0, ®s->hashl); +- /* Write bits [63:32] in TOP */ +- writel(0x0, ®s->hashh); ++ if (!priv->init) { ++ /* Disable all interrupts */ ++ writel(0xFFFFFFFF, ®s->idr); ++ ++ /* Disable the receiver & transmitter */ ++ writel(0, ®s->nwctrl); ++ writel(0, ®s->txsr); ++ writel(0, ®s->rxsr); ++ writel(0, ®s->phymntnc); ++ ++ /* ++ * Clear the Hash registers for the mac address ++ * pointed by AddressPtr ++ */ ++ writel(0x0, ®s->hashl); ++ /* Write bits [63:32] in TOP */ ++ writel(0x0, ®s->hashh); ++ ++ /* Clear all counters */ ++ for (i = 0; i <= stat_size; i++) ++ readl(®s->stat[i]); ++ ++ /* Setup RxBD space */ ++ memset(&(priv->rx_bd), 0, sizeof(priv->rx_bd)); ++ /* Create the RxBD ring */ ++ memset(&(priv->rxbuffers), 0, sizeof(priv->rxbuffers)); ++ ++ for (i = 0; i < RX_BUF; i++) { ++ priv->rx_bd[i].status = 0xF0000000; ++ priv->rx_bd[i].addr = ++ (u32)((char *) &(priv->rxbuffers) + ++ (i * PKTSIZE_ALIGN)); ++ } ++ /* WRAP bit to last BD */ ++ priv->rx_bd[--i].addr |= ZYNQ_GEM_RXBUF_WRAP_MASK; ++ /* Write RxBDs to IP */ ++ writel((u32) &(priv->rx_bd), ®s->rxqbase); + +- /* Clear all counters */ +- for (i = 0; i <= stat_size; i++) +- readl(®s->stat[i]); ++ /* Setup for DMA Configuration register */ ++ writel(ZYNQ_GEM_DMACR_INIT, ®s->dmacr); + +- /* Setup RxBD space */ +- memset(&(priv->rx_bd), 0, sizeof(priv->rx_bd)); +- /* Create the RxBD ring */ +- memset(&(priv->rxbuffers), 0, sizeof(priv->rxbuffers)); ++ /* Setup for Network Control register, MDIO, Rx and Tx enable */ ++ setbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_MDEN_MASK); + +- for (i = 0; i < RX_BUF; i++) { +- priv->rx_bd[i].status = 0xF0000000; +- priv->rx_bd[i].addr = (u32)((char *) &(priv->rxbuffers) + +- (i * PKTSIZE_ALIGN)); ++ priv->init++; + } +- /* WRAP bit to last BD */ +- priv->rx_bd[--i].addr |= ZYNQ_GEM_RXBUF_WRAP_MASK; +- /* Write RxBDs to IP */ +- writel((u32) &(priv->rx_bd), ®s->rxqbase); + +- /* MAC Setup */ +- /* Setup Network Configuration register */ +- writel(ZYNQ_GEM_NWCFG_INIT, ®s->nwcfg); ++ phy_detection(dev); + +- /* Setup for DMA Configuration register */ +- writel(ZYNQ_GEM_DMACR_INIT, ®s->dmacr); +- +- /* Setup for Network Control register, MDIO, Rx and Tx enable */ +- setbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_MDEN_MASK | +- ZYNQ_GEM_NWCTRL_RXEN_MASK | ZYNQ_GEM_NWCTRL_TXEN_MASK); ++#ifdef CONFIG_PHYLIB ++ u32 rclk, clk = 0; + + /* interface - look at tsec */ + phydev = phy_connect(priv->bus, priv->phyaddr, dev, 0); + +- phydev->supported &= supported; ++ phydev->supported = supported | ADVERTISED_Pause | ADVERTISED_Asym_Pause; + phydev->advertising = phydev->supported; + priv->phydev = phydev; + phy_config(phydev); + phy_startup(phydev); + ++ switch(phydev->speed) { ++ case SPEED_1000: ++ writel(ZYNQ_GEM_NWCFG_INIT | ZYNQ_GEM_NWCFG_SPEED1000, ++ ®s->nwcfg); ++ rclk = (0 << 4) | (1 << 0); ++ clk = (1 << 20) | (8 << 8) | (0 << 4) | (1 << 0); ++ break; ++ case SPEED_100: ++ clrsetbits_le32(®s->nwcfg, ZYNQ_GEM_NWCFG_SPEED1000, ++ ZYNQ_GEM_NWCFG_INIT | ZYNQ_GEM_NWCFG_SPEED100); ++ rclk = 1 << 0; ++ clk = (5 << 20) | (8 << 8) | (0 << 4) | (1 << 0); ++ break; ++ case SPEED_10: ++ rclk = 1 << 0; ++ /* FIXME untested */ ++ clk = (5 << 20) | (8 << 8) | (0 << 4) | (1 << 0); ++ break; ++ } ++ /* FIXME maybe better to define gem address in hardware.h */ ++ zynq_slcr_gem_clk_setup(dev->iobase != 0xE000B000, rclk, clk); ++ ++#else ++ /* PHY Setup */ ++ phywrite(dev, priv->phyaddr, 22, 2); /* page 2 */ ++ ++ /* rx clock transition when data stable */ ++ phywrite(dev, priv->phyaddr, 21, 0x3030); ++ ++ phywrite(dev, priv->phyaddr, 22, 0); /* page 0 */ ++ ++ u16 tmp; ++ ++ /* link speed advertisement for autonegotiation */ ++ phyread(dev, priv->phyaddr, 4, &tmp); ++ tmp |= 0xd80; /* enable 100Mbps */ ++ tmp &= ~0x60; /* disable 10 Mbps */ ++ phywrite(dev, priv->phyaddr, 4, tmp); ++ ++ /* *disable* gigabit advertisement */ ++ phyread(dev, priv->phyaddr, 9, &tmp); ++ tmp &= ~0x0300; ++ phywrite(dev, priv->phyaddr, 9, tmp); ++ ++ /* enable autonegotiation, set 100Mbps, full-duplex, restart aneg */ ++ phyread(dev, priv->phyaddr, 0, &tmp); ++ phywrite(dev, priv->phyaddr, 0, 0x3300 | (tmp & 0x1F)); ++ ++ if (phy_rst(dev)) ++ return -1; ++ ++ puts("\nWaiting for PHY to complete autonegotiation."); ++ do { ++ phyread(dev, priv->phyaddr, 1, &tmp); ++ } while (tmp & (1 << 5)); ++ ++ puts("\nPHY claims autonegotiation complete...\n"); ++ ++ puts("GEM link speed is 100Mbps\n"); ++ writel(ZYNQ_GEM_NWCFG_INIT | ZYNQ_GEM_NWCFG_SPEED100, ®s->nwcfg); ++#endif ++ ++ setbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_RXEN_MASK | ++ ZYNQ_GEM_NWCTRL_TXEN_MASK); ++ + return 0; + } + +@@ -310,8 +452,7 @@ static int zynq_gem_send(struct eth_device *dev, void *ptr, int len) + memset((void *) &(priv->tx_bd), 0, sizeof(struct emac_bd)); + + priv->tx_bd.addr = (u32)ptr; +- priv->tx_bd.status = len | ZYNQ_GEM_TXBUF_LAST_MASK | +- ZYNQ_GEM_TXBUF_WRAP_MASK; ++ priv->tx_bd.status = len | ZYNQ_GEM_TXBUF_LAST_MASK; + + /* Start transmit */ + setbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_STARTTX_MASK); +@@ -364,19 +505,17 @@ static int zynq_gem_recv(struct eth_device *dev) + + if ((++priv->rxbd_current) >= RX_BUF) + priv->rxbd_current = 0; +- +- return frame_len; + } + +- return 0; ++ return frame_len; + } + + static void zynq_gem_halt(struct eth_device *dev) + { + struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; + +- /* Disable the receiver & transmitter */ +- writel(0, ®s->nwctrl); ++ clrsetbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_RXEN_MASK | ++ ZYNQ_GEM_NWCTRL_TXEN_MASK, 0); + } + + static int zynq_gem_miiphyread(const char *devname, uchar addr, +@@ -433,8 +572,10 @@ int zynq_gem_initialize(bd_t *bis, int base_addr) + + eth_register(dev); + ++#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB) + miiphy_register(dev->name, zynq_gem_miiphyread, zynq_gem_miiphy_write); + priv->bus = miiphy_get_dev_by_name(dev->name); ++#endif + + return 1; + } +diff --git a/drivers/serial/arm_dcc.c b/drivers/serial/arm_dcc.c +index 7b5ecb5..c217c88 100644 +--- a/drivers/serial/arm_dcc.c ++++ b/drivers/serial/arm_dcc.c +@@ -89,15 +89,6 @@ + + #define TIMEOUT_COUNT 0x4000000 + +-#ifndef CONFIG_ARM_DCC_MULTI +-#define arm_dcc_init serial_init +-void serial_setbrg(void) {} +-#define arm_dcc_getc serial_getc +-#define arm_dcc_putc serial_putc +-#define arm_dcc_puts serial_puts +-#define arm_dcc_tstc serial_tstc +-#endif +- + int arm_dcc_init(void) + { + return 0; +@@ -147,16 +138,10 @@ int arm_dcc_tstc(void) + return reg; + } + +-#ifdef CONFIG_ARM_DCC_MULTI + static struct stdio_dev arm_dcc_dev; + + int drv_arm_dcc_init(void) + { +- int rc; +- +- /* Device initialization */ +- memset(&arm_dcc_dev, 0, sizeof(arm_dcc_dev)); +- + strcpy(arm_dcc_dev.name, "dcc"); + arm_dcc_dev.ext = 0; /* No extensions */ + arm_dcc_dev.flags = DEV_FLAGS_INPUT | DEV_FLAGS_OUTPUT; +@@ -167,4 +152,8 @@ int drv_arm_dcc_init(void) + + return stdio_register(&arm_dcc_dev); + } +-#endif ++ ++__weak struct serial_device *default_serial_console(void) ++{ ++ return NULL; ++} +diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile +index 824d357..0f324f4 100644 +--- a/drivers/spi/Makefile ++++ b/drivers/spi/Makefile +@@ -47,6 +47,7 @@ COBJS-$(CONFIG_SH_SPI) += sh_spi.o + COBJS-$(CONFIG_FSL_ESPI) += fsl_espi.o + COBJS-$(CONFIG_TEGRA_SPI) += tegra_spi.o + COBJS-$(CONFIG_XILINX_SPI) += xilinx_spi.o ++COBJS-$(CONFIG_ZYNQ_SPI) += zynq_qspips.o + + COBJS := $(COBJS-y) + SRCS := $(COBJS:.o=.c) +diff --git a/drivers/spi/xilinx_spi.c b/drivers/spi/xilinx_spi.c +index 52a4134..db01cc2 100644 +--- a/drivers/spi/xilinx_spi.c ++++ b/drivers/spi/xilinx_spi.c +@@ -99,6 +99,8 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, + debug("%s: bus:%i cs:%i base:%p mode:%x max_hz:%d\n", __func__, + bus, cs, xilspi->regs, xilspi->mode, xilspi->freq); + ++ writel(SPISSR_RESET_VALUE, &xilspi->regs->srr); ++ + return &xilspi->slave; + } + +diff --git a/drivers/spi/xilinx_spi.h b/drivers/spi/xilinx_spi.h +index 32610d2..69d0b94 100644 +--- a/drivers/spi/xilinx_spi.h ++++ b/drivers/spi/xilinx_spi.h +@@ -119,6 +119,9 @@ struct xilinx_spi_reg { + #define SPIRFOR_OCYVAL_POS 0 + #define SPIRFOR_OCYVAL_MASK (0xf << SPIRFOR_OCYVAL_POS) + ++/* SPI Software Reset Register (ssr) */ ++#define SPISSR_RESET_VALUE 0x0a ++ + struct xilinx_spi_slave { + struct spi_slave slave; + struct xilinx_spi_reg *regs; +diff --git a/drivers/spi/zynq_qspips.c b/drivers/spi/zynq_qspips.c +new file mode 100644 +index 0000000..46a2b62 +--- /dev/null ++++ b/drivers/spi/zynq_qspips.c +@@ -0,0 +1,1056 @@ ++/* ++ * (C) Copyright 2011 Xilinx ++ * ++ * Xilinx PS Quad-SPI (QSPI) controller driver (master mode only) ++ * based on Xilinx PS SPI Driver (xspips.c) ++ * ++ * This program is free software; you can redistribute it and/or modify it under ++ * the terms of the GNU General Public License version 2 as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++ ++/* QSPI Transmit Data Register */ ++#define XQSPIPS_TXD_00_00_OFFSET 0x1C /* Transmit 4-byte inst, WO */ ++#define XQSPIPS_TXD_00_01_OFFSET 0x80 /* Transmit 1-byte inst, WO */ ++#define XQSPIPS_TXD_00_10_OFFSET 0x84 /* Transmit 2-byte inst, WO */ ++#define XQSPIPS_TXD_00_11_OFFSET 0x88 /* Transmit 3-byte inst, WO */ ++ ++/* ++ * QSPI Configuration Register bit Masks ++ * ++ * This register contains various control bits that effect the operation ++ * of the QSPI controller ++ */ ++#define XQSPIPS_CONFIG_MANSRT_MASK 0x00010000 /* Manual TX Start */ ++#define XQSPIPS_CONFIG_CPHA_MASK 0x00000004 /* Clock Phase Control */ ++#define XQSPIPS_CONFIG_CPOL_MASK 0x00000002 /* Clock Polarity Control */ ++#define XQSPIPS_CONFIG_SSCTRL_MASK 0x00003C00 /* Slave Select Mask */ ++ ++/* ++ * QSPI Interrupt Registers bit Masks ++ * ++ * All the four interrupt registers (Status/Mask/Enable/Disable) have the same ++ * bit definitions. ++ */ ++#define XQSPIPS_IXR_TXNFULL_MASK 0x00000004 /* QSPI TX FIFO Overflow */ ++#define XQSPIPS_IXR_TXFULL_MASK 0x00000008 /* QSPI TX FIFO is full */ ++#define XQSPIPS_IXR_RXNEMTY_MASK 0x00000010 /* QSPI RX FIFO Not Empty */ ++#define XQSPIPS_IXR_ALL_MASK (XQSPIPS_IXR_TXNFULL_MASK | \ ++ XQSPIPS_IXR_RXNEMTY_MASK) ++ ++/* ++ * QSPI Enable Register bit Masks ++ * ++ * This register is used to enable or disable the QSPI controller ++ */ ++#define XQSPIPS_ENABLE_ENABLE_MASK 0x00000001 /* QSPI Enable Bit Mask */ ++ ++/* ++ * QSPI Linear Configuration Register ++ * ++ * It is named Linear Configuration but it controls other modes when not in ++ * linear mode also. ++ */ ++#define XQSPIPS_LCFG_TWO_MEM_MASK 0x40000000 /* QSPI Enable Bit Mask */ ++#define XQSPIPS_LCFG_SEP_BUS_MASK 0x20000000 /* QSPI Enable Bit Mask */ ++#define XQSPIPS_LCFG_U_PAGE 0x8000000 /* QSPI Upper memory set */ ++ ++#define XQSPIPS_LCFG_DUMMY_SHIFT 8 ++ ++#define XQSPIPS_FAST_READ_QOUT_CODE 0x6B /* read instruction code */ ++ ++/* ++ * The modebits configurable by the driver to make the SPI support different ++ * data formats ++ */ ++#define MODEBITS (SPI_CPOL | SPI_CPHA) ++ ++/* Definitions for the status of queue */ ++#define XQSPIPS_QUEUE_STOPPED 0 ++#define XQSPIPS_QUEUE_RUNNING 1 ++ ++/* QSPI MIO's count for different connection topologies */ ++#define XQSPIPS_MIO_NUM_QSPI0 6 ++#define XQSPIPS_MIO_NUM_QSPI1 5 ++#define XQSPIPS_MIO_NUM_QSPI1_CS 1 ++ ++/* QSPI connections topology */ ++enum xqspips_con_topology { ++ MODE_UNKNOWN = -1, ++ MODE_SINGLE, ++ MODE_DUAL_PARALLEL, ++ MODE_DUAL_STACKED, ++}; ++ ++/* Definitions of the flash commands - Flash opcodes in ascending order */ ++#define XQSPIPS_FLASH_OPCODE_WRSR 0x01 /* Write status register */ ++#define XQSPIPS_FLASH_OPCODE_PP 0x02 /* Page program */ ++#define XQSPIPS_FLASH_OPCODE_NORM_READ 0x03 /* Normal read data bytes */ ++#define XQSPIPS_FLASH_OPCODE_WRDS 0x04 /* Write disable */ ++#define XQSPIPS_FLASH_OPCODE_RDSR1 0x05 /* Read status register 1 */ ++#define XQSPIPS_FLASH_OPCODE_WREN 0x06 /* Write enable */ ++#define XQSPIPS_FLASH_OPCODE_FAST_READ 0x0B /* Fast read data bytes */ ++#define XQSPIPS_FLASH_OPCODE_BRRD 0x16 /* Bank address reg read */ ++#define XQSPIPS_FLASH_OPCODE_BRWR 0x17 /* Bank address reg write */ ++#define XQSPIPS_FLASH_OPCODE_BE_4K 0x20 /* Erase 4KiB block */ ++#define XQSPIPS_FLASH_OPCODE_RDSR2 0x35 /* Read status register 2 */ ++#define XQSPIPS_FLASH_OPCODE_DUAL_READ 0x3B /* Dual read data bytes */ ++#define XQSPIPS_FLASH_OPCODE_BE_32K 0x52 /* Erase 32KiB block */ ++#define XQSPIPS_FLASH_OPCODE_QUAD_READ 0x6B /* Quad read data bytes */ ++#define XQSPIPS_FLASH_OPCODE_ERASE_SUS 0x75 /* Erase suspend */ ++#define XQSPIPS_FLASH_OPCODE_ERASE_RES 0x7A /* Erase resume */ ++#define XQSPIPS_FLASH_OPCODE_RDID 0x9F /* Read JEDEC ID */ ++#define XQSPIPS_FLASH_OPCODE_BE 0xC7 /* Erase whole flash block */ ++#define XQSPIPS_FLASH_OPCODE_SE 0xD8 /* Sector erase (usually 64KB)*/ ++ ++/* Few mtd flash functions */ ++extern int spi_flash_cmd(struct spi_slave *spi, u8 cmd, ++ void *response, size_t len); ++extern int spi_flash_cmd_read(struct spi_slave *spi, const u8 *cmd, ++ size_t cmd_len, void *data, size_t data_len); ++ ++/* QSPI register offsets */ ++struct xqspips_regs { ++ u32 confr; /* 0x00 */ ++ u32 isr; /* 0x04 */ ++ u32 ier; /* 0x08 */ ++ u32 idisr; /* 0x0C */ ++ u32 imaskr; /* 0x10 */ ++ u32 enbr; /* 0x14 */ ++ u32 dr; /* 0x18 */ ++ u32 txd0r; /* 0x1C */ ++ u32 drxr; /* 0x20 */ ++ u32 sicr; /* 0x24 */ ++ u32 txftr; /* 0x28 */ ++ u32 rxftr; /* 0x2C */ ++ u32 gpior; /* 0x30 */ ++ u32 reserved0[19]; ++ u32 txd1r; /* 0x80 */ ++ u32 txd2r; /* 0x84 */ ++ u32 txd3r; /* 0x88 */ ++ u32 reserved1[5]; ++ u32 lcr; /* 0xA0 */ ++ u32 reserved2[22]; ++ u32 midr; /* 0xFC */ ++}; ++ ++#define xqspips_base ((struct xqspips_regs *) XPSS_QSPI_BASEADDR) ++ ++struct xqspips { ++ u32 input_clk_hz; ++ u32 speed_hz; ++ const void *txbuf; ++ void *rxbuf; ++ int bytes_to_transfer; ++ int bytes_to_receive; ++ struct xqspips_inst_format *curr_inst; ++ u8 inst_response; ++ unsigned int is_inst; ++ unsigned int is_dual; ++}; ++ ++struct spi_device { ++ struct xqspips master; ++ u32 max_speed_hz; ++ u8 chip_select; ++ u8 mode; ++ u8 bits_per_word; ++}; ++ ++struct spi_transfer { ++ const void *tx_buf; ++ void *rx_buf; ++ unsigned len; ++ unsigned cs_change:1; ++ u8 bits_per_word; ++ u16 delay_usecs; ++ u32 speed_hz; ++}; ++ ++struct zynq_spi_slave { ++ struct spi_slave slave; ++ struct spi_device qspi; ++}; ++#define to_zynq_spi_slave(s) container_of(s, struct zynq_spi_slave, slave) ++ ++/* ++ * struct xqspips_inst_format - Defines qspi flash instruction format ++ * @opcode: Operational code of instruction ++ * @inst_size: Size of the instruction including address bytes ++ * @offset: Register address where instruction has to be written ++ */ ++struct xqspips_inst_format { ++ u8 opcode; ++ u8 inst_size; ++ u8 offset; ++}; ++ ++/* List of all the QSPI instructions and its format */ ++static struct xqspips_inst_format flash_inst[] = { ++ { XQSPIPS_FLASH_OPCODE_WREN, 1, XQSPIPS_TXD_00_01_OFFSET }, ++ { XQSPIPS_FLASH_OPCODE_WRDS, 1, XQSPIPS_TXD_00_01_OFFSET }, ++ { XQSPIPS_FLASH_OPCODE_RDSR1, 1, XQSPIPS_TXD_00_01_OFFSET }, ++ { XQSPIPS_FLASH_OPCODE_RDSR2, 1, XQSPIPS_TXD_00_01_OFFSET }, ++ { XQSPIPS_FLASH_OPCODE_WRSR, 1, XQSPIPS_TXD_00_01_OFFSET }, ++ { XQSPIPS_FLASH_OPCODE_PP, 4, XQSPIPS_TXD_00_00_OFFSET }, ++ { XQSPIPS_FLASH_OPCODE_SE, 4, XQSPIPS_TXD_00_00_OFFSET }, ++ { XQSPIPS_FLASH_OPCODE_BE_32K, 4, XQSPIPS_TXD_00_00_OFFSET }, ++ { XQSPIPS_FLASH_OPCODE_BE_4K, 4, XQSPIPS_TXD_00_00_OFFSET }, ++ { XQSPIPS_FLASH_OPCODE_BE, 1, XQSPIPS_TXD_00_01_OFFSET }, ++ { XQSPIPS_FLASH_OPCODE_ERASE_SUS, 1, XQSPIPS_TXD_00_01_OFFSET }, ++ { XQSPIPS_FLASH_OPCODE_ERASE_RES, 1, XQSPIPS_TXD_00_01_OFFSET }, ++ { XQSPIPS_FLASH_OPCODE_RDID, 1, XQSPIPS_TXD_00_01_OFFSET }, ++ { XQSPIPS_FLASH_OPCODE_NORM_READ, 4, XQSPIPS_TXD_00_00_OFFSET }, ++ { XQSPIPS_FLASH_OPCODE_FAST_READ, 1, XQSPIPS_TXD_00_01_OFFSET }, ++ { XQSPIPS_FLASH_OPCODE_DUAL_READ, 1, XQSPIPS_TXD_00_01_OFFSET }, ++ { XQSPIPS_FLASH_OPCODE_QUAD_READ, 1, XQSPIPS_TXD_00_01_OFFSET }, ++ { XQSPIPS_FLASH_OPCODE_BRWR, 1, XQSPIPS_TXD_00_01_OFFSET }, ++ { XQSPIPS_FLASH_OPCODE_BRRD, 1, XQSPIPS_TXD_00_01_OFFSET }, ++ /* Add all the instructions supported by the flash device */ ++}; ++ ++/* ++ * xqspips_init_hw - Initialize the hardware ++ * @is_dual: Indicates whether dual memories are used ++ * @cs: Indicates which chip select is used in dual stacked ++ * ++ * The default settings of the QSPI controller's configurable parameters on ++ * reset are ++ * - Master mode ++ * - Baud rate divisor is set to 2 ++ * - Threshold value for TX FIFO not full interrupt is set to 1 ++ * - Flash memory interface mode enabled ++ * - Size of the word to be transferred as 8 bit ++ * This function performs the following actions ++ * - Disable and clear all the interrupts ++ * - Enable manual slave select ++ * - Enable manual start ++ * - Deselect all the chip select lines ++ * - Set the size of the word to be transferred as 32 bit ++ * - Set the little endian mode of TX FIFO and ++ * - Enable the QSPI controller ++ */ ++static void xqspips_init_hw(int is_dual, unsigned int cs) ++{ ++ u32 config_reg; ++ ++ writel(~XQSPIPS_ENABLE_ENABLE_MASK, &xqspips_base->enbr); ++ writel(0x7F, &xqspips_base->idisr); ++ ++ /* Disable linear mode as the boot loader may have used it */ ++ writel(0x0, &xqspips_base->lcr); ++ ++ /* Clear the RX FIFO */ ++ while (readl(&xqspips_base->isr) & XQSPIPS_IXR_RXNEMTY_MASK) ++ readl(&xqspips_base->drxr); ++ ++ writel(0x7F, &xqspips_base->isr); ++ config_reg = readl(&xqspips_base->confr); ++ config_reg &= 0xFBFFFFFF; /* Set little endian mode of TX FIFO */ ++ config_reg |= 0x8000FCC1; ++ writel(config_reg, &xqspips_base->confr); ++ ++ if (is_dual == MODE_DUAL_PARALLEL) ++ /* Enable two memories on seperate buses */ ++ writel((XQSPIPS_LCFG_TWO_MEM_MASK | ++ XQSPIPS_LCFG_SEP_BUS_MASK | ++ (1 << XQSPIPS_LCFG_DUMMY_SHIFT) | ++ XQSPIPS_FAST_READ_QOUT_CODE), ++ &xqspips_base->lcr); ++ else if (is_dual == MODE_DUAL_STACKED) { ++ if (cs) ++ /* Enable two memories on shared buse with upper mem */ ++ writel((XQSPIPS_LCFG_TWO_MEM_MASK | ++ XQSPIPS_LCFG_U_PAGE | ++ (1 << XQSPIPS_LCFG_DUMMY_SHIFT) | ++ XQSPIPS_FAST_READ_QOUT_CODE), ++ &xqspips_base->lcr); ++ else ++ /* Enable two memories on shared buse with lower mem */ ++ writel((XQSPIPS_LCFG_TWO_MEM_MASK | ++ (1 << XQSPIPS_LCFG_DUMMY_SHIFT) | ++ XQSPIPS_FAST_READ_QOUT_CODE), ++ &xqspips_base->lcr); ++ } ++ ++ writel(XQSPIPS_ENABLE_ENABLE_MASK, &xqspips_base->enbr); ++} ++ ++/* ++ * xqspips_copy_read_data - Copy data to RX buffer ++ * @xqspi: Pointer to the xqspips structure ++ * @data: The 32 bit variable where data is stored ++ * @size: Number of bytes to be copied from data to RX buffer ++ */ ++static void xqspips_copy_read_data(struct xqspips *xqspi, u32 data, u8 size) ++{ ++ u8 byte3; ++ ++ debug("xqspips_copy_read_data: data 0x%04x rxbuf addr: 0x%08x" ++ " size %d\n", data, (unsigned)(xqspi->rxbuf), size); ++ ++ if (xqspi->rxbuf) { ++ switch (size) { ++ case 1: ++ *((u8 *)xqspi->rxbuf) = data; ++ xqspi->rxbuf += 1; ++ break; ++ case 2: ++ *((u16 *)xqspi->rxbuf) = data; ++ xqspi->rxbuf += 2; ++ break; ++ case 3: ++ *((u16 *)xqspi->rxbuf) = data; ++ xqspi->rxbuf += 2; ++ byte3 = (u8)(data >> 16); ++ *((u8 *)xqspi->rxbuf) = byte3; ++ xqspi->rxbuf += 1; ++ break; ++ case 4: ++ /* Can not assume word aligned buffer */ ++ memcpy(xqspi->rxbuf, &data, size); ++ xqspi->rxbuf += 4; ++ break; ++ default: ++ /* This will never execute */ ++ break; ++ } ++ } ++ xqspi->bytes_to_receive -= size; ++ if (xqspi->bytes_to_receive < 0) ++ xqspi->bytes_to_receive = 0; ++} ++ ++/* ++ * xqspips_copy_write_data - Copy data from TX buffer ++ * @xqspi: Pointer to the xqspips structure ++ * @data: Pointer to the 32 bit variable where data is to be copied ++ * @size: Number of bytes to be copied from TX buffer to data ++ */ ++static void xqspips_copy_write_data(struct xqspips *xqspi, u32 *data, u8 size) ++{ ++ ++ if (xqspi->txbuf) { ++ switch (size) { ++ case 1: ++ *data = *((u8 *)xqspi->txbuf); ++ xqspi->txbuf += 1; ++ *data |= 0xFFFFFF00; ++ break; ++ case 2: ++ *data = *((u16 *)xqspi->txbuf); ++ xqspi->txbuf += 2; ++ *data |= 0xFFFF0000; ++ break; ++ case 3: ++ *data = *((u16 *)xqspi->txbuf); ++ xqspi->txbuf += 2; ++ *data |= (*((u8 *)xqspi->txbuf) << 16); ++ xqspi->txbuf += 1; ++ *data |= 0xFF000000; ++ break; ++ case 4: ++ /* Can not assume word aligned buffer */ ++ memcpy(data, xqspi->txbuf, size); ++ xqspi->txbuf += 4; ++ break; ++ default: ++ /* This will never execute */ ++ break; ++ } ++ } else ++ *data = 0; ++ ++ debug("xqspips_copy_write_data: data 0x%08x txbuf addr: 0x%08x" ++ " size %d\n", *data, (u32)xqspi->txbuf, size); ++ ++ xqspi->bytes_to_transfer -= size; ++ if (xqspi->bytes_to_transfer < 0) ++ xqspi->bytes_to_transfer = 0; ++} ++ ++/* ++ * xqspips_chipselect - Select or deselect the chip select line ++ * @qspi: Pointer to the spi_device structure ++ * @is_on: Select(1) or deselect (0) the chip select line ++ */ ++static void xqspips_chipselect(struct spi_device *qspi, int is_on) ++{ ++ u32 config_reg; ++ ++ debug("xqspips_chipselect: is_on: %d\n", is_on); ++ ++ config_reg = readl(&xqspips_base->confr); ++ ++ if (is_on) { ++ /* Select the slave */ ++ config_reg &= ~XQSPIPS_CONFIG_SSCTRL_MASK; ++ config_reg |= (((~(0x0001 << qspi->chip_select)) << 10) & ++ XQSPIPS_CONFIG_SSCTRL_MASK); ++ } else ++ /* Deselect the slave */ ++ config_reg |= XQSPIPS_CONFIG_SSCTRL_MASK; ++ ++ writel(config_reg, &xqspips_base->confr); ++} ++ ++/* ++ * xqspips_setup_transfer - Configure QSPI controller for specified transfer ++ * @qspi: Pointer to the spi_device structure ++ * @transfer: Pointer to the spi_transfer structure which provides information ++ * about next transfer setup parameters ++ * ++ * Sets the operational mode of QSPI controller for the next QSPI transfer and ++ * sets the requested clock frequency. ++ * ++ * returns: 0 on success and -1 on invalid input parameter ++ * ++ * Note: If the requested frequency is not an exact match with what can be ++ * obtained using the prescalar value, the driver sets the clock frequency which ++ * is lower than the requested frequency (maximum lower) for the transfer. If ++ * the requested frequency is higher or lower than that is supported by the QSPI ++ * controller the driver will set the highest or lowest frequency supported by ++ * controller. ++ */ ++static int xqspips_setup_transfer(struct spi_device *qspi, ++ struct spi_transfer *transfer) ++{ ++ struct xqspips *xqspi = &qspi->master; ++ u8 bits_per_word; ++ u32 config_reg; ++ u32 req_hz; ++ u32 baud_rate_val = 0; ++ ++ debug("xqspips_setup_transfer: qspi: 0x%08x transfer: 0x%08x\n", ++ (u32)qspi, (u32)transfer); ++ ++ bits_per_word = (transfer) ? ++ transfer->bits_per_word : qspi->bits_per_word; ++ req_hz = (transfer) ? transfer->speed_hz : qspi->max_speed_hz; ++ ++ if (qspi->mode & ~MODEBITS) { ++ printf("%s, unsupported mode bits %x\n", ++ __func__, qspi->mode & ~MODEBITS); ++ return -1; ++ } ++ ++ if (bits_per_word != 32) ++ bits_per_word = 32; ++ ++ config_reg = readl(&xqspips_base->confr); ++ ++ /* Set the QSPI clock phase and clock polarity */ ++ config_reg &= (~XQSPIPS_CONFIG_CPHA_MASK) & ++ (~XQSPIPS_CONFIG_CPOL_MASK); ++ if (qspi->mode & SPI_CPHA) ++ config_reg |= XQSPIPS_CONFIG_CPHA_MASK; ++ if (qspi->mode & SPI_CPOL) ++ config_reg |= XQSPIPS_CONFIG_CPOL_MASK; ++ ++ /* Set the clock frequency */ ++ if (xqspi->speed_hz != req_hz) { ++ baud_rate_val = 0; ++ while ((baud_rate_val < 8) && ++ (xqspi->input_clk_hz / (2 << baud_rate_val)) > req_hz) { ++ baud_rate_val++; ++ } ++ config_reg &= 0xFFFFFFC7; ++ config_reg |= (baud_rate_val << 3); ++ xqspi->speed_hz = req_hz; ++ } ++ ++ writel(config_reg, &xqspips_base->confr); ++ ++ debug("xqspips_setup_transfer: mode %d, %u bits/w, %u clock speed\n", ++ qspi->mode & MODEBITS, qspi->bits_per_word, xqspi->speed_hz); ++ ++ return 0; ++} ++ ++/* ++ * xqspips_fill_tx_fifo - Fills the TX FIFO with as many bytes as possible ++ * @xqspi: Pointer to the xqspips structure ++ */ ++static void xqspips_fill_tx_fifo(struct xqspips *xqspi) ++{ ++ u32 data = 0; ++ unsigned len, offset; ++ static const unsigned offsets[4] = { ++ XQSPIPS_TXD_00_00_OFFSET, XQSPIPS_TXD_00_01_OFFSET, ++ XQSPIPS_TXD_00_10_OFFSET, XQSPIPS_TXD_00_11_OFFSET }; ++ ++ while ((!(readl(&xqspips_base->isr) & ++ XQSPIPS_IXR_TXFULL_MASK)) && ++ (xqspi->bytes_to_transfer > 0)) { ++ if (xqspi->bytes_to_transfer < 4) { ++ /* Write TXD1, TXD2, TXD3 only if TxFIFO is empty. */ ++ if (!(readl(&xqspips_base->isr) ++ & XQSPIPS_IXR_TXNFULL_MASK) && ++ !xqspi->rxbuf) ++ return; ++ len = xqspi->bytes_to_transfer; ++ xqspips_copy_write_data(xqspi, &data, len); ++ offset = (xqspi->rxbuf) ? offsets[0] : offsets[len]; ++ writel(data, &xqspips_base->confr + (offset / 4)); ++ } else { ++ xqspips_copy_write_data(xqspi, &data, 4); ++ writel(data, &xqspips_base->txd0r); ++ } ++ } ++} ++ ++/* ++ * xqspips_irq_poll - Interrupt service routine of the QSPI controller ++ * @xqspi: Pointer to the xqspips structure ++ * ++ * This function handles TX empty and Mode Fault interrupts only. ++ * On TX empty interrupt this function reads the received data from RX FIFO and ++ * fills the TX FIFO if there is any data remaining to be transferred. ++ * On Mode Fault interrupt this function indicates that transfer is completed, ++ * the SPI subsystem will identify the error as the remaining bytes to be ++ * transferred is non-zero. ++ * ++ * returns: 0 for poll timeout ++ * 1 transfer operation complete ++ */ ++static int xqspips_irq_poll(struct xqspips *xqspi) ++{ ++ int max_loop; ++ u32 intr_status; ++ ++ debug("xqspips_irq_poll: xqspi: 0x%08x\n", (u32)xqspi); ++ ++ /* Poll until any of the interrupt status bits are set */ ++ max_loop = 0; ++ do { ++ intr_status = readl(&xqspips_base->isr); ++ max_loop++; ++ } while ((intr_status == 0) && (max_loop < 100000)); ++ ++ if (intr_status == 0) { ++ printf("xqspips_irq_poll: timeout\n"); ++ return 0; ++ } ++ ++ writel(intr_status, &xqspips_base->isr); ++ ++ /* Disable all interrupts */ ++ writel(XQSPIPS_IXR_ALL_MASK, &xqspips_base->idisr); ++ if ((intr_status & XQSPIPS_IXR_TXNFULL_MASK) || ++ (intr_status & XQSPIPS_IXR_RXNEMTY_MASK)) { ++ ++ /* ++ * This bit is set when Tx FIFO has < THRESHOLD entries. We have ++ * the THRESHOLD value set to 1, so this bit indicates Tx FIFO ++ * is empty ++ */ ++ u32 config_reg; ++ ++ /* Read out the data from the RX FIFO */ ++ while (readl(&xqspips_base->isr) & ++ XQSPIPS_IXR_RXNEMTY_MASK) { ++ u32 data; ++ ++ data = readl(&xqspips_base->drxr); ++ ++ if ((xqspi->inst_response) && ++ (!((xqspi->curr_inst->opcode == ++ XQSPIPS_FLASH_OPCODE_RDSR1) || ++ (xqspi->curr_inst->opcode == ++ XQSPIPS_FLASH_OPCODE_RDSR2)))) { ++ xqspi->inst_response = 0; ++ xqspips_copy_read_data(xqspi, data, ++ xqspi->curr_inst->inst_size); ++ } else if (xqspi->bytes_to_receive < 4) ++ xqspips_copy_read_data(xqspi, data, ++ xqspi->bytes_to_receive); ++ else ++ xqspips_copy_read_data(xqspi, data, 4); ++ } ++ ++ if (xqspi->bytes_to_transfer) { ++ /* There is more data to send */ ++ xqspips_fill_tx_fifo(xqspi); ++ ++ writel(XQSPIPS_IXR_ALL_MASK, &xqspips_base->ier); ++ ++ config_reg = readl(&xqspips_base->confr); ++ ++ config_reg |= XQSPIPS_CONFIG_MANSRT_MASK; ++ writel(config_reg, &xqspips_base->confr); ++ } else { ++ /* ++ * If transfer and receive is completed then only send ++ * complete signal ++ */ ++ if (!xqspi->bytes_to_receive) { ++ /* return operation complete */ ++ writel(XQSPIPS_IXR_ALL_MASK, ++ &xqspips_base->idisr); ++ return 1; ++ } ++ } ++ } ++ ++ return 0; ++} ++ ++/* ++ * xqspips_start_transfer - Initiates the QSPI transfer ++ * @qspi: Pointer to the spi_device structure ++ * @transfer: Pointer to the spi_transfer structure which provide information ++ * about next transfer parameters ++ * ++ * This function fills the TX FIFO, starts the QSPI transfer, and waits for the ++ * transfer to be completed. ++ * ++ * returns: Number of bytes transferred in the last transfer ++ */ ++static int xqspips_start_transfer(struct spi_device *qspi, ++ struct spi_transfer *transfer) ++{ ++ struct xqspips *xqspi = &qspi->master; ++ u32 config_reg; ++ u32 data = 0; ++ u8 instruction = 0; ++ u8 index; ++ ++ debug("xqspips_start_transfer: qspi: 0x%08x transfer: 0x%08x len: %d\n", ++ (u32)qspi, (u32)transfer, transfer->len); ++ ++ xqspi->txbuf = transfer->tx_buf; ++ xqspi->rxbuf = transfer->rx_buf; ++ xqspi->bytes_to_transfer = transfer->len; ++ xqspi->bytes_to_receive = transfer->len; ++ ++ if (xqspi->txbuf) ++ instruction = *(u8 *)xqspi->txbuf; ++ ++ if (instruction && xqspi->is_inst) { ++ for (index = 0 ; index < ARRAY_SIZE(flash_inst); index++) ++ if (instruction == flash_inst[index].opcode) ++ break; ++ ++ /* ++ * Instruction might have already been transmitted. This is a ++ * 'data only' transfer ++ */ ++ if (index == ARRAY_SIZE(flash_inst)) ++ goto xfer_data; ++ ++ xqspi->curr_inst = &flash_inst[index]; ++ xqspi->inst_response = 1; ++ ++ /* ++ * In case of dual memories, convert 25 bit address to 24 bit ++ * address before transmitting to the 2 memories ++ */ ++ if ((xqspi->is_dual == MODE_DUAL_PARALLEL) && ++ ((instruction == XQSPIPS_FLASH_OPCODE_PP) || ++ (instruction == XQSPIPS_FLASH_OPCODE_SE) || ++ (instruction == XQSPIPS_FLASH_OPCODE_BE_32K) || ++ (instruction == XQSPIPS_FLASH_OPCODE_BE_4K) || ++ (instruction == XQSPIPS_FLASH_OPCODE_BE) || ++ (instruction == XQSPIPS_FLASH_OPCODE_NORM_READ) || ++ (instruction == XQSPIPS_FLASH_OPCODE_FAST_READ) || ++ (instruction == XQSPIPS_FLASH_OPCODE_DUAL_READ) || ++ (instruction == XQSPIPS_FLASH_OPCODE_QUAD_READ))) { ++ ++ u8 *ptr = (u8 *) (xqspi->txbuf); ++ data = ((u32) ptr[1] << 24) | ((u32) ptr[2] << 16) | ++ ((u32) ptr[3] << 8) | ((u32) ptr[4]); ++ data = data/2; ++ ptr[1] = (u8) (data >> 16); ++ ptr[2] = (u8) (data >> 8); ++ ptr[3] = (u8) (data); ++ xqspi->bytes_to_transfer -= 1; ++ xqspi->bytes_to_receive -= 1; ++ } ++ ++ /* Get the instruction */ ++ data = 0; ++ xqspips_copy_write_data(xqspi, &data, ++ xqspi->curr_inst->inst_size); ++ ++ /* ++ * Write the instruction to LSB of the FIFO. The core is ++ * designed such that it is not necessary to check whether the ++ * write FIFO is full before writing. However, write would be ++ * delayed if the user tries to write when write FIFO is full ++ */ ++ writel(data, &xqspips_base->confr + ++ (xqspi->curr_inst->offset / 4)); ++ ++ /* ++ * Read status register and Read ID instructions don't require ++ * to ignore the extra bytes in response of instruction as ++ * response contains the value ++ */ ++ if ((instruction == XQSPIPS_FLASH_OPCODE_RDSR1) || ++ (instruction == XQSPIPS_FLASH_OPCODE_RDSR2) || ++ (instruction == XQSPIPS_FLASH_OPCODE_RDID) || ++ (instruction == XQSPIPS_FLASH_OPCODE_BRRD)) { ++ if (xqspi->bytes_to_transfer < 4) ++ xqspi->bytes_to_transfer = 0; ++ else ++ xqspi->bytes_to_transfer -= 3; ++ } ++ } ++ ++xfer_data: ++ /* ++ * In case of Fast, Dual and Quad reads, transmit the instruction first. ++ * Address and dummy byte should be transmitted after instruction ++ * is transmitted ++ */ ++ if (((xqspi->is_inst == 0) && (xqspi->bytes_to_transfer)) || ++ ((xqspi->bytes_to_transfer) && ++ (instruction != XQSPIPS_FLASH_OPCODE_FAST_READ) && ++ (instruction != XQSPIPS_FLASH_OPCODE_DUAL_READ) && ++ (instruction != XQSPIPS_FLASH_OPCODE_QUAD_READ))) ++ xqspips_fill_tx_fifo(xqspi); ++ ++ writel(XQSPIPS_IXR_ALL_MASK, &xqspips_base->ier); ++ /* Start the transfer by enabling manual start bit */ ++ config_reg = readl(&xqspips_base->confr) | XQSPIPS_CONFIG_MANSRT_MASK; ++ writel(config_reg, &xqspips_base->confr); ++ ++ /* wait for completion */ ++ do { ++ data = xqspips_irq_poll(xqspi); ++ } while (data == 0); ++ ++ return (transfer->len) - (xqspi->bytes_to_transfer); ++} ++ ++static int xqspips_transfer(struct spi_device *qspi, ++ struct spi_transfer *transfer) ++{ ++ struct xqspips *xqspi = &qspi->master; ++ unsigned cs_change = 1; ++ int status = 0; ++ ++ debug("xqspips_transfer\n"); ++ ++ while (1) { ++ if (transfer->bits_per_word || transfer->speed_hz) { ++ status = xqspips_setup_transfer(qspi, transfer); ++ if (status < 0) ++ break; ++ } ++ ++ /* Select the chip if required */ ++ if (cs_change) ++ xqspips_chipselect(qspi, 1); ++ ++ cs_change = transfer->cs_change; ++ ++ if (!transfer->tx_buf && !transfer->rx_buf && transfer->len) { ++ status = -1; ++ break; ++ } ++ ++ /* Request the transfer */ ++ if (transfer->len) { ++ status = xqspips_start_transfer(qspi, transfer); ++ xqspi->is_inst = 0; ++ } ++ ++ if (status != transfer->len) { ++ if (status > 0) ++ status = -EMSGSIZE; ++ break; ++ } ++ status = 0; ++ ++ if (transfer->delay_usecs) ++ udelay(transfer->delay_usecs); ++ ++ if (cs_change) ++ /* Deselect the chip */ ++ xqspips_chipselect(qspi, 0); ++ ++ break; ++ } ++ ++ xqspips_setup_transfer(qspi, NULL); ++ ++ return 0; ++} ++ ++/* ++ * xqspips_check_is_dual_flash - checking for dual or single qspi ++ * ++ * This function will check the type of the flash whether it supports ++ * single or dual qspi based on the MIO configuration done by FSBL. ++ * ++ * User needs to correctly configure the MIO's based on the ++ * number of qspi flashes present on the board. ++ * ++ * function will return -1, if there is no MIO configuration for ++ * qspi flash. ++ */ ++static int xqspips_check_is_dual_flash(void) ++{ ++ int is_dual = MODE_UNKNOWN; ++ int lower_mio = 0, upper_mio = 0, upper_mio_cs1 = 0; ++ ++ lower_mio = zynq_slcr_get_mio_pin_status("qspi0"); ++ if (lower_mio == XQSPIPS_MIO_NUM_QSPI0) ++ is_dual = MODE_SINGLE; ++ ++ upper_mio_cs1 = zynq_slcr_get_mio_pin_status("qspi1_cs"); ++ if ((lower_mio == XQSPIPS_MIO_NUM_QSPI0) && ++ (upper_mio_cs1 == XQSPIPS_MIO_NUM_QSPI1_CS)) ++ is_dual = MODE_DUAL_STACKED; ++ ++ upper_mio = zynq_slcr_get_mio_pin_status("qspi1"); ++ if ((lower_mio == XQSPIPS_MIO_NUM_QSPI0) && ++ (upper_mio_cs1 == XQSPIPS_MIO_NUM_QSPI1_CS) && ++ (upper_mio == XQSPIPS_MIO_NUM_QSPI1)) ++ is_dual = MODE_DUAL_PARALLEL; ++ ++ return is_dual; ++} ++ ++/* ++ * xqspips_write_quad_bit - Write 1 to QUAD bit on flash ++ * ++ * This function will write a 1 to quad bit in flash ++ * using QSPI controller and supports only spansion flash. ++ * ++ * @regs_base: base address of QSPI controller ++ */ ++static void xqspips_write_quad_bit(void __iomem *regs_base) ++{ ++ u32 config_reg, intr_status; ++ ++ /* enable the QSPI controller */ ++ writel(XQSPIPS_ENABLE_ENABLE_MASK, &xqspips_base->enbr); ++ ++ /* Write QUAD bit with 3-byte instruction */ ++ writel(0x20001, &xqspips_base->txd3r); ++ ++ /* Enable manual start command */ ++ config_reg = readl(&xqspips_base->confr) | XQSPIPS_CONFIG_MANSRT_MASK; ++ writel(config_reg, &xqspips_base->confr); ++ ++ /* Wait for the transfer to finish by polling Tx fifo status */ ++ do { ++ intr_status = readl(&xqspips_base->isr); ++ } while ((intr_status & 0x04) == 0); ++ ++ /* Read data receive register */ ++ config_reg = readl(&xqspips_base->drxr); ++} ++ ++int spi_cs_is_valid(unsigned int bus, unsigned int cs) ++{ ++ /* 1 bus with 2 chipselect */ ++ return bus == 0 && cs < 2; ++} ++ ++void spi_cs_activate(struct spi_slave *slave) ++{ ++ debug("spi_cs_activate: slave 0x%08x\n", (unsigned)slave); ++} ++ ++void spi_cs_deactivate(struct spi_slave *slave) ++{ ++ debug("spi_cs_deactivate: slave 0x%08x\n", (unsigned)slave); ++} ++ ++void spi_init() ++{ ++ debug("spi_init\n"); ++} ++ ++/* ++ * spi_enable_quad_bit - Enable the QUAD bit for SPI flash ++ * ++ * This function will enable the quad bit in flash using ++ * the QSPI controller. Supports only spansion. ++ * ++ * @spi : SPI slave structure ++ */ ++void spi_enable_quad_bit(struct spi_slave *spi) ++{ ++ int ret; ++ u8 idcode[5]; ++ u8 rdid_cmd = 0x9f; /* RDID */ ++ u8 rcr_data = 0; ++ u8 rcr_cmd = 0x35; /* RCR */ ++ u8 rdsr_cmd = 0x05; /* RDSR */ ++ u8 wren_cmd = 0x06; /* WREN */ ++ ++ ret = spi_flash_cmd(spi, rdid_cmd, &idcode, sizeof(idcode)); ++ if (ret) { ++ debug("SF error: Failed read RDID\n"); ++ return; ++ } ++ ++ if ((idcode[0] == 0x01) || (idcode[0] == 0xef)) { ++ /* Read config register */ ++ ret = spi_flash_cmd_read(spi, &rcr_cmd, sizeof(rcr_cmd), ++ &rcr_data, sizeof(rcr_data)); ++ if (ret) { ++ debug("SF error: Failed read RCR\n"); ++ return; ++ } ++ ++ if (rcr_data & 0x2) ++ debug("QUAD bit is already set..\n"); ++ else { ++ debug("QUAD bit needs to be set ..\n"); ++ ++ /* Write enable */ ++ ret = spi_flash_cmd(spi, wren_cmd, NULL, 0); ++ if (ret) { ++ debug("SF error: Failed write WREN\n"); ++ return; ++ } ++ ++ /* Write QUAD bit */ ++ xqspips_write_quad_bit((void *)XPSS_QSPI_BASEADDR); ++ ++ /* Read RDSR */ ++ do { ++ ret = spi_flash_cmd_read(spi, &rdsr_cmd, ++ sizeof(rdsr_cmd), &rcr_data, ++ sizeof(rcr_data)); ++ } while ((ret == 0) && (rcr_data != 0)); ++ ++ /* Read config register */ ++ ret = spi_flash_cmd_read(spi, &rcr_cmd, sizeof(rcr_cmd), ++ &rcr_data, sizeof(rcr_data)); ++ if (!(rcr_data & 0x2)) { ++ printf("SF error: Fail to set QUAD enable bit" ++ " 0x%x\n", rcr_data); ++ return; ++ } else ++ debug("SF: QUAD enable bit is set 0x%x\n", ++ rcr_data); ++ } ++ } else ++ debug("SF: QUAD bit not enabled for 0x%x SPI flash\n", ++ idcode[0]); ++ ++ return; ++} ++ ++struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, ++ unsigned int max_hz, unsigned int mode) ++{ ++ int is_dual; ++ struct zynq_spi_slave *pspi; ++ ++ debug("spi_setup_slave: bus: %d cs: %d max_hz: %d mode: %d\n", ++ bus, cs, max_hz, mode); ++ ++ if (!spi_cs_is_valid(bus, cs)) ++ return NULL; ++ ++ is_dual = xqspips_check_is_dual_flash(); ++ ++ if (is_dual == MODE_UNKNOWN) { ++ printf("SPI error: No QSPI device detected based" ++ " on MIO settings\n"); ++ return NULL; ++ } ++ ++ xqspips_init_hw(is_dual, cs); ++ ++ pspi = malloc(sizeof(struct zynq_spi_slave)); ++ if (!pspi) { ++ printf("SPI error: fail to allocate zynq_spi_slave\n"); ++ return NULL; ++ } ++ ++ pspi->slave.bus = bus; ++ pspi->slave.cs = cs; ++ pspi->slave.is_dual = is_dual; ++ pspi->qspi.master.input_clk_hz = 100000000; ++ pspi->qspi.master.speed_hz = pspi->qspi.master.input_clk_hz / 2; ++ pspi->qspi.max_speed_hz = pspi->qspi.master.speed_hz; ++ pspi->qspi.master.is_dual = is_dual; ++ pspi->qspi.mode = mode; ++ pspi->qspi.chip_select = 0; ++ pspi->qspi.bits_per_word = 32; ++ xqspips_setup_transfer(&pspi->qspi, NULL); ++ ++ spi_enable_quad_bit(&pspi->slave); ++ ++ return &pspi->slave; ++} ++ ++void spi_free_slave(struct spi_slave *slave) ++{ ++ struct zynq_spi_slave *pspi; ++ ++ debug("spi_free_slave: slave: 0x%08x\n", (u32)slave); ++ ++ pspi = to_zynq_spi_slave(slave); ++ free(pspi); ++} ++ ++int spi_claim_bus(struct spi_slave *slave) ++{ ++ debug("spi_claim_bus: slave: 0x%08x\n", (u32)slave); ++ return 0; ++} ++ ++void spi_release_bus(struct spi_slave *slave) ++{ ++ debug("spi_release_bus: slave: 0x%08x\n", (u32)slave); ++} ++ ++int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, ++ void *din, unsigned long flags) ++{ ++ struct zynq_spi_slave *pspi; ++ struct spi_transfer transfer; ++ ++ debug("spi_xfer: slave: 0x%08x bitlen: %d dout: 0x%08x din:" ++ " 0x%08x flags: 0x%lx\n", ++ (u32)slave, bitlen, (u32)dout, (u32)din, flags); ++ ++ pspi = (struct zynq_spi_slave *)slave; ++ transfer.tx_buf = dout; ++ transfer.rx_buf = din; ++ transfer.len = bitlen / 8; ++ ++ /* ++ * Festering sore. ++ * Assume that the beginning of a transfer with bits to ++ * transmit must contain a device command. ++ */ ++ if (dout && flags & SPI_XFER_BEGIN) ++ pspi->qspi.master.is_inst = 1; ++ else ++ pspi->qspi.master.is_inst = 0; ++ ++ if (flags & SPI_XFER_END) ++ transfer.cs_change = 1; ++ else ++ transfer.cs_change = 0; ++ ++ transfer.delay_usecs = 0; ++ transfer.bits_per_word = 32; ++ transfer.speed_hz = pspi->qspi.max_speed_hz; ++ ++ xqspips_transfer(&pspi->qspi, &transfer); ++ ++ return 0; ++} +diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile +index b1f4e0f..13e7c37 100644 +--- a/drivers/watchdog/Makefile ++++ b/drivers/watchdog/Makefile +@@ -32,6 +32,7 @@ COBJS-y += imx_watchdog.o + endif + COBJS-$(CONFIG_TNETV107X_WATCHDOG) += tnetv107x_wdt.o + COBJS-$(CONFIG_S5P) += s5p_wdt.o ++COBJS-$(CONFIG_XILINX_TB_WATCHDOG) += xilinx_tb_wdt.o + + COBJS := $(COBJS-y) + SRCS := $(COBJS:.o=.c) +diff --git a/drivers/watchdog/xilinx_tb_wdt.c b/drivers/watchdog/xilinx_tb_wdt.c +new file mode 100644 +index 0000000..96caa07 +--- /dev/null ++++ b/drivers/watchdog/xilinx_tb_wdt.c +@@ -0,0 +1,87 @@ ++/* ++ * Copyright (c) 2011-2013 Xilinx Inc. ++ * ++ * 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 ++#include ++#include ++#include ++#include ++ ++#define XWT_CSR0_WRS_MASK 0x00000008 /* Reset status Mask */ ++#define XWT_CSR0_WDS_MASK 0x00000004 /* Timer state Mask */ ++#define XWT_CSR0_EWDT1_MASK 0x00000002 /* Enable bit 1 Mask*/ ++#define XWT_CSRX_EWDT2_MASK 0x00000001 /* Enable bit 2 Mask */ ++ ++struct watchdog_regs { ++ u32 twcsr0; /* 0x0 */ ++ u32 twcsr1; /* 0x4 */ ++ u32 tbr; /* 0x8 */ ++}; ++ ++#define watchdog_base ((struct watchdog_regs *) CONFIG_WATCHDOG_BASEADDR) ++ ++void hw_watchdog_reset(void) ++{ ++ u32 reg; ++ ++ /* Read the current contents of TCSR0 */ ++ reg = readl(&watchdog_base->twcsr0); ++ ++ /* Clear the watchdog WDS bit */ ++ if (reg & (XWT_CSR0_EWDT1_MASK | XWT_CSRX_EWDT2_MASK)) { ++ writel(reg | XWT_CSR0_WDS_MASK, &watchdog_base->twcsr0); ++ } ++} ++ ++void hw_watchdog_disable(void) ++{ ++ u32 reg; ++ ++ /* Read the current contents of TCSR0 */ ++ reg = readl(&watchdog_base->twcsr0); ++ ++ writel(reg & ~XWT_CSR0_EWDT1_MASK, &watchdog_base->twcsr0); ++ writel(~XWT_CSRX_EWDT2_MASK, &watchdog_base->twcsr1); ++ ++ puts("Watchdog disabled!\n"); ++} ++ ++static void hw_watchdog_isr(void *arg) ++{ ++ hw_watchdog_reset(); ++} ++ ++int hw_watchdog_init(void) ++{ ++ int ret; ++ ++ writel((XWT_CSR0_WRS_MASK | XWT_CSR0_WDS_MASK | XWT_CSR0_EWDT1_MASK), ++ &watchdog_base->twcsr0); ++ writel(XWT_CSRX_EWDT2_MASK, &watchdog_base->twcsr1); ++ ++ ret = install_interrupt_handler(CONFIG_WATCHDOG_IRQ, ++ hw_watchdog_isr, NULL); ++ if (ret) ++ return 1; ++ ++ return 0; ++} +diff --git a/include/netdev.h b/include/netdev.h +index 7f158d4..bef033c 100644 +--- a/include/netdev.h ++++ b/include/netdev.h +@@ -102,8 +102,8 @@ int xilinx_axiemac_initialize(bd_t *bis, unsigned long base_addr, + unsigned long dma_addr); + int xilinx_emaclite_initialize(bd_t *bis, unsigned long base_addr, + int txpp, int rxpp); +-int xilinx_ll_temac_eth_init(bd_t *bis, unsigned long base_addr, int flags, +- unsigned long ctrl_addr); ++int xilinx_ll_temac_initialize(bd_t *bis, unsigned long base_addr, ++ int mode, unsigned long ctrl); + int zynq_gem_initialize(bd_t *bis, int base_addr); + /* + * As long as the Xilinx xps_ll_temac ethernet driver has not its own interface +diff --git a/include/spi.h b/include/spi.h +index 60e85db..f483742 100644 +--- a/include/spi.h ++++ b/include/spi.h +@@ -49,10 +49,12 @@ + * + * bus: ID of the bus that the slave is attached to. + * cs: ID of the chip select connected to the slave. ++ * is_dual: Indicates whether dual memories are used + */ + struct spi_slave { + unsigned int bus; + unsigned int cs; ++ unsigned int is_dual; + }; + + /*----------------------------------------------------------------------- +diff --git a/include/spi_flash.h b/include/spi_flash.h +index 9da9062..9b0d104 100644 +--- a/include/spi_flash.h ++++ b/include/spi_flash.h +@@ -38,6 +38,8 @@ struct spi_flash { + u32 page_size; + /* Erase (sector) size */ + u32 sector_size; ++ /* To find whether single/dual spi device */ ++ u8 addr_width; + + int (*read)(struct spi_flash *flash, u32 offset, + size_t len, void *buf); +diff --git a/include/stdio_dev.h b/include/stdio_dev.h +index 932d093..9451740 100644 +--- a/include/stdio_dev.h ++++ b/include/stdio_dev.h +@@ -99,7 +99,7 @@ struct list_head* stdio_get_list(void); + struct stdio_dev* stdio_get_by_name(const char* name); + struct stdio_dev* stdio_clone(struct stdio_dev *dev); + +-#ifdef CONFIG_ARM_DCC_MULTI ++#ifdef CONFIG_ARM_DCC + int drv_arm_dcc_init(void); + #endif + #ifdef CONFIG_LCD +diff --git a/include/xilinx.h b/include/xilinx.h +index 5f25b7a..4cf53cb 100644 +--- a/include/xilinx.h ++++ b/include/xilinx.h +@@ -33,10 +33,12 @@ + #define CONFIG_SYS_VIRTEX_E CONFIG_SYS_FPGA_DEV( 0x2 ) + #define CONFIG_SYS_VIRTEX2 CONFIG_SYS_FPGA_DEV( 0x4 ) + #define CONFIG_SYS_SPARTAN3 CONFIG_SYS_FPGA_DEV( 0x8 ) ++#define CONFIG_SYS_ZYNQ CONFIG_SYS_FPGA_DEV(0x10) + #define CONFIG_SYS_XILINX_SPARTAN2 (CONFIG_SYS_FPGA_XILINX | CONFIG_SYS_SPARTAN2) + #define CONFIG_SYS_XILINX_VIRTEX_E (CONFIG_SYS_FPGA_XILINX | CONFIG_SYS_VIRTEX_E) + #define CONFIG_SYS_XILINX_VIRTEX2 (CONFIG_SYS_FPGA_XILINX | CONFIG_SYS_VIRTEX2) + #define CONFIG_SYS_XILINX_SPARTAN3 (CONFIG_SYS_FPGA_XILINX | CONFIG_SYS_SPARTAN3) ++#define CONFIG_SYS_XILINX_ZYNQ (CONFIG_SYS_FPGA_XILINX | CONFIG_SYS_ZYNQ) + /* XXX - Add new models here */ + + +@@ -59,6 +61,7 @@ typedef enum { /* typedef Xilinx_iface */ + jtag_mode, /* jtag/tap serial (not used ) */ + master_selectmap, /* master SelectMap (virtex2) */ + slave_selectmap, /* slave SelectMap (virtex2) */ ++ devcfg, /* devcfg interface (zynq) */ + max_xilinx_iface_type /* insert all new types before this */ + } Xilinx_iface; /* end, typedef Xilinx_iface */ + +@@ -68,6 +71,7 @@ typedef enum { /* typedef Xilinx_Family */ + Xilinx_VirtexE, /* Virtex-E Family */ + Xilinx_Virtex2, /* Virtex2 Family */ + Xilinx_Spartan3, /* Spartan-III Family */ ++ Xilinx_Zynq, /* Zynq Family */ + max_xilinx_type /* insert all new types before this */ + } Xilinx_Family; /* end, typedef Xilinx_Family */ + +-- +1.7.5.4 + diff --git a/recipes-bsp/u-boot/u-boot/xilinx-v2013.01/0005-Xilinx-modifications-to-configs.patch b/recipes-bsp/u-boot/u-boot/xilinx-v2013.01/0005-Xilinx-modifications-to-configs.patch new file mode 100644 index 00000000..f6445d98 --- /dev/null +++ b/recipes-bsp/u-boot/u-boot/xilinx-v2013.01/0005-Xilinx-modifications-to-configs.patch @@ -0,0 +1,2333 @@ +From 6272d1e2e2723000ea1e56e080e0c49495c6b126 Mon Sep 17 00:00:00 2001 +From: Sipke Vriend +Date: Tue, 21 May 2013 07:19:13 +1000 +Subject: [PATCH 5/5] Xilinx modifications to configs + +Signed-off-by: Sipke Vriend +--- + include/configs/fx12mm.h | 68 ----- + include/configs/microblaze-generic.h | 476 +++++++++++------------------- + include/configs/ml507.h | 49 ---- + include/configs/v5fx30teval.h | 49 ---- + include/configs/xilinx-ppc.h | 137 --------- + include/configs/xilinx-ppc405-generic.h | 305 ++++++++++++++++++--- + include/configs/xilinx-ppc405.h | 39 --- + include/configs/xilinx-ppc440-generic.h | 325 +++++++++++++++++++--- + include/configs/xilinx-ppc440.h | 28 -- + include/configs/zynq_afx.h | 36 +++ + include/configs/zynq_common.h | 300 +++++++++++++++++++ + include/configs/zynq_cseflash.h | 73 +++++ + include/configs/zynq_zc70x.h | 36 +++ + include/configs/zynq_zc770.h | 52 ++++ + include/configs/zynq_zed.h | 34 +++ + include/zynqpl.h | 60 ++++ + 16 files changed, 1325 insertions(+), 742 deletions(-) + delete mode 100644 include/configs/fx12mm.h + delete mode 100644 include/configs/ml507.h + delete mode 100644 include/configs/v5fx30teval.h + delete mode 100644 include/configs/xilinx-ppc.h + delete mode 100644 include/configs/xilinx-ppc405.h + delete mode 100644 include/configs/xilinx-ppc440.h + create mode 100644 include/configs/zynq_afx.h + create mode 100644 include/configs/zynq_common.h + create mode 100644 include/configs/zynq_cseflash.h + create mode 100644 include/configs/zynq_zc70x.h + create mode 100644 include/configs/zynq_zc770.h + create mode 100644 include/configs/zynq_zed.h + create mode 100644 include/zynqpl.h + +diff --git a/include/configs/fx12mm.h b/include/configs/fx12mm.h +deleted file mode 100644 +index e825c21..0000000 +--- a/include/configs/fx12mm.h ++++ /dev/null +@@ -1,68 +0,0 @@ +-/* +- * (C) Copyright 2008 +- * +- * Ricado Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es +- * This work has been supported by: QTechnology http://qtec.com +- * +- * Georg Schardt +- * +- * 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 +- */ +- +-/* +- * Configuration file for the Virtex4FX12 Minimodul by Avnet/Memec, +- * see http://www.em.avnet.com +- */ +- +-#ifndef __CONFIG_FX12_H +-#define __CONFIG_FX12_H +- +-#include "../board/avnet/fx12mm/xparameters.h" +- +-/* cmd config */ +-#define CONFIG_CMD_JFFS2 +-#define CONFIG_CMD_MTDPARTS +-#define CONFIG_MTD_DEVICE /* needed for mtdparts commands */ +-#define CONFIG_FLASH_CFI_MTD +-#undef CONFIG_CMD_NET +- +-/* sdram */ +-#define CONFIG_SYS_SDRAM_SIZE_MB 64 +- +-/* environment */ +-#define CONFIG_ENV_IS_IN_FLASH 1 +-#define CONFIG_ENV_SIZE 0x10000 +-#define CONFIG_ENV_SECT_SIZE 0x10000 +-#define CONFIG_SYS_ENV_OFFSET 0xA0000 +-#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE+CONFIG_SYS_ENV_OFFSET) +-#define CONFIG_ENV_OVERWRITE 1 +- +-/*Misc*/ +-#define CONFIG_SYS_PROMPT "FX12MM:/# " /* Monitor Command Prompt */ +-#define CONFIG_PREBOOT "echo U-Boot is up and running;" +- +-/*Flash*/ +-#define CONFIG_SYS_FLASH_SIZE (4*1024*1024) +-#define CONFIG_SYS_MAX_FLASH_SECT 71 +-#define MTDIDS_DEFAULT "nor0=fx12mm-flash" +-#define MTDPARTS_DEFAULT "mtdparts=fx12mm-flash:-(user)" +- +-#include "configs/xilinx-ppc405.h" +- +-#endif /* __CONFIG_H */ +diff --git a/include/configs/microblaze-generic.h b/include/configs/microblaze-generic.h +index eed38c1..5657582 100644 +--- a/include/configs/microblaze-generic.h ++++ b/include/configs/microblaze-generic.h +@@ -27,128 +27,147 @@ + + #include "../board/xilinx/microblaze-generic/xparameters.h" + +-/* MicroBlaze CPU */ +-#define CONFIG_MICROBLAZE 1 ++ ++#define CONFIG_MICROBLAZE 1 /* MicroBlaze CPU */ + #define MICROBLAZE_V5 1 + +-/* Open Firmware DTS */ +-#define CONFIG_OF_CONTROL 1 +-#define CONFIG_OF_EMBED 1 +-#define CONFIG_DEFAULT_DEVICE_TREE microblaze ++/* Memory test handling */ ++#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE ++#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x1000) + +-/* linear and spi flash memory */ +-#ifdef XILINX_FLASH_START +-#define FLASH +-#undef SPIFLASH +-#undef RAMENV /* hold environment in flash */ +-#else +-#ifdef XILINX_SPI_FLASH_BASEADDR +-#undef FLASH +-#define SPIFLASH +-#undef RAMENV /* hold environment in flash */ +-#else +-#undef FLASH +-#undef SPIFLASH +-#define RAMENV /* hold environment in RAM */ +-#endif ++/* global pointer */ ++/* start of global data */ ++#define CONFIG_SYS_GBL_DATA_OFFSET (CONFIG_SYS_SDRAM_SIZE - GENERATED_GBL_DATA_SIZE) ++ ++/* monitor code */ ++#define SIZE 0x40000 ++#define CONFIG_SYS_MONITOR_LEN SIZE ++#define CONFIG_SYS_MONITOR_BASE (CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_GBL_DATA_OFFSET - CONFIG_SYS_MONITOR_LEN - GENERATED_BD_INFO_SIZE) ++ ++#define CONFIG_SYS_MONITOR_END (CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN) ++#define CONFIG_SYS_MALLOC_LEN SIZE ++#define CONFIG_SYS_MALLOC_BASE (CONFIG_SYS_MONITOR_BASE - CONFIG_SYS_MALLOC_LEN) ++ ++/* stack */ ++#define CONFIG_SYS_INIT_SP_OFFSET CONFIG_SYS_MALLOC_BASE ++ ++#define CONFIG_SYS_BOOTMAPSZ (1 << 31) /* Initial Memory map for Linux */ ++ ++#undef CONFIG_PHYLIB ++#define CONFIG_LMB 1 ++ ++/* Default cache size if not specified */ ++#ifndef XILINX_DCACHE_BYTE_SIZE ++# define XILINX_DCACHE_BYTE_SIZE 32768 + #endif + +-/* uart */ ++ ++/* The following table includes the supported baudrates */ ++#define CONFIG_SYS_BAUDRATE_TABLE \ ++ {300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400} ++ ++/* use serial multi for all serial devices */ ++#define CONFIG_SYS_CONSOLE_IS_IN_ENV 1 ++ + #ifdef XILINX_UARTLITE_BASEADDR + # define CONFIG_XILINX_UARTLITE +-# define CONFIG_SERIAL_BASE XILINX_UARTLITE_BASEADDR +-# define CONFIG_BAUDRATE XILINX_UARTLITE_BAUDRATE +-# define CONFIG_SYS_BAUDRATE_TABLE { CONFIG_BAUDRATE } +-# define CONSOLE_ARG "console=console=ttyUL0,115200\0" +-#elif XILINX_UART16550_BASEADDR +-# define CONFIG_SYS_NS16550 1 ++# if defined(XILINX_UARTLITE_BAUDRATE) ++# define CONFIG_BAUDRATE XILINX_UARTLITE_BAUDRATE ++# endif ++#endif ++ ++#if XILINX_UART16550_BASEADDR ++# define CONFIG_SYS_NS16550 1 + # define CONFIG_SYS_NS16550_SERIAL ++# define CONFIG_SYS_NS16550_COM1 ((XILINX_UART16550_BASEADDR & ~0xF) + 0x1000) ++# define CONFIG_SYS_NS16550_CLK XILINX_UART16550_CLOCK_HZ ++ + # if defined(__MICROBLAZEEL__) + # define CONFIG_SYS_NS16550_REG_SIZE -4 + # else + # define CONFIG_SYS_NS16550_REG_SIZE 4 + # endif +-# define CONFIG_CONS_INDEX 1 +-# define CONFIG_SYS_NS16550_COM1 \ +- ((XILINX_UART16550_BASEADDR & ~0xF) + 0x1000) +-# define CONFIG_SYS_NS16550_CLK XILINX_UART16550_CLOCK_HZ +-# define CONFIG_BAUDRATE 115200 + +-/* The following table includes the supported baudrates */ +-# define CONFIG_SYS_BAUDRATE_TABLE \ +- {300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400} +-# define CONSOLE_ARG "console=console=ttyS0,115200\0" +-#else +-# error Undefined uart ++/* CONS_INDEX for system with uartlite only mustn't define CONFIG_CONS_INDEX ++ * u-boot BSP generates CONFIG_CONS_INDEX for system with several uart16550 */ ++# if !defined(CONFIG_CONS_INDEX) ++# define CONFIG_CONS_INDEX 1 ++# endif + #endif + +-/* setting reset address */ +-/*#define CONFIG_SYS_RESET_ADDRESS CONFIG_SYS_TEXT_BASE*/ ++#if !defined(CONFIG_BAUDRATE) ++ #define CONFIG_BAUDRATE 115200 ++#endif + +-/* ethernet */ + #undef CONFIG_SYS_ENET ++#ifdef XILINX_EMAC_BASEADDR ++ #define CONFIG_XILINX_EMAC 1 ++ #define CONFIG_SYS_ENET ++#endif + #if defined(XILINX_EMACLITE_BASEADDR) +-# define CONFIG_XILINX_EMACLITE 1 +-# define CONFIG_SYS_ENET ++ #define CONFIG_XILINX_EMACLITE 1 ++ #define CONFIG_SYS_ENET + #endif + #if defined(XILINX_LLTEMAC_BASEADDR) +-# define CONFIG_XILINX_LL_TEMAC 1 +-# define CONFIG_SYS_ENET ++ #define CONFIG_XILINX_LL_TEMAC 1 ++ #define CONFIG_SYS_ENET + #endif + #if defined(XILINX_AXIEMAC_BASEADDR) +-# define CONFIG_XILINX_AXIEMAC 1 +-# define CONFIG_SYS_ENET ++ #define CONFIG_XILINX_AXIEMAC 1 ++ #define CONFIG_SYS_ENET + #endif + + #undef ET_DEBUG + +-/* gpio */ +-#ifdef XILINX_GPIO_BASEADDR +-# define CONFIG_SYS_GPIO_0 1 +-# define CONFIG_SYS_GPIO_0_ADDR XILINX_GPIO_BASEADDR +-#endif + + /* interrupt controller */ + #ifdef XILINX_INTC_BASEADDR +-# define CONFIG_SYS_INTC_0_ADDR XILINX_INTC_BASEADDR +-# define CONFIG_SYS_INTC_0_NUM XILINX_INTC_NUM_INTR_INPUTS ++ #define CONFIG_SYS_INTC_0 1 ++ #define CONFIG_SYS_INTC_0_ADDR XILINX_INTC_BASEADDR ++ #define CONFIG_SYS_INTC_0_NUM XILINX_INTC_NUM_INTR_INPUTS + #endif + + /* timer */ +-#if defined(XILINX_TIMER_BASEADDR) && defined(XILINX_TIMER_IRQ) +-# define CONFIG_SYS_TIMER_0_ADDR XILINX_TIMER_BASEADDR +-# define CONFIG_SYS_TIMER_0_IRQ XILINX_TIMER_IRQ ++#ifdef XILINX_TIMER_BASEADDR ++ #if (XILINX_TIMER_IRQ != -1) ++ #define CONFIG_SYS_TIMER_0 1 ++ #define CONFIG_SYS_TIMER_0_ADDR XILINX_TIMER_BASEADDR ++ #define CONFIG_SYS_TIMER_0_IRQ XILINX_TIMER_IRQ ++ #define FREQUENCE XILINX_CLOCK_FREQ ++ #define CONFIG_SYS_TIMER_0_PRELOAD ( FREQUENCE/1000 ) ++ #endif ++#else ++# error Please setup TIMER in BSP + #endif + +-/* FSL */ +-/* #define CONFIG_SYS_FSL_2 */ +-/* #define FSL_INTR_2 1 */ ++#if defined(XILINX_WATCHDOG_BASEADDR) && defined(XILINX_WATCHDOG_IRQ) ++# define CONFIG_WATCHDOG_BASEADDR XILINX_WATCHDOG_BASEADDR ++# define CONFIG_WATCHDOG_IRQ XILINX_WATCHDOG_IRQ ++# define CONFIG_HW_WATCHDOG 1 ++# define CONFIG_XILINX_TB_WATCHDOG 1 ++#endif + + /* + * memory layout - Example +- * CONFIG_SYS_TEXT_BASE = 0x1200_0000; defined in config.mk ++ * TEXT_BASE = 0x1200_0000; + * CONFIG_SYS_SRAM_BASE = 0x1000_0000; +- * CONFIG_SYS_SRAM_SIZE = 0x0400_0000; 64MB +- * +- * CONFIG_SYS_MONITOR_LEN = 0x40000 +- * CONFIG_SYS_MALLOC_LEN = 3 * CONFIG_SYS_MONITOR_LEN = 0xC0000 ++ * CONFIG_SYS_SRAM_SIZE = 0x0400_0000; + * + * CONFIG_SYS_GBL_DATA_OFFSET = 0x1000_0000 + 0x0400_0000 - 0x1000 = 0x13FF_F000 +- * CONFIG_SYS_MONITOR_BASE = 0x13FF_F000 - CONFIG_SYS_MONITOR_LEN = 0x13FB_F000 +- * CONFIG_SYS_MALLOC_BASE = 0x13FB_F000 - CONFIG_SYS_MALLOC_LEN = 0x13EF_F000 ++ * CONFIG_SYS_MONITOR_BASE = 0x13FF_F000 - 0x40000 = 0x13FB_F000 ++ * CONFIG_SYS_MALLOC_BASE = 0x13FB_F000 - 0x40000 = 0x13F7_F000 + * + * 0x1000_0000 CONFIG_SYS_SDRAM_BASE +- * MEMTEST_AREA 64kB + * FREE +- * 0x1200_0000 CONFIG_SYS_TEXT_BASE ++ * 0x1200_0000 TEXT_BASE + * U-BOOT code + * 0x1202_0000 + * FREE + * + * STACK +- * 0x13EF_F000 CONFIG_SYS_MALLOC_BASE +- * MALLOC_AREA 768kB Alloc +- * 0x13FB_F000 CONFIG_SYS_MONITOR_BASE ++ * 0x13F7_F000 CONFIG_SYS_MALLOC_BASE ++ * MALLOC_AREA 256kB Alloc ++ * 0x11FB_F000 CONFIG_SYS_MONITOR_BASE + * MONITOR_CODE 256kB Env + * 0x13FF_F000 CONFIG_SYS_GBL_DATA_OFFSET + * GLOBAL_DATA 4kB bd, gd +@@ -158,133 +177,48 @@ + /* ddr sdram - main memory */ + #define CONFIG_SYS_SDRAM_BASE XILINX_RAM_START + #define CONFIG_SYS_SDRAM_SIZE XILINX_RAM_SIZE +-#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE +-#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x1000) +- +-/* global pointer */ +-/* start of global data */ +-#define CONFIG_SYS_GBL_DATA_OFFSET \ +- (CONFIG_SYS_SDRAM_SIZE - GENERATED_GBL_DATA_SIZE) + +-/* monitor code */ +-#define SIZE 0x40000 +-#define CONFIG_SYS_MONITOR_LEN SIZE +-#define CONFIG_SYS_MONITOR_BASE \ +- (CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_GBL_DATA_OFFSET \ +- - CONFIG_SYS_MONITOR_LEN - GENERATED_BD_INFO_SIZE) +-#define CONFIG_SYS_MONITOR_END \ +- (CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN) +-#define CONFIG_SYS_MALLOC_LEN (SIZE * 3) +-#define CONFIG_SYS_MALLOC_BASE \ +- (CONFIG_SYS_MONITOR_BASE - CONFIG_SYS_MALLOC_LEN) +- +-/* stack */ +-#define CONFIG_SYS_INIT_SP_OFFSET CONFIG_SYS_MALLOC_BASE +- +-/* +- * CFI flash memory layout - Example +- * CONFIG_SYS_FLASH_BASE = 0x2200_0000; +- * CONFIG_SYS_FLASH_SIZE = 0x0080_0000; 8MB +- * +- * SECT_SIZE = 0x20000; 128kB is one sector +- * CONFIG_ENV_SIZE = SECT_SIZE; 128kB environment store +- * +- * 0x2200_0000 CONFIG_SYS_FLASH_BASE +- * FREE 256kB +- * 0x2204_0000 CONFIG_ENV_ADDR +- * ENV_AREA 128kB +- * 0x2206_0000 +- * FREE +- * 0x2280_0000 CONFIG_SYS_FLASH_BASE + CONFIG_SYS_FLASH_SIZE +- * +- */ +- +-#ifdef FLASH +-# define CONFIG_SYS_FLASH_BASE XILINX_FLASH_START +-# define CONFIG_SYS_FLASH_SIZE XILINX_FLASH_SIZE +-# define CONFIG_SYS_FLASH_CFI 1 +-# define CONFIG_FLASH_CFI_DRIVER 1 +-/* ?empty sector */ +-# define CONFIG_SYS_FLASH_EMPTY_INFO 1 +-/* max number of memory banks */ +-# define CONFIG_SYS_MAX_FLASH_BANKS 1 +-/* max number of sectors on one chip */ +-# define CONFIG_SYS_MAX_FLASH_SECT 512 +-/* hardware flash protection */ +-# define CONFIG_SYS_FLASH_PROTECTION +- +-# ifdef RAMENV +-# define CONFIG_ENV_IS_NOWHERE 1 +-# define CONFIG_ENV_SIZE 0x1000 +-# define CONFIG_ENV_ADDR (CONFIG_SYS_MONITOR_BASE - CONFIG_ENV_SIZE) +- +-# else /* FLASH && !RAMENV */ +-# define CONFIG_ENV_IS_IN_FLASH 1 +-/* 128K(one sector) for env */ +-# define CONFIG_ENV_SECT_SIZE 0x20000 +-# define CONFIG_ENV_ADDR \ +- (CONFIG_SYS_FLASH_BASE + (2 * CONFIG_ENV_SECT_SIZE)) +-# define CONFIG_ENV_SIZE 0x20000 +-# endif /* FLASH && !RAMBOOT */ +-#else /* !FLASH */ +- +-#ifdef SPIFLASH +-# define CONFIG_SYS_NO_FLASH 1 +-# define CONFIG_SYS_SPI_BASE XILINX_SPI_FLASH_BASEADDR +-# define CONFIG_XILINX_SPI 1 +-# define CONFIG_SPI 1 +-# define CONFIG_SPI_FLASH 1 +-# define CONFIG_SPI_FLASH_STMICRO 1 +-# define CONFIG_SF_DEFAULT_MODE SPI_MODE_3 +-# define CONFIG_SF_DEFAULT_SPEED XILINX_SPI_FLASH_MAX_FREQ +-# define CONFIG_SF_DEFAULT_CS XILINX_SPI_FLASH_CS +- +-# ifdef RAMENV +-# define CONFIG_ENV_IS_NOWHERE 1 +-# define CONFIG_ENV_SIZE 0x1000 +-# define CONFIG_ENV_ADDR (CONFIG_SYS_MONITOR_BASE - CONFIG_ENV_SIZE) +- +-# else /* SPIFLASH && !RAMENV */ +-# define CONFIG_ENV_IS_IN_SPI_FLASH 1 +-# define CONFIG_ENV_SPI_MODE SPI_MODE_3 +-# define CONFIG_ENV_SPI_MAX_HZ CONFIG_SF_DEFAULT_SPEED +-# define CONFIG_ENV_SPI_CS CONFIG_SF_DEFAULT_CS +-/* 128K(two sectors) for env */ +-# define CONFIG_ENV_SECT_SIZE 0x10000 +-# define CONFIG_ENV_SIZE (2 * CONFIG_ENV_SECT_SIZE) +-/* Warning: adjust the offset in respect of other flash content and size */ +-# define CONFIG_ENV_OFFSET (128 * CONFIG_ENV_SECT_SIZE) /* at 8MB */ +-# endif /* SPIFLASH && !RAMBOOT */ +-#else /* !SPIFLASH */ +- +-/* ENV in RAM */ +-# define CONFIG_SYS_NO_FLASH 1 +-# define CONFIG_ENV_IS_NOWHERE 1 +-# define CONFIG_ENV_SIZE 0x1000 +-# define CONFIG_ENV_ADDR (CONFIG_SYS_MONITOR_BASE - CONFIG_ENV_SIZE) +-#endif /* !SPIFLASH */ +-#endif /* !FLASH */ +- +-/* system ace */ +-#ifdef XILINX_SYSACE_BASEADDR +-# define CONFIG_SYSTEMACE +-/* #define DEBUG_SYSTEMACE */ +-# define SYSTEMACE_CONFIG_FPGA +-# define CONFIG_SYS_SYSTEMACE_BASE XILINX_SYSACE_BASEADDR +-# define CONFIG_SYS_SYSTEMACE_WIDTH XILINX_SYSACE_MEM_WIDTH +-# define CONFIG_DOS_PARTITION ++#if defined(XILINX_FLASH_START) /* Parallel Flash */ ++ #define FLASH ++ #define CONFIG_SYS_FLASH_BASE XILINX_FLASH_START ++ #define CONFIG_SYS_FLASH_SIZE XILINX_FLASH_SIZE ++ #define CONFIG_SYS_FLASH_CFI 1 ++ #define CONFIG_FLASH_CFI_DRIVER 1 ++ #define CONFIG_SYS_FLASH_EMPTY_INFO 1 /* ?empty sector */ ++ #define CONFIG_SYS_MAX_FLASH_BANKS 1 /* max number of memory banks */ ++ #define CONFIG_SYS_MAX_FLASH_SECT 2048 /* max number of sectors on one chip */ ++ ++ /* Assume env is in flash, this may be undone lower down */ ++ #define CONFIG_ENV_IS_IN_FLASH 1 ++ #define CONFIG_ENV_SECT_SIZE 0x20000 /* 128K(one sector) for env */ ++ ++ #define CONFIG_SYS_FLASH_PROTECTION ++ ++ #define CONFIG_ENV_ADDR XILINX_FLASH_START ++ #define CONFIG_ENV_SIZE CONFIG_ENV_SECT_SIZE ++#else /* No flash memory at all */ ++ /* ENV in RAM */ ++ #define RAMENV ++ #define CONFIG_SYS_NO_FLASH 1 ++ ++ #define CONFIG_ENV_IS_NOWHERE 1 ++ #undef CONFIG_ENV_IS_IN_FLASH ++ #undef CONFIG_ENV_IS_IN_SPI_FLASH ++ #define CONFIG_ENV_SIZE 0x1000 ++ #define CONFIG_ENV_ADDR (CONFIG_SYS_MONITOR_BASE - CONFIG_ENV_SIZE) ++ #define CONFIG_SYS_FLASH_PROTECTION /* hardware flash protection */ + #endif + + #if defined(XILINX_USE_ICACHE) +-# define CONFIG_ICACHE ++ #define CONFIG_ICACHE + #else +-# undef CONFIG_ICACHE ++ #undef CONFIG_ICACHE + #endif + + #if defined(XILINX_USE_DCACHE) +-# define CONFIG_DCACHE ++ #define CONFIG_DCACHE + #else +-# undef CONFIG_DCACHE ++ #undef CONFIG_DCACHE + #endif + + #ifndef XILINX_DCACHE_BYTE_SIZE +@@ -305,146 +239,86 @@ + #include + + #define CONFIG_CMD_ASKENV ++/* FIXME: hack for zynq */ + #define CONFIG_CMD_IRQ +-#define CONFIG_CMD_MFSL + #define CONFIG_CMD_ECHO + +-#if defined(CONFIG_DCACHE) || defined(CONFIG_ICACHE) +-# define CONFIG_CMD_CACHE +-#else +-# undef CONFIG_CMD_CACHE +-#endif +- ++#undef CONFIG_CMD_NFS ++#undef CONFIG_CMD_JFFS2 + #ifndef CONFIG_SYS_ENET +-# undef CONFIG_CMD_NET +-# undef CONFIG_CMD_NFS ++ #undef CONFIG_CMD_NET ++ #undef CONFIG_NET_MULTI + #else +-# define CONFIG_CMD_PING +-# define CONFIG_CMD_DHCP +-# define CONFIG_CMD_TFTPPUT +-#endif +- +-#if defined(CONFIG_SYSTEMACE) +-# define CONFIG_CMD_EXT2 +-# define CONFIG_CMD_FAT ++ #define CONFIG_CMD_PING ++ #define CONFIG_NET_MULTI + #endif + + #if defined(FLASH) +-# define CONFIG_CMD_ECHO +-# define CONFIG_CMD_FLASH +-# define CONFIG_CMD_IMLS +-# define CONFIG_CMD_JFFS2 +-# define CONFIG_CMD_UBI +-# undef CONFIG_CMD_UBIFS +- +-# if !defined(RAMENV) +-# define CONFIG_CMD_SAVEENV +-# define CONFIG_CMD_SAVES +-# endif +- ++ #define CONFIG_CMD_FLASH ++ #define CONFIG_CMD_IMLS + #else +-#if defined(SPIFLASH) +-# define CONFIG_CMD_SF +- +-# if !defined(RAMENV) +-# define CONFIG_CMD_SAVEENV +-# define CONFIG_CMD_SAVES +-# endif +-#else +-# undef CONFIG_CMD_IMLS +-# undef CONFIG_CMD_FLASH +-# undef CONFIG_CMD_JFFS2 +-# undef CONFIG_CMD_UBI +-# undef CONFIG_CMD_UBIFS +-#endif ++ #undef CONFIG_CMD_IMLS ++ #undef CONFIG_CMD_FLASH ++ #undef CONFIG_CMD_SAVEENV ++ #undef CONFIG_CMD_SAVES + #endif + +-#if defined(CONFIG_CMD_JFFS2) +-# define CONFIG_MTD_PARTITIONS +-#endif +- +-#if defined(CONFIG_CMD_UBIFS) +-# define CONFIG_CMD_UBI +-# define CONFIG_LZO +-#endif +- +-#if defined(CONFIG_CMD_UBI) +-# define CONFIG_MTD_PARTITIONS +-# define CONFIG_RBTREE +-#endif +- +-#if defined(CONFIG_MTD_PARTITIONS) +-/* MTD partitions */ +-#define CONFIG_CMD_MTDPARTS /* mtdparts command line support */ +-#define CONFIG_MTD_DEVICE /* needed for mtdparts commands */ +-#define CONFIG_FLASH_CFI_MTD +-#define MTDIDS_DEFAULT "nor0=flash-0" +- +-/* default mtd partition table */ +-#define MTDPARTS_DEFAULT "mtdparts=flash-0:256k(u-boot),"\ +- "256k(env),3m(kernel),1m(romfs),"\ +- "1m(cramfs),-(jffs2)" ++#if !defined(RAMENV) ++ #define CONFIG_CMD_SAVEENV ++ #define CONFIG_CMD_SAVES + #endif + + /* Miscellaneous configurable options */ +-#define CONFIG_SYS_PROMPT "U-Boot-mONStR> " +-/* size of console buffer */ +-#define CONFIG_SYS_CBSIZE 512 +- /* print buffer size */ +-#define CONFIG_SYS_PBSIZE \ +- (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16) +-/* max number of command args */ +-#define CONFIG_SYS_MAXARGS 15 ++#define CONFIG_SYS_PROMPT "U-Boot> " ++#define CONFIG_SYS_CBSIZE 256/* Console I/O Buffer Size */ ++#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE +\ ++ sizeof(CONFIG_SYS_PROMPT) + 16) ++#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE ++ /* Boot Argument Buffer Size */ ++#define CONFIG_SYS_MAXARGS 15 /* max number of command args */ + #define CONFIG_SYS_LONGHELP +-/* default load address */ +-#define CONFIG_SYS_LOAD_ADDR XILINX_RAM_START ++#define CONFIG_SYS_LOAD_ADDR XILINX_RAM_START /* default load address */ + +-#define CONFIG_BOOTDELAY -1 /* -1 disables auto-boot */ +-#define CONFIG_BOOTARGS "root=romfs" ++#define CONFIG_BOOTDELAY 4 ++/* Don't define BOOTARGS, we get it from the DTB chosen fragment */ ++#undef CONFIG_BOOTARGS + #define CONFIG_HOSTNAME XILINX_BOARD_NAME +-#define CONFIG_BOOTCOMMAND "base 0;tftp 11000000 image.img;bootm" +-#define CONFIG_IPADDR 192.168.0.3 +-#define CONFIG_SERVERIP 192.168.0.5 +-#define CONFIG_GATEWAYIP 192.168.0.1 +-#define CONFIG_ETHADDR 00:E0:0C:00:00:FD ++ ++#define CONFIG_BOOTCOMMAND "" + + /* architecture dependent code */ + #define CONFIG_SYS_USR_EXCEP /* user exception */ +-#define CONFIG_SYS_HZ 1000 ++#define CONFIG_SYS_HZ 1000 + +-#define CONFIG_PREBOOT "echo U-BOOT for ${hostname};setenv preboot;echo" +- +-#define CONFIG_EXTRA_ENV_SETTINGS "unlock=yes\0" \ +- "nor0=flash-0\0"\ +- "mtdparts=mtdparts=flash-0:"\ +- "256k(u-boot),256k(env),3m(kernel),"\ +- "1m(romfs),1m(cramfs),-(jffs2)\0" ++#define CONFIG_ENV_OVERWRITE /* Allow to overwrite the u-boot environment variables */ ++#define CONFIG_IPADDR 192.168.0.90 ++#define CONFIG_SERVERIP 192.168.0.101 ++#define CONFIG_ETHADDR 00:0a:35:00:92:d4 ++#define CONFIG_BOOTP_SERVERIP + + #define CONFIG_CMDLINE_EDITING + + /* Use the HUSH parser */ +-#define CONFIG_SYS_HUSH_PARSER ++#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " + +-/* Enable flat device tree support */ +-#define CONFIG_LMB 1 + #define CONFIG_FIT 1 + #define CONFIG_OF_LIBFDT 1 + + #if defined(CONFIG_XILINX_LL_TEMAC) || defined(CONFIG_XILINX_AXIEMAC) +-# define CONFIG_MII 1 +-# define CONFIG_CMD_MII 1 +-# define CONFIG_PHY_GIGE 1 +-# define CONFIG_SYS_FAULT_ECHO_LINK_DOWN 1 +-# define CONFIG_PHYLIB 1 +-# define CONFIG_PHY_ATHEROS 1 +-# define CONFIG_PHY_BROADCOM 1 +-# define CONFIG_PHY_DAVICOM 1 +-# define CONFIG_PHY_LXT 1 +-# define CONFIG_PHY_MARVELL 1 +-# define CONFIG_PHY_MICREL 1 +-# define CONFIG_PHY_NATSEMI 1 +-# define CONFIG_PHY_REALTEK 1 +-# define CONFIG_PHY_VITESSE 1 ++# define CONFIG_MII 1 ++# define CONFIG_CMD_MII 1 ++# define CONFIG_PHY_GIGE 1 ++# define CONFIG_SYS_FAULT_ECHO_LINK_DOWN 1 ++# define CONFIG_PHYLIB 1 ++# define CONFIG_PHY_ATHEROS 1 ++# define CONFIG_PHY_BROADCOM 1 ++# define CONFIG_PHY_DAVICOM 1 ++# define CONFIG_PHY_LXT 1 ++# define CONFIG_PHY_MARVELL 1 ++# define CONFIG_PHY_MICREL 1 ++# define CONFIG_PHY_NATSEMI 1 ++# define CONFIG_PHY_REALTEK 1 ++# define CONFIG_PHY_VITESSE 1 + #else + # undef CONFIG_MII + # undef CONFIG_CMD_MII +diff --git a/include/configs/ml507.h b/include/configs/ml507.h +deleted file mode 100644 +index a7319e4..0000000 +--- a/include/configs/ml507.h ++++ /dev/null +@@ -1,49 +0,0 @@ +-/* +- * (C) Copyright 2008 +- * Ricado Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es +- * This work has been supported by: QTechnology http://qtec.com/ +- * 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, see . +-*/ +- +-#ifndef __CONFIG_H +-#define __CONFIG_H +- +-/*CPU*/ +-#define CONFIG_440 1 +-#define CONFIG_XILINX_ML507 1 +-#include "../board/xilinx/ml507/xparameters.h" +- +-/*Mem Map*/ +-#define CONFIG_SYS_SDRAM_SIZE_MB 256 +- +-/*Env*/ +-#define CONFIG_ENV_IS_IN_FLASH 1 +-#define CONFIG_ENV_SIZE 0x20000 +-#define CONFIG_ENV_SECT_SIZE 0x20000 +-#define CONFIG_ENV_OFFSET 0x340000 +-#define CONFIG_ENV_ADDR (XPAR_FLASH_MEM0_BASEADDR+CONFIG_ENV_OFFSET) +- +-/*Misc*/ +-#define CONFIG_SYS_PROMPT "ml507:/# " /* Monitor Command Prompt */ +-#define CONFIG_PREBOOT "echo U-Boot is up and runnining;" +- +-/*Flash*/ +-#define CONFIG_SYS_FLASH_SIZE (32*1024*1024) +-#define CONFIG_SYS_MAX_FLASH_SECT 259 +-#define MTDIDS_DEFAULT "nor0=ml507-flash" +-#define MTDPARTS_DEFAULT "mtdparts=ml507-flash:-(user)" +- +-/*Generic Configs*/ +-#include +- +-#endif /* __CONFIG_H */ +diff --git a/include/configs/v5fx30teval.h b/include/configs/v5fx30teval.h +deleted file mode 100644 +index d300c4b..0000000 +--- a/include/configs/v5fx30teval.h ++++ /dev/null +@@ -1,49 +0,0 @@ +-/* +- * (C) Copyright 2008 +- * Ricado Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es +- * This work has been supported by: QTechnology http://qtec.com/ +- * 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, see . +-*/ +- +-#ifndef __CONFIG_H +-#define __CONFIG_H +- +-/*CPU*/ +-#define CONFIG_440 1 +-#define CONFIG_XILINX_ML507 1 +-#include "../board/avnet/v5fx30teval/xparameters.h" +- +-/*Mem Map*/ +-#define CONFIG_SYS_SDRAM_SIZE_MB 64 +- +-/*Env*/ +-#define CONFIG_ENV_IS_IN_FLASH 1 +-#define CONFIG_ENV_SIZE 0x20000 +-#define CONFIG_ENV_SECT_SIZE 0x20000 +-#define CONFIG_ENV_OFFSET 0x1A0000 +-#define CONFIG_ENV_ADDR (XPAR_FLASH_MEM0_BASEADDR+CONFIG_ENV_OFFSET) +- +-/*Misc*/ +-#define CONFIG_SYS_PROMPT "v5fx30t:/# " /* Monitor Command Prompt */ +-#define CONFIG_PREBOOT "echo U-Boot is up and runnining;" +- +-/*Flash*/ +-#define CONFIG_SYS_FLASH_SIZE (16*1024*1024) +-#define CONFIG_SYS_MAX_FLASH_SECT 131 +-#define MTDIDS_DEFAULT "nor0=v5fx30t-flash" +-#define MTDPARTS_DEFAULT "mtdparts=v5fx30t-flash:-(user)" +- +-/*Generic Configs*/ +-#include +- +-#endif /* __CONFIG_H */ +diff --git a/include/configs/xilinx-ppc.h b/include/configs/xilinx-ppc.h +deleted file mode 100644 +index 2bdaa05..0000000 +--- a/include/configs/xilinx-ppc.h ++++ /dev/null +@@ -1,137 +0,0 @@ +-/* +- * (C) Copyright 2008 +- * Ricado Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es +- * This work has been supported by: QTechnology http://qtec.com/ +- * +- * (C) Copyright 2008 +- * Georg Schardt +- * +- * 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, see . +-*/ +- +-#ifndef __CONFIG_XLX_H +-#define __CONFIG_XLX_H +-/* +-#define DEBUG +-#define ET_DEBUG +-*/ +- +-/*Mem Map*/ +-#define CONFIG_SYS_SDRAM_BASE 0x0 +-#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE +-#define CONFIG_SYS_MONITOR_LEN (192 * 1024) +-#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 128 * 1024) +- +-/*Cmd*/ +-#include +-#define CONFIG_CMD_ASKENV +-#define CONFIG_CMD_CACHE +-#define CONFIG_CMD_DIAG +-#define CONFIG_CMD_ELF +-#define CONFIG_CMD_IRQ +-#define CONFIG_CMD_REGINFO +-#undef CONFIG_CMD_JFFS2 +-#undef CONFIG_CMD_MTDPARTS +-#undef CONFIG_CMD_SPI +-#undef CONFIG_CMD_I2C +-#undef CONFIG_CMD_DTT +-#undef CONFIG_CMD_NET +-#undef CONFIG_CMD_PING +-#undef CONFIG_CMD_DHCP +-#undef CONFIG_CMD_EEPROM +-#undef CONFIG_CMD_IMLS +-#undef CONFIG_CMD_NFS +- +-/*Misc*/ +-#define CONFIG_BOOTDELAY 5/* autoboot after 5 seconds */ +-#define CONFIG_SYS_LONGHELP /* undef to save memory */ +-#if defined(CONFIG_CMD_KGDB) +-#define CONFIG_SYS_CBSIZE 1024/* Console I/O Buffer Size */ +-#else +-#define CONFIG_SYS_CBSIZE 256/* Console I/O Buffer Size */ +-#endif +-#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE +\ +- sizeof(CONFIG_SYS_PROMPT) + 16) +-#define CONFIG_SYS_MAXARGS 16 +- /* max number of command args */ +-#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE +- /* Boot Argument Buffer Size */ +-#define CONFIG_SYS_MEMTEST_START 0x00400000 +- /* memtest works on */ +-#define CONFIG_SYS_MEMTEST_END 0x00C00000 +- /* 4 ... 12 MB in DRAM */ +-#define CONFIG_SYS_LOAD_ADDR 0x00400000 +- /* default load address */ +-#define CONFIG_SYS_EXTBDINFO 1 +- /* Extended board_into (bd_t) */ +-#define CONFIG_SYS_HZ 1000 +- /* decrementer freq: 1 ms ticks */ +-#define CONFIG_CMDLINE_EDITING /* add command line history */ +-#define CONFIG_AUTO_COMPLETE /* add autocompletion support */ +-#define CONFIG_LOOPW /* enable loopw command */ +-#define CONFIG_MX_CYCLIC /* enable mdc/mwc commands */ +-#define CONFIG_ZERO_BOOTDELAY_CHECK /* check for keypress on bootdelay==0 */ +-#define CONFIG_VERSION_VARIABLE /* include version env variable */ +-#define CONFIG_SYS_CONSOLE_INFO_QUIET /* don't print console @ startup */ +-#define CONFIG_SYS_HUSH_PARSER /* Use the HUSH parser */ +-#define CONFIG_LOADS_ECHO /* echo on for serial download */ +-#define CONFIG_SYS_LOADS_BAUD_CHANGE /* allow baudrate change */ +-#define CONFIG_SYS_BOOTMAPSZ (8 << 20) +- /* Initial Memory map for Linux */ +- +-/*Stack*/ +-#define CONFIG_SYS_INIT_RAM_ADDR 0x800000/* Initial RAM address */ +-#define CONFIG_SYS_INIT_RAM_SIZE 0x2000 /* Size of used area in RAM */ +-#define CONFIG_SYS_GBL_DATA_OFFSET (CONFIG_SYS_INIT_RAM_SIZE \ +- - GENERATED_GBL_DATA_SIZE) +-#define CONFIG_SYS_INIT_SP_OFFSET CONFIG_SYS_GBL_DATA_OFFSET +-/*Speed*/ +-#define CONFIG_SYS_CLK_FREQ XPAR_CORE_CLOCK_FREQ_HZ +- +-/*Flash*/ +-#ifdef XPAR_FLASH_MEM0_BASEADDR +-#define CONFIG_SYS_FLASH_BASE XPAR_FLASH_MEM0_BASEADDR +-#define CONFIG_SYS_FLASH_CFI 1 +-#define CONFIG_FLASH_CFI_DRIVER 1 +-#define CONFIG_SYS_FLASH_EMPTY_INFO 1 +-#define CONFIG_SYS_MAX_FLASH_BANKS 1 +-#define CONFIG_SYS_FLASH_PROTECTION +-#define CONFIG_CMD_JFFS2 +-#define CONFIG_CMD_MTDPARTS +-#define CONFIG_MTD_DEVICE /* needed for mtdparts commands */ +-#define CONFIG_FLASH_CFI_MTD +-#else +-#define CONFIG_ENV_IS_NOWHERE +-#define CONFIG_SYS_NO_FLASH +-#endif +- +-/* serial communication */ +-#ifdef XPAR_UARTLITE_0_BASEADDR +-#define CONFIG_XILINX_UARTLITE +-#define XILINX_UARTLITE_BASEADDR XPAR_UARTLITE_0_BASEADDR +-#define CONFIG_BAUDRATE XPAR_UARTLITE_0_BAUDRATE +-#define CONFIG_SYS_BAUDRATE_TABLE { CONFIG_BAUDRATE } +-#else +-#ifdef XPAR_UARTNS550_0_BASEADDR +-#define CONFIG_SYS_NS16550 +-#define CONFIG_SYS_NS16550_SERIAL +-#define CONFIG_SYS_NS16550_REG_SIZE 4 +-#define CONFIG_CONS_INDEX 1 +-#define CONFIG_SYS_NS16550_COM1 XPAR_UARTNS550_0_BASEADDR +-#define CONFIG_SYS_NS16550_CLK XPAR_UARTNS550_0_CLOCK_FREQ_HZ +-#define CONFIG_BAUDRATE 115200 +-#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 115200 } +-#endif +-#endif +- +-#endif /* __CONFIG_H */ +diff --git a/include/configs/xilinx-ppc405-generic.h b/include/configs/xilinx-ppc405-generic.h +index 5036c62..000afe5 100644 +--- a/include/configs/xilinx-ppc405-generic.h ++++ b/include/configs/xilinx-ppc405-generic.h +@@ -1,11 +1,7 @@ + /* ++ * (C) Copyright 2007-2010 Michal Simek + * +- * (C) Copyright 2008 +- * Ricado Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es +- * This work has been supported by: QTechnology http://qtec.com/ +- * +- * (C) Copyright 2008 +- * Georg Schardt ++ * Michal SIMEK + * + * See file CREDITS for list of people who contributed to this + * project. +@@ -25,34 +21,275 @@ + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +-#ifndef __CONFIG_GEN_H +-#define __CONFIG_GEN_H ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H + + #include "../board/xilinx/ppc405-generic/xparameters.h" + +-/* sdram */ +-#define CONFIG_SYS_SDRAM_SIZE_MB 256 +- +-/* environment */ +-#define CONFIG_ENV_IS_IN_FLASH 1 +-#define CONFIG_ENV_SIZE 0x10000 +-#define CONFIG_ENV_SECT_SIZE 0x10000 +-#define CONFIG_SYS_ENV_OFFSET 0x3F0000 +-#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE+CONFIG_SYS_ENV_OFFSET) +-#define CONFIG_ENV_OVERWRITE 1 +- +-/*Misc*/ +-#define CONFIG_SYS_PROMPT "xlx-ppc405:/# " /* Monitor Command Prompt */ +-#define CONFIG_PREBOOT "echo U-Boot is up and runnining;" +- +-/*Flash*/ +-#define CONFIG_SYS_FLASH_BASE XPAR_FLASH_MEM0_BASEADDR +-#define CONFIG_SYS_FLASH_SIZE (32*1024*1024) +-#define CONFIG_SYS_MAX_FLASH_SECT 71 +-#define CONFIG_SYS_FLASH_CFI 1 +-#define CONFIG_FLASH_CFI_DRIVER 1 +-#define MTDIDS_DEFAULT "nor0=ppc405-flash" +-#define MTDPARTS_DEFAULT "mtdpartsa=ppc405-flash:-(user)" +- +-#include +-#endif /* __CONFIG_H */ ++/* cpu parameter */ ++#define CONFIG_405 1 ++#define CONFIG_4xx 1 ++#define CONFIG_XILINX_405 1 ++ ++/* PPC-specific memory layout */ ++#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE ++#define CONFIG_SYS_MONITOR_LEN (192 * 1024) ++#define CONFIG_SYS_MALLOC_LEN (128 * 1024) ++ ++/*Stack*/ ++#define CONFIG_SYS_INIT_RAM_ADDR 0x800000/* Initial RAM address */ ++#define CONFIG_SYS_INIT_RAM_END 0x2000 /* End of used area in RAM */ ++#define CONFIG_SYS_GBL_DATA_SIZE 128 /* num bytes initial data */ ++#define CONFIG_SYS_GBL_DATA_OFFSET (CONFIG_SYS_INIT_RAM_END \ ++ - CONFIG_SYS_GBL_DATA_SIZE) ++#define CONFIG_SYS_INIT_SP_OFFSET CONFIG_SYS_GBL_DATA_OFFSET ++ ++/*Speed*/ ++#define CONFIG_SYS_CLK_FREQ XPAR_CORE_CLOCK_FREQ_HZ ++ ++/* Common PPC-specific settings */ ++#define CONFIG_SYS_MEMTEST_START 0x00400000 ++ /* memtest works on */ ++#define CONFIG_SYS_MEMTEST_END 0x00C00000 ++ /* 4 ... 12 MB in DRAM */ ++#define CONFIG_SYS_EXTBDINFO 1 ++ /* Extended board_into (bd_t) */ ++#define CONFIG_SYS_HZ 1000 ++ /* decrementer freq: 1 ms ticks */ ++#define CONFIG_SYS_BOOTMAPSZ (8 << 20) ++ /* Initial Memory map for Linux */ ++ ++/* The following table includes the supported baudrates */ ++#define CONFIG_SYS_BAUDRATE_TABLE \ ++ {300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400} ++ ++/* use serial multi for all serial devices */ ++#define CONFIG_SYS_CONSOLE_IS_IN_ENV 1 ++ ++#ifdef XILINX_UARTLITE_BASEADDR ++# define CONFIG_XILINX_UARTLITE ++# if defined(XILINX_UARTLITE_BAUDRATE) ++# define CONFIG_BAUDRATE XILINX_UARTLITE_BAUDRATE ++# endif ++#endif ++ ++#if XILINX_UART16550_BASEADDR ++# define CONFIG_SYS_NS16550 1 ++# define CONFIG_SYS_NS16550_SERIAL ++# define CONFIG_SYS_NS16550_COM1 ((XILINX_UART16550_BASEADDR & ~0xF) + 0x1000) ++# define CONFIG_SYS_NS16550_CLK XILINX_UART16550_CLOCK_HZ ++ ++# if defined(__MICROBLAZEEL__) ++# define CONFIG_SYS_NS16550_REG_SIZE -4 ++# else ++# define CONFIG_SYS_NS16550_REG_SIZE 4 ++# endif ++ ++/* CONS_INDEX for system with uartlite only mustn't define CONFIG_CONS_INDEX ++ * u-boot BSP generates CONFIG_CONS_INDEX for system with several uart16550 */ ++# if !defined(CONFIG_CONS_INDEX) ++# define CONFIG_CONS_INDEX 1 ++# endif ++#endif ++ ++#if !defined(CONFIG_BAUDRATE) ++ #define CONFIG_BAUDRATE 115200 ++#endif ++ ++#undef CONFIG_SYS_ENET ++#if defined(XILINX_EMACLITE_BASEADDR) ++ #define CONFIG_XILINX_EMACLITE 1 ++ #define CONFIG_SYS_ENET ++#endif ++#if defined(XILINX_LLTEMAC_BASEADDR) ++ #define CONFIG_XILINX_LL_TEMAC 1 ++ #define CONFIG_SYS_ENET ++#endif ++ ++#undef ET_DEBUG ++ ++ ++/* interrupt controller */ ++#ifdef XILINX_INTC_BASEADDR ++ #define CONFIG_SYS_INTC_0 1 ++ #define CONFIG_SYS_INTC_0_ADDR XILINX_INTC_BASEADDR ++ #define CONFIG_SYS_INTC_0_NUM XILINX_INTC_NUM_INTR_INPUTS ++#endif ++ ++/* timer */ ++#ifdef XILINX_TIMER_BASEADDR ++ #if (XILINX_TIMER_IRQ != -1) ++ #define CONFIG_SYS_TIMER_0 1 ++ #define CONFIG_SYS_TIMER_0_ADDR XILINX_TIMER_BASEADDR ++ #define CONFIG_SYS_TIMER_0_IRQ XILINX_TIMER_IRQ ++ #define FREQUENCE XILINX_CLOCK_FREQ ++ #define CONFIG_SYS_TIMER_0_PRELOAD ( FREQUENCE/1000 ) ++ #endif ++#else ++# error Please setup TIMER in BSP ++#endif ++ ++/* ++ * memory layout - Example ++ * TEXT_BASE = 0x1200_0000; ++ * CONFIG_SYS_SRAM_BASE = 0x1000_0000; ++ * CONFIG_SYS_SRAM_SIZE = 0x0400_0000; ++ * ++ * CONFIG_SYS_GBL_DATA_OFFSET = 0x1000_0000 + 0x0400_0000 - 0x1000 = 0x13FF_F000 ++ * CONFIG_SYS_MONITOR_BASE = 0x13FF_F000 - 0x40000 = 0x13FB_F000 ++ * CONFIG_SYS_MALLOC_BASE = 0x13FB_F000 - 0x40000 = 0x13F7_F000 ++ * ++ * 0x1000_0000 CONFIG_SYS_SDRAM_BASE ++ * FREE ++ * 0x1200_0000 TEXT_BASE ++ * U-BOOT code ++ * 0x1202_0000 ++ * FREE ++ * ++ * STACK ++ * 0x13F7_F000 CONFIG_SYS_MALLOC_BASE ++ * MALLOC_AREA 256kB Alloc ++ * 0x11FB_F000 CONFIG_SYS_MONITOR_BASE ++ * MONITOR_CODE 256kB Env ++ * 0x13FF_F000 CONFIG_SYS_GBL_DATA_OFFSET ++ * GLOBAL_DATA 4kB bd, gd ++ * 0x1400_0000 CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_SDRAM_SIZE ++ */ ++ ++/* ddr sdram - main memory */ ++#define CONFIG_SYS_SDRAM_BASE XILINX_RAM_START ++#define CONFIG_SYS_SDRAM_SIZE XILINX_RAM_SIZE ++ ++#if defined(XILINX_FLASH_START) /* Parallel Flash */ ++ #define FLASH ++ #define CONFIG_SYS_FLASH_BASE XILINX_FLASH_START ++ #define CONFIG_SYS_FLASH_SIZE XILINX_FLASH_SIZE ++ #define CONFIG_SYS_FLASH_CFI 1 ++ #define CONFIG_FLASH_CFI_DRIVER 1 ++ #define CONFIG_SYS_FLASH_EMPTY_INFO 1 /* ?empty sector */ ++ #define CONFIG_SYS_MAX_FLASH_BANKS 1 /* max number of memory banks */ ++ #define CONFIG_SYS_MAX_FLASH_SECT 2048 /* max number of sectors on one chip */ ++ ++ /* Assume env is in flash, this may be undone lower down */ ++ #define CONFIG_ENV_IS_IN_FLASH 1 ++ #define CONFIG_ENV_SECT_SIZE 0x20000 /* 128K(one sector) for env */ ++ ++ #define CONFIG_SYS_FLASH_PROTECTION ++ ++ #define CONFIG_ENV_ADDR XILINX_FLASH_START ++ #define CONFIG_ENV_SIZE CONFIG_ENV_SECT_SIZE ++#else /* No flash memory at all */ ++ /* ENV in RAM */ ++ #define RAMENV ++ #define CONFIG_SYS_NO_FLASH 1 ++ ++ #define CONFIG_ENV_IS_NOWHERE 1 ++ #undef CONFIG_ENV_IS_IN_FLASH ++ #undef CONFIG_ENV_IS_IN_SPI_FLASH ++ #define CONFIG_ENV_SIZE 0x1000 ++ #define CONFIG_ENV_ADDR (CONFIG_SYS_MONITOR_BASE - CONFIG_ENV_SIZE) ++ #define CONFIG_SYS_FLASH_PROTECTION /* hardware flash protection */ ++#endif ++ ++/* ++ * BOOTP options ++ */ ++#define CONFIG_BOOTP_BOOTFILESIZE ++#define CONFIG_BOOTP_BOOTPATH ++#define CONFIG_BOOTP_GATEWAY ++#define CONFIG_BOOTP_HOSTNAME ++ ++/* ++ * Command line configuration. ++ */ ++#include ++ ++#define CONFIG_CMD_ASKENV ++/* FIXME: hack for zynq */ ++#define CONFIG_CMD_IRQ ++#define CONFIG_CMD_ECHO ++ ++#undef CONFIG_CMD_NFS ++#undef CONFIG_CMD_JFFS2 ++#ifndef CONFIG_SYS_ENET ++ #undef CONFIG_CMD_NET ++ #undef CONFIG_NET_MULTI ++#else ++ #define CONFIG_CMD_PING ++ #define CONFIG_NET_MULTI ++#endif ++ ++#if defined(FLASH) ++ #define CONFIG_CMD_FLASH ++ #define CONFIG_CMD_IMLS ++#else ++ #undef CONFIG_CMD_IMLS ++ #undef CONFIG_CMD_FLASH ++ #undef CONFIG_CMD_SAVEENV ++ #undef CONFIG_CMD_SAVES ++#endif ++ ++#if !defined(RAMENV) ++ #define CONFIG_CMD_SAVEENV ++ #define CONFIG_CMD_SAVES ++#endif ++ ++/* Miscellaneous configurable options */ ++#define CONFIG_SYS_PROMPT "U-Boot> " ++#define CONFIG_SYS_CBSIZE 256/* Console I/O Buffer Size */ ++#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE +\ ++ sizeof(CONFIG_SYS_PROMPT) + 16) ++#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE ++ /* Boot Argument Buffer Size */ ++#define CONFIG_SYS_MAXARGS 15 /* max number of command args */ ++#define CONFIG_SYS_LONGHELP ++#define CONFIG_SYS_LOAD_ADDR XILINX_RAM_START /* default load address */ ++ ++#define CONFIG_BOOTDELAY 4 ++/* Don't define BOOTARGS, we get it from the DTB chosen fragment */ ++#undef CONFIG_BOOTARGS ++#define CONFIG_HOSTNAME XILINX_BOARD_NAME ++ ++#define CONFIG_BOOTCOMMAND "" ++ ++/* architecture dependent code */ ++#define CONFIG_SYS_USR_EXCEP /* user exception */ ++#define CONFIG_SYS_HZ 1000 ++ ++#define CONFIG_ENV_OVERWRITE /* Allow to overwrite the u-boot environment variables */ ++#define CONFIG_IPADDR 192.168.10.90 ++#define CONFIG_SERVERIP 192.168.10.101 ++#define CONFIG_ETHADDR 00:0a:35:00:92:d4 ++#define CONFIG_BOOTP_SERVERIP ++ ++#define CONFIG_CMDLINE_EDITING ++ ++/* Use the HUSH parser */ ++#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " ++ ++#define CONFIG_FIT 1 ++#define CONFIG_OF_LIBFDT 1 ++ ++#if defined(CONFIG_XILINX_LL_TEMAC) ++# define CONFIG_MII 1 ++# define CONFIG_CMD_MII 1 ++# define CONFIG_PHY_GIGE 1 ++# define CONFIG_SYS_FAULT_ECHO_LINK_DOWN 1 ++# define CONFIG_PHYLIB 1 ++# define CONFIG_PHY_ATHEROS 1 ++# define CONFIG_PHY_BROADCOM 1 ++# define CONFIG_PHY_DAVICOM 1 ++# define CONFIG_PHY_LXT 1 ++# define CONFIG_PHY_MARVELL 1 ++# define CONFIG_PHY_MICREL 1 ++# define CONFIG_PHY_NATSEMI 1 ++# define CONFIG_PHY_REALTEK 1 ++# define CONFIG_PHY_VITESSE 1 ++#else ++# undef CONFIG_MII ++# undef CONFIG_CMD_MII ++# undef CONFIG_PHYLIB ++#endif ++ ++#endif /* __CONFIG_H */ +diff --git a/include/configs/xilinx-ppc405.h b/include/configs/xilinx-ppc405.h +deleted file mode 100644 +index d335f1e..0000000 +--- a/include/configs/xilinx-ppc405.h ++++ /dev/null +@@ -1,39 +0,0 @@ +-/* +- * +- * (C) Copyright 2008 +- * Ricado Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es +- * This work has been supported by: QTechnology http://qtec.com/ +- * +- * (C) Copyright 2008 +- * Georg Schardt +- * +- * 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 +- */ +- +-#ifndef __CONFIG_H +-#define __CONFIG_H +- +-/* cpu parameter */ +-#define CONFIG_405 1 +-#define CONFIG_4xx 1 +-#define CONFIG_XILINX_405 1 +- +-#include +- +-#endif +diff --git a/include/configs/xilinx-ppc440-generic.h b/include/configs/xilinx-ppc440-generic.h +index fc0f932..78c0dec 100644 +--- a/include/configs/xilinx-ppc440-generic.h ++++ b/include/configs/xilinx-ppc440-generic.h +@@ -1,49 +1,300 @@ + /* +- * (C) Copyright 2008 +- * Ricado Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es +- * This work has been supported by: QTechnology http://qtec.com/ +- * 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, see . +-*/ ++ * (C) Copyright 2007-2010 Michal Simek ++ * ++ * Michal SIMEK ++ * ++ * 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 ++ */ + + #ifndef __CONFIG_H + #define __CONFIG_H + +-/*CPU*/ +-#define CONFIG_440 1 +-#define CONFIG_XILINX_PPC440_GENERIC 1 + #include "../board/xilinx/ppc440-generic/xparameters.h" + +-/*Mem Map*/ +-#define CONFIG_SYS_SDRAM_SIZE_MB 256 ++/* cpu parameter */ ++#define CONFIG_4xx 1 ++#define CONFIG_440 1 ++#define CONFIG_XILINX_440 1 ++#define CONFIG_XILINX_440_GENERIC 1 ++ ++/* Gross XPAR_ hackery */ ++#define XPAR_INTC_0_BASEADDR XILINX_INTC_BASEADDR ++#define XPAR_INTC_MAX_NUM_INTR_INPUTS XILINX_INTC_NUM_INTR_INPUTS ++ ++/* PPC-specific memory layout */ ++#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE ++#define CONFIG_SYS_MONITOR_LEN (256 * 1024) ++#define CONFIG_SYS_MALLOC_LEN (128 * 1024) ++ ++/*Stack*/ ++#define CONFIG_SYS_INIT_RAM_ADDR 0x800000/* Initial RAM address */ ++#define CONFIG_SYS_INIT_RAM_END 0x2000 /* End of used area in RAM */ ++#define CONFIG_SYS_GBL_DATA_OFFSET (CONFIG_SYS_INIT_RAM_END \ ++ - GENERATED_GBL_DATA_SIZE) ++#define CONFIG_SYS_INIT_SP_OFFSET CONFIG_SYS_GBL_DATA_OFFSET ++ ++/*Speed*/ ++#define CONFIG_SYS_CLK_FREQ XILINX_CLOCK_FREQ ++ ++/* Common PPC-specific settings */ ++#define CONFIG_SYS_MEMTEST_START 0x00400000 ++ /* memtest works on */ ++#define CONFIG_SYS_MEMTEST_END 0x00C00000 ++ /* 4 ... 12 MB in DRAM */ ++#define CONFIG_SYS_EXTBDINFO 1 ++ /* Extended board_into (bd_t) */ ++#define CONFIG_SYS_HZ 1000 ++ /* decrementer freq: 1 ms ticks */ ++ ++#define CONFIG_SYS_BOOTMAPSZ (16 << 20) ++ /* Initial Memory map for Linux */ ++ ++/* The following table includes the supported baudrates */ ++#define CONFIG_SYS_BAUDRATE_TABLE \ ++ {300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400} ++ ++/* use serial multi for all serial devices */ ++#define CONFIG_SYS_CONSOLE_IS_IN_ENV 1 ++ ++#ifdef XILINX_UARTLITE_BASEADDR ++# define CONFIG_XILINX_UARTLITE ++# if defined(XILINX_UARTLITE_BAUDRATE) ++# define CONFIG_BAUDRATE XILINX_UARTLITE_BAUDRATE ++# endif ++#endif ++ ++#if XILINX_UART16550_BASEADDR ++# define CONFIG_SYS_NS16550 1 ++# define CONFIG_SYS_NS16550_SERIAL ++# define CONFIG_SYS_NS16550_COM1 ((XILINX_UART16550_BASEADDR & ~0xF) + 0x1000) ++# define CONFIG_SYS_NS16550_CLK XILINX_UART16550_CLOCK_HZ ++ ++# if defined(__MICROBLAZEEL__) ++# define CONFIG_SYS_NS16550_REG_SIZE -4 ++# else ++# define CONFIG_SYS_NS16550_REG_SIZE 4 ++# endif ++ ++/* CONS_INDEX for system with uartlite only mustn't define CONFIG_CONS_INDEX ++ * u-boot BSP generates CONFIG_CONS_INDEX for system with several uart16550 */ ++# if !defined(CONFIG_CONS_INDEX) ++# define CONFIG_CONS_INDEX 1 ++# endif ++#endif ++ ++#if !defined(CONFIG_BAUDRATE) ++ #define CONFIG_BAUDRATE 115200 ++#endif ++ ++#undef CONFIG_SYS_ENET ++#if defined(XILINX_EMACLITE_BASEADDR) ++ #define CONFIG_XILINX_EMACLITE 1 ++ #define CONFIG_SYS_ENET ++#endif ++#if defined(XILINX_LLTEMAC_BASEADDR) ++ #define CONFIG_XILINX_LL_TEMAC 1 ++ #define CONFIG_SYS_ENET ++#endif ++ ++#undef ET_DEBUG ++ ++ ++/* interrupt controller */ ++#ifdef XILINX_INTC_BASEADDR ++ #define CONFIG_SYS_INTC_0 1 ++ #define CONFIG_SYS_INTC_0_ADDR XILINX_INTC_BASEADDR ++ #define CONFIG_SYS_INTC_0_NUM XILINX_INTC_NUM_INTR_INPUTS ++#endif ++ ++/* timer */ ++#ifdef XILINX_TIMER_BASEADDR ++ #if (XILINX_TIMER_IRQ != -1) ++ #define CONFIG_SYS_TIMER_0 1 ++ #define CONFIG_SYS_TIMER_0_ADDR XILINX_TIMER_BASEADDR ++ #define CONFIG_SYS_TIMER_0_IRQ XILINX_TIMER_IRQ ++ #define FREQUENCE XILINX_CLOCK_FREQ ++ #define CONFIG_SYS_TIMER_0_PRELOAD ( FREQUENCE/1000 ) ++ #endif ++#else ++# error Please setup TIMER in BSP ++#endif ++ ++/* ++ * memory layout - Example ++ * TEXT_BASE = 0x1200_0000; ++ * CONFIG_SYS_SRAM_BASE = 0x1000_0000; ++ * CONFIG_SYS_SRAM_SIZE = 0x0400_0000; ++ * ++ * CONFIG_SYS_GBL_DATA_OFFSET = 0x1000_0000 + 0x0400_0000 - 0x1000 = 0x13FF_F000 ++ * CONFIG_SYS_MONITOR_BASE = 0x13FF_F000 - 0x40000 = 0x13FB_F000 ++ * CONFIG_SYS_MALLOC_BASE = 0x13FB_F000 - 0x40000 = 0x13F7_F000 ++ * ++ * 0x1000_0000 CONFIG_SYS_SDRAM_BASE ++ * FREE ++ * 0x1200_0000 TEXT_BASE ++ * U-BOOT code ++ * 0x1202_0000 ++ * FREE ++ * ++ * STACK ++ * 0x13F7_F000 CONFIG_SYS_MALLOC_BASE ++ * MALLOC_AREA 256kB Alloc ++ * 0x11FB_F000 CONFIG_SYS_MONITOR_BASE ++ * MONITOR_CODE 256kB Env ++ * 0x13FF_F000 CONFIG_SYS_GBL_DATA_OFFSET ++ * GLOBAL_DATA 4kB bd, gd ++ * 0x1400_0000 CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_SDRAM_SIZE ++ */ ++ ++/* ddr sdram - main memory */ ++#define CONFIG_SYS_SDRAM_BASE XILINX_RAM_START ++#define CONFIG_SYS_SDRAM_SIZE XILINX_RAM_SIZE ++ ++#if defined(XILINX_FLASH_START) /* Parallel Flash */ ++ #define FLASH ++ #define CONFIG_SYS_FLASH_BASE XILINX_FLASH_START ++ #define CONFIG_SYS_FLASH_SIZE XILINX_FLASH_SIZE ++ #define CONFIG_SYS_FLASH_CFI 1 ++ #define CONFIG_FLASH_CFI_DRIVER 1 ++ #define CONFIG_SYS_FLASH_EMPTY_INFO 1 /* ?empty sector */ ++ #define CONFIG_SYS_MAX_FLASH_BANKS 1 /* max number of memory banks */ ++ #define CONFIG_SYS_MAX_FLASH_SECT 2048 /* max number of sectors on one chip */ ++ ++ /* Assume env is in flash, this may be undone lower down */ ++ #define CONFIG_ENV_IS_IN_FLASH 1 ++ #define CONFIG_ENV_SECT_SIZE 0x20000 /* 128K(one sector) for env */ ++ ++ #define CONFIG_SYS_FLASH_PROTECTION ++ ++ #define CONFIG_ENV_ADDR XILINX_FLASH_START ++ #define CONFIG_ENV_SIZE CONFIG_ENV_SECT_SIZE ++#else /* No flash memory at all */ ++ /* ENV in RAM */ ++ #define RAMENV ++ #define CONFIG_SYS_NO_FLASH 1 ++ ++ #define CONFIG_ENV_IS_NOWHERE 1 ++ #undef CONFIG_ENV_IS_IN_FLASH ++ #undef CONFIG_ENV_IS_IN_SPI_FLASH ++ #define CONFIG_ENV_SIZE 0x1000 ++ #define CONFIG_ENV_ADDR (CONFIG_SYS_MONITOR_BASE - CONFIG_ENV_SIZE) ++ #define CONFIG_SYS_FLASH_PROTECTION /* hardware flash protection */ ++#endif ++ ++/* ++ * BOOTP options ++ */ ++#define CONFIG_BOOTP_BOOTFILESIZE ++#define CONFIG_BOOTP_BOOTPATH ++#define CONFIG_BOOTP_GATEWAY ++#define CONFIG_BOOTP_HOSTNAME ++ ++/* ++ * Command line configuration. ++ */ ++#include ++ ++#define CONFIG_CMD_ASKENV ++/* FIXME: hack for zynq */ ++#define CONFIG_CMD_IRQ ++#define CONFIG_CMD_ECHO ++ ++#undef CONFIG_CMD_NFS ++#undef CONFIG_CMD_JFFS2 ++#ifndef CONFIG_SYS_ENET ++ #undef CONFIG_CMD_NET ++ #undef CONFIG_NET_MULTI ++#else ++ #define CONFIG_CMD_PING ++ #define CONFIG_NET_MULTI ++#endif ++ ++#if defined(FLASH) ++ #define CONFIG_CMD_FLASH ++ #define CONFIG_CMD_IMLS ++#else ++ #undef CONFIG_CMD_IMLS ++ #undef CONFIG_CMD_FLASH ++ #undef CONFIG_CMD_SAVEENV ++ #undef CONFIG_CMD_SAVES ++#endif ++ ++#if !defined(RAMENV) ++ #define CONFIG_CMD_SAVEENV ++ #define CONFIG_CMD_SAVES ++#endif ++ ++/* Miscellaneous configurable options */ ++#define CONFIG_SYS_PROMPT "U-Boot> " ++#define CONFIG_SYS_CBSIZE 256/* Console I/O Buffer Size */ ++#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE +\ ++ sizeof(CONFIG_SYS_PROMPT) + 16) ++#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE ++ /* Boot Argument Buffer Size */ ++#define CONFIG_SYS_MAXARGS 15 /* max number of command args */ ++#define CONFIG_SYS_LONGHELP ++#define CONFIG_SYS_LOAD_ADDR XILINX_RAM_START /* default load address */ ++ ++#define CONFIG_BOOTDELAY 4 ++/* Don't define BOOTARGS, we get it from the DTB chosen fragment */ ++#undef CONFIG_BOOTARGS ++#define CONFIG_HOSTNAME XILINX_BOARD_NAME ++ ++#define CONFIG_BOOTCOMMAND "" ++ ++/* architecture dependent code */ ++#define CONFIG_SYS_USR_EXCEP /* user exception */ ++#define CONFIG_SYS_HZ 1000 ++ ++#define CONFIG_ENV_OVERWRITE /* Allow to overwrite the u-boot environment variables */ ++#define CONFIG_IPADDR 192.168.10.90 ++#define CONFIG_SERVERIP 192.168.10.101 ++#define CONFIG_ETHADDR 00:0a:35:00:92:d4 ++#define CONFIG_BOOTP_SERVERIP + +-/*Env*/ +-#define CONFIG_ENV_IS_IN_FLASH 1 +-#define CONFIG_ENV_SIZE 0x20000 +-#define CONFIG_ENV_SECT_SIZE 0x20000 +-#define CONFIG_ENV_OFFSET 0x340000 +-#define CONFIG_ENV_ADDR (XPAR_FLASH_MEM0_BASEADDR+CONFIG_ENV_OFFSET) ++#define CONFIG_CMDLINE_EDITING + +-/*Misc*/ +-#define CONFIG_SYS_PROMPT "board:/# " /* Monitor Command Prompt */ +-#define CONFIG_PREBOOT "echo U-Boot is up and runnining;" ++/* Use the HUSH parser */ ++#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " + +-/*Flash*/ +-#define CONFIG_SYS_FLASH_SIZE (32*1024*1024) +-#define CONFIG_SYS_MAX_FLASH_SECT 259 +-#define MTDIDS_DEFAULT "nor0=ml507-flash" +-#define MTDPARTS_DEFAULT "mtdparts=ml507-flash:-(user)" ++#define CONFIG_FIT 1 ++#define CONFIG_OF_LIBFDT 1 + +-/*Generic Configs*/ +-#include ++#if defined(CONFIG_XILINX_LL_TEMAC) ++# define CONFIG_MII 1 ++# define CONFIG_CMD_MII 1 ++# define CONFIG_PHY_GIGE 1 ++# define CONFIG_SYS_FAULT_ECHO_LINK_DOWN 1 ++# define CONFIG_PHYLIB 1 ++# define CONFIG_PHY_ATHEROS 1 ++# define CONFIG_PHY_BROADCOM 1 ++# define CONFIG_PHY_DAVICOM 1 ++# define CONFIG_PHY_LXT 1 ++# define CONFIG_PHY_MARVELL 1 ++# define CONFIG_PHY_MICREL 1 ++# define CONFIG_PHY_NATSEMI 1 ++# define CONFIG_PHY_REALTEK 1 ++# define CONFIG_PHY_VITESSE 1 ++#else ++# undef CONFIG_MII ++# undef CONFIG_CMD_MII ++# undef CONFIG_PHYLIB ++#endif + +-#endif /* __CONFIG_H */ ++#endif /* __CONFIG_H */ +diff --git a/include/configs/xilinx-ppc440.h b/include/configs/xilinx-ppc440.h +deleted file mode 100644 +index 6e938dc..0000000 +--- a/include/configs/xilinx-ppc440.h ++++ /dev/null +@@ -1,28 +0,0 @@ +-/* +- * (C) Copyright 2008 +- * Ricado Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es +- * This work has been supported by: QTechnology http://qtec.com/ +- * 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, see . +-*/ +- +-#ifndef __CONFIG_GEN_H +-#define __CONFIG_GEN_H +- +-/*CPU*/ +-#define CONFIG_4xx 1 +-#define CONFIG_440 1 +-#define CONFIG_XILINX_440 1 +- +-#include +- +-#endif /* __CONFIG_H */ +diff --git a/include/configs/zynq_afx.h b/include/configs/zynq_afx.h +new file mode 100644 +index 0000000..7339fbc +--- /dev/null ++++ b/include/configs/zynq_afx.h +@@ -0,0 +1,36 @@ ++/* ++ * (C) Copyright 2012 Xilinx ++ * ++ * Configuration settings for the Xilinx Zynq AFX board. ++ * See zynq_common.h for Zynq common configs ++ * ++ * 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. ++ * ++ * 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 ++ */ ++ ++#ifndef __CONFIG_ZYNQ_AFX_H ++#define __CONFIG_ZYNQ_AFX_H ++ ++#define PHYS_SDRAM_1_SIZE (128 * 1024 * 1024) ++ ++#define CONFIG_ZYNQ_SERIAL_UART1 ++ ++#define CONFIG_SYS_NO_FLASH ++#if defined(CONFIG_AFX_NOR) ++# undef CONFIG_SYS_NO_FLASH ++#elif defined(CONFIG_AFX_QSPI) ++# define CONFIG_ZYNQ_SPI ++#elif defined(CONFIG_AFX_NAND) ++# define CONFIG_NAND_ZYNQ ++#endif ++ ++#include ++ ++#endif /* __CONFIG_ZYNQ_AFX_H */ +diff --git a/include/configs/zynq_common.h b/include/configs/zynq_common.h +new file mode 100644 +index 0000000..28948fb +--- /dev/null ++++ b/include/configs/zynq_common.h +@@ -0,0 +1,300 @@ ++/* ++ * (C) Copyright 2012 Xilinx ++ * ++ * Xilinx Zynq common configuration settings ++ * ++ * 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. ++ * ++ * 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 ++ */ ++ ++#ifndef __CONFIG_ZYNQ_COMMON_H ++#define __CONFIG_ZYNQ_COMMON_H ++ ++/* High Level Configuration Options */ ++#define CONFIG_ARMV7 /* CPU */ ++#define CONFIG_ZYNQ /* SoC */ ++ ++/* Default environment */ ++#define CONFIG_IPADDR 10.10.70.102 ++#define CONFIG_SERVERIP 10.10.70.101 ++ ++#define CONFIG_SYS_SDRAM_BASE 0 ++#define CONFIG_SYS_SDRAM_SIZE PHYS_SDRAM_1_SIZE ++ ++/* Total Size of Environment Sector */ ++#define CONFIG_ENV_SIZE (128 << 10) ++ ++/* allow to overwrite serial and ethaddr */ ++#define CONFIG_ENV_OVERWRITE ++ ++/* Size of malloc() pool */ ++#define CONFIG_SYS_MALLOC_LEN 0x400000 ++ ++/* Serial drivers */ ++#define CONFIG_BAUDRATE 115200 ++#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 38400, 115200 } ++ ++/* Zynq serial driver */ ++#ifdef CONFIG_ZYNQ_SERIAL_UART0 ++# define CONFIG_ZYNQ_SERIAL_BASEADDR0 0xE0000000 ++# define CONFIG_ZYNQ_SERIAL_BAUDRATE0 CONFIG_BAUDRATE ++# define CONFIG_ZYNQ_SERIAL_CLOCK0 50000000 ++#endif ++ ++#ifdef CONFIG_ZYNQ_SERIAL_UART1 ++# define CONFIG_ZYNQ_SERIAL_BASEADDR1 0xE0001000 ++# define CONFIG_ZYNQ_SERIAL_BAUDRATE1 CONFIG_BAUDRATE ++# define CONFIG_ZYNQ_SERIAL_CLOCK1 50000000 ++#endif ++ ++#if defined(CONFIG_ZYNQ_SERIAL_UART0) || defined(CONFIG_ZYNQ_SERIAL_UART1) ++#define CONFIG_ZYNQ_SERIAL ++#endif ++ ++/* Ethernet driver */ ++#ifdef CONFIG_ZYNQ_GEM0 ++# define CONFIG_ZYNQ_GEM_BASEADDR0 0xE000B000 ++#endif ++ ++#ifdef CONFIG_ZYNQ_GEM1 ++# define CONFIG_ZYNQ_GEM_BASEADDR1 0xE000C000 ++#endif ++ ++#if defined(CONFIG_ZYNQ_GEM0) || defined(CONFIG_ZYNQ_GEM1) ++# define CONFIG_NET_MULTI ++# define CONFIG_ZYNQ_GEM ++# define CONFIG_MII ++# define CONFIG_SYS_FAULT_ECHO_LINK_DOWN ++# define CONFIG_PHYLIB ++# define CONFIG_PHY_MARVELL ++# define CONFIG_SYS_ENET ++#endif ++ ++/* SCU timer address is hardcoded */ ++#define CONFIG_SCUTIMER_BASEADDR 0xF8F00600 ++#ifndef CONFIG_CPU_FREQ_HZ ++#define CONFIG_CPU_FREQ_HZ 800000000 ++#endif ++#define CONFIG_SYS_HZ 1000 ++ ++/* Miscellaneous configurable options */ ++#define CONFIG_SYS_PROMPT "zynq-uboot> " ++#define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */ ++#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " ++ ++#define CONFIG_CMDLINE_EDITING ++#define CONFIG_AUTO_COMPLETE ++#define CONFIG_SYS_LONGHELP ++#define CONFIG_BOARD_LATE_INIT ++#define CONFIG_SYS_MAXARGS 16 ++#define CONFIG_SYS_CBSIZE 2048 ++#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ ++ sizeof(CONFIG_SYS_PROMPT) + 16) ++ ++/* Open Firmware flat tree */ ++#define CONFIG_OF_LIBFDT ++ ++#include ++ ++#ifdef CONFIG_SYS_ENET ++# define CONFIG_CMD_PING ++# define CONFIG_CMD_MII ++#else ++# undef CONFIG_CMD_NET ++# undef CONFIG_CMD_NFS ++#endif ++ ++/* NOR */ ++#ifndef CONFIG_SYS_NO_FLASH ++# define CONFIG_SYS_FLASH_BASE 0xE2000000 ++# define CONFIG_SYS_FLASH_SIZE (16 * 1024 * 1024) ++# define CONFIG_SYS_MAX_FLASH_BANKS 1 ++/* max number of sectors/blocks on one chip */ ++# define CONFIG_SYS_MAX_FLASH_SECT 512 ++# define CONFIG_SYS_FLASH_ERASE_TOUT 1000 ++# define CONFIG_SYS_FLASH_WRITE_TOUT 5000 ++# define CONFIG_FLASH_SHOW_PROGRESS 10 ++# define CONFIG_SYS_FLASH_CFI ++# undef CONFIG_SYS_FLASH_EMPTY_INFO ++# define CONFIG_FLASH_CFI_DRIVER ++# undef CONFIG_SYS_FLASH_PROTECTION /* don't use hardware protection */ ++/* use buffered writes (20x faster) */ ++# define CONFIG_SYS_FLASH_USE_BUFFER_WRITE ++#endif ++ ++/* QSPI */ ++#ifdef CONFIG_ZYNQ_SPI ++# define CONFIG_SF_DEFAULT_SPEED 30000000 ++# define CONFIG_SPI_FLASH ++# define CONFIG_SPI_FLASH_SPANSION ++# define CONFIG_SPI_FLASH_STMICRO ++# define CONFIG_SPI_FLASH_WINBOND ++# define CONFIG_CMD_SPI ++# define CONFIG_CMD_SF ++#endif ++ ++/* MMC */ ++#ifdef CONFIG_MMC ++# define CONFIG_GENERIC_MMC ++# define CONFIG_SDHCI ++# define CONFIG_ZYNQ_SDHCI ++# define CONFIG_CMD_MMC ++# define CONFIG_CMD_FAT ++# define CONFIG_SUPPORT_VFAT ++# define CONFIG_CMD_EXT2 ++# define CONFIG_DOS_PARTITION ++#endif ++ ++/* NAND */ ++#ifdef CONFIG_NAND_ZYNQ ++# define CONFIG_CMD_NAND ++# define CONFIG_CMD_NAND_LOCK_UNLOCK ++# define CONFIG_SYS_MAX_NAND_DEVICE 1 ++# define CONFIG_SYS_NAND_BASE XPSS_NAND_BASEADDR ++# define CONFIG_SYS_NAND_ONFI_DETECTION ++# define CONFIG_MTD_DEVICE ++#endif ++ ++/* I2C */ ++#ifdef CONFIG_ZYNQ_I2C ++# define CONFIG_CMD_I2C ++# define CONFIG_ZYNQ_I2C_CTLR_0 ++# define CONFIG_HARD_I2C 1 ++# define CONFIG_SYS_I2C_SPEED 100000 ++# define CONFIG_SYS_I2C_SLAVE 1 ++#endif ++ ++/* EEPROM */ ++#ifdef CONFIG_ZYNQ_EEPROM ++# define CONFIG_CMD_EEPROM ++# define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 1 ++# define CONFIG_SYS_I2C_EEPROM_ADDR 0x54 ++# define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS 4 ++# define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS 5 ++# define CONFIG_SYS_EEPROM_SIZE 1024 /* Bytes */ ++#endif ++ ++#ifndef CONFIG_ENV_IS_NOWHERE ++# ifndef CONFIG_SYS_NO_FLASH ++/* Environment in NOR flash */ ++# define CONFIG_ENV_IS_IN_FLASH ++# elif defined(CONFIG_ZYNQ_SPI) ++/* Environment in Serial Flash */ ++# define CONFIG_ENV_IS_IN_SPI_FLASH ++# elif defined(CONFIG_NAND_ZYNQ) ++/* Environment in NAND flash */ ++# define CONFIG_ENV_IS_IN_NAND ++# elif defined(CONFIG_SYS_NO_FLASH) ++# define CONFIG_ENV_IS_NOWHERE ++# endif ++ ++# define CONFIG_ENV_SECT_SIZE CONFIG_ENV_SIZE ++# define CONFIG_ENV_OFFSET 0xE0000 ++# define CONFIG_CMD_SAVEENV /* Command to save ENV to Flash */ ++#endif ++ ++/* For development/debugging */ ++#ifdef DEBUG ++# define CONFIG_CMD_REGINFO ++# define CONFIG_PANIC_HANG ++#endif ++ ++/* Default environment */ ++#define CONFIG_EXTRA_ENV_SETTINGS \ ++ "ethaddr=00:0a:35:00:01:22\0" \ ++ "kernel_image=uImage\0" \ ++ "ramdisk_image=uramdisk.image.gz\0" \ ++ "devicetree_image=devicetree.dtb\0" \ ++ "bitstream_image=system.bit.bin\0" \ ++ "loadbit_addr=0x100000\0" \ ++ "kernel_size=0x500000\0" \ ++ "devicetree_size=0x20000\0" \ ++ "ramdisk_size=0x5E0000\0" \ ++ "fdt_high=0x20000000\0" \ ++ "initrd_high=0x20000000\0" \ ++ "mmc_loadbit_fat=echo Loading bitstream from SD/MMC/eMMC to RAM.. && " \ ++ "mmcinfo && " \ ++ "fatload mmc 0 ${loadbit_addr} ${bitstream_image} && " \ ++ "fpga load 0 ${loadbit_addr} ${filesize}\0" \ ++ "norboot=echo Copying Linux from NOR flash to RAM... && " \ ++ "cp 0xE2100000 0x3000000 ${kernel_size} && " \ ++ "cp 0xE2600000 0x2A00000 ${devicetree_size} && " \ ++ "echo Copying ramdisk... && " \ ++ "cp 0xE2620000 0x2000000 ${ramdisk_size} && " \ ++ "bootm 0x3000000 0x2000000 0x2A00000\0" \ ++ "qspiboot=echo Copying Linux from QSPI flash to RAM... && " \ ++ "sf probe 0 0 0 && " \ ++ "sf read 0x3000000 0x100000 ${kernel_size} && " \ ++ "sf read 0x2A00000 0x600000 ${devicetree_size} && " \ ++ "echo Copying ramdisk... && " \ ++ "sf read 0x2000000 0x620000 ${ramdisk_size} && " \ ++ "bootm 0x3000000 0x2000000 0x2A00000\0" \ ++ "sdboot=echo Copying Linux from SD to RAM... && " \ ++ "mmcinfo && " \ ++ "fatload mmc 0 0x3000000 ${kernel_image} && " \ ++ "fatload mmc 0 0x2A00000 ${devicetree_image} && " \ ++ "fatload mmc 0 0x2000000 ${ramdisk_image} && " \ ++ "bootm 0x3000000 0x2000000 0x2A00000\0" \ ++ "nandboot=echo Copying Linux from NAND flash to RAM... && " \ ++ "nand read 0x3000000 0x100000 ${kernel_size} && " \ ++ "nand read 0x2A00000 0x600000 ${devicetree_size} && " \ ++ "echo Copying ramdisk... && " \ ++ "nand read 0x2000000 0x620000 ${ramdisk_size} && " \ ++ "bootm 0x3000000 0x2000000 0x2A00000\0" \ ++ "jtagboot=echo TFTPing Linux to RAM... && " \ ++ "tftp 0x3000000 ${kernel_image} && " \ ++ "tftp 0x2A00000 ${devicetree_image} && " \ ++ "tftp 0x2000000 ${ramdisk_image} && " \ ++ "bootm 0x3000000 0x2000000 0x2A00000\0" ++ ++/* default boot is according to the bootmode switch settings */ ++#define CONFIG_BOOTCOMMAND "run $modeboot" ++#define CONFIG_BOOTDELAY 3 /* -1 to Disable autoboot */ ++#define CONFIG_SYS_LOAD_ADDR 0 /* default? */ ++ ++/* Keep L2 Cache Disabled */ ++#define CONFIG_SYS_L2CACHE_OFF ++#define CONFIG_SYS_CACHELINE_SIZE 32 ++ ++/* Physical Memory map */ ++#define CONFIG_NR_DRAM_BANKS 1 ++#define PHYS_SDRAM_1 0 ++#define CONFIG_SYS_TEXT_BASE 0x04000000 ++ ++#define CONFIG_SYS_MEMTEST_START PHYS_SDRAM_1 ++#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_MEMTEST_START + \ ++ PHYS_SDRAM_1_SIZE - (16 * 1024 * 1024)) ++ ++#define CONFIG_SYS_INIT_RAM_ADDR 0xFFFF0000 ++#define CONFIG_SYS_INIT_RAM_SIZE 0x1000 ++#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_INIT_RAM_ADDR + \ ++ CONFIG_SYS_INIT_RAM_SIZE - \ ++ GENERATED_GBL_DATA_SIZE) ++ ++/* Enable the PL to be downloaded */ ++#define CONFIG_FPGA ++#define CONFIG_FPGA_XILINX ++#define CONFIG_FPGA_ZYNQPL ++#define CONFIG_CMD_FPGA ++ ++/* FIT support */ ++#define CONFIG_FIT 1 ++#define CONFIG_FIT_VERBOSE 1 /* enable fit_format_{error,warning}() */ ++ ++#define CONFIG_CMD_BOOTZ ++#undef CONFIG_BOOTM_NETBSD ++ ++/* FIXME this should be removed pretty soon */ ++#define XPSS_QSPI_BASEADDR 0xE000D000 ++#define XPSS_NAND_BASEADDR 0xE1000000 ++#define XPSS_CRTL_PARPORT_BASEADDR 0xE000E000 ++#define SD_BASEADDR 0xE0100000 ++ ++#endif /* __CONFIG_ZYNQ_COMMON_H */ +diff --git a/include/configs/zynq_cseflash.h b/include/configs/zynq_cseflash.h +new file mode 100644 +index 0000000..495530e +--- /dev/null ++++ b/include/configs/zynq_cseflash.h +@@ -0,0 +1,73 @@ ++/* ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++#define PHYS_SDRAM_1_SIZE (256 * 1024 * 1024) ++ ++#define CONFIG_ENV_IS_NOWHERE ++ ++#include ++ ++/* Disable uart console */ ++#undef CONFIG_ZYNQ_SERIAL ++ ++ ++#define CONFIG_ARM_DCC ++#define CONFIG_CPU_V6 /* Required by CONFIG_ARM_DCC */ ++ ++/* ++ * Open Firmware flat tree ++ */ ++#undef CONFIG_OF_LIBFDT ++ ++ ++ ++ ++#undef CONFIG_CMD_EDITENV ++#undef CONFIG_CMD_SAVEENV ++ ++#undef CONFIG_CMD_FPGA ++#undef CONFIG_CMD_XIMG ++ ++#undef CONFIG_CMD_LOADB /* loadb */ ++#undef CONFIG_CMD_LOADS /* loads */ ++ ++#define CONFIG_CMD_MEMORY /* md mm nm mw cp cmp crc base loop mtest */ ++ ++#undef CONFIG_CMD_MISC /* Misc functions like sleep etc*/ ++#undef CONFIG_CMD_RUN /* run command in env variable */ ++#undef CONFIG_CMD_SOURCE /* "source" command support */ ++ ++#undef CONFIG_CMD_BDI /* bdinfo */ ++#undef CONFIG_CMD_BOOTD /* bootd */ ++#undef CONFIG_CMD_CONSOLE /* coninfo */ ++#undef CONFIG_CMD_ECHO /* echo arguments */ ++#undef CONFIG_CMD_IMI /* iminfo */ ++#undef CONFIG_CMD_ITEST /* Integer (and string) test */ ++#undef CONFIG_CMD_IMLS /* List all found images */ ++ ++ ++// FIXME this is silly - there is no any bootm image enabled - disable BOOTM ++//#undef CONFIG_BOOTM_LINUX ++#undef CONFIG_BOOTM_NETBSD ++#undef CONFIG_BOOTM_RTEMS ++#undef CONFIG_GZIP ++#undef CONFIG_ZLIB ++ ++#undef CONFIG_AUTO_COMPLETE ++#define CONFIG_CMDLINE_EDITING ++#undef CONFIG_SYS_LONGHELP ++ ++ ++/* Because (at least at first) we're going to be loaded via JTAG_Tcl */ ++#define CONFIG_SKIP_LOWLEVEL_INIT ++ ++ ++ ++/* Why? */ ++#undef CONFIG_ENV_SIZE ++#define CONFIG_ENV_SIZE 896 ++ ++#endif /* __CONFIG_H */ +diff --git a/include/configs/zynq_zc70x.h b/include/configs/zynq_zc70x.h +new file mode 100644 +index 0000000..4e7df2e +--- /dev/null ++++ b/include/configs/zynq_zc70x.h +@@ -0,0 +1,36 @@ ++/* ++ * (C) Copyright 2012 Xilinx ++ * ++ * Configuration settings for the Xilinx Zynq ZC702 and ZC706 boards ++ * See zynq_common.h for Zynq common configs ++ * ++ * 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. ++ * ++ * 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 ++ */ ++ ++#ifndef __CONFIG_ZYNQ_ZC70X_H ++#define __CONFIG_ZYNQ_ZC70X_H ++ ++#define PHYS_SDRAM_1_SIZE (1024 * 1024 * 1024) ++ ++#define CONFIG_ZYNQ_SERIAL_UART1 ++#define CONFIG_ZYNQ_GEM0 ++#define CONFIG_PHY_ADDR 7 ++ ++#define CONFIG_SYS_NO_FLASH ++ ++#define CONFIG_MMC ++#define CONFIG_ZYNQ_SPI ++#define CONFIG_ZYNQ_I2C ++#define CONFIG_ZYNQ_EEPROM ++ ++#include ++ ++#endif /* __CONFIG_ZYNQ_ZC70X_H */ +diff --git a/include/configs/zynq_zc770.h b/include/configs/zynq_zc770.h +new file mode 100644 +index 0000000..3bfe631 +--- /dev/null ++++ b/include/configs/zynq_zc770.h +@@ -0,0 +1,52 @@ ++/* ++ * (C) Copyright 2012 Xilinx ++ * ++ * Configuration settings for the Xilinx Zynq ZC770 board. ++ * See zynq_common.h for Zynq common configs ++ * ++ * 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. ++ * ++ * 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 ++ */ ++ ++#ifndef __CONFIG_ZYNQ_ZC770_H ++#define __CONFIG_ZYNQ_ZC770_H ++ ++#define PHYS_SDRAM_1_SIZE (1024 * 1024 * 1024) ++ ++#define CONFIG_SYS_NO_FLASH ++ ++#if defined(CONFIG_ZC770_XM010) ++# define CONFIG_ZYNQ_SERIAL_UART1 ++# define CONFIG_ZYNQ_GEM0 ++# define CONFIG_PHY_ADDR 7 ++# define CONFIG_MMC ++# define CONFIG_ZYNQ_SPI ++ ++#elif defined(CONFIG_ZC770_XM011) ++# define CONFIG_ZYNQ_SERIAL_UART1 ++# define CONFIG_NAND_ZYNQ ++ ++#elif defined(CONFIG_ZC770_XM012) ++# define CONFIG_ZYNQ_SERIAL_UART1 ++# undef CONFIG_SYS_NO_FLASH ++ ++#elif defined(CONFIG_ZC770_XM013) ++# define CONFIG_ZYNQ_SERIAL_UART0 ++# define CONFIG_ZYNQ_GEM1 ++# define CONFIG_PHY_ADDR 7 ++# define CONFIG_ZYNQ_SPI ++ ++#else ++# define CONFIG_ZYNQ_SERIAL_UART0 ++#endif ++ ++#include ++ ++#endif /* __CONFIG_ZYNQ_ZC770_H */ +diff --git a/include/configs/zynq_zed.h b/include/configs/zynq_zed.h +new file mode 100644 +index 0000000..b065ef7 +--- /dev/null ++++ b/include/configs/zynq_zed.h +@@ -0,0 +1,34 @@ ++/* ++ * (C) Copyright 2012 Xilinx ++ * ++ * Configuration for Zynq Evaluation and Development Board - ZedBoard ++ * See zynq_common.h for Zynq common configs ++ * ++ * 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. ++ * ++ * 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 ++ */ ++ ++#ifndef __CONFIG_ZYNQ_ZED_H ++#define __CONFIG_ZYNQ_ZED_H ++ ++#define PHYS_SDRAM_1_SIZE (512 * 1024 * 1024) ++ ++#define CONFIG_ZYNQ_SERIAL_UART1 ++#define CONFIG_ZYNQ_GEM0 ++#define CONFIG_PHY_ADDR 0 ++ ++#define CONFIG_SYS_NO_FLASH ++ ++#define CONFIG_MMC ++#define CONFIG_ZYNQ_SPI ++ ++#include ++ ++#endif /* __CONFIG_ZYNQ_ZED_H */ +diff --git a/include/zynqpl.h b/include/zynqpl.h +new file mode 100644 +index 0000000..c9629e1 +--- /dev/null ++++ b/include/zynqpl.h +@@ -0,0 +1,60 @@ ++/* ++ * (C) Copyright 2012 ++ * Joe Hershberger ++ * ++ * 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 ++ * ++ */ ++ ++#ifndef _ZYNQPL_H_ ++#define _ZYNQPL_H_ ++ ++#include ++ ++extern int zynq_load(Xilinx_desc *desc, const void *image, size_t size); ++extern int zynq_dump(Xilinx_desc *desc, const void *buf, size_t bsize); ++extern int zynq_info(Xilinx_desc *desc); ++ ++#define XILINX_ZYNQ_7010 0x2 ++#define XILINX_ZYNQ_7020 0x7 ++#define XILINX_ZYNQ_7030 0xc ++#define XILINX_ZYNQ_7045 0x11 ++ ++/* Device Image Sizes ++ *********************************************************************/ ++#define XILINX_XC7Z010_SIZE 16669920/8 ++#define XILINX_XC7Z020_SIZE 32364512/8 ++#define XILINX_XC7Z030_SIZE 47839328/8 ++#define XILINX_XC7Z045_SIZE 106571232/8 ++ ++/* Descriptor Macros ++ *********************************************************************/ ++#define XILINX_XC7Z010_DESC(cookie) \ ++{ Xilinx_Zynq, devcfg, XILINX_XC7Z010_SIZE, NULL, cookie } ++ ++#define XILINX_XC7Z020_DESC(cookie) \ ++{ Xilinx_Zynq, devcfg, XILINX_XC7Z020_SIZE, NULL, cookie } ++ ++#define XILINX_XC7Z030_DESC(cookie) \ ++{ Xilinx_Zynq, devcfg, XILINX_XC7Z030_SIZE, NULL, cookie } ++ ++#define XILINX_XC7Z045_DESC(cookie) \ ++{ Xilinx_Zynq, devcfg, XILINX_XC7Z045_SIZE, NULL, cookie } ++ ++#endif /* _ZYNQPL_H_ */ +-- +1.7.5.4 + diff --git a/recipes-bsp/u-boot/u-boot_2013.01.01.bbappend b/recipes-bsp/u-boot/u-boot_2013.01.01.bbappend new file mode 100644 index 00000000..73363cab --- /dev/null +++ b/recipes-bsp/u-boot/u-boot_2013.01.01.bbappend @@ -0,0 +1,15 @@ +# Include path to xilinx-v14.5 modifications to u-boot 2013.01.01 +FILESEXTRAPATHS_prepend := "${THISDIR}/u-boot:" +# Include path to patches to xilinx-v14.5 +FILESEXTRAPATHS_prepend := "${THISDIR}/u-boot-xlnx:" + +SRC_URI += "file://xilinx-v2013.01/0001-Xilinx-modifications-to-arch.patch \ + file://xilinx-v2013.01/0002-Xilinx-modifications-to-boards.patch \ + file://xilinx-v2013.01/0003-Xilinx-modifications-to-commmon.patch \ + file://xilinx-v2013.01/0004-Xilinx-modifications-to-drivers.patch \ + file://xilinx-v2013.01/0005-Xilinx-modifications-to-configs.patch \ + file://microblaze_bootm_Add_support_for_loading_initrd.patch \ + file://microblaze_bootm_Fix_coding_style_issues.patch \ + file://microblaze_Fix_coding_style_for_bootb.patch \ + " +include u-boot-extra.inc -- cgit v1.2.3-54-g00ecf