]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/mips/cpu/xburst/jz_serial.c
MIPS: Ingenic XBurst Jz4740 processor support
[karo-tx-uboot.git] / arch / mips / cpu / xburst / jz_serial.c
1 /*
2  * Jz4740 UART support
3  * Copyright (c) 2011
4  * Qi Hardware, Xiangfu Liu <xiangfu@sharism.cc>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19  * MA 02111-1307 USA
20  */
21
22 #include <config.h>
23 #include <common.h>
24 #include <asm/io.h>
25 #include <asm/jz4740.h>
26
27 /*
28  * serial_init - initialize a channel
29  *
30  * This routine initializes the number of data bits, parity
31  * and set the selected baud rate. Interrupts are disabled.
32  * Set the modem control signals if the option is selected.
33  *
34  * RETURNS: N/A
35  */
36 struct jz4740_uart *uart = (struct jz4740_uart *)CONFIG_SYS_UART_BASE;
37
38 int serial_init(void)
39 {
40         /* Disable port interrupts while changing hardware */
41         writeb(0, &uart->dlhr_ier);
42
43         /* Disable UART unit function */
44         writeb(~UART_FCR_UUE, &uart->iir_fcr);
45
46         /* Set both receiver and transmitter in UART mode (not SIR) */
47         writeb(~(SIRCR_RSIRE | SIRCR_TSIRE), &uart->isr);
48
49         /*
50          * Set databits, stopbits and parity.
51          * (8-bit data, 1 stopbit, no parity)
52          */
53         writeb(UART_LCR_WLEN_8 | UART_LCR_STOP_1, &uart->lcr);
54
55         /* Set baud rate */
56         serial_setbrg();
57
58         /* Enable UART unit, enable and clear FIFO */
59         writeb(UART_FCR_UUE | UART_FCR_FE | UART_FCR_TFLS | UART_FCR_RFLS,
60                &uart->iir_fcr);
61
62         return 0;
63 }
64
65 void serial_setbrg(void)
66 {
67         u32 baud_div, tmp;
68
69         baud_div = CONFIG_SYS_EXTAL / 16 / CONFIG_BAUDRATE;
70
71         tmp = readb(&uart->lcr);
72         tmp |= UART_LCR_DLAB;
73         writeb(tmp, &uart->lcr);
74
75         writeb((baud_div >> 8) & 0xff, &uart->dlhr_ier);
76         writeb(baud_div & 0xff, &uart->rbr_thr_dllr);
77
78         tmp &= ~UART_LCR_DLAB;
79         writeb(tmp, &uart->lcr);
80 }
81
82 int serial_tstc(void)
83 {
84         if (readb(&uart->lsr) & UART_LSR_DR)
85                 return 1;
86
87         return 0;
88 }
89
90 void serial_putc(const char c)
91 {
92         if (c == '\n')
93                 serial_putc('\r');
94
95         /* Wait for fifo to shift out some bytes */
96         while (!((readb(&uart->lsr) & (UART_LSR_TDRQ | UART_LSR_TEMT)) == 0x60))
97                 ;
98
99         writeb((u8)c, &uart->rbr_thr_dllr);
100 }
101
102 int serial_getc(void)
103 {
104         while (!serial_tstc())
105                 ;
106
107         return readb(&uart->rbr_thr_dllr);
108 }
109
110 void serial_puts(const char *s)
111 {
112         while (*s)
113                 serial_putc(*s++);
114 }