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