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_DUMMY_CONSOLE 180 conswitchp = &dummy_con; 181 #endif 182 #ifdef CONFIG_HEARTBEAT 183 mach_heartbeat = dn_heartbeat; 184 #endif 185 mach_get_model = dn_get_model; 186 187 cpuctrl=0xaa00; 188 189 /* clear DMA translation table */ 190 for(i=0;i<0x400;i++) 191 addr_xlat_map[i]=0; 192 193 } 194 195 irqreturn_t dn_timer_int(int irq, void *dev_id, struct pt_regs *fp) { 196 197 volatile unsigned char x; 198 199 sched_timer_handler(irq,dev_id,fp); 200 201 x=*(volatile unsigned char *)(timer+3); 202 x=*(volatile unsigned char *)(timer+5); 203 204 return IRQ_HANDLED; 205 } 206 207 void dn_sched_init(irqreturn_t (*timer_routine)(int, void *, struct pt_regs *)) { 208 209 /* program timer 1 */ 210 *(volatile unsigned char *)(timer+3)=0x01; 211 *(volatile unsigned char *)(timer+1)=0x40; 212 *(volatile unsigned char *)(timer+5)=0x09; 213 *(volatile unsigned char *)(timer+7)=0xc4; 214 215 /* enable IRQ of PIC B */ 216 *(volatile unsigned char *)(pica+1)&=(~8); 217 218 #if 0 219 printk("*(0x10803) %02x\n",*(volatile unsigned char *)(timer+0x3)); 220 printk("*(0x10803) %02x\n",*(volatile unsigned char *)(timer+0x3)); 221 #endif 222 223 sched_timer_handler=timer_routine; 224 request_irq(0,dn_timer_int,0,NULL,NULL); 225 226 } 227 228 unsigned long dn_gettimeoffset(void) { 229 230 return 0xdeadbeef; 231 232 } 233 234 int dn_dummy_hwclk(int op, struct rtc_time *t) { 235 236 237 if(!op) { /* read */ 238 t->tm_sec=rtc->second; 239 t->tm_min=rtc->minute; 240 t->tm_hour=rtc->hours; 241 t->tm_mday=rtc->day_of_month; 242 t->tm_wday=rtc->day_of_week; 243 t->tm_mon=rtc->month; 244 t->tm_year=rtc->year; 245 } else { 246 rtc->second=t->tm_sec; 247 rtc->minute=t->tm_min; 248 rtc->hours=t->tm_hour; 249 rtc->day_of_month=t->tm_mday; 250 if(t->tm_wday!=-1) 251 rtc->day_of_week=t->tm_wday; 252 rtc->month=t->tm_mon; 253 rtc->year=t->tm_year; 254 } 255 256 return 0; 257 258 } 259 260 int dn_dummy_set_clock_mmss(unsigned long nowtime) { 261 262 printk("set_clock_mmss\n"); 263 264 return 0; 265 266 } 267 268 void dn_dummy_reset(void) { 269 270 dn_serial_print("The end !\n"); 271 272 for(;;); 273 274 } 275 276 void dn_dummy_waitbut(void) { 277 278 dn_serial_print("waitbut\n"); 279 280 } 281 282 static void dn_get_model(char *model) 283 { 284 strcpy(model, "Apollo "); 285 if (apollo_model >= APOLLO_DN3000 && apollo_model <= APOLLO_DN4500) 286 strcat(model, apollo_models[apollo_model - APOLLO_DN3000]); 287 } 288 289 #ifdef CONFIG_HEARTBEAT 290 static int dn_cpuctrl=0xff00; 291 292 static void dn_heartbeat(int on) { 293 294 if(on) { 295 dn_cpuctrl&=~0x100; 296 cpuctrl=dn_cpuctrl; 297 } 298 else { 299 dn_cpuctrl&=~0x100; 300 dn_cpuctrl|=0x100; 301 cpuctrl=dn_cpuctrl; 302 } 303 } 304 #endif 305 306