]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/glsdk-u-boot.git/blob - arch/ppc/cpu/mpc512x/serial.c
nios2: Move individual board linker scripts to common script in cpu tree.
[glsdk/glsdk-u-boot.git] / arch / ppc / cpu / mpc512x / serial.c
1 /*
2  * (C) Copyright 2000 - 2010
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
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  * Based ont the MPC5200 PSC driver.
24  * Adapted for MPC512x by Jan Wrobel <wrr@semihalf.com>
25  */
27 /*
28  * Minimal serial functions needed to use one of the PSC ports
29  * as serial console interface.
30  */
32 #include <common.h>
33 #include <asm/io.h>
34 #include <asm/processor.h>
36 DECLARE_GLOBAL_DATA_PTR;
38 #if defined(CONFIG_PSC_CONSOLE)
40 static void fifo_init (volatile psc512x_t *psc)
41 {
42         volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
44         /* reset Rx & Tx fifo slice */
45         out_be32(&psc->rfcmd, PSC_FIFO_RESET_SLICE);
46         out_be32(&psc->tfcmd, PSC_FIFO_RESET_SLICE);
48         /* disable Tx & Rx FIFO interrupts */
49         out_be32(&psc->rfintmask, 0);
50         out_be32(&psc->tfintmask, 0);
52         out_be32(&psc->tfsize, CONSOLE_FIFO_TX_SIZE | (CONSOLE_FIFO_TX_ADDR << 16));
53         out_be32(&psc->rfsize, CONSOLE_FIFO_RX_SIZE | (CONSOLE_FIFO_RX_ADDR << 16));
55         /* enable Tx & Rx FIFO slice */
56         out_be32(&psc->rfcmd, PSC_FIFO_ENABLE_SLICE);
57         out_be32(&psc->tfcmd, PSC_FIFO_ENABLE_SLICE);
59         out_be32(&im->fifoc.fifoc_cmd, FIFOC_DISABLE_CLOCK_GATE);
60         __asm__ volatile ("sync");
61 }
63 void serial_setbrg(void)
64 {
65         volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
66         volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE];
67         unsigned long baseclk, div;
69         /* calculate dividor for setting PSC CTUR and CTLR registers */
70         baseclk = (gd->ips_clk + 8) / 16;
71         div = (baseclk + (gd->baudrate / 2)) / gd->baudrate;
73         out_8(&psc->ctur, (div >> 8) & 0xff);
74         out_8(&psc->ctlr,  div & 0xff); /* set baudrate */
75 }
77 int serial_init(void)
78 {
79         volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
80         volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE];
82         fifo_init (psc);
84         /* set MR register to point to MR1 */
85         out_8(&psc->command, PSC_SEL_MODE_REG_1);
87         /* disable Tx/Rx */
88         out_8(&psc->command, PSC_TX_DISABLE | PSC_RX_DISABLE);
90         /* choose the prescaler by 16 for the Tx/Rx clock generation */
91         out_be16(&psc->psc_clock_select, 0xdd00);
93         /* switch to UART mode */
94         out_be32(&psc->sicr, 0);
96         /* mode register points to mr1 */
97         /* configure parity, bit length and so on in mode register 1*/
98         out_8(&psc->mode, PSC_MODE_8_BITS | PSC_MODE_PARNONE);
99         /* now, mode register points to mr2 */
100         out_8(&psc->mode, PSC_MODE_1_STOPBIT);
102         /* set baudrate */
103         serial_setbrg();
105         /* disable all interrupts */
106         out_be16(&psc->psc_imr, 0);
108         /* reset and enable Rx/Tx */
109         out_8(&psc->command, PSC_RST_RX);
110         out_8(&psc->command, PSC_RST_TX);
111         out_8(&psc->command, PSC_RX_ENABLE | PSC_TX_ENABLE);
113         return 0;
116 void serial_putc (const char c)
118         volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
119         volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE];
121         if (c == '\n')
122                 serial_putc ('\r');
124         /* Wait for last character to go. */
125         while (!(in_be16(&psc->psc_status) & PSC_SR_TXEMP))
126                 ;
128         out_8(&psc->tfdata_8, c);
131 void serial_putc_raw (const char c)
133         volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
134         volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE];
136         /* Wait for last character to go. */
137         while (!(in_be16(&psc->psc_status) & PSC_SR_TXEMP))
138                 ;
140         out_8(&psc->tfdata_8, c);
144 void serial_puts (const char *s)
146         while (*s) {
147                 serial_putc (*s++);
148         }
151 int serial_getc (void)
153         volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
154         volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE];
156         /* Wait for a character to arrive. */
157         while (in_be32(&psc->rfstat) & PSC_FIFO_EMPTY)
158                 ;
160         return in_8(&psc->rfdata_8);
163 int serial_tstc (void)
165         volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
166         volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE];
168         return !(in_be32(&psc->rfstat) & PSC_FIFO_EMPTY);
171 void serial_setrts(int s)
173         volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
174         volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE];
176         if (s) {
177                 /* Assert RTS (become LOW) */
178                 out_8(&psc->op1, 0x1);
179         }
180         else {
181                 /* Negate RTS (become HIGH) */
182                 out_8(&psc->op0, 0x1);
183         }
186 int serial_getcts(void)
188         volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
189         volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE];
191         return (in_8(&psc->ip) & 0x1) ? 0 : 1;
193 #endif /* CONFIG_PSC_CONSOLE */