| /* | 
 |  * (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> | 
 |  | 
 | DECLARE_GLOBAL_DATA_PTR; | 
 |  | 
 | #define PSC_BASE   MMAP_PSC1 | 
 |  | 
 | #if defined(CONFIG_PSC_CONSOLE) | 
 | int serial_init (void) | 
 | { | 
 | 	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_MR2_STOP_BITS_1; | 
 |  | 
 | 	/* 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 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_TXRDY)); | 
 |  | 
 | 	psc->xmitbuf[0] = c; | 
 | } | 
 |  | 
 | void serial_puts (const char *s) | 
 | { | 
 | 	while (*s) { | 
 | 		serial_putc (*s++); | 
 | 	} | 
 | } | 
 |  | 
 | int 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 serial_tstc (void) | 
 | { | 
 | 	volatile psc8220_t *psc = (psc8220_t *) PSC_BASE; | 
 |  | 
 | 	return (psc->sr_csr & PSC_SR_RXRDY); | 
 | } | 
 |  | 
 | void serial_setbrg (void) | 
 | { | 
 | 	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 */ |