drivers/gpu/drm/radeon/rv730_dpm.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/radeon/rv730_dpm.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/radeon/rv730_dpm.c- Extension
.c- Size
- 16768 bytes
- Lines
- 506
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
radeon.hrv730d.hr600_dpm.hrv770.hrv770_dpm.hatom.h
Detected Declarations
function filesfunction rv730_populate_mclk_valuefunction rv730_read_clock_registersfunction rv730_populate_smc_acpi_statefunction rv730_populate_smc_initial_statefunction rv730_program_memory_timing_parametersfunction rv730_start_dpmfunction rv730_stop_dpmfunction rv730_program_dcodtfunction rv730_get_odt_values
Annotated Snippet
#include "radeon.h"
#include "rv730d.h"
#include "r600_dpm.h"
#include "rv770.h"
#include "rv770_dpm.h"
#include "atom.h"
#define MC_CG_ARB_FREQ_F0 0x0a
#define MC_CG_ARB_FREQ_F1 0x0b
#define MC_CG_ARB_FREQ_F2 0x0c
#define MC_CG_ARB_FREQ_F3 0x0d
int rv730_populate_sclk_value(struct radeon_device *rdev,
u32 engine_clock,
RV770_SMC_SCLK_VALUE *sclk)
{
struct rv7xx_power_info *pi = rv770_get_pi(rdev);
struct atom_clock_dividers dividers;
u32 spll_func_cntl = pi->clk_regs.rv730.cg_spll_func_cntl;
u32 spll_func_cntl_2 = pi->clk_regs.rv730.cg_spll_func_cntl_2;
u32 spll_func_cntl_3 = pi->clk_regs.rv730.cg_spll_func_cntl_3;
u32 cg_spll_spread_spectrum = pi->clk_regs.rv730.cg_spll_spread_spectrum;
u32 cg_spll_spread_spectrum_2 = pi->clk_regs.rv730.cg_spll_spread_spectrum_2;
u64 tmp;
u32 reference_clock = rdev->clock.spll.reference_freq;
u32 reference_divider, post_divider;
u32 fbdiv;
int ret;
ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
engine_clock, false, ÷rs);
if (ret)
return ret;
reference_divider = 1 + dividers.ref_div;
if (dividers.enable_post_div)
post_divider = ((dividers.post_div >> 4) & 0xf) +
(dividers.post_div & 0xf) + 2;
else
post_divider = 1;
tmp = (u64) engine_clock * reference_divider * post_divider * 16384;
do_div(tmp, reference_clock);
fbdiv = (u32) tmp;
/* set up registers */
if (dividers.enable_post_div)
spll_func_cntl |= SPLL_DIVEN;
else
spll_func_cntl &= ~SPLL_DIVEN;
spll_func_cntl &= ~(SPLL_HILEN_MASK | SPLL_LOLEN_MASK | SPLL_REF_DIV_MASK);
spll_func_cntl |= SPLL_REF_DIV(dividers.ref_div);
spll_func_cntl |= SPLL_HILEN((dividers.post_div >> 4) & 0xf);
spll_func_cntl |= SPLL_LOLEN(dividers.post_div & 0xf);
spll_func_cntl_2 &= ~SCLK_MUX_SEL_MASK;
spll_func_cntl_2 |= SCLK_MUX_SEL(2);
spll_func_cntl_3 &= ~SPLL_FB_DIV_MASK;
spll_func_cntl_3 |= SPLL_FB_DIV(fbdiv);
spll_func_cntl_3 |= SPLL_DITHEN;
if (pi->sclk_ss) {
struct radeon_atom_ss ss;
u32 vco_freq = engine_clock * post_divider;
if (radeon_atombios_get_asic_ss_info(rdev, &ss,
ASIC_INTERNAL_ENGINE_SS, vco_freq)) {
u32 clk_s = reference_clock * 5 / (reference_divider * ss.rate);
u32 clk_v = ss.percentage * fbdiv / (clk_s * 10000);
cg_spll_spread_spectrum &= ~CLK_S_MASK;
cg_spll_spread_spectrum |= CLK_S(clk_s);
cg_spll_spread_spectrum |= SSEN;
cg_spll_spread_spectrum_2 &= ~CLK_V_MASK;
cg_spll_spread_spectrum_2 |= CLK_V(clk_v);
}
}
sclk->sclk_value = cpu_to_be32(engine_clock);
sclk->vCG_SPLL_FUNC_CNTL = cpu_to_be32(spll_func_cntl);
sclk->vCG_SPLL_FUNC_CNTL_2 = cpu_to_be32(spll_func_cntl_2);
sclk->vCG_SPLL_FUNC_CNTL_3 = cpu_to_be32(spll_func_cntl_3);
sclk->vCG_SPLL_SPREAD_SPECTRUM = cpu_to_be32(cg_spll_spread_spectrum);
sclk->vCG_SPLL_SPREAD_SPECTRUM_2 = cpu_to_be32(cg_spll_spread_spectrum_2);
return 0;
}
Annotation
- Immediate include surface: `radeon.h`, `rv730d.h`, `r600_dpm.h`, `rv770.h`, `rv770_dpm.h`, `atom.h`.
- Detected declarations: `function files`, `function rv730_populate_mclk_value`, `function rv730_read_clock_registers`, `function rv730_populate_smc_acpi_state`, `function rv730_populate_smc_initial_state`, `function rv730_program_memory_timing_parameters`, `function rv730_start_dpm`, `function rv730_stop_dpm`, `function rv730_program_dcodt`, `function rv730_get_odt_values`.
- 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.