From: Kuo-Jung Su <dant...@faraday-tech.com>

Faraday FTPWMTMR010 is a simple APB device which supports
both timer and pwm functions.

Signed-off-by: Kuo-Jung Su <dant...@faraday-tech.com>
CC: Albert Aribaud <albert.u.b...@aribaud.net>
---
Changes for v11:
        - Directly specify the timer object in 
'arch/arm/cpu/faraday/<soc>/Makefile'
          instead of using CONFIG_FTPWMTMR010 in 'arch/arm/cpu/faraday/Makefile'

Changes for v8, v9, v10:
        - Nothing updates

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/ftpwmtmr010.c |  112 ++++++++++++++++++++++++++++++++++++
 include/faraday/ftpwmtmr010.h      |   41 +++++++++++++
 2 files changed, 153 insertions(+)
 create mode 100644 arch/arm/cpu/faraday/ftpwmtmr010.c
 create mode 100644 include/faraday/ftpwmtmr010.h

diff --git a/arch/arm/cpu/faraday/ftpwmtmr010.c 
b/arch/arm/cpu/faraday/ftpwmtmr010.c
new file mode 100644
index 0000000..1032e44
--- /dev/null
+++ b/arch/arm/cpu/faraday/ftpwmtmr010.c
@@ -0,0 +1,112 @@
+/*
+ * (C) Copyright 2013
+ * Faraday Technology Corporation. <http://www.faraday-tech.com/tw/>
+ * Kuo-Jung Su <dant...@gmail.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+
+#include <faraday/ftpwmtmr010.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define TIMER_ID    0
+
+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, &regs->t[id].ctrl);
+       writel(BIT_MASK(id), &regs->isr);
+       writel(0, &regs->t[id].cmpb);
+       writel((freq / 1000000) * usec, &regs->t[id].cntb);
+       writel(CTRL_INTEN | CTRL_START | CTRL_UPDATE, &regs->t[id].ctrl);
+
+       /* wait for timer interrupt */
+       while (!(readl(&regs->isr) & BIT_MASK(id)))
+               ;
+
+       /* timer disabled */
+       writel(0, &regs->t[id].ctrl);
+       writel(BIT_MASK(id), &regs->isr);
+}
+
+void reset_timer_masked(void)
+{
+       int id = TIMER_ID;
+       ulong freq = gd->arch.timer_rate_hz;
+
+       writel(0, &regs->t[id].ctrl);
+       writel(BIT_MASK(id), &regs->isr);
+
+       /* setup a longest periodic timer */
+       writel((0xffffffff / freq) * freq, &regs->t[id].cntb);
+
+       writel(0, &regs->t[id].cmpb);
+       writel(CTRL_AUTORELOAD | CTRL_INTEN | CTRL_START | CTRL_UPDATE,
+               &regs->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(&regs->isr) & BIT_MASK(id)) {
+               writel(BIT_MASK(id), &regs->isr);
+               gd->arch.tbl += secs * CONFIG_SYS_HZ;
+       }
+
+       return gd->arch.tbl
+               + ((secs * freq - readl(&regs->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..29f4f05
--- /dev/null
+++ b/include/faraday/ftpwmtmr010.h
@@ -0,0 +1,41 @@
+/*
+ * arch/arm/cpu/faraday/ftpwmtmr010.h
+ *
+ * (C) Copyright 2013
+ * Faraday Technology Corporation. <http://www.faraday-tech.com/tw/>
+ * Kuo-Jung Su <dant...@gmail.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

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to