From mboxrd@z Thu Jan 1 00:00:00 1970 From: Kuo-Jung Su Date: Wed, 26 Mar 2014 14:03:16 +0800 Subject: [U-Boot] [PATCH v11 3/6] arm: faraday: add FTPWMTMR010 timer support In-Reply-To: <1395813799-3672-1-git-send-email-dantesu@gmail.com> References: <1395813799-3672-1-git-send-email-dantesu@gmail.com> Message-ID: <1395813799-3672-4-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 Faraday FTPWMTMR010 is a simple APB device which supports both timer and pwm functions. Signed-off-by: Kuo-Jung Su CC: Albert Aribaud --- Changes for v11: - Directly specify the timer object in 'arch/arm/cpu/faraday//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. + * Kuo-Jung Su + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include + +#include + +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, ®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..29f4f05 --- /dev/null +++ b/include/faraday/ftpwmtmr010.h @@ -0,0 +1,41 @@ +/* + * arch/arm/cpu/faraday/ftpwmtmr010.h + * + * (C) Copyright 2013 + * Faraday Technology Corporation. + * Kuo-Jung Su + * + * 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