/*
 * Try to find monitor informations & EDID data out of the Open Firmware
 * device-tree. This also contains some "hacks" to work around a few machine
 * models with broken OF probing by hard-coding known EDIDs for some Mac
 * laptops internal LVDS panel. (XXX: not done yet)
 */
static int __devinit radeon_parse_montype_prop(struct device_node *dp, u8 **out_EDID,
					       int hdno)
{
        static char *propnames[] = { "DFP,EDID", "LCD,EDID", "EDID",
				     "EDID1", "EDID2",  NULL };
	u8 *pedid = NULL;
	u8 *pmt = NULL;
	u8 *tmp;
        int i, mt = MT_NONE;  
	
	RTRACE("analyzing OF properties...\n");
	pmt = (u8 *)get_property(dp, "display-type", NULL);
	if (!pmt)
		return MT_NONE;
	RTRACE("display-type: %s\n", pmt);
	/* OF says "LCD" for DFP as well, we discriminate from the caller of this
	 * function
	 */
	if (!strcmp(pmt, "LCD") || !strcmp(pmt, "DFP"))
		mt = MT_DFP;
	else if (!strcmp(pmt, "CRT"))
		mt = MT_CRT;
	else {
		if (strcmp(pmt, "NONE") != 0)
			printk(KERN_WARNING "radeonfb: Unknown OF display-type: %s\n",
			       pmt);
		return MT_NONE;
	}

	for (i = 0; propnames[i] != NULL; ++i) {
		pedid = (u8 *)get_property(dp, propnames[i], NULL);
		if (pedid != NULL)
			break;
	}
	/* We didn't find the EDID in the leaf node, some cards will actually
	 * put EDID1/EDID2 in the parent, look for these (typically M6 tipb).
	 * single-head cards have hdno == -1 and skip this step
	 */
	if (pedid == NULL && dp->parent && (hdno != -1))
		pedid = get_property(dp->parent, (hdno == 0) ? "EDID1" : "EDID2", NULL);
	if (pedid == NULL && dp->parent && (hdno == 0))
		pedid = get_property(dp->parent, "EDID", NULL);
	if (pedid == NULL)
		return mt;

	tmp = (u8 *)kmalloc(EDID_LENGTH, GFP_KERNEL);
	if (!tmp)
		return mt;
	memcpy(tmp, pedid, EDID_LENGTH);
	*out_EDID = tmp;
	return mt;
}
static int __devinit radeon_probe_OF_head(struct radeonfb_info *rinfo, int head_no,
					  u8 **out_EDID)
{
        struct device_node *dp;

	RTRACE("radeon_probe_OF_head\n");

        dp = rinfo->of_node;
        while (dp == NULL)
		return MT_NONE;

	if (rinfo->has_CRTC2) {
		char *pname;
		int len, second = 0;

		dp = dp->child;
		do {
			if (!dp)
				return MT_NONE;
			pname = (char *)get_property(dp, "name", NULL);
			if (!pname)
				return MT_NONE;
			len = strlen(pname);
			RTRACE("head: %s (letter: %c, head_no: %d)\n",
			       pname, pname[len-1], head_no);
			if (pname[len-1] == 'A' && head_no == 0) {
				int mt = radeon_parse_montype_prop(dp, out_EDID, 0);
				/* Maybe check for LVDS_GEN_CNTL here ? I need to check out
				 * what OF does when booting with lid closed
				 */
				if (mt == MT_DFP && rinfo->is_mobility)
					mt = MT_LCD;
				return mt;
			} else if (pname[len-1] == 'B' && head_no == 1)
				return radeon_parse_montype_prop(dp, out_EDID, 1);
			second = 1;
			dp = dp->sibling;
		} while(!second);
	} else {
		if (head_no > 0)
			return MT_NONE;
		return radeon_parse_montype_prop(dp, out_EDID, -1);
	}
        return MT_NONE;
}
Example #3
0
File: debug.c Project: skyguy94/R
SEXP attribute_hidden do_retracemem(SEXP call, SEXP op, SEXP args, SEXP rho)
{
#ifdef R_MEMORY_PROFILING
    SEXP object, previous, ans, argList;
    char buffer[21];
    static SEXP do_retracemem_formals = NULL;

    if (do_retracemem_formals == NULL)
        do_retracemem_formals = allocFormalsList2(install("x"),
						  R_PreviousSymbol);

    PROTECT(argList =  matchArgs(do_retracemem_formals, args, call));
    if(CAR(argList) == R_MissingArg) SETCAR(argList, R_NilValue);
    if(CADR(argList) == R_MissingArg) SETCAR(CDR(argList), R_NilValue);

    object = CAR(argList);
    if (TYPEOF(object) == CLOSXP ||
	TYPEOF(object) == BUILTINSXP ||
	TYPEOF(object) == SPECIALSXP)
	errorcall(call, _("argument must not be a function"));

    previous = CADR(argList);
    if(!isNull(previous) && !isString(previous))
	    errorcall(call, _("invalid '%s' argument"), "previous");

    if (RTRACE(object)) {
	snprintf(buffer, 21, "<%p>", (void *) object);
	ans = mkString(buffer);
    } else {
	R_Visible = 0;
	ans = R_NilValue;
    }

    if (previous != R_NilValue){
	SET_RTRACE(object, 1);
	if (R_current_trace_state()) {
	    /* FIXME: previous will have <0x....> whereas other values are
	       without the < > */
	    Rprintf("tracemem[%s -> %p]: ",
		    translateChar(STRING_ELT(previous, 0)), (void *) object);
	    memtrace_stack_dump();
	}
    }
    UNPROTECT(1);
    return ans;
#else
    R_Visible = 0; /* for consistency with other case */
    return R_NilValue;
#endif
}
Example #4
0
SEXP duplicate(SEXP s){
    SEXP t;

#ifdef R_PROFILING
    duplicate_counter++;
#endif
    t = duplicate1(s, TRUE);
#ifdef R_MEMORY_PROFILING
    if (RTRACE(s) && !(TYPEOF(s) == CLOSXP || TYPEOF(s) == BUILTINSXP ||
		      TYPEOF(s) == SPECIALSXP || TYPEOF(s) == PROMSXP ||
		      TYPEOF(s) == ENVSXP)){
	    memtrace_report(s,t);
	    SET_RTRACE(t,1);
    }
#endif
    return t;
}
Example #5
0
SEXP attribute_hidden do_untracemem(SEXP call, SEXP op, SEXP args, SEXP rho)
{
    SEXP object;

    checkArity(op, args);
    check1arg(args, call, "x");

    object=CAR(args);
    if (TYPEOF(object) == CLOSXP ||
	TYPEOF(object) == BUILTINSXP ||
	TYPEOF(object) == SPECIALSXP)
	errorcall(call, _("argument must not be a function"));

    if (RTRACE(object))
	SET_RTRACE(object, 0);
    return R_NilValue;
}
Example #6
0
File: debug.c Project: skyguy94/R
SEXP attribute_hidden do_untracemem(SEXP call, SEXP op, SEXP args, SEXP rho)
{
#ifdef R_MEMORY_PROFILING
    SEXP object;

    checkArity(op, args);
    check1arg(args, call, "x");

    object=CAR(args);
    if (TYPEOF(object) == CLOSXP ||
	TYPEOF(object) == BUILTINSXP ||
	TYPEOF(object) == SPECIALSXP)
	errorcall(call, _("argument must not be a function"));

    if (RTRACE(object))
	SET_RTRACE(object, 0);
#else
    errorcall(call, _("R was not compiled with support for memory profiling"));
#endif
    return R_NilValue;
}
static int __devinit radeon_get_panel_info_BIOS(struct radeonfb_info *rinfo)
{
	unsigned long tmp, tmp0;
	char stmp[30];
	int i;

	if (!rinfo->bios_seg)
		return 0;

	if (!(tmp = BIOS_IN16(rinfo->fp_bios_start + 0x40))) {
		printk(KERN_ERR "radeonfb: Failed to detect DFP panel info using BIOS\n");
		rinfo->panel_info.pwr_delay = 200;
		return 0;
	}

	for(i=0; i<24; i++)
		stmp[i] = BIOS_IN8(tmp+i+1);
	stmp[24] = 0;
	printk("radeonfb: panel ID string: %s\n", stmp);
	rinfo->panel_info.xres = BIOS_IN16(tmp + 25);
	rinfo->panel_info.yres = BIOS_IN16(tmp + 27);
	printk("radeonfb: detected LVDS panel size from BIOS: %dx%d\n",
		rinfo->panel_info.xres, rinfo->panel_info.yres);

	rinfo->panel_info.pwr_delay = BIOS_IN16(tmp + 44);
	RTRACE("BIOS provided panel power delay: %d\n", rinfo->panel_info.pwr_delay);
	if (rinfo->panel_info.pwr_delay > 2000 || rinfo->panel_info.pwr_delay <= 0)
		rinfo->panel_info.pwr_delay = 2000;

	/*
	 * Some panels only work properly with some divider combinations
	 */
	rinfo->panel_info.ref_divider = BIOS_IN16(tmp + 46);
	rinfo->panel_info.post_divider = BIOS_IN8(tmp + 48);
	rinfo->panel_info.fbk_divider = BIOS_IN16(tmp + 49);
	if (rinfo->panel_info.ref_divider != 0 &&
	    rinfo->panel_info.fbk_divider > 3) {
		rinfo->panel_info.use_bios_dividers = 1;
		printk(KERN_INFO "radeondb: BIOS provided dividers will be used\n");
		RTRACE("ref_divider = %x\n", rinfo->panel_info.ref_divider);
		RTRACE("post_divider = %x\n", rinfo->panel_info.post_divider);
		RTRACE("fbk_divider = %x\n", rinfo->panel_info.fbk_divider);
	}
	RTRACE("Scanning BIOS table ...\n");
	for(i=0; i<32; i++) {
		tmp0 = BIOS_IN16(tmp+64+i*2);
		if (tmp0 == 0)
			break;
		RTRACE(" %d x %d\n", BIOS_IN16(tmp0), BIOS_IN16(tmp0+2));
		if ((BIOS_IN16(tmp0) == rinfo->panel_info.xres) &&
		    (BIOS_IN16(tmp0+2) == rinfo->panel_info.yres)) {
			rinfo->panel_info.hblank = (BIOS_IN16(tmp0+17) - BIOS_IN16(tmp0+19)) * 8;
			rinfo->panel_info.hOver_plus = ((BIOS_IN16(tmp0+21) -
							 BIOS_IN16(tmp0+19) -1) * 8) & 0x7fff;
			rinfo->panel_info.hSync_width = BIOS_IN8(tmp0+23) * 8;
			rinfo->panel_info.vblank = BIOS_IN16(tmp0+24) - BIOS_IN16(tmp0+26);
			rinfo->panel_info.vOver_plus = (BIOS_IN16(tmp0+28) & 0x7ff) - BIOS_IN16(tmp0+26);
			rinfo->panel_info.vSync_width = (BIOS_IN16(tmp0+28) & 0xf800) >> 11;
			rinfo->panel_info.clock = BIOS_IN16(tmp0+9);
			/* Assume high active syncs for now until ATI tells me more... maybe we
			 * can probe register values here ?
			 */
			rinfo->panel_info.hAct_high = 1;
			rinfo->panel_info.vAct_high = 1;
			/* Mark panel infos valid */
			rinfo->panel_info.valid = 1;

			RTRACE("Found panel in BIOS table:\n");
			RTRACE("  hblank: %d\n", rinfo->panel_info.hblank);
			RTRACE("  hOver_plus: %d\n", rinfo->panel_info.hOver_plus);
			RTRACE("  hSync_width: %d\n", rinfo->panel_info.hSync_width);
			RTRACE("  vblank: %d\n", rinfo->panel_info.vblank);
			RTRACE("  vOver_plus: %d\n", rinfo->panel_info.vOver_plus);
			RTRACE("  vSync_width: %d\n", rinfo->panel_info.vSync_width);
			RTRACE("  clock: %d\n", rinfo->panel_info.clock);
				
			return 1;
		}
	}
Example #8
0
int ATIRadeon::MapROM( int nFd, PCI_Info_s *dev )
{
	uint16 dptr;
	uint8 rom_type;
	unsigned long rom_base_phys;

	/* If this is a primary card, there is a shadow copy of the
	 * ROM somewhere in the first meg (presumably at 0xc0000)
	 */

	/* Fix from ATI for problem with Radeon hardware not leaving ROM enabled */
	unsigned int temp;
	temp = INREG(MPP_TB_CONFIG);
	temp &= 0x00ffffffu;
	temp |= 0x04 << 24;
	OUTREG(MPP_TB_CONFIG, temp);
	temp = INREG(MPP_TB_CONFIG);

	rom_base_phys = RADEON_I386_ROM_ADDRESS;

	pci_gfx_write_config( nFd, dev->nBus, dev->nDevice,
		dev->nFunction, PCI_ROM_BASE, 4, RADEON_I386_ROM_ENABLE );

	RTRACE("Radeon :: ROM base address %x\n", (uint) rom_base_phys);
	RTRACE("Radeon :: ROM size %x\n", (uint) get_pci_rom_memory_size(nFd, dev));

	// map the ROM
	m_pROMBase = NULL;
	m_hROMArea = create_area ("radeon_rom", (void **)&m_pROMBase,
		get_pci_rom_memory_size(nFd, dev), AREA_FULL_ACCESS, AREA_NO_LOCK);
	if( m_hROMArea < 0 ) {
		dbprintf ("Radeon :: failed to create ROM area\n");
		return false;
	}

	if( remap_area (m_hROMArea, (void *)((rom_base_phys))) < 0 ) {
		printf("Radeon :: failed to map ROM area (%d)\n", m_hROMArea);
		return false;
	}

	rinfo.bios_seg = m_pROMBase;

	/* Very simple test to make sure it appeared */
	if (BIOS_IN16(0) != 0xaa55) {
		dbprintf("Radeon :: Warning: Invalid ROM signature %x should be 0xaa55\n",
		       BIOS_IN16(0));
		goto failed;
	}
	/* Look for the PCI data to check the ROM type */
	dptr = BIOS_IN16(0x18);

	/* Check the PCI data signature. If it's wrong, we still assume a normal x86 ROM
	 * for now, until I've verified this works everywhere. The goal here is more
	 * to phase out Open Firmware images.
	 *
	 * Currently, we only look at the first PCI data, we could iteratre and deal with
	 * them all, and we should use fb_bios_start relative to start of image and not
	 * relative start of ROM, but so far, I never found a dual-image ATI card
	 *
	 * typedef struct {
	 * 	uint32	signature;	+ 0x00
	 * 	uint16	vendor;		+ 0x04
	 * 	uint16	device;		+ 0x06
	 * 	uint16	reserved_1;	+ 0x08
	 * 	uint16	dlen;		+ 0x0a
	 * 	uint8	drevision;	+ 0x0c
	 * 	uint8	class_hi;	+ 0x0d
	 * 	uint16	class_lo;	+ 0x0e
	 * 	uint16	ilen;		+ 0x10
	 * 	uint16	irevision;	+ 0x12
	 * 	uint8	type;		+ 0x14
	 * 	uint8	indicator;	+ 0x15
	 * 	uint16	reserved_2;	+ 0x16
	 * } pci_data_t;
	 */
	if (BIOS_IN32(dptr) !=  (('R' << 24) | ('I' << 16) | ('C' << 8) | 'P')) {
		dbprintf("Radeon :: Warning: PCI DATA signature in ROM incorrect: %08x\n",
		       BIOS_IN32(dptr));
		goto anyway;
	}
	rom_type = BIOS_IN8(dptr + 0x14);
	switch(rom_type) {
	case 0:
		dbprintf("Radeon :: Found Intel x86 BIOS ROM Image\n");
		break;
	case 1:
		dbprintf("Radeon :: Found Open Firmware ROM Image\n");
		goto failed;
	case 2:
		dbprintf("Radeon :: Found HP PA-RISC ROM Image\n");
		goto failed;
	default:
		dbprintf("Radeon :: Found unknown type %d ROM Image\n", rom_type);
		goto failed;
	}
 anyway:
	/* Locate the flat panel infos, do some sanity checking !!! */
	rinfo.fp_bios_start = BIOS_IN16(0x48);

	/* Check for ATOM BIOS */
	dptr = rinfo.fp_bios_start + 4;
	if ((BIOS_IN8(dptr)   == 'A' &&
		 BIOS_IN8(dptr+1) == 'T' &&
		 BIOS_IN8(dptr+2) == 'O' &&
		 BIOS_IN8(dptr+3) == 'M') ||
		(BIOS_IN8(dptr)   == 'M' &&
		 BIOS_IN8(dptr+1) == 'O' &&
		 BIOS_IN8(dptr+2) == 'T' &&
		 BIOS_IN8(dptr+3) == 'A'))
		rinfo.bios_type = bios_atom;
	else
		rinfo.bios_type = bios_legacy;

    if (rinfo.bios_type == bios_atom) 
		rinfo.fp_atom_bios_start = BIOS_IN16 (rinfo.fp_bios_start + 32);

	dbprintf( "Radeon :: %s BIOS detected\n", (rinfo.bios_type == bios_atom) ? "ATOM" : "Legacy" );

	return 0;

 failed:
	rinfo.bios_seg = NULL;

	return -ENXIO;
}