uboot/arch/arm/mach-stm32/stm32f7/timer.c
<<
>>
Prefs
   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