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