1 /* 2 * Marvell PXA2xx/3xx timer driver 3 * 4 * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com> 5 * 6 * See file CREDITS for list of people who contributed to this 7 * project. 8 * 9 * This program is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU General Public License as 11 * published by the Free Software Foundation; either version 2 of 12 * the License, or (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 22 * MA 02111-1307 USA 23 */ 24 25 #include <asm/arch/pxa-regs.h> 26 #include <asm/io.h> 27 #include <common.h> 28 #include <div64.h> 29 30 DECLARE_GLOBAL_DATA_PTR; 31 32 #define TIMER_LOAD_VAL 0xffffffff 33 34 #define timestamp (gd->arch.tbl) 35 #define lastinc (gd->arch.lastinc) 36 37 #if defined(CONFIG_CPU_PXA27X) || defined(CONFIG_CPU_MONAHANS) 38 #define TIMER_FREQ_HZ 3250000 39 #elif defined(CONFIG_CPU_PXA25X) 40 #define TIMER_FREQ_HZ 3686400 41 #else 42 #error "Timer frequency unknown - please config PXA CPU type" 43 #endif 44 45 static unsigned long long tick_to_time(unsigned long long tick) 46 { 47 return tick * CONFIG_SYS_HZ / TIMER_FREQ_HZ; 48 } 49 50 static unsigned long long us_to_tick(unsigned long long us) 51 { 52 return (us * TIMER_FREQ_HZ) / 1000000; 53 } 54 55 int timer_init(void) 56 { 57 writel(0, OSCR); 58 return 0; 59 } 60 61 unsigned long long get_ticks(void) 62 { 63 /* Current tick value */ 64 uint32_t now = readl(OSCR); 65 66 if (now >= lastinc) { 67 /* 68 * Normal mode (non roll) 69 * Move stamp forward with absolute diff ticks 70 */ 71 timestamp += (now - lastinc); 72 } else { 73 /* We have rollover of incrementer */ 74 timestamp += (TIMER_LOAD_VAL - lastinc) + now; 75 } 76 77 lastinc = now; 78 return timestamp; 79 } 80 81 ulong get_timer(ulong base) 82 { 83 return tick_to_time(get_ticks()) - base; 84 } 85 86 void __udelay(unsigned long usec) 87 { 88 unsigned long long tmp; 89 ulong tmo; 90 91 tmo = us_to_tick(usec); 92 tmp = get_ticks() + tmo; /* get current timestamp */ 93 94 while (get_ticks() < tmp) /* loop till event */ 95 /*NOP*/; 96 } 97 98 ulong get_tbclk(void) 99 { 100 return TIMER_FREQ_HZ; 101 } 102