]> Git Repo - J-linux.git/blobdiff - drivers/gpu/drm/amd/amdgpu/soc15.c
Merge tag 'kvmarm-fixes-for-5.3' of git://git.kernel.org/pub/scm/linux/kernel/git...
[J-linux.git] / drivers / gpu / drm / amd / amdgpu / soc15.c
index b7e594c2bfb431e2c4f192de5f046ffbf3a87a75..23265414d44867b81c36d85f1ef87e67013ca95f 100644 (file)
@@ -23,7 +23,8 @@
 #include <linux/firmware.h>
 #include <linux/slab.h>
 #include <linux/module.h>
-#include <drm/drmP.h>
+#include <linux/pci.h>
+
 #include "amdgpu.h"
 #include "amdgpu_atombios.h"
 #include "amdgpu_ih.h"
@@ -44,6 +45,7 @@
 #include "smuio/smuio_9_0_offset.h"
 #include "smuio/smuio_9_0_sh_mask.h"
 #include "nbio/nbio_7_0_default.h"
+#include "nbio/nbio_7_0_offset.h"
 #include "nbio/nbio_7_0_sh_mask.h"
 #include "nbio/nbio_7_0_smn.h"
 #include "mp/mp_9_0_offset.h"
@@ -64,6 +66,9 @@
 #include "dce_virtual.h"
 #include "mxgpu_ai.h"
 #include "amdgpu_smu.h"
+#include "amdgpu_ras.h"
+#include "amdgpu_xgmi.h"
+#include <uapi/linux/kfd_ioctl.h>
 
 #define mmMP0_MISC_CGTT_CTRL0                                                                   0x01b9
 #define mmMP0_MISC_CGTT_CTRL0_BASE_IDX                                                          0
@@ -230,7 +235,7 @@ void soc15_grbm_select(struct amdgpu_device *adev,
        grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, VMID, vmid);
        grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, QUEUEID, queue);
 
-       WREG32(SOC15_REG_OFFSET(GC, 0, mmGRBM_GFX_CNTL), grbm_gfx_cntl);
+       WREG32_SOC15_RLC_SHADOW(GC, 0, mmGRBM_GFX_CNTL, grbm_gfx_cntl);
 }
 
 static void soc15_vga_set_state(struct amdgpu_device *adev, bool state)
@@ -270,15 +275,6 @@ static bool soc15_read_bios_from_rom(struct amdgpu_device *adev,
        return true;
 }
 
-struct soc15_allowed_register_entry {
-       uint32_t hwip;
-       uint32_t inst;
-       uint32_t seg;
-       uint32_t reg_offset;
-       bool grbm_indexed;
-};
-
-
 static struct soc15_allowed_register_entry soc15_allowed_read_registers[] = {
        { SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS)},
        { SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS2)},
@@ -383,9 +379,17 @@ void soc15_program_register_sequence(struct amdgpu_device *adev,
                } else {
                        tmp = RREG32(reg);
                        tmp &= ~(entry->and_mask);
-                       tmp |= entry->or_mask;
+                       tmp |= (entry->or_mask & entry->and_mask);
                }
-               WREG32(reg, tmp);
+
+               if (reg == SOC15_REG_OFFSET(GC, 0, mmPA_SC_BINNER_EVENT_CNTL_3) ||
+                       reg == SOC15_REG_OFFSET(GC, 0, mmPA_SC_ENHANCE) ||
+                       reg == SOC15_REG_OFFSET(GC, 0, mmPA_SC_ENHANCE_1) ||
+                       reg == SOC15_REG_OFFSET(GC, 0, mmSH_MEM_CONFIG))
+                       WREG32_RLC(reg, tmp);
+               else
+                       WREG32(reg, tmp);
+
        }
 
 }
@@ -475,6 +479,13 @@ static int soc15_asic_reset(struct amdgpu_device *adev)
                        soc15_asic_get_baco_capability(adev, &baco_reset);
                else
                        baco_reset = false;
+               if (baco_reset) {
+                       struct amdgpu_hive_info *hive = amdgpu_get_xgmi_hive(adev, 0);
+                       struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
+
+                       if (hive || (ras && ras->supported))
+                               baco_reset = false;
+               }
                break;
        default:
                baco_reset = false;
