mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH v3 0/5] ARM: add support for Zynq
@ 2013-03-25 13:02 Steffen Trumtrar
  2013-03-25 13:02 ` [PATCH v3 1/5] serial: Add driver for Cadence UART Steffen Trumtrar
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Steffen Trumtrar @ 2013-03-25 13:02 UTC (permalink / raw)
  To: barebox; +Cc: Steffen Trumtrar

Hi!

Next shot at Zynq support.
I addressed all/most comments from Jean-Christophe and Josh
(changelogs are in the respective patches).
The lowlevel stuff is still suboptimal with a bunch of writels.
Reason: no complete clk- and no pinctrl-support yet. This will be added
next.

Regards,
Steffen

Steffen Trumtrar (5):
  serial: Add driver for Cadence UART
  ARM: zynq: Add new architecture zynq
  ARM: zynq: add clk support for zynq7000
  ARM: zynq: add zynq fsbl checksum script
  ARM: zynq: Add support for the Avnet Zedboard

 arch/arm/Kconfig                                   |   5 +
 arch/arm/Makefile                                  |   2 +
 arch/arm/boards/avnet-zedboard/Makefile            |   3 +
 arch/arm/boards/avnet-zedboard/board.c             |  38 ++
 arch/arm/boards/avnet-zedboard/config.h            |   4 +
 .../boards/avnet-zedboard/env/init/config-board    |   7 +
 arch/arm/boards/avnet-zedboard/flash_header.c      |  62 +++
 arch/arm/boards/avnet-zedboard/lowlevel.c          | 252 +++++++++++++
 arch/arm/configs/zedboard_defconfig                |  49 +++
 arch/arm/mach-zynq/Kconfig                         |  38 ++
 arch/arm/mach-zynq/Makefile                        |   1 +
 arch/arm/mach-zynq/clk-zynq7000.c                  | 417 +++++++++++++++++++++
 arch/arm/mach-zynq/devices.c                       |   8 +
 arch/arm/mach-zynq/include/mach/barebox.lds.h      |   8 +
 arch/arm/mach-zynq/include/mach/clkdev.h           |   6 +
 arch/arm/mach-zynq/include/mach/debug_ll.h         |  37 ++
 arch/arm/mach-zynq/include/mach/devices.h          |  13 +
 .../arm/mach-zynq/include/mach/zynq-flash-header.h |  38 ++
 arch/arm/mach-zynq/include/mach/zynq7000-regs.h    | 132 +++++++
 arch/arm/mach-zynq/zynq.c                          |  56 +++
 drivers/serial/Kconfig                             |   5 +
 drivers/serial/Makefile                            |   1 +
 drivers/serial/serial_cadence.c                    | 307 +++++++++++++++
 include/asm-generic/barebox.lds.h                  |   3 +-
 scripts/Makefile                                   |   1 +
 scripts/zynq_checksum.c                            |  72 ++++
 26 files changed, 1564 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boards/avnet-zedboard/Makefile
 create mode 100644 arch/arm/boards/avnet-zedboard/board.c
 create mode 100644 arch/arm/boards/avnet-zedboard/config.h
 create mode 100644 arch/arm/boards/avnet-zedboard/env/init/config-board
 create mode 100644 arch/arm/boards/avnet-zedboard/flash_header.c
 create mode 100644 arch/arm/boards/avnet-zedboard/lowlevel.c
 create mode 100644 arch/arm/configs/zedboard_defconfig
 create mode 100644 arch/arm/mach-zynq/Kconfig
 create mode 100644 arch/arm/mach-zynq/Makefile
 create mode 100644 arch/arm/mach-zynq/clk-zynq7000.c
 create mode 100644 arch/arm/mach-zynq/devices.c
 create mode 100644 arch/arm/mach-zynq/include/mach/barebox.lds.h
 create mode 100644 arch/arm/mach-zynq/include/mach/clkdev.h
 create mode 100644 arch/arm/mach-zynq/include/mach/debug_ll.h
 create mode 100644 arch/arm/mach-zynq/include/mach/devices.h
 create mode 100644 arch/arm/mach-zynq/include/mach/zynq-flash-header.h
 create mode 100644 arch/arm/mach-zynq/include/mach/zynq7000-regs.h
 create mode 100644 arch/arm/mach-zynq/zynq.c
 create mode 100644 drivers/serial/serial_cadence.c
 create mode 100644 scripts/zynq_checksum.c

-- 
1.8.2.rc2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v3 1/5] serial: Add driver for Cadence UART
  2013-03-25 13:02 [PATCH v3 0/5] ARM: add support for Zynq Steffen Trumtrar
@ 2013-03-25 13:02 ` Steffen Trumtrar
  2013-03-25 13:02 ` [PATCH v3 2/5] ARM: zynq: Add new architecture zynq Steffen Trumtrar
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Steffen Trumtrar @ 2013-03-25 13:02 UTC (permalink / raw)
  To: barebox; +Cc: Steffen Trumtrar

Support for Cadence UART core.

Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
---

Changes since v2:
	- remove superfluous Kconfig option
	- add help text to Kconfig option

 drivers/serial/Kconfig          |   5 +
 drivers/serial/Makefile         |   1 +
 drivers/serial/serial_cadence.c | 307 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 313 insertions(+)
 create mode 100644 drivers/serial/serial_cadence.c

diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index f61d670..73cb9f8 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -113,4 +113,9 @@ config DRIVER_SERIAL_OMAP4_USBBOOT
 	help
 	  Enable this to get console support over the usb bus used to boot an OMAP4
 
+config DRIVER_SERIAL_CADENCE
+	bool "Cadence UART driver"
+	help
+	  Say Y here if you have a Cadence serial IP core.
+
 endmenu
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 893e282..963a7df 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -21,3 +21,4 @@ obj-$(CONFIG_DRIVER_SERIAL_ALTERA)		+= serial_altera.o
 obj-$(CONFIG_DRIVER_SERIAL_ALTERA_JTAG)		+= serial_altera_jtag.o
 obj-$(CONFIG_DRIVER_SERIAL_PXA)			+= serial_pxa.o
 obj-$(CONFIG_DRIVER_SERIAL_OMAP4_USBBOOT)	+= serial_omap4_usbboot.o
+obj-$(CONFIG_DRIVER_SERIAL_CADENCE)		+= serial_cadence.o
diff --git a/drivers/serial/serial_cadence.c b/drivers/serial/serial_cadence.c
new file mode 100644
index 0000000..c29c391
--- /dev/null
+++ b/drivers/serial/serial_cadence.c
@@ -0,0 +1,307 @@
+/*
+ * (c) 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <common.h>
+#include <driver.h>
+#include <init.h>
+#include <malloc.h>
+#include <notifier.h>
+#include <io.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+
+#define CADENCE_UART_CONTROL		0x00
+#define CADENCE_UART_MODE		0x04
+#define CADENCE_UART_BAUD_GEN		0x18
+#define CADENCE_UART_CHANNEL_STS	0x2C
+#define CADENCE_UART_RXTXFIFO		0x30
+#define CADENCE_UART_BAUD_DIV		0x34
+
+#define CADENCE_CTRL_RXRES		(1 << 0)
+#define CADENCE_CTRL_TXRES		(1 << 1)
+#define CADENCE_CTRL_RXEN		(1 << 2)
+#define CADENCE_CTRL_RXDIS		(1 << 3)
+#define CADENCE_CTRL_TXEN		(1 << 4)
+#define CADENCE_CTRL_TXDIS		(1 << 5)
+#define CADENCE_CTRL_RSTTO		(1 << 6)
+#define CADENCE_CTRL_STTBRK		(1 << 7)
+#define CADENCE_CTRL_STPBRK		(1 << 8)
+
+#define CADENCE_MODE_CLK_REF		(0 << 0)
+#define CADENCE_MODE_CLK_REF_DIV	(1 << 0)
+#define CADENCE_MODE_CHRL_6		(3 << 1)
+#define CADENCE_MODE_CHRL_7		(2 << 1)
+#define CADENCE_MODE_CHRL_8		(0 << 1)
+#define CADENCE_MODE_PAR_EVEN		(0 << 3)
+#define CADENCE_MODE_PAR_ODD		(1 << 3)
+#define CADENCE_MODE_PAR_SPACE		(2 << 3)
+#define CADENCE_MODE_PAR_MARK		(3 << 3)
+#define CADENCE_MODE_PAR_NONE		(4 << 3)
+
+#define CADENCE_STS_REMPTY		(1 << 1)
+#define CADENCE_STS_RFUL		(1 << 2)
+#define CADENCE_STS_TEMPTY		(1 << 3)
+#define CADENCE_STS_TFUL		(1 << 4)
+
+/*
+ * create default values for different platforms
+ */
+struct cadence_serial_devtype_data {
+	u32 ctrl;
+	u32 mode;
+};
+
+static struct cadence_serial_devtype_data cadence_r1p08_data = {
+	.ctrl = CADENCE_CTRL_RXEN | CADENCE_CTRL_TXEN,
+	.mode = CADENCE_MODE_CLK_REF | CADENCE_MODE_CHRL_8 | CADENCE_MODE_PAR_NONE,
+};
+
+struct cadence_serial_priv {
+	struct console_device cdev;
+	int baudrate;
+	struct notifier_block notify;
+	void __iomem *regs;
+	struct clk *clk;
+	struct cadence_serial_devtype_data *devtype;
+};
+
+static int cadence_serial_reset(struct console_device *cdev)
+{
+	struct cadence_serial_priv *priv = container_of(cdev,
+					struct cadence_serial_priv, cdev);
+
+	/* Soft-Reset Tx/Rx paths */
+	writel(CADENCE_CTRL_RXRES | CADENCE_CTRL_TXRES, priv->regs +
+		CADENCE_UART_CONTROL);
+
+	while (readl(priv->regs + CADENCE_UART_CONTROL) &
+		(CADENCE_CTRL_RXRES | CADENCE_CTRL_TXRES))
+		;
+
+	return 0;
+}
+
+static int cadence_serial_setbaudrate(struct console_device *cdev, int baudrate)
+{
+	struct cadence_serial_priv *priv = container_of(cdev,
+					struct cadence_serial_priv, cdev);
+	unsigned int gen, div;
+	int calc_rate;
+	unsigned long clk;
+	int error;
+	int val;
+
+	clk = clk_get_rate(priv->clk);
+	priv->baudrate = baudrate;
+
+	/* disable transmitter and receiver */
+	val = readl(priv->regs + CADENCE_UART_CONTROL);
+	val &= ~CADENCE_CTRL_TXEN & ~CADENCE_CTRL_RXEN;
+	writel(val, priv->regs + CADENCE_UART_CONTROL);
+
+	/*
+	 *	      clk
+	 * rate = -----------
+	 *	  gen*(div+1)
+	 */
+
+	for (div = 4; div < 256; div++) {
+		gen = clk / (baudrate * (div + 1));
+
+		if (gen < 1 || gen > 65535)
+			continue;
+
+		calc_rate = clk / (gen * (div + 1));
+		error = baudrate - calc_rate;
+		if (error < 0)
+			error *= -1;
+		if (((error * 100) / baudrate) < 3)
+			break;
+	}
+
+	writel(gen, priv->regs + CADENCE_UART_BAUD_GEN);
+	writel(div, priv->regs + CADENCE_UART_BAUD_DIV);
+
+	/* Soft-Reset Tx/Rx paths */
+	writel(CADENCE_CTRL_RXRES | CADENCE_CTRL_TXRES, priv->regs +
+		CADENCE_UART_CONTROL);
+
+	while (readl(priv->regs + CADENCE_UART_CONTROL) &
+		(CADENCE_CTRL_RXRES | CADENCE_CTRL_TXRES))
+		;
+
+	/* Enable UART */
+	writel(priv->devtype->ctrl, priv->regs + CADENCE_UART_CONTROL);
+
+	return 0;
+}
+
+static int cadence_serial_init_port(struct console_device *cdev)
+{
+	struct cadence_serial_priv *priv = container_of(cdev,
+					struct cadence_serial_priv, cdev);
+
+	cadence_serial_reset(cdev);
+
+	/* Enable UART */
+	writel(priv->devtype->ctrl, priv->regs + CADENCE_UART_CONTROL);
+	writel(priv->devtype->mode, priv->regs + CADENCE_UART_MODE);
+
+	return 0;
+}
+
+static void cadence_serial_putc(struct console_device *cdev, char c)
+{
+	struct cadence_serial_priv *priv = container_of(cdev,
+					struct cadence_serial_priv, cdev);
+
+	while ((readl(priv->regs + CADENCE_UART_CHANNEL_STS) &
+		CADENCE_STS_TFUL) != 0)
+		;
+
+	writel(c, priv->regs + CADENCE_UART_RXTXFIFO);
+}
+
+static int cadence_serial_tstc(struct console_device *cdev)
+{
+	struct cadence_serial_priv *priv = container_of(cdev,
+					struct cadence_serial_priv, cdev);
+
+	return ((readl(priv->regs + CADENCE_UART_CHANNEL_STS) &
+		 CADENCE_STS_REMPTY) == 0);
+}
+
+static int cadence_serial_getc(struct console_device *cdev)
+{
+	struct cadence_serial_priv *priv = container_of(cdev,
+					struct cadence_serial_priv, cdev);
+
+	while (!cadence_serial_tstc(cdev))
+		;
+
+	return readl(priv->regs + CADENCE_UART_RXTXFIFO);
+}
+
+static void cadence_serial_flush(struct console_device *cdev)
+{
+	struct cadence_serial_priv *priv = container_of(cdev,
+					struct cadence_serial_priv, cdev);
+
+	while ((readl(priv->regs + CADENCE_UART_CHANNEL_STS) &
+		CADENCE_STS_TEMPTY) != 0)
+		;
+}
+
+static int cadence_clocksource_clock_change(struct notifier_block *nb,
+			unsigned long event, void *data)
+{
+	struct cadence_serial_priv *priv = container_of(nb,
+					struct cadence_serial_priv, notify);
+
+	cadence_serial_setbaudrate(&priv->cdev, priv->baudrate);
+
+	return 0;
+}
+
+static int cadence_serial_probe(struct device_d *dev)
+{
+	struct console_device *cdev;
+	struct cadence_serial_priv *priv;
+	struct cadence_serial_devtype_data *devtype;
+	int ret;
+
+	ret = dev_get_drvdata(dev, (unsigned long *)&devtype);
+	if (ret)
+		return ret;
+
+	priv = xzalloc(sizeof(*priv));
+	priv->devtype = devtype;
+	cdev = &priv->cdev;
+	dev->priv = priv;
+
+	priv->clk = clk_get(dev, NULL);
+	if (IS_ERR(priv->clk)) {
+		ret = -ENODEV;
+		goto err_free;
+	}
+
+	if (devtype->mode & CADENCE_MODE_CLK_REF_DIV)
+		clk_set_rate(priv->clk, clk_get_rate(priv->clk) / 8);
+
+	priv->regs = dev_request_mem_region(dev, 0);
+	if (!priv->regs) {
+		ret = -EBUSY;
+		goto err_free;
+	}
+
+	cdev->dev = dev;
+	cdev->f_caps = CONSOLE_STDIN | CONSOLE_STDOUT | CONSOLE_STDERR;
+	cdev->tstc = cadence_serial_tstc;
+	cdev->putc = cadence_serial_putc;
+	cdev->getc = cadence_serial_getc;
+	cdev->flush = cadence_serial_flush;
+	cdev->setbrg = cadence_serial_setbaudrate;
+
+	cadence_serial_init_port(cdev);
+
+	console_register(cdev);
+	priv->notify.notifier_call = cadence_clocksource_clock_change;
+	clock_register_client(&priv->notify);
+
+	return 0;
+
+err_free:
+	free(priv);
+	return ret;
+}
+
+static void cadence_serial_remove(struct device_d *dev)
+{
+	struct cadence_serial_priv *priv = dev->priv;
+
+	console_unregister(&priv->cdev);
+	free(priv);
+}
+
+static __maybe_unused struct of_device_id cadence_serial_dt_ids[] = {
+	{
+		.compatible = "xlnx,xuartps",
+		.data = (unsigned long)&cadence_r1p08_data,
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct platform_device_id cadence_serial_ids[] = {
+	{
+		.name = "cadence-uart",
+		.driver_data = (unsigned long)&cadence_r1p08_data,
+	}, {
+		/* sentinel */
+	},
+};
+
+static struct driver_d cadence_serial_driver = {
+	.name   = "cadence_serial",
+	.probe  = cadence_serial_probe,
+	.remove = cadence_serial_remove,
+	.of_compatible = DRV_OF_COMPAT(cadence_serial_dt_ids),
+	.id_table = cadence_serial_ids,
+};
+
+static int cadence_serial_init(void)
+{
+	return platform_driver_register(&cadence_serial_driver);
+}
+console_initcall(cadence_serial_init);
-- 
1.8.2.rc2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v3 2/5] ARM: zynq: Add new architecture zynq
  2013-03-25 13:02 [PATCH v3 0/5] ARM: add support for Zynq Steffen Trumtrar
  2013-03-25 13:02 ` [PATCH v3 1/5] serial: Add driver for Cadence UART Steffen Trumtrar
