Ejemplo n.º 1
0
static ssize_t
nouveau_hwmon_set_max_temp(struct device *d, struct device_attribute *a,
						const char *buf, size_t count)
{
	struct drm_device *dev = dev_get_drvdata(d);
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
	struct nouveau_pm_threshold_temp *temp = &pm->threshold_temp;
	long value;

	if (strict_strtol(buf, 10, &value) == -EINVAL)
		return count;

	temp->down_clock = value/1000;

	nouveau_temp_safety_checks(dev);

	return count;
}
Ejemplo n.º 2
0
static void
nouveau_temp_vbios_parse(struct drm_device *dev, u8 *temp)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
	struct nouveau_pm_temp_sensor_constants *sensor = &pm->sensor_constants;
	struct nouveau_pm_threshold_temp *temps = &pm->threshold_temp;
	int i, headerlen, recordlen, entries;

	if (!temp) {
		NV_DEBUG(dev, "temperature table pointer invalid\n");
		return;
	}

	/* Set the default sensor's contants */
	sensor->offset_constant = 0;
	sensor->offset_mult = 1;
	sensor->offset_div = 1;
	sensor->slope_mult = 1;
	sensor->slope_div = 1;

	/* Set the default temperature thresholds */
	temps->critical = 110;
	temps->down_clock = 100;
	temps->fan_boost = 90;

	/* Set the known default values to setup the temperature sensor */
	if (dev_priv->card_type >= NV_40) {
		switch (dev_priv->chipset) {
		case 0x43:
			sensor->offset_mult = 32060;
			sensor->offset_div = 1000;
			sensor->slope_mult = 792;
			sensor->slope_div = 1000;
			break;

		case 0x44:
		case 0x47:
		case 0x4a:
			sensor->offset_mult = 27839;
			sensor->offset_div = 1000;
			sensor->slope_mult = 780;
			sensor->slope_div = 1000;
			break;

		case 0x46:
			sensor->offset_mult = -24775;
			sensor->offset_div = 100;
			sensor->slope_mult = 467;
			sensor->slope_div = 10000;
			break;

		case 0x49:
			sensor->offset_mult = -25051;
			sensor->offset_div = 100;
			sensor->slope_mult = 458;
			sensor->slope_div = 10000;
			break;

		case 0x4b:
			sensor->offset_mult = -24088;
			sensor->offset_div = 100;
			sensor->slope_mult = 442;
			sensor->slope_div = 10000;
			break;

		case 0x50:
			sensor->offset_mult = -22749;
			sensor->offset_div = 100;
			sensor->slope_mult = 431;
			sensor->slope_div = 10000;
			break;
		}
	}

	headerlen = temp[1];
	recordlen = temp[2];
	entries = temp[3];
	temp = temp + headerlen;

	/* Read the entries from the table */
	for (i = 0; i < entries; i++) {
		u16 value = ROM16(temp[1]);

		switch (temp[0]) {
		case 0x01:
			if ((value & 0x8f) == 0)
				sensor->offset_constant = (value >> 9) & 0x7f;
			break;

		case 0x04:
			if ((value & 0xf00f) == 0xa000) /* core */
				temps->critical = (value&0x0ff0) >> 4;
			break;

		case 0x07:
			if ((value & 0xf00f) == 0xa000) /* core */
				temps->down_clock = (value&0x0ff0) >> 4;
			break;

		case 0x08:
			if ((value & 0xf00f) == 0xa000) /* core */
				temps->fan_boost = (value&0x0ff0) >> 4;
			break;

		case 0x10:
			sensor->offset_mult = value;
			break;

		case 0x11:
			sensor->offset_div = value;
			break;

		case 0x12:
			sensor->slope_mult = value;
			break;

		case 0x13:
			sensor->slope_div = value;
			break;
		case 0x22:
			pm->fan.min_duty = value & 0xff;
			pm->fan.max_duty = (value & 0xff00) >> 8;
			break;
		case 0x26:
			pm->fan.pwm_freq = value;
			break;
		}
		temp += recordlen;
	}

	nouveau_temp_safety_checks(dev);

	/* check the fan min/max settings */
	if (pm->fan.min_duty < 10)
		pm->fan.min_duty = 10;
	if (pm->fan.max_duty > 100)
		pm->fan.max_duty = 100;
	if (pm->fan.max_duty < pm->fan.min_duty)
		pm->fan.max_duty = pm->fan.min_duty;
}