1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/init.h>
3 #include <linux/types.h>
4 #include <linux/kernel.h>
7 #include <linux/console.h>
9 #include <linux/vt_kern.h>
10 #include <linux/interrupt.h>
12 #include <asm/setup.h>
13 #include <asm/bootinfo.h>
14 #include <asm/bootinfo-apollo.h>
15 #include <asm/byteorder.h>
16 #include <asm/apollohw.h>
18 #include <asm/machdep.h>
20 u_long sio01_physaddr
;
21 u_long sio23_physaddr
;
25 u_long cpuctrl_physaddr
;
26 u_long timer_physaddr
;
29 extern void dn_sched_init(void);
30 extern void dn_init_IRQ(void);
31 extern int dn_dummy_hwclk(int, struct rtc_time
*);
32 extern void dn_dummy_reset(void);
33 #ifdef CONFIG_HEARTBEAT
34 static void dn_heartbeat(int on
);
36 static irqreturn_t
dn_timer_int(int irq
,void *);
37 static void dn_get_model(char *model
);
38 static const char *apollo_models
[] = {
39 [APOLLO_DN3000
-APOLLO_DN3000
] = "DN3000 (Otter)",
40 [APOLLO_DN3010
-APOLLO_DN3000
] = "DN3010 (Otter)",
41 [APOLLO_DN3500
-APOLLO_DN3000
] = "DN3500 (Cougar II)",
42 [APOLLO_DN4000
-APOLLO_DN3000
] = "DN4000 (Mink)",
43 [APOLLO_DN4500
-APOLLO_DN3000
] = "DN4500 (Roadrunner)"
46 int __init
apollo_parse_bootinfo(const struct bi_record
*record
)
49 const void *data
= record
->data
;
51 switch (be16_to_cpu(record
->tag
)) {
53 apollo_model
= be32_to_cpup(data
);
63 static void __init
dn_setup_model(void)
65 pr_info("Apollo hardware found: [%s]\n",
66 apollo_models
[apollo_model
- APOLLO_DN3000
]);
68 switch(apollo_model
) {
70 panic("Unknown apollo model");
74 sio01_physaddr
=SAU8_SIO01_PHYSADDR
;
75 rtc_physaddr
=SAU8_RTC_PHYSADDR
;
76 pica_physaddr
=SAU8_PICA
;
77 picb_physaddr
=SAU8_PICB
;
78 cpuctrl_physaddr
=SAU8_CPUCTRL
;
79 timer_physaddr
=SAU8_TIMER
;
82 sio01_physaddr
=SAU7_SIO01_PHYSADDR
;
83 sio23_physaddr
=SAU7_SIO23_PHYSADDR
;
84 rtc_physaddr
=SAU7_RTC_PHYSADDR
;
85 pica_physaddr
=SAU7_PICA
;
86 picb_physaddr
=SAU7_PICB
;
87 cpuctrl_physaddr
=SAU7_CPUCTRL
;
88 timer_physaddr
=SAU7_TIMER
;
91 panic("Apollo model not yet supported");
94 sio01_physaddr
=SAU7_SIO01_PHYSADDR
;
95 sio23_physaddr
=SAU7_SIO23_PHYSADDR
;
96 rtc_physaddr
=SAU7_RTC_PHYSADDR
;
97 pica_physaddr
=SAU7_PICA
;
98 picb_physaddr
=SAU7_PICB
;
99 cpuctrl_physaddr
=SAU7_CPUCTRL
;
100 timer_physaddr
=SAU7_TIMER
;
103 panic("Undefined apollo model");
110 int dn_serial_console_wait_key(struct console
*co
) {
112 while(!(sio01
.srb_csrb
& 1))
114 return sio01
.rhrb_thrb
;
117 void dn_serial_console_write (struct console
*co
, const char *str
,unsigned int count
)
121 sio01
.rhrb_thrb
= (unsigned char)'\r';
122 while (!(sio01
.srb_csrb
& 0x4))
125 sio01
.rhrb_thrb
= (unsigned char)*str
++;
126 while (!(sio01
.srb_csrb
& 0x4))
131 void dn_serial_print (const char *str
)
135 sio01
.rhrb_thrb
= (unsigned char)'\r';
136 while (!(sio01
.srb_csrb
& 0x4))
139 sio01
.rhrb_thrb
= (unsigned char)*str
++;
140 while (!(sio01
.srb_csrb
& 0x4))
145 void __init
config_apollo(void)
151 mach_sched_init
=dn_sched_init
; /* */
152 mach_init_IRQ
=dn_init_IRQ
;
153 mach_hwclk
= dn_dummy_hwclk
; /* */
154 mach_reset
= dn_dummy_reset
; /* */
155 #ifdef CONFIG_HEARTBEAT
156 mach_heartbeat
= dn_heartbeat
;
158 mach_get_model
= dn_get_model
;
162 /* clear DMA translation table */
168 irqreturn_t
dn_timer_int(int irq
, void *dev_id
)
170 volatile unsigned char x
;
172 legacy_timer_tick(1);
175 x
= *(volatile unsigned char *)(apollo_timer
+ 3);
176 x
= *(volatile unsigned char *)(apollo_timer
+ 5);
181 void dn_sched_init(void)
183 /* program timer 1 */
184 *(volatile unsigned char *)(apollo_timer
+ 3) = 0x01;
185 *(volatile unsigned char *)(apollo_timer
+ 1) = 0x40;
186 *(volatile unsigned char *)(apollo_timer
+ 5) = 0x09;
187 *(volatile unsigned char *)(apollo_timer
+ 7) = 0xc4;
189 /* enable IRQ of PIC B */
190 *(volatile unsigned char *)(pica
+1)&=(~8);
193 pr_info("*(0x10803) %02x\n",
194 *(volatile unsigned char *)(apollo_timer
+ 0x3));
195 pr_info("*(0x10803) %02x\n",
196 *(volatile unsigned char *)(apollo_timer
+ 0x3));
199 if (request_irq(IRQ_APOLLO
, dn_timer_int
, 0, "time", NULL
))
200 pr_err("Couldn't register timer interrupt\n");
203 int dn_dummy_hwclk(int op
, struct rtc_time
*t
) {
207 t
->tm_sec
=rtc
->second
;
208 t
->tm_min
=rtc
->minute
;
209 t
->tm_hour
=rtc
->hours
;
210 t
->tm_mday
=rtc
->day_of_month
;
211 t
->tm_wday
=rtc
->day_of_week
;
212 t
->tm_mon
= rtc
->month
- 1;
213 t
->tm_year
=rtc
->year
;
217 rtc
->second
=t
->tm_sec
;
218 rtc
->minute
=t
->tm_min
;
219 rtc
->hours
=t
->tm_hour
;
220 rtc
->day_of_month
=t
->tm_mday
;
222 rtc
->day_of_week
=t
->tm_wday
;
223 rtc
->month
= t
->tm_mon
+ 1;
224 rtc
->year
= t
->tm_year
% 100;
231 void dn_dummy_reset(void) {
233 dn_serial_print("The end !\n");
239 void dn_dummy_waitbut(void) {
241 dn_serial_print("waitbut\n");
245 static void dn_get_model(char *model
)
247 strcpy(model
, "Apollo ");
248 if (apollo_model
>= APOLLO_DN3000
&& apollo_model
<= APOLLO_DN4500
)
249 strcat(model
, apollo_models
[apollo_model
- APOLLO_DN3000
]);
252 #ifdef CONFIG_HEARTBEAT
253 static int dn_cpuctrl
=0xff00;
255 static void dn_heartbeat(int on
) {