Blame view

arch/mips/kernel/cevt-txx9.c 5.54 KB
229f773ef   Atsushi Nemoto   [MIPS] txx9tmr cl...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  /*
   * This file is subject to the terms and conditions of the GNU General Public
   * License.  See the file "COPYING" in the main directory of this archive
   * for more details.
   *
   * Based on linux/arch/mips/kernel/cevt-r4k.c,
   *          linux/arch/mips/jmr3927/rbhma3100/setup.c
   *
   * Copyright 2001 MontaVista Software Inc.
   * Copyright (C) 2000-2001 Toshiba Corporation
   * Copyright (C) 2007 MIPS Technologies, Inc.
   * Copyright (C) 2007 Ralf Baechle <ralf@linux-mips.org>
   */
  #include <linux/init.h>
  #include <linux/interrupt.h>
ca4d3e674   David Howells   MIPS: Add missing...
16
  #include <linux/irq.h>
229f773ef   Atsushi Nemoto   [MIPS] txx9tmr cl...
17
18
19
20
21
22
  #include <asm/time.h>
  #include <asm/txx9tmr.h>
  
  #define TCR_BASE (TXx9_TMTCR_CCDE | TXx9_TMTCR_CRE | TXx9_TMTCR_TMODE_ITVL)
  #define TIMER_CCD	0	/* 1/2 */
  #define TIMER_CLK(imclk)	((imclk) / (2 << TIMER_CCD))
a43da03ca   Atsushi Nemoto   MIPS: TXx9: micro...
23
24
25
26
  struct txx9_clocksource {
  	struct clocksource cs;
  	struct txx9_tmr_reg __iomem *tmrptr;
  };
229f773ef   Atsushi Nemoto   [MIPS] txx9tmr cl...
27

8e19608e8   Magnus Damm   clocksource: pass...
28
  static cycle_t txx9_cs_read(struct clocksource *cs)
229f773ef   Atsushi Nemoto   [MIPS] txx9tmr cl...
29
  {
a43da03ca   Atsushi Nemoto   MIPS: TXx9: micro...
30
31
32
  	struct txx9_clocksource *txx9_cs =
  		container_of(cs, struct txx9_clocksource, cs);
  	return __raw_readl(&txx9_cs->tmrptr->trr);
229f773ef   Atsushi Nemoto   [MIPS] txx9tmr cl...
33
34
35
36
  }
  
  /* Use 1 bit smaller width to use full bits in that width */
  #define TXX9_CLOCKSOURCE_BITS (TXX9_TIMER_BITS - 1)
a43da03ca   Atsushi Nemoto   MIPS: TXx9: micro...
37
38
39
40
41
42
43
44
  static struct txx9_clocksource txx9_clocksource = {
  	.cs = {
  		.name		= "TXx9",
  		.rating		= 200,
  		.read		= txx9_cs_read,
  		.mask		= CLOCKSOURCE_MASK(TXX9_CLOCKSOURCE_BITS),
  		.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
  	},
229f773ef   Atsushi Nemoto   [MIPS] txx9tmr cl...
45
46
47
48
49
50
  };
  
  void __init txx9_clocksource_init(unsigned long baseaddr,
  				  unsigned int imbusclk)
  {
  	struct txx9_tmr_reg __iomem *tmrptr;
75c4fd8c7   John Stultz   mips: convert to ...
51
  	clocksource_register_hz(&txx9_clocksource.cs, TIMER_CLK(imbusclk));
229f773ef   Atsushi Nemoto   [MIPS] txx9tmr cl...
52
53
54
55
56
57
58
59
  
  	tmrptr = ioremap(baseaddr, sizeof(struct txx9_tmr_reg));
  	__raw_writel(TCR_BASE, &tmrptr->tcr);
  	__raw_writel(0, &tmrptr->tisr);
  	__raw_writel(TIMER_CCD, &tmrptr->ccdr);
  	__raw_writel(TXx9_TMITMR_TZCE, &tmrptr->itmr);
  	__raw_writel(1 << TXX9_CLOCKSOURCE_BITS, &tmrptr->cpra);
  	__raw_writel(TCR_BASE | TXx9_TMTCR_TCE, &tmrptr->tcr);
a43da03ca   Atsushi Nemoto   MIPS: TXx9: micro...
60
  	txx9_clocksource.tmrptr = tmrptr;
229f773ef   Atsushi Nemoto   [MIPS] txx9tmr cl...
61
  }
