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