1*ea0364f1SPeter Tyser /* 2*ea0364f1SPeter Tyser * (C) Copyright 2009 3*ea0364f1SPeter Tyser * Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> 4*ea0364f1SPeter Tyser * 5*ea0364f1SPeter Tyser * (C) Copyright 2007-2008 6*ea0364f1SPeter Tyser * Nobobuhiro Iwamatsu <iwamatsu@nigauri.org> 7*ea0364f1SPeter Tyser * 8*ea0364f1SPeter Tyser * (C) Copyright 2003 9*ea0364f1SPeter Tyser * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 10*ea0364f1SPeter Tyser * 11*ea0364f1SPeter Tyser * See file CREDITS for list of people who contributed to this 12*ea0364f1SPeter Tyser * project. 13*ea0364f1SPeter Tyser * 14*ea0364f1SPeter Tyser * This program is free software; you can redistribute it and/or 15*ea0364f1SPeter Tyser * modify it under the terms of the GNU General Public License as 16*ea0364f1SPeter Tyser * published by the Free Software Foundation; either version 2 of 17*ea0364f1SPeter Tyser * the License, or (at your option) any later version. 18*ea0364f1SPeter Tyser * 19*ea0364f1SPeter Tyser * This program is distributed in the hope that it will be useful, 20*ea0364f1SPeter Tyser * but WITHOUT ANY WARRANTY; without even the implied warranty of 21*ea0364f1SPeter Tyser * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22*ea0364f1SPeter Tyser * GNU General Public License for more details. 23*ea0364f1SPeter Tyser * 24*ea0364f1SPeter Tyser * You should have received a copy of the GNU General Public License 25*ea0364f1SPeter Tyser * along with this program; if not, write to the Free Software 26*ea0364f1SPeter Tyser * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 27*ea0364f1SPeter Tyser * MA 02111-1307 USA 28*ea0364f1SPeter Tyser */ 29*ea0364f1SPeter Tyser 30*ea0364f1SPeter Tyser #include <common.h> 31*ea0364f1SPeter Tyser #include <div64.h> 32*ea0364f1SPeter Tyser #include <asm/processor.h> 33*ea0364f1SPeter Tyser #include <asm/clk.h> 34*ea0364f1SPeter Tyser #include <asm/io.h> 35*ea0364f1SPeter Tyser 36*ea0364f1SPeter Tyser #define TMU_MAX_COUNTER (~0UL) 37*ea0364f1SPeter Tyser 38*ea0364f1SPeter Tyser static ulong timer_freq; 39*ea0364f1SPeter Tyser 40*ea0364f1SPeter Tyser static inline unsigned long long tick_to_time(unsigned long long tick) 41*ea0364f1SPeter Tyser { 42*ea0364f1SPeter Tyser tick *= CONFIG_SYS_HZ; 43*ea0364f1SPeter Tyser do_div(tick, timer_freq); 44*ea0364f1SPeter Tyser 45*ea0364f1SPeter Tyser return tick; 46*ea0364f1SPeter Tyser } 47*ea0364f1SPeter Tyser 48*ea0364f1SPeter Tyser static inline unsigned long long usec_to_tick(unsigned long long usec) 49*ea0364f1SPeter Tyser { 50*ea0364f1SPeter Tyser usec *= timer_freq; 51*ea0364f1SPeter Tyser do_div(usec, 1000000); 52*ea0364f1SPeter Tyser 53*ea0364f1SPeter Tyser return usec; 54*ea0364f1SPeter Tyser } 55*ea0364f1SPeter Tyser 56*ea0364f1SPeter Tyser static void tmu_timer_start (unsigned int timer) 57*ea0364f1SPeter Tyser { 58*ea0364f1SPeter Tyser if (timer > 2) 59*ea0364f1SPeter Tyser return; 60*ea0364f1SPeter Tyser writeb(readb(TSTR) | (1 << timer), TSTR); 61*ea0364f1SPeter Tyser } 62*ea0364f1SPeter Tyser 63*ea0364f1SPeter Tyser static void tmu_timer_stop (unsigned int timer) 64*ea0364f1SPeter Tyser { 65*ea0364f1SPeter Tyser if (timer > 2) 66*ea0364f1SPeter Tyser return; 67*ea0364f1SPeter Tyser writeb(readb(TSTR) & ~(1 << timer), TSTR); 68*ea0364f1SPeter Tyser } 69*ea0364f1SPeter Tyser 70*ea0364f1SPeter Tyser int timer_init (void) 71*ea0364f1SPeter Tyser { 72*ea0364f1SPeter Tyser /* Divide clock by CONFIG_SYS_TMU_CLK_DIV */ 73*ea0364f1SPeter Tyser u16 bit = 0; 74*ea0364f1SPeter Tyser 75*ea0364f1SPeter Tyser switch (CONFIG_SYS_TMU_CLK_DIV) { 76*ea0364f1SPeter Tyser case 1024: 77*ea0364f1SPeter Tyser bit = 4; 78*ea0364f1SPeter Tyser break; 79*ea0364f1SPeter Tyser case 256: 80*ea0364f1SPeter Tyser bit = 3; 81*ea0364f1SPeter Tyser break; 82*ea0364f1SPeter Tyser case 64: 83*ea0364f1SPeter Tyser bit = 2; 84*ea0364f1SPeter Tyser break; 85*ea0364f1SPeter Tyser case 16: 86*ea0364f1SPeter Tyser bit = 1; 87*ea0364f1SPeter Tyser break; 88*ea0364f1SPeter Tyser case 4: 89*ea0364f1SPeter Tyser default: 90*ea0364f1SPeter Tyser break; 91*ea0364f1SPeter Tyser } 92*ea0364f1SPeter Tyser writew(readw(TCR0) | bit, TCR0); 93*ea0364f1SPeter Tyser 94*ea0364f1SPeter Tyser /* Calc clock rate */ 95*ea0364f1SPeter Tyser timer_freq = get_tmu0_clk_rate() >> ((bit + 1) * 2); 96*ea0364f1SPeter Tyser 97*ea0364f1SPeter Tyser tmu_timer_stop(0); 98*ea0364f1SPeter Tyser tmu_timer_start(0); 99*ea0364f1SPeter Tyser 100*ea0364f1SPeter Tyser return 0; 101*ea0364f1SPeter Tyser } 102*ea0364f1SPeter Tyser 103*ea0364f1SPeter Tyser unsigned long long get_ticks (void) 104*ea0364f1SPeter Tyser { 105*ea0364f1SPeter Tyser return 0 - readl(TCNT0); 106*ea0364f1SPeter Tyser } 107*ea0364f1SPeter Tyser 108*ea0364f1SPeter Tyser void __udelay (unsigned long usec) 109*ea0364f1SPeter Tyser { 110*ea0364f1SPeter Tyser unsigned long long tmp; 111*ea0364f1SPeter Tyser ulong tmo; 112*ea0364f1SPeter Tyser 113*ea0364f1SPeter Tyser tmo = usec_to_tick(usec); 114*ea0364f1SPeter Tyser tmp = get_ticks() + tmo; /* get current timestamp */ 115*ea0364f1SPeter Tyser 116*ea0364f1SPeter Tyser while (get_ticks() < tmp) /* loop till event */ 117*ea0364f1SPeter Tyser /*NOP*/; 118*ea0364f1SPeter Tyser } 119*ea0364f1SPeter Tyser 120*ea0364f1SPeter Tyser unsigned long get_timer (unsigned long base) 121*ea0364f1SPeter Tyser { 122*ea0364f1SPeter Tyser /* return msec */ 123*ea0364f1SPeter Tyser return tick_to_time(get_ticks()) - base; 124*ea0364f1SPeter Tyser } 125*ea0364f1SPeter Tyser 126*ea0364f1SPeter Tyser void set_timer (unsigned long t) 127*ea0364f1SPeter Tyser { 128*ea0364f1SPeter Tyser writel((0 - t), TCNT0); 129*ea0364f1SPeter Tyser } 130*ea0364f1SPeter Tyser 131*ea0364f1SPeter Tyser void reset_timer (void) 132*ea0364f1SPeter Tyser { 133*ea0364f1SPeter Tyser tmu_timer_stop(0); 134*ea0364f1SPeter Tyser set_timer (0); 135*ea0364f1SPeter Tyser tmu_timer_start(0); 136*ea0364f1SPeter Tyser } 137*ea0364f1SPeter Tyser 138*ea0364f1SPeter Tyser unsigned long get_tbclk (void) 139*ea0364f1SPeter Tyser { 140*ea0364f1SPeter Tyser return timer_freq; 141*ea0364f1SPeter Tyser } 142