📄 atiprobe.c
字号:
{ outw(ERR_TERM, 0x2525U); if (inw(ERR_TERM) == 0x2525U) { pATI = (ATIPtr)xnfcalloc(1, SizeOf(ATIRec)); pATI->Adapter = ATI_ADAPTER_8514A; pATI->ChipHasSUBSYS_CNTL = TRUE; pATI->PCIInfo = pVideo; } } outw(ERR_TERM, IOValue2); /* Restore register value clobbered by 8514/A reset attempt */ if (!pATI) { outw(SUBSYS_CNTL, IOValue1); return NULL; } /* Ensure any Mach8 or Mach32 is not in 8514/A emulation mode */ IOValue1 = inw(CLOCK_SEL); outw(CLOCK_SEL, IOValue1); ProbeWaitIdleEmpty(); IOValue1 = IOValue2 = inw(ROM_ADDR_1); outw(ROM_ADDR_1, 0x5555U); ProbeWaitIdleEmpty(); if (inw(ROM_ADDR_1) == 0x5555U) { outw(ROM_ADDR_1, 0x2A2AU); ProbeWaitIdleEmpty(); if (inw(ROM_ADDR_1) == 0x2A2AU) pATI->Adapter = ATI_ADAPTER_MACH8; } outw(ROM_ADDR_1, IOValue1); if (pATI->Adapter == ATI_ADAPTER_MACH8) { /* A Mach8 or Mach32 has been detected */ IOValue1 = inw(READ_SRC_X); outw(DESTX_DIASTP, 0xAAAAU); ProbeWaitIdleEmpty(); if (inw(READ_SRC_X) == 0x02AAU) pATI->Adapter = ATI_ADAPTER_MACH32; outw(DESTX_DIASTP, 0x5555U); ProbeWaitIdleEmpty(); if (inw(READ_SRC_X) == 0x0555U) { if (pATI->Adapter != ATI_ADAPTER_MACH32) pATI->Adapter = ATI_ADAPTER_8514A; } else { if (pATI->Adapter != ATI_ADAPTER_MACH8) pATI->Adapter = ATI_ADAPTER_8514A; } outw(DESTX_DIASTP, IOValue1); } switch (pATI->Adapter) { case ATI_ADAPTER_8514A: pATI->Coprocessor = ATI_CHIP_8514A; IOValue1 = inb(EXT_CONFIG_3); outb(EXT_CONFIG_3, IOValue1 & 0x0FU); if (!(inb(EXT_CONFIG_3) & 0xF0U)) { outb(EXT_CONFIG_3, IOValue1 | 0xF0U); if ((inb(EXT_CONFIG_3) & 0xF0U) == 0xF0U) pATI->Coprocessor = ATI_CHIP_CT480; } outb(EXT_CONFIG_3, IOValue1); break; case ATI_ADAPTER_MACH8: pATI->Coprocessor = ATI_CHIP_38800_1; if (inw(CONFIG_STATUS_1) & MC_BUS) pATI->BusType = ATI_BUS_MCA16; break; case ATI_ADAPTER_MACH32: IOValue1 = inw(CONFIG_STATUS_1); pATI->BusType = GetBits(IOValue1, BUS_TYPE); pATI->BIOSBase = 0x000C0000U + (GetBits(IOValue2, BIOS_BASE_SEGMENT) << 11); if (!(IOValue1 & (_8514_ONLY | CHIP_DIS))) { pATI->VGAAdapter = ATI_ADAPTER_MACH32; if ((xf86ReadBIOS(pATI->BIOSBase, 0x10U, (pointer)(&pATI->CPIO_VGAWonder), SizeOf(pATI->CPIO_VGAWonder)) < SizeOf(pATI->CPIO_VGAWonder)) || !(pATI->CPIO_VGAWonder &= SPARSE_IO_PORT)) pATI->CPIO_VGAWonder = 0x01CEU; pATI->VGAOffset = 0x80U; } ATIMach32ChipID(pATI); break; default: break; } return pATI;}#endif /* AVOID_CPIO *//* * ATIMach64Detect -- * * This function determines if a Mach64 is detectable at a particular base * address. */static BoolATIMach64Detect( ATIPtr pATI, const CARD16 ChipType, const ATIChipType Chip){ CARD32 IOValue, bus_cntl, gen_test_cntl; (void)ATIMapApertures(-1, pATI); /* Ignore errors */#ifdef AVOID_CPIO if (!pATI->pBlock[0]) { ATIUnmapApertures(-1, pATI); return FALSE; }#endif /* AVOID_CPIO */ /* Make sure any Mach64 is not in some weird state */ bus_cntl = inr(BUS_CNTL); if (Chip < ATI_CHIP_264VTB) outr(BUS_CNTL, (bus_cntl & ~(BUS_HOST_ERR_INT_EN | BUS_FIFO_ERR_INT_EN)) | (BUS_HOST_ERR_INT | BUS_FIFO_ERR_INT)); else if (Chip < ATI_CHIP_264VT4) outr(BUS_CNTL, (bus_cntl & ~BUS_HOST_ERR_INT_EN) | BUS_HOST_ERR_INT); gen_test_cntl = inr(GEN_TEST_CNTL); IOValue = gen_test_cntl & (GEN_OVR_OUTPUT_EN | GEN_OVR_POLARITY | GEN_CUR_EN | GEN_BLOCK_WR_EN); outr(GEN_TEST_CNTL, IOValue | GEN_GUI_EN); outr(GEN_TEST_CNTL, IOValue); outr(GEN_TEST_CNTL, IOValue | GEN_GUI_EN); /* See if a Mach64 answers */ IOValue = inr(SCRATCH_REG0); /* Test odd bits */ outr(SCRATCH_REG0, 0x55555555U); if (inr(SCRATCH_REG0) == 0x55555555U) { /* Test even bits */ outr(SCRATCH_REG0, 0xAAAAAAAAU); if (inr(SCRATCH_REG0) == 0xAAAAAAAAU) { /* * *Something* has a R/W 32-bit register at this address. Try to * make sure it's a Mach64. The following assumes that ATI will * not be producing any more adapters that do not register * themselves in PCI configuration space. */ ATIMach64ChipID(pATI, ChipType); if ((pATI->Chip != ATI_CHIP_Mach64) || (pATI->CPIODecoding == BLOCK_IO)) pATI->Adapter = ATI_ADAPTER_MACH64; } } /* Restore clobbered register value */ outr(SCRATCH_REG0, IOValue); /* If no Mach64 was detected, return now */ if (pATI->Adapter != ATI_ADAPTER_MACH64) { outr(GEN_TEST_CNTL, gen_test_cntl); outr(BUS_CNTL, bus_cntl); ATIUnmapApertures(-1, pATI); return FALSE; } /* Determine legacy BIOS address */ pATI->BIOSBase = 0x000C0000U + (GetBits(inr(SCRATCH_REG1), BIOS_BASE_SEGMENT) << 11); ATIUnmapApertures(-1, pATI); pATI->PCIInfo = NULL; return TRUE;}#ifdef AVOID_CPIO/* * ATIMach64Probe -- * * This function looks for a Mach64 at a particular MMIO address and returns an * ATIRec if one is found. */static ATIPtrATIMach64Probe( pciVideoPtr pVideo, const IOADDRESS IOBase, const CARD8 IODecoding, const ATIChipType Chip){ ATIPtr pATI = (ATIPtr)xnfcalloc(1, SizeOf(ATIRec)); CARD16 ChipType = 0; pATI->CPIOBase = IOBase; pATI->CPIODecoding = IODecoding; if (pVideo) { pATI->PCIInfo = pVideo; ChipType = pVideo->chipType; /* * Probe through auxiliary MMIO aperture if one exists. Because such * apertures can be enabled/disabled only through PCI, this probes no * further. */ if ((pVideo->size[2] >= 12) && (pATI->Block0Base = pVideo->memBase[2]) && (pATI->Block0Base < (CARD32)(-1 << pVideo->size[2]))) { pATI->Block0Base += 0x00000400U; goto LastProbe; } /* * Probe through the primary MMIO aperture that exists at the tail end * of the linear aperture. Test for both 8MB and 4MB linear apertures. */ if ((pVideo->size[0] >= 22) && (pATI->Block0Base = pVideo->memBase[0])) { pATI->Block0Base += 0x007FFC00U; if ((pVideo->size[0] >= 23) && ATIMach64Detect(pATI, ChipType, Chip)) return pATI; pATI->Block0Base -= 0x00400000U; if (ATIMach64Detect(pATI, ChipType, Chip)) return pATI; } } /* * A last, perhaps desparate, probe attempt. Note that if this succeeds, * there's a VGA in the system and it's likely the PIO version of the * driver should be used instead (barring OS issues). */ pATI->Block0Base = 0x000BFC00U;LastProbe: if (ATIMach64Detect(pATI, ChipType, Chip)) return pATI; xfree(pATI); return NULL;}#else /* AVOID_CPIO *//* * ATIMach64Probe -- * * This function looks for a Mach64 at a particular PIO address and returns an * ATIRec if one is found. */static ATIPtrATIMach64Probe( pciVideoPtr pVideo, const IOADDRESS IOBase, const CARD8 IODecoding, const ATIChipType Chip){ ATIPtr pATI; CARD32 IOValue; CARD16 ChipType = 0; if (!IOBase) return NULL; if (pVideo) { if ((IODecoding == BLOCK_IO) && ((pVideo->size[1] < 8) || (IOBase >= (CARD32)(-1 << pVideo->size[1])))) return NULL; ChipType = pVideo->chipType; } pATI = (ATIPtr)xnfcalloc(1, SizeOf(ATIRec)); pATI->CPIOBase = IOBase; pATI->CPIODecoding = IODecoding; pATI->PCIInfo = pVideo; if (!ATIMach64Detect(pATI, ChipType, Chip)) { xfree(pATI); return NULL; } /* * Determine VGA capability. VGA can always be enabled on integrated * controllers. For the GX/CX, it's a board strap. */ if (pATI->Chip >= ATI_CHIP_264CT) { pATI->VGAAdapter = ATI_ADAPTER_MACH64; } else { IOValue = inr(CONFIG_STATUS64_0); pATI->BusType = GetBits(IOValue, CFG_BUS_TYPE); IOValue &= (CFG_VGA_EN | CFG_CHIP_EN); if (pATI->Chip == ATI_CHIP_88800CX) IOValue |= CFG_VGA_EN; if (IOValue == (CFG_VGA_EN | CFG_CHIP_EN)) { pATI->VGAAdapter = ATI_ADAPTER_MACH64; pATI->CPIO_VGAWonder = 0x01CEU; pATI->VGAOffset = 0x80U; } } return pATI;}/* * ATIAssignVGA -- * * This function is called to associate a VGA interface with an accelerator. * This is done by temporarily configuring the accelerator to route VGA RAMDAC * I/O through the accelerator's RAMDAC. A value is then written through the * VGA DAC ports and a check is made to see if the same value shows up on the * accelerator side. */static voidATIAssignVGA( pciVideoPtr pVideo, ATIPtr *ppVGA, ATIPtr pATI, ATIPtr p8514, CARD8 *ProbeFlags){ ATIPtr pVGA = *ppVGA; CARD8 OldDACMask; /* Assume unassignable VGA */ pATI->VGAAdapter = ATI_ADAPTER_NONE; /* If no assignable VGA, return now */ if ((pATI != pVGA) && (!pVGA || (pVGA->Adapter > ATI_ADAPTER_VGA))) return; switch (pATI->Adapter) { case ATI_ADAPTER_8514A: { /* * Assumption: Bit DISABPASSTHRU in ADVFUNC_CNTL is already * off. */ OldDACMask = inb(VGA_DAC_MASK); if (inb(IBM_DAC_MASK) == OldDACMask) { outb(VGA_DAC_MASK, 0xA5U); if (inb(IBM_DAC_MASK) == 0xA5U) pATI->VGAAdapter = ATI_ADAPTER_VGA; outb(VGA_DAC_MASK, OldDACMask); } } break; case ATI_ADAPTER_MACH8: { CARD16 ClockSel = inw(CLOCK_SEL); if (ClockSel & DISABPASSTHRU) outw(CLOCK_SEL, ClockSel & ~DISABPASSTHRU); ProbeWaitIdleEmpty(); OldDACMask = inb(VGA_DAC_MASK); if (inb(IBM_DAC_MASK) == OldDACMask)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -