Commit 667a4822 authored by Le Ma's avatar Le Ma Committed by Alex Deucher

drm/amdgpu: reorganize sdma v4 code to support more instances

This change is needed for Arcturus which has 8 sdma instances.
The CG/PG part is not covered for now.
Signed-off-by: default avatarLe Ma <le.ma@amd.com>
Acked-by: Snow Zhang < Snow.Zhang@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 51c60898
...@@ -25,11 +25,17 @@ ...@@ -25,11 +25,17 @@
#define __AMDGPU_SDMA_H__ #define __AMDGPU_SDMA_H__
/* max number of IP instances */ /* max number of IP instances */
#define AMDGPU_MAX_SDMA_INSTANCES 2 #define AMDGPU_MAX_SDMA_INSTANCES 8
enum amdgpu_sdma_irq { enum amdgpu_sdma_irq {
AMDGPU_SDMA_IRQ_INSTANCE0 = 0, AMDGPU_SDMA_IRQ_INSTANCE0 = 0,
AMDGPU_SDMA_IRQ_INSTANCE1, AMDGPU_SDMA_IRQ_INSTANCE1,
AMDGPU_SDMA_IRQ_INSTANCE2,
AMDGPU_SDMA_IRQ_INSTANCE3,
AMDGPU_SDMA_IRQ_INSTANCE4,
AMDGPU_SDMA_IRQ_INSTANCE5,
AMDGPU_SDMA_IRQ_INSTANCE6,
AMDGPU_SDMA_IRQ_INSTANCE7,
AMDGPU_SDMA_IRQ_LAST AMDGPU_SDMA_IRQ_LAST
}; };
......
...@@ -205,8 +205,77 @@ static const struct soc15_reg_golden golden_settings_sdma_rv2[] = ...@@ -205,8 +205,77 @@ static const struct soc15_reg_golden golden_settings_sdma_rv2[] =
static u32 sdma_v4_0_get_reg_offset(struct amdgpu_device *adev, static u32 sdma_v4_0_get_reg_offset(struct amdgpu_device *adev,
u32 instance, u32 offset) u32 instance, u32 offset)
{ {
return ( 0 == instance ? (adev->reg_offset[SDMA0_HWIP][0][0] + offset) : switch (instance) {
(adev->reg_offset[SDMA1_HWIP][0][0] + offset)); case 0:
return (adev->reg_offset[SDMA0_HWIP][0][0] + offset);
case 1:
return (adev->reg_offset[SDMA1_HWIP][0][0] + offset);
case 2:
return (adev->reg_offset[SDMA2_HWIP][0][0] + offset);
case 3:
return (adev->reg_offset[SDMA3_HWIP][0][0] + offset);
case 4:
return (adev->reg_offset[SDMA4_HWIP][0][0] + offset);
case 5:
return (adev->reg_offset[SDMA5_HWIP][0][0] + offset);
case 6:
return (adev->reg_offset[SDMA6_HWIP][0][0] + offset);
case 7:
return (adev->reg_offset[SDMA7_HWIP][0][0] + offset);
default:
break;
}
return 0;
}
static unsigned sdma_v4_0_seq_to_irq_id(int seq_num)
{
switch (seq_num) {
case 0:
return SOC15_IH_CLIENTID_SDMA0;
case 1:
return SOC15_IH_CLIENTID_SDMA1;
case 2:
return SOC15_IH_CLIENTID_SDMA2;
case 3:
return SOC15_IH_CLIENTID_SDMA3;
case 4:
return SOC15_IH_CLIENTID_SDMA4;
case 5:
return SOC15_IH_CLIENTID_SDMA5;
case 6:
return SOC15_IH_CLIENTID_SDMA6;
case 7:
return SOC15_IH_CLIENTID_SDMA7;
default:
break;
}
return 0;
}
static int sdma_v4_0_irq_id_to_seq(unsigned client_id)
{
switch (client_id) {
case SOC15_IH_CLIENTID_SDMA0:
return 0;
case SOC15_IH_CLIENTID_SDMA1:
return 1;
case SOC15_IH_CLIENTID_SDMA2:
return 2;
case SOC15_IH_CLIENTID_SDMA3:
return 3;
case SOC15_IH_CLIENTID_SDMA4:
return 4;
case SOC15_IH_CLIENTID_SDMA5:
return 5;
case SOC15_IH_CLIENTID_SDMA6:
return 6;
case SOC15_IH_CLIENTID_SDMA7:
return 7;
default:
break;
}
return 0;
} }
static void sdma_v4_0_init_golden_registers(struct amdgpu_device *adev) static void sdma_v4_0_init_golden_registers(struct amdgpu_device *adev)
...@@ -308,7 +377,7 @@ static int sdma_v4_0_init_microcode(struct amdgpu_device *adev) ...@@ -308,7 +377,7 @@ static int sdma_v4_0_init_microcode(struct amdgpu_device *adev)
if (i == 0) if (i == 0)
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sdma.bin", chip_name); snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sdma.bin", chip_name);
else else
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sdma1.bin", chip_name); snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sdma%d.bin", chip_name, i);
err = request_firmware(&adev->sdma.instance[i].fw, fw_name, adev->dev); err = request_firmware(&adev->sdma.instance[i].fw, fw_name, adev->dev);
if (err) if (err)
goto out; goto out;
...@@ -620,26 +689,27 @@ static void sdma_v4_0_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 se ...@@ -620,26 +689,27 @@ static void sdma_v4_0_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 se
*/ */
static void sdma_v4_0_gfx_stop(struct amdgpu_device *adev) static void sdma_v4_0_gfx_stop(struct amdgpu_device *adev)
{ {
struct amdgpu_ring *sdma0 = &adev->sdma.instance[0].ring; struct amdgpu_ring *sdma[AMDGPU_MAX_SDMA_INSTANCES];
struct amdgpu_ring *sdma1 = &adev->sdma.instance[1].ring;
u32 rb_cntl, ib_cntl; u32 rb_cntl, ib_cntl;
int i; int i, unset = 0;
if ((adev->mman.buffer_funcs_ring == sdma0) || for (i = 0; i < adev->sdma.num_instances; i++) {
(adev->mman.buffer_funcs_ring == sdma1)) sdma[i] = &adev->sdma.instance[i].ring;
if ((adev->mman.buffer_funcs_ring == sdma[i]) && unset != 1) {
amdgpu_ttm_set_buffer_funcs_status(adev, false); amdgpu_ttm_set_buffer_funcs_status(adev, false);
unset = 1;
}
for (i = 0; i < adev->sdma.num_instances; i++) {
rb_cntl = RREG32_SDMA(i, mmSDMA0_GFX_RB_CNTL); rb_cntl = RREG32_SDMA(i, mmSDMA0_GFX_RB_CNTL);
rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_ENABLE, 0); rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_ENABLE, 0);
WREG32_SDMA(i, mmSDMA0_GFX_RB_CNTL, rb_cntl); WREG32_SDMA(i, mmSDMA0_GFX_RB_CNTL, rb_cntl);
ib_cntl = RREG32_SDMA(i, mmSDMA0_GFX_IB_CNTL); ib_cntl = RREG32_SDMA(i, mmSDMA0_GFX_IB_CNTL);
ib_cntl = REG_SET_FIELD(ib_cntl, SDMA0_GFX_IB_CNTL, IB_ENABLE, 0); ib_cntl = REG_SET_FIELD(ib_cntl, SDMA0_GFX_IB_CNTL, IB_ENABLE, 0);
WREG32_SDMA(i, mmSDMA0_GFX_IB_CNTL, ib_cntl); WREG32_SDMA(i, mmSDMA0_GFX_IB_CNTL, ib_cntl);
}
sdma0->sched.ready = false; sdma[i]->sched.ready = false;
sdma1->sched.ready = false; }
} }
/** /**
...@@ -1606,16 +1676,13 @@ static int sdma_v4_0_sw_init(void *handle) ...@@ -1606,16 +1676,13 @@ static int sdma_v4_0_sw_init(void *handle)
struct amdgpu_device *adev = (struct amdgpu_device *)handle; struct amdgpu_device *adev = (struct amdgpu_device *)handle;
/* SDMA trap event */ /* SDMA trap event */
r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_SDMA0, SDMA0_4_0__SRCID__SDMA_TRAP, for (i = 0; i < adev->sdma.num_instances; i++) {
&adev->sdma.trap_irq); r = amdgpu_irq_add_id(adev, sdma_v4_0_seq_to_irq_id(i),
if (r) SDMA0_4_0__SRCID__SDMA_TRAP,
return r; &adev->sdma.trap_irq);
if (r)
/* SDMA trap event */ return r;
r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_SDMA1, SDMA1_4_0__SRCID__SDMA_TRAP, }
&adev->sdma.trap_irq);
if (r)
return r;
/* SDMA SRAM ECC event */ /* SDMA SRAM ECC event */
r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_SDMA0, SDMA0_4_0__SRCID__SDMA_SRAM_ECC, r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_SDMA0, SDMA0_4_0__SRCID__SDMA_SRAM_ECC,
...@@ -1641,11 +1708,8 @@ static int sdma_v4_0_sw_init(void *handle) ...@@ -1641,11 +1708,8 @@ static int sdma_v4_0_sw_init(void *handle)
ring->doorbell_index = adev->doorbell_index.sdma_engine[i] << 1; ring->doorbell_index = adev->doorbell_index.sdma_engine[i] << 1;
sprintf(ring->name, "sdma%d", i); sprintf(ring->name, "sdma%d", i);
r = amdgpu_ring_init(adev, ring, 1024, r = amdgpu_ring_init(adev, ring, 1024, &adev->sdma.trap_irq,
&adev->sdma.trap_irq, AMDGPU_SDMA_IRQ_INSTANCE0 + i);
(i == 0) ?
AMDGPU_SDMA_IRQ_INSTANCE0 :
AMDGPU_SDMA_IRQ_INSTANCE1);
if (r) if (r)
return r; return r;
...@@ -1776,15 +1840,17 @@ static bool sdma_v4_0_is_idle(void *handle) ...@@ -1776,15 +1840,17 @@ static bool sdma_v4_0_is_idle(void *handle)
static int sdma_v4_0_wait_for_idle(void *handle) static int sdma_v4_0_wait_for_idle(void *handle)
{ {
unsigned i; unsigned i, j;
u32 sdma0, sdma1; u32 sdma[AMDGPU_MAX_SDMA_INSTANCES];
struct amdgpu_device *adev = (struct amdgpu_device *)handle; struct amdgpu_device *adev = (struct amdgpu_device *)handle;
for (i = 0; i < adev->usec_timeout; i++) { for (i = 0; i < adev->usec_timeout; i++) {
sdma0 = RREG32_SDMA(0, mmSDMA0_STATUS_REG); for (j = 0; j < adev->sdma.num_instances; j++) {
sdma1 = RREG32_SDMA(1, mmSDMA0_STATUS_REG); sdma[j] = RREG32_SDMA(j, mmSDMA0_STATUS_REG);
if (!(sdma[j] & SDMA0_STATUS_REG__IDLE_MASK))
if (sdma0 & sdma1 & SDMA0_STATUS_REG__IDLE_MASK) break;
}
if (j == adev->sdma.num_instances)
return 0; return 0;
udelay(1); udelay(1);
} }
...@@ -1820,17 +1886,7 @@ static int sdma_v4_0_process_trap_irq(struct amdgpu_device *adev, ...@@ -1820,17 +1886,7 @@ static int sdma_v4_0_process_trap_irq(struct amdgpu_device *adev,
uint32_t instance; uint32_t instance;
DRM_DEBUG("IH: SDMA trap\n"); DRM_DEBUG("IH: SDMA trap\n");
switch (entry->client_id) { instance = sdma_v4_0_irq_id_to_seq(entry->client_id);
case SOC15_IH_CLIENTID_SDMA0:
instance = 0;
break;
case SOC15_IH_CLIENTID_SDMA1:
instance = 1;
break;
default:
return 0;
}
switch (entry->ring_id) { switch (entry->ring_id) {
case 0: case 0:
amdgpu_fence_process(&adev->sdma.instance[instance].ring); amdgpu_fence_process(&adev->sdma.instance[instance].ring);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment