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);
78 for (i = 0; propnames[i] != NULL; ++i) {
79 pedid = (u8 *)get_property(dp, propnames[i], NULL);
83 /* We didn't find the EDID in the leaf node, some cards will actually
84 * put EDID1/EDID2 in the parent, look for these (typically M6 tipb).
85 * single-head cards have hdno == -1 and skip this step
87 if (pedid == NULL && dp->parent && (hdno != -1))
88 pedid = get_property(dp->parent, (hdno == 0) ? "EDID1" : "EDID2", NULL);
89 if (pedid == NULL && dp->parent && (hdno == 0))
90 pedid = get_property(dp->parent, "EDID", NULL);
94 tmp = (u8 *)kmalloc(EDID_LENGTH, GFP_KERNEL);
97 memcpy(tmp, pedid, EDID_LENGTH);
102 static int __devinit radeon_probe_OF_head(struct radeonfb_info *rinfo, int head_no,
105 struct device_node *dp;
107 RTRACE("radeon_probe_OF_head\n");
109 dp = pci_device_to_OF_node(rinfo->pdev);
113 if (rinfo->has_CRTC2) {
121 pname = (char *)get_property(dp, "name", NULL);
125 RTRACE("head: %s (letter: %c, head_no: %d)\n",
126 pname, pname[len-1], head_no);
127 if (pname[len-1] == 'A' && head_no == 0) {
128 int mt = radeon_parse_montype_prop(dp, out_EDID, 0);
129 /* Maybe check for LVDS_GEN_CNTL here ? I need to check out
130 * what OF does when booting with lid closed
132 if (mt == MT_DFP && rinfo->is_mobility)
135 } else if (pname[len-1] == 'B' && head_no == 1)
136 return radeon_parse_montype_prop(dp, out_EDID, 1);
143 return radeon_parse_montype_prop(dp, out_EDID, -1);
147 #endif /* CONFIG_PPC_OF */
150 static int __devinit radeon_get_panel_info_BIOS(struct radeonfb_info *rinfo)
152 unsigned long tmp, tmp0;
156 if (!rinfo->bios_seg)
159 if (!(tmp = BIOS_IN16(rinfo->fp_bios_start + 0x40))) {
160 printk(KERN_ERR "radeonfb: Failed to detect DFP panel info using BIOS\n");
161 rinfo->panel_info.pwr_delay = 200;
166 stmp[i] = BIOS_IN8(tmp+i+1);
168 printk("radeonfb: panel ID string: %s\n", stmp);
169 rinfo->panel_info.xres = BIOS_IN16(tmp + 25);
170 rinfo->panel_info.yres = BIOS_IN16(tmp + 27);
171 printk("radeonfb: detected LVDS panel size from BIOS: %dx%d\n",
172 rinfo->panel_info.xres, rinfo->panel_info.yres);
174 rinfo->panel_info.pwr_delay = BIOS_IN16(tmp + 44);
175 RTRACE("BIOS provided panel power delay: %d\n", rinfo->panel_info.pwr_delay);
176 if (rinfo->panel_info.pwr_delay > 2000 || rinfo->panel_info.pwr_delay <= 0)
177 rinfo->panel_info.pwr_delay = 2000;
180 * Some panels only work properly with some divider combinations
182 rinfo->panel_info.ref_divider = BIOS_IN16(tmp + 46);
183 rinfo->panel_info.post_divider = BIOS_IN8(tmp + 48);
184 rinfo->panel_info.fbk_divider = BIOS_IN16(tmp + 49);
185 if (rinfo->panel_info.ref_divider != 0 &&
186 rinfo->panel_info.fbk_divider > 3) {
187 rinfo->panel_info.use_bios_dividers = 1;
188 printk(KERN_INFO "radeondb: BIOS provided dividers will be used\n");
189 RTRACE("ref_divider = %x\n", rinfo->panel_info.ref_divider);
190 RTRACE("post_divider = %x\n", rinfo->panel_info.post_divider);
191 RTRACE("fbk_divider = %x\n", rinfo->panel_info.fbk_divider);
193 RTRACE("Scanning BIOS table ...\n");
194 for(i=0; i<32; i++) {
195 tmp0 = BIOS_IN16(tmp+64+i*2);
198 RTRACE(" %d x %d\n", BIOS_IN16(tmp0), BIOS_IN16(tmp0+2));
199 if ((BIOS_IN16(tmp0) == rinfo->panel_info.xres) &&
200 (BIOS_IN16(tmp0+2) == rinfo->panel_info.yres)) {
201 rinfo->panel_info.hblank = (BIOS_IN16(tmp0+17) - BIOS_IN16(tmp0+19)) * 8;
202 rinfo->panel_info.hOver_plus = ((BIOS_IN16(tmp0+21) -
203 BIOS_IN16(tmp0+19) -1) * 8) & 0x7fff;
204 rinfo->panel_info.hSync_width = BIOS_IN8(tmp0+23) * 8;
205 rinfo->panel_info.vblank = BIOS_IN16(tmp0+24) - BIOS_IN16(tmp0+26);
206 rinfo->panel_info.vOver_plus = (BIOS_IN16(tmp0+28) & 0x7ff) - BIOS_IN16(tmp0+26);
207 rinfo->panel_info.vSync_width = (BIOS_IN16(tmp0+28) & 0xf800) >> 11;
208 rinfo->panel_info.clock = BIOS_IN16(tmp0+9);
209 /* Assume high active syncs for now until ATI tells me more... maybe we
210 * can probe register values here ?
212 rinfo->panel_info.hAct_high = 1;
213 rinfo->panel_info.vAct_high = 1;
214 /* Mark panel infos valid */
215 rinfo->panel_info.valid = 1;
217 RTRACE("Found panel in BIOS table:\n");
218 RTRACE(" hblank: %d\n", rinfo->panel_info.hblank);
219 RTRACE(" hOver_plus: %d\n", rinfo->panel_info.hOver_plus);
220 RTRACE(" hSync_width: %d\n", rinfo->panel_info.hSync_width);
221 RTRACE(" vblank: %d\n", rinfo->panel_info.vblank);
222 RTRACE(" vOver_plus: %d\n", rinfo->panel_info.vOver_plus);
223 RTRACE(" vSync_width: %d\n", rinfo->panel_info.vSync_width);
224 RTRACE(" clock: %d\n", rinfo->panel_info.clock);
229 RTRACE("Didn't find panel in BIOS table !\n");
234 /* Try to extract the connector informations from the BIOS. This
235 * doesn't quite work yet, but it's output is still useful for
238 static void __devinit radeon_parse_connector_info(struct radeonfb_info *rinfo)
240 int offset, chips, connectors, tmp, i, conn, type;
242 static char* __conn_type_table[16] = {
243 "NONE", "Proprietary", "CRT", "DVI-I", "DVI-D", "Unknown", "Unknown",
244 "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown",
245 "Unknown", "Unknown", "Unknown"
248 if (!rinfo->bios_seg)
251 offset = BIOS_IN16(rinfo->fp_bios_start + 0x50);
253 printk(KERN_WARNING "radeonfb: No connector info table detected\n");
257 /* Don't do much more at this point but displaying the data if
260 chips = BIOS_IN8(offset++) >> 4;
261 RTRACE("%d chips in connector info\n", chips);
262 for (i = 0; i < chips; i++) {
263 tmp = BIOS_IN8(offset++);
264 connectors = tmp & 0x0f;
265 RTRACE(" - chip %d has %d connectors\n", tmp >> 4, connectors);
266 for (conn = 0; ; conn++) {
267 tmp = BIOS_IN16(offset);
271 type = (tmp >> 12) & 0x0f;
272 RTRACE(" * connector %d of type %d (%s) : %04x\n",
273 conn, type, __conn_type_table[type], tmp);
280 * Probe physical connection of a CRT. This code comes from XFree
281 * as well and currently is only implemented for the CRT DAC, the
282 * code for the TVDAC is commented out in XFree as "non working"
284 static int __devinit radeon_crt_is_connected(struct radeonfb_info *rinfo, int is_crt_dac)
288 /* the monitor either wasn't connected or it is a non-DDC CRT.
292 unsigned long ulOrigVCLK_ECP_CNTL;
293 unsigned long ulOrigDAC_CNTL;
294 unsigned long ulOrigDAC_EXT_CNTL;
295 unsigned long ulOrigCRTC_EXT_CNTL;
296 unsigned long ulData;
297 unsigned long ulMask;
299 ulOrigVCLK_ECP_CNTL = INPLL(VCLK_ECP_CNTL);
301 ulData = ulOrigVCLK_ECP_CNTL;
302 ulData &= ~(PIXCLK_ALWAYS_ONb
303 | PIXCLK_DAC_ALWAYS_ONb);
304 ulMask = ~(PIXCLK_ALWAYS_ONb
305 | PIXCLK_DAC_ALWAYS_ONb);
306 OUTPLLP(VCLK_ECP_CNTL, ulData, ulMask);
308 ulOrigCRTC_EXT_CNTL = INREG(CRTC_EXT_CNTL);
309 ulData = ulOrigCRTC_EXT_CNTL;
310 ulData |= CRTC_CRT_ON;
311 OUTREG(CRTC_EXT_CNTL, ulData);
313 ulOrigDAC_EXT_CNTL = INREG(DAC_EXT_CNTL);
314 ulData = ulOrigDAC_EXT_CNTL;
315 ulData &= ~DAC_FORCE_DATA_MASK;
316 ulData |= (DAC_FORCE_BLANK_OFF_EN
318 |DAC_FORCE_DATA_SEL_MASK);
319 if ((rinfo->family == CHIP_FAMILY_RV250) ||
320 (rinfo->family == CHIP_FAMILY_RV280))
321 ulData |= (0x01b6 << DAC_FORCE_DATA_SHIFT);
323 ulData |= (0x01ac << DAC_FORCE_DATA_SHIFT);
325 OUTREG(DAC_EXT_CNTL, ulData);
327 ulOrigDAC_CNTL = INREG(DAC_CNTL);
328 ulData = ulOrigDAC_CNTL;
329 ulData |= DAC_CMP_EN;
330 ulData &= ~(DAC_RANGE_CNTL_MASK
333 OUTREG(DAC_CNTL, ulData);
337 ulData = INREG(DAC_CNTL);
338 connected = (DAC_CMP_OUTPUT & ulData) ? 1 : 0;
340 ulData = ulOrigVCLK_ECP_CNTL;
341 ulMask = 0xFFFFFFFFL;
342 OUTPLLP(VCLK_ECP_CNTL, ulData, ulMask);
344 OUTREG(DAC_CNTL, ulOrigDAC_CNTL );
345 OUTREG(DAC_EXT_CNTL, ulOrigDAC_EXT_CNTL );
346 OUTREG(CRTC_EXT_CNTL, ulOrigCRTC_EXT_CNTL);
349 return connected ? MT_CRT : MT_NONE;
353 * Parse the "monitor_layout" string if any. This code is mostly
354 * copied from XFree's radeon driver
356 static int __devinit radeon_parse_monitor_layout(struct radeonfb_info *rinfo,
357 const char *monitor_layout)
360 int i = 0, second = 0;
393 if (strcmp(s1, "CRT") == 0)
394 rinfo->mon1_type = MT_CRT;
395 else if (strcmp(s1, "TMDS") == 0)
396 rinfo->mon1_type = MT_DFP;
397 else if (strcmp(s1, "LVDS") == 0)
398 rinfo->mon1_type = MT_LCD;
400 if (strcmp(s2, "CRT") == 0)
401 rinfo->mon2_type = MT_CRT;
402 else if (strcmp(s2, "TMDS") == 0)
403 rinfo->mon2_type = MT_DFP;
404 else if (strcmp(s2, "LVDS") == 0)
405 rinfo->mon2_type = MT_LCD;
411 * Probe display on both primary and secondary card's connector (if any)
412 * by various available techniques (i2c, OF device tree, BIOS, ...) and
413 * try to retreive EDID. The algorithm here comes from XFree's radeon
416 void __devinit radeon_probe_screens(struct radeonfb_info *rinfo,
417 const char *monitor_layout, int ignore_edid)
419 #ifdef CONFIG_FB_RADEON_I2C
420 int ddc_crt2_used = 0;
424 radeon_parse_connector_info(rinfo);
426 if (radeon_parse_monitor_layout(rinfo, monitor_layout)) {
429 * If user specified a monitor_layout option, use it instead
430 * of auto-detecting. Maybe we should only use this argument
431 * on the first radeon card probed or provide a way to specify
432 * a layout for each card ?
435 RTRACE("Using specified monitor layout: %s", monitor_layout);
436 #ifdef CONFIG_FB_RADEON_I2C
438 if (rinfo->mon1_type != MT_NONE)
439 if (!radeon_probe_i2c_connector(rinfo, ddc_dvi, &rinfo->mon1_EDID)) {
440 radeon_probe_i2c_connector(rinfo, ddc_crt2, &rinfo->mon1_EDID);
443 if (rinfo->mon2_type != MT_NONE)
444 if (!radeon_probe_i2c_connector(rinfo, ddc_vga, &rinfo->mon2_EDID) &&
446 radeon_probe_i2c_connector(rinfo, ddc_crt2, &rinfo->mon2_EDID);
448 #endif /* CONFIG_FB_RADEON_I2C */
449 if (rinfo->mon1_type == MT_NONE) {
450 if (rinfo->mon2_type != MT_NONE) {
451 rinfo->mon1_type = rinfo->mon2_type;
452 rinfo->mon1_EDID = rinfo->mon2_EDID;
454 rinfo->mon1_type = MT_CRT;
455 printk(KERN_INFO "radeonfb: No valid monitor, assuming CRT on first port\n");
457 rinfo->mon2_type = MT_NONE;
458 rinfo->mon2_EDID = NULL;
462 * Auto-detecting display type (well... trying to ...)
465 RTRACE("Starting monitor auto detection...\n");
467 #if DEBUG && defined(CONFIG_FB_RADEON_I2C)
469 u8 *EDIDs[4] = { NULL, NULL, NULL, NULL };
470 int mon_types[4] = {MT_NONE, MT_NONE, MT_NONE, MT_NONE};
473 for (i = 0; i < 4; i++)
474 mon_types[i] = radeon_probe_i2c_connector(rinfo,
479 * Old single head cards
481 if (!rinfo->has_CRTC2) {
483 if (rinfo->mon1_type == MT_NONE)
484 rinfo->mon1_type = radeon_probe_OF_head(rinfo, 0,
486 #endif /* CONFIG_PPC_OF */
487 #ifdef CONFIG_FB_RADEON_I2C
488 if (rinfo->mon1_type == MT_NONE)
489 rinfo->mon1_type = radeon_probe_i2c_connector(rinfo, ddc_dvi,
491 if (rinfo->mon1_type == MT_NONE)
493 radeon_probe_i2c_connector(rinfo, ddc_vga,
495 if (rinfo->mon1_type == MT_NONE)
497 radeon_probe_i2c_connector(rinfo, ddc_crt2,
499 #endif /* CONFIG_FB_RADEON_I2C */
500 if (rinfo->mon1_type == MT_NONE)
501 rinfo->mon1_type = MT_CRT;
506 * Check for cards with reversed DACs or TMDS controllers using BIOS
508 if (rinfo->bios_seg &&
509 (tmp = BIOS_IN16(rinfo->fp_bios_start + 0x50))) {
510 for (i = 1; i < 4; i++) {
513 if (!BIOS_IN8(tmp + i*2) && i > 1)
515 tmp0 = BIOS_IN16(tmp + i*2);
516 if ((!(tmp0 & 0x01)) && (((tmp0 >> 8) & 0x0f) == ddc_dvi)) {
517 rinfo->reversed_DAC = 1;
518 printk(KERN_INFO "radeonfb: Reversed DACs detected\n");
520 if ((((tmp0 >> 8) & 0x0f) == ddc_dvi) && ((tmp0 >> 4) & 0x01)) {
521 rinfo->reversed_TMDS = 1;
522 printk(KERN_INFO "radeonfb: Reversed TMDS detected\n");
528 * Probe primary head (DVI or laptop internal panel)
531 if (rinfo->mon1_type == MT_NONE)
532 rinfo->mon1_type = radeon_probe_OF_head(rinfo, 0, &rinfo->mon1_EDID);
533 #endif /* CONFIG_PPC_OF */
534 #ifdef CONFIG_FB_RADEON_I2C
535 if (rinfo->mon1_type == MT_NONE)
536 rinfo->mon1_type = radeon_probe_i2c_connector(rinfo, ddc_dvi,
538 if (rinfo->mon1_type == MT_NONE) {
539 rinfo->mon1_type = radeon_probe_i2c_connector(rinfo, ddc_crt2,
541 if (rinfo->mon1_type != MT_NONE)
544 #endif /* CONFIG_FB_RADEON_I2C */
545 if (rinfo->mon1_type == MT_NONE && rinfo->is_mobility &&
546 ((rinfo->bios_seg && (INREG(BIOS_4_SCRATCH) & 4))
547 || (INREG(LVDS_GEN_CNTL) & LVDS_ON))) {
548 rinfo->mon1_type = MT_LCD;
549 printk("Non-DDC laptop panel detected\n");
551 if (rinfo->mon1_type == MT_NONE)
552 rinfo->mon1_type = radeon_crt_is_connected(rinfo, rinfo->reversed_DAC);
555 * Probe secondary head (mostly VGA, can be DVI)
558 if (rinfo->mon2_type == MT_NONE)
559 rinfo->mon2_type = radeon_probe_OF_head(rinfo, 1, &rinfo->mon2_EDID);
560 #endif /* CONFIG_PPC_OF */
561 #ifdef CONFIG_FB_RADEON_I2C
562 if (rinfo->mon2_type == MT_NONE)
563 rinfo->mon2_type = radeon_probe_i2c_connector(rinfo, ddc_vga,
565 if (rinfo->mon2_type == MT_NONE && !ddc_crt2_used)
566 rinfo->mon2_type = radeon_probe_i2c_connector(rinfo, ddc_crt2,
568 #endif /* CONFIG_FB_RADEON_I2C */
569 if (rinfo->mon2_type == MT_NONE)
570 rinfo->mon2_type = radeon_crt_is_connected(rinfo, !rinfo->reversed_DAC);
573 * If we only detected port 2, we swap them, if none detected,
574 * assume CRT (maybe fallback to old BIOS_SCRATCH stuff ? or look
577 if (rinfo->mon1_type == MT_NONE) {
578 if (rinfo->mon2_type != MT_NONE) {
579 rinfo->mon1_type = rinfo->mon2_type;
580 rinfo->mon1_EDID = rinfo->mon2_EDID;
582 rinfo->mon1_type = MT_CRT;
583 rinfo->mon2_type = MT_NONE;
584 rinfo->mon2_EDID = NULL;
588 * Deal with reversed TMDS
590 if (rinfo->reversed_TMDS) {
591 /* Always keep internal TMDS as primary head */
592 if (rinfo->mon1_type == MT_DFP || rinfo->mon2_type == MT_DFP) {
593 int tmp_type = rinfo->mon1_type;
594 u8 *tmp_EDID = rinfo->mon1_EDID;
595 rinfo->mon1_type = rinfo->mon2_type;
596 rinfo->mon1_EDID = rinfo->mon2_EDID;
597 rinfo->mon2_type = tmp_type;
598 rinfo->mon2_EDID = tmp_EDID;
599 if (rinfo->mon1_type == MT_CRT || rinfo->mon2_type == MT_CRT)
600 rinfo->reversed_DAC ^= 1;
605 if (rinfo->mon1_EDID)
606 kfree(rinfo->mon1_EDID);
607 rinfo->mon1_EDID = NULL;
608 if (rinfo->mon2_EDID)
609 kfree(rinfo->mon2_EDID);
610 rinfo->mon2_EDID = NULL;
614 printk(KERN_INFO "radeonfb: Monitor 1 type %s found\n",
615 radeon_get_mon_name(rinfo->mon1_type));
616 if (rinfo->mon1_EDID)
617 printk(KERN_INFO "radeonfb: EDID probed\n");
618 if (!rinfo->has_CRTC2)
620 printk(KERN_INFO "radeonfb: Monitor 2 type %s found\n",
621 radeon_get_mon_name(rinfo->mon2_type));
622 if (rinfo->mon2_EDID)
623 printk(KERN_INFO "radeonfb: EDID probed\n");
628 * This functions applyes any arch/model/machine specific fixups
629 * to the panel info. It may eventually alter EDID block as
630 * well or whatever is specific to a given model and not probed
631 * properly by the default code
633 static void radeon_fixup_panel_info(struct radeonfb_info *rinfo)
636 * A few iBook laptop panels seem to need a fixed PLL setting
638 * We should probably do this differently based on the panel
639 * type/model or eventually some other device-tree informations,
640 * but these tweaks below work enough for now. --BenH
644 if (machine_is_compatible("PowerBook4,3")) {
645 rinfo->panel_info.ref_divider = rinfo->pll.ref_div;
646 rinfo->panel_info.post_divider = 0x6;
647 rinfo->panel_info.fbk_divider = 0xad;
648 rinfo->panel_info.use_bios_dividers = 1;
650 /* Aluminium PowerBook 15" */
651 if (machine_is_compatible("PowerBook5,4")) {
652 rinfo->panel_info.ref_divider = rinfo->pll.ref_div;
653 rinfo->panel_info.post_divider = 0x2;
654 rinfo->panel_info.fbk_divider = 0x8e;
655 rinfo->panel_info.use_bios_dividers = 1;
657 /* Aluminium PowerBook 17" */
658 if (machine_is_compatible("PowerBook5,3") ||
659 machine_is_compatible("PowerBook5,5")) {
660 rinfo->panel_info.ref_divider = rinfo->pll.ref_div;
661 rinfo->panel_info.post_divider = 0x4;
662 rinfo->panel_info.fbk_divider = 0x80;
663 rinfo->panel_info.use_bios_dividers = 1;
666 if (machine_is_compatible("PowerBook6,3") ||
667 machine_is_compatible("PowerBook6,5")) {
668 rinfo->panel_info.ref_divider = rinfo->pll.ref_div;
669 rinfo->panel_info.post_divider = 0x6;
670 rinfo->panel_info.fbk_divider = 0xad;
671 rinfo->panel_info.use_bios_dividers = 1;
673 #endif /* CONFIG_PPC_OF */
678 * Fill up panel infos from a mode definition, either returned by the EDID
679 * or from the default mode when we can't do any better
681 static void radeon_var_to_panel_info(struct radeonfb_info *rinfo, struct fb_var_screeninfo *var)
683 rinfo->panel_info.xres = var->xres;
684 rinfo->panel_info.yres = var->yres;
685 rinfo->panel_info.clock = 100000000 / var->pixclock;
686 rinfo->panel_info.hOver_plus = var->right_margin;
687 rinfo->panel_info.hSync_width = var->hsync_len;
688 rinfo->panel_info.hblank = var->left_margin +
689 (var->right_margin + var->hsync_len);
690 rinfo->panel_info.vOver_plus = var->lower_margin;
691 rinfo->panel_info.vSync_width = var->vsync_len;
692 rinfo->panel_info.vblank = var->upper_margin +
693 (var->lower_margin + var->vsync_len);
694 rinfo->panel_info.hAct_high =
695 (var->sync & FB_SYNC_HOR_HIGH_ACT) != 0;
696 rinfo->panel_info.vAct_high =
697 (var->sync & FB_SYNC_VERT_HIGH_ACT) != 0;
698 rinfo->panel_info.valid = 1;
699 /* We use a default of 200ms for the panel power delay,
700 * I need to have a real schedule() instead of mdelay's in the panel code.
701 * we might be possible to figure out a better power delay either from
702 * MacOS OF tree or from the EDID block (proprietary extensions ?)
704 rinfo->panel_info.pwr_delay = 200;
707 static void radeon_var_to_videomode(struct fb_videomode *mode,
708 const struct fb_var_screeninfo *var)
710 mode->xres = var->xres;
711 mode->yres = var->yres;
712 mode->pixclock = var->pixclock;
713 mode->left_margin = var->left_margin;
714 mode->right_margin = var->right_margin;
715 mode->upper_margin = var->upper_margin;
716 mode->lower_margin = var->lower_margin;
717 mode->hsync_len = var->hsync_len;
718 mode->vsync_len = var->vsync_len;
719 mode->sync = var->sync;
720 mode->vmode = var->vmode;
723 static void radeon_videomode_to_var(struct fb_var_screeninfo *var,
724 const struct fb_videomode *mode)
726 var->xres = mode->xres;
727 var->yres = mode->yres;
728 var->xres_virtual = mode->xres;
729 var->yres_virtual = mode->yres;
732 var->pixclock = mode->pixclock;
733 var->left_margin = mode->left_margin;
734 var->right_margin = mode->right_margin;
735 var->upper_margin = mode->upper_margin;
736 var->lower_margin = mode->lower_margin;
737 var->hsync_len = mode->hsync_len;
738 var->vsync_len = mode->vsync_len;
739 var->sync = mode->sync;
740 var->vmode = mode->vmode;
744 * Build the modedb for head 1 (head 2 will come later), check panel infos
745 * from either BIOS or EDID, and pick up the default mode
747 void __devinit radeon_check_modes(struct radeonfb_info *rinfo, const char *mode_option)
749 int has_default_mode = 0;
752 * Fill default var first
754 rinfo->info->var = radeonfb_default_var;
757 * First check out what BIOS has to say
759 if (rinfo->mon1_type == MT_LCD)
760 radeon_get_panel_info_BIOS(rinfo);
763 * Parse EDID detailed timings and deduce panel infos if any. Right now
764 * we only deal with first entry returned by parse_EDID, we may do better
767 if (!rinfo->panel_info.use_bios_dividers && rinfo->mon1_type != MT_CRT
768 && rinfo->mon1_EDID) {
769 struct fb_var_screeninfo var;
770 RTRACE("Parsing EDID data for panel info\n");
771 if (fb_parse_edid(rinfo->mon1_EDID, &var) == 0) {
772 if (var.xres >= rinfo->panel_info.xres &&
773 var.yres >= rinfo->panel_info.yres)
774 radeon_var_to_panel_info(rinfo, &var);
779 * Do any additional platform/arch fixups to the panel infos
781 radeon_fixup_panel_info(rinfo);
784 * If we have some valid panel infos, we setup the default mode based on
787 if (rinfo->mon1_type != MT_CRT && rinfo->panel_info.valid) {
788 struct fb_var_screeninfo *var = &rinfo->info->var;
790 RTRACE("Setting up default mode based on panel info\n");
791 var->xres = rinfo->panel_info.xres;
792 var->yres = rinfo->panel_info.yres;
793 var->xres_virtual = rinfo->panel_info.xres;
794 var->yres_virtual = rinfo->panel_info.yres;
795 var->xoffset = var->yoffset = 0;
796 var->bits_per_pixel = 8;
797 var->pixclock = 100000000 / rinfo->panel_info.clock;
798 var->left_margin = (rinfo->panel_info.hblank - rinfo->panel_info.hOver_plus
799 - rinfo->panel_info.hSync_width);
800 var->right_margin = rinfo->panel_info.hOver_plus;
801 var->upper_margin = (rinfo->panel_info.vblank - rinfo->panel_info.vOver_plus
802 - rinfo->panel_info.vSync_width);
803 var->lower_margin = rinfo->panel_info.vOver_plus;
804 var->hsync_len = rinfo->panel_info.hSync_width;
805 var->vsync_len = rinfo->panel_info.vSync_width;
807 if (rinfo->panel_info.hAct_high)
808 var->sync |= FB_SYNC_HOR_HIGH_ACT;
809 if (rinfo->panel_info.vAct_high)
810 var->sync |= FB_SYNC_VERT_HIGH_ACT;
812 has_default_mode = 1;
816 * Now build modedb from EDID
818 if (rinfo->mon1_EDID) {
819 rinfo->mon1_modedb = fb_create_modedb(rinfo->mon1_EDID,
820 &rinfo->mon1_dbsize);
821 fb_get_monitor_limits(rinfo->mon1_EDID, &rinfo->info->monspecs);
826 * Finally, if we don't have panel infos we need to figure some (or
827 * we try to read it from card), we try to pick a default mode
828 * and create some panel infos. Whatever...
830 if (rinfo->mon1_type != MT_CRT && !rinfo->panel_info.valid) {
831 struct fb_videomode *modedb;
835 RTRACE("Guessing panel info...\n");
836 if (rinfo->panel_info.xres == 0 || rinfo->panel_info.yres == 0) {
837 u32 tmp = INREG(FP_HORZ_STRETCH) & HORZ_PANEL_SIZE;
838 rinfo->panel_info.xres = ((tmp >> HORZ_PANEL_SHIFT) + 1) * 8;
839 tmp = INREG(FP_VERT_STRETCH) & VERT_PANEL_SIZE;
840 rinfo->panel_info.yres = (tmp >> VERT_PANEL_SHIFT) + 1;
842 if (rinfo->panel_info.xres == 0 || rinfo->panel_info.yres == 0) {
843 printk(KERN_WARNING "radeonfb: Can't find panel size, going back to CRT\n");
844 rinfo->mon1_type = MT_CRT;
847 printk(KERN_WARNING "radeonfb: Assuming panel size %dx%d\n",
848 rinfo->panel_info.xres, rinfo->panel_info.yres);
849 modedb = rinfo->mon1_modedb;
850 dbsize = rinfo->mon1_dbsize;
851 snprintf(modename, 31, "%dx%d", rinfo->panel_info.xres, rinfo->panel_info.yres);
852 if (fb_find_mode(&rinfo->info->var, rinfo->info, modename,
853 modedb, dbsize, NULL, 8) == 0) {
854 printk(KERN_WARNING "radeonfb: Can't find mode for panel size, going back to CRT\n");
855 rinfo->mon1_type = MT_CRT;
858 has_default_mode = 1;
859 radeon_var_to_panel_info(rinfo, &rinfo->info->var);
864 * Pick up a random default mode
866 if (!has_default_mode || mode_option) {
867 struct fb_videomode default_mode;
868 if (has_default_mode)
869 radeon_var_to_videomode(&default_mode, &rinfo->info->var);
871 radeon_var_to_videomode(&default_mode, &radeonfb_default_var);
872 if (fb_find_mode(&rinfo->info->var, rinfo->info, mode_option,
873 rinfo->mon1_modedb, rinfo->mon1_dbsize, &default_mode, 8) == 0)
874 rinfo->info->var = radeonfb_default_var;
880 * The code below is used to pick up a mode in check_var and
881 * set_var. It should be made generic
885 * This is used when looking for modes. We assign a "goodness" value
886 * to a mode in the modedb depending how "close" it is from what we
888 * Currently, we don't compare that much, we could do better but
889 * the current fbcon doesn't quite mind ;)
891 static int radeon_compare_modes(const struct fb_var_screeninfo *var,
892 const struct fb_videomode *mode)
896 if (var->yres == mode->yres)
898 if (var->xres == mode->xres)
904 * This function is called by check_var, it gets the passed in mode parameter, and
905 * outputs a valid mode matching the passed-in one as closely as possible.
906 * We need something better ultimately. Things like fbcon basically pass us out
907 * current mode with xres/yres hacked, while things like XFree will actually
908 * produce a full timing that we should respect as much as possible.
910 * This is why I added the FB_ACTIVATE_FIND that is used by fbcon. Without this,
911 * we do a simple spec match, that's all. With it, we actually look for a mode in
912 * either our monitor modedb or the vesa one if none
915 int radeon_match_mode(struct radeonfb_info *rinfo,
916 struct fb_var_screeninfo *dest,
917 const struct fb_var_screeninfo *src)
919 const struct fb_videomode *db = vesa_modes;
921 int has_rmx, native_db = 0;
923 const struct fb_videomode *candidate = NULL;
925 /* Start with a copy of the requested mode */
926 memcpy(dest, src, sizeof(struct fb_var_screeninfo));
928 /* Check if we have a modedb built from EDID */
929 if (rinfo->mon1_modedb) {
930 db = rinfo->mon1_modedb;
931 dbsize = rinfo->mon1_dbsize;
935 /* Check if we have a scaler allowing any fancy mode */
936 has_rmx = rinfo->mon1_type == MT_LCD || rinfo->mon1_type == MT_DFP;
938 /* If we have a scaler and are passed FB_ACTIVATE_TEST or
939 * FB_ACTIVATE_NOW, just do basic checking and return if the
942 if ((src->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_TEST ||
943 (src->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
944 /* We don't have an RMX, validate timings. If we don't have
945 * monspecs, we should be paranoid and not let use go above
946 * 640x480-60, but I assume userland knows what it's doing here
947 * (though I may be proven wrong...)
949 if (has_rmx == 0 && rinfo->mon1_modedb)
950 if (fb_validate_mode((struct fb_var_screeninfo *)src, rinfo->info))
955 /* Now look for a mode in the database */
957 for (i = 0; i < dbsize; i++) {
960 if (db[i].yres < src->yres)
962 if (db[i].xres < src->xres)
964 g = radeon_compare_modes(src, &db[i]);
965 /* If the new mode is at least as good as the previous one,
966 * then it's our new candidate
974 /* If we have a scaler, we allow any mode from the database */
975 if (native_db && has_rmx) {
982 /* If we have found a match, return it */
983 if (candidate != NULL) {
984 radeon_videomode_to_var(dest, candidate);
988 /* If we haven't and don't have a scaler, fail */