Merge tag 'drm-for-v4.15-part2' of git://people.freedesktop.org/~airlied/linux
[sfrench/cifs-2.6.git] / drivers / gpu / drm / amd / amdgpu / amdgpu_device.c
index e630d918fefc0993e540ac4ecb1734eeaaf3aec6..2c574374d9b6884e6c4473f2dd3ede86b7a612df 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/debugfs.h>
 #include <drm/drmP.h>
 #include <drm/drm_crtc_helper.h>
+#include <drm/drm_atomic_helper.h>
 #include <drm/amdgpu_drm.h>
 #include <linux/vgaarb.h>
 #include <linux/vga_switcheroo.h>
@@ -56,6 +57,7 @@
 #include "amdgpu_vf_error.h"
 
 #include "amdgpu_amdkfd.h"
+#include "amdgpu_pm.h"
 
 MODULE_FIRMWARE("amdgpu/vega10_gpu_info.bin");
 MODULE_FIRMWARE("amdgpu/raven_gpu_info.bin");
@@ -65,6 +67,7 @@ MODULE_FIRMWARE("amdgpu/raven_gpu_info.bin");
 static int amdgpu_debugfs_regs_init(struct amdgpu_device *adev);
 static void amdgpu_debugfs_regs_cleanup(struct amdgpu_device *adev);
 static int amdgpu_debugfs_test_ib_ring_init(struct amdgpu_device *adev);