a43da03ca   Atsushi Nemoto   MIPS: TXx9: micro...
62
63
64
65
  struct txx9_clock_event_device {
  	struct clock_event_device cd;
  	struct txx9_tmr_reg __iomem *tmrptr;
  };
229f773ef   Atsushi Nemoto   [MIPS] txx9tmr cl...
66
67
68
69
70
71
72
73
74
75
76
77
  
  static void txx9tmr_stop_and_clear(struct txx9_tmr_reg __iomem *tmrptr)
  {
  	/* stop and reset counter */
  	__raw_writel(TCR_BASE, &tmrptr->tcr);
  	/* clear pending interrupt */
  	__raw_writel(0, &tmrptr->tisr);
  }
  
  static void txx9tmr_set_mode(enum clock_event_mode mode,
  			     struct clock_event_device *evt)
  {
a43da03ca   Atsushi Nemoto   MIPS: TXx9: micro...
78
79
80
  	struct txx9_clock_event_device *txx9_cd =
  		container_of(evt, struct txx9_clock_event_device, cd);
  	struct txx9_tmr_reg __iomem *tmrptr = txx9_cd->tmrptr;
229f773ef   Atsushi Nemoto   [MIPS] txx9tmr cl...
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
  
  	txx9tmr_stop_and_clear(tmrptr);
  	switch (mode) {
  	case CLOCK_EVT_MODE_PERIODIC:
  		__raw_writel(TXx9_TMITMR_TIIE | TXx9_TMITMR_TZCE,
  			     &tmrptr->itmr);
  		/* start timer */
  		__raw_writel(((u64)(NSEC_PER_SEC / HZ) * evt->mult) >>
  			     evt->shift,
  			     &tmrptr->cpra);
  		__raw_writel(TCR_BASE | TXx9_TMTCR_TCE, &tmrptr->tcr);
  		break;
  	case CLOCK_EVT_MODE_SHUTDOWN:
  	case CLOCK_EVT_MODE_UNUSED:
  		__raw_writel(0, &tmrptr->itmr);
  		break;
  	case CLOCK_EVT_MODE_ONESHOT:
  		__raw_writel(TXx9_TMITMR_TIIE, &tmrptr->itmr);
  		break;
  	case CLOCK_EVT_MODE_RESUME:
  		__raw_writel(TIMER_CCD, &tmrptr->ccdr);
  		__raw_writel(0, &tmrptr->itmr);
  		break;
  	}
  }
  
  static int txx9tmr_set_next_event(unsigned long delta,
  				  struct clock_event_device *evt)
  {
a43da03ca   Atsushi Nemoto   MIPS: TXx9: micro...
110
111
112
  	struct txx9_clock_event_device *txx9_cd =
  		container_of(evt, struct txx9_clock_event_device, cd);
  	struct txx9_tmr_reg __iomem *tmrptr = txx9_cd->tmrptr;
229f773ef   Atsushi Nemoto   [MIPS] txx9tmr cl...
113
114
115
116
117
118
119
  
  	txx9tmr_stop_and_clear(tmrptr);
  	/* start timer */
  	__raw_writel(delta, &tmrptr->cpra);
  	__raw_writel(TCR_BASE | TXx9_TMTCR_TCE, &tmrptr->tcr);
  	return 0;
  }
