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#elif defined(CONFIG_ETRAX_DEBUG_PORT4) 81 &ports[4]; 82#else 83 NULL; 84#endif 85 86#ifdef CONFIG_ETRAX_KGDB 87static struct dbg_port *kgdb_port = 88#if defined(CONFIG_ETRAX_KGDB_PORT0) 89 &ports[0]; 90#elif defined(CONFIG_ETRAX_KGDB_PORT1) 91 &ports[1]; 92#elif defined(CONFIG_ETRAX_KGDB_PORT2) 93 &ports[2]; 94#elif defined(CONFIG_ETRAX_KGDB_PORT3) 95 &ports[3]; 96#elif defined(CONFIG_ETRAX_KGDB_PORT4) 97 &ports[4]; 98#else 99 NULL; 100#endif 101#endif 102 103static void start_port(struct dbg_port *p) 104{ 105 /* Set up serial port registers */ 106 reg_ser_rw_tr_ctrl tr_ctrl = {0}; 107 reg_ser_rw_tr_dma_en tr_dma_en = {0}; 108 109 reg_ser_rw_rec_ctrl rec_ctrl = {0}; 110 reg_ser_rw_tr_baud_div tr_baud_div = {0}; 111 reg_ser_rw_rec_baud_div rec_baud_div = {0}; 112 113 if (!p || p->started) 114 return; 115 116 p->started = 1; 117 118 if (p->nbr == 1) 119 crisv32_pinmux_alloc_fixed(pinmux_ser1); 120 else if (p->nbr == 2) 121 crisv32_pinmux_alloc_fixed(pinmux_ser2); 122 else if (p->nbr == 3) 123 crisv32_pinmux_alloc_fixed(pinmux_ser3); 124#if CONFIG_ETRAX_SERIAL_PORTS == 5 125 else if (p->nbr == 4) 126 crisv32_pinmux_alloc_fixed(pinmux_ser4); 127#endif 128 129 tr_ctrl.base_freq = rec_ctrl.base_freq = regk_ser_f29_493; 130 tr_dma_en.en = rec_ctrl.dma_mode = regk_ser_no; 131 tr_baud_div.div = rec_baud_div.div = 29493000 / p->baudrate / 8; 132 tr_ctrl.en = rec_ctrl.en = 1; 133 134 if (p->parity == 'O') { 135 tr_ctrl.par_en = regk_ser_yes; 136 tr_ctrl.par = regk_ser_odd; 137 rec_ctrl.par_en = regk_ser_yes; 138 rec_ctrl.par = regk_ser_odd; 139 } else if (p->parity == 'E') { 140 tr_ctrl.par_en = regk_ser_yes; 141 tr_ctrl.par = regk_ser_even; 142 rec_ctrl.par_en = regk_ser_yes; 143 rec_ctrl.par = regk_ser_odd; 144 } 145 146 if (p->bits == 7) { 147 tr_ctrl.data_bits = regk_ser_bits7; 148 rec_ctrl.data_bits = regk_ser_bits7; 149 } 150 151 REG_WR (ser, p->instance, rw_tr_baud_div, tr_baud_div); 152 REG_WR (ser, p->instance, rw_rec_baud_div, rec_baud_div); 153 REG_WR (ser, p->instance, rw_tr_dma_en, tr_dma_en); 154 REG_WR (ser, p->instance, rw_tr_ctrl, tr_ctrl); 155 REG_WR (ser, p->instance, rw_rec_ctrl, rec_ctrl); 156} 157 158#ifdef CONFIG_ETRAX_KGDB 159/* Use polling to get a single character from the kernel debug port */ 160int getDebugChar(void) 161{ 162 reg_ser_rs_stat_din stat; 163 reg_ser_rw_ack_intr ack_intr = { 0 }; 164 165 do { 166 stat = REG_RD(ser, kgdb_port->instance, rs_stat_din); 167 } while (!stat.dav); 168 169 /* Ack the data_avail interrupt. */ 170 ack_intr.dav = 1; 171 REG_WR(ser, kgdb_port->instance, rw_ack_intr, ack_intr); 172 173 return stat.data; 174} 175 176/* Use polling to put a single character to the kernel debug port */ 177void putDebugChar(int val) 178{ 179 reg_ser_r_stat_din stat; 180 do { 181 stat = REG_RD(ser, kgdb_port->instance, r_stat_din); 182 } while (!stat.tr_rdy); 183 REG_WR_INT(ser, kgdb_port->instance, rw_dout, val); 184} 185#endif /* CONFIG_ETRAX_KGDB */ 186 187static void __init early_putch(int c) 188{ 189 reg_ser_r_stat_din stat; 190 /* Wait until transmitter is ready and send. */ 191 do 192 stat = REG_RD(ser, port->instance, r_stat_din); 193 while (!stat.tr_rdy); 194 REG_WR_INT(ser, port->instance, rw_dout, c); 195} 196 197static void __init 198early_console_write(struct console *con, const char *s, unsigned n) 199{ 200 extern void reset_watchdog(void); 201 int i; 202 203 /* Send data. */ 204 for (i = 0; i < n; i++) { 205 /* TODO: the '\n' -> '\n\r' translation should be done at the 206 receiver. Remove it when the serial driver removes it. */ 207 if (s[i] == '\n') 208 early_putch('\r'); 209 early_putch(s[i]); 210 reset_watchdog(); 211 } 212} 213 214static struct console early_console_dev __initdata = { 215 .name = "early", 216 .write = early_console_write, 217 .flags = CON_PRINTBUFFER | CON_BOOT, 218 .index = -1 219}; 220 221/* Register console for printk's, etc. */ 222int __init init_etrax_debug(void) 223{ 224 start_port(port); 225 226 /* Register an early console if a debug port was chosen. */ 227 register_console(&early_console_dev); 228 229#ifdef CONFIG_ETRAX_KGDB 230 start_port(kgdb_port); 231#endif /* CONFIG_ETRAX_KGDB */ 232 return 0; 233} 234