Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
      3  *
      4  * SPDX-License-Identifier: BSD-3-Clause
      5  */
      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 
     28 unsigned int remaining_usecs;
     29 
     30 static 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 
     43 void 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 
     57 int 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 
     70 void stopwatch_reset(void)
     71 {
     72 	mmio_clrbits_32(SYST_CST, ENABLE);
     73 	remaining_usecs = 0;
     74 }
     75