diff options
Diffstat (limited to 'arch/m68k/apollo/config.c')
-rw-r--r-- | arch/m68k/apollo/config.c | 305 |
1 files changed, 305 insertions, 0 deletions
diff --git a/arch/m68k/apollo/config.c b/arch/m68k/apollo/config.c new file mode 100644 index 000000000000..264929471253 --- /dev/null +++ b/arch/m68k/apollo/config.c | |||
@@ -0,0 +1,305 @@ | |||
1 | #include <linux/config.h> | ||
2 | #include <linux/types.h> | ||
3 | #include <linux/kernel.h> | ||
4 | #include <linux/mm.h> | ||
5 | #include <linux/tty.h> | ||
6 | #include <linux/console.h> | ||
7 | #include <linux/rtc.h> | ||
8 | #include <linux/vt_kern.h> | ||
9 | #include <linux/interrupt.h> | ||
10 | |||
11 | #include <asm/setup.h> | ||
12 | #include <asm/bootinfo.h> | ||
13 | #include <asm/system.h> | ||
14 | #include <asm/pgtable.h> | ||
15 | #include <asm/apollohw.h> | ||
16 | #include <asm/irq.h> | ||
17 | #include <asm/rtc.h> | ||
18 | #include <asm/machdep.h> | ||
19 | |||
20 | u_long sio01_physaddr; | ||
21 | u_long sio23_physaddr; | ||
22 | u_long rtc_physaddr; | ||
23 | u_long pica_physaddr; | ||
24 | u_long picb_physaddr; | ||
25 | u_long cpuctrl_physaddr; | ||
26 | u_long timer_physaddr; | ||
27 | u_long apollo_model; | ||
28 | |||
29 | extern void dn_sched_init(irqreturn_t (*handler)(int,void *,struct pt_regs *)); | ||
30 | extern void dn_init_IRQ(void); | ||
31 | extern int dn_request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id); | ||
32 | extern void dn_free_irq(unsigned int irq, void *dev_id); | ||
33 | extern void dn_enable_irq(unsigned int); | ||
34 | extern void dn_disable_irq(unsigned int); | ||
35 | extern int show_dn_interrupts(struct seq_file *, void *); | ||
36 | extern unsigned long dn_gettimeoffset(void); | ||
37 | extern int dn_dummy_hwclk(int, struct rtc_time *); | ||
38 | extern int dn_dummy_set_clock_mmss(unsigned long); | ||
39 | extern void dn_dummy_reset(void); | ||
40 | extern void dn_dummy_waitbut(void); | ||
41 | extern struct fb_info *dn_fb_init(long *); | ||
42 | extern void dn_dummy_debug_init(void); | ||
43 | extern void dn_dummy_video_setup(char *,int *); | ||
44 | extern irqreturn_t dn_process_int(int irq, struct pt_regs *fp); | ||
45 | #ifdef CONFIG_HEARTBEAT | ||
46 | static void dn_heartbeat(int on); | ||
47 | #endif | ||
48 | static irqreturn_t dn_timer_int(int irq,void *, struct pt_regs *); | ||
49 | static irqreturn_t (*sched_timer_handler)(int, void *, struct pt_regs *)=NULL; | ||
50 | static void dn_get_model(char *model); | ||
51 | static const char *apollo_models[] = { | ||
52 | [APOLLO_DN3000-APOLLO_DN3000] = "DN3000 (Otter)", | ||
53 | [APOLLO_DN3010-APOLLO_DN3000] = "DN3010 (Otter)", | ||
54 | [APOLLO_DN3500-APOLLO_DN3000] = "DN3500 (Cougar II)", | ||
55 | [APOLLO_DN4000-APOLLO_DN3000] = "DN4000 (Mink)", | ||
56 | [APOLLO_DN4500-APOLLO_DN3000] = "DN4500 (Roadrunner)" | ||
57 | }; | ||
58 | |||
59 | int apollo_parse_bootinfo(const struct bi_record *record) { | ||
60 | |||
61 | int unknown = 0; | ||
62 | const unsigned long *data = record->data; | ||
63 | |||
64 | switch(record->tag) { | ||
65 | case BI_APOLLO_MODEL: | ||
66 | apollo_model=*data; | ||
67 | break; | ||
68 | |||
69 | default: | ||
70 | unknown=1; | ||
71 | } | ||
72 | |||
73 | return unknown; | ||
74 | } | ||
75 | |||
76 | void dn_setup_model(void) { | ||
77 | |||
78 | |||
79 | printk("Apollo hardware found: "); | ||
80 | printk("[%s]\n", apollo_models[apollo_model - APOLLO_DN3000]); | ||
81 | |||
82 | switch(apollo_model) { | ||
83 | case APOLLO_UNKNOWN: | ||
84 | panic("Unknown apollo model"); | ||
85 | break; | ||
86 | case APOLLO_DN3000: | ||
87 | case APOLLO_DN3010: | ||
88 | sio01_physaddr=SAU8_SIO01_PHYSADDR; | ||
89 | rtc_physaddr=SAU8_RTC_PHYSADDR; | ||
90 | pica_physaddr=SAU8_PICA; | ||
91 | picb_physaddr=SAU8_PICB; | ||
92 | cpuctrl_physaddr=SAU8_CPUCTRL; | ||
93 | timer_physaddr=SAU8_TIMER; | ||
94 | break; | ||
95 | case APOLLO_DN4000: | ||
96 | sio01_physaddr=SAU7_SIO01_PHYSADDR; | ||
97 | sio23_physaddr=SAU7_SIO23_PHYSADDR; | ||
98 | rtc_physaddr=SAU7_RTC_PHYSADDR; | ||
99 | pica_physaddr=SAU7_PICA; | ||
100 | picb_physaddr=SAU7_PICB; | ||
101 | cpuctrl_physaddr=SAU7_CPUCTRL; | ||
102 | timer_physaddr=SAU7_TIMER; | ||
103 | break; | ||
104 | case APOLLO_DN4500: | ||
105 | panic("Apollo model not yet supported"); | ||
106 | break; | ||
107 | case APOLLO_DN3500: | ||
108 | sio01_physaddr=SAU7_SIO01_PHYSADDR; | ||
109 | sio23_physaddr=SAU7_SIO23_PHYSADDR; | ||
110 | rtc_physaddr=SAU7_RTC_PHYSADDR; | ||
111 | pica_physaddr=SAU7_PICA; | ||
112 | picb_physaddr=SAU7_PICB; | ||
113 | cpuctrl_physaddr=SAU7_CPUCTRL; | ||
114 | timer_physaddr=SAU7_TIMER; | ||
115 | break; | ||
116 | default: | ||
117 | panic("Undefined apollo model"); | ||
118 | break; | ||
119 | } | ||
120 | |||
121 | |||
122 | } | ||
123 | |||
124 | int dn_serial_console_wait_key(struct console *co) { | ||
125 | |||
126 | while(!(sio01.srb_csrb & 1)) | ||
127 | barrier(); | ||
128 | return sio01.rhrb_thrb; | ||
129 | } | ||
130 | |||
131 | void dn_serial_console_write (struct console *co, const char *str,unsigned int count) | ||
132 | { | ||
133 | while(count--) { | ||
134 | if (*str == '\n') { | ||
135 | sio01.rhrb_thrb = (unsigned char)'\r'; | ||
136 | while (!(sio01.srb_csrb & 0x4)) | ||
137 | ; | ||
138 | } | ||
139 | sio01.rhrb_thrb = (unsigned char)*str++; | ||
140 | while (!(sio01.srb_csrb & 0x4)) | ||
141 | ; | ||
142 | } | ||
143 | } | ||
144 | |||
145 | void dn_serial_print (const char *str) | ||
146 | { | ||
147 | while (*str) { | ||
148 | if (*str == '\n') { | ||
149 | sio01.rhrb_thrb = (unsigned char)'\r'; | ||
150 | while (!(sio01.srb_csrb & 0x4)) | ||
151 | ; | ||
152 | } | ||
153 | sio01.rhrb_thrb = (unsigned char)*str++; | ||
154 | while (!(sio01.srb_csrb & 0x4)) | ||
155 | ; | ||
156 | } | ||
157 | } | ||
158 | |||
159 | void config_apollo(void) { | ||
160 | |||
161 | int i; | ||
162 | |||
163 | dn_setup_model(); | ||
164 | |||
165 | mach_sched_init=dn_sched_init; /* */ | ||
166 | mach_init_IRQ=dn_init_IRQ; | ||
167 | mach_default_handler=NULL; | ||
168 | mach_request_irq = dn_request_irq; | ||
169 | mach_free_irq = dn_free_irq; | ||
170 | enable_irq = dn_enable_irq; | ||
171 | disable_irq = dn_disable_irq; | ||
172 | mach_get_irq_list = show_dn_interrupts; | ||
173 | mach_gettimeoffset = dn_gettimeoffset; | ||
174 | mach_max_dma_address = 0xffffffff; | ||
175 | mach_hwclk = dn_dummy_hwclk; /* */ | ||
176 | mach_set_clock_mmss = dn_dummy_set_clock_mmss; /* */ | ||
177 | mach_process_int = dn_process_int; | ||
178 | mach_reset = dn_dummy_reset; /* */ | ||
179 | #ifdef CONFIG_DUMMY_CONSOLE | ||
180 | conswitchp = &dummy_con; | ||
181 | #endif | ||
182 | #ifdef CONFIG_HEARTBEAT | ||
183 | mach_heartbeat = dn_heartbeat; | ||
184 | #endif | ||
185 | mach_get_model = dn_get_model; | ||
186 | |||
187 | cpuctrl=0xaa00; | ||
188 | |||
189 | /* clear DMA translation table */ | ||
190 | for(i=0;i<0x400;i++) | ||
191 | addr_xlat_map[i]=0; | ||
192 | |||
193 | } | ||
194 | |||
195 | irqreturn_t dn_timer_int(int irq, void *dev_id, struct pt_regs *fp) { | ||
196 | |||
197 | volatile unsigned char x; | ||
198 | |||
199 | sched_timer_handler(irq,dev_id,fp); | ||
200 | |||
201 | x=*(volatile unsigned char *)(timer+3); | ||
202 | x=*(volatile unsigned char *)(timer+5); | ||
203 | |||
204 | return IRQ_HANDLED; | ||
205 | } | ||
206 | |||
207 | void dn_sched_init(irqreturn_t (*timer_routine)(int, void *, struct pt_regs *)) { | ||
208 | |||
209 | /* program timer 1 */ | ||
210 | *(volatile unsigned char *)(timer+3)=0x01; | ||
211 | *(volatile unsigned char *)(timer+1)=0x40; | ||
212 | *(volatile unsigned char *)(timer+5)=0x09; | ||
213 | *(volatile unsigned char *)(timer+7)=0xc4; | ||
214 | |||
215 | /* enable IRQ of PIC B */ | ||
216 | *(volatile unsigned char *)(pica+1)&=(~8); | ||
217 | |||
218 | #if 0 | ||
219 | printk("*(0x10803) %02x\n",*(volatile unsigned char *)(timer+0x3)); | ||
220 | printk("*(0x10803) %02x\n",*(volatile unsigned char *)(timer+0x3)); | ||
221 | #endif | ||
222 | |||
223 | sched_timer_handler=timer_routine; | ||
224 | request_irq(0,dn_timer_int,0,NULL,NULL); | ||
225 | |||
226 | } | ||
227 | |||
228 | unsigned long dn_gettimeoffset(void) { | ||
229 | |||
230 | return 0xdeadbeef; | ||
231 | |||
232 | } | ||
233 | |||
234 | int dn_dummy_hwclk(int op, struct rtc_time *t) { | ||
235 | |||
236 | |||
237 | if(!op) { /* read */ | ||
238 | t->tm_sec=rtc->second; | ||
239 | t->tm_min=rtc->minute; | ||
240 | t->tm_hour=rtc->hours; | ||
241 | t->tm_mday=rtc->day_of_month; | ||
242 | t->tm_wday=rtc->day_of_week; | ||
243 | t->tm_mon=rtc->month; | ||
244 | t->tm_year=rtc->year; | ||
245 | } else { | ||
246 | rtc->second=t->tm_sec; | ||
247 | rtc->minute=t->tm_min; | ||
248 | rtc->hours=t->tm_hour; | ||
249 | rtc->day_of_month=t->tm_mday; | ||
250 | if(t->tm_wday!=-1) | ||
251 | rtc->day_of_week=t->tm_wday; | ||
252 | rtc->month=t->tm_mon; | ||
253 | rtc->year=t->tm_year; | ||
254 | } | ||
255 | |||
256 | return 0; | ||
257 | |||
258 | } | ||
259 | |||
260 | int dn_dummy_set_clock_mmss(unsigned long nowtime) { | ||
261 | |||
262 | printk("set_clock_mmss\n"); | ||
263 | |||
264 | return 0; | ||
265 | |||
266 | } | ||
267 | |||
268 | void dn_dummy_reset(void) { | ||
269 | |||
270 | dn_serial_print("The end !\n"); | ||
271 | |||
272 | for(;;); | ||
273 | |||
274 | } | ||
275 | |||
276 | void dn_dummy_waitbut(void) { | ||
277 | |||
278 | dn_serial_print("waitbut\n"); | ||
279 | |||
280 | } | ||
281 | |||
282 | static void dn_get_model(char *model) | ||
283 | { | ||
284 | strcpy(model, "Apollo "); | ||
285 | if (apollo_model >= APOLLO_DN3000 && apollo_model <= APOLLO_DN4500) | ||
286 | strcat(model, apollo_models[apollo_model - APOLLO_DN3000]); | ||
287 | } | ||
288 | |||
289 | #ifdef CONFIG_HEARTBEAT | ||
290 | static int dn_cpuctrl=0xff00; | ||
291 | |||
292 | static void dn_heartbeat(int on) { | ||
293 | |||
294 | if(on) { | ||
295 | dn_cpuctrl&=~0x100; | ||
296 | cpuctrl=dn_cpuctrl; | ||
297 | } | ||
298 | else { | ||
299 | dn_cpuctrl&=~0x100; | ||
300 | dn_cpuctrl|=0x100; | ||
301 | cpuctrl=dn_cpuctrl; | ||
302 | } | ||
303 | } | ||
304 | #endif | ||
305 | |||