diff options
author | Martin Peres <martin.peres@labri.fr> | 2012-08-30 02:31:59 +0200 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2012-10-03 05:13:13 +0200 |
commit | d46497dce7376e9d3e2e10c59d92e1c3b665b5dd (patch) | |
tree | 9494a77fb4b375f724676ea0ee771228c012ddec /drivers | |
parent | drm/nouveau/therm: use the EXTDEV table to detect i2c monitoring devices (diff) | |
download | linux-d46497dce7376e9d3e2e10c59d92e1c3b665b5dd.tar.xz linux-d46497dce7376e9d3e2e10c59d92e1c3b665b5dd.zip |
drm/nouveau/bios: parse the pwm divisor from the perf table
v2: perf_table now is more in line with the other functions
Signed-off-by: Martin Peres <martin.peres@labri.fr>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/nouveau/Makefile | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/include/subdev/bios/perf.h | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/bios/perf.c | 75 |
3 files changed, 90 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile index 6adf1455255c..1b05d114deea 100644 --- a/drivers/gpu/drm/nouveau/Makefile +++ b/drivers/gpu/drm/nouveau/Makefile @@ -35,6 +35,7 @@ nouveau-y += core/subdev/bios/gpio.o nouveau-y += core/subdev/bios/i2c.o nouveau-y += core/subdev/bios/init.o nouveau-y += core/subdev/bios/mxm.o +nouveau-y += core/subdev/bios/perf.o nouveau-y += core/subdev/bios/pll.o nouveau-y += core/subdev/bios/therm.o nouveau-y += core/subdev/clock/nv04.o diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/perf.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/perf.h new file mode 100644 index 000000000000..0b285e99be5a --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/perf.h @@ -0,0 +1,14 @@ +#ifndef __NVBIOS_PERF_H__ +#define __NVBIOS_PERF_H__ + +struct nouveau_bios; + +struct nvbios_perf_fan { + u32 pwm_divisor; +}; + +int +nvbios_perf_fan_parse(struct nouveau_bios *, struct nvbios_perf_fan *); + + +#endif diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/perf.c b/drivers/gpu/drm/nouveau/core/subdev/bios/perf.c new file mode 100644 index 000000000000..bcbb056c2887 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/perf.c @@ -0,0 +1,75 @@ +/* + * Copyright 2012 Nouveau Community + * + * 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/perf.h> + +static u16 +perf_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) +{ + struct bit_entry bit_P; + u16 perf = 0x0000; + + if (!bit_entry(bios, 'P', &bit_P)) { + if (bit_P.version <= 2) { + perf = nv_ro16(bios, bit_P.offset + 0); + if (perf) { + *ver = nv_ro08(bios, perf + 0); + *hdr = nv_ro08(bios, perf + 1); + } + } else + nv_error(bios, "unknown offset for perf in BIT P %d\n", + bit_P.version); + } + + if (bios->bmp_offset) { + if (nv_ro08(bios, bios->bmp_offset + 6) >= 0x25) { + perf = nv_ro16(bios, bios->bmp_offset + 0x94); + if (perf) { + *hdr = nv_ro08(bios, perf + 0); + *ver = nv_ro08(bios, perf + 1); + } + } + } + + return perf; +} + +int +nvbios_perf_fan_parse(struct nouveau_bios *bios, + struct nvbios_perf_fan *fan) +{ + u8 ver = 0, hdr = 0, cnt = 0, len = 0; + u16 perf = perf_table(bios, &ver, &hdr, &cnt, &len); + if (!perf) + return -ENODEV; + + if (ver >= 0x20 && ver < 0x40 && hdr > 6) + fan->pwm_divisor = nv_ro16(bios, perf + 6); + else + fan->pwm_divisor = 0; + + return 0; +} |