drm/amdgpu: teach amdgpu how to enable interrupts for any pipe v3
The current implementation is hardcoded to enable ME1/PIPE0 interrupts only. This patch allows amdgpu to enable interrupts for any pipe of ME1. v2: added gfx9 support v3: use soc15_grbm_select for gfx9 Acked-by: Felix Kuehling <Felix.Kuehling@amd.com> Signed-off-by: Andres Rodriguez <andresx7@gmail.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
78c1683423
commit
763a47b8e1
@ -5066,42 +5066,28 @@ static void gfx_v7_0_set_compute_eop_interrupt_state(struct amdgpu_device *adev,
|
|||||||
int me, int pipe,
|
int me, int pipe,
|
||||||
enum amdgpu_interrupt_state state)
|
enum amdgpu_interrupt_state state)
|
||||||
{
|
{
|
||||||
u32 mec_int_cntl, mec_int_cntl_reg;
|
/* Me 0 is for graphics and Me 2 is reserved for HW scheduling
|
||||||
|
* So we should only really be configuring ME 1 i.e. MEC0
|
||||||
/*
|
|
||||||
* amdgpu controls only pipe 0 of MEC1. That's why this function only
|
|
||||||
* handles the setting of interrupts for this specific pipe. All other
|
|
||||||
* pipes' interrupts are set by amdkfd.
|
|
||||||
*/
|
*/
|
||||||
|
if (me != 1) {
|
||||||
if (me == 1) {
|
DRM_ERROR("Ignoring request to enable interrupts for invalid me:%d\n", me);
|
||||||
switch (pipe) {
|
|
||||||
case 0:
|
|
||||||
mec_int_cntl_reg = mmCP_ME1_PIPE0_INT_CNTL;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
DRM_DEBUG("invalid pipe %d\n", pipe);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
DRM_DEBUG("invalid me %d\n", me);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (state) {
|
if (pipe >= adev->gfx.mec.num_pipe_per_mec) {
|
||||||
case AMDGPU_IRQ_STATE_DISABLE:
|
DRM_ERROR("Ignoring request to enable interrupts for invalid "
|
||||||
mec_int_cntl = RREG32(mec_int_cntl_reg);
|
"me:%d pipe:%d\n", pipe, me);
|
||||||
mec_int_cntl &= ~CP_INT_CNTL_RING0__TIME_STAMP_INT_ENABLE_MASK;
|
return;
|
||||||
WREG32(mec_int_cntl_reg, mec_int_cntl);
|
|
||||||
break;
|
|
||||||
case AMDGPU_IRQ_STATE_ENABLE:
|
|
||||||
mec_int_cntl = RREG32(mec_int_cntl_reg);
|
|
||||||
mec_int_cntl |= CP_INT_CNTL_RING0__TIME_STAMP_INT_ENABLE_MASK;
|
|
||||||
WREG32(mec_int_cntl_reg, mec_int_cntl);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex_lock(&adev->srbm_mutex);
|
||||||
|
cik_srbm_select(adev, me, pipe, 0, 0);
|
||||||
|
|
||||||
|
WREG32_FIELD(CPC_INT_CNTL, TIME_STAMP_INT_ENABLE,
|
||||||
|
state == AMDGPU_IRQ_STATE_DISABLE ? 0 : 1);
|
||||||
|
|
||||||
|
cik_srbm_select(adev, 0, 0, 0, 0);
|
||||||
|
mutex_unlock(&adev->srbm_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gfx_v7_0_set_priv_reg_fault_state(struct amdgpu_device *adev,
|
static int gfx_v7_0_set_priv_reg_fault_state(struct amdgpu_device *adev,
|
||||||
|
@ -6803,27 +6803,26 @@ static void gfx_v8_0_set_compute_eop_interrupt_state(struct amdgpu_device *adev,
|
|||||||
int me, int pipe,
|
int me, int pipe,
|
||||||
enum amdgpu_interrupt_state state)
|
enum amdgpu_interrupt_state state)
|
||||||
{
|
{
|
||||||
/*
|
/* Me 0 is reserved for graphics */
|
||||||
* amdgpu controls only pipe 0 of MEC1. That's why this function only
|
if (me < 1 || me > adev->gfx.mec.num_mec) {
|
||||||
* handles the setting of interrupts for this specific pipe. All other
|
DRM_ERROR("Ignoring request to enable interrupts for invalid me:%d\n", me);
|
||||||
* pipes' interrupts are set by amdkfd.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (me == 1) {
|
|
||||||
switch (pipe) {
|
|
||||||
case 0:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
DRM_DEBUG("invalid pipe %d\n", pipe);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
DRM_DEBUG("invalid me %d\n", me);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
WREG32_FIELD(CP_ME1_PIPE0_INT_CNTL, TIME_STAMP_INT_ENABLE,
|
if (pipe >= adev->gfx.mec.num_pipe_per_mec) {
|
||||||
state == AMDGPU_IRQ_STATE_DISABLE ? 0 : 1);
|
DRM_ERROR("Ignoring request to enable interrupts for invalid "
|
||||||
|
"me:%d pipe:%d\n", pipe, me);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_lock(&adev->srbm_mutex);
|
||||||
|
vi_srbm_select(adev, me, pipe, 0, 0);
|
||||||
|
|
||||||
|
WREG32_FIELD(CPC_INT_CNTL, TIME_STAMP_INT_ENABLE,
|
||||||
|
state == AMDGPU_IRQ_STATE_DISABLE ? 0 : 1);
|
||||||
|
|
||||||
|
vi_srbm_select(adev, 0, 0, 0, 0);
|
||||||
|
mutex_unlock(&adev->srbm_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gfx_v8_0_set_priv_reg_fault_state(struct amdgpu_device *adev,
|
static int gfx_v8_0_set_priv_reg_fault_state(struct amdgpu_device *adev,
|
||||||
|
@ -4147,44 +4147,26 @@ static void gfx_v9_0_set_compute_eop_interrupt_state(struct amdgpu_device *adev,
|
|||||||
int me, int pipe,
|
int me, int pipe,
|
||||||
enum amdgpu_interrupt_state state)
|
enum amdgpu_interrupt_state state)
|
||||||
{
|
{
|
||||||
u32 mec_int_cntl, mec_int_cntl_reg;
|
/* Me 0 is reserved for graphics */
|
||||||
|
if (me < 1 || me > adev->gfx.mec.num_mec) {
|
||||||
/*
|
DRM_ERROR("Ignoring request to enable interrupts for invalid me:%d\n", me);
|
||||||
* amdgpu controls only pipe 0 of MEC1. That's why this function only
|
|
||||||
* handles the setting of interrupts for this specific pipe. All other
|
|
||||||
* pipes' interrupts are set by amdkfd.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (me == 1) {
|
|
||||||
switch (pipe) {
|
|
||||||
case 0:
|
|
||||||
mec_int_cntl_reg = SOC15_REG_OFFSET(GC, 0, mmCP_ME1_PIPE0_INT_CNTL);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
DRM_DEBUG("invalid pipe %d\n", pipe);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
DRM_DEBUG("invalid me %d\n", me);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (state) {
|
if (pipe >= adev->gfx.mec.num_pipe_per_mec) {
|
||||||
case AMDGPU_IRQ_STATE_DISABLE:
|
DRM_ERROR("Ignoring request to enable interrupts for invalid "
|
||||||
mec_int_cntl = RREG32(mec_int_cntl_reg);
|
"me:%d pipe:%d\n", pipe, me);
|
||||||
mec_int_cntl = REG_SET_FIELD(mec_int_cntl, CP_ME1_PIPE0_INT_CNTL,
|
return;
|
||||||
TIME_STAMP_INT_ENABLE, 0);
|
|
||||||
WREG32(mec_int_cntl_reg, mec_int_cntl);
|
|
||||||
break;
|
|
||||||
case AMDGPU_IRQ_STATE_ENABLE:
|
|
||||||
mec_int_cntl = RREG32(mec_int_cntl_reg);
|
|
||||||
mec_int_cntl = REG_SET_FIELD(mec_int_cntl, CP_ME1_PIPE0_INT_CNTL,
|
|
||||||
TIME_STAMP_INT_ENABLE, 1);
|
|
||||||
WREG32(mec_int_cntl_reg, mec_int_cntl);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex_lock(&adev->srbm_mutex);
|
||||||
|
soc15_grbm_select(adev, me, pipe, 0, 0);
|
||||||
|
|
||||||
|
WREG32_FIELD(CPC_INT_CNTL, TIME_STAMP_INT_ENABLE,
|
||||||
|
state == AMDGPU_IRQ_STATE_DISABLE ? 0 : 1);
|
||||||
|
|
||||||
|
soc15_grbm_select(adev, 0, 0, 0, 0);
|
||||||
|
mutex_unlock(&adev->srbm_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gfx_v9_0_set_priv_reg_fault_state(struct amdgpu_device *adev,
|
static int gfx_v9_0_set_priv_reg_fault_state(struct amdgpu_device *adev,
|
||||||
|
Loading…
Reference in New Issue
Block a user