drivers/gpu/drm/radeon/btc_dpm.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/radeon/btc_dpm.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/radeon/btc_dpm.c
Extension
.c
Size
87664 bytes
Lines
2796
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 (clock <= table->entries[i].clk) {
			if (*voltage < table->entries[i].v)
				*voltage = (u16)((table->entries[i].v < max_voltage) ?
						  table->entries[i].v : max_voltage);
			return;
		}
	}

	*voltage = (*voltage > max_voltage) ? *voltage : max_voltage;
}

static u32 btc_find_valid_clock(struct radeon_clock_array *clocks,
				u32 max_clock, u32 requested_clock)
{
	unsigned int i;

	if ((clocks == NULL) || (clocks->count == 0))
		return (requested_clock < max_clock) ? requested_clock : max_clock;

	for (i = 0; i < clocks->count; i++) {
		if (clocks->values[i] >= requested_clock)
			return (clocks->values[i] < max_clock) ? clocks->values[i] : max_clock;
	}

	return (clocks->values[clocks->count - 1] < max_clock) ?
		clocks->values[clocks->count - 1] : max_clock;
}

static u32 btc_get_valid_mclk(struct radeon_device *rdev,
			      u32 max_mclk, u32 requested_mclk)
{
	return btc_find_valid_clock(&rdev->pm.dpm.dyn_state.valid_mclk_values,
				    max_mclk, requested_mclk);
}

static u32 btc_get_valid_sclk(struct radeon_device *rdev,
			      u32 max_sclk, u32 requested_sclk)
{
	return btc_find_valid_clock(&rdev->pm.dpm.dyn_state.valid_sclk_values,
				    max_sclk, requested_sclk);
}

void btc_skip_blacklist_clocks(struct radeon_device *rdev,
			       const u32 max_sclk, const u32 max_mclk,
			       u32 *sclk, u32 *mclk)
{
	int i, num_blacklist_clocks;

	if ((sclk == NULL) || (mclk == NULL))
		return;

	num_blacklist_clocks = ARRAY_SIZE(btc_blacklist_clocks);

	for (i = 0; i < num_blacklist_clocks; i++) {
		if ((btc_blacklist_clocks[i].sclk == *sclk) &&
		    (btc_blacklist_clocks[i].mclk == *mclk))
			break;
	}

	if (i < num_blacklist_clocks) {
		if (btc_blacklist_clocks[i].action == RADEON_SCLK_UP) {
			*sclk = btc_get_valid_sclk(rdev, max_sclk, *sclk + 1);

			if (*sclk < max_sclk)
				btc_skip_blacklist_clocks(rdev, max_sclk, max_mclk, sclk, mclk);
		}
	}
}

void btc_adjust_clock_combinations(struct radeon_device *rdev,
				   const struct radeon_clock_and_voltage_limits *max_limits,
				   struct rv7xx_pl *pl)
{

	if ((pl->mclk == 0) || (pl->sclk == 0))
		return;

	if (pl->mclk == pl->sclk)
		return;

	if (pl->mclk > pl->sclk) {
		if (((pl->mclk + (pl->sclk - 1)) / pl->sclk) > rdev->pm.dpm.dyn_state.mclk_sclk_ratio)
			pl->sclk = btc_get_valid_sclk(rdev,
						      max_limits->sclk,
						      (pl->mclk +
						       (rdev->pm.dpm.dyn_state.mclk_sclk_ratio - 1)) /
						      rdev->pm.dpm.dyn_state.mclk_sclk_ratio);
	} else {
		if ((pl->sclk - pl->mclk) > rdev->pm.dpm.dyn_state.sclk_mclk_delta)
			pl->mclk = btc_get_valid_mclk(rdev,

Annotation

Implementation Notes