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