Merge tag 'drm-next-2024-01-19' of git://anongit.freedesktop.org/drm/drm
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 19 Jan 2024 19:50:00 +0000 (11:50 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 19 Jan 2024 19:50:00 +0000 (11:50 -0800)
Pull more drm fixes from Dave Airlie:
 "This is mostly amdgpu and xe fixes, with an amdkfd and nouveau fix
  thrown in.

  The amdgpu ones are just the usual couple of weeks of fixes. The xe
  ones are bunch of cleanups for the new xe driver, the fix you put in
  on the merge commit and the kconfig fix that was hiding the problem
  from me.

  amdgpu:
   - DSC fixes
   - DC resource pool fixes
   - OTG fix
   - DML2 fixes
   - Aux fix
   - GFX10 RLC firmware handling fix
   - Revert a broken workaround for SMU 13.0.2
   - DC writeback fix
   - Enable gfxoff when ROCm apps are active on gfx11 with the proper FW
     version

  amdkfd:
   - Fix dma-buf exports using GEM handles

  nouveau:
   - fix a unneeded WARN_ON triggering

  xe:
   - Fix for definition of wakeref_t
   - Fix for an error code aliasing
   - Fix for VM_UNBIND_ALL in the case there are no bound VMAs
   - Fixes for a number of __iomem address space mismatches reported by
     sparse
   - Fixes for the assignment of exec_queue priority
   - A Fix for skip_guc_pc not taking effect
   - Workaround for a build problem on GCC 11
   - A couple of fixes for error paths
   - Fix a Flat CCS compression metadata copy issue
   - Fix a misplace array bounds checking
   - Don't have display support depend on EXPERT (as discussed on IRC)"

* tag 'drm-next-2024-01-19' of git://anongit.freedesktop.org/drm/drm: (71 commits)
  nouveau/vmm: don't set addr on the fail path to avoid warning
  drm/amdgpu: Enable GFXOFF for Compute on GFX11
  drm/amd/display: Drop 'acrtc' and add 'new_crtc_state' NULL check for writeback requests.
  drm/amdgpu: revert "Adjust removal control flow for smu v13_0_2"
  drm/amdkfd: init drm_client with funcs hook
  drm/amd/display: Fix a switch statement in populate_dml_output_cfg_from_stream_state()
  drm/amdgpu: Fix the null pointer when load rlc firmware
  drm/amd/display: Align the returned error code with legacy DP
  drm/amd/display: Fix DML2 watermark calculation
  drm/amd/display: Clear OPTC mem select on disable
  drm/amd/display: Port DENTIST hang and TDR fixes to OTG disable W/A
  drm/amd/display: Add logging resource checks
  drm/amd/display: Init link enc resources in dc_state only if res_pool presents
  drm/amd/display: Fix late derefrence 'dsc' check in 'link_set_dsc_pps_packet()'
  drm/amd/display: Avoid enum conversion warning
  drm/amd/pm: Fix smuv13.0.6 current clock reporting
  drm/amd/pm: Add error log for smu v13.0.6 reset
  drm/amdkfd: Fix 'node' NULL check in 'svm_range_get_range_boundaries()'
  drm/amdgpu: drop exp hw support check for GC 9.4.3
  drm/amdgpu: move debug options init prior to amdgpu device init
  ...

85 files changed:
drivers/gpu/drm/amd/amdgpu/amdgpu.h
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h
drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.c
drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.h
drivers/gpu/drm/amd/amdgpu/athub_v3_0.c
drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
drivers/gpu/drm/amd/amdgpu/gfxhub_v1_2.c
drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c
drivers/gpu/drm/amd/amdgpu/nbio_v7_9.c
drivers/gpu/drm/amd/amdgpu/umc_v6_7.c
drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
drivers/gpu/drm/amd/amdkfd/kfd_priv.h
drivers/gpu/drm/amd/amdkfd/kfd_process.c
drivers/gpu/drm/amd/amdkfd/kfd_svm.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.h
drivers/gpu/drm/amd/display/dc/core/dc.c
drivers/gpu/drm/amd/display/dc/core/dc_resource.c
drivers/gpu/drm/amd/display/dc/core/dc_state.c
drivers/gpu/drm/amd/display/dc/dc.h
drivers/gpu/drm/amd/display/dc/dc_stream.h
drivers/gpu/drm/amd/display/dc/dc_types.h
drivers/gpu/drm/amd/display/dc/dce/dce_audio.c
drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c
drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c
drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c
drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c
drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h
drivers/gpu/drm/amd/display/dc/inc/resource.h
drivers/gpu/drm/amd/display/dc/link/link_dpms.c
drivers/gpu/drm/amd/display/dc/link/link_validation.c
drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia.c
drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c
drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.h
drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c
drivers/gpu/drm/amd/display/dc/optc/dcn32/dcn32_optc.c
drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.c
drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.h
drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c
drivers/gpu/drm/amd/display/include/audio_types.h
drivers/gpu/drm/amd/include/asic_reg/nbio/nbio_7_11_0_offset.h
drivers/gpu/drm/amd/pm/amdgpu_pm.c
drivers/gpu/drm/amd/pm/powerplay/hwmgr/process_pptables_v1_0.c
drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c
drivers/gpu/drm/nouveau/nouveau_vmm.c
drivers/gpu/drm/xe/Kconfig
drivers/gpu/drm/xe/Makefile
drivers/gpu/drm/xe/tests/xe_bo.c
drivers/gpu/drm/xe/tests/xe_migrate.c
drivers/gpu/drm/xe/xe_bo.c
drivers/gpu/drm/xe/xe_device.c
drivers/gpu/drm/xe/xe_device_types.h
drivers/gpu/drm/xe/xe_exec.c
drivers/gpu/drm/xe/xe_exec_queue.c
drivers/gpu/drm/xe/xe_exec_queue_types.h
drivers/gpu/drm/xe/xe_gt_freq.c
drivers/gpu/drm/xe/xe_guc.c
drivers/gpu/drm/xe/xe_guc_submit.c
drivers/gpu/drm/xe/xe_migrate.c
drivers/gpu/drm/xe/xe_mmio.c
drivers/gpu/drm/xe/xe_ttm_stolen_mgr.c
drivers/gpu/drm/xe/xe_vm.c

index 9da14436a3738f8b950db3aa44a71b47c6e4952c..3d8a48f46b015613dc44517ebd20d5250df5a3b1 100644 (file)
@@ -254,8 +254,6 @@ extern int amdgpu_agp;
 
 extern int amdgpu_wbrf;
 
-extern int fw_bo_location;
-
 #define AMDGPU_VM_MAX_NUM_CTX                  4096
 #define AMDGPU_SG_THRESHOLD                    (256*1024*1024)
 #define AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS         3000
@@ -1146,6 +1144,7 @@ struct amdgpu_device {
        bool                            debug_vm;
        bool                            debug_largebar;
        bool                            debug_disable_soft_recovery;
+       bool                            debug_use_vram_fw_buf;
 };
 
 static inline uint32_t amdgpu_ip_version(const struct amdgpu_device *adev,
index 067690ba7bffd4192817fe3acf9d46a19f1f274c..77e2636602887034c188ec695591d20e5b087b60 100644 (file)
@@ -138,6 +138,9 @@ static void amdgpu_amdkfd_reset_work(struct work_struct *work)
        amdgpu_device_gpu_recover(adev, NULL, &reset_context);
 }
 
+static const struct drm_client_funcs kfd_client_funcs = {
+       .unregister     = drm_client_release,
+};
 void amdgpu_amdkfd_device_init(struct amdgpu_device *adev)
 {
        int i;
@@ -161,7 +164,7 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev)
                        .enable_mes = adev->enable_mes,
                };
 