a43da03ca   Atsushi Nemoto   MIPS: TXx9: micro...
120
121
122
123
124
125
126
127
128
  static struct txx9_clock_event_device txx9_clock_event_device = {
  	.cd = {
  		.name		= "TXx9",
  		.features	= CLOCK_EVT_FEAT_PERIODIC |
  				  CLOCK_EVT_FEAT_ONESHOT,
  		.rating		= 200,
  		.set_mode	= txx9tmr_set_mode,
  		.set_next_event	= txx9tmr_set_next_event,
  	},
229f773ef   Atsushi Nemoto   [MIPS] txx9tmr cl...
129
130
131
132
  };
  
  static irqreturn_t txx9tmr_interrupt(int irq, void *dev_id)
  {
a43da03ca   Atsushi Nemoto   MIPS: TXx9: micro...
133
134
135
  	struct txx9_clock_event_device *txx9_cd = dev_id;
  	struct clock_event_device *cd = &txx9_cd->cd;
  	struct txx9_tmr_reg __iomem *tmrptr = txx9_cd->tmrptr;
229f773ef   Atsushi Nemoto   [MIPS] txx9tmr cl...
136
137
138
139
140
141
142
143
  
  	__raw_writel(0, &tmrptr->tisr);	/* ack interrupt */
  	cd->event_handler(cd);
  	return IRQ_HANDLED;
  }
  
  static struct irqaction txx9tmr_irq = {
  	.handler	= txx9tmr_interrupt,
8b5690f88   Yong Zhang   MIPS: irq: Remove...
144
  	.flags		= IRQF_PERCPU | IRQF_TIMER,
229f773ef   Atsushi Nemoto   [MIPS] txx9tmr cl...
145
  	.name		= "txx9tmr",
a43da03ca   Atsushi Nemoto   MIPS: TXx9: micro...
146
  	.dev_id		= &txx9_clock_event_device,
229f773ef   Atsushi Nemoto   [MIPS] txx9tmr cl...
147
148
149
150
151
  };
  
  void __init txx9_clockevent_init(unsigned long baseaddr, int irq,
  				 unsigned int imbusclk)
  {
a43da03ca   Atsushi Nemoto   MIPS: TXx9: micro...
152
  	struct clock_event_device *cd = &txx9_clock_event_device.cd;
229f773ef   Atsushi Nemoto   [MIPS] txx9tmr cl...
153
154
155
156
157
158
  	struct txx9_tmr_reg __iomem *tmrptr;
  
  	tmrptr = ioremap(baseaddr, sizeof(struct txx9_tmr_reg));
  	txx9tmr_stop_and_clear(tmrptr);
  	__raw_writel(TIMER_CCD, &tmrptr->ccdr);
  	__raw_writel(0, &tmrptr->itmr);
a43da03ca   Atsushi Nemoto   MIPS: TXx9: micro...
159
  	txx9_clock_event_device.tmrptr = tmrptr;
229f773ef   Atsushi Nemoto   [MIPS] txx9tmr cl...
160
161
162
163
164
165
  
  	clockevent_set_clock(cd, TIMER_CLK(imbusclk));
  	cd->max_delta_ns =
  		clockevent_delta2ns(0xffffffff >> (32 - TXX9_TIMER_BITS), cd);
  	cd->min_delta_ns = clockevent_delta2ns(0xf, cd);
  	cd->irq = irq;
320ab2b0b   Rusty Russell   cpumask: convert ...
166
  	cd->cpumask = cpumask_of(0),
229f773ef   Atsushi Nemoto   [MIPS] txx9tmr cl...
167
168
169
170
171
172
173
174
175
176
177
178
  	clockevents_register_device(cd);
  	setup_irq(irq, &txx9tmr_irq);
  	printk(KERN_INFO "TXx9: clockevent device at 0x%lx, irq %d
  ",
  	       baseaddr, irq);
  }
  
  void __init txx9_tmr_init(unsigned long baseaddr)
  {
  	struct txx9_tmr_reg __iomem *tmrptr;
  
  	tmrptr = ioremap(baseaddr, sizeof(struct txx9_tmr_reg));
8986d2f50   Atsushi Nemoto   [MIPS] cevt-txx9:...
179
180
181
  	/* Start once to make CounterResetEnable effective */
  	__raw_writel(TXx9_TMTCR_CRE | TXx9_TMTCR_TCE, &tmrptr->tcr);
  	/* Stop and reset the counter */
229f773ef   Atsushi Nemoto   [MIPS] txx9tmr cl...
182
183
184
185
186
187
188
189
  	__raw_writel(TXx9_TMTCR_CRE, &tmrptr->tcr);
  	__raw_writel(0, &tmrptr->tisr);
  	__raw_writel(0xffffffff, &tmrptr->cpra);
  	__raw_writel(0, &tmrptr->itmr);
  	__raw_writel(0, &tmrptr->ccdr);
  	__raw_writel(0, &tmrptr->pgmr);
  	iounmap(tmrptr);
  }