/*
 * (C) Copyright 2000 - 2007
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 *
 * Based ont the MPC5200 PSC driver.
 * Adapted for MPC512x by Jan Wrobel <wrr@semihalf.com>
 */

/*
 * Minimal serial functions needed to use one of the PSC ports
 * as serial console interface.
 */

#include <common.h>

DECLARE_GLOBAL_DATA_PTR;

#if defined(CONFIG_PSC_CONSOLE)

static void fifo_init (volatile psc512x_t *psc)
{
	volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;

	/* reset Rx & Tx fifo slice */
	psc->rfcmd = PSC_FIFO_RESET_SLICE;
	psc->tfcmd = PSC_FIFO_RESET_SLICE;

	/* disable Tx & Rx FIFO interrupts */
	psc->rfintmask = 0;
	psc->tfintmask = 0;

	psc->tfsize = CONSOLE_FIFO_TX_SIZE | (CONSOLE_FIFO_TX_ADDR << 16);
	psc->rfsize = CONSOLE_FIFO_RX_SIZE | (CONSOLE_FIFO_RX_ADDR << 16);

	/* enable Tx & Rx FIFO slice */
	psc->rfcmd = PSC_FIFO_ENABLE_SLICE;
	psc->tfcmd = PSC_FIFO_ENABLE_SLICE;

	im->fifoc.fifoc_cmd = FIFOC_DISABLE_CLOCK_GATE;
	__asm__ volatile ("sync");
}

int serial_init(void)
{
	volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
	volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE];
	unsigned long baseclk;
	int div;

	fifo_init (psc);

	/* set MR register to point to MR1 */
	psc->command = PSC_SEL_MODE_REG_1;

	/* disable Tx/Rx */
	psc->command = PSC_TX_DISABLE | PSC_RX_DISABLE;

	/* choose the prescaler	by 16 for the Tx/Rx clock generation */
	psc->psc_clock_select =  0xdd00;

	/* switch to UART mode */
	psc->sicr = 0;

	/* mode register points to mr1 */
	/* configure parity, bit length and so on in mode register 1*/
	psc->mode = PSC_MODE_8_BITS | PSC_MODE_PARNONE;
	/* now, mode register points to mr2 */
	psc->mode = PSC_MODE_1_STOPBIT;

	/* calculate dividor for setting PSC CTUR and CTLR registers */
	baseclk = (gd->ips_clk + 8) / 16;
	div = (baseclk + (gd->baudrate / 2)) / gd->baudrate;

	psc->ctur = (div >> 8) & 0xff;
	/* set baudrate */
	psc->ctlr = div & 0xff;

	/* disable all interrupts */
	psc->psc_imr = 0;

	/* reset and enable Rx/Tx */
	psc->command = PSC_RST_RX;
	psc->command = PSC_RST_TX;
	psc->command = PSC_RX_ENABLE | PSC_TX_ENABLE;

	return 0;
}

void serial_putc (const char c)
{
	volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
	volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE];

	if (c == '\n')
		serial_putc ('\r');

	/* Wait for last character to go. */
	while (!(psc->psc_status & PSC_SR_TXEMP))
		;

	psc->tfdata_8 = c;
}

void serial_putc_raw (const char c)
{
	volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
	volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE];

	/* Wait for last character to go. */
	while (!(psc->psc_status & PSC_SR_TXEMP))
		;

	psc->tfdata_8 = c;
}


void serial_puts (const char *s)
{
	while (*s) {
		serial_putc (*s++);
	}
}

int serial_getc (void)
{
	volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
	volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE];

	/* Wait for a character to arrive. */
	while (psc->rfstat & PSC_FIFO_EMPTY)
		;

	return psc->rfdata_8;
}

int serial_tstc (void)
{
	volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
	volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE];

	return !(psc->rfstat & PSC_FIFO_EMPTY);
}

void serial_setbrg (void)
{
	volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
	volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE];
	unsigned long baseclk, div;

	baseclk = (gd->csb_clk + 8) / 16;
	div = (baseclk + (gd->baudrate / 2)) / gd->baudrate;

	psc->ctur = (div >> 8) & 0xFF;
	psc->ctlr =  div & 0xff; /* set baudrate */
}

void serial_setrts(int s)
{
	volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
	volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE];

	if (s) {
		/* Assert RTS (become LOW) */
		psc->op1 = 0x1;
	}
	else {
		/* Negate RTS (become HIGH) */
		psc->op0 = 0x1;
	}
}

int serial_getcts(void)
{
	volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
	volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE];

	return (psc->ip & 0x1) ? 0 : 1;
}
#endif /* CONFIG_PSC_CONSOLE */
