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