コード例 #1
0
ファイル: conn.c プロジェクト: 020gzh/linux
u32
nvbios_connEp(struct nvkm_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     =  nvbios_rd08(bios, data + 0x00);
		info->location =  nvbios_rd08(bios, data + 0x01) & 0x0f;
		info->hpd      = (nvbios_rd08(bios, data + 0x01) & 0x30) >> 4;
		info->dp       = (nvbios_rd08(bios, data + 0x01) & 0xc0) >> 6;
		if (*len < 4)
			return data;
		info->hpd     |= (nvbios_rd08(bios, data + 0x02) & 0x03) << 2;
		info->dp      |=  nvbios_rd08(bios, data + 0x02) & 0x0c;
		info->di       = (nvbios_rd08(bios, data + 0x02) & 0xf0) >> 4;
		info->hpd     |= (nvbios_rd08(bios, data + 0x03) & 0x07) << 4;
		info->sr       = (nvbios_rd08(bios, data + 0x03) & 0x08) >> 3;
		info->lcdid    = (nvbios_rd08(bios, data + 0x03) & 0x70) >> 4;
		return data;
	default:
		break;
	}
	return 0x00000000;
}
コード例 #2
0
ファイル: iccsense.c プロジェクト: ChineseDr/linux
static u16
nvbios_iccsense_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt,
                      u8 *len)
{
    struct bit_entry bit_P;
    u16 iccsense;

    if (bit_entry(bios, 'P', &bit_P) || bit_P.version != 2 ||
            bit_P.length < 0x2c)
        return 0;

    iccsense = nvbios_rd16(bios, bit_P.offset + 0x28);
    if (!iccsense)
        return 0;

    *ver = nvbios_rd08(bios, iccsense + 0);
    switch (*ver) {
    case 0x10:
    case 0x20:
        *hdr = nvbios_rd08(bios, iccsense + 1);
        *len = nvbios_rd08(bios, iccsense + 2);
        *cnt = nvbios_rd08(bios, iccsense + 3);
        return iccsense;
    default:
        break;
    }

    return 0;
}
コード例 #3
0
ファイル: mxm.c プロジェクト: 020gzh/linux
u8
mxm_ddc_map(struct nvkm_bios *bios, u8 port)
{
	struct nvkm_subdev *subdev = &bios->subdev;
	u8  ver, hdr;
	u16 mxm = mxm_table(bios, &ver, &hdr);
	if (mxm && hdr >= 8) {
		u16 map = nvbios_rd16(bios, mxm + 6);
		if (map) {
			ver = nvbios_rd08(bios, map);
			if (ver == 0x10) {
				if (port < nvbios_rd08(bios, map + 3)) {
					map += nvbios_rd08(bios, map + 1);
					map += port;
					return nvbios_rd08(bios, map);
				}

				return 0x00;
			}

			nvkm_warn(subdev, "unknown ddc map v%02x\n", ver);
		}
	}

	/* v2.x: directly write port as dcb i2cidx */
	return (port << 4) | port;
}
コード例 #4
0
ファイル: P0260.c プロジェクト: 020gzh/linux
u32
nvbios_P0260Te(struct nvkm_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 = nvbios_rd32(bios, bit_P.offset + 0x60);
		if (data) {
			*ver = nvbios_rd08(bios, data + 0);
			switch (*ver) {
			case 0x10:
				*hdr = nvbios_rd08(bios, data + 1);
				*cnt = nvbios_rd08(bios, data + 2);
				*len = 4;
				*xnr = nvbios_rd08(bios, data + 3);
				*xsz = 4;
				return data;
			default:
				break;
			}
		}
	}

	return 0x00000000;
}
コード例 #5
0
ファイル: vmap.c プロジェクト: AlexShiLucky/linux
u32
nvbios_vmap_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
	struct bit_entry bit_P;
	u32 vmap = 0;

	if (!bit_entry(bios, 'P', &bit_P)) {
		if (bit_P.version == 2) {
			vmap = nvbios_rd32(bios, bit_P.offset + 0x20);
			if (vmap) {
				*ver = nvbios_rd08(bios, vmap + 0);
				switch (*ver) {
				case 0x10:
				case 0x20:
					*hdr = nvbios_rd08(bios, vmap + 1);
					*cnt = nvbios_rd08(bios, vmap + 3);
					*len = nvbios_rd08(bios, vmap + 2);
					return vmap;
				default:
					break;
				}
			}
		}
	}

	return 0;
}
コード例 #6
0
ファイル: pll.c プロジェクト: AK101111/linux
static u32
pll_limits_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
	struct bit_entry bit_C;
	u32 data = 0x0000;

	if (!bit_entry(bios, 'C', &bit_C)) {
		if (bit_C.version == 1 && bit_C.length >= 10)
			data = nvbios_rd16(bios, bit_C.offset + 8);
		if (bit_C.version == 2 && bit_C.length >= 4)
			data = nvbios_rd32(bios, bit_C.offset + 0);
		if (data) {
			*ver = nvbios_rd08(bios, data + 0);
			*hdr = nvbios_rd08(bios, data + 1);
			*len = nvbios_rd08(bios, data + 2);
			*cnt = nvbios_rd08(bios, data + 3);
			return data;
		}
	}

	if (bmp_version(bios) >= 0x0524) {
		data = nvbios_rd16(bios, bios->bmp_offset + 142);
		if (data) {
			*ver = nvbios_rd08(bios, data + 0);
			*hdr = 1;
			*cnt = 1;
			*len = 0x18;
			return data;
		}
	}

	*ver = 0x00;
	return data;
}
コード例 #7
0
ファイル: dp.c プロジェクト: AlexShiLucky/linux
static u16
nvbios_dpout_entry(struct nvkm_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 = nvbios_rd16(bios, data + *hdr + idx * *len);
		switch (*ver * !!outp) {
		case 0x20:
		case 0x21:
		case 0x30:
			*hdr = nvbios_rd08(bios, data + 0x04);
			*len = nvbios_rd08(bios, data + 0x05);
			*cnt = nvbios_rd08(bios, outp + 0x04);
			break;
		case 0x40:
		case 0x41:
		case 0x42:
			*hdr = nvbios_rd08(bios, data + 0x04);
			*cnt = 0;
			*len = 0;
			break;
		default:
			break;
		}
		return outp;
	}
	*ver = 0x00;
	return 0x0000;
}
コード例 #8
0
ファイル: vmap.c プロジェクト: AlexShiLucky/linux
u32
nvbios_vmap_entry_parse(struct nvkm_bios *bios, int idx, u8 *ver, u8 *len,
			struct nvbios_vmap_entry *info)
{
	u32 vmap = nvbios_vmap_entry(bios, idx, ver, len);
	memset(info, 0x00, sizeof(*info));
	switch (!!vmap * *ver) {
	case 0x10:
		info->link   = 0xff;
		info->min    = nvbios_rd32(bios, vmap + 0x00);
		info->max    = nvbios_rd32(bios, vmap + 0x04);
		info->arg[0] = nvbios_rd32(bios, vmap + 0x08);
		info->arg[1] = nvbios_rd32(bios, vmap + 0x0c);
		info->arg[2] = nvbios_rd32(bios, vmap + 0x10);
		break;
	case 0x20:
		info->mode   = nvbios_rd08(bios, vmap + 0x00);
		info->link   = nvbios_rd08(bios, vmap + 0x01);
		info->min    = nvbios_rd32(bios, vmap + 0x02);
		info->max    = nvbios_rd32(bios, vmap + 0x06);
		info->arg[0] = nvbios_rd32(bios, vmap + 0x0a);
		info->arg[1] = nvbios_rd32(bios, vmap + 0x0e);
		info->arg[2] = nvbios_rd32(bios, vmap + 0x12);
		info->arg[3] = nvbios_rd32(bios, vmap + 0x16);
		info->arg[4] = nvbios_rd32(bios, vmap + 0x1a);
		info->arg[5] = nvbios_rd32(bios, vmap + 0x1e);
		break;
	}
	return vmap;
}
コード例 #9
0
ファイル: dp.c プロジェクト: AlexShiLucky/linux
u16
nvbios_dp_table(struct nvkm_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 = nvbios_rd16(bios, d.offset);
			if (data) {
				*ver = nvbios_rd08(bios, data + 0x00);
				switch (*ver) {
				case 0x20:
				case 0x21:
				case 0x30:
				case 0x40:
				case 0x41:
				case 0x42:
					*hdr = nvbios_rd08(bios, data + 0x01);
					*len = nvbios_rd08(bios, data + 0x02);
					*cnt = nvbios_rd08(bios, data + 0x03);
					return data;
				default:
					break;
				}
			}
		}
	}

	return 0x0000;
}
コード例 #10
0
ファイル: dp.c プロジェクト: AlexShiLucky/linux
u16
nvbios_dpcfg_match(struct nvkm_bios *bios, u16 outp, u8 pc, u8 vs, u8 pe,
		   u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
		   struct nvbios_dpcfg *info)
{
	u8 idx = 0xff;
	u16 data;

