static u16 therm_table(struct nouveau_device *device, u8 *ver, u8 *hdr, u8 *len, u8 *cnt)
{
    struct bit_entry bit_P;
    u16 therm = 0;
    
    if (!nouveau_bit_entry(device, 'P', &bit_P)) {
        if (bit_P.version == 1)
            therm = nv_ro16(device, bit_P.offset + 12);
        else if (bit_P.version == 2)
            therm = nv_ro16(device, bit_P.offset + 16);
        else
            nv_error(device,
                     "unknown offset for thermal in BIT P %d\n",
                     bit_P.version);
    }
    
    /* exit now if we haven't found the thermal table */
    if (!therm)
        return 0x0000;
    
    *ver = nv_ro08(device, therm + 0);
    *hdr = nv_ro08(device, therm + 1);
    *len = nv_ro08(device, therm + 2);
    *cnt = nv_ro08(device, therm + 3);
    
    return therm + nv_ro08(device, therm + 1);
}
示例#2
0
文件: P0260.c 项目: 24hours/linux
u32
nvbios_P0260Te(struct nouveau_bios *bios,
	       u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *xnr, u8 *xsz)
{
	struct bit_entry bit_P;
	u32 data = 0x00000000;

	if (!bit_entry(bios, 'P', &bit_P)) {
		if (bit_P.version == 2 && bit_P.length > 0x63)
			data = nv_ro32(bios, bit_P.offset + 0x60);
		if (data) {
			*ver = nv_ro08(bios, data + 0);
			switch (*ver) {
			case 0x10:
				*hdr = nv_ro08(bios, data + 1);
				*cnt = nv_ro08(bios, data + 2);
				*len = 4;
				*xnr = nv_ro08(bios, data + 3);
				*xsz = 4;
				return data;
			default:
				break;
			}
		}
	}

	return 0x00000000;
}
示例#3
0
文件: dp.c 项目: 03199618/linux
static u16
nvbios_dpout_entry(struct nouveau_bios *bios, u8 idx,
		   u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
	u16 data = nvbios_dp_table(bios, ver, hdr, cnt, len);
	if (data && idx < *cnt) {
		u16 outp = nv_ro16(bios, data + *hdr + idx * *len);
		switch (*ver * !!outp) {
		case 0x21:
		case 0x30:
			*hdr = nv_ro08(bios, data + 0x04);
			*len = nv_ro08(bios, data + 0x05);
			*cnt = nv_ro08(bios, outp + 0x04);
			break;
		case 0x40:
			*hdr = nv_ro08(bios, data + 0x04);
			*cnt = 0;
			*len = 0;
			break;
		default:
			break;
		}
		return outp;
	}
	*ver = 0x00;
	return 0x0000;
}
示例#4
0
/**
 * INIT_IO_RESTRICT_PROG - opcode 0x32
 *
 */
