183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+ 29fa32b12SVikas Manocha /* 31537d386SPatrice Chotard * Copyright (C) 2014, STMicroelectronics - All Rights Reserved 41537d386SPatrice Chotard * Author(s): Vikas Manocha, <vikas.manocha@st.com> for STMicroelectronics. 59fa32b12SVikas Manocha */ 69fa32b12SVikas Manocha 79fa32b12SVikas Manocha #include <common.h> 89fa32b12SVikas Manocha #include <asm/io.h> 99fa32b12SVikas Manocha #include <asm/arch-stv0991/hardware.h> 109fa32b12SVikas Manocha #include <asm/arch-stv0991/stv0991_cgu.h> 119fa32b12SVikas Manocha #include <asm/arch-stv0991/stv0991_gpt.h> 129fa32b12SVikas Manocha 139fa32b12SVikas Manocha static struct stv0991_cgu_regs *const stv0991_cgu_regs = \ 149fa32b12SVikas Manocha (struct stv0991_cgu_regs *) (CGU_BASE_ADDR); 159fa32b12SVikas Manocha 169fa32b12SVikas Manocha #define READ_TIMER() (readl(&gpt1_regs_ptr->cnt) & GPT_FREE_RUNNING) 179fa32b12SVikas Manocha #define GPT_RESOLUTION (CONFIG_STV0991_HZ_CLOCK / CONFIG_STV0991_HZ) 189fa32b12SVikas Manocha 199fa32b12SVikas Manocha DECLARE_GLOBAL_DATA_PTR; 209fa32b12SVikas Manocha 219fa32b12SVikas Manocha #define timestamp gd->arch.tbl 229fa32b12SVikas Manocha #define lastdec gd->arch.lastinc 239fa32b12SVikas Manocha 24*6180ea7eSPatrick Delaunay static ulong get_timer_masked(void); 25*6180ea7eSPatrick Delaunay timer_init(void)269fa32b12SVikas Manochaint timer_init(void) 279fa32b12SVikas Manocha { 289fa32b12SVikas Manocha /* Timer1 clock configuration */ 299fa32b12SVikas Manocha writel(TIMER1_CLK_CFG, &stv0991_cgu_regs->tim_freq); 309fa32b12SVikas Manocha writel(readl(&stv0991_cgu_regs->cgu_enable_2) | 319fa32b12SVikas Manocha TIMER1_CLK_EN, &stv0991_cgu_regs->cgu_enable_2); 329fa32b12SVikas Manocha 339fa32b12SVikas Manocha /* Stop the timer */ 349fa32b12SVikas Manocha writel(readl(&gpt1_regs_ptr->cr1) & ~GPT_CR1_CEN, &gpt1_regs_ptr->cr1); 359fa32b12SVikas Manocha writel(GPT_PRESCALER_128, &gpt1_regs_ptr->psc); 369fa32b12SVikas Manocha /* Configure timer for auto-reload */ 379fa32b12SVikas Manocha writel(readl(&gpt1_regs_ptr->cr1) | GPT_MODE_AUTO_RELOAD, 389fa32b12SVikas Manocha &gpt1_regs_ptr->cr1); 399fa32b12SVikas Manocha 409fa32b12SVikas Manocha /* load value for free running */ 419fa32b12SVikas Manocha writel(GPT_FREE_RUNNING, &gpt1_regs_ptr->arr); 429fa32b12SVikas Manocha 439fa32b12SVikas Manocha /* start timer */ 449fa32b12SVikas Manocha writel(readl(&gpt1_regs_ptr->cr1) | GPT_CR1_CEN, 459fa32b12SVikas Manocha &gpt1_regs_ptr->cr1); 469fa32b12SVikas Manocha 479fa32b12SVikas Manocha /* Reset the timer */ 489fa32b12SVikas Manocha lastdec = READ_TIMER(); 499fa32b12SVikas Manocha timestamp = 0; 509fa32b12SVikas Manocha 519fa32b12SVikas Manocha return 0; 529fa32b12SVikas Manocha } 539fa32b12SVikas Manocha 549fa32b12SVikas Manocha /* 559fa32b12SVikas Manocha * timer without interrupts 569fa32b12SVikas Manocha */ get_timer(ulong base)579fa32b12SVikas Manochaulong get_timer(ulong base) 589fa32b12SVikas Manocha { 599fa32b12SVikas Manocha return (get_timer_masked() / GPT_RESOLUTION) - base; 609fa32b12SVikas Manocha } 619fa32b12SVikas Manocha __udelay(unsigned long usec)629fa32b12SVikas Manochavoid __udelay(unsigned long usec) 639fa32b12SVikas Manocha { 649fa32b12SVikas Manocha ulong tmo; 659fa32b12SVikas Manocha ulong start = get_timer_masked(); 669fa32b12SVikas Manocha ulong tenudelcnt = CONFIG_STV0991_HZ_CLOCK / (1000 * 100); 679fa32b12SVikas Manocha ulong rndoff; 689fa32b12SVikas Manocha 699fa32b12SVikas Manocha rndoff = (usec % 10) ? 1 : 0; 709fa32b12SVikas Manocha 719fa32b12SVikas Manocha /* tenudelcnt timer tick gives 10 microsecconds delay */ 729fa32b12SVikas Manocha tmo = ((usec / 10) + rndoff) * tenudelcnt; 739fa32b12SVikas Manocha 749fa32b12SVikas Manocha while ((ulong) (get_timer_masked() - start) < tmo) 759fa32b12SVikas Manocha ; 769fa32b12SVikas Manocha } 779fa32b12SVikas Manocha get_timer_masked(void)78*6180ea7eSPatrick Delaunaystatic ulong get_timer_masked(void) 799fa32b12SVikas Manocha { 809fa32b12SVikas Manocha ulong now = READ_TIMER(); 819fa32b12SVikas Manocha 829fa32b12SVikas Manocha if (now >= lastdec) { 839fa32b12SVikas Manocha /* normal mode */ 849fa32b12SVikas Manocha timestamp += now - lastdec; 859fa32b12SVikas Manocha } else { 869fa32b12SVikas Manocha /* we have an overflow ... */ 879fa32b12SVikas Manocha timestamp += now + GPT_FREE_RUNNING - lastdec; 889fa32b12SVikas Manocha } 899fa32b12SVikas Manocha lastdec = now; 909fa32b12SVikas Manocha 919fa32b12SVikas Manocha return timestamp; 929fa32b12SVikas Manocha } 939fa32b12SVikas Manocha 949fa32b12SVikas Manocha /* 959fa32b12SVikas Manocha * This function is derived from PowerPC code (read timebase as long long). 969fa32b12SVikas Manocha * On ARM it just returns the timer value. 979fa32b12SVikas Manocha */ get_ticks(void)989fa32b12SVikas Manochaunsigned long long get_ticks(void) 999fa32b12SVikas Manocha { 1009fa32b12SVikas Manocha return get_timer(0); 1019fa32b12SVikas Manocha } 1029fa32b12SVikas Manocha 1039fa32b12SVikas Manocha /* 1049fa32b12SVikas Manocha * This function is derived from PowerPC code (timebase clock frequency). 1059fa32b12SVikas Manocha * On ARM it returns the number of timer ticks per second. 1069fa32b12SVikas Manocha */ get_tbclk(void)1079fa32b12SVikas Manochaulong get_tbclk(void) 1089fa32b12SVikas Manocha { 1099fa32b12SVikas Manocha return CONFIG_STV0991_HZ; 1109fa32b12SVikas Manocha } 111