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.

Dependency Surface

Detected Declarations

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

Implementation Notes