/*
 * (C) Copyright 2004, Freescale, Inc
 * TsiChung Liew, Tsi-Chung.Liew@freescale.com.
 *
 * 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
 *
 */

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

#include <common.h>
#include <mpc8220.h>

#define PSC_BASE   MMAP_PSC1

#if defined(CONFIG_PSC_CONSOLE)
int psc_serial_init (void)
{
	DECLARE_GLOBAL_DATA_PTR;
	volatile psc8220_t *psc = (psc8220_t *) PSC_BASE;
	u32 counter;

	/* write to SICR: SIM2 = uart mode,dcd does not affect rx */
	psc->cr = 0;
	psc->ipcr_acr = 0;
	psc->isr_imr = 0;

	/* write to CSR: RX/TX baud rate from timers */
	psc->sr_csr = 0xdd000000;

	psc->mr1_2 = PSC_MR1_BITS_CHAR_8 | PSC_MR1_NO_PARITY | PSC_MR1_RX_RTS;
	psc->mr1_2 = PSC_MR2_STOP_BITS_1 | PSC_MR2_TX_CTS;

	/* Setting up BaudRate */
	counter = ((gd->bus_clk / gd->baudrate)) >> 5;
	counter++;

	/* write to CTUR: divide counter upper byte */
	psc->ctur = ((counter & 0xff00) << 16);
	/* write to CTLR: divide counter lower byte */
	psc->ctlr = ((counter & 0x00ff) << 24);

	psc->cr = PSC_CR_RST_RX_CMD;
	psc->cr = PSC_CR_RST_TX_CMD;
	psc->cr = PSC_CR_RST_ERR_STS_CMD;
	psc->cr = PSC_CR_RST_BRK_INT_CMD;
	psc->cr = PSC_CR_RST_MR_PTR_CMD;

	psc->cr = PSC_CR_RX_ENABLE | PSC_CR_TX_ENABLE;
	return (0);
}

void psc_serial_putc (const char c)
{
	volatile psc8220_t *psc = (psc8220_t *) PSC_BASE;

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

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

	psc->xmitbuf[0] = c;
}

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

int psc_serial_getc (void)
{
	volatile psc8220_t *psc = (psc8220_t *) PSC_BASE;

	/* Wait for a character to arrive. */
	while (!(psc->sr_csr & PSC_SR_RXRDY));
	return psc->xmitbuf[2];
}

int psc_serial_tstc (void)
{
	volatile psc8220_t *psc = (psc8220_t *) PSC_BASE;

	return (psc->sr_csr & PSC_SR_RXRDY);
}

void psc_serial_setbrg (void)
{
	DECLARE_GLOBAL_DATA_PTR;

	volatile psc8220_t *psc = (psc8220_t *) PSC_BASE;
	u32 counter;

	counter = ((gd->bus_clk / gd->baudrate)) >> 5;
	counter++;

	/* write to CTUR: divide counter upper byte */
	psc->ctur = ((counter & 0xff00) << 16);
	/* write to CTLR: divide counter lower byte */
	psc->ctlr = ((counter & 0x00ff) << 24);

	psc->cr = PSC_CR_RST_RX_CMD;
	psc->cr = PSC_CR_RST_TX_CMD;

	psc->cr = PSC_CR_RX_ENABLE | PSC_CR_TX_ENABLE;
}
#endif /* CONFIG_PSC_CONSOLE */
