Build and program doorbell entry control values through the common
NBIO helpers while preserving the existing nbif v6_3_1 client
routing and field values.

Signed-off-by: Hawking Zhang <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/nbif_v6_3_1.c | 317 +++++++++++++----------
 1 file changed, 187 insertions(+), 130 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/nbif_v6_3_1.c 
b/drivers/gpu/drm/amd/amdgpu/nbif_v6_3_1.c
index 766cfbde55aa..ce05f40f548a 100644
--- a/drivers/gpu/drm/amd/amdgpu/nbif_v6_3_1.c
+++ b/drivers/gpu/drm/amd/amdgpu/nbif_v6_3_1.c
@@ -30,6 +30,91 @@
 #include "ivsrcid/nbio/irqsrcs_nbif_7_4.h"
 #include <uapi/linux/kfd_ioctl.h>
 
+static const struct amdgpu_nbio_doorbell_layout
+nbif_v6_3_1_doorbell_layout = {
+       .ctrl = {
+               .enable = REG_FIELD_MASK(
+                       GDC_S2A0_S2A_DOORBELL_ENTRY_0_CTRL,
+                       S2A_DOORBELL_PORT0_ENABLE),
+               .awid = REG_FIELD_MASK(
+                       GDC_S2A0_S2A_DOORBELL_ENTRY_0_CTRL,
+                       S2A_DOORBELL_PORT0_AWID),
+               .fence_enable = REG_FIELD_MASK(
+                       GDC_S2A0_S2A_DOORBELL_ENTRY_0_CTRL,
+                       S2A_DOORBELL_PORT0_FENCE_ENABLE),
+               .range_offset = REG_FIELD_MASK(
+                       GDC_S2A0_S2A_DOORBELL_ENTRY_0_CTRL,
+                       S2A_DOORBELL_PORT0_RANGE_OFFSET),
+               .range_size = REG_FIELD_MASK(
+                       GDC_S2A0_S2A_DOORBELL_ENTRY_0_CTRL,
+                       S2A_DOORBELL_PORT0_RANGE_SIZE),
+               .disable_64bit = REG_FIELD_MASK(
+                       GDC_S2A0_S2A_DOORBELL_ENTRY_0_CTRL,
+                       S2A_DOORBELL_PORT0_64BIT_SUPPORT_DIS),
+               .deduct_range_offset = REG_FIELD_MASK(
+                       GDC_S2A0_S2A_DOORBELL_ENTRY_0_CTRL,
+                       S2A_DOORBELL_PORT0_NEED_DEDUCT_RANGE_OFFSET),
+               .drop = REG_FIELD_MASK(
+                       GDC_S2A0_S2A_DOORBELL_ENTRY_0_CTRL,
+                       S2A_DOORBELL_PORT0_DROP_EN),
+               .awaddr_31_28 = REG_FIELD_MASK(
+                       GDC_S2A0_S2A_DOORBELL_ENTRY_0_CTRL,
+                       S2A_DOORBELL_PORT0_AWADDR_31_28_VALUE),
+       },
+};
+
+static void nbif_v6_3_1_init_doorbell_entry_registers(
+       struct amdgpu_device *adev)
+{
+       struct amdgpu_nbio_doorbell_entries *entries;
+       u32 ctrl_base;
+
+       memset(adev->nbio.doorbell_entries, 0,
+              sizeof(adev->nbio.doorbell_entries));
+       adev->nbio.doorbell_layout = &nbif_v6_3_1_doorbell_layout;
+
+       ctrl_base = SOC15_REG_OFFSET(
+               NBIO, 0, regGDC_S2A0_S2A_DOORBELL_ENTRY_0_CTRL);
+
+       entries = &adev->nbio.doorbell_entries[
+               AMDGPU_NBIO_DOORBELL_CLIENT_CP];
+       entries->num_entries = 1;
+       entries->entry[0].port = 0;
+       entries->entry[0].ctrl_reg = ctrl_base;
+
+       entries = &adev->nbio.doorbell_entries[
+               AMDGPU_NBIO_DOORBELL_CLIENT_IH];
+       entries->num_entries = 1;
+       entries->entry[0].port = 1;
+       entries->entry[0].ctrl_reg = ctrl_base + 1;
+
+       entries = &adev->nbio.doorbell_entries[
+               AMDGPU_NBIO_DOORBELL_CLIENT_SDMA];
+       entries->num_entries = 1;
+       entries->entry[0].port = 2;
+       entries->entry[0].ctrl_reg = ctrl_base + 2;
+
+       entries = &adev->nbio.doorbell_entries[
+               AMDGPU_NBIO_DOORBELL_CLIENT_RLC];
+       entries->num_entries = 1;
+       entries->entry[0].port = 3;
+       entries->entry[0].ctrl_reg = ctrl_base + 3;
+
+       entries = &adev->nbio.doorbell_entries[
+               AMDGPU_NBIO_DOORBELL_CLIENT_VCN];
+       entries->num_entries = 2;
+       entries->entry[0].port = 4;
+       entries->entry[0].ctrl_reg = ctrl_base + 4;
+       entries->entry[1].port = 5;
+       entries->entry[1].ctrl_reg = ctrl_base + 5;
+
+       entries = &adev->nbio.doorbell_entries[
+               AMDGPU_NBIO_DOORBELL_CLIENT_VPE];
+       entries->num_entries = 1;
+       entries->entry[0].port = 5;
+       entries->entry[0].ctrl_reg = ctrl_base + 5;
+}
+
 static void nbif_v6_3_1_remap_hdp_registers(struct amdgpu_device *adev)
 {
        WREG32_SOC15(NBIO, 0, regBIF_BX0_REMAP_HDP_MEM_FLUSH_CNTL,
@@ -70,84 +155,59 @@ static void nbif_v6_3_1_sdma_doorbell_range(struct 
amdgpu_device *adev,
                                            int doorbell_index,
                                            int doorbell_size)
 {
-       if (instance == 0) {
-               u32 doorbell_range = RREG32_SOC15(NBIO, 0, 
regGDC_S2A0_S2A_DOORBELL_ENTRY_2_CTRL);
-
-               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,
-                                                      0xe);
-                       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,
-                                                      doorbell_size);
-                       doorbell_range = REG_SET_FIELD(doorbell_range,
-                                                      
GDC_S2A0_S2A_DOORBELL_ENTRY_2_CTRL,
-                                                      
S2A_DOORBELL_PORT2_AWADDR_31_28_VALUE,
-                                                      0x3);
-               } else
-                       doorbell_range = REG_SET_FIELD(doorbell_range,
-                                                      
GDC_S2A0_S2A_DOORBELL_ENTRY_2_CTRL,
-                                                      
S2A_DOORBELL_PORT2_RANGE_SIZE,
-                                                      0);
-
-               WREG32_SOC15(NBIO, 0, regGDC_S2A0_S2A_DOORBELL_ENTRY_2_CTRL,
-                            doorbell_range);
+       const struct amdgpu_nbio_doorbell_fields fields = {
+               .enable = true,
+               .awid = 0xe,
+               .range_offset = doorbell_index,
+               .range_size = doorbell_size,
+               .awaddr_31_28 = 0x3,
+       };
+       u32 ctrl;
+
+       if (instance != 0)
+               return;
+
+       if (!use_doorbell) {
+               amdgpu_nbio_program_doorbell_entry(adev,
+                       AMDGPU_NBIO_DOORBELL_CLIENT_SDMA, instance,
+                       NULL, NULL);
+               return;
        }
+
+       if (WARN_ON_ONCE(amdgpu_nbio_build_doorbell_entry(
+                               adev, &fields, &ctrl, NULL)))
+               return;
+
+       amdgpu_nbio_program_doorbell_entry(adev,
+               AMDGPU_NBIO_DOORBELL_CLIENT_SDMA, instance, &ctrl, NULL);
 }
 
 static void nbif_v6_3_1_vcn_doorbell_range(struct amdgpu_device *adev,
                                           bool use_doorbell, int 
doorbell_index,
                                           int instance)
 {
-       u32 doorbell_range;
-
-       if (instance) {
-               doorbell_range = RREG32_SOC15(NBIO, 0, 
regGDC_S2A0_S2A_DOORBELL_ENTRY_5_CTRL);
-       } else {
-               doorbell_range = RREG32_SOC15(NBIO, 0, 
regGDC_S2A0_S2A_DOORBELL_ENTRY_4_CTRL);
+       struct amdgpu_nbio_doorbell_fields fields = {
+               .enable = true,
+               .range_offset = doorbell_index,
+               .range_size = 8,
+       };
+       u32 ctrl, entry = !!instance;
+
+       if (!use_doorbell) {
+               amdgpu_nbio_program_doorbell_entry(adev,
+                       AMDGPU_NBIO_DOORBELL_CLIENT_VCN, entry,
+                       NULL, NULL);
+               return;
        }
 
-       if (use_doorbell) {
-               doorbell_range = REG_SET_FIELD(doorbell_range,
-                                              
GDC_S2A0_S2A_DOORBELL_ENTRY_4_CTRL,
-                                              S2A_DOORBELL_PORT4_ENABLE,
-                                              0x1);
-               doorbell_range = REG_SET_FIELD(doorbell_range,
-                                              
GDC_S2A0_S2A_DOORBELL_ENTRY_4_CTRL,
-                                              S2A_DOORBELL_PORT4_AWID,
-                                              instance ? 0x7 : 0x4);
-               doorbell_range = REG_SET_FIELD(doorbell_range,
-                                              
GDC_S2A0_S2A_DOORBELL_ENTRY_4_CTRL,
-                                              S2A_DOORBELL_PORT4_RANGE_OFFSET,
-                                              doorbell_index);
-               doorbell_range = REG_SET_FIELD(doorbell_range,
-                                              
GDC_S2A0_S2A_DOORBELL_ENTRY_4_CTRL,
-                                              S2A_DOORBELL_PORT4_RANGE_SIZE,
-                                              8);
-               doorbell_range = REG_SET_FIELD(doorbell_range,
-                                              
GDC_S2A0_S2A_DOORBELL_ENTRY_4_CTRL,
-                                              
S2A_DOORBELL_PORT4_AWADDR_31_28_VALUE,
-                                              instance ? 0x7 : 0x4);
-       } else
-               doorbell_range = REG_SET_FIELD(doorbell_range,
-                                              
GDC_S2A0_S2A_DOORBELL_ENTRY_4_CTRL,
-                                              S2A_DOORBELL_PORT4_RANGE_SIZE,
-                                              0);
+       fields.awid = instance ? 0x7 : 0x4;
+       fields.awaddr_31_28 = fields.awid;
+       if (WARN_ON_ONCE(amdgpu_nbio_build_doorbell_entry(
+                               adev, &fields, &ctrl, NULL)))
+               return;
 
-       if (instance)
-               WREG32_SOC15(NBIO, 0, regGDC_S2A0_S2A_DOORBELL_ENTRY_5_CTRL, 
doorbell_range);
-       else
-               WREG32_SOC15(NBIO, 0, regGDC_S2A0_S2A_DOORBELL_ENTRY_4_CTRL, 
doorbell_range);
+       amdgpu_nbio_program_doorbell_entry(adev,
+               AMDGPU_NBIO_DOORBELL_CLIENT_VCN, entry, &ctrl, NULL);
 }
 
 static void nbif_v6_3_1_vpe_doorbell_range(struct amdgpu_device *adev,
@@ -155,47 +215,54 @@ static void nbif_v6_3_1_vpe_doorbell_range(struct 
amdgpu_device *adev,
                                                        int doorbell_index,
                                                        int doorbell_size)
 {
+       const struct amdgpu_nbio_doorbell_fields fields = {
+               .enable = true,
+               .awid = 0xf,
+               .range_offset = doorbell_index,
+               .range_size = doorbell_size,
+               .awaddr_31_28 = 0xf,
+       };
+       u32 ctrl;
+
        if (instance)
                return;
 
-       u32 doorbell_range = RREG32_SOC15(NBIO, 0, 
regGDC_S2A0_S2A_DOORBELL_ENTRY_5_CTRL);
-
-       if (use_doorbell) {
-               doorbell_range = REG_SET_FIELD(doorbell_range,
-                                              
GDC_S2A0_S2A_DOORBELL_ENTRY_5_CTRL,
-                                              S2A_DOORBELL_PORT5_ENABLE,
-                                              0x1);
-               doorbell_range = REG_SET_FIELD(doorbell_range,
-                                              
GDC_S2A0_S2A_DOORBELL_ENTRY_5_CTRL,
-                                              S2A_DOORBELL_PORT5_AWID,
-                                              0xf);
-               doorbell_range = REG_SET_FIELD(doorbell_range,
-                                              
GDC_S2A0_S2A_DOORBELL_ENTRY_5_CTRL,
-                                              S2A_DOORBELL_PORT5_RANGE_OFFSET,
-                                              doorbell_index);
-               doorbell_range = REG_SET_FIELD(doorbell_range,
-                                              
GDC_S2A0_S2A_DOORBELL_ENTRY_5_CTRL,
-                                              S2A_DOORBELL_PORT5_RANGE_SIZE,
-                                              doorbell_size);
-               doorbell_range = REG_SET_FIELD(doorbell_range,
-                                              
GDC_S2A0_S2A_DOORBELL_ENTRY_5_CTRL,
-                                              
S2A_DOORBELL_PORT5_AWADDR_31_28_VALUE,
-                                              0xf);
-       } else {
-               doorbell_range = REG_SET_FIELD(doorbell_range,
-                                              
GDC_S2A0_S2A_DOORBELL_ENTRY_5_CTRL,
-                                              S2A_DOORBELL_PORT5_RANGE_SIZE,
-                                              0);
+       if (!use_doorbell) {
+               amdgpu_nbio_program_doorbell_entry(adev,
+                       AMDGPU_NBIO_DOORBELL_CLIENT_VPE, instance,
+                       NULL, NULL);
+               return;
        }
 
-       WREG32_SOC15(NBIO, 0, regGDC_S2A0_S2A_DOORBELL_ENTRY_5_CTRL, 
doorbell_range);
+       if (WARN_ON_ONCE(amdgpu_nbio_build_doorbell_entry(
+                               adev, &fields, &ctrl, NULL)))
+               return;
 
+       amdgpu_nbio_program_doorbell_entry(adev,
+               AMDGPU_NBIO_DOORBELL_CLIENT_VPE, instance, &ctrl, NULL);
 }
 
 static void nbif_v6_3_1_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_3_CTRL, 
0x3000000d);
+       struct amdgpu_nbio_doorbell_fields fields = {
+               .enable = true,
+               .awaddr_31_28 = 0x3,
+       };
+       u32 ctrl;
+
+       fields.awid = 0x3;
+       if (WARN_ON_ONCE(amdgpu_nbio_build_doorbell_entry(
+                               adev, &fields, &ctrl, NULL)))
+               return;
+       amdgpu_nbio_program_doorbell_entry(adev,
+               AMDGPU_NBIO_DOORBELL_CLIENT_CP, 0, &ctrl, NULL);
+
+       fields.awid = 0x6;
+       if (WARN_ON_ONCE(amdgpu_nbio_build_doorbell_entry(
+                               adev, &fields, &ctrl, NULL)))
+               return;
+       amdgpu_nbio_program_doorbell_entry(adev,
+               AMDGPU_NBIO_DOORBELL_CLIENT_RLC, 0, &ctrl, NULL);
 }
 
 static void nbif_v6_3_1_enable_doorbell_aperture(struct amdgpu_device *adev,
@@ -231,37 +298,25 @@ nbif_v6_3_1_enable_doorbell_selfring_aperture(struct 
amdgpu_device *adev,
 static void nbif_v6_3_1_ih_doorbell_range(struct amdgpu_device *adev,
                                          bool use_doorbell, int doorbell_index)
 {
-       u32 ih_doorbell_range = RREG32_SOC15(NBIO, 0, 
regGDC_S2A0_S2A_DOORBELL_ENTRY_1_CTRL);
-
-       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);
-       } else
-               ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range,
-                                                 
GDC_S2A0_S2A_DOORBELL_ENTRY_1_CTRL,
-                                                 S2A_DOORBELL_PORT1_RANGE_SIZE,
-                                                 0);
-
-       WREG32_SOC15(NBIO, 0, regGDC_S2A0_S2A_DOORBELL_ENTRY_1_CTRL,
-                    ih_doorbell_range);
+       const struct amdgpu_nbio_doorbell_fields fields = {
+               .enable = true,
+               .range_offset = doorbell_index,
+               .range_size = 8,
+       };
+       u32 ctrl;
+
+       if (!use_doorbell) {
+               amdgpu_nbio_program_doorbell_entry(adev,
+                       AMDGPU_NBIO_DOORBELL_CLIENT_IH, 0, NULL, NULL);
+               return;
+       }
+
+       if (WARN_ON_ONCE(amdgpu_nbio_build_doorbell_entry(
+                               adev, &fields, &ctrl, NULL)))
+               return;
+
+       amdgpu_nbio_program_doorbell_entry(adev,
+               AMDGPU_NBIO_DOORBELL_CLIENT_IH, 0, &ctrl, NULL);
 }
 
 static void nbif_v6_3_1_ih_control(struct amdgpu_device *adev)
@@ -343,6 +398,8 @@ static void nbif_v6_3_1_init_registers(struct amdgpu_device 
*adev)
 {
        uint32_t data;
 
+       nbif_v6_3_1_init_doorbell_entry_registers(adev);
+
        data = RREG32_SOC15(NBIO, 0, regRCC_DEV0_EPF2_STRAP2);
        data &= ~RCC_DEV0_EPF2_STRAP2__STRAP_NO_SOFT_RESET_DEV0_F2_MASK;
        WREG32_SOC15(NBIO, 0, regRCC_DEV0_EPF2_STRAP2, data);
-- 
2.17.1

Reply via email to