Blame view
drivers/clocksource/clksrc-dbx500-prcmu.c
2.51 KB
489bccea6 clocksource: add ... |
1 2 3 4 5 6 7 8 9 10 11 12 |
/* * Copyright (C) ST-Ericsson SA 2011 * * License Terms: GNU General Public License v2 * Author: Mattias Wallin <mattias.wallin@stericsson.com> for ST-Ericsson * Author: Sundar Iyer for ST-Ericsson * sched_clock implementation is based on: * plat-nomadik/timer.c Linus Walleij <linus.walleij@stericsson.com> * * DBx500-PRCMU Timer * The PRCMU has 5 timers which are available in a always-on * power domain. We use the Timer 4 for our always-on clock |
807eba55f clocksource: dbx5... |
13 |
* source on DB8500. |
489bccea6 clocksource: add ... |
14 |
*/ |
9d2aa8c79 ARM/clocksource: ... |
15 16 |
#include <linux/of.h> #include <linux/of_address.h> |
489bccea6 clocksource: add ... |
17 |
#include <linux/clockchips.h> |
38ff87f77 sched_clock: Make... |
18 |
#include <linux/sched_clock.h> |
489bccea6 clocksource: add ... |
19 |
|
489bccea6 clocksource: add ... |
20 21 22 23 24 25 26 27 28 29 |
#define RATE_32K 32768 #define TIMER_MODE_CONTINOUS 0x1 #define TIMER_DOWNCOUNT_VAL 0xffffffff #define PRCMU_TIMER_REF 0 #define PRCMU_TIMER_DOWNCOUNT 0x4 #define PRCMU_TIMER_MODE 0x8 #define SCHED_CLOCK_MIN_WRAP 131072 /* 2^32 / 32768 */ |
b1e3be064 clocksource: fixu... |
30 |
static void __iomem *clksrc_dbx500_timer_base; |
489bccea6 clocksource: add ... |
31 |
|
530282278 clocksource: dbx5... |
32 |
static cycle_t notrace clksrc_dbx500_prcmu_read(struct clocksource *cs) |
489bccea6 clocksource: add ... |
33 |
{ |
530282278 clocksource: dbx5... |
34 |
void __iomem *base = clksrc_dbx500_timer_base; |
489bccea6 clocksource: add ... |
35 36 37 |
u32 count, count2; do { |
530282278 clocksource: dbx5... |
38 39 |
count = readl_relaxed(base + PRCMU_TIMER_DOWNCOUNT); count2 = readl_relaxed(base + PRCMU_TIMER_DOWNCOUNT); |
489bccea6 clocksource: add ... |
40 41 42 43 44 45 46 47 48 49 |
} while (count2 != count); /* Negate because the timer is a decrementing counter */ return ~count; } static struct clocksource clocksource_dbx500_prcmu = { .name = "dbx500-prcmu-timer", .rating = 300, .read = clksrc_dbx500_prcmu_read, |
489bccea6 clocksource: add ... |
50 51 52 53 54 |
.mask = CLOCKSOURCE_MASK(32), .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; #ifdef CONFIG_CLKSRC_DBX500_PRCMU_SCHED_CLOCK |
489bccea6 clocksource: add ... |
55 |
|
5602d7c80 clocksource: dbx5... |
56 |
static u64 notrace dbx500_prcmu_sched_clock_read(void) |
489bccea6 clocksource: add ... |
57 |
{ |
489bccea6 clocksource: add ... |
58 59 |
if (unlikely(!clksrc_dbx500_timer_base)) return 0; |
cfef0320e ARM: 7261/1: cloc... |
60 |
return clksrc_dbx500_prcmu_read(&clocksource_dbx500_prcmu); |
489bccea6 clocksource: add ... |
61 |
} |
489bccea6 clocksource: add ... |
62 |
#endif |
108a4ed96 clocksource/drive... |
63 |
static int __init clksrc_dbx500_prcmu_init(struct device_node *node) |
489bccea6 clocksource: add ... |
64 |
{ |
9d2aa8c79 ARM/clocksource: ... |
65 |
clksrc_dbx500_timer_base = of_iomap(node, 0); |
b1e3be064 clocksource: fixu... |
66 |
|
489bccea6 clocksource: add ... |
67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
/* * The A9 sub system expects the timer to be configured as * a continous looping timer. * The PRCMU should configure it but if it for some reason * don't we do it here. */ if (readl(clksrc_dbx500_timer_base + PRCMU_TIMER_MODE) != TIMER_MODE_CONTINOUS) { writel(TIMER_MODE_CONTINOUS, clksrc_dbx500_timer_base + PRCMU_TIMER_MODE); writel(TIMER_DOWNCOUNT_VAL, clksrc_dbx500_timer_base + PRCMU_TIMER_REF); } #ifdef CONFIG_CLKSRC_DBX500_PRCMU_SCHED_CLOCK |
5602d7c80 clocksource: dbx5... |
81 |
sched_clock_register(dbx500_prcmu_sched_clock_read, 32, RATE_32K); |
489bccea6 clocksource: add ... |
82 |
#endif |
108a4ed96 clocksource/drive... |
83 |
return clocksource_register_hz(&clocksource_dbx500_prcmu, RATE_32K); |
489bccea6 clocksource: add ... |
84 |
} |
177cf6e52 clocksources: Swi... |
85 |
CLOCKSOURCE_OF_DECLARE(dbx500_prcmu, "stericsson,db8500-prcmu-timer-4", |
9d2aa8c79 ARM/clocksource: ... |
86 |
clksrc_dbx500_prcmu_init); |