Linux Audio

Check our new training course

Loading...
v5.9
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * System timer for CSR SiRFprimaII
  4 *
  5 * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
 
 
  6 */
  7
  8#include <linux/kernel.h>
  9#include <linux/interrupt.h>
 10#include <linux/clockchips.h>
 11#include <linux/clocksource.h>
 12#include <linux/bitops.h>
 13#include <linux/irq.h>
 14#include <linux/clk.h>
 15#include <linux/err.h>
 16#include <linux/slab.h>
 17#include <linux/of.h>
 18#include <linux/of_irq.h>
 19#include <linux/of_address.h>
 20#include <linux/sched_clock.h>
 
 21
 22#define PRIMA2_CLOCK_FREQ 1000000
 23
 24#define SIRFSOC_TIMER_COUNTER_LO	0x0000
 25#define SIRFSOC_TIMER_COUNTER_HI	0x0004
 26#define SIRFSOC_TIMER_MATCH_0		0x0008
 27#define SIRFSOC_TIMER_MATCH_1		0x000C
 28#define SIRFSOC_TIMER_MATCH_2		0x0010
 29#define SIRFSOC_TIMER_MATCH_3		0x0014
 30#define SIRFSOC_TIMER_MATCH_4		0x0018
 31#define SIRFSOC_TIMER_MATCH_5		0x001C
 32#define SIRFSOC_TIMER_STATUS		0x0020
 33#define SIRFSOC_TIMER_INT_EN		0x0024
 34#define SIRFSOC_TIMER_WATCHDOG_EN	0x0028
 35#define SIRFSOC_TIMER_DIV		0x002C
 36#define SIRFSOC_TIMER_LATCH		0x0030
 37#define SIRFSOC_TIMER_LATCHED_LO	0x0034
 38#define SIRFSOC_TIMER_LATCHED_HI	0x0038
 39
 40#define SIRFSOC_TIMER_WDT_INDEX		5
 41
 42#define SIRFSOC_TIMER_LATCH_BIT	 BIT(0)
 43
 44#define SIRFSOC_TIMER_REG_CNT 11
 45
 46static const u32 sirfsoc_timer_reg_list[SIRFSOC_TIMER_REG_CNT] = {
 47	SIRFSOC_TIMER_MATCH_0, SIRFSOC_TIMER_MATCH_1, SIRFSOC_TIMER_MATCH_2,
 48	SIRFSOC_TIMER_MATCH_3, SIRFSOC_TIMER_MATCH_4, SIRFSOC_TIMER_MATCH_5,
 49	SIRFSOC_TIMER_INT_EN, SIRFSOC_TIMER_WATCHDOG_EN, SIRFSOC_TIMER_DIV,
 50	SIRFSOC_TIMER_LATCHED_LO, SIRFSOC_TIMER_LATCHED_HI,
 51};
 52
 53static u32 sirfsoc_timer_reg_val[SIRFSOC_TIMER_REG_CNT];
 54
 55static void __iomem *sirfsoc_timer_base;
 56
 57/* timer0 interrupt handler */
 58static irqreturn_t sirfsoc_timer_interrupt(int irq, void *dev_id)
 59{
 60	struct clock_event_device *ce = dev_id;
 61
 62	WARN_ON(!(readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_STATUS) &
 63		BIT(0)));
 64
 65	/* clear timer0 interrupt */
 66	writel_relaxed(BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_STATUS);
 67
 68	ce->event_handler(ce);
 69
 70	return IRQ_HANDLED;
 71}
 72
 73/* read 64-bit timer counter */
 74static u64 notrace sirfsoc_timer_read(struct clocksource *cs)
 75{
 76	u64 cycles;
 77
 78	/* latch the 64-bit timer counter */
 79	writel_relaxed(SIRFSOC_TIMER_LATCH_BIT,
 80		sirfsoc_timer_base + SIRFSOC_TIMER_LATCH);
 81	cycles = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_LATCHED_HI);
 82	cycles = (cycles << 32) |
 83		readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_LATCHED_LO);
 84
 85	return cycles;
 86}
 87
 88static int sirfsoc_timer_set_next_event(unsigned long delta,
 89	struct clock_event_device *ce)
 90{
 91	unsigned long now, next;
 92
 93	writel_relaxed(SIRFSOC_TIMER_LATCH_BIT,
 94		sirfsoc_timer_base + SIRFSOC_TIMER_LATCH);
 95	now = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_LATCHED_LO);
 96	next = now + delta;
 97	writel_relaxed(next, sirfsoc_timer_base + SIRFSOC_TIMER_MATCH_0);
 98	writel_relaxed(SIRFSOC_TIMER_LATCH_BIT,
 99		sirfsoc_timer_base + SIRFSOC_TIMER_LATCH);
