Linux Audio

Check our new training course

Loading...
v6.2
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 *  linux/arch/arm/mach-footbridge/dc21285-timer.c
  4 *
  5 *  Copyright (C) 1998 Russell King.
  6 *  Copyright (C) 1998 Phil Blundell
  7 */
  8#include <linux/clockchips.h>
  9#include <linux/clocksource.h>
 10#include <linux/init.h>
 11#include <linux/interrupt.h>
 12#include <linux/irq.h>
 13#include <linux/sched_clock.h>
 14
 15#include <asm/irq.h>
 16
 17#include <asm/hardware/dec21285.h>
 18#include <asm/mach/time.h>
 19#include <asm/system_info.h>
 20
 21#include "common.h"
 22
 23static u64 cksrc_dc21285_read(struct clocksource *cs)
 24{
 25	return cs->mask - *CSR_TIMER2_VALUE;
 26}
 27
 28static int cksrc_dc21285_enable(struct clocksource *cs)
 29{
 30	*CSR_TIMER2_LOAD = cs->mask;
 31	*CSR_TIMER2_CLR = 0;
 32	*CSR_TIMER2_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_DIV16;
 33	return 0;
 34}
 35
 36static void cksrc_dc21285_disable(struct clocksource *cs)
 37{
 38	*CSR_TIMER2_CNTL = 0;
 39}
 40
 41static struct clocksource cksrc_dc21285 = {
 42	.name		= "dc21285_timer2",
 43	.rating		= 200,
 44	.read		= cksrc_dc21285_read,
 45	.enable		= cksrc_dc21285_enable,
 46	.disable	= cksrc_dc21285_disable,
 47	.mask		= CLOCKSOURCE_MASK(24),
 48	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 49};
 50
 51static int ckevt_dc21285_set_next_event(unsigned long delta,
 52	struct clock_event_device *c)
 53{
 54	*CSR_TIMER1_CLR = 0;
 55	*CSR_TIMER1_LOAD = delta;
 56	*CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_DIV16;
 57
 58	return 0;
 59}
 60
 61static int ckevt_dc21285_shutdown(struct clock_event_device *c)
 62{
 63	*CSR_TIMER1_CNTL = 0;
 64	return 0;
 65}
 66
 67static int ckevt_dc21285_set_periodic(struct clock_event_device *c)
 68{
 69	*CSR_TIMER1_CLR = 0;
 70	*CSR_TIMER1_LOAD = (mem_fclk_21285 + 8 * HZ) / (16 * HZ);
 71	*CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD |
 72			   TIMER_CNTL_DIV16;
 73	return 0;
 74}
 75
 76static struct clock_event_device ckevt_dc21285 = {
 77	.name			= "dc21285_timer1",
 78	.features		= CLOCK_EVT_FEAT_PERIODIC |
 79				  CLOCK_EVT_FEAT_ONESHOT,
 80	.rating			= 200,
 81	.irq			= IRQ_TIMER1,
 82	.set_next_event		= ckevt_dc21285_set_next_event,
 83	.set_state_shutdown	= ckevt_dc21285_shutdown,
 84	.set_state_periodic	= ckevt_dc21285_set_periodic,
 85	.set_state_oneshot	= ckevt_dc21285_shutdown,
 86	.tick_resume		= ckevt_dc21285_set_periodic,
 87};
 88
 89static irqreturn_t timer1_interrupt(int irq, void *dev_id)
 90{
 91	struct clock_event_device *ce = dev_id;
 92
 93	*CSR_TIMER1_CLR = 0;
 94
 95	/* Stop the timer if in one-shot mode */
 96	if (clockevent_state_oneshot(ce))
 97		*CSR_TIMER1_CNTL = 0;
 98
 99	ce->event_handler(ce);
100
101	return IRQ_HANDLED;
102}
103
 
 
 
 
 
 
 
