1 /* 2 * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * Redistributions of source code must retain the above copyright notice, this 8 * list of conditions and the following disclaimer. 9 * 10 * Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * Neither the name of ARM nor the names of its contributors may be used 15 * to endorse or promote products derived from this software without specific 16 * prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include <m0_param.h> 32 #include "rk3399_mcu.h" 33 34 /* use 24MHz SysTick */ 35 #define US_TO_CYCLE(US) (US * 24) 36 37 #define SYST_CST 0xe000e010 38 /* enable counter */ 39 #define ENABLE (1 << 0) 40 /* count down to 0 does not cause SysTick exception to pend */ 41 #define TICKINT (1 << 1) 42 /* core clock used for SysTick */ 43 #define CLKSOURCE (1 << 2) 44 45 #define COUNTFLAG (1 << 16) 46 #define SYST_RVR 0xe000e014 47 #define MAX_VALUE 0xffffff 48 #define MAX_USECS (MAX_VALUE / US_TO_CYCLE(1)) 49 #define SYST_CVR 0xe000e018 50 #define SYST_CALIB 0xe000e01c 51 52 unsigned int remaining_usecs; 53 54 static inline void stopwatch_set_usecs(void) 55 { 56 unsigned int cycle; 57 unsigned int usecs = MIN(MAX_USECS, remaining_usecs); 58 59 remaining_usecs -= usecs; 60 cycle = US_TO_CYCLE(usecs); 61 mmio_write_32(SYST_RVR, cycle); 62 mmio_write_32(SYST_CVR, 0); 63 64 mmio_write_32(SYST_CST, ENABLE | TICKINT | CLKSOURCE); 65 } 66 67 void stopwatch_init_usecs_expire(unsigned int usecs) 68 { 69 /* 70 * Enter an inifite loop if the stopwatch is in use. This will allow the 71 * state to be analyzed with a debugger. 72 */ 73 if (mmio_read_32(SYST_CST) & ENABLE) 74 while (1) 75 ; 76 77 remaining_usecs = usecs; 78 stopwatch_set_usecs(); 79 } 80 81 int stopwatch_expired(void) 82 { 83 int val = mmio_read_32(SYST_CST); 84 if ((val & COUNTFLAG) || !(val & ENABLE)) { 85 if (!remaining_usecs) 86 return 1; 87 88 stopwatch_set_usecs(); 89 } 90 91 return 0; 92 } 93 94 void stopwatch_reset(void) 95 { 96 mmio_clrbits_32(SYST_CST, ENABLE); 97 remaining_usecs = 0; 98 } 99