static void
nouveau_therm_update(struct nouveau_therm *therm, int mode)
{
	struct nouveau_timer *ptimer = nouveau_timer(therm);
	struct nouveau_therm_priv *priv = (void *)therm;
	unsigned long flags;
	bool immd = true;
	bool poll = true;
	int duty = -1;

	spin_lock_irqsave(&priv->lock, flags);
	if (mode < 0)
		mode = priv->mode;
	priv->mode = mode;

	switch (mode) {
	case NOUVEAU_THERM_CTRL_MANUAL:
		ptimer->alarm_cancel(ptimer, &priv->alarm);
		duty = nouveau_therm_fan_get(therm);
		if (duty < 0)
			duty = 100;
		poll = false;
		break;
	case NOUVEAU_THERM_CTRL_AUTO:
		switch(priv->fan->bios.fan_mode) {
		case NVBIOS_THERM_FAN_TRIP:
			duty = nouveau_therm_update_trip(therm);
			break;
		case NVBIOS_THERM_FAN_LINEAR:
			duty = nouveau_therm_update_linear(therm);
			break;
		case NVBIOS_THERM_FAN_OTHER:
			if (priv->cstate)
				duty = priv->cstate;
			poll = false;
			break;
		}
		immd = false;
		break;
	case NOUVEAU_THERM_CTRL_NONE:
	default:
		ptimer->alarm_cancel(ptimer, &priv->alarm);
		poll = false;
	}

	if (list_empty(&priv->alarm.head) && poll)
		ptimer->alarm(ptimer, 1000000000ULL, &priv->alarm);
	spin_unlock_irqrestore(&priv->lock, flags);

	if (duty >= 0) {
		nv_debug(therm, "FAN target request: %d%%\n", duty);
		nouveau_therm_fan_set(therm, immd, duty);
	}
}
예제 #2
0
static void
nouveau_therm_update(struct nouveau_therm *therm, int mode)
{
    struct nouveau_timer *ptimer = nouveau_timer(therm);
    struct nouveau_therm_priv *priv = (void *)therm;
    unsigned long flags;
    int duty;

    spin_lock_irqsave(&priv->lock, flags);
    nv_debug(therm, "FAN speed check\n");
    if (mode < 0)
        mode = priv->mode;
    priv->mode = mode;

    switch (mode) {
    case NOUVEAU_THERM_CTRL_MANUAL:
        ptimer->alarm_cancel(ptimer, &priv->alarm);
        duty = nouveau_therm_fan_get(therm);
        if (duty < 0)
            duty = 100;
        break;
    case NOUVEAU_THERM_CTRL_AUTO:
        if (priv->fan->bios.nr_fan_trip)
            duty = nouveau_therm_update_trip(therm);
        else
            duty = nouveau_therm_update_linear(therm);
        break;
    case NOUVEAU_THERM_CTRL_NONE:
    default:
        ptimer->alarm_cancel(ptimer, &priv->alarm);
        goto done;
    }

    nv_debug(therm, "FAN target request: %d%%\n", duty);
    nouveau_therm_fan_set(therm, (mode != NOUVEAU_THERM_CTRL_AUTO), duty);

done:
    if (list_empty(&priv->alarm.head) && (mode == NOUVEAU_THERM_CTRL_AUTO))
        ptimer->alarm(ptimer, 1000000000ULL, &priv->alarm);
    else if (!list_empty(&priv->alarm.head))
        nv_debug(therm, "therm fan alarm list is not empty\n");
    spin_unlock_irqrestore(&priv->lock, flags);
}