Merge branch 'drm-fixes-4.6' of git://people.freedesktop.org/~agd5f/linux into drm...
authorDave Airlie <airlied@redhat.com>
Wed, 6 Apr 2016 21:08:46 +0000 (07:08 +1000)
committerDave Airlie <airlied@redhat.com>
Wed, 6 Apr 2016 21:08:46 +0000 (07:08 +1000)
Lots of misc bug fixes for radeon and amdgpu and one for ttm.
- fix vram info fetching on Fiji and unposted boards
- additional vblank fixes from the conversion to drm_vblank_on/off
- UVD dGPU suspend and resume fixes
- lots of powerplay fixes
- fix a fence leak in the pageflip code
- ttm fix for platforms where CPU is 32 bit, but physical addresses are >32bits

* 'drm-fixes-4.6' of git://people.freedesktop.org/~agd5f/linux: (21 commits)
  drm/amdgpu: total vram size also reduces pin size
  drm/amd/powerplay: add uvd/vce dpm enabling flag default.
  drm/amd/powerplay: fix issue that resume back, dpm can't work on FIJI.
  drm/amdgpu: save and restore the firwmware cache part when suspend resume
  drm/amdgpu: save and restore UVD context with suspend and resume
  drm/ttm: use phys_addr_t for ttm_bus_placement
  drm/radeon: Only call drm_vblank_on/off between drm_vblank_init/cleanup
  drm/amdgpu: fence wait old rcu slot
  drm/amdgpu: fix leaking fence in the pageflip code
  drm/amdgpu: print vram type rather than just DDR
  drm/amdgpu/gmc: use proper register for vram type on Fiji
  drm/amdgpu/gmc: move vram type fetching into sw_init
  drm/amdgpu: Set vblank_disable_allowed = true
  drm/radeon: Set vblank_disable_allowed = true
  drm/amd/powerplay: Need to change boot to performance state in resume.
  drm/amd/powerplay: add new Fiji function for not setting same ps.
  drm/amdgpu: check dpm state before pm system fs initialized.
  drm/amd/powerplay: notify amdgpu whether dpm is enabled or not.
  drm/amdgpu: Not support disable dpm in powerplay.
  drm/amdgpu: add an cgs interface to notify amdgpu the dpm state.
  ...

22 files changed:
drivers/gpu/drm/amd/amdgpu/amdgpu.h
drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c
drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c
drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c
drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c
drivers/gpu/drm/amd/include/cgs_common.h
drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c
drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c
drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c
drivers/gpu/drm/radeon/atombios_crtc.c
drivers/gpu/drm/radeon/radeon_irq_kms.c
drivers/gpu/drm/radeon/radeon_legacy_crtc.c
include/drm/ttm/ttm_bo_api.h

