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,
24 /* Modified by Udi Finkelstein
26 * This file includes communication routines for SMC1 that can run even if
27 * SMC2 have already been initialized.
33 #include <stdio_dev.h>
36 DECLARE_GLOBAL_DATA_PTR
;
39 #define PROFF_SMC PROFF_SMC1
40 #define CPM_CR_CH_SMC CPM_CR_CH_SMC1
42 #define RBC823_KBD_BAUDRATE 38400
43 #define CPM_KEYBOARD_BASE 0x1000
45 * Minimal serial functions needed to use one of the SMC ports
46 * as serial console interface.
49 void smc1_setbrg (void)
51 volatile immap_t
*im
= (immap_t
*)CONFIG_SYS_IMMR
;
52 volatile cpm8xx_t
*cp
= &(im
->im_cpm
);
54 /* Set up the baud rate generator.
55 * See 8xx_io/commproc.c for details.
57 * Wire BRG2 to SMC1, BRG1 to SMC2
60 cp
->cp_simode
= 0x00001000;
63 (((gd
->cpu_clk
/ 16 / RBC823_KBD_BAUDRATE
)-1) << 1) | CPM_BRG_EN
;
68 volatile immap_t
*im
= (immap_t
*)CONFIG_SYS_IMMR
;
70 volatile smc_uart_t
*up
;
71 volatile cbd_t
*tbdf
, *rbdf
;
72 volatile cpm8xx_t
*cp
= &(im
->im_cpm
);
75 /* initialize pointers to SMC */
77 sp
= (smc_t
*) &(cp
->cp_smc
[SMC_INDEX
]);
78 up
= (smc_uart_t
*) &cp
->cp_dparam
[PROFF_SMC
];
80 /* Disable transmitter/receiver.
82 sp
->smc_smcmr
&= ~(SMCMR_REN
| SMCMR_TEN
);
86 im
->im_siu_conf
.sc_sdcr
= 1;
88 /* clear error conditions */
89 #ifdef CONFIG_SYS_SDSR
90 im
->im_sdma
.sdma_sdsr
= CONFIG_SYS_SDSR
;
92 im
->im_sdma
.sdma_sdsr
= 0x83;
95 /* clear SDMA interrupt mask */
96 #ifdef CONFIG_SYS_SDMR
97 im
->im_sdma
.sdma_sdmr
= CONFIG_SYS_SDMR
;
99 im
->im_sdma
.sdma_sdmr
= 0x00;
102 /* Use Port B for SMC1 instead of other functions.
104 cp
->cp_pbpar
|= 0x000000c0;
105 cp
->cp_pbdir
&= ~0x000000c0;
106 cp
->cp_pbodr
&= ~0x000000c0;
108 /* Set the physical address of the host memory buffers in
109 * the buffer descriptors.
112 #ifdef CONFIG_SYS_ALLOC_DPRAM
113 dpaddr
= dpram_alloc_align (sizeof(cbd_t
)*2 + 2, 8) ;
115 dpaddr
= CPM_KEYBOARD_BASE
;
118 /* Allocate space for two buffer descriptors in the DP ram.
119 * For now, this address seems OK, but it may have to
120 * change with newer versions of the firmware.
121 * damm: allocating space after the two buffers for rx/tx data
124 rbdf
= (cbd_t
*)&cp
->cp_dpmem
[dpaddr
];
125 rbdf
->cbd_bufaddr
= (uint
) (rbdf
+2);
128 tbdf
->cbd_bufaddr
= ((uint
) (rbdf
+2)) + 1;
131 /* Set up the uart parameters in the parameter ram.
133 up
->smc_rbase
= dpaddr
;
134 up
->smc_tbase
= dpaddr
+sizeof(cbd_t
);
135 up
->smc_rfcr
= SMC_EB
;
136 up
->smc_tfcr
= SMC_EB
;
138 /* Set UART mode, 8 bit, no parity, one stop.
139 * Enable receive and transmit.
141 sp
->smc_smcmr
= smcr_mk_clen(9) | SMCMR_SM_UART
;
143 /* Mask all interrupts and remove anything pending.
148 /* Set up the baud rate generator.
152 /* Make the first buffer the only buffer.
154 tbdf
->cbd_sc
|= BD_SC_WRAP
;
155 rbdf
->cbd_sc
|= BD_SC_EMPTY
| BD_SC_WRAP
;
157 /* Single character receive.
162 /* Initialize Tx/Rx parameters.
165 while (cp
->cp_cpcr
& CPM_CR_FLG
) /* wait if cp is busy */
168 cp
->cp_cpcr
= mk_cr_cmd(CPM_CR_CH_SMC
, CPM_CR_INIT_TRX
) | CPM_CR_FLG
;
170 while (cp
->cp_cpcr
& CPM_CR_FLG
) /* wait if cp is busy */
173 /* Enable transmitter/receiver.
175 sp
->smc_smcmr
|= SMCMR_REN
| SMCMR_TEN
;
180 void smc1_putc(const char c
)
182 volatile cbd_t
*tbdf
;
184 volatile smc_uart_t
*up
;
185 volatile immap_t
*im
= (immap_t
*)CONFIG_SYS_IMMR
;
186 volatile cpm8xx_t
*cpmp
= &(im
->im_cpm
);
188 up
= (smc_uart_t
*)&cpmp
->cp_dparam
[PROFF_SMC
];
190 tbdf
= (cbd_t
*)&cpmp
->cp_dpmem
[up
->smc_tbase
];
192 /* Wait for last character to go.
195 buf
= (char *)tbdf
->cbd_bufaddr
;
198 tbdf
->cbd_datlen
= 1;
199 tbdf
->cbd_sc
|= BD_SC_READY
;
202 while (tbdf
->cbd_sc
& BD_SC_READY
) {
210 volatile cbd_t
*rbdf
;
211 volatile unsigned char *buf
;
212 volatile smc_uart_t
*up
;
213 volatile immap_t
*im
= (immap_t
*)CONFIG_SYS_IMMR
;
214 volatile cpm8xx_t
*cpmp
= &(im
->im_cpm
);
217 up
= (smc_uart_t
*)&cpmp
->cp_dparam
[PROFF_SMC
];
219 rbdf
= (cbd_t
*)&cpmp
->cp_dpmem
[up
->smc_rbase
];
221 /* Wait for character to show up.
223 buf
= (unsigned char *)rbdf
->cbd_bufaddr
;
225 while (rbdf
->cbd_sc
& BD_SC_EMPTY
)
229 rbdf
->cbd_sc
|= BD_SC_EMPTY
;
236 volatile cbd_t
*rbdf
;
237 volatile smc_uart_t
*up
;
238 volatile immap_t
*im
= (immap_t
*)CONFIG_SYS_IMMR
;
239 volatile cpm8xx_t
*cpmp
= &(im
->im_cpm
);
241 up
= (smc_uart_t
*)&cpmp
->cp_dparam
[PROFF_SMC
];
243 rbdf
= (cbd_t
*)&cpmp
->cp_dpmem
[up
->smc_rbase
];
245 return(!(rbdf
->cbd_sc
& BD_SC_EMPTY
));
248 /* search for keyboard and register it if found */
249 int drv_keyboard_init(void)
252 struct stdio_dev kbd_dev
;
255 /* register the keyboard */
256 memset (&kbd_dev
, 0, sizeof(struct stdio_dev
));
257 strcpy(kbd_dev
.name
, "kbd");
258 kbd_dev
.flags
= DEV_FLAGS_INPUT
| DEV_FLAGS_SYSTEM
;
261 kbd_dev
.getc
= smc1_getc
;
262 kbd_dev
.tstc
= smc1_tstc
;
263 error
= stdio_register (&kbd_dev
);