Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c913e23a authored by Rafał Miłecki's avatar Rafał Miłecki Committed by Dave Airlie
Browse files

drm/radeon/kms: add dynamic engine reclocking (V9)



V2: reorganize functions, fix modesetting calls
V3: rebase patch, use radeon's workqueue
V4: enable on tested chipsets only, request VBLANK IRQs
V5: enable PM on older hardware (IRQs, mode_fixup, dpms)
V6: use separate dynpm module parameter
V7: drop RADEON_ prefix, set minimum mode for dpms off
V8: update legacy encoder call, fix order in rs600 IRQ
V9: update compute_clocks call in legacy, not only DPMS_OFF

Signed-off-by: default avatarRafał Miłecki <zajec5@gmail.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 18917b60
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -312,9 +312,13 @@ int r100_irq_process(struct radeon_device *rdev)
		/* Vertical blank interrupts */
		if (status & RADEON_CRTC_VBLANK_STAT) {
			drm_handle_vblank(rdev->ddev, 0);
			if (rdev->pm.vblank_callback)
				queue_work(rdev->wq, &rdev->pm.reclock_work);
		}
		if (status & RADEON_CRTC2_VBLANK_STAT) {
			drm_handle_vblank(rdev->ddev, 1);
			if (rdev->pm.vblank_callback)
				queue_work(rdev->wq, &rdev->pm.reclock_work);
		}
		if (status & RADEON_FP_DETECT_STAT) {
			queue_hotplug = true;
+4 −0
Original line number Diff line number Diff line
@@ -2744,6 +2744,8 @@ int r600_irq_process(struct radeon_device *rdev)
			case 0: /* D1 vblank */
				if (disp_int & LB_D1_VBLANK_INTERRUPT) {
					drm_handle_vblank(rdev->ddev, 0);
					if (rdev->pm.vblank_callback)
						queue_work(rdev->wq, &rdev->pm.reclock_work);
					disp_int &= ~LB_D1_VBLANK_INTERRUPT;
					DRM_DEBUG("IH: D1 vblank\n");
				}
@@ -2764,6 +2766,8 @@ int r600_irq_process(struct radeon_device *rdev)
			case 0: /* D2 vblank */
				if (disp_int & LB_D2_VBLANK_INTERRUPT) {
					drm_handle_vblank(rdev->ddev, 1);
					if (rdev->pm.vblank_callback)
						queue_work(rdev->wq, &rdev->pm.reclock_work);
					disp_int &= ~LB_D2_VBLANK_INTERRUPT;
					DRM_DEBUG("IH: D2 vblank\n");
				}
+28 −0
Original line number Diff line number Diff line
@@ -89,6 +89,7 @@ extern int radeon_testing;
extern int radeon_connector_table;
extern int radeon_tv;
extern int radeon_new_pll;
extern int radeon_dynpm;
extern int radeon_audio;

/*
@@ -148,6 +149,7 @@ struct radeon_clock {
 * Power management
 */
int radeon_pm_init(struct radeon_device *rdev);
void radeon_pm_compute_clocks(struct radeon_device *rdev);

/*
 * Fences.
@@ -569,7 +571,33 @@ struct radeon_wb {
 * Equation between gpu/memory clock and available bandwidth is hw dependent
 * (type of memory, bus size, efficiency, ...)
 */
enum radeon_pm_state {
	PM_STATE_DISABLED,
	PM_STATE_MINIMUM,
	PM_STATE_PAUSED,
	PM_STATE_ACTIVE
};
enum radeon_pm_action {
	PM_ACTION_NONE,
	PM_ACTION_MINIMUM,
	PM_ACTION_DOWNCLOCK,
	PM_ACTION_UPCLOCK
};
struct radeon_pm {
	struct mutex		mutex;
	struct work_struct	reclock_work;
	struct delayed_work	idle_work;
	enum radeon_pm_state	state;
	enum radeon_pm_action	planned_action;
	unsigned long		action_timeout;
	bool 			downclocked;
	bool			vblank_callback;
	int			active_crtcs;
	int			req_vblank;
	uint32_t		min_gpu_engine_clock;
	uint32_t		min_gpu_memory_clock;
	uint32_t		min_mode_engine_clock;
	uint32_t		min_mode_memory_clock;
	fixed20_12		max_bandwidth;
	fixed20_12		igp_sideport_mclk;
	fixed20_12		igp_system_mclk;
+1 −0
Original line number Diff line number Diff line
@@ -642,6 +642,7 @@ int radeon_device_init(struct radeon_device *rdev,
	if (rdev->family >= CHIP_R600)
		spin_lock_init(&rdev->ih.lock);
	mutex_init(&rdev->gem.mutex);
	mutex_init(&rdev->pm.mutex);
	rwlock_init(&rdev->fence_drv.lock);
	INIT_LIST_HEAD(&rdev->gem.objects);

+4 −0
Original line number Diff line number Diff line
@@ -87,6 +87,7 @@ int radeon_testing = 0;
int radeon_connector_table = 0;
int radeon_tv = 1;
int radeon_new_pll = 1;
int radeon_dynpm = -1;
int radeon_audio = 1;

MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers");
@@ -125,6 +126,9 @@ module_param_named(tv, radeon_tv, int, 0444);
MODULE_PARM_DESC(new_pll, "Select new PLL code for AVIVO chips");
module_param_named(new_pll, radeon_new_pll, int, 0444);

MODULE_PARM_DESC(dynpm, "Disable/Enable dynamic power management (1 = enable)");
module_param_named(dynpm, radeon_dynpm, int, 0444);

MODULE_PARM_DESC(audio, "Audio enable (0 = disable)");
module_param_named(audio, radeon_audio, int, 0444);

Loading