@ 2013-03-25 13:02 ` Steffen Trumtrar
  2013-03-25 13:02 ` [PATCH v2 3/5] ARM: zynq: add clk support for zynq7000 Steffen Trumtrar
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Steffen Trumtrar @ 2013-03-25 13:02 UTC (permalink / raw)
  To: barebox; +Cc: Steffen Trumtrar

Add basic support for the Xilinx Zynq-7000 EPP architecture.
The Zynq-7000 is an embedded processing platform that combines a Cortex A9
dualcore MPSoC with an Artix-7 FPGA.

Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
---

Changes since v2:
	- don't force serial driver in Kconfig
	- remove MACH_HAS_LOWLEVEL_INIT
	- use (void __iomem *) in debug_ll.h
	- remove zynq_add_device inline function
	- use resource_size_t instead of void *
	- use __le32 consistently in zynq-flash-header.h
	- remove useless flash_header_start section

 arch/arm/Kconfig                                   |   5 +
 arch/arm/Makefile                                  |   2 +
 arch/arm/mach-zynq/Kconfig                         |  38 ++++++
 arch/arm/mach-zynq/Makefile                        |   1 +
 arch/arm/mach-zynq/devices.c                       |   8 ++
 arch/arm/mach-zynq/include/mach/barebox.lds.h      |   8 ++
 arch/arm/mach-zynq/include/mach/debug_ll.h         |  37 ++++++
 arch/arm/mach-zynq/include/mach/devices.h          |  13 ++
 .../arm/mach-zynq/include/mach/zynq-flash-header.h |  38 ++++++
 arch/arm/mach-zynq/include/mach/zynq7000-regs.h    | 132 +++++++++++++++++++++
 arch/arm/mach-zynq/zynq.c                          |  56 +++++++++
 include/asm-generic/barebox.lds.h                  |   3 +-
 12 files changed, 340 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/mach-zynq/Kconfig
 create mode 100644 arch/arm/mach-zynq/Makefile
 create mode 100644 arch/arm/mach-zynq/devices.c
 create mode 100644 arch/arm/mach-zynq/include/mach/barebox.lds.h
 create mode 100644 arch/arm/mach-zynq/include/mach/debug_ll.h
 create mode 100644 arch/arm/mach-zynq/include/mach/devices.h
 create mode 100644 arch/arm/mach-zynq/include/mach/zynq-flash-header.h
 create mode 100644 arch/arm/mach-zynq/include/mach/zynq7000-regs.h
 create mode 100644 arch/arm/mach-zynq/zynq.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 28332ec..8431fa8 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -110,6 +110,10 @@ config ARCH_TEGRA
 	select CPU_ARM926T
 	select HAS_DEBUG_LL
 
+config ARCH_ZYNQ
+	bool "Xilinx Zynq-based boards"
+	select HAS_DEBUG_LL
+
 endchoice
 
 source arch/arm/cpu/Kconfig
@@ -126,6 +130,7 @@ source arch/arm/mach-pxa/Kconfig
 source arch/arm/mach-samsung/Kconfig
 source arch/arm/mach-versatile/Kconfig
 source arch/arm/mach-tegra/Kconfig
+source arch/arm/mach-zynq/Kconfig
 
 config ARM_ASM_UNIFIED
 	bool
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index fcb2969..ceb45dc 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -64,6 +64,7 @@ machine-$(CONFIG_ARCH_PXA)		:= pxa
 machine-$(CONFIG_ARCH_SAMSUNG)		:= samsung
 machine-$(CONFIG_ARCH_VERSATILE)	:= versatile
 machine-$(CONFIG_ARCH_TEGRA)		:= tegra
+machine-$(CONFIG_ARCH_ZYNQ)		:= zynq
 
 # Board directory name.  This list is sorted alphanumerically
 # by CONFIG_* macro name.
@@ -157,6 +158,7 @@ board-$(CONFIG_MACH_SABRELITE)			:= freescale-mx6-sabrelite
 board-$(CONFIG_MACH_TX53)			:= karo-tx53
 board-$(CONFIG_MACH_GUF_VINCELL)		:= guf-vincell
 board-$(CONFIG_MACH_EFIKA_MX_SMARTBOOK)		:= efika-mx-smartbook
+board-$(CONFIG_MACH_ZEDBOARD)			:= avnet-zedboard
 
 machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
 
