/* 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/system.h>
#include <asm/gdb-stub.h>
#include <asm/exceptions.h>
#include <asm/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, GxICR_LEVEL_0);
	set_intr_level(gdbstub_port->tx_irq, GxICR_LEVEL_0);
	set_intr_stub(EXCEP_IRQ_LEVEL0, 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 */
	asm volatile(
		"	and %0,epsw	\n"
		"	or %1,epsw	\n"
		:
		: "i"(~EPSW_IM), "i"(EPSW_IE|EPSW_IM_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;

	*_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;
	if (ix == gdbstub_rx_inp) {
		if (nonblock)
			return -EAGAIN;
#ifdef CONFIG_MN10300_WD_TIMER
		watchdog_alert_counter = 0;
#endif /* CONFIG_MN10300_WD_TIMER */
		goto try_again;
	}

	ch = gdbstub_rx_buffer[ix++];
	st = gdbstub_rx_buffer[ix++];
	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;
}