index c4a21c6428f5f526289c1da50b77d4a77157fe60..62a778012fe06cc572964b463f873c987ca34755 100644 (file)
@@ -1591,6 +1591,7 @@ struct amdgpu_uvd {
        struct amdgpu_bo        *vcpu_bo;
        void                    *cpu_addr;
        uint64_t                gpu_addr;
+       void                    *saved_bo;
        atomic_t                handles[AMDGPU_MAX_UVD_HANDLES];
        struct drm_file         *filp[AMDGPU_MAX_UVD_HANDLES];
        struct delayed_work     idle_work;
index 7a4b101e10c63564aa3b0b8fffc638c171c1d199..6043dc7c3a94d75350a6e8760376b772f0fc4baf 100644 (file)
@@ -816,10 +816,13 @@ static int amdgpu_cgs_get_active_displays_info(void *cgs_device,
        struct drm_device *ddev = adev->ddev;
        struct drm_crtc *crtc;
        uint32_t line_time_us, vblank_lines;
+       struct cgs_mode_info *mode_info;
 
        if (info == NULL)
                return -EINVAL;
 
+       mode_info = info->mode_info;
+
        if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {
                list_for_each_entry(crtc,
                                &ddev->mode_config.crtc_list, head) {
@@ -828,7 +831,7 @@ static int amdgpu_cgs_get_active_displays_info(void *cgs_device,
                                info->active_display_mask |= (1 << amdgpu_crtc->crtc_id);
                                info->display_count++;
                        }
-                       if (info->mode_info != NULL &&
+                       if (mode_info != NULL &&
                                crtc->enabled && amdgpu_crtc->enabled &&
                                amdgpu_crtc->hw_mode.clock) {
                                line_time_us = (amdgpu_crtc->hw_mode.crtc_htotal * 1000) /
@@ -836,10 +839,10 @@ static int amdgpu_cgs_get_active_displays_info(void *cgs_device,
                                vblank_lines = amdgpu_crtc->hw_mode.crtc_vblank_end -
                                                        amdgpu_crtc->hw_mode.crtc_vdisplay +
                                                        (amdgpu_crtc->v_border * 2);
-                               info->mode_info->vblank_time_us = vblank_lines * line_time_us;
-                               info->mode_info->refresh_rate = drm_mode_vrefresh(&amdgpu_crtc->hw_mode);
-                               info->mode_info->ref_clock = adev->clock.spll.reference_freq;
-                               info->mode_info++;
+                               mode_info->vblank_time_us = vblank_lines * line_time_us;
+                               mode_info->refresh_rate = drm_mode_vrefresh(&amdgpu_crtc->hw_mode);
+                               mode_info->ref_clock = adev->clock.spll.reference_freq;
+                               mode_info = NULL;
                        }
                }
        }
@@ -847,6 +850,16 @@ static int amdgpu_cgs_get_active_displays_info(void *cgs_device,
        return 0;
 }
 
+
+static int amdgpu_cgs_notify_dpm_enabled(void *cgs_device, bool enabled)
+{
+       CGS_FUNC_ADEV;
+
+       adev->pm.dpm_enabled = enabled;
+
+       return 0;
+}
+
 /** \brief evaluate acpi namespace object, handle or pathname must be valid
  *  \param cgs_device
  *  \param info input/output arguments for the control method
@@ -1097,6 +1110,7 @@ static const struct cgs_ops amdgpu_cgs_ops = {
        amdgpu_cgs_set_powergating_state,
        amdgpu_cgs_set_clockgating_state,
        amdgpu_cgs_get_active_displays_info,
+       amdgpu_cgs_notify_dpm_enabled,
        amdgpu_cgs_call_acpi_method,
        amdgpu_cgs_query_system_info,
 };
index f0ed974bd4e090f65881d5f3604475d7e44f38ee..3fb405b3a61457e4622dfe4b788ac3925d088f4a 100644 (file)
@@ -57,7 +57,7 @@ static bool amdgpu_flip_handle_fence(struct amdgpu_flip_work *work,
        if (!fence_add_callback(fence, &work->cb, amdgpu_flip_callback))
                return true;
 
-       fence_put(*f);
+       fence_put(fence);
        return false;
 }
 
index 4303b447efe898145433985079a6cd10273acc81..d81f1f4883a6c4b1adff92ba0c32b52f1999b2fd 100644 (file)
@@ -121,7 +121,7 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct fence **f)
 {
        struct amdgpu_device *adev = ring->adev;
        struct amdgpu_fence *fence;
-       struct fence **ptr;
+       struct fence *old, **ptr;
        uint32_t seq;
 
        fence = kmem_cache_alloc(amdgpu_fence_slab, GFP_KERNEL);
@@ -141,7 +141,11 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct fence **f)
        /* This function can't be called concurrently anyway, otherwise
         * emitting the fence would mess up the hardware ring buffer.
         */
-       BUG_ON(rcu_dereference_protected(*ptr, 1));
+       old = rcu_dereference_protected(*ptr, 1);
+       if (old && !fence_is_signaled(old)) {
+               DRM_INFO("rcu slot is busy\n");
+               fence_wait(old, false);
+       }
 
        rcu_assign_pointer(*ptr, fence_get(&fence->base));
 
index f594cfaa97e513f0bc6d436e26430abc8783e5ce..762cfdb85147471855418fff997877951d4aca6d 100644 (file)
@@ -219,6 +219,8 @@ int amdgpu_irq_init(struct amdgpu_device *adev)
        if (r) {
                return r;
        }
+       adev->ddev->vblank_disable_allowed = true;
+
        /* enable msi */
        adev->irq.msi_enabled = false;
 
index 7805a8706af7bfb9cde33e30a5761db9eab0abd4..598eb0cd5aab6a1b437ad04d0c58dce24adc8d9d 100644 (file)
@@ -382,6 +382,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
                struct drm_amdgpu_info_vram_gtt vram_gtt;
 
                vram_gtt.vram_size = adev->mc.real_vram_size;
+               vram_gtt.vram_size -= adev->vram_pin_size;
                vram_gtt.vram_cpu_accessible_size = adev->mc.visible_vram_size;
                vram_gtt.vram_cpu_accessible_size -= adev->vram_pin_size;
                vram_gtt.gtt_size  = adev->mc.gtt_size;
index 56d1458393ccfd86992be99d5b19db235ac40f11..5b6639faa731e83b1b14c07bf673aa30deff52c8 100644 (file)
@@ -476,6 +476,17 @@ int amdgpu_bo_evict_vram(struct amdgpu_device *adev)
        return ttm_bo_evict_mm(&adev->mman.bdev, TTM_PL_VRAM);
 }
 
+static const char *amdgpu_vram_names[] = {
+       "UNKNOWN",
+       "GDDR1",
+       "DDR2",
+       "GDDR3",
+       "GDDR4",
+       "GDDR5",
+       "HBM",
+       "DDR3"
+};
+
 int amdgpu_bo_init(struct amdgpu_device *adev)
 {
        /* Add an MTRR for the VRAM */
@@ -484,8 +495,8 @@ int amdgpu_bo_init(struct amdgpu_device *adev)
        DRM_INFO("Detected VRAM RAM=%lluM, BAR=%lluM\n",
                adev->mc.mc_vram_size >> 20,
                (unsigned long long)adev->mc.aper_size >> 20);
-       DRM_INFO("RAM width %dbits DDR\n",
-                       adev->mc.vram_width);
+       DRM_INFO("RAM width %dbits %s\n",
+                adev->mc.vram_width, amdgpu_vram_names[adev->mc.vram_type]);
        return amdgpu_ttm_init(adev);
 }
 
index 3cb6d6c413c71b0207fe1766d26ca190a083e880..e9c6ae6ed2f73357d762f9aa75406c010238dd4a 100644 (file)
@@ -143,7 +143,7 @@ static int amdgpu_pp_late_init(void *handle)
                                        adev->powerplay.pp_handle);
 
 #ifdef CONFIG_DRM_AMD_POWERPLAY
-       if (adev->pp_enabled) {
+       if (adev->pp_enabled && adev->pm.dpm_enabled) {
                amdgpu_pm_sysfs_init(adev);
                amdgpu_dpm_dispatch_task(adev, AMD_PP_EVENT_COMPLETE_INIT, NULL, NULL);
        }
@@ -161,12 +161,8 @@ static int amdgpu_pp_sw_init(void *handle)
                                        adev->powerplay.pp_handle);
 
 #ifdef CONFIG_DRM_AMD_POWERPLAY
-       if (adev->pp_enabled) {
-               if (amdgpu_dpm == 0)
-                       adev->pm.dpm_enabled = false;
-               else
-                       adev->pm.dpm_enabled = true;
-       }
+       if (adev->pp_enabled)
+               adev->pm.dpm_enabled = true;
 #endif
 
        return ret;
index c1a5810444174522193111d9a41ff26d6fc0eb16..338da80006b66ced7671b5ed63fabb02750355ba 100644 (file)
@@ -241,32 +241,28 @@ int amdgpu_uvd_sw_fini(struct amdgpu_device *adev)
 
 int amdgpu_uvd_suspend(struct amdgpu_device *adev)
 {
-       struct amdgpu_ring *ring = &adev->uvd.ring;
-       int i, r;
+       unsigned size;
+       void *ptr;
+       int i;
 
        if (adev->uvd.vcpu_bo == NULL)
                return 0;
 
-       for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i) {
-               uint32_t handle = atomic_read(&adev->uvd.handles[i]);
-               if (handle != 0) {
-                       struct fence *fence;
+       for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i)
+               if (atomic_read(&adev->uvd.handles[i]))
+                       break;
 
-                       amdgpu_uvd_note_usage(adev);
+       if (i == AMDGPU_MAX_UVD_HANDLES)
+               return 0;
 
-                       r = amdgpu_uvd_get_destroy_msg(ring, handle, false, &fence);
-                       if (r) {
-                               DRM_ERROR("Error destroying UVD (%d)!\n", r);
-                               continue;
-                       }
+       size = amdgpu_bo_size(adev->uvd.vcpu_bo);
+       ptr = adev->uvd.cpu_addr;
 
-                       fence_wait(fence, false);
-                       fence_put(fence);
+       adev->uvd.saved_bo = kmalloc(size, GFP_KERNEL);
+       if (!adev->uvd.saved_bo)
+               return -ENOMEM;
 
-                       adev->uvd.filp[i] = NULL;
-                       atomic_set(&adev->uvd.handles[i], 0);
-               }
-       }
+       memcpy(adev->uvd.saved_bo, ptr, size);
 
        return 0;
 }
