1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (C) 2007,2008 Nobobuhiro Iwamatsu <iwamatsu@nigauri.org> 4 * Copyright (C) 2008 Renesas Solutions Corp. 5 * 6 * (C) Copyright 2003 7 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 8 */ 9 10#include <common.h> 11#include <asm/io.h> 12#include <asm/processor.h> 13 14#define CMT_CMCSR_INIT 0x0001 /* PCLK/32 */ 15#define CMT_CMCSR_CALIB 0x0000 16#define CMT_MAX_COUNTER (0xFFFFFFFF) 17#define CMT_TIMER_RESET (0xFFFF) 18 19static vu_long cmt0_timer; 20 21static void cmt_timer_start(unsigned int timer) 22{ 23 writew(readw(CMSTR) | 0x01, CMSTR); 24} 25 26static void cmt_timer_stop(unsigned int timer) 27{ 28 writew(readw(CMSTR) & ~0x01, CMSTR); 29} 30 31int timer_init(void) 32{ 33 cmt0_timer = 0; 34 /* Divide clock by 32 */ 35 readw(CMCSR_0); 36 writew(CMT_CMCSR_INIT, CMCSR_0); 37 38 /* User Device 0 only */ 39 cmt_timer_stop(0); 40 writew(CMT_TIMER_RESET, CMCOR_0); 41 cmt_timer_start(0); 42 43 return 0; 44} 45 46unsigned long long get_ticks(void) 47{ 48 return cmt0_timer; 49} 50 51static vu_long cmcnt = 0; 52static unsigned long get_usec (void) 53{ 54 ulong data = readw(CMCNT_0); 55 56 if (data >= cmcnt) 57 cmcnt = data - cmcnt; 58 else 59 cmcnt = (CMT_TIMER_RESET - cmcnt) + data; 60 61 if ((cmt0_timer + cmcnt) > CMT_MAX_COUNTER) 62 cmt0_timer = ((cmt0_timer + cmcnt) - CMT_MAX_COUNTER); 63 else 64 cmt0_timer += cmcnt; 65 66 cmcnt = data; 67 return cmt0_timer; 68} 69 70/* return msec */ 71ulong get_timer(ulong base) 72{ 73 return (get_usec() / 1000) - base; 74} 75 76void __udelay(unsigned long usec) 77{ 78 unsigned long end = get_usec() + usec; 79 80 while (get_usec() < end) 81 continue; 82} 83 84unsigned long get_tbclk(void) 85{ 86 return CONFIG_SH_CMT_CLK_FREQ; 87} 88