	if (*ver >= 0x30) {
		const u8 vsoff[] = { 0, 4, 7, 9 };
		idx = (pc * 10) + vsoff[vs] + pe;
		if (*ver >= 0x40 && *ver <= 0x41 && *hdr >= 0x12)
			idx += nvbios_rd08(bios, outp + 0x11) * 40;
		else
		if (*ver >= 0x42)
			idx += nvbios_rd08(bios, outp + 0x11) * 10;
	} else {
		while ((data = nvbios_dpcfg_entry(bios, outp, ++idx,
						  ver, hdr, cnt, len))) {
			if (nvbios_rd08(bios, data + 0x00) == vs &&
			    nvbios_rd08(bios, data + 0x01) == pe)
				break;
		}
	}

	return nvbios_dpcfg_parse(bios, outp, idx, ver, hdr, cnt, len, info);
}
コード例 #11
0
ファイル: dp.c プロジェクト: AlexShiLucky/linux
u16
nvbios_dpcfg_parse(struct nvkm_bios *bios, u16 outp, u8 idx,
		   u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
		   struct nvbios_dpcfg *info)
{
	u16 data = nvbios_dpcfg_entry(bios, outp, idx, ver, hdr, cnt, len);
	memset(info, 0x00, sizeof(*info));
	if (data) {
		switch (*ver) {
		case 0x20:
		case 0x21:
			info->dc    = nvbios_rd08(bios, data + 0x02);
			info->pe    = nvbios_rd08(bios, data + 0x03);
			info->tx_pu = nvbios_rd08(bios, data + 0x04);
			break;
		case 0x30:
		case 0x40:
		case 0x41:
			info->pc    = nvbios_rd08(bios, data + 0x00);
			info->dc    = nvbios_rd08(bios, data + 0x01);
			info->pe    = nvbios_rd08(bios, data + 0x02);
			info->tx_pu = nvbios_rd08(bios, data + 0x03);
			break;
		case 0x42:
			info->dc    = nvbios_rd08(bios, data + 0x00);
			info->pe    = nvbios_rd08(bios, data + 0x01);
			info->tx_pu = nvbios_rd08(bios, data + 0x02);
			break;
		default:
			data = 0x0000;
			break;
		}
	}
	return data;
}
コード例 #12
0
ファイル: rammap.c プロジェクト: AK101111/linux
/* Pretend a performance mode is also a rammap entry, helps coalesce entries
 * later on */
u32
nvbios_rammapEp_from_perf(struct nvkm_bios *bios, u32 data, u8 size,
		struct nvbios_ramcfg *p)
{
	memset(p, 0x00, sizeof(*p));