@@ -275,23 +271,29 @@ int amdgpu_uvd_resume(struct amdgpu_device *adev)
 {
        unsigned size;
        void *ptr;
-       const struct common_firmware_header *hdr;
-       unsigned offset;
 
        if (adev->uvd.vcpu_bo == NULL)
                return -EINVAL;
 
-       hdr = (const struct common_firmware_header *)adev->uvd.fw->data;
-       offset = le32_to_cpu(hdr->ucode_array_offset_bytes);
-       memcpy(adev->uvd.cpu_addr, (adev->uvd.fw->data) + offset,
-               (adev->uvd.fw->size) - offset);
-
        size = amdgpu_bo_size(adev->uvd.vcpu_bo);
-       size -= le32_to_cpu(hdr->ucode_size_bytes);
        ptr = adev->uvd.cpu_addr;
-       ptr += le32_to_cpu(hdr->ucode_size_bytes);
 
-       memset(ptr, 0, size);
+       if (adev->uvd.saved_bo != NULL) {
+               memcpy(ptr, adev->uvd.saved_bo, size);
+               kfree(adev->uvd.saved_bo);
+               adev->uvd.saved_bo = NULL;
+       } else {
+               const struct common_firmware_header *hdr;
+               unsigned offset;
+
+               hdr = (const struct common_firmware_header *)adev->uvd.fw->data;
+               offset = le32_to_cpu(hdr->ucode_array_offset_bytes);
+               memcpy(adev->uvd.cpu_addr, (adev->uvd.fw->data) + offset,
+                       (adev->uvd.fw->size) - offset);
+               size -= le32_to_cpu(hdr->ucode_size_bytes);
+               ptr += le32_to_cpu(hdr->ucode_size_bytes);
+               memset(ptr, 0, size);
+       }
 
        return 0;
 }
