]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
zynqmp: Changes to bring up on ep108 A53 RTL 3.1
authorSiva Durga Prasad Paladugu <siva.durga.paladugu@xilinx.com>
Tue, 8 Jul 2014 10:01:01 +0000 (15:31 +0530)
committerMichal Simek <michal.simek@xilinx.com>
Mon, 21 Jul 2014 14:36:38 +0000 (16:36 +0200)
Changes to bring up on ep108 A53.
ARM global timer is not working that's why TTC timer
is used instead.
Fixing GIC address and GIC version to fit RTL 3.1.

Signed-off-by: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
arch/arm/cpu/armv8/generic_timer.c
arch/arm/cpu/armv8/zynqmp/Makefile
arch/arm/cpu/armv8/zynqmp/clk.c
arch/arm/cpu/armv8/zynqmp/timer.c [new file with mode: 0644]
arch/arm/include/asm/arch-zynqmp/clk.h
arch/arm/include/asm/arch-zynqmp/hardware.h
board/xilinx/zynqmp/zynqmp.c

index 223b95e210edd7146c6a8549bbf7f43b362d105b..f0994693f361ca88d27abc36508fe71bfed34100 100644 (file)
@@ -9,6 +9,7 @@
 #include <command.h>
 #include <asm/system.h>
 
+#ifndef XILINX_ZYNQMP
 /*
  * Generic timer implementation of get_tbclk()
  */
@@ -18,6 +19,7 @@ unsigned long get_tbclk(void)
        asm volatile("mrs %0, cntfrq_el0" : "=r" (cntfrq));
        return cntfrq;
 }
+#endif
 
 /*
  * Generic timer implementation of timer_read_counter()
index 831d0256a4a12e257d45a68bf596d2b713c8bca9..2db71f1e25a9aaeaeb731ba5a0a89aab7c1edcfa 100644 (file)
@@ -6,3 +6,4 @@
 #
 
 obj-y  += clk.o
+obj-y  += timer.o
index 41fb60e9ba74f2aea42a62853e2e676eecb59c47..fef7cb7a8f1546f9def4ef191c4afdf2e72dc986 100644 (file)
@@ -9,3 +9,8 @@ unsigned long get_uart_clk(int dev_id)
 {
        return 25000000;
 }
+
+unsigned long get_ttc_clk(int dev_id)
+{
+       return 25000000;
+}
diff --git a/arch/arm/cpu/armv8/zynqmp/timer.c b/arch/arm/cpu/armv8/zynqmp/timer.c
new file mode 100644 (file)
index 0000000..a51e11f
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * 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 ttc0_timer {
+       u32 clkctrl; /* Timer Load Register */
+       u32 reserved0[2];
+       u32 cntctrl; /* Timer Counter Register */
+       u32 reserved1[2];
+       u32 counter; /* Timer Control Register */
+};
+
+static struct ttc0_timer *timer_base =
+                             (struct ttc0_timer *)ZYNQ_TTC_BASEADDR0;
+
+#define TIMER_LOAD_VAL 0xFFFFFFFF
+
+#define PRESCALE_EXPONENT      11      /* 2 ^ PRESCALE_EXPONENT = PRESCALE */
+#define PRESCALE               2048    /* The exponent must match this */
+#define CLK_CNTRL_PRESCALE     ((PRESCALE_EXPONENT - 1) << 1)
+#define CLK_CNTRL_PRESCALE_EN  1
+#define CNT_CNTRL_RESET                (1 << 4)
+
+int timer_init(void)
+{
+       gd->arch.timer_rate_hz = get_ttc_clk(0) / PRESCALE;
+
+       writel(CLK_CNTRL_PRESCALE | CLK_CNTRL_PRESCALE_EN,
+              &timer_base->clkctrl);
+       writel(CNT_CNTRL_RESET, &timer_base->cntctrl);
+
+       /* 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 += now - gd->arch.lastinc;
+       } else {
+               /* We have an overflow ... */
+               gd->arch.tbl += now + TIMER_LOAD_VAL - gd->arch.lastinc + 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 = timeend - timenow;
+               } else {
+                       if ((TIMER_LOAD_VAL - timenow + timeend) <=
+                                                               countticks) {
+                               /* overflow */
+                               timediff = TIMER_LOAD_VAL - timenow + timeend;
+                       } 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;
+}
index 9f18ea9be0bb7d247f337bd4a792c9ad058bd4ff..9b5c6ef7beb9ca8227af0c4fabf861d1bb7004a2 100644 (file)
@@ -9,5 +9,6 @@
 #define _ASM_ARCH_CLK_H_
 
 unsigned long get_uart_clk(int dev_id);
+unsigned long get_ttc_clk(int dev_id);
 
 #endif /* _ASM_ARCH_CLK_H_ */
index f6ede5b050d90d2a3718b627ab6a339f9975617a..f1c16a0092d03c348e29f782678bf569f7486f0b 100644 (file)
@@ -16,6 +16,8 @@
 #define ZYNQ_GEM_BASEADDR2     0xFF00B000
 #define ZYNQ_GEM_BASEADDR3     0xFF00C000
 
+#define ZYNQ_TTC_BASEADDR0     0xFF00F000
+
 #define ZYNQ_QSPI_BASEADDR     0xFF00D000
 
 #define ZYNQ_SDHCI_BASEADDR0   0xFF014000
index d477402753f424bb18c65cc409bb12896fac70da..5120160c70e251f8183379b3108bb9918b716f4d 100644 (file)
@@ -25,11 +25,6 @@ int dram_init(void)
        return 0;
 }
 
-int timer_init(void)
-{
-       return 0;
-}
-
 void reset_cpu(ulong addr)
 {
 }