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; } }
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; }