1 /* $NetBSD: radeonfb_bios.c,v 1.7 2022/09/25 17:52:25 thorpej Exp $ */
2 
3 /*-
4  * Copyright (c) 2006 Itronix Inc.
5  * All rights reserved.
6  *
7  * Written by Garrett D'Amore for Itronix Inc.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. The name of Itronix Inc. may not be used to endorse
18  *    or promote products derived from this software without specific
19  *    prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
25  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28  * ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 /*
35  * ATI Technologies Inc. ("ATI") has not assisted in the creation of, and
36  * does not endorse, this software.  ATI will not be responsible or liable
37  * for any actual or alleged damage or loss caused by or in connection with
38  * the use of or reliance on this software.
39  */
40 
41 #include <sys/cdefs.h>
42 __KERNEL_RCSID(0, "$NetBSD: radeonfb_bios.c,v 1.7 2022/09/25 17:52:25 thorpej Exp $");
43 
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/device.h>
47 #include <sys/bus.h>
48 
49 #include <dev/pci/pcidevs.h>
50 #include <dev/pci/pcireg.h>
51 #include <dev/pci/pcivar.h>
52 #include <dev/pci/radeonfbreg.h>
53 #include <dev/pci/radeonfbvar.h>
54 
55 #include "opt_radeonfb.h"
56 
57 #ifdef RADEONFB_BIOS_INIT
58 
59 /*
60  * Globals for the entire BIOS.
61  */
62 #define   ROM_HEADER_OFFSET             0x48
63 #define   MAX_REVISION                            0x10
64 #define   SINGLE_TABLE_REVISION                   0x09
65 #define   MIN_OFFSET                              0x60
66 
67 /*
68  * Offsets of specific tables.
69  */
70 #define   RAGE_REGS1_OFFSET             0x0c
71 #define   RAGE_REGS2_OFFSET             0x4e
72 #define   DYN_CLOCK_OFFSET              0x52
73 #define   PLL_INIT_OFFSET                         0x46
74 #define   MEM_CONFIG_OFFSET             0x48
75 
76 /*
77  * Values related to generic initialization tables.
78  */
79 #define   TABLE_ENTRY_FLAG_MASK                   0xe000
80 #define   TABLE_ENTRY_INDEX_MASK                  0x1fff
81 #define   TABLE_ENTRY_COMMAND_MASK      0x00ff
82 
83 #define   TABLE_FLAG_WRITE_INDEXED      0x0000
84 #define   TABLE_FLAG_WRITE_DIRECT                 0x2000
85 #define   TABLE_FLAG_MASK_INDEXED                 0x4000
86 #define   TABLE_FLAG_MASK_DIRECT                  0x6000
87 #define   TABLE_FLAG_DELAY              0x8000
88 #define   TABLE_FLAG_SCOMMAND           0xa000
89 
90 #define   TABLE_SCOMMAND_WAIT_MC_BUSY_MASK        0x03
91 #define   TABLE_SCOMMAND_WAIT_MEM_PWRUP_COMPLETE  0x08
92 
93 /*
94  * PLL initialization block values.
95  */
96 #define   PLL_FLAG_MASK                           0xc0
97 #define   PLL_INDEX_MASK                          0x3f
98 
99 #define   PLL_FLAG_WRITE                          0x00
100 #define   PLL_FLAG_MASK_BYTE            0x40
101 #define   PLL_FLAG_WAIT                           0x80
102 
103 #define   PLL_WAIT_150MKS                                   1
104 #define   PLL_WAIT_5MS                                      2
105 #define   PLL_WAIT_MC_BUSY_MASK                             3
106 #define   PLL_WAIT_DLL_READY_MASK                           4
107 #define   PLL_WAIT_CHK_SET_CLK_PWRMGT_CNTL24      5
108 
109 
110 #ifdef    RADEONFB_BIOS_DEBUG
111 #define   DPRINTF(x)          printf x
112 #else
113 #define   DPRINTF(x)
114 #endif
115 
116 struct rb_table;
117 
118 static void rb_validate(struct radeonfb_softc *, struct rb_table *);
119 static uint16_t rb_find_asic_table(struct radeonfb_softc *, struct rb_table *);
120 static uint16_t rb_find_mem_reset_table(struct radeonfb_softc *,
121     struct rb_table *);
122 static uint16_t rb_find_short_mem_reset_table(struct radeonfb_softc *,
123     struct rb_table *);
124 static int rb_load_init_block(struct radeonfb_softc *, struct rb_table *);
125 static int rb_load_pll_block(struct radeonfb_softc *, struct rb_table *);
126 static int rb_reset_sdram(struct radeonfb_softc *, struct rb_table *);
127 
128 static void rb_wait_mc_busy_mask(struct radeonfb_softc *, uint16_t);
129 static void rb_wait_mem_pwrup_complete(struct radeonfb_softc *, uint16_t);
130 static void rb_wait_dll_ready_mask(struct radeonfb_softc *, uint16_t);
131 static void rb_wait_chk_set_clk_pwrmgt_cntl24(struct radeonfb_softc *);
132 
133 /*
134  * Generic structure describing the tables.
135  */
136 struct rb_table {
137           const unsigned char *name;
138           uint16_t            offset;
139           struct rb_table     *parent;
140 
141           /* validate that the table looks sane */
142           void      (*validate)(struct radeonfb_softc *, struct rb_table *);
143 
144           /* find looks for the table relative to its "parent" */
145           uint16_t  (*find)(struct radeonfb_softc *, struct rb_table *);
146 };
147 
148 /*
149  * Instances of specific tables.
150  */
151 static struct rb_table rb_rage_regs1_table = {
152           "rage_regs_1",                          /* name */
153           RAGE_REGS1_OFFSET,            /* offset */
154           NULL,                                   /* parent */
155           rb_validate,                            /* validate */
156           NULL,                                   /* find */
157 };
158 
159 static struct rb_table rb_rage_regs2_table = {
160           "rage_regs_2",                          /* name */
161           RAGE_REGS2_OFFSET,            /* offset */
162           NULL,                                   /* parent */
163           rb_validate,                            /* validate */
164           NULL,                                   /* find */
165 };
166 
167 static struct rb_table rb_dyn_clock_table = {
168           "dyn_clock",                            /* name */
169           DYN_CLOCK_OFFSET,             /* offset */
170           NULL,                                   /* parent */
171           rb_validate,                            /* validate */
172           NULL,                                   /* find */
173 };
174 
175 static struct rb_table rb_pll_init_table = {
176           "pll_init",                             /* name */
177           PLL_INIT_OFFSET,              /* offset */
178           NULL,                                   /* parent */
179           rb_validate,                            /* validate */
180           NULL,                                   /* find */
181 };
182 
183 static struct rb_table rb_mem_config_table = {
184           "mem_config",                           /* name */
185           MEM_CONFIG_OFFSET,            /* offset */
186           NULL,                                   /* parent */
187           rb_validate,                            /* validate */
188           NULL,                                   /* find */
189 };
190 
191 static struct rb_table rb_mem_reset_table = {
192           "mem_reset",                            /* name */
193           0,                                      /* offset */
194           &rb_mem_config_table,                   /* parent */
195           NULL,                                   /* validate */
196           rb_find_mem_reset_table,      /* find */
197 };
198 
199 static struct rb_table rb_short_mem_reset_table = {
200           "short_mem_reset",            /* name */
201           0,                                      /* offset */
202           &rb_mem_config_table,                   /* parent */
203           NULL,                                   /* validate */
204           rb_find_short_mem_reset_table,          /* find */
205 };
206 
207 static struct rb_table rb_rage_regs3_table = {
208           "rage_regs_3",                          /* name */
209           0,                                      /* offset */
210           &rb_rage_regs2_table,                   /* parent */
211           NULL,                                   /* validate */
212           rb_find_asic_table,           /* find */
213 };
214 
215 static struct rb_table rb_rage_regs4_table = {
216           "rage_regs_4",                          /* name */
217           0,                                      /* offset */
218           &rb_rage_regs3_table,                   /* parent */
219           NULL,                                   /* validate */
220           rb_find_asic_table,           /* find */
221 };
222 
223 static struct rb_table *rb_tables[] = {
224           &rb_rage_regs1_table,
225           &rb_rage_regs2_table,
226           &rb_dyn_clock_table,
227           &rb_pll_init_table,
228           &rb_mem_config_table,
229           &rb_mem_reset_table,
230           &rb_short_mem_reset_table,
231           &rb_rage_regs3_table,
232           &rb_rage_regs4_table,
233           NULL
234 };
235 
236 void
rb_validate(struct radeonfb_softc * sc,struct rb_table * tp)237 rb_validate(struct radeonfb_softc *sc, struct rb_table *tp)
238 {
239           uint8_t   rev;
240 
241           rev = GETBIOS8(sc, tp->offset - 1);
242 
243           if (rev > MAX_REVISION) {
244                     DPRINTF(("%s: bad rev %x of %s\n", XNAME(sc), rev, tp->name));
245                     tp->offset = 0;
246                     return;
247           }
248 
249           if (tp->offset < MIN_OFFSET) {
250                     DPRINTF(("%s: wrong pointer to %s!\n", XNAME(sc), tp->name));
251                     tp->offset = 0;
252                     return;
253           }
254 }
255 
256 uint16_t
rb_find_asic_table(struct radeonfb_softc * sc,struct rb_table * tp)257 rb_find_asic_table(struct radeonfb_softc *sc, struct rb_table *tp)
258 {
259           uint16_t            offset;
260           uint8_t                       c;
261 
262           if ((offset = tp->offset) != 0) {
263                     while ((c = GETBIOS8(sc, offset + 1)) != 0) {
264                               if (c & 0x40)
265                                         offset += 10;
266                               else if (c & 0x80)
267                                         offset += 4;
268                               else
269                                         offset += 6;
270                     }
271                     return offset + 2;
272           }
273           return 0;
274 }
275 
276 uint16_t
rb_find_mem_reset_table(struct radeonfb_softc * sc,struct rb_table * tp)277 rb_find_mem_reset_table(struct radeonfb_softc *sc, struct rb_table *tp)
278 {
279           uint16_t            offset;
280 
281           if ((offset = tp->offset) != 0) {
282                     while (GETBIOS8(sc, offset))
283                               offset++;
284                     offset++;
285                     return offset + 2;  /* skip table revision and mask */
286           }
287           return 0;
288 }
289 
290 uint16_t
rb_find_short_mem_reset_table(struct radeonfb_softc * sc,struct rb_table * tp)291 rb_find_short_mem_reset_table(struct radeonfb_softc *sc, struct rb_table *tp)
292 {
293 
294           if ((tp->offset != 0) && (GETBIOS8(sc, tp->offset - 2) <= 64))
295                     return (tp->offset + GETBIOS8(sc, tp->offset - 3));
296 
297           return 0;
298 }
299 
300 /* helper commands */
301 void
rb_wait_mc_busy_mask(struct radeonfb_softc * sc,uint16_t count)302 rb_wait_mc_busy_mask(struct radeonfb_softc *sc, uint16_t count)
303 {
304           DPRINTF(("WAIT_MC_BUSY_MASK: %d ", count));
305           while (count--) {
306                     if (!(radeonfb_getpll(sc, RADEON_CLK_PWRMGT_CNTL) &
307                               RADEON_MC_BUSY))
308                               break;
309           }
310           DPRINTF(("%d\n", count));
311 }
312 
313 void
rb_wait_mem_pwrup_complete(struct radeonfb_softc * sc,uint16_t count)314 rb_wait_mem_pwrup_complete(struct radeonfb_softc *sc, uint16_t count)
315 {
316           DPRINTF(("WAIT_MEM_PWRUP_COMPLETE: %d ", count));
317           while (count--) {
318                     if ((radeonfb_getindex(sc, RADEON_MEM_STR_CNTL) &
319                               RADEON_MEM_PWRUP_COMPLETE) ==
320                         RADEON_MEM_PWRUP_COMPLETE)
321                               break;
322           }
323           DPRINTF(("%d\n", count));
324 }
325 
326 void
rb_wait_dll_ready_mask(struct radeonfb_softc * sc,uint16_t count)327 rb_wait_dll_ready_mask(struct radeonfb_softc *sc, uint16_t count)
328 {
329           DPRINTF(("WAIT_DLL_READY_MASK: %d ", count));
330           while (count--) {
331                     if (radeonfb_getpll(sc, RADEON_CLK_PWRMGT_CNTL) &
332                         RADEON_DLL_READY)
333                               break;
334           }
335           DPRINTF(("%d\n", count));
336 }
337 
338 void
rb_wait_chk_set_clk_pwrmgt_cntl24(struct radeonfb_softc * sc)339 rb_wait_chk_set_clk_pwrmgt_cntl24(struct radeonfb_softc *sc)
340 {
341           uint32_t  pmc;
342           DPRINTF(("WAIT CHK_SET_CLK_PWRMGT_CNTL24\n"));
343           pmc = radeonfb_getpll(sc, RADEON_CLK_PWRMGT_CNTL);
344 
345           if (pmc & RADEON_CLK_PWRMGT_CNTL24) {
346                     radeonfb_maskpll(sc, RADEON_MCLK_CNTL, 0xFFFF0000,
347                         RADEON_SET_ALL_SRCS_TO_PCI);
348                     delay(10000);
349                     radeonfb_putpll(sc, RADEON_CLK_PWRMGT_CNTL,
350                         pmc & ~RADEON_CLK_PWRMGT_CNTL24);
351                     delay(10000);
352           }
353 }
354 
355 /*
356  * Block initialization routines.  These take action based on data in
357  * the tables.
358  */
359 int
rb_load_init_block(struct radeonfb_softc * sc,struct rb_table * tp)360 rb_load_init_block(struct radeonfb_softc *sc, struct rb_table *tp)
361 {
362           uint16_t  offset;
363           uint16_t  value;
364 
365           if ((tp == NULL) || ((offset = tp->offset) == 0))
366                     return 1;
367 
368           DPRINTF(("%s: load_init_block processing %s\n", XNAME(sc), tp->name));
369           while ((value = GETBIOS16(sc, offset)) != 0) {
370                     uint16_t  flag = value & TABLE_ENTRY_FLAG_MASK;
371                     uint16_t  index = value & TABLE_ENTRY_INDEX_MASK;
372                     uint8_t             command = value & TABLE_ENTRY_COMMAND_MASK;
373                     uint32_t  ormask;
374                     uint32_t  andmask;
375                     uint16_t  count;
376 
377                     offset += 2;
378 
379                     switch (flag) {
380                     case TABLE_FLAG_WRITE_INDEXED:
381                               DPRINTF(("WRITE INDEXED: %x %x\n",
382                                             index, (uint32_t)GETBIOS32(sc, offset)));
383                               radeonfb_putindex(sc, index, GETBIOS32(sc, offset));
384                               offset += 4;
385                               break;
386 
387                     case TABLE_FLAG_WRITE_DIRECT:
388                               DPRINTF(("WRITE DIRECT: %x %x\n",
389                                             index, (uint32_t)GETBIOS32(sc, offset)));
390                               radeonfb_put32(sc, index, GETBIOS32(sc, offset));
391                               offset += 4;
392                               break;
393 
394                     case TABLE_FLAG_MASK_INDEXED:
395                               andmask = GETBIOS32(sc, offset);
396                               offset += 4;
397                               ormask = GETBIOS32(sc, offset);
398                               offset += 4;
399                               DPRINTF(("MASK INDEXED: %x %x %x\n",
400                                             index, andmask, ormask));
401                               radeonfb_maskindex(sc, index, andmask, ormask);
402                               break;
403 
404                     case TABLE_FLAG_MASK_DIRECT:
405                               andmask = GETBIOS32(sc, offset);
406                               offset += 4;
407                               ormask = GETBIOS32(sc, offset);
408                               offset += 4;
409                               DPRINTF(("MASK DIRECT: %x %x %x\n",
410                                             index, andmask, ormask));
411                               radeonfb_mask32(sc, index,  andmask, ormask);
412                               break;
413 
414                     case TABLE_FLAG_DELAY:
415                               /* in the worst case, this would be 16msec */
416                               count = GETBIOS16(sc, offset);
417                               DPRINTF(("DELAY: %d\n", count));
418                               delay(count);
419                               offset += 2;
420                               break;
421 
422                     case TABLE_FLAG_SCOMMAND:
423                               DPRINTF(("SCOMMAND %x\n", command));
424                               switch (command) {
425 
426                               case TABLE_SCOMMAND_WAIT_MC_BUSY_MASK:
427                                         count = GETBIOS16(sc, offset);
428                                         rb_wait_mc_busy_mask(sc, count);
429                                         break;
430 
431                               case TABLE_SCOMMAND_WAIT_MEM_PWRUP_COMPLETE:
432                                         count = GETBIOS16(sc, offset);
433                                         rb_wait_mem_pwrup_complete(sc, count);
434                                         break;
435 
436                               }
437                               offset += 2;
438                               break;
439                     }
440           }
441           return 0;
442 }
443 
444 int
rb_load_pll_block(struct radeonfb_softc * sc,struct rb_table * tp)445 rb_load_pll_block(struct radeonfb_softc *sc, struct rb_table *tp)
446 {
447           uint16_t  offset;
448           uint8_t             index;
449           uint8_t             shift;
450           uint32_t  andmask;
451           uint32_t  ormask;
452 
453           if ((tp == NULL) || ((offset = tp->offset) == 0))
454                     return 1;
455 
456           DPRINTF(("%s: load_pll_block processing %s\n", XNAME(sc), tp->name));
457           while ((index = GETBIOS8(sc, offset)) != 0) {
458                     offset++;
459 
460                     switch (index & PLL_FLAG_MASK) {
461                     case PLL_FLAG_WAIT:
462                               switch (index & PLL_INDEX_MASK) {
463                               case PLL_WAIT_150MKS:
464                                         delay(150);
465                                         break;
466                               case PLL_WAIT_5MS:
467                                         /* perhaps this should be tsleep? */
468                                         delay(5000);
469                                         break;
470 
471                               case PLL_WAIT_MC_BUSY_MASK:
472                                         rb_wait_mc_busy_mask(sc, 1000);
473                                         break;
474 
475                               case PLL_WAIT_DLL_READY_MASK:
476                                         rb_wait_dll_ready_mask(sc, 1000);
477                                         break;
478 
479                               case PLL_WAIT_CHK_SET_CLK_PWRMGT_CNTL24:
480                                         rb_wait_chk_set_clk_pwrmgt_cntl24(sc);
481                                         break;
482                               }
483                               break;
484 
485                     case PLL_FLAG_MASK_BYTE:
486                               shift = GETBIOS8(sc, offset) * 8;
487                               offset++;
488 
489                               andmask =
490                                   (((uint32_t)GETBIOS8(sc, offset)) << shift) |
491                                   ~((uint32_t)0xff << shift);
492                               offset++;
493 
494                               ormask = ((uint32_t)GETBIOS8(sc, offset)) << shift;
495                               offset++;
496 
497                               DPRINTF(("PLL_MASK_BYTE %u %u %x %x\n", index,
498                                             shift, andmask, ormask));
499                               radeonfb_maskpll(sc, index, andmask, ormask);
500                               break;
501 
502                     case PLL_FLAG_WRITE:
503                               DPRINTF(("PLL_WRITE %u %x\n", index,
504                                             GETBIOS32(sc, offset)));
505                               radeonfb_putpll(sc, index, GETBIOS32(sc, offset));
506                               offset += 4;
507                               break;
508                     }
509           }
510 
511           return 0;
512 }
513 
514 int
rb_reset_sdram(struct radeonfb_softc * sc,struct rb_table * tp)515 rb_reset_sdram(struct radeonfb_softc *sc, struct rb_table *tp)
516 {
517           uint16_t offset;
518           uint8_t   index;
519 
520           if ((tp == NULL) || ((offset = tp->offset) == 0))
521                     return 1;
522 
523           DPRINTF(("%s: reset_sdram processing %s\n", XNAME(sc), tp->name));
524 
525           while ((index = GETBIOS8(sc, offset)) != 0xff) {
526                     offset++;
527                     if (index == 0x0f) {
528                               rb_wait_mem_pwrup_complete(sc, 20000);
529                     } else {
530                               uint32_t  ormask;
531 
532                               ormask = GETBIOS16(sc, offset);
533                               offset += 2;
534 
535                               DPRINTF(("INDEX reg RADEON_MEM_SDRAM_MODE_REG %x %x\n",
536                                             RADEON_SDRAM_MODE_MASK, ormask));
537                               radeonfb_maskindex(sc, RADEON_MEM_SDRAM_MODE_REG,
538                                   RADEON_SDRAM_MODE_MASK, ormask);
539 
540                               ormask = (uint32_t)index << 24;
541                               DPRINTF(("INDEX reg RADEON_MEM_SDRAM_MODE_REG %x %x\n",
542                                             RADEON_B3MEM_RESET_MASK, ormask));
543                               radeonfb_maskindex(sc, RADEON_MEM_SDRAM_MODE_REG,
544                                   RADEON_B3MEM_RESET_MASK, ormask);
545                     }
546           }
547           return 0;
548 }
549 
550 /*
551  * Master entry point to parse and act on table data.
552  */
553 int
radeonfb_bios_init(struct radeonfb_softc * sc)554 radeonfb_bios_init(struct radeonfb_softc *sc)
555 {
556           uint16_t            revision;
557           uint16_t            scratch;
558           int                           i;
559           struct rb_table               *tp;
560 
561           if (!sc->sc_biossz)
562                     return 1;
563 
564           scratch = GETBIOS16(sc, ROM_HEADER_OFFSET);
565           revision = GETBIOS8(sc, scratch);
566           DPRINTF(("%s: Bios Rev: %d\n", XNAME(sc), revision));
567 
568 
569           /* First parse pass -- locate tables  */
570           for (i = 0; (tp = rb_tables[i]) != NULL; i++) {
571 
572                     DPRINTF(("%s: parsing table %s\n", XNAME(sc), tp->name));
573 
574                     if (tp->offset != 0) {
575                               uint16_t  temp, offset;
576 
577                               temp = GETBIOS16(sc, ROM_HEADER_OFFSET);
578                               offset = GETBIOS16(sc, temp + tp->offset);
579                               if (offset)
580                                         tp->offset = offset;
581 
582                     } else {
583                               tp->offset = tp->find(sc, tp->parent);
584                     }
585 
586                     if (tp->validate)
587                               tp->validate(sc, tp);
588 
589                     if (revision > SINGLE_TABLE_REVISION)
590                               break;
591           }
592 
593           if (rb_rage_regs3_table.offset + 1 == rb_pll_init_table.offset) {
594                     rb_rage_regs3_table.offset = 0;
595                     rb_rage_regs4_table.offset = 0;
596           }
597 
598           if (rb_rage_regs1_table.offset)
599                     rb_load_init_block(sc, &rb_rage_regs1_table);
600 
601           if (revision < SINGLE_TABLE_REVISION) {
602                     if (rb_pll_init_table.offset)
603                               rb_load_pll_block(sc, &rb_pll_init_table);
604                     if (rb_rage_regs2_table.offset)
605                               rb_load_init_block(sc, &rb_rage_regs2_table);
606                     if (rb_rage_regs4_table.offset)
607                               rb_load_init_block(sc, &rb_rage_regs4_table);
608                     if (rb_mem_reset_table.offset)
609                               rb_reset_sdram(sc, &rb_mem_reset_table);
610                     if (rb_rage_regs3_table.offset)
611                               rb_load_init_block(sc, &rb_rage_regs3_table);
612                     if (rb_dyn_clock_table.offset)
613                               rb_load_pll_block(sc, &rb_dyn_clock_table);
614           }
615 
616           DPRINTF(("%s: BIOS parse done\n", XNAME(sc)));
617           return 0;
618 }
619 
620 #endif
621