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