2 * (C) Copyright 2000, 2001, 2002
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5 * See file CREDITS for list of people who contributed to this
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.
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.
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,
23 * Hacked for MPC8260 by Murray.Jensen@cmst.csiro.au, 19-Oct-00, with
24 * changes based on the file arch/ppc/mbxboot/m8260_tty.c from the
25 * Linux/PPC sources (m8260_tty.c had no copyright info in it).
29 * Minimal serial functions needed to use one of the SMC ports
30 * as serial console interface.
35 #include <asm/cpm_8260.h>
37 #if defined(CONFIG_CONS_ON_SMC)
39 #if CONFIG_CONS_INDEX == 1 /* Console on SMC1 */
42 #define PROFF_SMC_BASE PROFF_SMC1_BASE
43 #define PROFF_SMC PROFF_SMC1
44 #define CPM_CR_SMC_PAGE CPM_CR_SMC1_PAGE
45 #define CPM_CR_SMC_SBLOCK CPM_CR_SMC1_SBLOCK
46 #define CMXSMR_MASK (CMXSMR_SMC1|CMXSMR_SMC1CS_MSK)
47 #define CMXSMR_VALUE CMXSMR_SMC1CS_BRG7
49 #elif CONFIG_CONS_INDEX == 2 /* Console on SMC2 */
52 #define PROFF_SMC_BASE PROFF_SMC2_BASE
53 #define PROFF_SMC PROFF_SMC2
54 #define CPM_CR_SMC_PAGE CPM_CR_SMC2_PAGE
55 #define CPM_CR_SMC_SBLOCK CPM_CR_SMC2_SBLOCK
56 #define CMXSMR_MASK (CMXSMR_SMC2|CMXSMR_SMC2CS_MSK)
57 #define CMXSMR_VALUE CMXSMR_SMC2CS_BRG8
61 #error "console not correctly defined"
65 /* map rs_table index to baud rate generator index */
66 static unsigned char brg_map[] = {
67 6, /* BRG7 for SMC1 */
68 7, /* BRG8 for SMC2 */
69 0, /* BRG1 for SCC1 */
70 1, /* BRG1 for SCC2 */
71 2, /* BRG1 for SCC3 */
72 3, /* BRG1 for SCC4 */
75 int serial_init (void)
77 volatile immap_t *im = (immap_t *)CFG_IMMR;
79 volatile smc_uart_t *up;
80 volatile cbd_t *tbdf, *rbdf;
81 volatile cpm8260_t *cp = &(im->im_cpm);
84 /* initialize pointers to SMC */
86 sp = (smc_t *) &(im->im_smc[SMC_INDEX]);
87 *(ushort *)(&im->im_dprambase[PROFF_SMC_BASE]) = PROFF_SMC;
88 up = (smc_uart_t *)&im->im_dprambase[PROFF_SMC];
90 /* Disable transmitter/receiver.
92 sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
94 /* NOTE: I/O port pins are set up via the iop_conf_tab[] table */
96 /* Allocate space for two buffer descriptors in the DP ram.
97 * damm: allocating space after the two buffers for rx/tx data
100 dpaddr = m8260_cpm_dpalloc((2 * sizeof (cbd_t)) + 2, 16);
102 /* Set the physical address of the host memory buffers in
103 * the buffer descriptors.
105 rbdf = (cbd_t *)&im->im_dprambase[dpaddr];
106 rbdf->cbd_bufaddr = (uint) (rbdf+2);
109 tbdf->cbd_bufaddr = ((uint) (rbdf+2)) + 1;
112 /* Set up the uart parameters in the parameter ram.
114 up->smc_rbase = dpaddr;
115 up->smc_tbase = dpaddr+sizeof(cbd_t);
116 up->smc_rfcr = CPMFCR_EB;
117 up->smc_tfcr = CPMFCR_EB;
122 /* Set UART mode, 8 bit, no parity, one stop.
123 * Enable receive and transmit.
125 sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART;
127 /* Mask all interrupts and remove anything pending.
132 /* put the SMC channel into NMSI (non multiplexd serial interface)
133 * mode and wire either BRG7 to SMC1 or BRG8 to SMC2 (15-17).
135 im->im_cpmux.cmx_smr = (im->im_cpmux.cmx_smr&~CMXSMR_MASK)|CMXSMR_VALUE;
137 /* Set up the baud rate generator.
141 /* Make the first buffer the only buffer.
143 tbdf->cbd_sc |= BD_SC_WRAP;
144 rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP;
146 /* Single character receive.
151 /* Initialize Tx/Rx parameters.
154 while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */
157 cp->cp_cpcr = mk_cr_cmd(CPM_CR_SMC_PAGE, CPM_CR_SMC_SBLOCK,
158 0, CPM_CR_INIT_TRX) | CPM_CR_FLG;
160 while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */
163 /* Enable transmitter/receiver.
165 sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN;
173 DECLARE_GLOBAL_DATA_PTR;
175 #if defined(CONFIG_CONS_USE_EXTC)
176 m8260_cpm_extcbrg(brg_map[SMC_INDEX], gd->baudrate,
177 CONFIG_CONS_EXTC_RATE, CONFIG_CONS_EXTC_PINSEL);
179 m8260_cpm_setbrg(brg_map[SMC_INDEX], gd->baudrate);
184 serial_putc(const char c)
186 volatile cbd_t *tbdf;
188 volatile smc_uart_t *up;
189 volatile immap_t *im = (immap_t *)CFG_IMMR;
194 up = (smc_uart_t *)&(im->im_dprambase[PROFF_SMC]);
196 tbdf = (cbd_t *)&im->im_dprambase[up->smc_tbase];
198 /* Wait for last character to go.
200 buf = (char *)tbdf->cbd_bufaddr;
201 while (tbdf->cbd_sc & BD_SC_READY)
205 tbdf->cbd_datlen = 1;
206 tbdf->cbd_sc |= BD_SC_READY;
210 serial_puts (const char *s)
220 volatile cbd_t *rbdf;
221 volatile unsigned char *buf;
222 volatile smc_uart_t *up;
223 volatile immap_t *im = (immap_t *)CFG_IMMR;
226 up = (smc_uart_t *)&(im->im_dprambase[PROFF_SMC]);
228 rbdf = (cbd_t *)&im->im_dprambase[up->smc_rbase];
230 /* Wait for character to show up.
232 buf = (unsigned char *)rbdf->cbd_bufaddr;
233 while (rbdf->cbd_sc & BD_SC_EMPTY)
236 rbdf->cbd_sc |= BD_SC_EMPTY;
244 volatile cbd_t *rbdf;
245 volatile smc_uart_t *up;
246 volatile immap_t *im = (immap_t *)CFG_IMMR;
248 up = (smc_uart_t *)&(im->im_dprambase[PROFF_SMC]);
250 rbdf = (cbd_t *)&im->im_dprambase[up->smc_rbase];
252 return(!(rbdf->cbd_sc & BD_SC_EMPTY));
255 #endif /* CONFIG_CONS_ON_SMC */
257 #if defined(CONFIG_KGDB_ON_SMC)
259 #if defined(CONFIG_CONS_ON_SMC) && CONFIG_KGDB_INDEX == CONFIG_CONS_INDEX
260 #error Whoops! serial console and kgdb are on the same smc serial port
263 #if CONFIG_KGDB_INDEX == 1 /* KGDB Port on SMC1 */
265 #define KGDB_SMC_INDEX 0
266 #define KGDB_PROFF_SMC_BASE PROFF_SMC1_BASE
267 #define KGDB_PROFF_SMC PROFF_SMC1
268 #define KGDB_CPM_CR_SMC_PAGE CPM_CR_SMC1_PAGE
269 #define KGDB_CPM_CR_SMC_SBLOCK CPM_CR_SMC1_SBLOCK
270 #define KGDB_CMXSMR_MASK (CMXSMR_SMC1|CMXSMR_SMC1CS_MSK)
271 #define KGDB_CMXSMR_VALUE CMXSMR_SMC1CS_BRG7
273 #elif CONFIG_KGDB_INDEX == 2 /* KGDB Port on SMC2 */
275 #define KGDB_SMC_INDEX 1
276 #define KGDB_PROFF_SMC_BASE PROFF_SMC2_BASE
277 #define KGDB_PROFF_SMC PROFF_SMC2
278 #define KGDB_CPM_CR_SMC_PAGE CPM_CR_SMC2_PAGE
279 #define KGDB_CPM_CR_SMC_SBLOCK CPM_CR_SMC2_SBLOCK
280 #define KGDB_CMXSMR_MASK (CMXSMR_SMC2|CMXSMR_SMC2CS_MSK)
281 #define KGDB_CMXSMR_VALUE CMXSMR_SMC2CS_BRG8
285 #error "console not correctly defined"
290 kgdb_serial_init (void)
292 volatile immap_t *im = (immap_t *)CFG_IMMR;
294 volatile smc_uart_t *up;
295 volatile cbd_t *tbdf, *rbdf;
296 volatile cpm8260_t *cp = &(im->im_cpm);
297 uint dpaddr, speed = CONFIG_KGDB_BAUDRATE;
300 if ((s = getenv("kgdbrate")) != NULL && *s != '\0') {
301 ulong rate = simple_strtoul(s, &e, 10);
302 if (e > s && *e == '\0')
306 /* initialize pointers to SMC */
308 sp = (smc_t *) &(im->im_smc[KGDB_SMC_INDEX]);
309 *(ushort *)(&im->im_dprambase[KGDB_PROFF_SMC_BASE]) = KGDB_PROFF_SMC;
310 up = (smc_uart_t *)&im->im_dprambase[KGDB_PROFF_SMC];
312 /* Disable transmitter/receiver.
314 sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
316 /* NOTE: I/O port pins are set up via the iop_conf_tab[] table */
318 /* Allocate space for two buffer descriptors in the DP ram.
319 * damm: allocating space after the two buffers for rx/tx data
322 dpaddr = m8260_cpm_dpalloc((2 * sizeof (cbd_t)) + 2, 16);
324 /* Set the physical address of the host memory buffers in
325 * the buffer descriptors.
327 rbdf = (cbd_t *)&im->im_dprambase[dpaddr];
328 rbdf->cbd_bufaddr = (uint) (rbdf+2);
331 tbdf->cbd_bufaddr = ((uint) (rbdf+2)) + 1;
334 /* Set up the uart parameters in the parameter ram.
336 up->smc_rbase = dpaddr;
337 up->smc_tbase = dpaddr+sizeof(cbd_t);
338 up->smc_rfcr = CPMFCR_EB;
339 up->smc_tfcr = CPMFCR_EB;
344 /* Set UART mode, 8 bit, no parity, one stop.
345 * Enable receive and transmit.
347 sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART;
349 /* Mask all interrupts and remove anything pending.
354 /* put the SMC channel into NMSI (non multiplexd serial interface)
355 * mode and wire either BRG7 to SMC1 or BRG8 to SMC2 (15-17).
357 im->im_cpmux.cmx_smr =
358 (im->im_cpmux.cmx_smr & ~KGDB_CMXSMR_MASK) | KGDB_CMXSMR_VALUE;
360 /* Set up the baud rate generator.
362 #if defined(CONFIG_KGDB_USE_EXTC)
363 m8260_cpm_extcbrg(KGDB_SMC_INDEX, speed,
364 CONFIG_KGDB_EXTC_RATE, CONFIG_KGDB_EXTC_PINSEL);
366 m8260_cpm_setbrg(KGDB_SMC_INDEX, speed);
369 /* Make the first buffer the only buffer.
371 tbdf->cbd_sc |= BD_SC_WRAP;
372 rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP;
374 /* Single character receive.
379 /* Initialize Tx/Rx parameters.
382 while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */
385 cp->cp_cpcr = mk_cr_cmd(KGDB_CPM_CR_SMC_PAGE, KGDB_CPM_CR_SMC_SBLOCK,
386 0, CPM_CR_INIT_TRX) | CPM_CR_FLG;
388 while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */
391 /* Enable transmitter/receiver.
393 sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN;
395 printf("SMC%d at %dbps ", CONFIG_KGDB_INDEX, speed);
399 putDebugChar(const char c)
401 volatile cbd_t *tbdf;
403 volatile smc_uart_t *up;
404 volatile immap_t *im = (immap_t *)CFG_IMMR;
409 up = (smc_uart_t *)&(im->im_dprambase[KGDB_PROFF_SMC]);
411 tbdf = (cbd_t *)&im->im_dprambase[up->smc_tbase];
413 /* Wait for last character to go.
415 buf = (char *)tbdf->cbd_bufaddr;
416 while (tbdf->cbd_sc & BD_SC_READY)
420 tbdf->cbd_datlen = 1;
421 tbdf->cbd_sc |= BD_SC_READY;
425 putDebugStr (const char *s)
435 volatile cbd_t *rbdf;
436 volatile unsigned char *buf;
437 volatile smc_uart_t *up;
438 volatile immap_t *im = (immap_t *)CFG_IMMR;
441 up = (smc_uart_t *)&(im->im_dprambase[KGDB_PROFF_SMC]);
443 rbdf = (cbd_t *)&im->im_dprambase[up->smc_rbase];
445 /* Wait for character to show up.
447 buf = (unsigned char *)rbdf->cbd_bufaddr;
448 while (rbdf->cbd_sc & BD_SC_EMPTY)
451 rbdf->cbd_sc |= BD_SC_EMPTY;
457 kgdb_interruptible(int yes)
462 #endif /* CONFIG_KGDB_ON_SMC */