Home | History | Annotate | Download | only in lib
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * Copyright (C) 2007,2008 Nobobuhiro Iwamatsu <iwamatsu (at) nigauri.org>
      4  * Copyright (C) 2008 Renesas Solutions Corp.
      5  *
      6  * (C) Copyright 2003
      7  * Wolfgang Denk, DENX Software Engineering, wd (at) 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 
     19 static vu_long cmt0_timer;
     20 
     21 static void cmt_timer_start(unsigned int timer)
     22 {
     23 	writew(readw(CMSTR) | 0x01, CMSTR);
     24 }
     25 
     26 static void cmt_timer_stop(unsigned int timer)
     27 {
     28 	writew(readw(CMSTR) & ~0x01, CMSTR);
     29 }
     30 
     31 int 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 
     46 unsigned long long get_ticks(void)
     47 {
     48 	return cmt0_timer;
     49 }
     50 
     51 static vu_long cmcnt = 0;
     52 static 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 */
     71 ulong get_timer(ulong base)
     72 {
     73 	return (get_usec() / 1000) - base;
     74 }
     75 
     76 void __udelay(unsigned long usec)
     77 {
     78 	unsigned long end = get_usec() + usec;
     79 
     80 	while (get_usec() < end)
     81 		continue;
     82 }
     83 
     84 unsigned long get_tbclk(void)
     85 {
     86 	return CONFIG_SH_CMT_CLK_FREQ;
     87 }
     88