/*
 * Copyright (C) 2003, Axis Communications AB.
 */

#include <linux/console.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/string.h>
#include <hwregs/reg_rdwr.h>
#include <hwregs/reg_map.h>
#include <hwregs/ser_defs.h>
#include <hwregs/dma_defs.h>
#include <mach/pinmux.h>

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
  },
#if CONFIG_ETRAX_SERIAL_PORTS == 5
  {
    4,
    regi_ser4,
    0,
    115200,
    'N',
    8
  },
#endif
};

static struct dbg_port *port =
#if defined(CONFIG_ETRAX_DEBUG_PORT0)
	&ports[0];
#elif defined(CONFIG_ETRAX_DEBUG_PORT1)
	&ports[1];
#elif defined(CONFIG_ETRAX_DEBUG_PORT2)
	&ports[2];
#elif defined(CONFIG_ETRAX_DEBUG_PORT3)
	&ports[3];
#elif defined(CONFIG_ETRAX_DEBUG_PORT4)
	&ports[4];
#else
	NULL;
#endif

#ifdef CONFIG_ETRAX_KGDB
static struct dbg_port *kgdb_port =
#if defined(CONFIG_ETRAX_KGDB_PORT0)
	&ports[0];
#elif defined(CONFIG_ETRAX_KGDB_PORT1)
	&ports[1];
#elif defined(CONFIG_ETRAX_KGDB_PORT2)
	&ports[2];
#elif defined(CONFIG_ETRAX_KGDB_PORT3)
	&ports[3];
#elif defined(CONFIG_ETRAX_KGDB_PORT4)
	&ports[4];
#else
	NULL;
#endif
#endif

static void start_port(struct dbg_port *p)
{
	/* 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};

	if (!p || 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);
#if CONFIG_ETRAX_SERIAL_PORTS == 5
	else if (p->nbr == 4)
		crisv32_pinmux_alloc_fixed(pinmux_ser4);
#endif

	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)
{
	reg_ser_rs_stat_din stat;
	reg_ser_rw_ack_intr ack_intr = { 0 };

	do {
		stat = REG_RD(ser, kgdb_port->instance, rs_stat_din);
	} while (!stat.dav);

	/* Ack the data_avail interrupt. */
	ack_intr.dav = 1;
	REG_WR(ser, kgdb_port->instance, rw_ack_intr, ack_intr);

	return stat.data;
}

/* Use polling to put a single character to the kernel debug port */
void putDebugChar(int val)
{
	reg_ser_r_stat_din stat;
	do {
		stat = REG_RD(ser, kgdb_port->instance, r_stat_din);
	} while (!stat.tr_rdy);
	REG_WR_INT(ser, kgdb_port->instance, rw_dout, val);
}
#endif /* CONFIG_ETRAX_KGDB */

static void __init early_putch(int c)
{
	reg_ser_r_stat_din stat;
	/* Wait until transmitter is ready and send. */
	do
		stat = REG_RD(ser, port->instance, r_stat_din);
	while (!stat.tr_rdy);
	REG_WR_INT(ser, port->instance, rw_dout, c);
}

static void __init
early_console_write(struct console *con, const char *s, unsigned n)
{
	extern void reset_watchdog(void);
	int i;

	/* Send data. */
	for (i = 0; i < n; i++) {
		/* TODO: the '\n' -> '\n\r' translation should be done at the
		   receiver. Remove it when the serial driver removes it.   */
		if (s[i] == '\n')
			early_putch('\r');
		early_putch(s[i]);
		reset_watchdog();
	}
}

static struct console early_console_dev __initdata = {
	.name   = "early",
	.write  = early_console_write,
	.flags  = CON_PRINTBUFFER | CON_BOOT,
	.index  = -1
};

/* Register console for printk's, etc. */
int __init init_etrax_debug(void)
{
        start_port(port);

	/* Register an early console if a debug port was chosen.  */
	register_console(&early_console_dev);

#ifdef CONFIG_ETRAX_KGDB
	start_port(kgdb_port);
#endif /* CONFIG_ETRAX_KGDB */
	return 0;
}
