Skip to content

Commit

Permalink
drm/nv40/therm: improve selection between the old and the new style
Browse files Browse the repository at this point in the history
The condition to select between the old and new style was a thinko
as rnndb orders chipsets based on their release date (or general
chronologie hw-wise) and not based on their chipset number.

As the nv40 family is a mess when it comes to numbers, this patch
introduces a switch-based selection between the old and new style.

Signed-off-by: Martin Peres <martin.peres@labri.fr>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
  • Loading branch information
Martin Peres authored and Ben Skeggs committed Mar 18, 2013
1 parent c1b90df commit 7ae9712
Showing 1 changed file with 38 additions and 12 deletions.
50 changes: 38 additions & 12 deletions drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,42 +29,68 @@ struct nv40_therm_priv {
struct nouveau_therm_priv base;
};

enum nv40_sensor_style { INVALID_STYLE = -1, OLD_STYLE = 0, NEW_STYLE = 1 };

static enum nv40_sensor_style
nv40_sensor_style(struct nouveau_therm *therm)
{
struct nouveau_device *device = nv_device(therm);

switch (device->chipset) {
case 0x43:
case 0x44:
case 0x4a:
case 0x47:
return OLD_STYLE;

case 0x46:
case 0x49:
case 0x4b:
case 0x4e:
case 0x4c:
case 0x67:
case 0x68:
case 0x63:
return NEW_STYLE;
default:
return INVALID_STYLE;
}
}

static int
nv40_sensor_setup(struct nouveau_therm *therm)
{
struct nouveau_device *device = nv_device(therm);
enum nv40_sensor_style style = nv40_sensor_style(therm);

/* enable ADC readout and disable the ALARM threshold */
if (device->chipset >= 0x46) {
if (style == NEW_STYLE) {
nv_mask(therm, 0x15b8, 0x80000000, 0);
nv_wr32(therm, 0x15b0, 0x80003fff);
mdelay(10); /* wait for the temperature to stabilize */
return nv_rd32(therm, 0x15b4) & 0x3fff;
} else {
} else if (style == OLD_STYLE) {
nv_wr32(therm, 0x15b0, 0xff);
return nv_rd32(therm, 0x15b4) & 0xff;
}
} else
return -ENODEV;
}

static int
nv40_temp_get(struct nouveau_therm *therm)
{
struct nouveau_therm_priv *priv = (void *)therm;
struct nouveau_device *device = nv_device(therm);
struct nvbios_therm_sensor *sensor = &priv->bios_sensor;
enum nv40_sensor_style style = nv40_sensor_style(therm);
int core_temp;

if (device->chipset >= 0x46) {
if (style == NEW_STYLE) {
nv_wr32(therm, 0x15b0, 0x80003fff);
core_temp = nv_rd32(therm, 0x15b4) & 0x3fff;
} else {
} else if (style == OLD_STYLE) {
nv_wr32(therm, 0x15b0, 0xff);
core_temp = nv_rd32(therm, 0x15b4) & 0xff;
}

/* Setup the sensor if the temperature is 0 */
if (core_temp == 0)
core_temp = nv40_sensor_setup(therm);
} else
return -ENODEV;

if (sensor->slope_div == 0)
sensor->slope_div = 1;
Expand Down

0 comments on commit 7ae9712

Please sign in to comment.