drm/amdgpu: use begin/end_use for VCE power/clock gating
This fixes turning power and clock on when it is actually needed. Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Edward O'Callaghan <funfunctor@folklore1984.net> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Родитель
c4120d55ff
Коммит
ebff485e93
|
@ -1702,6 +1702,7 @@ struct amdgpu_vce {
|
|||
struct drm_file *filp[AMDGPU_MAX_VCE_HANDLES];
|
||||
uint32_t img_size[AMDGPU_MAX_VCE_HANDLES];
|
||||
struct delayed_work idle_work;
|
||||
struct mutex idle_mutex;
|
||||
const struct firmware *fw; /* VCE firmware */
|
||||
struct amdgpu_ring ring[AMDGPU_MAX_VCE_RINGS];
|
||||
struct amdgpu_irq_src irq;
|
||||
|
|
|
@ -85,8 +85,6 @@ int amdgpu_vce_sw_init(struct amdgpu_device *adev, unsigned long size)
|
|||
unsigned ucode_version, version_major, version_minor, binary_id;
|
||||
int i, r;
|
||||
|
||||
INIT_DELAYED_WORK(&adev->vce.idle_work, amdgpu_vce_idle_work_handler);
|
||||
|
||||
switch (adev->asic_type) {
|
||||
#ifdef CONFIG_DRM_AMDGPU_CIK
|
||||
case CHIP_BONAIRE:
|
||||
|
@ -197,6 +195,9 @@ int amdgpu_vce_sw_init(struct amdgpu_device *adev, unsigned long size)
|
|||
adev->vce.filp[i] = NULL;
|
||||
}
|
||||
|
||||
INIT_DELAYED_WORK(&adev->vce.idle_work, amdgpu_vce_idle_work_handler);
|
||||
mutex_init(&adev->vce.idle_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -220,6 +221,7 @@ int amdgpu_vce_sw_fini(struct amdgpu_device *adev)
|
|||
amdgpu_ring_fini(&adev->vce.ring[1]);
|
||||
|
||||
release_firmware(adev->vce.fw);
|
||||
mutex_destroy(&adev->vce.idle_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -315,19 +317,19 @@ static void amdgpu_vce_idle_work_handler(struct work_struct *work)
|
|||
}
|
||||
|
||||
/**
|
||||
* amdgpu_vce_note_usage - power up VCE
|
||||
* amdgpu_vce_ring_begin_use - power up VCE
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @ring: amdgpu ring
|
||||
*
|
||||
* Make sure VCE is powerd up when we want to use it
|
||||
*/
|
||||
static void amdgpu_vce_note_usage(struct amdgpu_device *adev)
|
||||
void amdgpu_vce_ring_begin_use(struct amdgpu_ring *ring)
|
||||
{
|
||||
bool set_clocks = !cancel_delayed_work_sync(&adev->vce.idle_work);
|
||||
|
||||
set_clocks &= schedule_delayed_work(&adev->vce.idle_work,
|
||||
VCE_IDLE_TIMEOUT);
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
bool set_clocks;
|
||||
|
||||
mutex_lock(&adev->vce.idle_mutex);
|
||||
set_clocks = !cancel_delayed_work_sync(&adev->vce.idle_work);
|
||||
if (set_clocks) {
|
||||
if (adev->pm.dpm_enabled) {
|
||||
amdgpu_dpm_enable_vce(adev, true);
|
||||
|
@ -335,6 +337,19 @@ static void amdgpu_vce_note_usage(struct amdgpu_device *adev)
|
|||
amdgpu_asic_set_vce_clocks(adev, 53300, 40000);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&adev->vce.idle_mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_vce_ring_end_use - power VCE down
|
||||
*
|
||||
* @ring: amdgpu ring
|
||||
*
|
||||
* Schedule work to power VCE down again
|
||||
*/
|
||||
void amdgpu_vce_ring_end_use(struct amdgpu_ring *ring)
|
||||
{
|
||||
schedule_delayed_work(&ring->adev->vce.idle_work, VCE_IDLE_TIMEOUT);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -355,8 +370,6 @@ void amdgpu_vce_free_handles(struct amdgpu_device *adev, struct drm_file *filp)
|
|||
if (!handle || adev->vce.filp[i] != filp)
|
||||
continue;
|
||||
|
||||
amdgpu_vce_note_usage(adev);
|
||||
|
||||
r = amdgpu_vce_get_destroy_msg(ring, handle, false, NULL);
|
||||
if (r)
|
||||
DRM_ERROR("Error destroying VCE handle (%d)!\n", r);
|
||||
|
@ -622,8 +635,6 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx)
|
|||
uint32_t *size = &tmp;
|
||||
int i, r = 0, idx = 0;
|
||||
|
||||
amdgpu_vce_note_usage(p->adev);
|
||||
|
||||
while (idx < ib->length_dw) {
|
||||
uint32_t len = amdgpu_get_ib_value(p, ib_idx, idx);
|
||||
uint32_t cmd = amdgpu_get_ib_value(p, ib_idx, idx + 1);
|
||||
|
|
|
@ -40,5 +40,7 @@ void amdgpu_vce_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq,
|
|||
unsigned flags);
|
||||
int amdgpu_vce_ring_test_ring(struct amdgpu_ring *ring);
|
||||
int amdgpu_vce_ring_test_ib(struct amdgpu_ring *ring);
|
||||
void amdgpu_vce_ring_begin_use(struct amdgpu_ring *ring);
|
||||
void amdgpu_vce_ring_end_use(struct amdgpu_ring *ring);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -594,6 +594,8 @@ static const struct amdgpu_ring_funcs vce_v2_0_ring_funcs = {
|
|||
.test_ib = amdgpu_vce_ring_test_ib,
|
||||
.insert_nop = amdgpu_ring_insert_nop,
|
||||
.pad_ib = amdgpu_ring_generic_pad_ib,
|
||||
.begin_use = amdgpu_vce_ring_begin_use,
|
||||
.end_use = amdgpu_vce_ring_end_use,
|
||||
};
|
||||
|
||||
static void vce_v2_0_set_ring_funcs(struct amdgpu_device *adev)
|
||||
|
|
|
@ -767,6 +767,8 @@ static const struct amdgpu_ring_funcs vce_v3_0_ring_funcs = {
|
|||
.test_ib = amdgpu_vce_ring_test_ib,
|
||||
.insert_nop = amdgpu_ring_insert_nop,
|
||||
.pad_ib = amdgpu_ring_generic_pad_ib,
|
||||
.begin_use = amdgpu_vce_ring_begin_use,
|
||||
.end_use = amdgpu_vce_ring_end_use,
|
||||
};
|
||||
|
||||
static void vce_v3_0_set_ring_funcs(struct amdgpu_device *adev)
|
||||
|
|
Загрузка…
Ссылка в новой задаче