1/* 2 * Copyright (C) 2003, Axis Communications AB. 3 */ 4 5#include <linux/console.h> 6#include <linux/init.h> 7#include <asm/system.h> 8#include <hwregs/reg_rdwr.h> 9#include <hwregs/reg_map.h> 10#include <hwregs/ser_defs.h> 11#include <hwregs/dma_defs.h> 12#include <mach/pinmux.h> 13 14struct dbg_port 15{ 16 unsigned char nbr; 17 unsigned long instance; 18 unsigned int started; 19 unsigned long baudrate; 20 unsigned char parity; 21 unsigned int bits; 22}; 23 24struct dbg_port ports[] = 25{ 26 { 27 0, 28 regi_ser0, 29 0, 30 115200, 31 'N', 32 8 33 }, 34 { 35 1, 36 regi_ser1, 37 0, 38 115200, 39 'N', 40 8 41 }, 42 { 43 2, 44 regi_ser2, 45 0, 46 115200, 47 'N', 48 8 49 }, 50 { 51 3, 52 regi_ser3, 53 0, 54 115200, 55 'N', 56 8 57 }, 58#if CONFIG_ETRAX_SERIAL_PORTS == 5 59 { 60 4, 61 regi_ser4, 62 0, 63 115200, 64 'N', 65 8 66 }, 67#endif 68}; 69static struct dbg_port *port = 70#if defined(CONFIG_ETRAX_DEBUG_PORT0) 71 &ports[0]; 72#elif defined(CONFIG_ETRAX_DEBUG_PORT1) 73 &ports[1]; 74#elif defined(CONFIG_ETRAX_DEBUG_PORT2) 75 &ports[2]; 76#elif defined(CONFIG_ETRAX_DEBUG_PORT3) 77 &ports[3]; 78#elif defined(CONFIG_ETRAX_DEBUG_PORT4) 79 &ports[4]; 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 102start_port(struct dbg_port* p) 103{ 104 if (!p) 105 return; 106 107 if (p->started) 108 return; 109 p->started = 1; 110 111 if (p->nbr == 1) 112 crisv32_pinmux_alloc_fixed(pinmux_ser1); 113 else if (p->nbr == 2) 114 crisv32_pinmux_alloc_fixed(pinmux_ser2); 115 else if (p->nbr == 3) 116 crisv32_pinmux_alloc_fixed(pinmux_ser3); 117#if CONFIG_ETRAX_SERIAL_PORTS == 5 118 else if (p->nbr == 4) 119 crisv32_pinmux_alloc_fixed(pinmux_ser4); 120#endif 121 122 /* Set up serial port registers */ 123 reg_ser_rw_tr_ctrl tr_ctrl = {0}; 124 reg_ser_rw_tr_dma_en tr_dma_en = {0}; 125 126 reg_ser_rw_rec_ctrl rec_ctrl = {0}; 127 reg_ser_rw_tr_baud_div tr_baud_div = {0}; 128 reg_ser_rw_rec_baud_div rec_baud_div = {0}; 129 130 tr_ctrl.base_freq = rec_ctrl.base_freq = regk_ser_f29_493; 131 tr_dma_en.en = rec_ctrl.dma_mode = regk_ser_no; 132 tr_baud_div.div = rec_baud_div.div = 29493000 / p->baudrate / 8; 133 tr_ctrl.en = rec_ctrl.en = 1; 134 135 if (p->parity == 'O') 136 { 137 tr_ctrl.par_en = regk_ser_yes; 138 tr_ctrl.par = regk_ser_odd; 139 rec_ctrl.par_en = regk_ser_yes; 140 rec_ctrl.par = regk_ser_odd; 141 } 142 else if (p->parity == 'E') 143 { 144 tr_ctrl.par_en = regk_ser_yes; 145 tr_ctrl.par = regk_ser_even; 146 rec_ctrl.par_en = regk_ser_yes; 147 rec_ctrl.par = regk_ser_odd; 148 } 149 150 if (p->bits == 7) 151 { 152 tr_ctrl.data_bits = regk_ser_bits7; 153 rec_ctrl.data_bits = regk_ser_bits7; 154 } 155 156 REG_WR (ser, p->instance, rw_tr_baud_div, tr_baud_div); 157 REG_WR (ser, p->instance, rw_rec_baud_div, rec_baud_div); 158 REG_WR (ser, p->instance, rw_tr_dma_en, tr_dma_en); 159 REG_WR (ser, p->instance, rw_tr_ctrl, tr_ctrl); 160 REG_WR (ser, p->instance, rw_rec_ctrl, rec_ctrl); 161} 162 163#ifdef CONFIG_ETRAX_KGDB 164/* Use polling to get a single character from the kernel debug port */ 165int 166getDebugChar(void) 167{ 168 reg_ser_rs_stat_din stat; 169 reg_ser_rw_ack_intr ack_intr = { 0 }; 170 171 do { 172 stat = REG_RD(ser, kgdb_port->instance, rs_stat_din); 173 } while (!stat.dav); 174 175 /* Ack the data_avail interrupt. */ 176 ack_intr.dav = 1; 177 REG_WR(ser, kgdb_port->instance, rw_ack_intr, ack_intr); 178 179 return stat.data; 180} 181 182/* Use polling to put a single character to the kernel debug port */ 183void 184putDebugChar(int val) 185{ 186 reg_ser_r_stat_din stat; 187 do { 188 stat = REG_RD(ser, kgdb_port->instance, r_stat_din); 189 } while (!stat.tr_rdy); 190 REG_WR_INT(ser, kgdb_port->instance, rw_dout, val); 191} 192#endif /* CONFIG_ETRAX_KGDB */ 193 194/* Register console for printk's, etc. */ 195int __init 196init_etrax_debug(void) 197{ 198 start_port(port); 199 200#ifdef CONFIG_ETRAX_KGDB 201 start_port(kgdb_port); 202#endif /* CONFIG_ETRAX_KGDB */ 203 return 0; 204} 205