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

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/nouveau/nvkm/subdev/therm/gf119.c
Extension
.c
Size
4579 bytes
Lines
155
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 (gpio & 0x0000001f) {
		case 0x00: return 2;
		case 0x19: return 1;
		case 0x1c: return 0;
		case 0x1e: return 2;
		default:
			break;
		}
		break;
	default:
		break;
	}

	nvkm_error(subdev, "GPIO %d unknown PWM: %08x\n", line, gpio);
	return -ENODEV;
}

int
gf119_fan_pwm_ctrl(struct nvkm_therm *therm, int line, bool enable)
{
	struct nvkm_device *device = therm->subdev.device;
	u32 data = enable ? 0x00000040 : 0x00000000;
	int indx = pwm_info(therm, line);
	if (indx < 0)
		return indx;
	else if (indx < 2)
		nvkm_mask(device, 0x00d610 + (line * 0x04), 0x000000c0, data);
	/* nothing to do for indx == 2, it seems hardwired to PTHERM */
	return 0;
}

int
gf119_fan_pwm_get(struct nvkm_therm *therm, int line, u32 *divs, u32 *duty)
{
	struct nvkm_device *device = therm->subdev.device;
	int indx = pwm_info(therm, line);
	if (indx < 0)
		return indx;
	else if (indx < 2) {
		if (nvkm_rd32(device, 0x00d610 + (line * 0x04)) & 0x00000040) {
			*divs = nvkm_rd32(device, 0x00e114 + (indx * 8));
			*duty = nvkm_rd32(device, 0x00e118 + (indx * 8));
			return 0;
		}
	} else if (indx == 2) {
		*divs = nvkm_rd32(device, 0x0200d8) & 0x1fff;
		*duty = nvkm_rd32(device, 0x0200dc) & 0x1fff;
		return 0;
	}

	return -EINVAL;
}

int
gf119_fan_pwm_set(struct nvkm_therm *therm, int line, u32 divs, u32 duty)
{
	struct nvkm_device *device = therm->subdev.device;
	int indx = pwm_info(therm, line);
	if (indx < 0)
		return indx;
	else if (indx < 2) {
		nvkm_wr32(device, 0x00e114 + (indx * 8), divs);
		nvkm_wr32(device, 0x00e118 + (indx * 8), duty | 0x80000000);
	} else if (indx == 2) {
		nvkm_mask(device, 0x0200d8, 0x1fff, divs); /* keep the high bits */
		nvkm_wr32(device, 0x0200dc, duty | 0x40000000);
	}
	return 0;
}

int
gf119_fan_pwm_clock(struct nvkm_therm *therm, int line)
{
	struct nvkm_device *device = therm->subdev.device;
	int indx = pwm_info(therm, line);
	if (indx < 0)
		return 0;
	else if (indx < 2)
		return (device->crystal * 1000) / 20;
	else
		return device->crystal * 1000 / 10;
}

void
gf119_therm_init(struct nvkm_therm *therm)
{
	struct nvkm_device *device = therm->subdev.device;

	g84_sensor_setup(therm);

Annotation

Implementation Notes