0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 #include <subdev/bios.h>
0025 #include <subdev/bios/bit.h>
0026 #include <subdev/bios/boost.h>
0027
0028 u32
0029 nvbios_boostTe(struct nvkm_bios *bios,
0030 u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *snr, u8 *ssz)
0031 {
0032 struct bit_entry bit_P;
0033 u32 boost = 0;
0034
0035 if (!bit_entry(bios, 'P', &bit_P)) {
0036 if (bit_P.version == 2 && bit_P.length >= 0x34)
0037 boost = nvbios_rd32(bios, bit_P.offset + 0x30);
0038
0039 if (boost) {
0040 *ver = nvbios_rd08(bios, boost + 0);
0041 switch (*ver) {
0042 case 0x11:
0043 *hdr = nvbios_rd08(bios, boost + 1);
0044 *cnt = nvbios_rd08(bios, boost + 5);
0045 *len = nvbios_rd08(bios, boost + 2);
0046 *snr = nvbios_rd08(bios, boost + 4);
0047 *ssz = nvbios_rd08(bios, boost + 3);
0048 return boost;
0049 default:
0050 break;
0051 }
0052 }
0053 }
0054
0055 return 0;
0056 }
0057
0058 u32
0059 nvbios_boostEe(struct nvkm_bios *bios, int idx,
0060 u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
0061 {
0062 u8 snr, ssz;
0063 u32 data = nvbios_boostTe(bios, ver, hdr, cnt, len, &snr, &ssz);
0064 if (data && idx < *cnt) {
0065 data = data + *hdr + (idx * (*len + (snr * ssz)));
0066 *hdr = *len;
0067 *cnt = snr;
0068 *len = ssz;
0069 return data;
0070 }
0071 return 0;
0072 }
0073
0074 u32
0075 nvbios_boostEp(struct nvkm_bios *bios, int idx,
0076 u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_boostE *info)
0077 {
0078 u32 data = nvbios_boostEe(bios, idx, ver, hdr, cnt, len);
0079 memset(info, 0x00, sizeof(*info));
0080 if (data) {
0081 info->pstate = (nvbios_rd16(bios, data + 0x00) & 0x01e0) >> 5;
0082 info->min = nvbios_rd16(bios, data + 0x02) * 1000;
0083 info->max = nvbios_rd16(bios, data + 0x04) * 1000;
0084 }
0085 return data;
0086 }
0087
0088 u32
0089 nvbios_boostEm(struct nvkm_bios *bios, u8 pstate,
0090 u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_boostE *info)
0091 {
0092 u32 data, idx = 0;
0093 while ((data = nvbios_boostEp(bios, idx++, ver, hdr, cnt, len, info))) {
0094 if (info->pstate == pstate)
0095 break;
0096 }
0097 return data;
0098 }
0099
0100 u32
0101 nvbios_boostSe(struct nvkm_bios *bios, int idx,
0102 u32 data, u8 *ver, u8 *hdr, u8 cnt, u8 len)
0103 {
0104 if (data && idx < cnt) {
0105 data = data + *hdr + (idx * len);
0106 *hdr = len;
0107 return data;
0108 }
0109 return 0;
0110 }
0111
0112 u32
0113 nvbios_boostSp(struct nvkm_bios *bios, int idx,
0114 u32 data, u8 *ver, u8 *hdr, u8 cnt, u8 len,
0115 struct nvbios_boostS *info)
0116 {
0117 data = nvbios_boostSe(bios, idx, data, ver, hdr, cnt, len);
0118 memset(info, 0x00, sizeof(*info));
0119 if (data) {
0120 info->domain = nvbios_rd08(bios, data + 0x00);
0121 info->percent = nvbios_rd08(bios, data + 0x01);
0122 info->min = nvbios_rd16(bios, data + 0x02) * 1000;
0123 info->max = nvbios_rd16(bios, data + 0x04) * 1000;
0124 }
0125 return data;
0126 }