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