Beispiel #1
0
int ATIRadeon::FindMemVBios()
{
	/* I simplified this code as we used to miss the signatures in
	 * a lot of case. It's now closer to XFree, we just don't check
	 * for signatures at all... Something better will have to be done
	 * if we end up having conflicts
	 */
	uint32  segstart;

	for(segstart = 0x000c1000; segstart < 0x000f0000; segstart += 0x00001000) {
		if( remap_area (m_hROMArea, (void *)((segstart))) < 0 ) {
			printf("Radeon :: failed to remap ROM area (%d)\n", m_hROMArea);
			return false;
		}
		if ((*m_pROMBase == 0x55) && (((*(m_pROMBase + 1)) & 0xff) == 0xaa))
			break;
	}

	dbprintf("Radeon :: VBIOS at %x detected\n", (uint)segstart);

	/* Locate the flat panel infos, do some sanity checking !!! */
	rinfo.bios_seg = m_pROMBase;
	rinfo.fp_bios_start = BIOS_IN16(0x48);
	return 0;
}
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;
		}
	}
Beispiel #3
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;
}