drm/nouveau/therm: use the EXTDEV table to detect i2c monitoring devices
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / drm / nouveau / nouveau_temp.c
1 /*
2  * Copyright 2010 PathScale inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * Authors: Martin Peres
23  */
24
25 #include <linux/module.h>
26
27 #include "drmP.h"
28
29 #include "nouveau_drm.h"
30 #include "nouveau_pm.h"
31
32 #include <subdev/i2c.h>
33 #include <subdev/bios/therm.h>
34 #include <subdev/bios/extdev.h>
35
36 static int
37 nv40_sensor_setup(struct drm_device *dev)
38 {
39         struct nouveau_device *device = nouveau_dev(dev);
40         struct nouveau_drm *drm = nouveau_drm(dev);
41
42         /* enable ADC readout and disable the ALARM threshold */
43         if (nv_device(drm->device)->chipset >= 0x46) {
44                 nv_mask(device, 0x15b8, 0x80000000, 0);
45                 nv_wr32(device, 0x15b0, 0x80003fff);
46                 return nv_rd32(device, 0x15b4) & 0x3fff;
47         } else {
48                 nv_wr32(device, 0x15b0, 0xff);
49                 return nv_rd32(device, 0x15b4) & 0xff;
50         }
51 }
52
53 int
54 nv40_temp_get(struct drm_device *dev)
55 {
56         struct nouveau_device *device = nouveau_dev(dev);
57         struct nouveau_drm *drm = nouveau_drm(dev);
58         struct nouveau_pm *pm = nouveau_pm(dev);
59         struct nouveau_pm_temp_sensor_constants *sensor = &pm->sensor_constants;
60         int core_temp;
61
62         if (nv_device(drm->device)->chipset >= 0x46) {
63                 nv_wr32(device, 0x15b0, 0x80003fff);
64                 core_temp = nv_rd32(device, 0x15b4) & 0x3fff;
65         } else {
66                 nv_wr32(device, 0x15b0, 0xff);
67                 core_temp = nv_rd32(device, 0x15b4) & 0xff;
68         }
69
70         /* Setup the sensor if the temperature is 0 */
71         if (core_temp == 0)
72                 core_temp = nv40_sensor_setup(dev);
73
74         if (sensor->slope_div == 0)
75                 sensor->slope_div = 1;
76         if (sensor->offset_div == 0)
77                 sensor->offset_div = 1;
78         if (sensor->slope_mult < 1)
79                 sensor->slope_mult = 1;
80
81         core_temp = core_temp * sensor->slope_mult / sensor->slope_div;
82         core_temp = core_temp + sensor->offset_mult / sensor->offset_div;
83         core_temp = core_temp + sensor->offset_constant - 8;
84
85         return core_temp;
86 }
87
88 int
89 nv84_temp_get(struct drm_device *dev)
90 {
91         struct nouveau_device *device = nouveau_dev(dev);
92         return nv_rd32(device, 0x20400);
93 }
94
95 void
96 nouveau_temp_safety_checks(struct drm_device *dev)
97 {
98         struct nouveau_pm *pm = nouveau_pm(dev);
99         struct nouveau_pm_threshold_temp *temps = &pm->threshold_temp;
100
101         if (temps->critical > 120)
102                 temps->critical = 120;
103         else if (temps->critical < 80)
104                 temps->critical = 80;
105
106         if (temps->down_clock > 110)
107                 temps->down_clock = 110;
108         else if (temps->down_clock < 60)
109                 temps->down_clock = 60;
110 }
111
112 static bool
113 probe_monitoring_device(struct nouveau_i2c_port *i2c,
114                         struct i2c_board_info *info)
115 {
116         struct i2c_client *client;
117
118         request_module("%s%s", I2C_MODULE_PREFIX, info->type);
119
120         client = i2c_new_device(&i2c->adapter, info);
121         if (!client)
122                 return false;
123
124         if (!client->driver || client->driver->detect(client, info)) {
125                 i2c_unregister_device(client);
126                 return false;
127         }
128
129         return true;
130 }
131
132 static void
133 nouveau_temp_probe_i2c(struct drm_device *dev)
134 {
135         struct nouveau_device *device = nouveau_dev(dev);
136         struct nouveau_bios *bios = nouveau_bios(device);
137         struct nouveau_i2c *i2c = nouveau_i2c(device);
138         struct nvbios_extdev_func extdev_entry;
139         struct i2c_board_info info[] = {
140                 { I2C_BOARD_INFO("w83l785ts", 0x2d) },
141                 { I2C_BOARD_INFO("w83781d", 0x2d) },
142                 { I2C_BOARD_INFO("adt7473", 0x2e) },
143                 { I2C_BOARD_INFO("adt7473", 0x2d) },
144                 { I2C_BOARD_INFO("adt7473", 0x2c) },
145                 { I2C_BOARD_INFO("f75375", 0x2e) },
146                 { I2C_BOARD_INFO("lm99", 0x4c) },
147                 { I2C_BOARD_INFO("lm90", 0x4c) },
148                 { I2C_BOARD_INFO("lm90", 0x4d) },
149                 { I2C_BOARD_INFO("adm1021", 0x18) },
150                 { I2C_BOARD_INFO("adm1021", 0x19) },
151                 { I2C_BOARD_INFO("adm1021", 0x1a) },
152                 { I2C_BOARD_INFO("adm1021", 0x29) },
153                 { I2C_BOARD_INFO("adm1021", 0x2a) },
154                 { I2C_BOARD_INFO("adm1021", 0x2b) },
155                 { I2C_BOARD_INFO("adm1021", 0x4c) },
156                 { I2C_BOARD_INFO("adm1021", 0x4d) },
157                 { I2C_BOARD_INFO("adm1021", 0x4e) },
158                 { I2C_BOARD_INFO("lm63", 0x18) },
159                 { I2C_BOARD_INFO("lm63", 0x4e) },
160                 { }
161         };
162
163         if (!nvbios_extdev_find(bios, NVBIOS_EXTDEV_LM89, &extdev_entry)) {
164                 struct i2c_board_info board[] = {
165                         { I2C_BOARD_INFO("lm90", extdev_entry.addr >> 1) },
166                         { }
167                 };
168
169                 if (i2c->identify(i2c, NV_I2C_DEFAULT(0), "monitoring device",
170                                   board, probe_monitoring_device))
171                         return;
172         }
173
174         if (!nvbios_extdev_find(bios, NVBIOS_EXTDEV_ADT7473, &extdev_entry)) {
175                 struct i2c_board_info board[] = {
176                         { I2C_BOARD_INFO("adt7473", extdev_entry.addr >> 1) },
177                         { }
178                 };
179
180                 if (i2c->identify(i2c, NV_I2C_DEFAULT(0), "monitoring device",
181                                   board, probe_monitoring_device))
182                         return;
183         }
184
185         /* The vbios doesn't provide the address of an exisiting monitoring
186            device. Let's try our static list.
187          */
188         i2c->identify(i2c, NV_I2C_DEFAULT(0), "monitoring device", info,
189                       probe_monitoring_device);
190 }
191
192 void
193 nouveau_temp_init(struct drm_device *dev)
194 {
195         struct nouveau_drm *drm = nouveau_drm(dev);
196         struct nouveau_device *device = nv_device(drm->device);
197         struct nouveau_bios *bios = nouveau_bios(device);
198         struct nouveau_pm *pm = nouveau_pm(dev);
199         struct nouveau_pm_temp_sensor_constants *sensor = &pm->sensor_constants;
200         struct nouveau_pm_threshold_temp *temps = &pm->threshold_temp;
201         struct nvbios_therm_sensor bios_sensor;
202         struct nvbios_therm_fan bios_fan;
203
204         /* store some safe defaults */
205         sensor->offset_constant = 0;
206         sensor->offset_mult = 0;
207         sensor->offset_div = 1;
208         sensor->slope_mult = 1;
209         sensor->slope_div = 1;
210
211         if (!nvbios_therm_sensor_parse(bios, NVBIOS_THERM_DOMAIN_CORE,
212                                        &bios_sensor)) {
213                 sensor->slope_mult = bios_sensor.slope_mult;
214                 sensor->slope_div = bios_sensor.slope_div;
215                 sensor->offset_mult = bios_sensor.offset_num;
216                 sensor->offset_div = bios_sensor.offset_den;
217                 sensor->offset_constant = bios_sensor.offset_constant;
218
219                 temps->down_clock = bios_sensor.thrs_down_clock.temp;
220                 temps->critical = bios_sensor.thrs_critical.temp;
221         }
222
223         if (nvbios_therm_fan_parse(bios, &bios_fan)) {
224                 pm->fan.min_duty = bios_fan.min_duty;
225                 pm->fan.max_duty = bios_fan.max_duty;
226                 pm->fan.pwm_freq = bios_fan.pwm_freq;
227         }
228
229         nouveau_temp_safety_checks(dev);
230         nouveau_temp_probe_i2c(dev);
231 }
232
233 void
234 nouveau_temp_fini(struct drm_device *dev)
235 {
236
237 }