diff mbox

[U-Boot,v4,5/7] arm: add Faraday FTPWMTMR010 timer support

Message ID 1367907913-11859-6-git-send-email-dantesu@gmail.com
State Changes Requested
Delegated to: Albert ARIBAUD
Headers show

Commit Message

Kuo-Jung Su May 7, 2013, 6:25 a.m. UTC
From: Kuo-Jung Su <dantesu@faraday-tech.com>

Signed-off-by: Kuo-Jung Su <dantesu@faraday-tech.com>
CC: Albert Aribaud <albert.u.boot@aribaud.net>
---
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 |  160 ++++++++++++++++++++++++++++++++++++
 include/faraday/ftpwmtmr010.h      |   41 +++++++++
 3 files changed, 202 insertions(+)
 create mode 100644 arch/arm/cpu/faraday/ftpwmtmr010.c
 create mode 100644 include/faraday/ftpwmtmr010.h

--
1.7.9.5
diff mbox

Patch

diff --git a/arch/arm/cpu/faraday/Makefile b/arch/arm/cpu/faraday/Makefile
index 5de417c..290400a 100644
--- a/arch/arm/cpu/faraday/Makefile
+++ b/arch/arm/cpu/faraday/Makefile
@@ -27,6 +27,7 @@  LIB	= $(obj)lib$(CPU).o

 src-y  := cpu.o interrupts.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..e959d8b
--- /dev/null
+++ b/arch/arm/cpu/faraday/ftpwmtmr010.c
@@ -0,0 +1,160 @@ 
+/*
+ * arch/arm/cpu/faraday/ftpwmtmr010.c
+ *
+ * (C) Copyright 2010 Faraday Technology
+ * Dante Su <dantesu@faraday-tech.com>
+ *
+ * This file is released under the terms of GPL v2 and any later version.
+ * See the file COPYING in the root directory of the source tree for details.
+ */
+
+#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
+
+static ulong ticks;				/* U-Boot ticks since startup */
+static ulong sclk  = 66000000;	/* source clock (66MHz by default) */
+static struct ftpwmtmr010_regs __iomem *regs =
+	(void __iomem *)CONFIG_TIMER_BASE;
+
+void udelay_masked(unsigned long usec)
+{
+	int id = TIMER_ID + 1;
+
+	/* timer re-start */
+	writel(0, &regs->t[id].ctrl);
+	writel(BIT_MASK(id), &regs->isr);
+	writel(0, &regs->t[id].cmpb);
+	writel((sclk / 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);
+}
+
+#ifdef CONFIG_USE_IRQ
+
+void timer_interrupt(struct pt_regs *ctx)
+{
+	int id = TIMER_ID;
+
+	++ticks;
+	writel(BIT_MASK(id), &regs->isr);
+}
+
+#endif    /* #ifdef CONFIG_USE_IRQ */
+
+void reset_timer_masked(void)
+{
+	int id = TIMER_ID;
+
+	writel(0, &regs->t[id].ctrl);
+	writel(BIT_MASK(id), &regs->isr);
+
+#ifdef CONFIG_USE_IRQ
+	/* setup a 1 sec periodic timer */
+	writel(0,
+		&regs->t[id].cmpb);
+	writel(sclk / CONFIG_SYS_HZ,
+		&regs->t[id].cntb);
+	writel(CTRL_AUTORELOAD | CTRL_INTEN | CTRL_START | CTRL_UPDATE,
+		&regs->t[id].ctrl);
+	irq_install_handler(CONFIG_TIMER_IRQ, (void *)timer_interrupt, NULL);
+	irq_enable(CONFIG_TIMER_IRQ);
+	enable_interrupts();
+#else
+	/* setup a 30 sec one-shot timer */
+	writel(0,
+		&regs->t[id].cmpb);
+	writel(30 * sclk,
+		&regs->t[id].cntb);
+	writel(CTRL_INTEN | CTRL_START | CTRL_UPDATE,
+		&regs->t[id].ctrl);
+#endif    /* #ifdef CONFIG_USE_IRQ */
+}
+
+ulong get_timer_masked(void)
+{
+#ifdef CONFIG_USE_IRQ
+	return ticks;
+#else
+	ulong s = sclk / CONFIG_SYS_HZ;
+	ulong t = (30 * sclk - readl(&regs->t[TIMER_ID].cnto)) / s;
+
+	return ticks + t;
+#endif
+}
+
+int timer_init(void)
+{
+	ticks = 0;
+#ifdef CONFIG_TIMER_FREQ
+	sclk  = CONFIG_TIMER_FREQ;
+#else
+	sclk  = clk_get_rate("APB");
+#endif
+
+#ifdef CONFIG_USE_IRQ
+	/* interrupt is not yet initialized here */
+#else
+	reset_timer_masked();
+#endif
+
+	return 0;
+}
+
+void reset_timer(void)
+{
+	reset_timer_masked();
+}
+
+ulong get_timer(ulong base)
+{
+#ifndef CONFIG_USE_IRQ
+	if (!readl(&regs->t[TIMER_ID].cnto)) {
+		ticks += 30 * CONFIG_SYS_HZ;
+		reset_timer_masked();
+	}
+#endif
+	return get_timer_masked() - base;
+}
+
+void set_timer(ulong t)
+{
+	ticks = t;
+}
+
+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..9455577
--- /dev/null
+++ b/include/faraday/ftpwmtmr010.h
@@ -0,0 +1,41 @@ 
+/*
+ * arch/arm/cpu/faraday/ftpwmtmr010.h
+ *
+ * (C) Copyright 2010 Faraday Technology
+ * Dante Su <dantesu@faraday-tech.com>
+ *
+ * This file is released under the terms of GPL v2 and any later version.
+ * See the file COPYING in the root directory of the source tree for details.
+ */
+
+#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