mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-24 15:02:54 -04:00
drm/amdgpu: add doorbell range function for nbio v6_3_2
Add doorbell range and ih control related function for NBIO version 6.3.2. v2: squash in doorbell range fixes v3: squash in xcd doorbell fix Signed-off-by: Likun Gao <Likun.Gao@amd.com> Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
@@ -71,6 +71,13 @@ static void nbio_v6_3_2_mc_access_enable(struct amdgpu_device *adev,
|
||||
WREG32_SOC15(NBIO, 0, regBIF_BX0_BIF_FB_EN, 0);
|
||||
}
|
||||
|
||||
static void nbio_v6_3_2_init_registers(struct amdgpu_device *adev)
|
||||
{
|
||||
WREG32_SOC15(NBIO, 0, regXCD_DOORBELL_FENCE_1,
|
||||
(0xff & ~(adev->gfx.xcc_mask)) <<
|
||||
XCD_DOORBELL_FENCE_1__XCD_0_DOORBELL_DISABLE__SHIFT);
|
||||
}
|
||||
|
||||
static u32 nbio_v6_3_2_get_memsize(struct amdgpu_device *adev)
|
||||
{
|
||||
return RREG32_SOC15(NBIO, 0, regRCC_DEV0_EPF0_RCC_CONFIG_MEMSIZE);
|
||||
@@ -114,6 +121,194 @@ static void nbio_v6_3_2_enable_doorbell_interrupt(struct amdgpu_device *adev,
|
||||
DOORBELL_INTERRUPT_DISABLE, enable ? 0 : 1);
|
||||
}
|
||||
|
||||
static void nbio_v6_3_2_ih_control(struct amdgpu_device *adev)
|
||||
{
|
||||
u32 interrupt_cntl;
|
||||
|
||||
/* setup interrupt control */
|
||||
WREG32_SOC15(NBIO, 0, regBIF_BX0_INTERRUPT_CNTL2, adev->dummy_page_addr >> 8);
|
||||
|
||||
interrupt_cntl = RREG32_SOC15(NBIO, 0, regBIF_BX0_INTERRUPT_CNTL);
|
||||
/*
|
||||
* BIF_BX0_INTERRUPT_CNTL__IH_DUMMY_RD_OVERRIDE_MASK=0 - dummy read disabled with msi, enabled without msi
|
||||
* BIF_BX0_INTERRUPT_CNTL__IH_DUMMY_RD_OVERRIDE_MASK=1 - dummy read controlled by IH_DUMMY_RD_EN
|
||||
*/
|
||||
interrupt_cntl = REG_SET_FIELD(interrupt_cntl, BIF_BX0_INTERRUPT_CNTL,
|
||||
IH_DUMMY_RD_OVERRIDE, 0);
|
||||
|
||||
/* BIF_BX0_INTERRUPT_CNTL__IH_REQ_NONSNOOP_EN_MASK=1 if ring is in non-cacheable memory, e.g., vram */
|
||||
interrupt_cntl = REG_SET_FIELD(interrupt_cntl, BIF_BX0_INTERRUPT_CNTL,
|
||||
IH_REQ_NONSNOOP_EN, 0);
|
||||
|
||||
WREG32_SOC15(NBIO, 0, regBIF_BX0_INTERRUPT_CNTL, interrupt_cntl);
|
||||
}
|
||||
|
||||
static void nbio_v6_3_2_ih_doorbell_range(struct amdgpu_device *adev,
|
||||
bool use_doorbell, int doorbell_index)
|
||||
{
|
||||
u32 ih_doorbell_range = 0;
|
||||
u32 ih_doorbell_range1 = 0;
|
||||
|
||||
if (use_doorbell) {
|
||||
ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range,
|
||||
GDC_S2A0_S2A_DOORBELL_ENTRY_1_CTRL,
|
||||
S2A_DOORBELL_PORT1_ENABLE,
|
||||
0x1);
|
||||
ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range,
|
||||
GDC_S2A0_S2A_DOORBELL_ENTRY_1_CTRL,
|
||||
S2A_DOORBELL_PORT1_AWID,
|
||||
0x0);
|
||||
ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range,
|
||||
GDC_S2A0_S2A_DOORBELL_ENTRY_1_CTRL,
|
||||
S2A_DOORBELL_PORT1_RANGE_OFFSET,
|
||||
doorbell_index);
|
||||
ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range,
|
||||
GDC_S2A0_S2A_DOORBELL_ENTRY_1_CTRL,
|
||||
S2A_DOORBELL_PORT1_RANGE_SIZE,
|
||||
8);
|
||||
ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range,
|
||||
GDC_S2A0_S2A_DOORBELL_ENTRY_1_CTRL,
|
||||
S2A_DOORBELL_PORT1_AWADDR_31_28_VALUE,
|
||||
0x0);
|
||||
ih_doorbell_range1 = REG_SET_FIELD(ih_doorbell_range1,
|
||||
GDC_S2A0_S2A_DOORBELL_ENTRY_1_CTRL1,
|
||||
S2A_DOORBELL_PORT1_TARGET_PORT_TYPE,
|
||||
0x3);
|
||||
ih_doorbell_range1 = REG_SET_FIELD(ih_doorbell_range1,
|
||||
GDC_S2A0_S2A_DOORBELL_ENTRY_1_CTRL1,
|
||||
S2A_DOORBELL_PORT1_TARGET_DIEID,
|
||||
0x0);
|
||||
ih_doorbell_range1 = REG_SET_FIELD(ih_doorbell_range1,
|
||||
GDC_S2A0_S2A_DOORBELL_ENTRY_1_CTRL1,
|
||||
S2A_DOORBELL_PORT1_TARGET_PORT_ID,
|
||||
0x0);
|
||||
}
|
||||
|
||||
WREG32_SOC15(NBIO, 0, regGDC_S2A0_S2A_DOORBELL_ENTRY_1_CTRL, ih_doorbell_range);
|
||||
WREG32_SOC15(NBIO, 0, regGDC_S2A0_S2A_DOORBELL_ENTRY_1_CTRL1, ih_doorbell_range1);
|
||||
}
|
||||
|
||||
static void nbio_v6_3_2_gc_doorbell_init(struct amdgpu_device *adev)
|
||||
{
|
||||
WREG32_SOC15(NBIO, 0, regGDC_S2A0_S2A_DOORBELL_ENTRY_0_CTRL, 0x30000007);
|
||||
WREG32_SOC15(NBIO, 0, regGDC_S2A0_S2A_DOORBELL_ENTRY_0_CTRL1, 0x3);
|
||||
}
|
||||
|
||||
static void nbio_v6_3_2_sdma_doorbell_range(struct amdgpu_device *adev,
|
||||
int instance, bool use_doorbell,
|
||||
int doorbell_index,
|
||||
int doorbell_size)
|
||||
{
|
||||
if (instance == 0) {
|
||||
u32 doorbell_range = 0;
|
||||
u32 doorbell_range1 = 0;
|
||||
|
||||
if (use_doorbell) {
|
||||
doorbell_range = REG_SET_FIELD(doorbell_range,
|
||||
GDC_S2A0_S2A_DOORBELL_ENTRY_6_CTRL,
|
||||
S2A_DOORBELL_PORT6_ENABLE,
|
||||
0x1);
|
||||
doorbell_range = REG_SET_FIELD(doorbell_range,
|
||||
GDC_S2A0_S2A_DOORBELL_ENTRY_6_CTRL,
|
||||
S2A_DOORBELL_PORT6_AWID,
|
||||
0xe);
|
||||
doorbell_range = REG_SET_FIELD(doorbell_range,
|
||||
GDC_S2A0_S2A_DOORBELL_ENTRY_6_CTRL,
|
||||
S2A_DOORBELL_PORT6_RANGE_OFFSET,
|
||||
doorbell_index);
|
||||
doorbell_range = REG_SET_FIELD(doorbell_range,
|
||||
GDC_S2A0_S2A_DOORBELL_ENTRY_6_CTRL,
|
||||
S2A_DOORBELL_PORT6_RANGE_SIZE,
|
||||
doorbell_size);
|
||||
doorbell_range = REG_SET_FIELD(doorbell_range,
|
||||
GDC_S2A0_S2A_DOORBELL_ENTRY_6_CTRL,
|
||||
S2A_DOORBELL_PORT6_AWADDR_31_28_VALUE,
|
||||
0xe);
|
||||
doorbell_range1 = REG_SET_FIELD(doorbell_range1,
|
||||
GDC_S2A0_S2A_DOORBELL_ENTRY_6_CTRL1,
|
||||
S2A_DOORBELL_PORT6_TARGET_PORT_TYPE,
|
||||
0x3);
|
||||
doorbell_range1 = REG_SET_FIELD(doorbell_range1,
|
||||
GDC_S2A0_S2A_DOORBELL_ENTRY_6_CTRL1,
|
||||
S2A_DOORBELL_PORT6_TARGET_DIEID,
|
||||
0x0);
|
||||
doorbell_range1 = REG_SET_FIELD(doorbell_range1,
|
||||
GDC_S2A0_S2A_DOORBELL_ENTRY_6_CTRL1,
|
||||
S2A_DOORBELL_PORT6_TARGET_PORT_ID,
|
||||
0x0);
|
||||
}
|
||||
|
||||
WREG32_SOC15(NBIO, 0, regGDC_S2A0_S2A_DOORBELL_ENTRY_6_CTRL, doorbell_range);
|
||||
WREG32_SOC15(NBIO, 0, regGDC_S2A0_S2A_DOORBELL_ENTRY_6_CTRL1, doorbell_range1);
|
||||
}
|
||||
}
|
||||
|
||||
static void nbio_v6_3_2_vcn_doorbell_range(struct amdgpu_device *adev,
|
||||
bool use_doorbell, int doorbell_index,
|
||||
int instance)
|
||||
{
|
||||
u32 doorbell_range = 0;
|
||||
u32 doorbell_range1 = 0;
|
||||
|
||||
if (use_doorbell) {
|
||||
doorbell_range = REG_SET_FIELD(doorbell_range,
|
||||
GDC_S2A0_S2A_DOORBELL_ENTRY_2_CTRL,
|
||||
S2A_DOORBELL_PORT2_ENABLE,
|
||||
0x1);
|
||||
doorbell_range = REG_SET_FIELD(doorbell_range,
|
||||
GDC_S2A0_S2A_DOORBELL_ENTRY_2_CTRL,
|
||||
S2A_DOORBELL_PORT2_AWID,
|
||||
(instance % adev->vcn.num_inst_per_aid) ? 0x7 : 0x4);
|
||||
doorbell_range = REG_SET_FIELD(doorbell_range,
|
||||
GDC_S2A0_S2A_DOORBELL_ENTRY_2_CTRL,
|
||||
S2A_DOORBELL_PORT2_RANGE_OFFSET,
|
||||
doorbell_index);
|
||||
doorbell_range = REG_SET_FIELD(doorbell_range,
|
||||
GDC_S2A0_S2A_DOORBELL_ENTRY_2_CTRL,
|
||||
S2A_DOORBELL_PORT2_RANGE_SIZE,
|
||||
8);
|
||||
doorbell_range = REG_SET_FIELD(doorbell_range,
|
||||
GDC_S2A0_S2A_DOORBELL_ENTRY_2_CTRL,
|
||||
S2A_DOORBELL_PORT2_AWADDR_31_28_VALUE,
|
||||
(instance % adev->vcn.num_inst_per_aid) ? 0x7 : 0x4);
|
||||
doorbell_range1 = REG_SET_FIELD(doorbell_range1,
|
||||
GDC_S2A0_S2A_DOORBELL_ENTRY_2_CTRL1,
|
||||
S2A_DOORBELL_PORT2_TARGET_PORT_TYPE,
|
||||
0x3);
|
||||
doorbell_range1 = REG_SET_FIELD(doorbell_range1,
|
||||
GDC_S2A0_S2A_DOORBELL_ENTRY_2_CTRL1,
|
||||
S2A_DOORBELL_PORT2_TARGET_DIEID,
|
||||
(instance / adev->vcn.num_inst_per_aid) ? 0x3 : 0x0);
|
||||
doorbell_range1 = REG_SET_FIELD(doorbell_range1,
|
||||
GDC_S2A0_S2A_DOORBELL_ENTRY_2_CTRL1,
|
||||
S2A_DOORBELL_PORT2_TARGET_PORT_ID,
|
||||
0x0);
|
||||
}
|
||||
|
||||
switch (instance) {
|
||||
case 0:
|
||||
WREG32_SOC15(NBIO, 0, regGDC_S2A0_S2A_DOORBELL_ENTRY_2_CTRL, doorbell_range);
|
||||
WREG32_SOC15(NBIO, 0, regGDC_S2A0_S2A_DOORBELL_ENTRY_2_CTRL1, doorbell_range1);
|
||||
break;
|
||||
case 1:
|
||||
WREG32_SOC15(NBIO, 0, regGDC_S2A0_S2A_DOORBELL_ENTRY_3_CTRL, doorbell_range);
|
||||
WREG32_SOC15(NBIO, 0, regGDC_S2A0_S2A_DOORBELL_ENTRY_3_CTRL1, doorbell_range1);
|
||||
break;
|
||||
case 2:
|
||||
WREG32_SOC15(NBIO, 0, regGDC_S2A0_S2A_DOORBELL_ENTRY_4_CTRL, doorbell_range);
|
||||
WREG32_SOC15(NBIO, 0, regGDC_S2A0_S2A_DOORBELL_ENTRY_4_CTRL1, doorbell_range1);
|
||||
break;
|
||||
case 3:
|
||||
WREG32_SOC15(NBIO, 0, regGDC_S2A0_S2A_DOORBELL_ENTRY_5_CTRL, doorbell_range);
|
||||
WREG32_SOC15(NBIO, 0, regGDC_S2A0_S2A_DOORBELL_ENTRY_5_CTRL1, doorbell_range1);
|
||||
break;
|
||||
default:
|
||||
dev_err(adev->dev,
|
||||
"amdgpu: invalid vcn instance set when program doorbell range\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int nbio_v6_3_2_get_compute_partition_mode(struct amdgpu_device *adev)
|
||||
{
|
||||
u32 tmp, px;
|
||||
@@ -165,4 +360,10 @@ const struct amdgpu_nbio_funcs nbio_v6_3_2_funcs = {
|
||||
.get_compute_partition_mode = nbio_v6_3_2_get_compute_partition_mode,
|
||||
.get_memory_partition_mode = nbio_v6_3_2_get_memory_partition_mode,
|
||||
.is_nps_switch_requested = nbio_v6_3_2_is_nps_switch_requested,
|
||||
.ih_control = nbio_v6_3_2_ih_control,
|
||||
.ih_doorbell_range = nbio_v6_3_2_ih_doorbell_range,
|
||||
.gc_doorbell_init = nbio_v6_3_2_gc_doorbell_init,
|
||||
.sdma_doorbell_range = nbio_v6_3_2_sdma_doorbell_range,
|
||||
.vcn_doorbell_range = nbio_v6_3_2_vcn_doorbell_range,
|
||||
.init_registers = nbio_v6_3_2_init_registers,
|
||||
};
|
||||
|
||||
@@ -330,6 +330,8 @@ static int soc_v1_0_common_early_init(struct amdgpu_ip_block *ip_block)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
adev->nbio.funcs->init_registers(adev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user