blob: 5af8caa40522ee90ea8aa3767806552bddb2db25 [file] [log] [blame]
Lin Huange7c24222016-11-30 16:57:08 +08001/*
2 * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
3 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Lin Huange7c24222016-11-30 16:57:08 +08005 */
6
7#include <m0_param.h>
8#include "rk3399_mcu.h"
9
10/* use 24MHz SysTick */
11#define US_TO_CYCLE(US) (US * 24)
12
13#define SYST_CST 0xe000e010
14/* enable counter */
15#define ENABLE (1 << 0)
16/* count down to 0 does not cause SysTick exception to pend */
17#define TICKINT (1 << 1)
18/* core clock used for SysTick */
19#define CLKSOURCE (1 << 2)
20
21#define COUNTFLAG (1 << 16)
22#define SYST_RVR 0xe000e014
23#define MAX_VALUE 0xffffff
24#define MAX_USECS (MAX_VALUE / US_TO_CYCLE(1))
25#define SYST_CVR 0xe000e018
26#define SYST_CALIB 0xe000e01c
27
28unsigned int remaining_usecs;
29
30static inline void stopwatch_set_usecs(void)
31{
32 unsigned int cycle;
33 unsigned int usecs = MIN(MAX_USECS, remaining_usecs);
34
35 remaining_usecs -= usecs;
36 cycle = US_TO_CYCLE(usecs);
37 mmio_write_32(SYST_RVR, cycle);
38 mmio_write_32(SYST_CVR, 0);
39
40 mmio_write_32(SYST_CST, ENABLE | TICKINT | CLKSOURCE);
41}
42
43void stopwatch_init_usecs_expire(unsigned int usecs)
44{
45 /*
46 * Enter an inifite loop if the stopwatch is in use. This will allow the
47 * state to be analyzed with a debugger.
48 */
49 if (mmio_read_32(SYST_CST) & ENABLE)
50 while (1)
51 ;
52
53 remaining_usecs = usecs;
54 stopwatch_set_usecs();
55}
56
57int stopwatch_expired(void)
58{
59 int val = mmio_read_32(SYST_CST);
60 if ((val & COUNTFLAG) || !(val & ENABLE)) {
61 if (!remaining_usecs)
62 return 1;
63
64 stopwatch_set_usecs();
65 }
66
67 return 0;
68}
69
70void stopwatch_reset(void)
71{
72 mmio_clrbits_32(SYST_CST, ENABLE);
73 remaining_usecs = 0;
74}