diff options
author | André Fabian Silva Delgado <emulatorman@parabola.nu> | 2016-06-10 05:30:17 -0300 |
---|---|---|
committer | André Fabian Silva Delgado <emulatorman@parabola.nu> | 2016-06-10 05:30:17 -0300 |
commit | d635711daa98be86d4c7fd01499c34f566b54ccb (patch) | |
tree | aa5cc3760a27c3d57146498cb82fa549547de06c /drivers/gpu/drm/nouveau/nvkm/subdev/bios | |
parent | c91265cd0efb83778f015b4d4b1129bd2cfd075e (diff) |
Linux-libre 4.6.2-gnu
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/subdev/bios')
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/bios/Kbuild | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/bios/extdev.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/bios/iccsense.c | 100 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c | 13 |
4 files changed, 109 insertions, 7 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/Kbuild index 64730d5e9..dbcb0ef21 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/Kbuild @@ -10,6 +10,7 @@ nvkm-y += nvkm/subdev/bios/extdev.o nvkm-y += nvkm/subdev/bios/fan.o nvkm-y += nvkm/subdev/bios/gpio.o nvkm-y += nvkm/subdev/bios/i2c.o +nvkm-y += nvkm/subdev/bios/iccsense.o nvkm-y += nvkm/subdev/bios/image.o nvkm-y += nvkm/subdev/bios/init.o nvkm-y += nvkm/subdev/bios/mxm.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/extdev.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/extdev.c index c9e6f6ff7..b8578359e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/extdev.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/extdev.c @@ -32,7 +32,7 @@ extdev_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *len, u8 *cnt) u16 dcb, extdev = 0; dcb = dcb_table(bios, &dcb_ver, &dcb_hdr, &dcb_cnt, &dcb_len); - if (!dcb || (dcb_ver != 0x30 && dcb_ver != 0x40)) + if (!dcb || (dcb_ver != 0x30 && dcb_ver != 0x40 && dcb_ver != 0x41)) return 0x0000; extdev = nvbios_rd16(bios, dcb + 18); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/iccsense.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/iccsense.c new file mode 100644 index 000000000..084328028 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/iccsense.c @@ -0,0 +1,100 @@ +/* + * Copyright 2015 Martin Peres + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Martin Peres + */ +#include <subdev/bios.h> +#include <subdev/bios/bit.h> +#include <subdev/bios/iccsense.h> + +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; +} + +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; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c index a7d69ce7a..38ed09fd3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c @@ -786,20 +786,20 @@ init_io_flag_condition(struct nvbios_init *init) } /** - * INIT_DP_CONDITION - opcode 0x3a + * INIT_GENERIC_CONDITION - opcode 0x3a * */ static void -init_dp_condition(struct nvbios_init *init) +init_generic_condition(struct nvbios_init *init) { struct nvkm_bios *bios = init->bios; struct nvbios_dpout info; u8 cond = nvbios_rd08(bios, init->offset + 1); - u8 unkn = nvbios_rd08(bios, init->offset + 2); + u8 size = nvbios_rd08(bios, init->offset + 2); u8 ver, hdr, cnt, len; u16 data; - trace("DP_CONDITION\t0x%02x 0x%02x\n", cond, unkn); + trace("GENERIC_CONDITION\t0x%02x 0x%02x\n", cond, size); init->offset += 3; switch (cond) { @@ -828,7 +828,8 @@ init_dp_condition(struct nvbios_init *init) init_exec_set(init, false); break; default: - warn("unknown dp condition 0x%02x\n", cond); + warn("INIT_GENERIC_CONDITON: unknown 0x%02x\n", cond); + init->offset += size; break; } } @@ -2205,7 +2206,7 @@ static struct nvbios_init_opcode { [0x37] = { init_copy }, [0x38] = { init_not }, [0x39] = { init_io_flag_condition }, - [0x3a] = { init_dp_condition }, + [0x3a] = { init_generic_condition }, [0x3b] = { init_io_mask_or }, [0x3c] = { init_io_or }, [0x47] = { init_andn_reg }, |