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.
- 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.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/pci.hlinux/seq_file.hatom.hbtc_dpm.hbtcd.hcypress_dpm.hevergreen.hr600_dpm.hrv770.hradeon.hradeon_asic.h
Detected Declarations
function btc_get_max_clock_from_voltage_dependency_tablefunction btc_apply_voltage_dependency_rulesfunction btc_find_valid_clockfunction btc_get_valid_mclkfunction btc_get_valid_sclkfunction btc_skip_blacklist_clocksfunction btc_adjust_clock_combinationsfunction btc_find_voltagefunction btc_apply_voltage_delta_rulesfunction btc_enable_bif_dynamic_pcie_gen2function btc_enable_dynamic_pcie_gen2function btc_disable_ulvfunction btc_populate_ulv_statefunction btc_populate_smc_acpi_statefunction btc_program_mgcg_hw_sequencefunction btc_cg_clock_gating_defaultfunction btc_cg_clock_gating_enablefunction btc_mg_clock_gating_defaultfunction btc_mg_clock_gating_enablefunction btc_ls_clock_gating_defaultfunction btc_ls_clock_gating_enablefunction btc_dpm_enabledfunction btc_init_smc_tablefunction btc_set_at_for_uvdfunction btc_notify_uvd_to_smcfunction btc_reset_to_defaultfunction btc_stop_smcfunction btc_read_arb_registersfunction btc_set_arb0_registersfunction btc_set_boot_state_timingfunction btc_is_state_ulv_compatiblefunction btc_set_ulv_dram_timingfunction btc_enable_ulvfunction btc_set_power_state_conditionally_enable_ulvfunction btc_check_s0_mc_reg_indexfunction btc_set_valid_flagfunction btc_set_mc_special_registersfunction btc_set_s0_mc_reg_indexfunction btc_copy_vbios_mc_reg_tablefunction btc_initialize_mc_reg_tablefunction btc_init_stutter_modefunction btc_dpm_vblank_too_shortfunction btc_apply_state_adjust_rulesfunction btc_update_current_psfunction btc_update_requested_psfunction btc_dpm_reset_asicfunction btc_dpm_pre_set_power_statefunction btc_dpm_set_power_state
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
- Immediate include surface: `linux/pci.h`, `linux/seq_file.h`, `atom.h`, `btc_dpm.h`, `btcd.h`, `cypress_dpm.h`, `evergreen.h`, `r600_dpm.h`.
- Detected declarations: `function btc_get_max_clock_from_voltage_dependency_table`, `function btc_apply_voltage_dependency_rules`, `function btc_find_valid_clock`, `function btc_get_valid_mclk`, `function btc_get_valid_sclk`, `function btc_skip_blacklist_clocks`, `function btc_adjust_clock_combinations`, `function btc_find_voltage`, `function btc_apply_voltage_delta_rules`, `function btc_enable_bif_dynamic_pcie_gen2`.
- Atlas domain: Driver Families / drivers/gpu.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.