uboot/drivers/timer/fttmr010_timer.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (C) Copyright 2009 Faraday Technology
   4 * Po-Yu Chuang <ratbert@faraday-tech.com>
   5 *
   6 * 23/08/2022 Port to DM
   7 */
   8#include <common.h>
   9#include <dm.h>
  10#include <log.h>
  11#include <timer.h>
  12#include <asm/io.h>
  13#include <dm/ofnode.h>
  14#include <faraday/fttmr010.h>
  15#include <asm/global_data.h>
  16
  17#define TIMER_LOAD_VAL  0xffffffff
  18
  19struct fttmr010_timer_priv {
  20        struct fttmr010 __iomem *regs;
  21};
  22
  23static u64 fttmr010_timer_get_count(struct udevice *dev)
  24{
  25        struct fttmr010_timer_priv *priv = dev_get_priv(dev);
  26        struct fttmr010 *tmr = priv->regs;
  27        u32 now = TIMER_LOAD_VAL - readl(&tmr->timer3_counter);
  28
  29        /* increment tbu if tbl has rolled over */
  30        if (now < gd->arch.tbl)
  31                gd->arch.tbu++;
  32        gd->arch.tbl = now;
  33
  34        return ((u64)gd->arch.tbu << 32) | gd->arch.tbl;
  35}
  36
  37static int fttmr010_timer_probe(struct udevice *dev)
  38{
  39        struct fttmr010_timer_priv *priv = dev_get_priv(dev);
  40        struct fttmr010 *tmr;
  41        unsigned int cr;
  42
  43        priv->regs = dev_read_addr_ptr(dev);
  44        if (!priv->regs)
  45                return -EINVAL;
  46        tmr = priv->regs;
  47
  48        debug("Faraday FTTMR010 timer revision 0x%08X\n", readl(&tmr->revision));
  49
  50        /* disable timers */
  51        writel(0, &tmr->cr);
  52
  53        /* setup timer */
  54        writel(TIMER_LOAD_VAL, &tmr->timer3_load);
  55        writel(TIMER_LOAD_VAL, &tmr->timer3_counter);
  56        writel(0, &tmr->timer3_match1);
  57        writel(0, &tmr->timer3_match2);
  58
  59        /* we don't want timer to issue interrupts */
  60        writel(FTTMR010_TM3_MATCH1 |
  61               FTTMR010_TM3_MATCH2 |
  62               FTTMR010_TM3_OVERFLOW,
  63               &tmr->interrupt_mask);
  64
  65        cr = readl(&tmr->cr);
  66        cr |= FTTMR010_TM3_CLOCK;       /* use external clock */
  67        cr |= FTTMR010_TM3_ENABLE;
  68        writel(cr, &tmr->cr);
  69
  70        gd->arch.tbl = 0;
  71        gd->arch.tbu = 0;
  72
  73        return 0;
  74}
  75
  76static const struct timer_ops fttmr010_timer_ops = {
  77        .get_count = fttmr010_timer_get_count,
  78};
  79
  80static const struct udevice_id fttmr010_timer_ids[] = {
  81        { .compatible = "faraday,fttmr010-timer" },
  82        {}
  83};
  84
  85U_BOOT_DRIVER(fttmr010_timer) = {
  86        .name = "fttmr010_timer",
  87        .id = UCLASS_TIMER,
  88        .of_match = fttmr010_timer_ids,
  89        .priv_auto = sizeof(struct fttmr010_timer_priv),
  90        .probe = fttmr010_timer_probe,
  91        .ops = &fttmr010_timer_ops,
  92};
  93