index 82ce7d9438843283d6afd1d7eb764fb26de266ae..05b0353d3880092271da1115007ae7ce91e4e69b 100644 (file)
@@ -903,14 +903,6 @@ static int gmc_v7_0_early_init(void *handle)
        gmc_v7_0_set_gart_funcs(adev);
        gmc_v7_0_set_irq_funcs(adev);
 
-       if (adev->flags & AMD_IS_APU) {
-               adev->mc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN;
-       } else {
-               u32 tmp = RREG32(mmMC_SEQ_MISC0);
-               tmp &= MC_SEQ_MISC0__MT__MASK;
-               adev->mc.vram_type = gmc_v7_0_convert_vram_type(tmp);
-       }
-
        return 0;
 }
 
@@ -927,6 +919,14 @@ static int gmc_v7_0_sw_init(void *handle)
        int dma_bits;
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
+       if (adev->flags & AMD_IS_APU) {
+               adev->mc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN;
+       } else {
+               u32 tmp = RREG32(mmMC_SEQ_MISC0);
+               tmp &= MC_SEQ_MISC0__MT__MASK;
+               adev->mc.vram_type = gmc_v7_0_convert_vram_type(tmp);
+       }
+
        r = amdgpu_irq_add_id(adev, 146, &adev->mc.vm_fault);
        if (r)
                return r;
index 29bd7b57dc912be1b33fdc06ce7ab8944527c804..02deb322940565baa6d1d3e3f648fe7cf152e6aa 100644 (file)
@@ -863,14 +863,6 @@ static int gmc_v8_0_early_init(void *handle)
        gmc_v8_0_set_gart_funcs(adev);
        gmc_v8_0_set_irq_funcs(adev);
 
-       if (adev->flags & AMD_IS_APU) {
-               adev->mc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN;
-       } else {
-               u32 tmp = RREG32(mmMC_SEQ_MISC0);
-               tmp &= MC_SEQ_MISC0__MT__MASK;
-               adev->mc.vram_type = gmc_v8_0_convert_vram_type(tmp);
-       }
-
        return 0;
 }
 
