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/M0205.h>
0027
0028 u32
0029 nvbios_M0205Te(struct nvkm_bios *bios,
0030 u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *snr, u8 *ssz)
0031 {
0032 struct bit_entry bit_M;
0033 u32 data = 0x00000000;
0034
0035 if (!bit_entry(bios, 'M', &bit_M)) {
0036 if (bit_M.version == 2 && bit_M.length > 0x08)
0037 data = nvbios_rd32(bios, bit_M.offset + 0x05);
0038 if (data) {
0039 *ver = nvbios_rd08(bios, data + 0x00);
0040 switch (*ver) {
0041 case 0x10:
0042 *hdr = nvbios_rd08(bios, data + 0x01);
0043 *len = nvbios_rd08(bios, data + 0x02);
0044 *ssz = nvbios_rd08(bios, data + 0x03);
0045 *snr = nvbios_rd08(bios, data + 0x04);
0046 *cnt = nvbios_rd08(bios, data + 0x05);
0047 return data;
0048 default:
0049 break;
0050 }
0051 }
0052 }
0053
0054 return 0x00000000;
0055 }
0056
0057 u32
0058 nvbios_M0205Tp(struct nvkm_bios *bios,
0059 u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *snr, u8 *ssz,
0060 struct nvbios_M0205T *info)
0061 {
0062 u32 data = nvbios_M0205Te(bios, ver, hdr, cnt, len, snr, ssz);
0063 memset(info, 0x00, sizeof(*info));
0064 switch (!!data * *ver) {
0065 case 0x10:
0066 info->freq = nvbios_rd16(bios, data + 0x06);
0067 break;
0068 default:
0069 break;
0070 }
0071 return data;
0072 }
0073
0074 u32
0075 nvbios_M0205Ee(struct nvkm_bios *bios, int idx,
0076 u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
0077 {
0078 u8 snr, ssz;
0079 u32 data = nvbios_M0205Te(bios, ver, hdr, cnt, len, &snr, &ssz);
0080 if (data && idx < *cnt) {
0081 data = data + *hdr + idx * (*len + (snr * ssz));
0082 *hdr = *len;
0083 *cnt = snr;
0084 *len = ssz;
0085 return data;
0086 }
0087 return 0x00000000;
0088 }
0089
0090 u32
0091 nvbios_M0205Ep(struct nvkm_bios *bios, int idx,
0092 u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
0093 struct nvbios_M0205E *info)
0094 {
0095 u32 data = nvbios_M0205Ee(bios, idx, ver, hdr, cnt, len);
0096 memset(info, 0x00, sizeof(*info));
0097 switch (!!data * *ver) {
0098 case 0x10:
0099 info->type = nvbios_rd08(bios, data + 0x00) & 0x0f;
0100 return data;
0101 default:
0102 break;
0103 }
0104 return 0x00000000;
0105 }
0106
0107 u32
0108 nvbios_M0205Se(struct nvkm_bios *bios, int ent, int idx, u8 *ver, u8 *hdr)
0109 {
0110
0111 u8 cnt, len;
0112 u32 data = nvbios_M0205Ee(bios, ent, ver, hdr, &cnt, &len);
0113 if (data && idx < cnt) {
0114 data = data + *hdr + idx * len;
0115 *hdr = len;
0116 return data;
0117 }
0118 return 0x00000000;
0119 }
0120
0121 u32
0122 nvbios_M0205Sp(struct nvkm_bios *bios, int ent, int idx, u8 *ver, u8 *hdr,
0123 struct nvbios_M0205S *info)
0124 {
0125 u32 data = nvbios_M0205Se(bios, ent, idx, ver, hdr);
0126 memset(info, 0x00, sizeof(*info));
0127 switch (!!data * *ver) {
0128 case 0x10:
0129 info->data = nvbios_rd08(bios, data + 0x00);
0130 return data;
0131 default:
0132 break;
0133 }
0134 return 0x00000000;
0135 }