2 * arch/ppc/boot/simple/mpc52xx_tty.c
4 * Minimal serial functions needed to send messages out a MPC52xx
5 * Programmable Serial Controller (PSC).
7 * Author: Dale Farnsworth <dfarnsworth@mvista.com>
9 * 2003-2004 (c) MontaVista, Software, Inc. This file is licensed under the
10 * terms of the GNU General Public License version 2. This program is licensed
11 * "as is" without any warranty of any kind, whether express or implied.
14 #include <linux/config.h>
15 #include <linux/types.h>
16 #include <asm/uaccess.h>
17 #include <asm/mpc52xx.h>
18 #include <asm/mpc52xx_psc.h>
19 #include <asm/serial.h>
22 #if MPC52xx_PF_CONSOLE_PORT == 0
23 #define MPC52xx_CONSOLE MPC52xx_PSC1
24 #define MPC52xx_PSC_CONFIG_SHIFT 0
25 #elif MPC52xx_PF_CONSOLE_PORT == 1
26 #define MPC52xx_CONSOLE MPC52xx_PSC2
27 #define MPC52xx_PSC_CONFIG_SHIFT 4
28 #elif MPC52xx_PF_CONSOLE_PORT == 2
29 #define MPC52xx_CONSOLE MPC52xx_PSC3
30 #define MPC52xx_PSC_CONFIG_SHIFT 8
32 #error "MPC52xx_PF_CONSOLE_PORT not defined"
35 static struct mpc52xx_psc *psc = (struct mpc52xx_psc *)MPC52xx_CONSOLE;
37 /* The decrementer counts at the system bus clock frequency
38 * divided by four. The most accurate time base is connected to the
39 * rtc. We read the decrementer change during one rtc tick (one second)
40 * and multiply by 4 to get the system bus clock frequency.
45 struct mpc52xx_rtc *rtc = (struct mpc52xx_rtc*)MPC52xx_RTC;
46 struct mpc52xx_cdm *cdm = (struct mpc52xx_cdm*)MPC52xx_CDM;
47 int current_time, previous_time;
48 int tbl_start, tbl_end;
51 out_be32(&rtc->dividers, 0x8f1f0000); /* Set RTC 64x faster */
52 previous_time = in_be32(&rtc->time);
53 while ((current_time = in_be32(&rtc->time)) == previous_time) ;
54 tbl_start = get_tbl();
55 previous_time = current_time;
56 while ((current_time = in_be32(&rtc->time)) == previous_time) ;
58 out_be32(&rtc->dividers, 0xffff0000); /* Restore RTC */
60 xlbfreq = (tbl_end - tbl_start) << 8;
61 ipbfreq = (in_8(&cdm->ipb_clk_sel) & 1) ? xlbfreq / 2 : xlbfreq;
67 serial_init(int ignored, void *ignored2)
69 struct mpc52xx_gpio *gpio = (struct mpc52xx_gpio *)MPC52xx_GPIO;
75 static int been_here = 0;
82 val32 = in_be32(&gpio->port_config);
83 val32 &= ~(0x7 << MPC52xx_PSC_CONFIG_SHIFT);
84 val32 |= MPC52xx_GPIO_PSC_CONFIG_UART_WITHOUT_CD
85 << MPC52xx_PSC_CONFIG_SHIFT;
86 out_be32(&gpio->port_config, val32);
88 out_8(&psc->command, MPC52xx_PSC_RST_TX
89 | MPC52xx_PSC_RX_DISABLE | MPC52xx_PSC_TX_ENABLE);
90 out_8(&psc->command, MPC52xx_PSC_RST_RX);
92 out_be32(&psc->sicr, 0x0);
93 out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00);
94 out_be16(&psc->tfalarm, 0xf8);
96 out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1
97 | MPC52xx_PSC_RX_ENABLE
98 | MPC52xx_PSC_TX_ENABLE);
100 divisor = ((mpc52xx_ipbfreq()
101 / (CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD * 16)) + 1) >> 1;
103 mode1 = MPC52xx_PSC_MODE_8_BITS | MPC52xx_PSC_MODE_PARNONE
104 | MPC52xx_PSC_MODE_ERR;
105 mode2 = MPC52xx_PSC_MODE_ONE_STOP;
107 out_8(&psc->ctur, divisor>>8);
108 out_8(&psc->ctlr, divisor);
109 out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1);
110 out_8(&psc->mode, mode1);
111 out_8(&psc->mode, mode2);
113 return 0; /* ignored */
117 serial_putc(void *ignored, const char c)
121 while (!(in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_TXEMP)) ;
122 out_8(&psc->mpc52xx_psc_buffer_8, c);
123 while (!(in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_TXEMP)) ;
127 serial_getc(void *ignored)
129 while (!(in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_RXRDY)) ;
131 return in_8(&psc->mpc52xx_psc_buffer_8);
135 serial_tstc(void *ignored)
137 return (in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_RXRDY) != 0;