@@ -881,12 +873,27 @@ static int gmc_v8_0_late_init(void *handle)
        return amdgpu_irq_get(adev, &adev->mc.vm_fault, 0);
 }
 
+#define mmMC_SEQ_MISC0_FIJI 0xA71
+
 static int gmc_v8_0_sw_init(void *handle)
 {
        int r;
        int dma_bits;
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
+       if (adev->flags & AMD_IS_APU) {
+               adev->mc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN;
+       } else {
+               u32 tmp;
+
+               if (adev->asic_type == CHIP_FIJI)
+                       tmp = RREG32(mmMC_SEQ_MISC0_FIJI);
+               else
+                       tmp = RREG32(mmMC_SEQ_MISC0);
+               tmp &= MC_SEQ_MISC0__MT__MASK;
+               adev->mc.vram_type = gmc_v8_0_convert_vram_type(tmp);
+       }
+
        r = amdgpu_irq_add_id(adev, 146, &adev->mc.vm_fault);
        if (r)
                return r;
index c606ccb38d8b98bd8e05fd588352102cd3601cbc..cb463753115b8d4f8266464a9d69956be21a5750 100644 (file)
@@ -224,11 +224,11 @@ static int uvd_v4_2_suspend(void *handle)
        int r;
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
-       r = amdgpu_uvd_suspend(adev);
+       r = uvd_v4_2_hw_fini(adev);
        if (r)
                return r;
 
-       r = uvd_v4_2_hw_fini(adev);
+       r = amdgpu_uvd_suspend(adev);
        if (r)
                return r;
 
index e3c852d9d79a45285c0dcb9445e43896be763eae..16476d80f475a77c17ae4bb8a5f60aa05c4562c8 100644 (file)
@@ -220,11 +220,11 @@ static int uvd_v5_0_suspend(void *handle)
        int r;
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
-       r = amdgpu_uvd_suspend(adev);
+       r = uvd_v5_0_hw_fini(adev);
        if (r)
                return r;
 
-       r = uvd_v5_0_hw_fini(adev);
+       r = amdgpu_uvd_suspend(adev);
        if (r)
                return r;
 
index 3375e614ac67121f5832f56e0e480a1166601481..d49379145ef22e8468866a1b60bb17d40ebb5e70 100644 (file)
@@ -214,15 +214,16 @@ static int uvd_v6_0_suspend(void *handle)
        int r;
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
+       r = uvd_v6_0_hw_fini(adev);
+       if (r)
+               return r;
+
        /* Skip this for APU for now */
        if (!(adev->flags & AMD_IS_APU)) {
                r = amdgpu_uvd_suspend(adev);
                if (r)
                        return r;
        }
-       r = uvd_v6_0_hw_fini(adev);
-       if (r)
-               return r;
 
        return r;
 }
index aec38fc3834f9d867b4477c2f1d1d1166285f1fe..ab84d494724774d77100756c85c6d2a689b25516 100644 (file)
@@ -589,6 +589,8 @@ typedef int(*cgs_get_active_displays_info)(
                                        void *cgs_device,
                                        struct cgs_display_info *info);
 