	p->rammap_00_16_20 = (nvbios_rd08(bios, data + 0x16) & 0x20) >> 5;
	p->rammap_00_16_40 = (nvbios_rd08(bios, data + 0x16) & 0x40) >> 6;
	p->rammap_00_17_02 = (nvbios_rd08(bios, data + 0x17) & 0x02) >> 1;

	return data;
}
コード例 #13
0
ファイル: conn.c プロジェクト: 020gzh/linux
u32
nvbios_connTe(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
	u32 dcb = dcb_table(bios, ver, hdr, cnt, len);
	if (dcb && *ver >= 0x30 && *hdr >= 0x16) {
		u32 data = nvbios_rd16(bios, dcb + 0x14);
		if (data) {
			*ver = nvbios_rd08(bios, data + 0);
			*hdr = nvbios_rd08(bios, data + 1);
			*cnt = nvbios_rd08(bios, data + 2);
			*len = nvbios_rd08(bios, data + 3);
			return data;
		}
	}
	return 0x00000000;
}
コード例 #14
0
ファイル: volt.c プロジェクト: 020gzh/linux
u16
nvbios_volt_parse(struct nvkm_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->type    = NVBIOS_VOLT_GPIO;
		info->vidmask = nvbios_rd08(bios, volt + 0x04);
		break;
	case 0x20:
		info->type    = NVBIOS_VOLT_GPIO;
		info->vidmask = nvbios_rd08(bios, volt + 0x05);
		break;
	case 0x30:
		info->type    = NVBIOS_VOLT_GPIO;
		info->vidmask = nvbios_rd08(bios, volt + 0x04);
		break;
	case 0x40:
		info->type    = NVBIOS_VOLT_GPIO;
		info->base    = nvbios_rd32(bios, volt + 0x04);
		info->step    = nvbios_rd16(bios, volt + 0x08);
		info->vidmask = nvbios_rd08(bios, volt + 0x0b);
		/*XXX*/
		info->min     = 0;
		info->max     = info->base;
		break;
	case 0x50:
		info->min     = nvbios_rd32(bios, volt + 0x0a);
		info->max     = nvbios_rd32(bios, volt + 0x0e);
		info->base    = nvbios_rd32(bios, volt + 0x12) & 0x00ffffff;

		/* offset 4 seems to be a flag byte */
		if (nvbios_rd32(bios, volt + 0x4) & 1) {
			info->type      = NVBIOS_VOLT_PWM;
			info->pwm_freq  = nvbios_rd32(bios, volt + 0x5) / 1000;
			info->pwm_range = nvbios_rd32(bios, volt + 0x16);
		} else {
			info->type      = NVBIOS_VOLT_GPIO;
			info->vidmask   = nvbios_rd08(bios, volt + 0x06);
			info->step      = nvbios_rd16(bios, volt + 0x16);
		}
		break;
	}
	return volt;
}
コード例 #15
0
ファイル: dp.c プロジェクト: AlexShiLucky/linux
u16
nvbios_dpout_parse(struct nvkm_bios *bios, u8 idx,
		   u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
		   struct nvbios_dpout *info)
{
	u16 data = nvbios_dpout_entry(bios, idx, ver, hdr, cnt, len);
	memset(info, 0x00, sizeof(*info));
	if (data && *ver) {
		info->type = nvbios_rd16(bios, data + 0x00);
		info->mask = nvbios_rd16(bios, data + 0x02);
		switch (*ver) {
		case 0x20:
			info->mask |= 0x00c0; /* match any link */
			/* fall-through */
		case 0x21:
		case 0x30:
			info->flags     = nvbios_rd08(bios, data + 0x05);
			info->script[0] = nvbios_rd16(bios, data + 0x06);
			info->script[1] = nvbios_rd16(bios, data + 0x08);
			if (*len >= 0x0c)
				info->lnkcmp    = nvbios_rd16(bios, data + 0x0a);
			if (*len >= 0x0f) {
				info->script[2] = nvbios_rd16(bios, data + 0x0c);
				info->script[3] = nvbios_rd16(bios, data + 0x0e);
			}
			if (*len >= 0x11)
				info->script[4] = nvbios_rd16(bios, data + 0x10);
			break;
		case 0x40:
		case 0x41:
		case 0x42:
			info->flags     = nvbios_rd08(bios, data + 0x04);
			info->script[0] = nvbios_rd16(bios, data + 0x05);
			info->script[1] = nvbios_rd16(bios, data + 0x07);
			info->lnkcmp    = nvbios_rd16(bios, data + 0x09);
			info->script[2] = nvbios_rd16(bios, data + 0x0b);
			info->script[3] = nvbios_rd16(bios, data + 0x0d);
			info->script[4] = nvbios_rd16(bios, data + 0x0f);
			break;
		default:
			data = 0x0000;
			break;
		}
	}
	return data;
}
コード例 #16
0
ファイル: dp.c プロジェクト: AlexShiLucky/linux
static u16
nvbios_dpcfg_entry(struct nvkm_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 = nvbios_rd08(bios, outp + 0x06);
		*cnt = nvbios_rd08(bios, outp + 0x07) *
		       nvbios_rd08(bios, outp + 0x05);
	}

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

	return 0x0000;
}
コード例 #17
0
ファイル: pmu.c プロジェクト: 020gzh/linux
u32
nvbios_pmuTe(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
	struct bit_entry bit_p;
	u32 data = 0;

	if (!bit_entry(bios, 'p', &bit_p)) {
		if (bit_p.version == 2 && bit_p.length >= 4)
			data = nvbios_rd32(bios, bit_p.offset + 0x00);
		if ((data = weirdo_pointer(bios, data))) {
			*ver = nvbios_rd08(bios, data + 0x00); /* maybe? */
			*hdr = nvbios_rd08(bios, data + 0x01);
			*len = nvbios_rd08(bios, data + 0x02);
			*cnt = nvbios_rd08(bios, data + 0x03);
		}
	}

	return data;
}
コード例 #18
0
ファイル: rammap.c プロジェクト: AK101111/linux
u32
nvbios_rammapTe(struct nvkm_bios *bios, u8 *ver, u8 *hdr,
		u8 *cnt, u8 *len, u8 *snr, u8 *ssz)
{
	struct bit_entry bit_P;
	u32 rammap = 0x0000;

	if (!bit_entry(bios, 'P', &bit_P)) {
		if (bit_P.version == 2)
			rammap = nvbios_rd32(bios, bit_P.offset + 4);

		if (rammap) {
			*ver = nvbios_rd08(bios, rammap + 0);
			switch (*ver) {
			case 0x10:
			case 0x11:
				*hdr = nvbios_rd08(bios, rammap + 1);
				*cnt = nvbios_rd08(bios, rammap + 5);
				*len = nvbios_rd08(bios, rammap + 2);
				*snr = nvbios_rd08(bios, rammap + 4);
				*ssz = nvbios_rd08(bios, rammap + 3);
				return rammap;
			default:
				break;
			}
		}
	}

	return 0x0000;
}
コード例 #19
0
ファイル: volt.c プロジェクト: 020gzh/linux
u16
nvbios_volt_entry_parse(struct nvkm_bios *bios, int idx, u8 *ver, u8 *len,
			struct nvbios_volt_entry *info)
{
	u16 volt = nvbios_volt_entry(bios, idx, ver, len);
	memset(info, 0x00, sizeof(*info));
	switch (!!volt * *ver) {
	case 0x12:
	case 0x20:
		info->voltage = nvbios_rd08(bios, volt + 0x00) * 10000;
		info->vid     = nvbios_rd08(bios, volt + 0x01);
		break;
	case 0x30:
		info->voltage = nvbios_rd08(bios, volt + 0x00) * 10000;
		info->vid     = nvbios_rd08(bios, volt + 0x01) >> 2;
		break;
	case 0x40:
	case 0x50:
		break;
	}
	return volt;
}
コード例 #20
0
ファイル: base.c プロジェクト: 513855417/linux
int
nvbios_memcmp(struct nvkm_bios *bios, u32 addr, const char *str, u32 len)
{
	unsigned char c1, c2;

	while (len--) {
		c1 = nvbios_rd08(bios, addr++);
		c2 = *(str++);
		if (c1 != c2)
			return c1 - c2;
	}
	return 0;
}
コード例 #21
0
ファイル: vmap.c プロジェクト: AlexShiLucky/linux
u32
nvbios_vmap_parse(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
		  struct nvbios_vmap *info)
{
	u32 vmap = nvbios_vmap_table(bios, ver, hdr, cnt, len);
	memset(info, 0x00, sizeof(*info));
	switch (!!vmap * *ver) {
	case 0x10:
		info->max0 = 0xff;
		info->max1 = 0xff;
		info->max2 = 0xff;
		break;
	case 0x20:
		info->max0 = nvbios_rd08(bios, vmap + 0x7);
		info->max1 = nvbios_rd08(bios, vmap + 0x8);
		if (*len >= 0xc)
			info->max2 = nvbios_rd08(bios, vmap + 0xc);
		else
			info->max2 = 0xff;
		break;
	}
	return vmap;
}
コード例 #22
0
ファイル: pmu.c プロジェクト: 020gzh/linux
u32
nvbios_pmuEp(struct nvkm_bios *bios, int idx, u8 *ver, u8 *hdr,
	     struct nvbios_pmuE *info)
{
	u32 data = nvbios_pmuEe(bios, idx, ver, hdr);
	memset(info, 0x00, sizeof(*info));
	switch (!!data * *ver) {
	default:
		info->type = nvbios_rd08(bios, data + 0x00);
		info->data = nvbios_rd32(bios, data + 0x02);
		break;
	}
	return data;
}
コード例 #23
0
ファイル: rammap.c プロジェクト: AK101111/linux
u32
nvbios_rammapEp(struct nvkm_bios *bios, int idx,
		u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ramcfg *p)
{
	u32 data = nvbios_rammapEe(bios, idx, ver, hdr, cnt, len), temp;
	memset(p, 0x00, sizeof(*p));
	p->rammap_ver = *ver;
	p->rammap_hdr = *hdr;
	switch (!!data * *ver) {
	case 0x10:
		p->rammap_min      =  nvbios_rd16(bios, data + 0x00);
		p->rammap_max      =  nvbios_rd16(bios, data + 0x02);
		p->rammap_10_04_02 = (nvbios_rd08(bios, data + 0x04) & 0x02) >> 1;
		p->rammap_10_04_08 = (nvbios_rd08(bios, data + 0x04) & 0x08) >> 3;
		break;
	case 0x11:
		p->rammap_min      =  nvbios_rd16(bios, data + 0x00);
		p->rammap_max      =  nvbios_rd16(bios, data + 0x02);
		p->rammap_11_08_01 = (nvbios_rd08(bios, data + 0x08) & 0x01) >> 0;
		p->rammap_11_08_0c = (nvbios_rd08(bios, data + 0x08) & 0x0c) >> 2;
		p->rammap_11_08_10 = (nvbios_rd08(bios, data + 0x08) & 0x10) >> 4;
		temp = nvbios_rd32(bios, data + 0x09);
		p->rammap_11_09_01ff = (temp & 0x000001ff) >> 0;
		p->rammap_11_0a_03fe = (temp & 0x0003fe00) >> 9;
		p->rammap_11_0a_0400 = (temp & 0x00040000) >> 18;
		p->rammap_11_0a_0800 = (temp & 0x00080000) >> 19;
		p->rammap_11_0b_01f0 = (temp & 0x01f00000) >> 20;
		p->rammap_11_0b_0200 = (temp & 0x02000000) >> 25;
		p->rammap_11_0b_0400 = (temp & 0x04000000) >> 26;
		p->rammap_11_0b_0800 = (temp & 0x08000000) >> 27;
		p->rammap_11_0d    =  nvbios_rd08(bios, data + 0x0d);
		p->rammap_11_0e    =  nvbios_rd08(bios, data + 0x0e);
		p->rammap_11_0f    =  nvbios_rd08(bios, data + 0x0f);
		p->rammap_11_11_0c = (nvbios_rd08(bios, data + 0x11) & 0x0c) >> 2;
		break;
	default:
		data = 0;
		break;
	}
	return data;
}
コード例 #24
0
ファイル: mxm.c プロジェクト: 020gzh/linux
u8
mxm_sor_map(struct nvkm_bios *bios, u8 conn)
{
	struct nvkm_subdev *subdev = &bios->subdev;
	u8  ver, hdr;
	u16 mxm = mxm_table(bios, &ver, &hdr);
	if (mxm && hdr >= 6) {
		u16 map = nvbios_rd16(bios, mxm + 4);
		if (map) {
			ver = nvbios_rd08(bios, map);
			if (ver == 0x10) {
				if (conn < nvbios_rd08(bios, map + 3)) {
					map += nvbios_rd08(bios, map + 1);
					map += conn;
					return nvbios_rd08(bios, map);
				}

				return 0x00;
			}

			nvkm_warn(subdev, "unknown sor map v%02x\n", ver);
		}
	}

	if (bios->version.chip == 0x84 || bios->version.chip == 0x86)
		return g84_sor_map[conn];
	if (bios->version.chip == 0x92)
		return g92_sor_map[conn];
	if (bios->version.chip == 0x94 || bios->version.chip == 0x96)
		return g94_sor_map[conn];
	if (bios->version.chip == 0x98)
		return g98_sor_map[conn];

	nvkm_warn(subdev, "missing sor map\n");
	return 0x00;
}
コード例 #25
0
ファイル: volt.c プロジェクト: 020gzh/linux
u16
nvbios_volt_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
	struct bit_entry bit_P;
	u16 volt = 0x0000;

	if (!bit_entry(bios, 'P', &bit_P)) {
		if (bit_P.version == 2)
			volt = nvbios_rd16(bios, bit_P.offset + 0x0c);
		else
		if (bit_P.version == 1)
			volt = nvbios_rd16(bios, bit_P.offset + 0x10);

		if (volt) {
			*ver = nvbios_rd08(bios, volt + 0);
			switch (*ver) {
			case 0x12:
				*hdr = 5;
				*cnt = nvbios_rd08(bios, volt + 2);
				*len = nvbios_rd08(bios, volt + 1);
				return volt;
			case 0x20:
				*hdr = nvbios_rd08(bios, volt + 1);
				*cnt = nvbios_rd08(bios, volt + 2);
				*len = nvbios_rd08(bios, volt + 3);
				return volt;
			case 0x30:
			case 0x40:
			case 0x50:
				*hdr = nvbios_rd08(bios, volt + 1);
				*cnt = nvbios_rd08(bios, volt + 3);
				*len = nvbios_rd08(bios, volt + 2);
				return volt;
			}
		}
	}

	return 0x0000;
}
コード例 #26
0
ファイル: iccsense.c プロジェクト: ChineseDr/linux
int
nvbios_iccsense_parse(struct nvkm_bios *bios, struct nvbios_iccsense *iccsense)
{
    struct nvkm_subdev *subdev = &bios->subdev;
    u8 ver, hdr, cnt, len, i;
    u16 table, entry;

    table = nvbios_iccsense_table(bios, &ver, &hdr, &cnt, &len);
    if (!table || !cnt)
        return -EINVAL;

    if (ver != 0x10 && ver != 0x20) {
        nvkm_error(subdev, "ICCSENSE version 0x%02x unknown\n", ver);
        return -EINVAL;
    }

    iccsense->nr_entry = cnt;
    iccsense->rail = kmalloc(sizeof(struct pwr_rail_t) * cnt, GFP_KERNEL);
    if (!iccsense->rail)
        return -ENOMEM;

    for (i = 0; i < cnt; ++i) {
        struct pwr_rail_t *rail = &iccsense->rail[i];
        entry = table + hdr + i * len;

        switch(ver) {
        case 0x10:
            rail->mode = nvbios_rd08(bios, entry + 0x1);
            rail->extdev_id = nvbios_rd08(bios, entry + 0x2);
            rail->resistor_mohm = nvbios_rd08(bios, entry + 0x3);
            rail->rail = nvbios_rd08(bios, entry + 0x4);
            break;
        case 0x20:
            rail->mode = nvbios_rd08(bios, entry);
            rail->extdev_id = nvbios_rd08(bios, entry + 0x1);
            rail->resistor_mohm = nvbios_rd08(bios, entry + 0x5);
            rail->rail = nvbios_rd08(bios, entry + 0x6);
            break;
        };
    }

    return 0;
}
コード例 #27
0
ファイル: pll.c プロジェクト: AK101111/linux
static u32
pll_map_type(struct nvkm_bios *bios, u8 type, u32 *reg, u8 *ver, u8 *len)
{
	struct pll_mapping *map;
	u8  hdr, cnt;
	u32 data;

	data = pll_limits_table(bios, ver, &hdr, &cnt, len);
	if (data && *ver >= 0x30) {
		data += hdr;
		while (cnt--) {
			if (nvbios_rd08(bios, data + 0) == type) {
				*reg = nvbios_rd32(bios, data + 3);
				return data;
			}
			data += *len;
		}
		return 0x0000;
	}

	map = pll_map(bios);
	while (map && map->reg) {
		if (map->type == type && *ver >= 0x20) {
			u32 addr = (data += hdr);
			*reg = map->reg;
			while (cnt--) {
				if (nvbios_rd32(bios, data) == map->reg)
					return data;
				data += *len;
			}
			return addr;
		} else
		if (map->type == type) {
			*reg = map->reg;
			return data + 1;
		}
		map++;
	}

	return 0x0000;
}
コード例 #28
0
ファイル: pll.c プロジェクト: AK101111/linux
int
nvbios_pll_parse(struct nvkm_bios *bios, u32 type, struct nvbios_pll *info)
{
	struct nvkm_subdev *subdev = &bios->subdev;
	struct nvkm_device *device = subdev->device;
	u8  ver, len;
	u32 reg = type;
	u32 data;

	if (type > PLL_MAX) {
		reg  = type;
		data = pll_map_reg(bios, reg, &type, &ver, &len);
	} else {
		data = pll_map_type(bios, type, &reg, &ver, &len);
	}

	if (ver && !data)
		return -ENOENT;

	memset(info, 0, sizeof(*info));
	info->type = type;
	info->reg = reg;

	switch (ver) {
	case 0x00:
		break;
	case 0x10:
	case 0x11:
		info->vco1.min_freq = nvbios_rd32(bios, data + 0);
		info->vco1.max_freq = nvbios_rd32(bios, data + 4);
		info->vco2.min_freq = nvbios_rd32(bios, data + 8);
		info->vco2.max_freq = nvbios_rd32(bios, data + 12);
		info->vco1.min_inputfreq = nvbios_rd32(bios, data + 16);
		info->vco2.min_inputfreq = nvbios_rd32(bios, data + 20);
		info->vco1.max_inputfreq = INT_MAX;
		info->vco2.max_inputfreq = INT_MAX;

		info->max_p = 0x7;
		info->max_p_usable = 0x6;

		/* these values taken from nv30/31/36 */
		switch (bios->version.chip) {
		case 0x36:
			info->vco1.min_n = 0x5;
			break;
		default:
			info->vco1.min_n = 0x1;
			break;
		}
		info->vco1.max_n = 0xff;
		info->vco1.min_m = 0x1;
		info->vco1.max_m = 0xd;

		/*
		 * On nv30, 31, 36 (i.e. all cards with two stage PLLs with this
		 * table version (apart from nv35)), N2 is compared to
		 * maxN2 (0x46) and 10 * maxM2 (0x4), so set maxN2 to 0x28 and
		 * save a comparison
		 */
		info->vco2.min_n = 0x4;
		switch (bios->version.chip) {
		case 0x30:
		case 0x35:
			info->vco2.max_n = 0x1f;
			break;
		default:
			info->vco2.max_n = 0x28;
			break;
		}
		info->vco2.min_m = 0x1;
		info->vco2.max_m = 0x4;
		break;
	case 0x20:
	case 0x21:
		info->vco1.min_freq = nvbios_rd16(bios, data + 4) * 1000;
		info->vco1.max_freq = nvbios_rd16(bios, data + 6) * 1000;
		info->vco2.min_freq = nvbios_rd16(bios, data + 8) * 1000;
		info->vco2.max_freq = nvbios_rd16(bios, data + 10) * 1000;
		info->vco1.min_inputfreq = nvbios_rd16(bios, data + 12) * 1000;
		info->vco2.min_inputfreq = nvbios_rd16(bios, data + 14) * 1000;
		info->vco1.max_inputfreq = nvbios_rd16(bios, data + 16) * 1000;
		info->vco2.max_inputfreq = nvbios_rd16(bios, data + 18) * 1000;
		info->vco1.min_n = nvbios_rd08(bios, data + 20);
		info->vco1.max_n = nvbios_rd08(bios, data + 21);
		info->vco1.min_m = nvbios_rd08(bios, data + 22);
		info->vco1.max_m = nvbios_rd08(bios, data + 23);
		info->vco2.min_n = nvbios_rd08(bios, data + 24);
		info->vco2.max_n = nvbios_rd08(bios, data + 25);
		info->vco2.min_m = nvbios_rd08(bios, data + 26);
		info->vco2.max_m = nvbios_rd08(bios, data + 27);

		info->max_p = nvbios_rd08(bios, data + 29);
		info->max_p_usable = info->max_p;
		if (bios->version.chip < 0x60)
			info->max_p_usable = 0x6;
		info->bias_p = nvbios_rd08(bios, data + 30);

		if (len > 0x22)
			info->refclk = nvbios_rd32(bios, data + 31);
		break;
	case 0x30:
		data = nvbios_rd16(bios, data + 1);

		info->vco1.min_freq = nvbios_rd16(bios, data + 0) * 1000;
		info->vco1.max_freq = nvbios_rd16(bios, data + 2) * 1000;
		info->vco2.min_freq = nvbios_rd16(bios, data + 4) * 1000;
		info->vco2.max_freq = nvbios_rd16(bios, data + 6) * 1000;
		info->vco1.min_inputfreq = nvbios_rd16(bios, data + 8) * 1000;
		info->vco2.min_inputfreq = nvbios_rd16(bios, data + 10) * 1000;
		info->vco1.max_inputfreq = nvbios_rd16(bios, data + 12) * 1000;
		info->vco2.max_inputfreq = nvbios_rd16(bios, data + 14) * 1000;
		info->vco1.min_n = nvbios_rd08(bios, data + 16);
		info->vco1.max_n = nvbios_rd08(bios, data + 17);
		info->vco1.min_m = nvbios_rd08(bios, data + 18);
		info->vco1.max_m = nvbios_rd08(bios, data + 19);
		info->vco2.min_n = nvbios_rd08(bios, data + 20);
		info->vco2.max_n = nvbios_rd08(bios, data + 21);
		info->vco2.min_m = nvbios_rd08(bios, data + 22);
		info->vco2.max_m = nvbios_rd08(bios, data + 23);
		info->max_p_usable = info->max_p = nvbios_rd08(bios, data + 25);
		info->bias_p = nvbios_rd08(bios, data + 27);
		info->refclk = nvbios_rd32(bios, data + 28);
		break;
	case 0x40:
		info->refclk = nvbios_rd16(bios, data + 9) * 1000;
		data = nvbios_rd16(bios, data + 1);

		info->vco1.min_freq = nvbios_rd16(bios, data + 0) * 1000;
		info->vco1.max_freq = nvbios_rd16(bios, data + 2) * 1000;
		info->vco1.min_inputfreq = nvbios_rd16(bios, data + 4) * 1000;
		info->vco1.max_inputfreq = nvbios_rd16(bios, data + 6) * 1000;
		info->vco1.min_m = nvbios_rd08(bios, data + 8);
		info->vco1.max_m = nvbios_rd08(bios, data + 9);
		info->vco1.min_n = nvbios_rd08(bios, data + 10);
		info->vco1.max_n = nvbios_rd08(bios, data + 11);
		info->min_p = nvbios_rd08(bios, data + 12);
		info->max_p = nvbios_rd08(bios, data + 13);
		break;
	default:
		nvkm_error(subdev, "unknown pll limits version 0x%02x\n", ver);
		return -EINVAL;
	}

	if (!info->refclk) {
		info->refclk = device->crystal;
		if (bios->version.chip == 0x51) {
			u32 sel_clk = nvkm_rd32(device, 0x680524);
			if ((info->reg == 0x680508 && sel_clk & 0x20) ||
			    (info->reg == 0x680520 && sel_clk & 0x80)) {
				if (nvkm_rdvgac(device, 0, 0x27) < 0xa3)
					info->refclk = 200000;
				else
					info->refclk = 25000;
			}
		}
	}

	/*
	 * By now any valid limit table ought to have set a max frequency for
	 * vco1, so if it's zero it's either a pre limit table bios, or one
	 * with an empty limit table (seen on nv18)
	 */
	if (!info->vco1.max_freq) {
		info->vco1.max_freq = nvbios_rd32(bios, bios->bmp_offset + 67);
		info->vco1.min_freq = nvbios_rd32(bios, bios->bmp_offset + 71);
		if (bmp_version(bios) < 0x0506) {
			info->vco1.max_freq = 256000;
			info->vco1.min_freq = 128000;
		}

		info->vco1.min_inputfreq = 0;
		info->vco1.max_inputfreq = INT_MAX;
		info->vco1.min_n = 0x1;
		info->vco1.max_n = 0xff;
		info->vco1.min_m = 0x1;

		if (device->crystal == 13500) {
			/* nv05 does this, nv11 doesn't, nv10 unknown */
			if (bios->version.chip < 0x11)
				info->vco1.min_m = 0x7;
			info->vco1.max_m = 0xd;
		} else {
			if (bios->version.chip < 0x11)
				info->vco1.min_m = 0x8;
			info->vco1.max_m = 0xe;
		}

		if (bios->version.chip <  0x17 ||
		    bios->version.chip == 0x1a ||
		    bios->version.chip == 0x20)
			info->max_p = 4;
		else
			info->max_p = 5;
		info->max_p_usable = info->max_p;
	}

	return 0;
}
コード例 #29
0
ファイル: rammap.c プロジェクト: AK101111/linux
u32
nvbios_rammapSp(struct nvkm_bios *bios, u32 data,
		u8 ever, u8 ehdr, u8 ecnt, u8 elen, int idx,
		u8 *ver, u8 *hdr, struct nvbios_ramcfg *p)
{
	data = nvbios_rammapSe(bios, data, ever, ehdr, ecnt, elen, idx, ver, hdr);
	p->ramcfg_ver = *ver;
	p->ramcfg_hdr = *hdr;
	switch (!!data * *ver) {
	case 0x10:
		p->ramcfg_timing   =  nvbios_rd08(bios, data + 0x01);
		p->ramcfg_10_02_01 = (nvbios_rd08(bios, data + 0x02) & 0x01) >> 0;
		p->ramcfg_10_02_02 = (nvbios_rd08(bios, data + 0x02) & 0x02) >> 1;
		p->ramcfg_10_02_04 = (nvbios_rd08(bios, data + 0x02) & 0x04) >> 2;
		p->ramcfg_10_02_08 = (nvbios_rd08(bios, data + 0x02) & 0x08) >> 3;
		p->ramcfg_10_02_10 = (nvbios_rd08(bios, data + 0x02) & 0x10) >> 4;
		p->ramcfg_10_02_20 = (nvbios_rd08(bios, data + 0x02) & 0x20) >> 5;
		p->ramcfg_DLLoff   = (nvbios_rd08(bios, data + 0x02) & 0x40) >> 6;
		p->ramcfg_10_03_0f = (nvbios_rd08(bios, data + 0x03) & 0x0f) >> 0;
		p->ramcfg_10_04_01 = (nvbios_rd08(bios, data + 0x04) & 0x01) >> 0;
		p->ramcfg_FBVDDQ   = (nvbios_rd08(bios, data + 0x04) & 0x08) >> 3;
		p->ramcfg_10_05    = (nvbios_rd08(bios, data + 0x05) & 0xff) >> 0;
		p->ramcfg_10_06    = (nvbios_rd08(bios, data + 0x06) & 0xff) >> 0;
		p->ramcfg_10_07    = (nvbios_rd08(bios, data + 0x07) & 0xff) >> 0;
		p->ramcfg_10_08    = (nvbios_rd08(bios, data + 0x08) & 0xff) >> 0;
		p->ramcfg_10_09_0f = (nvbios_rd08(bios, data + 0x09) & 0x0f) >> 0;
		p->ramcfg_10_09_f0 = (nvbios_rd08(bios, data + 0x09) & 0xf0) >> 4;
		break;
	case 0x11:
		p->ramcfg_timing   =  nvbios_rd08(bios, data + 0x00);
		p->ramcfg_11_01_01 = (nvbios_rd08(bios, data + 0x01) & 0x01) >> 0;
		p->ramcfg_11_01_02 = (nvbios_rd08(bios, data + 0x01) & 0x02) >> 1;
		p->ramcfg_11_01_04 = (nvbios_rd08(bios, data + 0x01) & 0x04) >> 2;
		p->ramcfg_11_01_08 = (nvbios_rd08(bios, data + 0x01) & 0x08) >> 3;
		p->ramcfg_11_01_10 = (nvbios_rd08(bios, data + 0x01) & 0x10) >> 4;
		p->ramcfg_DLLoff =   (nvbios_rd08(bios, data + 0x01) & 0x20) >> 5;
		p->ramcfg_11_01_40 = (nvbios_rd08(bios, data + 0x01) & 0x40) >> 6;
		p->ramcfg_11_01_80 = (nvbios_rd08(bios, data + 0x01) & 0x80) >> 7;
		p->ramcfg_11_02_03 = (nvbios_rd08(bios, data + 0x02) & 0x03) >> 0;
		p->ramcfg_11_02_04 = (nvbios_rd08(bios, data + 0x02) & 0x04) >> 2;
		p->ramcfg_11_02_08 = (nvbios_rd08(bios, data + 0x02) & 0x08) >> 3;
		p->ramcfg_11_02_10 = (nvbios_rd08(bios, data + 0x02) & 0x10) >> 4;
		p->ramcfg_11_02_40 = (nvbios_rd08(bios, data + 0x02) & 0x40) >> 6;
		p->ramcfg_11_02_80 = (nvbios_rd08(bios, data + 0x02) & 0x80) >> 7;
		p->ramcfg_11_03_0f = (nvbios_rd08(bios, data + 0x03) & 0x0f) >> 0;
		p->ramcfg_11_03_30 = (nvbios_rd08(bios, data + 0x03) & 0x30) >> 4;
		p->ramcfg_11_03_c0 = (nvbios_rd08(bios, data + 0x03) & 0xc0) >> 6;
		p->ramcfg_11_03_f0 = (nvbios_rd08(bios, data + 0x03) & 0xf0) >> 4;
		p->ramcfg_11_04    = (nvbios_rd08(bios, data + 0x04) & 0xff) >> 0;
		p->ramcfg_11_06    = (nvbios_rd08(bios, data + 0x06) & 0xff) >> 0;
		p->ramcfg_11_07_02 = (nvbios_rd08(bios, data + 0x07) & 0x02) >> 1;
		p->ramcfg_11_07_04 = (nvbios_rd08(bios, data + 0x07) & 0x04) >> 2;
		p->ramcfg_11_07_08 = (nvbios_rd08(bios, data + 0x07) & 0x08) >> 3;
		p->ramcfg_11_07_10 = (nvbios_rd08(bios, data + 0x07) & 0x10) >> 4;
		p->ramcfg_11_07_40 = (nvbios_rd08(bios, data + 0x07) & 0x40) >> 6;
		p->ramcfg_11_07_80 = (nvbios_rd08(bios, data + 0x07) & 0x80) >> 7;
		p->ramcfg_11_08_01 = (nvbios_rd08(bios, data + 0x08) & 0x01) >> 0;
		p->ramcfg_11_08_02 = (nvbios_rd08(bios, data + 0x08) & 0x02) >> 1;
		p->ramcfg_11_08_04 = (nvbios_rd08(bios, data + 0x08) & 0x04) >> 2;
		p->ramcfg_11_08_08 = (nvbios_rd08(bios, data + 0x08) & 0x08) >> 3;
		p->ramcfg_11_08_10 = (nvbios_rd08(bios, data + 0x08) & 0x10) >> 4;
		p->ramcfg_11_08_20 = (nvbios_rd08(bios, data + 0x08) & 0x20) >> 5;
		p->ramcfg_11_09    = (nvbios_rd08(bios, data + 0x09) & 0xff) >> 0;
		break;
	default:
		data = 0;
		break;
	}
	return data;
}
コード例 #30
0
ファイル: rammap.c プロジェクト: AK101111/linux
u32
nvbios_rammapSp_from_perf(struct nvkm_bios *bios, u32 data, u8 size, int idx,
		struct nvbios_ramcfg *p)
{
	data += (idx * size);

