]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - arch/arm/imx-common/timer.c
upgrade to upstream version 2013.07
[karo-tx-uboot.git] / arch / arm / imx-common / timer.c
index 1dbc413d469cdf6b206976175b2f319e191b8fe1..92712a6de55b86a2432bbbf02ac694566b2c3b68 100644 (file)
@@ -4,23 +4,7 @@
  *
  * (C) Copyright 2009 Freescale Semiconductor, Inc.
  *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * 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
+ * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
@@ -52,10 +36,18 @@ static inline unsigned long long tick_to_time(unsigned long long tick)
 {
        tick *= CONFIG_SYS_HZ;
        do_div(tick, MXC_CLK32);
-
        return tick;
 }
 
+static inline unsigned long time_to_tick(unsigned long time)
+{
+       unsigned long long ticks = (unsigned long long)time;
+
+       ticks *= MXC_CLK32;
+       do_div(ticks, CONFIG_SYS_HZ);
+       return ticks;
+}
+
 static inline unsigned long long us_to_tick(unsigned long long usec)
 {
        usec = usec * MXC_CLK32 + 999999;
@@ -84,6 +76,7 @@ int timer_init(void)
        gd->arch.tbl = __raw_readl(&cur_gpt->counter);
        gd->arch.tbu = 0;
 
+       gd->arch.timer_rate_hz = MXC_CLK32;
        return 0;
 }
 
@@ -106,25 +99,36 @@ ulong get_timer_masked(void)
         * 5 * 10^9 days... and get_ticks() * CONFIG_SYS_HZ wraps in
         * 5 * 10^6 days - long enough.
         */
+       /*
+        * LW: get_ticks() returns a long long with the top 32 bits always ZERO!
+        * Thus the calculation above is not true.
+        * A 64bit timer value would only make sense if it was
+        * consistently used throughout the code. Thus also the parameter
+        * to get_timer() and its return value would need to be 64bit wide!
+        */
        return tick_to_time(get_ticks());
 }
 
 ulong get_timer(ulong base)
 {
-       return get_timer_masked() - base;
+       return tick_to_time(get_ticks() - time_to_tick(base));
 }
 
 /* delay x useconds AND preserve advance timstamp value */
 void __udelay(unsigned long usec)
 {
-       unsigned long long tmp;
-       ulong tmo;
+       unsigned long start = __raw_readl(&cur_gpt->counter);
+       unsigned long ticks;
+
+       if (usec == 0)
+               return;
 
-       tmo = us_to_tick(usec);
-       tmp = get_ticks() + tmo;        /* get current timestamp */
+       ticks = us_to_tick(usec);
+       if (ticks == 0)
+               ticks++;
 
-       while (get_ticks() < tmp)       /* loop till event */
-                /*NOP*/;
+       while (__raw_readl(&cur_gpt->counter) - start < ticks)
+               /* loop till event */;
 }
 
 /*
@@ -133,5 +137,5 @@ void __udelay(unsigned long usec)
  */
 ulong get_tbclk(void)
 {
-       return MXC_CLK32;
+       return gd->arch.timer_rate_hz;
 }