linux/arch/cris/arch-v32/kernel/debugport.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2003, Axis Communications AB.
   3 */
   4
   5#include <linux/console.h>
   6#include <linux/kernel.h>
   7#include <linux/init.h>
   8#include <linux/string.h>
   9#include <hwregs/reg_rdwr.h>
  10#include <hwregs/reg_map.h>
  11#include <hwregs/ser_defs.h>
  12#include <hwregs/dma_defs.h>
  13#include <mach/pinmux.h>
  14
  15struct dbg_port
  16{
  17        unsigned char nbr;
  18        unsigned long instance;
  19        unsigned int started;
  20        unsigned long baudrate;
  21        unsigned char parity;
  22        unsigned int bits;
  23};
  24
  25struct dbg_port ports[] =
  26{
  27  {
  28    0,
  29    regi_ser0,
  30    0,
  31    115200,
  32    'N',
  33    8
  34  },
  35  {
  36    1,
  37    regi_ser1,
  38    0,
  39    115200,
  40    'N',
  41    8
  42  },
  43  {
  44    2,
  45    regi_ser2,
  46    0,
  47    115200,
  48    'N',
  49    8
  50  },
  51  {
  52    3,
  53    regi_ser3,
  54    0,
  55    115200,
  56    'N',
  57    8
  58  },
  59#if CONFIG_ETRAX_SERIAL_PORTS == 5
  60  {
  61    4,
  62    regi_ser4,
  63    0,
  64    115200,
  65    'N',
  66    8
  67  },
  68#endif
  69};
  70
  71static struct dbg_port *port =
  72#if defined(CONFIG_ETRAX_DEBUG_PORT0)
  73        &ports[0];
  74#elif defined(CONFIG_ETRAX_DEBUG_PORT1)
  75        &ports[1];
  76#elif defined(CONFIG_ETRAX_DEBUG_PORT2)
  77        &ports[2];
  78#elif defined(CONFIG_ETRAX_DEBUG_PORT3)
  79        &ports[3];
  80#else
  81        NULL;
  82#endif
  83
  84#ifdef CONFIG_ETRAX_KGDB
  85static struct dbg_port *kgdb_port =
  86#if defined(CONFIG_ETRAX_KGDB_PORT0)
  87        &ports[0];
  88#elif defined(CONFIG_ETRAX_KGDB_PORT1)
  89        &ports[1];
  90#elif defined(CONFIG_ETRAX_KGDB_PORT2)
  91        &ports[2];
  92#elif defined(CONFIG_ETRAX_KGDB_PORT3)
  93        &ports[3];
  94#elif defined(CONFIG_ETRAX_KGDB_PORT4)
  95        &ports[4];
  96#else
  97        NULL;
  98#endif
  99#endif
 100
 101static void start_port(struct dbg_port *p)
 102{
 103        /* Set up serial port registers */
 104        reg_ser_rw_tr_ctrl tr_ctrl = {0};
 105        reg_ser_rw_tr_dma_en tr_dma_en = {0};
 106
 107        reg_ser_rw_rec_ctrl rec_ctrl = {0};
 108        reg_ser_rw_tr_baud_div tr_baud_div = {0};
 109        reg_ser_rw_rec_baud_div rec_baud_div = {0};
 110
 111        if (!p || p->started)
 112                return;
 113
 114        p->started = 1;
 115
 116        if (p->nbr == 1)
 117                crisv32_pinmux_alloc_fixed(pinmux_ser1);
 118        else if (p->nbr == 2)
 119                crisv32_pinmux_alloc_fixed(pinmux_ser2);
 120        else if (p->nbr == 3)
 121                crisv32_pinmux_alloc_fixed(pinmux_ser3);
 122#if CONFIG_ETRAX_SERIAL_PORTS == 5
 123        else if (p->nbr == 4)
 124                crisv32_pinmux_alloc_fixed(pinmux_ser4);
 125#endif
 126
 127        tr_ctrl.base_freq = rec_ctrl.base_freq = regk_ser_f29_493;
 128        tr_dma_en.en = rec_ctrl.dma_mode = regk_ser_no;
 129        tr_baud_div.div = rec_baud_div.div = 29493000 / p->baudrate / 8;
 130        tr_ctrl.en = rec_ctrl.en = 1;
 131
 132        if (p->parity == 'O') {
 133                tr_ctrl.par_en = regk_ser_yes;
 134                tr_ctrl.par = regk_ser_odd;
 135                rec_ctrl.par_en = regk_ser_yes;
 136                rec_ctrl.par = regk_ser_odd;
 137        } else if (p->parity == 'E') {
 138                tr_ctrl.par_en = regk_ser_yes;
 139                tr_ctrl.par = regk_ser_even;
 140                rec_ctrl.par_en = regk_ser_yes;
 141                rec_ctrl.par = regk_ser_odd;
 142        }
 143
 144        if (p->bits == 7) {
 145                tr_ctrl.data_bits = regk_ser_bits7;
 146                rec_ctrl.data_bits = regk_ser_bits7;
 147        }
 148
 149        REG_WR (ser, p->instance, rw_tr_baud_div, tr_baud_div);
 150        REG_WR (ser, p->instance, rw_rec_baud_div, rec_baud_div);
 151        REG_WR (ser, p->instance, rw_tr_dma_en, tr_dma_en);
 152        REG_WR (ser, p->instance, rw_tr_ctrl, tr_ctrl);
 153        REG_WR (ser, p->instance, rw_rec_ctrl, rec_ctrl);
 154}
 155
 156#ifdef CONFIG_ETRAX_KGDB
 157/* Use polling to get a single character from the kernel debug port */
 158int getDebugChar(void)
 159{
 160        reg_ser_rs_stat_din stat;
 161        reg_ser_rw_ack_intr ack_intr = { 0 };
 162
 163        do {
 164                stat = REG_RD(ser, kgdb_port->instance, rs_stat_din);
 165        } while (!stat.dav);
 166
 167        /* Ack the data_avail interrupt. */
 168        ack_intr.dav = 1;
 169        REG_WR(ser, kgdb_port->instance, rw_ack_intr, ack_intr);
 170
 171        return stat.data;
 172}
 173
 174/* Use polling to put a single character to the kernel debug port */
 175void putDebugChar(int val)
 176{
 177        reg_ser_r_stat_din stat;
 178        do {
 179                stat = REG_RD(ser, kgdb_port->instance, r_stat_din);
 180        } while (!stat.tr_rdy);
 181        REG_WR_INT(ser, kgdb_port->instance, rw_dout, val);
 182}
 183#endif /* CONFIG_ETRAX_KGDB */
 184
 185static void __init early_putch(int c)
 186{
 187        reg_ser_r_stat_din stat;
 188        /* Wait until transmitter is ready and send. */
 189        do
 190                stat = REG_RD(ser, port->instance, r_stat_din);
 191        while (!stat.tr_rdy);
 192        REG_WR_INT(ser, port->instance, rw_dout, c);
 193}
 194
 195static void __init
 196early_console_write(struct console *con, const char *s, unsigned n)
 197{
 198        extern void reset_watchdog(void);
 199        int i;
 200
 201        /* Send data. */
 202        for (i = 0; i < n; i++) {
 203                /* TODO: the '\n' -> '\n\r' translation should be done at the
 204                   receiver. Remove it when the serial driver removes it.   */
 205                if (s[i] == '\n')
 206                        early_putch('\r');
 207                early_putch(s[i]);
 208                reset_watchdog();
 209        }
 210}
 211
 212static struct console early_console_dev __initdata = {
 213        .name   = "early",
 214        .write  = early_console_write,
 215        .flags  = CON_PRINTBUFFER | CON_BOOT,
 216        .index  = -1
 217};
 218
 219/* Register console for printk's, etc. */
 220int __init init_etrax_debug(void)
 221{
 222        start_port(port);
 223
 224        /* Register an early console if a debug port was chosen.  */
 225        register_console(&early_console_dev);
 226
 227#ifdef CONFIG_ETRAX_KGDB
 228        start_port(kgdb_port);
 229#endif /* CONFIG_ETRAX_KGDB */
 230        return 0;
 231}
 232