root/arch/m68k/atari/debug.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ata_mfp_out
  2. atari_mfp_console_write
  3. ata_scc_out
  4. atari_scc_console_write
  5. ata_midi_out
  6. atari_midi_console_write
  7. ata_par_out
  8. atari_par_console_write
  9. atari_mfp_console_wait_key
  10. atari_scc_console_wait_key
  11. atari_midi_console_wait_key
  12. atari_init_mfp_port
  13. atari_init_scc_port
  14. atari_init_midi_port
  15. atari_debug_setup

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

/* [<][>][^][v][top][bottom][index][help] */