+typedef int (*cgs_notify_dpm_enabled)(void *cgs_device, bool enabled);
+
 typedef int (*cgs_call_acpi_method)(void *cgs_device,
                                        uint32_t acpi_method,
                                        uint32_t acpi_function,
@@ -644,6 +646,8 @@ struct cgs_ops {
        cgs_set_clockgating_state set_clockgating_state;
        /* display manager */
        cgs_get_active_displays_info get_active_displays_info;
+       /* notify dpm enabled */
+       cgs_notify_dpm_enabled notify_dpm_enabled;
        /* ACPI */
        cgs_call_acpi_method call_acpi_method;
        /* get system info */
@@ -734,8 +738,12 @@ struct cgs_device
        CGS_CALL(set_powergating_state, dev, block_type, state)
 #define cgs_set_clockgating_state(dev, block_type, state)      \
        CGS_CALL(set_clockgating_state, dev, block_type, state)
+#define cgs_notify_dpm_enabled(dev, enabled)   \
+       CGS_CALL(notify_dpm_enabled, dev, enabled)
+
 #define cgs_get_active_displays_info(dev, info)        \
        CGS_CALL(get_active_displays_info, dev, info)
+
 #define cgs_call_acpi_method(dev, acpi_method, acpi_function, pintput, poutput, output_count, input_size, output_size) \
        CGS_CALL(call_acpi_method, dev, acpi_method, acpi_function, pintput, poutput, output_count, input_size, output_size)
 #define cgs_query_system_info(dev, sys_info)   \
index 6b52c78cb404870ae019b3cd262f7d9711b590b3..56856a2864d108c89cb2a961398f8f3613159fcc 100644 (file)
@@ -137,14 +137,14 @@ static const pem_event_action *resume_event[] = {
        reset_display_configCounter_tasks,
        update_dal_configuration_tasks,
        vari_bright_resume_tasks,
-       block_adjust_power_state_tasks,
        setup_asic_tasks,
        enable_stutter_mode_tasks, /*must do this in boot state and before SMC is started */
        enable_dynamic_state_management_tasks,
        enable_clock_power_gatings_tasks,
        enable_disable_bapm_tasks,
        initialize_thermal_controller_tasks,
-       reset_boot_state_tasks,
+       get_2d_performance_state_tasks,
+       set_performance_state_tasks,
        adjust_power_state_tasks,
        enable_disable_fps_tasks,
        notify_hw_power_source_tasks,
index 51dedf84623c6b7473e3c753143e95fa7791e1e8..89f31bc5b68b9e061d31a2fb2494c7e4f60d276f 100644 (file)
@@ -2389,6 +2389,7 @@ static int fiji_populate_smc_vce_level(struct pp_hwmgr *hwmgr,
 
        for(count = 0; count < table->VceLevelCount; count++) {
                table->VceLevel[count].Frequency = mm_table->entries[count].eclk;
+               table->VceLevel[count].MinVoltage = 0;
                table->VceLevel[count].MinVoltage |=
                                (mm_table->entries[count].vddc * VOLTAGE_SCALE) << VDDC_SHIFT;
                table->VceLevel[count].MinVoltage |=
@@ -2465,6 +2466,7 @@ static int fiji_populate_smc_samu_level(struct pp_hwmgr *hwmgr,
 
        for (count = 0; count < table->SamuLevelCount; count++) {
                /* not sure whether we need evclk or not */
+               table->SamuLevel[count].MinVoltage = 0;
                table->SamuLevel[count].Frequency = mm_table->entries[count].samclock;
                table->SamuLevel[count].MinVoltage |= (mm_table->entries[count].vddc *
                                VOLTAGE_SCALE) << VDDC_SHIFT;
@@ -2562,6 +2564,7 @@ static int fiji_populate_smc_uvd_level(struct pp_hwmgr *hwmgr,
        table->UvdBootLevel = 0;
 
        for (count = 0; count < table->UvdLevelCount; count++) {
+               table->UvdLevel[count].MinVoltage = 0;
                table->UvdLevel[count].VclkFrequency = mm_table->entries[count].vclk;
                table->UvdLevel[count].DclkFrequency = mm_table->entries[count].dclk;
                table->UvdLevel[count].MinVoltage |= (mm_table->entries[count].vddc *
@@ -2900,6 +2903,8 @@ static int fiji_init_smc_table(struct pp_hwmgr *hwmgr)
        if(FIJI_VOLTAGE_CONTROL_NONE != data->voltage_control)
                fiji_populate_smc_voltage_tables(hwmgr, table);
 
+       table->SystemFlags = 0;
+
        if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
                        PHM_PlatformCaps_AutomaticDCTransition))
                table->SystemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC;
@@ -2997,6 +3002,7 @@ static int fiji_init_smc_table(struct pp_hwmgr *hwmgr)
        table->MemoryThermThrottleEnable = 1;
        table->PCIeBootLinkLevel = 0;      /* 0:Gen1 1:Gen2 2:Gen3*/
        table->PCIeGenInterval = 1;
+       table->VRConfig = 0;
 
        result = fiji_populate_vr_config(hwmgr, table);
        PP_ASSERT_WITH_CODE(0 == result,
@@ -5195,6 +5201,67 @@ static int fiji_print_clock_levels(struct pp_hwmgr *hwmgr,
        return size;
 }
 
+static inline bool fiji_are_power_levels_equal(const struct fiji_performance_level *pl1,
+                                                          const struct fiji_performance_level *pl2)
+{
+       return ((pl1->memory_clock == pl2->memory_clock) &&
+                 (pl1->engine_clock == pl2->engine_clock) &&
+                 (pl1->pcie_gen == pl2->pcie_gen) &&
+                 (pl1->pcie_lane == pl2->pcie_lane));
+}
+
+int fiji_check_states_equal(struct pp_hwmgr *hwmgr, const struct pp_hw_power_state *pstate1, const struct pp_hw_power_state *pstate2, bool *equal)
+{
+       const struct fiji_power_state *psa = cast_const_phw_fiji_power_state(pstate1);
+       const struct fiji_power_state *psb = cast_const_phw_fiji_power_state(pstate2);
+       int i;
+
+       if (equal == NULL || psa == NULL || psb == NULL)
+               return -EINVAL;
+
+       /* If the two states don't even have the same number of performance levels they cannot be the same state. */
+       if (psa->performance_level_count != psb->performance_level_count) {
+               *equal = false;
+               return 0;
+       }
+
+       for (i = 0; i < psa->performance_level_count; i++) {
+               if (!fiji_are_power_levels_equal(&(psa->performance_levels[i]), &(psb->performance_levels[i]))) {
+                       /* If we have found even one performance level pair that is different the states are different. */
+                       *equal = false;
+                       return 0;
+               }
+       }
+
+       /* If all performance levels are the same try to use the UVD clocks to break the tie.*/
+       *equal = ((psa->uvd_clks.vclk == psb->uvd_clks.vclk) && (psa->uvd_clks.dclk == psb->uvd_clks.dclk));
+       *equal &= ((psa->vce_clks.evclk == psb->vce_clks.evclk) && (psa->vce_clks.ecclk == psb->vce_clks.ecclk));
+       *equal &= (psa->sclk_threshold == psb->sclk_threshold);
+       *equal &= (psa->acp_clk == psb->acp_clk);
+
+       return 0;
+}
+
+bool fiji_check_smc_update_required_for_display_configuration(struct pp_hwmgr *hwmgr)
+{
+       struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+       bool is_update_required = false;
+       struct cgs_display_info info = {0,0,NULL};
+
+       cgs_get_active_displays_info(hwmgr->device, &info);
+
+       if (data->display_timing.num_existing_displays != info.display_count)
+               is_update_required = true;
+/* TO DO NEED TO GET DEEP SLEEP CLOCK FROM DAL
+       if (phm_cap_enabled(hwmgr->hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_SclkDeepSleep)) {
+               cgs_get_min_clock_settings(hwmgr->device, &min_clocks);
+               if(min_clocks.engineClockInSR != data->display_timing.minClockInSR)
+                       is_update_required = true;
+*/
+       return is_update_required;
+}
+
+
 static const struct pp_hwmgr_func fiji_hwmgr_funcs = {
        .backend_init = &fiji_hwmgr_backend_init,
        .backend_fini = &tonga_hwmgr_backend_fini,
@@ -5230,6 +5297,8 @@ static const struct pp_hwmgr_func fiji_hwmgr_funcs = {
        .register_internal_thermal_interrupt = fiji_register_internal_thermal_interrupt,
        .set_fan_control_mode = fiji_set_fan_control_mode,
        .get_fan_control_mode = fiji_get_fan_control_mode,
+       .check_states_equal = fiji_check_states_equal,
+       .check_smc_update_required_for_display_configuration = fiji_check_smc_update_required_for_display_configuration,
        .get_pp_table = fiji_get_pp_table,
        .set_pp_table = fiji_set_pp_table,
        .force_clock_level = fiji_force_clock_level,
index be31bed2538ade909b95b4cc95c6c24602466c35..fa208ada689219f4eb072ebb5e655e0a03cc9ab7 100644 (file)
@@ -58,6 +58,9 @@ void phm_init_dynamic_caps(struct pp_hwmgr *hwmgr)
 
        phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_VpuRecoveryInProgress);
 
+       phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_UVDDPM);
+       phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_VCEDPM);
+
        if (acpi_atcs_functions_supported(hwmgr->device, ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST) &&
                acpi_atcs_functions_supported(hwmgr->device, ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION))
                phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PCIEPerformanceRequest);
@@ -130,18 +133,25 @@ int phm_set_power_state(struct pp_hwmgr *hwmgr,
 
 int phm_enable_dynamic_state_management(struct pp_hwmgr *hwmgr)
 {
+       int ret = 1;
+       bool enabled;
        PHM_FUNC_CHECK(hwmgr);
 
        if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
                PHM_PlatformCaps_TablelessHardwareInterface)) {
                if (NULL != hwmgr->hwmgr_func->dynamic_state_management_enable)
-                       return hwmgr->hwmgr_func->dynamic_state_management_enable(hwmgr);
+                       ret = hwmgr->hwmgr_func->dynamic_state_management_enable(hwmgr);
        } else {
-               return phm_dispatch_table(hwmgr,
+               ret = phm_dispatch_table(hwmgr,
                                &(hwmgr->enable_dynamic_state_management),
                                NULL, NULL);
        }
-       return 0;
+
+       enabled = ret == 0 ? true : false;
+
+       cgs_notify_dpm_enabled(hwmgr->device, enabled);
+
+       return ret;
 }
 
 int phm_force_dpm_levels(struct pp_hwmgr *hwmgr, enum amd_dpm_forced_level level)
index cf61e0856f4af2faa699118cf08bbf097cc24763..b80b08f71cb46e8d69d7bd94f6d951008267500e 100644 (file)
@@ -275,13 +275,15 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
                if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev))
                        atombios_enable_crtc_memreq(crtc, ATOM_ENABLE);
                atombios_blank_crtc(crtc, ATOM_DISABLE);
-               drm_vblank_on(dev, radeon_crtc->crtc_id);
+               if (dev->num_crtcs > radeon_crtc->crtc_id)
+                       drm_vblank_on(dev, radeon_crtc->crtc_id);
                radeon_crtc_load_lut(crtc);
                break;
        case DRM_MODE_DPMS_STANDBY:
        case DRM_MODE_DPMS_SUSPEND:
        case DRM_MODE_DPMS_OFF:
-               drm_vblank_off(dev, radeon_crtc->crtc_id);
+               if (dev->num_crtcs > radeon_crtc->crtc_id)
+                       drm_vblank_off(dev, radeon_crtc->crtc_id);
                if (radeon_crtc->enabled)
                        atombios_blank_crtc(crtc, ATOM_ENABLE);
                if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev))
index 979f3bf65f2c474f231a26eb47af963d4436be0f..1e9304d1c88fd4e844ee9c5bd36300ed992e0f29 100644 (file)
@@ -291,6 +291,8 @@ int radeon_irq_kms_init(struct radeon_device *rdev)
        if (r) {
                return r;
        }
+       rdev->ddev->vblank_disable_allowed = true;
+
        /* enable msi */
        rdev->msi_enabled = 0;
 
index 24152dfef19985bccc02b869853dd66f77d12e9e..478d4099b0d0e2b2d995d47bb74322ab46adf73b 100644 (file)
@@ -331,13 +331,15 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode)
                                                                         RADEON_CRTC_DISP_REQ_EN_B));
                        WREG32_P(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl, ~(mask | crtc_ext_cntl));
                }