100	now = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_LATCHED_LO);
101
102	return next - now > delta ? -ETIME : 0;
103}
104
105static int sirfsoc_timer_shutdown(struct clock_event_device *evt)
106{
107	u32 val = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_INT_EN);
108
109	writel_relaxed(val & ~BIT(0),
110		       sirfsoc_timer_base + SIRFSOC_TIMER_INT_EN);
111	return 0;
112}
113
114static int sirfsoc_timer_set_oneshot(struct clock_event_device *evt)
115{
116	u32 val = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_INT_EN);
117
118	writel_relaxed(val | BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_INT_EN);
119	return 0;
120}
121
122static void sirfsoc_clocksource_suspend(struct clocksource *cs)
123{
124	int i;
125
126	writel_relaxed(SIRFSOC_TIMER_LATCH_BIT,
127		sirfsoc_timer_base + SIRFSOC_TIMER_LATCH);
128
129	for (i = 0; i < SIRFSOC_TIMER_REG_CNT; i++)
130		sirfsoc_timer_reg_val[i] =
131			readl_relaxed(sirfsoc_timer_base +
132				sirfsoc_timer_reg_list[i]);
133}
134
135static void sirfsoc_clocksource_resume(struct clocksource *cs)
136{
137	int i;
138
139	for (i = 0; i < SIRFSOC_TIMER_REG_CNT - 2; i++)
140		writel_relaxed(sirfsoc_timer_reg_val[i],
141			sirfsoc_timer_base + sirfsoc_timer_reg_list[i]);
142
143	writel_relaxed(sirfsoc_timer_reg_val[SIRFSOC_TIMER_REG_CNT - 2],
144		sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_LO);
145	writel_relaxed(sirfsoc_timer_reg_val[SIRFSOC_TIMER_REG_CNT - 1],
146		sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_HI);
147}
148
149static struct clock_event_device sirfsoc_clockevent = {
150	.name = "sirfsoc_clockevent",
151	.rating = 200,
152	.features = CLOCK_EVT_FEAT_ONESHOT,
153	.set_state_shutdown = sirfsoc_timer_shutdown,
154	.set_state_oneshot = sirfsoc_timer_set_oneshot,
155	.set_next_event = sirfsoc_timer_set_next_event,
156};
157
158static struct clocksource sirfsoc_clocksource = {
159	.name = "sirfsoc_clocksource",
160	.rating = 200,
161	.mask = CLOCKSOURCE_MASK(64),
162	.flags = CLOCK_SOURCE_IS_CONTINUOUS,
163	.read = sirfsoc_timer_read,
164	.suspend = sirfsoc_clocksource_suspend,
165	.resume = sirfsoc_clocksource_resume,
166};
167
 
 
 
 
 
 
 
 
168/* Overwrite weak default sched_clock with more precise one */
169static u64 notrace sirfsoc_read_sched_clock(void)
170{
171	return sirfsoc_timer_read(NULL);
172}
173
174static void __init sirfsoc_clockevent_init(void)
175{
176	sirfsoc_clockevent.cpumask = cpumask_of(0);
177	clockevents_config_and_register(&sirfsoc_clockevent, PRIMA2_CLOCK_FREQ,
178					2, -2);
179}
180
181/* initialize the kernel jiffy timer source */
182static int __init sirfsoc_prima2_timer_init(struct device_node *np)
183{
184	unsigned long rate;
185	unsigned int irq;
186	struct clk *clk;
187	int ret;
188
189	clk = of_clk_get(np, 0);
190	if (IS_ERR(clk)) {
191		pr_err("Failed to get clock\n");
192		return PTR_ERR(clk);
193	}
194
195	ret = clk_prepare_enable(clk);
196	if (ret) {
197		pr_err("Failed to enable clock\n");
198		return ret;
199	}
200
201	rate = clk_get_rate(clk);
202
203	if (rate < PRIMA2_CLOCK_FREQ || rate % PRIMA2_CLOCK_FREQ) {
204		pr_err("Invalid clock rate\n");
205		return -EINVAL;
206	}
207
208	sirfsoc_timer_base = of_iomap(np, 0);
209	if (!sirfsoc_timer_base) {
210		pr_err("unable to map timer cpu registers\n");
211		return -ENXIO;
212	}
213
214	irq = irq_of_parse_and_map(np, 0);
215
216	writel_relaxed(rate / PRIMA2_CLOCK_FREQ / 2 - 1,
217		sirfsoc_timer_base + SIRFSOC_TIMER_DIV);
218	writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_LO);
219	writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_HI);
220	writel_relaxed(BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_STATUS);
221
222	ret = clocksource_register_hz(&sirfsoc_clocksource, PRIMA2_CLOCK_FREQ);
223	if (ret) {
224		pr_err("Failed to register clocksource\n");
225		return ret;
226	}
227
228	sched_clock_register(sirfsoc_read_sched_clock, 64, PRIMA2_CLOCK_FREQ);
229
230	ret = request_irq(irq, sirfsoc_timer_interrupt, IRQF_TIMER,
231			  "sirfsoc_timer0", &sirfsoc_clockevent);
232	if (ret) {
233		pr_err("Failed to setup irq\n");
234		return ret;
235	}
236
237	sirfsoc_clockevent_init();
238
239	return 0;
240}
241TIMER_OF_DECLARE(sirfsoc_prima2_timer,
242	"sirf,prima2-tick", sirfsoc_prima2_timer_init);
v4.6
 
  1/*
  2 * System timer for CSR SiRFprimaII
  3 *
  4 * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
  5 *
  6 * Licensed under GPLv2 or later.
  7 */
  8
  9#include <linux/kernel.h>
 10#include <linux/interrupt.h>
 11#include <linux/clockchips.h>
 12#include <linux/clocksource.h>
 13#include <linux/bitops.h>
 14#include <linux/irq.h>
 15#include <linux/clk.h>
 16#include <linux/err.h>
 17#include <linux/slab.h>
 18#include <linux/of.h>
 19#include <linux/of_irq.h>
 20#include <linux/of_address.h>
 21#include <linux/sched_clock.h>
 22#include <asm/mach/time.h>
 23
 24#define PRIMA2_CLOCK_FREQ 1000000
 25
 26#define SIRFSOC_TIMER_COUNTER_LO	0x0000
 27#define SIRFSOC_TIMER_COUNTER_HI	0x0004
 28#define SIRFSOC_TIMER_MATCH_0		0x0008
 29#define SIRFSOC_TIMER_MATCH_1		0x000C
 30#define SIRFSOC_TIMER_MATCH_2		0x0010
 31#define SIRFSOC_TIMER_MATCH_3		0x0014
 32#define SIRFSOC_TIMER_MATCH_4		0x0018
 33#define SIRFSOC_TIMER_MATCH_5		0x001C
 34#define SIRFSOC_TIMER_STATUS		0x0020
 35#define SIRFSOC_TIMER_INT_EN		0x0024
 36#define SIRFSOC_TIMER_WATCHDOG_EN	0x0028
 37#define SIRFSOC_TIMER_DIV		0x002C
 38#define SIRFSOC_TIMER_LATCH		0x0030
 39#define SIRFSOC_TIMER_LATCHED_LO	0x0034
 40#define SIRFSOC_TIMER_LATCHED_HI	0x0038
 41
 42#define SIRFSOC_TIMER_WDT_INDEX		5
 43
 44#define SIRFSOC_TIMER_LATCH_BIT	 BIT(0)
 45
 46#define SIRFSOC_TIMER_REG_CNT 11
 47
 48static const u32 sirfsoc_timer_reg_list[SIRFSOC_TIMER_REG_CNT] = {
 49	SIRFSOC_TIMER_MATCH_0, SIRFSOC_TIMER_MATCH_1, SIRFSOC_TIMER_MATCH_2,
 50	SIRFSOC_TIMER_MATCH_3, SIRFSOC_TIMER_MATCH_4, SIRFSOC_TIMER_MATCH_5,
 51	SIRFSOC_TIMER_INT_EN, SIRFSOC_TIMER_WATCHDOG_EN, SIRFSOC_TIMER_DIV,
 52	SIRFSOC_TIMER_LATCHED_LO, SIRFSOC_TIMER_LATCHED_HI,
 53};
 54
 55static u32 sirfsoc_timer_reg_val[SIRFSOC_TIMER_REG_CNT];
 56
 57static void __iomem *sirfsoc_timer_base;
 58
 59/* timer0 interrupt handler */
 60static irqreturn_t sirfsoc_timer_interrupt(int irq, void *dev_id)
 61{
 62	struct clock_event_device *ce = dev_id;
 63
 64	WARN_ON(!(readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_STATUS) &
 65		BIT(0)));
 66
 67	/* clear timer0 interrupt */
 68	writel_relaxed(BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_STATUS);
 69
 70	ce->event_handler(ce);
 71
 72	return IRQ_HANDLED;
 73}
 74
 75/* read 64-bit timer counter */
 76static cycle_t notrace sirfsoc_timer_read(struct clocksource *cs)
 77{
 78	u64 cycles;
 79
 80	/* latch the 64-bit timer counter */
 81	writel_relaxed(SIRFSOC_TIMER_LATCH_BIT,
 82		sirfsoc_timer_base + SIRFSOC_TIMER_LATCH);
 83	cycles = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_LATCHED_HI);
 84	cycles = (cycles << 32) |
 85		readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_LATCHED_LO);
 86
 87	return cycles;
 88}
 89
 90static int sirfsoc_timer_set_next_event(unsigned long delta,
 91	struct clock_event_device *ce)
 92{
 93	unsigned long now, next;
 94
 95	writel_relaxed(SIRFSOC_TIMER_LATCH_BIT,
 96		sirfsoc_timer_base + SIRFSOC_TIMER_LATCH);
 97	now = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_LATCHED_LO);
 98	next = now + delta;
 99	writel_relaxed(next, sirfsoc_timer_base + SIRFSOC_TIMER_MATCH_0);
