1
2
3
4
5
6
7
8
9
10
11
12
13#include <linux/kernel.h>
14#include <linux/interrupt.h>
15#include <linux/init.h>
16#include <linux/time.h>
17#include <linux/rtc.h>
18#include <linux/fsl_devices.h>
19
20#include <asm/io.h>
21#include <asm/mpc8xx.h>
22#include <asm/8xx_immap.h>
23#include <asm/prom.h>
24#include <asm/fs_pd.h>
25#include <mm/mmu_decl.h>
26
27#include <sysdev/mpc8xx_pic.h>
28
29#include "mpc8xx.h"
30
31struct mpc8xx_pcmcia_ops m8xx_pcmcia_ops;
32
33extern int cpm_pic_init(void);
34extern int cpm_get_irq(void);
35
36
37static irqreturn_t timebase_interrupt(int irq, void *dev)
38{
39 printk ("timebase_interrupt()\n");
40
41 return IRQ_HANDLED;
42}
43
44static struct irqaction tbint_irqaction = {
45 .handler = timebase_interrupt,
46 .name = "tbint",
47};
48
49
50void __init __attribute__ ((weak))
51init_internal_rtc(void)
52{
53 sit8xx_t __iomem *sys_tmr = immr_map(im_sit);
54
55
56 clrbits16(&sys_tmr->sit_rtcsc, (RTCSC_SIE | RTCSC_ALE));
57
58
59 setbits16(&sys_tmr->sit_rtcsc, (RTCSC_RTF | RTCSC_RTE));
60 immr_unmap(sys_tmr);
61}
62
63static int __init get_freq(char *name, unsigned long *val)
64{
65 struct device_node *cpu;
66 const unsigned int *fp;
67 int found = 0;
68
69
70 cpu = of_find_node_by_type(NULL, "cpu");
71
72 if (cpu) {
73 fp = of_get_property(cpu, name, NULL);
74 if (fp) {
75 found = 1;
76 *val = *fp;
77 }
78
79 of_node_put(cpu);
80 }
81
82 return found;
83}
84
85
86
87
88
89void __init mpc8xx_calibrate_decr(void)
90{
91 struct device_node *cpu;
92 cark8xx_t __iomem *clk_r1;
93 car8xx_t __iomem *clk_r2;
94 sitk8xx_t __iomem *sys_tmr1;
95 sit8xx_t __iomem *sys_tmr2;
96 int irq, virq;
97
98 clk_r1 = immr_map(im_clkrstk);
99
100
101 out_be32(&clk_r1->cark_sccrk, ~KAPWR_KEY);
102 out_be32(&clk_r1->cark_sccrk, KAPWR_KEY);
103 immr_unmap(clk_r1);
104
105
106 clk_r2 = immr_map(im_clkrst);
107 setbits32(&clk_r2->car_sccr, 0x02000000);
108 immr_unmap(clk_r2);
109
110
111
112 ppc_proc_freq = 50000000;
113 if (!get_freq("clock-frequency", &ppc_proc_freq))
114 printk(KERN_ERR "WARNING: Estimating processor frequency "
115 "(not found)\n");
116
117 ppc_tb_freq = ppc_proc_freq / 16;
118 printk("Decrementer Frequency = 0x%lx\n", ppc_tb_freq);
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135 sys_tmr1 = immr_map(im_sitk);
136 out_be32(&sys_tmr1->sitk_tbscrk, ~KAPWR_KEY);
137 out_be32(&sys_tmr1->sitk_rtcsck, ~KAPWR_KEY);
138 out_be32(&sys_tmr1->sitk_tbk, ~KAPWR_KEY);
139 out_be32(&sys_tmr1->sitk_tbscrk, KAPWR_KEY);
140 out_be32(&sys_tmr1->sitk_rtcsck, KAPWR_KEY);
141 out_be32(&sys_tmr1->sitk_tbk, KAPWR_KEY);
142 immr_unmap(sys_tmr1);
143
144 init_internal_rtc();
145
146
147
148
149
150
151 cpu = of_find_node_by_type(NULL, "cpu");
152 virq= irq_of_parse_and_map(cpu, 0);
153 irq = virq_to_hw(virq);
154
155 sys_tmr2 = immr_map(im_sit);
156 out_be16(&sys_tmr2->sit_tbscr, ((1 << (7 - (irq/2))) << 8) |
157 (TBSCR_TBF | TBSCR_TBE));
158 immr_unmap(sys_tmr2);
159
160 if (setup_irq(virq, &tbint_irqaction))
161 panic("Could not allocate timer IRQ!");
162}
163
164
165
166
167
168
169int mpc8xx_set_rtc_time(struct rtc_time *tm)
170{
171 sitk8xx_t __iomem *sys_tmr1;
172 sit8xx_t __iomem *sys_tmr2;
173 int time;
174
175 sys_tmr1 = immr_map(im_sitk);
176 sys_tmr2 = immr_map(im_sit);
177 time = mktime(tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
178 tm->tm_hour, tm->tm_min, tm->tm_sec);
179
180 out_be32(&sys_tmr1->sitk_rtck, KAPWR_KEY);
181 out_be32(&sys_tmr2->sit_rtc, time);
182 out_be32(&sys_tmr1->sitk_rtck, ~KAPWR_KEY);
183
184 immr_unmap(sys_tmr2);
185 immr_unmap(sys_tmr1);
186 return 0;
187}
188
189void mpc8xx_get_rtc_time(struct rtc_time *tm)
190{
191 unsigned long data;
192 sit8xx_t __iomem *sys_tmr = immr_map(im_sit);
193
194
195 data = in_be32(&sys_tmr->sit_rtc);
196 to_tm(data, tm);
197 tm->tm_year -= 1900;
198 tm->tm_mon -= 1;
199 immr_unmap(sys_tmr);
200 return;
201}
202
203void mpc8xx_restart(char *cmd)
204{
205 car8xx_t __iomem *clk_r = immr_map(im_clkrst);
206
207
208 local_irq_disable();
209
210 setbits32(&clk_r->car_plprcr, 0x00000080);
211
212
213 mtmsr(mfmsr() & ~0x1000);
214
215 in_8(&clk_r->res[0]);
216 panic("Restart failed\n");
217}
218
219static void cpm_cascade(unsigned int irq, struct irq_desc *desc)
220{
221 struct irq_chip *chip;
222 int cascade_irq;
223
224 if ((cascade_irq = cpm_get_irq()) >= 0) {
225 struct irq_desc *cdesc = irq_to_desc(cascade_irq);
226
227 generic_handle_irq(cascade_irq);
228
229 chip = irq_desc_get_chip(cdesc);
230 chip->irq_eoi(&cdesc->irq_data);
231 }
232
233 chip = irq_desc_get_chip(desc);
234 chip->irq_eoi(&desc->irq_data);
235}
236
237
238
239
240
241
242
243void __init mpc8xx_pics_init(void)
244{
245 int irq;
246
247 if (mpc8xx_pic_init()) {
248 printk(KERN_ERR "Failed interrupt 8xx controller initialization\n");
249 return;
250 }
251
252 irq = cpm_pic_init();
253 if (irq != NO_IRQ)
254 irq_set_chained_handler(irq, cpm_cascade);
255}
256