drivers/gpu/drm/radeon/r600_dpm.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/radeon/r600_dpm.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/radeon/r600_dpm.c- Extension
.c- Size
- 43780 bytes
- Lines
- 1369
- 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
radeon.hradeon_asic.hr600d.hr600_dpm.hatom.h
Detected Declarations
function r600_dpm_print_class_infofunction r600_dpm_print_cap_infofunction r600_dpm_print_ps_statusfunction r600_dpm_get_vblank_timefunction r600_dpm_get_vrefreshfunction r600_calculate_u_and_pfunction r600_calculate_atfunction r600_gfx_clockgating_enablefunction r600_dynamicpm_enablefunction r600_enable_thermal_protectionfunction r600_enable_acpi_pmfunction r600_enable_dynamic_pcie_gen2function r600_dynamicpm_enabledfunction r600_enable_sclk_controlfunction r600_enable_mclk_controlfunction r600_enable_spll_bypassfunction r600_wait_for_spll_changefunction r600_set_bspfunction r600_set_atfunction r600_set_tcfunction r600_select_tdfunction r600_set_vrcfunction r600_set_tpufunction r600_set_tpcfunction r600_set_sstufunction r600_set_sstfunction r600_set_gitfunction r600_set_fctufunction r600_set_fctfunction r600_set_ctxcgtt3d_rphcfunction r600_set_ctxcgtt3d_rsdcfunction r600_set_vddc3d_oorsufunction r600_set_vddc3d_oorphcfunction r600_set_vddc3d_oorsdcfunction r600_set_mpll_lock_timefunction r600_set_mpll_reset_timefunction r600_engine_clock_entry_enablefunction r600_engine_clock_entry_enable_pulse_skippingfunction r600_engine_clock_entry_enable_post_dividerfunction r600_engine_clock_entry_set_post_dividerfunction r600_engine_clock_entry_set_reference_dividerfunction r600_engine_clock_entry_set_feedback_dividerfunction r600_engine_clock_entry_set_step_timefunction r600_vid_rt_set_ssufunction r600_vid_rt_set_vrufunction r600_vid_rt_set_vrtfunction r600_voltage_control_enable_pinsfunction r600_voltage_control_program_voltages
Annotated Snippet
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
radeon_crtc = to_radeon_crtc(crtc);
if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) {
vblank_in_pixels =
radeon_crtc->hw_mode.crtc_htotal *
(radeon_crtc->hw_mode.crtc_vblank_end -
radeon_crtc->hw_mode.crtc_vdisplay +
(radeon_crtc->v_border * 2));
vblank_time_us = vblank_in_pixels * 1000 / radeon_crtc->hw_mode.clock;
break;
}
}
}
return vblank_time_us;
}
u32 r600_dpm_get_vrefresh(struct radeon_device *rdev)
{
struct drm_device *dev = rdev_to_drm(rdev);
struct drm_crtc *crtc;
struct radeon_crtc *radeon_crtc;
u32 vrefresh = 0;
if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) {
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
radeon_crtc = to_radeon_crtc(crtc);
if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) {
vrefresh = drm_mode_vrefresh(&radeon_crtc->hw_mode);
break;
}
}
}
return vrefresh;
}
void r600_calculate_u_and_p(u32 i, u32 r_c, u32 p_b,
u32 *p, u32 *u)
{
u32 b_c = 0;
u32 i_c;
u32 tmp;
i_c = (i * r_c) / 100;
tmp = i_c >> p_b;
while (tmp) {
b_c++;
tmp >>= 1;
}
*u = (b_c + 1) / 2;
*p = i_c / (1 << (2 * (*u)));
}
int r600_calculate_at(u32 t, u32 h, u32 fh, u32 fl, u32 *tl, u32 *th)
{
u32 k, a, ah, al;
u32 t1;
if ((fl == 0) || (fh == 0) || (fl > fh))
return -EINVAL;
k = (100 * fh) / fl;
t1 = (t * (k - 100));
a = (1000 * (100 * h + t1)) / (10000 + (t1 / 100));
a = (a + 5) / 10;
ah = ((a * t) + 5000) / 10000;
al = a - ah;
*th = t - ah;
*tl = t + al;
return 0;
}
void r600_gfx_clockgating_enable(struct radeon_device *rdev, bool enable)
{
int i;
if (enable) {
WREG32_P(SCLK_PWRMGT_CNTL, DYN_GFX_CLK_OFF_EN, ~DYN_GFX_CLK_OFF_EN);
} else {
WREG32_P(SCLK_PWRMGT_CNTL, 0, ~DYN_GFX_CLK_OFF_EN);
WREG32(CG_RLC_REQ_AND_RSP, 0x2);
for (i = 0; i < rdev->usec_timeout; i++) {
if (((RREG32(CG_RLC_REQ_AND_RSP) & CG_RLC_RSP_TYPE_MASK) >> CG_RLC_RSP_TYPE_SHIFT) == 1)
Annotation
- Immediate include surface: `radeon.h`, `radeon_asic.h`, `r600d.h`, `r600_dpm.h`, `atom.h`.
- Detected declarations: `function r600_dpm_print_class_info`, `function r600_dpm_print_cap_info`, `function r600_dpm_print_ps_status`, `function r600_dpm_get_vblank_time`, `function r600_dpm_get_vrefresh`, `function r600_calculate_u_and_p`, `function r600_calculate_at`, `function r600_gfx_clockgating_enable`, `function r600_dynamicpm_enable`, `function r600_enable_thermal_protection`.
- 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.