drivers/gpu/drm/nouveau/nvkm/subdev/pci/agp.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/nouveau/nvkm/subdev/pci/agp.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/nouveau/nvkm/subdev/pci/agp.c
Extension
.c
Size
5321 bytes
Lines
176
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct nvkm_device_agp_quirk {
	u16 hostbridge_vendor;
	u16 hostbridge_device;
	u16 chip_vendor;
	u16 chip_device;
	int mode;
};

static const struct nvkm_device_agp_quirk
nvkm_device_agp_quirks[] = {
	/* VIA Apollo PRO133x / GeForce FX 5600 Ultra - fdo#20341 */
	{ PCI_VENDOR_ID_VIA, 0x0691, PCI_VENDOR_ID_NVIDIA, 0x0311, 2 },
	/* SiS 761 does not support AGP cards, use PCI mode */
	{ PCI_VENDOR_ID_SI, 0x0761, PCI_ANY_ID, PCI_ANY_ID, 0 },
	{},
};

void
nvkm_agp_fini(struct nvkm_pci *pci)
{
	if (pci->agp.acquired) {
		agp_backend_release(pci->agp.bridge);
		pci->agp.acquired = false;
	}
}

/* Ensure AGP controller is in a consistent state in case we need to
 * execute the VBIOS DEVINIT scripts.
 */
void
nvkm_agp_preinit(struct nvkm_pci *pci)
{
	struct nvkm_device *device = pci->subdev.device;
	u32 mode = nvkm_pci_rd32(pci, 0x004c);
	u32 save[2];

	/* First of all, disable fast writes, otherwise if it's already
	 * enabled in the AGP bridge and we disable the card's AGP
	 * controller we might be locking ourselves out of it.
	 */
	if ((mode | pci->agp.mode) & PCI_AGP_COMMAND_FW) {
		mode = pci->agp.mode & ~PCI_AGP_COMMAND_FW;
		agp_enable(pci->agp.bridge, mode);
	}

	/* clear busmaster bit, and disable AGP */
	save[0] = nvkm_pci_rd32(pci, 0x0004);
	nvkm_pci_wr32(pci, 0x0004, save[0] & ~0x00000004);
	nvkm_pci_wr32(pci, 0x004c, 0x00000000);

	/* reset PGRAPH, PFIFO and PTIMER */
	save[1] = nvkm_mask(device, 0x000200, 0x00011100, 0x00000000);
	nvkm_mask(device, 0x000200, 0x00011100, save[1]);

	/* and restore busmaster bit (gives effect of resetting AGP) */
	nvkm_pci_wr32(pci, 0x0004, save[0]);
}

int
nvkm_agp_init(struct nvkm_pci *pci)
{
	if (!agp_backend_acquire(pci->pdev)) {
		nvkm_error(&pci->subdev, "failed to acquire agp\n");
		return -ENODEV;
	}

	agp_enable(pci->agp.bridge, pci->agp.mode);
	pci->agp.acquired = true;
	return 0;
}

void
nvkm_agp_dtor(struct nvkm_pci *pci)
{
	arch_phys_wc_del(pci->agp.mtrr);
}

void
nvkm_agp_ctor(struct nvkm_pci *pci)
{
	const struct nvkm_device_agp_quirk *quirk = nvkm_device_agp_quirks;
	struct nvkm_subdev *subdev = &pci->subdev;
	struct nvkm_device *device = subdev->device;
	struct agp_kern_info info;
	int mode = -1;

#ifdef __powerpc__
	/* Disable AGP by default on all PowerPC machines for now -- At
	 * least some UniNorth-2 AGP bridges are known to be broken:
	 * DMA from the host to the card works just fine, but writeback

Annotation

Implementation Notes