On 25 October 2016 7:25:46 a.m. GMT+02:00, Martin Peres <martin.pe...@free.fr> wrote: >On 25/10/16 00:11, Karol Herbst wrote: >> Signed-off-by: Karol Herbst <karolher...@gmail.com> >> --- >> .../include/nvkm/subdev/bios/power_budget.h | 20 ++++ >> drm/nouveau/nvkm/subdev/bios/Kbuild | 1 + >> drm/nouveau/nvkm/subdev/bios/power_budget.c | 108 >+++++++++++++++++++++ >> 3 files changed, 129 insertions(+) >> create mode 100644 >drm/nouveau/include/nvkm/subdev/bios/power_budget.h >> create mode 100644 drm/nouveau/nvkm/subdev/bios/power_budget.c >> >> diff --git a/drm/nouveau/include/nvkm/subdev/bios/power_budget.h >b/drm/nouveau/include/nvkm/subdev/bios/power_budget.h >> new file mode 100644 >> index 0000000..dd65c08 >> --- /dev/null >> +++ b/drm/nouveau/include/nvkm/subdev/bios/power_budget.h >> @@ -0,0 +1,20 @@ >> +#ifndef __NVBIOS_POWER_BUDGET_H__ >> +#define __NVBIOS_POWER_BUDGET_H__ >> + >> +#include <nvkm/subdev/bios.h> >> + >> +struct nvbios_power_budget_entry { >> + u32 min_w; >> + u32 avg_w; >> + u32 max_w; >> +}; >> + >> +struct nvbios_power_budget { >> + u8 nr_entry; >> + u8 cap_entry; >> + struct nvbios_power_budget_entry *entries; >> +}; >> + >> +int nvbios_power_budget_parse(struct nvkm_bios *, struct >nvbios_power_budget *); >> + >> +#endif >> diff --git a/drm/nouveau/nvkm/subdev/bios/Kbuild >b/drm/nouveau/nvkm/subdev/bios/Kbuild >> index be57220..6b4f1e0 100644 >> --- a/drm/nouveau/nvkm/subdev/bios/Kbuild >> +++ b/drm/nouveau/nvkm/subdev/bios/Kbuild >> @@ -19,6 +19,7 @@ nvkm-y += nvkm/subdev/bios/pcir.o >> nvkm-y += nvkm/subdev/bios/perf.o >> nvkm-y += nvkm/subdev/bios/pll.o >> nvkm-y += nvkm/subdev/bios/pmu.o >> +nvkm-y += nvkm/subdev/bios/power_budget.o >> nvkm-y += nvkm/subdev/bios/ramcfg.o >> nvkm-y += nvkm/subdev/bios/rammap.o >> nvkm-y += nvkm/subdev/bios/shadow.o >> diff --git a/drm/nouveau/nvkm/subdev/bios/power_budget.c >b/drm/nouveau/nvkm/subdev/bios/power_budget.c >> new file mode 100644 >> index 0000000..538497b >> --- /dev/null >> +++ b/drm/nouveau/nvkm/subdev/bios/power_budget.c >> @@ -0,0 +1,108 @@ >> +/* >> + * Copyright 2015 Karol Herbst >> + * >> + * 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: Karol Herbst >> + */ >> +#include <subdev/bios.h> >> +#include <subdev/bios/bit.h> >> +#include <subdev/bios/power_budget.h> >> + >> +static u32 >> +nvbios_power_budget_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, >u8 *cnt, >> + u8 *len) >> +{ >> + struct bit_entry bit_P; >> + u32 power_budget; >> + >> + if (bit_entry(bios, 'P', &bit_P) || bit_P.version != 2 || >> + bit_P.length < 0x2c) >> + return 0; >> + >> + power_budget = nvbios_rd32(bios, bit_P.offset + 0x2c); >> + if (!power_budget) >> + return 0; >> + >> + *ver = nvbios_rd08(bios, power_budget); >> + switch (*ver) { >> + case 0x10: >> + case 0x20: >> + case 0x30: >> + *hdr = nvbios_rd08(bios, power_budget + 0x1); >> + *len = nvbios_rd08(bios, power_budget + 0x2); >> + *cnt = nvbios_rd08(bios, power_budget + 0x3); >> + return power_budget; >> + default: >> + break; >> + } >> + >> + return 0; >> +} >> + >> +int >> +nvbios_power_budget_parse(struct nvkm_bios *bios, struct >nvbios_power_budget *budget) >> +{ >> + struct nvkm_subdev *subdev = &bios->subdev; >> + u8 ver, hdr, cnt, len, i, cap_entry; >> + u32 header; >> + >> + header = nvbios_power_budget_table(bios, &ver, &hdr, &cnt, &len); >> + if (!header || !cnt) >> + return -ENODEV; >> + >> + budget->entries = kmalloc_array(cnt, sizeof(*budget->entries), >GFP_KERNEL); >> + if (!budget->entries) >> + return -ENOMEM; >> + >> + budget->nr_entry = cnt; >> + switch (ver) { >> + case 0x20: >> + cap_entry = nvbios_rd08(bios, header + 0x9); >> + break; >> + default: >> + cap_entry = 0; > >Are you sure about this? How about setting it to 0xff instead? >
right, has to be 0xff >> + } >> + >> + if (cap_entry < cnt) >> + budget->cap_entry = cap_entry; >> + else { >> + if (cap_entry != 0xff) >> + nvkm_warn(subdev, >> + "invalid cap_entry in power budget table >> found\n"); >> + budget->cap_entry = 0xff; >> + } >> + >> + for (i = 0; i < cnt; ++i) { >> + u32 entry_offset = header + hdr + i * len; >> + struct nvbios_power_budget_entry *entry = &budget->entries[i]; >> + >> + if (len >= 0xe) { >> + entry->min_w = nvbios_rd32(bios, entry_offset + 0x2); >> + entry->avg_w = nvbios_rd32(bios, entry_offset + 0x6); >> + entry->max_w = nvbios_rd32(bios, entry_offset + 0xa); >> + } else { >> + entry->min_w = 0; >> + entry->max_w = nvbios_rd32(bios, entry_offset + 0x2); >> + entry->avg_w = entry->max_w; >> + } >> + } >> + >> + return 0; >> +} >> _______________________________________________ Nouveau mailing list Nouveau@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/nouveau