xref: /rk3399_rockchip-uboot/arch/sh/lib/time_sh2.c (revision 707acd01ded3c60a4e277f7c5432d397897b4dfd)
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 Tyser static 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 Tyser static void cmt_timer_stop(unsigned int timer)
28ea0364f1SPeter Tyser {
29ea0364f1SPeter Tyser 	writew(readw(CMSTR) & ~0x01, CMSTR);
30ea0364f1SPeter Tyser }
31ea0364f1SPeter Tyser 
timer_init(void)32ea0364f1SPeter Tyser int 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 Tyser unsigned 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 Tyser static 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 Tyser ulong get_timer(ulong base)
73ea0364f1SPeter Tyser {
74ea0364f1SPeter Tyser 	return (get_usec() / 1000) - base;
75ea0364f1SPeter Tyser }
76ea0364f1SPeter Tyser 
__udelay(unsigned long usec)77ea0364f1SPeter Tyser void __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 Tyser unsigned long get_tbclk(void)
86ea0364f1SPeter Tyser {
87*8f0960e8SNobuhiro Iwamatsu 	return CONFIG_SH_CMT_CLK_FREQ;
88ea0364f1SPeter Tyser }
89