diff options
| author | Ben Skeggs <bskeggs@redhat.com> | 2014-11-03 21:06:25 -0500 |
|---|---|---|
| committer | Ben Skeggs <bskeggs@redhat.com> | 2014-12-02 00:44:05 -0500 |
| commit | 4766ec53945f14f134fc51de782b362a51351cb1 (patch) | |
| tree | 8fdb9f9b33be4d006e8c18cffcbb5f3d63b7e786 | |
| parent | ddbb55ab04db3edbc2d0910c5060c025a9ae4425 (diff) | |
drm/nouveau/bios: add parsing of BIT M(v2) +0x03 table
We only support one kind of matching here (ramcfg strap), but it appears
alternate methods are possible. I wrote a tool to scan our vbios repo
for other types, but did not see any used. Hopefully this means there
aren't any in the wild that will now break.
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
| -rw-r--r-- | drivers/gpu/drm/nouveau/Makefile | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/include/subdev/bios/M0203.h | 31 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/bios/M0203.c | 129 |
3 files changed, 161 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile index e72b488c739e..1ec77ccc9611 100644 --- a/drivers/gpu/drm/nouveau/Makefile +++ b/drivers/gpu/drm/nouveau/Makefile | |||
| @@ -62,6 +62,7 @@ nouveau-y += core/subdev/bios/therm.o | |||
| 62 | nouveau-y += core/subdev/bios/vmap.o | 62 | nouveau-y += core/subdev/bios/vmap.o |
| 63 | nouveau-y += core/subdev/bios/volt.o | 63 | nouveau-y += core/subdev/bios/volt.o |
| 64 | nouveau-y += core/subdev/bios/xpio.o | 64 | nouveau-y += core/subdev/bios/xpio.o |
| 65 | nouveau-y += core/subdev/bios/M0203.o | ||
| 65 | nouveau-y += core/subdev/bios/M0205.o | 66 | nouveau-y += core/subdev/bios/M0205.o |
| 66 | nouveau-y += core/subdev/bios/M0209.o | 67 | nouveau-y += core/subdev/bios/M0209.o |
| 67 | nouveau-y += core/subdev/bios/P0260.o | 68 | nouveau-y += core/subdev/bios/P0260.o |
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/M0203.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/M0203.h new file mode 100644 index 000000000000..1f84d3612dd8 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/M0203.h | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | #ifndef __NVBIOS_M0203_H__ | ||
| 2 | #define __NVBIOS_M0203_H__ | ||
| 3 | |||
| 4 | struct nvbios_M0203T { | ||
| 5 | #define M0203T_TYPE_RAMCFG 0x00 | ||
| 6 | u8 type; | ||
| 7 | u16 pointer; | ||
| 8 | }; | ||
| 9 | |||
| 10 | u32 nvbios_M0203Te(struct nouveau_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len); | ||
| 11 | u32 nvbios_M0203Tp(struct nouveau_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len, | ||
| 12 | struct nvbios_M0203T *); | ||
| 13 | |||
| 14 | struct nvbios_M0203E { | ||
| 15 | #define M0203E_TYPE_DDR2 0x0 | ||
| 16 | #define M0203E_TYPE_DDR3 0x1 | ||
| 17 | #define M0203E_TYPE_GDDR3 0x2 | ||
| 18 | #define M0203E_TYPE_GDDR5 0x3 | ||
| 19 | #define M0203E_TYPE_SKIP 0xf | ||
| 20 | u8 type; | ||
| 21 | u8 strap; | ||
| 22 | u8 group; | ||
| 23 | }; | ||
| 24 | |||
| 25 | u32 nvbios_M0203Ee(struct nouveau_bios *, int idx, u8 *ver, u8 *hdr); | ||
| 26 | u32 nvbios_M0203Ep(struct nouveau_bios *, int idx, u8 *ver, u8 *hdr, | ||
| 27 | struct nvbios_M0203E *); | ||
| 28 | u32 nvbios_M0203Em(struct nouveau_bios *, u8 ramcfg, u8 *ver, u8 *hdr, | ||
| 29 | struct nvbios_M0203E *); | ||
| 30 | |||
| 31 | #endif | ||
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/M0203.c b/drivers/gpu/drm/nouveau/core/subdev/bios/M0203.c new file mode 100644 index 000000000000..28906b16d4e5 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/M0203.c | |||
| @@ -0,0 +1,129 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2014 Red Hat Inc. | ||
| 3 | * | ||
| 4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
| 5 | * copy of this software and associated documentation files (the "Software"), | ||
| 6 | * to deal in the Software without restriction, including without limitation | ||
| 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
| 8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
| 9 | * Software is furnished to do so, subject to the following conditions: | ||
| 10 | * | ||
| 11 | * The above copyright notice and this permission notice shall be included in | ||
| 12 | * all copies or substantial portions of the Software. | ||
| 13 | * | ||
| 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
| 17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
| 18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
| 19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
| 20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
| 21 | * | ||
| 22 | * Authors: Ben Skeggs | ||
| 23 | */ | ||
| 24 | |||
| 25 | #include <subdev/bios.h> | ||
| 26 | #include <subdev/bios/bit.h> | ||
| 27 | #include <subdev/bios/M0203.h> | ||
| 28 | |||
| 29 | u32 | ||
| 30 | nvbios_M0203Te(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) | ||
| 31 | { | ||
| 32 | struct bit_entry bit_M; | ||
| 33 | u32 data = 0x00000000; | ||
| 34 | |||
| 35 | if (!bit_entry(bios, 'M', &bit_M)) { | ||
| 36 | if (bit_M.version == 2 && bit_M.length > 0x04) | ||
| 37 | data = nv_ro16(bios, bit_M.offset + 0x03); | ||
| 38 | if (data) { | ||
| 39 | *ver = nv_ro08(bios, data + 0x00); | ||
| 40 | switch (*ver) { | ||
| 41 | case 0x10: | ||
| 42 | *hdr = nv_ro08(bios, data + 0x01); | ||
| 43 | *len = nv_ro08(bios, data + 0x02); | ||
| 44 | *cnt = nv_ro08(bios, data + 0x03); | ||
| 45 | return data; | ||
| 46 | default: | ||
| 47 | break; | ||
| 48 | } | ||
| 49 | } | ||
| 50 | } | ||
| 51 | |||
| 52 | return 0x00000000; | ||
| 53 | } | ||
| 54 | |||
| 55 | u32 | ||
| 56 | nvbios_M0203Tp(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len, | ||
| 57 | struct nvbios_M0203T *info) | ||
| 58 | { | ||
| 59 | u32 data = nvbios_M0203Te(bios, ver, hdr, cnt, len); | ||
| 60 | memset(info, 0x00, sizeof(*info)); | ||
| 61 | switch (!!data * *ver) { | ||
| 62 | case 0x10: | ||
| 63 | info->type = nv_ro08(bios, data + 0x04); | ||
| 64 | info->pointer = nv_ro16(bios, data + 0x05); | ||
| 65 | break; | ||
| 66 | default: | ||
| 67 | break; | ||
| 68 | } | ||
| 69 | return data; | ||
| 70 | } | ||
| 71 | |||
| 72 | u32 | ||
| 73 | nvbios_M0203Ee(struct nouveau_bios *bios, int idx, u8 *ver, u8 *hdr) | ||
| 74 | { | ||
| 75 | u8 cnt, len; | ||
| 76 | u32 data = nvbios_M0203Te(bios, ver, hdr, &cnt, &len); | ||
| 77 | if (data && idx < cnt) { | ||
| 78 | data = data + *hdr + idx * len; | ||
| 79 | *hdr = len; | ||
| 80 | return data; | ||
| 81 | } | ||
| 82 | return 0x00000000; | ||
| 83 | } | ||
| 84 | |||
| 85 | u32 | ||
| 86 | nvbios_M0203Ep(struct nouveau_bios *bios, int idx, u8 *ver, u8 *hdr, | ||
| 87 | struct nvbios_M0203E *info) | ||
| 88 | { | ||
| 89 | u32 data = nvbios_M0203Ee(bios, idx, ver, hdr); | ||
| 90 | memset(info, 0x00, sizeof(*info)); | ||
| 91 | switch (!!data * *ver) { | ||
| 92 | case 0x10: | ||
| 93 | info->type = (nv_ro08(bios, data + 0x00) & 0x0f) >> 0; | ||
| 94 | info->strap = (nv_ro08(bios, data + 0x00) & 0xf0) >> 4; | ||
| 95 | info->group = (nv_ro08(bios, data + 0x01) & 0x0f) >> 0; | ||
| 96 | return data; | ||
| 97 | default: | ||
| 98 | break; | ||
| 99 | } | ||
| 100 | return 0x00000000; | ||
| 101 | } | ||
| 102 | |||
| 103 | u32 | ||
| 104 | nvbios_M0203Em(struct nouveau_bios *bios, u8 ramcfg, u8 *ver, u8 *hdr, | ||
| 105 | struct nvbios_M0203E *info) | ||
| 106 | { | ||
| 107 | struct nvbios_M0203T M0203T; | ||
| 108 | u8 cnt, len, idx = 0xff; | ||
| 109 | u32 data; | ||
| 110 | |||
| 111 | if (!nvbios_M0203Tp(bios, ver, hdr, &cnt, &len, &M0203T)) { | ||
| 112 | nv_warn(bios, "M0203T not found\n"); | ||
| 113 | return 0x00000000; | ||
| 114 | } | ||
| 115 | |||
| 116 | while ((data = nvbios_M0203Ep(bios, ++idx, ver, hdr, info))) { | ||
| 117 | switch (M0203T.type) { | ||
| 118 | case M0203T_TYPE_RAMCFG: | ||
| 119 | if (info->strap != ramcfg) | ||
| 120 | continue; | ||
| 121 | return data; | ||
| 122 | default: | ||
| 123 | nv_warn(bios, "M0203T type %02x\n", M0203T.type); | ||
| 124 | return 0x00000000; | ||
| 125 | } | ||
| 126 | } | ||
| 127 | |||
| 128 | return data; | ||
| 129 | } | ||