static void
init_io_restrict_prog(struct nvbios_init *init)
{
	struct nouveau_bios *bios = init->bios;
	u16 port = nv_ro16(bios, init->offset + 1);
	u8 index = nv_ro08(bios, init->offset + 3);
	u8  mask = nv_ro08(bios, init->offset + 4);
	u8 shift = nv_ro08(bios, init->offset + 5);
	u8 count = nv_ro08(bios, init->offset + 6);
	u32  reg = nv_ro32(bios, init->offset + 7);
	u8 conf, i;

	trace("IO_RESTRICT_PROG\tR[0x%06x] = "
	      "((0x%04x[0x%02x] & 0x%02x) >> %d) [{\n",
	      reg, port, index, mask, shift);
	init->offset += 11;

	conf = (init_rdvgai(init, port, index) & mask) >> shift;
	for (i = 0; i < count; i++) {
		u32 data = nv_ro32(bios, init->offset);

		if (i == conf) {
			trace("\t0x%08x *\n", data);
			init_wr32(init, reg, data);
		} else {
			trace("\t0x%08x\n", data);
		}

		init->offset += 4;
	}
	trace("}]\n");
}
示例#5
0
int
dcb_outp_foreach(struct nouveau_bios *bios, void *data,
		 int (*exec)(struct nouveau_bios *, void *, int, u16))
{
	int ret, idx = -1;
	u8  ver, len;
	u16 outp;

	while ((outp = dcb_outp(bios, ++idx, &ver, &len))) {
		if (nv_ro32(bios, outp) == 0x00000000)
			break; /* seen on an NV11 with DCB v1.5 */
		if (nv_ro32(bios, outp) == 0xffffffff)
			break; /* seen on an NV17 with DCB v2.0 */

		if (nv_ro08(bios, outp) == DCB_OUTPUT_UNUSED)
			continue;
		if (nv_ro08(bios, outp) == DCB_OUTPUT_EOL)
			break;

		ret = exec(bios, data, idx, outp);
		if (ret)
			return ret;
	}

	return 0;
}
示例#6
0
文件: M0203.c 项目: 383530895/linux
u32
nvbios_M0203Te(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
	struct bit_entry bit_M;
	u32 data = 0x00000000;

	if (!bit_entry(bios, 'M', &bit_M)) {
		if (bit_M.version == 2 && bit_M.length > 0x04)
			data = nv_ro16(bios, bit_M.offset + 0x03);
		if (data) {
			*ver = nv_ro08(bios, data + 0x00);
			switch (*ver) {
			case 0x10:
				*hdr = nv_ro08(bios, data + 0x01);
				*len = nv_ro08(bios, data + 0x02);
				*cnt = nv_ro08(bios, data + 0x03);
				return data;
			default:
				break;
			}
		}
	}

	return 0x00000000;
}
示例#7
0
文件: dp.c 项目: 03199618/linux
static u16
nvbios_dp_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
	struct bit_entry d;

	if (!bit_entry(bios, 'd', &d)) {
		if (d.version == 1 && d.length >= 2) {
			u16 data = nv_ro16(bios, d.offset);
			if (data) {
				*ver = nv_ro08(bios, data + 0x00);
				switch (*ver) {
				case 0x21:
				case 0x30:
				case 0x40:
					*hdr = nv_ro08(bios, data + 0x01);
					*len = nv_ro08(bios, data + 0x02);
					*cnt = nv_ro08(bios, data + 0x03);
					return data;
				default:
					break;
				}
			}
		}
	}

	return 0x0000;
}
示例#8
0
文件: volt.c 项目: 24hours/linux
u16
nvbios_volt_parse(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
		  struct nvbios_volt *info)
{
	u16 volt = nvbios_volt_table(bios, ver, hdr, cnt, len);
	memset(info, 0x00, sizeof(*info));
	switch (!!volt * *ver) {
	case 0x12:
		info->vidmask = nv_ro08(bios, volt + 0x04);
		break;
	case 0x20:
		info->vidmask = nv_ro08(bios, volt + 0x05);
		break;
	case 0x30:
		info->vidmask = nv_ro08(bios, volt + 0x04);
		break;
	case 0x40:
		info->base    = nv_ro32(bios, volt + 0x04);
		info->step    = nv_ro16(bios, volt + 0x08);
		info->vidmask = nv_ro08(bios, volt + 0x0b);
		/*XXX*/
		info->min     = 0;
		info->max     = info->base;
		break;
	case 0x50:
		info->vidmask = nv_ro08(bios, volt + 0x06);
		info->min     = nv_ro32(bios, volt + 0x0a);
		info->max     = nv_ro32(bios, volt + 0x0e);
		info->base    = nv_ro32(bios, volt + 0x12) & 0x00ffffff;
		info->step    = nv_ro16(bios, volt + 0x16);
		break;
	}
	return volt;
}
示例#9
0
u16
nvbios_disp_table(struct nouveau_bios *bios,
		  u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *sub)
{
	struct bit_entry U;

	if (!bit_entry(bios, 'U', &U)) {
		if (U.version == 1) {
			u16 data = nv_ro16(bios, U.offset);
			if (data) {
				*ver = nv_ro08(bios, data + 0x00);
				switch (*ver) {
				case 0x20:
				case 0x21:
					*hdr = nv_ro08(bios, data + 0x01);
					*len = nv_ro08(bios, data + 0x02);
					*cnt = nv_ro08(bios, data + 0x03);
					*sub = nv_ro08(bios, data + 0x04);
					return data;
				default:
					break;
				}
			}
		}
	}

	return 0x0000;
}
示例#10
0
文件: i2c.c 项目: 383530895/linux
u16
dcb_i2c_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
	u16 i2c = 0x0000;
	u16 dcb = dcb_table(bios, ver, hdr, cnt, len);
	if (dcb) {
		if (*ver >= 0x15)
			i2c = nv_ro16(bios, dcb + 2);
		if (*ver >= 0x30)
			i2c = nv_ro16(bios, dcb + 4);
	}

	if (i2c && *ver >= 0x42) {
		nv_warn(bios, "ccb %02x not supported\n", *ver);
		return 0x0000;
	}

	if (i2c && *ver >= 0x30) {
		*ver = nv_ro08(bios, i2c + 0);
		*hdr = nv_ro08(bios, i2c + 1);
		*cnt = nv_ro08(bios, i2c + 2);
		*len = nv_ro08(bios, i2c + 3);
	} else {
		*ver = *ver; /* use DCB version */
		*hdr = 0;
		*cnt = 16;
		*len = 4;
	}

	return i2c;
}
示例#11
0
文件: conn.c 项目: 383530895/linux
u32
nvbios_connEp(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len,
	      struct nvbios_connE *info)
{
	u32 data = nvbios_connEe(bios, idx, ver, len);
	memset(info, 0x00, sizeof(*info));
	switch (!!data * *ver) {
	case 0x30:
	case 0x40:
		info->type     =  nv_ro08(bios, data + 0x00);
		info->location =  nv_ro08(bios, data + 0x01) & 0x0f;
		info->hpd      = (nv_ro08(bios, data + 0x01) & 0x30) >> 4;
		info->dp       = (nv_ro08(bios, data + 0x01) & 0xc0) >> 6;
		if (*len < 4)
			return data;
		info->hpd     |= (nv_ro08(bios, data + 0x02) & 0x03) << 2;
		info->dp      |=  nv_ro08(bios, data + 0x02) & 0x0c;
		info->di       = (nv_ro08(bios, data + 0x02) & 0xf0) >> 4;
		info->hpd     |= (nv_ro08(bios, data + 0x03) & 0x07) << 4;
		info->sr       = (nv_ro08(bios, data + 0x03) & 0x08) >> 3;
		info->lcdid    = (nv_ro08(bios, data + 0x03) & 0x70) >> 4;
		return data;
	default:
		break;
	}
	return 0x00000000;
}
示例#12
0
int
nouveau_fb_bios_memtype(struct nouveau_bios *bios)
{
	struct bit_entry M;
	u8 ramcfg;

	ramcfg = (nv_rd32(bios, 0x101000) & 0x0000003c) >> 2;
	if (!bit_entry(bios, 'M', &M) && M.version == 2 && M.length >= 5) {
		u16 table   = nv_ro16(bios, M.offset + 3);
		u8  version = nv_ro08(bios, table + 0);
		u8  header  = nv_ro08(bios, table + 1);
		u8  record  = nv_ro08(bios, table + 2);
		u8  entries = nv_ro08(bios, table + 3);
		if (table && version == 0x10 && ramcfg < entries) {
			u16 entry = table + header + (ramcfg * record);
			switch (nv_ro08(bios, entry) & 0x0f) {
			case 0: return NV_MEM_TYPE_DDR2;
			case 1: return NV_MEM_TYPE_DDR3;
			case 2: return NV_MEM_TYPE_GDDR3;
			case 3: return NV_MEM_TYPE_GDDR5;
			default:
				break;
			}

		}
	}

	return NV_MEM_TYPE_UNKNOWN;
}
示例#13
0
文件: xpio.c 项目: 168519/linux
u16
dcb_xpio_parse(struct nvkm_bios *bios, u8 idx,
	       u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_xpio *info)
{
	u16 data = dcb_xpio_table(bios, idx, ver, hdr, cnt, len);
	if (data && *len >= 6) {
		info->type = nv_ro08(bios, data + 0x04);
		info->addr = nv_ro08(bios, data + 0x05);
		info->flags = nv_ro08(bios, data + 0x06);
	}
	return 0x0000;
}
示例#14
0
文件: ramcfg.c 项目: 383530895/linux
u8
nvbios_ramcfg_count(struct nouveau_bios *bios)
{
	struct bit_entry bit_M;

	if (!bit_entry(bios, 'M', &bit_M)) {
		if (bit_M.version == 1 && bit_M.length >= 5)
			return nv_ro08(bios, bit_M.offset + 2);
		if (bit_M.version == 2 && bit_M.length >= 3)
			return nv_ro08(bios, bit_M.offset + 0);
	}

	return 0x00;
}
示例#15
0
文件: timing.c 项目: 3null/linux
u16
nvbios_timingEp(struct nouveau_bios *bios, int idx,
		u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
		struct nvbios_ramcfg *p)
{
	u16 data = nvbios_timingEe(bios, idx, ver, hdr, cnt, len), temp;
	p->timing_ver = *ver;
	p->timing_hdr = *hdr;
	switch (!!data * *ver) {
	case 0x10:
		p->timing_10_WR = nv_ro08(bios, data + 0x00);
		p->timing_10_CL = nv_ro08(bios, data + 0x02);
		p->timing_10_ODT = nv_ro08(bios, data + 0x0e) & 0x07;
		p->timing_10_CWL = nv_ro08(bios, data + 0x13);
		break;
	case 0x20:
		p->timing[0] = nv_ro32(bios, data + 0x00);
		p->timing[1] = nv_ro32(bios, data + 0x04);
		p->timing[2] = nv_ro32(bios, data + 0x08);
		p->timing[3] = nv_ro32(bios, data + 0x0c);
		p->timing[4] = nv_ro32(bios, data + 0x10);
		p->timing[5] = nv_ro32(bios, data + 0x14);
		p->timing[6] = nv_ro32(bios, data + 0x18);
		p->timing[7] = nv_ro32(bios, data + 0x1c);
		p->timing[8] = nv_ro32(bios, data + 0x20);
		p->timing[9] = nv_ro32(bios, data + 0x24);
		p->timing[10] = nv_ro32(bios, data + 0x28);
		p->timing_20_2e_03 = (nv_ro08(bios, data + 0x2e) & 0x03) >> 0;
		p->timing_20_2e_30 = (nv_ro08(bios, data + 0x2e) & 0x30) >> 4;
		p->timing_20_2e_c0 = (nv_ro08(bios, data + 0x2e) & 0xc0) >> 6;
		p->timing_20_2f_03 = (nv_ro08(bios, data + 0x2f) & 0x03) >> 0;
		temp = nv_ro16(bios, data + 0x2c);
		p->timing_20_2c_003f = (temp & 0x003f) >> 0;
		p->timing_20_2c_1fc0 = (temp & 0x1fc0) >> 6;
		p->timing_20_30_07 = (nv_ro08(bios, data + 0x30) & 0x07) >> 0;
		p->timing_20_30_f8 = (nv_ro08(bios, data + 0x30) & 0xf8) >> 3;
		temp = nv_ro16(bios, data + 0x31);
		p->timing_20_31_0007 = (temp & 0x0007) >> 0;
		p->timing_20_31_0078 = (temp & 0x0078) >> 3;
		p->timing_20_31_0780 = (temp & 0x0780) >> 7;
		p->timing_20_31_0800 = (temp & 0x0800) >> 11;
		p->timing_20_31_7000 = (temp & 0x7000) >> 12;
		p->timing_20_31_8000 = (temp & 0x8000) >> 15;
		break;
	default:
		data = 0;
		break;
	}
	return data;
}
示例#16
0
static u8
init_ram_restrict_group_count(struct nvbios_init *init)
{
	struct nouveau_bios *bios = init->bios;
	struct bit_entry bit_M;

	if (!bit_entry(bios, 'M', &bit_M)) {
		if (bit_M.version == 1 && bit_M.length >= 5)
			return nv_ro08(bios, bit_M.offset + 2);
		if (bit_M.version == 2 && bit_M.length >= 3)
			return nv_ro08(bios, bit_M.offset + 0);
	}

	return 0x00;
}
示例#17
0
文件: dp.c 项目: 03199618/linux
static u16
nvbios_dpcfg_entry(struct nouveau_bios *bios, u16 outp, u8 idx,
		   u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
	if (*ver >= 0x40) {
		outp = nvbios_dp_table(bios, ver, hdr, cnt, len);
		*hdr = *hdr + (*len * * cnt);
		*len = nv_ro08(bios, outp + 0x06);
		*cnt = nv_ro08(bios, outp + 0x07);
	}

	if (idx < *cnt)
		return outp + *hdr + (idx * *len);

	return 0x0000;
}
示例#18
0
文件: ramcfg.c 项目: 383530895/linux
u8
nvbios_ramcfg_index(struct nouveau_subdev *subdev)
{
	struct nouveau_bios *bios = nouveau_bios(subdev);
	u8 strap = nvbios_ramcfg_strap(subdev);
	u32 xlat = 0x00000000;
	struct bit_entry bit_M;
	struct nvbios_M0203E M0203E;
	u8 ver, hdr;

	if (!bit_entry(bios, 'M', &bit_M)) {
		if (bit_M.version == 1 && bit_M.length >= 5)
			xlat = nv_ro16(bios, bit_M.offset + 3);
		if (bit_M.version == 2 && bit_M.length >= 3) {
			/*XXX: is M ever shorter than this?
			 *     if not - what is xlat used for now?
			 *     also - sigh..
			 */
			if (bit_M.length >= 7 &&
			    nvbios_M0203Em(bios, strap, &ver, &hdr, &M0203E))
				return M0203E.group;
			xlat = nv_ro16(bios, bit_M.offset + 1);
		}
	}

	if (xlat)
		strap = nv_ro08(bios, xlat + strap);
	return strap;
}
示例#19
0
static u16
dcb_xpiod_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
	u16 data = dcb_gpio_table(bios, ver, hdr, cnt, len);
	if (data && *ver >= 0x40 && *hdr >= 0x06) {
		u16 xpio = nv_ro16(bios, data + 0x04);
		if (xpio) {
			*ver = nv_ro08(bios, data + 0x00);
			*hdr = nv_ro08(bios, data + 0x01);
			*cnt = nv_ro08(bios, data + 0x02);
			*len = nv_ro08(bios, data + 0x03);
			return xpio;
		}
	}
	return 0x0000;
}
示例#20
0
/**
 * init_reserved - stub for various unknown/unused single-byte opcodes
 *
 */
