2005-07-27 11:44:44 -07:00
/*
* Copyright ( C ) 2003 , Axis Communications AB .
*/
# include <linux/console.h>
# include <linux/init.h>
# include <asm/system.h>
2007-11-30 17:26:23 +01:00
# include <hwregs/reg_rdwr.h>
# include <hwregs/reg_map.h>
# include <hwregs/ser_defs.h>
# include <hwregs/dma_defs.h>
# include <asm/arch/mach/pinmux.h>
2005-07-27 11:44:44 -07:00
struct dbg_port
{
unsigned char nbr ;
unsigned long instance ;
unsigned int started ;
unsigned long baudrate ;
unsigned char parity ;
unsigned int bits ;
} ;
struct dbg_port ports [ ] =
{
{
0 ,
regi_ser0 ,
0 ,
115200 ,
' N ' ,
8
} ,
{
1 ,
regi_ser1 ,
0 ,
115200 ,
' N ' ,
8
} ,
{
2 ,
regi_ser2 ,
0 ,
115200 ,
' N ' ,
8
} ,
{
3 ,
regi_ser3 ,
0 ,
115200 ,
' N ' ,
8
2007-11-30 17:26:23 +01:00
} ,
# if CONFIG_ETRAX_SERIAL_PORTS == 5
{
4 ,
regi_ser4 ,
0 ,
115200 ,
' N ' ,
8
} ,
# endif
2005-07-27 11:44:44 -07:00
} ;
static struct dbg_port * port =
# if defined(CONFIG_ETRAX_DEBUG_PORT0)
2007-11-30 17:26:23 +01:00
& ports [ 0 ] ;
2005-07-27 11:44:44 -07:00
# elif defined(CONFIG_ETRAX_DEBUG_PORT1)
2007-11-30 17:26:23 +01:00
& ports [ 1 ] ;
2005-07-27 11:44:44 -07:00
# elif defined(CONFIG_ETRAX_DEBUG_PORT2)
2007-11-30 17:26:23 +01:00
& ports [ 2 ] ;
2005-07-27 11:44:44 -07:00
# elif defined(CONFIG_ETRAX_DEBUG_PORT3)
2007-11-30 17:26:23 +01:00
& ports [ 3 ] ;
# elif defined(CONFIG_ETRAX_DEBUG_PORT4)
& ports [ 4 ] ;
2005-07-27 11:44:44 -07:00
# else
2007-11-30 17:26:23 +01:00
NULL ;
2005-07-27 11:44:44 -07:00
# endif
# ifdef CONFIG_ETRAX_KGDB
static struct dbg_port * kgdb_port =
# if defined(CONFIG_ETRAX_KGDB_PORT0)
2007-11-30 17:26:23 +01:00
& ports [ 0 ] ;
2005-07-27 11:44:44 -07:00
# elif defined(CONFIG_ETRAX_KGDB_PORT1)
2007-11-30 17:26:23 +01:00
& ports [ 1 ] ;
2005-07-27 11:44:44 -07:00
# elif defined(CONFIG_ETRAX_KGDB_PORT2)
2007-11-30 17:26:23 +01:00
& ports [ 2 ] ;
2005-07-27 11:44:44 -07:00
# elif defined(CONFIG_ETRAX_KGDB_PORT3)
2007-11-30 17:26:23 +01:00
& ports [ 3 ] ;
# elif defined(CONFIG_ETRAX_KGDB_PORT4)
& ports [ 4 ] ;
2005-07-27 11:44:44 -07:00
# else
2007-11-30 17:26:23 +01:00
NULL ;
2005-07-27 11:44:44 -07:00
# endif
# endif
static void
start_port ( struct dbg_port * p )
{
if ( ! p )
return ;
if ( p - > started )
return ;
p - > started = 1 ;
if ( p - > nbr = = 1 )
crisv32_pinmux_alloc_fixed ( pinmux_ser1 ) ;
else if ( p - > nbr = = 2 )
crisv32_pinmux_alloc_fixed ( pinmux_ser2 ) ;
else if ( p - > nbr = = 3 )
crisv32_pinmux_alloc_fixed ( pinmux_ser3 ) ;
2007-11-30 17:26:23 +01:00
# if CONFIG_ETRAX_SERIAL_PORTS == 5
else if ( p - > nbr = = 4 )
crisv32_pinmux_alloc_fixed ( pinmux_ser4 ) ;
# endif
2005-07-27 11:44:44 -07:00
/* Set up serial port registers */
reg_ser_rw_tr_ctrl tr_ctrl = { 0 } ;
reg_ser_rw_tr_dma_en tr_dma_en = { 0 } ;
reg_ser_rw_rec_ctrl rec_ctrl = { 0 } ;
reg_ser_rw_tr_baud_div tr_baud_div = { 0 } ;
reg_ser_rw_rec_baud_div rec_baud_div = { 0 } ;
tr_ctrl . base_freq = rec_ctrl . base_freq = regk_ser_f29_493 ;
tr_dma_en . en = rec_ctrl . dma_mode = regk_ser_no ;
tr_baud_div . div = rec_baud_div . div = 29493000 / p - > baudrate / 8 ;
tr_ctrl . en = rec_ctrl . en = 1 ;
if ( p - > parity = = ' O ' )
{
tr_ctrl . par_en = regk_ser_yes ;
tr_ctrl . par = regk_ser_odd ;
rec_ctrl . par_en = regk_ser_yes ;
rec_ctrl . par = regk_ser_odd ;
}
else if ( p - > parity = = ' E ' )
{
tr_ctrl . par_en = regk_ser_yes ;
tr_ctrl . par = regk_ser_even ;
rec_ctrl . par_en = regk_ser_yes ;
rec_ctrl . par = regk_ser_odd ;
}
if ( p - > bits = = 7 )
{
tr_ctrl . data_bits = regk_ser_bits7 ;
rec_ctrl . data_bits = regk_ser_bits7 ;
}
REG_WR ( ser , p - > instance , rw_tr_baud_div , tr_baud_div ) ;
REG_WR ( ser , p - > instance , rw_rec_baud_div , rec_baud_div ) ;
REG_WR ( ser , p - > instance , rw_tr_dma_en , tr_dma_en ) ;
REG_WR ( ser , p - > instance , rw_tr_ctrl , tr_ctrl ) ;
REG_WR ( ser , p - > instance , rw_rec_ctrl , rec_ctrl ) ;
}
# ifdef CONFIG_ETRAX_KGDB
/* Use polling to get a single character from the kernel debug port */
int
getDebugChar ( void )
{
2007-11-30 17:26:23 +01:00
reg_ser_rs_stat_din stat ;
2005-07-27 11:44:44 -07:00
reg_ser_rw_ack_intr ack_intr = { 0 } ;
do {
2007-11-30 17:26:23 +01:00
stat = REG_RD ( ser , kgdb_port - > instance , rs_stat_din ) ;
} while ( ! stat . dav ) ;
2005-07-27 11:44:44 -07:00
/* Ack the data_avail interrupt. */
2007-11-30 17:26:23 +01:00
ack_intr . dav = 1 ;
REG_WR ( ser , kgdb_port - > instance , rw_ack_intr , ack_intr ) ;
2005-07-27 11:44:44 -07:00
return stat . data ;
}
/* Use polling to put a single character to the kernel debug port */
void
putDebugChar ( int val )
{
2007-11-30 17:26:23 +01:00
reg_ser_r_stat_din stat ;
2005-07-27 11:44:44 -07:00
do {
2007-11-30 17:26:23 +01:00
stat = REG_RD ( ser , kgdb_port - > instance , r_stat_din ) ;
} while ( ! stat . tr_rdy ) ;
REG_WR_INT ( ser , kgdb_port - > instance , rw_dout , val ) ;
2005-07-27 11:44:44 -07:00
}
# endif /* CONFIG_ETRAX_KGDB */
/* Register console for printk's, etc. */
int __init
init_etrax_debug ( void )
{
start_port ( port ) ;
# ifdef CONFIG_ETRAX_KGDB
start_port ( kgdb_port ) ;
# endif /* CONFIG_ETRAX_KGDB */
return 0 ;
}