1*601fbec7SMasahiro Yamada /* 2*601fbec7SMasahiro Yamada * (C) Copyright 2003 3*601fbec7SMasahiro Yamada * Texas Instruments <www.ti.com> 4*601fbec7SMasahiro Yamada * 5*601fbec7SMasahiro Yamada * (C) Copyright 2002 6*601fbec7SMasahiro Yamada * Sysgo Real-Time Solutions, GmbH <www.elinos.com> 7*601fbec7SMasahiro Yamada * Marius Groeger <mgroeger@sysgo.de> 8*601fbec7SMasahiro Yamada * 9*601fbec7SMasahiro Yamada * (C) Copyright 2002 10*601fbec7SMasahiro Yamada * Sysgo Real-Time Solutions, GmbH <www.elinos.com> 11*601fbec7SMasahiro Yamada * Alex Zuepke <azu@sysgo.de> 12*601fbec7SMasahiro Yamada * 13*601fbec7SMasahiro Yamada * (C) Copyright 2002-2004 14*601fbec7SMasahiro Yamada * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> 15*601fbec7SMasahiro Yamada * 16*601fbec7SMasahiro Yamada * (C) Copyright 2004 17*601fbec7SMasahiro Yamada * Philippe Robin, ARM Ltd. <philippe.robin@arm.com> 18*601fbec7SMasahiro Yamada * 19*601fbec7SMasahiro Yamada * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net> 20*601fbec7SMasahiro Yamada * 21*601fbec7SMasahiro Yamada * SPDX-License-Identifier: GPL-2.0+ 22*601fbec7SMasahiro Yamada */ 23*601fbec7SMasahiro Yamada 24*601fbec7SMasahiro Yamada #include <common.h> 25*601fbec7SMasahiro Yamada #include <asm/io.h> 26*601fbec7SMasahiro Yamada #include <asm/arch/timer_defs.h> 27*601fbec7SMasahiro Yamada #include <div64.h> 28*601fbec7SMasahiro Yamada 29*601fbec7SMasahiro Yamada DECLARE_GLOBAL_DATA_PTR; 30*601fbec7SMasahiro Yamada 31*601fbec7SMasahiro Yamada static struct davinci_timer * const timer = 32*601fbec7SMasahiro Yamada (struct davinci_timer *)CONFIG_SYS_TIMERBASE; 33*601fbec7SMasahiro Yamada 34*601fbec7SMasahiro Yamada #define TIMER_LOAD_VAL 0xffffffff 35*601fbec7SMasahiro Yamada 36*601fbec7SMasahiro Yamada #define TIM_CLK_DIV 16 37*601fbec7SMasahiro Yamada 38*601fbec7SMasahiro Yamada int timer_init(void) 39*601fbec7SMasahiro Yamada { 40*601fbec7SMasahiro Yamada /* We are using timer34 in unchained 32-bit mode, full speed */ 41*601fbec7SMasahiro Yamada writel(0x0, &timer->tcr); 42*601fbec7SMasahiro Yamada writel(0x0, &timer->tgcr); 43*601fbec7SMasahiro Yamada writel(0x06 | ((TIM_CLK_DIV - 1) << 8), &timer->tgcr); 44*601fbec7SMasahiro Yamada writel(0x0, &timer->tim34); 45*601fbec7SMasahiro Yamada writel(TIMER_LOAD_VAL, &timer->prd34); 46*601fbec7SMasahiro Yamada writel(2 << 22, &timer->tcr); 47*601fbec7SMasahiro Yamada gd->arch.timer_rate_hz = CONFIG_SYS_HZ_CLOCK / TIM_CLK_DIV; 48*601fbec7SMasahiro Yamada gd->arch.timer_reset_value = 0; 49*601fbec7SMasahiro Yamada 50*601fbec7SMasahiro Yamada return(0); 51*601fbec7SMasahiro Yamada } 52*601fbec7SMasahiro Yamada 53*601fbec7SMasahiro Yamada /* 54*601fbec7SMasahiro Yamada * Get the current 64 bit timer tick count 55*601fbec7SMasahiro Yamada */ 56*601fbec7SMasahiro Yamada unsigned long long get_ticks(void) 57*601fbec7SMasahiro Yamada { 58*601fbec7SMasahiro Yamada unsigned long now = readl(&timer->tim34); 59*601fbec7SMasahiro Yamada 60*601fbec7SMasahiro Yamada /* increment tbu if tbl has rolled over */ 61*601fbec7SMasahiro Yamada if (now < gd->arch.tbl) 62*601fbec7SMasahiro Yamada gd->arch.tbu++; 63*601fbec7SMasahiro Yamada gd->arch.tbl = now; 64*601fbec7SMasahiro Yamada 65*601fbec7SMasahiro Yamada return (((unsigned long long)gd->arch.tbu) << 32) | gd->arch.tbl; 66*601fbec7SMasahiro Yamada } 67*601fbec7SMasahiro Yamada 68*601fbec7SMasahiro Yamada ulong get_timer(ulong base) 69*601fbec7SMasahiro Yamada { 70*601fbec7SMasahiro Yamada unsigned long long timer_diff; 71*601fbec7SMasahiro Yamada 72*601fbec7SMasahiro Yamada timer_diff = get_ticks() - gd->arch.timer_reset_value; 73*601fbec7SMasahiro Yamada 74*601fbec7SMasahiro Yamada return lldiv(timer_diff, 75*601fbec7SMasahiro Yamada (gd->arch.timer_rate_hz / CONFIG_SYS_HZ)) - base; 76*601fbec7SMasahiro Yamada } 77*601fbec7SMasahiro Yamada 78*601fbec7SMasahiro Yamada void __udelay(unsigned long usec) 79*601fbec7SMasahiro Yamada { 80*601fbec7SMasahiro Yamada unsigned long long endtime; 81*601fbec7SMasahiro Yamada 82*601fbec7SMasahiro Yamada endtime = lldiv((unsigned long long)usec * gd->arch.timer_rate_hz, 83*601fbec7SMasahiro Yamada 1000000UL); 84*601fbec7SMasahiro Yamada endtime += get_ticks(); 85*601fbec7SMasahiro Yamada 86*601fbec7SMasahiro Yamada while (get_ticks() < endtime) 87*601fbec7SMasahiro Yamada ; 88*601fbec7SMasahiro Yamada } 89*601fbec7SMasahiro Yamada 90*601fbec7SMasahiro Yamada /* 91*601fbec7SMasahiro Yamada * This function is derived from PowerPC code (timebase clock frequency). 92*601fbec7SMasahiro Yamada * On ARM it returns the number of timer ticks per second. 93*601fbec7SMasahiro Yamada */ 94*601fbec7SMasahiro Yamada ulong get_tbclk(void) 95*601fbec7SMasahiro Yamada { 96*601fbec7SMasahiro Yamada return gd->arch.timer_rate_hz; 97*601fbec7SMasahiro Yamada } 98*601fbec7SMasahiro Yamada 99*601fbec7SMasahiro Yamada #ifdef CONFIG_HW_WATCHDOG 100*601fbec7SMasahiro Yamada static struct davinci_timer * const wdttimer = 101*601fbec7SMasahiro Yamada (struct davinci_timer *)CONFIG_SYS_WDTTIMERBASE; 102*601fbec7SMasahiro Yamada 103*601fbec7SMasahiro Yamada /* 104*601fbec7SMasahiro Yamada * See prufw2.pdf for using Timer as a WDT 105*601fbec7SMasahiro Yamada */ 106*601fbec7SMasahiro Yamada void davinci_hw_watchdog_enable(void) 107*601fbec7SMasahiro Yamada { 108*601fbec7SMasahiro Yamada writel(0x0, &wdttimer->tcr); 109*601fbec7SMasahiro Yamada writel(0x0, &wdttimer->tgcr); 110*601fbec7SMasahiro Yamada /* TIMMODE = 2h */ 111*601fbec7SMasahiro Yamada writel(0x08 | 0x03 | ((TIM_CLK_DIV - 1) << 8), &wdttimer->tgcr); 112*601fbec7SMasahiro Yamada writel(CONFIG_SYS_WDT_PERIOD_LOW, &wdttimer->prd12); 113*601fbec7SMasahiro Yamada writel(CONFIG_SYS_WDT_PERIOD_HIGH, &wdttimer->prd34); 114*601fbec7SMasahiro Yamada writel(2 << 22, &wdttimer->tcr); 115*601fbec7SMasahiro Yamada writel(0x0, &wdttimer->tim12); 116*601fbec7SMasahiro Yamada writel(0x0, &wdttimer->tim34); 117*601fbec7SMasahiro Yamada /* set WDEN bit, WDKEY 0xa5c6 */ 118*601fbec7SMasahiro Yamada writel(0xa5c64000, &wdttimer->wdtcr); 119*601fbec7SMasahiro Yamada /* clear counter register */ 120*601fbec7SMasahiro Yamada writel(0xda7e4000, &wdttimer->wdtcr); 121*601fbec7SMasahiro Yamada } 122*601fbec7SMasahiro Yamada 123*601fbec7SMasahiro Yamada void davinci_hw_watchdog_reset(void) 124*601fbec7SMasahiro Yamada { 125*601fbec7SMasahiro Yamada writel(0xa5c64000, &wdttimer->wdtcr); 126*601fbec7SMasahiro Yamada writel(0xda7e4000, &wdttimer->wdtcr); 127*601fbec7SMasahiro Yamada } 128*601fbec7SMasahiro Yamada #endif 129