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 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);
}
Beispiel #4
0
u8
nv_rdport(void *obj, int head, u16 port)
{
	struct nouveau_device *device = nv_device(obj);

	if (device->card_type >= NV_50)
		return nv_rd08(obj, 0x601000 + port);

	if (port == 0x03c0 || port == 0x03c1 ||	/* AR */
	    port == 0x03c2 || port == 0x03da ||	/* INP0 */
	    port == 0x03d4 || port == 0x03d5)	/* CR */
		return nv_rd08(obj, 0x601000 + (head * 0x2000) + port);

	if (port == 0x03c2 || port == 0x03cc ||	/* MISC */
	    port == 0x03c4 || port == 0x03c5 ||	/* SR */
	    port == 0x03ce || port == 0x03cf) {	/* GR */
		if (device->card_type < NV_40)
			head = 0; /* CR44 selects head */
		return nv_rd08(obj, 0x0c0000 + (head * 0x2000) + port);
	}

	nv_error(obj, "unknown vga port 0x%04x\n", port);
	return 0x00;
}