X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=arch%2Farm%2Fcpu%2Farmv7%2Fzynq%2Ftimer.c;h=0133565299fbb89e4c1a96d51edef54eaaebb5a2;hb=1a4596601fd395f3afb8f82f3f840c5e00bdd57a;hp=45b405a4ba2a764831615a24ecd86d2cb6214466;hpb=2d795c9621de274cb0cb8cf4af5941293f89c3be;p=platform%2Fkernel%2Fu-boot.git diff --git a/arch/arm/cpu/armv7/zynq/timer.c b/arch/arm/cpu/armv7/zynq/timer.c index 45b405a..0133565 100644 --- a/arch/arm/cpu/armv7/zynq/timer.c +++ b/arch/arm/cpu/armv7/zynq/timer.c @@ -22,28 +22,13 @@ * Sysgo Real-Time Solutions, GmbH * Alex Zuepke * - * 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 #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -54,7 +39,7 @@ struct scu_timer { }; static struct scu_timer *timer_base = - (struct scu_timer *) CONFIG_SCUTIMER_BASEADDR; + (struct scu_timer *)ZYNQ_SCUTIMER_BASEADDR; #define SCUTIMER_CONTROL_PRESCALER_MASK 0x0000FF00 /* Prescaler */ #define SCUTIMER_CONTROL_PRESCALER_SHIFT 8 @@ -114,15 +99,43 @@ ulong get_timer_masked(void) void __udelay(unsigned long usec) { - unsigned long long tmp; - ulong tmo; - - tmo = usec / (1000000 / CONFIG_SYS_HZ); - tmp = get_ticks() + tmo; /* Get current timestamp */ - - while (get_ticks() < tmp) { /* Loop till event */ - /* NOP */; - } + u32 countticks; + u32 timeend; + u32 timediff; + u32 timenow; + + if (usec == 0) + return; + + countticks = (u32) (((unsigned long long) TIMER_TICK_HZ * usec) / + 1000000); + + /* decrementing timer */ + timeend = readl(&timer_base->counter) - countticks; + +#if TIMER_LOAD_VAL != 0xFFFFFFFF + /* do not manage multiple overflow */ + if (countticks >= TIMER_LOAD_VAL) + countticks = TIMER_LOAD_VAL - 1; +#endif + + do { + timenow = readl(&timer_base->counter); + + if (timenow >= timeend) { + /* normal case */ + timediff = timenow - timeend; + } else { + if ((TIMER_LOAD_VAL - timeend + timenow) <= + countticks) { + /* overflow */ + timediff = TIMER_LOAD_VAL - timeend + timenow; + } else { + /* missed the exact match */ + break; + } + } + } while (timediff > 0); } /* Timer without interrupts */