From mboxrd@z Thu Jan 1 00:00:00 1970 From: Kuo-Jung Su Date: Tue, 7 May 2013 14:25:11 +0800 Subject: [U-Boot] [PATCH v4 5/7] arm: add Faraday FTPWMTMR010 timer support In-Reply-To: <1367907913-11859-1-git-send-email-dantesu@gmail.com> References: <1367907913-11859-1-git-send-email-dantesu@gmail.com> Message-ID: <1367907913-11859-6-git-send-email-dantesu@gmail.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de From: Kuo-Jung Su Signed-off-by: Kuo-Jung Su CC: Albert Aribaud --- 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 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 + * + * 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 +#include + +#include + +#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, ®s->t[id].ctrl); + writel(BIT_MASK(id), ®s->isr); + writel(0, ®s->t[id].cmpb); + writel((sclk / 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); +} + +#ifdef CONFIG_USE_IRQ + +void timer_interrupt(struct pt_regs *ctx) +{ + int id = TIMER_ID; + + ++ticks; + writel(BIT_MASK(id), ®s->isr); +} + +#endif /* #ifdef CONFIG_USE_IRQ */ + +void reset_timer_masked(void) +{ + int id = TIMER_ID; + + writel(0, ®s->t[id].ctrl); + writel(BIT_MASK(id), ®s->isr); + +#ifdef CONFIG_USE_IRQ + /* setup a 1 sec periodic timer */ + writel(0, + ®s->t[id].cmpb); + writel(sclk / CONFIG_SYS_HZ, + ®s->t[id].cntb); + writel(CTRL_AUTORELOAD | CTRL_INTEN | CTRL_START | CTRL_UPDATE, + ®s->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, + ®s->t[id].cmpb); + writel(30 * sclk, + ®s->t[id].cntb); + writel(CTRL_INTEN | CTRL_START | CTRL_UPDATE, + ®s->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(®s->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(®s->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 + * + * 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 -- 1.7.9.5