1 /* Minimal serial functions needed to send messages out the serial
2 * port on the MBX console.
4 * The MBX uxes SMC1 for the serial port. We reset the port and use
5 * only the first BD that EPPC-Bug set up as a character FIFO.
7 * Later versions (at least 1.4, maybe earlier) of the MBX EPPC-Bug
8 * use COM1 instead of SMC1 as the console port. This kinda sucks
9 * for the rest of the kernel, so here we force the use of SMC1 again.
11 #include <linux/config.h>
12 #include <linux/types.h>
13 #include <asm/uaccess.h>
14 #include <asm/mpc8xx.h>
15 #include <asm/commproc.h>
18 #define MBX_CSR1 ((volatile u_char *)0xfa100000)
19 #define CSR1_COMEN (u_char)0x02
22 #ifdef TQM_SMC2_CONSOLE
23 #define PROFF_CONS PROFF_SMC2
24 #define CPM_CR_CH_CONS CPM_CR_CH_SMC2
26 static volatile iop8xx_t
*iopp
= (iop8xx_t
*)&(((immap_t
*)IMAP_ADDR
)->im_ioport
);
28 #define PROFF_CONS PROFF_SMC1
29 #define CPM_CR_CH_CONS CPM_CR_CH_SMC1
33 static cpm8xx_t
*cpmp
= (cpm8xx_t
*)&(((immap_t
*)IMAP_ADDR
)->im_cpm
);
36 serial_init(int ignored
, bd_t
*bd
)
39 volatile smc_uart_t
*up
;
40 volatile cbd_t
*tbdf
, *rbdf
;
41 volatile cpm8xx_t
*cp
;
48 sp
= (smc_t
*)&(cp
->cp_smc
[SMC_INDEX
]);
49 up
= (smc_uart_t
*)&cp
->cp_dparam
[PROFF_CONS
];
51 /* Disable transmitter/receiver.
53 sp
->smc_smcmr
&= ~(SMCMR_REN
| SMCMR_TEN
);
56 /* Enable SMC1/2 transceivers.
58 *((volatile uint
*)BCSR1
) &= ~(BCSR1_RS232EN_1
|BCSR1_RS232EN_2
);
63 /* Initialize SMCx and use it for the console port.
68 ((immap_t
*)IMAP_ADDR
)->im_siu_conf
.sc_sdcr
= 1;
70 #ifdef TQM_SMC2_CONSOLE
71 /* Use Port A for SMC2 instead of other functions.
73 iopp
->iop_papar
|= 0x00c0;
74 iopp
->iop_padir
&= ~0x00c0;
75 iopp
->iop_paodr
&= ~0x00c0;
77 /* Use Port B for SMCs instead of other functions.
79 cp
->cp_pbpar
|= 0x00000cc0;
80 cp
->cp_pbdir
&= ~0x00000cc0;
81 cp
->cp_pbodr
&= ~0x00000cc0;
84 /* Allocate space for two buffer descriptors in the DP ram.
85 * For now, this address seems OK, but it may have to
86 * change with newer versions of the firmware.
90 /* Grab a few bytes from the top of memory for SMC FIFOs.
92 memaddr
= (bd
->bi_memsize
- 32) & ~15;
94 /* Set the physical address of the host memory buffers in
95 * the buffer descriptors.
97 rbdf
= (cbd_t
*)&cp
->cp_dpmem
[dpaddr
];
98 rbdf
->cbd_bufaddr
= memaddr
;
101 tbdf
->cbd_bufaddr
= memaddr
+4;
104 /* Set up the uart parameters in the parameter ram.
106 up
->smc_rbase
= dpaddr
;
107 up
->smc_tbase
= dpaddr
+sizeof(cbd_t
);
108 up
->smc_rfcr
= SMC_EB
;
109 up
->smc_tfcr
= SMC_EB
;
111 /* Set UART mode, 8 bit, no parity, one stop.
112 * Enable receive and transmit.
114 sp
->smc_smcmr
= smcr_mk_clen(9) | SMCMR_SM_UART
;
116 /* Mask all interrupts and remove anything pending.
121 /* Set up the baud rate generator.
122 * See 8xx_io/commproc.c for details.
123 * This wires BRG1 to SMC1 and BRG2 to SMC2;
125 cp
->cp_simode
= 0x10000000;
126 ui
= bd
->bi_intfreq
/ 16 / bd
->bi_baudrate
;
127 #ifdef TQM_SMC2_CONSOLE
133 ? (((ui
- 1) << 1) | CPM_BRG_EN
)
134 : ((((ui
/ 16) - 1) << 1) | CPM_BRG_EN
| CPM_BRG_DIV16
);
136 #else /* CONFIG_MBX */
137 if (*MBX_CSR1
& CSR1_COMEN
) {
138 /* COM1 is enabled. Initialize SMC1 and use it for
144 ((immap_t
*)IMAP_ADDR
)->im_siu_conf
.sc_sdcr
= 1;
146 /* Use Port B for SMCs instead of other functions.
148 cp
->cp_pbpar
|= 0x00000cc0;
149 cp
->cp_pbdir
&= ~0x00000cc0;
150 cp
->cp_pbodr
&= ~0x00000cc0;
152 /* Allocate space for two buffer descriptors in the DP ram.
153 * For now, this address seems OK, but it may have to
154 * change with newer versions of the firmware.
158 /* Grab a few bytes from the top of memory. EPPC-Bug isn't
159 * running any more, so we can do this.
161 memaddr
= (bd
->bi_memsize
- 32) & ~15;
163 /* Set the physical address of the host memory buffers in
164 * the buffer descriptors.
166 rbdf
= (cbd_t
*)&cp
->cp_dpmem
[dpaddr
];
167 rbdf
->cbd_bufaddr
= memaddr
;
170 tbdf
->cbd_bufaddr
= memaddr
+4;
173 /* Set up the uart parameters in the parameter ram.
175 up
->smc_rbase
= dpaddr
;
176 up
->smc_tbase
= dpaddr
+sizeof(cbd_t
);
177 up
->smc_rfcr
= SMC_EB
;
178 up
->smc_tfcr
= SMC_EB
;
180 /* Set UART mode, 8 bit, no parity, one stop.
181 * Enable receive and transmit.
183 sp
->smc_smcmr
= smcr_mk_clen(9) | SMCMR_SM_UART
;
185 /* Mask all interrupts and remove anything pending.
190 /* Set up the baud rate generator.
191 * See 8xx_io/commproc.c for details.
193 cp
->cp_simode
= 0x10000000;
195 (((bd
->bi_intfreq
/16) / 9600) << 1) | CPM_BRG_EN
;
197 /* Enable SMC1 for console output.
199 *MBX_CSR1
&= ~CSR1_COMEN
;
202 #endif /* ndef CONFIG_MBX */
203 /* SMCx is used as console port.
205 tbdf
= (cbd_t
*)&cp
->cp_dpmem
[up
->smc_tbase
];
206 rbdf
= (cbd_t
*)&cp
->cp_dpmem
[up
->smc_rbase
];
208 /* Issue a stop transmit, and wait for it.
210 cp
->cp_cpcr
= mk_cr_cmd(CPM_CR_CH_CONS
,
211 CPM_CR_STOP_TX
) | CPM_CR_FLG
;
212 while (cp
->cp_cpcr
& CPM_CR_FLG
);
215 /* Make the first buffer the only buffer.
217 tbdf
->cbd_sc
|= BD_SC_WRAP
;
218 rbdf
->cbd_sc
|= BD_SC_EMPTY
| BD_SC_WRAP
;
220 /* Single character receive.
225 /* Initialize Tx/Rx parameters.
227 cp
->cp_cpcr
= mk_cr_cmd(CPM_CR_CH_CONS
, CPM_CR_INIT_TRX
) | CPM_CR_FLG
;
228 while (cp
->cp_cpcr
& CPM_CR_FLG
);
230 /* Enable transmitter/receiver.
232 sp
->smc_smcmr
|= SMCMR_REN
| SMCMR_TEN
;
240 serial_putc(void *ignored
, const char c
)
242 volatile cbd_t
*tbdf
;
244 volatile smc_uart_t
*up
;
246 up
= (smc_uart_t
*)&cpmp
->cp_dparam
[PROFF_CONS
];
247 tbdf
= (cbd_t
*)&cpmp
->cp_dpmem
[up
->smc_tbase
];
249 /* Wait for last character to go.
251 buf
= (char *)tbdf
->cbd_bufaddr
;
252 while (tbdf
->cbd_sc
& BD_SC_READY
);
255 tbdf
->cbd_datlen
= 1;
256 tbdf
->cbd_sc
|= BD_SC_READY
;
260 serial_getc(void *ignored
)
262 volatile cbd_t
*rbdf
;
264 volatile smc_uart_t
*up
;
267 up
= (smc_uart_t
*)&cpmp
->cp_dparam
[PROFF_CONS
];
268 rbdf
= (cbd_t
*)&cpmp
->cp_dpmem
[up
->smc_rbase
];
270 /* Wait for character to show up.
272 buf
= (char *)rbdf
->cbd_bufaddr
;
273 while (rbdf
->cbd_sc
& BD_SC_EMPTY
);
275 rbdf
->cbd_sc
|= BD_SC_EMPTY
;
281 serial_tstc(void *ignored
)
283 volatile cbd_t
*rbdf
;
284 volatile smc_uart_t
*up
;
286 up
= (smc_uart_t
*)&cpmp
->cp_dparam
[PROFF_CONS
];
287 rbdf
= (cbd_t
*)&cpmp
->cp_dpmem
[up
->smc_rbase
];
289 return(!(rbdf
->cbd_sc
& BD_SC_EMPTY
));