Merge branch 'master' of git://git.denx.de/u-boot-nds32
[platform/kernel/u-boot.git] / board / r360mpi / r360mpi.c
1 /*
2  * (C) Copyright 2001-2003
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8 #include <common.h>
9 #include <config.h>
10 #include <mpc8xx.h>
11 #include <i2c.h>
12
13 #include <commproc.h>
14 #include <command.h>
15 #include <malloc.h>
16
17 #include <linux/types.h>
18 #include <linux/string.h>       /* for strdup */
19
20
21 /*
22  *  Memory Controller Using
23  *
24  *  CS0 - Flash memory          (0x40000000)
25  *  CS1 - FLASH memory          (0x????????)
26  *  CS2 - SDRAM                 (0x00000000)
27  *  CS3 -
28  *  CS4 -
29  *  CS5 -
30  *  CS6 - PCMCIA device
31  *  CS7 - PCMCIA device
32  */
33
34 /* ------------------------------------------------------------------------- */
35
36 #define _not_used_      0xffffffff
37
38 const uint sdram_table[]=
39 {
40         /* single read. (offset 0 in upm RAM) */
41         0x1f07fc04, 0xeeaefc04, 0x11adfc04, 0xefbbbc00,
42         0x1ff77c47,
43
44         /* MRS initialization (offset 5) */
45
46         0x1ff77c34, 0xefeabc34, 0x1fb57c35,
47
48         /* burst read. (offset 8 in upm RAM) */
49         0x1f07fc04, 0xeeaefc04, 0x10adfc04, 0xf0affc00,
50         0xf0affc00, 0xf1affc00, 0xefbbbc00, 0x1ff77c47,
51         _not_used_, _not_used_, _not_used_, _not_used_,
52         _not_used_, _not_used_, _not_used_, _not_used_,
53
54         /* single write. (offset 18 in upm RAM) */
55         0x1f27fc04, 0xeeaebc00, 0x01b93c04, 0x1ff77c47,
56         _not_used_, _not_used_, _not_used_, _not_used_,
57
58         /* burst write. (offset 20 in upm RAM) */
59         0x1f07fc04, 0xeeaebc00, 0x10ad7c00, 0xf0affc00,
60         0xf0affc00, 0xe1bbbc04, 0x1ff77c47, _not_used_,
61         _not_used_, _not_used_, _not_used_, _not_used_,
62         _not_used_, _not_used_, _not_used_, _not_used_,
63
64         /* refresh. (offset 30 in upm RAM) */
65         0x1ff5fc84, 0xfffffc04, 0xfffffc04, 0xfffffc04,
66         0xfffffc84, 0xfffffc07, _not_used_, _not_used_,
67         _not_used_, _not_used_, _not_used_, _not_used_,
68
69         /* exception. (offset 3c in upm RAM) */
70         0x7ffffc07, _not_used_, _not_used_, _not_used_ };
71
72 /* ------------------------------------------------------------------------- */
73
74 /*
75  * Check Board Identity:
76  */
77
78 int checkboard (void)
79 {
80         puts ("Board: R360 MPI Board\n");
81         return 0;
82 }
83
84 /* ------------------------------------------------------------------------- */
85
86 static long int dram_size (long int, long int *, long int);
87
88 /* ------------------------------------------------------------------------- */
89
90 phys_size_t initdram (int board_type)
91 {
92         volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
93         volatile memctl8xx_t *memctl = &immap->im_memctl;
94         long int size8, size9;
95         long int size_b0 = 0;
96         unsigned long reg;
97
98         upmconfig (UPMA, (uint *) sdram_table,
99                            sizeof (sdram_table) / sizeof (uint));
100
101         /*
102          * Preliminary prescaler for refresh (depends on number of
103          * banks): This value is selected for four cycles every 62.4 us
104          * with two SDRAM banks or four cycles every 31.2 us with one
105          * bank. It will be adjusted after memory sizing.
106          */
107         memctl->memc_mptpr = CONFIG_SYS_MPTPR_2BK_8K;
108
109         memctl->memc_mar = 0x00000088;
110
111         /*
112          * Map controller bank 2 to the SDRAM bank at
113          * preliminary address - these have to be modified after the
114          * SDRAM size has been determined.
115          */
116         memctl->memc_or2 = CONFIG_SYS_OR2_PRELIM;
117         memctl->memc_br2 = CONFIG_SYS_BR2_PRELIM;
118
119         memctl->memc_mamr = CONFIG_SYS_MAMR_8COL & (~(MAMR_PTAE));      /* no refresh yet */
120
121         udelay (200);
122
123         /* perform SDRAM initializsation sequence */
124
125         memctl->memc_mcr = 0x80004105;  /* SDRAM bank 0 */
126         udelay (200);
127         memctl->memc_mcr = 0x80004230;  /* SDRAM bank 0 - execute twice */
128         udelay (200);
129
130         memctl->memc_mamr |= MAMR_PTAE; /* enable refresh */
131
132         udelay (1000);
133
134         /*
135          * Check Bank 2 Memory Size for re-configuration
136          *
137          * try 8 column mode
138          */
139         size8 = dram_size (CONFIG_SYS_MAMR_8COL, (long *) SDRAM_BASE2_PRELIM,
140                                            SDRAM_MAX_SIZE);
141
142         udelay (1000);
143
144         /*
145          * try 9 column mode
146          */
147         size9 = dram_size (CONFIG_SYS_MAMR_9COL, (long *) SDRAM_BASE2_PRELIM,
148                                            SDRAM_MAX_SIZE);
149
150         if (size8 < size9) {            /* leave configuration at 9 columns */
151                 size_b0 = size9;
152 /*      debug ("SDRAM Bank 0 in 9 column mode: %ld MB\n", size >> 20);  */
153         } else {                        /* back to 8 columns            */
154                 size_b0 = size8;
155                 memctl->memc_mamr = CONFIG_SYS_MAMR_8COL;
156                 udelay (500);
157 /*      debug ("SDRAM Bank 0 in 8 column mode: %ld MB\n", size >> 20);  */
158         }
159
160         udelay (1000);
161
162         /*
163          * Adjust refresh rate depending on SDRAM type, both banks
164          * For types > 128 MBit leave it at the current (fast) rate
165          */
166         if ((size_b0 < 0x02000000)) {
167                 /* reduce to 15.6 us (62.4 us / quad) */
168                 memctl->memc_mptpr = CONFIG_SYS_MPTPR_2BK_4K;
169                 udelay (1000);
170         }
171
172         /*
173          * Final mapping
174          */
175
176         memctl->memc_or1 = ((-size_b0) & 0xFFFF0000) | CONFIG_SYS_OR_TIMING_SDRAM;
177         memctl->memc_br1 = (CONFIG_SYS_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V;
178
179         /* adjust refresh rate depending on SDRAM type, one bank */
180         reg = memctl->memc_mptpr;
181         reg >>= 1;              /* reduce to CONFIG_SYS_MPTPR_1BK_8K / _4K */
182         memctl->memc_mptpr = reg;
183
184         udelay (10000);
185
186 #ifdef CONFIG_CAN_DRIVER
187         /* Initialize OR3 / BR3 */
188         memctl->memc_or3 = CONFIG_SYS_OR3_CAN;          /* switch GPLB_5 to GPLA_5 */
189         memctl->memc_br3 = CONFIG_SYS_BR3_CAN;
190
191         /* Initialize MBMR */
192         memctl->memc_mbmr = MBMR_GPL_B4DIS;     /* GPL_B4 works as UPWAITB */
193
194         /* Initialize UPMB for CAN: single read */
195         memctl->memc_mdr = 0xFFFFC004;
196         memctl->memc_mcr = 0x0100 | UPMB;
197
198         memctl->memc_mdr = 0x0FFFD004;
199         memctl->memc_mcr = 0x0101 | UPMB;
200
201         memctl->memc_mdr = 0x0FFFC000;
202         memctl->memc_mcr = 0x0102 | UPMB;
203
204         memctl->memc_mdr = 0x3FFFC004;
205         memctl->memc_mcr = 0x0103 | UPMB;
206
207         memctl->memc_mdr = 0xFFFFDC05;
208         memctl->memc_mcr = 0x0104 | UPMB;
209
210         /* Initialize UPMB for CAN: single write */
211         memctl->memc_mdr = 0xFFFCC004;
212         memctl->memc_mcr = 0x0118 | UPMB;
213
214         memctl->memc_mdr = 0xCFFCD004;
215         memctl->memc_mcr = 0x0119 | UPMB;
216
217         memctl->memc_mdr = 0x0FFCC000;
218         memctl->memc_mcr = 0x011A | UPMB;
219
220         memctl->memc_mdr = 0x7FFCC004;
221         memctl->memc_mcr = 0x011B | UPMB;
222
223         memctl->memc_mdr = 0xFFFDCC05;
224         memctl->memc_mcr = 0x011C | UPMB;
225 #endif
226
227         return (size_b0);
228 }
229
230 /* ------------------------------------------------------------------------- */
231
232 /*
233  * Check memory range for valid RAM. A simple memory test determines
234  * the actually available RAM size between addresses `base' and
235  * `base + maxsize'. Some (not all) hardware errors are detected:
236  * - short between address lines
237  * - short between data lines
238  */
239
240 static long int dram_size (long int mamr_value,
241                            long int *base, long int maxsize)
242 {
243         volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
244         volatile memctl8xx_t *memctl = &immap->im_memctl;
245
246         memctl->memc_mamr = mamr_value;
247
248         return (get_ram_size(base, maxsize));
249 }
250
251 /* ------------------------------------------------------------------------- */
252
253 void r360_i2c_lcd_write (uchar data0, uchar data1)
254 {
255         if (i2c_write (CONFIG_SYS_I2C_LCD_ADDR, data0, 1, &data1, 1)) {
256                 printf("Can't write lcd data 0x%02X 0x%02X.\n", data0, data1);
257         }
258 }
259
260 /* ------------------------------------------------------------------------- */
261
262 /*-----------------------------------------------------------------------
263  * Keyboard Controller
264  */
265
266 /* Number of bytes returned from Keyboard Controller */
267 #define KEYBD_KEY_MAX   16                              /* maximum key number */
268 #define KEYBD_DATALEN   ((KEYBD_KEY_MAX + 7) / 8)       /* normal key scan data */
269
270 static uchar *key_match (uchar *);
271
272 int misc_init_r (void)
273 {
274         char kbd_data[KEYBD_DATALEN];
275         char keybd_env[2 * KEYBD_DATALEN + 1];
276         char *str;
277         int i;
278
279         i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
280
281         i2c_read (CONFIG_SYS_I2C_KEY_ADDR, 0, 0, (uchar *)kbd_data, KEYBD_DATALEN);
282
283         for (i = 0; i < KEYBD_DATALEN; ++i) {
284                 sprintf (keybd_env + i + i, "%02X", kbd_data[i]);
285         }
286         setenv ("keybd", keybd_env);
287
288         str = strdup ((char *)key_match ((uchar *)keybd_env));  /* decode keys */
289
290 #ifdef CONFIG_PREBOOT   /* automatically configure "preboot" command on key match */
291         setenv ("preboot", str);        /* set or delete definition */
292 #endif /* CONFIG_PREBOOT */
293         if (str != NULL) {
294                 free (str);
295         }
296
297         return (0);
298 }
299
300 /*-----------------------------------------------------------------------
301  * Check if pressed key(s) match magic sequence,
302  * and return the command string associated with that key(s).
303  *
304  * If no key press was decoded, NULL is returned.
305  *
306  * Note: the first character of the argument will be overwritten with
307  * the "magic charcter code" of the decoded key(s), or '\0'.
308  *
309  *
310  * Note: the string points to static environment data and must be
311  * saved before you call any function that modifies the environment.
312  */
313 #ifdef CONFIG_PREBOOT
314
315 static uchar kbd_magic_prefix[] = "key_magic";
316 static uchar kbd_command_prefix[] = "key_cmd";
317
318 static uchar *key_match (uchar * kbd_str)
319 {
320         uchar magic[sizeof (kbd_magic_prefix) + 1];
321         uchar cmd_name[sizeof (kbd_command_prefix) + 1];
322         uchar *str, *suffix;
323         uchar *kbd_magic_keys;
324         char *cmd;
325
326         /*
327          * The following string defines the characters that can pe appended
328          * to "key_magic" to form the names of environment variables that
329          * hold "magic" key codes, i. e. such key codes that can cause
330          * pre-boot actions. If the string is empty (""), then only
331          * "key_magic" is checked (old behaviour); the string "125" causes
332          * checks for "key_magic1", "key_magic2" and "key_magic5", etc.
333          */
334         if ((kbd_magic_keys = (uchar *)getenv ("magic_keys")) != NULL) {
335                 /* loop over all magic keys;
336                  * use '\0' suffix in case of empty string
337                  */
338                 for (suffix = kbd_magic_keys;
339                      *suffix || suffix == kbd_magic_keys;
340                      ++suffix) {
341                         sprintf ((char *)magic, "%s%c", kbd_magic_prefix, *suffix);
342
343 #if 0
344                         printf ("### Check magic \"%s\"\n", magic);
345 #endif
346
347                         if ((str = (uchar *)getenv ((char *)magic)) != 0) {
348
349 #if 0
350                                 printf ("### Compare \"%s\" \"%s\"\n",
351                                         kbd_str, str);
352 #endif
353                                 if (strcmp ((char *)kbd_str, (char *)str) == 0) {
354                                         sprintf ((char *)cmd_name, "%s%c",
355                                                  kbd_command_prefix,
356                                                  *suffix);
357
358                                         if ((cmd = getenv ((char *)cmd_name)) != 0) {
359 #if 0
360                                                 printf ("### Set PREBOOT to $(%s): \"%s\"\n",
361                                                         cmd_name, cmd);
362 #endif
363                                                 return ((uchar *)cmd);
364                                         }
365                                 }
366                         }
367                 }
368         }
369 #if 0
370         printf ("### Delete PREBOOT\n");
371 #endif
372         *kbd_str = '\0';
373         return (NULL);
374 }
375 #endif  /* CONFIG_PREBOOT */
376
377 /* Read Keyboard status */
378 int do_kbd (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
379 {
380         uchar kbd_data[KEYBD_DATALEN];
381         uchar keybd_env[2 * KEYBD_DATALEN + 1];
382         int i;
383
384         i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
385
386         /* Read keys */
387         i2c_read (CONFIG_SYS_I2C_KEY_ADDR, 0, 0, kbd_data, KEYBD_DATALEN);
388
389         puts ("Keys:");
390         for (i = 0; i < KEYBD_DATALEN; ++i) {
391                 sprintf ((char *)(keybd_env + i + i), "%02X", kbd_data[i]);
392                 printf (" %02x", kbd_data[i]);
393         }
394         putc ('\n');
395         setenv ("keybd", (char *)keybd_env);
396         return 0;
397 }
398
399 U_BOOT_CMD(
400         kbd,    1,      1,      do_kbd,
401         "read keyboard status",
402         ""
403 );