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