]> git.sur5r.net Git - u-boot/blob - board/tqm5200/tqm5200.c
Add command for handling DDR ECC registers on MPC8349EE MDS board.
[u-boot] / board / tqm5200 / tqm5200.c
1 /*
2  * (C) Copyright 2003-2004
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * (C) Copyright 2004
6  * Mark Jonas, Freescale Semiconductor, mark.jonas@motorola.com.
7  *
8  * (C) Copyright 2004-2005
9  * Martin Krause, TQ-Systems GmbH, martin.krause@tqs.de
10  *
11  * See file CREDITS for list of people who contributed to this
12  * project.
13  *
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License as
16  * published by the Free Software Foundation; either version 2 of
17  * the License, or (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
27  * MA 02111-1307 USA
28  */
29
30 #include <common.h>
31 #include <mpc5xxx.h>
32 #include <pci.h>
33
34 #ifdef CONFIG_VIDEO_SM501
35 #include <sm501.h>
36 #endif
37
38 #if defined(CONFIG_MPC5200_DDR)
39 #include "mt46v16m16-75.h"
40 #else
41 #include "mt48lc16m16a2-75.h"
42 #endif
43
44 #ifdef CONFIG_PS2MULT
45 void ps2mult_early_init(void);
46 #endif
47
48 #ifndef CFG_RAMBOOT
49 static void sdram_start (int hi_addr)
50 {
51         long hi_addr_bit = hi_addr ? 0x01000000 : 0;
52
53         /* unlock mode register */
54         *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000000 |
55                 hi_addr_bit;
56         __asm__ volatile ("sync");
57
58         /* precharge all banks */
59         *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000002 |
60                 hi_addr_bit;
61         __asm__ volatile ("sync");
62
63 #if SDRAM_DDR
64         /* set mode register: extended mode */
65         *(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_EMODE;
66         __asm__ volatile ("sync");
67
68         /* set mode register: reset DLL */
69         *(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_MODE | 0x04000000;
70         __asm__ volatile ("sync");
71 #endif
72
73         /* precharge all banks */
74         *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000002 |
75                 hi_addr_bit;
76         __asm__ volatile ("sync");
77
78         /* auto refresh */
79         *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000004 |
80                 hi_addr_bit;
81         __asm__ volatile ("sync");
82
83         /* set mode register */
84         *(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_MODE;
85         __asm__ volatile ("sync");
86
87         /* normal operation */
88         *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | hi_addr_bit;
89         __asm__ volatile ("sync");
90 }
91 #endif
92
93 /*
94  * ATTENTION: Although partially referenced initdram does NOT make real use
95  *            use of CFG_SDRAM_BASE. The code does not work if CFG_SDRAM_BASE
96  *            is something else than 0x00000000.
97  */
98
99 #if defined(CONFIG_MPC5200)
100 long int initdram (int board_type)
101 {
102         ulong dramsize = 0;
103         ulong dramsize2 = 0;
104 #ifndef CFG_RAMBOOT
105         ulong test1, test2;
106
107         /* setup SDRAM chip selects */
108         *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x0000001c; /* 512MB at 0x0 */
109         *(vu_long *)MPC5XXX_SDRAM_CS1CFG = 0x40000000; /* disabled */
110         __asm__ volatile ("sync");
111
112         /* setup config registers */
113         *(vu_long *)MPC5XXX_SDRAM_CONFIG1 = SDRAM_CONFIG1;
114         *(vu_long *)MPC5XXX_SDRAM_CONFIG2 = SDRAM_CONFIG2;
115         __asm__ volatile ("sync");
116
117 #if SDRAM_DDR
118         /* set tap delay */
119         *(vu_long *)MPC5XXX_CDM_PORCFG = SDRAM_TAPDELAY;
120         __asm__ volatile ("sync");
121 #endif
122
123         /* find RAM size using SDRAM CS0 only */
124         sdram_start(0);
125         test1 = get_ram_size((long *)CFG_SDRAM_BASE, 0x20000000);
126         sdram_start(1);
127         test2 = get_ram_size((long *)CFG_SDRAM_BASE, 0x20000000);
128         if (test1 > test2) {
129                 sdram_start(0);
130                 dramsize = test1;
131         } else {
132                 dramsize = test2;
133         }
134
135         /* memory smaller than 1MB is impossible */
136         if (dramsize < (1 << 20)) {
137                 dramsize = 0;
138         }
139
140         /* set SDRAM CS0 size according to the amount of RAM found */
141         if (dramsize > 0) {
142                 *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x13 +
143                         __builtin_ffs(dramsize >> 20) - 1;
144         } else {
145                 *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0; /* disabled */
146         }
147
148         /* let SDRAM CS1 start right after CS0 */
149         *(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize + 0x0000001c; /* 512MB */
150
151         /* find RAM size using SDRAM CS1 only */
152         sdram_start(0);
153         test1 = get_ram_size((long *)(CFG_SDRAM_BASE + dramsize), 0x20000000);
154         sdram_start(1);
155         test2 = get_ram_size((long *)(CFG_SDRAM_BASE + dramsize), 0x20000000);
156         if (test1 > test2) {
157                 sdram_start(0);
158                 dramsize2 = test1;
159         } else {
160                 dramsize2 = test2;
161         }
162
163         /* memory smaller than 1MB is impossible */
164         if (dramsize2 < (1 << 20)) {
165                 dramsize2 = 0;
166         }
167
168         /* set SDRAM CS1 size according to the amount of RAM found */
169         if (dramsize2 > 0) {
170                 *(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize
171                         | (0x13 + __builtin_ffs(dramsize2 >> 20) - 1);
172         } else {
173                 *(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize; /* disabled */
174         }
175
176 #else /* CFG_RAMBOOT */
177
178         /* retrieve size of memory connected to SDRAM CS0 */
179         dramsize = *(vu_long *)MPC5XXX_SDRAM_CS0CFG & 0xFF;
180         if (dramsize >= 0x13) {
181                 dramsize = (1 << (dramsize - 0x13)) << 20;
182         } else {
183                 dramsize = 0;
184         }
185
186         /* retrieve size of memory connected to SDRAM CS1 */
187         dramsize2 = *(vu_long *)MPC5XXX_SDRAM_CS1CFG & 0xFF;
188         if (dramsize2 >= 0x13) {
189                 dramsize2 = (1 << (dramsize2 - 0x13)) << 20;
190         } else {
191                 dramsize2 = 0;
192         }
193
194 #endif /* CFG_RAMBOOT */
195
196 /*      return dramsize + dramsize2; */
197         return dramsize;
198 }
199
200 #elif defined(CONFIG_MGT5100)
201
202 long int initdram (int board_type)
203 {
204         ulong dramsize = 0;
205 #ifndef CFG_RAMBOOT
206         ulong test1, test2;
207
208         /* setup and enable SDRAM chip selects */
209         *(vu_long *)MPC5XXX_SDRAM_START = 0x00000000;
210         *(vu_long *)MPC5XXX_SDRAM_STOP = 0x0000ffff;/* 2G */
211         *(vu_long *)MPC5XXX_ADDECR |= (1 << 22); /* Enable SDRAM */
212         __asm__ volatile ("sync");
213
214         /* setup config registers */
215         *(vu_long *)MPC5XXX_SDRAM_CONFIG1 = SDRAM_CONFIG1;
216         *(vu_long *)MPC5XXX_SDRAM_CONFIG2 = SDRAM_CONFIG2;
217
218         /* address select register */
219         *(vu_long *)MPC5XXX_SDRAM_XLBSEL = SDRAM_ADDRSEL;
220         __asm__ volatile ("sync");
221
222         /* find RAM size */
223         sdram_start(0);
224         test1 = get_ram_size((ulong *)CFG_SDRAM_BASE, 0x80000000);
225         sdram_start(1);
226         test2 = get_ram_size((ulong *)CFG_SDRAM_BASE, 0x80000000);
227         if (test1 > test2) {
228                 sdram_start(0);
229                 dramsize = test1;
230         } else {
231                 dramsize = test2;
232         }
233
234         /* set SDRAM end address according to size */
235         *(vu_long *)MPC5XXX_SDRAM_STOP = ((dramsize - 1) >> 15);
236
237 #else /* CFG_RAMBOOT */
238
239         /* Retrieve amount of SDRAM available */
240         dramsize = ((*(vu_long *)MPC5XXX_SDRAM_STOP + 1) << 15);
241
242 #endif /* CFG_RAMBOOT */
243
244         return dramsize;
245 }
246
247 #else
248 #error Neither CONFIG_MPC5200 or CONFIG_MGT5100 defined
249 #endif
250
251 int checkboard (void)
252 {
253 #if defined (CONFIG_AEVFIFO)
254         puts ("Board: AEVFIFO\n");
255         return 0;
256 #endif
257 #if defined (CONFIG_TQM5200_AA)
258         puts ("Board: TQM5200-AA (TQ-Components GmbH)\n");
259 #elif defined (CONFIG_TQM5200_AB)
260         puts ("Board: TQM5200-AB (TQ-Components GmbH)\n");
261 #elif defined (CONFIG_TQM5200_AC)
262         puts ("Board: TQM5200-AC (TQ-Components GmbH)\n");
263 #elif defined (CONFIG_TQM5200)
264         puts ("Board: TQM5200 (TQ-Components GmbH)\n");
265 #endif
266 #if defined (CONFIG_STK52XX)
267         puts ("       on a STK52XX baseboard\n");
268 #endif
269
270         return 0;
271 }
272
273 void flash_preinit(void)
274 {
275         /*
276          * Now, when we are in RAM, enable flash write
277          * access for detection process.
278          * Note that CS_BOOT cannot be cleared when
279          * executing in flash.
280          */
281 #if defined(CONFIG_MGT5100)
282         *(vu_long *)MPC5XXX_ADDECR &= ~(1 << 25); /* disable CS_BOOT */
283         *(vu_long *)MPC5XXX_ADDECR |= (1 << 16); /* enable CS0 */
284 #endif
285         *(vu_long *)MPC5XXX_BOOTCS_CFG &= ~0x1; /* clear RO */
286 }
287
288
289 #ifdef  CONFIG_PCI
290 static struct pci_controller hose;
291
292 extern void pci_mpc5xxx_init(struct pci_controller *);
293
294 void pci_init_board(void)
295 {
296         pci_mpc5xxx_init(&hose);
297 }
298 #endif
299
300 #if defined (CFG_CMD_IDE) && defined (CONFIG_IDE_RESET)
301
302 #if defined (CONFIG_MINIFAP)
303 #define SM501_POWER_MODE0_GATE          0x00000040UL
304 #define SM501_POWER_MODE1_GATE          0x00000048UL
305 #define POWER_MODE_GATE_GPIO_PWM_I2C    0x00000040UL
306 #define SM501_GPIO_DATA_DIR_HIGH        0x0001000CUL
307 #define SM501_GPIO_DATA_HIGH            0x00010004UL
308 #define SM501_GPIO_51                   0x00080000UL
309 #else
310 #define GPIO_PSC1_4     0x01000000UL
311 #endif
312
313 void init_ide_reset (void)
314 {
315         debug ("init_ide_reset\n");
316
317 #if defined (CONFIG_MINIFAP)
318         /* Configure GPIO_51 of the SM501 grafic controller as ATA reset */
319
320         /* enable GPIO control (in both power modes) */
321         *(vu_long *) (SM501_MMIO_BASE+SM501_POWER_MODE0_GATE) |=
322                 POWER_MODE_GATE_GPIO_PWM_I2C;
323         *(vu_long *) (SM501_MMIO_BASE+SM501_POWER_MODE1_GATE) |=
324                 POWER_MODE_GATE_GPIO_PWM_I2C;
325         /* configure GPIO51 as output */
326         *(vu_long *) (SM501_MMIO_BASE+SM501_GPIO_DATA_DIR_HIGH) |=
327                 SM501_GPIO_51;
328 #else
329         /* Configure PSC1_4 as GPIO output for ATA reset */
330         *(vu_long *) MPC5XXX_WU_GPIO_ENABLE |= GPIO_PSC1_4;
331         *(vu_long *) MPC5XXX_WU_GPIO_DIR    |= GPIO_PSC1_4;
332 #endif
333 }
334
335 void ide_set_reset (int idereset)
336 {
337         debug ("ide_reset(%d)\n", idereset);
338
339 #if defined (CONFIG_MINIFAP)
340         if (idereset) {
341                 *(vu_long *) (SM501_MMIO_BASE+SM501_GPIO_DATA_HIGH) &=
342                         ~SM501_GPIO_51;
343         } else {
344                 *(vu_long *) (SM501_MMIO_BASE+SM501_GPIO_DATA_HIGH) |=
345                         SM501_GPIO_51;
346         }
347 #else
348         if (idereset) {
349                 *(vu_long *) MPC5XXX_WU_GPIO_DATA &= ~GPIO_PSC1_4;
350         } else {
351                 *(vu_long *) MPC5XXX_WU_GPIO_DATA |=  GPIO_PSC1_4;
352         }
353 #endif
354 }
355 #endif /* defined (CFG_CMD_IDE) && defined (CONFIG_IDE_RESET) */
356
357 #ifdef CONFIG_POST
358 /*
359  * Reads GPIO pin PSC6_3. A keypress is reported, if PSC6_3 is low. If PSC6_3
360  * is left open, no keypress is detected.
361  */
362 int post_hotkeys_pressed(void)
363 {
364         struct mpc5xxx_gpio *gpio;
365
366         gpio = (struct mpc5xxx_gpio*) MPC5XXX_GPIO;
367
368         /*
369          * Configure PSC6_1 and PSC6_3 as GPIO. PSC6 then couldn't be used in
370          * CODEC or UART mode. Consumer IrDA should still be possible.
371          */
372         gpio->port_config &= ~(0x07000000);
373         gpio->port_config |=   0x03000000;
374
375         /* Enable GPIO for GPIO_IRDA_1 (IR_USB_CLK pin) = PSC6_3 */
376         gpio->simple_gpioe |= 0x20000000;
377
378         /* Configure GPIO_IRDA_1 as input */
379         gpio->simple_ddr &= ~(0x20000000);
380
381         return ((gpio->simple_ival & 0x20000000) ? 0 : 1);
382 }
383 #endif
384
385 #if defined(CONFIG_POST) || defined(CONFIG_LOGBUFFER)
386
387 void post_word_store (ulong a)
388 {
389         volatile ulong *save_addr =
390                 (volatile ulong *)(MPC5XXX_SRAM + MPC5XXX_SRAM_POST_SIZE);
391
392         *save_addr = a;
393 }
394
395 ulong post_word_load (void)
396 {
397         volatile ulong *save_addr =
398                 (volatile ulong *)(MPC5XXX_SRAM + MPC5XXX_SRAM_POST_SIZE);
399
400         return *save_addr;
401 }
402 #endif  /* CONFIG_POST || CONFIG_LOGBUFFER*/
403
404 #ifdef CONFIG_PS2MULT
405 #ifdef CONFIG_BOARD_EARLY_INIT_R
406 int board_early_init_r (void)
407 {
408         ps2mult_early_init();
409         return (0);
410 }
411 #endif
412 #endif /* CONFIG_PS2MULT */
413
414 #if defined(CONFIG_CS_AUTOCONF)
415 int last_stage_init (void)
416 {
417         /*
418          * auto scan for really existing devices and re-set chip select
419          * configuration.
420          */
421         u16 save, tmp;
422         int restore;
423
424         /*
425          * Check for SRAM and SRAM size
426          */
427
428         /* save original SRAM content  */
429         save = *(volatile u16 *)CFG_CS2_START;
430         restore = 1;
431
432         /* write test pattern to SRAM */
433         *(volatile u16 *)CFG_CS2_START = 0xA5A5;
434         __asm__ volatile ("sync");
435         /*
436          * Put a different pattern on the data lines: otherwise they may float
437          * long enough to read back what we wrote.
438          */
439         tmp = *(volatile u16 *)CFG_FLASH_BASE;
440         if (tmp == 0xA5A5)
441                 puts ("!! possible error in SRAM detection\n");
442
443         if (*(volatile u16 *)CFG_CS2_START != 0xA5A5) {
444                 /* no SRAM at all, disable cs */
445                 *(vu_long *)MPC5XXX_ADDECR &= ~(1 << 18);
446                 *(vu_long *)MPC5XXX_CS2_START = 0x0000FFFF;
447                 *(vu_long *)MPC5XXX_CS2_STOP = 0x0000FFFF;
448                 restore = 0;
449                 __asm__ volatile ("sync");
450         } else if (*(volatile u16 *)(CFG_CS2_START + (1<<19)) == 0xA5A5) {
451                 /* make sure that we access a mirrored address */
452                 *(volatile u16 *)CFG_CS2_START = 0x1111;
453                 __asm__ volatile ("sync");
454                 if (*(volatile u16 *)(CFG_CS2_START + (1<<19)) == 0x1111) {
455                         /* SRAM size = 512 kByte */
456                         *(vu_long *)MPC5XXX_CS2_STOP = STOP_REG(CFG_CS2_START,
457                                                                 0x80000);
458                         __asm__ volatile ("sync");
459                         puts ("SRAM:  512 kB\n");
460                 }
461                 else
462                         puts ("!! possible error in SRAM detection\n");
463         } else {
464                 puts ("SRAM:  1 MB\n");
465         }
466         /* restore origianl SRAM content  */
467         if (restore) {
468                 *(volatile u16 *)CFG_CS2_START = save;
469                 __asm__ volatile ("sync");
470         }
471
472         /*
473          * Check for Grafic Controller
474          */
475
476         /* save origianl FB content  */
477         save = *(volatile u16 *)CFG_CS1_START;
478         restore = 1;
479
480         /* write test pattern to FB memory */
481         *(volatile u16 *)CFG_CS1_START = 0xA5A5;
482         __asm__ volatile ("sync");
483         /*
484          * Put a different pattern on the data lines: otherwise they may float
485          * long enough to read back what we wrote.
486          */
487         tmp = *(volatile u16 *)CFG_FLASH_BASE;
488         if (tmp == 0xA5A5)
489                 puts ("!! possible error in grafic controller detection\n");
490
491         if (*(volatile u16 *)CFG_CS1_START != 0xA5A5) {
492                 /* no grafic controller at all, disable cs */
493                 *(vu_long *)MPC5XXX_ADDECR &= ~(1 << 17);
494                 *(vu_long *)MPC5XXX_CS1_START = 0x0000FFFF;
495                 *(vu_long *)MPC5XXX_CS1_STOP = 0x0000FFFF;
496                 restore = 0;
497                 __asm__ volatile ("sync");
498         } else {
499                 puts ("VGA:   SMI501 (Voyager) with 8 MB\n");
500         }
501         /* restore origianl FB content  */
502         if (restore) {
503                 *(volatile u16 *)CFG_CS1_START = save;
504                 __asm__ volatile ("sync");
505         }
506
507         return 0;
508 }
509 #endif /* CONFIG_CS_AUTOCONF */
510
511 #ifdef CONFIG_VIDEO_SM501
512
513 #define DISPLAY_WIDTH   640
514 #define DISPLAY_HEIGHT  480
515
516 #ifdef CONFIG_VIDEO_SM501_8BPP
517 #error CONFIG_VIDEO_SM501_8BPP not supported.
518 #endif /* CONFIG_VIDEO_SM501_8BPP */
519
520 #ifdef CONFIG_VIDEO_SM501_16BPP
521 #error CONFIG_VIDEO_SM501_16BPP not supported.
522 #endif /* CONFIG_VIDEO_SM501_16BPP */
523 #ifdef CONFIG_VIDEO_SM501_32BPP
524 static const SMI_REGS init_regs [] =
525 {
526 #if 0 /* CRT only */
527         {0x00004, 0x0},
528         {0x00048, 0x00021807},
529         {0x0004C, 0x10090a01},
530         {0x00054, 0x1},
531         {0x00040, 0x00021807},
532         {0x00044, 0x10090a01},
533         {0x00054, 0x0},
534         {0x80200, 0x00010000},
535         {0x80204, 0x0},
536         {0x80208, 0x0A000A00},
537         {0x8020C, 0x02fa027f},
538         {0x80210, 0x004a028b},
539         {0x80214, 0x020c01df},
540         {0x80218, 0x000201e9},
541         {0x80200, 0x00013306},
542 #else  /* panel + CRT */
543         {0x00004, 0x0},
544         {0x00048, 0x00021807},
545         {0x0004C, 0x091a0a01},
546         {0x00054, 0x1},
547         {0x00040, 0x00021807},
548         {0x00044, 0x091a0a01},
549         {0x00054, 0x0},
550         {0x80000, 0x0f013106},
551         {0x80004, 0xc428bb17},
552         {0x8000C, 0x00000000},
553         {0x80010, 0x0a000a00},
554         {0x80014, 0x02800000},
555         {0x80018, 0x01e00000},
556         {0x8001C, 0x00000000},
557         {0x80020, 0x01e00280},
558         {0x80024, 0x02fa027f},
559         {0x80028, 0x004a028b},
560         {0x8002C, 0x020c01df},
561         {0x80030, 0x000201e9},
562         {0x80200, 0x00010000},
563 #endif
564         {0, 0}
565 };
566 #endif /* CONFIG_VIDEO_SM501_32BPP */
567
568 #ifdef CONFIG_CONSOLE_EXTRA_INFO
569 /*
570  * Return text to be printed besides the logo.
571  */
572 void video_get_info_str (int line_number, char *info)
573 {
574         if (line_number == 1) {
575 #if defined (CONFIG_TQM5200_AA)
576                 strcpy (info, " Board: TQM5200-AA (TQ-Components GmbH)");
577 #elif defined (CONFIG_TQM5200_AB)
578                 strcpy (info, " Board: TQM5200-AB (TQ-Components GmbH)");
579 #elif defined (CONFIG_TQM5200_AC)
580                 strcpy (info, " Board: TQM5200-AC (TQ-Components GmbH)");
581 #elif defined (CONFIG_TQM5200)
582                 strcpy (info, " Board: TQM5200 (TQ-Components GmbH)");
583 #else
584 #error No supported board selected
585 #endif
586 #if defined (CONFIG_STK52XX)
587         } else if (line_number == 2) {
588                 strcpy (info, "        on a STK52XX baseboard");
589 #endif
590         }
591         else {
592                 info [0] = '\0';
593         }
594 }
595 #endif
596
597 /*
598  * Returns SM501 register base address. First thing called in the
599  * driver. Checks if SM501 is physically present.
600  */
601 unsigned int board_video_init (void)
602 {
603         u16 save, tmp;
604         int restore, ret;
605
606         /*
607          * Check for Grafic Controller
608          */
609
610         /* save origianl FB content  */
611         save = *(volatile u16 *)CFG_CS1_START;
612         restore = 1;
613
614         /* write test pattern to FB memory */
615         *(volatile u16 *)CFG_CS1_START = 0xA5A5;
616         __asm__ volatile ("sync");
617         /*
618          * Put a different pattern on the data lines: otherwise they may float
619          * long enough to read back what we wrote.
620          */
621         tmp = *(volatile u16 *)CFG_FLASH_BASE;
622         if (tmp == 0xA5A5)
623                 puts ("!! possible error in grafic controller detection\n");
624
625         if (*(volatile u16 *)CFG_CS1_START != 0xA5A5) {
626                 /* no grafic controller found */
627                 restore = 0;
628                 ret = 0;
629         } else {
630                 ret = SM501_MMIO_BASE;
631         }
632
633         if (restore) {
634                 *(volatile u16 *)CFG_CS1_START = save;
635                 __asm__ volatile ("sync");
636         }
637         return ret;
638 }
639
640 /*
641  * Returns SM501 framebuffer address
642  */
643 unsigned int board_video_get_fb (void)
644 {
645         return SM501_FB_BASE;
646 }
647
648 /*
649  * Called after initializing the SM501 and before clearing the screen.
650  */
651 void board_validate_screen (unsigned int base)
652 {
653 }
654
655 /*
656  * Return a pointer to the initialization sequence.
657  */
658 const SMI_REGS *board_get_regs (void)
659 {
660         return init_regs;
661 }
662
663 int board_get_width (void)
664 {
665         return DISPLAY_WIDTH;
666 }
667
668 int board_get_height (void)
669 {
670         return DISPLAY_HEIGHT;
671 }
672
673 #endif /* CONFIG_VIDEO_SM501 */