+static int amdgpu_debugfs_vbios_dump_init(struct amdgpu_device *adev);
 
 static const char *amdgpu_asic_name[] = {
        "TAHITI",
@@ -107,10 +110,8 @@ uint32_t amdgpu_mm_rreg(struct amdgpu_device *adev, uint32_t reg,
 {
        uint32_t ret;
 
-       if (!(acc_flags & AMDGPU_REGS_NO_KIQ) && amdgpu_sriov_runtime(adev)) {
-               BUG_ON(in_interrupt());
+       if (!(acc_flags & AMDGPU_REGS_NO_KIQ) && amdgpu_sriov_runtime(adev))
                return amdgpu_virt_kiq_rreg(adev, reg);
-       }
 
        if ((reg * 4) < adev->rmmio_size && !(acc_flags & AMDGPU_REGS_IDX))
                ret = readl(((void __iomem *)adev->rmmio) + (reg * 4));
@@ -135,10 +136,8 @@ void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
                adev->last_mm_index = v;
        }
 
-       if (!(acc_flags & AMDGPU_REGS_NO_KIQ) && amdgpu_sriov_runtime(adev)) {
-               BUG_ON(in_interrupt());
+       if (!(acc_flags & AMDGPU_REGS_NO_KIQ) && amdgpu_sriov_runtime(adev))
                return amdgpu_virt_kiq_wreg(adev, reg, v);
-       }
 
        if ((reg * 4) < adev->rmmio_size && !(acc_flags & AMDGPU_REGS_IDX))
                writel(v, ((void __iomem *)adev->rmmio) + (reg * 4));
@@ -402,6 +401,15 @@ void amdgpu_pci_config_reset(struct amdgpu_device *adev)
  */
 static int amdgpu_doorbell_init(struct amdgpu_device *adev)
 {
+       /* No doorbell on SI hardware generation */
+       if (adev->asic_type < CHIP_BONAIRE) {
+               adev->doorbell.base = 0;
+               adev->doorbell.size = 0;
+               adev->doorbell.num_doorbells = 0;
+               adev->doorbell.ptr = NULL;
+               return 0;
+       }
+
        /* doorbell bar mapping */
        adev->doorbell.base = pci_resource_start(adev->pdev, 2);
        adev->doorbell.size = pci_resource_len(adev->pdev, 2);
@@ -539,7 +547,7 @@ int amdgpu_wb_get(struct amdgpu_device *adev, u32 *wb)
 
        if (offset < adev->wb.num_wb) {
                __set_bit(offset, adev->wb.used);
-               *wb = offset * 8; /* convert to dw offset */
+               *wb = offset << 3; /* convert to dw offset */
                return 0;
        } else {
                return -EINVAL;
@@ -557,7 +565,7 @@ int amdgpu_wb_get(struct amdgpu_device *adev, u32 *wb)
 void amdgpu_wb_free(struct amdgpu_device *adev, u32 wb)
 {
        if (wb < adev->wb.num_wb)
-               __clear_bit(wb, adev->wb.used);
+               __clear_bit(wb >> 3, adev->wb.used);
 }
 
 /**
@@ -647,42 +655,96 @@ void amdgpu_gart_location(struct amdgpu_device *adev, struct amdgpu_mc *mc)
 }
 
 /*
- * GPU helpers function.
+ * Firmware Reservation functions
  */
 /**
- * amdgpu_need_post - check if the hw need post or not
+ * amdgpu_fw_reserve_vram_fini - free fw reserved vram
  *
  * @adev: amdgpu_device pointer
  *
- * Check if the asic has been initialized (all asics) at driver startup
- * or post is needed if  hw reset is performed.
- * Returns true if need or false if not.
+ * free fw reserved vram if it has been reserved.
  */
-bool amdgpu_need_post(struct amdgpu_device *adev)
+void amdgpu_fw_reserve_vram_fini(struct amdgpu_device *adev)
 {
-       uint32_t reg;
+       amdgpu_bo_free_kernel(&adev->fw_vram_usage.reserved_bo,
+               NULL, &adev->fw_vram_usage.va);
+}
 
-       if (adev->has_hw_reset) {
-               adev->has_hw_reset = false;
-               return true;
-       }
+/**
+ * amdgpu_fw_reserve_vram_init - create bo vram reservation from fw
+ *
+ * @adev: amdgpu_device pointer
+ *
+ * create bo vram reservation from fw.
+ */
+int amdgpu_fw_reserve_vram_init(struct amdgpu_device *adev)
+{
+       int r = 0;
+       u64 gpu_addr;
+       u64 vram_size = adev->mc.visible_vram_size;
 
-       /* bios scratch used on CIK+ */
-       if (adev->asic_type >= CHIP_BONAIRE)
-               return amdgpu_atombios_scratch_need_asic_init(adev);
+       adev->fw_vram_usage.va = NULL;
+       adev->fw_vram_usage.reserved_bo = NULL;
 
-       /* check MEM_SIZE for older asics */
-       reg = amdgpu_asic_get_config_memsize(adev);
+       if (adev->fw_vram_usage.size > 0 &&
+               adev->fw_vram_usage.size <= vram_size) {
 
-       if ((reg != 0) && (reg != 0xffffffff))
-               return false;
+               r = amdgpu_bo_create(adev, adev->fw_vram_usage.size,
+                       PAGE_SIZE, true, 0,
+                       AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
+                       AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS, NULL, NULL, 0,
+                       &adev->fw_vram_usage.reserved_bo);
+               if (r)
+                       goto error_create;
 
-       return true;
+               r = amdgpu_bo_reserve(adev->fw_vram_usage.reserved_bo, false);
+               if (r)
+                       goto error_reserve;
+               r = amdgpu_bo_pin_restricted(adev->fw_vram_usage.reserved_bo,
+                       AMDGPU_GEM_DOMAIN_VRAM,
+                       adev->fw_vram_usage.start_offset,
+                       (adev->fw_vram_usage.start_offset +
+                       adev->fw_vram_usage.size), &gpu_addr);
+               if (r)
+                       goto error_pin;
+               r = amdgpu_bo_kmap(adev->fw_vram_usage.reserved_bo,
+                       &adev->fw_vram_usage.va);
+               if (r)
+                       goto error_kmap;
+
+               amdgpu_bo_unreserve(adev->fw_vram_usage.reserved_bo);
+       }
+       return r;
 
+error_kmap:
+       amdgpu_bo_unpin(adev->fw_vram_usage.reserved_bo);
+error_pin:
+       amdgpu_bo_unreserve(adev->fw_vram_usage.reserved_bo);
+error_reserve:
+       amdgpu_bo_unref(&adev->fw_vram_usage.reserved_bo);
+error_create:
+       adev->fw_vram_usage.va = NULL;
+       adev->fw_vram_usage.reserved_bo = NULL;
+       return r;
 }
 
-static bool amdgpu_vpost_needed(struct amdgpu_device *adev)
+
+/*
+ * GPU helpers function.
+ */
+/**
+ * amdgpu_need_post - check if the hw need post or not
+ *
+ * @adev: amdgpu_device pointer
+ *
+ * Check if the asic has been initialized (all asics) at driver startup
+ * or post is needed if  hw reset is performed.
+ * Returns true if need or false if not.
+ */
+bool amdgpu_need_post(struct amdgpu_device *adev)
 {
+       uint32_t reg;
+
        if (amdgpu_sriov_vf(adev))
                return false;
 
@@ -705,7 +767,23 @@ static bool amdgpu_vpost_needed(struct amdgpu_device *adev)
                                return true;
                }
        }
-       return amdgpu_need_post(adev);
+
+       if (adev->has_hw_reset) {
+               adev->has_hw_reset = false;
+               return true;
+       }
+
+       /* bios scratch used on CIK+ */
+       if (adev->asic_type >= CHIP_BONAIRE)
+               return amdgpu_atombios_scratch_need_asic_init(adev);
+
+       /* check MEM_SIZE for older asics */
+       reg = amdgpu_asic_get_config_memsize(adev);
+
+       if ((reg != 0) && (reg != 0xffffffff))
+               return false;
+
+       return true;
 }
 
 /**
@@ -887,6 +965,20 @@ static uint32_t cail_ioreg_read(struct card_info *info, uint32_t reg)
        return r;
 }
 
+static ssize_t amdgpu_atombios_get_vbios_version(struct device *dev,
+                                                struct device_attribute *attr,
+                                                char *buf)
+{
+       struct drm_device *ddev = dev_get_drvdata(dev);
+       struct amdgpu_device *adev = ddev->dev_private;
+       struct atom_context *ctx = adev->mode_info.atom_context;
+
+       return snprintf(buf, PAGE_SIZE, "%s\n", ctx->vbios_version);
+}
+
+static DEVICE_ATTR(vbios_version, 0444, amdgpu_atombios_get_vbios_version,
+                  NULL);
+
 /**
  * amdgpu_atombios_fini - free the driver info and callbacks for atombios
  *
@@ -906,6 +998,7 @@ static void amdgpu_atombios_fini(struct amdgpu_device *adev)
        adev->mode_info.atom_context = NULL;
        kfree(adev->mode_info.atom_card_info);
        adev->mode_info.atom_card_info = NULL;
+       device_remove_file(adev->dev, &dev_attr_vbios_version);
 }
 
 /**
@@ -922,6 +1015,7 @@ static int amdgpu_atombios_init(struct amdgpu_device *adev)
 {
        struct card_info *atom_card_info =
            kzalloc(sizeof(struct card_info), GFP_KERNEL);
+       int ret;
 
        if (!atom_card_info)
                return -ENOMEM;
@@ -958,6 +1052,13 @@ static int amdgpu_atombios_init(struct amdgpu_device *adev)
                amdgpu_atombios_scratch_regs_init(adev);
                amdgpu_atombios_allocate_fb_scratch(adev);
        }
+
+       ret = device_create_file(adev->dev, &dev_attr_vbios_version);
+       if (ret) {
+               DRM_ERROR("Failed to create device file for VBIOS version\n");
+               return ret;
+       }
+
        return 0;
 }
 
@@ -1736,6 +1837,9 @@ static int amdgpu_fini(struct amdgpu_device *adev)
                adev->ip_blocks[i].status.hw = false;
        }
 
+       if (adev->firmware.load_type == AMDGPU_FW_LOAD_SMU)
+               amdgpu_ucode_fini_bo(adev);
+
        for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
                if (!adev->ip_blocks[i].status.sw)
                        continue;
@@ -1757,10 +1861,8 @@ static int amdgpu_fini(struct amdgpu_device *adev)
                adev->ip_blocks[i].status.late_initialized = false;
        }
 
-       if (amdgpu_sriov_vf(adev)) {
-               amdgpu_bo_free_kernel(&adev->virt.csa_obj, &adev->virt.csa_vmid0_addr, NULL);
+       if (amdgpu_sriov_vf(adev))
                amdgpu_virt_release_full_gpu(adev, false);
-       }
 
        return 0;
 }
@@ -1848,6 +1950,7 @@ static int amdgpu_sriov_reinit_late(struct amdgpu_device *adev)
 
        static enum amd_ip_block_type ip_order[] = {
                AMD_IP_BLOCK_TYPE_SMC,
+               AMD_IP_BLOCK_TYPE_PSP,
                AMD_IP_BLOCK_TYPE_DCE,
                AMD_IP_BLOCK_TYPE_GFX,
                AMD_IP_BLOCK_TYPE_SDMA,
@@ -1933,15 +2036,66 @@ static int amdgpu_resume(struct amdgpu_device *adev)
 
 static void amdgpu_device_detect_sriov_bios(struct amdgpu_device *adev)
 {
-       if (adev->is_atom_fw) {
-               if (amdgpu_atomfirmware_gpu_supports_virtualization(adev))
-                       adev->virt.caps |= AMDGPU_SRIOV_CAPS_SRIOV_VBIOS;
-       } else {
-               if (amdgpu_atombios_has_gpu_virtualization_table(adev))
-                       adev->virt.caps |= AMDGPU_SRIOV_CAPS_SRIOV_VBIOS;
+       if (amdgpu_sriov_vf(adev)) {
+               if (adev->is_atom_fw) {
+                       if (amdgpu_atomfirmware_gpu_supports_virtualization(adev))
+                               adev->virt.caps |= AMDGPU_SRIOV_CAPS_SRIOV_VBIOS;
+               } else {
+                       if (amdgpu_atombios_has_gpu_virtualization_table(adev))
+                               adev->virt.caps |= AMDGPU_SRIOV_CAPS_SRIOV_VBIOS;
+               }
+
+               if (!(adev->virt.caps & AMDGPU_SRIOV_CAPS_SRIOV_VBIOS))
+                       amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_NO_VBIOS, 0, 0);
+       }
+}
+
+bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type)
+{
+       switch (asic_type) {
+#if defined(CONFIG_DRM_AMD_DC)
+       case CHIP_BONAIRE:
+       case CHIP_HAWAII:
+       case CHIP_KAVERI:
+       case CHIP_CARRIZO:
+       case CHIP_STONEY:
+       case CHIP_POLARIS11:
+       case CHIP_POLARIS10:
+       case CHIP_POLARIS12:
+       case CHIP_TONGA:
+       case CHIP_FIJI:
+#if defined(CONFIG_DRM_AMD_DC_PRE_VEGA)
+               return amdgpu_dc != 0;
+#endif
+       case CHIP_KABINI:
+       case CHIP_MULLINS:
+               return amdgpu_dc > 0;
+       case CHIP_VEGA10:
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
+       case CHIP_RAVEN:
+#endif
+               return amdgpu_dc != 0;
+#endif
+       default:
+               return false;
        }
 }
 
+/**
+ * amdgpu_device_has_dc_support - check if dc is supported
+ *
+ * @adev: amdgpu_device_pointer
+ *
+ * Returns true for supported, false for not supported
+ */
+bool amdgpu_device_has_dc_support(struct amdgpu_device *adev)
+{
+       if (amdgpu_sriov_vf(adev))
+               return false;
+
+       return amdgpu_device_asic_has_dc_support(adev->asic_type);
+}
+
 /**
  * amdgpu_device_init - initialize the driver
  *
@@ -1979,6 +2133,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
        adev->vm_manager.vm_pte_num_rings = 0;
        adev->gart.gart_funcs = NULL;
        adev->fence_context = dma_fence_context_alloc(AMDGPU_MAX_RINGS);
+       bitmap_zero(adev->gfx.pipe_reserve_bitmap, AMDGPU_MAX_COMPUTE_QUEUES);
 
        adev->smc_rreg = &amdgpu_invalid_rreg;
        adev->smc_wreg = &amdgpu_invalid_wreg;
@@ -1995,7 +2150,6 @@ int amdgpu_device_init(struct amdgpu_device *adev,
        adev->audio_endpt_rreg = &amdgpu_block_invalid_rreg;
        adev->audio_endpt_wreg = &amdgpu_block_invalid_wreg;
 
-
        DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X 0x%04X:0x%04X 0x%02X).\n",
                 amdgpu_asic_name[adev->asic_type], pdev->vendor, pdev->device,
                 pdev->subsystem_vendor, pdev->subsystem_device, pdev->revision);
@@ -2007,8 +2161,10 @@ int amdgpu_device_init(struct amdgpu_device *adev,
        mutex_init(&adev->pm.mutex);
        mutex_init(&adev->gfx.gpu_clock_mutex);
        mutex_init(&adev->srbm_mutex);
+       mutex_init(&adev->gfx.pipe_reserve_mutex);
        mutex_init(&adev->grbm_idx_mutex);
        mutex_init(&adev->mn_lock);
+       mutex_init(&adev->virt.vf_errors.lock);
        hash_init(adev->mn_hash);
 
        amdgpu_check_arguments(adev);
@@ -2051,9 +2207,8 @@ int amdgpu_device_init(struct amdgpu_device *adev,
        DRM_INFO("register mmio base: 0x%08X\n", (uint32_t)adev->rmmio_base);
        DRM_INFO("register mmio size: %u\n", (unsigned)adev->rmmio_size);
 
-       if (adev->asic_type >= CHIP_BONAIRE)
-               /* doorbell bar mapping */
-               amdgpu_doorbell_init(adev);
+       /* doorbell bar mapping */
+       amdgpu_doorbell_init(adev);
 
        /* io port mapping */
        for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
@@ -2095,7 +2250,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
        r = amdgpu_atombios_init(adev);
        if (r) {
                dev_err(adev->dev, "amdgpu_atombios_init failed\n");
-               amdgpu_vf_error_put(AMDGIM_ERROR_VF_ATOMBIOS_INIT_FAIL, 0, 0);
+               amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_ATOMBIOS_INIT_FAIL, 0, 0);
                goto failed;
        }
 
@@ -2103,10 +2258,9 @@ int amdgpu_device_init(struct amdgpu_device *adev,
        amdgpu_device_detect_sriov_bios(adev);
 
        /* Post card if necessary */
-       if (amdgpu_vpost_needed(adev)) {
+       if (amdgpu_need_post(adev)) {
                if (!adev->bios) {
                        dev_err(adev->dev, "no vBIOS found\n");
-                       amdgpu_vf_error_put(AMDGIM_ERROR_VF_NO_VBIOS, 0, 0);
                        r = -EINVAL;
                        goto failed;
                }
@@ -2114,7 +2268,6 @@ int amdgpu_device_init(struct amdgpu_device *adev,
                r = amdgpu_atom_asic_init(adev->mode_info.atom_context);
                if (r) {
                        dev_err(adev->dev, "gpu post error!\n");
-                       amdgpu_vf_error_put(AMDGIM_ERROR_VF_GPU_POST_ERROR, 0, 0);
                        goto failed;
                }
        } else {
@@ -2126,7 +2279,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
                r = amdgpu_atomfirmware_get_clock_info(adev);
                if (r) {
                        dev_err(adev->dev, "amdgpu_atomfirmware_get_clock_info failed\n");
-                       amdgpu_vf_error_put(AMDGIM_ERROR_VF_ATOMBIOS_GET_CLOCK_FAIL, 0, 0);
+                       amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_ATOMBIOS_GET_CLOCK_FAIL, 0, 0);
                        goto failed;
                }
        } else {
@@ -2134,18 +2287,19 @@ int amdgpu_device_init(struct amdgpu_device *adev,
                r = amdgpu_atombios_get_clock_info(adev);
                if (r) {
                        dev_err(adev->dev, "amdgpu_atombios_get_clock_info failed\n");
-                       amdgpu_vf_error_put(AMDGIM_ERROR_VF_ATOMBIOS_GET_CLOCK_FAIL, 0, 0);
+                       amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_ATOMBIOS_GET_CLOCK_FAIL, 0, 0);
                        goto failed;
                }
                /* init i2c buses */
-               amdgpu_atombios_i2c_init(adev);
+               if (!amdgpu_device_has_dc_support(adev))
+                       amdgpu_atombios_i2c_init(adev);
        }
 
        /* Fence driver */
        r = amdgpu_fence_driver_init(adev);
        if (r) {
                dev_err(adev->dev, "amdgpu_fence_driver_init failed\n");
-               amdgpu_vf_error_put(AMDGIM_ERROR_VF_FENCE_INIT_FAIL, 0, 0);
+               amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_FENCE_INIT_FAIL, 0, 0);
                goto failed;
        }
 
@@ -2155,7 +2309,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
        r = amdgpu_init(adev);
        if (r) {
                dev_err(adev->dev, "amdgpu_init failed\n");
-               amdgpu_vf_error_put(AMDGIM_ERROR_VF_AMDGPU_INIT_FAIL, 0, 0);
+               amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_AMDGPU_INIT_FAIL, 0, 0);
                amdgpu_fini(adev);
                goto failed;
        }
@@ -2175,7 +2329,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
        r = amdgpu_ib_pool_init(adev);
        if (r) {
                dev_err(adev->dev, "IB initialization failed (%d).\n", r);
-               amdgpu_vf_error_put(AMDGIM_ERROR_VF_IB_INIT_FAIL, 0, r);
+               amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_IB_INIT_FAIL, 0, r);
                goto failed;
        }
 
