]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/rbc823/kbd.c
imported Freescale specific U-Boot additions for i.MX28,... release L2.6.31_10.08.01
[karo-tx-uboot.git] / board / rbc823 / kbd.c
1 /*
2  * (C) Copyright 2000
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
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.
12  *
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.
17  *
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,
21  * MA 02111-1307 USA
22  */
23
24 /* Modified by Udi Finkelstein
25  *
26  * This file includes communication routines for SMC1 that can run even if
27  * SMC2 have already been initialized.
28  */
29
30 #include <common.h>
31 #include <watchdog.h>
32 #include <commproc.h>
33 #include <stdio_dev.h>
34 #include <lcd.h>
35
36 DECLARE_GLOBAL_DATA_PTR;
37
38 #define SMC_INDEX       0
39 #define PROFF_SMC       PROFF_SMC1
40 #define CPM_CR_CH_SMC   CPM_CR_CH_SMC1
41
42 #define RBC823_KBD_BAUDRATE     38400
43 #define CPM_KEYBOARD_BASE       0x1000
44 /*
45  * Minimal serial functions needed to use one of the SMC ports
46  * as serial console interface.
47  */
48
49 void smc1_setbrg (void)
50 {
51         volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
52         volatile cpm8xx_t *cp = &(im->im_cpm);
53
54         /* Set up the baud rate generator.
55          * See 8xx_io/commproc.c for details.
56          *
57          * Wire BRG2 to SMC1, BRG1 to SMC2
58          */
59
60         cp->cp_simode = 0x00001000;
61
62         cp->cp_brgc2 =
63                 (((gd->cpu_clk / 16 / RBC823_KBD_BAUDRATE)-1) << 1) | CPM_BRG_EN;
64 }
65
66 int smc1_init (void)
67 {
68         volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
69         volatile smc_t *sp;
70         volatile smc_uart_t *up;
71         volatile cbd_t *tbdf, *rbdf;
72         volatile cpm8xx_t *cp = &(im->im_cpm);
73         uint    dpaddr;
74
75         /* initialize pointers to SMC */
76
77         sp = (smc_t *) &(cp->cp_smc[SMC_INDEX]);
78         up = (smc_uart_t *) &cp->cp_dparam[PROFF_SMC];
79
80         /* Disable transmitter/receiver.
81         */
82         sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
83
84         /* Enable SDMA.
85         */
86         im->im_siu_conf.sc_sdcr = 1;
87
88         /* clear error conditions */
89 #ifdef  CONFIG_SYS_SDSR
90         im->im_sdma.sdma_sdsr = CONFIG_SYS_SDSR;
91 #else
92         im->im_sdma.sdma_sdsr = 0x83;
93 #endif
94
95         /* clear SDMA interrupt mask */
96 #ifdef  CONFIG_SYS_SDMR
97         im->im_sdma.sdma_sdmr = CONFIG_SYS_SDMR;
98 #else
99         im->im_sdma.sdma_sdmr = 0x00;
100 #endif
101
102         /* Use Port B for SMC1 instead of other functions.
103         */
104         cp->cp_pbpar |=  0x000000c0;
105         cp->cp_pbdir &= ~0x000000c0;
106         cp->cp_pbodr &= ~0x000000c0;
107
108         /* Set the physical address of the host memory buffers in
109          * the buffer descriptors.
110          */
111
112 #ifdef CONFIG_SYS_ALLOC_DPRAM
113         dpaddr = dpram_alloc_align (sizeof(cbd_t)*2 + 2, 8) ;
114 #else
115         dpaddr = CPM_KEYBOARD_BASE ;
116 #endif
117
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
122          */
123
124         rbdf = (cbd_t *)&cp->cp_dpmem[dpaddr];
125         rbdf->cbd_bufaddr = (uint) (rbdf+2);
126         rbdf->cbd_sc = 0;
127         tbdf = rbdf + 1;
128         tbdf->cbd_bufaddr = ((uint) (rbdf+2)) + 1;
129         tbdf->cbd_sc = 0;
130
131         /* Set up the uart parameters in the parameter ram.
132         */
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;
137
138         /* Set UART mode, 8 bit, no parity, one stop.
139          * Enable receive and transmit.
140          */
141         sp->smc_smcmr = smcr_mk_clen(9) |  SMCMR_SM_UART;
142
143         /* Mask all interrupts and remove anything pending.
144         */
145         sp->smc_smcm = 0;
146         sp->smc_smce = 0xff;
147
148         /* Set up the baud rate generator.
149         */
150         smc1_setbrg ();
151
152         /* Make the first buffer the only buffer.
153         */
154         tbdf->cbd_sc |= BD_SC_WRAP;
155         rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP;
156
157         /* Single character receive.
158         */
159         up->smc_mrblr = 1;
160         up->smc_maxidl = 0;
161
162         /* Initialize Tx/Rx parameters.
163         */
164
165         while (cp->cp_cpcr & CPM_CR_FLG)  /* wait if cp is busy */
166           ;
167
168         cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC, CPM_CR_INIT_TRX) | CPM_CR_FLG;
169
170         while (cp->cp_cpcr & CPM_CR_FLG)  /* wait if cp is busy */
171           ;
172
173         /* Enable transmitter/receiver.
174         */
175         sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN;
176
177         return (0);
178 }
179
180 void smc1_putc(const char c)
181 {
182         volatile cbd_t          *tbdf;
183         volatile char           *buf;
184         volatile smc_uart_t     *up;
185         volatile immap_t        *im = (immap_t *)CONFIG_SYS_IMMR;
186         volatile cpm8xx_t       *cpmp = &(im->im_cpm);
187
188         up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_SMC];
189
190         tbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_tbase];
191
192         /* Wait for last character to go.
193         */
194
195         buf = (char *)tbdf->cbd_bufaddr;
196
197         *buf = c;
198         tbdf->cbd_datlen = 1;
199         tbdf->cbd_sc |= BD_SC_READY;
200         __asm__("eieio");
201
202         while (tbdf->cbd_sc & BD_SC_READY) {
203                 WATCHDOG_RESET ();
204                 __asm__("eieio");
205         }
206 }
207
208 int smc1_getc(void)
209 {
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);
215         unsigned char           c;
216
217         up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_SMC];
218
219         rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase];
220
221         /* Wait for character to show up.
222         */
223         buf = (unsigned char *)rbdf->cbd_bufaddr;
224
225         while (rbdf->cbd_sc & BD_SC_EMPTY)
226                 WATCHDOG_RESET ();
227
228         c = *buf;
229         rbdf->cbd_sc |= BD_SC_EMPTY;
230
231         return(c);
232 }
233
234 int smc1_tstc(void)
235 {
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);
240
241         up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_SMC];
242
243         rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase];
244
245         return(!(rbdf->cbd_sc & BD_SC_EMPTY));
246 }
247
248 /* search for keyboard and register it if found */
249 int drv_keyboard_init(void)
250 {
251         int error = 0;
252         struct stdio_dev kbd_dev;
253
254         if (0) {
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;
259                 kbd_dev.putc = NULL;
260                 kbd_dev.puts = NULL;
261                 kbd_dev.getc = smc1_getc;
262                 kbd_dev.tstc = smc1_tstc;
263                 error = stdio_register (&kbd_dev);
264         } else {
265                 lcd_is_enabled = 0;
266                 lcd_disable();
267         }
268         return error;
269 }