uboot/drivers/timer/omap-timer.c
<<
>>
Prefs
   1/*
   2 * TI OMAP timer driver
   3 *
   4 * Copyright (C) 2015, Texas Instruments, Incorporated
   5 *
   6 * SPDX-License-Identifier: GPL-2.0+
   7 */
   8
   9#include <common.h>
  10#include <dm.h>
  11#include <errno.h>
  12#include <timer.h>
  13#include <asm/io.h>
  14#include <asm/arch/clock.h>
  15
  16DECLARE_GLOBAL_DATA_PTR;
  17
  18/* Timer register bits */
  19#define TCLR_START                      BIT(0)  /* Start=1 */
  20#define TCLR_AUTO_RELOAD                BIT(1)  /* Auto reload */
  21#define TCLR_PRE_EN                     BIT(5)  /* Pre-scaler enable */
  22#define TCLR_PTV_SHIFT                  (2)     /* Pre-scaler shift value */
  23
  24#define TIMER_CLOCK             (V_SCLK / (2 << CONFIG_SYS_PTV))
  25
  26struct omap_gptimer_regs {
  27        unsigned int tidr;              /* offset 0x00 */
  28        unsigned char res1[12];
  29        unsigned int tiocp_cfg;         /* offset 0x10 */
  30        unsigned char res2[12];
  31        unsigned int tier;              /* offset 0x20 */
  32        unsigned int tistatr;           /* offset 0x24 */
  33        unsigned int tistat;            /* offset 0x28 */
  34        unsigned int tisr;              /* offset 0x2c */
  35        unsigned int tcicr;             /* offset 0x30 */
  36        unsigned int twer;              /* offset 0x34 */
  37        unsigned int tclr;              /* offset 0x38 */
  38        unsigned int tcrr;              /* offset 0x3c */
  39        unsigned int tldr;              /* offset 0x40 */
  40        unsigned int ttgr;              /* offset 0x44 */
  41        unsigned int twpc;              /* offset 0x48 */
  42        unsigned int tmar;              /* offset 0x4c */
  43        unsigned int tcar1;             /* offset 0x50 */
  44        unsigned int tscir;             /* offset 0x54 */
  45        unsigned int tcar2;             /* offset 0x58 */
  46};
  47
  48/* Omap Timer Priv */
  49struct omap_timer_priv {
  50        struct omap_gptimer_regs *regs;
  51};
  52
  53static int omap_timer_get_count(struct udevice *dev, u64 *count)
  54{
  55        struct omap_timer_priv *priv = dev_get_priv(dev);
  56
  57        *count = readl(&priv->regs->tcrr);
  58
  59        return 0;
  60}
  61
  62static int omap_timer_probe(struct udevice *dev)
  63{
  64        struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
  65        struct omap_timer_priv *priv = dev_get_priv(dev);
  66
  67        uc_priv->clock_rate = TIMER_CLOCK;
  68
  69        /* start the counter ticking up, reload value on overflow */
  70        writel(0, &priv->regs->tldr);
  71        /* enable timer */
  72        writel((CONFIG_SYS_PTV << 2) | TCLR_PRE_EN | TCLR_AUTO_RELOAD |
  73               TCLR_START, &priv->regs->tclr);
  74
  75        return 0;
  76}
  77
  78static int omap_timer_ofdata_to_platdata(struct udevice *dev)
  79{
  80        struct omap_timer_priv *priv = dev_get_priv(dev);
  81
  82        priv->regs = map_physmem(dev_get_addr(dev),
  83                                 sizeof(struct omap_gptimer_regs), MAP_NOCACHE);
  84
  85        return 0;
  86}
  87
  88
  89static const struct timer_ops omap_timer_ops = {
  90        .get_count = omap_timer_get_count,
  91};
  92
  93static const struct udevice_id omap_timer_ids[] = {
  94        { .compatible = "ti,am335x-timer" },
  95        { .compatible = "ti,am4372-timer" },
  96        { .compatible = "ti,omap5430-timer" },
  97        {}
  98};
  99
 100U_BOOT_DRIVER(omap_timer) = {
 101        .name   = "omap_timer",
 102        .id     = UCLASS_TIMER,
 103        .of_match = omap_timer_ids,
 104        .ofdata_to_platdata = omap_timer_ofdata_to_platdata,
 105        .priv_auto_alloc_size = sizeof(struct omap_timer_priv),
 106        .probe = omap_timer_probe,
 107        .ops    = &omap_timer_ops,
 108        .flags = DM_FLAG_PRE_RELOC,
 109};
 110