@@ -2183,8 +2337,15 @@ int amdgpu_device_init(struct amdgpu_device *adev,
        if (r)
                DRM_ERROR("ib ring test failed (%d).\n", r);
 
+       if (amdgpu_sriov_vf(adev))
+               amdgpu_virt_init_data_exchange(adev);
+
        amdgpu_fbdev_init(adev);
 
+       r = amdgpu_pm_sysfs_init(adev);
+       if (r)
+               DRM_ERROR("registering pm debugfs failed (%d).\n", r);
+
        r = amdgpu_gem_debugfs_init(adev);
        if (r)
                DRM_ERROR("registering gem debugfs failed (%d).\n", r);
@@ -2201,6 +2362,10 @@ int amdgpu_device_init(struct amdgpu_device *adev,
        if (r)
                DRM_ERROR("registering firmware debugfs failed (%d).\n", r);
 
+       r = amdgpu_debugfs_vbios_dump_init(adev);
+       if (r)
+               DRM_ERROR("Creating vbios dump debugfs failed (%d).\n", r);
+
        if ((amdgpu_testing & 1)) {
                if (adev->accel_working)
                        amdgpu_test_moves(adev);
@@ -2220,7 +2385,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
        r = amdgpu_late_init(adev);
        if (r) {
                dev_err(adev->dev, "amdgpu_late_init failed\n");
-               amdgpu_vf_error_put(AMDGIM_ERROR_VF_AMDGPU_LATE_INIT_FAIL, 0, r);
+               amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_AMDGPU_LATE_INIT_FAIL, 0, r);
                goto failed;
        }
 
@@ -2252,6 +2417,7 @@ void amdgpu_device_fini(struct amdgpu_device *adev)
        /* evict vram memory */
        amdgpu_bo_evict_vram(adev);
        amdgpu_ib_pool_fini(adev);
+       amdgpu_fw_reserve_vram_fini(adev);
        amdgpu_fence_driver_fini(adev);
        amdgpu_fbdev_fini(adev);
        r = amdgpu_fini(adev);
@@ -2262,7 +2428,8 @@ void amdgpu_device_fini(struct amdgpu_device *adev)
        adev->accel_working = false;
        cancel_delayed_work_sync(&adev->late_init_work);
        /* free i2c buses */
-       amdgpu_i2c_fini(adev);
+       if (!amdgpu_device_has_dc_support(adev))
+               amdgpu_i2c_fini(adev);
        amdgpu_atombios_fini(adev);
        kfree(adev->bios);
        adev->bios = NULL;
@@ -2276,8 +2443,8 @@ void amdgpu_device_fini(struct amdgpu_device *adev)
        adev->rio_mem = NULL;
        iounmap(adev->rmmio);
        adev->rmmio = NULL;
-       if (adev->asic_type >= CHIP_BONAIRE)
-               amdgpu_doorbell_fini(adev);
+       amdgpu_doorbell_fini(adev);
+       amdgpu_pm_sysfs_fini(adev);
        amdgpu_debugfs_regs_cleanup(adev);
 }
 
@@ -2313,12 +2480,14 @@ int amdgpu_device_suspend(struct drm_device *dev, bool suspend, bool fbcon)
 
        drm_kms_helper_poll_disable(dev);
 
-       /* turn off display hw */
-       drm_modeset_lock_all(dev);
-       list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-               drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
+       if (!amdgpu_device_has_dc_support(adev)) {
+               /* turn off display hw */
+               drm_modeset_lock_all(dev);
+               list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+                       drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
+               }
+               drm_modeset_unlock_all(dev);
        }
