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