diff --git a/arch/arm/mach-zynq/Kconfig b/arch/arm/mach-zynq/Kconfig
new file mode 100644
index 0000000..5bbd648
--- /dev/null
+++ b/arch/arm/mach-zynq/Kconfig
@@ -0,0 +1,38 @@
+if ARCH_ZYNQ
+
+config ARCH_TEXT_BASE
+	hex
+	default 0x1ff00000 if MACH_ZEDBOARD
+
+config ZYNQ_DEBUG_LL_UART_BASE
+	hex
+	default 0xe0001000 if MACH_ZEDBOARD
+
+config BOARDINFO
+	default "ZedBoard" if MACH_ZEDBOARD
+
+choice
+	prompt "Xilinx Zynq type board"
+
+config ARCH_ZYNQ7000
+	bool "Zynq-7000"
+	select CPU_V7
+	select CLKDEV_LOOKUP
+	select COMMON_CLK
+	select ARM_SMP_TWD
+
+endchoice
+
+if ARCH_ZYNQ7000
+
+choice
+	prompt "Zynq-7000 Board Type"
+
+config MACH_ZEDBOARD
+	bool "Avnet Zynq-7000 ZedBoard"
+	select DRIVER_SERIAL_CADENCE
+
+endchoice
+endif
+
+endif
diff --git a/arch/arm/mach-zynq/Makefile b/arch/arm/mach-zynq/Makefile
new file mode 100644
index 0000000..459c957
--- /dev/null
+++ b/arch/arm/mach-zynq/Makefile
@@ -0,0 +1 @@
+obj-y += zynq.o devices.o clk-zynq7000.o
diff --git a/arch/arm/mach-zynq/devices.c b/arch/arm/mach-zynq/devices.c
new file mode 100644
index 0000000..777bb87
--- /dev/null
+++ b/arch/arm/mach-zynq/devices.c
@@ -0,0 +1,8 @@
+#include <common.h>
+#include <driver.h>
+#include <mach/devices.h>
+
+struct device_d *zynq_add_uart(resource_size_t base, int id)
+{
+	return add_generic_device("cadence-uart", id, NULL, base, 0x1000, IORESOURCE_MEM, NULL);
+}
diff --git a/arch/arm/mach-zynq/include/mach/barebox.lds.h b/arch/arm/mach-zynq/include/mach/barebox.lds.h
new file mode 100644
index 0000000..3d35fe9
--- /dev/null
+++ b/arch/arm/mach-zynq/include/mach/barebox.lds.h
@@ -0,0 +1,8 @@
+#define PRE_IMAGE \
+	.pre_image : {					\
+		. = 0x20;				\
+		KEEP(*(.flash_header_0x0*))		\
+		. = 0xa0;				\
+		KEEP(*(.ps7reg_entry_0x0A0))		\
+		. = 0x8c0;				\
+	}
diff --git a/arch/arm/mach-zynq/include/mach/debug_ll.h b/arch/arm/mach-zynq/include/mach/debug_ll.h
new file mode 100644
index 0000000..6c20dd5
--- /dev/null
+++ b/arch/arm/mach-zynq/include/mach/debug_ll.h
@@ -0,0 +1,37 @@
+/*
+ * based on mach-imx/include/mach/debug_ll.h
+ */
+
+#ifndef __MACH_DEBUG_LL_H__
+#define __MACH_DEBUG_LL_H__
+
+#include <io.h>
+#include <mach/zynq7000-regs.h>
+
+#ifndef CONFIG_ZYNQ_DEBUG_LL_UART_BASE
+#warning define ZYNQ_DEBUG_LL_UART_BASE properly for debug_ll
+#define ZYNQ_DEBUG_LL_UART_BASE ZYNQ_UART1_BASE_ADDR
+#else
+#define ZYNQ_DEBUG_LL_UART_BASE CONFIG_ZYNQ_DEBUG_LL_UART_BASE
+#endif
+
+#define ZYNQ_UART_RXTXFIFO	0x30
+#define ZYNQ_UART_CHANNEL_STS	0x2C
+
+#define ZYNQ_UART_STS_TFUL	(1 << 4)
+#define ZYNQ_UART_TXDIS		(1 << 5)
+
+static inline void PUTC_LL(int c)
+{
+	void __iomem *base = (void __iomem *)ZYNQ_DEBUG_LL_UART_BASE;
+
+	if (readl(base) & ZYNQ_UART_TXDIS)
+		return;
+
+	while ((readl(base + ZYNQ_UART_CHANNEL_STS) & ZYNQ_UART_STS_TFUL) != 0)
+		;
+
+	writel(c, base + ZYNQ_UART_RXTXFIFO);
+}
+
+#endif
diff --git a/arch/arm/mach-zynq/include/mach/devices.h b/arch/arm/mach-zynq/include/mach/devices.h
new file mode 100644
index 0000000..281d7c6
--- /dev/null
+++ b/arch/arm/mach-zynq/include/mach/devices.h
@@ -0,0 +1,13 @@
+#include <mach/zynq7000-regs.h>
+
+struct device_d *zynq_add_uart(resource_size_t base, int id);
+
+static inline struct device_d *zynq_add_uart0(void)
+{
+	return zynq_add_uart((resource_size_t)ZYNQ_UART0_BASE_ADDR, 0);
+}
+
+static inline struct device_d *zynq_add_uart1(void)
+{
+	return zynq_add_uart((resource_size_t)ZYNQ_UART1_BASE_ADDR, 1);
+}
diff --git a/arch/arm/mach-zynq/include/mach/zynq-flash-header.h b/arch/arm/mach-zynq/include/mach/zynq-flash-header.h
new file mode 100644
index 0000000..3b67e55
--- /dev/null
+++ b/arch/arm/mach-zynq/include/mach/zynq-flash-header.h
@@ -0,0 +1,38 @@
+#ifndef __MACH_FLASH_HEADER_H
+#define __MACH_FLASH_HEADER_H
+
+#include <asm-generic/sections.h>
+
+#define __flash_header_section		__section(.flash_header_0x0)
+#define __ps7reg_entry_section		__section(.ps7reg_entry_0x0A0)
+#define __image_len_section		__section(.image_len_0x08c0)
+#define FLASH_HEADER_OFFSET		0x0
+#define IMAGE_OFFSET			0x8c0
+
+#define DEST_BASE			0x8c0
+#define FLASH_HEADER_BASE	(DEST_BASE + FLASH_HEADER_OFFSET)
+
+struct zynq_reg_entry {
+	__le32 addr;
+	__le32 val;
+};
+
+#define WIDTH_DETECTION_MAGIC	0xAA995566
+#define IMAGE_IDENTIFICATION	0x584C4E58	/* "XLNX" */
+
+struct zynq_flash_header {
+	__le32 width_det;
+	__le32 image_id;
+	__le32 enc_stat;
+	__le32 user;
+	__le32 flash_offset;
+	__le32 length;
+	__le32 res0;
+	__le32 start_of_exec;
+	__le32 total_len;
+	__le32 res1;
+	__le32 checksum;
+	__le32 res2;
+};
+
+#endif /* __MACH_FLASH_HEADER_H */
diff --git a/arch/arm/mach-zynq/include/mach/zynq7000-regs.h b/arch/arm/mach-zynq/include/mach/zynq7000-regs.h
new file mode 100644
index 0000000..f5ccbb0
--- /dev/null
+++ b/arch/arm/mach-zynq/include/mach/zynq7000-regs.h
@@ -0,0 +1,132 @@
+/*
+ * (c) 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#define ZYNQ_UART0_BASE_ADDR		0xE0000000
+#define ZYNQ_UART1_BASE_ADDR		0xE0001000
+#define ZYNQ_I2C0_BASE_ADDR		0xE0004000
+#define ZYNQ_I2C1_BASE_ADDR		0xE0005000
+#define ZYNQ_SPI0_BASE_ADDR		0xE0006000
+#define ZYNQ_SPI1_BASE_ADDR		0xE0007000
+#define ZYNQ_CAN0_BASE_ADDR		0xE0008000
+#define ZYNQ_CAN1_BASE_ADDR		0xE0009000
+#define ZYNQ_GPIO_BASE_ADDR		0xE000A000
+
+#define ZYNQ_SLCR_BASE			0xF8000000
+#define ZYNQ_SLCR_SCL			(ZYNQ_SLCR_BASE + 0x000)
+#define ZYNQ_SLCR_LOCK			(ZYNQ_SLCR_BASE + 0x004)
+#define ZYNQ_SLCR_UNLOCK		(ZYNQ_SLCR_BASE + 0x008)
+#define ZYNQ_SLCR_LOCKSTA		(ZYNQ_SLCR_BASE + 0x00C)
+#define ZYNQ_CLOCK_CTRL_BASE		(ZYNQ_SLCR_BASE + 0x100)
+#define ZYNQ_ARM_PLL_CTRL		0x000
+#define ZYNQ_DDR_PLL_CTRL		0x004
+#define ZYNQ_IO_PLL_CTRL		0x008
+#define ZYNQ_PLL_STATUS			0x00C
+#define ZYNQ_ARM_PLL_CFG		0x010
+#define ZYNQ_DDR_PLL_CFG		0x014
+#define ZYNQ_IO_PLL_CFG			0x018
+#define ZYNQ_ARM_CLK_CTRL		0x020
+#define ZYNQ_DDR_CLK_CTRL		0x024
+#define ZYNQ_DCI_CLK_CTRL		0x028
+#define ZYNQ_APER_CLK_CTRL		0x02C
+#define ZYNQ_USB0_CLK_CTRL		0x030
+#define ZYNQ_USB1_CLK_CTRL		0x034
+#define ZYNQ_GEM0_RCLK_CTRL		0x038
+#define ZYNQ_GEM1_RCLK_CTRL		0x03C
+#define ZYNQ_GEM0_CLK_CTRL		0x040
+#define ZYNQ_GEM1_CLK_CTRL		0x044
+#define ZYNQ_SMC_CLK_CTRL		0x048
+#define ZYNQ_LQSPI_CLK_CTRL		0x04C
+#define ZYNQ_SDIO_CLK_CTRL		0x050
+#define ZYNQ_UART_CLK_CTRL		0x054
+#define ZYNQ_SPI_CLK_CTRL		0x058
+#define ZYNQ_CAN_CLK_CTRL		0x05C
+#define ZYNQ_CAN_MIOCLK_CTRL		0x060
+#define ZYNQ_DBG_CLK_CTRL		0x064
+#define ZYNQ_PCAP_CLK_CTRL		0x068
+#define ZYNQ_TOPSW_CLK_CTRL		0x06C
+#define ZYNQ_FPGA0_CLK_CTRL		0x070
+#define ZYNQ_FPGA1_CLK_CTRL		0x080
+#define ZYNQ_FPGA2_CLK_CTRL		0x090
+#define ZYNQ_FPGA3_CLK_CTRL		0x0A0
+#define ZYNQ_CLK_621_TRUE		0x0C4
+#define ZYNQ_RST_CTRL_BASE		(ZYNQ_SLCR_BASE + 0x200)
+#define ZYNQ_PSS_RST_CTRL		(ZYNQ_RST_CTRL_BASE + 0x000)
+#define ZYNQ_DDR_RST_CTRL		(ZYNQ_RST_CTRL_BASE + 0x004)
+#define ZYNQ_TOPSW_RST_CTRL		(ZYNQ_RST_CTRL_BASE + 0x008)
+#define ZYNQ_DMAC_RST_CTRL		(ZYNQ_RST_CTRL_BASE + 0x00C)
+#define ZYNQ_USB_RST_CTRL		(ZYNQ_RST_CTRL_BASE + 0x010)
+#define ZYNQ_GEM_RST_CTRL		(ZYNQ_RST_CTRL_BASE + 0x014)
+#define ZYNQ_SDIO_RST_CTRL		(ZYNQ_RST_CTRL_BASE + 0x018)
+#define ZYNQ_SPI_RST_CTRL		(ZYNQ_RST_CTRL_BASE + 0x01C)
+#define ZYNQ_CAN_RST_CTRL		(ZYNQ_RST_CTRL_BASE + 0x020)
+#define ZYNQ_I2C_RST_CTRL		(ZYNQ_RST_CTRL_BASE + 0x024)
+#define ZYNQ_UART_RST_CTRL		(ZYNQ_RST_CTRL_BASE + 0x028)
+#define ZYNQ_GPIO_RST_CTRL		(ZYNQ_RST_CTRL_BASE + 0x02C)
+#define ZYNQ_LQSPI_RST_CTRL		(ZYNQ_RST_CTRL_BASE + 0x030)
+#define ZYNQ_SMC_RST_CTRL		(ZYNQ_RST_CTRL_BASE + 0x034)
+#define ZYNQ_OCM_RST_CTRL		(ZYNQ_RST_CTRL_BASE + 0x038)
+#define ZYNQ_DEVCI_RST_CTRL		(ZYNQ_RST_CTRL_BASE + 0x03C)
+#define ZYNQ_FPGA_RST_CTRL		(ZYNQ_RST_CTRL_BASE + 0x040)
+#define ZYNQ_A9_CPU_RST_CTRL		(ZYNQ_RST_CTRL_BASE + 0x044)
+#define ZYNQ_RS_AWDT_CTRL		(ZYNQ_RST_CTRL_BASE + 0x04C)
+#define ZYNQ_REBOOT_STATUS		(ZYNQ_SLCR_BASE + 0x258)
+#define ZYNQ_BOOT_MODE			(ZYNQ_SLCR_BASE + 0x25C)
+#define ZYNQ_APU_CTRL			(ZYNQ_SLCR_BASE + 0x300)
+#define ZYNQ_WDT_CLK_SEL		(ZYNQ_SLCR_BASE + 0x304)
+#define ZYNQ_PSS_IDCODE			(ZYNQ_SLCR_BASE + 0x530)
+#define ZYNQ_DDR_URGENT			(ZYNQ_SLCR_BASE + 0x600)
+#define ZYNQ_DDR_CAL_START		(ZYNQ_SLCR_BASE + 0x60C)
+#define ZYNQ_DDR_REF_START		(ZYNQ_SLCR_BASE + 0x614)
+#define ZYNQ_DDR_CMD_STA		(ZYNQ_SLCR_BASE + 0x618)
+#define ZYNQ_DDR_URGENT_SEL		(ZYNQ_SLCR_BASE + 0x61C)
+#define ZYNQ_DDR_DFI_STATUS		(ZYNQ_SLCR_BASE + 0x620)
+#define ZYNQ_MIO_BASE			(ZYNQ_SLCR_BASE + 0x700)
+#define ZYNQ_MIO_LOOPBACK		(ZYNQ_MIO_BASE + 0x104)
+#define ZYNQ_MIO_MST_TRI0		(ZYNQ_MIO_BASE + 0x10C)
+#define ZYNQ_MIO_MST_TRI1		(ZYNQ_MIO_BASE + 0x110)
+#define ZYNQ_SD0_WP_SEL			(ZYNQ_SLCR_BASE + 0x830)
+#define ZYNQ_SD1_WP_SEL			(ZYNQ_SLCR_BASE + 0x834)
+#define ZYNQ_LVL_SHIFTR_EN		(ZYNQ_SLCR_BASE + 0x900)
+#define ZYNQ_OCM_CFG			(ZYNQ_SLCR_BASE + 0x910)
+#define ZYNQ_GPIOB_BASE			(ZYNQ_SLCR_BASE + 0xB00)
+#define ZYNQ_GPIOB_CTRL			(ZYNQ_GPIOB_BASE + 0x000)
+#define ZYNQ_GPIOB_CFG_CMOS18		(ZYNQ_GPIOB_BASE + 0x004)
+#define ZYNQ_GPIOB_CFG_CMOS25		(ZYNQ_GPIOB_BASE + 0x008)
+#define ZYNQ_GPIOB_CFG_CMOS33		(ZYNQ_GPIOB_BASE + 0x00C)
+#define ZYNQ_GPIOB_CFG_LVTTL		(ZYNQ_GPIOB_BASE + 0x010)
+#define ZYNQ_GPIOB_CFG_HSTL		(ZYNQ_GPIOB_BASE + 0x014)
+#define ZYNQ_GPIOB_DRV_BIAS_CTRL	(ZYNQ_GPIOB_BASE + 0x018)
+#define ZYNQ_DDRIOB_BASE		(ZYNQ_SLCR_BASE + 0xB40)
+#define ZYNQ_DDRIOB_ADDR0		(ZYNQ_DDRIOB_BASE + 0x000)
+#define ZYNQ_DDRIOB_ADDR1		(ZYNQ_DDRIOB_BASE + 0x004)
+#define ZYNQ_DDRIOB_DATA0		(ZYNQ_DDRIOB_BASE + 0x008)
+#define ZYNQ_DDRIOB_DATA1		(ZYNQ_DDRIOB_BASE + 0x00C)
+#define ZYNQ_DDRIOB_DIFF0		(ZYNQ_DDRIOB_BASE + 0x010)
+#define ZYNQ_DDRIOB_DIFF1		(ZYNQ_DDRIOB_BASE + 0x014)
+#define ZYNQ_DDRIOB_CLOCK		(ZYNQ_DDRIOB_BASE + 0x018)
+#define ZYNQ_DDRIOB_DRIVE_SLEW_ADDR	(ZYNQ_DDRIOB_BASE + 0x01C)
+#define ZYNQ_DDRIOB_DRIVE_SLEW_DATA	(ZYNQ_DDRIOB_BASE + 0x020)
+#define ZYNQ_DDRIOB_DRIVE_SLEW_DIFF	(ZYNQ_DDRIOB_BASE + 0x024)
+#define ZYNQ_DDRIOB_DRIVE_SLEW_CLOCK	(ZYNQ_DDRIOB_BASE + 0x028)
+#define ZYNQ_DDRIOB_DDR_CTRL		(ZYNQ_DDRIOB_BASE + 0x02C)
+#define ZYNQ_DDRIOB_DCI_CTRL		(ZYNQ_DDRIOB_BASE + 0x030)
+#define ZYNQ_DDRIOB_DCI_STATUS		(ZYNQ_DDRIOB_BASE + 0x034)
+
+#define ZYNQ_TTC0_BASE_ADDR		0xF8001000
+#define ZYNQ_TTC1_BASE_ADDR		0xF8002000
+
+#define ZYNQ_DDRC_BASE			0xF8006000
+
+#define CORTEXA9_SCU_TIMER_BASE_ADDR	0xF8F00600
diff --git a/arch/arm/mach-zynq/zynq.c b/arch/arm/mach-zynq/zynq.c
new file mode 100644
index 0000000..bd29e13
--- /dev/null
+++ b/arch/arm/mach-zynq/zynq.c
@@ -0,0 +1,56 @@
+/*
+ * (c) 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <asm/system.h>
+#include <asm-generic/io.h>
+#include <common.h>
+#include <init.h>
+#include <mach/zynq7000-regs.h>
+
+static int zynq_init(void)
+{
+	u32 val;
+
+	dsb();
+	isb();
+	writel(0xDF0D, ZYNQ_SLCR_UNLOCK);
+	/* remap ocm high */
+	writel(0x0000000F, 0xf8000910);
+	/* mpcore.filtering_start_address */
+	writel(0x00000000, 0xf8f00040);
+	/* mpcore.filtering_end_address */
+	writel(0xffe00000, 0xf8f00044);
+	val = readl(0xf8f00000);
+	val |= 0x2;
+	writel(val, 0xf8f00000);
+	dmb();
+
+	add_generic_device("zynq-clock", 0, NULL, ZYNQ_SLCR_BASE, 0x4000, IORESOURCE_MEM, NULL);
+	add_generic_device("smp_twd", 0, NULL, CORTEXA9_SCU_TIMER_BASE_ADDR,
+				0x4000, IORESOURCE_MEM, NULL);
+	return 0;
+}
+postcore_initcall(zynq_init);
+
+void __noreturn reset_cpu(unsigned long addr)
+{
+	/* write unlock key to slcr */
+	writel(0xDF0D, ZYNQ_SLCR_UNLOCK);
+	/* reset */
+	writel(0x1, ZYNQ_PSS_RST_CTRL);
+
+	while (1)
+		;
+}
diff --git a/include/asm-generic/barebox.lds.h b/include/asm-generic/barebox.lds.h
index b2bd19e..0b98c96 100644
--- a/include/asm-generic/barebox.lds.h
+++ b/include/asm-generic/barebox.lds.h
@@ -5,7 +5,8 @@
 	defined CONFIG_ARCH_IMX53 || \
 	defined CONFIG_ARCH_IMX6 || \
 	defined CONFIG_X86 || \
