uboot/drivers/timer/ast_timer.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright 2016 Google Inc.
   4 */
   5
   6#include <common.h>
   7#include <dm.h>
   8#include <errno.h>
   9#include <timer.h>
  10#include <asm/io.h>
  11#include <asm/arch/timer.h>
  12
  13#define AST_TICK_TIMER  1
  14#define AST_TMC_RELOAD_VAL  0xffffffff
  15
  16struct ast_timer_priv {
  17        struct ast_timer *regs;
  18        struct ast_timer_counter *tmc;
  19};
  20
  21static struct ast_timer_counter *ast_get_timer_counter(struct ast_timer *timer,
  22                                                       int n)
  23{
  24        if (n > 3)
  25                return &timer->timers2[n - 4];
  26        else
  27                return &timer->timers1[n - 1];
  28}
  29
  30static int ast_timer_probe(struct udevice *dev)
  31{
  32        struct ast_timer_priv *priv = dev_get_priv(dev);
  33        struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
  34
  35        writel(AST_TMC_RELOAD_VAL, &priv->tmc->reload_val);
  36
  37        /*
  38         * Stop the timer. This will also load reload_val into
  39         * the status register.
  40         */
  41        clrbits_le32(&priv->regs->ctrl1,
  42                     AST_TMC_EN << AST_TMC_CTRL1_SHIFT(AST_TICK_TIMER));
  43        /* Start the timer from the fixed 1MHz clock. */
  44        setbits_le32(&priv->regs->ctrl1,
  45                     (AST_TMC_EN | AST_TMC_1MHZ) <<
  46                     AST_TMC_CTRL1_SHIFT(AST_TICK_TIMER));
  47
  48        uc_priv->clock_rate = AST_TMC_RATE;
  49
  50        return 0;
  51}
  52
  53static int ast_timer_get_count(struct udevice *dev, u64 *count)
  54{
  55        struct ast_timer_priv *priv = dev_get_priv(dev);
  56
  57        *count = AST_TMC_RELOAD_VAL - readl(&priv->tmc->status);
  58
  59        return 0;
  60}
  61
  62static int ast_timer_ofdata_to_platdata(struct udevice *dev)
  63{
  64        struct ast_timer_priv *priv = dev_get_priv(dev);
  65
  66        priv->regs = devfdt_get_addr_ptr(dev);
  67        if (IS_ERR(priv->regs))
  68                return PTR_ERR(priv->regs);
  69
  70        priv->tmc = ast_get_timer_counter(priv->regs, AST_TICK_TIMER);
  71
  72        return 0;
  73}
  74
  75static const struct timer_ops ast_timer_ops = {
  76        .get_count = ast_timer_get_count,
  77};
  78
  79static const struct udevice_id ast_timer_ids[] = {
  80        { .compatible = "aspeed,ast2500-timer" },
  81        { .compatible = "aspeed,ast2400-timer" },
  82        { }
  83};
  84
  85U_BOOT_DRIVER(ast_timer) = {
  86        .name = "ast_timer",
  87        .id = UCLASS_TIMER,
  88        .of_match = ast_timer_ids,
  89        .probe = ast_timer_probe,
  90        .priv_auto_alloc_size = sizeof(struct ast_timer_priv),
  91        .ofdata_to_platdata = ast_timer_ofdata_to_platdata,
  92        .ops = &ast_timer_ops,
  93};
  94