Beispiel #1
0
static void
nouveau_bios_shadow_pramin(struct nouveau_bios *bios)
{
	struct nouveau_device *device = nv_device(bios);
	u64 addr = 0;
	u32 bar0 = 0;
	int i;

	if (device->card_type >= NV_50) {
		if (device->card_type >= NV_C0 && device->card_type < GM100) {
			if (nv_rd32(bios, 0x022500) & 0x00000001)
				return;
		} else
		if (device->card_type >= GM100) {
			if (nv_rd32(bios, 0x021c04) & 0x00000001)
				return;
		}

		addr = nv_rd32(bios, 0x619f04);
		if (!(addr & 0x00000008)) {
			nv_debug(bios, "... not enabled\n");
			return;
		}
		if ( (addr & 0x00000003) != 1) {
			nv_debug(bios, "... not in vram\n");
			return;
		}

		addr = (addr & 0xffffff00) << 8;
		if (!addr) {
			addr  = (u64)nv_rd32(bios, 0x001700) << 16;
			addr += 0xf0000;
		}

		bar0 = nv_mask(bios, 0x001700, 0xffffffff, addr >> 16);
	}

	/* bail if no rom signature */
	if (nv_rd08(bios, 0x700000) != 0x55 ||
	    nv_rd08(bios, 0x700001) != 0xaa)
		goto out;

	bios->size = nv_rd08(bios, 0x700002) * 512;
	if (!bios->size)
		goto out;

	bios->data = kmalloc(bios->size, GFP_KERNEL);
	if (bios->data) {
		for (i = 0; i < bios->size; i++)
			nv_wo08(bios, i, nv_rd08(bios, 0x700000 + i));
	}

out:
	if (device->card_type >= NV_50)
		nv_wr32(bios, 0x001700, bar0);
}
Beispiel #2
0
static void
nouveau_bios_shadow_prom(struct nouveau_bios *bios)
{
	struct nouveau_device *device = nv_device(bios);
	u32 pcireg, access;
	u16 pcir;
	int i;

	/* enable access to rom */
	if (device->card_type >= NV_50)
		pcireg = 0x088050;
	else
		pcireg = 0x001850;
	access = nv_mask(bios, pcireg, 0x00000001, 0x00000000);

	/* bail if no rom signature, with a workaround for a PROM reading
	 * issue on some chipsets.  the first read after a period of
	 * inactivity returns the wrong result, so retry the first header
	 * byte a few times before giving up as a workaround
	 */
	i = 16;
	do {
		if (nv_rd08(bios, 0x300000) == 0x55)
			break;
	} while (i--);

	if (!i || nv_rd08(bios, 0x300001) != 0xaa)
		goto out;

	/* additional check (see note below) - read PCI record header */
	pcir = nv_rd08(bios, 0x300018) |
	       nv_rd08(bios, 0x300019) << 8;
	if (nv_rd08(bios, 0x300000 + pcir) != 'P' ||
	    nv_rd08(bios, 0x300001 + pcir) != 'C' ||
	    nv_rd08(bios, 0x300002 + pcir) != 'I' ||
	    nv_rd08(bios, 0x300003 + pcir) != 'R')
		goto out;

	/* read entire bios image to system memory */
	bios->size = nv_rd08(bios, 0x300002) * 512;
	if (!bios->size)
		goto out;

	bios->data = kmalloc(bios->size, GFP_KERNEL);
	if (bios->data) {
		for (i = 0; i < bios->size; i++)
			nv_wo08(bios, i, nv_rd08(bios, 0x300000 + i));
	}

out:
	/* disable access to rom */
	nv_wr32(bios, pcireg, access);
}
Beispiel #3
0
static int
nvkm_ioctl_wr(struct nouveau_handle *handle, void *data, u32 size)
{
	struct nouveau_object *object = handle->object;
	struct nouveau_ofuncs *ofuncs = object->oclass->ofuncs;
	union {
		struct nvif_ioctl_wr_v0 v0;
	} *args = data;
	int ret;

	nv_ioctl(object, "wr size %d\n", size);
	if (nvif_unpack(args->v0, 0, 0, false)) {
		nv_ioctl(object, "wr vers %d size %d addr %016llx data %08x\n",
			 args->v0.version, args->v0.size, args->v0.addr,
			 args->v0.data);
		switch (args->v0.size) {
		case 1:
			if (ret = -ENODEV, ofuncs->wr08) {
				nv_wo08(object, args->v0.addr, args->v0.data);
				ret = 0;
			}
			break;
		case 2:
			if (ret = -ENODEV, ofuncs->wr16) {
				nv_wo16(object, args->v0.addr, args->v0.data);
				ret = 0;
			}
			break;
		case 4:
			if (ret = -ENODEV, ofuncs->wr32) {
				nv_wo32(object, args->v0.addr, args->v0.data);
				ret = 0;
			}
			break;
		default:
			ret = -EINVAL;
			break;
		}
	}

	return ret;
}
Beispiel #4
0
static void
nouveau_bios_shadow_pramin(struct nouveau_bios *bios)
{
	struct nouveau_device *device = nv_device(bios);
	u64 addr = 0;
	u32 bar0 = 0;
	int i;

	if (device->card_type >= NV_50) {
		if (  device->card_type < NV_C0 ||
		    !(nv_rd32(bios, 0x022500) & 0x00000001))
			addr = (u64)(nv_rd32(bios, 0x619f04) & 0xffffff00) << 8;

		if (!addr) {
			addr  = (u64)nv_rd32(bios, 0x001700) << 16;
			addr += 0xf0000;
		}

		bar0 = nv_mask(bios, 0x001700, 0xffffffff, addr >> 16);
	}

	/* bail if no rom signature */
	if (nv_rd08(bios, 0x700000) != 0x55 ||
	    nv_rd08(bios, 0x700001) != 0xaa)
		goto out;

	bios->size = nv_rd08(bios, 0x700002) * 512;
	if (!bios->size)
		goto out;

	bios->data = kmalloc(bios->size, GFP_KERNEL);
	if (bios->data) {
		for (i = 0; i < bios->size; i++)
			nv_wo08(bios, i, nv_rd08(bios, 0x700000 + i));
	}

out:
	if (device->card_type >= NV_50)
		nv_wr32(bios, 0x001700, bar0);
}