-	defined CONFIG_ARCH_EP93XX
+	defined CONFIG_ARCH_EP93XX || \
+	defined CONFIG_ARCH_ZYNQ
 #include <mach/barebox.lds.h>
 #endif
 
-- 
1.8.2.rc2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v2 3/5] ARM: zynq: add clk support for zynq7000
  2013-03-25 13:02 [PATCH v3 0/5] ARM: add support for Zynq Steffen Trumtrar
  2013-03-25 13:02 ` [PATCH v3 1/5] serial: Add driver for Cadence UART Steffen Trumtrar
  2013-03-25 13:02 ` [PATCH v3 2/5] ARM: zynq: Add new architecture zynq Steffen Trumtrar
@ 2013-03-25 13:02 ` Steffen Trumtrar
  2013-03-25 13:02 ` [PATCH v2 4/5] ARM: zynq: add zynq fsbl checksum script Steffen Trumtrar
  2013-03-25 13:02 ` [PATCH v3 5/5] ARM: zynq: Add support for the Avnet Zedboard Steffen Trumtrar
  4 siblings, 0 replies; 7+ messages in thread
From: Steffen Trumtrar @ 2013-03-25 13:02 UTC (permalink / raw)
  To: barebox; +Cc: Steffen Trumtrar

This adds support for the clocktree on zynq7000 SoCs.
The patch is based on clocks.c from the larger patch
	ARM: zynq: add suppport for Zynq 7000 SoC
by Josh Cartwright.

The driver in that patch is converted to a platform_driver and code to
enable plls was added.

Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
---
 arch/arm/mach-zynq/clk-zynq7000.c        | 417 +++++++++++++++++++++++++++++++
 arch/arm/mach-zynq/include/mach/clkdev.h |   6 +
 2 files changed, 423 insertions(+)
 create mode 100644 arch/arm/mach-zynq/clk-zynq7000.c
 create mode 100644 arch/arm/mach-zynq/include/mach/clkdev.h

diff --git a/arch/arm/mach-zynq/clk-zynq7000.c b/arch/arm/mach-zynq/clk-zynq7000.c
new file mode 100644
index 0000000..1e03514
--- /dev/null
+++ b/arch/arm/mach-zynq/clk-zynq7000.c
@@ -0,0 +1,417 @@
+/*
+ * Copyright (c) 2013 Josh Cartwright <joshc@eso.teric.us>
+ * Copyright (c) 2013 Steffen Trumtrar <s.trumtrar@pengutronix.de>
+ *
+ * Based on drivers/clk-zynq.c from Linux.
+ *
+ * Copyright (c) 2012 National Instruments
+ *
+ * Josh Cartwright <josh.cartwright@ni.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <common.h>
+#include <init.h>
+#include <io.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <mach/zynq7000-regs.h>
+#include <malloc.h>
+
+enum zynq_clks {
+	dummy, ps_clk, arm_pll, ddr_pll, io_pll, uart_clk, uart0, uart1,
+	cpu_clk, cpu_6x4x, cpu_3x2x, cpu_2x, cpu_1x, clks_max
+};
+
+enum zynq_pll_type {
+	ZYNQ_PLL_ARM,
+	ZYNQ_PLL_DDR,
+	ZYNQ_PLL_IO,
+};
+
+#define PLL_STATUS_ARM_PLL_LOCK		(1 << 0)
+#define PLL_STATUS_DDR_PLL_LOCK		(1 << 1)
+#define PLL_STATUS_IO_PLL_LOCK		(1 << 2)
+#define PLL_STATUS_ARM_PLL_STABLE	(1 << 0)
+#define PLL_STATUS_DDR_PLL_STABLE	(1 << 1)
+#define PLL_STATUS_IO_PLL_STABLE	(1 << 2)
+#define PLL_CTRL_BYPASS_FORCE		(1 << 4)
+
+static struct clk *clks[clks_max];
+
+struct zynq_pll_clk {
+	struct clk	clk;
+	u32		pll_lock;
+	void __iomem	*pll_ctrl;
+};
+
+#define to_zynq_pll_clk(c)	container_of(c, struct zynq_pll_clk, clk)
+
+#define PLL_CTRL_FDIV(x)	(((x) >> 12) & 0x7F)
+
+static unsigned long zynq_pll_recalc_rate(struct clk *clk,
+					  unsigned long parent_rate)
+{
+	struct zynq_pll_clk *pll = to_zynq_pll_clk(clk);
+	return parent_rate * PLL_CTRL_FDIV(readl(pll->pll_ctrl));
+}
+
+static int zynq_pll_enable(struct clk *clk)
+{
+	struct zynq_pll_clk *pll = to_zynq_pll_clk(clk);
+	u32 val;
+	int timeout = 10000;
+
+	val = readl(pll->pll_ctrl);
+	val &= ~PLL_CTRL_BYPASS_FORCE;
+	writel(val, pll->pll_ctrl);
+
+	while (timeout--) {
+		if (readl(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_PLL_STATUS) & pll->pll_lock)
+			break;
+	}
+
+	if (!timeout)
+		return -ETIMEDOUT;
+
+	return 0;
+}
+
+static struct clk_ops zynq_pll_clk_ops = {
+	.recalc_rate = zynq_pll_recalc_rate,
+	.enable = zynq_pll_enable,
+};
+
+static inline struct clk *zynq_pll_clk(enum zynq_pll_type type,
+				       const char *name,
+				       void __iomem *pll_ctrl)
+{
+	static const char *pll_parent = "ps_clk";
+	struct zynq_pll_clk *pll;
+	int ret;
+
+	pll = xzalloc(sizeof(*pll));
+	pll->pll_ctrl		= pll_ctrl;
+	pll->clk.ops		= &zynq_pll_clk_ops;
+	pll->clk.name		= name;
+	pll->clk.parent_names	= &pll_parent;
+	pll->clk.num_parents	= 1;
+
+	switch(type) {
+	case ZYNQ_PLL_ARM:
+		pll->pll_lock = PLL_STATUS_ARM_PLL_LOCK;
+		break;
+	case ZYNQ_PLL_DDR:
+		pll->pll_lock = PLL_STATUS_DDR_PLL_LOCK;
+		break;
+	case ZYNQ_PLL_IO:
+		pll->pll_lock = PLL_STATUS_IO_PLL_LOCK;
+		break;
+	}
+
+	ret = clk_register(&pll->clk);
+	if (ret) {
+		free(pll);
+		return ERR_PTR(ret);
+	}
+
+	return &pll->clk;
+}
+
+struct zynq_periph_clk {
+	struct clk	clk;
+	void __iomem	*clk_ctrl;
+};
+
+#define to_zynq_periph_clk(c)  container_of(c, struct zynq_periph_clk, c)
+
+static const u8 periph_clk_parent_map[] = {
+	0, 0, 1, 2
+};
+#define PERIPH_CLK_CTRL_SRC(x) (periph_clk_parent_map[((x) & 0x30) >> 4])
+#define PERIPH_CLK_CTRL_DIV(x) (((x) & 0x3F00) >> 8)
+
+static unsigned long zynq_periph_recalc_rate(struct clk *clk,
+					     unsigned long parent_rate)
+{
+	struct zynq_periph_clk *periph = to_zynq_periph_clk(clk);
+	return parent_rate / PERIPH_CLK_CTRL_DIV(readl(periph->clk_ctrl));
+}
+
+static int zynq_periph_get_parent(struct clk *clk)
+{
+	struct zynq_periph_clk *periph = to_zynq_periph_clk(clk);
+	return PERIPH_CLK_CTRL_SRC(readl(periph->clk_ctrl));
+}
+
+static const struct clk_ops zynq_periph_clk_ops = {
+	.recalc_rate	= zynq_periph_recalc_rate,
+	.get_parent	= zynq_periph_get_parent,
+};
+
+static struct clk *zynq_periph_clk(const char *name, void __iomem *clk_ctrl)
+{
+	static const char *peripheral_parents[] = {
+		"io_pll",
+		"arm_pll",
+		"ddr_pll",
+	};
+	struct zynq_periph_clk *periph;
+	int ret;
+
+	periph = xzalloc(sizeof(*periph));
+
+	periph->clk_ctrl	= clk_ctrl;
+	periph->clk.name	= name;
+	periph->clk.ops		= &zynq_periph_clk_ops;
+	periph->clk.parent_names = peripheral_parents;
+	periph->clk.num_parents	= ARRAY_SIZE(peripheral_parents);
+
+	ret = clk_register(&periph->clk);
+	if (ret) {
+		free(periph);
+		return ERR_PTR(ret);
+	}
+
+	return &periph->clk;
+}
+
+/* CPU Clock domain is modelled as a mux with 4 children subclks, whose
+ * derivative rates depend on CLK_621_TRUE
+ */
+
+struct zynq_cpu_clk {
+	struct clk	clk;
+	void __iomem	*clk_ctrl;
+};
+
+#define to_zynq_cpu_clk(c)	container_of(c, struct zynq_cpu_clk, c)
+
+static const u8 zynq_cpu_clk_parent_map[] = {
+	1, 1, 2, 0
+};
+#define CPU_CLK_SRCSEL(x)	(zynq_cpu_clk_parent_map[(((x) & 0x30) >> 4)])
+#define CPU_CLK_CTRL_DIV(x)	(((x) & 0x3F00) >> 8)
+
+static unsigned long zynq_cpu_clk_recalc_rate(struct clk *clk,
+					      unsigned long parent_rate)
+{
+	struct zynq_cpu_clk *cpuclk = to_zynq_cpu_clk(clk);
+	return parent_rate / CPU_CLK_CTRL_DIV(readl(cpuclk->clk_ctrl));
+}
+
+static int zynq_cpu_clk_get_parent(struct clk *clk)
+{
+	struct zynq_cpu_clk *cpuclk = to_zynq_cpu_clk(clk);
+	return CPU_CLK_SRCSEL(readl(cpuclk->clk_ctrl));
+}
+
+static const struct clk_ops zynq_cpu_clk_ops = {
+	.get_parent	= zynq_cpu_clk_get_parent,
+	.recalc_rate	= zynq_cpu_clk_recalc_rate,
+};
+
+static struct clk *zynq_cpu_clk(const char *name, void __iomem *clk_ctrl)
+{
+	static const char *cpu_parents[] = {
+		"io_pll",
+		"arm_pll",
+		"ddr_pll",
+	};
+	struct zynq_cpu_clk *cpu;
+	int ret;
+
+	cpu = xzalloc(sizeof(*cpu));
+
+	cpu->clk_ctrl		= clk_ctrl;
+	cpu->clk.ops		= &zynq_cpu_clk_ops;
+	cpu->clk.name		= name;
+	cpu->clk.parent_names	= cpu_parents;
+	cpu->clk.num_parents	= ARRAY_SIZE(cpu_parents);
+
+	ret = clk_register(&cpu->clk);
+	if (ret) {
+		free(cpu);
+		return ERR_PTR(ret);
+	}
+
+	return &cpu->clk;
+}
+
+enum zynq_cpu_subclk_which {
+	CPU_SUBCLK_6X4X,
+	CPU_SUBCLK_3X2X,
+	CPU_SUBCLK_2X,
+	CPU_SUBCLK_1X,
+};
+
+struct zynq_cpu_subclk {
+	struct clk	clk;
+	void __iomem	*clk_ctrl;
+	void __iomem	*clk_621;
+	enum zynq_cpu_subclk_which which;
+};
+
+#define CLK_621_TRUE(x)		((x) & 1)
+
+#define to_zynq_cpu_subclk(c)	container_of(c, struct zynq_cpu_subclk, c);
+
+static unsigned long zynq_cpu_subclk_recalc_rate(struct clk *clk,
+						 unsigned long parent_rate)
+{
+	unsigned long uninitialized_var(rate);
+	struct zynq_cpu_subclk *subclk;
+	bool is_621;
+
+	subclk = to_zynq_cpu_subclk(clk);
+	is_621 = CLK_621_TRUE(readl(subclk->clk_621));
+
+	switch (subclk->which) {
+	case CPU_SUBCLK_6X4X:
+		rate = parent_rate;
+		break;
+	case CPU_SUBCLK_3X2X:
+		rate = parent_rate / 2;
+		break;
+	case CPU_SUBCLK_2X:
+		rate = parent_rate / (is_621 ? 3 : 2);
+		break;
+	case CPU_SUBCLK_1X:
+		rate = parent_rate / (is_621 ? 6 : 4);
+		break;
+	};
+
+	return rate;
+}
+
+static int zynq_cpu_subclk_enable(struct clk *clk)
+{
+	struct zynq_cpu_subclk *subclk;
+	u32 tmp;
+
+	subclk = to_zynq_cpu_subclk(clk);
+
+	tmp = readl(subclk->clk_ctrl);
+	tmp |= 1 << (24 + subclk->which);
+	writel(tmp, subclk->clk_ctrl);
+
+	return 0;
+}
+
+static void zynq_cpu_subclk_disable(struct clk *clk)
+{
+	struct zynq_cpu_subclk *subclk;
+	u32 tmp;
+
+	subclk = to_zynq_cpu_subclk(clk);
+
+	tmp = readl(subclk->clk_ctrl);
+	tmp &= ~(1 << (24 + subclk->which));
+	writel(tmp, subclk->clk_ctrl);
+}
+
+static const struct clk_ops zynq_cpu_subclk_ops = {
+	.enable		= zynq_cpu_subclk_enable,
+	.disable	= zynq_cpu_subclk_disable,
+	.recalc_rate	= zynq_cpu_subclk_recalc_rate,
+};
+
+static struct clk *zynq_cpu_subclk(const char *name,
+				   enum zynq_cpu_subclk_which which,
+				   void __iomem *clk_ctrl,
+				   void __iomem *clk_621)
+{
+	static const char *subclk_parent = "cpu_clk";
+	struct zynq_cpu_subclk *subclk;
+	int ret;
+
+	subclk = xzalloc(sizeof(*subclk));
+
+	subclk->clk_ctrl	= clk_ctrl;
+	subclk->clk_621		= clk_621;
+	subclk->which		= which;
+	subclk->clk.name	= name;
+	subclk->clk.ops		= &zynq_cpu_subclk_ops;
+
+	subclk->clk.parent_names = &subclk_parent;
+	subclk->clk.num_parents	= 1;
+
+	ret = clk_register(&subclk->clk);
+	if (ret) {
+		free(subclk);
+		return ERR_PTR(ret);
+	}
+
+	return &subclk->clk;
+}
+
+static int zynq_clock_probe(struct device_d *dev)
+{
+	void __iomem *slcr_base;
+	unsigned long ps_clk_rate = 33333330;
+
+	slcr_base = dev_request_mem_region(dev, 0);
+	if (!slcr_base)
+		return -EBUSY;
+
+	clks[ps_clk]  = clk_fixed("ps_clk", ps_clk_rate);
+
+	clks[arm_pll] = zynq_pll_clk(ZYNQ_PLL_ARM, "arm_pll", slcr_base + 0x100);
+	clks[ddr_pll] = zynq_pll_clk(ZYNQ_PLL_DDR, "ddr_pll", slcr_base + 0x104);
+	clks[io_pll]  = zynq_pll_clk(ZYNQ_PLL_IO,  "io_pll", slcr_base + 0x108);
+
+	clks[uart_clk] = zynq_periph_clk("uart_clk", slcr_base + 0x154);
+
+	clks[uart0] = clk_gate("uart0", "uart_clk", slcr_base + 0x154, 0);
+	clks[uart1] = clk_gate("uart1", "uart_clk", slcr_base + 0x154, 1);
+
+	clks[cpu_clk] = zynq_cpu_clk("cpu_clk", slcr_base + 0x120);
+
+	clks[cpu_6x4x] = zynq_cpu_subclk("cpu_6x4x", CPU_SUBCLK_6X4X,
+					slcr_base + 0x120, slcr_base + 0x1C4);
+	clks[cpu_3x2x] = zynq_cpu_subclk("cpu_3x2x", CPU_SUBCLK_3X2X,
+					slcr_base + 0x120, slcr_base + 0x1C4);
+	clks[cpu_2x] = zynq_cpu_subclk("cpu_2x", CPU_SUBCLK_2X,
+					slcr_base + 0x120, slcr_base + 0x1C4);
+	clks[cpu_1x] = zynq_cpu_subclk("cpu_1x", CPU_SUBCLK_1X,
+					slcr_base + 0x120, slcr_base + 0x1C4);
+
+	clk_register_clkdev(clks[cpu_3x2x], NULL, "arm_smp_twd");
+	clk_register_clkdev(clks[uart0], NULL, "zynq_serial0");
+	clk_register_clkdev(clks[uart1], NULL, "zynq_serial1");
+
+	clkdev_add_physbase(clks[cpu_3x2x], CORTEXA9_SCU_TIMER_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[uart1], ZYNQ_UART1_BASE_ADDR, NULL);
+	return 0;
+}
+
+static __maybe_unused struct of_device_id zynq_clock_dt_ids[] = {
+	{
+		.compatible = "xlnx,zynq-clock",
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct driver_d zynq_clock_driver = {
+	.probe  = zynq_clock_probe,
+	.name   = "zynq-clock",
+	.of_compatible = DRV_OF_COMPAT(zynq_clock_dt_ids),
+};
+
+static int zynq_clock_init(void)
+{
+	return platform_driver_register(&zynq_clock_driver);
+}
+postcore_initcall(zynq_clock_init);
diff --git a/arch/arm/mach-zynq/include/mach/clkdev.h b/arch/arm/mach-zynq/include/mach/clkdev.h
new file mode 100644
index 0000000..31f7035
--- /dev/null
+++ b/arch/arm/mach-zynq/include/mach/clkdev.h
@@ -0,0 +1,6 @@
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+#endif
-- 
1.8.2.rc2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v2 4/5] ARM: zynq: add zynq fsbl checksum script
  2013-03-25 13:02 [PATCH v3 0/5] ARM: add support for Zynq Steffen Trumtrar
                   ` (2 preceding siblings ...)
  2013-03-25 13:02 ` [PATCH v2 3/5] ARM: zynq: add clk support for zynq7000 Steffen Trumtrar
@ 2013-03-25 13:02 ` Steffen Trumtrar
  2013-03-25 13:02 ` [PATCH v3 5/5] ARM: zynq: Add support for the Avnet Zedboard Steffen Trumtrar
  4 siblings, 0 replies; 7+ messages in thread
From: Steffen Trumtrar @ 2013-03-25 13:02 UTC (permalink / raw)
  To: barebox; +Cc: Steffen Trumtrar

The bootrom only reads an image if the correct checksum is present in the
header. The calculation is pretty simple:
sum over all words from 0x20 to 0x44
Two of this words are the image length. That is why the checksum can not be
calculated until barebox_image_size is known.
The easiest solution is a program that has to be run after make.

Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
---
 scripts/Makefile        |  1 +
 scripts/zynq_checksum.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 73 insertions(+)
 create mode 100644 scripts/zynq_checksum.c

diff --git a/scripts/Makefile b/scripts/Makefile
index 08b325c..41c892e 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -12,6 +12,7 @@ hostprogs-$(CONFIG_ARCH_NETX)    += gen_netx_image
 hostprogs-$(CONFIG_ARCH_OMAP)    += omap_signGP mk-am35xx-spi-image
 hostprogs-$(CONFIG_ARCH_S5PCxx)  += s5p_cksum
 hostprogs-$(CONFIG_ARCH_DAVINCI) += mkublheader
+hostprogs-$(CONFIG_ARCH_ZYNQ)	 += zynq_checksum
 
 HOSTLOADLIBES_omap4_usbboot = -lpthread
 omap4_usbboot-objs               := usb_linux.o omap4_usbboot.o
diff --git a/scripts/zynq_checksum.c b/scripts/zynq_checksum.c
new file mode 100644
index 0000000..f32db61
--- /dev/null
+++ b/scripts/zynq_checksum.c
@@ -0,0 +1,72 @@
+#include <endian.h>
+#include <errno.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+static void usage(char *name)
+{
+	printf("Usage: %s barebox.bin <outfile>\n", name);
+}
+
+int main(int argc, char *argv[])
+{
+	FILE *ifile, *ofile;
+	unsigned int *buf;
+	const char *infile;
+	const char *outfile;
+	struct stat st;
+	unsigned int i;
+	unsigned long sum = 0;
+
+	if (argc != 3) {
+		usage(argv[0]);
+		exit(1);
+	}
+
+	infile = argv[1];
+	outfile = argv[2];
+
+	if (stat(infile, &st) == -1) {
+		perror("stat");
+		exit(EXIT_FAILURE);
+	}
+
+	buf = malloc(sizeof(*buf) * st.st_size);
+	if (!buf) {
+		fprintf(stderr, "Unable to allocate buffer\n");
+		return -1;
+	}
+	ifile = fopen(infile, "rb");
+	if (!ifile) {
+		fprintf(stderr, "Cannot open %s for reading\n",
+			infile);
+		free(buf);
+		exit(EXIT_FAILURE);
+	}
+	ofile = fopen(outfile, "wb");
+	if (!ofile) {
+		fprintf(stderr, "Cannot open %s for writing\n",
+			outfile);
+		fclose(ifile);
+		free(buf);
+		exit(EXIT_FAILURE);
+	}
+
+	fread(buf, 4, st.st_size, ifile);
+
+	for (i = 0x8; i < 0x12; i++)
+		sum += htole32(buf[i]);
+
+	sum = ~sum;
+	buf[i] = sum;
+
+	fwrite(buf, st.st_size / 4, 4, ofile);
+
+	fclose(ofile);
+	fclose(ifile);
+	free(buf);
+
+	return 0;
+}
-- 
1.8.2.rc2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v3 5/5] ARM: zynq: Add support for the Avnet Zedboard
  2013-03-25 13:02 [PATCH v3 0/5] ARM: add support for Zynq Steffen Trumtrar
                   ` (3 preceding siblings ...)
  2013-03-25 13:02 ` [PATCH v2 4/5] ARM: zynq: add zynq fsbl checksum script Steffen Trumtrar
@ 2013-03-25 13:02 ` Steffen Trumtrar
  4 siblings, 0 replies; 7+ messages in thread
