Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 | /* * linux/arch/m68k/atari/debug.c * * Atari debugging and serial console stuff * * Assembled of parts of former atari/config.c 97-12-18 by Roman Hodek * * This file is subject to the terms and conditions of the GNU General Public * License. See the file COPYING in the main directory of this archive * for more details. */ #include <linux/config.h> #include <linux/types.h> #include <linux/tty.h> #include <linux/console.h> #include <linux/init.h> #include <linux/delay.h> #include <asm/atarihw.h> #include <asm/atariints.h> extern char m68k_debug_device[]; /* Flag that Modem1 port is already initialized and used */ int atari_MFP_init_done = 0; /* Flag that Modem1 port is already initialized and used */ int atari_SCC_init_done = 0; /* Can be set somewhere, if a SCC master reset has already be done and should * not be repeated; used by kgdb */ int atari_SCC_reset_done = 0; static struct console atari_console_driver = { "debug", NULL, /* write */ NULL, /* read */ NULL, /* device */ NULL, /* wait_key */ NULL, /* unblank */ NULL, /* setup */ CON_PRINTBUFFER, -1, 0, NULL }; static inline void ata_mfp_out (char c) { while (!(mfp.trn_stat & 0x80)) /* wait for tx buf empty */ barrier (); mfp.usart_dta = c; } void atari_mfp_console_write (struct console *co, const char *str, unsigned int count) { while (count--) { if (*str == '\n') ata_mfp_out( '\r' ); ata_mfp_out( *str++ ); } } static inline void ata_scc_out (char c) { do { MFPDELAY(); } while (!(scc.cha_b_ctrl & 0x04)); /* wait for tx buf empty */ MFPDELAY(); scc.cha_b_data = c; } void atari_scc_console_write (struct console *co, const char *str, unsigned int count) { while (count--) { if (*str == '\n') ata_scc_out( '\r' ); ata_scc_out( *str++ ); } } static inline void ata_midi_out (char c) { while (!(acia.mid_ctrl & ACIA_TDRE)) /* wait for tx buf empty */ barrier (); acia.mid_data = c; } void atari_midi_console_write (struct console *co, const char *str, unsigned int count) { while (count--) { if (*str == '\n') ata_midi_out( '\r' ); ata_midi_out( *str++ ); } } static int ata_par_out (char c) { unsigned char tmp; /* This a some-seconds timeout in case no printer is connected */ unsigned long i = loops_per_sec > 1 ? loops_per_sec : 10000000; while( (mfp.par_dt_reg & 1) && --i ) /* wait for BUSY == L */ ; if (!i) return( 0 ); sound_ym.rd_data_reg_sel = 15; /* select port B */ sound_ym.wd_data = c; /* put char onto port */ sound_ym.rd_data_reg_sel = 14; /* select port A */ tmp = sound_ym.rd_data_reg_sel; sound_ym.wd_data = tmp & ~0x20; /* set strobe L */ MFPDELAY(); /* wait a bit */ sound_ym.wd_data = tmp | 0x20; /* set strobe H */ return( 1 ); } static void atari_par_console_write (struct console *co, const char *str, unsigned int count) { static int printer_present = 1; if (!printer_present) return; while (count--) { if (*str == '\n') if (!ata_par_out( '\r' )) { printer_present = 0; return; } if (!ata_par_out( *str++ )) { printer_present = 0; return; } } } #ifdef CONFIG_SERIAL_CONSOLE int atari_mfp_console_wait_key(struct console *co) { while( !(mfp.rcv_stat & 0x80) ) /* wait for rx buf filled */ barrier(); return( mfp.usart_dta ); } int atari_scc_console_wait_key(struct console *co) { do { MFPDELAY(); } while( !(scc.cha_b_ctrl & 0x01) ); /* wait for rx buf filled */ MFPDELAY(); return( scc.cha_b_data ); } int atari_midi_console_wait_key(struct console *co) { while( !(acia.mid_ctrl & ACIA_RDRF) ) /* wait for rx buf filled */ barrier(); return( acia.mid_data ); } #endif /* The following two functions do a quick'n'dirty initialization of the MFP or * SCC serial ports. They're used by the debugging interface, kgdb, and the * serial console code. */ #ifndef CONFIG_SERIAL_CONSOLE __initfunc(static void atari_init_mfp_port( int cflag )) #else void atari_init_mfp_port( int cflag ) #endif { /* timer values for 1200...115200 bps; > 38400 select 110, 134, or 150 * bps, resp., and work only correct if there's a RSVE or RSSPEED */ static int baud_table[9] = { 16, 11, 8, 4, 2, 1, 175, 143, 128 }; int baud = cflag & CBAUD; int parity = (cflag & PARENB) ? ((cflag & PARODD) ? 0x04 : 0x06) : 0; int csize = ((cflag & CSIZE) == CS7) ? 0x20 : 0x00; if (cflag & CBAUDEX) baud += B38400; if (baud < B1200 || baud > B38400+2) baud = B9600; /* use default 9600bps for non-implemented rates */ baud -= B1200; /* baud_table[] starts at 1200bps */ mfp.trn_stat &= ~0x01; /* disable TX */ mfp.usart_ctr = parity | csize | 0x88; /* 1:16 clk mode, 1 stop bit */ mfp.tim_ct_cd &= 0x70; /* stop timer D */ mfp.tim_dt_d = baud_table[baud]; mfp.tim_ct_cd |= 0x01; /* start timer D, 1:4 */ mfp.trn_stat |= 0x01; /* enable TX */ atari_MFP_init_done = 1; } #define SCC_WRITE(reg,val) \ do { \ scc.cha_b_ctrl = (reg); \ MFPDELAY(); \ scc.cha_b_ctrl = (val); \ MFPDELAY(); \ } while(0) /* loops_per_sec isn't initialized yet, so we can't use udelay(). This does a * delay of ~ 60us. */ #define LONG_DELAY() \ do { \ int i; \ for( i = 100; i > 0; --i ) \ MFPDELAY(); \ } while(0) #ifndef CONFIG_SERIAL_CONSOLE __initfunc(static void atari_init_scc_port( int cflag )) #else void atari_init_scc_port( int cflag ) #endif { extern int atari_SCC_reset_done; static int clksrc_table[9] = /* reg 11: 0x50 = BRG, 0x00 = RTxC, 0x28 = TRxC */ { 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x00, 0x00 }; static int brgsrc_table[9] = /* reg 14: 0 = RTxC, 2 = PCLK */ { 2, 2, 2, 2, 2, 2, 0, 2, 2 }; static int clkmode_table[9] = /* reg 4: 0x40 = x16, 0x80 = x32, 0xc0 = x64 */ { 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xc0, 0x80 }; static int div_table[9] = /* reg12 (BRG low) */ { 208, 138, 103, 50, 24, 11, 1, 0, 0 }; int baud = cflag & CBAUD; int clksrc, clkmode, div, reg3, reg5; if (cflag & CBAUDEX) baud += B38400; if (baud < B1200 || baud > B38400+2) baud = B9600; /* use default 9600bps for non-implemented rates */ baud -= B1200; /* tables starts at 1200bps */ clksrc = clksrc_table[baud]; clkmode = clkmode_table[baud]; div = div_table[baud]; if (ATARIHW_PRESENT(TT_MFP) && baud >= 6) { /* special treatment for TT, where rates >= 38400 are done via TRxC */ clksrc = 0x28; /* TRxC */ clkmode = baud == 6 ? 0xc0 : baud == 7 ? 0x80 : /* really 76800bps */ 0x40; /* really 153600bps */ div = 0; } reg3 = (cflag & CSIZE) == CS8 ? 0xc0 : 0x40; reg5 = (cflag & CSIZE) == CS8 ? 0x60 : 0x20 | 0x82 /* assert DTR/RTS */; (void)scc.cha_b_ctrl; /* reset reg pointer */ SCC_WRITE( 9, 0xc0 ); /* reset */ LONG_DELAY(); /* extra delay after WR9 access */ SCC_WRITE( 4, (cflag & PARENB) ? ((cflag & PARODD) ? 0x01 : 0x03) : 0 | 0x04 /* 1 stopbit */ | clkmode ); SCC_WRITE( 3, reg3 ); SCC_WRITE( 5, reg5 ); SCC_WRITE( 9, 0 ); /* no interrupts */ LONG_DELAY(); /* extra delay after WR9 access */ SCC_WRITE( 10, 0 ); /* NRZ mode */ SCC_WRITE( 11, clksrc ); /* main clock source */ SCC_WRITE( 12, div ); /* BRG value */ SCC_WRITE( 13, 0 ); /* BRG high byte */ SCC_WRITE( 14, brgsrc_table[baud] ); SCC_WRITE( 14, brgsrc_table[baud] | (div ? 1 : 0) ); SCC_WRITE( 3, reg3 | 1 ); SCC_WRITE( 5, reg5 | 8 ); atari_SCC_reset_done = 1; atari_SCC_init_done = 1; } #ifndef CONFIG_SERIAL_CONSOLE __initfunc(static void atari_init_midi_port( int cflag )) #else void atari_init_midi_port( int cflag ) #endif { int baud = cflag & CBAUD; int csize = ((cflag & CSIZE) == CS8) ? 0x10 : 0x00; /* warning 7N1 isn't possible! (instead 7O2 is used...) */ int parity = (cflag & PARENB) ? ((cflag & PARODD) ? 0x0c : 0x08) : 0x04; int div; /* 4800 selects 7812.5, 115200 selects 500000, all other (incl. 9600 as * default) the standard MIDI speed 31250. */ if (cflag & CBAUDEX) baud += B38400; if (baud == B4800) div = ACIA_DIV64; /* really 7812.5 bps */ else if (baud == B38400+2 /* 115200 */) div = ACIA_DIV1; /* really 500 kbps (does that work??) */ else div = ACIA_DIV16; /* 31250 bps, standard for MIDI */ /* RTS low, ints disabled */ acia.mid_ctrl = div | csize | parity | ((atari_switches & ATARI_SWITCH_MIDI) ? ACIA_RHTID : ACIA_RLTID); } __initfunc(void atari_debug_init(void)) { #ifdef CONFIG_KGDB /* the m68k_debug_device is used by the GDB stub, do nothing here */ return; #endif if (!strcmp( m68k_debug_device, "ser" )) { /* defaults to ser2 for a Falcon and ser1 otherwise */ strcpy( m68k_debug_device, MACH_IS_FALCON ? "ser2" : "ser1" ); } if (!strcmp( m68k_debug_device, "ser1" )) { /* ST-MFP Modem1 serial port */ atari_init_mfp_port( B9600|CS8 ); atari_console_driver.write = atari_mfp_console_write; } else if (!strcmp( m68k_debug_device, "ser2" )) { /* SCC Modem2 serial port */ atari_init_scc_port( B9600|CS8 ); atari_console_driver.write = atari_scc_console_write; } else if (!strcmp( m68k_debug_device, "midi" )) { /* MIDI port */ atari_init_midi_port( B9600|CS8 ); atari_console_driver.write = atari_midi_console_write; } else if (!strcmp( m68k_debug_device, "par" )) { /* parallel printer */ atari_turnoff_irq( IRQ_MFP_BUSY ); /* avoid ints */ sound_ym.rd_data_reg_sel = 7; /* select mixer control */ sound_ym.wd_data = 0xff; /* sound off, ports are output */ sound_ym.rd_data_reg_sel = 15; /* select port B */ sound_ym.wd_data = 0; /* no char */ sound_ym.rd_data_reg_sel = 14; /* select port A */ sound_ym.wd_data = sound_ym.rd_data_reg_sel | 0x20; /* strobe H */ atari_console_driver.write = atari_par_console_write; } if (atari_console_driver.write) register_console(&atari_console_driver); } /* * Local variables: * c-indent-level: 4 * tab-width: 8 * End: */ |