1/* 2 * (C) Copyright 2003 3 * Texas Instruments <www.ti.com> 4 * 5 * (C) Copyright 2002 6 * Sysgo Real-Time Solutions, GmbH <www.elinos.com> 7 * Marius Groeger <mgroeger@sysgo.de> 8 * 9 * (C) Copyright 2002 10 * Sysgo Real-Time Solutions, GmbH <www.elinos.com> 11 * Alex Zuepke <azu@sysgo.de> 12 * 13 * (C) Copyright 2002-2004 14 * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> 15 * 16 * (C) Copyright 2004 17 * Philippe Robin, ARM Ltd. <philippe.robin@arm.com> 18 * 19 * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net> 20 * 21 * See file CREDITS for list of people who contributed to this 22 * project. 23 * 24 * This program is free software; you can redistribute it and/or 25 * modify it under the terms of the GNU General Public License as 26 * published by the Free Software Foundation; either version 2 of 27 * the License, or (at your option) any later version. 28 * 29 * This program is distributed in the hope that it will be useful, 30 * but WITHOUT ANY WARRANTY; without even the implied warranty of 31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 32 * GNU General Public License for more details. 33 * 34 * You should have received a copy of the GNU General Public License 35 * along with this program; if not, write to the Free Software 36 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 37 * MA 02111-1307 USA 38 */ 39 40#include <common.h> 41#include <asm/io.h> 42 43DECLARE_GLOBAL_DATA_PTR; 44 45struct davinci_timer { 46 u_int32_t pid12; 47 u_int32_t emumgt; 48 u_int32_t na1; 49 u_int32_t na2; 50 u_int32_t tim12; 51 u_int32_t tim34; 52 u_int32_t prd12; 53 u_int32_t prd34; 54 u_int32_t tcr; 55 u_int32_t tgcr; 56 u_int32_t wdtcr; 57}; 58 59static struct davinci_timer * const timer = 60 (struct davinci_timer *)CONFIG_SYS_TIMERBASE; 61 62#define TIMER_LOAD_VAL 0xffffffff 63 64#define TIM_CLK_DIV 16 65 66int timer_init(void) 67{ 68 /* We are using timer34 in unchained 32-bit mode, full speed */ 69 writel(0x0, &timer->tcr); 70 writel(0x0, &timer->tgcr); 71 writel(0x06 | ((TIM_CLK_DIV - 1) << 8), &timer->tgcr); 72 writel(0x0, &timer->tim34); 73 writel(TIMER_LOAD_VAL, &timer->prd34); 74 writel(2 << 22, &timer->tcr); 75 gd->timer_rate_hz = CONFIG_SYS_HZ_CLOCK / TIM_CLK_DIV; 76 gd->timer_reset_value = 0; 77 78 return(0); 79} 80 81void reset_timer(void) 82{ 83 gd->timer_reset_value = get_ticks(); 84} 85 86/* 87 * Get the current 64 bit timer tick count 88 */ 89unsigned long long get_ticks(void) 90{ 91 unsigned long now = readl(&timer->tim34); 92 93 /* increment tbu if tbl has rolled over */ 94 if (now < gd->tbl) 95 gd->tbu++; 96 gd->tbl = now; 97 98 return (((unsigned long long)gd->tbu) << 32) | gd->tbl; 99} 100 101ulong get_timer(ulong base) 102{ 103 unsigned long long timer_diff; 104 105 timer_diff = get_ticks() - gd->timer_reset_value; 106 107 return (timer_diff / (gd->timer_rate_hz / CONFIG_SYS_HZ)) - base; 108} 109 110void __udelay(unsigned long usec) 111{ 112 unsigned long long endtime; 113 114 endtime = ((unsigned long long)usec * gd->timer_rate_hz) / 1000000UL; 115 endtime += get_ticks(); 116 117 while (get_ticks() < endtime) 118 ; 119} 120 121/* 122 * This function is derived from PowerPC code (timebase clock frequency). 123 * On ARM it returns the number of timer ticks per second. 124 */ 125ulong get_tbclk(void) 126{ 127 return CONFIG_SYS_HZ; 128} 129