From: Steffen Trumtrar @ 2013-03-25 13:02 UTC (permalink / raw)
  To: barebox; +Cc: Steffen Trumtrar

The Avnet ZedBoard is an evalboard with a Zynq-7020 based MPSoC.
There is also a Digilent ZedBoard, that is the same but only for
academic customers.

Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
---

Changes since v2:
	- use pbl image
	- remove useless flash_header_start

 arch/arm/boards/avnet-zedboard/Makefile            |   3 +
 arch/arm/boards/avnet-zedboard/board.c             |  38 ++++
 arch/arm/boards/avnet-zedboard/config.h            |   4 +
 .../boards/avnet-zedboard/env/init/config-board    |   7 +
 arch/arm/boards/avnet-zedboard/flash_header.c      |  62 +++++
 arch/arm/boards/avnet-zedboard/lowlevel.c          | 252 +++++++++++++++++++++
 arch/arm/configs/zedboard_defconfig                |  49 ++++
 7 files changed, 415 insertions(+)
 create mode 100644 arch/arm/boards/avnet-zedboard/Makefile
 create mode 100644 arch/arm/boards/avnet-zedboard/board.c
 create mode 100644 arch/arm/boards/avnet-zedboard/config.h
 create mode 100644 arch/arm/boards/avnet-zedboard/env/init/config-board
 create mode 100644 arch/arm/boards/avnet-zedboard/flash_header.c
 create mode 100644 arch/arm/boards/avnet-zedboard/lowlevel.c
 create mode 100644 arch/arm/configs/zedboard_defconfig

