[U-Boot] [PATCH v7 08/11] arm: add Faraday FTPWMTMR010 timer support
Kuo-Jung Su
dantesu at gmail.com
Mon Jul 29 07:51:50 CEST 2013
From: Kuo-Jung Su <dantesu at faraday-tech.com>
Signed-off-by: Kuo-Jung Su <dantesu at faraday-tech.com>
CC: Albert Aribaud <albert.u.boot at aribaud.net>
---
Changes for v7:
- Update license to use SPDX identifiers.
Changes for v6:
- Nothing updates
Changes for v5:
- Drop IRQ dependant implementation
- Use gd->arch.timer_rate_hz for timer clock source
- Use gd->arch.tbl for timestamp
Changes for v4:
- Coding Style cleanup.
- Break up from [arm: add Faraday A36x SoC platform support]
Changes for v3:
- Coding Style cleanup.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Add '__iomem' to all the declaration of HW register pointers.
Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().
arch/arm/cpu/faraday/Makefile | 1 +
arch/arm/cpu/faraday/ftpwmtmr010.c | 116 ++++++++++++++++++++++++++++++++++++
include/faraday/ftpwmtmr010.h | 40 +++++++++++++
3 files changed, 157 insertions(+)
create mode 100644 arch/arm/cpu/faraday/ftpwmtmr010.c
create mode 100644 include/faraday/ftpwmtmr010.h
diff --git a/arch/arm/cpu/faraday/Makefile b/arch/arm/cpu/faraday/Makefile
index df28792..715bb5d 100644
--- a/arch/arm/cpu/faraday/Makefile
+++ b/arch/arm/cpu/faraday/Makefile
@@ -12,6 +12,7 @@ LIB = $(obj)lib$(CPU).o
src-y := cpu.o
src-$(CONFIG_FTINTC020) += ftintc020.o
src-$(CONFIG_FTTMR010) += fttmr010.o
+src-$(CONFIG_FTPWMTMR010) += ftpwmtmr010.o
START = start.o
COBJS = $(src-y)
diff --git a/arch/arm/cpu/faraday/ftpwmtmr010.c b/arch/arm/cpu/faraday/ftpwmtmr010.c
new file mode 100644
index 0000000..db49d39
--- /dev/null
+++ b/arch/arm/cpu/faraday/ftpwmtmr010.c
@@ -0,0 +1,116 @@
+/*
+ * arch/arm/cpu/faraday/ftpwmtmr010.c
+ *
+ * (C) Copyright 2013 Faraday Technology
+ * Dante Su <dantesu at faraday-tech.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+
+#include <faraday/ftpwmtmr010.h>
+
+#ifdef CONFIG_A369_FA606TE_PLATFORM
+#define TIMER_ID 4
+#else
+#define TIMER_ID 0
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static struct ftpwmtmr010_regs *regs = (void __iomem *)CONFIG_FTPWMTMR010_BASE;
+
+void udelay_masked(unsigned long usec)
+{
+ int id = TIMER_ID + 1;
+ ulong freq = gd->arch.timer_rate_hz;
+
+ /* timer re-start */
+ writel(0, ®s->t[id].ctrl);
+ writel(BIT_MASK(id), ®s->isr);
+ writel(0, ®s->t[id].cmpb);
+ writel((freq / 1000000) * usec, ®s->t[id].cntb);
+ writel(CTRL_INTEN | CTRL_START | CTRL_UPDATE, ®s->t[id].ctrl);
+
+ /* wait for timer interrupt */
+ while (!(readl(®s->isr) & BIT_MASK(id)))
+ ;
+
+ /* timer disabled */
+ writel(0, ®s->t[id].ctrl);
+ writel(BIT_MASK(id), ®s->isr);
+}
+
+void reset_timer_masked(void)
+{
+ int id = TIMER_ID;
+ ulong freq = gd->arch.timer_rate_hz;
+
+ writel(0, ®s->t[id].ctrl);
+ writel(BIT_MASK(id), ®s->isr);
+
+ /* setup a longest periodic timer */
+ writel((0xffffffff / freq) * freq, ®s->t[id].cntb);
+
+ writel(0, ®s->t[id].cmpb);
+ writel(CTRL_AUTORELOAD | CTRL_INTEN | CTRL_START | CTRL_UPDATE,
+ ®s->t[id].ctrl);
+}
+
+ulong get_timer_masked(void)
+{
+ int id = TIMER_ID;
+ ulong freq = gd->arch.timer_rate_hz;
+ ulong secs = 0xffffffff / freq;
+ ulong ms = freq / CONFIG_SYS_HZ;
+
+ if (readl(®s->isr) & BIT_MASK(id)) {
+ writel(BIT_MASK(id), ®s->isr);
+ gd->arch.tbl += secs * CONFIG_SYS_HZ;
+ }
+
+ return gd->arch.tbl
+ + ((secs * freq - readl(®s->t[id].cnto)) / ms);
+}
+
+int timer_init(void)
+{
+ gd->arch.tbl = 0;
+ reset_timer_masked();
+ return 0;
+}
+
+void reset_timer(void)
+{
+ reset_timer_masked();
+}
+
+ulong get_timer(ulong base)
+{
+ return get_timer_masked() - base;
+}
+
+void __udelay(unsigned long usec)
+{
+ udelay_masked(usec);
+}
+
+/*
+ * 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/include/faraday/ftpwmtmr010.h b/include/faraday/ftpwmtmr010.h
new file mode 100644
index 0000000..806f4c0
--- /dev/null
+++ b/include/faraday/ftpwmtmr010.h
@@ -0,0 +1,40 @@
+/*
+ * arch/arm/cpu/faraday/ftpwmtmr010.h
+ *
+ * (C) Copyright 2013 Faraday Technology
+ * Dante Su <dantesu at faraday-tech.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef ARCH_ARM_CPU_FARADAY_FTPWMTMR010_H
+#define ARCH_ARM_CPU_FARADAY_FTPWMTMR010_H
+
+struct ftpwmtmr010_timer {
+ uint32_t ctrl; /* Control */
+#define CTRL_EXTCLK (1 << 0) /* use external clock */
+#define CTRL_START (1 << 1) /* timer start */
+#define CTRL_UPDATE (1 << 2) /* update timer counter */
+#define CTRL_AUTORELOAD (1 << 4) /* auto-reload timer counter */
+#define CTRL_INTEN (1 << 5) /* interrupt enabled */
+
+ uint32_t cntb; /* Count buffer */
+ uint32_t cmpb; /* Compare buffer */
+ uint32_t cnto; /* Count observation */
+};
+
+struct ftpwmtmr010_regs {
+ /* 0x00: Interrupt status register */
+ uint32_t isr;
+
+ /* 0x04 - 0x0C: Reserved */
+ uint32_t rsvd[3];
+
+ /* 0x10 - 0x8C: timer registers */
+ struct ftpwmtmr010_timer t[8];
+
+ /* 0x90: Revision register */
+ uint32_t rev;
+};
+
+#endif
--
1.7.9.5
More information about the U-Boot
mailing list