3 * Martin Winistoerfer, martinwinistoerfer@gmx.ch.
5 * SPDX-License-Identifier: GPL-2.0+
11 * Discription: Serial interface driver for SCI1 and SCI2.
12 * Since this code will be called from ROM use
13 * only non-static local variables.
22 #include <linux/compiler.h>
24 DECLARE_GLOBAL_DATA_PTR;
30 static int ready_to_send(void)
32 volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
33 volatile short status;
36 #if defined(CONFIG_5xx_CONS_SCI1)
37 status = immr->im_qsmcm.qsmcm_sc1sr;
39 status = immr->im_qsmcm.qsmcm_sc2sr;
42 #if defined(CONFIG_WATCHDOG)
43 reset_5xx_watchdog (immr);
45 } while ((status & SCI_TDRE) == 0);
51 * Minimal global serial functions needed to use one of the SCI modules.
54 static int mpc5xx_serial_init(void)
56 volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
60 #if defined(CONFIG_5xx_CONS_SCI1)
61 /* 10-Bit, 1 start bit, 8 data bit, no parity, 1 stop bit */
62 immr->im_qsmcm.qsmcm_scc1r1 = SCI_M_10;
63 immr->im_qsmcm.qsmcm_scc1r1 = SCI_TE | SCI_RE;
65 immr->im_qsmcm.qsmcm_scc2r1 = SCI_M_10;
66 immr->im_qsmcm.qsmcm_scc2r1 = SCI_TE | SCI_RE;
71 static void mpc5xx_serial_putc(const char c)
73 volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
75 /* Test for completition */
77 #if defined(CONFIG_5xx_CONS_SCI1)
78 immr->im_qsmcm.qsmcm_sc1dr = (short)c;
80 immr->im_qsmcm.qsmcm_sc2dr = (short)c;
84 #if defined(CONFIG_5xx_CONS_SCI1)
85 immr->im_qsmcm.qsmcm_sc1dr = (short)'\r';
87 immr->im_qsmcm.qsmcm_sc2dr = (short)'\r';
93 static int mpc5xx_serial_getc(void)
95 volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
96 volatile short status;
101 #if defined(CONFIG_5xx_CONS_SCI1)
102 status = immr->im_qsmcm.qsmcm_sc1sr;
104 status = immr->im_qsmcm.qsmcm_sc2sr;
107 #if defined(CONFIG_WATCHDOG)
108 reset_5xx_watchdog (immr);
110 } while ((status & SCI_RDRF) == 0);
113 #if defined(CONFIG_5xx_CONS_SCI1)
114 tmp = (unsigned char)(immr->im_qsmcm.qsmcm_sc1dr & SCI_SCXDR_MK);
116 tmp = (unsigned char)( immr->im_qsmcm.qsmcm_sc2dr & SCI_SCXDR_MK);
121 static int mpc5xx_serial_tstc(void)
123 volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
126 /* New data character ? */
127 #if defined(CONFIG_5xx_CONS_SCI1)
128 status = immr->im_qsmcm.qsmcm_sc1sr;
130 status = immr->im_qsmcm.qsmcm_sc2sr;
132 return (status & SCI_RDRF);
135 static void mpc5xx_serial_setbrg(void)
137 volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
141 scxbr = (gd->cpu_clk / (32 * gd->baudrate));
142 #if defined(CONFIG_5xx_CONS_SCI1)
143 immr->im_qsmcm.qsmcm_scc1r0 = (scxbr & SCI_SCXBR_MK);
145 immr->im_qsmcm.qsmcm_scc2r0 = (scxbr & SCI_SCXBR_MK);
149 static struct serial_device mpc5xx_serial_drv = {
150 .name = "mpc5xx_serial",
151 .start = mpc5xx_serial_init,
153 .setbrg = mpc5xx_serial_setbrg,
154 .putc = mpc5xx_serial_putc,
155 .puts = default_serial_puts,
156 .getc = mpc5xx_serial_getc,
157 .tstc = mpc5xx_serial_tstc,
160 void mpc5xx_serial_initialize(void)
162 serial_register(&mpc5xx_serial_drv);
165 __weak struct serial_device *default_serial_console(void)
167 return &mpc5xx_serial_drv;