diff --git a/arch/arm/boards/avnet-zedboard/Makefile b/arch/arm/boards/avnet-zedboard/Makefile
new file mode 100644
index 0000000..a2c3104
--- /dev/null
+++ b/arch/arm/boards/avnet-zedboard/Makefile
@@ -0,0 +1,3 @@
+obj-y += board.o
+lwl-y += lowlevel.o
+lwl-y += flash_header.o
diff --git a/arch/arm/boards/avnet-zedboard/board.c b/arch/arm/boards/avnet-zedboard/board.c
new file mode 100644
index 0000000..4e3d5a5
--- /dev/null
+++ b/arch/arm/boards/avnet-zedboard/board.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2013 Steffen Trumtrar <s.trumtrar@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <asm/armlinux.h>
+#include <common.h>
+#include <environment.h>
+#include <generated/mach-types.h>
+#include <init.h>
+#include <mach/devices.h>
+#include <mach/zynq7000-regs.h>
+#include <sizes.h>
+
+static int zedboard_mem_init(void)
+{
+	arm_add_mem_device("ram0", 0, SZ_512M);
+
+	return 0;
+}
+mem_initcall(zedboard_mem_init);
+
+static int zedboard_console_init(void)
+{
+	zynq_add_uart1();
+
+	return 0;
+}
+console_initcall(zedboard_console_init);
diff --git a/arch/arm/boards/avnet-zedboard/config.h b/arch/arm/boards/avnet-zedboard/config.h
new file mode 100644
index 0000000..ca15136
--- /dev/null
+++ b/arch/arm/boards/avnet-zedboard/config.h
@@ -0,0 +1,4 @@
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#endif	/* __CONFIG_H */
diff --git a/arch/arm/boards/avnet-zedboard/env/init/config-board b/arch/arm/boards/avnet-zedboard/env/init/config-board
new file mode 100644
index 0000000..9957653
--- /dev/null
+++ b/arch/arm/boards/avnet-zedboard/env/init/config-board
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+# board defaults, do not change in running system. Change /env/config
+# instead
+
+global.hostname=ZedBoard
+global.linux.bootargs.base="console=ttyPS1,115200"
diff --git a/arch/arm/boards/avnet-zedboard/flash_header.c b/arch/arm/boards/avnet-zedboard/flash_header.c
new file mode 100644
index 0000000..ea20524
--- /dev/null
+++ b/arch/arm/boards/avnet-zedboard/flash_header.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <common.h>
+#include <asm/byteorder.h>
+#include <mach/zynq-flash-header.h>
+#include <mach/zynq7000-regs.h>
+#include <asm/barebox-arm-head.h>
+
+#define REG(a, v) { .addr = cpu_to_le32(a), .val = cpu_to_le32(v), }
+
+struct zynq_reg_entry __ps7reg_entry_section reg_entry[] = {
+	REG(ZYNQ_SLCR_UNLOCK, 0x0000DF0D),
+	REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_CLK_621_TRUE, 0x00000001),
+	REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_APER_CLK_CTRL, 0x01FC044D),
+
+	REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_ARM_PLL_CTRL, 0x00028008),
+	REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_ARM_PLL_CFG, 0x000FA220),
+	REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_ARM_PLL_CTRL, 0x00028010),
+	REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_ARM_PLL_CTRL, 0x00028011),
+	REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_ARM_PLL_CTRL, 0x00028010),
+	REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_ARM_PLL_CTRL, 0x00028000),
+
+	REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_IO_PLL_CTRL, 0x0001E008),
+	REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_IO_PLL_CFG, 0x001452C0),
+	REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_IO_PLL_CTRL, 0x0001E010),
+	REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_IO_PLL_CTRL, 0x0001E011),
+	REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_IO_PLL_CTRL, 0x0001E010),
+	REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_IO_PLL_CTRL, 0x0001E000),
+
+	REG(0xf8000150, 0x00000a03),
+
+	/* stop */
+	REG(0xFFFFFFFF, 0x00000000),
+};
+
+struct zynq_flash_header __flash_header_section flash_header = {
+	.width_det		= WIDTH_DETECTION_MAGIC,
+	.image_id		= IMAGE_IDENTIFICATION,
+	.enc_stat		= 0x0,
+	.user			= 0x0,
+	.flash_offset		= 0x8c0,
+	.length			= barebox_image_size,
+	.res0			= 0x0,
+	.start_of_exec		= 0x0,
+	.total_len		= barebox_image_size,
+	.res1			= 0x1,
+	.checksum		= 0x0,
+	.res2			= 0x0,
+};
diff --git a/arch/arm/boards/avnet-zedboard/lowlevel.c b/arch/arm/boards/avnet-zedboard/lowlevel.c
new file mode 100644
index 0000000..b50886e
--- /dev/null
+++ b/arch/arm/boards/avnet-zedboard/lowlevel.c
@@ -0,0 +1,252 @@
+/*
+ *
+ * (c) 2013 Steffen Trumtrar <s.trumtrar@pengutronix.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <common.h>
+#include <io.h>
+#include <asm/barebox-arm.h>
+#include <asm/barebox-arm-head.h>
+#include <mach/zynq7000-regs.h>
+
+#define DCI_DONE	(1 << 13)
+#define PLL_ARM_LOCK	(1 << 0)
+#define PLL_DDR_LOCK	(1 << 1)
+#define PLL_IO_LOCK	(1 << 2)
+
+void __naked barebox_arm_reset_vector(void)
+{
+	/* open sesame */
+	writel(0x0000DF0D, ZYNQ_SLCR_UNLOCK);
+
+	/* turn on LD9 */
+	writel(0x00000200, 0xF800071C);
+	writel(0x00000080, 0xE000A204);
+	writel(0x00000080, 0xE000A000);
+
+	/* ps7_clock_init_data */
+	writel(0x1F000200, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_ARM_CLK_CTRL);
+	writel(0x00F00701, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_DCI_CLK_CTRL);
+	writel(0x00002803, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_UART_CLK_CTRL);
+	writel(0x00000A03, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_DBG_CLK_CTRL);
+	writel(0x00000501, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_PCAP_CLK_CTRL);
+	writel(0x00000000, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_TOPSW_CLK_CTRL);
+	writel(0x00100A00, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_FPGA0_CLK_CTRL);
+	writel(0x00100700, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_FPGA1_CLK_CTRL);
+	writel(0x00101400, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_FPGA2_CLK_CTRL);
+	writel(0x00101400, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_FPGA3_CLK_CTRL);
+	/* 6:2:1 mode */
+	writel(0x00000001, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_CLK_621_TRUE);
+	writel(0x01FC044D, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_APER_CLK_CTRL);
+
+	/* configure the PLLs */
+	/* ARM PLL */
+	writel(0x00028008, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_ARM_PLL_CTRL);
+	writel(0x000FA220, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_ARM_PLL_CFG);
+	writel(0x00028010, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_ARM_PLL_CTRL);
+	writel(0x00028011, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_ARM_PLL_CTRL);
+	writel(0x00028010, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_ARM_PLL_CTRL);
+
+	while (!(readl(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_PLL_STATUS) & PLL_ARM_LOCK))
+		;
+	writel(0x00028000, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_ARM_PLL_CTRL);
+
+	/* DDR PLL */
+	/* set to bypass mode */
+	writel(0x0001A018, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_DDR_PLL_CTRL);
+	/* assert reset */
+	writel(0x0001A019, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_DDR_PLL_CTRL);
+	/* set feedback divs */
+	writel(0x00020019, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_DDR_PLL_CTRL);
+	writel(0x0012C220, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_DDR_PLL_CFG);
+	/* set ddr2xclk and ddr3xclk: 3,2 */
+	writel(0x0C200003, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_DDR_CLK_CTRL);
+	/* deassert reset */
+	writel(0x00020018, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_DDR_PLL_CTRL);
+	/* wait pll lock */
+	while (!(readl(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_PLL_STATUS) & PLL_DDR_LOCK))
+		;
+	/* remove bypass mode */
+	writel(0x00020008, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_DDR_PLL_CTRL);
+
+	/* IO PLL */
+	writel(0x0001E008, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_IO_PLL_CTRL);
+	writel(0x001452C0, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_IO_PLL_CFG);
+	writel(0x0001E010, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_IO_PLL_CTRL);
+	writel(0x0001E011, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_IO_PLL_CTRL);
+	writel(0x0001E010, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_IO_PLL_CTRL);
+
+	while (!(readl(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_PLL_STATUS) & PLL_IO_LOCK))
+		;
+	writel(0x0001E000, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_IO_PLL_CTRL);
+
+	/*
+	 * INP_TYPE[1:2] = {off, vref, diff, lvcmos}
+	 * DCI_UPDATE[3], TERM_EN[4]
+	 * DCI_TYPE[5:6] = {off, drive, res, term}
+	 * IBUF_DISABLE_MODE[7] = {ibuf, ibuf_disable}
+	 * TERM_DISABLE_MODE[8] = {always, dynamic}
+	 * OUTPUT_EN[9:10] = {ibuf, res, res, obuf}
+	 * PULLUP_EN[11]
+	 */
+	writel(0x00000600, ZYNQ_DDRIOB_ADDR0);
+	writel(0x00000600, ZYNQ_DDRIOB_ADDR1);
+	writel(0x00000672, ZYNQ_DDRIOB_DATA0);
+	writel(0x00000672, ZYNQ_DDRIOB_DATA1);
+	writel(0x00000674, ZYNQ_DDRIOB_DIFF0);
+	writel(0x00000674, ZYNQ_DDRIOB_DIFF1);
+	writel(0x00000600, ZYNQ_DDRIOB_CLOCK);
+	/*
+	 * Drive_P[0:6], Drive_N[7:13]
+	 * Slew_P[14:18], Slew_N[19:23]
+	 * GTL[24:26], RTerm[27:31]
+	 */
+	writel(0x00D6861C, ZYNQ_DDRIOB_DRIVE_SLEW_ADDR);
+	writel(0x00F9861C, ZYNQ_DDRIOB_DRIVE_SLEW_DATA);
+	writel(0x00F9861C, ZYNQ_DDRIOB_DRIVE_SLEW_DIFF);
+	writel(0x00D6861C, ZYNQ_DDRIOB_DRIVE_SLEW_CLOCK);
+	/*
+	 * VREF_INT_EN[0]
+	 * VREF_SEL[1:4] = {0001=0.6V, 0100=0.75V, 1000=0.9V}
+	 * VREF_EXT_EN[5:6] = {dis/dis, dis/en, en/dis, en/en}
+	 * RES[7:8], REFIO_EN[9]
+	 */
+	/* FIXME: Xilinx sets this to internal, but Zedboard should support
+	   external VRef, too */
+	writel(0x00000E09, ZYNQ_DDRIOB_DDR_CTRL);
+	/*
+	 * RESET[0], ENABLE[1]
+	 * NREF_OPT1[6:7], NREF_OPT2[8:10], NREF_OPT4[11:13]
+	 * PREF_OPT1[14:15], PREF_OPT2[17:19], UPDATE_CONTROL[20]
+	 */
+	writel(0x00000021, ZYNQ_DDRIOB_DCI_CTRL);
+	writel(0x00000020, ZYNQ_DDRIOB_DCI_CTRL);
+	writel(0x00100823, ZYNQ_DDRIOB_DCI_CTRL);
+
+	while (!(readl(ZYNQ_DDRIOB_DCI_STATUS) & DCI_DONE))
+		;
+
+	writel(0x0E00E07F, 0xF8007000);
+
+	/* ps7_ddr_init_data */
+	writel(0x00000080, 0XF8006000);
+	writel(0x00081081, 0XF8006004);
+	writel(0x03C0780F, 0XF8006008);
+	writel(0x02001001, 0XF800600C);
+	writel(0x00014001, 0XF8006010);
+	writel(0x0004159B, 0XF8006014);
+	writel(0x452460D2, 0XF8006018);
+	writel(0x720238E5, 0XF800601C);
+	writel(0x272872D0, 0XF8006020);
+	writel(0x0000003C, 0XF8006024);
+	writel(0x00002007, 0XF8006028);
+	writel(0x00000008, 0XF800602C);
+	writel(0x00040930, 0XF8006030);
+	writel(0x00010694, 0XF8006034);
+	writel(0x00000000, 0XF8006038);
+	writel(0x00000777, 0XF800603C);
+	writel(0xFFF00000, 0XF8006040);
+	writel(0x0FF66666, 0XF8006044);
+	writel(0x0003C248, 0XF8006048);
+	writel(0x77010800, 0XF8006050);
+	writel(0x00000101, 0XF8006058);
+	writel(0x00005003, 0XF800605C);
+	writel(0x0000003E, 0XF8006060);
+	writel(0x00020000, 0XF8006064);
+	writel(0x00284141, 0XF8006068);
+	writel(0x00001610, 0XF800606C);
+	writel(0x00008000, 0XF80060A0);
+	writel(0x10200802, 0XF80060A4);
+	writel(0x0690CB73, 0XF80060A8);
+	writel(0x000001FE, 0XF80060AC);
+	writel(0x1CFFFFFF, 0XF80060B0);
+	writel(0x00000200, 0XF80060B4);
+	writel(0x00200066, 0XF80060B8);
+	writel(0x00000000, 0XF80060BC);
+	writel(0x00000000, 0XF80060C4);
+	writel(0x00000000, 0XF80060C8);
+	writel(0x00000000, 0XF80060DC);
+	writel(0x00000000, 0XF80060F0);
+	writel(0x00000008, 0XF80060F4);
+	writel(0x00000000, 0XF8006114);
+	writel(0x40000001, 0XF8006118);
+	writel(0x40000001, 0XF800611C);
+	writel(0x40000001, 0XF8006120);
+	writel(0x40000001, 0XF8006124);
+	writel(0x00033C03, 0XF800612C);
+	writel(0x00034003, 0XF8006130);
+	writel(0x0002F400, 0XF8006134);
+	writel(0x00030400, 0XF8006138);
+	writel(0x00000035, 0XF8006140);
+	writel(0x00000035, 0XF8006144);
+	writel(0x00000035, 0XF8006148);
+	writel(0x00000035, 0XF800614C);
+	writel(0x00000083, 0XF8006154);
+	writel(0x00000083, 0XF8006158);
+	writel(0x0000007F, 0XF800615C);
+	writel(0x00000078, 0XF8006160);
+	writel(0x00000124, 0XF8006168);
+	writel(0x00000125, 0XF800616C);
+	writel(0x00000112, 0XF8006170);
+	writel(0x00000116, 0XF8006174);
+	writel(0x000000C3, 0XF800617C);
+	writel(0x000000C3, 0XF8006180);
+	writel(0x000000BF, 0XF8006184);
+	writel(0x000000B8, 0XF8006188);
+	writel(0x10040080, 0XF8006190);
+	writel(0x0001FC82, 0XF8006194);
+	writel(0x00000000, 0XF8006204);
+	writel(0x000803FF, 0XF8006208);
+	writel(0x000803FF, 0XF800620C);
+	writel(0x000803FF, 0XF8006210);
+	writel(0x000803FF, 0XF8006214);
+	writel(0x000003FF, 0XF8006218);
+	writel(0x000003FF, 0XF800621C);
+	writel(0x000003FF, 0XF8006220);
+	writel(0x000003FF, 0XF8006224);
+	writel(0x00000000, 0XF80062A8);
+	writel(0x00000000, 0XF80062AC);
+	writel(0x00005125, 0XF80062B0);
+	writel(0x000012A8, 0XF80062B4);
+	writel(0x00000081, 0XF8006000);
+
+	/* poor mans pinctrl */
+	writel(0x000002E0, ZYNQ_MIO_BASE + 0xC0);
+	writel(0x000002E1, ZYNQ_MIO_BASE + 0xC4);
+	/* UART1 pinmux */
+	writel(0x000002E1, ZYNQ_MIO_BASE + 0xC8);
+	writel(0x000002E0, ZYNQ_MIO_BASE + 0xCC);
+
+	/* poor mans clkctrl */
+	writel(0x00001403, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_UART_CLK_CTRL);
+
+	writel(0x00000001, 0xf8000138);
+	writel(0x00100801, 0xf8000140);
+	writel(0x00000302, 0xf8000740);
+	writel(0x00000302, 0xf8000744);
+	writel(0x00000302, 0xf8000748);
+	writel(0x00000302, 0xf800074C);
+	writel(0x00000302, 0xf8000750);
+	writel(0x00000302, 0xf8000754);
+
+	writel(0x00000001, 0xf8000B00);
+
+	/* lock up. secure, secure */
+	writel(0x0000767B, ZYNQ_SLCR_LOCK);
+
+	arm_cpu_lowlevel_init();
+	barebox_arm_entry(0, SZ_512M, 0);
+}
diff --git a/arch/arm/configs/zedboard_defconfig b/arch/arm/configs/zedboard_defconfig
new file mode 100644
index 0000000..773177c
--- /dev/null
+++ b/arch/arm/configs/zedboard_defconfig
@@ -0,0 +1,49 @@
+CONFIG_ARCH_ZYNQ=y
+CONFIG_AEABI=y
+CONFIG_CMD_ARM_MMUINFO=y
+CONFIG_ARM_UNWIND=y
+CONFIG_PBL_IMAGE=y
+CONFIG_MMU=y
+CONFIG_STACK_SIZE=0xf000
+CONFIG_MALLOC_SIZE=0x8000000
+CONFIG_MALLOC_TLSF=y
+CONFIG_KALLSYMS=y
+CONFIG_LONGHELP=y
+CONFIG_HUSH_FANCY_PROMPT=y
+CONFIG_CMDLINE_EDITING=y
+CONFIG_AUTO_COMPLETE=y
+CONFIG_MENU=y
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/avnet-zedboard/env"
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_LL=y
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_EXPORT=y
+CONFIG_CMD_PRINTENV=y
+CONFIG_CMD_READLINE=y
+CONFIG_CMD_MENU=y
+CONFIG_CMD_MENU_MANAGEMENT=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_DIRNAME=y
+CONFIG_CMD_LN=y
+CONFIG_CMD_READLINK=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_BOOTM_SHOW_TYPE=y
+CONFIG_CMD_BOOTM_VERBOSE=y
+CONFIG_CMD_BOOTM_INITRD=y
+CONFIG_CMD_BOOTM_OFTREE=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_GO=y
+CONFIG_CMD_OFTREE=y
+CONFIG_CMD_OFTREE_PROBE=y
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_PARTITION=y
+CONFIG_CMD_CLK=y
+CONFIG_NET=y
+CONFIG_NET_DHCP=y
+# CONFIG_SPI is not set
+CONFIG_FS_TFTP=y
+CONFIG_DIGEST=y
+CONFIG_MD5=y
-- 
1.8.2.rc2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v3 5/5] ARM: zynq: Add support for the Avnet Zedboard
  2013-03-26  9:11 [PATCH v4 0/5] ARM: add support for Zynq Steffen Trumtrar
