drm/nouveau/bios: parse fan bump/slow periods, and trip points
authorMartin Peres <martin.peres@labri.fr>
Wed, 5 Dec 2012 08:42:00 +0000 (18:42 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Wed, 20 Feb 2013 06:00:20 +0000 (16:00 +1000)
Signed-off-by: Martin Peres <martin.peres@labri.fr>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/core/include/subdev/bios/therm.h
drivers/gpu/drm/nouveau/core/subdev/bios/therm.c

index a2c4296..083541d 100644 (file)
@@ -23,11 +23,27 @@ struct nvbios_therm_sensor {
        struct nvbios_therm_threshold thrs_shutdown;
 };
 
+/* no vbios have more than 6 */
+#define NOUVEAU_TEMP_FAN_TRIP_MAX 10
+struct nouveau_therm_trip_point {
+       int fan_duty;
+       int temp;
+       int hysteresis;
+};
+
 struct nvbios_therm_fan {
        u16 pwm_freq;
 
        u8 min_duty;
        u8 max_duty;
+
+       u16 bump_period;
+       u16 slow_down_period;
+
+       struct nouveau_therm_trip_point trip[NOUVEAU_TEMP_FAN_TRIP_MAX];
+       u8 nr_fan_trip;
+       u8 linear_min_temp;
+       u8 linear_max_temp;
 };
 
 enum nvbios_therm_domain {
index 862a08a..b7916a5 100644 (file)
@@ -155,10 +155,15 @@ int
 nvbios_therm_fan_parse(struct nouveau_bios *bios,
                          struct nvbios_therm_fan *fan)
 {
+       struct nouveau_therm_trip_point *cur_trip = NULL;
        u8 ver, len, i;
        u16 entry;
 
+       uint8_t duty_lut[] = { 0, 0, 25, 0, 40, 0, 50, 0,
+                               75, 0, 85, 0, 100, 0, 100, 0 };
+
        i = 0;
+       fan->nr_fan_trip = 0;
        while ((entry = nvbios_therm_entry(bios, i++, &ver, &len))) {
                s16 value = nv_ro16(bios, entry + 1);
 
@@ -167,9 +172,30 @@ nvbios_therm_fan_parse(struct nouveau_bios *bios,
                        fan->min_duty = value & 0xff;
                        fan->max_duty = (value & 0xff00) >> 8;
                        break;
+               case 0x24:
+                       fan->nr_fan_trip++;
+                       cur_trip = &fan->trip[fan->nr_fan_trip - 1];
+                       cur_trip->hysteresis = value & 0xf;
+                       cur_trip->temp = (value & 0xff0) >> 4;
+                       cur_trip->fan_duty = duty_lut[(value & 0xf000) >> 12];
+                       break;
+               case 0x25:
+                       cur_trip = &fan->trip[fan->nr_fan_trip - 1];
+                       cur_trip->fan_duty = value;
+                       break;
                case 0x26:
                        fan->pwm_freq = value;
                        break;
+               case 0x3b:
+                       fan->bump_period = value;
+                       break;
+               case 0x3c:
+                       fan->slow_down_period = value;
+                       break;
+               case 0x46:
+                       fan->linear_min_temp = nv_ro08(bios, entry + 1);
+                       fan->linear_max_temp = nv_ro08(bios, entry + 2);
+                       break;
                }
        }