6 #include <asm/pci-bridge.h>
7 #endif /* CONFIG_PPC_OF */
9 static struct fb_var_screeninfo radeonfb_default_var = {
10 640, 480, 640, 480, 0, 0, 8, 0,
11 {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
12 0, 0, -1, -1, 0, 39721, 40, 24, 32, 11, 96, 2,
13 0, FB_VMODE_NONINTERLACED
16 static char *radeon_get_mon_name(int type)
47 * Try to find monitor informations & EDID data out of the Open Firmware
48 * device-tree. This also contains some "hacks" to work around a few machine
49 * models with broken OF probing by hard-coding known EDIDs for some Mac
50 * laptops internal LVDS panel. (XXX: not done yet)
52 static int __devinit radeon_parse_montype_prop(struct device_node *dp, u8 **out_EDID, int hdno)
54 static char *propnames[] = { "DFP,EDID", "LCD,EDID", "EDID", "EDID1", "EDID2", NULL };
60 RTRACE("analyzing OF properties...\n");
61 pmt = (u8 *)get_property(dp, "display-type", NULL);
64 RTRACE("display-type: %s\n", pmt);
65 /* OF says "LCD" for DFP as well, we discriminate from the caller of this
68 if (!strcmp(pmt, "LCD") || !strcmp(pmt, "DFP"))
70 else if (!strcmp(pmt, "CRT"))
72 else if (strcmp(pmt, "NONE")) {
73 printk(KERN_WARNING "radeonfb: Unknown OF display-type: %s\n", pmt);
76 for (i = 0; propnames[i] != NULL; ++i) {
77 pedid = (u8 *)get_property(dp, propnames[i], NULL);
81 /* We didn't find the EDID in the leaf node, some cards will actually
82 * put EDID1/EDID2 in the parent, look for these (typically M6 tipb).
83 * single-head cards have hdno == -1 and skip this step
85 if (pedid == NULL && dp->parent && (hdno != -1))
86 pedid = get_property(dp->parent, (hdno == 0) ? "EDID1" : "EDID2", NULL);
87 if (pedid == NULL && dp->parent && (hdno == 0))
88 pedid = get_property(dp->parent, "EDID", NULL);
92 tmp = (u8 *)kmalloc(EDID_LENGTH, GFP_KERNEL);
95 memcpy(tmp, pedid, EDID_LENGTH);
100 static int __devinit radeon_probe_OF_head(struct radeonfb_info *rinfo, int head_no,
103 struct device_node *dp;
105 RTRACE("radeon_probe_OF_head\n");
107 dp = pci_device_to_OF_node(rinfo->pdev);
111 if (rinfo->has_CRTC2) {
119 pname = (char *)get_property(dp, "name", NULL);
123 RTRACE("head: %s (letter: %c, head_no: %d)\n",
124 pname, pname[len-1], head_no);
125 if (pname[len-1] == 'A' && head_no == 0) {
126 int mt = radeon_parse_montype_prop(dp, out_EDID, 0);
127 /* Maybe check for LVDS_GEN_CNTL here ? I need to check out
128 * what OF does when booting with lid closed
130 if (mt == MT_DFP && rinfo->is_mobility)
133 } else if (pname[len-1] == 'B' && head_no == 1)
134 return radeon_parse_montype_prop(dp, out_EDID, 1);
141 return radeon_parse_montype_prop(dp, out_EDID, -1);
145 #endif /* CONFIG_PPC_OF */
148 static int __devinit radeon_get_panel_info_BIOS(struct radeonfb_info *rinfo)
150 unsigned long tmp, tmp0;
154 if (!rinfo->bios_seg)
157 if (!(tmp = BIOS_IN16(rinfo->fp_bios_start + 0x40))) {
158 printk(KERN_ERR "radeonfb: Failed to detect DFP panel info using BIOS\n");
159 rinfo->panel_info.pwr_delay = 200;
164 stmp[i] = BIOS_IN8(tmp+i+1);
166 printk("radeonfb: panel ID string: %s\n", stmp);
167 rinfo->panel_info.xres = BIOS_IN16(tmp + 25);
168 rinfo->panel_info.yres = BIOS_IN16(tmp + 27);
169 printk("radeonfb: detected LVDS panel size from BIOS: %dx%d\n",
170 rinfo->panel_info.xres, rinfo->panel_info.yres);
172 rinfo->panel_info.pwr_delay = BIOS_IN16(tmp + 44);
173 RTRACE("BIOS provided panel power delay: %d\n", rinfo->panel_info.pwr_delay);
174 if (rinfo->panel_info.pwr_delay > 2000 || rinfo->panel_info.pwr_delay <= 0)
175 rinfo->panel_info.pwr_delay = 2000;
178 * Some panels only work properly with some divider combinations
180 rinfo->panel_info.ref_divider = BIOS_IN16(tmp + 46);
181 rinfo->panel_info.post_divider = BIOS_IN8(tmp + 48);
182 rinfo->panel_info.fbk_divider = BIOS_IN16(tmp + 49);
183 if (rinfo->panel_info.ref_divider != 0 &&
184 rinfo->panel_info.fbk_divider > 3) {
185 rinfo->panel_info.use_bios_dividers = 1;
186 printk(KERN_INFO "radeondb: BIOS provided dividers will be used\n");
187 RTRACE("ref_divider = %x\n", rinfo->panel_info.ref_divider);
188 RTRACE("post_divider = %x\n", rinfo->panel_info.post_divider);
189 RTRACE("fbk_divider = %x\n", rinfo->panel_info.fbk_divider);
191 RTRACE("Scanning BIOS table ...\n");
192 for(i=0; i<32; i++) {
193 tmp0 = BIOS_IN16(tmp+64+i*2);
196 RTRACE(" %d x %d\n", BIOS_IN16(tmp0), BIOS_IN16(tmp0+2));
197 if ((BIOS_IN16(tmp0) == rinfo->panel_info.xres) &&
198 (BIOS_IN16(tmp0+2) == rinfo->panel_info.yres)) {
199 rinfo->panel_info.hblank = (BIOS_IN16(tmp0+17) - BIOS_IN16(tmp0+19)) * 8;
200 rinfo->panel_info.hOver_plus = ((BIOS_IN16(tmp0+21) -
201 BIOS_IN16(tmp0+19) -1) * 8) & 0x7fff;
202 rinfo->panel_info.hSync_width = BIOS_IN8(tmp0+23) * 8;
203 rinfo->panel_info.vblank = BIOS_IN16(tmp0+24) - BIOS_IN16(tmp0+26);
204 rinfo->panel_info.vOver_plus = (BIOS_IN16(tmp0+28) & 0x7ff) - BIOS_IN16(tmp0+26);
205 rinfo->panel_info.vSync_width = (BIOS_IN16(tmp0+28) & 0xf800) >> 11;
206 rinfo->panel_info.clock = BIOS_IN16(tmp0+9);
207 /* Assume high active syncs for now until ATI tells me more... maybe we
208 * can probe register values here ?
210 rinfo->panel_info.hAct_high = 1;
211 rinfo->panel_info.vAct_high = 1;
212 /* Mark panel infos valid */
213 rinfo->panel_info.valid = 1;
215 RTRACE("Found panel in BIOS table:\n");
216 RTRACE(" hblank: %d\n", rinfo->panel_info.hblank);
217 RTRACE(" hOver_plus: %d\n", rinfo->panel_info.hOver_plus);
218 RTRACE(" hSync_width: %d\n", rinfo->panel_info.hSync_width);
219 RTRACE(" vblank: %d\n", rinfo->panel_info.vblank);
220 RTRACE(" vOver_plus: %d\n", rinfo->panel_info.vOver_plus);
221 RTRACE(" vSync_width: %d\n", rinfo->panel_info.vSync_width);
222 RTRACE(" clock: %d\n", rinfo->panel_info.clock);
227 RTRACE("Didn't find panel in BIOS table !\n");
232 /* Try to extract the connector informations from the BIOS. This
233 * doesn't quite work yet, but it's output is still useful for
236 static void __devinit radeon_parse_connector_info(struct radeonfb_info *rinfo)
238 int offset, chips, connectors, tmp, i, conn, type;
240 static char* __conn_type_table[16] = {
241 "NONE", "Proprietary", "CRT", "DVI-I", "DVI-D", "Unknown", "Unknown",
242 "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown",
243 "Unknown", "Unknown", "Unknown"
246 if (!rinfo->bios_seg)
249 offset = BIOS_IN16(rinfo->fp_bios_start + 0x50);
251 printk(KERN_WARNING "radeonfb: No connector info table detected\n");
255 /* Don't do much more at this point but displaying the data if
258 chips = BIOS_IN8(offset++) >> 4;
259 RTRACE("%d chips in connector info\n", chips);
260 for (i = 0; i < chips; i++) {
261 tmp = BIOS_IN8(offset++);
262 connectors = tmp & 0x0f;
263 RTRACE(" - chip %d has %d connectors\n", tmp >> 4, connectors);
264 for (conn = 0; ; conn++) {
265 tmp = BIOS_IN16(offset);
269 type = (tmp >> 12) & 0x0f;
270 RTRACE(" * connector %d of type %d (%s) : %04x\n",
271 conn, type, __conn_type_table[type], tmp);
278 * Probe physical connection of a CRT. This code comes from XFree
279 * as well and currently is only implemented for the CRT DAC, the
280 * code for the TVDAC is commented out in XFree as "non working"
282 static int __devinit radeon_crt_is_connected(struct radeonfb_info *rinfo, int is_crt_dac)
286 /* the monitor either wasn't connected or it is a non-DDC CRT.
290 unsigned long ulOrigVCLK_ECP_CNTL;
291 unsigned long ulOrigDAC_CNTL;
292 unsigned long ulOrigDAC_EXT_CNTL;
293 unsigned long ulOrigCRTC_EXT_CNTL;
294 unsigned long ulData;
295 unsigned long ulMask;
297 ulOrigVCLK_ECP_CNTL = INPLL(VCLK_ECP_CNTL);
299 ulData = ulOrigVCLK_ECP_CNTL;
300 ulData &= ~(PIXCLK_ALWAYS_ONb
301 | PIXCLK_DAC_ALWAYS_ONb);
302 ulMask = ~(PIXCLK_ALWAYS_ONb
303 | PIXCLK_DAC_ALWAYS_ONb);
304 OUTPLLP(VCLK_ECP_CNTL, ulData, ulMask);
306 ulOrigCRTC_EXT_CNTL = INREG(CRTC_EXT_CNTL);
307 ulData = ulOrigCRTC_EXT_CNTL;
308 ulData |= CRTC_CRT_ON;
309 OUTREG(CRTC_EXT_CNTL, ulData);
311 ulOrigDAC_EXT_CNTL = INREG(DAC_EXT_CNTL);
312 ulData = ulOrigDAC_EXT_CNTL;
313 ulData &= ~DAC_FORCE_DATA_MASK;
314 ulData |= (DAC_FORCE_BLANK_OFF_EN
316 |DAC_FORCE_DATA_SEL_MASK);
317 if ((rinfo->family == CHIP_FAMILY_RV250) ||
318 (rinfo->family == CHIP_FAMILY_RV280))
319 ulData |= (0x01b6 << DAC_FORCE_DATA_SHIFT);
321 ulData |= (0x01ac << DAC_FORCE_DATA_SHIFT);
323 OUTREG(DAC_EXT_CNTL, ulData);
325 ulOrigDAC_CNTL = INREG(DAC_CNTL);
326 ulData = ulOrigDAC_CNTL;
327 ulData |= DAC_CMP_EN;
328 ulData &= ~(DAC_RANGE_CNTL_MASK
331 OUTREG(DAC_CNTL, ulData);
335 ulData = INREG(DAC_CNTL);
336 connected = (DAC_CMP_OUTPUT & ulData) ? 1 : 0;
338 ulData = ulOrigVCLK_ECP_CNTL;
339 ulMask = 0xFFFFFFFFL;
340 OUTPLLP(VCLK_ECP_CNTL, ulData, ulMask);
342 OUTREG(DAC_CNTL, ulOrigDAC_CNTL );
343 OUTREG(DAC_EXT_CNTL, ulOrigDAC_EXT_CNTL );
344 OUTREG(CRTC_EXT_CNTL, ulOrigCRTC_EXT_CNTL);
347 return connected ? MT_CRT : MT_NONE;
351 * Parse the "monitor_layout" string if any. This code is mostly
352 * copied from XFree's radeon driver
354 static int __devinit radeon_parse_monitor_layout(struct radeonfb_info *rinfo,
355 const char *monitor_layout)
358 int i = 0, second = 0;
391 if (strcmp(s1, "CRT") == 0)
392 rinfo->mon1_type = MT_CRT;
393 else if (strcmp(s1, "TMDS") == 0)
394 rinfo->mon1_type = MT_DFP;
395 else if (strcmp(s1, "LVDS") == 0)
396 rinfo->mon1_type = MT_LCD;
398 if (strcmp(s2, "CRT") == 0)
399 rinfo->mon2_type = MT_CRT;
400 else if (strcmp(s2, "TMDS") == 0)
401 rinfo->mon2_type = MT_DFP;
402 else if (strcmp(s2, "LVDS") == 0)
403 rinfo->mon2_type = MT_LCD;
409 * Probe display on both primary and secondary card's connector (if any)
410 * by various available techniques (i2c, OF device tree, BIOS, ...) and
411 * try to retreive EDID. The algorithm here comes from XFree's radeon
414 void __devinit radeon_probe_screens(struct radeonfb_info *rinfo,
415 const char *monitor_layout, int ignore_edid)
417 #ifdef CONFIG_FB_RADEON_I2C
418 int ddc_crt2_used = 0;
422 radeon_parse_connector_info(rinfo);
424 if (radeon_parse_monitor_layout(rinfo, monitor_layout)) {
427 * If user specified a monitor_layout option, use it instead
428 * of auto-detecting. Maybe we should only use this argument
429 * on the first radeon card probed or provide a way to specify
430 * a layout for each card ?
433 RTRACE("Using specified monitor layout: %s", monitor_layout);
434 #ifdef CONFIG_FB_RADEON_I2C
436 if (rinfo->mon1_type != MT_NONE)
437 if (!radeon_probe_i2c_connector(rinfo, ddc_dvi, &rinfo->mon1_EDID)) {
438 radeon_probe_i2c_connector(rinfo, ddc_crt2, &rinfo->mon1_EDID);
441 if (rinfo->mon2_type != MT_NONE)
442 if (!radeon_probe_i2c_connector(rinfo, ddc_vga, &rinfo->mon2_EDID) &&
444 radeon_probe_i2c_connector(rinfo, ddc_crt2, &rinfo->mon2_EDID);
446 #endif /* CONFIG_FB_RADEON_I2C */
447 if (rinfo->mon1_type == MT_NONE) {
448 if (rinfo->mon2_type != MT_NONE) {
449 rinfo->mon1_type = rinfo->mon2_type;
450 rinfo->mon1_EDID = rinfo->mon2_EDID;
452 rinfo->mon1_type = MT_CRT;
453 printk(KERN_INFO "radeonfb: No valid monitor, assuming CRT on first port\n");
455 rinfo->mon2_type = MT_NONE;
456 rinfo->mon2_EDID = NULL;
460 * Auto-detecting display type (well... trying to ...)
463 RTRACE("Starting monitor auto detection...\n");
465 #if DEBUG && defined(CONFIG_FB_RADEON_I2C)
467 u8 *EDIDs[4] = { NULL, NULL, NULL, NULL };
468 int mon_types[4] = {MT_NONE, MT_NONE, MT_NONE, MT_NONE};
471 for (i = 0; i < 4; i++)
472 mon_types[i] = radeon_probe_i2c_connector(rinfo,
477 * Old single head cards
479 if (!rinfo->has_CRTC2) {
481 if (rinfo->mon1_type == MT_NONE)
482 rinfo->mon1_type = radeon_probe_OF_head(rinfo, 0,
484 #endif /* CONFIG_PPC_OF */
485 #ifdef CONFIG_FB_RADEON_I2C
486 if (rinfo->mon1_type == MT_NONE)
487 rinfo->mon1_type = radeon_probe_i2c_connector(rinfo, ddc_dvi,
489 if (rinfo->mon1_type == MT_NONE)
491 radeon_probe_i2c_connector(rinfo, ddc_vga,
493 if (rinfo->mon1_type == MT_NONE)
495 radeon_probe_i2c_connector(rinfo, ddc_crt2,
497 #endif /* CONFIG_FB_RADEON_I2C */
498 if (rinfo->mon1_type == MT_NONE)
499 rinfo->mon1_type = MT_CRT;
504 * Check for cards with reversed DACs or TMDS controllers using BIOS
506 if (rinfo->bios_seg &&
507 (tmp = BIOS_IN16(rinfo->fp_bios_start + 0x50))) {
508 for (i = 1; i < 4; i++) {
511 if (!BIOS_IN8(tmp + i*2) && i > 1)
513 tmp0 = BIOS_IN16(tmp + i*2);
514 if ((!(tmp0 & 0x01)) && (((tmp0 >> 8) & 0x0f) == ddc_dvi)) {
515 rinfo->reversed_DAC = 1;
516 printk(KERN_INFO "radeonfb: Reversed DACs detected\n");
518 if ((((tmp0 >> 8) & 0x0f) == ddc_dvi) && ((tmp0 >> 4) & 0x01)) {
519 rinfo->reversed_TMDS = 1;
520 printk(KERN_INFO "radeonfb: Reversed TMDS detected\n");
526 * Probe primary head (DVI or laptop internal panel)
529 if (rinfo->mon1_type == MT_NONE)
530 rinfo->mon1_type = radeon_probe_OF_head(rinfo, 0, &rinfo->mon1_EDID);
531 #endif /* CONFIG_PPC_OF */
532 #ifdef CONFIG_FB_RADEON_I2C
533 if (rinfo->mon1_type == MT_NONE)
534 rinfo->mon1_type = radeon_probe_i2c_connector(rinfo, ddc_dvi,
536 if (rinfo->mon1_type == MT_NONE) {
537 rinfo->mon1_type = radeon_probe_i2c_connector(rinfo, ddc_crt2,
539 if (rinfo->mon1_type != MT_NONE)
542 #endif /* CONFIG_FB_RADEON_I2C */
543 if (rinfo->mon1_type == MT_NONE && rinfo->is_mobility &&
544 ((rinfo->bios_seg && (INREG(BIOS_4_SCRATCH) & 4))
545 || (INREG(LVDS_GEN_CNTL) & LVDS_ON))) {
546 rinfo->mon1_type = MT_LCD;
547 printk("Non-DDC laptop panel detected\n");
549 if (rinfo->mon1_type == MT_NONE)
550 rinfo->mon1_type = radeon_crt_is_connected(rinfo, rinfo->reversed_DAC);
553 * Probe secondary head (mostly VGA, can be DVI)
556 if (rinfo->mon2_type == MT_NONE)
557 rinfo->mon2_type = radeon_probe_OF_head(rinfo, 1, &rinfo->mon2_EDID);
558 #endif /* CONFIG_PPC_OF */
559 #ifdef CONFIG_FB_RADEON_I2C
560 if (rinfo->mon2_type == MT_NONE)
561 rinfo->mon2_type = radeon_probe_i2c_connector(rinfo, ddc_vga,
563 if (rinfo->mon2_type == MT_NONE && !ddc_crt2_used)
564 rinfo->mon2_type = radeon_probe_i2c_connector(rinfo, ddc_crt2,
566 #endif /* CONFIG_FB_RADEON_I2C */
567 if (rinfo->mon2_type == MT_NONE)
568 rinfo->mon2_type = radeon_crt_is_connected(rinfo, !rinfo->reversed_DAC);
571 * If we only detected port 2, we swap them, if none detected,
572 * assume CRT (maybe fallback to old BIOS_SCRATCH stuff ? or look
575 if (rinfo->mon1_type == MT_NONE) {
576 if (rinfo->mon2_type != MT_NONE) {
577 rinfo->mon1_type = rinfo->mon2_type;
578 rinfo->mon1_EDID = rinfo->mon2_EDID;
580 rinfo->mon1_type = MT_CRT;
581 rinfo->mon2_type = MT_NONE;
582 rinfo->mon2_EDID = NULL;
586 * Deal with reversed TMDS
588 if (rinfo->reversed_TMDS) {
589 /* Always keep internal TMDS as primary head */
590 if (rinfo->mon1_type == MT_DFP || rinfo->mon2_type == MT_DFP) {
591 int tmp_type = rinfo->mon1_type;
592 u8 *tmp_EDID = rinfo->mon1_EDID;
593 rinfo->mon1_type = rinfo->mon2_type;
594 rinfo->mon1_EDID = rinfo->mon2_EDID;
595 rinfo->mon2_type = tmp_type;
596 rinfo->mon2_EDID = tmp_EDID;
597 if (rinfo->mon1_type == MT_CRT || rinfo->mon2_type == MT_CRT)
598 rinfo->reversed_DAC ^= 1;
603 if (rinfo->mon1_EDID)
604 kfree(rinfo->mon1_EDID);
605 rinfo->mon1_EDID = NULL;
606 if (rinfo->mon2_EDID)
607 kfree(rinfo->mon2_EDID);
608 rinfo->mon2_EDID = NULL;
612 printk(KERN_INFO "radeonfb: Monitor 1 type %s found\n",
613 radeon_get_mon_name(rinfo->mon1_type));
614 if (rinfo->mon1_EDID)
615 printk(KERN_INFO "radeonfb: EDID probed\n");
616 if (!rinfo->has_CRTC2)
618 printk(KERN_INFO "radeonfb: Monitor 2 type %s found\n",
619 radeon_get_mon_name(rinfo->mon2_type));
620 if (rinfo->mon2_EDID)
621 printk(KERN_INFO "radeonfb: EDID probed\n");
626 * This functions applyes any arch/model/machine specific fixups
627 * to the panel info. It may eventually alter EDID block as
628 * well or whatever is specific to a given model and not probed
629 * properly by the default code
631 static void radeon_fixup_panel_info(struct radeonfb_info *rinfo)
634 * A few iBook laptop panels seem to need a fixed PLL setting
636 * We should probably do this differently based on the panel
637 * type/model or eventually some other device-tree informations,
638 * but these tweaks below work enough for now. --BenH
642 if (machine_is_compatible("PowerBook4,3")) {
643 rinfo->panel_info.ref_divider = rinfo->pll.ref_div;
644 rinfo->panel_info.post_divider = 0x6;
645 rinfo->panel_info.fbk_divider = 0xad;
646 rinfo->panel_info.use_bios_dividers = 1;
648 /* Aluminium PowerBook 17" */
649 if (machine_is_compatible("PowerBook5,3")) {
650 rinfo->panel_info.ref_divider = rinfo->pll.ref_div;
651 rinfo->panel_info.post_divider = 0x4;
652 rinfo->panel_info.fbk_divider = 0x80;
653 rinfo->panel_info.use_bios_dividers = 1;
656 if (machine_is_compatible("PowerBook6,3") |
657 machine_is_compatible("PowerBook6,5")) {
658 rinfo->panel_info.ref_divider = rinfo->pll.ref_div;
659 rinfo->panel_info.post_divider = 0x6;
660 rinfo->panel_info.fbk_divider = 0xad;
661 rinfo->panel_info.use_bios_dividers = 1;
663 #endif /* CONFIG_PPC_OF */
668 * Fill up panel infos from a mode definition, either returned by the EDID
669 * or from the default mode when we can't do any better
671 static void radeon_var_to_panel_info(struct radeonfb_info *rinfo, struct fb_var_screeninfo *var)
673 rinfo->panel_info.xres = var->xres;
674 rinfo->panel_info.yres = var->yres;
675 rinfo->panel_info.clock = 100000000 / var->pixclock;
676 rinfo->panel_info.hOver_plus = var->right_margin;
677 rinfo->panel_info.hSync_width = var->hsync_len;
678 rinfo->panel_info.hblank = var->left_margin +
679 (var->right_margin + var->hsync_len);
680 rinfo->panel_info.vOver_plus = var->lower_margin;
681 rinfo->panel_info.vSync_width = var->vsync_len;
682 rinfo->panel_info.vblank = var->upper_margin +
683 (var->lower_margin + var->vsync_len);
684 rinfo->panel_info.hAct_high =
685 (var->sync & FB_SYNC_HOR_HIGH_ACT) != 0;
686 rinfo->panel_info.vAct_high =
687 (var->sync & FB_SYNC_VERT_HIGH_ACT) != 0;
688 rinfo->panel_info.valid = 1;
689 /* We use a default of 200ms for the panel power delay,
690 * I need to have a real schedule() instead of mdelay's in the panel code.
691 * we might be possible to figure out a better power delay either from
692 * MacOS OF tree or from the EDID block (proprietary extensions ?)
694 rinfo->panel_info.pwr_delay = 200;
697 static void radeon_var_to_videomode(struct fb_videomode *mode,
698 const struct fb_var_screeninfo *var)
700 mode->xres = var->xres;
701 mode->yres = var->yres;
702 mode->pixclock = var->pixclock;
703 mode->left_margin = var->left_margin;
704 mode->right_margin = var->right_margin;
705 mode->upper_margin = var->upper_margin;
706 mode->lower_margin = var->lower_margin;
707 mode->hsync_len = var->hsync_len;
708 mode->vsync_len = var->vsync_len;
709 mode->sync = var->sync;
710 mode->vmode = var->vmode;
713 static void radeon_videomode_to_var(struct fb_var_screeninfo *var,
714 const struct fb_videomode *mode)
716 var->xres = mode->xres;
717 var->yres = mode->yres;
718 var->xres_virtual = mode->xres;
719 var->yres_virtual = mode->yres;
722 var->pixclock = mode->pixclock;
723 var->left_margin = mode->left_margin;
724 var->right_margin = mode->right_margin;
725 var->upper_margin = mode->upper_margin;
726 var->lower_margin = mode->lower_margin;
727 var->hsync_len = mode->hsync_len;
728 var->vsync_len = mode->vsync_len;
729 var->sync = mode->sync;
730 var->vmode = mode->vmode;
734 * Build the modedb for head 1 (head 2 will come later), check panel infos
735 * from either BIOS or EDID, and pick up the default mode
737 void __devinit radeon_check_modes(struct radeonfb_info *rinfo, const char *mode_option)
739 int has_default_mode = 0;
742 * Fill default var first
744 rinfo->info->var = radeonfb_default_var;
747 * First check out what BIOS has to say
749 if (rinfo->mon1_type == MT_LCD)
750 radeon_get_panel_info_BIOS(rinfo);
753 * Parse EDID detailed timings and deduce panel infos if any. Right now
754 * we only deal with first entry returned by parse_EDID, we may do better
757 if (!rinfo->panel_info.use_bios_dividers && rinfo->mon1_type != MT_CRT
758 && rinfo->mon1_EDID) {
759 struct fb_var_screeninfo var;
760 RTRACE("Parsing EDID data for panel info\n");
761 if (fb_parse_edid(rinfo->mon1_EDID, &var) == 0) {
762 if (var.xres >= rinfo->panel_info.xres &&
763 var.yres >= rinfo->panel_info.yres)
764 radeon_var_to_panel_info(rinfo, &var);
769 * Do any additional platform/arch fixups to the panel infos
771 radeon_fixup_panel_info(rinfo);
774 * If we have some valid panel infos, we setup the default mode based on
777 if (rinfo->mon1_type != MT_CRT && rinfo->panel_info.valid) {
778 struct fb_var_screeninfo *var = &rinfo->info->var;
780 RTRACE("Setting up default mode based on panel info\n");
781 var->xres = rinfo->panel_info.xres;
782 var->yres = rinfo->panel_info.yres;
783 var->xres_virtual = rinfo->panel_info.xres;
784 var->yres_virtual = rinfo->panel_info.yres;
785 var->xoffset = var->yoffset = 0;
786 var->bits_per_pixel = 8;
787 var->pixclock = 100000000 / rinfo->panel_info.clock;
788 var->left_margin = (rinfo->panel_info.hblank - rinfo->panel_info.hOver_plus
789 - rinfo->panel_info.hSync_width);
790 var->right_margin = rinfo->panel_info.hOver_plus;
791 var->upper_margin = (rinfo->panel_info.vblank - rinfo->panel_info.vOver_plus
792 - rinfo->panel_info.vSync_width);
793 var->lower_margin = rinfo->panel_info.vOver_plus;
794 var->hsync_len = rinfo->panel_info.hSync_width;
795 var->vsync_len = rinfo->panel_info.vSync_width;
797 if (rinfo->panel_info.hAct_high)
798 var->sync |= FB_SYNC_HOR_HIGH_ACT;
799 if (rinfo->panel_info.vAct_high)
800 var->sync |= FB_SYNC_VERT_HIGH_ACT;
802 has_default_mode = 1;
806 * Now build modedb from EDID
808 if (rinfo->mon1_EDID) {
809 rinfo->mon1_modedb = fb_create_modedb(rinfo->mon1_EDID,
810 &rinfo->mon1_dbsize);
811 fb_get_monitor_limits(rinfo->mon1_EDID, &rinfo->info->monspecs);
816 * Finally, if we don't have panel infos we need to figure some (or
817 * we try to read it from card), we try to pick a default mode
818 * and create some panel infos. Whatever...
820 if (rinfo->mon1_type != MT_CRT && !rinfo->panel_info.valid) {
821 struct fb_videomode *modedb;
825 RTRACE("Guessing panel info...\n");
826 if (rinfo->panel_info.xres == 0 || rinfo->panel_info.yres == 0) {
827 u32 tmp = INREG(FP_HORZ_STRETCH) & HORZ_PANEL_SIZE;
828 rinfo->panel_info.xres = ((tmp >> HORZ_PANEL_SHIFT) + 1) * 8;
829 tmp = INREG(FP_VERT_STRETCH) & VERT_PANEL_SIZE;
830 rinfo->panel_info.yres = (tmp >> VERT_PANEL_SHIFT) + 1;
832 if (rinfo->panel_info.xres == 0 || rinfo->panel_info.yres == 0) {
833 printk(KERN_WARNING "radeonfb: Can't find panel size, going back to CRT\n");
834 rinfo->mon1_type = MT_CRT;
837 printk(KERN_WARNING "radeonfb: Assuming panel size %dx%d\n",
838 rinfo->panel_info.xres, rinfo->panel_info.yres);
839 modedb = rinfo->mon1_modedb;
840 dbsize = rinfo->mon1_dbsize;
841 snprintf(modename, 31, "%dx%d", rinfo->panel_info.xres, rinfo->panel_info.yres);
842 if (fb_find_mode(&rinfo->info->var, rinfo->info, modename,
843 modedb, dbsize, NULL, 8) == 0) {
844 printk(KERN_WARNING "radeonfb: Can't find mode for panel size, going back to CRT\n");
845 rinfo->mon1_type = MT_CRT;
848 has_default_mode = 1;
849 radeon_var_to_panel_info(rinfo, &rinfo->info->var);
854 * Pick up a random default mode
856 if (!has_default_mode || mode_option) {
857 struct fb_videomode default_mode;
858 if (has_default_mode)
859 radeon_var_to_videomode(&default_mode, &rinfo->info->var);
861 radeon_var_to_videomode(&default_mode, &radeonfb_default_var);
862 if (fb_find_mode(&rinfo->info->var, rinfo->info, mode_option,
863 rinfo->mon1_modedb, rinfo->mon1_dbsize, &default_mode, 8) == 0)
864 rinfo->info->var = radeonfb_default_var;
870 * The code below is used to pick up a mode in check_var and
871 * set_var. It should be made generic
875 * This is used when looking for modes. We assign a "goodness" value
876 * to a mode in the modedb depending how "close" it is from what we
878 * Currently, we don't compare that much, we could do better but
879 * the current fbcon doesn't quite mind ;)
881 static int radeon_compare_modes(const struct fb_var_screeninfo *var,
882 const struct fb_videomode *mode)
886 if (var->yres == mode->yres)
888 if (var->xres == mode->xres)
894 * This function is called by check_var, it gets the passed in mode parameter, and
895 * outputs a valid mode matching the passed-in one as closely as possible.
896 * We need something better ultimately. Things like fbcon basically pass us out
897 * current mode with xres/yres hacked, while things like XFree will actually
898 * produce a full timing that we should respect as much as possible.
900 * This is why I added the FB_ACTIVATE_FIND that is used by fbcon. Without this,
901 * we do a simple spec match, that's all. With it, we actually look for a mode in
902 * either our monitor modedb or the vesa one if none
905 int radeon_match_mode(struct radeonfb_info *rinfo,
906 struct fb_var_screeninfo *dest,
907 const struct fb_var_screeninfo *src)
909 const struct fb_videomode *db = vesa_modes;
911 int has_rmx, native_db = 0;
913 const struct fb_videomode *candidate = NULL;
915 /* Start with a copy of the requested mode */
916 memcpy(dest, src, sizeof(struct fb_var_screeninfo));
918 /* Check if we have a modedb built from EDID */
919 if (rinfo->mon1_modedb) {
920 db = rinfo->mon1_modedb;
921 dbsize = rinfo->mon1_dbsize;
925 /* Check if we have a scaler allowing any fancy mode */
926 has_rmx = rinfo->mon1_type == MT_LCD || rinfo->mon1_type == MT_DFP;
928 /* If we have a scaler and are passed FB_ACTIVATE_TEST or
929 * FB_ACTIVATE_NOW, just do basic checking and return if the
932 if ((src->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_TEST ||
933 (src->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
934 /* We don't have an RMX, validate timings. If we don't have
935 * monspecs, we should be paranoid and not let use go above
936 * 640x480-60, but I assume userland knows what it's doing here
937 * (though I may be proven wrong...)
939 if (has_rmx == 0 && rinfo->mon1_modedb)
940 if (fb_validate_mode((struct fb_var_screeninfo *)src, rinfo->info))
945 /* Now look for a mode in the database */
947 for (i = 0; i < dbsize; i++) {
950 if (db[i].yres < src->yres)
952 if (db[i].xres < src->xres)
954 g = radeon_compare_modes(src, &db[i]);
955 /* If the new mode is at least as good as the previous one,
956 * then it's our new candidate
964 /* If we have a scaler, we allow any mode from the database */
965 if (native_db && has_rmx) {
972 /* If we have found a match, return it */
973 if (candidate != NULL) {
974 radeon_videomode_to_var(dest, candidate);
978 /* If we haven't and don't have a scaler, fail */