@ 2013-03-26  9:11 ` Steffen Trumtrar
  0 siblings, 0 replies; 7+ messages in thread
From: Steffen Trumtrar @ 2013-03-26  9:11 UTC (permalink / raw)
  To: barebox; +Cc: Steffen Trumtrar

The Avnet ZedBoard is an evalboard with a Zynq-7020 based MPSoC.
There is also a Digilent ZedBoard, that is the same but only for
academic customers.

Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
---

Changes since v2:
	- use pbl image
	- remove useless flash_header_start

 arch/arm/boards/avnet-zedboard/Makefile            |   3 +
 arch/arm/boards/avnet-zedboard/board.c             |  38 ++++
 arch/arm/boards/avnet-zedboard/config.h            |   4 +
 .../boards/avnet-zedboard/env/init/config-board    |   7 +
 arch/arm/boards/avnet-zedboard/flash_header.c      |  62 +++++
 arch/arm/boards/avnet-zedboard/lowlevel.c          | 252 +++++++++++++++++++++
 arch/arm/configs/zedboard_defconfig                |  49 ++++
 7 files changed, 415 insertions(+)
 create mode 100644 arch/arm/boards/avnet-zedboard/Makefile
 create mode 100644 arch/arm/boards/avnet-zedboard/board.c
 create mode 100644 arch/arm/boards/avnet-zedboard/config.h
 create mode 100644 arch/arm/boards/avnet-zedboard/env/init/config-board
 create mode 100644 arch/arm/boards/avnet-zedboard/flash_header.c
 create mode 100644 arch/arm/boards/avnet-zedboard/lowlevel.c
 create mode 100644 arch/arm/configs/zedboard_defconfig

diff --git a/arch/arm/boards/avnet-zedboard/Makefile b/arch/arm/boards/avnet-zedboard/Makefile
new file mode 100644
index 0000000..a2c3104
--- /dev/null
+++ b/arch/arm/boards/avnet-zedboard/Makefile
@@ -0,0 +1,3 @@
+obj-y += board.o
+lwl-y += lowlevel.o
+lwl-y += flash_header.o
diff --git a/arch/arm/boards/avnet-zedboard/board.c b/arch/arm/boards/avnet-zedboard/board.c
new file mode 100644
index 0000000..4e3d5a5
--- /dev/null
+++ b/arch/arm/boards/avnet-zedboard/board.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2013 Steffen Trumtrar <s.trumtrar@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <asm/armlinux.h>
+#include <common.h>
+#include <environment.h>
+#include <generated/mach-types.h>
+#include <init.h>
+#include <mach/devices.h>
+#include <mach/zynq7000-regs.h>
+#include <sizes.h>
+
+static int zedboard_mem_init(void)
+{
+	arm_add_mem_device("ram0", 0, SZ_512M);
+
+	return 0;
+}
+mem_initcall(zedboard_mem_init);
+
+static int zedboard_console_init(void)
+{
+	zynq_add_uart1();
+
+	return 0;
+}
+console_initcall(zedboard_console_init);
diff --git a/arch/arm/boards/avnet-zedboard/config.h b/arch/arm/boards/avnet-zedboard/config.h
new file mode 100644
index 0000000..ca15136
--- /dev/null
+++ b/arch/arm/boards/avnet-zedboard/config.h
@@ -0,0 +1,4 @@
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#endif	/* __CONFIG_H */
diff --git a/arch/arm/boards/avnet-zedboard/env/init/config-board b/arch/arm/boards/avnet-zedboard/env/init/config-board
new file mode 100644
index 0000000..9957653
--- /dev/null
+++ b/arch/arm/boards/avnet-zedboard/env/init/config-board
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+# board defaults, do not change in running system. Change /env/config
+# instead
+
+global.hostname=ZedBoard
+global.linux.bootargs.base="console=ttyPS1,115200"
diff --git a/arch/arm/boards/avnet-zedboard/flash_header.c b/arch/arm/boards/avnet-zedboard/flash_header.c
new file mode 100644
index 0000000..ea20524
--- /dev/null
+++ b/arch/arm/boards/avnet-zedboard/flash_header.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <common.h>
+#include <asm/byteorder.h>
+#include <mach/zynq-flash-header.h>
+#include <mach/zynq7000-regs.h>
+#include <asm/barebox-arm-head.h>
+
+#define REG(a, v) { .addr = cpu_to_le32(a), .val = cpu_to_le32(v), }
+
+struct zynq_reg_entry __ps7reg_entry_section reg_entry[] = {
+	REG(ZYNQ_SLCR_UNLOCK, 0x0000DF0D),
+	REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_CLK_621_TRUE, 0x00000001),
+	REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_APER_CLK_CTRL, 0x01FC044D),
+
+	REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_ARM_PLL_CTRL, 0x00028008),
+	REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_ARM_PLL_CFG, 0x000FA220),
+	REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_ARM_PLL_CTRL, 0x00028010),
+	REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_ARM_PLL_CTRL, 0x00028011),
+	REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_ARM_PLL_CTRL, 0x00028010),
+	REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_ARM_PLL_CTRL, 0x00028000),
+
+	REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_IO_PLL_CTRL, 0x0001E008),
+	REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_IO_PLL_CFG, 0x001452C0),
+	REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_IO_PLL_CTRL, 0x0001E010),
+	REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_IO_PLL_CTRL, 0x0001E011),
+	REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_IO_PLL_CTRL, 0x0001E010),
+	REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_IO_PLL_CTRL, 0x0001E000),
+
+	REG(0xf8000150, 0x00000a03),
+
+	/* stop */
+	REG(0xFFFFFFFF, 0x00000000),
+};
+
+struct zynq_flash_header __flash_header_section flash_header = {
+	.width_det		= WIDTH_DETECTION_MAGIC,
+	.image_id		= IMAGE_IDENTIFICATION,
+	.enc_stat		= 0x0,
+	.user			= 0x0,
+	.flash_offset		= 0x8c0,
+	.length			= barebox_image_size,
+	.res0			= 0x0,
+	.start_of_exec		= 0x0,
+	.total_len		= barebox_image_size,
+	.res1			= 0x1,
+	.checksum		= 0x0,
+	.res2			= 0x0,
+};
diff --git a/arch/arm/boards/avnet-zedboard/lowlevel.c b/arch/arm/boards/avnet-zedboard/lowlevel.c
new file mode 100644
index 0000000..b50886e
--- /dev/null
+++ b/arch/arm/boards/avnet-zedboard/lowlevel.c
@@ -0,0 +1,252 @@
+/*
+ *
+ * (c) 2013 Steffen Trumtrar <s.trumtrar@pengutronix.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <common.h>
+#include <io.h>
+#include <asm/barebox-arm.h>
+#include <asm/barebox-arm-head.h>
+#include <mach/zynq7000-regs.h>
+
+#define DCI_DONE	(1 << 13)
+#define PLL_ARM_LOCK	(1 << 0)
+#define PLL_DDR_LOCK	(1 << 1)
+#define PLL_IO_LOCK	(1 << 2)
+
+void __naked barebox_arm_reset_vector(void)
+{
+	/* open sesame */
+	writel(0x0000DF0D, ZYNQ_SLCR_UNLOCK);
+
+	/* turn on LD9 */
+	writel(0x00000200, 0xF800071C);
+	writel(0x00000080, 0xE000A204);
+	writel(0x00000080, 0xE000A000);
+
+	/* ps7_clock_init_data */
+	writel(0x1F000200, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_ARM_CLK_CTRL);
+	writel(0x00F00701, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_DCI_CLK_CTRL);
+	writel(0x00002803, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_UART_CLK_CTRL);
+	writel(0x00000A03, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_DBG_CLK_CTRL);
+	writel(0x00000501, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_PCAP_CLK_CTRL);
+	writel(0x00000000, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_TOPSW_CLK_CTRL);
+	writel(0x00100A00, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_FPGA0_CLK_CTRL);
+	writel(0x00100700, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_FPGA1_CLK_CTRL);
+	writel(0x00101400, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_FPGA2_CLK_CTRL);
+	writel(0x00101400, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_FPGA3_CLK_CTRL);
+	/* 6:2:1 mode */
+	writel(0x00000001, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_CLK_621_TRUE);
+	writel(0x01FC044D, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_APER_CLK_CTRL);
+
+	/* configure the PLLs */
+	/* ARM PLL */
+	writel(0x00028008, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_ARM_PLL_CTRL);
+	writel(0x000FA220, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_ARM_PLL_CFG);
+	writel(0x00028010, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_ARM_PLL_CTRL);
+	writel(0x00028011, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_ARM_PLL_CTRL);
+	writel(0x00028010, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_ARM_PLL_CTRL);
+
+	while (!(readl(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_PLL_STATUS) & PLL_ARM_LOCK))
+		;
+	writel(0x00028000, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_ARM_PLL_CTRL);
+
+	/* DDR PLL */
+	/* set to bypass mode */
+	writel(0x0001A018, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_DDR_PLL_CTRL);
+	/* assert reset */
+	writel(0x0001A019, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_DDR_PLL_CTRL);
+	/* set feedback divs */
+	writel(0x00020019, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_DDR_PLL_CTRL);
+	writel(0x0012C220, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_DDR_PLL_CFG);
+	/* set ddr2xclk and ddr3xclk: 3,2 */
+	writel(0x0C200003, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_DDR_CLK_CTRL);
+	/* deassert reset */
+	writel(0x00020018, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_DDR_PLL_CTRL);
+	/* wait pll lock */
+	while (!(readl(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_PLL_STATUS) & PLL_DDR_LOCK))
+		;
+	/* remove bypass mode */
+	writel(0x00020008, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_DDR_PLL_CTRL);
+
+	/* IO PLL */
+	writel(0x0001E008, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_IO_PLL_CTRL);
+	writel(0x001452C0, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_IO_PLL_CFG);
+	writel(0x0001E010, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_IO_PLL_CTRL);
+	writel(0x0001E011, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_IO_PLL_CTRL);
+	writel(0x0001E010, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_IO_PLL_CTRL);
+
+	while (!(readl(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_PLL_STATUS) & PLL_IO_LOCK))
+		;
+	writel(0x0001E000, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_IO_PLL_CTRL);
+
+	/*
+	 * INP_TYPE[1:2] = {off, vref, diff, lvcmos}
+	 * DCI_UPDATE[3], TERM_EN[4]
+	 * DCI_TYPE[5:6] = {off, drive, res, term}
+	 * IBUF_DISABLE_MODE[7] = {ibuf, ibuf_disable}
+	 * TERM_DISABLE_MODE[8] = {always, dynamic}
+	 * OUTPUT_EN[9:10] = {ibuf, res, res, obuf}
+	 * PULLUP_EN[11]
+	 */
+	writel(0x00000600, ZYNQ_DDRIOB_ADDR0);
+	writel(0x00000600, ZYNQ_DDRIOB_ADDR1);
+	writel(0x00000672, ZYNQ_DDRIOB_DATA0);
+	writel(0x00000672, ZYNQ_DDRIOB_DATA1);
+	writel(0x00000674, ZYNQ_DDRIOB_DIFF0);
+	writel(0x00000674, ZYNQ_DDRIOB_DIFF1);
+	writel(0x00000600, ZYNQ_DDRIOB_CLOCK);
+	/*
+	 * Drive_P[0:6], Drive_N[7:13]
+	 * Slew_P[14:18], Slew_N[19:23]
+	 * GTL[24:26], RTerm[27:31]
+	 */
+	writel(0x00D6861C, ZYNQ_DDRIOB_DRIVE_SLEW_ADDR);
+	writel(0x00F9861C, ZYNQ_DDRIOB_DRIVE_SLEW_DATA);
+	writel(0x00F9861C, ZYNQ_DDRIOB_DRIVE_SLEW_DIFF);
+	writel(0x00D6861C, ZYNQ_DDRIOB_DRIVE_SLEW_CLOCK);
+	/*
+	 * VREF_INT_EN[0]
+	 * VREF_SEL[1:4] = {0001=0.6V, 0100=0.75V, 1000=0.9V}
+	 * VREF_EXT_EN[5:6] = {dis/dis, dis/en, en/dis, en/en}
+	 * RES[7:8], REFIO_EN[9]
+	 */
+	/* FIXME: Xilinx sets this to internal, but Zedboard should support
+	   external VRef, too */
+	writel(0x00000E09, ZYNQ_DDRIOB_DDR_CTRL);
+	/*
+	 * RESET[0], ENABLE[1]
+	 * NREF_OPT1[6:7], NREF_OPT2[8:10], NREF_OPT4[11:13]
+	 * PREF_OPT1[14:15], PREF_OPT2[17:19], UPDATE_CONTROL[20]
+	 */
+	writel(0x00000021, ZYNQ_DDRIOB_DCI_CTRL);
+	writel(0x00000020, ZYNQ_DDRIOB_DCI_CTRL);
+	writel(0x00100823, ZYNQ_DDRIOB_DCI_CTRL);
+
+	while (!(readl(ZYNQ_DDRIOB_DCI_STATUS) & DCI_DONE))
+		;
+
+	writel(0x0E00E07F, 0xF8007000);
+
+	/* ps7_ddr_init_data */
+	writel(0x00000080, 0XF8006000);
+	writel(0x00081081, 0XF8006004);
+	writel(0x03C0780F, 0XF8006008);
+	writel(0x02001001, 0XF800600C);
+	writel(0x00014001, 0XF8006010);
+	writel(0x0004159B, 0XF8006014);
+	writel(0x452460D2, 0XF8006018);
+	writel(0x720238E5, 0XF800601C);
+	writel(0x272872D0, 0XF8006020);
+	writel(0x0000003C, 0XF8006024);
+	writel(0x00002007, 0XF8006028);
+	writel(0x00000008, 0XF800602C);
+	writel(0x00040930, 0XF8006030);
+	writel(0x00010694, 0XF8006034);
+	writel(0x00000000, 0XF8006038);
+	writel(0x00000777, 0XF800603C);
+	writel(0xFFF00000, 0XF8006040);
+	writel(0x0FF66666, 0XF8006044);
+	writel(0x0003C248, 0XF8006048);
+	writel(0x77010800, 0XF8006050);
+	writel(0x00000101, 0XF8006058);
+	writel(0x00005003, 0XF800605C);
+	writel(0x0000003E, 0XF8006060);
+	writel(0x00020000, 0XF8006064);
+	writel(0x00284141, 0XF8006068);
+	writel(0x00001610, 0XF800606C);
+	writel(0x00008000, 0XF80060A0);
+	writel(0x10200802, 0XF80060A4);
+	writel(0x0690CB73, 0XF80060A8);
+	writel(0x000001FE, 0XF80060AC);
+	writel(0x1CFFFFFF, 0XF80060B0);
+	writel(0x00000200, 0XF80060B4);
+	writel(0x00200066, 0XF80060B8);
+	writel(0x00000000, 0XF80060BC);
+	writel(0x00000000, 0XF80060C4);
+	writel(0x00000000, 0XF80060C8);
+	writel(0x00000000, 0XF80060DC);
+	writel(0x00000000, 0XF80060F0);
+	writel(0x00000008, 0XF80060F4);
+	writel(0x00000000, 0XF8006114);
+	writel(0x40000001, 0XF8006118);
+	writel(0x40000001, 0XF800611C);
+	writel(0x40000001, 0XF8006120);
+	writel(0x40000001, 0XF8006124);
+	writel(0x00033C03, 0XF800612C);
+	writel(0x00034003, 0XF8006130);
+	writel(0x0002F400, 0XF8006134);
+	writel(0x00030400, 0XF8006138);
+	writel(0x00000035, 0XF8006140);
+	writel(0x00000035, 0XF8006144);
+	writel(0x00000035, 0XF8006148);
+	writel(0x00000035, 0XF800614C);
+	writel(0x00000083, 0XF8006154);
+	writel(0x00000083, 0XF8006158);
+	writel(0x0000007F, 0XF800615C);
+	writel(0x00000078, 0XF8006160);
+	writel(0x00000124, 0XF8006168);
+	writel(0x00000125, 0XF800616C);
+	writel(0x00000112, 0XF8006170);
+	writel(0x00000116, 0XF8006174);
+	writel(0x000000C3, 0XF800617C);
+	writel(0x000000C3, 0XF8006180);
+	writel(0x000000BF, 0XF8006184);
+	writel(0x000000B8, 0XF8006188);
+	writel(0x10040080, 0XF8006190);
+	writel(0x0001FC82, 0XF8006194);
+	writel(0x00000000, 0XF8006204);
+	writel(0x000803FF, 0XF8006208);
+	writel(0x000803FF, 0XF800620C);
+	writel(0x000803FF, 0XF8006210);
+	writel(0x000803FF, 0XF8006214);
+	writel(0x000003FF, 0XF8006218);
+	writel(0x000003FF, 0XF800621C);
+	writel(0x000003FF, 0XF8006220);
+	writel(0x000003FF, 0XF8006224);
+	writel(0x00000000, 0XF80062A8);
+	writel(0x00000000, 0XF80062AC);
+	writel(0x00005125, 0XF80062B0);
+	writel(0x000012A8, 0XF80062B4);
+	writel(0x00000081, 0XF8006000);
+
+	/* poor mans pinctrl */
+	writel(0x000002E0, ZYNQ_MIO_BASE + 0xC0);
+	writel(0x000002E1, ZYNQ_MIO_BASE + 0xC4);
+	/* UART1 pinmux */
+	writel(0x000002E1, ZYNQ_MIO_BASE + 0xC8);
+	writel(0x000002E0, ZYNQ_MIO_BASE + 0xCC);
+
+	/* poor mans clkctrl */
+	writel(0x00001403, ZYNQ_CLOCK_CTRL_BASE + ZYNQ_UART_CLK_CTRL);
+
+	writel(0x00000001, 0xf8000138);
+	writel(0x00100801, 0xf8000140);
+	writel(0x00000302, 0xf8000740);
+	writel(0x00000302, 0xf8000744);
+	writel(0x00000302, 0xf8000748);
+	writel(0x00000302, 0xf800074C);
+	writel(0x00000302, 0xf8000750);
+	writel(0x00000302, 0xf8000754);
+
+	writel(0x00000001, 0xf8000B00);
+
+	/* lock up. secure, secure */
+	writel(0x0000767B, ZYNQ_SLCR_LOCK);
+
+	arm_cpu_lowlevel_init();
+	barebox_arm_entry(0, SZ_512M, 0);
+}
diff --git a/arch/arm/configs/zedboard_defconfig b/arch/arm/configs/zedboard_defconfig
new file mode 100644
index 0000000..773177c
--- /dev/null
+++ b/arch/arm/configs/zedboard_defconfig
@@ -0,0 +1,49 @@
+CONFIG_ARCH_ZYNQ=y
+CONFIG_AEABI=y
+CONFIG_CMD_ARM_MMUINFO=y
+CONFIG_ARM_UNWIND=y
+CONFIG_PBL_IMAGE=y
+CONFIG_MMU=y
+CONFIG_STACK_SIZE=0xf000
+CONFIG_MALLOC_SIZE=0x8000000
+CONFIG_MALLOC_TLSF=y
+CONFIG_KALLSYMS=y
+CONFIG_LONGHELP=y
+CONFIG_HUSH_FANCY_PROMPT=y
+CONFIG_CMDLINE_EDITING=y
+CONFIG_AUTO_COMPLETE=y
+CONFIG_MENU=y
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/avnet-zedboard/env"
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_LL=y
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_EXPORT=y
+CONFIG_CMD_PRINTENV=y
+CONFIG_CMD_READLINE=y
+CONFIG_CMD_MENU=y
+CONFIG_CMD_MENU_MANAGEMENT=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_DIRNAME=y
+CONFIG_CMD_LN=y
+CONFIG_CMD_READLINK=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_BOOTM_SHOW_TYPE=y
+CONFIG_CMD_BOOTM_VERBOSE=y
+CONFIG_CMD_BOOTM_INITRD=y
+CONFIG_CMD_BOOTM_OFTREE=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_GO=y
+CONFIG_CMD_OFTREE=y
+CONFIG_CMD_OFTREE_PROBE=y
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_PARTITION=y
+CONFIG_CMD_CLK=y
+CONFIG_NET=y
+CONFIG_NET_DHCP=y
+# CONFIG_SPI is not set
+CONFIG_FS_TFTP=y
+CONFIG_DIGEST=y
+CONFIG_MD5=y
-- 
1.8.2.rc2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2013-03-26  9:12 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-03-25 13:02 [PATCH v3 0/5] ARM: add support for Zynq Steffen Trumtrar
2013-03-25 13:02 ` [PATCH v3 1/5] serial: Add driver for Cadence UART Steffen Trumtrar
2013-03-25 13:02 ` [PATCH v3 2/5] ARM: zynq: Add new architecture zynq Steffen Trumtrar
2013-03-25 13:02 ` [PATCH v2 3/5] ARM: zynq: add clk support for zynq7000 Steffen Trumtrar
2013-03-25 13:02 ` [PATCH v2 4/5] ARM: zynq: add zynq fsbl checksum script Steffen Trumtrar
2013-03-25 13:02 ` [PATCH v3 5/5] ARM: zynq: Add support for the Avnet Zedboard Steffen Trumtrar
2013-03-26  9:11 [PATCH v4 0/5] ARM: add support for Zynq Steffen Trumtrar
2013-03-26  9:11 ` [PATCH v3 5/5] ARM: zynq: Add support for the Avnet Zedboard Steffen Trumtrar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox