xref: /linux/arch/m68k/apollo/config.c (revision 91e60731dd605c5d6bab8b9ccac886da1780d5ca)
1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/init.h>
3 #include <linux/types.h>
4 #include <linux/kernel.h>
5 #include <linux/mm.h>
6 #include <linux/rtc.h>
7 #include <linux/interrupt.h>
8 
9 #include <asm/setup.h>
10 #include <asm/bootinfo.h>
11 #include <asm/bootinfo-apollo.h>
12 #include <asm/byteorder.h>
13 #include <asm/apollohw.h>
14 #include <asm/irq.h>
15 #include <asm/machdep.h>
16 #include <asm/config.h>
17 
18 #include "apollo.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(void);
30 extern int dn_dummy_hwclk(int, struct rtc_time *);
31 static void dn_dummy_reset(void);
32 #ifdef CONFIG_HEARTBEAT
33 static void dn_heartbeat(int on);
34 #endif
35 static irqreturn_t dn_timer_int(int irq,void *);
36 static void dn_get_model(char *model);
37 static const char *apollo_models[] = {
38 	[APOLLO_DN3000-APOLLO_DN3000] = "DN3000 (Otter)",
39 	[APOLLO_DN3010-APOLLO_DN3000] = "DN3010 (Otter)",
40 	[APOLLO_DN3500-APOLLO_DN3000] = "DN3500 (Cougar II)",
41 	[APOLLO_DN4000-APOLLO_DN3000] = "DN4000 (Mink)",
42 	[APOLLO_DN4500-APOLLO_DN3000] = "DN4500 (Roadrunner)"
43 };
44 
apollo_parse_bootinfo(const struct bi_record * record)45 int __init apollo_parse_bootinfo(const struct bi_record *record)
46 {
47 	int unknown = 0;
48 	const void *data = record->data;
49 
50 	switch (be16_to_cpu(record->tag)) {
51 	case BI_APOLLO_MODEL:
52 		apollo_model = be32_to_cpup(data);
53 		break;
54 
55 	default:
56 		 unknown=1;
57 	}
58 
59 	return unknown;
60 }
61 
dn_setup_model(void)62 static void __init dn_setup_model(void)
63 {
64 	pr_info("Apollo hardware found: [%s]\n",
65 		apollo_models[apollo_model - APOLLO_DN3000]);
66 
67 	switch(apollo_model) {
68 		case APOLLO_UNKNOWN:
69 			panic("Unknown apollo model");
70 			break;
71 		case APOLLO_DN3000:
72 		case APOLLO_DN3010:
73 			sio01_physaddr=SAU8_SIO01_PHYSADDR;
74 			rtc_physaddr=SAU8_RTC_PHYSADDR;
75 			pica_physaddr=SAU8_PICA;
76 			picb_physaddr=SAU8_PICB;
77 			cpuctrl_physaddr=SAU8_CPUCTRL;
78 			timer_physaddr=SAU8_TIMER;
79 			break;
80 		case APOLLO_DN4000:
81 			sio01_physaddr=SAU7_SIO01_PHYSADDR;
82 			sio23_physaddr=SAU7_SIO23_PHYSADDR;
83 			rtc_physaddr=SAU7_RTC_PHYSADDR;
84 			pica_physaddr=SAU7_PICA;
85 			picb_physaddr=SAU7_PICB;
86 			cpuctrl_physaddr=SAU7_CPUCTRL;
87 			timer_physaddr=SAU7_TIMER;
88 			break;
89 		case APOLLO_DN4500:
90 			panic("Apollo model not yet supported");
91 			break;
92 		case APOLLO_DN3500:
93 			sio01_physaddr=SAU7_SIO01_PHYSADDR;
94 			sio23_physaddr=SAU7_SIO23_PHYSADDR;
95 			rtc_physaddr=SAU7_RTC_PHYSADDR;
96 			pica_physaddr=SAU7_PICA;
97 			picb_physaddr=SAU7_PICB;
98 			cpuctrl_physaddr=SAU7_CPUCTRL;
99 			timer_physaddr=SAU7_TIMER;
100 			break;
101 		default:
102 			panic("Undefined apollo model");
103 			break;
104 	}
105 
106 
107 }
108 
dn_serial_print(const char * str)109 static void dn_serial_print(const char *str)
110 {
111     while (*str) {
112         if (*str == '\n') {
113             sio01.rhrb_thrb = (unsigned char)'\r';
114             while (!(sio01.srb_csrb & 0x4))
115                 ;
116         }
117         sio01.rhrb_thrb = (unsigned char)*str++;
118         while (!(sio01.srb_csrb & 0x4))
119             ;
120     }
121 }
122 
config_apollo(void)123 void __init config_apollo(void)
124 {
125 	int i;
126 
127 	dn_setup_model();
128 
129 	mach_sched_init=dn_sched_init; /* */
130 	mach_init_IRQ=dn_init_IRQ;
131 	mach_hwclk           = dn_dummy_hwclk; /* */
132 	mach_reset	     = dn_dummy_reset;  /* */
133 #ifdef CONFIG_HEARTBEAT
134 	mach_heartbeat = dn_heartbeat;
135 #endif
136 	mach_get_model       = dn_get_model;
137 
138 	cpuctrl=0xaa00;
139 
140 	/* clear DMA translation table */
141 	for(i=0;i<0x400;i++)
142 		addr_xlat_map[i]=0;
143 
144 }
145 
dn_timer_int(int irq,void * dev_id)146 irqreturn_t dn_timer_int(int irq, void *dev_id)
147 {
148 	unsigned char *at = (unsigned char *)apollo_timer;
149 
150 	legacy_timer_tick(1);
151 	timer_heartbeat();
152 
153 	READ_ONCE(*(at + 3));
154 	READ_ONCE(*(at + 5));
155 
156 	return IRQ_HANDLED;
157 }
158 
dn_sched_init(void)159 void dn_sched_init(void)
160 {
161 	/* program timer 1 */
162 	*(volatile unsigned char *)(apollo_timer + 3) = 0x01;
163 	*(volatile unsigned char *)(apollo_timer + 1) = 0x40;
164 	*(volatile unsigned char *)(apollo_timer + 5) = 0x09;
165 	*(volatile unsigned char *)(apollo_timer + 7) = 0xc4;
166 
167 	/* enable IRQ of PIC B */
168 	*(volatile unsigned char *)(pica+1)&=(~8);
169 
170 #if 0
171 	pr_info("*(0x10803) %02x\n",
172 		*(volatile unsigned char *)(apollo_timer + 0x3));
173 	pr_info("*(0x10803) %02x\n",
174 		*(volatile unsigned char *)(apollo_timer + 0x3));
175 #endif
176 
177 	if (request_irq(IRQ_APOLLO, dn_timer_int, 0, "time", NULL))
178 		pr_err("Couldn't register timer interrupt\n");
179 }
180 
dn_dummy_hwclk(int op,struct rtc_time * t)181 int dn_dummy_hwclk(int op, struct rtc_time *t) {
182 
183 
184   if(!op) { /* read */
185     t->tm_sec=rtc->second;
186     t->tm_min=rtc->minute;
187     t->tm_hour=rtc->hours;
188     t->tm_mday=rtc->day_of_month;
189     t->tm_wday=rtc->day_of_week;
190     t->tm_mon = rtc->month - 1;
191     t->tm_year=rtc->year;
192     if (t->tm_year < 70)
193 	t->tm_year += 100;
194   } else {
195     rtc->second=t->tm_sec;
196     rtc->minute=t->tm_min;
197     rtc->hours=t->tm_hour;
198     rtc->day_of_month=t->tm_mday;
199     if(t->tm_wday!=-1)
200       rtc->day_of_week=t->tm_wday;
201     rtc->month = t->tm_mon + 1;
202     rtc->year = t->tm_year % 100;
203   }
204 
205   return 0;
206 
207 }
208 
dn_dummy_reset(void)209 static void dn_dummy_reset(void)
210 {
211   dn_serial_print("The end !\n");
212 
213   for(;;);
214 
215 }
216 
dn_get_model(char * model)217 static void dn_get_model(char *model)
218 {
219     strcpy(model, "Apollo ");
220     if (apollo_model >= APOLLO_DN3000 && apollo_model <= APOLLO_DN4500)
221         strcat(model, apollo_models[apollo_model - APOLLO_DN3000]);
222 }
223 
224 #ifdef CONFIG_HEARTBEAT
225 static int dn_cpuctrl=0xff00;
226 
dn_heartbeat(int on)227 static void dn_heartbeat(int on) {
228 
229 	if(on) {
230 		dn_cpuctrl&=~0x100;
231 		cpuctrl=dn_cpuctrl;
232 	}
233 	else {
234 		dn_cpuctrl&=~0x100;
235 		dn_cpuctrl|=0x100;
236 		cpuctrl=dn_cpuctrl;
237 	}
238 }
239 #endif
240 
241