@@ -606,12 +617,24 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
        case CHIP_VEGA20:
                amdgpu_device_ip_block_add(adev, &vega10_common_ip_block);
                amdgpu_device_ip_block_add(adev, &gmc_v9_0_ip_block);
-               amdgpu_device_ip_block_add(adev, &vega10_ih_ip_block);
-               if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) {
-                       if (adev->asic_type == CHIP_VEGA20)
-                               amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block);
-                       else
-                               amdgpu_device_ip_block_add(adev, &psp_v3_1_ip_block);
+
+               /* For Vega10 SR-IOV, PSP need to be initialized before IH */
+               if (amdgpu_sriov_vf(adev)) {
+                       if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) {
+                               if (adev->asic_type == CHIP_VEGA20)
+                                       amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block);
+                               else
+                                       amdgpu_device_ip_block_add(adev, &psp_v3_1_ip_block);
+                       }
+                       amdgpu_device_ip_block_add(adev, &vega10_ih_ip_block);
+               } else {
+                       amdgpu_device_ip_block_add(adev, &vega10_ih_ip_block);
+                       if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) {
+                               if (adev->asic_type == CHIP_VEGA20)
+                                       amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block);
+                               else
+                                       amdgpu_device_ip_block_add(adev, &psp_v3_1_ip_block);
+                       }
                }
                amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block);
                amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block);
@@ -626,8 +649,6 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
 #if defined(CONFIG_DRM_AMD_DC)
                else if (amdgpu_device_has_dc_support(adev))
                        amdgpu_device_ip_block_add(adev, &dm_ip_block);
-#else
-#      warning "Enable CONFIG_DRM_AMD_DC for display support on SOC15."
 #endif
                if (!(adev->asic_type == CHIP_VEGA20 && amdgpu_sriov_vf(adev))) {
                        amdgpu_device_ip_block_add(adev, &uvd_v7_0_ip_block);
@@ -648,8 +669,6 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
 #if defined(CONFIG_DRM_AMD_DC)
                else if (amdgpu_device_has_dc_support(adev))
                        amdgpu_device_ip_block_add(adev, &dm_ip_block);
-#else
-#      warning "Enable CONFIG_DRM_AMD_DC for display support on SOC15."
 #endif
                amdgpu_device_ip_block_add(adev, &vcn_v1_0_ip_block);
                break;
@@ -690,13 +709,19 @@ static void soc15_get_pcie_usage(struct amdgpu_device *adev, uint64_t *count0,
        /* This reports 0 on APUs, so return to avoid writing/reading registers
         * that may or may not be different from their GPU counterparts
         */
-        if (adev->flags & AMD_IS_APU)
-                return;
+       if (adev->flags & AMD_IS_APU)
+               return;
 
        /* Set the 2 events that we wish to watch, defined above */
-       /* Reg 40 is # received msgs, Reg 104 is # of posted requests sent */
+       /* Reg 40 is # received msgs */
        perfctr = REG_SET_FIELD(perfctr, PCIE_PERF_CNTL_TXCLK, EVENT0_SEL, 40);
-       perfctr = REG_SET_FIELD(perfctr, PCIE_PERF_CNTL_TXCLK, EVENT1_SEL, 104);
+       /* Pre-VG20, Reg 104 is # of posted requests sent. On VG20 it's 108 */
+       if (adev->asic_type == CHIP_VEGA20)
+               perfctr = REG_SET_FIELD(perfctr, PCIE_PERF_CNTL_TXCLK,
+                                       EVENT1_SEL, 108);
+       else
+               perfctr = REG_SET_FIELD(perfctr, PCIE_PERF_CNTL_TXCLK,
+                                       EVENT1_SEL, 104);
 
        /* Write to enable desired perf counters */
        WREG32_PCIE(smnPCIE_PERF_CNTL_TXCLK, perfctr);
@@ -733,7 +758,8 @@ static bool soc15_need_reset_on_init(struct amdgpu_device *adev)
        /* Just return false for soc15 GPUs.  Reset does not seem to
         * be necessary.
         */
-       return false;
+       if (!amdgpu_passthrough(adev))
+               return false;
 
        if (adev->flags & AMD_IS_APU)
                return false;
@@ -748,6 +774,18 @@ static bool soc15_need_reset_on_init(struct amdgpu_device *adev)
        return false;
 }
 
+static uint64_t soc15_get_pcie_replay_count(struct amdgpu_device *adev)
+{
+       uint64_t nak_r, nak_g;
+
+       /* Get the number of NAKs received and generated */
+       nak_r = RREG32_PCIE(smnPCIE_RX_NUM_NAK);
+       nak_g = RREG32_PCIE(smnPCIE_RX_NUM_NAK_GENERATED);
+
+       /* Add the total number of NAKs, i.e the number of replays */
+       return (nak_r + nak_g);
+}
+
 static const struct amdgpu_asic_funcs soc15_asic_funcs =
 {
        .read_disabled_bios = &soc15_read_disabled_bios,
@@ -765,6 +803,7 @@ static const struct amdgpu_asic_funcs soc15_asic_funcs =
        .init_doorbell_index = &vega10_doorbell_index_init,
        .get_pcie_usage = &soc15_get_pcie_usage,
        .need_reset_on_init = &soc15_need_reset_on_init,
+       .get_pcie_replay_count = &soc15_get_pcie_replay_count,
 };
 
 static const struct amdgpu_asic_funcs vega20_asic_funcs =
@@ -784,12 +823,16 @@ static const struct amdgpu_asic_funcs vega20_asic_funcs =
        .init_doorbell_index = &vega20_doorbell_index_init,
        .get_pcie_usage = &soc15_get_pcie_usage,
        .need_reset_on_init = &soc15_need_reset_on_init,
+       .get_pcie_replay_count = &soc15_get_pcie_replay_count,
 };
 
 static int soc15_common_early_init(void *handle)
 {
+#define MMIO_REG_HOLE_OFFSET (0x80000 - PAGE_SIZE)
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
+       adev->rmmio_remap.reg_offset = MMIO_REG_HOLE_OFFSET;
+       adev->rmmio_remap.bus_addr = adev->rmmio_base + MMIO_REG_HOLE_OFFSET;
        adev->smc_rreg = NULL;
        adev->smc_wreg = NULL;
        adev->pcie_rreg = &soc15_pcie_rreg;
@@ -985,6 +1028,8 @@ static int soc15_common_sw_init(void *handle)
        if (amdgpu_sriov_vf(adev))
                xgpu_ai_mailbox_add_irq_id(adev);
 
+       adev->df_funcs->sw_init(adev);
+
        return 0;
 }
 
