File Index
Files and directories
Sign in
FILE

radeon_monitor.c

File preview with syntax highlighting.

linux-6.19.14/drivers/video/fbdev/aty/radeon_monitor.c C
   1// SPDX-License-Identifier: GPL-2.0
   2#include "radeonfb.h"
   3
   4#include <linux/slab.h>
   5
   6#include "../edid.h"
   7
   8static const struct fb_var_screeninfo radeonfb_default_var = {
   9	.xres		= 640,
  10	.yres		= 480,
  11	.xres_virtual	= 640,
  12	.yres_virtual	= 480,
  13	.bits_per_pixel = 8,
  14	.red		= { .length = 8 },
  15	.green		= { .length = 8 },
  16	.blue		= { .length = 8 },
  17	.activate	= FB_ACTIVATE_NOW,
  18	.height		= -1,
  19	.width		= -1,
  20	.pixclock	= 39721,
  21	.left_margin	= 40,
  22	.right_margin	= 24,
  23	.upper_margin	= 32,
  24	.lower_margin	= 11,
  25	.hsync_len	= 96,
  26	.vsync_len	= 2,
  27	.vmode		= FB_VMODE_NONINTERLACED
  28};
  29
  30static char *radeon_get_mon_name(int type)
  31{
  32	char *pret = NULL;
  33
  34	switch (type) {
  35		case MT_NONE:
  36			pret = "no";
  37			break;
  38		case MT_CRT:
  39			pret = "CRT";
  40			break;
  41		case MT_DFP:
  42			pret = "DFP";
  43			break;
  44		case MT_LCD:
  45			pret = "LCD";
  46			break;
  47		case MT_CTV:
  48			pret = "CTV";
  49			break;
  50		case MT_STV:
  51			pret = "STV";
  52			break;
  53	}
  54
  55	return pret;
  56}
  57
  58
  59#if defined(CONFIG_PPC) || defined(CONFIG_SPARC)
  60/*
  61 * Try to find monitor informations & EDID data out of the Open Firmware
  62 * device-tree. This also contains some "hacks" to work around a few machine
  63 * models with broken OF probing by hard-coding known EDIDs for some Mac
  64 * laptops internal LVDS panel. (XXX: not done yet)
  65 */
  66static int radeon_parse_montype_prop(struct device_node *dp, u8 **out_EDID,
  67				     int hdno)
  68{
  69        static char *propnames[] = { "DFP,EDID", "LCD,EDID", "EDID",
  70				     "EDID1", "EDID2",  NULL };
  71	const u8 *pedid = NULL;
  72	const u8 *pmt = NULL;
  73	u8 *tmp;
  74        int i, mt = MT_NONE;  
  75	
  76	pr_debug("analyzing OF properties...\n");
  77	pmt = of_get_property(dp, "display-type", NULL);
  78	if (!pmt)
  79		return MT_NONE;
  80	pr_debug("display-type: %s\n", pmt);
  81	/* OF says "LCD" for DFP as well, we discriminate from the caller of this
  82	 * function
  83	 */
  84	if (!strcmp(pmt, "LCD") || !strcmp(pmt, "DFP"))
  85		mt = MT_DFP;
  86	else if (!strcmp(pmt, "CRT"))
  87		mt = MT_CRT;
  88	else {
  89		if (strcmp(pmt, "NONE") != 0)
  90			printk(KERN_WARNING "radeonfb: Unknown OF display-type: %s\n",
  91			       pmt);
  92		return MT_NONE;
  93	}
  94
  95	for (i = 0; propnames[i] != NULL; ++i) {
  96		pedid = of_get_property(dp, propnames[i], NULL);
  97		if (pedid != NULL)
  98			break;
  99	}
 100	/* We didn't find the EDID in the leaf node, some cards will actually
 101	 * put EDID1/EDID2 in the parent, look for these (typically M6 tipb).
 102	 * single-head cards have hdno == -1 and skip this step
 103	 */
 104	if (pedid == NULL && dp->parent && (hdno != -1))
 105		pedid = of_get_property(dp->parent,
 106				(hdno == 0) ? "EDID1" : "EDID2", NULL);
 107	if (pedid == NULL && dp->parent && (hdno == 0))
 108		pedid = of_get_property(dp->parent, "EDID", NULL);
 109	if (pedid == NULL)
 110		return mt;
 111
 112	tmp = kmemdup(pedid, EDID_LENGTH, GFP_KERNEL);
 113	if (!tmp)
 114		return mt;
 115	*out_EDID = tmp;
 116	return mt;
 117}
 118
 119static int radeon_probe_OF_head(struct radeonfb_info *rinfo, int head_no,
 120				u8 **out_EDID)
 121{
 122        struct device_node *dp;
 123
 124	pr_debug("radeon_probe_OF_head\n");
 125
 126        dp = rinfo->of_node;
 127        while (dp == NULL)
 128		return MT_NONE;
 129
 130	if (rinfo->has_CRTC2) {
 131		const char *pname;
 132		int len, second = 0;
 133
 134		dp = dp->child;
 135		do {
 136			if (!dp)
 137				return MT_NONE;
 138			pname = of_get_property(dp, "name", NULL);
 139			if (!pname)
 140				return MT_NONE;
 141			len = strlen(pname);
 142			pr_debug("head: %s (letter: %c, head_no: %d)\n",
 143			       pname, pname[len-1], head_no);
 144			if (pname[len-1] == 'A' && head_no == 0) {
 145				int mt = radeon_parse_montype_prop(dp, out_EDID, 0);
 146				/* Maybe check for LVDS_GEN_CNTL here ? I need to check out
 147				 * what OF does when booting with lid closed
 148				 */
 149				if (mt == MT_DFP && rinfo->is_mobility)
 150					mt = MT_LCD;
 151				return mt;
 152			} else if (pname[len-1] == 'B' && head_no == 1)
 153				return radeon_parse_montype_prop(dp, out_EDID, 1);
 154			second = 1;
 155			dp = dp->sibling;
 156		} while(!second);
 157	} else {
 158		if (head_no > 0)
 159			return MT_NONE;
 160		return radeon_parse_montype_prop(dp, out_EDID, -1);
 161	}
 162        return MT_NONE;
 163}
 164#endif /* CONFIG_PPC || CONFIG_SPARC */
 165
 166
 167static int radeon_get_panel_info_BIOS(struct radeonfb_info *rinfo)
 168{
 169	unsigned long tmp, tmp0;
 170	char stmp[30];
 171	int i;
 172
 173	if (!rinfo->bios_seg)
 174		return 0;
 175
 176	if (!(tmp = BIOS_IN16(rinfo->fp_bios_start + 0x40))) {
 177		printk(KERN_ERR "radeonfb: Failed to detect DFP panel info using BIOS\n");
 178		rinfo->panel_info.pwr_delay = 200;
 179		return 0;
 180	}
 181
 182	for(i=0; i<24; i++)
 183		stmp[i] = BIOS_IN8(tmp+i+1);
 184	stmp[24] = 0;
 185	printk("radeonfb: panel ID string: %s\n", stmp);
 186	rinfo->panel_info.xres = BIOS_IN16(tmp + 25);
 187	rinfo->panel_info.yres = BIOS_IN16(tmp + 27);
 188	printk("radeonfb: detected LVDS panel size from BIOS: %dx%d\n",
 189		rinfo->panel_info.xres, rinfo->panel_info.yres);
 190
 191	rinfo->panel_info.pwr_delay = BIOS_IN16(tmp + 44);
 192	pr_debug("BIOS provided panel power delay: %d\n", rinfo->panel_info.pwr_delay);
 193	if (rinfo->panel_info.pwr_delay > 2000 || rinfo->panel_info.pwr_delay <= 0)
 194		rinfo->panel_info.pwr_delay = 2000;
 195
 196	/*
 197	 * Some panels only work properly with some divider combinations
 198	 */
 199	rinfo->panel_info.ref_divider = BIOS_IN16(tmp + 46);
 200	rinfo->panel_info.post_divider = BIOS_IN8(tmp + 48);
 201	rinfo->panel_info.fbk_divider = BIOS_IN16(tmp + 49);
 202	if (rinfo->panel_info.ref_divider != 0 &&
 203	    rinfo->panel_info.fbk_divider > 3) {
 204		rinfo->panel_info.use_bios_dividers = 1;
 205		printk(KERN_INFO "radeondb: BIOS provided dividers will be used\n");
 206		pr_debug("ref_divider = %x\n", rinfo->panel_info.ref_divider);
 207		pr_debug("post_divider = %x\n", rinfo->panel_info.post_divider);
 208		pr_debug("fbk_divider = %x\n", rinfo->panel_info.fbk_divider);
 209	}
 210	pr_debug("Scanning BIOS table ...\n");
 211	for(i=0; i<32; i++) {
 212		tmp0 = BIOS_IN16(tmp+64+i*2);
 213		if (tmp0 == 0)
 214			break;
 215		pr_debug(" %d x %d\n", BIOS_IN16(tmp0), BIOS_IN16(tmp0+2));
 216		if ((BIOS_IN16(tmp0) == rinfo->panel_info.xres) &&
 217		    (BIOS_IN16(tmp0+2) == rinfo->panel_info.yres)) {
 218			rinfo->panel_info.hblank = (BIOS_IN16(tmp0+17) - BIOS_IN16(tmp0+19)) * 8;
 219			rinfo->panel_info.hOver_plus = ((BIOS_IN16(tmp0+21) -
 220							 BIOS_IN16(tmp0+19) -1) * 8) & 0x7fff;
 221			rinfo->panel_info.hSync_width = BIOS_IN8(tmp0+23) * 8;
 222			rinfo->panel_info.vblank = BIOS_IN16(tmp0+24) - BIOS_IN16(tmp0+26);
 223			rinfo->panel_info.vOver_plus = (BIOS_IN16(tmp0+28) & 0x7ff) - BIOS_IN16(tmp0+26);
 224			rinfo->panel_info.vSync_width = (BIOS_IN16(tmp0+28) & 0xf800) >> 11;
 225			rinfo->panel_info.clock = BIOS_IN16(tmp0+9);
 226			/* Assume high active syncs for now until ATI tells me more... maybe we
 227			 * can probe register values here ?
 228			 */
 229			rinfo->panel_info.hAct_high = 1;
 230			rinfo->panel_info.vAct_high = 1;
 231			/* Mark panel infos valid */
 232			rinfo->panel_info.valid = 1;
 233
 234			pr_debug("Found panel in BIOS table:\n");
 235			pr_debug("  hblank: %d\n", rinfo->panel_info.hblank);
 236			pr_debug("  hOver_plus: %d\n", rinfo->panel_info.hOver_plus);
 237			pr_debug("  hSync_width: %d\n", rinfo->panel_info.hSync_width);
 238			pr_debug("  vblank: %d\n", rinfo->panel_info.vblank);
 239			pr_debug("  vOver_plus: %d\n", rinfo->panel_info.vOver_plus);
 240			pr_debug("  vSync_width: %d\n", rinfo->panel_info.vSync_width);
 241			pr_debug("  clock: %d\n", rinfo->panel_info.clock);
 242				
 243			return 1;
 244		}
 245	}
 246	pr_debug("Didn't find panel in BIOS table !\n");
 247
 248	return 0;
 249}
 250
 251/* Try to extract the connector informations from the BIOS. This
 252 * doesn't quite work yet, but it's output is still useful for
 253 * debugging
 254 */
 255static void radeon_parse_connector_info(struct radeonfb_info *rinfo)
 256{
 257	int offset, chips, connectors, tmp, i, conn, type;
 258
 259	static char* __conn_type_table[16] = {
 260		"NONE", "Proprietary", "CRT", "DVI-I", "DVI-D", "Unknown", "Unknown",
 261		"Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown",
 262		"Unknown", "Unknown", "Unknown"
 263	};
 264
 265	if (!rinfo->bios_seg)
 266		return;
 267
 268	offset = BIOS_IN16(rinfo->fp_bios_start + 0x50);
 269	if (offset == 0) {
 270		printk(KERN_WARNING "radeonfb: No connector info table detected\n");
 271		return;
 272	}
 273
 274	/* Don't do much more at this point but displaying the data if
 275	 * DEBUG is enabled
 276	 */
 277	chips = BIOS_IN8(offset++) >> 4;
 278	pr_debug("%d chips in connector info\n", chips);
 279	for (i = 0; i < chips; i++) {
 280		tmp = BIOS_IN8(offset++);
 281		connectors = tmp & 0x0f;
 282		pr_debug(" - chip %d has %d connectors\n", tmp >> 4, connectors);
 283		for (conn = 0; ; conn++) {
 284			tmp = BIOS_IN16(offset);
 285			if (tmp == 0)
 286				break;
 287			offset += 2;
 288			type = (tmp >> 12) & 0x0f;
 289			pr_debug("  * connector %d of type %d (%s) : %04x\n",
 290			       conn, type, __conn_type_table[type], tmp);
 291		}
 292	}
 293}
 294
 295
 296/*
 297 * Probe physical connection of a CRT. This code comes from XFree
 298 * as well and currently is only implemented for the CRT DAC, the
 299 * code for the TVDAC is commented out in XFree as "non working"
 300 */
 301static int radeon_crt_is_connected(struct radeonfb_info *rinfo, int is_crt_dac)
 302{
 303    int	          connected = 0;
 304
 305    /* the monitor either wasn't connected or it is a non-DDC CRT.
 306     * try to probe it
 307     */
 308    if (is_crt_dac) {
 309	unsigned long ulOrigVCLK_ECP_CNTL;
 310	unsigned long ulOrigDAC_CNTL;
 311	unsigned long ulOrigDAC_EXT_CNTL;
 312	unsigned long ulOrigCRTC_EXT_CNTL;
 313	unsigned long ulData;
 314	unsigned long ulMask;
 315
 316	ulOrigVCLK_ECP_CNTL = INPLL(VCLK_ECP_CNTL);
 317
 318	ulData              = ulOrigVCLK_ECP_CNTL;
 319	ulData             &= ~(PIXCLK_ALWAYS_ONb
 320				| PIXCLK_DAC_ALWAYS_ONb);
 321	ulMask              = ~(PIXCLK_ALWAYS_ONb
 322				| PIXCLK_DAC_ALWAYS_ONb);
 323	OUTPLLP(VCLK_ECP_CNTL, ulData, ulMask);
 324
 325	ulOrigCRTC_EXT_CNTL = INREG(CRTC_EXT_CNTL);
 326	ulData              = ulOrigCRTC_EXT_CNTL;
 327	ulData             |= CRTC_CRT_ON;
 328	OUTREG(CRTC_EXT_CNTL, ulData);
 329   
 330	ulOrigDAC_EXT_CNTL = INREG(DAC_EXT_CNTL);
 331	ulData             = ulOrigDAC_EXT_CNTL;
 332	ulData            &= ~DAC_FORCE_DATA_MASK;
 333	ulData            |=  (DAC_FORCE_BLANK_OFF_EN
 334			       |DAC_FORCE_DATA_EN
 335			       |DAC_FORCE_DATA_SEL_MASK);
 336	if ((rinfo->family == CHIP_FAMILY_RV250) ||
 337	    (rinfo->family == CHIP_FAMILY_RV280))
 338	    ulData |= (0x01b6 << DAC_FORCE_DATA_SHIFT);
 339	else
 340	    ulData |= (0x01ac << DAC_FORCE_DATA_SHIFT);
 341
 342	OUTREG(DAC_EXT_CNTL, ulData);
 343
 344	ulOrigDAC_CNTL     = INREG(DAC_CNTL);
 345	ulData             = ulOrigDAC_CNTL;
 346	ulData            |= DAC_CMP_EN;
 347	ulData            &= ~(DAC_RANGE_CNTL_MASK
 348			       | DAC_PDWN);
 349	ulData            |= 0x2;
 350	OUTREG(DAC_CNTL, ulData);
 351
 352	mdelay(1);
 353
 354	ulData     = INREG(DAC_CNTL);
 355	connected =  (DAC_CMP_OUTPUT & ulData) ? 1 : 0;
 356  
 357	ulData    = ulOrigVCLK_ECP_CNTL;
 358	ulMask    = 0xFFFFFFFFL;
 359	OUTPLLP(VCLK_ECP_CNTL, ulData, ulMask);
 360
 361	OUTREG(DAC_CNTL,      ulOrigDAC_CNTL     );
 362	OUTREG(DAC_EXT_CNTL,  ulOrigDAC_EXT_CNTL );
 363	OUTREG(CRTC_EXT_CNTL, ulOrigCRTC_EXT_CNTL);
 364    }
 365
 366    return connected ? MT_CRT : MT_NONE;
 367}
 368
 369/*
 370 * Parse the "monitor_layout" string if any. This code is mostly
 371 * copied from XFree's radeon driver
 372 */
 373static int radeon_parse_monitor_layout(struct radeonfb_info *rinfo,
 374				       const char *monitor_layout)
 375{
 376	char s1[5], s2[5];
 377	int i = 0, second = 0;
 378	const char *s;
 379
 380	if (!monitor_layout)
 381		return 0;
 382
 383	s = monitor_layout;
 384	do {
 385		switch(*s) {
 386		case ',':
 387			s1[i] = '\0';
 388			i = 0;
 389			second = 1;
 390			break;
 391		case ' ':
 392		case '\0':
 393			break;
 394		default:
 395			if (i > 4)
 396				break;
 397			if (second)
 398				s2[i] = *s;
 399			else
 400				s1[i] = *s;
 401			i++;
 402		}
 403
 404		if (i > 4)
 405			i = 4;
 406
 407	} while (*s++);
 408	if (second)
 409		s2[i] = 0;
 410	else {
 411		s1[i] = 0;
 412		s2[0] = 0;
 413	}
 414	if (strcmp(s1, "CRT") == 0)
 415		rinfo->mon1_type = MT_CRT;
 416	else if (strcmp(s1, "TMDS") == 0)
 417		rinfo->mon1_type = MT_DFP;
 418	else if (strcmp(s1, "LVDS") == 0)
 419		rinfo->mon1_type = MT_LCD;
 420
 421	if (strcmp(s2, "CRT") == 0)
 422		rinfo->mon2_type = MT_CRT;
 423	else if (strcmp(s2, "TMDS") == 0)
 424		rinfo->mon2_type = MT_DFP;
 425	else if (strcmp(s2, "LVDS") == 0)
 426		rinfo->mon2_type = MT_LCD;
 427
 428	return 1;
 429}
 430
 431/*
 432 * Probe display on both primary and secondary card's connector (if any)
 433 * by various available techniques (i2c, OF device tree, BIOS, ...) and
 434 * try to retrieve EDID. The algorithm here comes from XFree's radeon
 435 * driver
 436 */
 437void radeon_probe_screens(struct radeonfb_info *rinfo,
 438			  const char *monitor_layout, int ignore_edid)
 439{
 440#ifdef CONFIG_FB_RADEON_I2C
 441	int ddc_crt2_used = 0;	
 442#endif
 443	int tmp, i;
 444
 445	radeon_parse_connector_info(rinfo);
 446
 447	if (radeon_parse_monitor_layout(rinfo, monitor_layout)) {
 448
 449		/*
 450		 * If user specified a monitor_layout option, use it instead
 451		 * of auto-detecting. Maybe we should only use this argument
 452		 * on the first radeon card probed or provide a way to specify
 453		 * a layout for each card ?
 454		 */
 455
 456		pr_debug("Using specified monitor layout: %s", monitor_layout);
 457#ifdef CONFIG_FB_RADEON_I2C
 458		if (!ignore_edid) {
 459			if (rinfo->mon1_type != MT_NONE)
 460				if (!radeon_probe_i2c_connector(rinfo, ddc_dvi, &rinfo->mon1_EDID)) {
 461					radeon_probe_i2c_connector(rinfo, ddc_crt2, &rinfo->mon1_EDID);
 462					ddc_crt2_used = 1;
 463				}
 464			if (rinfo->mon2_type != MT_NONE)
 465				if (!radeon_probe_i2c_connector(rinfo, ddc_vga, &rinfo->mon2_EDID) &&
 466				    !ddc_crt2_used)
 467					radeon_probe_i2c_connector(rinfo, ddc_crt2, &rinfo->mon2_EDID);
 468		}
 469#endif /* CONFIG_FB_RADEON_I2C */
 470		if (rinfo->mon1_type == MT_NONE) {
 471			if (rinfo->mon2_type != MT_NONE) {
 472				rinfo->mon1_type = rinfo->mon2_type;
 473				rinfo->mon1_EDID = rinfo->mon2_EDID;
 474			} else {
 475				rinfo->mon1_type = MT_CRT;
 476				printk(KERN_INFO "radeonfb: No valid monitor, assuming CRT on first port\n");
 477			}
 478			rinfo->mon2_type = MT_NONE;
 479			rinfo->mon2_EDID = NULL;
 480		}
 481	} else {
 482		/*
 483		 * Auto-detecting display type (well... trying to ...)
 484		 */
 485		
 486		pr_debug("Starting monitor auto detection...\n");
 487
 488#if defined(DEBUG) && defined(CONFIG_FB_RADEON_I2C)
 489		{
 490			u8 *EDIDs[4] = { NULL, NULL, NULL, NULL };
 491			int i;
 492
 493			for (i = 0; i < 4; i++)
 494				radeon_probe_i2c_connector(rinfo, i + 1, &EDIDs[i]);
 495		}
 496#endif /* DEBUG */
 497		/*
 498		 * Old single head cards
 499		 */
 500		if (!rinfo->has_CRTC2) {
 501#if defined(CONFIG_PPC) || defined(CONFIG_SPARC)
 502			if (rinfo->mon1_type == MT_NONE)
 503				rinfo->mon1_type = radeon_probe_OF_head(rinfo, 0,
 504									&rinfo->mon1_EDID);
 505#endif /* CONFIG_PPC || CONFIG_SPARC */
 506#ifdef CONFIG_FB_RADEON_I2C
 507			if (rinfo->mon1_type == MT_NONE)
 508				rinfo->mon1_type =
 509					radeon_probe_i2c_connector(rinfo, ddc_dvi,
 510								   &rinfo->mon1_EDID);
 511			if (rinfo->mon1_type == MT_NONE)
 512				rinfo->mon1_type =
 513					radeon_probe_i2c_connector(rinfo, ddc_vga,
 514								   &rinfo->mon1_EDID);
 515			if (rinfo->mon1_type == MT_NONE)
 516				rinfo->mon1_type =
 517					radeon_probe_i2c_connector(rinfo, ddc_crt2,
 518								   &rinfo->mon1_EDID);	
 519#endif /* CONFIG_FB_RADEON_I2C */
 520			if (rinfo->mon1_type == MT_NONE)
 521				rinfo->mon1_type = MT_CRT;
 522			goto bail;
 523		}
 524
 525		/*
 526		 * Check for cards with reversed DACs or TMDS controllers using BIOS
 527		 */
 528		if (rinfo->bios_seg &&
 529		    (tmp = BIOS_IN16(rinfo->fp_bios_start + 0x50))) {
 530			for (i = 1; i < 4; i++) {
 531				unsigned int tmp0;
 532
 533				if (!BIOS_IN8(tmp + i*2) && i > 1)
 534					break;
 535				tmp0 = BIOS_IN16(tmp + i*2);
 536				if ((!(tmp0 & 0x01)) && (((tmp0 >> 8) & 0x0f) == ddc_dvi)) {
 537					rinfo->reversed_DAC = 1;
 538					printk(KERN_INFO "radeonfb: Reversed DACs detected\n");
 539				}
 540				if ((((tmp0 >> 8) & 0x0f) == ddc_dvi) && ((tmp0 >> 4) & 0x01)) {
 541					rinfo->reversed_TMDS = 1;
 542					printk(KERN_INFO "radeonfb: Reversed TMDS detected\n");
 543				}
 544			}
 545		}
 546
 547		/*
 548		 * Probe primary head (DVI or laptop internal panel)
 549		 */
 550#if defined(CONFIG_PPC) || defined(CONFIG_SPARC)
 551		if (rinfo->mon1_type == MT_NONE)
 552			rinfo->mon1_type = radeon_probe_OF_head(rinfo, 0,
 553								&rinfo->mon1_EDID);
 554#endif /* CONFIG_PPC || CONFIG_SPARC */
 555#ifdef CONFIG_FB_RADEON_I2C
 556		if (rinfo->mon1_type == MT_NONE)
 557			rinfo->mon1_type = radeon_probe_i2c_connector(rinfo, ddc_dvi,
 558								      &rinfo->mon1_EDID);
 559		if (rinfo->mon1_type == MT_NONE) {
 560			rinfo->mon1_type = radeon_probe_i2c_connector(rinfo, ddc_crt2,
 561								      &rinfo->mon1_EDID);
 562			if (rinfo->mon1_type != MT_NONE)
 563				ddc_crt2_used = 1;
 564		}
 565#endif /* CONFIG_FB_RADEON_I2C */
 566		if (rinfo->mon1_type == MT_NONE && rinfo->is_mobility &&
 567		    ((rinfo->bios_seg && (INREG(BIOS_4_SCRATCH) & 4))
 568		     || (INREG(LVDS_GEN_CNTL) & LVDS_ON))) {
 569			rinfo->mon1_type = MT_LCD;
 570			printk("Non-DDC laptop panel detected\n");
 571		}
 572		if (rinfo->mon1_type == MT_NONE)
 573			rinfo->mon1_type = radeon_crt_is_connected(rinfo, rinfo->reversed_DAC);
 574
 575		/*
 576		 * Probe secondary head (mostly VGA, can be DVI)
 577		 */
 578#if defined(CONFIG_PPC) || defined(CONFIG_SPARC)
 579		if (rinfo->mon2_type == MT_NONE)
 580			rinfo->mon2_type = radeon_probe_OF_head(rinfo, 1,
 581								&rinfo->mon2_EDID);
 582#endif /* CONFIG_PPC || defined(CONFIG_SPARC) */
 583#ifdef CONFIG_FB_RADEON_I2C
 584		if (rinfo->mon2_type == MT_NONE)
 585			rinfo->mon2_type = radeon_probe_i2c_connector(rinfo, ddc_vga,
 586								      &rinfo->mon2_EDID);
 587		if (rinfo->mon2_type == MT_NONE && !ddc_crt2_used)
 588			rinfo->mon2_type = radeon_probe_i2c_connector(rinfo, ddc_crt2,
 589								      &rinfo->mon2_EDID);
 590#endif /* CONFIG_FB_RADEON_I2C */
 591		if (rinfo->mon2_type == MT_NONE)
 592			rinfo->mon2_type = radeon_crt_is_connected(rinfo, !rinfo->reversed_DAC);
 593
 594		/*
 595		 * If we only detected port 2, we swap them, if none detected,
 596		 * assume CRT (maybe fallback to old BIOS_SCRATCH stuff ? or look
 597		 * at FP registers ?)
 598		 */
 599		if (rinfo->mon1_type == MT_NONE) {
 600			if (rinfo->mon2_type != MT_NONE) {
 601				rinfo->mon1_type = rinfo->mon2_type;
 602				rinfo->mon1_EDID = rinfo->mon2_EDID;
 603			} else
 604				rinfo->mon1_type = MT_CRT;
 605			rinfo->mon2_type = MT_NONE;
 606			rinfo->mon2_EDID = NULL;
 607		}
 608
 609		/*
 610		 * Deal with reversed TMDS
 611		 */
 612		if (rinfo->reversed_TMDS) {
 613			/* Always keep internal TMDS as primary head */
 614			if (rinfo->mon1_type == MT_DFP || rinfo->mon2_type == MT_DFP) {
 615				int tmp_type = rinfo->mon1_type;
 616				u8 *tmp_EDID = rinfo->mon1_EDID;
 617				rinfo->mon1_type = rinfo->mon2_type;
 618				rinfo->mon1_EDID = rinfo->mon2_EDID;
 619				rinfo->mon2_type = tmp_type;
 620				rinfo->mon2_EDID = tmp_EDID;
 621				if (rinfo->mon1_type == MT_CRT || rinfo->mon2_type == MT_CRT)
 622					rinfo->reversed_DAC ^= 1;
 623			}
 624		}
 625	}
 626	if (ignore_edid) {
 627		kfree(rinfo->mon1_EDID);
 628		rinfo->mon1_EDID = NULL;
 629		kfree(rinfo->mon2_EDID);
 630		rinfo->mon2_EDID = NULL;
 631	}
 632
 633 bail:
 634	printk(KERN_INFO "radeonfb: Monitor 1 type %s found\n",
 635	       radeon_get_mon_name(rinfo->mon1_type));
 636	if (rinfo->mon1_EDID)
 637		printk(KERN_INFO "radeonfb: EDID probed\n");
 638	if (!rinfo->has_CRTC2)
 639		return;
 640	printk(KERN_INFO "radeonfb: Monitor 2 type %s found\n",
 641	       radeon_get_mon_name(rinfo->mon2_type));
 642	if (rinfo->mon2_EDID)
 643		printk(KERN_INFO "radeonfb: EDID probed\n");
 644}
 645
 646
 647/*
 648 * This function applies any arch/model/machine specific fixups
 649 * to the panel info. It may eventually alter EDID block as
 650 * well or whatever is specific to a given model and not probed
 651 * properly by the default code
 652 */
 653static void radeon_fixup_panel_info(struct radeonfb_info *rinfo)
 654{
 655#ifdef CONFIG_PPC
 656	/*
 657	 * LCD Flat panels should use fixed dividers, we enfore that on
 658	 * PPC only for now...
 659	 */
 660	if (!rinfo->panel_info.use_bios_dividers && rinfo->mon1_type == MT_LCD
 661	    && rinfo->is_mobility) {
 662		int ppll_div_sel;
 663		u32 ppll_divn;
 664		ppll_div_sel = INREG8(CLOCK_CNTL_INDEX + 1) & 0x3;
 665		radeon_pll_errata_after_index(rinfo);
 666		ppll_divn = INPLL(PPLL_DIV_0 + ppll_div_sel);
 667		rinfo->panel_info.ref_divider = rinfo->pll.ref_div;
 668		rinfo->panel_info.fbk_divider = ppll_divn & 0x7ff;
 669		rinfo->panel_info.post_divider = (ppll_divn >> 16) & 0x7;
 670		rinfo->panel_info.use_bios_dividers = 1;
 671
 672		printk(KERN_DEBUG "radeonfb: Using Firmware dividers 0x%08x "
 673		       "from PPLL %d\n",
 674		       rinfo->panel_info.fbk_divider |
 675		       (rinfo->panel_info.post_divider << 16),
 676		       ppll_div_sel);
 677	}
 678#endif /* CONFIG_PPC */
 679}
 680
 681
 682/*
 683 * Fill up panel infos from a mode definition, either returned by the EDID
 684 * or from the default mode when we can't do any better
 685 */
 686static void radeon_var_to_panel_info(struct radeonfb_info *rinfo, struct fb_var_screeninfo *var)
 687{
 688	rinfo->panel_info.xres = var->xres;
 689	rinfo->panel_info.yres = var->yres;
 690	rinfo->panel_info.clock = 100000000 / var->pixclock;
 691	rinfo->panel_info.hOver_plus = var->right_margin;
 692	rinfo->panel_info.hSync_width = var->hsync_len;
 693       	rinfo->panel_info.hblank = var->left_margin +
 694		(var->right_margin + var->hsync_len);
 695	rinfo->panel_info.vOver_plus = var->lower_margin;
 696	rinfo->panel_info.vSync_width = var->vsync_len;
 697       	rinfo->panel_info.vblank = var->upper_margin +
 698		(var->lower_margin + var->vsync_len);
 699	rinfo->panel_info.hAct_high =
 700		(var->sync & FB_SYNC_HOR_HIGH_ACT) != 0;
 701	rinfo->panel_info.vAct_high =
 702		(var->sync & FB_SYNC_VERT_HIGH_ACT) != 0;
 703	rinfo->panel_info.valid = 1;
 704	/* We use a default of 200ms for the panel power delay, 
 705	 * I need to have a real schedule() instead of mdelay's in the panel code.
 706	 * we might be possible to figure out a better power delay either from
 707	 * MacOS OF tree or from the EDID block (proprietary extensions ?)
 708	 */
 709	rinfo->panel_info.pwr_delay = 200;
 710}
 711
 712static void radeon_videomode_to_var(struct fb_var_screeninfo *var,
 713				    const struct fb_videomode *mode)
 714{
 715	var->xres = mode->xres;
 716	var->yres = mode->yres;
 717	var->xres_virtual = mode->xres;
 718	var->yres_virtual = mode->yres;
 719	var->xoffset = 0;
 720	var->yoffset = 0;
 721	var->pixclock = mode->pixclock;
 722	var->left_margin = mode->left_margin;
 723	var->right_margin = mode->right_margin;
 724	var->upper_margin = mode->upper_margin;
 725	var->lower_margin = mode->lower_margin;
 726	var->hsync_len = mode->hsync_len;
 727	var->vsync_len = mode->vsync_len;
 728	var->sync = mode->sync;
 729	var->vmode = mode->vmode;
 730}
 731
 732#ifdef CONFIG_PPC_PSERIES
 733static int is_powerblade(const char *model)
 734{
 735	struct device_node *root;
 736	const char* cp;
 737	int len, l, rc = 0;
 738
 739	root = of_find_node_by_path("/");
 740	if (root && model) {
 741		l = strlen(model);
 742		cp = of_get_property(root, "model", &len);
 743		if (cp)
 744			rc = memcmp(model, cp, min(len, l)) == 0;
 745		of_node_put(root);
 746	}
 747	return rc;
 748}
 749#endif
 750
 751/*
 752 * Build the modedb for head 1 (head 2 will come later), check panel infos
 753 * from either BIOS or EDID, and pick up the default mode
 754 */
 755void radeon_check_modes(struct radeonfb_info *rinfo, const char *mode_option)
 756{
 757	struct fb_info * info = rinfo->info;
 758	int has_default_mode = 0;
 759
 760	/*
 761	 * Fill default var first
 762	 */
 763	info->var = radeonfb_default_var;
 764	INIT_LIST_HEAD(&info->modelist);
 765
 766	/*
 767	 * First check out what BIOS has to say
 768	 */
 769	if (rinfo->mon1_type == MT_LCD)
 770		radeon_get_panel_info_BIOS(rinfo);
 771
 772	/*
 773	 * Parse EDID detailed timings and deduce panel infos if any. Right now
 774	 * we only deal with first entry returned by parse_EDID, we may do better
 775	 * some day...
 776	 */
 777	if (!rinfo->panel_info.use_bios_dividers && rinfo->mon1_type != MT_CRT
 778	    && rinfo->mon1_EDID) {
 779		struct fb_var_screeninfo var;
 780		pr_debug("Parsing EDID data for panel info\n");
 781		if (fb_parse_edid(rinfo->mon1_EDID, &var) == 0) {
 782			if (var.xres >= rinfo->panel_info.xres &&
 783			    var.yres >= rinfo->panel_info.yres)
 784				radeon_var_to_panel_info(rinfo, &var);
 785		}
 786	}
 787
 788	/*
 789	 * Do any additional platform/arch fixups to the panel infos
 790	 */
 791	radeon_fixup_panel_info(rinfo);
 792
 793	/*
 794	 * If we have some valid panel infos, we setup the default mode based on
 795	 * those
 796	 */
 797	if (rinfo->mon1_type != MT_CRT && rinfo->panel_info.valid) {
 798		struct fb_var_screeninfo *var = &info->var;
 799
 800		pr_debug("Setting up default mode based on panel info\n");
 801		var->xres = rinfo->panel_info.xres;
 802		var->yres = rinfo->panel_info.yres;
 803		var->xres_virtual = rinfo->panel_info.xres;
 804		var->yres_virtual = rinfo->panel_info.yres;
 805		var->xoffset = var->yoffset = 0;
 806		var->bits_per_pixel = 8;
 807		var->pixclock = 100000000 / rinfo->panel_info.clock;
 808		var->left_margin = (rinfo->panel_info.hblank - rinfo->panel_info.hOver_plus
 809				    - rinfo->panel_info.hSync_width);
 810		var->right_margin = rinfo->panel_info.hOver_plus;
 811		var->upper_margin = (rinfo->panel_info.vblank - rinfo->panel_info.vOver_plus
 812				     - rinfo->panel_info.vSync_width);
 813		var->lower_margin = rinfo->panel_info.vOver_plus;
 814		var->hsync_len = rinfo->panel_info.hSync_width;
 815		var->vsync_len = rinfo->panel_info.vSync_width;
 816		var->sync = 0;
 817		if (rinfo->panel_info.hAct_high)
 818			var->sync |= FB_SYNC_HOR_HIGH_ACT;
 819		if (rinfo->panel_info.vAct_high)
 820			var->sync |= FB_SYNC_VERT_HIGH_ACT;
 821		var->vmode = 0;
 822		has_default_mode = 1;
 823	}
 824
 825	/*
 826	 * Now build modedb from EDID
 827	 */
 828	if (rinfo->mon1_EDID) {
 829		fb_edid_to_monspecs(rinfo->mon1_EDID, &info->monspecs);
 830		fb_videomode_to_modelist(info->monspecs.modedb,
 831					 info->monspecs.modedb_len,
 832					 &info->modelist);
 833		rinfo->mon1_modedb = info->monspecs.modedb;
 834		rinfo->mon1_dbsize = info->monspecs.modedb_len;
 835	}
 836
 837	
 838	/*
 839	 * Finally, if we don't have panel infos we need to figure some (or
 840	 * we try to read it from card), we try to pick a default mode
 841	 * and create some panel infos. Whatever...
 842	 */
 843	if (rinfo->mon1_type != MT_CRT && !rinfo->panel_info.valid) {
 844		struct fb_videomode	*modedb;
 845		int			dbsize;
 846		char			modename[32];
 847
 848		pr_debug("Guessing panel info...\n");
 849		if (rinfo->panel_info.xres == 0 || rinfo->panel_info.yres == 0) {
 850			u32 tmp = INREG(FP_HORZ_STRETCH) & HORZ_PANEL_SIZE;
 851			rinfo->panel_info.xres = ((tmp >> HORZ_PANEL_SHIFT) + 1) * 8;
 852			tmp = INREG(FP_VERT_STRETCH) & VERT_PANEL_SIZE;
 853			rinfo->panel_info.yres = (tmp >> VERT_PANEL_SHIFT) + 1;
 854		}
 855		if (rinfo->panel_info.xres == 0 || rinfo->panel_info.yres == 0) {
 856			printk(KERN_WARNING "radeonfb: Can't find panel size, going back to CRT\n");
 857			rinfo->mon1_type = MT_CRT;
 858			goto pickup_default;
 859		}
 860		printk(KERN_WARNING "radeonfb: Assuming panel size %dx%d\n",
 861		       rinfo->panel_info.xres, rinfo->panel_info.yres);
 862		modedb = rinfo->mon1_modedb;
 863		dbsize = rinfo->mon1_dbsize;
 864		snprintf(modename, 31, "%dx%d", rinfo->panel_info.xres, rinfo->panel_info.yres);
 865		if (fb_find_mode(&info->var, info, modename,
 866				 modedb, dbsize, NULL, 8) == 0) {
 867			printk(KERN_WARNING "radeonfb: Can't find mode for panel size, going back to CRT\n");
 868			rinfo->mon1_type = MT_CRT;
 869			goto pickup_default;
 870		}
 871		has_default_mode = 1;
 872		radeon_var_to_panel_info(rinfo, &info->var);
 873	}
 874
 875 pickup_default:
 876	/*
 877	 * Apply passed-in mode option if any
 878	 */
 879	if (mode_option) {
 880		if (fb_find_mode(&info->var, info, mode_option,
 881				 info->monspecs.modedb,
 882				 info->monspecs.modedb_len, NULL, 8) != 0)
 883			has_default_mode = 1;
 884 	}
 885
 886#ifdef CONFIG_PPC_PSERIES
 887	if (!has_default_mode && (
 888		is_powerblade("IBM,8842") || /* JS20 */
 889		is_powerblade("IBM,8844") || /* JS21 */
 890		is_powerblade("IBM,7998") || /* JS12/JS21/JS22 */
 891		is_powerblade("IBM,0792") || /* QS21 */
 892		is_powerblade("IBM,0793")    /* QS22 */
 893	    )) {
 894		printk("Falling back to 800x600 on JSxx hardware\n");
 895		if (fb_find_mode(&info->var, info, "800x600@60",
 896				 info->monspecs.modedb,
 897				 info->monspecs.modedb_len, NULL, 8) != 0)
 898			has_default_mode = 1;
 899	}
 900#endif
 901
 902	/*
 903	 * Still no mode, let's pick up a default from the db
 904	 */
 905	if (!has_default_mode && info->monspecs.modedb != NULL) {
 906		struct fb_monspecs *specs = &info->monspecs;
 907		struct fb_videomode *modedb = NULL;
 908
 909		/* get preferred timing */
 910		if (specs->misc & FB_MISC_1ST_DETAIL) {
 911			int i;
 912
 913			for (i = 0; i < specs->modedb_len; i++) {
 914				if (specs->modedb[i].flag & FB_MODE_IS_FIRST) {
 915					modedb = &specs->modedb[i];
 916					break;
 917				}
 918			}
 919		} else {
 920			/* otherwise, get first mode in database */
 921			modedb = &specs->modedb[0];
 922		}
 923		if (modedb != NULL) {
 924			info->var.bits_per_pixel = 8;
 925			radeon_videomode_to_var(&info->var, modedb);
 926			has_default_mode = 1;
 927		}
 928	}
 929	if (1) {
 930		struct fb_videomode mode;
 931		/* Make sure that whatever mode got selected is actually in the
 932		 * modelist or the kernel may die
 933		 */
 934		fb_var_to_videomode(&mode, &info->var);
 935		fb_add_videomode(&mode, &info->modelist);
 936	}
 937}
 938
 939/*
 940 * The code below is used to pick up a mode in check_var and
 941 * set_var. It should be made generic
 942 */
 943
 944/*
 945 * This is used when looking for modes. We assign a "distance" value
 946 * to a mode in the modedb depending how "close" it is from what we
 947 * are looking for.
 948 * Currently, we don't compare that much, we could do better but
 949 * the current fbcon doesn't quite mind ;)
 950 */
 951static int radeon_compare_modes(const struct fb_var_screeninfo *var,
 952				const struct fb_videomode *mode)
 953{
 954	int distance = 0;
 955
 956	distance = mode->yres - var->yres;
 957	distance += (mode->xres - var->xres)/2;
 958	return distance;
 959}
 960
 961/*
 962 * This function is called by check_var, it gets the passed in mode parameter, and
 963 * outputs a valid mode matching the passed-in one as closely as possible.
 964 * We need something better ultimately. Things like fbcon basically pass us out
 965 * current mode with xres/yres hacked, while things like XFree will actually
 966 * produce a full timing that we should respect as much as possible.
 967 *
 968 * This is why I added the FB_ACTIVATE_FIND that is used by fbcon. Without this,
 969 * we do a simple spec match, that's all. With it, we actually look for a mode in
 970 * either our monitor modedb or the vesa one if none
 971 *
 972 */
 973int  radeon_match_mode(struct radeonfb_info *rinfo,
 974		       struct fb_var_screeninfo *dest,
 975		       const struct fb_var_screeninfo *src)
 976{
 977	const struct fb_videomode	*db = vesa_modes;
 978	int				i, dbsize = 34;
 979	int				has_rmx, native_db = 0;
 980	int				distance = INT_MAX;
 981	const struct fb_videomode	*candidate = NULL;
 982
 983	/* Start with a copy of the requested mode */
 984	memcpy(dest, src, sizeof(struct fb_var_screeninfo));
 985
 986	/* Check if we have a modedb built from EDID */
 987	if (rinfo->mon1_modedb) {
 988		db = rinfo->mon1_modedb;
 989		dbsize = rinfo->mon1_dbsize;
 990		native_db = 1;
 991	}
 992
 993	/* Check if we have a scaler allowing any fancy mode */
 994	has_rmx = rinfo->mon1_type == MT_LCD || rinfo->mon1_type == MT_DFP;
 995
 996	/* If we have a scaler and are passed FB_ACTIVATE_TEST or
 997	 * FB_ACTIVATE_NOW, just do basic checking and return if the
 998	 * mode match
 999	 */
1000	if ((src->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_TEST ||
1001	    (src->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
1002		/* We don't have an RMX, validate timings. If we don't have
1003	 	 * monspecs, we should be paranoid and not let use go above
1004		 * 640x480-60, but I assume userland knows what it's doing here
1005		 * (though I may be proven wrong...)
1006		 */
1007		if (has_rmx == 0 && rinfo->mon1_modedb)
1008			if (fb_validate_mode((struct fb_var_screeninfo *)src, rinfo->info))
1009				return -EINVAL;
1010		return 0;
1011	}
1012
1013	/* Now look for a mode in the database */
1014	while (db) {
1015		for (i = 0; i < dbsize; i++) {
1016			int d;
1017
1018			if (db[i].yres < src->yres)
1019				continue;	
1020			if (db[i].xres < src->xres)
1021				continue;
1022			d = radeon_compare_modes(src, &db[i]);
1023			/* If the new mode is at least as good as the previous one,
1024			 * then it's our new candidate
1025			 */
1026			if (d < distance) {
1027				candidate = &db[i];
1028				distance = d;
1029			}
1030		}
1031		db = NULL;
1032		/* If we have a scaler, we allow any mode from the database */
1033		if (native_db && has_rmx) {
1034			db = vesa_modes;
1035			dbsize = 34;
1036			native_db = 0;
1037		}
1038	}
1039
1040	/* If we have found a match, return it */
1041	if (candidate != NULL) {
1042		radeon_videomode_to_var(dest, candidate);
1043		return 0;
1044	}
1045
1046	/* If we haven't and don't have a scaler, fail */
1047	if (!has_rmx)
1048		return -EINVAL;
1049
1050	return 0;
1051}
~/ Read-only file preview.