-       drm_modeset_unlock_all(dev);
 
        amdgpu_amdkfd_suspend(adev);
 
@@ -2461,13 +2630,25 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon)
 
        /* blat the mode back in */
        if (fbcon) {
-               drm_helper_resume_force_mode(dev);
-               /* turn on display hw */
-               drm_modeset_lock_all(dev);
-               list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-                       drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
+               if (!amdgpu_device_has_dc_support(adev)) {
+                       /* pre DCE11 */
+                       drm_helper_resume_force_mode(dev);
+
+                       /* turn on display hw */
+                       drm_modeset_lock_all(dev);
+                       list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+                               drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
+                       }
+                       drm_modeset_unlock_all(dev);
+               } else {
+                       /*
+                        * There is no equivalent atomic helper to turn on
+                        * display, so we defined our own function for this,
+                        * once suspend resume is supported by the atomic
+                        * framework this will be reworked
+                        */
+                       amdgpu_dm_display_resume(adev);
                }
-               drm_modeset_unlock_all(dev);
        }
 
        drm_kms_helper_poll_enable(dev);
@@ -2484,7 +2665,10 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon)
 #ifdef CONFIG_PM
        dev->dev->power.disable_depth++;
 #endif
-       drm_helper_hpd_irq_event(dev);
+       if (!amdgpu_device_has_dc_support(adev))
+               drm_helper_hpd_irq_event(dev);
+       else
+               drm_kms_helper_hotplug_event(dev);
 #ifdef CONFIG_PM
        dev->dev->power.disable_depth--;
 #endif