100	writel_relaxed(SIRFSOC_TIMER_LATCH_BIT,
101		sirfsoc_timer_base + SIRFSOC_TIMER_LATCH);
102	now = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_LATCHED_LO);
103
104	return next - now > delta ? -ETIME : 0;
105}
106
107static int sirfsoc_timer_shutdown(struct clock_event_device *evt)
108{
109	u32 val = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_INT_EN);
110
111	writel_relaxed(val & ~BIT(0),
112		       sirfsoc_timer_base + SIRFSOC_TIMER_INT_EN);
113	return 0;
114}
115
116static int sirfsoc_timer_set_oneshot(struct clock_event_device *evt)
117{
118	u32 val = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_INT_EN);
119
120	writel_relaxed(val | BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_INT_EN);
121	return 0;
122}
123
124static void sirfsoc_clocksource_suspend(struct clocksource *cs)
125{
126	int i;
127
128	writel_relaxed(SIRFSOC_TIMER_LATCH_BIT,
129		sirfsoc_timer_base + SIRFSOC_TIMER_LATCH);
130
131	for (i = 0; i < SIRFSOC_TIMER_REG_CNT; i++)
132		sirfsoc_timer_reg_val[i] =
133			readl_relaxed(sirfsoc_timer_base +
134				sirfsoc_timer_reg_list[i]);
135}
136
137static void sirfsoc_clocksource_resume(struct clocksource *cs)
138{
139	int i;
140
141	for (i = 0; i < SIRFSOC_TIMER_REG_CNT - 2; i++)
142		writel_relaxed(sirfsoc_timer_reg_val[i],
143			sirfsoc_timer_base + sirfsoc_timer_reg_list[i]);
144
145	writel_relaxed(sirfsoc_timer_reg_val[SIRFSOC_TIMER_REG_CNT - 2],
146		sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_LO);
147	writel_relaxed(sirfsoc_timer_reg_val[SIRFSOC_TIMER_REG_CNT - 1],
148		sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_HI);
149}
150
151static struct clock_event_device sirfsoc_clockevent = {
152	.name = "sirfsoc_clockevent",
153	.rating = 200,
154	.features = CLOCK_EVT_FEAT_ONESHOT,
155	.set_state_shutdown = sirfsoc_timer_shutdown,
156	.set_state_oneshot = sirfsoc_timer_set_oneshot,
157	.set_next_event = sirfsoc_timer_set_next_event,
158};
159
160static struct clocksource sirfsoc_clocksource = {
161	.name = "sirfsoc_clocksource",
162	.rating = 200,
163	.mask = CLOCKSOURCE_MASK(64),
164	.flags = CLOCK_SOURCE_IS_CONTINUOUS,
165	.read = sirfsoc_timer_read,
166	.suspend = sirfsoc_clocksource_suspend,
167	.resume = sirfsoc_clocksource_resume,
168};
169
170static struct irqaction sirfsoc_timer_irq = {
171	.name = "sirfsoc_timer0",
172	.flags = IRQF_TIMER,
173	.irq = 0,
174	.handler = sirfsoc_timer_interrupt,
175	.dev_id = &sirfsoc_clockevent,
176};
177
178/* Overwrite weak default sched_clock with more precise one */
179static u64 notrace sirfsoc_read_sched_clock(void)
180{
181	return sirfsoc_timer_read(NULL);
182}
183
184static void __init sirfsoc_clockevent_init(void)
185{
186	sirfsoc_clockevent.cpumask = cpumask_of(0);
187	clockevents_config_and_register(&sirfsoc_clockevent, PRIMA2_CLOCK_FREQ,
188					2, -2);
189}
190
191/* initialize the kernel jiffy timer source */
192static void __init sirfsoc_prima2_timer_init(struct device_node *np)
193{
194	unsigned long rate;
 
195	struct clk *clk;
 
196
197	clk = of_clk_get(np, 0);
198	BUG_ON(IS_ERR(clk));
199
200	BUG_ON(clk_prepare_enable(clk));
 
 
 
 
 
 
 
201
202	rate = clk_get_rate(clk);
203
204	BUG_ON(rate < PRIMA2_CLOCK_FREQ);
205	BUG_ON(rate % PRIMA2_CLOCK_FREQ);
 
 
206
207	sirfsoc_timer_base = of_iomap(np, 0);
208	if (!sirfsoc_timer_base)
209		panic("unable to map timer cpu registers\n");
 
 
210
211	sirfsoc_timer_irq.irq = irq_of_parse_and_map(np, 0);
212
213	writel_relaxed(rate / PRIMA2_CLOCK_FREQ / 2 - 1,
214		sirfsoc_timer_base + SIRFSOC_TIMER_DIV);
215	writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_LO);
216	writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_HI);
217	writel_relaxed(BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_STATUS);
218
219	BUG_ON(clocksource_register_hz(&sirfsoc_clocksource,
220				       PRIMA2_CLOCK_FREQ));
 
 
 
221
222	sched_clock_register(sirfsoc_read_sched_clock, 64, PRIMA2_CLOCK_FREQ);
223
224	BUG_ON(setup_irq(sirfsoc_timer_irq.irq, &sirfsoc_timer_irq));
 
 
 
 
 
225
226	sirfsoc_clockevent_init();
 
 
227}
228CLOCKSOURCE_OF_DECLARE(sirfsoc_prima2_timer,
229	"sirf,prima2-tick", sirfsoc_prima2_timer_init);