Linux Audio

Check our new training course

Loading...
v6.8
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * linux/arch/arm/mach-at91/at91rm9200_time.c
  4 *
  5 *  Copyright (C) 2003 SAN People
  6 *  Copyright (C) 2003 ATMEL
  7 */
  8
  9#include <linux/kernel.h>
 10#include <linux/interrupt.h>
 11#include <linux/irq.h>
 12#include <linux/clk.h>
 13#include <linux/clockchips.h>
 14#include <linux/export.h>
 15#include <linux/mfd/syscon.h>
 16#include <linux/mfd/syscon/atmel-st.h>
 17#include <linux/of_irq.h>
 18#include <linux/regmap.h>
 19
 20static unsigned long last_crtr;
 21static u32 irqmask;
 22static struct clock_event_device clkevt;
 23static struct regmap *regmap_st;
 24static int timer_latch;
 25
 26/*
 27 * The ST_CRTR is updated asynchronously to the master clock ... but
 28 * the updates as seen by the CPU don't seem to be strictly monotonic.
 29 * Waiting until we read the same value twice avoids glitching.
 30 */
 31static inline unsigned long read_CRTR(void)
 32{
 33	unsigned int x1, x2;
 34
 35	regmap_read(regmap_st, AT91_ST_CRTR, &x1);
 36	do {
 37		regmap_read(regmap_st, AT91_ST_CRTR, &x2);
 38		if (x1 == x2)
 39			break;
 40		x1 = x2;
 41	} while (1);
 42	return x1;
 43}
 44
 45/*
 46 * IRQ handler for the timer.
 47 */
 48static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id)
 49{
 50	u32 sr;
 51
 52	regmap_read(regmap_st, AT91_ST_SR, &sr);
 53	sr &= irqmask;
 54
 55	/*
 56	 * irqs should be disabled here, but as the irq is shared they are only
 57	 * guaranteed to be off if the timer irq is registered first.
 58	 */
 59	WARN_ON_ONCE(!irqs_disabled());
 60
 61	/* simulate "oneshot" timer with alarm */
 62	if (sr & AT91_ST_ALMS) {
 63		clkevt.event_handler(&clkevt);
 64		return IRQ_HANDLED;
 65	}
 66
 67	/* periodic mode should handle delayed ticks */
 68	if (sr & AT91_ST_PITS) {
 69		u32	crtr = read_CRTR();
 70
 71		while (((crtr - last_crtr) & AT91_ST_CRTV) >= timer_latch) {
 72			last_crtr += timer_latch;
 73			clkevt.event_handler(&clkevt);
 74		}
 75		return IRQ_HANDLED;
 76	}
 77
 78	/* this irq is shared ... */
 79	return IRQ_NONE;
 80}
 81
 82static u64 read_clk32k(struct clocksource *cs)
 83{
 84	return read_CRTR();
 85}
 86
 87static struct clocksource clk32k = {
 88	.name		= "32k_counter",
 89	.rating		= 150,
 90	.read		= read_clk32k,
 91	.mask		= CLOCKSOURCE_MASK(20),
 92	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 93};
 94
 95static void clkdev32k_disable_and_flush_irq(void)
 96{
 97	unsigned int val;
 98
 99	/* Disable and flush pending timer interrupts */
100	regmap_write(regmap_st, AT91_ST_IDR, AT91_ST_PITS | AT91_ST_ALMS);
101	regmap_read(regmap_st, AT91_ST_SR, &val);
102	last_crtr = read_CRTR();
103}
104
105static int clkevt32k_shutdown(struct clock_event_device *evt)
106{
107	clkdev32k_disable_and_flush_irq();
108	irqmask = 0;
109	regmap_write(regmap_st, AT91_ST_IER, irqmask);
110	return 0;
111}
112
113static int clkevt32k_set_oneshot(struct clock_event_device *dev)
114{
115	clkdev32k_disable_and_flush_irq();
116
117	/*
118	 * ALM for oneshot irqs, set by next_event()
119	 * before 32 seconds have passed.
120	 */
121	irqmask = AT91_ST_ALMS;
122	regmap_write(regmap_st, AT91_ST_RTAR, last_crtr);
123	regmap_write(regmap_st, AT91_ST_IER, irqmask);
124	return 0;
125}
126
127static int clkevt32k_set_periodic(struct clock_event_device *dev)
128{
129	clkdev32k_disable_and_flush_irq();
130
131	/* PIT for periodic irqs; fixed rate of 1/HZ */
132	irqmask = AT91_ST_PITS;
133	regmap_write(regmap_st, AT91_ST_PIMR, timer_latch);
134	regmap_write(regmap_st, AT91_ST_IER, irqmask);
135	return 0;
136}
137
138static int
139clkevt32k_next_event(unsigned long delta, struct clock_event_device *dev)
140{
141	u32		alm;
 
142	unsigned int	val;
143
144	BUG_ON(delta < 2);
145
146	/* The alarm IRQ uses absolute time (now+delta), not the relative
147	 * time (delta) in our calling convention.  Like all clockevents
148	 * using such "match" hardware, we have a race to defend against.
149	 *
150	 * Our defense here is to have set up the clockevent device so the
151	 * delta is at least two.  That way we never end up writing RTAR
152	 * with the value then held in CRTR ... which would mean the match
153	 * wouldn't trigger until 32 seconds later, after CRTR wraps.
154	 */
155	alm = read_CRTR();
156
157	/* Cancel any pending alarm; flush any pending IRQ */
158	regmap_write(regmap_st, AT91_ST_RTAR, alm);
159	regmap_read(regmap_st, AT91_ST_SR, &val);
160
161	/* Schedule alarm by writing RTAR. */
162	alm += delta;
163	regmap_write(regmap_st, AT91_ST_RTAR, alm);
164
165	return 0;
166}
167
168static struct clock_event_device clkevt = {
169	.name			= "at91_tick",
170	.features		= CLOCK_EVT_FEAT_PERIODIC |
171				  CLOCK_EVT_FEAT_ONESHOT,
172	.rating			= 150,
173	.set_next_event		= clkevt32k_next_event,
174	.set_state_shutdown	= clkevt32k_shutdown,
175	.set_state_periodic	= clkevt32k_set_periodic,
176	.set_state_oneshot	= clkevt32k_set_oneshot,
177	.tick_resume		= clkevt32k_shutdown,
178};
179
180/*
181 * ST (system timer) module supports both clockevents and clocksource.
182 */
183static int __init atmel_st_timer_init(struct device_node *node)
184{
185	struct clk *sclk;
186	unsigned int sclk_rate, val;
187	int irq, ret;
188
189	regmap_st = syscon_node_to_regmap(node);
190	if (IS_ERR(regmap_st)) {
191		pr_err("Unable to get regmap\n");
192		return PTR_ERR(regmap_st);
193	}
194
195	/* Disable all timer interrupts, and clear any pending ones */
196	regmap_write(regmap_st, AT91_ST_IDR,
197		AT91_ST_PITS | AT91_ST_WDOVF | AT91_ST_RTTINC | AT91_ST_ALMS);
198	regmap_read(regmap_st, AT91_ST_SR, &val);
199
200	/* Get the interrupts property */
201	irq  = irq_of_parse_and_map(node, 0);
202	if (!irq) {
203		pr_err("Unable to get IRQ from DT\n");
204		return -EINVAL;
205	}
206
207	/* Make IRQs happen for the system timer */
208	ret = request_irq(irq, at91rm9200_timer_interrupt,
209			  IRQF_SHARED | IRQF_TIMER | IRQF_IRQPOLL,
210			  "at91_tick", regmap_st);
211	if (ret) {
212		pr_err("Unable to setup IRQ\n");
213		return ret;
214	}
215
216	sclk = of_clk_get(node, 0);
217	if (IS_ERR(sclk)) {
218		pr_err("Unable to get slow clock\n");
219		return PTR_ERR(sclk);
220	}
221
222	ret = clk_prepare_enable(sclk);
223	if (ret) {
224		pr_err("Could not enable slow clock\n");
225		return ret;
226	}
227
228	sclk_rate = clk_get_rate(sclk);
229	if (!sclk_rate) {
230		pr_err("Invalid slow clock rate\n");
231		return -EINVAL;
232	}
233	timer_latch = (sclk_rate + HZ / 2) / HZ;
234
235	/* The 32KiHz "Slow Clock" (tick every 30517.58 nanoseconds) is used
236	 * directly for the clocksource and all clockevents, after adjusting
237	 * its prescaler from the 1 Hz default.
238	 */
239	regmap_write(regmap_st, AT91_ST_RTMR, 1);
240
241	/* Setup timer clockevent, with minimum of two ticks (important!!) */
242	clkevt.cpumask = cpumask_of(0);
243	clockevents_config_and_register(&clkevt, sclk_rate,
244					2, AT91_ST_ALMV);
245
246	/* register clocksource */
247	return clocksource_register_hz(&clk32k, sclk_rate);
248}
249TIMER_OF_DECLARE(atmel_st_timer, "atmel,at91rm9200-st",
250		       atmel_st_timer_init);
v5.4
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * linux/arch/arm/mach-at91/at91rm9200_time.c
  4 *
  5 *  Copyright (C) 2003 SAN People
  6 *  Copyright (C) 2003 ATMEL
  7 */
  8
  9#include <linux/kernel.h>
 10#include <linux/interrupt.h>
 11#include <linux/irq.h>
 12#include <linux/clk.h>
 13#include <linux/clockchips.h>
 14#include <linux/export.h>
 15#include <linux/mfd/syscon.h>
 16#include <linux/mfd/syscon/atmel-st.h>
 17#include <linux/of_irq.h>
 18#include <linux/regmap.h>
 19
 20static unsigned long last_crtr;
 21static u32 irqmask;
 22static struct clock_event_device clkevt;
 23static struct regmap *regmap_st;
 24static int timer_latch;
 25
 26/*
 27 * The ST_CRTR is updated asynchronously to the master clock ... but
 28 * the updates as seen by the CPU don't seem to be strictly monotonic.
 29 * Waiting until we read the same value twice avoids glitching.
 30 */
 31static inline unsigned long read_CRTR(void)
 32{
 33	unsigned int x1, x2;
 34
 35	regmap_read(regmap_st, AT91_ST_CRTR, &x1);
 36	do {
 37		regmap_read(regmap_st, AT91_ST_CRTR, &x2);
 38		if (x1 == x2)
 39			break;
 40		x1 = x2;
 41	} while (1);
 42	return x1;
 43}
 44
 45/*
 46 * IRQ handler for the timer.
 47 */
 48static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id)
 49{
 50	u32 sr;
 51
 52	regmap_read(regmap_st, AT91_ST_SR, &sr);
 53	sr &= irqmask;
 54
 55	/*
 56	 * irqs should be disabled here, but as the irq is shared they are only
 57	 * guaranteed to be off if the timer irq is registered first.
 58	 */
 59	WARN_ON_ONCE(!irqs_disabled());
 60
 61	/* simulate "oneshot" timer with alarm */
 62	if (sr & AT91_ST_ALMS) {
 63		clkevt.event_handler(&clkevt);
 64		return IRQ_HANDLED;
 65	}
 66
 67	/* periodic mode should handle delayed ticks */
 68	if (sr & AT91_ST_PITS) {
 69		u32	crtr = read_CRTR();
 70
 71		while (((crtr - last_crtr) & AT91_ST_CRTV) >= timer_latch) {
 72			last_crtr += timer_latch;
 73			clkevt.event_handler(&clkevt);
 74		}
 75		return IRQ_HANDLED;
 76	}
 77
 78	/* this irq is shared ... */
 79	return IRQ_NONE;
 80}
 81
 82static u64 read_clk32k(struct clocksource *cs)
 83{
 84	return read_CRTR();
 85}
 86
 87static struct clocksource clk32k = {
 88	.name		= "32k_counter",
 89	.rating		= 150,
 90	.read		= read_clk32k,
 91	.mask		= CLOCKSOURCE_MASK(20),
 92	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 93};
 94
 95static void clkdev32k_disable_and_flush_irq(void)
 96{
 97	unsigned int val;
 98
 99	/* Disable and flush pending timer interrupts */
100	regmap_write(regmap_st, AT91_ST_IDR, AT91_ST_PITS | AT91_ST_ALMS);
101	regmap_read(regmap_st, AT91_ST_SR, &val);
102	last_crtr = read_CRTR();
103}
104
105static int clkevt32k_shutdown(struct clock_event_device *evt)
106{
107	clkdev32k_disable_and_flush_irq();
108	irqmask = 0;
109	regmap_write(regmap_st, AT91_ST_IER, irqmask);
110	return 0;
111}
112
113static int clkevt32k_set_oneshot(struct clock_event_device *dev)
114{
115	clkdev32k_disable_and_flush_irq();
116
117	/*
118	 * ALM for oneshot irqs, set by next_event()
119	 * before 32 seconds have passed.
120	 */
121	irqmask = AT91_ST_ALMS;
122	regmap_write(regmap_st, AT91_ST_RTAR, last_crtr);
123	regmap_write(regmap_st, AT91_ST_IER, irqmask);
124	return 0;
125}
126
127static int clkevt32k_set_periodic(struct clock_event_device *dev)
128{
129	clkdev32k_disable_and_flush_irq();
130
131	/* PIT for periodic irqs; fixed rate of 1/HZ */
132	irqmask = AT91_ST_PITS;
133	regmap_write(regmap_st, AT91_ST_PIMR, timer_latch);
134	regmap_write(regmap_st, AT91_ST_IER, irqmask);
135	return 0;
136}
137
138static int
139clkevt32k_next_event(unsigned long delta, struct clock_event_device *dev)
140{
141	u32		alm;
142	int		status = 0;
143	unsigned int	val;
144
145	BUG_ON(delta < 2);
146
147	/* The alarm IRQ uses absolute time (now+delta), not the relative
148	 * time (delta) in our calling convention.  Like all clockevents
149	 * using such "match" hardware, we have a race to defend against.
150	 *
151	 * Our defense here is to have set up the clockevent device so the
152	 * delta is at least two.  That way we never end up writing RTAR
153	 * with the value then held in CRTR ... which would mean the match
154	 * wouldn't trigger until 32 seconds later, after CRTR wraps.
155	 */
156	alm = read_CRTR();
157
158	/* Cancel any pending alarm; flush any pending IRQ */
159	regmap_write(regmap_st, AT91_ST_RTAR, alm);
160	regmap_read(regmap_st, AT91_ST_SR, &val);
161
162	/* Schedule alarm by writing RTAR. */
163	alm += delta;
164	regmap_write(regmap_st, AT91_ST_RTAR, alm);
165
166	return status;
167}
168
169static struct clock_event_device clkevt = {
170	.name			= "at91_tick",
171	.features		= CLOCK_EVT_FEAT_PERIODIC |
172				  CLOCK_EVT_FEAT_ONESHOT,
173	.rating			= 150,
174	.set_next_event		= clkevt32k_next_event,
175	.set_state_shutdown	= clkevt32k_shutdown,
176	.set_state_periodic	= clkevt32k_set_periodic,
177	.set_state_oneshot	= clkevt32k_set_oneshot,
178	.tick_resume		= clkevt32k_shutdown,
179};
180
181/*
182 * ST (system timer) module supports both clockevents and clocksource.
183 */
184static int __init atmel_st_timer_init(struct device_node *node)
185{
186	struct clk *sclk;
187	unsigned int sclk_rate, val;
188	int irq, ret;
189
190	regmap_st = syscon_node_to_regmap(node);
191	if (IS_ERR(regmap_st)) {
192		pr_err("Unable to get regmap\n");
193		return PTR_ERR(regmap_st);
194	}
195
196	/* Disable all timer interrupts, and clear any pending ones */
197	regmap_write(regmap_st, AT91_ST_IDR,
198		AT91_ST_PITS | AT91_ST_WDOVF | AT91_ST_RTTINC | AT91_ST_ALMS);
199	regmap_read(regmap_st, AT91_ST_SR, &val);
200
201	/* Get the interrupts property */
202	irq  = irq_of_parse_and_map(node, 0);
203	if (!irq) {
204		pr_err("Unable to get IRQ from DT\n");
205		return -EINVAL;
206	}
207
208	/* Make IRQs happen for the system timer */
209	ret = request_irq(irq, at91rm9200_timer_interrupt,
210			  IRQF_SHARED | IRQF_TIMER | IRQF_IRQPOLL,
211			  "at91_tick", regmap_st);
212	if (ret) {
213		pr_err("Unable to setup IRQ\n");
214		return ret;
215	}
216
217	sclk = of_clk_get(node, 0);
218	if (IS_ERR(sclk)) {
219		pr_err("Unable to get slow clock\n");
220		return PTR_ERR(sclk);
221	}
222
223	ret = clk_prepare_enable(sclk);
224	if (ret) {
225		pr_err("Could not enable slow clock\n");
226		return ret;
227	}
228
229	sclk_rate = clk_get_rate(sclk);
230	if (!sclk_rate) {
231		pr_err("Invalid slow clock rate\n");
232		return -EINVAL;
233	}
234	timer_latch = (sclk_rate + HZ / 2) / HZ;
235
236	/* The 32KiHz "Slow Clock" (tick every 30517.58 nanoseconds) is used
237	 * directly for the clocksource and all clockevents, after adjusting
238	 * its prescaler from the 1 Hz default.
239	 */
240	regmap_write(regmap_st, AT91_ST_RTMR, 1);
241
242	/* Setup timer clockevent, with minimum of two ticks (important!!) */
243	clkevt.cpumask = cpumask_of(0);
244	clockevents_config_and_register(&clkevt, sclk_rate,
245					2, AT91_ST_ALMV);
246
247	/* register clocksource */
248	return clocksource_register_hz(&clk32k, sclk_rate);
249}
250TIMER_OF_DECLARE(atmel_st_timer, "atmel,at91rm9200-st",
251		       atmel_st_timer_init);