@@ -2504,6 +2688,9 @@ static bool amdgpu_check_soft_reset(struct amdgpu_device *adev)
        int i;
        bool asic_hang = false;
 
+       if (amdgpu_sriov_vf(adev))
+               return true;
+
        for (i = 0; i < adev->num_ip_blocks; i++) {
                if (!adev->ip_blocks[i].status.valid)
                        continue;
@@ -2546,7 +2733,8 @@ static bool amdgpu_need_full_reset(struct amdgpu_device *adev)
                if ((adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC) ||
                    (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_SMC) ||
                    (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_ACP) ||
-                   (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_DCE)) {
+                   (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_DCE) ||
+                    adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_PSP) {
                        if (adev->ip_blocks[i].status.hang) {
                                DRM_INFO("Some block need full reset!\n");
                                return true;
@@ -2654,7 +2842,7 @@ int amdgpu_sriov_gpu_reset(struct amdgpu_device *adev, struct amdgpu_job *job)
 
        mutex_lock(&adev->virt.lock_reset);
        atomic_inc(&adev->gpu_reset_counter);
-       adev->gfx.in_reset = true;
+       adev->in_sriov_reset = true;
 
        /* block TTM */
        resched = ttm_bo_lock_delayed_workqueue(&adev->mman.bdev);
@@ -2765,7 +2953,7 @@ give_up_reset:
                dev_info(adev->dev, "GPU reset successed!\n");
        }
 
-       adev->gfx.in_reset = false;
+       adev->in_sriov_reset = false;
        mutex_unlock(&adev->virt.lock_reset);
        return r;
 }
@@ -2780,6 +2968,7 @@ give_up_reset:
  */
 int amdgpu_gpu_reset(struct amdgpu_device *adev)
 {
+       struct drm_atomic_state *state = NULL;
        int i, r;
        int resched;
        bool need_full_reset, vram_lost = false;
@@ -2793,6 +2982,9 @@ int amdgpu_gpu_reset(struct amdgpu_device *adev)
 
        /* block TTM */
        resched = ttm_bo_lock_delayed_workqueue(&adev->mman.bdev);
+       /* store modesetting */
+       if (amdgpu_device_has_dc_support(adev))
+               state = drm_atomic_helper_suspend(adev->ddev);
 
        /* block scheduler */
        for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
@@ -2902,7 +3094,6 @@ out:
                }
        } else {
                dev_err(adev->dev, "asic resume failed (%d).\n", r);
-               amdgpu_vf_error_put(AMDGIM_ERROR_VF_ASIC_RESUME_FAIL, 0, r);
                for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
                        if (adev->rings[i] && adev->rings[i]->sched.thread) {
                                kthread_unpark(adev->rings[i]->sched.thread);
@@ -2910,13 +3101,16 @@ out:
                }
        }
 
