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