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