drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv40.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv40.c
Extension
.c
Size
6315 bytes
Lines
224
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

if (vbl != nvkm_rd32(device, 0x600808 + (i * 0x2000))) {
				nvkm_wr08(device, 0x0c03c4 + (i * 0x2000), 0x01);
				sr1[i] = nvkm_rd08(device, 0x0c03c5 + (i * 0x2000));
				if (!(sr1[i] & 0x20))
					crtc_mask |= (1 << i);
				break;
			}
			udelay(1);
		} while (cnt++ < 32);
	}

	/* wait for vblank start on active crtcs, disable memory access */
	for (i = 0; i < 2; i++) {
		if (!(crtc_mask & (1 << i)))
			continue;

		nvkm_msec(device, 2000,
			u32 tmp = nvkm_rd32(device, 0x600808 + (i * 0x2000));
			if (!(tmp & 0x00010000))
				break;
		);

		nvkm_msec(device, 2000,
			u32 tmp = nvkm_rd32(device, 0x600808 + (i * 0x2000));
			if ( (tmp & 0x00010000))
				break;
		);

		nvkm_wr08(device, 0x0c03c4 + (i * 0x2000), 0x01);
		nvkm_wr08(device, 0x0c03c5 + (i * 0x2000), sr1[i] | 0x20);
	}

	/* prepare ram for reclocking */
	nvkm_wr32(device, 0x1002d4, 0x00000001); /* precharge */
	nvkm_wr32(device, 0x1002d0, 0x00000001); /* refresh */
	nvkm_wr32(device, 0x1002d0, 0x00000001); /* refresh */
	nvkm_mask(device, 0x100210, 0x80000000, 0x00000000); /* no auto refresh */
	nvkm_wr32(device, 0x1002dc, 0x00000001); /* enable self-refresh */

	/* change the PLL of each memory partition */
	nvkm_mask(device, 0x00c040, 0x0000c000, 0x00000000);
	switch (device->chipset) {
	case 0x40:
	case 0x45:
	case 0x41:
	case 0x42:
	case 0x47:
		nvkm_mask(device, 0x004044, 0xc0771100, ram->ctrl);
		nvkm_mask(device, 0x00402c, 0xc0771100, ram->ctrl);
		nvkm_wr32(device, 0x004048, ram->coef);
		nvkm_wr32(device, 0x004030, ram->coef);
		fallthrough;
	case 0x43:
	case 0x49:
	case 0x4b:
		nvkm_mask(device, 0x004038, 0xc0771100, ram->ctrl);
		nvkm_wr32(device, 0x00403c, ram->coef);
		fallthrough;
	default:
		nvkm_mask(device, 0x004020, 0xc0771100, ram->ctrl);
		nvkm_wr32(device, 0x004024, ram->coef);
		break;
	}
	udelay(100);
	nvkm_mask(device, 0x00c040, 0x0000c000, 0x0000c000);

	/* re-enable normal operation of memory controller */
	nvkm_wr32(device, 0x1002dc, 0x00000000);
	nvkm_mask(device, 0x100210, 0x80000000, 0x80000000);
	udelay(100);

	/* execute memory reset script from vbios */
	if (!bit_entry(bios, 'M', &M))
		nvbios_init(subdev, nvbios_rd16(bios, M.offset + 0x00));

	/* make sure we're in vblank (hopefully the same one as before), and
	 * then re-enable crtc memory access
	 */
	for (i = 0; i < 2; i++) {
		if (!(crtc_mask & (1 << i)))
			continue;

		nvkm_msec(device, 2000,
			u32 tmp = nvkm_rd32(device, 0x600808 + (i * 0x2000));
			if ( (tmp & 0x00010000))
				break;
		);

		nvkm_wr08(device, 0x0c03c4 + (i * 0x2000), 0x01);
		nvkm_wr08(device, 0x0c03c5 + (i * 0x2000), sr1[i]);

Annotation

Implementation Notes