@@ -998,11 +1043,17 @@ static void soc15_doorbell_range_init(struct amdgpu_device *adev)
        int i;
        struct amdgpu_ring *ring;
 
-       for (i = 0; i < adev->sdma.num_instances; i++) {
-               ring = &adev->sdma.instance[i].ring;
-               adev->nbio_funcs->sdma_doorbell_range(adev, i,
-                       ring->use_doorbell, ring->doorbell_index,
-                       adev->doorbell_index.sdma_doorbell_range);
+       /*  Two reasons to skip
+       *               1, Host driver already programmed them
+       *               2, To avoid registers program violations in SR-IOV
+       */
+       if (!amdgpu_virt_support_skip_setting(adev)) {
+               for (i = 0; i < adev->sdma.num_instances; i++) {
+                       ring = &adev->sdma.instance[i].ring;
+                       adev->nbio_funcs->sdma_doorbell_range(adev, i,
+                               ring->use_doorbell, ring->doorbell_index,
+                               adev->doorbell_index.sdma_doorbell_range);
+               }
        }
 
        adev->nbio_funcs->ih_doorbell_range(adev, adev->irq.ih.use_doorbell,
@@ -1019,6 +1070,13 @@ static int soc15_common_hw_init(void *handle)
        soc15_program_aspm(adev);
        /* setup nbio registers */
        adev->nbio_funcs->init_registers(adev);
+       /* remap HDP registers to a hole in mmio space,
+        * for the purpose of expose those registers
+        * to process space
+        */
+       if (adev->nbio_funcs->remap_hdp_registers)
+               adev->nbio_funcs->remap_hdp_registers(adev);
+
        /* enable the doorbell aperture */
        soc15_enable_doorbell_aperture(adev, true);
        /* HW doorbell routing policy: doorbell writing not
This page took 0.040892 seconds and 4 git commands to generate.