11aee5d7aSMark Rutland /* 21aee5d7aSMark Rutland * arch/arm64/include/asm/arch_timer.h 31aee5d7aSMark Rutland * 41aee5d7aSMark Rutland * Copyright (C) 2012 ARM Ltd. 51aee5d7aSMark Rutland * Author: Marc Zyngier <marc.zyngier@arm.com> 61aee5d7aSMark Rutland * 71aee5d7aSMark Rutland * This program is free software: you can redistribute it and/or modify 81aee5d7aSMark Rutland * it under the terms of the GNU General Public License version 2 as 91aee5d7aSMark Rutland * published by the Free Software Foundation. 101aee5d7aSMark Rutland * 111aee5d7aSMark Rutland * This program is distributed in the hope that it will be useful, 121aee5d7aSMark Rutland * but WITHOUT ANY WARRANTY; without even the implied warranty of 131aee5d7aSMark Rutland * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 141aee5d7aSMark Rutland * GNU General Public License for more details. 151aee5d7aSMark Rutland * 161aee5d7aSMark Rutland * You should have received a copy of the GNU General Public License 171aee5d7aSMark Rutland * along with this program. If not, see <http://www.gnu.org/licenses/>. 181aee5d7aSMark Rutland */ 191aee5d7aSMark Rutland #ifndef __ASM_ARCH_TIMER_H 201aee5d7aSMark Rutland #define __ASM_ARCH_TIMER_H 211aee5d7aSMark Rutland 221aee5d7aSMark Rutland #include <asm/barrier.h> 231aee5d7aSMark Rutland 241aee5d7aSMark Rutland #include <linux/init.h> 251aee5d7aSMark Rutland #include <linux/types.h> 261aee5d7aSMark Rutland 271aee5d7aSMark Rutland #include <clocksource/arm_arch_timer.h> 281aee5d7aSMark Rutland 291aee5d7aSMark Rutland static inline void arch_timer_reg_write(int access, int reg, u32 val) 301aee5d7aSMark Rutland { 311aee5d7aSMark Rutland if (access == ARCH_TIMER_PHYS_ACCESS) { 321aee5d7aSMark Rutland switch (reg) { 331aee5d7aSMark Rutland case ARCH_TIMER_REG_CTRL: 341aee5d7aSMark Rutland asm volatile("msr cntp_ctl_el0, %0" : : "r" (val)); 351aee5d7aSMark Rutland break; 361aee5d7aSMark Rutland case ARCH_TIMER_REG_TVAL: 371aee5d7aSMark Rutland asm volatile("msr cntp_tval_el0, %0" : : "r" (val)); 381aee5d7aSMark Rutland break; 391aee5d7aSMark Rutland default: 401aee5d7aSMark Rutland BUILD_BUG(); 411aee5d7aSMark Rutland } 421aee5d7aSMark Rutland } else if (access == ARCH_TIMER_VIRT_ACCESS) { 431aee5d7aSMark Rutland switch (reg) { 441aee5d7aSMark Rutland case ARCH_TIMER_REG_CTRL: 451aee5d7aSMark Rutland asm volatile("msr cntv_ctl_el0, %0" : : "r" (val)); 461aee5d7aSMark Rutland break; 471aee5d7aSMark Rutland case ARCH_TIMER_REG_TVAL: 481aee5d7aSMark Rutland asm volatile("msr cntv_tval_el0, %0" : : "r" (val)); 491aee5d7aSMark Rutland break; 501aee5d7aSMark Rutland default: 511aee5d7aSMark Rutland BUILD_BUG(); 521aee5d7aSMark Rutland } 531aee5d7aSMark Rutland } else { 541aee5d7aSMark Rutland BUILD_BUG(); 551aee5d7aSMark Rutland } 561aee5d7aSMark Rutland 571aee5d7aSMark Rutland isb(); 581aee5d7aSMark Rutland } 591aee5d7aSMark Rutland 601aee5d7aSMark Rutland static inline u32 arch_timer_reg_read(int access, int reg) 611aee5d7aSMark Rutland { 621aee5d7aSMark Rutland u32 val; 631aee5d7aSMark Rutland 641aee5d7aSMark Rutland if (access == ARCH_TIMER_PHYS_ACCESS) { 651aee5d7aSMark Rutland switch (reg) { 661aee5d7aSMark Rutland case ARCH_TIMER_REG_CTRL: 671aee5d7aSMark Rutland asm volatile("mrs %0, cntp_ctl_el0" : "=r" (val)); 681aee5d7aSMark Rutland break; 691aee5d7aSMark Rutland case ARCH_TIMER_REG_TVAL: 701aee5d7aSMark Rutland asm volatile("mrs %0, cntp_tval_el0" : "=r" (val)); 711aee5d7aSMark Rutland break; 721aee5d7aSMark Rutland default: 731aee5d7aSMark Rutland BUILD_BUG(); 741aee5d7aSMark Rutland } 751aee5d7aSMark Rutland } else if (access == ARCH_TIMER_VIRT_ACCESS) { 761aee5d7aSMark Rutland switch (reg) { 771aee5d7aSMark Rutland case ARCH_TIMER_REG_CTRL: 781aee5d7aSMark Rutland asm volatile("mrs %0, cntv_ctl_el0" : "=r" (val)); 791aee5d7aSMark Rutland break; 801aee5d7aSMark Rutland case ARCH_TIMER_REG_TVAL: 811aee5d7aSMark Rutland asm volatile("mrs %0, cntv_tval_el0" : "=r" (val)); 821aee5d7aSMark Rutland break; 831aee5d7aSMark Rutland default: 841aee5d7aSMark Rutland BUILD_BUG(); 851aee5d7aSMark Rutland } 861aee5d7aSMark Rutland } else { 871aee5d7aSMark Rutland BUILD_BUG(); 881aee5d7aSMark Rutland } 891aee5d7aSMark Rutland 901aee5d7aSMark Rutland return val; 911aee5d7aSMark Rutland } 921aee5d7aSMark Rutland 931aee5d7aSMark Rutland static inline u32 arch_timer_get_cntfrq(void) 941aee5d7aSMark Rutland { 951aee5d7aSMark Rutland u32 val; 961aee5d7aSMark Rutland asm volatile("mrs %0, cntfrq_el0" : "=r" (val)); 971aee5d7aSMark Rutland return val; 981aee5d7aSMark Rutland } 991aee5d7aSMark Rutland 1001aee5d7aSMark Rutland static inline void __cpuinit arch_counter_set_user_access(void) 1011aee5d7aSMark Rutland { 1021aee5d7aSMark Rutland u32 cntkctl; 1031aee5d7aSMark Rutland 1041aee5d7aSMark Rutland /* Disable user access to the timers and the physical counter. */ 1051aee5d7aSMark Rutland asm volatile("mrs %0, cntkctl_el1" : "=r" (cntkctl)); 1061aee5d7aSMark Rutland cntkctl &= ~((3 << 8) | (1 << 0)); 1071aee5d7aSMark Rutland 1081aee5d7aSMark Rutland /* Enable user access to the virtual counter and frequency. */ 1091aee5d7aSMark Rutland cntkctl |= (1 << 1); 1101aee5d7aSMark Rutland asm volatile("msr cntkctl_el1, %0" : : "r" (cntkctl)); 1111aee5d7aSMark Rutland } 1121aee5d7aSMark Rutland 1131aee5d7aSMark Rutland static inline u64 arch_counter_get_cntpct(void) 1141aee5d7aSMark Rutland { 1151aee5d7aSMark Rutland u64 cval; 1161aee5d7aSMark Rutland 1171aee5d7aSMark Rutland isb(); 1181aee5d7aSMark Rutland asm volatile("mrs %0, cntpct_el0" : "=r" (cval)); 1191aee5d7aSMark Rutland 1201aee5d7aSMark Rutland return cval; 1211aee5d7aSMark Rutland } 1221aee5d7aSMark Rutland 1231aee5d7aSMark Rutland static inline u64 arch_counter_get_cntvct(void) 1241aee5d7aSMark Rutland { 1251aee5d7aSMark Rutland u64 cval; 1261aee5d7aSMark Rutland 1271aee5d7aSMark Rutland isb(); 1281aee5d7aSMark Rutland asm volatile("mrs %0, cntvct_el0" : "=r" (cval)); 1291aee5d7aSMark Rutland 1301aee5d7aSMark Rutland return cval; 1311aee5d7aSMark Rutland } 1321aee5d7aSMark Rutland 133*0583fe47SRob Herring static inline int arch_timer_arch_init(void) 134*0583fe47SRob Herring { 135*0583fe47SRob Herring return 0; 136*0583fe47SRob Herring } 137*0583fe47SRob Herring 1381aee5d7aSMark Rutland #endif 139