uboot/drivers/timer/atmel_pit_timer.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2017 Microchip Corporation
   4 *                    Wenyou.Yang <wenyou.yang@microchip.com>
   5 */
   6
   7#include <common.h>
   8#include <clk.h>
   9#include <dm.h>
  10#include <timer.h>
  11#include <asm/io.h>
  12
  13#define AT91_PIT_VALUE          0xfffff
  14#define AT91_PIT_PITEN          BIT(24)         /* Timer Enabled */
  15
  16struct atmel_pit_regs {
  17        u32     mode;
  18        u32     status;
  19        u32     value;
  20        u32     value_image;
  21};
  22
  23struct atmel_pit_platdata {
  24        struct atmel_pit_regs *regs;
  25};
  26
  27static int atmel_pit_get_count(struct udevice *dev, u64 *count)
  28{
  29        struct atmel_pit_platdata *plat = dev_get_platdata(dev);
  30        struct atmel_pit_regs *const regs = plat->regs;
  31        u32 val = readl(&regs->value_image);
  32
  33        *count = timer_conv_64(val);
  34
  35        return 0;
  36}
  37
  38static int atmel_pit_probe(struct udevice *dev)
  39{
  40        struct atmel_pit_platdata *plat = dev_get_platdata(dev);
  41        struct atmel_pit_regs *const regs = plat->regs;
  42        struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
  43        struct clk clk;
  44        ulong clk_rate;
  45        int ret;
  46
  47        ret = clk_get_by_index(dev, 0, &clk);
  48        if (ret)
  49                return -EINVAL;
  50
  51        clk_rate = clk_get_rate(&clk);
  52        if (!clk_rate)
  53                return -EINVAL;
  54
  55        uc_priv->clock_rate = clk_rate / 16;
  56
  57        writel(AT91_PIT_VALUE | AT91_PIT_PITEN, &regs->mode);
  58
  59        return 0;
  60}
  61
  62static int atmel_pit_ofdata_to_platdata(struct udevice *dev)
  63{
  64        struct atmel_pit_platdata *plat = dev_get_platdata(dev);
  65
  66        plat->regs = (struct atmel_pit_regs *)devfdt_get_addr_ptr(dev);
  67
  68        return 0;
  69}
  70
  71static const struct timer_ops atmel_pit_ops = {
  72        .get_count = atmel_pit_get_count,
  73};
  74
  75static const struct udevice_id atmel_pit_ids[] = {
  76        { .compatible = "atmel,at91sam9260-pit" },
  77        { }
  78};
  79
  80U_BOOT_DRIVER(atmel_pit) = {
  81        .name   = "atmel_pit",
  82        .id     = UCLASS_TIMER,
  83        .of_match = atmel_pit_ids,
  84        .ofdata_to_platdata = atmel_pit_ofdata_to_platdata,
  85        .platdata_auto_alloc_size = sizeof(struct atmel_pit_platdata),
  86        .probe  = atmel_pit_probe,
  87        .ops    = &atmel_pit_ops,
  88};
  89