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

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c
Extension
.c
Size
18306 bytes
Lines
717
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

if (subd && boostS.domain == domain) {
				if (adjust)
					input = input * boostS.percent / 100;
				input = max(boostS.min, input);
				input = min(boostS.max, input);
				break;
			}
		} while (subd);
	}

	return input;
}

/******************************************************************************
 * C-States
 *****************************************************************************/
static bool
nvkm_cstate_valid(struct nvkm_clk *clk, struct nvkm_cstate *cstate,
		  u32 max_volt, int temp)
{
	const struct nvkm_domain *domain = clk->domains;
	struct nvkm_volt *volt = clk->subdev.device->volt;
	int voltage;

	while (domain && domain->name != nv_clk_src_max) {
		if (domain->flags & NVKM_CLK_DOM_FLAG_VPSTATE) {
			u32 freq = cstate->domain[domain->name];
			switch (clk->boost_mode) {
			case NVKM_CLK_BOOST_NONE:
				if (clk->base_khz && freq > clk->base_khz)
					return false;
				fallthrough;
			case NVKM_CLK_BOOST_BIOS:
				if (clk->boost_khz && freq > clk->boost_khz)
					return false;
			}
		}
		domain++;
	}

	if (!volt)
		return true;

	voltage = nvkm_volt_map(volt, cstate->voltage, temp);
	if (voltage < 0)
		return false;
	return voltage <= min(max_volt, volt->max_uv);
}

static struct nvkm_cstate *
nvkm_cstate_find_best(struct nvkm_clk *clk, struct nvkm_pstate *pstate,
		      struct nvkm_cstate *cstate)
{
	struct nvkm_device *device = clk->subdev.device;
	struct nvkm_volt *volt = device->volt;
	int max_volt;

	if (!pstate || !cstate)
		return NULL;

	if (!volt)
		return cstate;

	max_volt = volt->max_uv;
	if (volt->max0_id != 0xff)
		max_volt = min(max_volt,
			       nvkm_volt_map(volt, volt->max0_id, clk->temp));
	if (volt->max1_id != 0xff)
		max_volt = min(max_volt,
			       nvkm_volt_map(volt, volt->max1_id, clk->temp));
	if (volt->max2_id != 0xff)
		max_volt = min(max_volt,
			       nvkm_volt_map(volt, volt->max2_id, clk->temp));

	list_for_each_entry_from_reverse(cstate, &pstate->list, head) {
		if (nvkm_cstate_valid(clk, cstate, max_volt, clk->temp))
			return cstate;
	}

	return NULL;
}

static struct nvkm_cstate *
nvkm_cstate_get(struct nvkm_clk *clk, struct nvkm_pstate *pstate, int cstatei)
{
	struct nvkm_cstate *cstate;
	if (cstatei == NVKM_CLK_CSTATE_HIGHEST)
		return list_last_entry(&pstate->list, typeof(*cstate), head);
	else {
		list_for_each_entry(cstate, &pstate->list, head) {

Annotation

Implementation Notes