a8ca78ad8ca27be96d45aa54298903b4ad0ebf89
[platform/kernel/u-boot.git] / drivers / serial / mcfserial.c
1 /*
2  * (C) Copyright 2004, Freescale, Inc
3  * TsiChung Liew, Tsi-Chung.Liew@freescale.com.
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  *
23  */
24
25 /*
26  * Minimal serial functions needed to use one of the uart ports
27  * as serial console interface.
28  */
29
30 #include <common.h>
31 #include <asm/mcfuart.h>
32
33 DECLARE_GLOBAL_DATA_PTR;
34
35 #ifdef CONFIG_MCFSERIAL
36 int serial_init(void)
37 {
38         volatile uart_t *uart;
39         u32 counter;
40
41         uart = (volatile uart_t *)(CFG_UART_BASE);
42
43         /* write to SICR: SIM2 = uart mode,dcd does not affect rx */
44         uart->ucr = UART_UCR_RESET_RX;
45         uart->ucr = UART_UCR_RESET_TX;
46         uart->ucr = UART_UCR_RESET_ERROR;
47         uart->ucr = UART_UCR_RESET_MR;
48         __asm__("nop");
49
50         uart->uimr = 0;
51
52         /* write to CSR: RX/TX baud rate from timers */
53         uart->ucsr = (UART_UCSR_RCS_SYS_CLK | UART_UCSR_TCS_SYS_CLK);
54
55         uart->umr = (UART_UMR_BC_8 | UART_UMR_PM_NONE);
56         uart->umr = UART_UMR_SB_STOP_BITS_1;
57
58         /* Setting up BaudRate */
59         counter = (u32) (gd->bus_clk / (gd->baudrate));
60         counter >>= 5;
61
62         /* write to CTUR: divide counter upper byte */
63         uart->ubg1 = (u8) ((counter & 0xff00) >> 8);
64         /* write to CTLR: divide counter lower byte */
65         uart->ubg2 = (u8) (counter & 0x00ff);
66
67         uart->ucr = (UART_UCR_RX_ENABLED | UART_UCR_TX_ENABLED);
68
69         return (0);
70 }
71
72 void serial_putc(const char c)
73 {
74         volatile uart_t *uart = (volatile uart_t *)(CFG_UART_BASE);
75
76         if (c == '\n')
77                 serial_putc('\r');
78
79         /* Wait for last character to go. */
80         while (!(uart->usr & UART_USR_TXRDY)) ;
81
82         uart->utb = c;
83 }
84
85 void serial_puts(const char *s)
86 {
87         while (*s) {
88                 serial_putc(*s++);
89         }
90 }
91
92 int serial_getc(void)
93 {
94         volatile uart_t *uart = (volatile uart_t *)(CFG_UART_BASE);
95
96         /* Wait for a character to arrive. */
97         while (!(uart->usr & UART_USR_RXRDY)) ;
98         return uart->urb;
99 }
100
101 int serial_tstc(void)
102 {
103         volatile uart_t *uart = (volatile uart_t *)(CFG_UART_BASE);
104
105         return (uart->usr & UART_USR_RXRDY);
106 }
107
108 void serial_setbrg(void)
109 {
110         volatile uart_t *uart = (volatile uart_t *)(CFG_UART_BASE);
111         u32 counter;
112
113         counter = ((gd->bus_clk / gd->baudrate)) >> 5;
114         counter++;
115
116         /* write to CTUR: divide counter upper byte */
117         uart->ubg1 = ((counter & 0xff00) >> 8);
118         /* write to CTLR: divide counter lower byte */
119         uart->ubg2 = (counter & 0x00ff);
120
121         uart->ucr = UART_UCR_RESET_RX;
122         uart->ucr = UART_UCR_RESET_TX;
123
124         uart->ucr = UART_UCR_RX_ENABLED | UART_UCR_TX_ENABLED;
125 }
126 #endif                          /* CONFIG_MCFSERIAL */