-       drm_helper_resume_force_mode(adev->ddev);
+       if (amdgpu_device_has_dc_support(adev)) {
+               r = drm_atomic_helper_resume(adev->ddev, state);
+               amdgpu_dm_display_resume(adev);
+       } else
+               drm_helper_resume_force_mode(adev->ddev);
 
        ttm_bo_unlock_delayed_workqueue(&adev->mman.bdev, resched);
        if (r) {
                /* bad news, how to tell it to userspace ? */
                dev_info(adev->dev, "GPU reset failed\n");
-               amdgpu_vf_error_put(AMDGIM_ERROR_VF_GPU_RESET_FAIL, 0, r);
        }
        else {
                dev_info(adev->dev, "GPU reset successed!\n");
@@ -3070,9 +3264,9 @@ static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf,
        pm_pg_lock = (*pos >> 23) & 1;
 
        if (*pos & (1ULL << 62)) {
-               se_bank = (*pos >> 24) & 0x3FF;
-               sh_bank = (*pos >> 34) & 0x3FF;
-               instance_bank = (*pos >> 44) & 0x3FF;
+               se_bank = (*pos & GENMASK_ULL(33, 24)) >> 24;
+               sh_bank = (*pos & GENMASK_ULL(43, 34)) >> 34;
+               instance_bank = (*pos & GENMASK_ULL(53, 44)) >> 44;
 
                if (se_bank == 0x3FF)
                        se_bank = 0xFFFFFFFF;
@@ -3146,9 +3340,9 @@ static ssize_t amdgpu_debugfs_regs_write(struct file *f, const char __user *buf,
        pm_pg_lock = (*pos >> 23) & 1;
 
        if (*pos & (1ULL << 62)) {
-               se_bank = (*pos >> 24) & 0x3FF;
-               sh_bank = (*pos >> 34) & 0x3FF;
-               instance_bank = (*pos >> 44) & 0x3FF;
+               se_bank = (*pos & GENMASK_ULL(33, 24)) >> 24;
+               sh_bank = (*pos & GENMASK_ULL(43, 34)) >> 34;
+               instance_bank = (*pos & GENMASK_ULL(53, 44)) >> 44;
 
                if (se_bank == 0x3FF)
                        se_bank = 0xFFFFFFFF;
@@ -3463,10 +3657,7 @@ static ssize_t amdgpu_debugfs_sensor_read(struct file *f, char __user *buf,
 
        valuesize = sizeof(values);
        if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->read_sensor)
-               r = adev->powerplay.pp_funcs->read_sensor(adev->powerplay.pp_handle, idx, &values[0], &valuesize);
-       else if (adev->pm.funcs && adev->pm.funcs->read_sensor)
-               r = adev->pm.funcs->read_sensor(adev, idx, &values[0],
-                                               &valuesize);
+               r = amdgpu_dpm_read_sensor(adev, idx, &values[0], &valuesize);
        else
                return -EINVAL;
 
@@ -3499,12 +3690,12 @@ static ssize_t amdgpu_debugfs_wave_read(struct file *f, char __user *buf,
                return -EINVAL;
 
        /* decode offset */
-       offset = (*pos & 0x7F);
-       se = ((*pos >> 7) & 0xFF);
-       sh = ((*pos >> 15) & 0xFF);
-       cu = ((*pos >> 23) & 0xFF);
-       wave = ((*pos >> 31) & 0xFF);
-       simd = ((*pos >> 37) & 0xFF);
+       offset = (*pos & GENMASK_ULL(6, 0));
+       se = (*pos & GENMASK_ULL(14, 7)) >> 7;
+       sh = (*pos & GENMASK_ULL(22, 15)) >> 15;
+       cu = (*pos & GENMASK_ULL(30, 23)) >> 23;
+       wave = (*pos & GENMASK_ULL(36, 31)) >> 31;
+       simd = (*pos & GENMASK_ULL(44, 37)) >> 37;
 
        /* switch to the specific se/sh/cu */
        mutex_lock(&adev->grbm_idx_mutex);
@@ -3549,14 +3740,14 @@ static ssize_t amdgpu_debugfs_gpr_read(struct file *f, char __user *buf,
                return -EINVAL;
 
        /* decode offset */
-       offset = (*pos & 0xFFF);       /* in dwords */
-       se = ((*pos >> 12) & 0xFF);
-       sh = ((*pos >> 20) & 0xFF);
-       cu = ((*pos >> 28) & 0xFF);
-       wave = ((*pos >> 36) & 0xFF);
-       simd = ((*pos >> 44) & 0xFF);
-       thread = ((*pos >> 52) & 0xFF);
-       bank = ((*pos >> 60) & 1);
+       offset = *pos & GENMASK_ULL(11, 0);
+       se = (*pos & GENMASK_ULL(19, 12)) >> 12;
+       sh = (*pos & GENMASK_ULL(27, 20)) >> 20;
+       cu = (*pos & GENMASK_ULL(35, 28)) >> 28;
+       wave = (*pos & GENMASK_ULL(43, 36)) >> 36;
+       simd = (*pos & GENMASK_ULL(51, 44)) >> 44;
+       thread = (*pos & GENMASK_ULL(59, 52)) >> 52;
+       bank = (*pos & GENMASK_ULL(61, 60)) >> 60;
 
        data = kmalloc_array(1024, sizeof(*data), GFP_KERNEL);
        if (!data)
@@ -3754,6 +3945,28 @@ int amdgpu_debugfs_init(struct drm_minor *minor)
 {
        return 0;
 }
+
+static int amdgpu_debugfs_get_vbios_dump(struct seq_file *m, void *data)
+{
+       struct drm_info_node *node = (struct drm_info_node *) m->private;
+       struct drm_device *dev = node->minor->dev;
+       struct amdgpu_device *adev = dev->dev_private;
+
+       seq_write(m, adev->bios, adev->bios_size);
+       return 0;
+}
+
+static const struct drm_info_list amdgpu_vbios_dump_list[] = {
+               {"amdgpu_vbios",
+                amdgpu_debugfs_get_vbios_dump,
+                0, NULL},
+};
+
+static int amdgpu_debugfs_vbios_dump_init(struct amdgpu_device *adev)
+{
+       return amdgpu_debugfs_add_files(adev,
+                                       amdgpu_vbios_dump_list, 1);
+}
 #else
 static int amdgpu_debugfs_test_ib_ring_init(struct amdgpu_device *adev)
 {
@@ -3763,5 +3976,9 @@ static int amdgpu_debugfs_regs_init(struct amdgpu_device *adev)
 {
        return 0;
 }
+static int amdgpu_debugfs_vbios_dump_init(struct amdgpu_device *adev)
+{
+       return 0;
+}
 static void amdgpu_debugfs_regs_cleanup(struct amdgpu_device *adev) { }
 #endif