root/drivers/clocksource/clksrc-dbx500-prcmu.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. clksrc_dbx500_prcmu_read
  2. clksrc_dbx500_prcmu_init

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (C) ST-Ericsson SA 2011
   4  *
   5  * Author: Mattias Wallin <mattias.wallin@stericsson.com> for ST-Ericsson
   6  * Author: Sundar Iyer for ST-Ericsson
   7  * sched_clock implementation is based on:
   8  * plat-nomadik/timer.c Linus Walleij <linus.walleij@stericsson.com>
   9  *
  10  * DBx500-PRCMU Timer
  11  * The PRCMU has 5 timers which are available in a always-on
  12  * power domain.  We use the Timer 4 for our always-on clock
  13  * source on DB8500.
  14  */
  15 #include <linux/of.h>
  16 #include <linux/of_address.h>
  17 #include <linux/clockchips.h>
  18 
  19 #define RATE_32K                32768
  20 
  21 #define TIMER_MODE_CONTINOUS    0x1
  22 #define TIMER_DOWNCOUNT_VAL     0xffffffff
  23 
  24 #define PRCMU_TIMER_REF         0
  25 #define PRCMU_TIMER_DOWNCOUNT   0x4
  26 #define PRCMU_TIMER_MODE        0x8
  27 
  28 static void __iomem *clksrc_dbx500_timer_base;
  29 
  30 static u64 notrace clksrc_dbx500_prcmu_read(struct clocksource *cs)
  31 {
  32         void __iomem *base = clksrc_dbx500_timer_base;
  33         u32 count, count2;
  34 
  35         do {
  36                 count = readl_relaxed(base + PRCMU_TIMER_DOWNCOUNT);
  37                 count2 = readl_relaxed(base + PRCMU_TIMER_DOWNCOUNT);
  38         } while (count2 != count);
  39 
  40         /* Negate because the timer is a decrementing counter */
  41         return ~count;
  42 }
  43 
  44 static struct clocksource clocksource_dbx500_prcmu = {
  45         .name           = "dbx500-prcmu-timer",
  46         .rating         = 100,
  47         .read           = clksrc_dbx500_prcmu_read,
  48         .mask           = CLOCKSOURCE_MASK(32),
  49         .flags          = CLOCK_SOURCE_IS_CONTINUOUS | CLOCK_SOURCE_SUSPEND_NONSTOP,
  50 };
  51 
  52 static int __init clksrc_dbx500_prcmu_init(struct device_node *node)
  53 {
  54         clksrc_dbx500_timer_base = of_iomap(node, 0);
  55 
  56         /*
  57          * The A9 sub system expects the timer to be configured as
  58          * a continous looping timer.
  59          * The PRCMU should configure it but if it for some reason
  60          * don't we do it here.
  61          */
  62         if (readl(clksrc_dbx500_timer_base + PRCMU_TIMER_MODE) !=
  63             TIMER_MODE_CONTINOUS) {
  64                 writel(TIMER_MODE_CONTINOUS,
  65                        clksrc_dbx500_timer_base + PRCMU_TIMER_MODE);
  66                 writel(TIMER_DOWNCOUNT_VAL,
  67                        clksrc_dbx500_timer_base + PRCMU_TIMER_REF);
  68         }
  69         return clocksource_register_hz(&clocksource_dbx500_prcmu, RATE_32K);
  70 }
  71 TIMER_OF_DECLARE(dbx500_prcmu, "stericsson,db8500-prcmu-timer-4",
  72                        clksrc_dbx500_prcmu_init);

/* [<][>][^][v][top][bottom][index][help] */