104/*
105 * Set up timer interrupt.
106 */
107void __init footbridge_timer_init(void)
108{
109	struct clock_event_device *ce = &ckevt_dc21285;
110	unsigned rate = DIV_ROUND_CLOSEST(mem_fclk_21285, 16);
111
112	clocksource_register_hz(&cksrc_dc21285, rate);
113
114	if (request_irq(ce->irq, timer1_interrupt, IRQF_TIMER | IRQF_IRQPOLL,
115			"dc21285_timer1", &ckevt_dc21285))
116		pr_err("Failed to request irq %d (dc21285_timer1)", ce->irq);
117
118	ce->cpumask = cpumask_of(smp_processor_id());
119	clockevents_config_and_register(ce, rate, 0x4, 0xffffff);
120}
121
122static u64 notrace footbridge_read_sched_clock(void)
123{
124	return ~*CSR_TIMER3_VALUE;
125}
126
127void __init footbridge_sched_clock(void)
128{
129	unsigned rate = DIV_ROUND_CLOSEST(mem_fclk_21285, 16);
130
131	*CSR_TIMER3_LOAD = 0;
132	*CSR_TIMER3_CLR = 0;
133	*CSR_TIMER3_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_DIV16;
134
135	sched_clock_register(footbridge_read_sched_clock, 24, rate);
136}
v5.4
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 *  linux/arch/arm/mach-footbridge/dc21285-timer.c
  4 *
  5 *  Copyright (C) 1998 Russell King.
  6 *  Copyright (C) 1998 Phil Blundell
  7 */
  8#include <linux/clockchips.h>
  9#include <linux/clocksource.h>
 10#include <linux/init.h>
 11#include <linux/interrupt.h>
 12#include <linux/irq.h>
 13#include <linux/sched_clock.h>
 14
 15#include <asm/irq.h>
 16
 17#include <asm/hardware/dec21285.h>
 18#include <asm/mach/time.h>
 19#include <asm/system_info.h>
 20
 21#include "common.h"
 22
 23static u64 cksrc_dc21285_read(struct clocksource *cs)
 24{
 25	return cs->mask - *CSR_TIMER2_VALUE;
 26}
 27
 28static int cksrc_dc21285_enable(struct clocksource *cs)
 29{
 30	*CSR_TIMER2_LOAD = cs->mask;
 31	*CSR_TIMER2_CLR = 0;
 32	*CSR_TIMER2_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_DIV16;
 33	return 0;
 34}
 35
 36static void cksrc_dc21285_disable(struct clocksource *cs)
 37{
 38	*CSR_TIMER2_CNTL = 0;
 39}
 40
 41static struct clocksource cksrc_dc21285 = {
 42	.name		= "dc21285_timer2",
 43	.rating		= 200,
 44	.read		= cksrc_dc21285_read,
 45	.enable		= cksrc_dc21285_enable,
 46	.disable	= cksrc_dc21285_disable,
 47	.mask		= CLOCKSOURCE_MASK(24),
 48	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 49};
 50
 51static int ckevt_dc21285_set_next_event(unsigned long delta,
 52	struct clock_event_device *c)
 53{
 54	*CSR_TIMER1_CLR = 0;
 55	*CSR_TIMER1_LOAD = delta;
 56	*CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_DIV16;
 57
 58	return 0;
 59}
 60
 61static int ckevt_dc21285_shutdown(struct clock_event_device *c)
 62{
 63	*CSR_TIMER1_CNTL = 0;
 64	return 0;
 65}
 66
 67static int ckevt_dc21285_set_periodic(struct clock_event_device *c)
 68{
 69	*CSR_TIMER1_CLR = 0;
 70	*CSR_TIMER1_LOAD = (mem_fclk_21285 + 8 * HZ) / (16 * HZ);
 71	*CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD |
 72			   TIMER_CNTL_DIV16;
 73	return 0;
 74}
 75
 76static struct clock_event_device ckevt_dc21285 = {
 77	.name			= "dc21285_timer1",
 78	.features		= CLOCK_EVT_FEAT_PERIODIC |
 79				  CLOCK_EVT_FEAT_ONESHOT,
 80	.rating			= 200,
 81	.irq			= IRQ_TIMER1,
 82	.set_next_event		= ckevt_dc21285_set_next_event,
 83	.set_state_shutdown	= ckevt_dc21285_shutdown,
 84	.set_state_periodic	= ckevt_dc21285_set_periodic,
 85	.set_state_oneshot	= ckevt_dc21285_shutdown,
 86	.tick_resume		= ckevt_dc21285_set_periodic,
 87};
 88
 89static irqreturn_t timer1_interrupt(int irq, void *dev_id)
 90{
 91	struct clock_event_device *ce = dev_id;
 92
 93	*CSR_TIMER1_CLR = 0;
 94
 95	/* Stop the timer if in one-shot mode */
 96	if (clockevent_state_oneshot(ce))
 97		*CSR_TIMER1_CNTL = 0;
 98
 99	ce->event_handler(ce);
100
101	return IRQ_HANDLED;
102}
103
104static struct irqaction footbridge_timer_irq = {
105	.name		= "dc21285_timer1",
106	.handler	= timer1_interrupt,
107	.flags		= IRQF_TIMER | IRQF_IRQPOLL,
108	.dev_id		= &ckevt_dc21285,
109};
110
111/*
112 * Set up timer interrupt.
113 */
114void __init footbridge_timer_init(void)
115{
116	struct clock_event_device *ce = &ckevt_dc21285;
117	unsigned rate = DIV_ROUND_CLOSEST(mem_fclk_21285, 16);
118
119	clocksource_register_hz(&cksrc_dc21285, rate);
120
121	setup_irq(ce->irq, &footbridge_timer_irq);
 
 
122
123	ce->cpumask = cpumask_of(smp_processor_id());
124	clockevents_config_and_register(ce, rate, 0x4, 0xffffff);
125}
126
127static u64 notrace footbridge_read_sched_clock(void)
128{
129	return ~*CSR_TIMER3_VALUE;
130}
131
132void __init footbridge_sched_clock(void)
133{
134	unsigned rate = DIV_ROUND_CLOSEST(mem_fclk_21285, 16);
135
136	*CSR_TIMER3_LOAD = 0;
137	*CSR_TIMER3_CLR = 0;
138	*CSR_TIMER3_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_DIV16;
139
140	sched_clock_register(footbridge_read_sched_clock, 24, rate);
141}