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 "priv.h"
0025
0026 #include <subdev/volt.h>
0027 #include <subdev/gpio.h>
0028 #include <subdev/bios.h>
0029 #include <subdev/bios/volt.h>
0030 #include <subdev/fuse.h>
0031
0032 #define gk104_volt(p) container_of((p), struct gk104_volt, base)
0033 struct gk104_volt {
0034 struct nvkm_volt base;
0035 struct nvbios_volt bios;
0036 };
0037
0038 static int
0039 gk104_volt_get(struct nvkm_volt *base)
0040 {
0041 struct nvbios_volt *bios = &gk104_volt(base)->bios;
0042 struct nvkm_device *device = base->subdev.device;
0043 u32 div, duty;
0044
0045 div = nvkm_rd32(device, 0x20340);
0046 duty = nvkm_rd32(device, 0x20344);
0047
0048 return bios->base + bios->pwm_range * duty / div;
0049 }
0050
0051 static int
0052 gk104_volt_set(struct nvkm_volt *base, u32 uv)
0053 {
0054 struct nvbios_volt *bios = &gk104_volt(base)->bios;
0055 struct nvkm_device *device = base->subdev.device;
0056 u32 div, duty;
0057
0058
0059 div = 27648000 / bios->pwm_freq;
0060 duty = DIV_ROUND_UP((uv - bios->base) * div, bios->pwm_range);
0061
0062 nvkm_wr32(device, 0x20340, div);
0063 nvkm_wr32(device, 0x20344, 0x80000000 | duty);
0064
0065 return 0;
0066 }
0067
0068 static int
0069 gk104_volt_speedo_read(struct nvkm_volt *volt)
0070 {
0071 struct nvkm_device *device = volt->subdev.device;
0072 struct nvkm_fuse *fuse = device->fuse;
0073 int ret;
0074
0075 if (!fuse)
0076 return -EINVAL;
0077
0078 nvkm_wr32(device, 0x122634, 0x0);
0079 ret = nvkm_fuse_read(fuse, 0x3a8);
0080 nvkm_wr32(device, 0x122634, 0x41);
0081 return ret;
0082 }
0083
0084 static const struct nvkm_volt_func
0085 gk104_volt_pwm = {
0086 .oneinit = gf100_volt_oneinit,
0087 .volt_get = gk104_volt_get,
0088 .volt_set = gk104_volt_set,
0089 .speedo_read = gk104_volt_speedo_read,
0090 }, gk104_volt_gpio = {
0091 .oneinit = gf100_volt_oneinit,
0092 .vid_get = nvkm_voltgpio_get,
0093 .vid_set = nvkm_voltgpio_set,
0094 .speedo_read = gk104_volt_speedo_read,
0095 };
0096
0097 int
0098 gk104_volt_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
0099 struct nvkm_volt **pvolt)
0100 {
0101 const struct nvkm_volt_func *volt_func = &gk104_volt_gpio;
0102 struct dcb_gpio_func gpio;
0103 struct nvbios_volt bios;
0104 struct gk104_volt *volt;
0105 u8 ver, hdr, cnt, len;
0106 const char *mode;
0107
0108 if (!nvbios_volt_parse(device->bios, &ver, &hdr, &cnt, &len, &bios))
0109 return 0;
0110
0111 if (!nvkm_gpio_find(device->gpio, 0, DCB_GPIO_VID_PWM, 0xff, &gpio) &&
0112 bios.type == NVBIOS_VOLT_PWM) {
0113 volt_func = &gk104_volt_pwm;
0114 }
0115
0116 if (!(volt = kzalloc(sizeof(*volt), GFP_KERNEL)))
0117 return -ENOMEM;
0118 nvkm_volt_ctor(volt_func, device, type, inst, &volt->base);
0119 *pvolt = &volt->base;
0120 volt->bios = bios;
0121
0122
0123
0124
0125
0126 if (bios.type == NVBIOS_VOLT_PWM && volt_func != &gk104_volt_pwm) {
0127 nvkm_error(&volt->base.subdev,
0128 "Type mismatch between the voltage table type and "
0129 "the GPIO table. Fallback to GPIO mode.\n");
0130 }
0131
0132 if (volt_func == &gk104_volt_gpio) {
0133 nvkm_voltgpio_init(&volt->base);
0134 mode = "GPIO";
0135 } else
0136 mode = "PWM";
0137
0138 nvkm_debug(&volt->base.subdev, "Using %s mode\n", mode);
0139
0140 return 0;
0141 }