/* MN10300 On-chip serial driver for gdbstub I/O
 *
 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells (dhowells@redhat.com)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public Licence
 * as published by the Free Software Foundation; either version
 * 2 of the Licence, or (at your option) any later version.
 */
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/console.h>
#include <linux/init.h>
#include <linux/tty.h>
#include <asm/pgtable.h>
#include <asm/gdb-stub.h>
#include <asm/exceptions.h>
#include <unit/clock.h>
#include "mn10300-serial.h"

#if defined(CONFIG_GDBSTUB_ON_TTYSM0)
struct mn10300_serial_port *const gdbstub_port = &mn10300_serial_port_sif0;
#elif defined(CONFIG_GDBSTUB_ON_TTYSM1)
struct mn10300_serial_port *const gdbstub_port = &mn10300_serial_port_sif1;
#else
struct mn10300_serial_port *const gdbstub_port = &mn10300_serial_port_sif2;
#endif


/*
 * initialise the GDB stub I/O routines
 */
void __init gdbstub_io_init(void)
{
	uint16_t scxctr;
	int tmp;

	switch (gdbstub_port->clock_src) {
	case MNSCx_CLOCK_SRC_IOCLK:
		gdbstub_port->ioclk = MN10300_IOCLK;
		break;

#ifdef MN10300_IOBCLK
	case MNSCx_CLOCK_SRC_IOBCLK:
		gdbstub_port->ioclk = MN10300_IOBCLK;
		break;
#endif
	default:
		BUG();
	}

	/* set up the serial port */
	gdbstub_io_set_baud(115200);

	/* we want to get serial receive interrupts */
	set_intr_level(gdbstub_port->rx_irq,
		NUM2GxICR_LEVEL(CONFIG_DEBUGGER_IRQ_LEVEL));
	set_intr_level(gdbstub_port->tx_irq,
		NUM2GxICR_LEVEL(CONFIG_DEBUGGER_IRQ_LEVEL));
	set_intr_stub(NUM2EXCEP_IRQ_LEVEL(CONFIG_DEBUGGER_IRQ_LEVEL),
		gdbstub_io_rx_handler);

	*gdbstub_port->rx_icr |= GxICR_ENABLE;
	tmp = *gdbstub_port->rx_icr;

	/* enable the device */
	scxctr = SC01CTR_CLN_8BIT;	/* 1N8 */
	switch (gdbstub_port->div_timer) {
	case MNSCx_DIV_TIMER_16BIT:
		scxctr |= SC0CTR_CK_TM8UFLOW_8; /* == SC1CTR_CK_TM9UFLOW_8
						   == SC2CTR_CK_TM10UFLOW_8 */
		break;

	case MNSCx_DIV_TIMER_8BIT:
		scxctr |= SC0CTR_CK_TM2UFLOW_8;
		break;
	}

	scxctr |= SC01CTR_TXE | SC01CTR_RXE;

	*gdbstub_port->_control = scxctr;
	tmp = *gdbstub_port->_control;

	/* permit level 0 IRQs only */
	arch_local_change_intr_mask_level(
		NUM2EPSW_IM(CONFIG_DEBUGGER_IRQ_LEVEL + 1));
}

/*
 * set up the GDB stub serial port baud rate timers
 */
void gdbstub_io_set_baud(unsigned baud)
{
	const unsigned bits = 10; /* 1 [start] + 8 [data] + 0 [parity] +
				   * 1 [stop] */
	unsigned long ioclk = gdbstub_port->ioclk;
	unsigned xdiv, tmp;
	uint16_t tmxbr;
	uint8_t tmxmd;

	if (!baud) {
		baud = 9600;
	} else if (baud == 134) {
		baud = 269;	/* 134 is really 134.5 */
		xdiv = 2;
	}

try_alternative:
	xdiv = 1;

	switch (gdbstub_port->div_timer) {
	case MNSCx_DIV_TIMER_16BIT:
		tmxmd = TM8MD_SRC_IOCLK;
		tmxbr = tmp = (ioclk / (baud * xdiv) + 4) / 8 - 1;
		if (tmp > 0 && tmp <= 65535)
			goto timer_okay;

		tmxmd = TM8MD_SRC_IOCLK_8;
		tmxbr = tmp = (ioclk / (baud * 8 * xdiv) + 4) / 8 - 1;
		if (tmp > 0 && tmp <= 65535)
			goto timer_okay;

		tmxmd = TM8MD_SRC_IOCLK_32;
		tmxbr = tmp = (ioclk / (baud * 32 * xdiv) + 4) / 8 - 1;
		if (tmp > 0 && tmp <= 65535)
			goto timer_okay;

		break;

	case MNSCx_DIV_TIMER_8BIT:
		tmxmd = TM2MD_SRC_IOCLK;
		tmxbr = tmp = (ioclk / (baud * xdiv) + 4) / 8 - 1;
		if (tmp > 0 && tmp <= 255)
			goto timer_okay;

		tmxmd = TM2MD_SRC_IOCLK_8;
		tmxbr = tmp = (ioclk / (baud * 8 * xdiv) + 4) / 8 - 1;
		if (tmp > 0 && tmp <= 255)
			goto timer_okay;

		tmxmd = TM2MD_SRC_IOCLK_32;
		tmxbr = tmp = (ioclk / (baud * 32 * xdiv) + 4) / 8 - 1;
		if (tmp > 0 && tmp <= 255)
			goto timer_okay;
		break;
	}

	/* as a last resort, if the quotient is zero, default to 9600 bps */
	baud = 9600;
	goto try_alternative;

timer_okay:
	gdbstub_port->uart.timeout = (2 * bits * HZ) / baud;
	gdbstub_port->uart.timeout += HZ / 50;

	/* set the timer to produce the required baud rate */
	switch (gdbstub_port->div_timer) {
	case MNSCx_DIV_TIMER_16BIT:
		*gdbstub_port->_tmxmd = 0;
		*gdbstub_port->_tmxbr = tmxbr;
		*gdbstub_port->_tmxmd = TM8MD_INIT_COUNTER;
		*gdbstub_port->_tmxmd = tmxmd | TM8MD_COUNT_ENABLE;
		break;

	case MNSCx_DIV_TIMER_8BIT:
		*gdbstub_port->_tmxmd = 0;
		*(volatile u8 *) gdbstub_port->_tmxbr = (u8)tmxbr;
		*gdbstub_port->_tmxmd = TM2MD_INIT_COUNTER;
		*gdbstub_port->_tmxmd = tmxmd | TM2MD_COUNT_ENABLE;
		break;
	}
}

