ARM: zynq: move SoC sources to mach-zynq
authorMasahiro Yamada <yamada.masahiro@socionext.com>
Mon, 16 Mar 2015 07:43:22 +0000 (16:43 +0900)
committerMichal Simek <michal.simek@xilinx.com>
Wed, 29 Apr 2015 09:19:05 +0000 (11:19 +0200)
Move arch/arm/cpu/armv7/zynq/* -> arch/arm/mach-zynq/*

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
26 files changed:
arch/arm/Kconfig
arch/arm/Makefile
arch/arm/cpu/armv7/Makefile
arch/arm/cpu/armv7/zynq/Kconfig [deleted file]
arch/arm/cpu/armv7/zynq/Makefile [deleted file]
arch/arm/cpu/armv7/zynq/clk.c [deleted file]
arch/arm/cpu/armv7/zynq/cpu.c [deleted file]
arch/arm/cpu/armv7/zynq/ddrc.c [deleted file]
arch/arm/cpu/armv7/zynq/lowlevel_init.S [deleted file]
arch/arm/cpu/armv7/zynq/slcr.c [deleted file]
arch/arm/cpu/armv7/zynq/spl.c [deleted file]
arch/arm/cpu/armv7/zynq/timer.c [deleted file]
arch/arm/cpu/armv7/zynq/u-boot-spl.lds [deleted file]
arch/arm/cpu/armv7/zynq/u-boot.lds [deleted file]
arch/arm/mach-zynq/Kconfig [new file with mode: 0644]
arch/arm/mach-zynq/Makefile [new file with mode: 0644]
arch/arm/mach-zynq/clk.c [new file with mode: 0644]
arch/arm/mach-zynq/cpu.c [new file with mode: 0644]
arch/arm/mach-zynq/ddrc.c [new file with mode: 0644]
arch/arm/mach-zynq/lowlevel_init.S [new file with mode: 0644]
arch/arm/mach-zynq/slcr.c [new file with mode: 0644]
arch/arm/mach-zynq/spl.c [new file with mode: 0644]
arch/arm/mach-zynq/timer.c [new file with mode: 0644]
arch/arm/mach-zynq/u-boot-spl.lds [new file with mode: 0644]
arch/arm/mach-zynq/u-boot.lds [new file with mode: 0644]
include/configs/zynq-common.h

index 5f21b59ba813be88258a8b31877effd01d19cd0d..21cd1c8cdf4ed24890acb93f91da5791401ea4a9 100644 (file)
@@ -832,7 +832,7 @@ source "arch/arm/mach-uniphier/Kconfig"
 
 source "arch/arm/mach-versatile/Kconfig"
 
-source "arch/arm/cpu/armv7/zynq/Kconfig"
+source "arch/arm/mach-zynq/Kconfig"
 
 source "arch/arm/cpu/armv7/Kconfig"
 
index bd4749c55e95374e07a839d029449c39aac40ab1..5705d6402b9e29b79e572f101a38b2c3e07c09fc 100644 (file)
@@ -55,6 +55,7 @@ machine-$(CONFIG_ORION5X)             += orion5x
 machine-$(CONFIG_TEGRA)                        += tegra
 machine-$(CONFIG_ARCH_UNIPHIER)                += uniphier
 machine-$(CONFIG_ARCH_VERSATILE)       += versatile
+machine-$(CONFIG_ZYNQ)                 += zynq
 
 machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
 
index 21fc03b97eef431438f773757eb8e2bbcfc1df3a..3c991e152d311a62c6dbe1087b19fb40a085529f 100644 (file)
@@ -56,4 +56,3 @@ obj-$(if $(filter stv0991,$(SOC)),y) += stv0991/
 obj-$(CONFIG_ARCH_SUNXI) += sunxi/
 obj-$(CONFIG_U8500) += u8500/
 obj-$(CONFIG_VF610) += vf610/
-obj-$(CONFIG_ZYNQ) += zynq/
diff --git a/arch/arm/cpu/armv7/zynq/Kconfig b/arch/arm/cpu/armv7/zynq/Kconfig
deleted file mode 100644 (file)
index 26e570e..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-if ZYNQ
-
-choice
-       prompt "Xilinx Zynq board select"
-
-config TARGET_ZYNQ_ZED
-       bool "Zynq ZedBoard"
-
-config TARGET_ZYNQ_MICROZED
-       bool "Zynq MicroZed"
-
-config TARGET_ZYNQ_PICOZED
-       bool "Zynq PicoZed"
-
-config TARGET_ZYNQ_ZC70X
-       bool "Zynq ZC702/ZC706 Board"
-
-config TARGET_ZYNQ_ZC770
-       bool "Zynq ZC770 Board"
-
-config TARGET_ZYNQ_ZYBO
-       bool "Zynq Zybo Board"
-
-endchoice
-
-config SYS_BOARD
-       default "zynq"
-
-config SYS_VENDOR
-       default "xilinx"
-
-config SYS_SOC
-       default "zynq"
-
-config SYS_CONFIG_NAME
-       default "zynq_zed" if TARGET_ZYNQ_ZED
-       default "zynq_microzed" if TARGET_ZYNQ_MICROZED
-       default "zynq_picozed" if TARGET_ZYNQ_PICOZED
-       default "zynq_zc70x" if TARGET_ZYNQ_ZC70X
-       default "zynq_zc770" if TARGET_ZYNQ_ZC770
-       default "zynq_zybo" if TARGET_ZYNQ_ZYBO
-
-endif
diff --git a/arch/arm/cpu/armv7/zynq/Makefile b/arch/arm/cpu/armv7/zynq/Makefile
deleted file mode 100644 (file)
index bf29b4d..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# (C) Copyright 2000-2003
-# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
-#
-# (C) Copyright 2008
-# Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>
-#
-# SPDX-License-Identifier:     GPL-2.0+
-#
-
-obj-y  := timer.o
-obj-y  += cpu.o
-obj-y  += ddrc.o
-obj-y  += slcr.o
-obj-y  += clk.o
-obj-y  += lowlevel_init.o
-AFLAGS_lowlevel_init.o := -mfpu=neon
-obj-$(CONFIG_SPL_BUILD)        += spl.o
diff --git a/arch/arm/cpu/armv7/zynq/clk.c b/arch/arm/cpu/armv7/zynq/clk.c
deleted file mode 100644 (file)
index d2885dc..0000000
+++ /dev/null
@@ -1,664 +0,0 @@
-/*
- * Copyright (C) 2013 Soren Brinkmann <soren.brinkmann@xilinx.com>
- * Copyright (C) 2013 Xilinx, Inc. All rights reserved.
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-#include <common.h>
-#include <errno.h>
-#include <clk.h>
-#include <asm/io.h>
-#include <asm/arch/hardware.h>
-#include <asm/arch/clk.h>
-
-/* Board oscillator frequency */
-#ifndef CONFIG_ZYNQ_PS_CLK_FREQ
-# define CONFIG_ZYNQ_PS_CLK_FREQ       33333333UL
-#endif
-
-/* Register bitfield defines */
-#define PLLCTRL_FBDIV_MASK     0x7f000
-#define PLLCTRL_FBDIV_SHIFT    12
-#define PLLCTRL_BPFORCE_MASK   (1 << 4)
-#define PLLCTRL_PWRDWN_MASK    2
-#define PLLCTRL_PWRDWN_SHIFT   1
-#define PLLCTRL_RESET_MASK     1
-#define PLLCTRL_RESET_SHIFT    0
-
-#define ZYNQ_CLK_MAXDIV                0x3f
-#define CLK_CTRL_DIV1_SHIFT    20
-#define CLK_CTRL_DIV1_MASK     (ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV1_SHIFT)
-#define CLK_CTRL_DIV0_SHIFT    8
-#define CLK_CTRL_DIV0_MASK     (ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV0_SHIFT)
-#define CLK_CTRL_SRCSEL_SHIFT  4
-#define CLK_CTRL_SRCSEL_MASK   (0x3 << CLK_CTRL_SRCSEL_SHIFT)
-
-#define CLK_CTRL_DIV2X_SHIFT   26
-#define CLK_CTRL_DIV2X_MASK    (ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV2X_SHIFT)
-#define CLK_CTRL_DIV3X_SHIFT   20
-#define CLK_CTRL_DIV3X_MASK    (ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV3X_SHIFT)
-
-#define ZYNQ_CLKMUX_SEL_0      0
-#define ZYNQ_CLKMUX_SEL_1      1
-#define ZYNQ_CLKMUX_SEL_2      2
-#define ZYNQ_CLKMUX_SEL_3      3
-
-DECLARE_GLOBAL_DATA_PTR;
-
-struct clk;
-
-/**
- * struct clk_ops:
- * @set_rate:  Function pointer to set_rate() implementation
- * @get_rate:  Function pointer to get_rate() implementation
- */
-struct clk_ops {
-       int (*set_rate)(struct clk *clk, unsigned long rate);
-       unsigned long (*get_rate)(struct clk *clk);
-};
-
-/**
- * struct clk:
- * @name:      Clock name
- * @frequency: Currenct frequency
- * @parent:    Parent clock
- * @flags:     Clock flags
- * @reg:       Clock control register
- * @ops:       Clock operations
- */
-struct clk {
-       char            *name;
-       unsigned long   frequency;
-       enum zynq_clk   parent;
-       unsigned int    flags;
-       u32             *reg;
-       struct clk_ops  ops;
-};
-#define ZYNQ_CLK_FLAGS_HAS_2_DIVS      1
-
-static struct clk clks[clk_max];
-
-/**
- * __zynq_clk_cpu_get_parent() - Decode clock multiplexer
- * @srcsel:    Mux select value
- * Returns the clock identifier associated with the selected mux input.
- */
-static int __zynq_clk_cpu_get_parent(unsigned int srcsel)
-{
-       unsigned int ret;
-
-       switch (srcsel) {
-       case ZYNQ_CLKMUX_SEL_0:
-       case ZYNQ_CLKMUX_SEL_1:
-               ret = armpll_clk;
-               break;
-       case ZYNQ_CLKMUX_SEL_2:
-               ret = ddrpll_clk;
-               break;
-       case ZYNQ_CLKMUX_SEL_3:
-               ret = iopll_clk;
-               break;
-       default:
-               ret = armpll_clk;
-               break;
-       }
-
-       return ret;
-}
-
-/**
- * ddr2x_get_rate() - Get clock rate of DDR2x clock
- * @clk:       Clock handle
- * Returns the current clock rate of @clk.
- */
-static unsigned long ddr2x_get_rate(struct clk *clk)
-{
-       u32 clk_ctrl = readl(clk->reg);
-       u32 div = (clk_ctrl & CLK_CTRL_DIV2X_MASK) >> CLK_CTRL_DIV2X_SHIFT;
-
-       return DIV_ROUND_CLOSEST(zynq_clk_get_rate(clk->parent), div);
-}
-
-/**
- * ddr3x_get_rate() - Get clock rate of DDR3x clock
- * @clk:       Clock handle
- * Returns the current clock rate of @clk.
- */
-static unsigned long ddr3x_get_rate(struct clk *clk)
-{
-       u32 clk_ctrl = readl(clk->reg);
-       u32 div = (clk_ctrl & CLK_CTRL_DIV3X_MASK) >> CLK_CTRL_DIV3X_SHIFT;
-
-       return DIV_ROUND_CLOSEST(zynq_clk_get_rate(clk->parent), div);
-}
-
-static void init_ddr_clocks(void)
-{
-       u32 div0, div1;
-       unsigned long prate = zynq_clk_get_rate(ddrpll_clk);
-       u32 clk_ctrl = readl(&slcr_base->ddr_clk_ctrl);
-
-       /* DDR2x */
-       clks[ddr2x_clk].reg = &slcr_base->ddr_clk_ctrl;
-       clks[ddr2x_clk].parent = ddrpll_clk;
-       clks[ddr2x_clk].name = "ddr_2x";
-       clks[ddr2x_clk].frequency = ddr2x_get_rate(&clks[ddr2x_clk]);
-       clks[ddr2x_clk].ops.get_rate = ddr2x_get_rate;
-
-       /* DDR3x */
-       clks[ddr3x_clk].reg = &slcr_base->ddr_clk_ctrl;
-       clks[ddr3x_clk].parent = ddrpll_clk;
-       clks[ddr3x_clk].name = "ddr_3x";
-       clks[ddr3x_clk].frequency = ddr3x_get_rate(&clks[ddr3x_clk]);
-       clks[ddr3x_clk].ops.get_rate = ddr3x_get_rate;
-
-       /* DCI */
-       clk_ctrl = readl(&slcr_base->dci_clk_ctrl);
-       div0 = (clk_ctrl & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
-       div1 = (clk_ctrl & CLK_CTRL_DIV1_MASK) >> CLK_CTRL_DIV1_SHIFT;
-       clks[dci_clk].reg = &slcr_base->dci_clk_ctrl;
-       clks[dci_clk].parent = ddrpll_clk;
-       clks[dci_clk].frequency = DIV_ROUND_CLOSEST(
-                       DIV_ROUND_CLOSEST(prate, div0), div1);
-       clks[dci_clk].name = "dci";
-
-       gd->bd->bi_ddr_freq = clks[ddr3x_clk].frequency / 1000000;
-}
-
-static void init_cpu_clocks(void)
-{
-       int clk_621;
-       u32 reg, div, srcsel;
-       enum zynq_clk parent;
-
-       reg = readl(&slcr_base->arm_clk_ctrl);
-       clk_621 = readl(&slcr_base->clk_621_true) & 1;
-       div = (reg & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
-       srcsel = (reg & CLK_CTRL_SRCSEL_MASK) >> CLK_CTRL_SRCSEL_SHIFT;
-       parent = __zynq_clk_cpu_get_parent(srcsel);
-
-       /* cpu clocks */
-       clks[cpu_6or4x_clk].reg = &slcr_base->arm_clk_ctrl;
-       clks[cpu_6or4x_clk].parent = parent;
-       clks[cpu_6or4x_clk].frequency = DIV_ROUND_CLOSEST(
-                       zynq_clk_get_rate(parent), div);
-       clks[cpu_6or4x_clk].name = "cpu_6or4x";
-
-       clks[cpu_3or2x_clk].reg = &slcr_base->arm_clk_ctrl;
-       clks[cpu_3or2x_clk].parent = cpu_6or4x_clk;
-       clks[cpu_3or2x_clk].frequency = zynq_clk_get_rate(cpu_6or4x_clk) / 2;
-       clks[cpu_3or2x_clk].name = "cpu_3or2x";
-
-       clks[cpu_2x_clk].reg = &slcr_base->arm_clk_ctrl;
-       clks[cpu_2x_clk].parent = cpu_6or4x_clk;
-       clks[cpu_2x_clk].frequency = zynq_clk_get_rate(cpu_6or4x_clk) /
-                       (2 + clk_621);
-       clks[cpu_2x_clk].name = "cpu_2x";
-
-       clks[cpu_1x_clk].reg = &slcr_base->arm_clk_ctrl;
-       clks[cpu_1x_clk].parent = cpu_6or4x_clk;
-       clks[cpu_1x_clk].frequency = zynq_clk_get_rate(cpu_6or4x_clk) /
-                       (4 + 2 * clk_621);
-       clks[cpu_1x_clk].name = "cpu_1x";
-}
-
-/**
- * periph_calc_two_divs() - Calculate clock dividers
- * @cur_rate:  Current clock rate
- * @tgt_rate:  Target clock rate
- * @prate:     Parent clock rate
- * @div0:      First divider (output)
- * @div1:      Second divider (output)
- * Returns the actual clock rate possible.
- *
- * Calculates clock dividers for clocks with two 6-bit dividers.
- */
-static unsigned long periph_calc_two_divs(unsigned long cur_rate,
-               unsigned long tgt_rate, unsigned long prate, u32 *div0,
-               u32 *div1)
-{
-       long err, best_err = (long)(~0UL >> 1);
-       unsigned long rate, best_rate = 0;
-       u32 d0, d1;
-
-       for (d0 = 1; d0 <= ZYNQ_CLK_MAXDIV; d0++) {
-               for (d1 = 1; d1 <= ZYNQ_CLK_MAXDIV >> 1; d1++) {
-                       rate = DIV_ROUND_CLOSEST(DIV_ROUND_CLOSEST(prate, d0),
-                                       d1);
-                       err = abs(rate - tgt_rate);
-
-                       if (err < best_err) {
-                               *div0 = d0;
-                               *div1 = d1;
-                               best_err = err;
-                               best_rate = rate;
-                       }
-               }
-       }
-
-       return best_rate;
-}
-
-/**
- * zynq_clk_periph_set_rate() - Set clock rate
- * @clk:       Handle of the peripheral clock
- * @rate:      New clock rate
- * Sets the clock frequency of @clk to @rate. Returns zero on success.
- */
-static int zynq_clk_periph_set_rate(struct clk *clk,
-               unsigned long rate)
-{
-       u32 ctrl, div0 = 0, div1 = 0;
-       unsigned long prate, new_rate, cur_rate = clk->frequency;
-
-       ctrl = readl(clk->reg);
-       prate = zynq_clk_get_rate(clk->parent);
-       ctrl &= ~CLK_CTRL_DIV0_MASK;
-
-       if (clk->flags & ZYNQ_CLK_FLAGS_HAS_2_DIVS) {
-               ctrl &= ~CLK_CTRL_DIV1_MASK;
-               new_rate = periph_calc_two_divs(cur_rate, rate, prate, &div0,
-                               &div1);
-               ctrl |= div1 << CLK_CTRL_DIV1_SHIFT;
-       } else {
-               div0 = DIV_ROUND_CLOSEST(prate, rate);
-               div0 &= ZYNQ_CLK_MAXDIV;
-               new_rate = DIV_ROUND_CLOSEST(rate, div0);
-       }
-
-       /* write new divs to hardware */
-       ctrl |= div0 << CLK_CTRL_DIV0_SHIFT;
-       writel(ctrl, clk->reg);
-
-       /* update frequency in clk framework */
-       clk->frequency = new_rate;
-
-       return 0;
-}
-
-/**
- * zynq_clk_periph_get_rate() - Get clock rate
- * @clk:       Handle of the peripheral clock
- * Returns the current clock rate of @clk.
- */
-static unsigned long zynq_clk_periph_get_rate(struct clk *clk)
-{
-       u32 clk_ctrl = readl(clk->reg);
-       u32 div0 = (clk_ctrl & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
-       u32 div1 = 1;
-
-       if (clk->flags & ZYNQ_CLK_FLAGS_HAS_2_DIVS)
-               div1 = (clk_ctrl & CLK_CTRL_DIV1_MASK) >> CLK_CTRL_DIV1_SHIFT;
-
-       /* a register value of zero == division by 1 */
-       if (!div0)
-               div0 = 1;
-       if (!div1)
-               div1 = 1;
-
-       return
-               DIV_ROUND_CLOSEST(
-                       DIV_ROUND_CLOSEST(zynq_clk_get_rate(clk->parent), div0),
-                       div1);
-}
-
-/**
- * __zynq_clk_periph_get_parent() - Decode clock multiplexer
- * @srcsel:    Mux select value
- * Returns the clock identifier associated with the selected mux input.
- */
-static enum zynq_clk __zynq_clk_periph_get_parent(u32 srcsel)
-{
-       switch (srcsel) {
-       case ZYNQ_CLKMUX_SEL_0:
-       case ZYNQ_CLKMUX_SEL_1:
-               return iopll_clk;
-       case ZYNQ_CLKMUX_SEL_2:
-               return armpll_clk;
-       case ZYNQ_CLKMUX_SEL_3:
-               return ddrpll_clk;
-       default:
-               return 0;
-       }
-}
-
-/**
- * zynq_clk_periph_get_parent() - Decode clock multiplexer
- * @clk:       Clock handle
- * Returns the clock identifier associated with the selected mux input.
- */
-static enum zynq_clk zynq_clk_periph_get_parent(struct clk *clk)
-{
-       u32 clk_ctrl = readl(clk->reg);
-       u32 srcsel = (clk_ctrl & CLK_CTRL_SRCSEL_MASK) >> CLK_CTRL_SRCSEL_SHIFT;
-
-       return __zynq_clk_periph_get_parent(srcsel);
-}
-
-/**
- * zynq_clk_register_periph_clk() - Set up a peripheral clock with the framework
- * @clk:       Pointer to struct clk for the clock
- * @ctrl:      Clock control register
- * @name:      PLL name
- * @two_divs:  Indicates whether the clock features one or two dividers
- */
-static int zynq_clk_register_periph_clk(struct clk *clk, u32 *ctrl, char *name,
-               bool two_divs)
-{
-       clk->name = name;
-       clk->reg = ctrl;
-       if (two_divs)
-               clk->flags = ZYNQ_CLK_FLAGS_HAS_2_DIVS;
-       clk->parent = zynq_clk_periph_get_parent(clk);
-       clk->frequency = zynq_clk_periph_get_rate(clk);
-       clk->ops.get_rate = zynq_clk_periph_get_rate;
-       clk->ops.set_rate = zynq_clk_periph_set_rate;
-
-       return 0;
-}
-
-static void init_periph_clocks(void)
-{
-       zynq_clk_register_periph_clk(&clks[gem0_clk], &slcr_base->gem0_clk_ctrl,
-                                    "gem0", 1);
-       zynq_clk_register_periph_clk(&clks[gem1_clk], &slcr_base->gem1_clk_ctrl,
-                                    "gem1", 1);
-
-       zynq_clk_register_periph_clk(&clks[smc_clk], &slcr_base->smc_clk_ctrl,
-                                    "smc", 0);
-
-       zynq_clk_register_periph_clk(&clks[lqspi_clk],
-                                    &slcr_base->lqspi_clk_ctrl, "lqspi", 0);
-
-       zynq_clk_register_periph_clk(&clks[sdio0_clk],
-                                    &slcr_base->sdio_clk_ctrl, "sdio0", 0);
-       zynq_clk_register_periph_clk(&clks[sdio1_clk],
-                                    &slcr_base->sdio_clk_ctrl, "sdio1", 0);
-
-       zynq_clk_register_periph_clk(&clks[spi0_clk], &slcr_base->spi_clk_ctrl,
-                                    "spi0", 0);
-       zynq_clk_register_periph_clk(&clks[spi1_clk], &slcr_base->spi_clk_ctrl,
-                                    "spi1", 0);
-
-       zynq_clk_register_periph_clk(&clks[uart0_clk],
-                                    &slcr_base->uart_clk_ctrl, "uart0", 0);
-       zynq_clk_register_periph_clk(&clks[uart1_clk],
-                                    &slcr_base->uart_clk_ctrl, "uart1", 0);
-
-       zynq_clk_register_periph_clk(&clks[dbg_trc_clk],
-                                    &slcr_base->dbg_clk_ctrl, "dbg_trc", 0);
-       zynq_clk_register_periph_clk(&clks[dbg_apb_clk],
-                                    &slcr_base->dbg_clk_ctrl, "dbg_apb", 0);
-
-       zynq_clk_register_periph_clk(&clks[pcap_clk],
-                                    &slcr_base->pcap_clk_ctrl, "pcap", 0);
-
-       zynq_clk_register_periph_clk(&clks[fclk0_clk],
-                                    &slcr_base->fpga0_clk_ctrl, "fclk0", 1);
-       zynq_clk_register_periph_clk(&clks[fclk1_clk],
-                                    &slcr_base->fpga1_clk_ctrl, "fclk1", 1);
-       zynq_clk_register_periph_clk(&clks[fclk2_clk],
-                                    &slcr_base->fpga2_clk_ctrl, "fclk2", 1);
-       zynq_clk_register_periph_clk(&clks[fclk3_clk],
-                                    &slcr_base->fpga3_clk_ctrl, "fclk3", 1);
-}
-
-/**
- * zynq_clk_register_aper_clk() - Set up a APER clock with the framework
- * @clk:       Pointer to struct clk for the clock
- * @ctrl:      Clock control register
- * @name:      PLL name
- */
-static void zynq_clk_register_aper_clk(struct clk *clk, u32 *ctrl, char *name)
-{
-       clk->name = name;
-       clk->reg = ctrl;
-       clk->parent = cpu_1x_clk;
-       clk->frequency = zynq_clk_get_rate(clk->parent);
-}
-
-static void init_aper_clocks(void)
-{
-       zynq_clk_register_aper_clk(&clks[usb0_aper_clk],
-                                  &slcr_base->aper_clk_ctrl, "usb0_aper");
-       zynq_clk_register_aper_clk(&clks[usb1_aper_clk],
-                                  &slcr_base->aper_clk_ctrl, "usb1_aper");
-
-       zynq_clk_register_aper_clk(&clks[gem0_aper_clk],
-                                  &slcr_base->aper_clk_ctrl, "gem0_aper");
-       zynq_clk_register_aper_clk(&clks[gem1_aper_clk],
-                                  &slcr_base->aper_clk_ctrl, "gem1_aper");
-
-       zynq_clk_register_aper_clk(&clks[sdio0_aper_clk],
-                                  &slcr_base->aper_clk_ctrl, "sdio0_aper");
-       zynq_clk_register_aper_clk(&clks[sdio1_aper_clk],
-                                  &slcr_base->aper_clk_ctrl, "sdio1_aper");
-
-       zynq_clk_register_aper_clk(&clks[spi0_aper_clk],
-                                  &slcr_base->aper_clk_ctrl, "spi0_aper");
-       zynq_clk_register_aper_clk(&clks[spi1_aper_clk],
-                                  &slcr_base->aper_clk_ctrl, "spi1_aper");
-
-       zynq_clk_register_aper_clk(&clks[can0_aper_clk],
-                                  &slcr_base->aper_clk_ctrl, "can0_aper");
-       zynq_clk_register_aper_clk(&clks[can1_aper_clk],
-                                  &slcr_base->aper_clk_ctrl, "can1_aper");
-
-       zynq_clk_register_aper_clk(&clks[i2c0_aper_clk],
-                                  &slcr_base->aper_clk_ctrl, "i2c0_aper");
-       zynq_clk_register_aper_clk(&clks[i2c1_aper_clk],
-                                  &slcr_base->aper_clk_ctrl, "i2c1_aper");
-
-       zynq_clk_register_aper_clk(&clks[uart0_aper_clk],
-                                  &slcr_base->aper_clk_ctrl, "uart0_aper");
-       zynq_clk_register_aper_clk(&clks[uart1_aper_clk],
-                                  &slcr_base->aper_clk_ctrl, "uart1_aper");
-
-       zynq_clk_register_aper_clk(&clks[gpio_aper_clk],
-                                  &slcr_base->aper_clk_ctrl, "gpio_aper");
-
-       zynq_clk_register_aper_clk(&clks[lqspi_aper_clk],
-                                  &slcr_base->aper_clk_ctrl, "lqspi_aper");
-
-       zynq_clk_register_aper_clk(&clks[smc_aper_clk],
-                                  &slcr_base->aper_clk_ctrl, "smc_aper");
-}
-
-/**
- * __zynq_clk_pll_get_rate() - Get PLL rate
- * @addr:      Address of the PLL's control register
- * Returns the current PLL output rate.
- */
-static unsigned long __zynq_clk_pll_get_rate(u32 *addr)
-{
-       u32 reg, mul, bypass;
-
-       reg = readl(addr);
-       bypass = reg & PLLCTRL_BPFORCE_MASK;
-       if (bypass)
-               mul = 1;
-       else
-               mul = (reg & PLLCTRL_FBDIV_MASK) >> PLLCTRL_FBDIV_SHIFT;
-
-       return CONFIG_ZYNQ_PS_CLK_FREQ * mul;
-}
-
-/**
- * zynq_clk_pll_get_rate() - Get PLL rate
- * @pll:       Handle of the PLL
- * Returns the current clock rate of @pll.
- */
-static unsigned long zynq_clk_pll_get_rate(struct clk *pll)
-{
-       return __zynq_clk_pll_get_rate(pll->reg);
-}
-
-/**
- * zynq_clk_register_pll() - Set up a PLL with the framework
- * @clk:       Pointer to struct clk for the PLL
- * @ctrl:      PLL control register
- * @name:      PLL name
- * @prate:     PLL input clock rate
- */
-static void zynq_clk_register_pll(struct clk *clk, u32 *ctrl, char *name,
-               unsigned long prate)
-{
-       clk->name = name;
-       clk->reg = ctrl;
-       clk->frequency = zynq_clk_pll_get_rate(clk);
-       clk->ops.get_rate = zynq_clk_pll_get_rate;
-}
-
-/**
- * clkid_2_register() - Get clock control register
- * @id:        Clock identifier of one of the PLLs
- * Returns the address of the requested PLL's control register.
- */
-static u32 *clkid_2_register(enum zynq_clk id)
-{
-       switch (id) {
-       case armpll_clk:
-               return &slcr_base->arm_pll_ctrl;
-       case ddrpll_clk:
-               return &slcr_base->ddr_pll_ctrl;
-       case iopll_clk:
-               return &slcr_base->io_pll_ctrl;
-       default:
-               return &slcr_base->io_pll_ctrl;
-       }
-}
-
-/* API */
-/**
- * zynq_clk_early_init() - Early init for the clock framework
- *
- * This function is called from before relocation and sets up the CPU clock
- * frequency in the global data struct.
- */
-void zynq_clk_early_init(void)
-{
-       u32 reg = readl(&slcr_base->arm_clk_ctrl);
-       u32 div = (reg & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
-       u32 srcsel = (reg & CLK_CTRL_SRCSEL_MASK) >> CLK_CTRL_SRCSEL_SHIFT;
-       enum zynq_clk parent = __zynq_clk_cpu_get_parent(srcsel);
-       u32 *pllreg = clkid_2_register(parent);
-       unsigned long prate = __zynq_clk_pll_get_rate(pllreg);
-
-       if (!div)
-               div = 1;
-
-       gd->cpu_clk = DIV_ROUND_CLOSEST(prate, div);
-}
-
-/**
- * get_uart_clk() - Get UART input frequency
- * @dev_index: UART ID
- * Returns UART input clock frequency in Hz.
- *
- * Compared to zynq_clk_get_rate() this function is designed to work before
- * relocation and can be called when the serial UART is set up.
- */
-unsigned long get_uart_clk(int dev_index)
-{
-       u32 reg = readl(&slcr_base->uart_clk_ctrl);
-       u32 div = (reg & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
-       u32 srcsel = (reg & CLK_CTRL_SRCSEL_MASK) >> CLK_CTRL_SRCSEL_SHIFT;
-       enum zynq_clk parent = __zynq_clk_periph_get_parent(srcsel);
-       u32 *pllreg = clkid_2_register(parent);
-       unsigned long prate = __zynq_clk_pll_get_rate(pllreg);
-
-       if (!div)
-               div = 1;
-
-       return DIV_ROUND_CLOSEST(prate, div);
-}
-
-/**
- * set_cpu_clk_info() - Initialize clock framework
- * Always returns zero.
- *
- * This function is called from common code after relocation and sets up the
- * clock framework. The framework must not be used before this function had been
- * called.
- */
-int set_cpu_clk_info(void)
-{
-       zynq_clk_register_pll(&clks[armpll_clk], &slcr_base->arm_pll_ctrl,
-                             "armpll", CONFIG_ZYNQ_PS_CLK_FREQ);
-       zynq_clk_register_pll(&clks[ddrpll_clk], &slcr_base->ddr_pll_ctrl,
-                             "ddrpll", CONFIG_ZYNQ_PS_CLK_FREQ);
-       zynq_clk_register_pll(&clks[iopll_clk], &slcr_base->io_pll_ctrl,
-                             "iopll", CONFIG_ZYNQ_PS_CLK_FREQ);
-
-       init_ddr_clocks();
-       init_cpu_clocks();
-       init_periph_clocks();
-       init_aper_clocks();
-
-       gd->bd->bi_arm_freq = gd->cpu_clk / 1000000;
-       gd->bd->bi_dsp_freq = 0;
-
-       return 0;
-}
-
-/**
- * zynq_clk_get_rate() - Get clock rate
- * @clk:       Clock identifier
- * Returns the current clock rate of @clk on success or zero for an invalid
- * clock id.
- */
-unsigned long zynq_clk_get_rate(enum zynq_clk clk)
-{
-       if (clk < 0 || clk >= clk_max)
-               return 0;
-
-       return clks[clk].frequency;
-}
-
-/**
- * zynq_clk_set_rate() - Set clock rate
- * @clk:       Clock identifier
- * @rate:      Requested clock rate
- * Passes on the return value from the clock's set_rate() function or negative
- * errno.
- */
-int zynq_clk_set_rate(enum zynq_clk clk, unsigned long rate)
-{
-       if (clk < 0 || clk >= clk_max)
-               return -ENODEV;
-
-       if (clks[clk].ops.set_rate)
-               return clks[clk].ops.set_rate(&clks[clk], rate);
-
-       return -ENXIO;
-}
-
-/**
- * zynq_clk_get_name() - Get clock name
- * @clk:       Clock identifier
- * Returns the name of @clk.
- */
-const char *zynq_clk_get_name(enum zynq_clk clk)
-{
-       return clks[clk].name;
-}
-
-/**
- * soc_clk_dump() - Print clock frequencies
- * Returns zero on success
- *
- * Implementation for the clk dump command.
- */
-int soc_clk_dump(void)
-{
-       int i;
-
-       printf("clk\t\tfrequency\n");
-       for (i = 0; i < clk_max; i++) {
-               const char *name = zynq_clk_get_name(i);
-               if (name)
-                       printf("%10s%20lu\n", name, zynq_clk_get_rate(i));
-       }
-
-       return 0;
-}
diff --git a/arch/arm/cpu/armv7/zynq/cpu.c b/arch/arm/cpu/armv7/zynq/cpu.c
deleted file mode 100644 (file)
index 914b1fe..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2012 Michal Simek <monstr@monstr.eu>
- * Copyright (C) 2012 Xilinx, Inc. All rights reserved.
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-#include <common.h>
-#include <asm/io.h>
-#include <asm/arch/clk.h>
-#include <asm/arch/sys_proto.h>
-#include <asm/arch/hardware.h>
-
-#define ZYNQ_SILICON_VER_MASK  0xF0000000
-#define ZYNQ_SILICON_VER_SHIFT 28
-
-int arch_cpu_init(void)
-{
-       zynq_slcr_unlock();
-#ifndef CONFIG_SPL_BUILD
-       /* Device config APB, unlock the PCAP */
-       writel(0x757BDF0D, &devcfg_base->unlock);
-       writel(0xFFFFFFFF, &devcfg_base->rom_shadow);
-
-#if (CONFIG_SYS_SDRAM_BASE == 0)
-       /* remap DDR to zero, FILTERSTART */
-       writel(0, &scu_base->filter_start);
-
-       /* 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);
-       /* Set urgent bits with register */
-       writel(0x0, &slcr_base->ddr_urgent_sel);
-       /* Urgent write, ports S2/S3 */
-       writel(0xC, &slcr_base->ddr_urgent);
-#endif
-#endif
-       zynq_clk_early_init();
-       zynq_slcr_lock();
-
-       return 0;
-}
-
-unsigned int zynq_get_silicon_version(void)
-{
-       unsigned int ver;
-
-       ver = (readl(&devcfg_base->mctrl) &
-              ZYNQ_SILICON_VER_MASK) >> ZYNQ_SILICON_VER_SHIFT;
-
-       return ver;
-}
-
-void reset_cpu(ulong addr)
-{
-       zynq_slcr_cpu_reset();
-       while (1)
-               ;
-}
-
-#ifndef CONFIG_SYS_DCACHE_OFF
-void enable_caches(void)
-{
-       /* Enable D-cache. I-cache is already enabled in start.S */
-       dcache_enable();
-}
-#endif
diff --git a/arch/arm/cpu/armv7/zynq/ddrc.c b/arch/arm/cpu/armv7/zynq/ddrc.c
deleted file mode 100644 (file)
index 5b20acc..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2012 - 2013 Michal Simek <monstr@monstr.eu>
- * Copyright (C) 2012 - 2013 Xilinx, Inc. All rights reserved.
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-#include <common.h>
-#include <asm/io.h>
-#include <asm/arch/sys_proto.h>
-#include <asm/arch/hardware.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-/* Control regsiter bitfield definitions */
-#define ZYNQ_DDRC_CTRLREG_BUSWIDTH_MASK                0xC
-#define ZYNQ_DDRC_CTRLREG_BUSWIDTH_SHIFT       2
-#define ZYNQ_DDRC_CTRLREG_BUSWIDTH_16BIT       1
-
-/* ECC scrub regsiter definitions */
-#define ZYNQ_DDRC_ECC_SCRUBREG_ECC_MODE_MASK   0x7
-#define ZYNQ_DDRC_ECC_SCRUBREG_ECCMODE_SECDED  0x4
-
-void zynq_ddrc_init(void)
-{
-       u32 width, ecctype;
-
-       width = readl(&ddrc_base->ddrc_ctrl);
-       width = (width & ZYNQ_DDRC_CTRLREG_BUSWIDTH_MASK) >>
-                                       ZYNQ_DDRC_CTRLREG_BUSWIDTH_SHIFT;
-       ecctype = (readl(&ddrc_base->ecc_scrub) &
-               ZYNQ_DDRC_ECC_SCRUBREG_ECC_MODE_MASK);
-
-       /* ECC is enabled when memory is in 16bit mode and it is enabled */
-       if ((ecctype == ZYNQ_DDRC_ECC_SCRUBREG_ECCMODE_SECDED) &&
-           (width == ZYNQ_DDRC_CTRLREG_BUSWIDTH_16BIT)) {
-               puts("ECC enabled ");
-               /*
-                * Clear the first 1MB because it is not initialized from
-                * first stage bootloader. To get ECC to work all memory has
-                * been initialized by writing any value.
-                */
-               /* cppcheck-suppress nullPointer */
-               memset((void *)0, 0, 1 * 1024 * 1024);
-
-               gd->ram_size /= 2;
-       } else {
-               puts("ECC disabled ");
-       }
-}
diff --git a/arch/arm/cpu/armv7/zynq/lowlevel_init.S b/arch/arm/cpu/armv7/zynq/lowlevel_init.S
deleted file mode 100644 (file)
index 6d714b7..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2013 Xilinx, Inc. All rights reserved.
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-#include <asm-offsets.h>
-#include <config.h>
-#include <linux/linkage.h>
-
-ENTRY(lowlevel_init)
-
-       /* Enable the the VFP */
-       mrc     p15, 0, r1, c1, c0, 2
-       orr     r1, r1, #(0x3 << 20)
-       orr     r1, r1, #(0x3 << 20)
-       mcr     p15, 0, r1, c1, c0, 2
-       isb
-       fmrx    r1, FPEXC
-       orr     r1,r1, #(1<<30)
-       fmxr    FPEXC, r1
-
-       /* Move back to caller */
-       mov     pc, lr
-
-ENDPROC(lowlevel_init)
diff --git a/arch/arm/cpu/armv7/zynq/slcr.c b/arch/arm/cpu/armv7/zynq/slcr.c
deleted file mode 100644 (file)
index 05f4099..0000000
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright (c) 2013 Xilinx Inc.
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-#include <common.h>
-#include <asm/io.h>
-#include <malloc.h>
-#include <asm/arch/hardware.h>
-#include <asm/arch/sys_proto.h>
-#include <asm/arch/clk.h>
-
-#define SLCR_LOCK_MAGIC                0x767B
-#define SLCR_UNLOCK_MAGIC      0xDF0D
-
-#define SLCR_USB_L1_SEL                        0x04
-
-#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 usb0_pins[] = {
-       28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39
-};
-
-static const int usb1_pins[] = {
-       40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
-};
-
-static const struct zynq_slcr_mio_get_status mio_periphs[] = {
-       {
-               "usb0",
-               usb0_pins,
-               ARRAY_SIZE(usb0_pins),
-               SLCR_USB_L1_SEL,
-               SLCR_USB_L1_SEL,
-       },
-       {
-               "usb1",
-               usb1_pins,
-               ARRAY_SIZE(usb1_pins),
-               SLCR_USB_L1_SEL,
-               SLCR_USB_L1_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);
-               slcr_lock = 1;
-       }
-}
-
-void zynq_slcr_unlock(void)
-{
-       if (slcr_lock) {
-               writel(SLCR_UNLOCK_MAGIC, &slcr_base->slcr_unlock);
-               slcr_lock = 0;
-       }
-}
-
-/* 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, unsigned long clk_rate)
-{
-       int ret;
-
-       zynq_slcr_unlock();
-
-       if (gem_id > 1) {
-               printf("Non existing GEM id %d\n", gem_id);
-               goto out;
-       }
-
-       ret = zynq_clk_set_rate(gem0_clk + gem_id, clk_rate);
-       if (ret)
-               goto out;
-
-       if (gem_id) {
-               /* Configure GEM_RCLK_CTRL */
-               writel(1, &slcr_base->gem1_rclk_ctrl);
-       } else {
-               /* Configure GEM_RCLK_CTRL */
-               writel(1, &slcr_base->gem0_rclk_ctrl);
-       }
-       udelay(100000);
-out:
-       zynq_slcr_lock();
-}
-
-void zynq_slcr_devcfg_disable(void)
-{
-       u32 reg_val;
-
-       zynq_slcr_unlock();
-
-       /* Disable AXI interface by asserting FPGA resets */
-       writel(0xF, &slcr_base->fpga_rst_ctrl);
-
-       /* Disable Level shifters before setting PS-PL */
-       reg_val = readl(&slcr_base->lvl_shftr_en);
-       reg_val &= ~0xF;
-       writel(reg_val, &slcr_base->lvl_shftr_en);
-
-       /* 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);
-
-       /* Enable AXI interface by de-asserting FPGA resets */
-       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/cpu/armv7/zynq/spl.c b/arch/arm/cpu/armv7/zynq/spl.c
deleted file mode 100644 (file)
index 13025f0..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * (C) Copyright 2014 Xilinx, Inc. Michal Simek
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-#include <common.h>
-#include <spl.h>
-
-#include <asm/io.h>
-#include <asm/arch/hardware.h>
-#include <asm/spl.h>
-#include <asm/arch/sys_proto.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-void board_init_f(ulong dummy)
-{
-       ps7_init();
-
-       /* Clear the BSS. */
-       memset(__bss_start, 0, __bss_end - __bss_start);
-
-       preloader_console_init();
-       arch_cpu_init();
-       board_init_r(NULL, 0);
-}
-
-#ifdef CONFIG_SPL_BOARD_INIT
-void spl_board_init(void)
-{
-       board_init();
-}
-#endif
-
-u32 spl_boot_device(void)
-{
-       u32 mode;
-
-       switch ((zynq_slcr_get_boot_mode()) & ZYNQ_BM_MASK) {
-#ifdef CONFIG_SPL_SPI_SUPPORT
-       case ZYNQ_BM_QSPI:
-               puts("qspi boot\n");
-               mode = BOOT_DEVICE_SPI;
-               break;
-#endif
-       case ZYNQ_BM_NAND:
-               mode = BOOT_DEVICE_NAND;
-               break;
-       case ZYNQ_BM_NOR:
-               mode = BOOT_DEVICE_NOR;
-               break;
-#ifdef CONFIG_SPL_MMC_SUPPORT
-       case ZYNQ_BM_SD:
-               puts("mmc boot\n");
-               mode = BOOT_DEVICE_MMC1;
-               break;
-#endif
-       case ZYNQ_BM_JTAG:
-               mode = BOOT_DEVICE_RAM;
-               break;
-       default:
-               puts("Unsupported boot mode selected\n");
-               hang();
-       }
-
-       return mode;
-}
-
-#ifdef CONFIG_SPL_MMC_SUPPORT
-u32 spl_boot_mode(void)
-{
-       return MMCSD_MODE_FS;
-}
-#endif
-
-#ifdef CONFIG_SPL_OS_BOOT
-int spl_start_uboot(void)
-{
-       /* boot linux */
-       return 0;
-}
-#endif
-
-__weak void ps7_init(void)
-{
-       /*
-        * This function is overridden by the one in
-        * board/xilinx/zynq/ps7_init_gpl.c, if it exists.
-        */
-}
diff --git a/arch/arm/cpu/armv7/zynq/timer.c b/arch/arm/cpu/armv7/zynq/timer.c
deleted file mode 100644 (file)
index 5ed9642..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Copyright (C) 2012 Michal Simek <monstr@monstr.eu>
- * Copyright (C) 2011-2012 Xilinx, Inc. All rights reserved.
- *
- * (C) Copyright 2008
- * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>
- *
- * (C) Copyright 2004
- * Philippe Robin, ARM Ltd. <philippe.robin@arm.com>
- *
- * (C) Copyright 2002-2004
- * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
- *
- * (C) Copyright 2003
- * Texas Instruments <www.ti.com>
- *
- * (C) Copyright 2002
- * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- * Marius Groeger <mgroeger@sysgo.de>
- *
- * (C) Copyright 2002
- * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- * Alex Zuepke <azu@sysgo.de>
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-#include <common.h>
-#include <div64.h>
-#include <asm/io.h>
-#include <asm/arch/hardware.h>
-#include <asm/arch/clk.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-struct scu_timer {
-       u32 load; /* Timer Load Register */
-       u32 counter; /* Timer Counter Register */
-       u32 control; /* Timer Control Register */
-};
-
-static struct scu_timer *timer_base =
-                             (struct scu_timer *)ZYNQ_SCUTIMER_BASEADDR;
-
-#define SCUTIMER_CONTROL_PRESCALER_MASK        0x0000FF00 /* Prescaler */
-#define SCUTIMER_CONTROL_PRESCALER_SHIFT       8
-#define SCUTIMER_CONTROL_AUTO_RELOAD_MASK      0x00000002 /* Auto-reload */
-#define SCUTIMER_CONTROL_ENABLE_MASK           0x00000001 /* Timer enable */
-
-#define TIMER_LOAD_VAL 0xFFFFFFFF
-#define TIMER_PRESCALE 255
-
-int timer_init(void)
-{
-       const u32 emask = SCUTIMER_CONTROL_AUTO_RELOAD_MASK |
-                       (TIMER_PRESCALE << SCUTIMER_CONTROL_PRESCALER_SHIFT) |
-                       SCUTIMER_CONTROL_ENABLE_MASK;
-
-       gd->arch.timer_rate_hz = (gd->cpu_clk / 2) / (TIMER_PRESCALE + 1);
-
-       /* Load the timer counter register */
-       writel(0xFFFFFFFF, &timer_base->load);
-
-       /*
-        * Start the A9Timer device
-        * Enable Auto reload mode, Clear prescaler control bits
-        * Set prescaler value, Enable the decrementer
-        */
-       clrsetbits_le32(&timer_base->control, SCUTIMER_CONTROL_PRESCALER_MASK,
-                                                               emask);
-
-       /* Reset time */
-       gd->arch.lastinc = readl(&timer_base->counter) /
-                               (gd->arch.timer_rate_hz / CONFIG_SYS_HZ);
-       gd->arch.tbl = 0;
-
-       return 0;
-}
-
-/*
- * This function is derived from PowerPC code (read timebase as long long).
- * On ARM it just returns the timer value.
- */
-ulong get_timer_masked(void)
-{
-       ulong now;
-
-       now = readl(&timer_base->counter) /
-                       (gd->arch.timer_rate_hz / CONFIG_SYS_HZ);
-
-       if (gd->arch.lastinc >= now) {
-               /* Normal mode */
-               gd->arch.tbl += gd->arch.lastinc - now;
-       } else {
-               /* We have an overflow ... */
-               gd->arch.tbl += gd->arch.lastinc + (TIMER_LOAD_VAL /
-                               (gd->arch.timer_rate_hz / CONFIG_SYS_HZ)) -
-                               now + 1;
-       }
-       gd->arch.lastinc = now;
-
-       return gd->arch.tbl;
-}
-
-void __udelay(unsigned long usec)
-{
-       u32 countticks;
-       u32 timeend;
-       u32 timediff;
-       u32 timenow;
-
-       if (usec == 0)
-               return;
-
-       countticks = lldiv(((unsigned long long)gd->arch.timer_rate_hz * usec),
-                          1000000);
-
-       /* decrementing timer */
-       timeend = readl(&timer_base->counter) - countticks;
-
-#if TIMER_LOAD_VAL != 0xFFFFFFFF
-       /* do not manage multiple overflow */
-       if (countticks >= TIMER_LOAD_VAL)
-               countticks = TIMER_LOAD_VAL - 1;
-#endif
-
-       do {
-               timenow = readl(&timer_base->counter);
-
-               if (timenow >= timeend) {
-                       /* normal case */
-                       timediff = timenow - timeend;
-               } else {
-                       if ((TIMER_LOAD_VAL - timeend + timenow) <=
-                                                               countticks) {
-                               /* overflow */
-                               timediff = TIMER_LOAD_VAL - timeend + timenow;
-                       } else {
-                               /* missed the exact match */
-                               break;
-                       }
-               }
-       } while (timediff > 0);
-}
-
-/* Timer without interrupts */
-ulong get_timer(ulong base)
-{
-       return get_timer_masked() - base;
-}
-
-/*
- * This function is derived from PowerPC code (read timebase as long long).
- * On ARM it just returns the timer value.
- */
-unsigned long long get_ticks(void)
-{
-       return get_timer(0);
-}
-
-/*
- * This function is derived from PowerPC code (timebase clock frequency).
- * On ARM it returns the number of timer ticks per second.
- */
-ulong get_tbclk(void)
-{
-       return CONFIG_SYS_HZ;
-}
diff --git a/arch/arm/cpu/armv7/zynq/u-boot-spl.lds b/arch/arm/cpu/armv7/zynq/u-boot-spl.lds
deleted file mode 100644 (file)
index 0f2f756..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2014 Xilinx, Inc. Michal Simek
- * Copyright (c) 2004-2008 Texas Instruments
- *
- * (C) Copyright 2002
- * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-MEMORY { .sram : ORIGIN = CONFIG_SPL_TEXT_BASE,\
-               LENGTH = CONFIG_SPL_MAX_SIZE }
-MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, \
-               LENGTH = CONFIG_SPL_BSS_MAX_SIZE }
-
-OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
-OUTPUT_ARCH(arm)
-ENTRY(_start)
-SECTIONS
-{
-       . = ALIGN(4);
-       .text :
-       {
-               __image_copy_start = .;
-               *(.vectors)
-               CPUDIR/start.o (.text*)
-               *(.text*)
-       } > .sram
-
-       . = ALIGN(4);
-       .rodata : {
-               *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
-       } > .sram
-
-       . = ALIGN(4);
-       .data : {
-               *(.data*)
-       } > .sram
-
-       . = ALIGN(4);
-
-       . = .;
-
-       __image_copy_end = .;
-
-       _end = .;
-
-       /* Move BSS section to RAM because of FAT */
-       .bss (NOLOAD) : {
-               __bss_start = .;
-               *(.bss*)
-                . = ALIGN(4);
-               __bss_end = .;
-       } > .sdram
-
-       /DISCARD/ : { *(.dynsym) }
-       /DISCARD/ : { *(.dynstr*) }
-       /DISCARD/ : { *(.dynamic*) }
-       /DISCARD/ : { *(.plt*) }
-       /DISCARD/ : { *(.interp*) }
-       /DISCARD/ : { *(.gnu*) }
-}
diff --git a/arch/arm/cpu/armv7/zynq/u-boot.lds b/arch/arm/cpu/armv7/zynq/u-boot.lds
deleted file mode 100644 (file)
index 4dc9bb0..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (c) 2004-2008 Texas Instruments
- *
- * (C) Copyright 2002
- * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
-OUTPUT_ARCH(arm)
-ENTRY(_start)
-SECTIONS
-{
-       . = 0x00000000;
-
-       . = ALIGN(4);
-       .text :
-       {
-               *(.__image_copy_start)
-               *(.vectors)
-               CPUDIR/start.o (.text*)
-               *(.text*)
-       }
-
-       . = ALIGN(4);
-       .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
-
-       . = ALIGN(4);
-       .data : {
-               *(.data*)
-       }
-
-       . = ALIGN(4);
-
-       . = .;
-
-       . = ALIGN(4);
-       .u_boot_list : {
-               KEEP(*(SORT(.u_boot_list*)));
-       }
-
-       . = ALIGN(4);
-
-       .image_copy_end :
-       {
-               *(.__image_copy_end)
-       }
-
-       .rel_dyn_start :
-       {
-               *(.__rel_dyn_start)
-       }
-
-       .rel.dyn : {
-               *(.rel*)
-       }
-
-       .rel_dyn_end :
-       {
-               *(.__rel_dyn_end)
-       }
-
-       .end :
-       {
-               *(.__end)
-       }
-
-       _image_binary_end = .;
-
-/*
- * Compiler-generated __bss_start and __bss_end, see arch/arm/lib/bss.c
- * __bss_base and __bss_limit are for linker only (overlay ordering)
- */
-
-       .bss_start __rel_dyn_start (OVERLAY) : {
-               KEEP(*(.__bss_start));
-               __bss_base = .;
-       }
-
-       .bss __bss_base (OVERLAY) : {
-               *(.bss*)
-                . = ALIGN(4);
-                __bss_limit = .;
-       }
-
-       .bss_end __bss_limit (OVERLAY) : {
-               KEEP(*(.__bss_end));
-       }
-
-       /*
-        * Zynq needs to discard these sections because the user
-        * is expected to pass this image on to tools for boot.bin
-        * generation that require them to be dropped.
-        */
-       /DISCARD/ : { *(.dynsym) }
-       /DISCARD/ : { *(.dynbss*) }
-       /DISCARD/ : { *(.dynstr*) }
-       /DISCARD/ : { *(.dynamic*) }
-       /DISCARD/ : { *(.plt*) }
-       /DISCARD/ : { *(.interp*) }
-       /DISCARD/ : { *(.gnu*) }
-       /DISCARD/ : { *(.ARM.exidx*) }
-       /DISCARD/ : { *(.gnu.linkonce.armexidx.*) }
-}
diff --git a/arch/arm/mach-zynq/Kconfig b/arch/arm/mach-zynq/Kconfig
new file mode 100644 (file)
index 0000000..26e570e
--- /dev/null
@@ -0,0 +1,43 @@
+if ZYNQ
+
+choice
+       prompt "Xilinx Zynq board select"
+
+config TARGET_ZYNQ_ZED
+       bool "Zynq ZedBoard"
+
+config TARGET_ZYNQ_MICROZED
+       bool "Zynq MicroZed"
+
+config TARGET_ZYNQ_PICOZED
+       bool "Zynq PicoZed"
+
+config TARGET_ZYNQ_ZC70X
+       bool "Zynq ZC702/ZC706 Board"
+
+config TARGET_ZYNQ_ZC770
+       bool "Zynq ZC770 Board"
+
+config TARGET_ZYNQ_ZYBO
+       bool "Zynq Zybo Board"
+
+endchoice
+
+config SYS_BOARD
+       default "zynq"
+
+config SYS_VENDOR
+       default "xilinx"
+
+config SYS_SOC
+       default "zynq"
+
+config SYS_CONFIG_NAME
+       default "zynq_zed" if TARGET_ZYNQ_ZED
+       default "zynq_microzed" if TARGET_ZYNQ_MICROZED
+       default "zynq_picozed" if TARGET_ZYNQ_PICOZED
+       default "zynq_zc70x" if TARGET_ZYNQ_ZC70X
+       default "zynq_zc770" if TARGET_ZYNQ_ZC770
+       default "zynq_zybo" if TARGET_ZYNQ_ZYBO
+
+endif
diff --git a/arch/arm/mach-zynq/Makefile b/arch/arm/mach-zynq/Makefile
new file mode 100644 (file)
index 0000000..bf29b4d
--- /dev/null
@@ -0,0 +1,18 @@
+#
+# (C) Copyright 2000-2003
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# (C) Copyright 2008
+# Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y  := timer.o
+obj-y  += cpu.o
+obj-y  += ddrc.o
+obj-y  += slcr.o
+obj-y  += clk.o
+obj-y  += lowlevel_init.o
+AFLAGS_lowlevel_init.o := -mfpu=neon
+obj-$(CONFIG_SPL_BUILD)        += spl.o
diff --git a/arch/arm/mach-zynq/clk.c b/arch/arm/mach-zynq/clk.c
new file mode 100644 (file)
index 0000000..d2885dc
--- /dev/null
@@ -0,0 +1,664 @@
+/*
+ * Copyright (C) 2013 Soren Brinkmann <soren.brinkmann@xilinx.com>
+ * Copyright (C) 2013 Xilinx, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+#include <common.h>
+#include <errno.h>
+#include <clk.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/clk.h>
+
+/* Board oscillator frequency */
+#ifndef CONFIG_ZYNQ_PS_CLK_FREQ
+# define CONFIG_ZYNQ_PS_CLK_FREQ       33333333UL
+#endif
+
+/* Register bitfield defines */
+#define PLLCTRL_FBDIV_MASK     0x7f000
+#define PLLCTRL_FBDIV_SHIFT    12
+#define PLLCTRL_BPFORCE_MASK   (1 << 4)
+#define PLLCTRL_PWRDWN_MASK    2
+#define PLLCTRL_PWRDWN_SHIFT   1
+#define PLLCTRL_RESET_MASK     1
+#define PLLCTRL_RESET_SHIFT    0
+
+#define ZYNQ_CLK_MAXDIV                0x3f
+#define CLK_CTRL_DIV1_SHIFT    20
+#define CLK_CTRL_DIV1_MASK     (ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV1_SHIFT)
+#define CLK_CTRL_DIV0_SHIFT    8
+#define CLK_CTRL_DIV0_MASK     (ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV0_SHIFT)
+#define CLK_CTRL_SRCSEL_SHIFT  4
+#define CLK_CTRL_SRCSEL_MASK   (0x3 << CLK_CTRL_SRCSEL_SHIFT)
+
+#define CLK_CTRL_DIV2X_SHIFT   26
+#define CLK_CTRL_DIV2X_MASK    (ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV2X_SHIFT)
+#define CLK_CTRL_DIV3X_SHIFT   20
+#define CLK_CTRL_DIV3X_MASK    (ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV3X_SHIFT)
+
+#define ZYNQ_CLKMUX_SEL_0      0
+#define ZYNQ_CLKMUX_SEL_1      1
+#define ZYNQ_CLKMUX_SEL_2      2
+#define ZYNQ_CLKMUX_SEL_3      3
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct clk;
+
+/**
+ * struct clk_ops:
+ * @set_rate:  Function pointer to set_rate() implementation
+ * @get_rate:  Function pointer to get_rate() implementation
+ */
+struct clk_ops {
+       int (*set_rate)(struct clk *clk, unsigned long rate);
+       unsigned long (*get_rate)(struct clk *clk);
+};
+
+/**
+ * struct clk:
+ * @name:      Clock name
+ * @frequency: Currenct frequency
+ * @parent:    Parent clock
+ * @flags:     Clock flags
+ * @reg:       Clock control register
+ * @ops:       Clock operations
+ */
+struct clk {
+       char            *name;
+       unsigned long   frequency;
+       enum zynq_clk   parent;
+       unsigned int    flags;
+       u32             *reg;
+       struct clk_ops  ops;
+};
+#define ZYNQ_CLK_FLAGS_HAS_2_DIVS      1
+
+static struct clk clks[clk_max];
+
+/**
+ * __zynq_clk_cpu_get_parent() - Decode clock multiplexer
+ * @srcsel:    Mux select value
+ * Returns the clock identifier associated with the selected mux input.
+ */
+static int __zynq_clk_cpu_get_parent(unsigned int srcsel)
+{
+       unsigned int ret;
+
+       switch (srcsel) {
+       case ZYNQ_CLKMUX_SEL_0:
+       case ZYNQ_CLKMUX_SEL_1:
+               ret = armpll_clk;
+               break;
+       case ZYNQ_CLKMUX_SEL_2:
+               ret = ddrpll_clk;
+               break;
+       case ZYNQ_CLKMUX_SEL_3:
+               ret = iopll_clk;
+               break;
+       default:
+               ret = armpll_clk;
+               break;
+       }
+
+       return ret;
+}
+
+/**
+ * ddr2x_get_rate() - Get clock rate of DDR2x clock
+ * @clk:       Clock handle
+ * Returns the current clock rate of @clk.
+ */
+static unsigned long ddr2x_get_rate(struct clk *clk)
+{
+       u32 clk_ctrl = readl(clk->reg);
+       u32 div = (clk_ctrl & CLK_CTRL_DIV2X_MASK) >> CLK_CTRL_DIV2X_SHIFT;
+
+       return DIV_ROUND_CLOSEST(zynq_clk_get_rate(clk->parent), div);
+}
+
+/**
+ * ddr3x_get_rate() - Get clock rate of DDR3x clock
+ * @clk:       Clock handle
+ * Returns the current clock rate of @clk.
+ */
+static unsigned long ddr3x_get_rate(struct clk *clk)
+{
+       u32 clk_ctrl = readl(clk->reg);
+       u32 div = (clk_ctrl & CLK_CTRL_DIV3X_MASK) >> CLK_CTRL_DIV3X_SHIFT;
+
+       return DIV_ROUND_CLOSEST(zynq_clk_get_rate(clk->parent), div);
+}
+
+static void init_ddr_clocks(void)
+{
+       u32 div0, div1;
+       unsigned long prate = zynq_clk_get_rate(ddrpll_clk);
+       u32 clk_ctrl = readl(&slcr_base->ddr_clk_ctrl);
+
+       /* DDR2x */
+       clks[ddr2x_clk].reg = &slcr_base->ddr_clk_ctrl;
+       clks[ddr2x_clk].parent = ddrpll_clk;
+       clks[ddr2x_clk].name = "ddr_2x";
+       clks[ddr2x_clk].frequency = ddr2x_get_rate(&clks[ddr2x_clk]);
+       clks[ddr2x_clk].ops.get_rate = ddr2x_get_rate;
+
+       /* DDR3x */
+       clks[ddr3x_clk].reg = &slcr_base->ddr_clk_ctrl;
+       clks[ddr3x_clk].parent = ddrpll_clk;
+       clks[ddr3x_clk].name = "ddr_3x";
+       clks[ddr3x_clk].frequency = ddr3x_get_rate(&clks[ddr3x_clk]);
+       clks[ddr3x_clk].ops.get_rate = ddr3x_get_rate;
+
+       /* DCI */
+       clk_ctrl = readl(&slcr_base->dci_clk_ctrl);
+       div0 = (clk_ctrl & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
+       div1 = (clk_ctrl & CLK_CTRL_DIV1_MASK) >> CLK_CTRL_DIV1_SHIFT;
+       clks[dci_clk].reg = &slcr_base->dci_clk_ctrl;
+       clks[dci_clk].parent = ddrpll_clk;
+       clks[dci_clk].frequency = DIV_ROUND_CLOSEST(
+                       DIV_ROUND_CLOSEST(prate, div0), div1);
+       clks[dci_clk].name = "dci";
+
+       gd->bd->bi_ddr_freq = clks[ddr3x_clk].frequency / 1000000;
+}
+
+static void init_cpu_clocks(void)
+{
+       int clk_621;
+       u32 reg, div, srcsel;
+       enum zynq_clk parent;
+
+       reg = readl(&slcr_base->arm_clk_ctrl);
+       clk_621 = readl(&slcr_base->clk_621_true) & 1;
+       div = (reg & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
+       srcsel = (reg & CLK_CTRL_SRCSEL_MASK) >> CLK_CTRL_SRCSEL_SHIFT;
+       parent = __zynq_clk_cpu_get_parent(srcsel);
+
+       /* cpu clocks */
+       clks[cpu_6or4x_clk].reg = &slcr_base->arm_clk_ctrl;
+       clks[cpu_6or4x_clk].parent = parent;
+       clks[cpu_6or4x_clk].frequency = DIV_ROUND_CLOSEST(
+                       zynq_clk_get_rate(parent), div);
+       clks[cpu_6or4x_clk].name = "cpu_6or4x";
+
+       clks[cpu_3or2x_clk].reg = &slcr_base->arm_clk_ctrl;
+       clks[cpu_3or2x_clk].parent = cpu_6or4x_clk;
+       clks[cpu_3or2x_clk].frequency = zynq_clk_get_rate(cpu_6or4x_clk) / 2;
+       clks[cpu_3or2x_clk].name = "cpu_3or2x";
+
+       clks[cpu_2x_clk].reg = &slcr_base->arm_clk_ctrl;
+       clks[cpu_2x_clk].parent = cpu_6or4x_clk;
+       clks[cpu_2x_clk].frequency = zynq_clk_get_rate(cpu_6or4x_clk) /
+                       (2 + clk_621);
+       clks[cpu_2x_clk].name = "cpu_2x";
+
+       clks[cpu_1x_clk].reg = &slcr_base->arm_clk_ctrl;
+       clks[cpu_1x_clk].parent = cpu_6or4x_clk;
+       clks[cpu_1x_clk].frequency = zynq_clk_get_rate(cpu_6or4x_clk) /
+                       (4 + 2 * clk_621);
+       clks[cpu_1x_clk].name = "cpu_1x";
+}
+
+/**
+ * periph_calc_two_divs() - Calculate clock dividers
+ * @cur_rate:  Current clock rate
+ * @tgt_rate:  Target clock rate
+ * @prate:     Parent clock rate
+ * @div0:      First divider (output)
+ * @div1:      Second divider (output)
+ * Returns the actual clock rate possible.
+ *
+ * Calculates clock dividers for clocks with two 6-bit dividers.
+ */
+static unsigned long periph_calc_two_divs(unsigned long cur_rate,
+               unsigned long tgt_rate, unsigned long prate, u32 *div0,
+               u32 *div1)
+{
+       long err, best_err = (long)(~0UL >> 1);
+       unsigned long rate, best_rate = 0;
+       u32 d0, d1;
+
+       for (d0 = 1; d0 <= ZYNQ_CLK_MAXDIV; d0++) {
+               for (d1 = 1; d1 <= ZYNQ_CLK_MAXDIV >> 1; d1++) {
+                       rate = DIV_ROUND_CLOSEST(DIV_ROUND_CLOSEST(prate, d0),
+                                       d1);
+                       err = abs(rate - tgt_rate);
+
+                       if (err < best_err) {
+                               *div0 = d0;
+                               *div1 = d1;
+                               best_err = err;
+                               best_rate = rate;
+                       }
+               }
+       }
+
+       return best_rate;
+}
+
+/**
+ * zynq_clk_periph_set_rate() - Set clock rate
+ * @clk:       Handle of the peripheral clock
+ * @rate:      New clock rate
+ * Sets the clock frequency of @clk to @rate. Returns zero on success.
+ */
+static int zynq_clk_periph_set_rate(struct clk *clk,
+               unsigned long rate)
+{
+       u32 ctrl, div0 = 0, div1 = 0;
+       unsigned long prate, new_rate, cur_rate = clk->frequency;
+
+       ctrl = readl(clk->reg);
+       prate = zynq_clk_get_rate(clk->parent);
+       ctrl &= ~CLK_CTRL_DIV0_MASK;
+
+       if (clk->flags & ZYNQ_CLK_FLAGS_HAS_2_DIVS) {
+               ctrl &= ~CLK_CTRL_DIV1_MASK;
+               new_rate = periph_calc_two_divs(cur_rate, rate, prate, &div0,
+                               &div1);
+               ctrl |= div1 << CLK_CTRL_DIV1_SHIFT;
+       } else {
+               div0 = DIV_ROUND_CLOSEST(prate, rate);
+               div0 &= ZYNQ_CLK_MAXDIV;
+               new_rate = DIV_ROUND_CLOSEST(rate, div0);
+       }
+
+       /* write new divs to hardware */
+       ctrl |= div0 << CLK_CTRL_DIV0_SHIFT;
+       writel(ctrl, clk->reg);
+
+       /* update frequency in clk framework */
+       clk->frequency = new_rate;
+
+       return 0;
+}
+
+/**
+ * zynq_clk_periph_get_rate() - Get clock rate
+ * @clk:       Handle of the peripheral clock
+ * Returns the current clock rate of @clk.
+ */
+static unsigned long zynq_clk_periph_get_rate(struct clk *clk)
+{
+       u32 clk_ctrl = readl(clk->reg);
+       u32 div0 = (clk_ctrl & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
+       u32 div1 = 1;
+
+       if (clk->flags & ZYNQ_CLK_FLAGS_HAS_2_DIVS)
+               div1 = (clk_ctrl & CLK_CTRL_DIV1_MASK) >> CLK_CTRL_DIV1_SHIFT;
+
+       /* a register value of zero == division by 1 */
+       if (!div0)
+               div0 = 1;
+       if (!div1)
+               div1 = 1;
+
+       return
+               DIV_ROUND_CLOSEST(
+                       DIV_ROUND_CLOSEST(zynq_clk_get_rate(clk->parent), div0),
+                       div1);
+}
+
+/**
+ * __zynq_clk_periph_get_parent() - Decode clock multiplexer
+ * @srcsel:    Mux select value
+ * Returns the clock identifier associated with the selected mux input.
+ */
+static enum zynq_clk __zynq_clk_periph_get_parent(u32 srcsel)
+{
+       switch (srcsel) {
+       case ZYNQ_CLKMUX_SEL_0:
+       case ZYNQ_CLKMUX_SEL_1:
+               return iopll_clk;
+       case ZYNQ_CLKMUX_SEL_2:
+               return armpll_clk;
+       case ZYNQ_CLKMUX_SEL_3:
+               return ddrpll_clk;
+       default:
+               return 0;
+       }
+}
+
+/**
+ * zynq_clk_periph_get_parent() - Decode clock multiplexer
+ * @clk:       Clock handle
+ * Returns the clock identifier associated with the selected mux input.
+ */
+static enum zynq_clk zynq_clk_periph_get_parent(struct clk *clk)
+{
+       u32 clk_ctrl = readl(clk->reg);
+       u32 srcsel = (clk_ctrl & CLK_CTRL_SRCSEL_MASK) >> CLK_CTRL_SRCSEL_SHIFT;
+
+       return __zynq_clk_periph_get_parent(srcsel);
+}
+
+/**
+ * zynq_clk_register_periph_clk() - Set up a peripheral clock with the framework
+ * @clk:       Pointer to struct clk for the clock
+ * @ctrl:      Clock control register
+ * @name:      PLL name
+ * @two_divs:  Indicates whether the clock features one or two dividers
+ */
+static int zynq_clk_register_periph_clk(struct clk *clk, u32 *ctrl, char *name,
+               bool two_divs)
+{
+       clk->name = name;
+       clk->reg = ctrl;
+       if (two_divs)
+               clk->flags = ZYNQ_CLK_FLAGS_HAS_2_DIVS;
+       clk->parent = zynq_clk_periph_get_parent(clk);
+       clk->frequency = zynq_clk_periph_get_rate(clk);
+       clk->ops.get_rate = zynq_clk_periph_get_rate;
+       clk->ops.set_rate = zynq_clk_periph_set_rate;
+
+       return 0;
+}
+
+static void init_periph_clocks(void)
+{
+       zynq_clk_register_periph_clk(&clks[gem0_clk], &slcr_base->gem0_clk_ctrl,
+                                    "gem0", 1);
+       zynq_clk_register_periph_clk(&clks[gem1_clk], &slcr_base->gem1_clk_ctrl,
+                                    "gem1", 1);
+
+       zynq_clk_register_periph_clk(&clks[smc_clk], &slcr_base->smc_clk_ctrl,
+                                    "smc", 0);
+
+       zynq_clk_register_periph_clk(&clks[lqspi_clk],
+                                    &slcr_base->lqspi_clk_ctrl, "lqspi", 0);
+
+       zynq_clk_register_periph_clk(&clks[sdio0_clk],
+                                    &slcr_base->sdio_clk_ctrl, "sdio0", 0);
+       zynq_clk_register_periph_clk(&clks[sdio1_clk],
+                                    &slcr_base->sdio_clk_ctrl, "sdio1", 0);
+
+       zynq_clk_register_periph_clk(&clks[spi0_clk], &slcr_base->spi_clk_ctrl,
+                                    "spi0", 0);
+       zynq_clk_register_periph_clk(&clks[spi1_clk], &slcr_base->spi_clk_ctrl,
+                                    "spi1", 0);
+
+       zynq_clk_register_periph_clk(&clks[uart0_clk],
+                                    &slcr_base->uart_clk_ctrl, "uart0", 0);
+       zynq_clk_register_periph_clk(&clks[uart1_clk],
+                                    &slcr_base->uart_clk_ctrl, "uart1", 0);
+
+       zynq_clk_register_periph_clk(&clks[dbg_trc_clk],
+                                    &slcr_base->dbg_clk_ctrl, "dbg_trc", 0);
+       zynq_clk_register_periph_clk(&clks[dbg_apb_clk],
+                                    &slcr_base->dbg_clk_ctrl, "dbg_apb", 0);
+
+       zynq_clk_register_periph_clk(&clks[pcap_clk],
+                                    &slcr_base->pcap_clk_ctrl, "pcap", 0);
+
+       zynq_clk_register_periph_clk(&clks[fclk0_clk],
+                                    &slcr_base->fpga0_clk_ctrl, "fclk0", 1);
+       zynq_clk_register_periph_clk(&clks[fclk1_clk],
+                                    &slcr_base->fpga1_clk_ctrl, "fclk1", 1);
+       zynq_clk_register_periph_clk(&clks[fclk2_clk],
+                                    &slcr_base->fpga2_clk_ctrl, "fclk2", 1);
+       zynq_clk_register_periph_clk(&clks[fclk3_clk],
+                                    &slcr_base->fpga3_clk_ctrl, "fclk3", 1);
+}
+
+/**
+ * zynq_clk_register_aper_clk() - Set up a APER clock with the framework
+ * @clk:       Pointer to struct clk for the clock
+ * @ctrl:      Clock control register
+ * @name:      PLL name
+ */
+static void zynq_clk_register_aper_clk(struct clk *clk, u32 *ctrl, char *name)
+{
+       clk->name = name;
+       clk->reg = ctrl;
+       clk->parent = cpu_1x_clk;
+       clk->frequency = zynq_clk_get_rate(clk->parent);
+}
+
+static void init_aper_clocks(void)
+{
+       zynq_clk_register_aper_clk(&clks[usb0_aper_clk],
+                                  &slcr_base->aper_clk_ctrl, "usb0_aper");
+       zynq_clk_register_aper_clk(&clks[usb1_aper_clk],
+                                  &slcr_base->aper_clk_ctrl, "usb1_aper");
+
+       zynq_clk_register_aper_clk(&clks[gem0_aper_clk],
+                                  &slcr_base->aper_clk_ctrl, "gem0_aper");
+       zynq_clk_register_aper_clk(&clks[gem1_aper_clk],
+                                  &slcr_base->aper_clk_ctrl, "gem1_aper");
+
+       zynq_clk_register_aper_clk(&clks[sdio0_aper_clk],
+                                  &slcr_base->aper_clk_ctrl, "sdio0_aper");
+       zynq_clk_register_aper_clk(&clks[sdio1_aper_clk],
+                                  &slcr_base->aper_clk_ctrl, "sdio1_aper");
+
+       zynq_clk_register_aper_clk(&clks[spi0_aper_clk],
+                                  &slcr_base->aper_clk_ctrl, "spi0_aper");
+       zynq_clk_register_aper_clk(&clks[spi1_aper_clk],
+                                  &slcr_base->aper_clk_ctrl, "spi1_aper");
+
+       zynq_clk_register_aper_clk(&clks[can0_aper_clk],
+                                  &slcr_base->aper_clk_ctrl, "can0_aper");
+       zynq_clk_register_aper_clk(&clks[can1_aper_clk],
+                                  &slcr_base->aper_clk_ctrl, "can1_aper");
+
+       zynq_clk_register_aper_clk(&clks[i2c0_aper_clk],
+                                  &slcr_base->aper_clk_ctrl, "i2c0_aper");
+       zynq_clk_register_aper_clk(&clks[i2c1_aper_clk],
+                                  &slcr_base->aper_clk_ctrl, "i2c1_aper");
+
+       zynq_clk_register_aper_clk(&clks[uart0_aper_clk],
+                                  &slcr_base->aper_clk_ctrl, "uart0_aper");
+       zynq_clk_register_aper_clk(&clks[uart1_aper_clk],
+                                  &slcr_base->aper_clk_ctrl, "uart1_aper");
+
+       zynq_clk_register_aper_clk(&clks[gpio_aper_clk],
+                                  &slcr_base->aper_clk_ctrl, "gpio_aper");
+
+       zynq_clk_register_aper_clk(&clks[lqspi_aper_clk],
+                                  &slcr_base->aper_clk_ctrl, "lqspi_aper");
+
+       zynq_clk_register_aper_clk(&clks[smc_aper_clk],
+                                  &slcr_base->aper_clk_ctrl, "smc_aper");
+}
+
+/**
+ * __zynq_clk_pll_get_rate() - Get PLL rate
+ * @addr:      Address of the PLL's control register
+ * Returns the current PLL output rate.
+ */
+static unsigned long __zynq_clk_pll_get_rate(u32 *addr)
+{
+       u32 reg, mul, bypass;
+
+       reg = readl(addr);
+       bypass = reg & PLLCTRL_BPFORCE_MASK;
+       if (bypass)
+               mul = 1;
+       else
+               mul = (reg & PLLCTRL_FBDIV_MASK) >> PLLCTRL_FBDIV_SHIFT;
+
+       return CONFIG_ZYNQ_PS_CLK_FREQ * mul;
+}
+
+/**
+ * zynq_clk_pll_get_rate() - Get PLL rate
+ * @pll:       Handle of the PLL
+ * Returns the current clock rate of @pll.
+ */
+static unsigned long zynq_clk_pll_get_rate(struct clk *pll)
+{
+       return __zynq_clk_pll_get_rate(pll->reg);
+}
+
+/**
+ * zynq_clk_register_pll() - Set up a PLL with the framework
+ * @clk:       Pointer to struct clk for the PLL
+ * @ctrl:      PLL control register
+ * @name:      PLL name
+ * @prate:     PLL input clock rate
+ */
+static void zynq_clk_register_pll(struct clk *clk, u32 *ctrl, char *name,
+               unsigned long prate)
+{
+       clk->name = name;
+       clk->reg = ctrl;
+       clk->frequency = zynq_clk_pll_get_rate(clk);
+       clk->ops.get_rate = zynq_clk_pll_get_rate;
+}
+
+/**
+ * clkid_2_register() - Get clock control register
+ * @id:        Clock identifier of one of the PLLs
+ * Returns the address of the requested PLL's control register.
+ */
+static u32 *clkid_2_register(enum zynq_clk id)
+{
+       switch (id) {
+       case armpll_clk:
+               return &slcr_base->arm_pll_ctrl;
+       case ddrpll_clk:
+               return &slcr_base->ddr_pll_ctrl;
+       case iopll_clk:
+               return &slcr_base->io_pll_ctrl;
+       default:
+               return &slcr_base->io_pll_ctrl;
+       }
+}
+
+/* API */
+/**
+ * zynq_clk_early_init() - Early init for the clock framework
+ *
+ * This function is called from before relocation and sets up the CPU clock
+ * frequency in the global data struct.
+ */
+void zynq_clk_early_init(void)
+{
+       u32 reg = readl(&slcr_base->arm_clk_ctrl);
+       u32 div = (reg & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
+       u32 srcsel = (reg & CLK_CTRL_SRCSEL_MASK) >> CLK_CTRL_SRCSEL_SHIFT;
+       enum zynq_clk parent = __zynq_clk_cpu_get_parent(srcsel);
+       u32 *pllreg = clkid_2_register(parent);
+       unsigned long prate = __zynq_clk_pll_get_rate(pllreg);
+
+       if (!div)
+               div = 1;
+
+       gd->cpu_clk = DIV_ROUND_CLOSEST(prate, div);
+}
+
+/**
+ * get_uart_clk() - Get UART input frequency
+ * @dev_index: UART ID
+ * Returns UART input clock frequency in Hz.
+ *
+ * Compared to zynq_clk_get_rate() this function is designed to work before
+ * relocation and can be called when the serial UART is set up.
+ */
+unsigned long get_uart_clk(int dev_index)
+{
+       u32 reg = readl(&slcr_base->uart_clk_ctrl);
+       u32 div = (reg & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
+       u32 srcsel = (reg & CLK_CTRL_SRCSEL_MASK) >> CLK_CTRL_SRCSEL_SHIFT;
+       enum zynq_clk parent = __zynq_clk_periph_get_parent(srcsel);
+       u32 *pllreg = clkid_2_register(parent);
+       unsigned long prate = __zynq_clk_pll_get_rate(pllreg);
+
+       if (!div)
+               div = 1;
+
+       return DIV_ROUND_CLOSEST(prate, div);
+}
+
+/**
+ * set_cpu_clk_info() - Initialize clock framework
+ * Always returns zero.
+ *
+ * This function is called from common code after relocation and sets up the
+ * clock framework. The framework must not be used before this function had been
+ * called.
+ */
+int set_cpu_clk_info(void)
+{
+       zynq_clk_register_pll(&clks[armpll_clk], &slcr_base->arm_pll_ctrl,
+                             "armpll", CONFIG_ZYNQ_PS_CLK_FREQ);
+       zynq_clk_register_pll(&clks[ddrpll_clk], &slcr_base->ddr_pll_ctrl,
+                             "ddrpll", CONFIG_ZYNQ_PS_CLK_FREQ);
+       zynq_clk_register_pll(&clks[iopll_clk], &slcr_base->io_pll_ctrl,
+                             "iopll", CONFIG_ZYNQ_PS_CLK_FREQ);
+
+       init_ddr_clocks();
+       init_cpu_clocks();
+       init_periph_clocks();
+       init_aper_clocks();
+
+       gd->bd->bi_arm_freq = gd->cpu_clk / 1000000;
+       gd->bd->bi_dsp_freq = 0;
+
+       return 0;
+}
+
+/**
+ * zynq_clk_get_rate() - Get clock rate
+ * @clk:       Clock identifier
+ * Returns the current clock rate of @clk on success or zero for an invalid
+ * clock id.
+ */
+unsigned long zynq_clk_get_rate(enum zynq_clk clk)
+{
+       if (clk < 0 || clk >= clk_max)
+               return 0;
+
+       return clks[clk].frequency;
+}
+
+/**
+ * zynq_clk_set_rate() - Set clock rate
+ * @clk:       Clock identifier
+ * @rate:      Requested clock rate
+ * Passes on the return value from the clock's set_rate() function or negative
+ * errno.
+ */
+int zynq_clk_set_rate(enum zynq_clk clk, unsigned long rate)
+{
+       if (clk < 0 || clk >= clk_max)
+               return -ENODEV;
+
+       if (clks[clk].ops.set_rate)
+               return clks[clk].ops.set_rate(&clks[clk], rate);
+
+       return -ENXIO;
+}
+
+/**
+ * zynq_clk_get_name() - Get clock name
+ * @clk:       Clock identifier
+ * Returns the name of @clk.
+ */
+const char *zynq_clk_get_name(enum zynq_clk clk)
+{
+       return clks[clk].name;
+}
+
+/**
+ * soc_clk_dump() - Print clock frequencies
+ * Returns zero on success
+ *
+ * Implementation for the clk dump command.
+ */
+int soc_clk_dump(void)
+{
+       int i;
+
+       printf("clk\t\tfrequency\n");
+       for (i = 0; i < clk_max; i++) {
+               const char *name = zynq_clk_get_name(i);
+               if (name)
+                       printf("%10s%20lu\n", name, zynq_clk_get_rate(i));
+       }
+
+       return 0;
+}
diff --git a/arch/arm/mach-zynq/cpu.c b/arch/arm/mach-zynq/cpu.c
new file mode 100644 (file)
index 0000000..914b1fe
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2012 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2012 Xilinx, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/clk.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/hardware.h>
+
+#define ZYNQ_SILICON_VER_MASK  0xF0000000
+#define ZYNQ_SILICON_VER_SHIFT 28
+
+int arch_cpu_init(void)
+{
+       zynq_slcr_unlock();
+#ifndef CONFIG_SPL_BUILD
+       /* Device config APB, unlock the PCAP */
+       writel(0x757BDF0D, &devcfg_base->unlock);
+       writel(0xFFFFFFFF, &devcfg_base->rom_shadow);
+
+#if (CONFIG_SYS_SDRAM_BASE == 0)
+       /* remap DDR to zero, FILTERSTART */
+       writel(0, &scu_base->filter_start);
+
+       /* 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);
+       /* Set urgent bits with register */
+       writel(0x0, &slcr_base->ddr_urgent_sel);
+       /* Urgent write, ports S2/S3 */
+       writel(0xC, &slcr_base->ddr_urgent);
+#endif
+#endif
+       zynq_clk_early_init();
+       zynq_slcr_lock();
+
+       return 0;
+}
+
+unsigned int zynq_get_silicon_version(void)
+{
+       unsigned int ver;
+
+       ver = (readl(&devcfg_base->mctrl) &
+              ZYNQ_SILICON_VER_MASK) >> ZYNQ_SILICON_VER_SHIFT;
+
+       return ver;
+}
+
+void reset_cpu(ulong addr)
+{
+       zynq_slcr_cpu_reset();
+       while (1)
+               ;
+}
+
+#ifndef CONFIG_SYS_DCACHE_OFF
+void enable_caches(void)
+{
+       /* Enable D-cache. I-cache is already enabled in start.S */
+       dcache_enable();
+}
+#endif
diff --git a/arch/arm/mach-zynq/ddrc.c b/arch/arm/mach-zynq/ddrc.c
new file mode 100644 (file)
index 0000000..5b20acc
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2012 - 2013 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2012 - 2013 Xilinx, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/hardware.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Control regsiter bitfield definitions */
+#define ZYNQ_DDRC_CTRLREG_BUSWIDTH_MASK                0xC
+#define ZYNQ_DDRC_CTRLREG_BUSWIDTH_SHIFT       2
+#define ZYNQ_DDRC_CTRLREG_BUSWIDTH_16BIT       1
+
+/* ECC scrub regsiter definitions */
+#define ZYNQ_DDRC_ECC_SCRUBREG_ECC_MODE_MASK   0x7
+#define ZYNQ_DDRC_ECC_SCRUBREG_ECCMODE_SECDED  0x4
+
+void zynq_ddrc_init(void)
+{
+       u32 width, ecctype;
+
+       width = readl(&ddrc_base->ddrc_ctrl);
+       width = (width & ZYNQ_DDRC_CTRLREG_BUSWIDTH_MASK) >>
+                                       ZYNQ_DDRC_CTRLREG_BUSWIDTH_SHIFT;
+       ecctype = (readl(&ddrc_base->ecc_scrub) &
+               ZYNQ_DDRC_ECC_SCRUBREG_ECC_MODE_MASK);
+
+       /* ECC is enabled when memory is in 16bit mode and it is enabled */
+       if ((ecctype == ZYNQ_DDRC_ECC_SCRUBREG_ECCMODE_SECDED) &&
+           (width == ZYNQ_DDRC_CTRLREG_BUSWIDTH_16BIT)) {
+               puts("ECC enabled ");
+               /*
+                * Clear the first 1MB because it is not initialized from
+                * first stage bootloader. To get ECC to work all memory has
+                * been initialized by writing any value.
+                */
+               /* cppcheck-suppress nullPointer */
+               memset((void *)0, 0, 1 * 1024 * 1024);
+
+               gd->ram_size /= 2;
+       } else {
+               puts("ECC disabled ");
+       }
+}
diff --git a/arch/arm/mach-zynq/lowlevel_init.S b/arch/arm/mach-zynq/lowlevel_init.S
new file mode 100644 (file)
index 0000000..6d714b7
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2013 Xilinx, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <linux/linkage.h>
+
+ENTRY(lowlevel_init)
+
+       /* Enable the the VFP */
+       mrc     p15, 0, r1, c1, c0, 2
+       orr     r1, r1, #(0x3 << 20)
+       orr     r1, r1, #(0x3 << 20)
+       mcr     p15, 0, r1, c1, c0, 2
+       isb
+       fmrx    r1, FPEXC
+       orr     r1,r1, #(1<<30)
+       fmxr    FPEXC, r1
+
+       /* Move back to caller */
+       mov     pc, lr
+
+ENDPROC(lowlevel_init)
diff --git a/arch/arm/mach-zynq/slcr.c b/arch/arm/mach-zynq/slcr.c
new file mode 100644 (file)
index 0000000..05f4099
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2013 Xilinx Inc.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <malloc.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/clk.h>
+
+#define SLCR_LOCK_MAGIC                0x767B
+#define SLCR_UNLOCK_MAGIC      0xDF0D
+
+#define SLCR_USB_L1_SEL                        0x04
+
+#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 usb0_pins[] = {
+       28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39
+};
+
+static const int usb1_pins[] = {
+       40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
+};
+
+static const struct zynq_slcr_mio_get_status mio_periphs[] = {
+       {
+               "usb0",
+               usb0_pins,
+               ARRAY_SIZE(usb0_pins),
+               SLCR_USB_L1_SEL,
+               SLCR_USB_L1_SEL,
+       },
+       {
+               "usb1",
+               usb1_pins,
+               ARRAY_SIZE(usb1_pins),
+               SLCR_USB_L1_SEL,
+               SLCR_USB_L1_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);
+               slcr_lock = 1;
+       }
+}
+
+void zynq_slcr_unlock(void)
+{
+       if (slcr_lock) {
+               writel(SLCR_UNLOCK_MAGIC, &slcr_base->slcr_unlock);
+               slcr_lock = 0;
+       }
+}
+
+/* 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, unsigned long clk_rate)
+{
+       int ret;
+
+       zynq_slcr_unlock();
+
+       if (gem_id > 1) {
+               printf("Non existing GEM id %d\n", gem_id);
+               goto out;
+       }
+
+       ret = zynq_clk_set_rate(gem0_clk + gem_id, clk_rate);
+       if (ret)
+               goto out;
+
+       if (gem_id) {
+               /* Configure GEM_RCLK_CTRL */
+               writel(1, &slcr_base->gem1_rclk_ctrl);
+       } else {
+               /* Configure GEM_RCLK_CTRL */
+               writel(1, &slcr_base->gem0_rclk_ctrl);
+       }
+       udelay(100000);
+out:
+       zynq_slcr_lock();
+}
+
+void zynq_slcr_devcfg_disable(void)
+{
+       u32 reg_val;
+
+       zynq_slcr_unlock();
+
+       /* Disable AXI interface by asserting FPGA resets */
+       writel(0xF, &slcr_base->fpga_rst_ctrl);
+
+       /* Disable Level shifters before setting PS-PL */
+       reg_val = readl(&slcr_base->lvl_shftr_en);
+       reg_val &= ~0xF;
+       writel(reg_val, &slcr_base->lvl_shftr_en);
+
+       /* 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);
+
+       /* Enable AXI interface by de-asserting FPGA resets */
+       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/mach-zynq/spl.c b/arch/arm/mach-zynq/spl.c
new file mode 100644 (file)
index 0000000..13025f0
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * (C) Copyright 2014 Xilinx, Inc. Michal Simek
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+#include <common.h>
+#include <spl.h>
+
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/spl.h>
+#include <asm/arch/sys_proto.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void board_init_f(ulong dummy)
+{
+       ps7_init();
+
+       /* Clear the BSS. */
+       memset(__bss_start, 0, __bss_end - __bss_start);
+
+       preloader_console_init();
+       arch_cpu_init();
+       board_init_r(NULL, 0);
+}
+
+#ifdef CONFIG_SPL_BOARD_INIT
+void spl_board_init(void)
+{
+       board_init();
+}
+#endif
+
+u32 spl_boot_device(void)
+{
+       u32 mode;
+
+       switch ((zynq_slcr_get_boot_mode()) & ZYNQ_BM_MASK) {
+#ifdef CONFIG_SPL_SPI_SUPPORT
+       case ZYNQ_BM_QSPI:
+               puts("qspi boot\n");
+               mode = BOOT_DEVICE_SPI;
+               break;
+#endif
+       case ZYNQ_BM_NAND:
+               mode = BOOT_DEVICE_NAND;
+               break;
+       case ZYNQ_BM_NOR:
+               mode = BOOT_DEVICE_NOR;
+               break;
+#ifdef CONFIG_SPL_MMC_SUPPORT
+       case ZYNQ_BM_SD:
+               puts("mmc boot\n");
+               mode = BOOT_DEVICE_MMC1;
+               break;
+#endif
+       case ZYNQ_BM_JTAG:
+               mode = BOOT_DEVICE_RAM;
+               break;
+       default:
+               puts("Unsupported boot mode selected\n");
+               hang();
+       }
+
+       return mode;
+}
+
+#ifdef CONFIG_SPL_MMC_SUPPORT
+u32 spl_boot_mode(void)
+{
+       return MMCSD_MODE_FS;
+}
+#endif
+
+#ifdef CONFIG_SPL_OS_BOOT
+int spl_start_uboot(void)
+{
+       /* boot linux */
+       return 0;
+}
+#endif
+
+__weak void ps7_init(void)
+{
+       /*
+        * This function is overridden by the one in
+        * board/xilinx/zynq/ps7_init_gpl.c, if it exists.
+        */
+}
diff --git a/arch/arm/mach-zynq/timer.c b/arch/arm/mach-zynq/timer.c
new file mode 100644 (file)
index 0000000..5ed9642
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2012 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2011-2012 Xilinx, Inc. All rights reserved.
+ *
+ * (C) Copyright 2008
+ * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>
+ *
+ * (C) Copyright 2004
+ * Philippe Robin, ARM Ltd. <philippe.robin@arm.com>
+ *
+ * (C) Copyright 2002-2004
+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+ *
+ * (C) Copyright 2003
+ * Texas Instruments <www.ti.com>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <div64.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/clk.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct scu_timer {
+       u32 load; /* Timer Load Register */
+       u32 counter; /* Timer Counter Register */
+       u32 control; /* Timer Control Register */
+};
+
+static struct scu_timer *timer_base =
+                             (struct scu_timer *)ZYNQ_SCUTIMER_BASEADDR;
+
+#define SCUTIMER_CONTROL_PRESCALER_MASK        0x0000FF00 /* Prescaler */
+#define SCUTIMER_CONTROL_PRESCALER_SHIFT       8
+#define SCUTIMER_CONTROL_AUTO_RELOAD_MASK      0x00000002 /* Auto-reload */
+#define SCUTIMER_CONTROL_ENABLE_MASK           0x00000001 /* Timer enable */
+
+#define TIMER_LOAD_VAL 0xFFFFFFFF
+#define TIMER_PRESCALE 255
+
+int timer_init(void)
+{
+       const u32 emask = SCUTIMER_CONTROL_AUTO_RELOAD_MASK |
+                       (TIMER_PRESCALE << SCUTIMER_CONTROL_PRESCALER_SHIFT) |
+                       SCUTIMER_CONTROL_ENABLE_MASK;
+
+       gd->arch.timer_rate_hz = (gd->cpu_clk / 2) / (TIMER_PRESCALE + 1);
+
+       /* Load the timer counter register */
+       writel(0xFFFFFFFF, &timer_base->load);
+
+       /*
+        * Start the A9Timer device
+        * Enable Auto reload mode, Clear prescaler control bits
+        * Set prescaler value, Enable the decrementer
+        */
+       clrsetbits_le32(&timer_base->control, SCUTIMER_CONTROL_PRESCALER_MASK,
+                                                               emask);
+
+       /* Reset time */
+       gd->arch.lastinc = readl(&timer_base->counter) /
+                               (gd->arch.timer_rate_hz / CONFIG_SYS_HZ);
+       gd->arch.tbl = 0;
+
+       return 0;
+}
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+ulong get_timer_masked(void)
+{
+       ulong now;
+
+       now = readl(&timer_base->counter) /
+                       (gd->arch.timer_rate_hz / CONFIG_SYS_HZ);
+
+       if (gd->arch.lastinc >= now) {
+               /* Normal mode */
+               gd->arch.tbl += gd->arch.lastinc - now;
+       } else {
+               /* We have an overflow ... */
+               gd->arch.tbl += gd->arch.lastinc + (TIMER_LOAD_VAL /
+                               (gd->arch.timer_rate_hz / CONFIG_SYS_HZ)) -
+                               now + 1;
+       }
+       gd->arch.lastinc = now;
+
+       return gd->arch.tbl;
+}
+
+void __udelay(unsigned long usec)
+{
+       u32 countticks;
+       u32 timeend;
+       u32 timediff;
+       u32 timenow;
+
+       if (usec == 0)
+               return;
+
+       countticks = lldiv(((unsigned long long)gd->arch.timer_rate_hz * usec),
+                          1000000);
+
+       /* decrementing timer */
+       timeend = readl(&timer_base->counter) - countticks;
+
+#if TIMER_LOAD_VAL != 0xFFFFFFFF
+       /* do not manage multiple overflow */
+       if (countticks >= TIMER_LOAD_VAL)
+               countticks = TIMER_LOAD_VAL - 1;
+#endif
+
+       do {
+               timenow = readl(&timer_base->counter);
+
+               if (timenow >= timeend) {
+                       /* normal case */
+                       timediff = timenow - timeend;
+               } else {
+                       if ((TIMER_LOAD_VAL - timeend + timenow) <=
+                                                               countticks) {
+                               /* overflow */
+                               timediff = TIMER_LOAD_VAL - timeend + timenow;
+                       } else {
+                               /* missed the exact match */
+                               break;
+                       }
+               }
+       } while (timediff > 0);
+}
+
+/* Timer without interrupts */
+ulong get_timer(ulong base)
+{
+       return get_timer_masked() - base;
+}
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+       return get_timer(0);
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk(void)
+{
+       return CONFIG_SYS_HZ;
+}
diff --git a/arch/arm/mach-zynq/u-boot-spl.lds b/arch/arm/mach-zynq/u-boot-spl.lds
new file mode 100644 (file)
index 0000000..0f2f756
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2014 Xilinx, Inc. Michal Simek
+ * Copyright (c) 2004-2008 Texas Instruments
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+MEMORY { .sram : ORIGIN = CONFIG_SPL_TEXT_BASE,\
+               LENGTH = CONFIG_SPL_MAX_SIZE }
+MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, \
+               LENGTH = CONFIG_SPL_BSS_MAX_SIZE }
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+       . = ALIGN(4);
+       .text :
+       {
+               __image_copy_start = .;
+               *(.vectors)
+               CPUDIR/start.o (.text*)
+               *(.text*)
+       } > .sram
+
+       . = ALIGN(4);
+       .rodata : {
+               *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
+       } > .sram
+
+       . = ALIGN(4);
+       .data : {
+               *(.data*)
+       } > .sram
+
+       . = ALIGN(4);
+
+       . = .;
+
+       __image_copy_end = .;
+
+       _end = .;
+
+       /* Move BSS section to RAM because of FAT */
+       .bss (NOLOAD) : {
+               __bss_start = .;
+               *(.bss*)
+                . = ALIGN(4);
+               __bss_end = .;
+       } > .sdram
+
+       /DISCARD/ : { *(.dynsym) }
+       /DISCARD/ : { *(.dynstr*) }
+       /DISCARD/ : { *(.dynamic*) }
+       /DISCARD/ : { *(.plt*) }
+       /DISCARD/ : { *(.interp*) }
+       /DISCARD/ : { *(.gnu*) }
+}
diff --git a/arch/arm/mach-zynq/u-boot.lds b/arch/arm/mach-zynq/u-boot.lds
new file mode 100644 (file)
index 0000000..4dc9bb0
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2004-2008 Texas Instruments
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+       . = 0x00000000;
+
+       . = ALIGN(4);
+       .text :
+       {
+               *(.__image_copy_start)
+               *(.vectors)
+               CPUDIR/start.o (.text*)
+               *(.text*)
+       }
+
+       . = ALIGN(4);
+       .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
+
+       . = ALIGN(4);
+       .data : {
+               *(.data*)
+       }
+
+       . = ALIGN(4);
+
+       . = .;
+
+       . = ALIGN(4);
+       .u_boot_list : {
+               KEEP(*(SORT(.u_boot_list*)));
+       }
+
+       . = ALIGN(4);
+
+       .image_copy_end :
+       {
+               *(.__image_copy_end)
+       }
+
+       .rel_dyn_start :
+       {
+               *(.__rel_dyn_start)
+       }
+
+       .rel.dyn : {
+               *(.rel*)
+       }
+
+       .rel_dyn_end :
+       {
+               *(.__rel_dyn_end)
+       }
+
+       .end :
+       {
+               *(.__end)
+       }
+
+       _image_binary_end = .;
+
+/*
+ * Compiler-generated __bss_start and __bss_end, see arch/arm/lib/bss.c
+ * __bss_base and __bss_limit are for linker only (overlay ordering)
+ */
+
+       .bss_start __rel_dyn_start (OVERLAY) : {
+               KEEP(*(.__bss_start));
+               __bss_base = .;
+       }
+
+       .bss __bss_base (OVERLAY) : {
+               *(.bss*)
+                . = ALIGN(4);
+                __bss_limit = .;
+       }
+
+       .bss_end __bss_limit (OVERLAY) : {
+               KEEP(*(.__bss_end));
+       }
+
+       /*
+        * Zynq needs to discard these sections because the user
+        * is expected to pass this image on to tools for boot.bin
+        * generation that require them to be dropped.
+        */
+       /DISCARD/ : { *(.dynsym) }
+       /DISCARD/ : { *(.dynbss*) }
+       /DISCARD/ : { *(.dynstr*) }
+       /DISCARD/ : { *(.dynamic*) }
+       /DISCARD/ : { *(.plt*) }
+       /DISCARD/ : { *(.interp*) }
+       /DISCARD/ : { *(.gnu*) }
+       /DISCARD/ : { *(.ARM.exidx*) }
+       /DISCARD/ : { *(.gnu.linkonce.armexidx.*) }
+}
index f613b92047046a7fd09552acd6d5a8fa7489badd..b83e037f6f595bf56ea44f6eaf8ffc52e1d48ae2 100644 (file)
 # define CONFIG_SYS_MMC_MAX_DEVICE     1
 #endif
 
-#define CONFIG_SYS_LDSCRIPT  "arch/arm/cpu/armv7/zynq/u-boot.lds"
+#define CONFIG_SYS_LDSCRIPT  "arch/arm/mach-zynq/u-boot.lds"
 
 /* Commands */
 #include <config_cmd_default.h>
 #define CONFIG_SPL_SERIAL_SUPPORT
 #define CONFIG_SPL_BOARD_INIT
 
-#define CONFIG_SPL_LDSCRIPT    "arch/arm/cpu/armv7/zynq/u-boot-spl.lds"
+#define CONFIG_SPL_LDSCRIPT    "arch/arm/mach-zynq/u-boot-spl.lds"
 
 /* MMC support */
 #ifdef CONFIG_ZYNQ_SDHCI0