	if (size < 11)
		return 0x00000000;

	p->ramcfg_ver = 0;
	p->ramcfg_timing   =  nvbios_rd08(bios, data + 0x01);
	p->ramcfg_00_03_01 = (nvbios_rd08(bios, data + 0x03) & 0x01) >> 0;
	p->ramcfg_00_03_02 = (nvbios_rd08(bios, data + 0x03) & 0x02) >> 1;
	p->ramcfg_DLLoff   = (nvbios_rd08(bios, data + 0x03) & 0x04) >> 2;
	p->ramcfg_00_03_08 = (nvbios_rd08(bios, data + 0x03) & 0x08) >> 3;
	p->ramcfg_RON      = (nvbios_rd08(bios, data + 0x03) & 0x10) >> 3;
	p->ramcfg_FBVDDQ   = (nvbios_rd08(bios, data + 0x03) & 0x80) >> 7;
	p->ramcfg_00_04_02 = (nvbios_rd08(bios, data + 0x04) & 0x02) >> 1;
	p->ramcfg_00_04_04 = (nvbios_rd08(bios, data + 0x04) & 0x04) >> 2;
	p->ramcfg_00_04_20 = (nvbios_rd08(bios, data + 0x04) & 0x20) >> 5;
	p->ramcfg_00_05    = (nvbios_rd08(bios, data + 0x05) & 0xff) >> 0;
	p->ramcfg_00_06    = (nvbios_rd08(bios, data + 0x06) & 0xff) >> 0;
	p->ramcfg_00_07    = (nvbios_rd08(bios, data + 0x07) & 0xff) >> 0;
	p->ramcfg_00_08    = (nvbios_rd08(bios, data + 0x08) & 0xff) >> 0;
	p->ramcfg_00_09    = (nvbios_rd08(bios, data + 0x09) & 0xff) >> 0;
	p->ramcfg_00_0a_0f = (nvbios_rd08(bios, data + 0x0a) & 0x0f) >> 0;
	p->ramcfg_00_0a_f0 = (nvbios_rd08(bios, data + 0x0a) & 0xf0) >> 4;

	return data;
}