This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / arch / frv / kernel / setup.c
1 /* setup.c: FRV specific setup
2  *
3  * Copyright (C) 2003-5 Red Hat, Inc. All Rights Reserved.
4  * Written by David Howells (dhowells@redhat.com)
5  * - Derived from arch/m68k/kernel/setup.c
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version
10  * 2 of the License, or (at your option) any later version.
11  */
12
13 #include <linux/config.h>
14 #include <linux/version.h>
15 #include <linux/kernel.h>
16 #include <linux/sched.h>
17 #include <linux/delay.h>
18 #include <linux/interrupt.h>
19 #include <linux/fs.h>
20 #include <linux/mm.h>
21 #include <linux/fb.h>
22 #include <linux/console.h>
23 #include <linux/genhd.h>
24 #include <linux/errno.h>
25 #include <linux/string.h>
26 #include <linux/major.h>
27 #include <linux/bootmem.h>
28 #include <linux/highmem.h>
29 #include <linux/seq_file.h>
30 #include <linux/serial.h>
31 #include <linux/serial_core.h>
32 #include <linux/serial_reg.h>
33
34 #include <asm/setup.h>
35 #include <asm/serial.h>
36 #include <asm/irq.h>
37 #include <asm/sections.h>
38 #include <asm/pgalloc.h>
39 #include <asm/busctl-regs.h>
40 #include <asm/serial-regs.h>
41 #include <asm/timer-regs.h>
42 #include <asm/irc-regs.h>
43 #include <asm/spr-regs.h>
44 #include <asm/mb-regs.h>
45 #include <asm/mb93493-regs.h>
46 #include <asm/gdb-stub.h>
47 #include <asm/irq-routing.h>
48 #include <asm/io.h>
49
50 #ifdef CONFIG_BLK_DEV_INITRD
51 #include <linux/blk.h>
52 #include <asm/pgtable.h>
53 #endif
54
55 #include "local.h"
56
57 #ifdef CONFIG_MB93090_MB00
58 static void __init mb93090_display(void);
59 #endif
60 #ifdef CONFIG_MMU
61 static void __init setup_linux_memory(void);
62 #else
63 static void __init setup_uclinux_memory(void);
64 #endif
65
66 #ifdef CONFIG_CONSOLE
67 extern struct consw *conswitchp;
68 #ifdef CONFIG_FRAMEBUFFER
69 extern struct consw fb_con;
70 #endif
71 #endif
72
73 #ifdef CONFIG_MB93090_MB00
74 static char __initdata mb93090_banner[] = "FJ/RH FR-V Linux";
75 static char __initdata mb93090_version[] = UTS_RELEASE;
76
77 int __nongprelbss mb93090_mb00_detected;
78 #endif
79
80 const char __frv_unknown_system[] = "unknown";
81 const char __frv_mb93091_cb10[] = "mb93091-cb10";
82 const char __frv_mb93091_cb11[] = "mb93091-cb11";
83 const char __frv_mb93091_cb30[] = "mb93091-cb30";
84 const char __frv_mb93091_cb41[] = "mb93091-cb41";
85 const char __frv_mb93091_cb60[] = "mb93091-cb60";
86 const char __frv_mb93091_cb70[] = "mb93091-cb70";
87 const char __frv_mb93091_cb451[] = "mb93091-cb451";
88 const char __frv_mb93090_mb00[] = "mb93090-mb00";
89
90 const char __frv_mb93493[] = "mb93493";
91
92 const char __frv_mb93093[] = "mb93093";
93
94 static const char *__nongprelbss cpu_series;
95 static const char *__nongprelbss cpu_core;
96 static const char *__nongprelbss cpu_silicon;
97 static const char *__nongprelbss cpu_mmu;
98 static const char *__nongprelbss cpu_system;
99 static const char *__nongprelbss cpu_board1;
100 static const char *__nongprelbss cpu_board2;
101
102 static unsigned long __nongprelbss cpu_psr_all;
103 static unsigned long __nongprelbss cpu_hsr0_all;
104
105 unsigned long __nongprelbss pdm_suspend_mode;
106
107 unsigned long __nongprelbss rom_length;
108 unsigned long __nongprelbss memory_start;
109 unsigned long __nongprelbss memory_end;
110
111 unsigned long __nongprelbss dma_coherent_mem_start;
112 unsigned long __nongprelbss dma_coherent_mem_end;
113
114 unsigned long __initdata __sdram_old_base;
115 unsigned long __initdata num_mappedpages;
116
117 struct cpuinfo_frv __nongprelbss boot_cpu_data;
118
119 char command_line[COMMAND_LINE_SIZE];
120 char __initdata redboot_command_line[COMMAND_LINE_SIZE];
121
122 #ifdef CONFIG_PM
123 #define __pminit
124 #define __pminitdata
125 #else
126 #define __pminit __init
127 #define __pminitdata __initdata
128 #endif
129
130 struct clock_cmode {
131         uint8_t xbus, sdram, corebus, core, dsu;
132 };
133
134 #define _frac(N,D) ((N)<<4 | (D))
135 #define _x0_16  _frac(1,6)
136 #define _x0_25  _frac(1,4)
137 #define _x0_33  _frac(1,3)
138 #define _x0_375 _frac(3,8)
139 #define _x0_5   _frac(1,2)
140 #define _x0_66  _frac(2,3)
141 #define _x0_75  _frac(3,4)
142 #define _x1     _frac(1,1)
143 #define _x1_5   _frac(3,2)
144 #define _x2     _frac(2,1)
145 #define _x3     _frac(3,1)
146 #define _x4     _frac(4,1)
147 #define _x4_5   _frac(9,2)
148 #define _x6     _frac(6,1)
149 #define _x8     _frac(8,1)
150 #define _x9     _frac(9,1)
151
152 int __nongprelbss clock_p0_current;
153 int __nongprelbss clock_cm_current;
154 int __nongprelbss clock_cmode_current;
155 #ifdef CONFIG_PM
156 int __nongprelbss clock_cmodes_permitted;
157 unsigned long __nongprelbss clock_bits_settable;
158 #endif
159
160 static struct clock_cmode __pminitdata undef_clock_cmode = { _x1, _x1, _x1, _x1, _x1 };
161
162 static struct clock_cmode __pminitdata clock_cmodes_fr401_fr403[16] = {
163         [4]     = {     _x1,    _x1,    _x2,    _x2,    _x0_25  },
164         [5]     = {     _x1,    _x2,    _x4,    _x4,    _x0_5   },
165         [8]     = {     _x1,    _x1,    _x1,    _x2,    _x0_25  },
166         [9]     = {     _x1,    _x2,    _x2,    _x4,    _x0_5   },
167         [11]    = {     _x1,    _x4,    _x4,    _x8,    _x1     },
168         [12]    = {     _x1,    _x1,    _x2,    _x4,    _x0_5   },
169         [13]    = {     _x1,    _x2,    _x4,    _x8,    _x1     },
170 };
171
172 static struct clock_cmode __pminitdata clock_cmodes_fr405[16] = {
173         [0]     = {     _x1,    _x1,    _x1,    _x1,    _x0_5   },
174         [1]     = {     _x1,    _x1,    _x1,    _x3,    _x0_25  },
175         [2]     = {     _x1,    _x1,    _x2,    _x6,    _x0_5   },
176         [3]     = {     _x1,    _x2,    _x2,    _x6,    _x0_5   },
177         [4]     = {     _x1,    _x1,    _x2,    _x2,    _x0_16  },
178         [8]     = {     _x1,    _x1,    _x1,    _x2,    _x0_16  },
179         [9]     = {     _x1,    _x2,    _x2,    _x4,    _x0_33  },
180         [12]    = {     _x1,    _x1,    _x2,    _x4,    _x0_33  },
181         [14]    = {     _x1,    _x3,    _x3,    _x9,    _x0_75  },
182         [15]    = {     _x1,    _x1_5,  _x1_5,  _x4_5,  _x0_375 },
183
184 #define CLOCK_CMODES_PERMITTED_FR405 0xd31f
185 };
186
187 static struct clock_cmode __pminitdata clock_cmodes_fr555[16] = {
188         [0]     = {     _x1,    _x2,    _x2,    _x4,    _x0_33  },
189         [1]     = {     _x1,    _x3,    _x3,    _x6,    _x0_5   },
190         [2]     = {     _x1,    _x2,    _x4,    _x8,    _x0_66  },
191         [3]     = {     _x1,    _x1_5,  _x3,    _x6,    _x0_5   },
192         [4]     = {     _x1,    _x3,    _x3,    _x9,    _x0_75  },
193         [5]     = {     _x1,    _x2,    _x2,    _x6,    _x0_5   },
194         [6]     = {     _x1,    _x1_5,  _x1_5,  _x4_5,  _x0_375 },
195 };
196
197 static const struct clock_cmode __pminitdata *clock_cmodes;
198 static int __pminitdata clock_doubled;
199
200 static struct uart_port __initdata __frv_uart0 = {
201         .uartclk                = 0,
202         .membase                = (char *) UART0_BASE,
203         .irq                    = IRQ_CPU_UART0,
204         .regshift               = 3,
205         .iotype                 = UPIO_MEM,
206         .flags                  = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
207 };
208
209 static struct uart_port __initdata __frv_uart1 = {
210         .uartclk                = 0,
211         .membase                = (char *) UART1_BASE,
212         .irq                    = IRQ_CPU_UART1,
213         .regshift               = 3,
214         .iotype                 = UPIO_MEM,
215         .flags                  = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
216 };
217
218 #if 0
219 static void __init printk_xampr(unsigned long ampr, unsigned long amlr, char i_d, int n)
220 {
221         unsigned long phys, virt, cxn, size;
222
223 #ifdef CONFIG_MMU
224         virt = amlr & 0xffffc000;
225         cxn = amlr & 0x3fff;
226 #else
227         virt = ampr & 0xffffc000;
228         cxn = 0;
229 #endif
230         phys = ampr & xAMPRx_PPFN;
231         size = 1 << (((ampr & xAMPRx_SS) >> 4) + 17);
232
233         printk("%cAMPR%d: va %08lx-%08lx [pa %08lx] %c%c%c%c [cxn:%04lx]\n",
234                i_d, n,
235                virt, virt + size - 1,
236                phys,
237                ampr & xAMPRx_S  ? 'S' : '-',
238                ampr & xAMPRx_C  ? 'C' : '-',
239                ampr & DAMPRx_WP ? 'W' : '-',
240                ampr & xAMPRx_V  ? 'V' : '-',
241                cxn
242                );
243 }
244 #endif
245
246 /*****************************************************************************/
247 /*
248  * dump the memory map
249  */
250 static void __init dump_memory_map(void)
251 {
252
253 #if 0
254         /* dump the protection map */
255         printk_xampr(__get_IAMPR(0),  __get_IAMLR(0),  'I', 0);
256         printk_xampr(__get_IAMPR(1),  __get_IAMLR(1),  'I', 1);
257         printk_xampr(__get_IAMPR(2),  __get_IAMLR(2),  'I', 2);
258         printk_xampr(__get_IAMPR(3),  __get_IAMLR(3),  'I', 3);
259         printk_xampr(__get_IAMPR(4),  __get_IAMLR(4),  'I', 4);
260         printk_xampr(__get_IAMPR(5),  __get_IAMLR(5),  'I', 5);
261         printk_xampr(__get_IAMPR(6),  __get_IAMLR(6),  'I', 6);
262         printk_xampr(__get_IAMPR(7),  __get_IAMLR(7),  'I', 7);
263         printk_xampr(__get_IAMPR(8),  __get_IAMLR(8),  'I', 8);
264         printk_xampr(__get_IAMPR(9),  __get_IAMLR(9),  'i', 9);
265         printk_xampr(__get_IAMPR(10), __get_IAMLR(10), 'I', 10);
266         printk_xampr(__get_IAMPR(11), __get_IAMLR(11), 'I', 11);
267         printk_xampr(__get_IAMPR(12), __get_IAMLR(12), 'I', 12);
268         printk_xampr(__get_IAMPR(13), __get_IAMLR(13), 'I', 13);
269         printk_xampr(__get_IAMPR(14), __get_IAMLR(14), 'I', 14);
270         printk_xampr(__get_IAMPR(15), __get_IAMLR(15), 'I', 15);
271
272         printk_xampr(__get_DAMPR(0),  __get_DAMLR(0),  'D', 0);
273         printk_xampr(__get_DAMPR(1),  __get_DAMLR(1),  'D', 1);
274         printk_xampr(__get_DAMPR(2),  __get_DAMLR(2),  'D', 2);
275         printk_xampr(__get_DAMPR(3),  __get_DAMLR(3),  'D', 3);
276         printk_xampr(__get_DAMPR(4),  __get_DAMLR(4),  'D', 4);
277         printk_xampr(__get_DAMPR(5),  __get_DAMLR(5),  'D', 5);
278         printk_xampr(__get_DAMPR(6),  __get_DAMLR(6),  'D', 6);
279         printk_xampr(__get_DAMPR(7),  __get_DAMLR(7),  'D', 7);
280         printk_xampr(__get_DAMPR(8),  __get_DAMLR(8),  'D', 8);
281         printk_xampr(__get_DAMPR(9),  __get_DAMLR(9),  'D', 9);
282         printk_xampr(__get_DAMPR(10), __get_DAMLR(10), 'D', 10);
283         printk_xampr(__get_DAMPR(11), __get_DAMLR(11), 'D', 11);
284         printk_xampr(__get_DAMPR(12), __get_DAMLR(12), 'D', 12);
285         printk_xampr(__get_DAMPR(13), __get_DAMLR(13), 'D', 13);
286         printk_xampr(__get_DAMPR(14), __get_DAMLR(14), 'D', 14);
287         printk_xampr(__get_DAMPR(15), __get_DAMLR(15), 'D', 15);
288 #endif
289
290 #if 0
291         /* dump the bus controller registers */
292         printk("LGCR: %08lx\n", __get_LGCR());
293         printk("Master: %08lx-%08lx CR=%08lx\n",
294                __get_LEMBR(), __get_LEMBR() + __get_LEMAM(),
295                __get_LMAICR());
296
297         int loop;
298         for (loop = 1; loop <= 7; loop++) {
299                 unsigned long lcr = __get_LCR(loop), lsbr = __get_LSBR(loop);
300                 printk("CS#%d: %08lx-%08lx %c%c%c%c%c%c%c%c%c\n",
301                        loop,
302                        lsbr, lsbr + __get_LSAM(loop),
303                        lcr & 0x80000000 ? 'r' : '-',
304                        lcr & 0x40000000 ? 'w' : '-',
305                        lcr & 0x08000000 ? 'b' : '-',
306                        lcr & 0x04000000 ? 'B' : '-',
307                        lcr & 0x02000000 ? 'C' : '-',
308                        lcr & 0x01000000 ? 'D' : '-',
309                        lcr & 0x00800000 ? 'W' : '-',
310                        lcr & 0x00400000 ? 'R' : '-',
311                        (lcr & 0x00030000) == 0x00000000 ? '4' :
312                        (lcr & 0x00030000) == 0x00010000 ? '2' :
313                        (lcr & 0x00030000) == 0x00020000 ? '1' :
314                        '-'
315                        );
316         }
317 #endif
318
319 #if 0
320         printk("\n");
321 #endif
322 } /* end dump_memory_map() */
323
324 /*****************************************************************************/
325 /*
326  * attempt to detect a VDK motherboard and DAV daughter board on an MB93091 system
327  */
328 #ifdef CONFIG_MB93091_VDK
329 static void __init detect_mb93091(void)
330 {
331 #ifdef CONFIG_MB93090_MB00
332         /* Detect CB70 without motherboard */
333         if (!(cpu_system == __frv_mb93091_cb70 && ((*(unsigned short *)0xffc00030) & 0x100))) {
334                 cpu_board1 = __frv_mb93090_mb00;
335                 mb93090_mb00_detected = 1;
336         }
337 #endif
338
339 #ifdef CONFIG_FUJITSU_MB93493
340         cpu_board2 = __frv_mb93493;
341 #endif
342
343 } /* end detect_mb93091() */
344 #endif
345
346 /*****************************************************************************/
347 /*
348  * determine the CPU type and set appropriate parameters
349  *
350  * Family     Series      CPU Core    Silicon    Imple  Vers
351  * ----------------------------------------------------------
352  * FR-V --+-> FR400 --+-> FR401 --+-> MB93401     02     00 [1]
353  *        |           |           |
354  *        |           |           +-> MB93401/A   02     01
355  *        |           |           |
356  *        |           |           +-> MB93403     02     02
357  *        |           |
358  *        |           +-> FR405 ----> MB93405     04     00
359  *        |
360  *        +-> FR450 ----> FR451 ----> MB93451     05     00
361  *        |
362  *        +-> FR500 ----> FR501 --+-> MB93501     01     01 [2]
363  *        |                       |
364  *        |                       +-> MB93501/A   01     02
365  *        |
366  *        +-> FR550 --+-> FR551 ----> MB93555     03     01
367  *
368  *  [1] The MB93401 is an obsolete CPU replaced by the MB93401A
369  *  [2] The MB93501 is an obsolete CPU replaced by the MB93501A
370  *
371  * Imple is PSR(Processor Status Register)[31:28].
372  * Vers is PSR(Processor Status Register)[27:24].
373  *
374  * A "Silicon" consists of CPU core and some on-chip peripherals.
375  */
376 static void __init determine_cpu(void)
377 {
378         unsigned long hsr0 = __get_HSR(0);
379         unsigned long psr = __get_PSR();
380
381         /* work out what selectable services the CPU supports */
382         __set_PSR(psr | PSR_EM | PSR_EF | PSR_CM | PSR_NEM);
383         cpu_psr_all = __get_PSR();
384         __set_PSR(psr);
385
386         __set_HSR(0, hsr0 | HSR0_GRLE | HSR0_GRHE | HSR0_FRLE | HSR0_FRHE);
387         cpu_hsr0_all = __get_HSR(0);
388         __set_HSR(0, hsr0);
389
390         /* derive other service specs from the CPU type */
391         cpu_series              = "unknown";
392         cpu_core                = "unknown";
393         cpu_silicon             = "unknown";
394         cpu_mmu                 = "Prot";
395         cpu_system              = __frv_unknown_system;
396         clock_cmodes            = NULL;
397         clock_doubled           = 0;
398 #ifdef CONFIG_PM
399         clock_bits_settable     = CLOCK_BIT_CM_H | CLOCK_BIT_CM_M | CLOCK_BIT_P0;
400 #endif
401
402         switch (PSR_IMPLE(psr)) {
403         case PSR_IMPLE_FR401:
404                 cpu_series      = "fr400";
405                 cpu_core        = "fr401";
406                 pdm_suspend_mode = HSR0_PDM_PLL_RUN;
407
408                 switch (PSR_VERSION(psr)) {
409                 case PSR_VERSION_FR401_MB93401:
410                         cpu_silicon     = "mb93401";
411                         cpu_system      = __frv_mb93091_cb10;
412                         clock_cmodes    = clock_cmodes_fr401_fr403;
413                         clock_doubled   = 1;
414                         break;
415                 case PSR_VERSION_FR401_MB93401A:
416                         cpu_silicon     = "mb93401/A";
417                         cpu_system      = __frv_mb93091_cb11;
418                         clock_cmodes    = clock_cmodes_fr401_fr403;
419                         break;
420                 case PSR_VERSION_FR401_MB93403:
421                         cpu_silicon     = "mb93403";
422 #ifndef CONFIG_MB93093_PDK
423                         cpu_system      = __frv_mb93091_cb30;
424 #else
425                         cpu_system      = __frv_mb93093;
426 #endif
427                         clock_cmodes    = clock_cmodes_fr401_fr403;
428                         break;
429                 default:
430                         break;
431                 }
432                 break;
433
434         case PSR_IMPLE_FR405:
435                 cpu_series      = "fr400";
436                 cpu_core        = "fr405";
437                 pdm_suspend_mode = HSR0_PDM_PLL_STOP;
438
439                 switch (PSR_VERSION(psr)) {
440                 case PSR_VERSION_FR405_MB93405:
441                         cpu_silicon     = "mb93405";
442                         cpu_system      = __frv_mb93091_cb60;
443                         clock_cmodes    = clock_cmodes_fr405;
444 #ifdef CONFIG_PM
445                         clock_bits_settable |= CLOCK_BIT_CMODE;
446                         clock_cmodes_permitted = CLOCK_CMODES_PERMITTED_FR405;
447 #endif
448
449                         /* the FPGA on the CB70 has extra registers
450                          * - it has 0x0046 in the VDK_ID FPGA register at 0x1a0, which is
451                          *   how we tell the difference between it and a CB60
452                          */
453                         if (*(volatile unsigned short *) 0xffc001a0 == 0x0046)
454                                 cpu_system = __frv_mb93091_cb70;
455                         break;
456                 default:
457                         break;
458                 }
459                 break;
460
461         case PSR_IMPLE_FR451:
462                 cpu_series      = "fr450";
463                 cpu_core        = "fr451";
464                 pdm_suspend_mode = HSR0_PDM_PLL_STOP;
465 #ifdef CONFIG_PM
466                 clock_bits_settable |= CLOCK_BIT_CMODE;
467                 clock_cmodes_permitted = CLOCK_CMODES_PERMITTED_FR405;
468 #endif
469                 switch (PSR_VERSION(psr)) {
470                 case PSR_VERSION_FR451_MB93451:
471                         cpu_silicon     = "mb93451";
472                         cpu_mmu         = "Prot, SAT, xSAT, DAT";
473                         cpu_system      = __frv_mb93091_cb451;
474                         clock_cmodes    = clock_cmodes_fr405;
475                         break;
476                 default:
477                         break;
478                 }
479                 break;
480
481         case PSR_IMPLE_FR501:
482                 cpu_series      = "fr500";
483                 cpu_core        = "fr501";
484                 pdm_suspend_mode = HSR0_PDM_PLL_STOP;
485
486                 switch (PSR_VERSION(psr)) {
487                 case PSR_VERSION_FR501_MB93501:  cpu_silicon = "mb93501";   break;
488                 case PSR_VERSION_FR501_MB93501A: cpu_silicon = "mb93501/A"; break;
489                 default:
490                         break;
491                 }
492                 break;
493
494         case PSR_IMPLE_FR551:
495                 cpu_series      = "fr550";
496                 cpu_core        = "fr551";
497                 pdm_suspend_mode = HSR0_PDM_PLL_RUN;
498
499                 switch (PSR_VERSION(psr)) {
500                 case PSR_VERSION_FR551_MB93555:
501                         cpu_silicon     = "mb93555";
502                         cpu_mmu         = "Prot, SAT";
503                         cpu_system      = __frv_mb93091_cb41;
504                         clock_cmodes    = clock_cmodes_fr555;
505                         clock_doubled   = 1;
506                         break;
507                 default:
508                         break;
509                 }
510                 break;
511
512         default:
513                 break;
514         }
515
516         printk("- Series:%s CPU:%s Silicon:%s\n",
517                cpu_series, cpu_core, cpu_silicon);
518
519 #ifdef CONFIG_MB93091_VDK
520         detect_mb93091();
521 #endif
522
523 #if defined(CONFIG_MB93093_PDK) && defined(CONFIG_FUJITSU_MB93493)
524         cpu_board2 = __frv_mb93493;
525 #endif
526
527 } /* end determine_cpu() */
528
529 /*****************************************************************************/
530 /*
531  * calculate the bus clock speed
532  */
533 void __pminit determine_clocks(int verbose)
534 {
535         const struct clock_cmode *mode, *tmode;
536         unsigned long clkc, psr, quot;
537
538         clkc = __get_CLKC();
539         psr = __get_PSR();
540
541         clock_p0_current = !!(clkc & CLKC_P0);
542         clock_cm_current = clkc & CLKC_CM;
543         clock_cmode_current = (clkc & CLKC_CMODE) >> CLKC_CMODE_s;
544
545         if (verbose)
546                 printk("psr=%08lx hsr0=%08lx clkc=%08lx\n", psr, __get_HSR(0), clkc);
547
548         /* the CB70 has some alternative ways of setting the clock speed through switches accessed
549          * through the FPGA.  */
550         if (cpu_system == __frv_mb93091_cb70) {
551                 unsigned short clkswr = *(volatile unsigned short *) 0xffc00104UL & 0x1fffUL;
552
553                 if (clkswr & 0x1000)
554                         __clkin_clock_speed_HZ = 60000000UL;
555                 else
556                         __clkin_clock_speed_HZ =
557                                 ((clkswr >> 8) & 0xf) * 10000000 +
558                                 ((clkswr >> 4) & 0xf) * 1000000 +
559                                 ((clkswr     ) & 0xf) * 100000;
560         }
561         /* the FR451 is currently fixed at 24MHz */
562         else if (cpu_system == __frv_mb93091_cb451) {
563                 //__clkin_clock_speed_HZ = 24000000UL; // CB451-FPGA
564                 unsigned short clkswr = *(volatile unsigned short *) 0xffc00104UL & 0x1fffUL;
565
566                 if (clkswr & 0x1000)
567                         __clkin_clock_speed_HZ = 60000000UL;
568                 else
569                         __clkin_clock_speed_HZ =
570                                 ((clkswr >> 8) & 0xf) * 10000000 +
571                                 ((clkswr >> 4) & 0xf) * 1000000 +
572                                 ((clkswr     ) & 0xf) * 100000;
573         }
574         /* otherwise determine the clockspeed from VDK or other registers */
575         else {
576                 __clkin_clock_speed_HZ = __get_CLKIN();
577         }
578
579         /* look up the appropriate clock relationships table entry */
580         mode = &undef_clock_cmode;
581         if (clock_cmodes) {
582                 tmode = &clock_cmodes[(clkc & CLKC_CMODE) >> CLKC_CMODE_s];
583                 if (tmode->xbus)
584                         mode = tmode;
585         }
586
587 #define CLOCK(SRC,RATIO) ((SRC) * (((RATIO) >> 4) & 0x0f) / ((RATIO) & 0x0f))
588
589         if (clock_doubled)
590                 __clkin_clock_speed_HZ <<= 1;
591
592         __ext_bus_clock_speed_HZ        = CLOCK(__clkin_clock_speed_HZ, mode->xbus);
593         __sdram_clock_speed_HZ          = CLOCK(__clkin_clock_speed_HZ, mode->sdram);
594         __dsu_clock_speed_HZ            = CLOCK(__clkin_clock_speed_HZ, mode->dsu);
595
596         switch (clkc & CLKC_CM) {
597         case 0: /* High */
598                 __core_bus_clock_speed_HZ       = CLOCK(__clkin_clock_speed_HZ, mode->corebus);
599                 __core_clock_speed_HZ           = CLOCK(__clkin_clock_speed_HZ, mode->core);
600                 break;
601         case 1: /* Medium */
602                 __core_bus_clock_speed_HZ       = CLOCK(__clkin_clock_speed_HZ, mode->sdram);
603                 __core_clock_speed_HZ           = CLOCK(__clkin_clock_speed_HZ, mode->sdram);
604                 break;
605         case 2: /* Low; not supported */
606         case 3: /* UNDEF */
607                 printk("Unsupported CLKC CM %ld\n", clkc & CLKC_CM);
608                 panic("Bye");
609         }
610
611         __res_bus_clock_speed_HZ = __ext_bus_clock_speed_HZ;
612         if (clkc & CLKC_P0)
613                 __res_bus_clock_speed_HZ >>= 1;
614
615         if (verbose) {
616                 printk("CLKIN: %lu.%3.3luMHz\n",
617                        __clkin_clock_speed_HZ / 1000000,
618                        (__clkin_clock_speed_HZ / 1000) % 1000);
619
620                 printk("CLKS:"
621                        " ext=%luMHz res=%luMHz sdram=%luMHz cbus=%luMHz core=%luMHz dsu=%luMHz\n",
622                        __ext_bus_clock_speed_HZ / 1000000,
623                        __res_bus_clock_speed_HZ / 1000000,
624                        __sdram_clock_speed_HZ / 1000000,
625                        __core_bus_clock_speed_HZ / 1000000,
626                        __core_clock_speed_HZ / 1000000,
627                        __dsu_clock_speed_HZ / 1000000
628                        );
629         }
630
631         /* calculate the number of __delay() loop iterations per sec (2 insn loop) */
632         __delay_loops_MHz = __core_clock_speed_HZ / (1000000 * 2);
633
634         /* set the serial prescaler */
635         __serial_clock_speed_HZ = __res_bus_clock_speed_HZ;
636         quot = 1;
637         while (__serial_clock_speed_HZ / quot / 16 / 65536 > 3000)
638                 quot += 1;
639
640         /* double the divisor if P0 is clear, so that if/when P0 is set, it's still achievable
641          * - we have to be careful - dividing too much can mean we can't get 115200 baud
642          */
643         if (__serial_clock_speed_HZ > 32000000 && !(clkc & CLKC_P0))
644                 quot <<= 1;
645
646         __serial_clock_speed_HZ /= quot;
647         __frv_uart0.uartclk = __serial_clock_speed_HZ;
648         __frv_uart1.uartclk = __serial_clock_speed_HZ;
649
650         if (verbose)
651                 printk("      uart=%luMHz\n", __serial_clock_speed_HZ / 1000000 * quot);
652
653         while (!(__get_UART0_LSR() & UART_LSR_TEMT))
654                 continue;
655
656         while (!(__get_UART1_LSR() & UART_LSR_TEMT))
657                 continue;
658
659         __set_UCPVR(quot);
660         __set_UCPSR(0);
661 } /* end determine_clocks() */
662
663 /*****************************************************************************/
664 /*
665  * reserve some DMA consistent memory
666  */
667 #ifdef CONFIG_RESERVE_DMA_COHERENT
668 static void __init reserve_dma_coherent(void)
669 {
670         unsigned long ampr;
671
672         /* find the first non-kernel memory tile and steal it */
673 #define __steal_AMPR(r)                                         \
674         if (__get_DAMPR(r) & xAMPRx_V) {                        \
675                 ampr = __get_DAMPR(r);                          \
676                 __set_DAMPR(r, ampr | xAMPRx_S | xAMPRx_C);     \
677                 __set_IAMPR(r, 0);                              \
678                 goto found;                                     \
679         }
680
681         __steal_AMPR(1);
682         __steal_AMPR(2);
683         __steal_AMPR(3);
684         __steal_AMPR(4);
685         __steal_AMPR(5);
686         __steal_AMPR(6);
687
688         if (PSR_IMPLE(__get_PSR()) == PSR_IMPLE_FR551) {
689                 __steal_AMPR(7);
690                 __steal_AMPR(8);
691                 __steal_AMPR(9);
692                 __steal_AMPR(10);
693                 __steal_AMPR(11);
694                 __steal_AMPR(12);
695                 __steal_AMPR(13);
696                 __steal_AMPR(14);
697         }
698
699         /* unable to grant any DMA consistent memory */
700         printk("No DMA consistent memory reserved\n");
701         return;
702
703  found:
704         dma_coherent_mem_start = ampr & xAMPRx_PPFN;
705         ampr &= xAMPRx_SS;
706         ampr >>= 4;
707         ampr = 1 << (ampr - 3 + 20);
708         dma_coherent_mem_end = dma_coherent_mem_start + ampr;
709
710         printk("DMA consistent memory reserved %lx-%lx\n",
711                dma_coherent_mem_start, dma_coherent_mem_end);
712
713 } /* end reserve_dma_coherent() */
714 #endif
715
716 /*****************************************************************************/
717 /*
718  * calibrate the delay loop
719  */
720 void __init calibrate_delay(void)
721 {
722         loops_per_jiffy = __delay_loops_MHz * (1000000 / HZ);
723
724         printk("Calibrating delay loop... %lu.%02lu BogoMIPS\n",
725                loops_per_jiffy / (500000 / HZ),
726                (loops_per_jiffy / (5000 / HZ)) % 100);
727
728 } /* end calibrate_delay() */
729
730 /*****************************************************************************/
731 /*
732  * look through the command line for some things we need to know immediately
733  */
734 static void __init parse_cmdline_early(char *cmdline)
735 {
736         if (!cmdline)
737                 return;
738
739         while (*cmdline) {
740                 if (*cmdline == ' ')
741                         cmdline++;
742
743                 /* "mem=XXX[kKmM]" sets SDRAM size to <mem>, overriding the value we worked
744                  * out from the SDRAM controller mask register
745                  */
746                 if (!memcmp(cmdline, "mem=", 4)) {
747                         unsigned long long mem_size;
748
749                         mem_size = memparse(cmdline + 4, &cmdline);
750                         memory_end = memory_start + mem_size;
751                 }
752
753                 while (*cmdline && *cmdline != ' ')
754                         cmdline++;
755         }
756
757 } /* end parse_cmdline_early() */
758
759 /*****************************************************************************/
760 /*
761  *
762  */
763 void __init setup_arch(char **cmdline_p)
764 {
765 #ifdef CONFIG_MMU
766         printk("Linux FR-V port done by Red Hat Inc <dhowells@redhat.com>\n");
767 #else
768         printk("uClinux FR-V port done by Red Hat Inc <dhowells@redhat.com>\n");
769 #endif
770
771         memcpy(saved_command_line, redboot_command_line, COMMAND_LINE_SIZE);
772
773         determine_cpu();
774         determine_clocks(1);
775
776         /* For printk-directly-beats-on-serial-hardware hack */
777         console_set_baud(115200);
778 #ifdef CONFIG_GDBSTUB
779         gdbstub_set_baud(115200);
780 #endif
781
782 #ifdef CONFIG_RESERVE_DMA_COHERENT
783         reserve_dma_coherent();
784 #endif
785         dump_memory_map();
786
787 #ifdef CONFIG_MB93090_MB00
788         if (mb93090_mb00_detected)
789                 mb93090_display();
790 #endif
791
792         /* register those serial ports that are available */
793 #ifndef CONFIG_GDBSTUB_UART0
794         __reg(UART0_BASE + UART_IER * 8) = 0;
795         early_serial_setup(&__frv_uart0);
796 //      register_serial(&__frv_uart0);
797 #endif
798 #ifndef CONFIG_GDBSTUB_UART1
799         __reg(UART1_BASE + UART_IER * 8) = 0;
800         early_serial_setup(&__frv_uart1);
801 //      register_serial(&__frv_uart1);
802 #endif
803
804 #if defined(CONFIG_CHR_DEV_FLASH) || defined(CONFIG_BLK_DEV_FLASH)
805         /* we need to initialize the Flashrom device here since we might
806          * do things with flash early on in the boot
807          */
808         flash_probe();
809 #endif
810
811         /* deal with the command line - RedBoot may have passed one to the kernel */
812         memcpy(command_line, saved_command_line, sizeof(command_line));
813         *cmdline_p = &command_line[0];
814         parse_cmdline_early(command_line);
815
816         /* set up the memory description
817          * - by now the stack is part of the init task */
818         printk("Memory %08lx-%08lx\n", memory_start, memory_end);
819
820         if (memory_start == memory_end) BUG();
821
822         init_mm.start_code = (unsigned long) &_stext;
823         init_mm.end_code = (unsigned long) &_etext;
824         init_mm.end_data = (unsigned long) &_edata;
825 #if 0 /* DAVIDM - don't set brk just incase someone decides to use it */
826         init_mm.brk = (unsigned long) &_end;
827 #else
828         init_mm.brk = (unsigned long) 0;
829 #endif
830
831 #ifdef DEBUG
832         printk("KERNEL -> TEXT=0x%06x-0x%06x DATA=0x%06x-0x%06x BSS=0x%06x-0x%06x\n",
833                (int) &_stext, (int) &_etext,
834                (int) &_sdata, (int) &_edata,
835                (int) &_sbss, (int) &_ebss);
836 #endif
837
838 #ifdef CONFIG_VT
839 #if defined(CONFIG_VGA_CONSOLE)
840         conswitchp = &vga_con;
841 #elif defined(CONFIG_DUMMY_CONSOLE)
842         conswitchp = &dummy_con;
843 #endif
844 #endif
845
846 #ifdef CONFIG_BLK_DEV_BLKMEM
847         ROOT_DEV = MKDEV(BLKMEM_MAJOR,0);
848 #endif
849         /*rom_length = (unsigned long)&_flashend - (unsigned long)&_romvec;*/
850
851 #ifdef CONFIG_MMU
852         setup_linux_memory();
853 #else
854         setup_uclinux_memory();
855 #endif
856
857         /* get kmalloc into gear */
858         paging_init();
859
860         /* init DMA */
861         frv_dma_init();
862 #ifdef DEBUG
863         printk("Done setup_arch\n");
864 #endif
865
866         /* start the decrement timer running */
867 //      asm volatile("movgs %0,timerd" :: "r"(10000000));
868 //      __set_HSR(0, __get_HSR(0) | HSR0_ETMD);
869
870 } /* end setup_arch() */
871
872 #if 0
873 /*****************************************************************************/
874 /*
875  *
876  */
877 static int __devinit setup_arch_serial(void)
878 {
879         /* register those serial ports that are available */
880 #ifndef CONFIG_GDBSTUB_UART0
881         early_serial_setup(&__frv_uart0);
882 #endif
883 #ifndef CONFIG_GDBSTUB_UART1
884         early_serial_setup(&__frv_uart1);
885 #endif
886
887         return 0;
888 } /* end setup_arch_serial() */
889
890 late_initcall(setup_arch_serial);
891 #endif
892
893 /*****************************************************************************/
894 /*
895  * set up the memory map for normal MMU linux
896  */
897 #ifdef CONFIG_MMU
898 static void __init setup_linux_memory(void)
899 {
900         unsigned long bootmap_size, low_top_pfn, kstart, kend, high_mem;
901
902         kstart  = (unsigned long) &__kernel_image_start - PAGE_OFFSET;
903         kend    = (unsigned long) &__kernel_image_end - PAGE_OFFSET;
904
905         kstart = kstart & PAGE_MASK;
906         kend = (kend + PAGE_SIZE - 1) & PAGE_MASK;
907
908         /* give all the memory to the bootmap allocator,  tell it to put the
909          * boot mem_map immediately following the kernel image
910          */
911         bootmap_size = init_bootmem_node(NODE_DATA(0),
912                                          kend >> PAGE_SHIFT,            /* map addr */
913                                          memory_start >> PAGE_SHIFT,    /* start of RAM */
914                                          memory_end >> PAGE_SHIFT       /* end of RAM */
915                                          );
916
917         /* pass the memory that the kernel can immediately use over to the bootmem allocator */
918         max_mapnr = num_physpages = (memory_end - memory_start) >> PAGE_SHIFT;
919         low_top_pfn = (KERNEL_LOWMEM_END - KERNEL_LOWMEM_START) >> PAGE_SHIFT;
920         high_mem = 0;
921
922         if (num_physpages > low_top_pfn) {
923 #ifdef CONFIG_HIGHMEM
924                 high_mem = num_physpages - low_top_pfn;
925 #else
926                 max_mapnr = num_physpages = low_top_pfn;
927 #endif
928         }
929         else {
930                 low_top_pfn = num_physpages;
931         }
932
933         min_low_pfn = memory_start >> PAGE_SHIFT;
934         max_low_pfn = low_top_pfn;
935         max_pfn = memory_end >> PAGE_SHIFT;
936
937         num_mappedpages = low_top_pfn;
938
939         printk(KERN_NOTICE "%ldMB LOWMEM available.\n", low_top_pfn >> (20 - PAGE_SHIFT));
940
941         free_bootmem(memory_start, low_top_pfn << PAGE_SHIFT);
942
943 #ifdef CONFIG_HIGHMEM
944         if (high_mem)
945                 printk(KERN_NOTICE "%ldMB HIGHMEM available.\n", high_mem >> (20 - PAGE_SHIFT));
946 #endif
947
948         /* take back the memory occupied by the kernel image and the bootmem alloc map */
949         reserve_bootmem(kstart, kend - kstart + bootmap_size);
950
951         /* reserve the memory occupied by the initial ramdisk */
952 #ifdef CONFIG_BLK_DEV_INITRD
953         if (LOADER_TYPE && INITRD_START) {
954                 if (INITRD_START + INITRD_SIZE <= (low_top_pfn << PAGE_SHIFT)) {
955                         reserve_bootmem(INITRD_START, INITRD_SIZE);
956                         initrd_start = INITRD_START ? INITRD_START + PAGE_OFFSET : 0;
957                         initrd_end = initrd_start + INITRD_SIZE;
958                 }
959                 else {
960                         printk(KERN_ERR
961                                "initrd extends beyond end of memory (0x%08lx > 0x%08lx)\n"
962                                "disabling initrd\n",
963                                INITRD_START + INITRD_SIZE,
964                                low_top_pfn << PAGE_SHIFT);
965                         initrd_start = 0;
966                 }
967         }
968 #endif
969
970 } /* end setup_linux_memory() */
971 #endif
972
973 /*****************************************************************************/
974 /*
975  * set up the memory map for uClinux
976  */
977 #ifndef CONFIG_MMU
978 static void __init setup_uclinux_memory(void)
979 {
980 #ifdef CONFIG_PROTECT_KERNEL
981         unsigned long dampr;
982 #endif
983         unsigned long kend;
984         int bootmap_size;
985
986         kend = (unsigned long) &__kernel_image_end;
987         kend = (kend + PAGE_SIZE - 1) & PAGE_MASK;
988
989         /* give all the memory to the bootmap allocator,  tell it to put the
990          * boot mem_map immediately following the kernel image
991          */
992         bootmap_size = init_bootmem_node(NODE_DATA(0),
993                                          kend >> PAGE_SHIFT,            /* map addr */
994                                          memory_start >> PAGE_SHIFT,    /* start of RAM */
995                                          memory_end >> PAGE_SHIFT       /* end of RAM */
996                                          );
997
998         /* free all the usable memory */
999         free_bootmem(memory_start, memory_end - memory_start);
1000
1001         high_memory = (void *) (memory_end & PAGE_MASK);
1002         max_mapnr = num_physpages = ((unsigned long) high_memory - PAGE_OFFSET) >> PAGE_SHIFT;
1003
1004         min_low_pfn = memory_start >> PAGE_SHIFT;
1005         max_low_pfn = memory_end >> PAGE_SHIFT;
1006         max_pfn = max_low_pfn;
1007
1008         /* now take back the bits the core kernel is occupying */
1009 #ifndef CONFIG_PROTECT_KERNEL
1010         reserve_bootmem(kend, bootmap_size);
1011         reserve_bootmem((unsigned long) &__kernel_image_start,
1012                         kend - (unsigned long) &__kernel_image_start);
1013
1014 #else
1015         dampr = __get_DAMPR(0);
1016         dampr &= xAMPRx_SS;
1017         dampr = (dampr >> 4) + 17;
1018         dampr = 1 << dampr;
1019
1020         reserve_bootmem(__get_DAMPR(0) & xAMPRx_PPFN, dampr);
1021 #endif
1022
1023         /* reserve some memory to do uncached DMA through if requested */
1024 #ifdef CONFIG_RESERVE_DMA_COHERENT
1025         if (dma_coherent_mem_start)
1026                 reserve_bootmem(dma_coherent_mem_start,
1027                                 dma_coherent_mem_end - dma_coherent_mem_start);
1028 #endif
1029
1030 } /* end setup_uclinux_memory() */
1031 #endif
1032
1033 /*****************************************************************************/
1034 /*
1035  * get CPU information for use by procfs
1036  */
1037 static int show_cpuinfo(struct seq_file *m, void *v)
1038 {
1039         const char *gr, *fr, *fm, *fp, *cm, *nem, *ble;
1040 #ifdef CONFIG_PM
1041         const char *sep;
1042 #endif
1043
1044         gr  = cpu_hsr0_all & HSR0_GRHE  ? "gr0-63"      : "gr0-31";
1045         fr  = cpu_hsr0_all & HSR0_FRHE  ? "fr0-63"      : "fr0-31";
1046         fm  = cpu_psr_all  & PSR_EM     ? ", Media"     : "";
1047         fp  = cpu_psr_all  & PSR_EF     ? ", FPU"       : "";
1048         cm  = cpu_psr_all  & PSR_CM     ? ", CCCR"      : "";
1049         nem = cpu_psr_all  & PSR_NEM    ? ", NE"        : "";
1050         ble = cpu_psr_all  & PSR_BE     ? "BE"          : "LE";
1051
1052         seq_printf(m,
1053                    "CPU-Series:\t%s\n"
1054                    "CPU-Core:\t%s, %s, %s%s%s\n"
1055                    "CPU:\t\t%s\n"
1056                    "MMU:\t\t%s\n"
1057                    "FP-Media:\t%s%s%s\n"
1058                    "System:\t\t%s",
1059                    cpu_series,
1060                    cpu_core, gr, ble, cm, nem,
1061                    cpu_silicon,
1062                    cpu_mmu,
1063                    fr, fm, fp,
1064                    cpu_system);
1065
1066         if (cpu_board1)
1067                 seq_printf(m, ", %s", cpu_board1);
1068
1069         if (cpu_board2)
1070                 seq_printf(m, ", %s", cpu_board2);
1071
1072         seq_printf(m, "\n");
1073
1074 #ifdef CONFIG_PM
1075         seq_printf(m, "PM-Controls:");
1076         sep = "\t";
1077
1078         if (clock_bits_settable & CLOCK_BIT_CMODE) {
1079                 seq_printf(m, "%scmode=0x%04hx", sep, clock_cmodes_permitted);
1080                 sep = ", ";
1081         }
1082
1083         if (clock_bits_settable & CLOCK_BIT_CM) {
1084                 seq_printf(m, "%scm=0x%lx", sep, clock_bits_settable & CLOCK_BIT_CM);
1085                 sep = ", ";
1086         }
1087
1088         if (clock_bits_settable & CLOCK_BIT_P0) {
1089                 seq_printf(m, "%sp0=0x3", sep);
1090                 sep = ", ";
1091         }
1092
1093         seq_printf(m, "%ssuspend=0x22\n", sep);
1094 #endif
1095
1096         seq_printf(m,
1097                    "PM-Status:\tcmode=%d, cm=%d, p0=%d\n",
1098                    clock_cmode_current, clock_cm_current, clock_p0_current);
1099
1100 #define print_clk(TAG, VAR) \
1101         seq_printf(m, "Clock-" TAG ":\t%lu.%2.2lu MHz\n", VAR / 1000000, (VAR / 10000) % 100)
1102
1103         print_clk("In",    __clkin_clock_speed_HZ);
1104         print_clk("Core",  __core_clock_speed_HZ);
1105         print_clk("SDRAM", __sdram_clock_speed_HZ);
1106         print_clk("CBus",  __core_bus_clock_speed_HZ);
1107         print_clk("Res",   __res_bus_clock_speed_HZ);
1108         print_clk("Ext",   __ext_bus_clock_speed_HZ);
1109         print_clk("DSU",   __dsu_clock_speed_HZ);
1110
1111         seq_printf(m,
1112                    "BogoMips:\t%lu.%02lu\n",
1113                    (loops_per_jiffy * HZ) / 500000, ((loops_per_jiffy * HZ) / 5000) % 100);
1114
1115         return 0;
1116 } /* end show_cpuinfo() */
1117
1118 static void *c_start(struct seq_file *m, loff_t *pos)
1119 {
1120         return *pos < NR_CPUS ? (void *) 0x12345678 : NULL;
1121 }
1122
1123 static void *c_next(struct seq_file *m, void *v, loff_t *pos)
1124 {
1125         ++*pos;
1126         return c_start(m, pos);
1127 }
1128
1129 static void c_stop(struct seq_file *m, void *v)
1130 {
1131 }
1132
1133 struct seq_operations cpuinfo_op = {
1134         .start  = c_start,
1135         .next   = c_next,
1136         .stop   = c_stop,
1137         .show   = show_cpuinfo,
1138 };
1139
1140 void arch_gettod(int *year, int *mon, int *day, int *hour,
1141                  int *min, int *sec)
1142 {
1143         *year = *mon = *day = *hour = *min = *sec = 0;
1144 }
1145
1146 /*****************************************************************************/
1147 /*
1148  *
1149  */
1150 #ifdef CONFIG_MB93090_MB00
1151 static void __init mb93090_sendlcdcmd(uint32_t cmd)
1152 {
1153         unsigned long base = __addr_LCD();
1154         int loop;
1155
1156         /* request reading of the busy flag */
1157         __set_LCD(base, LCD_CMD_READ_BUSY);
1158         __set_LCD(base, LCD_CMD_READ_BUSY & ~LCD_E);
1159
1160         /* wait for the busy flag to become clear */
1161         for (loop = 10000; loop > 0; loop--)
1162                 if (!(__get_LCD(base) & 0x80))
1163                         break;
1164
1165         /* send the command */
1166         __set_LCD(base, cmd);
1167         __set_LCD(base, cmd & ~LCD_E);
1168
1169 } /* end mb93090_sendlcdcmd() */
1170
1171 /*****************************************************************************/
1172 /*
1173  * write to the MB93090 LEDs and LCD
1174  */
1175 static void __init mb93090_display(void)
1176 {
1177         const char *p;
1178
1179         __set_LEDS(0);
1180
1181         /* set up the LCD */
1182         mb93090_sendlcdcmd(LCD_CMD_CLEAR);
1183         mb93090_sendlcdcmd(LCD_CMD_FUNCSET(1,1,0));
1184         mb93090_sendlcdcmd(LCD_CMD_ON(0,0));
1185         mb93090_sendlcdcmd(LCD_CMD_HOME);
1186
1187         mb93090_sendlcdcmd(LCD_CMD_SET_DD_ADDR(0));
1188         for (p = mb93090_banner; *p; p++)
1189                 mb93090_sendlcdcmd(LCD_DATA_WRITE(*p));
1190
1191         mb93090_sendlcdcmd(LCD_CMD_SET_DD_ADDR(64));
1192         for (p = mb93090_version; *p; p++)
1193                 mb93090_sendlcdcmd(LCD_DATA_WRITE(*p));
1194
1195 } /* end mb93090_display() */
1196
1197 #endif // CONFIG_MB93090_MB00