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 DECLARE_GLOBAL_DATA_PTR
;
39 #if defined(CONFIG_CONS_ON_SMC)
41 #if CONFIG_CONS_INDEX == 1 /* Console on SMC1 */
44 #define PROFF_SMC_BASE PROFF_SMC1_BASE
45 #define PROFF_SMC PROFF_SMC1
46 #define CPM_CR_SMC_PAGE CPM_CR_SMC1_PAGE
47 #define CPM_CR_SMC_SBLOCK CPM_CR_SMC1_SBLOCK
48 #define CMXSMR_MASK (CMXSMR_SMC1|CMXSMR_SMC1CS_MSK)
49 #define CMXSMR_VALUE CMXSMR_SMC1CS_BRG7
51 #elif CONFIG_CONS_INDEX == 2 /* Console on SMC2 */
54 #define PROFF_SMC_BASE PROFF_SMC2_BASE
55 #define PROFF_SMC PROFF_SMC2
56 #define CPM_CR_SMC_PAGE CPM_CR_SMC2_PAGE
57 #define CPM_CR_SMC_SBLOCK CPM_CR_SMC2_SBLOCK
58 #define CMXSMR_MASK (CMXSMR_SMC2|CMXSMR_SMC2CS_MSK)
59 #define CMXSMR_VALUE CMXSMR_SMC2CS_BRG8
63 #error "console not correctly defined"
67 /* map rs_table index to baud rate generator index */
68 static unsigned char brg_map
[] = {
69 6, /* BRG7 for SMC1 */
70 7, /* BRG8 for SMC2 */
71 0, /* BRG1 for SCC1 */
72 1, /* BRG1 for SCC2 */
73 2, /* BRG1 for SCC3 */
74 3, /* BRG1 for SCC4 */
77 int serial_init (void)
79 volatile immap_t
*im
= (immap_t
*)CFG_IMMR
;
81 volatile smc_uart_t
*up
;
82 volatile cbd_t
*tbdf
, *rbdf
;
83 volatile cpm8260_t
*cp
= &(im
->im_cpm
);
86 /* initialize pointers to SMC */
88 sp
= (smc_t
*) &(im
->im_smc
[SMC_INDEX
]);
89 *(ushort
*)(&im
->im_dprambase
[PROFF_SMC_BASE
]) = PROFF_SMC
;
90 up
= (smc_uart_t
*)&im
->im_dprambase
[PROFF_SMC
];
92 /* Disable transmitter/receiver.
94 sp
->smc_smcmr
&= ~(SMCMR_REN
| SMCMR_TEN
);
96 /* NOTE: I/O port pins are set up via the iop_conf_tab[] table */
98 /* Allocate space for two buffer descriptors in the DP ram.
99 * damm: allocating space after the two buffers for rx/tx data
102 dpaddr
= m8260_cpm_dpalloc((2 * sizeof (cbd_t
)) + 2, 16);
104 /* Set the physical address of the host memory buffers in
105 * the buffer descriptors.
107 rbdf
= (cbd_t
*)&im
->im_dprambase
[dpaddr
];
108 rbdf
->cbd_bufaddr
= (uint
) (rbdf
+2);
111 tbdf
->cbd_bufaddr
= ((uint
) (rbdf
+2)) + 1;
114 /* Set up the uart parameters in the parameter ram.
116 up
->smc_rbase
= dpaddr
;
117 up
->smc_tbase
= dpaddr
+sizeof(cbd_t
);
118 up
->smc_rfcr
= CPMFCR_EB
;
119 up
->smc_tfcr
= CPMFCR_EB
;
124 /* Set UART mode, 8 bit, no parity, one stop.
125 * Enable receive and transmit.
127 sp
->smc_smcmr
= smcr_mk_clen(9) | SMCMR_SM_UART
;
129 /* Mask all interrupts and remove anything pending.
134 /* put the SMC channel into NMSI (non multiplexd serial interface)
135 * mode and wire either BRG7 to SMC1 or BRG8 to SMC2 (15-17).
137 im
->im_cpmux
.cmx_smr
= (im
->im_cpmux
.cmx_smr
&~CMXSMR_MASK
)|CMXSMR_VALUE
;
139 /* Set up the baud rate generator.
143 /* Make the first buffer the only buffer.
145 tbdf
->cbd_sc
|= BD_SC_WRAP
;
146 rbdf
->cbd_sc
|= BD_SC_EMPTY
| BD_SC_WRAP
;
148 /* Single character receive.
153 /* Initialize Tx/Rx parameters.
156 while (cp
->cp_cpcr
& CPM_CR_FLG
) /* wait if cp is busy */
159 cp
->cp_cpcr
= mk_cr_cmd(CPM_CR_SMC_PAGE
, CPM_CR_SMC_SBLOCK
,
160 0, CPM_CR_INIT_TRX
) | CPM_CR_FLG
;
162 while (cp
->cp_cpcr
& CPM_CR_FLG
) /* wait if cp is busy */
165 /* Enable transmitter/receiver.
167 sp
->smc_smcmr
|= SMCMR_REN
| SMCMR_TEN
;
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(brg_map
[KGDB_SMC_INDEX
], speed
,
364 CONFIG_KGDB_EXTC_RATE
, CONFIG_KGDB_EXTC_PINSEL
);
366 m8260_cpm_setbrg(brg_map
[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 */