drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c
Extension
.c
Size
12168 bytes
Lines
456
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

switch(therm->fan->bios.fan_mode) {
		case NVBIOS_THERM_FAN_TRIP:
			duty = nvkm_therm_update_trip(therm);
			break;
		case NVBIOS_THERM_FAN_LINEAR:
			duty = nvkm_therm_update_linear(therm);
			break;
		case NVBIOS_THERM_FAN_OTHER:
			if (therm->cstate) {
				duty = therm->cstate;
				poll = false;
			} else {
				duty = nvkm_therm_update_linear_fallback(therm);
			}
			break;
		}
		immd = false;
		break;
	case NVKM_THERM_CTRL_NONE:
	default:
		nvkm_timer_alarm(tmr, 0, &therm->alarm);
		poll = false;
	}

	if (poll)
		nvkm_timer_alarm(tmr, 1000000000ULL, &therm->alarm);
	spin_unlock_irqrestore(&therm->lock, flags);

	if (duty >= 0) {
		nvkm_debug(subdev, "FAN target request: %d%%\n", duty);
		nvkm_therm_fan_set(therm, immd, duty);
	}
}

int
nvkm_therm_cstate(struct nvkm_therm *therm, int fan, int dir)
{
	struct nvkm_subdev *subdev = &therm->subdev;
	if (!dir || (dir < 0 && fan < therm->cstate) ||
		    (dir > 0 && fan > therm->cstate)) {
		nvkm_debug(subdev, "default fan speed -> %d%%\n", fan);
		therm->cstate = fan;
		nvkm_therm_update(therm, -1);
	}
	return 0;
}

static void
nvkm_therm_alarm(struct nvkm_alarm *alarm)
{
	struct nvkm_therm *therm =
	       container_of(alarm, struct nvkm_therm, alarm);
	nvkm_therm_update(therm, -1);
}

int
nvkm_therm_fan_mode(struct nvkm_therm *therm, int mode)
{
	struct nvkm_subdev *subdev = &therm->subdev;
	struct nvkm_device *device = subdev->device;
	static const char *name[] = {
		"disabled",
		"manual",
		"automatic"
	};

	/* The default PPWR ucode on fermi interferes with fan management */
	if ((mode >= ARRAY_SIZE(name)) ||
	    (mode != NVKM_THERM_CTRL_NONE && nvkm_pmu_fan_controlled(device)))
		return -EINVAL;

	/* do not allow automatic fan management if the thermal sensor is
	 * not available */
	if (mode == NVKM_THERM_CTRL_AUTO &&
	    therm->func->temp_get(therm) < 0)
		return -EINVAL;

	if (therm->mode == mode)
		return 0;

	nvkm_debug(subdev, "fan management: %s\n", name[mode]);
	nvkm_therm_update(therm, mode);
	return 0;
}

int
nvkm_therm_attr_get(struct nvkm_therm *therm, enum nvkm_therm_attr_type type)
{
	switch (type) {
	case NVKM_THERM_ATTR_FAN_MIN_DUTY:

Annotation

Implementation Notes