-               drm_vblank_on(dev, radeon_crtc->crtc_id);
+               if (dev->num_crtcs > radeon_crtc->crtc_id)
+                       drm_vblank_on(dev, radeon_crtc->crtc_id);
                radeon_crtc_load_lut(crtc);
                break;
        case DRM_MODE_DPMS_STANDBY:
        case DRM_MODE_DPMS_SUSPEND:
        case DRM_MODE_DPMS_OFF:
-               drm_vblank_off(dev, radeon_crtc->crtc_id);
+               if (dev->num_crtcs > radeon_crtc->crtc_id)
+                       drm_vblank_off(dev, radeon_crtc->crtc_id);
                if (radeon_crtc->crtc_id)
                        WREG32_P(RADEON_CRTC2_GEN_CNTL, mask, ~(RADEON_CRTC2_EN | mask));
                else {
index afae2316bd434e0067f5007f4467c3b0e3f54bb9..055a08ddac02a4a5b1149470f7bd74a03b173096 100644 (file)
@@ -92,7 +92,7 @@ struct ttm_placement {
  */
 struct ttm_bus_placement {
        void            *addr;
-       unsigned long   base;
+       phys_addr_t     base;
        unsigned long   size;
        unsigned long   offset;
        bool            is_iomem;
This page took 0.039218 seconds and 5 git commands to generate.