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 static int
0027 pwm_info(struct nvkm_therm *therm, int line)
0028 {
0029 struct nvkm_subdev *subdev = &therm->subdev;
0030 struct nvkm_device *device = subdev->device;
0031 u32 gpio = nvkm_rd32(device, 0x00d610 + (line * 0x04));
0032
0033 switch (gpio & 0x000000c0) {
0034 case 0x00000000:
0035 case 0x00000040:
0036 switch (gpio & 0x0000001f) {
0037 case 0x00: return 2;
0038 case 0x19: return 1;
0039 case 0x1c: return 0;
0040 case 0x1e: return 2;
0041 default:
0042 break;
0043 }
0044 break;
0045 default:
0046 break;
0047 }
0048
0049 nvkm_error(subdev, "GPIO %d unknown PWM: %08x\n", line, gpio);
0050 return -ENODEV;
0051 }
0052
0053 int
0054 gf119_fan_pwm_ctrl(struct nvkm_therm *therm, int line, bool enable)
0055 {
0056 struct nvkm_device *device = therm->subdev.device;
0057 u32 data = enable ? 0x00000040 : 0x00000000;
0058 int indx = pwm_info(therm, line);
0059 if (indx < 0)
0060 return indx;
0061 else if (indx < 2)
0062 nvkm_mask(device, 0x00d610 + (line * 0x04), 0x000000c0, data);
0063
0064 return 0;
0065 }
0066
0067 int
0068 gf119_fan_pwm_get(struct nvkm_therm *therm, int line, u32 *divs, u32 *duty)
0069 {
0070 struct nvkm_device *device = therm->subdev.device;
0071 int indx = pwm_info(therm, line);
0072 if (indx < 0)
0073 return indx;
0074 else if (indx < 2) {
0075 if (nvkm_rd32(device, 0x00d610 + (line * 0x04)) & 0x00000040) {
0076 *divs = nvkm_rd32(device, 0x00e114 + (indx * 8));
0077 *duty = nvkm_rd32(device, 0x00e118 + (indx * 8));
0078 return 0;
0079 }
0080 } else if (indx == 2) {
0081 *divs = nvkm_rd32(device, 0x0200d8) & 0x1fff;
0082 *duty = nvkm_rd32(device, 0x0200dc) & 0x1fff;
0083 return 0;
0084 }
0085
0086 return -EINVAL;
0087 }
0088
0089 int
0090 gf119_fan_pwm_set(struct nvkm_therm *therm, int line, u32 divs, u32 duty)
0091 {
0092 struct nvkm_device *device = therm->subdev.device;
0093 int indx = pwm_info(therm, line);
0094 if (indx < 0)
0095 return indx;
0096 else if (indx < 2) {
0097 nvkm_wr32(device, 0x00e114 + (indx * 8), divs);
0098 nvkm_wr32(device, 0x00e118 + (indx * 8), duty | 0x80000000);
0099 } else if (indx == 2) {
0100 nvkm_mask(device, 0x0200d8, 0x1fff, divs);
0101 nvkm_wr32(device, 0x0200dc, duty | 0x40000000);
0102 }
0103 return 0;
0104 }
0105
0106 int
0107 gf119_fan_pwm_clock(struct nvkm_therm *therm, int line)
0108 {
0109 struct nvkm_device *device = therm->subdev.device;
0110 int indx = pwm_info(therm, line);
0111 if (indx < 0)
0112 return 0;
0113 else if (indx < 2)
0114 return (device->crystal * 1000) / 20;
0115 else
0116 return device->crystal * 1000 / 10;
0117 }
0118
0119 void
0120 gf119_therm_init(struct nvkm_therm *therm)
0121 {
0122 struct nvkm_device *device = therm->subdev.device;
0123
0124 g84_sensor_setup(therm);
0125
0126
0127 nvkm_mask(device, 0x00e720, 0x00000003, 0x00000002);
0128 if (therm->fan->tach.func != DCB_GPIO_UNUSED) {
0129 nvkm_mask(device, 0x00d79c, 0x000000ff, therm->fan->tach.line);
0130 nvkm_wr32(device, 0x00e724, device->crystal * 1000);
0131 nvkm_mask(device, 0x00e720, 0x00000001, 0x00000001);
0132 }
0133 nvkm_mask(device, 0x00e720, 0x00000002, 0x00000000);
0134 }
0135
0136 static const struct nvkm_therm_func
0137 gf119_therm = {
0138 .init = gf119_therm_init,
0139 .fini = g84_therm_fini,
0140 .pwm_ctrl = gf119_fan_pwm_ctrl,
0141 .pwm_get = gf119_fan_pwm_get,
0142 .pwm_set = gf119_fan_pwm_set,
0143 .pwm_clock = gf119_fan_pwm_clock,
0144 .temp_get = g84_temp_get,
0145 .fan_sense = gt215_therm_fan_sense,
0146 .program_alarms = nvkm_therm_program_alarms_polling,
0147 };
0148
0149 int
0150 gf119_therm_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
0151 struct nvkm_therm **ptherm)
0152 {
0153 return nvkm_therm_new_(&gf119_therm, device, type, inst, ptherm);
0154 }