From patchwork Thu Jul 4 03:40:40 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuo-Jung Su X-Patchwork-Id: 256786 X-Patchwork-Delegate: albert.aribaud@free.fr Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 62DDC2C00AD for ; Thu, 4 Jul 2013 13:43:07 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id D160D4A193; Thu, 4 Jul 2013 05:42:35 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id EH3xtRxRQmdB; Thu, 4 Jul 2013 05:42:35 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id A6AA84A0C5; Thu, 4 Jul 2013 05:41:26 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id D5D7C4A02E for ; Thu, 4 Jul 2013 05:41:08 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id qwQ4O8DB7H6n for ; Thu, 4 Jul 2013 05:41:03 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-pb0-f41.google.com (mail-pb0-f41.google.com [209.85.160.41]) by theia.denx.de (Postfix) with ESMTPS id 8EC3D4A023 for ; Thu, 4 Jul 2013 05:40:34 +0200 (CEST) Received: by mail-pb0-f41.google.com with SMTP id rp16so775955pbb.14 for ; Wed, 03 Jul 2013 20:40:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references :in-reply-to:references; bh=kbs6eK8S1/acbesZrVKfCSNPXiFfbV7jQdj/HkuXb2M=; b=s4kM9gp6QOjwZ5JpR+W1BihnpSEpgByIJFjjmnzDb3ZbukFstg3gKnmu5eu1raF3jp b2Zhp55Qc6MlfcONwUG2zy/SEUhgs43lNNhPZw9fE99hlP7079uZ9bs5+tmflJ+xalFI mnt1cI0FLVVkbPCOh8M+b5dBEwQN+FVrV8JAAfXb3T8YIWy6lxewgXGVgqRvshnFCz2x 5Wu6tXu09AOdvNpqQf/dlIfu9jBszH2tEpDGNYwajkNGl49IaQ7biYLrxnVsbQJqvtGn /zEp/Ln/RnOwRLwEgU+FMB4i5vC2qkIqvmafFGvHAa2qj+v+YIXyd+BJ2tCIxy5dZ3/Z m6+w== X-Received: by 10.66.186.79 with SMTP id fi15mr5050972pac.160.1372909233594; Wed, 03 Jul 2013 20:40:33 -0700 (PDT) Received: from localhost.localdomain (114-35-170-161.HINET-IP.hinet.net. [114.35.170.161]) by mx.google.com with ESMTPSA id kc8sm976470pbc.18.2013.07.03.20.40.31 for (version=TLSv1 cipher=DES-CBC3-SHA bits=168/168); Wed, 03 Jul 2013 20:40:32 -0700 (PDT) From: Kuo-Jung Su To: u-boot@lists.denx.de Date: Thu, 4 Jul 2013 11:40:40 +0800 Message-Id: <1372909244-25211-9-git-send-email-dantesu@gmail.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1372909244-25211-1-git-send-email-dantesu@gmail.com> References: <1372909244-25211-1-git-send-email-dantesu@gmail.com> In-Reply-To: <1364540788-13943-1-git-send-email-dantesu@gmail.com> References: <1364540788-13943-1-git-send-email-dantesu@gmail.com> Cc: Kuo-Jung Su Subject: [U-Boot] [PATCH v6 08/12] arm: add Faraday FTTMR010 timer support X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de From: Kuo-Jung Su Signed-off-by: Kuo-Jung Su CC: Albert Aribaud --- 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/fttmr010.c | 136 +++++++++++++++++++++++++++++++++++++++ include/faraday/fttmr010.h | 17 +++++ 3 files changed, 154 insertions(+) create mode 100644 arch/arm/cpu/faraday/fttmr010.c -- 1.7.9.5 diff --git a/arch/arm/cpu/faraday/Makefile b/arch/arm/cpu/faraday/Makefile index 35926c2..658d9ed 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 src-$(CONFIG_FTINTC020) += ftintc020.o +src-$(CONFIG_FTTMR010) += fttmr010.o START = start.o COBJS = $(src-y) diff --git a/arch/arm/cpu/faraday/fttmr010.c b/arch/arm/cpu/faraday/fttmr010.c new file mode 100644 index 0000000..9d6f7ac --- /dev/null +++ b/arch/arm/cpu/faraday/fttmr010.c @@ -0,0 +1,136 @@ +/* + * arch/arm/cpu/faraday/fttmr010.c + * + * (C) Copyright 2013 Faraday Technology + * Dante Su + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +static struct fttmr010 *regs = (void __iomem *)CONFIG_FTTMR010_BASE; + +void udelay_masked(unsigned long usec) +{ + ulong freq = gd->arch.timer_rate_hz; + + /* Disable Timer2 */ + clrbits_le32(®s->cr, FTTMR010_TM2_CRMASK); + /* Disable Timer2 interrupts */ + writel(FTTMR010_TM2_ISRMASK, ®s->interrupt_mask); + /* Clear Timer2 interrupts */ + writel(FTTMR010_TM2_ISRMASK, ®s->interrupt_state); + + /* Configure Timer2 */ + writel((freq / 1000000) * usec, ®s->timer2_counter); + writel(0, ®s->timer2_load); + writel(0, ®s->timer2_match1); + writel(0, ®s->timer2_match2); + + /* Enable Timer2 */ + setbits_le32(®s->cr, + FTTMR010_TM2_OFENABLE | FTTMR010_TM2_ENABLE); + + /* Wait until timeout */ + while (!(readl(®s->interrupt_state) & FTTMR010_TM2_ISRMASK)) + ; +} + +void reset_timer_masked(void) +{ + ulong freq = gd->arch.timer_rate_hz; + + /* Disable Timer1 */ + clrbits_le32(®s->cr, FTTMR010_TM1_CRMASK); + + /* Disable & Clear Timer1 interrupts */ + writel(FTTMR010_TM1_ISRMASK, ®s->interrupt_mask); + writel(FTTMR010_TM1_ISRMASK, ®s->interrupt_state); + + /* Setup a longest periodic timer */ + writel((0xffffffff / freq) * freq, ®s->timer1_counter); + writel((0xffffffff / freq) * freq, ®s->timer1_load); + + writel(0, ®s->timer1_match1); + writel(0, ®s->timer1_match2); + + /* Disable match interrupts */ + writel(FTTMR010_TM1_MATCH1 | FTTMR010_TM1_MATCH2, + ®s->interrupt_mask); + + /* Enable Timer1 with overflow interrupt */ + setbits_le32(®s->cr, + FTTMR010_TM1_OFENABLE | FTTMR010_TM1_ENABLE); +} + +ulong get_timer_masked(void) +{ + ulong freq = gd->arch.timer_rate_hz; + ulong secs = 0xffffffff / freq; + ulong ms = freq / CONFIG_SYS_HZ; + + if (readl(®s->interrupt_state) & FTTMR010_TM1_ISRMASK) { + writel(FTTMR010_TM1_ISRMASK, ®s->interrupt_state); + gd->arch.tbl += secs * CONFIG_SYS_HZ; + } + + return gd->arch.tbl + + ((secs * freq) - readl(®s->timer1_counter)) / 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/fttmr010.h b/include/faraday/fttmr010.h index 72abcb3..ef10f31 100644 --- a/include/faraday/fttmr010.h +++ b/include/faraday/fttmr010.h @@ -57,6 +57,16 @@ struct fttmr010 { #define FTTMR010_TM1_CLOCK (1 << 1) #define FTTMR010_TM1_ENABLE (1 << 0) +#define FTTMR010_TM1_CRMASK \ + (FTTMR010_TM1_UPDOWN | FTTMR010_TM1_OFENABLE \ + | FTTMR010_TM1_CLOCK | FTTMR010_TM1_ENABLE) +#define FTTMR010_TM2_CRMASK \ + (FTTMR010_TM2_UPDOWN | FTTMR010_TM2_OFENABLE \ + | FTTMR010_TM2_CLOCK | FTTMR010_TM2_ENABLE) +#define FTTMR010_TM3_CRMASK \ + (FTTMR010_TM3_UPDOWN | FTTMR010_TM3_OFENABLE \ + | FTTMR010_TM3_CLOCK | FTTMR010_TM3_ENABLE) + /* * Timer Interrupt State & Mask Registers */ @@ -70,4 +80,11 @@ struct fttmr010 { #define FTTMR010_TM1_MATCH2 (1 << 1) #define FTTMR010_TM1_MATCH1 (1 << 0) +#define FTTMR010_TM1_ISRMASK \ + (FTTMR010_TM1_OVERFLOW | FTTMR010_TM1_MATCH2 | FTTMR010_TM1_MATCH1) +#define FTTMR010_TM2_ISRMASK \ + (FTTMR010_TM2_OVERFLOW | FTTMR010_TM2_MATCH2 | FTTMR010_TM2_MATCH1) +#define FTTMR010_TM3_ISRMASK \ + (FTTMR010_TM3_OVERFLOW | FTTMR010_TM3_MATCH2 | FTTMR010_TM3_MATCH1) + #endif /* __FTTMR010_H */