1*0a61ee88SVikas Manocha /* 2*0a61ee88SVikas Manocha * (C) Copyright 2015 3*0a61ee88SVikas Manocha * Kamil Lulko, <kamil.lulko@gmail.com> 4*0a61ee88SVikas Manocha * 5*0a61ee88SVikas Manocha * SPDX-License-Identifier: GPL-2.0+ 6*0a61ee88SVikas Manocha */ 7*0a61ee88SVikas Manocha 8*0a61ee88SVikas Manocha #include <common.h> 9*0a61ee88SVikas Manocha #include <asm/io.h> 10*0a61ee88SVikas Manocha #include <asm/armv7m.h> 11*0a61ee88SVikas Manocha #include <asm/arch/stm32.h> 12*0a61ee88SVikas Manocha 13*0a61ee88SVikas Manocha DECLARE_GLOBAL_DATA_PTR; 14*0a61ee88SVikas Manocha 15*0a61ee88SVikas Manocha #define STM32_TIM2_BASE (STM32_APB1PERIPH_BASE + 0x0000) 16*0a61ee88SVikas Manocha 17*0a61ee88SVikas Manocha #define RCC_APB1ENR_TIM2EN (1 << 0) 18*0a61ee88SVikas Manocha 19*0a61ee88SVikas Manocha struct stm32_tim2_5 { 20*0a61ee88SVikas Manocha u32 cr1; 21*0a61ee88SVikas Manocha u32 cr2; 22*0a61ee88SVikas Manocha u32 smcr; 23*0a61ee88SVikas Manocha u32 dier; 24*0a61ee88SVikas Manocha u32 sr; 25*0a61ee88SVikas Manocha u32 egr; 26*0a61ee88SVikas Manocha u32 ccmr1; 27*0a61ee88SVikas Manocha u32 ccmr2; 28*0a61ee88SVikas Manocha u32 ccer; 29*0a61ee88SVikas Manocha u32 cnt; 30*0a61ee88SVikas Manocha u32 psc; 31*0a61ee88SVikas Manocha u32 arr; 32*0a61ee88SVikas Manocha u32 reserved1; 33*0a61ee88SVikas Manocha u32 ccr1; 34*0a61ee88SVikas Manocha u32 ccr2; 35*0a61ee88SVikas Manocha u32 ccr3; 36*0a61ee88SVikas Manocha u32 ccr4; 37*0a61ee88SVikas Manocha u32 reserved2; 38*0a61ee88SVikas Manocha u32 dcr; 39*0a61ee88SVikas Manocha u32 dmar; 40*0a61ee88SVikas Manocha u32 or; 41*0a61ee88SVikas Manocha }; 42*0a61ee88SVikas Manocha 43*0a61ee88SVikas Manocha #define TIM_CR1_CEN (1 << 0) 44*0a61ee88SVikas Manocha 45*0a61ee88SVikas Manocha #define TIM_EGR_UG (1 << 0) 46*0a61ee88SVikas Manocha timer_init(void)47*0a61ee88SVikas Manochaint timer_init(void) 48*0a61ee88SVikas Manocha { 49*0a61ee88SVikas Manocha struct stm32_tim2_5 *tim = (struct stm32_tim2_5 *)STM32_TIM2_BASE; 50*0a61ee88SVikas Manocha 51*0a61ee88SVikas Manocha setbits_le32(&STM32_RCC->apb1enr, RCC_APB1ENR_TIM2EN); 52*0a61ee88SVikas Manocha 53*0a61ee88SVikas Manocha if (clock_get(CLOCK_AHB) == clock_get(CLOCK_APB1)) 54*0a61ee88SVikas Manocha writel((clock_get(CLOCK_APB1) / CONFIG_SYS_HZ_CLOCK) - 1, 55*0a61ee88SVikas Manocha &tim->psc); 56*0a61ee88SVikas Manocha else 57*0a61ee88SVikas Manocha writel(((clock_get(CLOCK_APB1) * 2) / CONFIG_SYS_HZ_CLOCK) - 1, 58*0a61ee88SVikas Manocha &tim->psc); 59*0a61ee88SVikas Manocha 60*0a61ee88SVikas Manocha writel(0xFFFFFFFF, &tim->arr); 61*0a61ee88SVikas Manocha writel(TIM_CR1_CEN, &tim->cr1); 62*0a61ee88SVikas Manocha setbits_le32(&tim->egr, TIM_EGR_UG); 63*0a61ee88SVikas Manocha 64*0a61ee88SVikas Manocha gd->arch.tbl = 0; 65*0a61ee88SVikas Manocha gd->arch.tbu = 0; 66*0a61ee88SVikas Manocha gd->arch.lastinc = 0; 67*0a61ee88SVikas Manocha 68*0a61ee88SVikas Manocha return 0; 69*0a61ee88SVikas Manocha } 70*0a61ee88SVikas Manocha get_timer(ulong base)71*0a61ee88SVikas Manochaulong get_timer(ulong base) 72*0a61ee88SVikas Manocha { 73*0a61ee88SVikas Manocha return (get_ticks() / (CONFIG_SYS_HZ_CLOCK / CONFIG_SYS_HZ)) - base; 74*0a61ee88SVikas Manocha } 75*0a61ee88SVikas Manocha get_ticks(void)76*0a61ee88SVikas Manochaunsigned long long get_ticks(void) 77*0a61ee88SVikas Manocha { 78*0a61ee88SVikas Manocha struct stm32_tim2_5 *tim = (struct stm32_tim2_5 *)STM32_TIM2_BASE; 79*0a61ee88SVikas Manocha u32 now; 80*0a61ee88SVikas Manocha 81*0a61ee88SVikas Manocha now = readl(&tim->cnt); 82*0a61ee88SVikas Manocha 83*0a61ee88SVikas Manocha if (now >= gd->arch.lastinc) 84*0a61ee88SVikas Manocha gd->arch.tbl += (now - gd->arch.lastinc); 85*0a61ee88SVikas Manocha else 86*0a61ee88SVikas Manocha gd->arch.tbl += (0xFFFFFFFF - gd->arch.lastinc) + now; 87*0a61ee88SVikas Manocha 88*0a61ee88SVikas Manocha gd->arch.lastinc = now; 89*0a61ee88SVikas Manocha 90*0a61ee88SVikas Manocha return gd->arch.tbl; 91*0a61ee88SVikas Manocha } 92*0a61ee88SVikas Manocha reset_timer(void)93*0a61ee88SVikas Manochavoid reset_timer(void) 94*0a61ee88SVikas Manocha { 95*0a61ee88SVikas Manocha struct stm32_tim2_5 *tim = (struct stm32_tim2_5 *)STM32_TIM2_BASE; 96*0a61ee88SVikas Manocha 97*0a61ee88SVikas Manocha gd->arch.lastinc = readl(&tim->cnt); 98*0a61ee88SVikas Manocha gd->arch.tbl = 0; 99*0a61ee88SVikas Manocha } 100*0a61ee88SVikas Manocha 101*0a61ee88SVikas Manocha /* delay x useconds */ __udelay(ulong usec)102*0a61ee88SVikas Manochavoid __udelay(ulong usec) 103*0a61ee88SVikas Manocha { 104*0a61ee88SVikas Manocha unsigned long long start; 105*0a61ee88SVikas Manocha 106*0a61ee88SVikas Manocha start = get_ticks(); /* get current timestamp */ 107*0a61ee88SVikas Manocha while ((get_ticks() - start) < usec) 108*0a61ee88SVikas Manocha ; /* loop till time has passed */ 109*0a61ee88SVikas Manocha } 110*0a61ee88SVikas Manocha 111*0a61ee88SVikas Manocha /* 112*0a61ee88SVikas Manocha * This function is derived from PowerPC code (timebase clock frequency). 113*0a61ee88SVikas Manocha * On ARM it returns the number of timer ticks per second. 114*0a61ee88SVikas Manocha */ get_tbclk(void)115*0a61ee88SVikas Manochaulong get_tbclk(void) 116*0a61ee88SVikas Manocha { 117*0a61ee88SVikas Manocha return CONFIG_SYS_HZ_CLOCK; 118*0a61ee88SVikas Manocha } 119