Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/m68k/apollo/config.c
26424 views
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
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
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
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
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
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
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
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
209
static void dn_dummy_reset(void)
210
{
211
dn_serial_print("The end !\n");
212
213
for(;;);
214
215
}
216
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
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
242