-               ret = drm_client_init(&adev->ddev, &adev->kfd.client, "kfd", NULL);
+               ret = drm_client_init(&adev->ddev, &adev->kfd.client, "kfd", &kfd_client_funcs);
                if (ret) {
                        dev_err(adev->dev, "Failed to init DRM client: %d\n", ret);
                        return;
@@ -695,10 +698,8 @@ err:
 void amdgpu_amdkfd_set_compute_idle(struct amdgpu_device *adev, bool idle)
 {
        enum amd_powergating_state state = idle ? AMD_PG_STATE_GATE : AMD_PG_STATE_UNGATE;
-       /* Temporary workaround to fix issues observed in some
-        * compute applications when GFXOFF is enabled on GFX11.
-        */
-       if (IP_VERSION_MAJ(amdgpu_ip_version(adev, GC_HWIP, 0)) == 11) {
+       if (IP_VERSION_MAJ(amdgpu_ip_version(adev, GC_HWIP, 0)) == 11 &&
+           ((adev->mes.kiq_version & AMDGPU_MES_VERSION_MASK) <= 64)) {
                pr_debug("GFXOFF is %s\n", idle ? "enabled" : "disabled");
                amdgpu_gfx_off_ctrl(adev, idle);
        } else if ((IP_VERSION_MAJ(amdgpu_ip_version(adev, GC_HWIP, 0)) == 9) &&
index cf6ed5fce291f946854d329fa91e0fb6eedbc61a..f262b9d89541a8a971a394b5f0da0f6a1368ba65 100644 (file)
@@ -311,7 +311,7 @@ void amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(struct kgd_mem *mem);
 int amdgpu_amdkfd_map_gtt_bo_to_gart(struct amdgpu_device *adev, struct amdgpu_bo *bo);
 
 int amdgpu_amdkfd_gpuvm_restore_process_bos(void *process_info,
-                                           struct dma_fence **ef);
+                                           struct dma_fence __rcu **ef);
 int amdgpu_amdkfd_gpuvm_get_vm_fault_info(struct amdgpu_device *adev,
                                              struct kfd_vm_fault_info *info);
 int amdgpu_amdkfd_gpuvm_import_dmabuf_fd(struct amdgpu_device *adev, int fd,
index d17b2452cb1f69df276dd95518cf0ca340539237..f183d7faeeece16cfc7c211f5a6a0232dce37c36 100644 (file)
@@ -2802,7 +2802,7 @@ unlock_out:
        put_task_struct(usertask);
 }
 
-static void replace_eviction_fence(struct dma_fence **ef,
+static void replace_eviction_fence(struct dma_fence __rcu **ef,
                                   struct dma_fence *new_ef)
 {
        struct dma_fence *old_ef = rcu_replace_pointer(*ef, new_ef, true
@@ -2837,7 +2837,7 @@ static void replace_eviction_fence(struct dma_fence **ef,
  * 7.  Add fence to all PD and PT BOs.
  * 8.  Unreserve all BOs
  */
-int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct dma_fence **ef)
+int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct dma_fence __rcu **ef)
 {
        struct amdkfd_process_info *process_info = info;
        struct amdgpu_vm *peer_vm;
index 5bb444bb36cece19b00fe27f0923c42b1bc1c83f..b158d27d0a71cbbafb55f0d58657c1ec178fa6c2 100644 (file)
@@ -1544,6 +1544,7 @@ bool amdgpu_device_need_post(struct amdgpu_device *adev)
                                return true;
 
                        fw_ver = *((uint32_t *)adev->pm.fw->data + 69);
+                       release_firmware(adev->pm.fw);
                        if (fw_ver < 0x00160e00)
                                return true;
                }
@@ -5245,7 +5246,6 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle,
        struct amdgpu_device *tmp_adev = NULL;
        bool need_full_reset, skip_hw_reset, vram_lost = false;
        int r = 0;
-       bool gpu_reset_for_dev_remove = 0;
 
        /* Try reset handler method first */
        tmp_adev = list_first_entry(device_list_handle, struct amdgpu_device,
@@ -5265,10 +5265,6 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle,
                test_bit(AMDGPU_NEED_FULL_RESET, &reset_context->flags);
        skip_hw_reset = test_bit(AMDGPU_SKIP_HW_RESET, &reset_context->flags);
 
-       gpu_reset_for_dev_remove =
-               test_bit(AMDGPU_RESET_FOR_DEVICE_REMOVE, &reset_context->flags) &&
-                       test_bit(AMDGPU_NEED_FULL_RESET, &reset_context->flags);
-
        /*
         * ASIC reset has to be done on all XGMI hive nodes ASAP
         * to allow proper links negotiation in FW (within 1 sec)
@@ -5311,18 +5307,6 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle,
                amdgpu_ras_intr_cleared();
        }
 
-       /* Since the mode1 reset affects base ip blocks, the
-        * phase1 ip blocks need to be resumed. Otherwise there
-        * will be a BIOS signature error and the psp bootloader
-        * can't load kdb on the next amdgpu install.
-        */
-       if (gpu_reset_for_dev_remove) {
-               list_for_each_entry(tmp_adev, device_list_handle, reset_list)
-                       amdgpu_device_ip_resume_phase1(tmp_adev);
-
-               goto end;
-       }
-
        list_for_each_entry(tmp_adev, device_list_handle, reset_list) {
                if (need_full_reset) {
                        /* post card */
@@ -5559,11 +5543,6 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
        int i, r = 0;
        bool need_emergency_restart = false;
        bool audio_suspended = false;
-       bool gpu_reset_for_dev_remove = false;
-
-       gpu_reset_for_dev_remove =
-                       test_bit(AMDGPU_RESET_FOR_DEVICE_REMOVE, &reset_context->flags) &&
-                               test_bit(AMDGPU_NEED_FULL_RESET, &reset_context->flags);
 
        /*
         * Special case: RAS triggered and full reset isn't supported
@@ -5601,7 +5580,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
        if (!amdgpu_sriov_vf(adev) && (adev->gmc.xgmi.num_physical_nodes > 1)) {
                list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head) {
                        list_add_tail(&tmp_adev->reset_list, &device_list);
-                       if (gpu_reset_for_dev_remove && adev->shutdown)
+                       if (adev->shutdown)
                                tmp_adev->shutdown = true;
                }
                if (!list_is_first(&adev->reset_list, &device_list))
@@ -5686,10 +5665,6 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
 
 retry: /* Rest of adevs pre asic reset from XGMI hive. */
        list_for_each_entry(tmp_adev, device_list_handle, reset_list) {
-               if (gpu_reset_for_dev_remove) {
-                       /* Workaroud for ASICs need to disable SMC first */
-                       amdgpu_device_smu_fini_early(tmp_adev);
-               }
                r = amdgpu_device_pre_asic_reset(tmp_adev, reset_context);
                /*TODO Should we stop ?*/
                if (r) {
@@ -5721,9 +5696,6 @@ retry:    /* Rest of adevs pre asic reset from XGMI hive. */
                r = amdgpu_do_asic_reset(device_list_handle, reset_context);
                if (r && r == -EAGAIN)
                        goto retry;
-
-               if (!r && gpu_reset_for_dev_remove)
-                       goto recover_end;
        }
 
 skip_hw_reset:
@@ -5779,7 +5751,6 @@ skip_sched_resume:
                amdgpu_ras_set_error_query_ready(tmp_adev, true);
        }
 
-recover_end:
        tmp_adev = list_first_entry(device_list_handle, struct amdgpu_device,
                                            reset_list);
        amdgpu_device_unlock_reset_domain(tmp_adev->reset_domain);
index 0431eafa86b5324f4d63cc6060cea30baa03088b..c7d60dd0fb975d47d749300c79f976da15892736 100644 (file)
@@ -1963,8 +1963,6 @@ static int amdgpu_discovery_set_gc_ip_blocks(struct amdgpu_device *adev)
                amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block);
                break;
        case IP_VERSION(9, 4, 3):
-               if (!amdgpu_exp_hw_support)
-                       return -EINVAL;
                amdgpu_device_ip_block_add(adev, &gfx_v9_4_3_ip_block);
                break;
        case IP_VERSION(10, 1, 10):
index 852cec98ff262359fb823ccb26f1b9977da8dec9..cc69005f5b46e7b9f06d65db13287a617cc384e2 100644 (file)
@@ -128,6 +128,7 @@ enum AMDGPU_DEBUG_MASK {
        AMDGPU_DEBUG_VM = BIT(0),
        AMDGPU_DEBUG_LARGEBAR = BIT(1),
        AMDGPU_DEBUG_DISABLE_GPU_SOFT_RECOVERY = BIT(2),
+       AMDGPU_DEBUG_USE_VRAM_FW_BUF = BIT(3),
 };
 
 unsigned int amdgpu_vram_limit = UINT_MAX;
@@ -210,7 +211,6 @@ int amdgpu_seamless = -1; /* auto */
 uint amdgpu_debug_mask;
 int amdgpu_agp = -1; /* auto */
 int amdgpu_wbrf = -1;
-int fw_bo_location = -1;
 
 static void amdgpu_drv_delayed_reset_work_handler(struct work_struct *work);
 
@@ -990,10 +990,6 @@ MODULE_PARM_DESC(wbrf,
        "Enable Wifi RFI interference mitigation (0 = disabled, 1 = enabled, -1 = auto(default)");
 module_param_named(wbrf, amdgpu_wbrf, int, 0444);
 
-MODULE_PARM_DESC(fw_bo_location,
-       "location to put firmware bo for frontdoor loading (-1 = auto (default), 0 = on ram, 1 = on vram");
-module_param(fw_bo_location, int, 0644);
-
 /* These devices are not supported by amdgpu.
  * They are supported by the mach64, r128, radeon drivers
  */
@@ -2122,6 +2118,11 @@ static void amdgpu_init_debug_options(struct amdgpu_device *adev)
                pr_info("debug: soft reset for GPU recovery disabled\n");
                adev->debug_disable_soft_recovery = true;
        }
+
+       if (amdgpu_debug_mask & AMDGPU_DEBUG_USE_VRAM_FW_BUF) {
+               pr_info("debug: place fw in vram for frontdoor loading\n");
+               adev->debug_use_vram_fw_buf = true;
+       }
 }
 
 static unsigned long amdgpu_fix_asic_type(struct pci_dev *pdev, unsigned long flags)
@@ -2233,6 +2234,8 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
 
        pci_set_drvdata(pdev, ddev);
 
+       amdgpu_init_debug_options(adev);
+
        ret = amdgpu_driver_load_kms(adev, flags);
        if (ret)
                goto err_pci;
@@ -2313,8 +2316,6 @@ retry_init:
                        amdgpu_get_secondary_funcs(adev);
        }
 
-       amdgpu_init_debug_options(adev);
-
        return 0;
 
 err_pci:
@@ -2336,38 +2337,6 @@ amdgpu_pci_remove(struct pci_dev *pdev)
                pm_runtime_forbid(dev->dev);
        }
 
-       if (amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 2) &&
-           !amdgpu_sriov_vf(adev)) {
-               bool need_to_reset_gpu = false;
-
-               if (adev->gmc.xgmi.num_physical_nodes > 1) {
-                       struct amdgpu_hive_info *hive;
-
-                       hive = amdgpu_get_xgmi_hive(adev);
-                       if (hive->device_remove_count == 0)
-                               need_to_reset_gpu = true;
-                       hive->device_remove_count++;
-                       amdgpu_put_xgmi_hive(hive);
-               } else {
-                       need_to_reset_gpu = true;
-               }
-
-               /* Workaround for ASICs need to reset SMU.
-                * Called only when the first device is removed.
-                */
-               if (need_to_reset_gpu) {
-                       struct amdgpu_reset_context reset_context;
-
-                       adev->shutdown = true;
-                       memset(&reset_context, 0, sizeof(reset_context));
-                       reset_context.method = AMD_RESET_METHOD_NONE;
-                       reset_context.reset_req_dev = adev;
-                       set_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
-                       set_bit(AMDGPU_RESET_FOR_DEVICE_REMOVE, &reset_context.flags);
-                       amdgpu_device_gpu_recover(adev, NULL, &reset_context);
-               }
-       }
-
        amdgpu_driver_unload_kms(dev);
 
        /*
index d2f273d77e59557ba5185cbfa36e243788d3d86e..55784a9f26c4c83b17008a766130c234df8ecbaf 100644 (file)
@@ -1045,21 +1045,28 @@ int amdgpu_gmc_vram_checking(struct amdgpu_device *adev)
         * seconds, so here, we just pick up three parts for emulation.
         */
        ret = memcmp(vram_ptr, cptr, 10);
-       if (ret)
-               return ret;
+       if (ret) {
+               ret = -EIO;
+               goto release_buffer;
+       }
 
        ret = memcmp(vram_ptr + (size / 2), cptr, 10);
-       if (ret)
-               return ret;
+       if (ret) {
+               ret = -EIO;
+               goto release_buffer;
+       }
 
        ret = memcmp(vram_ptr + size - 10, cptr, 10);
-       if (ret)
-               return ret;
+       if (ret) {
+               ret = -EIO;
+               goto release_buffer;
+       }
 
+release_buffer:
        amdgpu_bo_free_kernel(&vram_bo, &vram_gpu,
                        &vram_ptr);
 
-       return 0;
+       return ret;
 }
 
 static ssize_t current_memory_partition_show(
index b5ebafd4a3adf82e37b29f9df84cbf6541955441..bf4f48fe438d1b5936852145c8b4c1059446381c 100644 (file)
@@ -1105,7 +1105,12 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
                        if (amdgpu_dpm_read_sensor(adev,
                                                   AMDGPU_PP_SENSOR_GPU_AVG_POWER,
                                                   (void *)&ui32, &ui32_size)) {
-                               return -EINVAL;
+                               /* fall back to input power for backwards compat */
+                               if (amdgpu_dpm_read_sensor(adev,
+                                                          AMDGPU_PP_SENSOR_GPU_INPUT_POWER,
+                                                          (void *)&ui32, &ui32_size)) {
+                                       return -EINVAL;
+                               }
                        }
                        ui32 >>= 8;
                        break;
index 2addbdf88394b8287b0ea9fb87297b3435e826fb..0328616473f80af861cd4a1176afc0221eee7db9 100644 (file)
@@ -466,7 +466,7 @@ static int psp_sw_init(void *handle)
        }
 
        ret = amdgpu_bo_create_kernel(adev, PSP_1_MEG, PSP_1_MEG,
-                                     (amdgpu_sriov_vf(adev) || fw_bo_location == 1) ?
+                                     (amdgpu_sriov_vf(adev) || adev->debug_use_vram_fw_buf) ?
                                      AMDGPU_GEM_DOMAIN_VRAM : AMDGPU_GEM_DOMAIN_GTT,
                                      &psp->fw_pri_bo,
                                      &psp->fw_pri_mc_addr,
index fc42fb6ee1914b82e0bec3897cf92594f587423f..31823a30dea217b5af3a8a36624a01fab70b48a5 100644 (file)
@@ -305,11 +305,13 @@ static int amdgpu_ras_debugfs_ctrl_parse_data(struct file *f,
                        return -EINVAL;
 
                data->head.block = block_id;
-               /* only ue and ce errors are supported */
+               /* only ue, ce and poison errors are supported */
                if (!memcmp("ue", err, 2))
                        data->head.type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE;
                else if (!memcmp("ce", err, 2))
                        data->head.type = AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE;
+               else if (!memcmp("poison", err, 6))
+                       data->head.type = AMDGPU_RAS_ERROR__POISON;
                else
                        return -EINVAL;
 
@@ -431,9 +433,10 @@ static void amdgpu_ras_instance_mask_check(struct amdgpu_device *adev,
  * The block is one of: umc, sdma, gfx, etc.
  *     see ras_block_string[] for details
  *
- * The error type is one of: ue, ce, where,
+ * The error type is one of: ue, ce and poison where,
  *     ue is multi-uncorrectable
  *     ce is single-correctable
+ *     poison is poison
  *
  * The sub-block is a the sub-block index, pass 0 if there is no sub-block.
  * The address and value are hexadecimal numbers, leading 0x is optional.
@@ -1067,8 +1070,7 @@ static void amdgpu_ras_error_print_error_data(struct amdgpu_device *adev,
                        mcm_info = &err_info->mcm_info;
                        if (err_info->ce_count) {
                                dev_info(adev->dev, "socket: %d, die: %d, "
-                                        "%lld new correctable hardware errors detected in %s block, "
-                                        "no user action is needed\n",
+                                        "%lld new correctable hardware errors detected in %s block\n",
                                         mcm_info->socket_id,
                                         mcm_info->die_id,
                                         err_info->ce_count,
@@ -1080,8 +1082,7 @@ static void amdgpu_ras_error_print_error_data(struct amdgpu_device *adev,
                        err_info = &err_node->err_info;
                        mcm_info = &err_info->mcm_info;
                        dev_info(adev->dev, "socket: %d, die: %d, "
-                                "%lld correctable hardware errors detected in total in %s block, "
-                                "no user action is needed\n",
+                                "%lld correctable hardware errors detected in total in %s block\n",
                                 mcm_info->socket_id, mcm_info->die_id, err_info->ce_count, blk_name);
                }
        }
@@ -1108,16 +1109,14 @@ static void amdgpu_ras_error_generate_report(struct amdgpu_device *adev,
                           adev->smuio.funcs->get_die_id) {
                        dev_info(adev->dev, "socket: %d, die: %d "
                                 "%ld correctable hardware errors "
-                                "detected in %s block, no user "
-                                "action is needed.\n",
+                                "detected in %s block\n",
                                 adev->smuio.funcs->get_socket_id(adev),
                                 adev->smuio.funcs->get_die_id(adev),
                                 ras_mgr->err_data.ce_count,
                                 blk_name);
                } else {
                        dev_info(adev->dev, "%ld correctable hardware errors "
-                                "detected in %s block, no user "
-                                "action is needed.\n",
+                                "detected in %s block\n",
                                 ras_mgr->err_data.ce_count,
                                 blk_name);
                }
@@ -1920,7 +1919,7 @@ static void amdgpu_ras_interrupt_poison_creation_handler(struct ras_manager *obj
                                struct amdgpu_iv_entry *entry)
 {
        dev_info(obj->adev->dev,
-               "Poison is created, no user action is needed.\n");
+               "Poison is created\n");
 }
 
 static void amdgpu_ras_interrupt_umc_handler(struct ras_manager *obj,
@@ -2920,6 +2919,11 @@ int amdgpu_ras_init(struct amdgpu_device *adev)
 
        amdgpu_ras_query_poison_mode(adev);
 
+       /* Packed socket_id to ras feature mask bits[31:29] */
+       if (adev->smuio.funcs &&
+           adev->smuio.funcs->get_socket_id)
+               con->features |= ((adev->smuio.funcs->get_socket_id(adev)) << 29);
+
        /* Get RAS schema for particular SOC */
        con->schema = amdgpu_get_ras_schema(adev);
 
index b0335a1c5e90cb8f000fe1989bfb20dfbbd53c58..19899f6b9b2b419a0fdf2ed84c71f0278963f511 100644 (file)
@@ -32,7 +32,6 @@ enum AMDGPU_RESET_FLAGS {
 
        AMDGPU_NEED_FULL_RESET = 0,
        AMDGPU_SKIP_HW_RESET = 1,
-       AMDGPU_RESET_FOR_DEVICE_REMOVE = 2,
 };
 
 struct amdgpu_reset_context {
index d334e42fe0ebe648e3efafb3970f650b615f716d..3e12763e477aa45724d0c16a1b514a5a299a76a9 100644 (file)
@@ -1062,7 +1062,7 @@ int amdgpu_ucode_create_bo(struct amdgpu_device *adev)
 {
        if (adev->firmware.load_type != AMDGPU_FW_LOAD_DIRECT) {
                amdgpu_bo_create_kernel(adev, adev->firmware.fw_size, PAGE_SIZE,
-                       (amdgpu_sriov_vf(adev) || fw_bo_location == 1) ?
+                       (amdgpu_sriov_vf(adev) || adev->debug_use_vram_fw_buf) ?
                        AMDGPU_GEM_DOMAIN_VRAM : AMDGPU_GEM_DOMAIN_GTT,
                        &adev->firmware.fw_buf,
                        &adev->firmware.fw_buf_mc,
index b6cd565562ad8d9a99270757fc2b37352600d2f3..4740dd65b99d6ccc107e5d63aba0f0d67d02d718 100644 (file)
@@ -116,7 +116,7 @@ struct amdgpu_mem_stats;
 #define AMDGPU_VM_FAULT_STOP_FIRST     1
 #define AMDGPU_VM_FAULT_STOP_ALWAYS    2
 
-/* Reserve 4MB VRAM for page tables */
+/* How much VRAM be reserved for page tables */
 #define AMDGPU_VM_RESERVED_VRAM                (8ULL << 20)
 
 /*
index 6f149b54d4d3970c5fe0a8255f8f7a080433381a..b9a15d51eb5c30e554d4e4f7c1397e3ce51996d9 100644 (file)
@@ -59,11 +59,8 @@ static inline uint16_t complete_integer_division_u16(
 
 static uint16_t vpe_u1_8_from_fraction(uint16_t numerator, uint16_t denominator)
 {
-       bool arg1_negative = numerator < 0;
-       bool arg2_negative = denominator < 0;
-
-       uint16_t arg1_value = (uint16_t)(arg1_negative ? -numerator : numerator);
-       uint16_t arg2_value = (uint16_t)(arg2_negative ? -denominator : denominator);
+       u16 arg1_value = numerator;
+       u16 arg2_value = denominator;
 
        uint16_t remainder;
 
@@ -100,9 +97,6 @@ static uint16_t vpe_u1_8_from_fraction(uint16_t numerator, uint16_t denominator)
                res_value += summand;
        }
 
-       if (arg1_negative ^ arg2_negative)
-               res_value = -res_value;
-
        return res_value;
 }
 
index 6cab882e8061e80f33bca5eb1a7b59d8cf0a687f..1592c63b3099b982d0b9bdda596919da8ec14f5f 100644 (file)
@@ -43,7 +43,6 @@ struct amdgpu_hive_info {
        } pstate;
 
        struct amdgpu_reset_domain *reset_domain;
-       uint32_t device_remove_count;
        atomic_t ras_recovery;
 };
 
index f0737fb3a999e03a44eb3c08f6e0099e3326c929..d1bba9c64e16d808fbaafd4e01d8764cb77b1a86 100644 (file)
@@ -30,6 +30,8 @@
 
 #define regATHUB_MISC_CNTL_V3_0_1                      0x00d7
 #define regATHUB_MISC_CNTL_V3_0_1_BASE_IDX             0
+#define regATHUB_MISC_CNTL_V3_3_0                      0x00d8
+#define regATHUB_MISC_CNTL_V3_3_0_BASE_IDX             0
 
 
 static uint32_t athub_v3_0_get_cg_cntl(struct amdgpu_device *adev)
@@ -40,6 +42,9 @@ static uint32_t athub_v3_0_get_cg_cntl(struct amdgpu_device *adev)
        case IP_VERSION(3, 0, 1):
                data = RREG32_SOC15(ATHUB, 0, regATHUB_MISC_CNTL_V3_0_1);
                break;
+       case IP_VERSION(3, 3, 0):
+               data = RREG32_SOC15(ATHUB, 0, regATHUB_MISC_CNTL_V3_3_0);
+               break;
        default:
                data = RREG32_SOC15(ATHUB, 0, regATHUB_MISC_CNTL);
                break;
@@ -53,6 +58,9 @@ static void athub_v3_0_set_cg_cntl(struct amdgpu_device *adev, uint32_t data)
        case IP_VERSION(3, 0, 1):
                WREG32_SOC15(ATHUB, 0, regATHUB_MISC_CNTL_V3_0_1, data);
                break;
+       case IP_VERSION(3, 3, 0):
+               WREG32_SOC15(ATHUB, 0, regATHUB_MISC_CNTL_V3_3_0, data);
+               break;
        default:
                WREG32_SOC15(ATHUB, 0, regATHUB_MISC_CNTL, data);
                break;
index 73f6d7e72c737537f17264746b061a936b4960e5..d63cab294883b8b44caa908d5bafaeaf19750ef6 100644 (file)
@@ -3996,16 +3996,13 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)
 
        if (!amdgpu_sriov_vf(adev)) {
                snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_rlc.bin", ucode_prefix);
-               err = amdgpu_ucode_request(adev, &adev->gfx.rlc_fw, fw_name);
-               /* don't check this.  There are apparently firmwares in the wild with
-                * incorrect size in the header
-                */
-               if (err == -ENODEV)
-                       goto out;
+               err = request_firmware(&adev->gfx.rlc_fw, fw_name, adev->dev);
                if (err)
-                       dev_dbg(adev->dev,
-                               "gfx10: amdgpu_ucode_request() failed \"%s\"\n",
-                               fw_name);
+                       goto out;
+
+               /* don't validate this firmware. There are apparently firmwares
+                * in the wild with incorrect size in the header
+                */
                rlc_hdr = (const struct rlc_firmware_header_v2_0 *)adev->gfx.rlc_fw->data;
                version_major = le16_to_cpu(rlc_hdr->header.header_version_major);
                version_minor = le16_to_cpu(rlc_hdr->header.header_version_minor);
index 2fbcd9765980d01a79b9b295fc28d82a909c69a9..0ea0866c261f84e24e8494755387b3d22482a0a2 100644 (file)
@@ -115,7 +115,7 @@ static const struct soc15_reg_golden golden_settings_gc_11_5_0[] = {
        SOC15_REG_GOLDEN_VALUE(GC, 0, regGL2C_ADDR_MATCH_MASK, 0xffffffff, 0xfffffff3),
        SOC15_REG_GOLDEN_VALUE(GC, 0, regGL2C_CTRL, 0xffffffff, 0xf37fff3f),
        SOC15_REG_GOLDEN_VALUE(GC, 0, regGL2C_CTRL3, 0xfffffffb, 0x00f40188),
-       SOC15_REG_GOLDEN_VALUE(GC, 0, regGL2C_CTRL4, 0xf0ffffff, 0x8000b007),
+       SOC15_REG_GOLDEN_VALUE(GC, 0, regGL2C_CTRL4, 0xf0ffffff, 0x80009007),
        SOC15_REG_GOLDEN_VALUE(GC, 0, regPA_CL_ENHANCE, 0xf1ffffff, 0x00880007),
        SOC15_REG_GOLDEN_VALUE(GC, 0, regPC_CONFIG_CNTL_1, 0xffffffff, 0x00010000),
        SOC15_REG_GOLDEN_VALUE(GC, 0, regTA_CNTL_AUX, 0xf7f7ffff, 0x01030000),
@@ -6383,6 +6383,9 @@ static int gfx_v11_0_get_cu_info(struct amdgpu_device *adev,
        mutex_lock(&adev->grbm_idx_mutex);
        for (i = 0; i < adev->gfx.config.max_shader_engines; i++) {
                for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) {
+                       bitmap = i * adev->gfx.config.max_sh_per_se + j;
+                       if (!((gfx_v11_0_get_sa_active_bitmap(adev) >> bitmap) & 1))
+                               continue;
                        mask = 1;
                        counter = 0;
                        gfx_v11_0_select_se_sh(adev, i, j, 0xffffffff, 0);
index 95d06da544e2a54ebe6fb10ad1309a0c8074814f..49aecdcee006959491e4dba90058faf35e205fdb 100644 (file)
@@ -456,10 +456,12 @@ static void gfxhub_v1_2_xcc_gart_disable(struct amdgpu_device *adev,
                WREG32_SOC15_RLC(GC, GET_INST(GC, j), regMC_VM_MX_L1_TLB_CNTL, tmp);
 
                /* Setup L2 cache */
-               tmp = RREG32_SOC15(GC, GET_INST(GC, j), regVM_L2_CNTL);
-               tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, ENABLE_L2_CACHE, 0);
-               WREG32_SOC15(GC, GET_INST(GC, j), regVM_L2_CNTL, tmp);
-               WREG32_SOC15(GC, GET_INST(GC, j), regVM_L2_CNTL3, 0);
+               if (!amdgpu_sriov_vf(adev)) {
+                       tmp = RREG32_SOC15(GC, GET_INST(GC, j), regVM_L2_CNTL);
+                       tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, ENABLE_L2_CACHE, 0);
+                       WREG32_SOC15(GC, GET_INST(GC, j), regVM_L2_CNTL, tmp);
+                       WREG32_SOC15(GC, GET_INST(GC, j), regVM_L2_CNTL3, 0);
+               }
        }
 }
 
index 6d24c84924cb5dd646ddaa69bb91a3193493b5f4..19986ff6a48d7e773dcc892b9dccd585fe69c306 100644 (file)
@@ -401,8 +401,7 @@ static void nbio_v7_4_handle_ras_controller_intr_no_bifring(struct amdgpu_device
 
                        if (err_data.ce_count)
                                dev_info(adev->dev, "%ld correctable hardware "
-                                               "errors detected in %s block, "
-                                               "no user action is needed.\n",
+                                               "errors detected in %s block\n",
                                                obj->err_data.ce_count,
                                                get_ras_block_str(adev->nbio.ras_if));
 
index 25a3da83e0fb97e5949221d17e3fcd63062dd29c..e90f33780803458c32843f2599c07e4f598ca659 100644 (file)
@@ -597,8 +597,7 @@ static void nbio_v7_9_handle_ras_controller_intr_no_bifring(struct amdgpu_device
 
                        if (err_data.ce_count)
                                dev_info(adev->dev, "%ld correctable hardware "
-                                               "errors detected in %s block, "
-                                               "no user action is needed.\n",
+                                               "errors detected in %s block\n",
                                                obj->err_data.ce_count,
                                                get_ras_block_str(adev->nbio.ras_if));
 
index 530549314ce46c541a192305d1a7e1db17f11ebf..a3ee3c4c650febb4ca6fa61c9b7b5b51f16ce60c 100644 (file)
@@ -64,7 +64,7 @@ static void umc_v6_7_query_error_status_helper(struct amdgpu_device *adev,
        uint64_t reg_value;
 
        if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Deferred) == 1)
-               dev_info(adev->dev, "Deferred error, no user action is needed.\n");
+               dev_info(adev->dev, "Deferred error\n");
 
        if (mc_umc_status)
                dev_info(adev->dev, "MCA STATUS 0x%llx, umc_reg_offset 0x%x\n", mc_umc_status, umc_reg_offset);
index d630100b9e91b8588dc2e9611e279fba909e54c5..f856901055d34e605cd4ec51fbdfc3be18e2abeb 100644 (file)
@@ -1026,7 +1026,7 @@ int kgd2kfd_init_zone_device(struct amdgpu_device *adev)
        } else {
                res = devm_request_free_mem_region(adev->dev, &iomem_resource, size);
                if (IS_ERR(res))
-                       return -ENOMEM;
+                       return PTR_ERR(res);
                pgmap->range.start = res->start;
                pgmap->range.end = res->end;
                pgmap->type = MEMORY_DEVICE_PRIVATE;
@@ -1042,10 +1042,10 @@ int kgd2kfd_init_zone_device(struct amdgpu_device *adev)
        r = devm_memremap_pages(adev->dev, pgmap);
        if (IS_ERR(r)) {
                pr_err("failed to register HMM device memory\n");
-               /* Disable SVM support capability */
-               pgmap->type = 0;
                if (pgmap->type == MEMORY_DEVICE_PRIVATE)
                        devm_release_mem_region(adev->dev, res->start, resource_size(res));
+               /* Disable SVM support capability */
+               pgmap->type = 0;
                return PTR_ERR(r);
        }
 
index 745024b313401261a73900360c3d50f62d8440d8..17fbedbf3651388edfcd0109a22d0fe9dfcd331f 100644 (file)
@@ -917,7 +917,7 @@ struct kfd_process {
         * fence will be triggered during eviction and new one will be created
         * during restore
         */
-       struct dma_fence *ef;
+       struct dma_fence __rcu *ef;
 
        /* Work items for evicting and restoring BOs */
        struct delayed_work eviction_work;
index 71df51fcc1b0d80f42899a0e15ae454b3f03f2bc..717a60d7a4ea953b8dfc369b09d855ad74b49659 100644 (file)
@@ -1110,6 +1110,7 @@ static void kfd_process_wq_release(struct work_struct *work)
 {
        struct kfd_process *p = container_of(work, struct kfd_process,
                                             release_work);
+       struct dma_fence *ef;
 
        kfd_process_dequeue_from_all_devices(p);
        pqm_uninit(&p->pqm);
@@ -1118,7 +1119,9 @@ static void kfd_process_wq_release(struct work_struct *work)
         * destroyed. This allows any BOs to be freed without
         * triggering pointless evictions or waiting for fences.
         */
-       dma_fence_signal(p->ef);
+       synchronize_rcu();
+       ef = rcu_access_pointer(p->ef);
+       dma_fence_signal(ef);
 
        kfd_process_remove_sysfs(p);
 
@@ -1127,7 +1130,7 @@ static void kfd_process_wq_release(struct work_struct *work)
        svm_range_list_fini(p);
 
        kfd_process_destroy_pdds(p);
-       dma_fence_put(p->ef);
+       dma_fence_put(ef);
 
        kfd_event_free_process(p);
 
index ac84c4a2ca072a7629f1f933214bd2d17a230ac7..c50a0dc9c9c072f5692d003bce90aaaf13615c5d 100644 (file)
@@ -404,14 +404,9 @@ static void svm_range_bo_release(struct kref *kref)
                spin_lock(&svm_bo->list_lock);
        }
        spin_unlock(&svm_bo->list_lock);
-       if (!dma_fence_is_signaled(&svm_bo->eviction_fence->base)) {
-               /* We're not in the eviction worker.
-                * Signal the fence and synchronize with any
-                * pending eviction work.
-                */
+       if (!dma_fence_is_signaled(&svm_bo->eviction_fence->base))
+               /* We're not in the eviction worker. Signal the fence. */
                dma_fence_signal(&svm_bo->eviction_fence->base);
-               cancel_work_sync(&svm_bo->eviction_work);
-       }
        dma_fence_put(&svm_bo->eviction_fence->base);
        amdgpu_bo_unref(&svm_bo->bo);
        kfree(svm_bo);
@@ -2345,8 +2340,10 @@ retry:
                mutex_unlock(&svms->lock);
                mmap_write_unlock(mm);
 
-               /* Pairs with mmget in svm_range_add_list_work */
-               mmput(mm);
+               /* Pairs with mmget in svm_range_add_list_work. If dropping the
+                * last mm refcount, schedule release work to avoid circular locking
+                */
+               mmput_async(mm);
 
                spin_lock(&svms->deferred_list_lock);
        }
@@ -2657,6 +2654,7 @@ svm_range_get_range_boundaries(struct kfd_process *p, int64_t addr,
 {
        struct vm_area_struct *vma;
        struct interval_tree_node *node;
+       struct rb_node *rb_node;
        unsigned long start_limit, end_limit;
 
        vma = vma_lookup(p->mm, addr << PAGE_SHIFT);
@@ -2676,16 +2674,15 @@ svm_range_get_range_boundaries(struct kfd_process *p, int64_t addr,
        if (node) {
                end_limit = min(end_limit, node->start);
                /* Last range that ends before the fault address */
-               node = container_of(rb_prev(&node->rb),
-                                   struct interval_tree_node, rb);
+               rb_node = rb_prev(&node->rb);
        } else {
                /* Last range must end before addr because
                 * there was no range after addr
                 */
-               node = container_of(rb_last(&p->svms.objects.rb_root),
-                                   struct interval_tree_node, rb);
+               rb_node = rb_last(&p->svms.objects.rb_root);
        }
-       if (node) {
+       if (rb_node) {
+               node = container_of(rb_node, struct interval_tree_node, rb);
                if (node->last >= addr) {
                        WARN(1, "Overlap with prev node and page fault addr\n");
                        return -EFAULT;
@@ -3432,13 +3429,14 @@ svm_range_trigger_migration(struct mm_struct *mm, struct svm_range *prange,
 
 int svm_range_schedule_evict_svm_bo(struct amdgpu_amdkfd_fence *fence)
 {
-       if (!fence)
-               return -EINVAL;
-
-       if (dma_fence_is_signaled(&fence->base))
-               return 0;
-
-       if (fence->svm_bo) {
+       /* Dereferencing fence->svm_bo is safe here because the fence hasn't
+        * signaled yet and we're under the protection of the fence->lock.
+        * After the fence is signaled in svm_range_bo_release, we cannot get
+        * here any more.
+        *
+        * Reference is dropped in svm_range_evict_svm_bo_worker.
+        */
+       if (svm_bo_ref_unless_zero(fence->svm_bo)) {
                WRITE_ONCE(fence->svm_bo->evicting, 1);
                schedule_work(&fence->svm_bo->eviction_work);
        }
@@ -3453,8 +3451,6 @@ static void svm_range_evict_svm_bo_worker(struct work_struct *work)
        int r = 0;
 
        svm_bo = container_of(work, struct svm_range_bo, eviction_work);
-       if (!svm_bo_ref_unless_zero(svm_bo))
-               return; /* svm_bo was freed while eviction was pending */
 
        if (mmget_not_zero(svm_bo->eviction_fence->mm)) {
                mm = svm_bo->eviction_fence->mm;
index b569b6eda4e3c9f0a978b2d9c65fd868e22a35d8..d4f525b66a09055909e163b815beee357f28d19d 100644 (file)
@@ -9292,10 +9292,10 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
                if (!new_con_state->writeback_job)
                        continue;
 
-               new_crtc_state = NULL;
+               new_crtc_state = drm_atomic_get_new_crtc_state(state, &acrtc->base);
 
-               if (acrtc)
-                       new_crtc_state = drm_atomic_get_new_crtc_state(state, &acrtc->base);
+               if (!new_crtc_state)
+                       continue;
 
                if (acrtc->wb_enabled)
                        continue;
@@ -10752,7 +10752,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
                        DRM_DEBUG_DRIVER("drm_dp_mst_atomic_check() failed\n");
                        goto fail;
                }
-               status = dc_validate_global_state(dc, dm_state->context, false);
+               status = dc_validate_global_state(dc, dm_state->context, true);
                if (status != DC_OK) {
                        DRM_DEBUG_DRIVER("DC global validation failure: %s (%d)",
                                       dc_status_to_str(status), status);
index 9b527bffe11a1f55e1a63d94c937c829e0d6f820..c87b64e464ed5c8e13c6fb823b8bf9ca0bcfe0fc 100644 (file)
@@ -1239,7 +1239,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
        if (has_crtc_cm_degamma && ret != -EINVAL) {
                drm_dbg_kms(crtc->base.crtc->dev,
                            "doesn't support plane and CRTC degamma at the same time\n");
-                       return -EINVAL;
+               return -EINVAL;
        }
 
        /* If we are here, it means we don't have plane degamma settings, check
index eaf8d9f482446d5ea9728ec17657189e25917ae8..85b7f58a7f35a478f551ec097b1613b504ced535 100644 (file)
@@ -979,6 +979,11 @@ int dm_helper_dmub_aux_transfer_sync(
                struct aux_payload *payload,
                enum aux_return_code_type *operation_result)
 {
+       if (!link->hpd_status) {
+               *operation_result = AUX_RET_ERROR_HPD_DISCON;
+               return -1;
+       }
+
        return amdgpu_dm_process_dmub_aux_transfer_sync(ctx, link->link_index, payload,
                        operation_result);
 }
index 7575282563267c6cd33872debc3f59b7819d35f5..a84f1e376dee45f7fbefea37053c0df57074789a 100644 (file)
@@ -87,6 +87,20 @@ static const struct IP_BASE CLK_BASE = { { { { 0x00016C00, 0x02401800, 0, 0, 0,
 #define CLK1_CLK_PLL_REQ__PllSpineDiv_MASK     0x0000F000L
 #define CLK1_CLK_PLL_REQ__FbMult_frac_MASK     0xFFFF0000L
 
+#define regCLK1_CLK2_BYPASS_CNTL                       0x029c
+#define regCLK1_CLK2_BYPASS_CNTL_BASE_IDX      0
+
+#define CLK1_CLK2_BYPASS_CNTL__CLK2_BYPASS_SEL__SHIFT  0x0
+#define CLK1_CLK2_BYPASS_CNTL__CLK2_BYPASS_DIV__SHIFT  0x10
+#define CLK1_CLK2_BYPASS_CNTL__CLK2_BYPASS_SEL_MASK            0x00000007L
+#define CLK1_CLK2_BYPASS_CNTL__CLK2_BYPASS_DIV_MASK            0x000F0000L
+
+#define regCLK6_0_CLK6_spll_field_8                            0x464b
+#define regCLK6_0_CLK6_spll_field_8_BASE_IDX   0
+
+#define CLK6_0_CLK6_spll_field_8__spll_ssc_en__SHIFT   0xd
+#define CLK6_0_CLK6_spll_field_8__spll_ssc_en_MASK             0x00002000L
+
 #define REG(reg_name) \
        (CLK_BASE.instance[0].segment[reg ## reg_name ## _BASE_IDX] + reg ## reg_name)
 
@@ -131,35 +145,63 @@ static int dcn314_get_active_display_cnt_wa(
        return display_count;
 }
 
-static void dcn314_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state *context, bool disable)
+static void dcn314_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state *context,
+                                 bool safe_to_lower, bool disable)
 {
        struct dc *dc = clk_mgr_base->ctx->dc;
        int i;
 
        for (i = 0; i < dc->res_pool->pipe_count; ++i) {
-               struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+               struct pipe_ctx *pipe = safe_to_lower
+                       ? &context->res_ctx.pipe_ctx[i]
+                       : &dc->current_state->res_ctx.pipe_ctx[i];
 
                if (pipe->top_pipe || pipe->prev_odm_pipe)
                        continue;
                if (pipe->stream && (pipe->stream->dpms_off || dc_is_virtual_signal(pipe->stream->signal))) {
-                       struct stream_encoder *stream_enc = pipe->stream_res.stream_enc;
-
                        if (disable) {
-                               if (stream_enc && stream_enc->funcs->disable_fifo)
-                                       pipe->stream_res.stream_enc->funcs->disable_fifo(stream_enc);
+                               if (pipe->stream_res.tg && pipe->stream_res.tg->funcs->immediate_disable_crtc)
+                                       pipe->stream_res.tg->funcs->immediate_disable_crtc(pipe->stream_res.tg);
 
-                               pipe->stream_res.tg->funcs->immediate_disable_crtc(pipe->stream_res.tg);
                                reset_sync_context_for_pipe(dc, context, i);
                        } else {
                                pipe->stream_res.tg->funcs->enable_crtc(pipe->stream_res.tg);
-
-                               if (stream_enc && stream_enc->funcs->enable_fifo)
-                                       pipe->stream_res.stream_enc->funcs->enable_fifo(stream_enc);
                        }
                }
        }
 }
 
+bool dcn314_is_spll_ssc_enabled(struct clk_mgr *clk_mgr_base)
+{
+       struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
+       uint32_t ssc_enable;
+
+       REG_GET(CLK6_0_CLK6_spll_field_8, spll_ssc_en, &ssc_enable);
+
+       return ssc_enable == 1;
+}
+
+void dcn314_init_clocks(struct clk_mgr *clk_mgr)
+{
+       struct clk_mgr_internal *clk_mgr_int = TO_CLK_MGR_INTERNAL(clk_mgr);
+       uint32_t ref_dtbclk = clk_mgr->clks.ref_dtbclk_khz;
+
+       memset(&(clk_mgr->clks), 0, sizeof(struct dc_clocks));
+       // Assumption is that boot state always supports pstate
+       clk_mgr->clks.ref_dtbclk_khz = ref_dtbclk;      // restore ref_dtbclk
+       clk_mgr->clks.p_state_change_support = true;
+       clk_mgr->clks.prev_p_state_change_support = true;
+       clk_mgr->clks.pwr_state = DCN_PWR_STATE_UNKNOWN;
+       clk_mgr->clks.zstate_support = DCN_ZSTATE_SUPPORT_UNKNOWN;
+
+       // to adjust dp_dto reference clock if ssc is enable otherwise to apply dprefclk
+       if (dcn314_is_spll_ssc_enabled(clk_mgr))
+               clk_mgr->dp_dto_source_clock_in_khz =
+                       dce_adjust_dp_ref_freq_for_ss(clk_mgr_int, clk_mgr->dprefclk_khz);
+       else
+               clk_mgr->dp_dto_source_clock_in_khz = clk_mgr->dprefclk_khz;
+}
+
 void dcn314_update_clocks(struct clk_mgr *clk_mgr_base,
                        struct dc_state *context,
                        bool safe_to_lower)
@@ -252,11 +294,11 @@ void dcn314_update_clocks(struct clk_mgr *clk_mgr_base,
        }
 
        if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz)) {
-               dcn314_disable_otg_wa(clk_mgr_base, context, true);
+               dcn314_disable_otg_wa(clk_mgr_base, context, safe_to_lower, true);
 
                clk_mgr_base->clks.dispclk_khz = new_clocks->dispclk_khz;
                dcn314_smu_set_dispclk(clk_mgr, clk_mgr_base->clks.dispclk_khz);
-               dcn314_disable_otg_wa(clk_mgr_base, context, false);
+               dcn314_disable_otg_wa(clk_mgr_base, context, safe_to_lower, false);
 
                update_dispclk = true;
        }
@@ -436,6 +478,11 @@ static DpmClocks314_t dummy_clocks;
 
 static struct dcn314_watermarks dummy_wms = { 0 };
 
+static struct dcn314_ss_info_table ss_info_table = {
+       .ss_divider = 1000,
+       .ss_percentage = {0, 0, 375, 375, 375}
+};
+
 static void dcn314_build_watermark_ranges(struct clk_bw_params *bw_params, struct dcn314_watermarks *table)
 {
        int i, num_valid_sets;
@@ -708,13 +755,31 @@ static struct clk_mgr_funcs dcn314_funcs = {
        .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
        .get_dtb_ref_clk_frequency = dcn31_get_dtb_ref_freq_khz,
        .update_clocks = dcn314_update_clocks,
-       .init_clocks = dcn31_init_clocks,
+       .init_clocks = dcn314_init_clocks,
        .enable_pme_wa = dcn314_enable_pme_wa,
        .are_clock_states_equal = dcn314_are_clock_states_equal,
        .notify_wm_ranges = dcn314_notify_wm_ranges
 };
 extern struct clk_mgr_funcs dcn3_fpga_funcs;
 
+static void dcn314_read_ss_info_from_lut(struct clk_mgr_internal *clk_mgr)
+{
+       uint32_t clock_source;
+       //uint32_t ssc_enable;
+
+       REG_GET(CLK1_CLK2_BYPASS_CNTL, CLK2_BYPASS_SEL, &clock_source);
+       //REG_GET(CLK6_0_CLK6_spll_field_8, spll_ssc_en, &ssc_enable);
+
+       if (dcn314_is_spll_ssc_enabled(&clk_mgr->base) && (clock_source < ARRAY_SIZE(ss_info_table.ss_percentage))) {
+               clk_mgr->dprefclk_ss_percentage = ss_info_table.ss_percentage[clock_source];
+
+               if (clk_mgr->dprefclk_ss_percentage != 0) {
+                       clk_mgr->ss_on_dprefclk = true;
+                       clk_mgr->dprefclk_ss_divider = ss_info_table.ss_divider;
+               }
+       }
+}
+
 void dcn314_clk_mgr_construct(
                struct dc_context *ctx,
                struct clk_mgr_dcn314 *clk_mgr,
@@ -782,6 +847,7 @@ void dcn314_clk_mgr_construct(
        clk_mgr->base.base.dprefclk_khz = 600000;
        clk_mgr->base.base.clks.ref_dtbclk_khz = 600000;
        dce_clock_read_ss_info(&clk_mgr->base);
+       dcn314_read_ss_info_from_lut(&clk_mgr->base);
        /*if bios enabled SS, driver needs to adjust dtb clock, only enable with correct bios*/
 
        clk_mgr->base.base.bw_params = &dcn314_bw_params;
index 171f84340eb2fb1d532776ac348cc1fbfad858f5..002c28e807208e584396fdc99dc1822072e8ffa5 100644 (file)
@@ -28,6 +28,8 @@
 #define __DCN314_CLK_MGR_H__
 #include "clk_mgr_internal.h"
 
+#define DCN314_NUM_CLOCK_SOURCES   5
+
 struct dcn314_watermarks;
 
 struct dcn314_smu_watermark_set {
@@ -40,9 +42,18 @@ struct clk_mgr_dcn314 {
        struct dcn314_smu_watermark_set smu_wm_set;
 };
 
+struct dcn314_ss_info_table {
+       uint32_t ss_divider;
+       uint32_t ss_percentage[DCN314_NUM_CLOCK_SOURCES];
+};
+
 bool dcn314_are_clock_states_equal(struct dc_clocks *a,
                struct dc_clocks *b);
 
+bool dcn314_is_spll_ssc_enabled(struct clk_mgr *clk_mgr_base);
+
+void dcn314_init_clocks(struct clk_mgr *clk_mgr);
+
 void dcn314_update_clocks(struct clk_mgr *clk_mgr_base,
                        struct dc_state *context,
                        bool safe_to_lower);
index 2d7205058c64abfece9cd154a4aebea8958e0168..aa7c02ba948e9ce63aa84eb7518f9c73c80d107a 100644 (file)
@@ -411,12 +411,9 @@ bool dc_stream_adjust_vmin_vmax(struct dc *dc,
         * avoid conflicting with firmware updates.
         */
        if (dc->ctx->dce_version > DCE_VERSION_MAX)
-               if (dc->optimized_required)
+               if (dc->optimized_required || dc->wm_optimized_required)
                        return false;
 
-       if (!memcmp(&stream->adjust, adjust, sizeof(*adjust)))
-               return true;
-
        stream->adjust.v_total_max = adjust->v_total_max;
        stream->adjust.v_total_mid = adjust->v_total_mid;
        stream->adjust.v_total_mid_frame_num = adjust->v_total_mid_frame_num;
@@ -2230,6 +2227,7 @@ void dc_post_update_surfaces_to_stream(struct dc *dc)
        }
 
        dc->optimized_required = false;
+       dc->wm_optimized_required = false;
 }
 
 bool dc_set_generic_gpio_for_stereo(bool enable,
@@ -2652,6 +2650,8 @@ enum surface_update_type dc_check_update_surfaces_for_stream(
                } else if (memcmp(&dc->current_state->bw_ctx.bw.dcn.clk, &dc->clk_mgr->clks, offsetof(struct dc_clocks, prev_p_state_change_support)) != 0) {
                        dc->optimized_required = true;
                }
+
+               dc->optimized_required |= dc->wm_optimized_required;
        }
 
        return type;
@@ -2859,6 +2859,9 @@ static void copy_stream_update_to_stream(struct dc *dc,
        if (update->vrr_active_fixed)
                stream->vrr_active_fixed = *update->vrr_active_fixed;
 
+       if (update->crtc_timing_adjust)
+               stream->adjust = *update->crtc_timing_adjust;
+
        if (update->dpms_off)
                stream->dpms_off = *update->dpms_off;
 
@@ -3519,7 +3522,7 @@ static void commit_planes_for_stream(struct dc *dc,
        top_pipe_to_program = resource_get_otg_master_for_stream(
                                &context->res_ctx,
                                stream);
-
+       ASSERT(top_pipe_to_program != NULL);
        for (i = 0; i < dc->res_pool->pipe_count; i++) {
                struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i];
 
@@ -4288,7 +4291,8 @@ static bool full_update_required(struct dc *dc,
                        stream_update->mst_bw_update ||
                        stream_update->func_shaper ||
                        stream_update->lut3d_func ||
-                       stream_update->pending_test_pattern))
+                       stream_update->pending_test_pattern ||
+                       stream_update->crtc_timing_adjust))
                return true;
 
        if (stream) {
@@ -4341,6 +4345,8 @@ static bool should_commit_minimal_transition_for_windowed_mpo_odm(struct dc *dc,
 
        cur_pipe = resource_get_otg_master_for_stream(&dc->current_state->res_ctx, stream);
        new_pipe = resource_get_otg_master_for_stream(&context->res_ctx, stream);
+       if (!cur_pipe || !new_pipe)
+               return false;
        cur_is_odm_in_use = resource_get_odm_slice_count(cur_pipe) > 1;
        new_is_odm_in_use = resource_get_odm_slice_count(new_pipe) > 1;
        if (cur_is_odm_in_use == new_is_odm_in_use)
index 57f0ddd1592399821222c4c5abd3708dbd2bd6b0..9fbdb09697fd5ea16abe86e4f970e80fb764ff7f 100644 (file)
@@ -2194,6 +2194,10 @@ void resource_log_pipe_topology_update(struct dc *dc, struct dc_state *state)
        for (stream_idx = 0; stream_idx < state->stream_count; stream_idx++) {
                otg_master = resource_get_otg_master_for_stream(
                                &state->res_ctx, state->streams[stream_idx]);
+               if (!otg_master || otg_master->stream_res.tg == NULL) {
+                       DC_LOG_DC("topology update: otg_master NULL stream_idx %d!\n", stream_idx);
+                       return;
+               }
                slice_count = resource_get_opp_heads_for_otg_master(otg_master,
                                &state->res_ctx, opp_heads);
                for (slice_idx = 0; slice_idx < slice_count; slice_idx++) {
@@ -4986,20 +4990,6 @@ enum dc_status update_dp_encoder_resources_for_test_harness(const struct dc *dc,
        return DC_OK;
 }
 
-bool resource_subvp_in_use(struct dc *dc,
-               struct dc_state *context)
-{
-       uint32_t i;
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
-
-               if (dc_state_get_pipe_subvp_type(context, pipe) != SUBVP_NONE)
-                       return true;
-       }
-       return false;
-}
-
 bool check_subvp_sw_cursor_fallback_req(const struct dc *dc, struct dc_stream_state *stream)
 {
        if (!dc->debug.disable_subvp_high_refresh && is_subvp_high_refresh_candidate(stream))
index 460a8010c79fef0496755ce435f4691e20c3a08e..88c6436b28b69ca7f4791bdc47404cd5f73a5f83 100644 (file)
@@ -267,7 +267,8 @@ void dc_state_construct(struct dc *dc, struct dc_state *state)
        state->clk_mgr = dc->clk_mgr;
 
        /* Initialise DIG link encoder resource tracking variables. */
-       link_enc_cfg_init(dc, state);
+       if (dc->res_pool)
+               link_enc_cfg_init(dc, state);
 }
 
 void dc_state_destruct(struct dc_state *state)
@@ -433,8 +434,9 @@ bool dc_state_add_plane(
 
        otg_master_pipe = resource_get_otg_master_for_stream(
                        &state->res_ctx, stream);
-       added = resource_append_dpp_pipes_for_plane_composition(state,
-                       dc->current_state, pool, otg_master_pipe, plane_state);
+       if (otg_master_pipe)
+               added = resource_append_dpp_pipes_for_plane_composition(state,
+                               dc->current_state, pool, otg_master_pipe, plane_state);
 
        if (added) {
                stream_status->plane_states[stream_status->plane_count] =
index f30a341bc09014b156dbe4463b41f84b0f16e083..5d7aa882416b3435a5dcfbaf502a9f326981bc81 100644 (file)
@@ -51,7 +51,7 @@ struct aux_payload;
 struct set_config_cmd_payload;
 struct dmub_notification;
 
-#define DC_VER "3.2.265"
+#define DC_VER "3.2.266"
 
 #define MAX_SURFACES 3
 #define MAX_PLANES 6
@@ -1036,6 +1036,7 @@ struct dc {
 
        /* Require to optimize clocks and bandwidth for added/removed planes */
        bool optimized_required;
+       bool wm_optimized_required;
        bool idle_optimizations_allowed;
        bool enable_c20_dtm_b0;
 
index a23eebd9933b72ea5c1c2a951a560232250bf34c..ee10941caa5980999044407184e7a41b8548e6b0 100644 (file)
@@ -139,6 +139,7 @@ union stream_update_flags {
                uint32_t wb_update:1;
                uint32_t dsc_changed : 1;
                uint32_t mst_bw : 1;
+               uint32_t crtc_timing_adjust : 1;
                uint32_t fams_changed : 1;
        } bits;
 
@@ -325,6 +326,7 @@ struct dc_stream_update {
        struct dc_3dlut *lut3d_func;
 
        struct test_pattern *pending_test_pattern;
+       struct dc_crtc_timing_adjust *crtc_timing_adjust;
 };
 
 bool dc_is_stream_unchanged(
index 4f276169e05a91098662edc07fd50d0bc1ed327b..b08ccb8c68bc366386e82a566c452459da0aabdc 100644 (file)
@@ -1140,23 +1140,25 @@ struct dc_panel_config {
        } ilr;
 };
 
+#define MAX_SINKS_PER_LINK 4
+
 /*
  *  USB4 DPIA BW ALLOCATION STRUCTS
  */
 struct dc_dpia_bw_alloc {
-       int sink_verified_bw;  // The Verified BW that sink can allocated and use that has been verified already
-       int sink_allocated_bw; // The Actual Allocated BW that sink currently allocated
-       int sink_max_bw;       // The Max BW that sink can require/support
+       int remote_sink_req_bw[MAX_SINKS_PER_LINK]; // BW requested by remote sinks
+       int link_verified_bw;  // The Verified BW that link can allocated and use that has been verified already
+       int link_max_bw;       // The Max BW that link can require/support
+       int allocated_bw;      // The Actual Allocated BW for this DPIA
        int estimated_bw;      // The estimated available BW for this DPIA
        int bw_granularity;    // BW Granularity
+       int dp_overhead;       // DP overhead in dp tunneling
        bool bw_alloc_enabled; // The BW Alloc Mode Support is turned ON for all 3:  DP-Tx & Dpia & CM
        bool response_ready;   // Response ready from the CM side
        uint8_t nrd_max_lane_count; // Non-reduced max lane count
        uint8_t nrd_max_link_rate; // Non-reduced max link rate
 };
 
-#define MAX_SINKS_PER_LINK 4
-
 enum dc_hpd_enable_select {
        HPD_EN_FOR_ALL_EDP = 0,
        HPD_EN_FOR_PRIMARY_EDP_ONLY,
index 140598f18bbdd4cb4758ec7e9ec17c91286d0ecc..f0458b8f00af842b87ab91feadd71eef4c680e27 100644 (file)
@@ -782,7 +782,7 @@ static void get_azalia_clock_info_dp(
        /*audio_dto_module = dpDtoSourceClockInkhz * 10,000;
         *  [khz] ->[100Hz] */
        azalia_clock_info->audio_dto_module =
-               pll_info->dp_dto_source_clock_in_khz * 10;
+               pll_info->audio_dto_source_clock_in_khz * 10;
 }
 
 void dce_aud_wall_dto_setup(
index 5d3f6fa1011e8e33f5e7772bee445cb6602e278d..970644b695cd4f1d96f166cc1786987b460cdafd 100644 (file)
@@ -975,6 +975,9 @@ static bool dcn31_program_pix_clk(
                        look_up_in_video_optimized_rate_tlb(pix_clk_params->requested_pix_clk_100hz / 10);
        struct bp_pixel_clock_parameters bp_pc_params = {0};
        enum transmitter_color_depth bp_pc_colour_depth = TRANSMITTER_COLOR_DEPTH_24;
+
+       if (clock_source->ctx->dc->clk_mgr->dp_dto_source_clock_in_khz != 0)
+               dp_dto_ref_khz = clock_source->ctx->dc->clk_mgr->dp_dto_source_clock_in_khz;
        // For these signal types Driver to program DP_DTO without calling VBIOS Command table
        if (dc_is_dp_signal(pix_clk_params->signal_type) || dc_is_virtual_signal(pix_clk_params->signal_type)) {
                if (e) {
@@ -1088,6 +1091,10 @@ static bool get_pixel_clk_frequency_100hz(
        struct dce110_clk_src *clk_src = TO_DCE110_CLK_SRC(clock_source);
        unsigned int clock_hz = 0;
        unsigned int modulo_hz = 0;
+       unsigned int dp_dto_ref_khz = clock_source->ctx->dc->clk_mgr->dprefclk_khz;
+
+       if (clock_source->ctx->dc->clk_mgr->dp_dto_source_clock_in_khz != 0)
+               dp_dto_ref_khz = clock_source->ctx->dc->clk_mgr->dp_dto_source_clock_in_khz;
 
        if (clock_source->id == CLOCK_SOURCE_ID_DP_DTO) {
                clock_hz = REG_READ(PHASE[inst]);
@@ -1100,7 +1107,7 @@ static bool get_pixel_clk_frequency_100hz(
                        modulo_hz = REG_READ(MODULO[inst]);
                        if (modulo_hz)
                                *pixel_clk_khz = div_u64((uint64_t)clock_hz*
-                                       clock_source->ctx->dc->clk_mgr->dprefclk_khz*10,
+                                       dp_dto_ref_khz*10,
                                        modulo_hz);
                        else
                                *pixel_clk_khz = 0;
index e4a328b45c8a5153c6468486dff940a6eb9435a3..87760600e154dad46e911e28f0b2937e6e012602 100644 (file)
@@ -183,6 +183,20 @@ bool dcn32_all_pipes_have_stream_and_plane(struct dc *dc,
        return true;
 }
 
+bool dcn32_subvp_in_use(struct dc *dc,
+               struct dc_state *context)
+{
+       uint32_t i;
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+
+               if (dc_state_get_pipe_subvp_type(context, pipe) != SUBVP_NONE)
+                       return true;
+       }
+       return false;
+}
+
 bool dcn32_mpo_in_use(struct dc_state *context)
 {
        uint32_t i;
index aa68d010cbfd247057da5a210b5209ad7a62ded3..9f37f717a1f86f88c5fa41bc30f477406d70f3b8 100644 (file)
@@ -33,7 +33,6 @@
 #include "dcn30/dcn30_resource.h"
 #include "link.h"
 #include "dc_state_priv.h"
-#include "resource.h"
 
 #define DC_LOGGER_INIT(logger)
 
@@ -292,7 +291,7 @@ int dcn32_find_dummy_latency_index_for_fw_based_mclk_switch(struct dc *dc,
 
                /* for subvp + DRR case, if subvp pipes are still present we support pstate */
                if (vba->DRAMClockChangeSupport[vlevel][vba->maxMpcComb] == dm_dram_clock_change_unsupported &&
-                               resource_subvp_in_use(dc, context))
+                               dcn32_subvp_in_use(dc, context))
                        vba->DRAMClockChangeSupport[vlevel][context->bw_ctx.dml.vba.maxMpcComb] = temp_clock_change_support;
 
                if (vlevel < context->bw_ctx.dml.vba.soc.num_states &&
@@ -2273,7 +2272,7 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context,
        unsigned int dummy_latency_index = 0;
        int maxMpcComb = context->bw_ctx.dml.vba.maxMpcComb;
        unsigned int min_dram_speed_mts = context->bw_ctx.dml.vba.DRAMSpeed;
-       bool subvp_active = resource_subvp_in_use(dc, context);
+       bool subvp_in_use = dcn32_subvp_in_use(dc, context);
        unsigned int min_dram_speed_mts_margin;
        bool need_fclk_lat_as_dummy = false;
        bool is_subvp_p_drr = false;
@@ -2282,7 +2281,7 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context,
        dc_assert_fp_enabled();
 
        /* need to find dummy latency index for subvp */
-       if (subvp_active) {
+       if (subvp_in_use) {
                /* Override DRAMClockChangeSupport for SubVP + DRR case where the DRR cannot switch without stretching it's VBLANK */
                if (!pstate_en) {
                        context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][maxMpcComb] = dm_dram_clock_change_vblank_w_mall_sub_vp;
@@ -2468,7 +2467,7 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context,
                                dc->clk_mgr->bw_params->clk_table.entries[min_dram_speed_mts_offset].memclk_mhz * 16;
                }
 
-               if (!context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching && !subvp_active) {
+               if (!context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching && !subvp_in_use) {
                        /* find largest table entry that is lower than dram speed,
                         * but lower than DPM0 still uses DPM0
                         */
@@ -3528,7 +3527,7 @@ void dcn32_set_clock_limits(const struct _vcs_dpi_soc_bounding_box_st *soc_bb)
 void dcn32_override_min_req_memclk(struct dc *dc, struct dc_state *context)
 {
        // WA: restrict FPO and SubVP to use first non-strobe mode (DCN32 BW issue)
-       if ((context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching || resource_subvp_in_use(dc, context)) &&
+       if ((context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching || dcn32_subvp_in_use(dc, context)) &&
                        dc->dml.soc.num_chans <= 8) {
                int num_mclk_levels = dc->clk_mgr->bw_params->clk_table.num_entries_per_clk.num_memclk_levels;
 
index 3d12dabd39e47d0d2a3fc918dd1d07dbc3902e5d..475c4ec43c013f481a71ad5668a8aef82ac7ba0a 100644 (file)
@@ -166,9 +166,9 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_5_soc = {
        .num_states = 5,
        .sr_exit_time_us = 14.0,
        .sr_enter_plus_exit_time_us = 16.0,
-       .sr_exit_z8_time_us = 525.0,
-       .sr_enter_plus_exit_z8_time_us = 715.0,
-       .fclk_change_latency_us = 20.0,
+       .sr_exit_z8_time_us = 210.0,
+       .sr_enter_plus_exit_z8_time_us = 320.0,
+       .fclk_change_latency_us = 24.0,
        .usr_retraining_latency_us = 2,
        .writeback_latency_us = 12.0,
 
index b95bf27f2fe2fe9a943cda43ce121c07c548f5dc..9be5ebf3a8c0ba7805b793b108923e057f2fdfe0 100644 (file)
@@ -6229,7 +6229,7 @@ static void set_calculate_prefetch_schedule_params(struct display_mode_lib_st *m
                                CalculatePrefetchSchedule_params->GPUVMEnable = mode_lib->ms.cache_display_cfg.plane.GPUVMEnable;
                                CalculatePrefetchSchedule_params->HostVMEnable = mode_lib->ms.cache_display_cfg.plane.HostVMEnable;
                                CalculatePrefetchSchedule_params->HostVMMaxNonCachedPageTableLevels = mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels;
-                               CalculatePrefetchSchedule_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes;
+                               CalculatePrefetchSchedule_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024;
                                CalculatePrefetchSchedule_params->DynamicMetadataEnable = mode_lib->ms.cache_display_cfg.plane.DynamicMetadataEnable[k];
                                CalculatePrefetchSchedule_params->DynamicMetadataVMEnabled = mode_lib->ms.ip.dynamic_metadata_vm_enabled;
                                CalculatePrefetchSchedule_params->DynamicMetadataLinesBeforeActiveRequired = mode_lib->ms.cache_display_cfg.plane.DynamicMetadataLinesBeforeActiveRequired[k];
@@ -6329,7 +6329,7 @@ static void dml_prefetch_check(struct display_mode_lib_st *mode_lib)
                                mode_lib->ms.NoOfDPPThisState,
                                mode_lib->ms.dpte_group_bytes,
                                s->HostVMInefficiencyFactor,
-                               mode_lib->ms.soc.hostvm_min_page_size_kbytes,
+                               mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024,
                                mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels);
 
                s->NextMaxVStartup = s->MaxVStartupAllPlanes[j];
@@ -6542,7 +6542,7 @@ static void dml_prefetch_check(struct display_mode_lib_st *mode_lib)
                                                mode_lib->ms.cache_display_cfg.plane.HostVMEnable,
                                                mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels,
                                                mode_lib->ms.cache_display_cfg.plane.GPUVMEnable,
-                                               mode_lib->ms.soc.hostvm_min_page_size_kbytes,
+                                               mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024,
                                                mode_lib->ms.PDEAndMetaPTEBytesPerFrame[j][k],
                                                mode_lib->ms.MetaRowBytes[j][k],
                                                mode_lib->ms.DPTEBytesPerRow[j][k],
@@ -7687,7 +7687,7 @@ dml_bool_t dml_core_mode_support(struct display_mode_lib_st *mode_lib)
                CalculateVMRowAndSwath_params->HostVMMaxNonCachedPageTableLevels = mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels;
                CalculateVMRowAndSwath_params->GPUVMMaxPageTableLevels = mode_lib->ms.cache_display_cfg.plane.GPUVMMaxPageTableLevels;
                CalculateVMRowAndSwath_params->GPUVMMinPageSizeKBytes = mode_lib->ms.cache_display_cfg.plane.GPUVMMinPageSizeKBytes;
-               CalculateVMRowAndSwath_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes;
+               CalculateVMRowAndSwath_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024;
                CalculateVMRowAndSwath_params->PTEBufferModeOverrideEn = mode_lib->ms.cache_display_cfg.plane.PTEBufferModeOverrideEn;
                CalculateVMRowAndSwath_params->PTEBufferModeOverrideVal = mode_lib->ms.cache_display_cfg.plane.PTEBufferMode;
                CalculateVMRowAndSwath_params->PTEBufferSizeNotExceeded = mode_lib->ms.PTEBufferSizeNotExceededPerState;
@@ -7957,7 +7957,7 @@ dml_bool_t dml_core_mode_support(struct display_mode_lib_st *mode_lib)
                UseMinimumDCFCLK_params->GPUVMMaxPageTableLevels = mode_lib->ms.cache_display_cfg.plane.GPUVMMaxPageTableLevels;
                UseMinimumDCFCLK_params->HostVMEnable = mode_lib->ms.cache_display_cfg.plane.HostVMEnable;
                UseMinimumDCFCLK_params->NumberOfActiveSurfaces = mode_lib->ms.num_active_planes;
-               UseMinimumDCFCLK_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes;
+               UseMinimumDCFCLK_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024;
                UseMinimumDCFCLK_params->HostVMMaxNonCachedPageTableLevels = mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels;
                UseMinimumDCFCLK_params->DynamicMetadataVMEnabled = mode_lib->ms.ip.dynamic_metadata_vm_enabled;
                UseMinimumDCFCLK_params->ImmediateFlipRequirement = s->ImmediateFlipRequiredFinal;
@@ -8699,7 +8699,7 @@ void dml_core_mode_programming(struct display_mode_lib_st *mode_lib, const struc
        CalculateVMRowAndSwath_params->HostVMMaxNonCachedPageTableLevels = mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels;
        CalculateVMRowAndSwath_params->GPUVMMaxPageTableLevels = mode_lib->ms.cache_display_cfg.plane.GPUVMMaxPageTableLevels;
        CalculateVMRowAndSwath_params->GPUVMMinPageSizeKBytes = mode_lib->ms.cache_display_cfg.plane.GPUVMMinPageSizeKBytes;
-       CalculateVMRowAndSwath_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes;
+       CalculateVMRowAndSwath_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024;
        CalculateVMRowAndSwath_params->PTEBufferModeOverrideEn = mode_lib->ms.cache_display_cfg.plane.PTEBufferModeOverrideEn;
        CalculateVMRowAndSwath_params->PTEBufferModeOverrideVal = mode_lib->ms.cache_display_cfg.plane.PTEBufferMode;
        CalculateVMRowAndSwath_params->PTEBufferSizeNotExceeded = s->dummy_boolean_array[0];
@@ -8805,7 +8805,7 @@ void dml_core_mode_programming(struct display_mode_lib_st *mode_lib, const struc
                        mode_lib->ms.cache_display_cfg.hw.DPPPerSurface,
                        locals->dpte_group_bytes,
                        s->HostVMInefficiencyFactor,
-                       mode_lib->ms.soc.hostvm_min_page_size_kbytes,
+                       mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024,
                        mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels);
 
        locals->TCalc = 24.0 / locals->DCFCLKDeepSleep;
@@ -8995,7 +8995,7 @@ void dml_core_mode_programming(struct display_mode_lib_st *mode_lib, const struc
                        CalculatePrefetchSchedule_params->GPUVMEnable = mode_lib->ms.cache_display_cfg.plane.GPUVMEnable;
                        CalculatePrefetchSchedule_params->HostVMEnable = mode_lib->ms.cache_display_cfg.plane.HostVMEnable;
                        CalculatePrefetchSchedule_params->HostVMMaxNonCachedPageTableLevels = mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels;
-                       CalculatePrefetchSchedule_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes;
+                       CalculatePrefetchSchedule_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024;
                        CalculatePrefetchSchedule_params->DynamicMetadataEnable = mode_lib->ms.cache_display_cfg.plane.DynamicMetadataEnable[k];
                        CalculatePrefetchSchedule_params->DynamicMetadataVMEnabled = mode_lib->ms.ip.dynamic_metadata_vm_enabled;
                        CalculatePrefetchSchedule_params->DynamicMetadataLinesBeforeActiveRequired = mode_lib->ms.cache_display_cfg.plane.DynamicMetadataLinesBeforeActiveRequired[k];
@@ -9240,7 +9240,7 @@ void dml_core_mode_programming(struct display_mode_lib_st *mode_lib, const struc
                                                mode_lib->ms.cache_display_cfg.plane.HostVMEnable,
                                                mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels,
                                                mode_lib->ms.cache_display_cfg.plane.GPUVMEnable,
-                                               mode_lib->ms.soc.hostvm_min_page_size_kbytes,
+                                               mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024,
                                                locals->PDEAndMetaPTEBytesFrame[k],
                                                locals->MetaRowByte[k],
                                                locals->PixelPTEBytesPerRow[k],
@@ -9446,13 +9446,13 @@ void dml_core_mode_programming(struct display_mode_lib_st *mode_lib, const struc
                CalculateWatermarks_params->CompressedBufferSizeInkByte = locals->CompressedBufferSizeInkByte;
 
                // Output
-               CalculateWatermarks_params->Watermark = &s->dummy_watermark; // Watermarks *Watermark
-               CalculateWatermarks_params->DRAMClockChangeSupport = &mode_lib->ms.support.DRAMClockChangeSupport[0];
-               CalculateWatermarks_params->MaxActiveDRAMClockChangeLatencySupported = &s->dummy_single_array[0][0]; // dml_float_t *MaxActiveDRAMClockChangeLatencySupported[]
-               CalculateWatermarks_params->SubViewportLinesNeededInMALL = &mode_lib->ms.SubViewportLinesNeededInMALL[j]; // dml_uint_t SubViewportLinesNeededInMALL[]
-               CalculateWatermarks_params->FCLKChangeSupport = &mode_lib->ms.support.FCLKChangeSupport[0];
-               CalculateWatermarks_params->MaxActiveFCLKChangeLatencySupported = &s->dummy_single[0]; // dml_float_t *MaxActiveFCLKChangeLatencySupported
-               CalculateWatermarks_params->USRRetrainingSupport = &mode_lib->ms.support.USRRetrainingSupport[0];
+               CalculateWatermarks_params->Watermark = &locals->Watermark; // Watermarks *Watermark
+               CalculateWatermarks_params->DRAMClockChangeSupport = &locals->DRAMClockChangeSupport;
+               CalculateWatermarks_params->MaxActiveDRAMClockChangeLatencySupported = locals->MaxActiveDRAMClockChangeLatencySupported; // dml_float_t *MaxActiveDRAMClockChangeLatencySupported[]
+               CalculateWatermarks_params->SubViewportLinesNeededInMALL = locals->SubViewportLinesNeededInMALL; // dml_uint_t SubViewportLinesNeededInMALL[]
+               CalculateWatermarks_params->FCLKChangeSupport = &locals->FCLKChangeSupport;
+               CalculateWatermarks_params->MaxActiveFCLKChangeLatencySupported = &locals->MaxActiveFCLKChangeLatencySupported; // dml_float_t *MaxActiveFCLKChangeLatencySupported
+               CalculateWatermarks_params->USRRetrainingSupport = &locals->USRRetrainingSupport;
 
                CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport(
                        &mode_lib->scratch,
index fa6a93dd9629558120304beae4da239a60268c0d..64d01a9cd68c859db9bcffbc478ef09090b07fbf 100644 (file)
@@ -626,8 +626,8 @@ static void populate_dml_output_cfg_from_stream_state(struct dml_output_cfg_st *
                if (is_dp2p0_output_encoder(pipe))
                        out->OutputEncoder[location] = dml_dp2p0;
                break;
-               out->OutputEncoder[location] = dml_edp;
        case SIGNAL_TYPE_EDP:
+               out->OutputEncoder[location] = dml_edp;
                break;
        case SIGNAL_TYPE_HDMI_TYPE_A:
        case SIGNAL_TYPE_DVI_SINGLE_LINK:
index fb328cd06cea2c8a00f7450c8ade7408fb4716a9..5660f15da291e9de58637c115e315b07f1cee7a3 100644 (file)
@@ -1354,7 +1354,7 @@ static void build_audio_output(
        if (state->clk_mgr &&
                (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT ||
                        pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)) {
-               audio_output->pll_info.dp_dto_source_clock_in_khz =
+               audio_output->pll_info.audio_dto_source_clock_in_khz =
                                state->clk_mgr->funcs->get_dp_ref_clk_frequency(
                                                state->clk_mgr);
        }
index 51dd2ae09b2a6235f822c7eb6c72335f38fafe24..6dd479e8a348502c9b285a38f16650fb7cb4f95e 100644 (file)
@@ -3076,7 +3076,7 @@ void dcn10_prepare_bandwidth(
                        context,
                        false);
 
-       dc->optimized_required |= hubbub->funcs->program_watermarks(hubbub,
+       dc->wm_optimized_required = hubbub->funcs->program_watermarks(hubbub,
                        &context->bw_ctx.bw.dcn.watermarks,
                        dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000,
                        true);
index bc71a9b058fedd2c211cf38088758ca6a71480b9..e931342fcf4cf1d4f4b0cf41628cd9f855fa6dac 100644 (file)
@@ -1882,42 +1882,6 @@ static void dcn20_program_pipe(
        }
 }
 
-static void update_vmin_vmax_fams(struct dc *dc,
-               struct dc_state *context)
-{
-       uint32_t i;
-       struct drr_params params = {0};
-       bool subvp_in_use = resource_subvp_in_use(dc, context);
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
-
-               if (resource_is_pipe_type(pipe, OTG_MASTER) &&
-                               ((subvp_in_use && dc_state_get_pipe_subvp_type(context, pipe) != SUBVP_PHANTOM &&
-                               pipe->stream->allow_freesync) || (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching && pipe->stream->fpo_in_use))) {
-                       if (!pipe->stream->vrr_active_variable && !pipe->stream->vrr_active_fixed) {
-                               struct timing_generator *tg = context->res_ctx.pipe_ctx[i].stream_res.tg;
-
-                               /* DRR should be configured already if we're in active variable
-                                * or active fixed, so only program if we're not in this state
-                                */
-                               params.vertical_total_min = pipe->stream->timing.v_total;
-                               params.vertical_total_max = pipe->stream->timing.v_total;
-                               tg->funcs->set_drr(tg, &params);
-                       }
-               } else {
-                       if (resource_is_pipe_type(pipe, OTG_MASTER) &&
-                                       !pipe->stream->vrr_active_variable &&
-                                       !pipe->stream->vrr_active_fixed) {
-                               struct timing_generator *tg = context->res_ctx.pipe_ctx[i].stream_res.tg;
-                               params.vertical_total_min = 0;
-                               params.vertical_total_max = 0;
-                               tg->funcs->set_drr(tg, &params);
-                       }
-               }
-       }
-}
-
 void dcn20_program_front_end_for_ctx(
                struct dc *dc,
                struct dc_state *context)
@@ -1994,7 +1958,6 @@ void dcn20_program_front_end_for_ctx(
                                && context->res_ctx.pipe_ctx[i].stream)
                        hws->funcs.blank_pixel_data(dc, &context->res_ctx.pipe_ctx[i], true);
 
-       update_vmin_vmax_fams(dc, context);
 
        /* Disconnect mpcc */
        for (i = 0; i < dc->res_pool->pipe_count; i++)
@@ -2196,10 +2159,10 @@ void dcn20_prepare_bandwidth(
        }
 
        /* program dchubbub watermarks:
-        * For assigning optimized_required, use |= operator since we don't want
+        * For assigning wm_optimized_required, use |= operator since we don't want
         * to clear the value if the optimize has not happened yet
         */
-       dc->optimized_required |= hubbub->funcs->program_watermarks(hubbub,
+       dc->wm_optimized_required |= hubbub->funcs->program_watermarks(hubbub,
                                        &context->bw_ctx.bw.dcn.watermarks,
                                        dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000,
                                        false);
@@ -2212,10 +2175,10 @@ void dcn20_prepare_bandwidth(
        if (hubbub->funcs->program_compbuf_size) {
                if (context->bw_ctx.dml.ip.min_comp_buffer_size_kbytes) {
                        compbuf_size_kb = context->bw_ctx.dml.ip.min_comp_buffer_size_kbytes;
-                       dc->optimized_required |= (compbuf_size_kb != dc->current_state->bw_ctx.dml.ip.min_comp_buffer_size_kbytes);
+                       dc->wm_optimized_required |= (compbuf_size_kb != dc->current_state->bw_ctx.dml.ip.min_comp_buffer_size_kbytes);
                } else {
                        compbuf_size_kb = context->bw_ctx.bw.dcn.compbuf_size_kb;
-                       dc->optimized_required |= (compbuf_size_kb != dc->current_state->bw_ctx.bw.dcn.compbuf_size_kb);
+                       dc->wm_optimized_required |= (compbuf_size_kb != dc->current_state->bw_ctx.bw.dcn.compbuf_size_kb);
                }
 
                hubbub->funcs->program_compbuf_size(hubbub, compbuf_size_kb, false);
index cbba39d251e5335d6e11604fc327b8ad31284aea..17e014d3bdc8401893847a4f0fd9670d664f65c5 100644 (file)
@@ -333,6 +333,7 @@ struct clk_mgr {
        bool force_smu_not_present;
        bool dc_mode_softmax_enabled;
        int dprefclk_khz; // Used by program pixel clock in clock source funcs, need to figureout where this goes
+       int dp_dto_source_clock_in_khz; // Used to program DP DTO with ss adjustment on DCN314
        int dentist_vco_freq_khz;
        struct clk_state_registers_and_bypass boot_snapshot;
        struct clk_bw_params *bw_params;
index 1d51fed12e20037b3baf40ed7f3b89095437457e..c958ef37b78a667b1bb9bfb26827ae3e45053715 100644 (file)
@@ -609,9 +609,6 @@ bool dc_resource_acquire_secondary_pipe_for_mpc_odm_legacy(
                struct pipe_ctx *sec_pipe,
                bool odm);
 
-bool resource_subvp_in_use(struct dc *dc,
-               struct dc_state *context);
-
 /* A test harness interface that modifies dp encoder resources in the given dc
  * state and bypasses the need to revalidate. The interface assumes that the
  * test harness interface is called with pre-validated link config stored in the
index 5fe8b4871c77614eb0fd46421db49fb79197e6f7..3cbfbf8d107e9b62c639ef1618041b8fc09dd9b5 100644 (file)
@@ -900,11 +900,15 @@ bool link_set_dsc_pps_packet(struct pipe_ctx *pipe_ctx, bool enable, bool immedi
 {
        struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
        struct dc_stream_state *stream = pipe_ctx->stream;
-       DC_LOGGER_INIT(dsc->ctx->logger);
 
-       if (!pipe_ctx->stream->timing.flags.DSC || !dsc)
+       if (!pipe_ctx->stream->timing.flags.DSC)
                return false;
 
+       if (!dsc)
+               return false;
+
+       DC_LOGGER_INIT(dsc->ctx->logger);
+
        if (enable) {
                struct dsc_config dsc_cfg;
                uint8_t dsc_packed_pps[128];
@@ -2005,17 +2009,11 @@ static enum dc_status enable_link_dp(struct dc_state *state,
                }
        }
 
-       /*
-        * If the link is DP-over-USB4 do the following:
-        * - Train with fallback when enabling DPIA link. Conventional links are
+       /* Train with fallback when enabling DPIA link. Conventional links are
         * trained with fallback during sink detection.
-        * - Allocate only what the stream needs for bw in Gbps. Inform the CM
-        * in case stream needs more or less bw from what has been allocated
-        * earlier at plug time.
         */
-       if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) {
+       if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
                do_fallback = true;
-       }
 
        /*
         * Temporary w/a to get DP2.0 link rates to work with SST.
@@ -2197,6 +2195,32 @@ static enum dc_status enable_link(
        return status;
 }
 
+static bool allocate_usb4_bandwidth_for_stream(struct dc_stream_state *stream, int bw)
+{
+       return true;
+}
+
+static bool allocate_usb4_bandwidth(struct dc_stream_state *stream)
+{
+       bool ret;
+
+       int bw = dc_bandwidth_in_kbps_from_timing(&stream->timing,
+                       dc_link_get_highest_encoding_format(stream->sink->link));
+
+       ret = allocate_usb4_bandwidth_for_stream(stream, bw);
+
+       return ret;
+}
+
+static bool deallocate_usb4_bandwidth(struct dc_stream_state *stream)
+{
+       bool ret;
+
+       ret = allocate_usb4_bandwidth_for_stream(stream, 0);
+
+       return ret;
+}
+
 void link_set_dpms_off(struct pipe_ctx *pipe_ctx)
 {
        struct dc  *dc = pipe_ctx->stream->ctx->dc;
@@ -2232,6 +2256,9 @@ void link_set_dpms_off(struct pipe_ctx *pipe_ctx)
        update_psp_stream_config(pipe_ctx, true);
        dc->hwss.blank_stream(pipe_ctx);
 
+       if (pipe_ctx->stream->link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
+               deallocate_usb4_bandwidth(pipe_ctx->stream);
+
        if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
                deallocate_mst_payload(pipe_ctx);
        else if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT &&
@@ -2474,6 +2501,9 @@ void link_set_dpms_on(
                }
        }
 
+       if (pipe_ctx->stream->link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
+               allocate_usb4_bandwidth(pipe_ctx->stream);
+
        if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
                allocate_mst_payload(pipe_ctx);
        else if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT &&
index b45fda96eaf649bf16f291df2294d787680e0287..8fe66c3678508d9aee6779fa25cd6128e1f30832 100644 (file)
@@ -346,23 +346,61 @@ enum dc_status link_validate_mode_timing(
        return DC_OK;
 }
 
+/*
+ * This function calculates the bandwidth required for the stream timing
+ * and aggregates the stream bandwidth for the respective dpia link
+ *
+ * @stream: pointer to the dc_stream_state struct instance
+ * @num_streams: number of streams to be validated
+ *
+ * return: true if validation is succeeded
+ */
 bool link_validate_dpia_bandwidth(const struct dc_stream_state *stream, const unsigned int num_streams)
 {
-       bool ret = true;
-       int bw_needed[MAX_DPIA_NUM];
-       struct dc_link *link[MAX_DPIA_NUM];
-
-       if (!num_streams || num_streams > MAX_DPIA_NUM)
-               return ret;
+       int bw_needed[MAX_DPIA_NUM] = {0};
+       struct dc_link *dpia_link[MAX_DPIA_NUM] = {0};
+       int num_dpias = 0;
 
        for (uint8_t i = 0; i < num_streams; ++i) {
+               if (stream[i].signal == SIGNAL_TYPE_DISPLAY_PORT) {
+                       /* new dpia sst stream, check whether it exceeds max dpia */
+                       if (num_dpias >= MAX_DPIA_NUM)
+                               return false;
 
-               link[i] = stream[i].link;
-               bw_needed[i] = dc_bandwidth_in_kbps_from_timing(&stream[i].timing,
-                               dc_link_get_highest_encoding_format(link[i]));
+                       dpia_link[num_dpias] = stream[i].link;
+                       bw_needed[num_dpias] = dc_bandwidth_in_kbps_from_timing(&stream[i].timing,
+                                       dc_link_get_highest_encoding_format(dpia_link[num_dpias]));
+                       num_dpias++;
+               } else if (stream[i].signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
+                       uint8_t j = 0;
+                       /* check whether its a known dpia link */
+                       for (; j < num_dpias; ++j) {
+                               if (dpia_link[j] == stream[i].link)
+                                       break;
+                       }
+
+                       if (j == num_dpias) {
+                               /* new dpia mst stream, check whether it exceeds max dpia */
+                               if (num_dpias >= MAX_DPIA_NUM)
+                                       return false;
+                               else {
+                                       dpia_link[j] = stream[i].link;
+                                       num_dpias++;
+                               }
+                       }
+
+                       bw_needed[j] += dc_bandwidth_in_kbps_from_timing(&stream[i].timing,
+                               dc_link_get_highest_encoding_format(dpia_link[j]));
+               }
        }
 
-       ret = dpia_validate_usb4_bw(link, bw_needed, num_streams);
+       /* Include dp overheads */
+       for (uint8_t i = 0; i < num_dpias; ++i) {
+               int dp_overhead = 0;
+
+               dp_overhead = link_dp_dpia_get_dp_overhead_in_dp_tunneling(dpia_link[i]);
+               bw_needed[i] += dp_overhead;
+       }
 
-       return ret;
+       return dpia_validate_usb4_bw(dpia_link, bw_needed, num_dpias);
 }
index 982eda3c46f5680af8c60042e4cc7fc8909f68d3..6af42ba9885c054ead528e11d14007622af098a8 100644 (file)
@@ -82,25 +82,33 @@ bool dpia_query_hpd_status(struct dc_link *link)
 {
        union dmub_rb_cmd cmd = {0};
        struct dc_dmub_srv *dmub_srv = link->ctx->dmub_srv;
-       bool is_hpd_high = false;
 
        /* prepare QUERY_HPD command */
        cmd.query_hpd.header.type = DMUB_CMD__QUERY_HPD_STATE;
        cmd.query_hpd.data.instance = link->link_id.enum_id - ENUM_ID_1;
        cmd.query_hpd.data.ch_type = AUX_CHANNEL_DPIA;
 
-       /* Return HPD status reported by DMUB if query successfully executed. */
-       if (dc_wake_and_execute_dmub_cmd(dmub_srv->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY) &&
-           cmd.query_hpd.data.status == AUX_RET_SUCCESS)
-               is_hpd_high = cmd.query_hpd.data.result;
-
-       DC_LOG_DEBUG("%s: link(%d) dpia(%d) cmd_status(%d) result(%d)\n",
-               __func__,
-               link->link_index,
-               link->link_id.enum_id - ENUM_ID_1,
-               cmd.query_hpd.data.status,
-               cmd.query_hpd.data.result);
-
-       return is_hpd_high;
+       /* Query dpia hpd status from dmub */
+       if (dc_wake_and_execute_dmub_cmd(dmub_srv->ctx, &cmd,
+               DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY) &&
+           cmd.query_hpd.data.status == AUX_RET_SUCCESS) {
+               DC_LOG_DEBUG("%s: for link(%d) dpia(%d) success, current_hpd_status(%d) new_hpd_status(%d)\n",
+                       __func__,
+                       link->link_index,
+                       link->link_id.enum_id - ENUM_ID_1,
+                       link->hpd_status,
+                       cmd.query_hpd.data.result);
+               link->hpd_status = cmd.query_hpd.data.result;
+       } else {
+               DC_LOG_ERROR("%s: for link(%d) dpia(%d) failed with status(%d), current_hpd_status(%d) new_hpd_status(0)\n",
+                       __func__,
+                       link->link_index,
+                       link->link_id.enum_id - ENUM_ID_1,
+                       cmd.query_hpd.data.status,
+                       link->hpd_status);
+               link->hpd_status = false;
+       }
+
+       return link->hpd_status;
 }
 
index a7aa8c9da868fcf81a335b3d1384aeb8e37a1f42..dd0d2b206462c927c5f68b355498e71250c154b9 100644 (file)
@@ -54,12 +54,18 @@ static bool get_bw_alloc_proceed_flag(struct dc_link *tmp)
 static void reset_bw_alloc_struct(struct dc_link *link)
 {
        link->dpia_bw_alloc_config.bw_alloc_enabled = false;
-       link->dpia_bw_alloc_config.sink_verified_bw = 0;
-       link->dpia_bw_alloc_config.sink_max_bw = 0;
+       link->dpia_bw_alloc_config.link_verified_bw = 0;
+       link->dpia_bw_alloc_config.link_max_bw = 0;
+       link->dpia_bw_alloc_config.allocated_bw = 0;
        link->dpia_bw_alloc_config.estimated_bw = 0;
        link->dpia_bw_alloc_config.bw_granularity = 0;
+       link->dpia_bw_alloc_config.dp_overhead = 0;
        link->dpia_bw_alloc_config.response_ready = false;
-       link->dpia_bw_alloc_config.sink_allocated_bw = 0;
+       link->dpia_bw_alloc_config.nrd_max_lane_count = 0;
+       link->dpia_bw_alloc_config.nrd_max_link_rate = 0;
+       for (int i = 0; i < MAX_SINKS_PER_LINK; i++)
+               link->dpia_bw_alloc_config.remote_sink_req_bw[i] = 0;
+       DC_LOG_DEBUG("reset usb4 bw alloc of link(%d)\n", link->link_index);
 }
 
 #define BW_GRANULARITY_0 4 // 0.25 Gbps
@@ -210,8 +216,8 @@ static int get_host_router_total_dp_tunnel_bw(const struct dc *dc, uint8_t hr_in
                                link_dpia_primary->dpia_bw_alloc_config.bw_alloc_enabled) &&
                                (link_dpia_secondary->hpd_status &&
                                link_dpia_secondary->dpia_bw_alloc_config.bw_alloc_enabled)) {
-                               total_bw += link_dpia_primary->dpia_bw_alloc_config.estimated_bw +
-                                       link_dpia_secondary->dpia_bw_alloc_config.sink_allocated_bw;
+                                       total_bw += link_dpia_primary->dpia_bw_alloc_config.estimated_bw +
+                                               link_dpia_secondary->dpia_bw_alloc_config.allocated_bw;
                        } else if (link_dpia_primary->hpd_status &&
                                        link_dpia_primary->dpia_bw_alloc_config.bw_alloc_enabled) {
                                total_bw = link_dpia_primary->dpia_bw_alloc_config.estimated_bw;
@@ -264,7 +270,7 @@ static void set_usb4_req_bw_req(struct dc_link *link, int req_bw)
 
        /* Error check whether requested and allocated are equal */
        req_bw = requested_bw * (Kbps_TO_Gbps / link->dpia_bw_alloc_config.bw_granularity);
-       if (req_bw == link->dpia_bw_alloc_config.sink_allocated_bw) {
+       if (req_bw == link->dpia_bw_alloc_config.allocated_bw) {
                DC_LOG_ERROR("%s: Request bw equals to allocated bw for link(%d)\n",
                        __func__, link->link_index);
        }
@@ -387,9 +393,9 @@ void dpia_handle_bw_alloc_response(struct dc_link *link, uint8_t bw, uint8_t res
                DC_LOG_DEBUG("%s: BW REQ SUCCESS for DP-TX Request for link(%d)\n",
                        __func__, link->link_index);
                DC_LOG_DEBUG("%s: current allocated_bw(%d), new allocated_bw(%d)\n",
-                       __func__, link->dpia_bw_alloc_config.sink_allocated_bw, bw_needed);
+                       __func__, link->dpia_bw_alloc_config.allocated_bw, bw_needed);
 
-               link->dpia_bw_alloc_config.sink_allocated_bw = bw_needed;
+               link->dpia_bw_alloc_config.allocated_bw = bw_needed;
 
                link->dpia_bw_alloc_config.response_ready = true;
                break;
@@ -427,8 +433,8 @@ int dpia_handle_usb4_bandwidth_allocation_for_link(struct dc_link *link, int pea
        if (link->hpd_status && peak_bw > 0) {
 
                // If DP over USB4 then we need to check BW allocation
-               link->dpia_bw_alloc_config.sink_max_bw = peak_bw;
-               set_usb4_req_bw_req(link, link->dpia_bw_alloc_config.sink_max_bw);
+               link->dpia_bw_alloc_config.link_max_bw = peak_bw;
+               set_usb4_req_bw_req(link, link->dpia_bw_alloc_config.link_max_bw);
 
                do {
                        if (timeout > 0)
@@ -440,8 +446,8 @@ int dpia_handle_usb4_bandwidth_allocation_for_link(struct dc_link *link, int pea
 
                if (!timeout)
                        ret = 0;// ERROR TIMEOUT waiting for response for allocating bw
-               else if (link->dpia_bw_alloc_config.sink_allocated_bw > 0)
-                       ret = link->dpia_bw_alloc_config.sink_allocated_bw;
+               else if (link->dpia_bw_alloc_config.allocated_bw > 0)
+                       ret = link->dpia_bw_alloc_config.allocated_bw;
        }
        //2. Cold Unplug
        else if (!link->hpd_status)
@@ -450,7 +456,6 @@ int dpia_handle_usb4_bandwidth_allocation_for_link(struct dc_link *link, int pea
 out:
        return ret;
 }
-
 bool link_dp_dpia_allocate_usb4_bandwidth_for_stream(struct dc_link *link, int req_bw)
 {
        bool ret = false;
@@ -458,7 +463,7 @@ bool link_dp_dpia_allocate_usb4_bandwidth_for_stream(struct dc_link *link, int r
 
        DC_LOG_DEBUG("%s: ENTER: link(%d), hpd_status(%d), current allocated_bw(%d), req_bw(%d)\n",
                __func__, link->link_index, link->hpd_status,
-               link->dpia_bw_alloc_config.sink_allocated_bw, req_bw);
+               link->dpia_bw_alloc_config.allocated_bw, req_bw);
 
        if (!get_bw_alloc_proceed_flag(link))
                goto out;
@@ -523,3 +528,30 @@ bool dpia_validate_usb4_bw(struct dc_link **link, int *bw_needed_per_dpia, const
 
        return ret;
 }
+
+int link_dp_dpia_get_dp_overhead_in_dp_tunneling(struct dc_link *link)
+{
+       int dp_overhead = 0, link_mst_overhead = 0;
+
+       if (!get_bw_alloc_proceed_flag((link)))
+               return dp_overhead;
+
+       /* if its mst link, add MTPH overhead */
+       if ((link->type == dc_connection_mst_branch) &&
+               !link->dpcd_caps.channel_coding_cap.bits.DP_128b_132b_SUPPORTED) {
+               /* For 8b/10b encoding: MTP is 64 time slots long, slot 0 is used for MTPH
+                * MST overhead is 1/64 of link bandwidth (excluding any overhead)
+                */
+               const struct dc_link_settings *link_cap =
+                       dc_link_get_link_cap(link);
+               uint32_t link_bw_in_kbps = (uint32_t)link_cap->link_rate *
+                                          (uint32_t)link_cap->lane_count *
+                                          LINK_RATE_REF_FREQ_IN_KHZ * 8;
+               link_mst_overhead = (link_bw_in_kbps / 64) + ((link_bw_in_kbps % 64) ? 1 : 0);
+       }
+
+       /* add all the overheads */
+       dp_overhead = link_mst_overhead;
+
+       return dp_overhead;
+}
index 981bc4eb6120e76ad959435be7ad716cdc498926..3b6d8494f9d5da4ceb05711c9596007ac73f08a2 100644 (file)
@@ -99,4 +99,13 @@ void dpia_handle_bw_alloc_response(struct dc_link *link, uint8_t bw, uint8_t res
  */
 bool dpia_validate_usb4_bw(struct dc_link **link, int *bw_needed, const unsigned int num_dpias);
 
+/*
+ * Obtain all the DP overheads in dp tunneling for the dpia link
+ *
+ * @link: pointer to the dc_link struct instance
+ *
+ * return: DP overheads in DP tunneling
+ */
+int link_dp_dpia_get_dp_overhead_in_dp_tunneling(struct dc_link *link);
+
 #endif /* DC_INC_LINK_DP_DPIA_BW_H_ */
index 7f1196528218692c98f1f15375f153dfe56fe514..046d3e205415311cd63a98aa3c0e59c8aaea2e89 100644 (file)
@@ -930,8 +930,8 @@ bool edp_get_replay_state(const struct dc_link *link, uint64_t *state)
 bool edp_setup_replay(struct dc_link *link, const struct dc_stream_state *stream)
 {
        /* To-do: Setup Replay */
-       struct dc *dc = link->ctx->dc;
-       struct dmub_replay *replay = dc->res_pool->replay;
+       struct dc *dc;
+       struct dmub_replay *replay;
        int i;
        unsigned int panel_inst;
        struct replay_context replay_context = { 0 };
@@ -947,6 +947,10 @@ bool edp_setup_replay(struct dc_link *link, const struct dc_stream_state *stream
        if (!link)
                return false;
 
+       dc = link->ctx->dc;
+
+       replay = dc->res_pool->replay;
+
        if (!replay)
                return false;
 
@@ -975,8 +979,7 @@ bool edp_setup_replay(struct dc_link *link, const struct dc_stream_state *stream
 
        replay_context.line_time_in_ns = lineTimeInNs;
 
-       if (replay)
-               link->replay_settings.replay_feature_enabled =
+       link->replay_settings.replay_feature_enabled =
                        replay->funcs->replay_copy_settings(replay, link, &replay_context, panel_inst);
        if (link->replay_settings.replay_feature_enabled) {
 
index 91ea0d4da06a9443bb199759fde0c75ae44fc8f3..82349354332548e160494c23bee15acaa18b7630 100644 (file)
@@ -166,12 +166,6 @@ static bool optc32_disable_crtc(struct timing_generator *optc)
 {
        struct optc *optc1 = DCN10TG_FROM_TG(optc);
 
-       /* disable otg request until end of the first line
-        * in the vertical blank region
-        */
-       REG_UPDATE(OTG_CONTROL,
-                       OTG_MASTER_EN, 0);
-
        REG_UPDATE_5(OPTC_DATA_SOURCE_SELECT,
                        OPTC_SEG0_SRC_SEL, 0xf,
                        OPTC_SEG1_SRC_SEL, 0xf,
@@ -179,6 +173,15 @@ static bool optc32_disable_crtc(struct timing_generator *optc)
                        OPTC_SEG3_SRC_SEL, 0xf,
                        OPTC_NUM_OF_INPUT_SEGMENT, 0);
 
+       REG_UPDATE(OPTC_MEMORY_CONFIG,
+                       OPTC_MEM_SEL, 0);
+
+       /* disable otg request until end of the first line
+        * in the vertical blank region
+        */
+       REG_UPDATE(OTG_CONTROL,
+                       OTG_MASTER_EN, 0);
+
        REG_UPDATE(CONTROL,
                        VTG0_ENABLE, 0);
 
@@ -205,6 +208,13 @@ static void optc32_disable_phantom_otg(struct timing_generator *optc)
 {
        struct optc *optc1 = DCN10TG_FROM_TG(optc);
 
+       REG_UPDATE_5(OPTC_DATA_SOURCE_SELECT,
+                       OPTC_SEG0_SRC_SEL, 0xf,
+                       OPTC_SEG1_SRC_SEL, 0xf,
+                       OPTC_SEG2_SRC_SEL, 0xf,
+                       OPTC_SEG3_SRC_SEL, 0xf,
+                       OPTC_NUM_OF_INPUT_SEGMENT, 0);
+
        REG_UPDATE(OTG_CONTROL, OTG_MASTER_EN, 0);
 }
 
index 08a59cf449cae5c27fe7dbe8fc1b2f847f462f9f..5b154750885030e171a483d30e014aa8f4bff8a1 100644 (file)
@@ -138,12 +138,6 @@ static bool optc35_disable_crtc(struct timing_generator *optc)
 {
        struct optc *optc1 = DCN10TG_FROM_TG(optc);
 
-       /* disable otg request until end of the first line
-        * in the vertical blank region
-        */
-       REG_UPDATE(OTG_CONTROL,
-                       OTG_MASTER_EN, 0);
-
        REG_UPDATE_5(OPTC_DATA_SOURCE_SELECT,
                        OPTC_SEG0_SRC_SEL, 0xf,
                        OPTC_SEG1_SRC_SEL, 0xf,
@@ -151,6 +145,15 @@ static bool optc35_disable_crtc(struct timing_generator *optc)
                        OPTC_SEG3_SRC_SEL, 0xf,
                        OPTC_NUM_OF_INPUT_SEGMENT, 0);
 
+       REG_UPDATE(OPTC_MEMORY_CONFIG,
+                       OPTC_MEM_SEL, 0);
+
+       /* disable otg request until end of the first line
+        * in the vertical blank region
+        */
+       REG_UPDATE(OTG_CONTROL,
+                       OTG_MASTER_EN, 0);
+
        REG_UPDATE(CONTROL,
                        VTG0_ENABLE, 0);
 
index ac04a9c9a3d86808000942fd4eae12d5f9fdea66..c4d71e7f18af47ba47dbc89e1a9098a0a4eade04 100644 (file)
@@ -1899,7 +1899,7 @@ int dcn32_populate_dml_pipes_from_context(
 
 static struct dc_cap_funcs cap_funcs = {
        .get_dcc_compression_cap = dcn20_get_dcc_compression_cap,
-       .get_subvp_en = resource_subvp_in_use,
+       .get_subvp_en = dcn32_subvp_in_use,
 };
 
 void dcn32_calculate_wm_and_dlg(struct dc *dc, struct dc_state *context,
index 62611acd4bcb522c78fafdaa8d811101b65b5f42..0c87b0fabba7d96ff38180900e41f1438419912c 100644 (file)
@@ -131,6 +131,9 @@ void dcn32_merge_pipes_for_subvp(struct dc *dc,
 bool dcn32_all_pipes_have_stream_and_plane(struct dc *dc,
                struct dc_state *context);
 
+bool dcn32_subvp_in_use(struct dc *dc,
+               struct dc_state *context);
+
 bool dcn32_mpo_in_use(struct dc_state *context);
 
 bool dcn32_any_surfaces_rotated(struct dc *dc, struct dc_state *context);
index e1ab207c46f15b1c6dd6e13ec35f6049674c0444..74412e5f03fefbaa9350982ac92bc528cc8e80e8 100644 (file)
@@ -1574,7 +1574,7 @@ static void dcn321_destroy_resource_pool(struct resource_pool **pool)
 
 static struct dc_cap_funcs cap_funcs = {
        .get_dcc_compression_cap = dcn20_get_dcc_compression_cap,
-       .get_subvp_en = resource_subvp_in_use,
+       .get_subvp_en = dcn32_subvp_in_use,
 };
 
 static void dcn321_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
index 66a54da0641ce11feb10e1d777395f9bcd85f658..915a031a43cb286fdb03f2fb2788d0fa9e539b59 100644 (file)
@@ -64,7 +64,7 @@ enum audio_dto_source {
 /* PLL information required for AZALIA DTO calculation */
 
 struct audio_pll_info {
-       uint32_t dp_dto_source_clock_in_khz;
+       uint32_t audio_dto_source_clock_in_khz;
        uint32_t feed_back_divider;
        enum audio_dto_source dto_source;
        bool ss_enabled;
index 7ee3d291120d5429d879745c2e63af38cd79f371..6f80bfa7e41ac9c1bdd2faaba4c298cc3f4f9d34 100644 (file)
 #define regBIF_BX1_MM_CFGREGS_CNTL_BASE_IDX                                                             2
 #define regBIF_BX1_BX_RESET_CNTL                                                                        0x00f0
 #define regBIF_BX1_BX_RESET_CNTL_BASE_IDX                                                               2
-#define regBIF_BX1_INTERRUPT_CNTL                                                                       0x8e11
-#define regBIF_BX1_INTERRUPT_CNTL_BASE_IDX                                                              5
-#define regBIF_BX1_INTERRUPT_CNTL2                                                                      0x8e12
-#define regBIF_BX1_INTERRUPT_CNTL2_BASE_IDX                                                             5
+#define regBIF_BX1_INTERRUPT_CNTL                                                                       0x00f1
+#define regBIF_BX1_INTERRUPT_CNTL_BASE_IDX                                                              2
+#define regBIF_BX1_INTERRUPT_CNTL2                                                                      0x00f2
+#define regBIF_BX1_INTERRUPT_CNTL2_BASE_IDX                                                             2
 #define regBIF_BX1_CLKREQB_PAD_CNTL                                                                     0x00f8
 #define regBIF_BX1_CLKREQB_PAD_CNTL_BASE_IDX                                                            2
 #define regBIF_BX1_BIF_FEATURES_CONTROL_MISC                                                            0x00fb
index f3cb490fe79b16baa5a917c8304b6fbfcfeb8729..087d57850304c45193a7f5de336953c1dec9cbba 100644 (file)
@@ -4349,11 +4349,19 @@ static int amdgpu_debugfs_pm_info_pp(struct seq_file *m, struct amdgpu_device *a
        if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_VDDNB, (void *)&value, &size))
                seq_printf(m, "\t%u mV (VDDNB)\n", value);
        size = sizeof(uint32_t);
-       if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_AVG_POWER, (void *)&query, &size))
-               seq_printf(m, "\t%u.%02u W (average GPU)\n", query >> 8, query & 0xff);
+       if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_AVG_POWER, (void *)&query, &size)) {
+               if (adev->flags & AMD_IS_APU)
+                       seq_printf(m, "\t%u.%02u W (average SoC including CPU)\n", query >> 8, query & 0xff);
+               else
+                       seq_printf(m, "\t%u.%02u W (average SoC)\n", query >> 8, query & 0xff);
+       }
        size = sizeof(uint32_t);
-       if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_INPUT_POWER, (void *)&query, &size))
-               seq_printf(m, "\t%u.%02u W (current GPU)\n", query >> 8, query & 0xff);
+       if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_INPUT_POWER, (void *)&query, &size)) {
+               if (adev->flags & AMD_IS_APU)
+                       seq_printf(m, "\t%u.%02u W (current SoC including CPU)\n", query >> 8, query & 0xff);
+               else
+                       seq_printf(m, "\t%u.%02u W (current SoC)\n", query >> 8, query & 0xff);
+       }
        size = sizeof(value);
        seq_printf(m, "\n");
 
@@ -4379,9 +4387,9 @@ static int amdgpu_debugfs_pm_info_pp(struct seq_file *m, struct amdgpu_device *a
                /* VCN clocks */
                if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_VCN_POWER_STATE, (void *)&value, &size)) {
                        if (!value) {
-                               seq_printf(m, "VCN: Disabled\n");
+                               seq_printf(m, "VCN: Powered down\n");
                        } else {
-                               seq_printf(m, "VCN: Enabled\n");
+                               seq_printf(m, "VCN: Powered up\n");
                                if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_UVD_DCLK, (void *)&value, &size))
                                        seq_printf(m, "\t%u MHz (DCLK)\n", value/100);
                                if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_UVD_VCLK, (void *)&value, &size))
@@ -4393,9 +4401,9 @@ static int amdgpu_debugfs_pm_info_pp(struct seq_file *m, struct amdgpu_device *a
                /* UVD clocks */
                if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_UVD_POWER, (void *)&value, &size)) {
                        if (!value) {
-                               seq_printf(m, "UVD: Disabled\n");
+                               seq_printf(m, "UVD: Powered down\n");
                        } else {
-                               seq_printf(m, "UVD: Enabled\n");
+                               seq_printf(m, "UVD: Powered up\n");
                                if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_UVD_DCLK, (void *)&value, &size))
                                        seq_printf(m, "\t%u MHz (DCLK)\n", value/100);
                                if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_UVD_VCLK, (void *)&value, &size))
@@ -4407,9 +4415,9 @@ static int amdgpu_debugfs_pm_info_pp(struct seq_file *m, struct amdgpu_device *a
                /* VCE clocks */
                if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_VCE_POWER, (void *)&value, &size)) {
                        if (!value) {
-                               seq_printf(m, "VCE: Disabled\n");
+                               seq_printf(m, "VCE: Powered down\n");
                        } else {
-                               seq_printf(m, "VCE: Enabled\n");
+                               seq_printf(m, "VCE: Powered up\n");
                                if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_VCE_ECCLK, (void *)&value, &size))
                                        seq_printf(m, "\t%u MHz (ECCLK)\n", value/100);
                        }
index f2a55c1413f597a4d643d1a2c99367517bdff17e..17882f8dfdd34f92d5d37a9b0ee37f4a7d1bb406 100644 (file)
@@ -200,7 +200,7 @@ static int get_platform_power_management_table(
                struct pp_hwmgr *hwmgr,
                ATOM_Tonga_PPM_Table *atom_ppm_table)
 {
-       struct phm_ppm_table *ptr = kzalloc(sizeof(ATOM_Tonga_PPM_Table), GFP_KERNEL);
+       struct phm_ppm_table *ptr = kzalloc(sizeof(*ptr), GFP_KERNEL);
        struct phm_ppt_v1_information *pp_table_information =
                (struct phm_ppt_v1_information *)(hwmgr->pptable);
 
index b1a8799e2dee320390d239c6242600d4d30cdc39..aa91730e4eaffdf7760c844a7722aa1dedcb42d9 100644 (file)
@@ -3999,6 +3999,7 @@ static int smu7_read_sensor(struct pp_hwmgr *hwmgr, int idx,
        uint32_t sclk, mclk, activity_percent;
        uint32_t offset, val_vid;
        struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
+       struct amdgpu_device *adev = hwmgr->adev;
 
        /* size must be at least 4 bytes for all sensors */
        if (*size < 4)
@@ -4042,7 +4043,21 @@ static int smu7_read_sensor(struct pp_hwmgr *hwmgr, int idx,
                *size = 4;
                return 0;
        case AMDGPU_PP_SENSOR_GPU_INPUT_POWER:
-               return smu7_get_gpu_power(hwmgr, (uint32_t *)value);
+               if ((adev->asic_type != CHIP_HAWAII) &&
+                   (adev->asic_type != CHIP_BONAIRE) &&
+                   (adev->asic_type != CHIP_FIJI) &&
+                   (adev->asic_type != CHIP_TONGA))
+                       return smu7_get_gpu_power(hwmgr, (uint32_t *)value);
+               else
+                       return -EOPNOTSUPP;
+       case AMDGPU_PP_SENSOR_GPU_AVG_POWER:
+               if ((adev->asic_type != CHIP_HAWAII) &&
+                   (adev->asic_type != CHIP_BONAIRE) &&
+                   (adev->asic_type != CHIP_FIJI) &&
+                   (adev->asic_type != CHIP_TONGA))
+                       return -EOPNOTSUPP;
+               else
+                       return smu7_get_gpu_power(hwmgr, (uint32_t *)value);
        case AMDGPU_PP_SENSOR_VDDGFX:
                if ((data->vr_config & VRCONF_VDDGFX_MASK) ==
                    (VR_SVI2_PLANE_2 << VRCONF_VDDGFX_SHIFT))
index cc2a02ceea85955bdb8f3904aebe9ba4fa7ac816..3c98a8a0386a2612d0470dd6dbd767a6ecc308b0 100644 (file)
@@ -970,7 +970,9 @@ static int smu_v13_0_6_print_clks(struct smu_context *smu, char *buf, int size,
                        if (i < (clocks.num_levels - 1))
                                clk2 = clocks.data[i + 1].clocks_in_khz / 1000;
 
-                       if (curr_clk >= clk1 && curr_clk < clk2) {
+                       if (curr_clk == clk1) {
+                               level = i;
+                       } else if (curr_clk >= clk1 && curr_clk < clk2) {
                                level = (curr_clk - clk1) <= (clk2 - curr_clk) ?
                                                i :
                                                i + 1;
@@ -2234,17 +2236,18 @@ static int smu_v13_0_6_mode2_reset(struct smu_context *smu)
                        continue;
                }
 
-               if (ret) {
-                       dev_err(adev->dev,
-                               "failed to send mode2 message \tparam: 0x%08x error code %d\n",
-                               SMU_RESET_MODE_2, ret);
+               if (ret)
                        goto out;
-               }
+
        } while (ret == -ETIME && timeout);
 
 out:
        mutex_unlock(&smu->message_lock);
 
+       if (ret)
+               dev_err(adev->dev, "failed to send mode2 reset, error code %d",
+                       ret);
+
        return ret;
 }
 
index a6602c0126715635d6328c2fb295d4195b7dd873..3dda885df5b223dc2b637592e50cc7e958b5cbb7 100644 (file)
@@ -108,6 +108,9 @@ nouveau_vma_new(struct nouveau_bo *nvbo, struct nouveau_vmm *vmm,
        } else {
                ret = nvif_vmm_get(&vmm->vmm, PTES, false, mem->mem.page, 0,
                                   mem->mem.size, &tmp);
+               if (ret)
+                       goto done;
+
                vma->addr = tmp.addr;
        }
 
index 1cced50d8d8c9dadcb40f7ebe75cf7474170772b..e36ae1f0d8859fc82f2e0a9ed06f8e7ee6387372 100644 (file)
@@ -47,7 +47,7 @@ config DRM_XE
 
 config DRM_XE_DISPLAY
        bool "Enable display support"
-       depends on DRM_XE && EXPERT && DRM_XE=m
+       depends on DRM_XE && DRM_XE=m
        select FB_IOMEM_HELPERS
        select I2C
        select I2C_ALGOBIT
index 53bd2a8ba1ae5cea2535c59047d028f18bec8e65..efcf0ab7a1a69d35271b5655c5a746e992459b02 100644 (file)
@@ -17,7 +17,6 @@ subdir-ccflags-y += $(call cc-option, -Wunused-const-variable)
 subdir-ccflags-y += $(call cc-option, -Wpacked-not-aligned)
 subdir-ccflags-y += $(call cc-option, -Wformat-overflow)
 subdir-ccflags-y += $(call cc-option, -Wformat-truncation)
-subdir-ccflags-y += $(call cc-option, -Wstringop-overflow)
 subdir-ccflags-y += $(call cc-option, -Wstringop-truncation)
 # The following turn off the warnings enabled by -Wextra
 ifeq ($(findstring 2, $(KBUILD_EXTRA_WARN)),)
index 412b2e7ce40cb3ea38b6f5c76fb293009c10c3a2..3436fd9cf2b2738446608990a5f5be1a4f33fb2e 100644 (file)
@@ -125,14 +125,13 @@ static void ccs_test_run_tile(struct xe_device *xe, struct xe_tile *tile,
 
        bo = xe_bo_create_user(xe, NULL, NULL, SZ_1M, DRM_XE_GEM_CPU_CACHING_WC,
                               ttm_bo_type_device, bo_flags);
-
-       xe_bo_lock(bo, false);
-
        if (IS_ERR(bo)) {
                KUNIT_FAIL(test, "Failed to create bo.\n");
                return;
        }
 
+       xe_bo_lock(bo, false);
+
        kunit_info(test, "Verifying that CCS data is cleared on creation.\n");
        ret = ccs_test_migrate(tile, bo, false, 0ULL, 0xdeadbeefdeadbeefULL,
                               test);
index 7a32faa2f68880dcd4cb5b217ff9986153b990cb..a6523df0f1d39fbe7f0354d404f95886a3d56424 100644 (file)
@@ -331,7 +331,7 @@ static void xe_migrate_sanity_test(struct xe_migrate *m, struct kunit *test)
                xe_res_first_sg(xe_bo_sg(pt), 0, pt->size, &src_it);
 
        emit_pte(m, bb, NUM_KERNEL_PDE - 1, xe_bo_is_vram(pt), false,
-                &src_it, XE_PAGE_SIZE, pt);
+                &src_it, XE_PAGE_SIZE, pt->ttm.resource);
 
        run_sanity_job(m, xe, bb, bb->len, "Writing PTE for our fake PT", test);
 
index 8e4a3b1f6b938e5a76b8fc6640058ca63a30c709..0b0e262e2166d69da1063915fa4c6eeedfd38bd6 100644 (file)
@@ -125,9 +125,9 @@ static struct xe_mem_region *res_to_mem_region(struct ttm_resource *res)
 static void try_add_system(struct xe_device *xe, struct xe_bo *bo,
                           u32 bo_flags, u32 *c)
 {
-       xe_assert(xe, *c < ARRAY_SIZE(bo->placements));
-
        if (bo_flags & XE_BO_CREATE_SYSTEM_BIT) {
+               xe_assert(xe, *c < ARRAY_SIZE(bo->placements));
+
                bo->placements[*c] = (struct ttm_place) {
                        .mem_type = XE_PL_TT,
                };
@@ -145,6 +145,8 @@ static void add_vram(struct xe_device *xe, struct xe_bo *bo,
        struct xe_mem_region *vram;
        u64 io_size;
 
+       xe_assert(xe, *c < ARRAY_SIZE(bo->placements));
+
        vram = to_xe_ttm_vram_mgr(ttm_manager_type(&xe->ttm, mem_type))->vram;
        xe_assert(xe, vram && vram->usable_size);
        io_size = vram->io_size;
@@ -175,8 +177,6 @@ static void add_vram(struct xe_device *xe, struct xe_bo *bo,
 static void try_add_vram(struct xe_device *xe, struct xe_bo *bo,
                         u32 bo_flags, u32 *c)
 {
-       xe_assert(xe, *c < ARRAY_SIZE(bo->placements));
-
        if (bo->props.preferred_gt == XE_GT1) {
                if (bo_flags & XE_BO_CREATE_VRAM1_BIT)
                        add_vram(xe, bo, bo->placements, bo_flags, XE_PL_VRAM1, c);
@@ -193,9 +193,9 @@ static void try_add_vram(struct xe_device *xe, struct xe_bo *bo,
 static void try_add_stolen(struct xe_device *xe, struct xe_bo *bo,
                           u32 bo_flags, u32 *c)
 {
-       xe_assert(xe, *c < ARRAY_SIZE(bo->placements));
-
        if (bo_flags & XE_BO_CREATE_STOLEN_BIT) {
+               xe_assert(xe, *c < ARRAY_SIZE(bo->placements));
+
                bo->placements[*c] = (struct ttm_place) {
                        .mem_type = XE_PL_STOLEN,
                        .flags = bo_flags & (XE_BO_CREATE_PINNED_BIT |
@@ -442,7 +442,7 @@ static int xe_ttm_io_mem_reserve(struct ttm_device *bdev,
 
                if (vram->mapping &&
                    mem->placement & TTM_PL_FLAG_CONTIGUOUS)
-                       mem->bus.addr = (u8 *)vram->mapping +
+                       mem->bus.addr = (u8 __force *)vram->mapping +
                                mem->bus.offset;
 
                mem->bus.offset += vram->io_start;
@@ -734,7 +734,7 @@ static int xe_bo_move(struct ttm_buffer_object *ttm_bo, bool evict,
                        /* Create a new VMAP once kernel BO back in VRAM */
                        if (!ret && resource_is_vram(new_mem)) {
                                struct xe_mem_region *vram = res_to_mem_region(new_mem);
-                               void *new_addr = vram->mapping +
+                               void __iomem *new_addr = vram->mapping +
                                        (new_mem->start << PAGE_SHIFT);
 
                                if (XE_WARN_ON(new_mem->start == XE_BO_INVALID_OFFSET)) {
index d9ae77fe7382ddf9997858995fe255108f7c5944..b8d8da5466708c6903ccb3ade3852a7ac9911235 100644 (file)
@@ -484,7 +484,7 @@ int xe_device_probe(struct xe_device *xe)
 
        err = xe_device_set_has_flat_ccs(xe);
        if (err)
-               return err;
+               goto err_irq_shutdown;
 
        err = xe_mmio_probe_vram(xe);
        if (err)
index c45ef17b347323801d397a964e53aa3fc5b060f4..5dc9127a20293e1ebb56c3684e2fdb7e6f425b43 100644 (file)
@@ -97,7 +97,7 @@ struct xe_mem_region {
         */
        resource_size_t actual_physical_size;
        /** @mapping: pointer to VRAM mappable space */
-       void *__iomem mapping;
+       void __iomem *mapping;
 };
 
 /**
@@ -146,7 +146,7 @@ struct xe_tile {
                size_t size;
 
                /** @regs: pointer to tile's MMIO space (starting with registers) */
-               void *regs;
+               void __iomem *regs;
        } mmio;
 
        /**
@@ -159,7 +159,7 @@ struct xe_tile {
                size_t size;
 
                /** @regs: pointer to tile's additional MMIO-extension space */
-               void *regs;
+               void __iomem *regs;
        } mmio_ext;
 
        /** @mem: memory management info for tile */
@@ -301,7 +301,7 @@ struct xe_device {
                /** @size: size of MMIO space for device */
                size_t size;
                /** @regs: pointer to MMIO space for device */
-               void *regs;
+               void __iomem *regs;
        } mmio;
 
        /** @mem: memory info for device */
index d30c0d0689bcc7d4ae55cdd7fc93b116826160e6..b853feed9ccc15eefab7f0ccdf070096521e6015 100644 (file)
@@ -115,7 +115,7 @@ int xe_exec_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
        struct xe_sched_job *job;
        struct dma_fence *rebind_fence;
        struct xe_vm *vm;
-       bool write_locked;
+       bool write_locked, skip_retry = false;
        ktime_t end = 0;
        int err = 0;
 
@@ -227,7 +227,8 @@ retry:
        }
 
        if (xe_exec_queue_is_lr(q) && xe_exec_queue_ring_full(q)) {
-               err = -EWOULDBLOCK;
+               err = -EWOULDBLOCK;     /* Aliased to -EAGAIN */
+               skip_retry = true;
                goto err_exec;
        }
 
@@ -337,7 +338,7 @@ err_unlock_list:
                up_write(&vm->lock);
        else
                up_read(&vm->lock);
-       if (err == -EAGAIN)
+       if (err == -EAGAIN && !skip_retry)
                goto retry;
 err_syncs:
        for (i = 0; i < num_syncs; i++)
index 44fe8097b7cdac8d5c89a3bf00168cf3b8343ca7..bcfc4127c7c59f0fffc8e40df70a5b1c8222495f 100644 (file)
@@ -67,6 +67,11 @@ static struct xe_exec_queue *__xe_exec_queue_create(struct xe_device *xe,
        q->sched_props.timeslice_us = hwe->eclass->sched_props.timeslice_us;
        q->sched_props.preempt_timeout_us =
                                hwe->eclass->sched_props.preempt_timeout_us;
+       if (q->flags & EXEC_QUEUE_FLAG_KERNEL &&
+           q->flags & EXEC_QUEUE_FLAG_HIGH_PRIORITY)
+               q->sched_props.priority = XE_EXEC_QUEUE_PRIORITY_KERNEL;
+       else
+               q->sched_props.priority = XE_EXEC_QUEUE_PRIORITY_NORMAL;
 
        if (xe_exec_queue_is_parallel(q)) {
                q->parallel.composite_fence_ctx = dma_fence_context_alloc(1);
index 3d7e704ec3d9f33b9c0e47867bb58135ea01df91..8d4b7feb8c306b8a406a46f74c5cad2a430bdef3 100644 (file)
@@ -52,8 +52,6 @@ struct xe_exec_queue {
        struct xe_vm *vm;
        /** @class: class of this exec queue */
        enum xe_engine_class class;
-       /** @priority: priority of this exec queue */
-       enum xe_exec_queue_priority priority;
        /**
         * @logical_mask: logical mask of where job submitted to exec queue can run
         */
@@ -84,6 +82,8 @@ struct xe_exec_queue {
 #define EXEC_QUEUE_FLAG_VM                     BIT(4)
 /* child of VM queue for multi-tile VM jobs */
 #define EXEC_QUEUE_FLAG_BIND_ENGINE_CHILD      BIT(5)
+/* kernel exec_queue only, set priority to highest level */
+#define EXEC_QUEUE_FLAG_HIGH_PRIORITY          BIT(6)
 
        /**
         * @flags: flags for this exec queue, should statically setup aside from ban
@@ -142,6 +142,8 @@ struct xe_exec_queue {
                u32 timeslice_us;
                /** @preempt_timeout_us: preemption timeout in micro-seconds */
                u32 preempt_timeout_us;
+               /** @priority: priority of this exec queue */
+               enum xe_exec_queue_priority priority;
        } sched_props;
 
        /** @compute: compute exec queue state */
index 3adfa6686e7cf9eb2763bccc28b7a0a382dd4834..e5b0f4ecdbe8261ee5c3fa9530a30dc2fd46c14b 100644 (file)
@@ -196,6 +196,9 @@ void xe_gt_freq_init(struct xe_gt *gt)
        struct xe_device *xe = gt_to_xe(gt);
        int err;
 
+       if (xe->info.skip_guc_pc)
+               return;
+
        gt->freq = kobject_create_and_add("freq0", gt->sysfs);
        if (!gt->freq) {
                drm_warn(&xe->drm, "failed to add freq0 directory to %s\n",
index 482cb0df9f15bc28d9f5c2a0ea194319f1b2a21a..0a61390c64a7b7100113641f2e073f4ce58d358e 100644 (file)
@@ -60,7 +60,12 @@ static u32 guc_ctl_debug_flags(struct xe_guc *guc)
 
 static u32 guc_ctl_feature_flags(struct xe_guc *guc)
 {
-       return GUC_CTL_ENABLE_SLPC;
+       u32 flags = 0;
+
+       if (!guc_to_xe(guc)->info.skip_guc_pc)
+               flags |= GUC_CTL_ENABLE_SLPC;
+
+       return flags;
 }
 
 static u32 guc_ctl_log_params_flags(struct xe_guc *guc)
index 21ac68e3246f86f1e16d05880da8aa9315769ecb..54ffcfcdd41f9ce3c590f5814fcbe3d3535946ac 100644 (file)
@@ -421,7 +421,7 @@ static void init_policies(struct xe_guc *guc, struct xe_exec_queue *q)
 {
        struct exec_queue_policy policy;
        struct xe_device *xe = guc_to_xe(guc);
-       enum xe_exec_queue_priority prio = q->priority;
+       enum xe_exec_queue_priority prio = q->sched_props.priority;
        u32 timeslice_us = q->sched_props.timeslice_us;
        u32 preempt_timeout_us = q->sched_props.preempt_timeout_us;
 
@@ -1231,7 +1231,6 @@ static int guc_exec_queue_init(struct xe_exec_queue *q)
        err = xe_sched_entity_init(&ge->entity, sched);
        if (err)
                goto err_sched;
-       q->priority = XE_EXEC_QUEUE_PRIORITY_NORMAL;
 
        if (xe_exec_queue_is_lr(q))
                INIT_WORK(&q->guc->lr_tdr, xe_guc_exec_queue_lr_cleanup);
@@ -1301,15 +1300,15 @@ static int guc_exec_queue_set_priority(struct xe_exec_queue *q,
 {
        struct xe_sched_msg *msg;
 
-       if (q->priority == priority || exec_queue_killed_or_banned(q))
+       if (q->sched_props.priority == priority || exec_queue_killed_or_banned(q))
                return 0;
 
        msg = kmalloc(sizeof(*msg), GFP_KERNEL);
        if (!msg)
                return -ENOMEM;
 
+       q->sched_props.priority = priority;
        guc_exec_queue_add_msg(q, msg, SET_SCHED_PROPS);
-       q->priority = priority;
 
        return 0;
 }
index adf1dab5eba253297fb8b4ae4c2c5b5f15b2ec7a..e05e9e7282b68abdcab839a9134efd09e60750f2 100644 (file)
@@ -62,6 +62,8 @@ struct xe_migrate {
         * out of the pt_bo.
         */
        struct drm_suballoc_manager vm_update_sa;
+       /** @min_chunk_size: For dgfx, Minimum chunk size */
+       u64 min_chunk_size;
 };
 
 #define MAX_PREEMPTDISABLE_TRANSFER SZ_8M /* Around 1ms. */
@@ -344,7 +346,8 @@ struct xe_migrate *xe_migrate_init(struct xe_tile *tile)
 
                m->q = xe_exec_queue_create(xe, vm, logical_mask, 1, hwe,
                                            EXEC_QUEUE_FLAG_KERNEL |
-                                           EXEC_QUEUE_FLAG_PERMANENT);
+                                           EXEC_QUEUE_FLAG_PERMANENT |
+                                           EXEC_QUEUE_FLAG_HIGH_PRIORITY);
        } else {
                m->q = xe_exec_queue_create_class(xe, primary_gt, vm,
                                                  XE_ENGINE_CLASS_COPY,
@@ -355,8 +358,6 @@ struct xe_migrate *xe_migrate_init(struct xe_tile *tile)
                xe_vm_close_and_put(vm);
                return ERR_CAST(m->q);
        }
-       if (xe->info.has_usm)
-               m->q->priority = XE_EXEC_QUEUE_PRIORITY_KERNEL;
 
        mutex_init(&m->job_mutex);
 
@@ -364,6 +365,19 @@ struct xe_migrate *xe_migrate_init(struct xe_tile *tile)
        if (err)
                return ERR_PTR(err);
 
+       if (IS_DGFX(xe)) {
+               if (xe_device_has_flat_ccs(xe))
+                       /* min chunk size corresponds to 4K of CCS Metadata */
+                       m->min_chunk_size = SZ_4K * SZ_64K /
+                               xe_device_ccs_bytes(xe, SZ_64K);
+               else
+                       /* Somewhat arbitrary to avoid a huge amount of blits */
+                       m->min_chunk_size = SZ_64K;
+               m->min_chunk_size = roundup_pow_of_two(m->min_chunk_size);
+               drm_dbg(&xe->drm, "Migrate min chunk size is 0x%08llx\n",
+                       (unsigned long long)m->min_chunk_size);
+       }
+
        return m;
 }
 
@@ -375,16 +389,35 @@ static u64 max_mem_transfer_per_pass(struct xe_device *xe)
        return MAX_PREEMPTDISABLE_TRANSFER;
 }
 
-static u64 xe_migrate_res_sizes(struct xe_device *xe, struct xe_res_cursor *cur)
+static u64 xe_migrate_res_sizes(struct xe_migrate *m, struct xe_res_cursor *cur)
 {
-       /*
-        * For VRAM we use identity mapped pages so we are limited to current
-        * cursor size. For system we program the pages ourselves so we have no
-        * such limitation.
-        */
-       return min_t(u64, max_mem_transfer_per_pass(xe),
-                    mem_type_is_vram(cur->mem_type) ? cur->size :
-                    cur->remaining);
+       struct xe_device *xe = tile_to_xe(m->tile);
+       u64 size = min_t(u64, max_mem_transfer_per_pass(xe), cur->remaining);
+
+       if (mem_type_is_vram(cur->mem_type)) {
+               /*
+                * VRAM we want to blit in chunks with sizes aligned to
+                * min_chunk_size in order for the offset to CCS metadata to be
+                * page-aligned. If it's the last chunk it may be smaller.
+                *
+                * Another constraint is that we need to limit the blit to
+                * the VRAM block size, unless size is smaller than
+                * min_chunk_size.
+                */
+               u64 chunk = max_t(u64, cur->size, m->min_chunk_size);
+
+               size = min_t(u64, size, chunk);
+               if (size > m->min_chunk_size)
+                       size = round_down(size, m->min_chunk_size);
+       }
+
+       return size;
+}
+
+static bool xe_migrate_allow_identity(u64 size, const struct xe_res_cursor *cur)
+{
+       /* If the chunk is not fragmented, allow identity map. */
+       return cur->size >= size;
 }
 
 static u32 pte_update_size(struct xe_migrate *m,
@@ -397,7 +430,12 @@ static u32 pte_update_size(struct xe_migrate *m,
        u32 cmds = 0;
 
        *L0_pt = pt_ofs;
-       if (!is_vram) {
+       if (is_vram && xe_migrate_allow_identity(*L0, cur)) {
+               /* Offset into identity map. */
+               *L0_ofs = xe_migrate_vram_ofs(tile_to_xe(m->tile),
+                                             cur->start + vram_region_gpu_offset(res));
+               cmds += cmd_size;
+       } else {
                /* Clip L0 to available size */
                u64 size = min(*L0, (u64)avail_pts * SZ_2M);
                u64 num_4k_pages = DIV_ROUND_UP(size, XE_PAGE_SIZE);
@@ -413,11 +451,6 @@ static u32 pte_update_size(struct xe_migrate *m,
 
                /* Each chunk has a single blit command */
                cmds += cmd_size;
-       } else {
-               /* Offset into identity map. */
-               *L0_ofs = xe_migrate_vram_ofs(tile_to_xe(m->tile),
-                                             cur->start + vram_region_gpu_offset(res));
-               cmds += cmd_size;
        }
 
        return cmds;
@@ -427,10 +460,10 @@ static void emit_pte(struct xe_migrate *m,
                     struct xe_bb *bb, u32 at_pt,
                     bool is_vram, bool is_comp_pte,
                     struct xe_res_cursor *cur,
-                    u32 size, struct xe_bo *bo)
+                    u32 size, struct ttm_resource *res)
 {
        struct xe_device *xe = tile_to_xe(m->tile);
-
+       struct xe_vm *vm = m->q->vm;
        u16 pat_index;
        u32 ptes;
        u64 ofs = at_pt * XE_PAGE_SIZE;
@@ -443,13 +476,6 @@ static void emit_pte(struct xe_migrate *m,
        else
                pat_index = xe->pat.idx[XE_CACHE_WB];
 
-       /*
-        * FIXME: Emitting VRAM PTEs to L0 PTs is forbidden. Currently
-        * we're only emitting VRAM PTEs during sanity tests, so when
-        * that's moved to a Kunit test, we should condition VRAM PTEs
-        * on running tests.
-        */
-
        ptes = DIV_ROUND_UP(size, XE_PAGE_SIZE);
 
        while (ptes) {
@@ -469,20 +495,22 @@ static void emit_pte(struct xe_migrate *m,
 
                        addr = xe_res_dma(cur) & PAGE_MASK;
                        if (is_vram) {
-                               /* Is this a 64K PTE entry? */
-                               if ((m->q->vm->flags & XE_VM_FLAG_64K) &&
-                                   !(cur_ofs & (16 * 8 - 1))) {
-                                       xe_tile_assert(m->tile, IS_ALIGNED(addr, SZ_64K));
+                               if (vm->flags & XE_VM_FLAG_64K) {
+                                       u64 va = cur_ofs * XE_PAGE_SIZE / 8;
+
+                                       xe_assert(xe, (va & (SZ_64K - 1)) ==
+                                                 (addr & (SZ_64K - 1)));
+
                                        flags |= XE_PTE_PS64;
                                }
 
-                               addr += vram_region_gpu_offset(bo->ttm.resource);
+                               addr += vram_region_gpu_offset(res);
                                devmem = true;
                        }
 
-                       addr = m->q->vm->pt_ops->pte_encode_addr(m->tile->xe,
-                                                                addr, pat_index,
-                                                                0, devmem, flags);
+                       addr = vm->pt_ops->pte_encode_addr(m->tile->xe,
+                                                          addr, pat_index,
+                                                          0, devmem, flags);
                        bb->cs[bb->len++] = lower_32_bits(addr);
                        bb->cs[bb->len++] = upper_32_bits(addr);
 
@@ -694,8 +722,8 @@ struct dma_fence *xe_migrate_copy(struct xe_migrate *m,
                bool usm = xe->info.has_usm;
                u32 avail_pts = max_mem_transfer_per_pass(xe) / LEVEL0_PAGE_TABLE_ENCODE_SIZE;
 
-               src_L0 = xe_migrate_res_sizes(xe, &src_it);
-               dst_L0 = xe_migrate_res_sizes(xe, &dst_it);
+               src_L0 = xe_migrate_res_sizes(m, &src_it);
+               dst_L0 = xe_migrate_res_sizes(m, &dst_it);
 
                drm_dbg(&xe->drm, "Pass %u, sizes: %llu & %llu\n",
                        pass++, src_L0, dst_L0);
@@ -716,6 +744,7 @@ struct dma_fence *xe_migrate_copy(struct xe_migrate *m,
                                                      &ccs_ofs, &ccs_pt, 0,
                                                      2 * avail_pts,
                                                      avail_pts);
+                       xe_assert(xe, IS_ALIGNED(ccs_it.start, PAGE_SIZE));
                }
 
                /* Add copy commands size here */
@@ -728,20 +757,20 @@ struct dma_fence *xe_migrate_copy(struct xe_migrate *m,
                        goto err_sync;
                }
 
-               if (!src_is_vram)
-                       emit_pte(m, bb, src_L0_pt, src_is_vram, true, &src_it, src_L0,
-                                src_bo);
-               else
+               if (src_is_vram && xe_migrate_allow_identity(src_L0, &src_it))
                        xe_res_next(&src_it, src_L0);
-
-               if (!dst_is_vram)
-                       emit_pte(m, bb, dst_L0_pt, dst_is_vram, true, &dst_it, src_L0,
-                                dst_bo);
                else
+                       emit_pte(m, bb, src_L0_pt, src_is_vram, true, &src_it, src_L0,
+                                src);
+
+               if (dst_is_vram && xe_migrate_allow_identity(src_L0, &dst_it))
                        xe_res_next(&dst_it, src_L0);
+               else
+                       emit_pte(m, bb, dst_L0_pt, dst_is_vram, true, &dst_it, src_L0,
+                                dst);
 
                if (copy_system_ccs)
-                       emit_pte(m, bb, ccs_pt, false, false, &ccs_it, ccs_size, src_bo);
+                       emit_pte(m, bb, ccs_pt, false, false, &ccs_it, ccs_size, src);
 
                bb->cs[bb->len++] = MI_BATCH_BUFFER_END;
                update_idx = bb->len;
@@ -950,7 +979,7 @@ struct dma_fence *xe_migrate_clear(struct xe_migrate *m,
                bool usm = xe->info.has_usm;
                u32 avail_pts = max_mem_transfer_per_pass(xe) / LEVEL0_PAGE_TABLE_ENCODE_SIZE;
 
-               clear_L0 = xe_migrate_res_sizes(xe, &src_it);
+               clear_L0 = xe_migrate_res_sizes(m, &src_it);
 
                drm_dbg(&xe->drm, "Pass %u, size: %llu\n", pass++, clear_L0);
 
@@ -977,12 +1006,12 @@ struct dma_fence *xe_migrate_clear(struct xe_migrate *m,
 
                size -= clear_L0;
                /* Preemption is enabled again by the ring ops. */
-               if (!clear_vram) {
-                       emit_pte(m, bb, clear_L0_pt, clear_vram, true, &src_it, clear_L0,
-                                bo);
-               } else {
+               if (clear_vram && xe_migrate_allow_identity(clear_L0, &src_it))
                        xe_res_next(&src_it, clear_L0);
-               }
+               else
+                       emit_pte(m, bb, clear_L0_pt, clear_vram, true, &src_it, clear_L0,
+                                dst);
+
                bb->cs[bb->len++] = MI_BATCH_BUFFER_END;
                update_idx = bb->len;
 
index f660cfb79f504e264f9a3ced4a5f5544fada74e0..c8c5d74b6e9041ec53c38ba81d184b83037427ab 100644 (file)
@@ -303,7 +303,7 @@ void xe_mmio_probe_tiles(struct xe_device *xe)
        u8 id, tile_count = xe->info.tile_count;
        struct xe_gt *gt = xe_root_mmio_gt(xe);
        struct xe_tile *tile;
-       void *regs;
+       void __iomem *regs;
        u32 mtcfg;
 
        if (tile_count == 1)
index d2b00d0bf1e203c8b9c9322bcf8a489b1409821b..e5d7d5e2bec129937317f14f6b0063308a19bf58 100644 (file)
@@ -31,7 +31,7 @@ struct xe_ttm_stolen_mgr {
        /* GPU base offset */
        resource_size_t stolen_base;
 
-       void *__iomem mapping;
+       void __iomem *mapping;
 };
 
 static inline struct xe_ttm_stolen_mgr *
@@ -275,7 +275,7 @@ static int __xe_ttm_stolen_io_mem_reserve_bar2(struct xe_device *xe,
        drm_WARN_ON(&xe->drm, !(mem->placement & TTM_PL_FLAG_CONTIGUOUS));
 
        if (mem->placement & TTM_PL_FLAG_CONTIGUOUS && mgr->mapping)
-               mem->bus.addr = (u8 *)mgr->mapping + mem->bus.offset;
+               mem->bus.addr = (u8 __force *)mgr->mapping + mem->bus.offset;
 
        mem->bus.offset += mgr->io_base;
        mem->bus.is_iomem = true;
index 0cfe7289b97efddd3d3b1177b6e91ebafd22fdc9..10b6995fbf294690a36234dc3c36bf741245b7a9 100644 (file)
@@ -335,13 +335,13 @@ int xe_vm_add_compute_exec_queue(struct xe_vm *vm, struct xe_exec_queue *q)
        down_write(&vm->lock);
        err = drm_gpuvm_exec_lock(&vm_exec);
        if (err)
-               return err;
+               goto out_up_write;
 
        pfence = xe_preempt_fence_create(q, q->compute.context,
                                         ++q->compute.seqno);
        if (!pfence) {
                err = -ENOMEM;
-               goto out_unlock;
+               goto out_fini;
        }
 
        list_add(&q->compute.link, &vm->preempt.exec_queues);
@@ -364,8 +364,9 @@ int xe_vm_add_compute_exec_queue(struct xe_vm *vm, struct xe_exec_queue *q)
 
        up_read(&vm->userptr.notifier_lock);
 
-out_unlock:
+out_fini:
        drm_exec_fini(exec);
+out_up_write:
        up_write(&vm->lock);
 
        return err;
@@ -2063,9 +2064,11 @@ vm_bind_ioctl_ops_create(struct xe_vm *vm, struct xe_bo *bo,
                if (err)
                        return ERR_PTR(err);
 
-               vm_bo = drm_gpuvm_bo_find(&vm->gpuvm, obj);
-               if (!vm_bo)
-                       break;
+               vm_bo = drm_gpuvm_bo_obtain(&vm->gpuvm, obj);
+               if (IS_ERR(vm_bo)) {
+                       xe_bo_unlock(bo);
+                       return ERR_CAST(vm_bo);
+               }
 
                ops = drm_gpuvm_bo_unmap_ops_create(vm_bo);
                drm_gpuvm_bo_put(vm_bo);