1 /* 2 * (C) Copyright 2016 3 * Vikas Manocha, ST Micoelectronics, vikas.manocha@st.com. 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <common.h> 9 #include <asm/io.h> 10 #include <asm/arch/stm32.h> 11 #include <asm/arch/stm32_defs.h> 12 #include <asm/arch/gpt.h> 13 14 #define READ_TIMER() (readl(&gpt1_regs_ptr->cnt) & GPT_FREE_RUNNING) 15 #define GPT_RESOLUTION (CONFIG_SYS_HZ_CLOCK/CONFIG_STM32_HZ) 16 17 DECLARE_GLOBAL_DATA_PTR; 18 19 #define timestamp gd->arch.tbl 20 #define lastdec gd->arch.lastinc 21 timer_init(void)22int timer_init(void) 23 { 24 /* Timer2 clock configuration */ 25 clock_setup(TIMER2_CLOCK_CFG); 26 /* Stop the timer */ 27 writel(readl(&gpt1_regs_ptr->cr1) & ~GPT_CR1_CEN, &gpt1_regs_ptr->cr1); 28 29 writel((CONFIG_SYS_CLK_FREQ/CONFIG_SYS_HZ_CLOCK) - 1, 30 &gpt1_regs_ptr->psc); 31 32 /* Configure timer for auto-reload */ 33 writel(readl(&gpt1_regs_ptr->cr1) | GPT_MODE_AUTO_RELOAD, 34 &gpt1_regs_ptr->cr1); 35 36 /* load value for free running */ 37 writel(GPT_FREE_RUNNING, &gpt1_regs_ptr->arr); 38 39 /* start timer */ 40 writel(readl(&gpt1_regs_ptr->cr1) | GPT_CR1_CEN, &gpt1_regs_ptr->cr1); 41 42 writel(readl(&gpt1_regs_ptr->egr) | TIM_EGR_UG, &gpt1_regs_ptr->egr); 43 44 /* Reset the timer */ 45 lastdec = READ_TIMER(); 46 timestamp = 0; 47 48 return 0; 49 } 50 51 /* 52 * timer without interrupts 53 */ get_timer(ulong base)54ulong get_timer(ulong base) 55 { 56 return (get_timer_masked() / GPT_RESOLUTION) - base; 57 } 58 __udelay(unsigned long usec)59void __udelay(unsigned long usec) 60 { 61 ulong tmo; 62 ulong start = get_timer_masked(); 63 ulong tenudelcnt = CONFIG_SYS_HZ_CLOCK / (1000 * 100); 64 ulong rndoff; 65 66 rndoff = (usec % 10) ? 1 : 0; 67 68 /* tenudelcnt timer tick gives 10 microsecconds delay */ 69 tmo = ((usec / 10) + rndoff) * tenudelcnt; 70 71 while ((ulong) (get_timer_masked() - start) < tmo) 72 ; 73 } 74 get_timer_masked(void)75ulong get_timer_masked(void) 76 { 77 ulong now = READ_TIMER(); 78 79 if (now >= lastdec) { 80 /* normal mode */ 81 timestamp += now - lastdec; 82 } else { 83 /* we have an overflow ... */ 84 timestamp += now + GPT_FREE_RUNNING - lastdec; 85 } 86 lastdec = now; 87 88 return timestamp; 89 } 90 udelay_masked(unsigned long usec)91void udelay_masked(unsigned long usec) 92 { 93 return udelay(usec); 94 } 95 96 /* 97 * This function is derived from PowerPC code (read timebase as long long). 98 * On ARM it just returns the timer value. 99 */ get_ticks(void)100unsigned long long get_ticks(void) 101 { 102 return get_timer(0); 103 } 104 105 /* 106 * This function is derived from PowerPC code (timebase clock frequency). 107 * On ARM it returns the number of timer ticks per second. 108 */ get_tbclk(void)109ulong get_tbclk(void) 110 { 111 return CONFIG_STM32_HZ; 112 } 113