/*
 * wait for a character to come from the debugger
 */
int gdbstub_io_rx_char(unsigned char *_ch, int nonblock)
{
	unsigned ix;
	u8 ch, st;
#if defined(CONFIG_MN10300_WD_TIMER)
	int cpu;
#endif

	*_ch = 0xff;

	if (gdbstub_rx_unget) {
		*_ch = gdbstub_rx_unget;
		gdbstub_rx_unget = 0;
		return 0;
	}

try_again:
	/* pull chars out of the buffer */
	ix = gdbstub_rx_outp;
	barrier();
	if (ix == gdbstub_rx_inp) {
		if (nonblock)
			return -EAGAIN;
#ifdef CONFIG_MN10300_WD_TIMER
	for (cpu = 0; cpu < NR_CPUS; cpu++)
		watchdog_alert_counter[cpu] = 0;
#endif
		goto try_again;
	}

	ch = gdbstub_rx_buffer[ix++];
	st = gdbstub_rx_buffer[ix++];
	barrier();
	gdbstub_rx_outp = ix & (PAGE_SIZE - 1);

	st &= SC01STR_RXF | SC01STR_RBF | SC01STR_FEF | SC01STR_PEF |
		SC01STR_OEF;

	/* deal with what we've got
	 * - note that the UART doesn't do BREAK-detection for us
	 */
	if (st & SC01STR_FEF && ch == 0) {
		switch (gdbstub_port->rx_brk) {
		case 0:	gdbstub_port->rx_brk = 1;	goto try_again;
		case 1:	gdbstub_port->rx_brk = 2;	goto try_again;
		case 2:
			gdbstub_port->rx_brk = 3;
			gdbstub_proto("### GDB MNSERIAL Rx Break Detected"
				      " ###\n");
			return -EINTR;
		default:
			goto try_again;
		}
	} else if (st & SC01STR_FEF) {
		if (gdbstub_port->rx_brk)
			goto try_again;

		gdbstub_proto("### GDB MNSERIAL Framing Error ###\n");
		return -EIO;
	} else if (st & SC01STR_OEF) {
		if (gdbstub_port->rx_brk)
			goto try_again;

		gdbstub_proto("### GDB MNSERIAL Overrun Error ###\n");
		return -EIO;
	} else if (st & SC01STR_PEF) {
		if (gdbstub_port->rx_brk)
			goto try_again;

		gdbstub_proto("### GDB MNSERIAL Parity Error ###\n");
		return -EIO;
	} else {
		/* look for the tail-end char on a break run */
		if (gdbstub_port->rx_brk == 3) {
			switch (ch) {
			case 0xFF:
			case 0xFE:
			case 0xFC:
			case 0xF8:
			case 0xF0:
			case 0xE0:
			case 0xC0:
			case 0x80:
			case 0x00:
				gdbstub_port->rx_brk = 0;
				goto try_again;
			default:
				break;
			}
		}

		gdbstub_port->rx_brk = 0;
		gdbstub_io("### GDB Rx %02x (st=%02x) ###\n", ch, st);
		*_ch = ch & 0x7f;
		return 0;
	}
}

/*
 * send a character to the debugger
 */
void gdbstub_io_tx_char(unsigned char ch)
{
	while (*gdbstub_port->_status & SC01STR_TBF)
		continue;

	if (ch == 0x0a) {
		*(u8 *) gdbstub_port->_txb = 0x0d;
		while (*gdbstub_port->_status & SC01STR_TBF)
			continue;
	}

	*(u8 *) gdbstub_port->_txb = ch;
}

/*
 * flush the transmission buffers
 */
void gdbstub_io_tx_flush(void)
{
	while (*gdbstub_port->_status & (SC01STR_TBF | SC01STR_TXF))
		continue;
}