static void
init_reserved(struct nvbios_init *init)
{
	u8 opcode = nv_ro08(init->bios, init->offset);
	trace("RESERVED\t0x%02x\n", opcode);
	init->offset += 1;
}
示例#21
0
static bool
init_io_condition_met(struct nvbios_init *init, u8 cond)
{
	struct nouveau_bios *bios = init->bios;
	u16 table = init_io_condition_table(init);
	if (table) {
		u16 port = nv_ro16(bios, table + (cond * 5) + 0);
		u8 index = nv_ro08(bios, table + (cond * 5) + 2);
		u8  mask = nv_ro08(bios, table + (cond * 5) + 3);
		u8 value = nv_ro08(bios, table + (cond * 5) + 4);
		trace("\t[0x%02x] (0x%04x[0x%02x] & 0x%02x) == 0x%02x\n",
		      cond, port, index, mask, value);
		return (init_rdvgai(init, port, index) & mask) == value;
	}
	return false;
}
示例#22
0
u16
dcb_conntab(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
	u16 dcb = dcb_table(bios, ver, hdr, cnt, len);
	if (dcb && *ver >= 0x30 && *hdr >= 0x16) {
		u16 data = nv_ro16(bios, dcb + 0x14);
		if (data) {
			*ver = nv_ro08(bios, data + 0);
			*hdr = nv_ro08(bios, data + 1);
			*cnt = nv_ro08(bios, data + 2);
			*len = nv_ro08(bios, data + 3);
			return data;
		}
	}
	return 0x0000;
}
示例#23
0
文件: M0203.c 项目: 383530895/linux
u32
nvbios_M0203Ep(struct nouveau_bios *bios, int idx, u8 *ver, u8 *hdr,
	       struct nvbios_M0203E *info)
{
	u32 data = nvbios_M0203Ee(bios, idx, ver, hdr);
	memset(info, 0x00, sizeof(*info));
	switch (!!data * *ver) {
	case 0x10:
		info->type  = (nv_ro08(bios, data + 0x00) & 0x0f) >> 0;
		info->strap = (nv_ro08(bios, data + 0x00) & 0xf0) >> 4;
		info->group = (nv_ro08(bios, data + 0x01) & 0x0f) >> 0;
		return data;
	default:
		break;
	}
	return 0x00000000;
}
示例#24
0
u16
dcb_xpio_table(struct nouveau_bios *bios, u8 idx,
	       u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
	u16 data = dcb_xpiod_table(bios, ver, hdr, cnt, len);
	if (data && idx < *cnt) {
		u16 xpio = nv_ro16(bios, data + *hdr + (idx * *len));
		if (xpio) {
			*ver = nv_ro08(bios, data + 0x00);
			*hdr = nv_ro08(bios, data + 0x01);
			*cnt = nv_ro08(bios, data + 0x02);
			*len = nv_ro08(bios, data + 0x03);
			return xpio;
		}
	}
	return 0x0000;
}
示例#25
0
static u8
init_ram_restrict(struct nvbios_init *init)
{
	u8  strap = init_ram_restrict_strap(init);
	u16 table = init_ram_restrict_table(init);
	if (table)
		return nv_ro08(init->bios, table + strap);
	return 0x00;
}
示例#26
0
文件: pcir.c 项目: 168519/linux
u32
nvbios_pcirTp(struct nvkm_bios *bios, u32 base, u8 *ver, u16 *hdr,
	      struct nvbios_pcirT *info)
{
	u32 data = nvbios_pcirTe(bios, base, ver, hdr);
	memset(info, 0x00, sizeof(*info));
	if (data) {
		info->vendor_id = nv_ro16(bios, data + 0x04);
		info->device_id = nv_ro16(bios, data + 0x06);
		info->class_code[0] = nv_ro08(bios, data + 0x0d);
		info->class_code[1] = nv_ro08(bios, data + 0x0e);
		info->class_code[2] = nv_ro08(bios, data + 0x0f);
		info->image_size = nv_ro16(bios, data + 0x10) * 512;
		info->image_rev = nv_ro16(bios, data + 0x12);
		info->image_type = nv_ro08(bios, data + 0x14);
		info->last = nv_ro08(bios, data + 0x15) & 0x80;
	}
	return data;
}
示例#27
0
文件: ramnve0.c 项目: JorgeFRod/linux
int
nve0_ram_init(struct nouveau_object *object)
{
	struct nouveau_fb *pfb = (void *)object->parent;
	struct nve0_ram *ram   = (void *)object;
	struct nouveau_bios *bios = nouveau_bios(pfb);
	static const u8  train0[] = {
		0x00, 0xff, 0xff, 0x00, 0xff, 0x00,
		0x00, 0xff, 0xff, 0x00, 0xff, 0x00,
	};
	static const u32 train1[] = {
		0x00000000, 0xffffffff,
		0x55555555, 0xaaaaaaaa,
		0x33333333, 0xcccccccc,
		0xf0f0f0f0, 0x0f0f0f0f,
		0x00ff00ff, 0xff00ff00,
		0x0000ffff, 0xffff0000,
	};
	u8  ver, hdr, cnt, len, snr, ssz;
	u32 data, save;
	int ret, i;

	ret = nouveau_ram_init(&ram->base);
	if (ret)
		return ret;

	/* run a bunch of tables from rammap table.  there's actually
	 * individual pointers for each rammap entry too, but, nvidia
	 * seem to just run the last two entries' scripts early on in
	 * their init, and never again.. we'll just run 'em all once
	 * for now.
	 *
	 * i strongly suspect that each script is for a separate mode
	 * (likely selected by 0x10f65c's lower bits?), and the
	 * binary driver skips the one that's already been setup by
	 * the init tables.
	 */
	data = nvbios_rammapTe(bios, &ver, &hdr, &cnt, &len, &snr, &ssz);
	if (!data || hdr < 0x15)
		return -EINVAL;

	cnt  = nv_ro08(bios, data + 0x14); /* guess at count */
	data = nv_ro32(bios, data + 0x10); /* guess u32... */
	save = nv_rd32(pfb, 0x10f65c);
	for (i = 0; i < cnt; i++) {
		nv_mask(pfb, 0x10f65c, 0x000000f0, i << 4);
		nvbios_exec(&(struct nvbios_init) {
				.subdev = nv_subdev(pfb),
				.bios = bios,
				.offset = nv_ro32(bios, data), /* guess u32 */
				.execute = 1,
			    });
		data += 4;
	}
示例#28
0
文件: ramnve0.c 项目: JorgeFRod/linux
static int
nve0_ram_calc_data(struct nouveau_fb *pfb, u32 freq,
		   struct nouveau_ram_data *data)
{
	struct nouveau_bios *bios = nouveau_bios(pfb);
	struct nve0_ram *ram = (void *)pfb->ram;
	u8 strap, cnt, len;

	/* lookup memory config data relevant to the target frequency */
	ram->base.rammap.data = nvbios_rammapEp(bios, freq / 1000,
					       &ram->base.rammap.version,
					       &ram->base.rammap.size,
					       &cnt, &len, &data->bios);
	if (!ram->base.rammap.data || ram->base.rammap.version != 0x11 ||
	     ram->base.rammap.size < 0x09) {
		nv_error(pfb, "invalid/missing rammap entry\n");
		return -EINVAL;
	}

	/* locate specific data set for the attached memory */
	strap = nvbios_ramcfg_index(nv_subdev(pfb));
	ram->base.ramcfg.data = nvbios_rammapSp(bios, ram->base.rammap.data,
						ram->base.rammap.version,
						ram->base.rammap.size,
						cnt, len, strap,
						&ram->base.ramcfg.version,
						&ram->base.ramcfg.size,
						&data->bios);
	if (!ram->base.ramcfg.data || ram->base.ramcfg.version != 0x11 ||
	     ram->base.ramcfg.size < 0x08) {
		nv_error(pfb, "invalid/missing ramcfg entry\n");
		return -EINVAL;
	}

	/* lookup memory timings, if bios says they're present */
	strap = nv_ro08(bios, ram->base.ramcfg.data + 0x00);
	if (strap != 0xff) {
		ram->base.timing.data =
			nvbios_timingEp(bios, strap, &ram->base.timing.version,
				       &ram->base.timing.size, &cnt, &len,
				       &data->bios);
		if (!ram->base.timing.data ||
		     ram->base.timing.version != 0x20 ||
		     ram->base.timing.size < 0x33) {
			nv_error(pfb, "invalid/missing timing entry\n");
			return -EINVAL;
		}
	} else {
		ram->base.timing.data = 0;
	}

	data->freq = freq;
	return 0;
}
示例#29
0
static u16 nvbios_volt_entry_parse(struct nouveau_device *device, int idx, u8 *ver, u8 *len,
                        struct nvbios_volt_entry *info)
{
	u16 volt = nvbios_volt_entry(device, idx, ver, len);
	memset(info, 0x00, sizeof(*info));
	switch (!!volt * *ver) {
        case 0x12:
        case 0x20:
            info->voltage = nv_ro08(device, volt + 0x00) * 10000;
            info->vid     = nv_ro08(device, volt + 0x01);
            break;
        case 0x30:
            info->voltage = nv_ro08(device, volt + 0x00) * 10000;
            info->vid     = nv_ro08(device, volt + 0x01) >> 2;
            break;
        case 0x40:
        case 0x50:
            break;
	}
	return volt;
}
示例#30
0
static inline int nv_memcmp(struct nouveau_device *device, u32 addr, const char *str, u32 len)
{
    unsigned char c1, c2;

    while (len--) {
        c1 = nv_ro08(device, addr++);
        c2 = *(str++);
        if (c1 != c2)
            return c1 - c2;
    }
    return 0;
}