1 /* Minimal serial functions needed to send messages out the serial
4 #include <linux/types.h>
5 #include <asm/mpc8260.h>
7 #include <asm/immap_cpm2.h>
10 extern char *params
[];
12 static u_char cons_hold
[128], *sgptr
;
13 static int cons_hold_cnt
;
15 /* If defined, enables serial console. The value (1 through 4)
16 * should designate which SCC is used, but this isn't complete. Only
17 * SCC1 is known to work at this time.
18 * We're only linked if SERIAL_CPM_CONSOLE=y, so we only need to test
21 #ifdef CONFIG_SERIAL_CPM_SCC1
26 serial_init(int ignored
, bd_t
*bd
)
30 volatile scc_uart_t
*sup
;
33 volatile smc_uart_t
*up
;
35 volatile cbd_t
*tbdf
, *rbdf
;
36 volatile cpm2_map_t
*ip
;
37 volatile iop_cpm2_t
*io
;
38 volatile cpm_cpm2_t
*cp
;
41 ip
= (cpm2_map_t
*)CPM_MAP_ADDR
;
47 cp
->cp_cpcr
= (CPM_CR_RST
| CPM_CR_FLG
);
51 while (cp
->cp_cpcr
& CPM_CR_FLG
);
54 /* Enable the RS-232 transceivers.
56 *(volatile uint
*)(BCSR_ADDR
+ 4) &=
57 ~(BCSR1_RS232_EN1
| BCSR1_RS232_EN2
);
61 sccp
= (scc_t
*)&(ip
->im_scc
[SCC_CONSOLE
-1]);
62 sup
= (scc_uart_t
*)&ip
->im_dprambase
[PROFF_SCC1
+ ((SCC_CONSOLE
-1) << 8)];
63 sccp
->scc_sccm
&= ~(UART_SCCM_TX
| UART_SCCM_RX
);
64 sccp
->scc_gsmrl
&= ~(SCC_GSMRL_ENR
| SCC_GSMRL_ENT
);
66 /* Use Port D for SCC1 instead of other functions.
68 io
->iop_ppard
|= 0x00000003;
69 io
->iop_psord
&= ~0x00000001; /* Rx */
70 io
->iop_psord
|= 0x00000002; /* Tx */
71 io
->iop_pdird
&= ~0x00000001; /* Rx */
72 io
->iop_pdird
|= 0x00000002; /* Tx */
75 sp
= (smc_t
*)&(ip
->im_smc
[0]);
76 *(ushort
*)(&ip
->im_dprambase
[PROFF_SMC1_BASE
]) = PROFF_SMC1
;
77 up
= (smc_uart_t
*)&ip
->im_dprambase
[PROFF_SMC1
];
79 /* Disable transmitter/receiver.
81 sp
->smc_smcmr
&= ~(SMCMR_REN
| SMCMR_TEN
);
83 /* Use Port D for SMC1 instead of other functions.
85 io
->iop_ppard
|= 0x00c00000;
86 io
->iop_pdird
|= 0x00400000;
87 io
->iop_pdird
&= ~0x00800000;
88 io
->iop_psord
&= ~0x00c00000;
91 /* Allocate space for two buffer descriptors in the DP ram.
92 * For now, this address seems OK, but it may have to
93 * change with newer versions of the firmware.
97 /* Grab a few bytes from the top of memory.
99 memaddr
= (bd
->bi_memsize
- 256) & ~15;
101 /* Set the physical address of the host memory buffers in
102 * the buffer descriptors.
104 rbdf
= (cbd_t
*)&ip
->im_dprambase
[dpaddr
];
105 rbdf
->cbd_bufaddr
= memaddr
;
108 tbdf
->cbd_bufaddr
= memaddr
+128;
111 /* Set up the uart parameters in the parameter ram.
114 sup
->scc_genscc
.scc_rbase
= dpaddr
;
115 sup
->scc_genscc
.scc_tbase
= dpaddr
+ sizeof(cbd_t
);
117 /* Set up the uart parameters in the
120 sup
->scc_genscc
.scc_rfcr
= CPMFCR_GBL
| CPMFCR_EB
;
121 sup
->scc_genscc
.scc_tfcr
= CPMFCR_GBL
| CPMFCR_EB
;
123 sup
->scc_genscc
.scc_mrblr
= 128;
133 sup
->scc_char1
= 0x8000;
134 sup
->scc_char2
= 0x8000;
135 sup
->scc_char3
= 0x8000;
136 sup
->scc_char4
= 0x8000;
137 sup
->scc_char5
= 0x8000;
138 sup
->scc_char6
= 0x8000;
139 sup
->scc_char7
= 0x8000;
140 sup
->scc_char8
= 0x8000;
141 sup
->scc_rccm
= 0xc0ff;
143 /* Send the CPM an initialize command.
145 cp
->cp_cpcr
= mk_cr_cmd(CPM_CR_SCC1_PAGE
, CPM_CR_SCC1_SBLOCK
, 0,
146 CPM_CR_INIT_TRX
) | CPM_CR_FLG
;
147 while (cp
->cp_cpcr
& CPM_CR_FLG
);
149 /* Set UART mode, 8 bit, no parity, one stop.
150 * Enable receive and transmit.
154 (SCC_GSMRL_MODE_UART
| SCC_GSMRL_TDCR_16
| SCC_GSMRL_RDCR_16
);
156 /* Disable all interrupts and clear all pending
160 sccp
->scc_scce
= 0xffff;
161 sccp
->scc_dsr
= 0x7e7e;
162 sccp
->scc_psmr
= 0x3000;
164 /* Wire BRG1 to SCC1. The console driver will take care of
167 ip
->im_cpmux
.cmx_scr
= 0;
169 up
->smc_rbase
= dpaddr
;
170 up
->smc_tbase
= dpaddr
+sizeof(cbd_t
);
171 up
->smc_rfcr
= CPMFCR_EB
;
172 up
->smc_tfcr
= CPMFCR_EB
;
179 /* Set UART mode, 8 bit, no parity, one stop.
180 * Enable receive and transmit.
182 sp
->smc_smcmr
= smcr_mk_clen(9) | SMCMR_SM_UART
;
184 /* Mask all interrupts and remove anything pending.
189 /* Set up the baud rate generator.
191 ip
->im_cpmux
.cmx_smr
= 0;
194 /* The baud rate divisor needs to be coordinated with clk_8260().
197 (((bd
->bi_brgfreq
/16) / bd
->bi_baudrate
) << 1) |
200 /* Make the first buffer the only buffer.
202 tbdf
->cbd_sc
|= BD_SC_WRAP
;
203 rbdf
->cbd_sc
|= BD_SC_EMPTY
| BD_SC_WRAP
;
205 /* Initialize Tx/Rx parameters.
208 sccp
->scc_gsmrl
|= (SCC_GSMRL_ENR
| SCC_GSMRL_ENT
);
210 cp
->cp_cpcr
= mk_cr_cmd(CPM_CR_SMC1_PAGE
, CPM_CR_SMC1_SBLOCK
, 0, CPM_CR_INIT_TRX
) | CPM_CR_FLG
;
211 while (cp
->cp_cpcr
& CPM_CR_FLG
);
213 /* Enable transmitter/receiver.
215 sp
->smc_smcmr
|= SMCMR_REN
| SMCMR_TEN
;
224 serial_readbuf(u_char
*cbuf
)
226 volatile cbd_t
*rbdf
;
229 volatile scc_uart_t
*sup
;
231 volatile smc_uart_t
*up
;
233 volatile cpm2_map_t
*ip
;
236 ip
= (cpm2_map_t
*)CPM_MAP_ADDR
;
239 sup
= (scc_uart_t
*)&ip
->im_dprambase
[PROFF_SCC1
+ ((SCC_CONSOLE
-1) << 8)];
240 rbdf
= (cbd_t
*)&ip
->im_dprambase
[sup
->scc_genscc
.scc_rbase
];
242 up
= (smc_uart_t
*)&(ip
->im_dprambase
[PROFF_SMC1
]);
243 rbdf
= (cbd_t
*)&ip
->im_dprambase
[up
->smc_rbase
];
246 /* Wait for character to show up.
248 buf
= (char *)rbdf
->cbd_bufaddr
;
249 while (rbdf
->cbd_sc
& BD_SC_EMPTY
);
250 nc
= rbdf
->cbd_datlen
;
253 rbdf
->cbd_sc
|= BD_SC_EMPTY
;
259 serial_putc(void *ignored
, const char c
)
261 volatile cbd_t
*tbdf
;
264 volatile scc_uart_t
*sup
;
266 volatile smc_uart_t
*up
;
268 volatile cpm2_map_t
*ip
;
270 ip
= (cpm2_map_t
*)CPM_MAP_ADDR
;
272 sup
= (scc_uart_t
*)&ip
->im_dprambase
[PROFF_SCC1
+ ((SCC_CONSOLE
-1) << 8)];
273 tbdf
= (cbd_t
*)&ip
->im_dprambase
[sup
->scc_genscc
.scc_tbase
];
275 up
= (smc_uart_t
*)&(ip
->im_dprambase
[PROFF_SMC1
]);
276 tbdf
= (cbd_t
*)&ip
->im_dprambase
[up
->smc_tbase
];
279 /* Wait for last character to go.
281 buf
= (char *)tbdf
->cbd_bufaddr
;
282 while (tbdf
->cbd_sc
& BD_SC_READY
);
285 tbdf
->cbd_datlen
= 1;
286 tbdf
->cbd_sc
|= BD_SC_READY
;
290 serial_getc(void *ignored
)
294 if (cons_hold_cnt
<= 0) {
295 cons_hold_cnt
= serial_readbuf(cons_hold
);
305 serial_tstc(void *ignored
)
307 volatile cbd_t
*rbdf
;
309 volatile scc_uart_t
*sup
;
311 volatile smc_uart_t
*up
;
313 volatile cpm2_map_t
*ip
;
315 ip
= (cpm2_map_t
*)CPM_MAP_ADDR
;
317 sup
= (scc_uart_t
*)&ip
->im_dprambase
[PROFF_SCC1
+ ((SCC_CONSOLE
-1) << 8)];
318 rbdf
= (cbd_t
*)&ip
->im_dprambase
[sup
->scc_genscc
.scc_rbase
];
320 up
= (smc_uart_t
*)&(ip
->im_dprambase
[PROFF_SMC1
]);
321 rbdf
= (cbd_t
*)&ip
->im_dprambase
[up
->smc_rbase
];
324 return(!(rbdf
->cbd_sc
& BD_SC_EMPTY
));