uboot/arch/arm/mach-at91/arm920t/timer.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (C) Copyright 2002
   4 * Lineo, Inc. <www.lineo.com>
   5 * Bernhard Kuhn <bkuhn@lineo.com>
   6 *
   7 * (C) Copyright 2002
   8 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
   9 * Marius Groeger <mgroeger@sysgo.de>
  10 *
  11 * (C) Copyright 2002
  12 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
  13 * Alex Zuepke <azu@sysgo.de>
  14 */
  15
  16#include <common.h>
  17
  18#include <asm/io.h>
  19#include <asm/arch/hardware.h>
  20#include <asm/arch/at91_tc.h>
  21#include <asm/arch/clk.h>
  22
  23DECLARE_GLOBAL_DATA_PTR;
  24
  25/* the number of clocks per CONFIG_SYS_HZ */
  26#define TIMER_LOAD_VAL (CONFIG_SYS_HZ_CLOCK/CONFIG_SYS_HZ)
  27
  28int timer_init(void)
  29{
  30        at91_tc_t *tc = (at91_tc_t *) ATMEL_BASE_TC;
  31
  32        at91_periph_clk_enable(ATMEL_ID_TC0);
  33
  34        writel(0, &tc->bcr);
  35        writel(AT91_TC_BMR_TC0XC0S_NONE | AT91_TC_BMR_TC1XC1S_NONE |
  36                AT91_TC_BMR_TC2XC2S_NONE , &tc->bmr);
  37
  38        writel(AT91_TC_CCR_CLKDIS, &tc->tc[0].ccr);
  39        /* set to MCLK/2 and restart the timer
  40        when the value in TC_RC is reached */
  41        writel(AT91_TC_CMR_TCCLKS_CLOCK1 | AT91_TC_CMR_CPCTRG, &tc->tc[0].cmr);
  42
  43        writel(0xFFFFFFFF, &tc->tc[0].idr); /* disable interrupts */
  44        writel(TIMER_LOAD_VAL, &tc->tc[0].rc);
  45
  46        writel(AT91_TC_CCR_SWTRG | AT91_TC_CCR_CLKEN, &tc->tc[0].ccr);
  47        gd->arch.lastinc = 0;
  48        gd->arch.tbl = 0;
  49
  50        return 0;
  51}
  52
  53/*
  54 * timer without interrupts
  55 */
  56ulong get_timer(ulong base)
  57{
  58        return get_timer_masked() - base;
  59}
  60
  61void __udelay(unsigned long usec)
  62{
  63        udelay_masked(usec);
  64}
  65
  66ulong get_timer_raw(void)
  67{
  68        at91_tc_t *tc = (at91_tc_t *) ATMEL_BASE_TC;
  69        u32 now;
  70
  71        now = readl(&tc->tc[0].cv) & 0x0000ffff;
  72
  73        if (now >= gd->arch.lastinc) {
  74                /* normal mode */
  75                gd->arch.tbl += now - gd->arch.lastinc;
  76        } else {
  77                /* we have an overflow ... */
  78                gd->arch.tbl += now + TIMER_LOAD_VAL - gd->arch.lastinc;
  79        }
  80        gd->arch.lastinc = now;
  81
  82        return gd->arch.tbl;
  83}
  84
  85ulong get_timer_masked(void)
  86{
  87        return get_timer_raw()/TIMER_LOAD_VAL;
  88}
  89
  90void udelay_masked(unsigned long usec)
  91{
  92        u32 tmo;
  93        u32 endtime;
  94        signed long diff;
  95
  96        tmo = CONFIG_SYS_HZ_CLOCK / 1000;
  97        tmo *= usec;
  98        tmo /= 1000;
  99
 100        endtime = get_timer_raw() + tmo;
 101
 102        do {
 103                u32 now = get_timer_raw();
 104                diff = endtime - now;
 105        } while (diff >= 0);
 106}
 107
 108/*
 109 * This function is derived from PowerPC code (read timebase as long long).
 110 * On ARM it just returns the timer value.
 111 */
 112unsigned long long get_ticks(void)
 113{
 114        return get_timer(0);
 115}
 116
 117/*
 118 * This function is derived from PowerPC code (timebase clock frequency).
 119 * On ARM it returns the number of timer ticks per second.
 120 */
 121ulong get_tbclk(void)
 122{
 123        return CONFIG_SYS_HZ;
 124}
 125