diff options
45 files changed, 388 insertions, 118 deletions
diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c index 3aa8733f832a..9bf06042619a 100644 --- a/drivers/dma-buf/dma-fence.c +++ b/drivers/dma-buf/dma-fence.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | 29 | ||
| 30 | EXPORT_TRACEPOINT_SYMBOL(dma_fence_emit); | 30 | EXPORT_TRACEPOINT_SYMBOL(dma_fence_emit); |
| 31 | EXPORT_TRACEPOINT_SYMBOL(dma_fence_enable_signal); | 31 | EXPORT_TRACEPOINT_SYMBOL(dma_fence_enable_signal); |
| 32 | EXPORT_TRACEPOINT_SYMBOL(dma_fence_signaled); | ||
| 32 | 33 | ||
| 33 | static DEFINE_SPINLOCK(dma_fence_stub_lock); | 34 | static DEFINE_SPINLOCK(dma_fence_stub_lock); |
| 34 | static struct dma_fence dma_fence_stub; | 35 | static struct dma_fence dma_fence_stub; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c index 4376b17ca594..56f8ca2a3bb4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | |||
| @@ -464,8 +464,7 @@ static int amdgpu_atif_handler(struct amdgpu_device *adev, | |||
| 464 | } | 464 | } |
| 465 | } | 465 | } |
| 466 | if (req.pending & ATIF_DGPU_DISPLAY_EVENT) { | 466 | if (req.pending & ATIF_DGPU_DISPLAY_EVENT) { |
| 467 | if ((adev->flags & AMD_IS_PX) && | 467 | if (adev->flags & AMD_IS_PX) { |
| 468 | amdgpu_atpx_dgpu_req_power_for_displays()) { | ||
| 469 | pm_runtime_get_sync(adev->ddev->dev); | 468 | pm_runtime_get_sync(adev->ddev->dev); |
| 470 | /* Just fire off a uevent and let userspace tell us what to do */ | 469 | /* Just fire off a uevent and let userspace tell us what to do */ |
| 471 | drm_helper_hpd_irq_event(adev->ddev); | 470 | drm_helper_hpd_irq_event(adev->ddev); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index 95144e49c7f9..34471dbaa872 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | |||
| @@ -342,6 +342,16 @@ static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev, | |||
| 342 | if (current_level == level) | 342 | if (current_level == level) |
| 343 | return count; | 343 | return count; |
| 344 | 344 | ||
| 345 | /* profile_exit setting is valid only when current mode is in profile mode */ | ||
| 346 | if (!(current_level & (AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD | | ||
| 347 | AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK | | ||
| 348 | AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK | | ||
| 349 | AMD_DPM_FORCED_LEVEL_PROFILE_PEAK)) && | ||
| 350 | (level == AMD_DPM_FORCED_LEVEL_PROFILE_EXIT)) { | ||
| 351 | pr_err("Currently not in any profile mode!\n"); | ||
| 352 | return -EINVAL; | ||
| 353 | } | ||
| 354 | |||
| 345 | if (is_support_sw_smu(adev)) { | 355 | if (is_support_sw_smu(adev)) { |
| 346 | mutex_lock(&adev->pm.mutex); | 356 | mutex_lock(&adev->pm.mutex); |
| 347 | if (adev->pm.dpm.thermal_active) { | 357 | if (adev->pm.dpm.thermal_active) { |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index 905cce1814f3..05897b05766b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | |||
| @@ -38,18 +38,10 @@ static void psp_set_funcs(struct amdgpu_device *adev); | |||
| 38 | static int psp_early_init(void *handle) | 38 | static int psp_early_init(void *handle) |
| 39 | { | 39 | { |
| 40 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 40 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 41 | struct psp_context *psp = &adev->psp; | ||
| 41 | 42 | ||
| 42 | psp_set_funcs(adev); | 43 | psp_set_funcs(adev); |
| 43 | 44 | ||
| 44 | return 0; | ||
| 45 | } | ||
| 46 | |||
| 47 | static int psp_sw_init(void *handle) | ||
| 48 | { | ||
| 49 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
| 50 | struct psp_context *psp = &adev->psp; | ||
| 51 | int ret; | ||
| 52 | |||
| 53 | switch (adev->asic_type) { | 45 | switch (adev->asic_type) { |
| 54 | case CHIP_VEGA10: | 46 | case CHIP_VEGA10: |
| 55 | case CHIP_VEGA12: | 47 | case CHIP_VEGA12: |
| @@ -67,6 +59,15 @@ static int psp_sw_init(void *handle) | |||
| 67 | 59 | ||
| 68 | psp->adev = adev; | 60 | psp->adev = adev; |
| 69 | 61 | ||
| 62 | return 0; | ||
| 63 | } | ||
| 64 | |||
| 65 | static int psp_sw_init(void *handle) | ||
| 66 | { | ||
| 67 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
| 68 | struct psp_context *psp = &adev->psp; | ||
| 69 | int ret; | ||
| 70 | |||
| 70 | ret = psp_init_microcode(psp); | 71 | ret = psp_init_microcode(psp); |
| 71 | if (ret) { | 72 | if (ret) { |
| 72 | DRM_ERROR("Failed to load psp firmware!\n"); | 73 | DRM_ERROR("Failed to load psp firmware!\n"); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index a07c85815b7a..4f10f5aba00b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | |||
| @@ -2757,6 +2757,37 @@ error_free_sched_entity: | |||
| 2757 | } | 2757 | } |
| 2758 | 2758 | ||
| 2759 | /** | 2759 | /** |
| 2760 | * amdgpu_vm_check_clean_reserved - check if a VM is clean | ||
| 2761 | * | ||
| 2762 | * @adev: amdgpu_device pointer | ||
| 2763 | * @vm: the VM to check | ||
| 2764 | * | ||
| 2765 | * check all entries of the root PD, if any subsequent PDs are allocated, | ||
| 2766 | * it means there are page table creating and filling, and is no a clean | ||
| 2767 | * VM | ||
| 2768 | * | ||
| 2769 | * Returns: | ||
| 2770 | * 0 if this VM is clean | ||
| 2771 | */ | ||
| 2772 | static int amdgpu_vm_check_clean_reserved(struct amdgpu_device *adev, | ||
| 2773 | struct amdgpu_vm *vm) | ||
| 2774 | { | ||
| 2775 | enum amdgpu_vm_level root = adev->vm_manager.root_level; | ||
| 2776 | unsigned int entries = amdgpu_vm_num_entries(adev, root); | ||
| 2777 | unsigned int i = 0; | ||
| 2778 | |||
| 2779 | if (!(vm->root.entries)) | ||
| 2780 | return 0; | ||
| 2781 | |||
| 2782 | for (i = 0; i < entries; i++) { | ||
| 2783 | if (vm->root.entries[i].base.bo) | ||
| 2784 | return -EINVAL; | ||
| 2785 | } | ||
| 2786 | |||
| 2787 | return 0; | ||
| 2788 | } | ||
| 2789 | |||
| 2790 | /** | ||
| 2760 | * amdgpu_vm_make_compute - Turn a GFX VM into a compute VM | 2791 | * amdgpu_vm_make_compute - Turn a GFX VM into a compute VM |
| 2761 | * | 2792 | * |
| 2762 | * @adev: amdgpu_device pointer | 2793 | * @adev: amdgpu_device pointer |
| @@ -2786,10 +2817,9 @@ int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm, uns | |||
| 2786 | return r; | 2817 | return r; |
| 2787 | 2818 | ||
| 2788 | /* Sanity checks */ | 2819 | /* Sanity checks */ |
| 2789 | if (!RB_EMPTY_ROOT(&vm->va.rb_root) || vm->root.entries) { | 2820 | r = amdgpu_vm_check_clean_reserved(adev, vm); |
| 2790 | r = -EINVAL; | 2821 | if (r) |
| 2791 | goto unreserve_bo; | 2822 | goto unreserve_bo; |
| 2792 | } | ||
| 2793 | 2823 | ||
| 2794 | if (pasid) { | 2824 | if (pasid) { |
| 2795 | unsigned long flags; | 2825 | unsigned long flags; |
diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c index 8dbad496b29f..2471e7cf75ea 100644 --- a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c +++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c | |||
| @@ -372,6 +372,9 @@ static int xgpu_ai_mailbox_rcv_irq(struct amdgpu_device *adev, | |||
| 372 | if (amdgpu_sriov_runtime(adev)) | 372 | if (amdgpu_sriov_runtime(adev)) |
| 373 | schedule_work(&adev->virt.flr_work); | 373 | schedule_work(&adev->virt.flr_work); |
| 374 | break; | 374 | break; |
| 375 | case IDH_QUERY_ALIVE: | ||
| 376 | xgpu_ai_mailbox_send_ack(adev); | ||
| 377 | break; | ||
| 375 | /* READY_TO_ACCESS_GPU is fetched by kernel polling, IRQ can ignore | 378 | /* READY_TO_ACCESS_GPU is fetched by kernel polling, IRQ can ignore |
| 376 | * it byfar since that polling thread will handle it, | 379 | * it byfar since that polling thread will handle it, |
| 377 | * other msg like flr complete is not handled here. | 380 | * other msg like flr complete is not handled here. |
diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h index 39d151b79153..077e91a33d62 100644 --- a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h +++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h | |||
| @@ -49,6 +49,7 @@ enum idh_event { | |||
| 49 | IDH_FLR_NOTIFICATION_CMPL, | 49 | IDH_FLR_NOTIFICATION_CMPL, |
| 50 | IDH_SUCCESS, | 50 | IDH_SUCCESS, |
| 51 | IDH_FAIL, | 51 | IDH_FAIL, |
| 52 | IDH_QUERY_ALIVE, | ||
| 52 | IDH_EVENT_MAX | 53 | IDH_EVENT_MAX |
| 53 | }; | 54 | }; |
| 54 | 55 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c index dc461df48da0..2191d3d0a219 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c | |||
| @@ -787,10 +787,13 @@ static int uvd_v7_0_sriov_start(struct amdgpu_device *adev) | |||
| 787 | 0xFFFFFFFF, 0x00000004); | 787 | 0xFFFFFFFF, 0x00000004); |
| 788 | /* mc resume*/ | 788 | /* mc resume*/ |
| 789 | if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { | 789 | if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { |
| 790 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), | 790 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, |
| 791 | lower_32_bits(adev->firmware.ucode[AMDGPU_UCODE_ID_UVD].mc_addr)); | 791 | mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), |
| 792 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), | 792 | adev->firmware.ucode[AMDGPU_UCODE_ID_UVD].tmr_mc_addr_lo); |
| 793 | upper_32_bits(adev->firmware.ucode[AMDGPU_UCODE_ID_UVD].mc_addr)); | 793 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, |
| 794 | mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), | ||
| 795 | adev->firmware.ucode[AMDGPU_UCODE_ID_UVD].tmr_mc_addr_hi); | ||
| 796 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CACHE_OFFSET0), 0); | ||
| 794 | offset = 0; | 797 | offset = 0; |
| 795 | } else { | 798 | } else { |
| 796 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), | 799 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), |
| @@ -798,10 +801,11 @@ static int uvd_v7_0_sriov_start(struct amdgpu_device *adev) | |||
| 798 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), | 801 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), |
| 799 | upper_32_bits(adev->uvd.inst[i].gpu_addr)); | 802 | upper_32_bits(adev->uvd.inst[i].gpu_addr)); |
| 800 | offset = size; | 803 | offset = size; |
| 804 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CACHE_OFFSET0), | ||
| 805 | AMDGPU_UVD_FIRMWARE_OFFSET >> 3); | ||
| 806 | |||
| 801 | } | 807 | } |
| 802 | 808 | ||
| 803 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CACHE_OFFSET0), | ||
| 804 | AMDGPU_UVD_FIRMWARE_OFFSET >> 3); | ||
| 805 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CACHE_SIZE0), size); | 809 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CACHE_SIZE0), size); |
| 806 | 810 | ||
| 807 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW), | 811 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW), |
diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c index f3f5938430d4..c0ec27991c22 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c | |||
| @@ -244,13 +244,18 @@ static int vce_v4_0_sriov_start(struct amdgpu_device *adev) | |||
| 244 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0, mmVCE_LMI_SWAP_CNTL1), 0); | 244 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0, mmVCE_LMI_SWAP_CNTL1), 0); |
| 245 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0, mmVCE_LMI_VM_CTRL), 0); | 245 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0, mmVCE_LMI_VM_CTRL), 0); |
| 246 | 246 | ||
| 247 | offset = AMDGPU_VCE_FIRMWARE_OFFSET; | ||
| 247 | if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { | 248 | if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { |
| 249 | uint32_t low = adev->firmware.ucode[AMDGPU_UCODE_ID_VCE].tmr_mc_addr_lo; | ||
| 250 | uint32_t hi = adev->firmware.ucode[AMDGPU_UCODE_ID_VCE].tmr_mc_addr_hi; | ||
| 251 | uint64_t tmr_mc_addr = (uint64_t)(hi) << 32 | low; | ||
| 252 | |||
| 248 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0, | 253 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0, |
| 249 | mmVCE_LMI_VCPU_CACHE_40BIT_BAR0), | 254 | mmVCE_LMI_VCPU_CACHE_40BIT_BAR0), tmr_mc_addr >> 8); |
| 250 | adev->firmware.ucode[AMDGPU_UCODE_ID_VCE].mc_addr >> 8); | ||
| 251 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0, | 255 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0, |
| 252 | mmVCE_LMI_VCPU_CACHE_64BIT_BAR0), | 256 | mmVCE_LMI_VCPU_CACHE_64BIT_BAR0), |
| 253 | (adev->firmware.ucode[AMDGPU_UCODE_ID_VCE].mc_addr >> 40) & 0xff); | 257 | (tmr_mc_addr >> 40) & 0xff); |
| 258 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0, mmVCE_VCPU_CACHE_OFFSET0), 0); | ||
| 254 | } else { | 259 | } else { |
| 255 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0, | 260 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0, |
| 256 | mmVCE_LMI_VCPU_CACHE_40BIT_BAR0), | 261 | mmVCE_LMI_VCPU_CACHE_40BIT_BAR0), |
| @@ -258,6 +263,9 @@ static int vce_v4_0_sriov_start(struct amdgpu_device *adev) | |||
| 258 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0, | 263 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0, |
| 259 | mmVCE_LMI_VCPU_CACHE_64BIT_BAR0), | 264 | mmVCE_LMI_VCPU_CACHE_64BIT_BAR0), |
| 260 | (adev->vce.gpu_addr >> 40) & 0xff); | 265 | (adev->vce.gpu_addr >> 40) & 0xff); |
| 266 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0, mmVCE_VCPU_CACHE_OFFSET0), | ||
| 267 | offset & ~0x0f000000); | ||
| 268 | |||
| 261 | } | 269 | } |
| 262 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0, | 270 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0, |
| 263 | mmVCE_LMI_VCPU_CACHE_40BIT_BAR1), | 271 | mmVCE_LMI_VCPU_CACHE_40BIT_BAR1), |
| @@ -272,10 +280,7 @@ static int vce_v4_0_sriov_start(struct amdgpu_device *adev) | |||
| 272 | mmVCE_LMI_VCPU_CACHE_64BIT_BAR2), | 280 | mmVCE_LMI_VCPU_CACHE_64BIT_BAR2), |
| 273 | (adev->vce.gpu_addr >> 40) & 0xff); | 281 | (adev->vce.gpu_addr >> 40) & 0xff); |
| 274 | 282 | ||
| 275 | offset = AMDGPU_VCE_FIRMWARE_OFFSET; | ||
| 276 | size = VCE_V4_0_FW_SIZE; | 283 | size = VCE_V4_0_FW_SIZE; |
| 277 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0, mmVCE_VCPU_CACHE_OFFSET0), | ||
| 278 | offset & ~0x0f000000); | ||
| 279 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0, mmVCE_VCPU_CACHE_SIZE0), size); | 284 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0, mmVCE_VCPU_CACHE_SIZE0), size); |
| 280 | 285 | ||
| 281 | offset = (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) ? offset + size : 0; | 286 | offset = (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) ? offset + size : 0; |
diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c index 1b2f69a9a24e..8d89ab7f0ae8 100644 --- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c | |||
| @@ -31,7 +31,7 @@ | |||
| 31 | #include "soc15_common.h" | 31 | #include "soc15_common.h" |
| 32 | #include "vega10_ih.h" | 32 | #include "vega10_ih.h" |
| 33 | 33 | ||
| 34 | 34 | #define MAX_REARM_RETRY 10 | |
| 35 | 35 | ||
| 36 | static void vega10_ih_set_interrupt_funcs(struct amdgpu_device *adev); | 36 | static void vega10_ih_set_interrupt_funcs(struct amdgpu_device *adev); |
| 37 | 37 | ||
| @@ -382,6 +382,38 @@ static void vega10_ih_decode_iv(struct amdgpu_device *adev, | |||
| 382 | } | 382 | } |
| 383 | 383 | ||
| 384 | /** | 384 | /** |
| 385 | * vega10_ih_irq_rearm - rearm IRQ if lost | ||
| 386 | * | ||
| 387 | * @adev: amdgpu_device pointer | ||
| 388 | * | ||
| 389 | */ | ||
| 390 | static void vega10_ih_irq_rearm(struct amdgpu_device *adev, | ||
| 391 | struct amdgpu_ih_ring *ih) | ||
| 392 | { | ||
| 393 | uint32_t reg_rptr = 0; | ||
| 394 | uint32_t v = 0; | ||
| 395 | uint32_t i = 0; | ||
| 396 | |||
| 397 | if (ih == &adev->irq.ih) | ||
| 398 | reg_rptr = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_RPTR); | ||
| 399 | else if (ih == &adev->irq.ih1) | ||
| 400 | reg_rptr = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_RPTR_RING1); | ||
| 401 | else if (ih == &adev->irq.ih2) | ||
| 402 | reg_rptr = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_RPTR_RING2); | ||
| 403 | else | ||
| 404 | return; | ||
| 405 | |||
| 406 | /* Rearm IRQ / re-wwrite doorbell if doorbell write is lost */ | ||
| 407 | for (i = 0; i < MAX_REARM_RETRY; i++) { | ||
| 408 | v = RREG32_NO_KIQ(reg_rptr); | ||
| 409 | if ((v < ih->ring_size) && (v != ih->rptr)) | ||
| 410 | WDOORBELL32(ih->doorbell_index, ih->rptr); | ||
| 411 | else | ||
| 412 | break; | ||
| 413 | } | ||
| 414 | } | ||
| 415 | |||
| 416 | /** | ||
| 385 | * vega10_ih_set_rptr - set the IH ring buffer rptr | 417 | * vega10_ih_set_rptr - set the IH ring buffer rptr |
| 386 | * | 418 | * |
| 387 | * @adev: amdgpu_device pointer | 419 | * @adev: amdgpu_device pointer |
| @@ -395,6 +427,9 @@ static void vega10_ih_set_rptr(struct amdgpu_device *adev, | |||
| 395 | /* XXX check if swapping is necessary on BE */ | 427 | /* XXX check if swapping is necessary on BE */ |
| 396 | *ih->rptr_cpu = ih->rptr; | 428 | *ih->rptr_cpu = ih->rptr; |
| 397 | WDOORBELL32(ih->doorbell_index, ih->rptr); | 429 | WDOORBELL32(ih->doorbell_index, ih->rptr); |
| 430 | |||
| 431 | if (amdgpu_sriov_vf(adev)) | ||
| 432 | vega10_ih_irq_rearm(adev, ih); | ||
| 398 | } else if (ih == &adev->irq.ih) { | 433 | } else if (ih == &adev->irq.ih) { |
| 399 | WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, ih->rptr); | 434 | WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, ih->rptr); |
| 400 | } else if (ih == &adev->irq.ih1) { | 435 | } else if (ih == &adev->irq.ih1) { |
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 1854506e3e8f..995f9df66142 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | |||
| @@ -5242,7 +5242,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, | |||
| 5242 | struct drm_crtc *pcrtc, | 5242 | struct drm_crtc *pcrtc, |
| 5243 | bool wait_for_vblank) | 5243 | bool wait_for_vblank) |
| 5244 | { | 5244 | { |
| 5245 | uint32_t i, r; | 5245 | uint32_t i; |
| 5246 | uint64_t timestamp_ns; | 5246 | uint64_t timestamp_ns; |
| 5247 | struct drm_plane *plane; | 5247 | struct drm_plane *plane; |
| 5248 | struct drm_plane_state *old_plane_state, *new_plane_state; | 5248 | struct drm_plane_state *old_plane_state, *new_plane_state; |
| @@ -5253,6 +5253,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, | |||
| 5253 | struct dm_crtc_state *dm_old_crtc_state = | 5253 | struct dm_crtc_state *dm_old_crtc_state = |
| 5254 | to_dm_crtc_state(drm_atomic_get_old_crtc_state(state, pcrtc)); | 5254 | to_dm_crtc_state(drm_atomic_get_old_crtc_state(state, pcrtc)); |
| 5255 | int planes_count = 0, vpos, hpos; | 5255 | int planes_count = 0, vpos, hpos; |
| 5256 | long r; | ||
| 5256 | unsigned long flags; | 5257 | unsigned long flags; |
| 5257 | struct amdgpu_bo *abo; | 5258 | struct amdgpu_bo *abo; |
| 5258 | uint64_t tiling_flags; | 5259 | uint64_t tiling_flags; |
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index ec2ca71e1323..c532e9c9e491 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | |||
| @@ -748,11 +748,11 @@ static void adv7511_mode_set(struct adv7511 *adv7511, | |||
| 748 | vsync_polarity = 1; | 748 | vsync_polarity = 1; |
| 749 | } | 749 | } |
| 750 | 750 | ||
| 751 | if (mode->vrefresh <= 24000) | 751 | if (drm_mode_vrefresh(mode) <= 24) |
| 752 | low_refresh_rate = ADV7511_LOW_REFRESH_RATE_24HZ; | 752 | low_refresh_rate = ADV7511_LOW_REFRESH_RATE_24HZ; |
| 753 | else if (mode->vrefresh <= 25000) | 753 | else if (drm_mode_vrefresh(mode) <= 25) |
| 754 | low_refresh_rate = ADV7511_LOW_REFRESH_RATE_25HZ; | 754 | low_refresh_rate = ADV7511_LOW_REFRESH_RATE_25HZ; |
| 755 | else if (mode->vrefresh <= 30000) | 755 | else if (drm_mode_vrefresh(mode) <= 30) |
| 756 | low_refresh_rate = ADV7511_LOW_REFRESH_RATE_30HZ; | 756 | low_refresh_rate = ADV7511_LOW_REFRESH_RATE_30HZ; |
| 757 | else | 757 | else |
| 758 | low_refresh_rate = ADV7511_LOW_REFRESH_RATE_NONE; | 758 | low_refresh_rate = ADV7511_LOW_REFRESH_RATE_NONE; |
diff --git a/drivers/gpu/drm/i915/gvt/debugfs.c b/drivers/gpu/drm/i915/gvt/debugfs.c index 2ec89bcb59f1..8a9606f91e68 100644 --- a/drivers/gpu/drm/i915/gvt/debugfs.c +++ b/drivers/gpu/drm/i915/gvt/debugfs.c | |||
| @@ -196,9 +196,9 @@ DEFINE_SIMPLE_ATTRIBUTE(vgpu_scan_nonprivbb_fops, | |||
| 196 | int intel_gvt_debugfs_add_vgpu(struct intel_vgpu *vgpu) | 196 | int intel_gvt_debugfs_add_vgpu(struct intel_vgpu *vgpu) |
| 197 | { | 197 | { |
| 198 | struct dentry *ent; | 198 | struct dentry *ent; |
| 199 | char name[10] = ""; | 199 | char name[16] = ""; |
| 200 | 200 | ||
| 201 | sprintf(name, "vgpu%d", vgpu->id); | 201 | snprintf(name, 16, "vgpu%d", vgpu->id); |
| 202 | vgpu->debugfs = debugfs_create_dir(name, vgpu->gvt->debugfs_root); | 202 | vgpu->debugfs = debugfs_create_dir(name, vgpu->gvt->debugfs_root); |
| 203 | if (!vgpu->debugfs) | 203 | if (!vgpu->debugfs) |
| 204 | return -ENOMEM; | 204 | return -ENOMEM; |
diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c b/drivers/gpu/drm/i915/gvt/dmabuf.c index 4e1e425189ba..41c8ebc60c63 100644 --- a/drivers/gpu/drm/i915/gvt/dmabuf.c +++ b/drivers/gpu/drm/i915/gvt/dmabuf.c | |||
| @@ -45,6 +45,7 @@ static int vgpu_gem_get_pages( | |||
| 45 | int i, ret; | 45 | int i, ret; |
| 46 | gen8_pte_t __iomem *gtt_entries; | 46 | gen8_pte_t __iomem *gtt_entries; |
| 47 | struct intel_vgpu_fb_info *fb_info; | 47 | struct intel_vgpu_fb_info *fb_info; |
| 48 | u32 page_num; | ||
| 48 | 49 | ||
| 49 | fb_info = (struct intel_vgpu_fb_info *)obj->gvt_info; | 50 | fb_info = (struct intel_vgpu_fb_info *)obj->gvt_info; |
| 50 | if (WARN_ON(!fb_info)) | 51 | if (WARN_ON(!fb_info)) |
| @@ -54,14 +55,15 @@ static int vgpu_gem_get_pages( | |||
| 54 | if (unlikely(!st)) | 55 | if (unlikely(!st)) |
| 55 | return -ENOMEM; | 56 | return -ENOMEM; |
| 56 | 57 | ||
| 57 | ret = sg_alloc_table(st, fb_info->size, GFP_KERNEL); | 58 | page_num = obj->base.size >> PAGE_SHIFT; |
| 59 | ret = sg_alloc_table(st, page_num, GFP_KERNEL); | ||
| 58 | if (ret) { | 60 | if (ret) { |
| 59 | kfree(st); | 61 | kfree(st); |
| 60 | return ret; | 62 | return ret; |
| 61 | } | 63 | } |
| 62 | gtt_entries = (gen8_pte_t __iomem *)dev_priv->ggtt.gsm + | 64 | gtt_entries = (gen8_pte_t __iomem *)dev_priv->ggtt.gsm + |
| 63 | (fb_info->start >> PAGE_SHIFT); | 65 | (fb_info->start >> PAGE_SHIFT); |
| 64 | for_each_sg(st->sgl, sg, fb_info->size, i) { | 66 | for_each_sg(st->sgl, sg, page_num, i) { |
| 65 | sg->offset = 0; | 67 | sg->offset = 0; |
| 66 | sg->length = PAGE_SIZE; | 68 | sg->length = PAGE_SIZE; |
| 67 | sg_dma_address(sg) = | 69 | sg_dma_address(sg) = |
| @@ -158,7 +160,7 @@ static struct drm_i915_gem_object *vgpu_create_gem(struct drm_device *dev, | |||
| 158 | return NULL; | 160 | return NULL; |
| 159 | 161 | ||
| 160 | drm_gem_private_object_init(dev, &obj->base, | 162 | drm_gem_private_object_init(dev, &obj->base, |
| 161 | info->size << PAGE_SHIFT); | 163 | roundup(info->size, PAGE_SIZE)); |
| 162 | i915_gem_object_init(obj, &intel_vgpu_gem_ops); | 164 | i915_gem_object_init(obj, &intel_vgpu_gem_ops); |
| 163 | 165 | ||
| 164 | obj->read_domains = I915_GEM_DOMAIN_GTT; | 166 | obj->read_domains = I915_GEM_DOMAIN_GTT; |
| @@ -206,11 +208,12 @@ static int vgpu_get_plane_info(struct drm_device *dev, | |||
| 206 | struct intel_vgpu_fb_info *info, | 208 | struct intel_vgpu_fb_info *info, |
| 207 | int plane_id) | 209 | int plane_id) |
| 208 | { | 210 | { |
| 209 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 210 | struct intel_vgpu_primary_plane_format p; | 211 | struct intel_vgpu_primary_plane_format p; |
| 211 | struct intel_vgpu_cursor_plane_format c; | 212 | struct intel_vgpu_cursor_plane_format c; |
| 212 | int ret, tile_height = 1; | 213 | int ret, tile_height = 1; |
| 213 | 214 | ||
| 215 | memset(info, 0, sizeof(*info)); | ||
| 216 | |||
| 214 | if (plane_id == DRM_PLANE_TYPE_PRIMARY) { | 217 | if (plane_id == DRM_PLANE_TYPE_PRIMARY) { |
| 215 | ret = intel_vgpu_decode_primary_plane(vgpu, &p); | 218 | ret = intel_vgpu_decode_primary_plane(vgpu, &p); |
| 216 | if (ret) | 219 | if (ret) |
| @@ -267,8 +270,7 @@ static int vgpu_get_plane_info(struct drm_device *dev, | |||
| 267 | return -EINVAL; | 270 | return -EINVAL; |
| 268 | } | 271 | } |
| 269 | 272 | ||
| 270 | info->size = (info->stride * roundup(info->height, tile_height) | 273 | info->size = info->stride * roundup(info->height, tile_height); |
| 271 | + PAGE_SIZE - 1) >> PAGE_SHIFT; | ||
| 272 | if (info->size == 0) { | 274 | if (info->size == 0) { |
| 273 | gvt_vgpu_err("fb size is zero\n"); | 275 | gvt_vgpu_err("fb size is zero\n"); |
| 274 | return -EINVAL; | 276 | return -EINVAL; |
| @@ -278,11 +280,6 @@ static int vgpu_get_plane_info(struct drm_device *dev, | |||
| 278 | gvt_vgpu_err("Not aligned fb address:0x%llx\n", info->start); | 280 | gvt_vgpu_err("Not aligned fb address:0x%llx\n", info->start); |
| 279 | return -EFAULT; | 281 | return -EFAULT; |
| 280 | } | 282 | } |
| 281 | if (((info->start >> PAGE_SHIFT) + info->size) > | ||
| 282 | ggtt_total_entries(&dev_priv->ggtt)) { | ||
| 283 | gvt_vgpu_err("Invalid GTT offset or size\n"); | ||
| 284 | return -EFAULT; | ||
| 285 | } | ||
| 286 | 283 | ||
| 287 | if (!intel_gvt_ggtt_validate_range(vgpu, info->start, info->size)) { | 284 | if (!intel_gvt_ggtt_validate_range(vgpu, info->start, info->size)) { |
| 288 | gvt_vgpu_err("invalid gma addr\n"); | 285 | gvt_vgpu_err("invalid gma addr\n"); |
diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index c2f7d20f6346..08c74e65836b 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c | |||
| @@ -811,7 +811,7 @@ static int reclaim_one_ppgtt_mm(struct intel_gvt *gvt); | |||
| 811 | 811 | ||
| 812 | /* Allocate shadow page table without guest page. */ | 812 | /* Allocate shadow page table without guest page. */ |
| 813 | static struct intel_vgpu_ppgtt_spt *ppgtt_alloc_spt( | 813 | static struct intel_vgpu_ppgtt_spt *ppgtt_alloc_spt( |
| 814 | struct intel_vgpu *vgpu, intel_gvt_gtt_type_t type) | 814 | struct intel_vgpu *vgpu, enum intel_gvt_gtt_type type) |
| 815 | { | 815 | { |
| 816 | struct device *kdev = &vgpu->gvt->dev_priv->drm.pdev->dev; | 816 | struct device *kdev = &vgpu->gvt->dev_priv->drm.pdev->dev; |
| 817 | struct intel_vgpu_ppgtt_spt *spt = NULL; | 817 | struct intel_vgpu_ppgtt_spt *spt = NULL; |
| @@ -861,7 +861,7 @@ err_free_spt: | |||
| 861 | 861 | ||
| 862 | /* Allocate shadow page table associated with specific gfn. */ | 862 | /* Allocate shadow page table associated with specific gfn. */ |
| 863 | static struct intel_vgpu_ppgtt_spt *ppgtt_alloc_spt_gfn( | 863 | static struct intel_vgpu_ppgtt_spt *ppgtt_alloc_spt_gfn( |
| 864 | struct intel_vgpu *vgpu, intel_gvt_gtt_type_t type, | 864 | struct intel_vgpu *vgpu, enum intel_gvt_gtt_type type, |
| 865 | unsigned long gfn, bool guest_pde_ips) | 865 | unsigned long gfn, bool guest_pde_ips) |
| 866 | { | 866 | { |
| 867 | struct intel_vgpu_ppgtt_spt *spt; | 867 | struct intel_vgpu_ppgtt_spt *spt; |
| @@ -936,7 +936,7 @@ static int ppgtt_invalidate_spt_by_shadow_entry(struct intel_vgpu *vgpu, | |||
| 936 | { | 936 | { |
| 937 | struct intel_gvt_gtt_pte_ops *ops = vgpu->gvt->gtt.pte_ops; | 937 | struct intel_gvt_gtt_pte_ops *ops = vgpu->gvt->gtt.pte_ops; |
| 938 | struct intel_vgpu_ppgtt_spt *s; | 938 | struct intel_vgpu_ppgtt_spt *s; |
| 939 | intel_gvt_gtt_type_t cur_pt_type; | 939 | enum intel_gvt_gtt_type cur_pt_type; |
| 940 | 940 | ||
| 941 | GEM_BUG_ON(!gtt_type_is_pt(get_next_pt_type(e->type))); | 941 | GEM_BUG_ON(!gtt_type_is_pt(get_next_pt_type(e->type))); |
| 942 | 942 | ||
| @@ -1076,6 +1076,9 @@ static struct intel_vgpu_ppgtt_spt *ppgtt_populate_spt_by_guest_entry( | |||
| 1076 | } else { | 1076 | } else { |
| 1077 | int type = get_next_pt_type(we->type); | 1077 | int type = get_next_pt_type(we->type); |
| 1078 | 1078 | ||
| 1079 | if (!gtt_type_is_pt(type)) | ||
| 1080 | goto err; | ||
| 1081 | |||
| 1079 | spt = ppgtt_alloc_spt_gfn(vgpu, type, ops->get_pfn(we), ips); | 1082 | spt = ppgtt_alloc_spt_gfn(vgpu, type, ops->get_pfn(we), ips); |
| 1080 | if (IS_ERR(spt)) { | 1083 | if (IS_ERR(spt)) { |
| 1081 | ret = PTR_ERR(spt); | 1084 | ret = PTR_ERR(spt); |
| @@ -1855,7 +1858,7 @@ static void vgpu_free_mm(struct intel_vgpu_mm *mm) | |||
| 1855 | * Zero on success, negative error code in pointer if failed. | 1858 | * Zero on success, negative error code in pointer if failed. |
| 1856 | */ | 1859 | */ |
| 1857 | struct intel_vgpu_mm *intel_vgpu_create_ppgtt_mm(struct intel_vgpu *vgpu, | 1860 | struct intel_vgpu_mm *intel_vgpu_create_ppgtt_mm(struct intel_vgpu *vgpu, |
| 1858 | intel_gvt_gtt_type_t root_entry_type, u64 pdps[]) | 1861 | enum intel_gvt_gtt_type root_entry_type, u64 pdps[]) |
| 1859 | { | 1862 | { |
| 1860 | struct intel_gvt *gvt = vgpu->gvt; | 1863 | struct intel_gvt *gvt = vgpu->gvt; |
| 1861 | struct intel_vgpu_mm *mm; | 1864 | struct intel_vgpu_mm *mm; |
| @@ -2309,7 +2312,7 @@ int intel_vgpu_emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, | |||
| 2309 | } | 2312 | } |
| 2310 | 2313 | ||
| 2311 | static int alloc_scratch_pages(struct intel_vgpu *vgpu, | 2314 | static int alloc_scratch_pages(struct intel_vgpu *vgpu, |
| 2312 | intel_gvt_gtt_type_t type) | 2315 | enum intel_gvt_gtt_type type) |
| 2313 | { | 2316 | { |
| 2314 | struct intel_vgpu_gtt *gtt = &vgpu->gtt; | 2317 | struct intel_vgpu_gtt *gtt = &vgpu->gtt; |
| 2315 | struct intel_gvt_gtt_pte_ops *ops = vgpu->gvt->gtt.pte_ops; | 2318 | struct intel_gvt_gtt_pte_ops *ops = vgpu->gvt->gtt.pte_ops; |
| @@ -2594,7 +2597,7 @@ struct intel_vgpu_mm *intel_vgpu_find_ppgtt_mm(struct intel_vgpu *vgpu, | |||
| 2594 | * Zero on success, negative error code if failed. | 2597 | * Zero on success, negative error code if failed. |
| 2595 | */ | 2598 | */ |
| 2596 | struct intel_vgpu_mm *intel_vgpu_get_ppgtt_mm(struct intel_vgpu *vgpu, | 2599 | struct intel_vgpu_mm *intel_vgpu_get_ppgtt_mm(struct intel_vgpu *vgpu, |
| 2597 | intel_gvt_gtt_type_t root_entry_type, u64 pdps[]) | 2600 | enum intel_gvt_gtt_type root_entry_type, u64 pdps[]) |
| 2598 | { | 2601 | { |
| 2599 | struct intel_vgpu_mm *mm; | 2602 | struct intel_vgpu_mm *mm; |
| 2600 | 2603 | ||
diff --git a/drivers/gpu/drm/i915/gvt/gtt.h b/drivers/gpu/drm/i915/gvt/gtt.h index 32c573aea494..42d0394f0de2 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.h +++ b/drivers/gpu/drm/i915/gvt/gtt.h | |||
| @@ -95,8 +95,8 @@ struct intel_gvt_gtt { | |||
| 95 | unsigned long scratch_mfn; | 95 | unsigned long scratch_mfn; |
| 96 | }; | 96 | }; |
| 97 | 97 | ||
| 98 | typedef enum { | 98 | enum intel_gvt_gtt_type { |
| 99 | GTT_TYPE_INVALID = -1, | 99 | GTT_TYPE_INVALID = 0, |
| 100 | 100 | ||
| 101 | GTT_TYPE_GGTT_PTE, | 101 | GTT_TYPE_GGTT_PTE, |
| 102 | 102 | ||
| @@ -124,7 +124,7 @@ typedef enum { | |||
| 124 | GTT_TYPE_PPGTT_PML4_PT, | 124 | GTT_TYPE_PPGTT_PML4_PT, |
| 125 | 125 | ||
| 126 | GTT_TYPE_MAX, | 126 | GTT_TYPE_MAX, |
| 127 | } intel_gvt_gtt_type_t; | 127 | }; |
| 128 | 128 | ||
| 129 | enum intel_gvt_mm_type { | 129 | enum intel_gvt_mm_type { |
| 130 | INTEL_GVT_MM_GGTT, | 130 | INTEL_GVT_MM_GGTT, |
| @@ -148,7 +148,7 @@ struct intel_vgpu_mm { | |||
| 148 | 148 | ||
| 149 | union { | 149 | union { |
| 150 | struct { | 150 | struct { |
| 151 | intel_gvt_gtt_type_t root_entry_type; | 151 | enum intel_gvt_gtt_type root_entry_type; |
| 152 | /* | 152 | /* |
| 153 | * The 4 PDPs in ring context. For 48bit addressing, | 153 | * The 4 PDPs in ring context. For 48bit addressing, |
| 154 | * only PDP0 is valid and point to PML4. For 32it | 154 | * only PDP0 is valid and point to PML4. For 32it |
| @@ -169,7 +169,7 @@ struct intel_vgpu_mm { | |||
| 169 | }; | 169 | }; |
| 170 | 170 | ||
| 171 | struct intel_vgpu_mm *intel_vgpu_create_ppgtt_mm(struct intel_vgpu *vgpu, | 171 | struct intel_vgpu_mm *intel_vgpu_create_ppgtt_mm(struct intel_vgpu *vgpu, |
| 172 | intel_gvt_gtt_type_t root_entry_type, u64 pdps[]); | 172 | enum intel_gvt_gtt_type root_entry_type, u64 pdps[]); |
| 173 | 173 | ||
| 174 | static inline void intel_vgpu_mm_get(struct intel_vgpu_mm *mm) | 174 | static inline void intel_vgpu_mm_get(struct intel_vgpu_mm *mm) |
| 175 | { | 175 | { |
| @@ -233,7 +233,7 @@ struct intel_vgpu_ppgtt_spt { | |||
| 233 | struct intel_vgpu *vgpu; | 233 | struct intel_vgpu *vgpu; |
| 234 | 234 | ||
| 235 | struct { | 235 | struct { |
| 236 | intel_gvt_gtt_type_t type; | 236 | enum intel_gvt_gtt_type type; |
| 237 | bool pde_ips; /* for 64KB PTEs */ | 237 | bool pde_ips; /* for 64KB PTEs */ |
| 238 | void *vaddr; | 238 | void *vaddr; |
| 239 | struct page *page; | 239 | struct page *page; |
| @@ -241,7 +241,7 @@ struct intel_vgpu_ppgtt_spt { | |||
| 241 | } shadow_page; | 241 | } shadow_page; |
| 242 | 242 | ||
| 243 | struct { | 243 | struct { |
| 244 | intel_gvt_gtt_type_t type; | 244 | enum intel_gvt_gtt_type type; |
| 245 | bool pde_ips; /* for 64KB PTEs */ | 245 | bool pde_ips; /* for 64KB PTEs */ |
| 246 | unsigned long gfn; | 246 | unsigned long gfn; |
| 247 | unsigned long write_cnt; | 247 | unsigned long write_cnt; |
| @@ -267,7 +267,7 @@ struct intel_vgpu_mm *intel_vgpu_find_ppgtt_mm(struct intel_vgpu *vgpu, | |||
| 267 | u64 pdps[]); | 267 | u64 pdps[]); |
| 268 | 268 | ||
| 269 | struct intel_vgpu_mm *intel_vgpu_get_ppgtt_mm(struct intel_vgpu *vgpu, | 269 | struct intel_vgpu_mm *intel_vgpu_get_ppgtt_mm(struct intel_vgpu *vgpu, |
| 270 | intel_gvt_gtt_type_t root_entry_type, u64 pdps[]); | 270 | enum intel_gvt_gtt_type root_entry_type, u64 pdps[]); |
| 271 | 271 | ||
| 272 | int intel_vgpu_put_ppgtt_mm(struct intel_vgpu *vgpu, u64 pdps[]); | 272 | int intel_vgpu_put_ppgtt_mm(struct intel_vgpu *vgpu, u64 pdps[]); |
| 273 | 273 | ||
diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index 18f01eeb2510..90673fca792f 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c | |||
| @@ -1206,7 +1206,7 @@ static int pvinfo_mmio_read(struct intel_vgpu *vgpu, unsigned int offset, | |||
| 1206 | 1206 | ||
| 1207 | static int handle_g2v_notification(struct intel_vgpu *vgpu, int notification) | 1207 | static int handle_g2v_notification(struct intel_vgpu *vgpu, int notification) |
| 1208 | { | 1208 | { |
| 1209 | intel_gvt_gtt_type_t root_entry_type = GTT_TYPE_PPGTT_ROOT_L4_ENTRY; | 1209 | enum intel_gvt_gtt_type root_entry_type = GTT_TYPE_PPGTT_ROOT_L4_ENTRY; |
| 1210 | struct intel_vgpu_mm *mm; | 1210 | struct intel_vgpu_mm *mm; |
| 1211 | u64 *pdps; | 1211 | u64 *pdps; |
| 1212 | 1212 | ||
| @@ -3303,7 +3303,7 @@ void intel_gvt_clean_mmio_info(struct intel_gvt *gvt) | |||
| 3303 | /* Special MMIO blocks. */ | 3303 | /* Special MMIO blocks. */ |
| 3304 | static struct gvt_mmio_block mmio_blocks[] = { | 3304 | static struct gvt_mmio_block mmio_blocks[] = { |
| 3305 | {D_SKL_PLUS, _MMIO(CSR_MMIO_START_RANGE), 0x3000, NULL, NULL}, | 3305 | {D_SKL_PLUS, _MMIO(CSR_MMIO_START_RANGE), 0x3000, NULL, NULL}, |
| 3306 | {D_ALL, MCHBAR_MIRROR_REG_BASE, 0x4000, NULL, NULL}, | 3306 | {D_ALL, _MMIO(MCHBAR_MIRROR_BASE_SNB), 0x40000, NULL, NULL}, |
| 3307 | {D_ALL, _MMIO(VGT_PVINFO_PAGE), VGT_PVINFO_SIZE, | 3307 | {D_ALL, _MMIO(VGT_PVINFO_PAGE), VGT_PVINFO_SIZE, |
| 3308 | pvinfo_mmio_read, pvinfo_mmio_write}, | 3308 | pvinfo_mmio_read, pvinfo_mmio_write}, |
| 3309 | {D_ALL, LGC_PALETTE(PIPE_A, 0), 1024, NULL, NULL}, | 3309 | {D_ALL, LGC_PALETTE(PIPE_A, 0), 1024, NULL, NULL}, |
diff --git a/drivers/gpu/drm/i915/gvt/mmio_context.c b/drivers/gpu/drm/i915/gvt/mmio_context.c index e7e14c842be4..edf6d646eb25 100644 --- a/drivers/gpu/drm/i915/gvt/mmio_context.c +++ b/drivers/gpu/drm/i915/gvt/mmio_context.c | |||
| @@ -132,6 +132,7 @@ static struct engine_mmio gen9_engine_mmio_list[] __cacheline_aligned = { | |||
| 132 | 132 | ||
| 133 | {RCS0, GEN9_GAMT_ECO_REG_RW_IA, 0x0, false}, /* 0x4ab0 */ | 133 | {RCS0, GEN9_GAMT_ECO_REG_RW_IA, 0x0, false}, /* 0x4ab0 */ |
| 134 | {RCS0, GEN9_CSFE_CHICKEN1_RCS, 0xffff, false}, /* 0x20d4 */ | 134 | {RCS0, GEN9_CSFE_CHICKEN1_RCS, 0xffff, false}, /* 0x20d4 */ |
| 135 | {RCS0, _MMIO(0x20D8), 0xffff, true}, /* 0x20d8 */ | ||
| 135 | 136 | ||
| 136 | {RCS0, GEN8_GARBCNTL, 0x0, false}, /* 0xb004 */ | 137 | {RCS0, GEN8_GARBCNTL, 0x0, false}, /* 0xb004 */ |
| 137 | {RCS0, GEN7_FF_THREAD_MODE, 0x0, false}, /* 0x20a0 */ | 138 | {RCS0, GEN7_FF_THREAD_MODE, 0x0, false}, /* 0x20a0 */ |
diff --git a/drivers/gpu/drm/i915/gvt/reg.h b/drivers/gpu/drm/i915/gvt/reg.h index 3de5b643b266..33aaa14bfdde 100644 --- a/drivers/gpu/drm/i915/gvt/reg.h +++ b/drivers/gpu/drm/i915/gvt/reg.h | |||
| @@ -126,7 +126,4 @@ | |||
| 126 | #define RING_GFX_MODE(base) _MMIO((base) + 0x29c) | 126 | #define RING_GFX_MODE(base) _MMIO((base) + 0x29c) |
| 127 | #define VF_GUARDBAND _MMIO(0x83a4) | 127 | #define VF_GUARDBAND _MMIO(0x83a4) |
| 128 | 128 | ||
| 129 | /* define the effective range of MCHBAR register on Sandybridge+ */ | ||
| 130 | #define MCHBAR_MIRROR_REG_BASE _MMIO(MCHBAR_MIRROR_BASE_SNB + 0x4000) | ||
| 131 | |||
| 132 | #endif | 129 | #endif |
diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c index 8998fa5ab198..7c99bbc3e2b8 100644 --- a/drivers/gpu/drm/i915/gvt/scheduler.c +++ b/drivers/gpu/drm/i915/gvt/scheduler.c | |||
| @@ -1343,7 +1343,7 @@ static int prepare_mm(struct intel_vgpu_workload *workload) | |||
| 1343 | struct execlist_ctx_descriptor_format *desc = &workload->ctx_desc; | 1343 | struct execlist_ctx_descriptor_format *desc = &workload->ctx_desc; |
| 1344 | struct intel_vgpu_mm *mm; | 1344 | struct intel_vgpu_mm *mm; |
| 1345 | struct intel_vgpu *vgpu = workload->vgpu; | 1345 | struct intel_vgpu *vgpu = workload->vgpu; |
| 1346 | intel_gvt_gtt_type_t root_entry_type; | 1346 | enum intel_gvt_gtt_type root_entry_type; |
| 1347 | u64 pdps[GVT_RING_CTX_NR_PDPS]; | 1347 | u64 pdps[GVT_RING_CTX_NR_PDPS]; |
| 1348 | 1348 | ||
| 1349 | switch (desc->addressing_mode) { | 1349 | switch (desc->addressing_mode) { |
diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c index b836721d3b13..f6c78c0fa74b 100644 --- a/drivers/gpu/drm/i915/i915_request.c +++ b/drivers/gpu/drm/i915/i915_request.c | |||
| @@ -425,6 +425,26 @@ void __i915_request_submit(struct i915_request *request) | |||
| 425 | if (i915_gem_context_is_banned(request->gem_context)) | 425 | if (i915_gem_context_is_banned(request->gem_context)) |
| 426 | i915_request_skip(request, -EIO); | 426 | i915_request_skip(request, -EIO); |
| 427 | 427 | ||
| 428 | /* | ||
| 429 | * Are we using semaphores when the gpu is already saturated? | ||
| 430 | * | ||
| 431 | * Using semaphores incurs a cost in having the GPU poll a | ||
| 432 | * memory location, busywaiting for it to change. The continual | ||
| 433 | * memory reads can have a noticeable impact on the rest of the | ||
| 434 | * system with the extra bus traffic, stalling the cpu as it too | ||
| 435 | * tries to access memory across the bus (perf stat -e bus-cycles). | ||
| 436 | * | ||
| 437 | * If we installed a semaphore on this request and we only submit | ||
| 438 | * the request after the signaler completed, that indicates the | ||
| 439 | * system is overloaded and using semaphores at this time only | ||
| 440 | * increases the amount of work we are doing. If so, we disable | ||
| 441 | * further use of semaphores until we are idle again, whence we | ||
| 442 | * optimistically try again. | ||
| 443 | */ | ||
| 444 | if (request->sched.semaphores && | ||
| 445 | i915_sw_fence_signaled(&request->semaphore)) | ||
| 446 | request->hw_context->saturated |= request->sched.semaphores; | ||
| 447 | |||
| 428 | /* We may be recursing from the signal callback of another i915 fence */ | 448 | /* We may be recursing from the signal callback of another i915 fence */ |
| 429 | spin_lock_nested(&request->lock, SINGLE_DEPTH_NESTING); | 449 | spin_lock_nested(&request->lock, SINGLE_DEPTH_NESTING); |
| 430 | 450 | ||
| @@ -432,6 +452,7 @@ void __i915_request_submit(struct i915_request *request) | |||
| 432 | set_bit(I915_FENCE_FLAG_ACTIVE, &request->fence.flags); | 452 | set_bit(I915_FENCE_FLAG_ACTIVE, &request->fence.flags); |
| 433 | 453 | ||
| 434 | if (test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &request->fence.flags) && | 454 | if (test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &request->fence.flags) && |
| 455 | !test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &request->fence.flags) && | ||
| 435 | !i915_request_enable_breadcrumb(request)) | 456 | !i915_request_enable_breadcrumb(request)) |
| 436 | intel_engine_queue_breadcrumbs(engine); | 457 | intel_engine_queue_breadcrumbs(engine); |
| 437 | 458 | ||
| @@ -799,6 +820,39 @@ err_unreserve: | |||
| 799 | } | 820 | } |
| 800 | 821 | ||
| 801 | static int | 822 | static int |
| 823 | i915_request_await_start(struct i915_request *rq, struct i915_request *signal) | ||
| 824 | { | ||
| 825 | if (list_is_first(&signal->ring_link, &signal->ring->request_list)) | ||
| 826 | return 0; | ||
| 827 | |||
| 828 | signal = list_prev_entry(signal, ring_link); | ||
| 829 | if (i915_timeline_sync_is_later(rq->timeline, &signal->fence)) | ||
| 830 | return 0; | ||
| 831 | |||
| 832 | return i915_sw_fence_await_dma_fence(&rq->submit, | ||
| 833 | &signal->fence, 0, | ||
| 834 | I915_FENCE_GFP); | ||
| 835 | } | ||
| 836 | |||
| 837 | static intel_engine_mask_t | ||
| 838 | already_busywaiting(struct i915_request *rq) | ||
| 839 | { | ||
| 840 | /* | ||
| 841 | * Polling a semaphore causes bus traffic, delaying other users of | ||
| 842 | * both the GPU and CPU. We want to limit the impact on others, | ||
| 843 | * while taking advantage of early submission to reduce GPU | ||
| 844 | * latency. Therefore we restrict ourselves to not using more | ||
| 845 | * than one semaphore from each source, and not using a semaphore | ||
| 846 | * if we have detected the engine is saturated (i.e. would not be | ||
| 847 | * submitted early and cause bus traffic reading an already passed | ||
| 848 | * semaphore). | ||
| 849 | * | ||
| 850 | * See the are-we-too-late? check in __i915_request_submit(). | ||
| 851 | */ | ||
| 852 | return rq->sched.semaphores | rq->hw_context->saturated; | ||
| 853 | } | ||
| 854 | |||
| 855 | static int | ||
| 802 | emit_semaphore_wait(struct i915_request *to, | 856 | emit_semaphore_wait(struct i915_request *to, |
| 803 | struct i915_request *from, | 857 | struct i915_request *from, |
| 804 | gfp_t gfp) | 858 | gfp_t gfp) |
| @@ -811,11 +865,15 @@ emit_semaphore_wait(struct i915_request *to, | |||
| 811 | GEM_BUG_ON(INTEL_GEN(to->i915) < 8); | 865 | GEM_BUG_ON(INTEL_GEN(to->i915) < 8); |
| 812 | 866 | ||
| 813 | /* Just emit the first semaphore we see as request space is limited. */ | 867 | /* Just emit the first semaphore we see as request space is limited. */ |
| 814 | if (to->sched.semaphores & from->engine->mask) | 868 | if (already_busywaiting(to) & from->engine->mask) |
| 815 | return i915_sw_fence_await_dma_fence(&to->submit, | 869 | return i915_sw_fence_await_dma_fence(&to->submit, |
| 816 | &from->fence, 0, | 870 | &from->fence, 0, |
| 817 | I915_FENCE_GFP); | 871 | I915_FENCE_GFP); |
| 818 | 872 | ||
| 873 | err = i915_request_await_start(to, from); | ||
| 874 | if (err < 0) | ||
| 875 | return err; | ||
| 876 | |||
| 819 | err = i915_sw_fence_await_dma_fence(&to->semaphore, | 877 | err = i915_sw_fence_await_dma_fence(&to->semaphore, |
| 820 | &from->fence, 0, | 878 | &from->fence, 0, |
| 821 | I915_FENCE_GFP); | 879 | I915_FENCE_GFP); |
diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c b/drivers/gpu/drm/i915/intel_breadcrumbs.c index 3cbffd400b1b..832cb6b1e9bd 100644 --- a/drivers/gpu/drm/i915/intel_breadcrumbs.c +++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | */ | 23 | */ |
| 24 | 24 | ||
| 25 | #include <linux/kthread.h> | 25 | #include <linux/kthread.h> |
| 26 | #include <trace/events/dma_fence.h> | ||
| 26 | #include <uapi/linux/sched/types.h> | 27 | #include <uapi/linux/sched/types.h> |
| 27 | 28 | ||
| 28 | #include "i915_drv.h" | 29 | #include "i915_drv.h" |
| @@ -80,9 +81,39 @@ static inline bool __request_completed(const struct i915_request *rq) | |||
| 80 | return i915_seqno_passed(__hwsp_seqno(rq), rq->fence.seqno); | 81 | return i915_seqno_passed(__hwsp_seqno(rq), rq->fence.seqno); |
| 81 | } | 82 | } |
| 82 | 83 | ||
| 84 | static bool | ||
| 85 | __dma_fence_signal(struct dma_fence *fence) | ||
| 86 | { | ||
| 87 | return !test_and_set_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags); | ||
| 88 | } | ||
| 89 | |||
| 90 | static void | ||
| 91 | __dma_fence_signal__timestamp(struct dma_fence *fence, ktime_t timestamp) | ||
| 92 | { | ||
| 93 | fence->timestamp = timestamp; | ||
| 94 | set_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT, &fence->flags); | ||
| 95 | trace_dma_fence_signaled(fence); | ||
| 96 | } | ||
| 97 | |||
| 98 | static void | ||
| 99 | __dma_fence_signal__notify(struct dma_fence *fence) | ||
| 100 | { | ||
| 101 | struct dma_fence_cb *cur, *tmp; | ||
| 102 | |||
| 103 | lockdep_assert_held(fence->lock); | ||
| 104 | lockdep_assert_irqs_disabled(); | ||
| 105 | |||
| 106 | list_for_each_entry_safe(cur, tmp, &fence->cb_list, node) { | ||
| 107 | INIT_LIST_HEAD(&cur->node); | ||
| 108 | cur->func(fence, cur); | ||
| 109 | } | ||
| 110 | INIT_LIST_HEAD(&fence->cb_list); | ||
| 111 | } | ||
| 112 | |||
| 83 | void intel_engine_breadcrumbs_irq(struct intel_engine_cs *engine) | 113 | void intel_engine_breadcrumbs_irq(struct intel_engine_cs *engine) |
| 84 | { | 114 | { |
| 85 | struct intel_breadcrumbs *b = &engine->breadcrumbs; | 115 | struct intel_breadcrumbs *b = &engine->breadcrumbs; |
| 116 | const ktime_t timestamp = ktime_get(); | ||
| 86 | struct intel_context *ce, *cn; | 117 | struct intel_context *ce, *cn; |
| 87 | struct list_head *pos, *next; | 118 | struct list_head *pos, *next; |
| 88 | LIST_HEAD(signal); | 119 | LIST_HEAD(signal); |
| @@ -104,6 +135,10 @@ void intel_engine_breadcrumbs_irq(struct intel_engine_cs *engine) | |||
| 104 | 135 | ||
| 105 | GEM_BUG_ON(!test_bit(I915_FENCE_FLAG_SIGNAL, | 136 | GEM_BUG_ON(!test_bit(I915_FENCE_FLAG_SIGNAL, |
| 106 | &rq->fence.flags)); | 137 | &rq->fence.flags)); |
| 138 | clear_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags); | ||
| 139 | |||
| 140 | if (!__dma_fence_signal(&rq->fence)) | ||
| 141 | continue; | ||
| 107 | 142 | ||
| 108 | /* | 143 | /* |
| 109 | * Queue for execution after dropping the signaling | 144 | * Queue for execution after dropping the signaling |
| @@ -111,14 +146,6 @@ void intel_engine_breadcrumbs_irq(struct intel_engine_cs *engine) | |||
| 111 | * more signalers to the same context or engine. | 146 | * more signalers to the same context or engine. |
| 112 | */ | 147 | */ |
| 113 | i915_request_get(rq); | 148 | i915_request_get(rq); |
| 114 | |||
| 115 | /* | ||
| 116 | * We may race with direct invocation of | ||
| 117 | * dma_fence_signal(), e.g. i915_request_retire(), | ||
| 118 | * so we need to acquire our reference to the request | ||
| 119 | * before we cancel the breadcrumb. | ||
| 120 | */ | ||
| 121 | clear_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags); | ||
| 122 | list_add_tail(&rq->signal_link, &signal); | 149 | list_add_tail(&rq->signal_link, &signal); |
| 123 | } | 150 | } |
| 124 | 151 | ||
| @@ -141,7 +168,12 @@ void intel_engine_breadcrumbs_irq(struct intel_engine_cs *engine) | |||
| 141 | struct i915_request *rq = | 168 | struct i915_request *rq = |
| 142 | list_entry(pos, typeof(*rq), signal_link); | 169 | list_entry(pos, typeof(*rq), signal_link); |
| 143 | 170 | ||
| 144 | dma_fence_signal(&rq->fence); | 171 | __dma_fence_signal__timestamp(&rq->fence, timestamp); |
| 172 | |||
| 173 | spin_lock(&rq->lock); | ||
| 174 | __dma_fence_signal__notify(&rq->fence); | ||
| 175 | spin_unlock(&rq->lock); | ||
| 176 | |||
| 145 | i915_request_put(rq); | 177 | i915_request_put(rq); |
| 146 | } | 178 | } |
| 147 | } | 179 | } |
| @@ -243,19 +275,17 @@ void intel_engine_fini_breadcrumbs(struct intel_engine_cs *engine) | |||
| 243 | 275 | ||
| 244 | bool i915_request_enable_breadcrumb(struct i915_request *rq) | 276 | bool i915_request_enable_breadcrumb(struct i915_request *rq) |
| 245 | { | 277 | { |
| 246 | struct intel_breadcrumbs *b = &rq->engine->breadcrumbs; | 278 | lockdep_assert_held(&rq->lock); |
| 247 | 279 | lockdep_assert_irqs_disabled(); | |
| 248 | GEM_BUG_ON(test_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags)); | ||
| 249 | 280 | ||
| 250 | if (!test_bit(I915_FENCE_FLAG_ACTIVE, &rq->fence.flags)) | 281 | if (test_bit(I915_FENCE_FLAG_ACTIVE, &rq->fence.flags)) { |
| 251 | return true; | 282 | struct intel_breadcrumbs *b = &rq->engine->breadcrumbs; |
| 252 | |||
| 253 | spin_lock(&b->irq_lock); | ||
| 254 | if (test_bit(I915_FENCE_FLAG_ACTIVE, &rq->fence.flags) && | ||
| 255 | !__request_completed(rq)) { | ||
| 256 | struct intel_context *ce = rq->hw_context; | 283 | struct intel_context *ce = rq->hw_context; |
| 257 | struct list_head *pos; | 284 | struct list_head *pos; |
| 258 | 285 | ||
| 286 | spin_lock(&b->irq_lock); | ||
| 287 | GEM_BUG_ON(test_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags)); | ||
| 288 | |||
| 259 | __intel_breadcrumbs_arm_irq(b); | 289 | __intel_breadcrumbs_arm_irq(b); |
| 260 | 290 | ||
| 261 | /* | 291 | /* |
| @@ -284,8 +314,8 @@ bool i915_request_enable_breadcrumb(struct i915_request *rq) | |||
| 284 | list_move_tail(&ce->signal_link, &b->signalers); | 314 | list_move_tail(&ce->signal_link, &b->signalers); |
| 285 | 315 | ||
| 286 | set_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags); | 316 | set_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags); |
| 317 | spin_unlock(&b->irq_lock); | ||
| 287 | } | 318 | } |
| 288 | spin_unlock(&b->irq_lock); | ||
| 289 | 319 | ||
| 290 | return !__request_completed(rq); | 320 | return !__request_completed(rq); |
| 291 | } | 321 | } |
| @@ -294,9 +324,15 @@ void i915_request_cancel_breadcrumb(struct i915_request *rq) | |||
| 294 | { | 324 | { |
| 295 | struct intel_breadcrumbs *b = &rq->engine->breadcrumbs; | 325 | struct intel_breadcrumbs *b = &rq->engine->breadcrumbs; |
| 296 | 326 | ||
| 297 | if (!test_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags)) | 327 | lockdep_assert_held(&rq->lock); |
| 298 | return; | 328 | lockdep_assert_irqs_disabled(); |
| 299 | 329 | ||
| 330 | /* | ||
| 331 | * We must wait for b->irq_lock so that we know the interrupt handler | ||
| 332 | * has released its reference to the intel_context and has completed | ||
| 333 | * the DMA_FENCE_FLAG_SIGNALED_BIT/I915_FENCE_FLAG_SIGNAL dance (if | ||
| 334 | * required). | ||
| 335 | */ | ||
| 300 | spin_lock(&b->irq_lock); | 336 | spin_lock(&b->irq_lock); |
| 301 | if (test_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags)) { | 337 | if (test_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags)) { |
| 302 | struct intel_context *ce = rq->hw_context; | 338 | struct intel_context *ce = rq->hw_context; |
diff --git a/drivers/gpu/drm/i915/intel_context.c b/drivers/gpu/drm/i915/intel_context.c index 8931e0fee873..924cc556223a 100644 --- a/drivers/gpu/drm/i915/intel_context.c +++ b/drivers/gpu/drm/i915/intel_context.c | |||
| @@ -230,6 +230,7 @@ intel_context_init(struct intel_context *ce, | |||
| 230 | ce->gem_context = ctx; | 230 | ce->gem_context = ctx; |
| 231 | ce->engine = engine; | 231 | ce->engine = engine; |
| 232 | ce->ops = engine->cops; | 232 | ce->ops = engine->cops; |
| 233 | ce->saturated = 0; | ||
| 233 | 234 | ||
| 234 | INIT_LIST_HEAD(&ce->signal_link); | 235 | INIT_LIST_HEAD(&ce->signal_link); |
| 235 | INIT_LIST_HEAD(&ce->signals); | 236 | INIT_LIST_HEAD(&ce->signals); |
diff --git a/drivers/gpu/drm/i915/intel_context_types.h b/drivers/gpu/drm/i915/intel_context_types.h index 68b4ca1611e0..339c7437fe82 100644 --- a/drivers/gpu/drm/i915/intel_context_types.h +++ b/drivers/gpu/drm/i915/intel_context_types.h | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <linux/types.h> | 14 | #include <linux/types.h> |
| 15 | 15 | ||
| 16 | #include "i915_active_types.h" | 16 | #include "i915_active_types.h" |
| 17 | #include "intel_engine_types.h" | ||
| 17 | 18 | ||
| 18 | struct i915_gem_context; | 19 | struct i915_gem_context; |
| 19 | struct i915_vma; | 20 | struct i915_vma; |
| @@ -58,6 +59,8 @@ struct intel_context { | |||
| 58 | atomic_t pin_count; | 59 | atomic_t pin_count; |
| 59 | struct mutex pin_mutex; /* guards pinning and associated on-gpuing */ | 60 | struct mutex pin_mutex; /* guards pinning and associated on-gpuing */ |
| 60 | 61 | ||
| 62 | intel_engine_mask_t saturated; /* submitting semaphores too late? */ | ||
| 63 | |||
| 61 | /** | 64 | /** |
| 62 | * active_tracker: Active tracker for the external rq activity | 65 | * active_tracker: Active tracker for the external rq activity |
| 63 | * on this intel_context object. | 66 | * on this intel_context object. |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3bd40a4a6739..5098228f1302 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -12082,6 +12082,7 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv, | |||
| 12082 | struct intel_crtc_state *pipe_config, | 12082 | struct intel_crtc_state *pipe_config, |
| 12083 | bool adjust) | 12083 | bool adjust) |
| 12084 | { | 12084 | { |
| 12085 | struct intel_crtc *crtc = to_intel_crtc(current_config->base.crtc); | ||
| 12085 | bool ret = true; | 12086 | bool ret = true; |
| 12086 | bool fixup_inherited = adjust && | 12087 | bool fixup_inherited = adjust && |
| 12087 | (current_config->base.mode.private_flags & I915_MODE_FLAG_INHERITED) && | 12088 | (current_config->base.mode.private_flags & I915_MODE_FLAG_INHERITED) && |
| @@ -12303,6 +12304,14 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv, | |||
| 12303 | PIPE_CONF_CHECK_X(gmch_pfit.pgm_ratios); | 12304 | PIPE_CONF_CHECK_X(gmch_pfit.pgm_ratios); |
| 12304 | PIPE_CONF_CHECK_X(gmch_pfit.lvds_border_bits); | 12305 | PIPE_CONF_CHECK_X(gmch_pfit.lvds_border_bits); |
| 12305 | 12306 | ||
| 12307 | /* | ||
| 12308 | * Changing the EDP transcoder input mux | ||
| 12309 | * (A_ONOFF vs. A_ON) requires a full modeset. | ||
| 12310 | */ | ||
| 12311 | if (IS_HASWELL(dev_priv) && crtc->pipe == PIPE_A && | ||
| 12312 | current_config->cpu_transcoder == TRANSCODER_EDP) | ||
| 12313 | PIPE_CONF_CHECK_BOOL(pch_pfit.enabled); | ||
| 12314 | |||
| 12306 | if (!adjust) { | 12315 | if (!adjust) { |
| 12307 | PIPE_CONF_CHECK_I(pipe_src_w); | 12316 | PIPE_CONF_CHECK_I(pipe_src_w); |
| 12308 | PIPE_CONF_CHECK_I(pipe_src_h); | 12317 | PIPE_CONF_CHECK_I(pipe_src_h); |
diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index c805a0966395..5679f2fffb7c 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c | |||
| @@ -1280,6 +1280,10 @@ static int intel_sanitize_fbc_option(struct drm_i915_private *dev_priv) | |||
| 1280 | if (!HAS_FBC(dev_priv)) | 1280 | if (!HAS_FBC(dev_priv)) |
| 1281 | return 0; | 1281 | return 0; |
| 1282 | 1282 | ||
| 1283 | /* https://bugs.freedesktop.org/show_bug.cgi?id=108085 */ | ||
| 1284 | if (IS_GEMINILAKE(dev_priv)) | ||
| 1285 | return 0; | ||
| 1286 | |||
| 1283 | if (IS_BROADWELL(dev_priv) || INTEL_GEN(dev_priv) >= 9) | 1287 | if (IS_BROADWELL(dev_priv) || INTEL_GEN(dev_priv) >= 9) |
| 1284 | return 1; | 1288 | return 1; |
| 1285 | 1289 | ||
diff --git a/drivers/gpu/drm/i915/intel_guc_submission.c b/drivers/gpu/drm/i915/intel_guc_submission.c index 37f60cb8e9e1..46cd0e70aecb 100644 --- a/drivers/gpu/drm/i915/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/intel_guc_submission.c | |||
| @@ -23,7 +23,6 @@ | |||
| 23 | */ | 23 | */ |
| 24 | 24 | ||
| 25 | #include <linux/circ_buf.h> | 25 | #include <linux/circ_buf.h> |
| 26 | #include <trace/events/dma_fence.h> | ||
| 27 | 26 | ||
| 28 | #include "intel_guc_submission.h" | 27 | #include "intel_guc_submission.h" |
| 29 | #include "intel_lrc_reg.h" | 28 | #include "intel_lrc_reg.h" |
diff --git a/drivers/gpu/drm/i915/intel_pipe_crc.c b/drivers/gpu/drm/i915/intel_pipe_crc.c index e94b5b1bc1b7..e7c7be4911c1 100644 --- a/drivers/gpu/drm/i915/intel_pipe_crc.c +++ b/drivers/gpu/drm/i915/intel_pipe_crc.c | |||
| @@ -311,10 +311,17 @@ retry: | |||
| 311 | pipe_config->base.mode_changed = pipe_config->has_psr; | 311 | pipe_config->base.mode_changed = pipe_config->has_psr; |
| 312 | pipe_config->crc_enabled = enable; | 312 | pipe_config->crc_enabled = enable; |
| 313 | 313 | ||
| 314 | if (IS_HASWELL(dev_priv) && crtc->pipe == PIPE_A) { | 314 | if (IS_HASWELL(dev_priv) && |
| 315 | pipe_config->base.active && crtc->pipe == PIPE_A && | ||
| 316 | pipe_config->cpu_transcoder == TRANSCODER_EDP) { | ||
| 317 | bool old_need_power_well = pipe_config->pch_pfit.enabled || | ||
| 318 | pipe_config->pch_pfit.force_thru; | ||
| 319 | bool new_need_power_well = pipe_config->pch_pfit.enabled || | ||
| 320 | enable; | ||
| 321 | |||
| 315 | pipe_config->pch_pfit.force_thru = enable; | 322 | pipe_config->pch_pfit.force_thru = enable; |
| 316 | if (pipe_config->cpu_transcoder == TRANSCODER_EDP && | 323 | |
| 317 | pipe_config->pch_pfit.enabled != enable) | 324 | if (old_need_power_well != new_need_power_well) |
| 318 | pipe_config->base.connectors_changed = true; | 325 | pipe_config->base.connectors_changed = true; |
| 319 | } | 326 | } |
| 320 | 327 | ||
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index 9155dafae2a9..38e2cfa9cec7 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c | |||
| @@ -747,7 +747,7 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu) | |||
| 747 | * will make sure that the refcounting is correct in case we need to | 747 | * will make sure that the refcounting is correct in case we need to |
| 748 | * bring down the GX after a GMU failure | 748 | * bring down the GX after a GMU failure |
| 749 | */ | 749 | */ |
| 750 | if (!IS_ERR(gmu->gxpd)) | 750 | if (!IS_ERR_OR_NULL(gmu->gxpd)) |
| 751 | pm_runtime_get(gmu->gxpd); | 751 | pm_runtime_get(gmu->gxpd); |
| 752 | 752 | ||
| 753 | out: | 753 | out: |
| @@ -863,7 +863,7 @@ int a6xx_gmu_stop(struct a6xx_gpu *a6xx_gpu) | |||
| 863 | * domain. Usually the GMU does this but only if the shutdown sequence | 863 | * domain. Usually the GMU does this but only if the shutdown sequence |
| 864 | * was successful | 864 | * was successful |
| 865 | */ | 865 | */ |
| 866 | if (!IS_ERR(gmu->gxpd)) | 866 | if (!IS_ERR_OR_NULL(gmu->gxpd)) |
| 867 | pm_runtime_put_sync(gmu->gxpd); | 867 | pm_runtime_put_sync(gmu->gxpd); |
| 868 | 868 | ||
| 869 | clk_bulk_disable_unprepare(gmu->nr_clocks, gmu->clocks); | 869 | clk_bulk_disable_unprepare(gmu->nr_clocks, gmu->clocks); |
| @@ -1234,7 +1234,7 @@ void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu) | |||
| 1234 | 1234 | ||
| 1235 | pm_runtime_disable(gmu->dev); | 1235 | pm_runtime_disable(gmu->dev); |
| 1236 | 1236 | ||
| 1237 | if (!IS_ERR(gmu->gxpd)) { | 1237 | if (!IS_ERR_OR_NULL(gmu->gxpd)) { |
| 1238 | pm_runtime_disable(gmu->gxpd); | 1238 | pm_runtime_disable(gmu->gxpd); |
| 1239 | dev_pm_domain_detach(gmu->gxpd, false); | 1239 | dev_pm_domain_detach(gmu->gxpd, false); |
| 1240 | } | 1240 | } |
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c index 018df2c3b7ed..45a5bc6ede5d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c | |||
| @@ -15,7 +15,6 @@ | |||
| 15 | #include "dpu_hwio.h" | 15 | #include "dpu_hwio.h" |
| 16 | #include "dpu_hw_lm.h" | 16 | #include "dpu_hw_lm.h" |
| 17 | #include "dpu_hw_mdss.h" | 17 | #include "dpu_hw_mdss.h" |
| 18 | #include "dpu_kms.h" | ||
| 19 | 18 | ||
| 20 | #define LM_OP_MODE 0x00 | 19 | #define LM_OP_MODE 0x00 |
| 21 | #define LM_OUT_SIZE 0x04 | 20 | #define LM_OUT_SIZE 0x04 |
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index da1f727d7495..ce1a555e1f31 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | |||
| @@ -780,7 +780,6 @@ static int dpu_plane_prepare_fb(struct drm_plane *plane, | |||
| 780 | struct dpu_plane_state *pstate = to_dpu_plane_state(new_state); | 780 | struct dpu_plane_state *pstate = to_dpu_plane_state(new_state); |
| 781 | struct dpu_hw_fmt_layout layout; | 781 | struct dpu_hw_fmt_layout layout; |
| 782 | struct drm_gem_object *obj; | 782 | struct drm_gem_object *obj; |
| 783 | struct msm_gem_object *msm_obj; | ||
| 784 | struct dma_fence *fence; | 783 | struct dma_fence *fence; |
| 785 | struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base); | 784 | struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base); |
| 786 | int ret; | 785 | int ret; |
| @@ -799,8 +798,7 @@ static int dpu_plane_prepare_fb(struct drm_plane *plane, | |||
| 799 | * implicit fence and fb prepare by hand here. | 798 | * implicit fence and fb prepare by hand here. |
| 800 | */ | 799 | */ |
| 801 | obj = msm_framebuffer_bo(new_state->fb, 0); | 800 | obj = msm_framebuffer_bo(new_state->fb, 0); |
| 802 | msm_obj = to_msm_bo(obj); | 801 | fence = reservation_object_get_excl_rcu(obj->resv); |
| 803 | fence = reservation_object_get_excl_rcu(msm_obj->resv); | ||
| 804 | if (fence) | 802 | if (fence) |
| 805 | drm_atomic_set_fence_for_plane(new_state, fence); | 803 | drm_atomic_set_fence_for_plane(new_state, fence); |
| 806 | 804 | ||
diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c index f5b1256e32b6..131c23a267ee 100644 --- a/drivers/gpu/drm/msm/msm_atomic.c +++ b/drivers/gpu/drm/msm/msm_atomic.c | |||
| @@ -49,15 +49,13 @@ int msm_atomic_prepare_fb(struct drm_plane *plane, | |||
| 49 | struct msm_drm_private *priv = plane->dev->dev_private; | 49 | struct msm_drm_private *priv = plane->dev->dev_private; |
| 50 | struct msm_kms *kms = priv->kms; | 50 | struct msm_kms *kms = priv->kms; |
| 51 | struct drm_gem_object *obj; | 51 | struct drm_gem_object *obj; |
| 52 | struct msm_gem_object *msm_obj; | ||
| 53 | struct dma_fence *fence; | 52 | struct dma_fence *fence; |
| 54 | 53 | ||
| 55 | if (!new_state->fb) | 54 | if (!new_state->fb) |
| 56 | return 0; | 55 | return 0; |
| 57 | 56 | ||
| 58 | obj = msm_framebuffer_bo(new_state->fb, 0); | 57 | obj = msm_framebuffer_bo(new_state->fb, 0); |
| 59 | msm_obj = to_msm_bo(obj); | 58 | fence = reservation_object_get_excl_rcu(obj->resv); |
| 60 | fence = reservation_object_get_excl_rcu(msm_obj->resv); | ||
| 61 | 59 | ||
| 62 | drm_atomic_set_fence_for_plane(new_state, fence); | 60 | drm_atomic_set_fence_for_plane(new_state, fence); |
| 63 | 61 | ||
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 31d5a744d84f..35f55dd25994 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c | |||
| @@ -803,7 +803,8 @@ void msm_gem_describe(struct drm_gem_object *obj, struct seq_file *m) | |||
| 803 | seq_puts(m, " vmas:"); | 803 | seq_puts(m, " vmas:"); |
| 804 | 804 | ||
| 805 | list_for_each_entry(vma, &msm_obj->vmas, list) | 805 | list_for_each_entry(vma, &msm_obj->vmas, list) |
| 806 | seq_printf(m, " [%s: %08llx,%s,inuse=%d]", vma->aspace->name, | 806 | seq_printf(m, " [%s: %08llx,%s,inuse=%d]", |
| 807 | vma->aspace != NULL ? vma->aspace->name : NULL, | ||
| 807 | vma->iova, vma->mapped ? "mapped" : "unmapped", | 808 | vma->iova, vma->mapped ? "mapped" : "unmapped", |
| 808 | vma->inuse); | 809 | vma->inuse); |
| 809 | 810 | ||
diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h index c5ac781dffee..812d1b1369a5 100644 --- a/drivers/gpu/drm/msm/msm_gem.h +++ b/drivers/gpu/drm/msm/msm_gem.h | |||
| @@ -86,10 +86,6 @@ struct msm_gem_object { | |||
| 86 | 86 | ||
| 87 | struct llist_node freed; | 87 | struct llist_node freed; |
| 88 | 88 | ||
| 89 | /* normally (resv == &_resv) except for imported bo's */ | ||
| 90 | struct reservation_object *resv; | ||
| 91 | struct reservation_object _resv; | ||
| 92 | |||
| 93 | /* For physically contiguous buffers. Used when we don't have | 89 | /* For physically contiguous buffers. Used when we don't have |
| 94 | * an IOMMU. Also used for stolen/splashscreen buffer. | 90 | * an IOMMU. Also used for stolen/splashscreen buffer. |
| 95 | */ | 91 | */ |
diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.h b/drivers/gpu/drm/nouveau/dispnv50/disp.h index 2216c58620c2..7c41b0599d1a 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.h +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.h | |||
| @@ -41,6 +41,7 @@ struct nv50_disp_interlock { | |||
| 41 | NV50_DISP_INTERLOCK__SIZE | 41 | NV50_DISP_INTERLOCK__SIZE |
| 42 | } type; | 42 | } type; |
| 43 | u32 data; | 43 | u32 data; |
| 44 | u32 wimm; | ||
| 44 | }; | 45 | }; |
| 45 | 46 | ||
| 46 | void corec37d_ntfy_init(struct nouveau_bo *, u32); | 47 | void corec37d_ntfy_init(struct nouveau_bo *, u32); |
diff --git a/drivers/gpu/drm/nouveau/dispnv50/head.c b/drivers/gpu/drm/nouveau/dispnv50/head.c index 2e7a0c347ddb..06ee23823a68 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head.c +++ b/drivers/gpu/drm/nouveau/dispnv50/head.c | |||
| @@ -306,7 +306,7 @@ nv50_head_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state) | |||
| 306 | asyh->set.or = head->func->or != NULL; | 306 | asyh->set.or = head->func->or != NULL; |
| 307 | } | 307 | } |
| 308 | 308 | ||
| 309 | if (asyh->state.mode_changed) | 309 | if (asyh->state.mode_changed || asyh->state.connectors_changed) |
| 310 | nv50_head_atomic_check_mode(head, asyh); | 310 | nv50_head_atomic_check_mode(head, asyh); |
| 311 | 311 | ||
| 312 | if (asyh->state.color_mgmt_changed || | 312 | if (asyh->state.color_mgmt_changed || |
| @@ -413,6 +413,7 @@ nv50_head_atomic_duplicate_state(struct drm_crtc *crtc) | |||
| 413 | asyh->ovly = armh->ovly; | 413 | asyh->ovly = armh->ovly; |
| 414 | asyh->dither = armh->dither; | 414 | asyh->dither = armh->dither; |
| 415 | asyh->procamp = armh->procamp; | 415 | asyh->procamp = armh->procamp; |
| 416 | asyh->or = armh->or; | ||
| 416 | asyh->dp = armh->dp; | 417 | asyh->dp = armh->dp; |
| 417 | asyh->clr.mask = 0; | 418 | asyh->clr.mask = 0; |
| 418 | asyh->set.mask = 0; | 419 | asyh->set.mask = 0; |
diff --git a/drivers/gpu/drm/nouveau/dispnv50/wimmc37b.c b/drivers/gpu/drm/nouveau/dispnv50/wimmc37b.c index 9103b8494279..f7dbd965e4e7 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wimmc37b.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wimmc37b.c | |||
| @@ -75,6 +75,7 @@ wimmc37b_init_(const struct nv50_wimm_func *func, struct nouveau_drm *drm, | |||
| 75 | return ret; | 75 | return ret; |
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | wndw->interlock.wimm = wndw->interlock.data; | ||
| 78 | wndw->immd = func; | 79 | wndw->immd = func; |
| 79 | return 0; | 80 | return 0; |
| 80 | } | 81 | } |
diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c b/drivers/gpu/drm/nouveau/dispnv50/wndw.c index b95181027b31..283ff690350e 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c | |||
| @@ -127,7 +127,7 @@ void | |||
| 127 | nv50_wndw_flush_set(struct nv50_wndw *wndw, u32 *interlock, | 127 | nv50_wndw_flush_set(struct nv50_wndw *wndw, u32 *interlock, |
| 128 | struct nv50_wndw_atom *asyw) | 128 | struct nv50_wndw_atom *asyw) |
| 129 | { | 129 | { |
| 130 | if (interlock) { | 130 | if (interlock[NV50_DISP_INTERLOCK_CORE]) { |
| 131 | asyw->image.mode = 0; | 131 | asyw->image.mode = 0; |
| 132 | asyw->image.interval = 1; | 132 | asyw->image.interval = 1; |
| 133 | } | 133 | } |
| @@ -149,7 +149,7 @@ nv50_wndw_flush_set(struct nv50_wndw *wndw, u32 *interlock, | |||
| 149 | if (asyw->set.point) { | 149 | if (asyw->set.point) { |
| 150 | if (asyw->set.point = false, asyw->set.mask) | 150 | if (asyw->set.point = false, asyw->set.mask) |
| 151 | interlock[wndw->interlock.type] |= wndw->interlock.data; | 151 | interlock[wndw->interlock.type] |= wndw->interlock.data; |
| 152 | interlock[NV50_DISP_INTERLOCK_WIMM] |= wndw->interlock.data; | 152 | interlock[NV50_DISP_INTERLOCK_WIMM] |= wndw->interlock.wimm; |
| 153 | 153 | ||
| 154 | wndw->immd->point(wndw, asyw); | 154 | wndw->immd->point(wndw, asyw); |
| 155 | wndw->immd->update(wndw, interlock); | 155 | wndw->immd->update(wndw, interlock); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 22cd45845e07..7c2fcaba42d6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c | |||
| @@ -631,7 +631,8 @@ static int nouveau_drm_probe(struct pci_dev *pdev, | |||
| 631 | /* We need to check that the chipset is supported before booting | 631 | /* We need to check that the chipset is supported before booting |
| 632 | * fbdev off the hardware, as there's no way to put it back. | 632 | * fbdev off the hardware, as there's no way to put it back. |
| 633 | */ | 633 | */ |
| 634 | ret = nvkm_device_pci_new(pdev, NULL, "error", true, false, 0, &device); | 634 | ret = nvkm_device_pci_new(pdev, nouveau_config, "error", |
| 635 | true, false, 0, &device); | ||
| 635 | if (ret) | 636 | if (ret) |
| 636 | return ret; | 637 | return ret; |
| 637 | 638 | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 7971096b6767..10d91e8bbb94 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | |||
| @@ -2540,6 +2540,41 @@ nv166_chipset = { | |||
| 2540 | .sec2 = tu102_sec2_new, | 2540 | .sec2 = tu102_sec2_new, |
| 2541 | }; | 2541 | }; |
| 2542 | 2542 | ||
| 2543 | static const struct nvkm_device_chip | ||
| 2544 | nv167_chipset = { | ||
| 2545 | .name = "TU117", | ||
| 2546 | .bar = tu102_bar_new, | ||
| 2547 | .bios = nvkm_bios_new, | ||
| 2548 | .bus = gf100_bus_new, | ||
| 2549 | .devinit = tu102_devinit_new, | ||
| 2550 | .fault = tu102_fault_new, | ||
| 2551 | .fb = gv100_fb_new, | ||
| 2552 | .fuse = gm107_fuse_new, | ||
| 2553 | .gpio = gk104_gpio_new, | ||
| 2554 | .gsp = gv100_gsp_new, | ||
| 2555 | .i2c = gm200_i2c_new, | ||
| 2556 | .ibus = gm200_ibus_new, | ||
| 2557 | .imem = nv50_instmem_new, | ||
| 2558 | .ltc = gp102_ltc_new, | ||
| 2559 | .mc = tu102_mc_new, | ||
| 2560 | .mmu = tu102_mmu_new, | ||
| 2561 | .pci = gp100_pci_new, | ||
| 2562 | .pmu = gp102_pmu_new, | ||
| 2563 | .therm = gp100_therm_new, | ||
| 2564 | .timer = gk20a_timer_new, | ||
| 2565 | .top = gk104_top_new, | ||
| 2566 | .ce[0] = tu102_ce_new, | ||
| 2567 | .ce[1] = tu102_ce_new, | ||
| 2568 | .ce[2] = tu102_ce_new, | ||
| 2569 | .ce[3] = tu102_ce_new, | ||
| 2570 | .ce[4] = tu102_ce_new, | ||
| 2571 | .disp = tu102_disp_new, | ||
| 2572 | .dma = gv100_dma_new, | ||
| 2573 | .fifo = tu102_fifo_new, | ||
| 2574 | .nvdec[0] = gp102_nvdec_new, | ||
| 2575 | .sec2 = tu102_sec2_new, | ||
| 2576 | }; | ||
| 2577 | |||
| 2543 | static int | 2578 | static int |
| 2544 | nvkm_device_event_ctor(struct nvkm_object *object, void *data, u32 size, | 2579 | nvkm_device_event_ctor(struct nvkm_object *object, void *data, u32 size, |
| 2545 | struct nvkm_notify *notify) | 2580 | struct nvkm_notify *notify) |
| @@ -2824,8 +2859,8 @@ nvkm_device_ctor(const struct nvkm_device_func *func, | |||
| 2824 | u64 mmio_base, mmio_size; | 2859 | u64 mmio_base, mmio_size; |
| 2825 | u32 boot0, strap; | 2860 | u32 boot0, strap; |
| 2826 | void __iomem *map; | 2861 | void __iomem *map; |
| 2827 | int ret = -EEXIST; | 2862 | int ret = -EEXIST, i; |
| 2828 | int i; | 2863 | unsigned chipset; |
| 2829 | 2864 | ||
| 2830 | mutex_lock(&nv_devices_mutex); | 2865 | mutex_lock(&nv_devices_mutex); |
| 2831 | if (nvkm_device_find_locked(handle)) | 2866 | if (nvkm_device_find_locked(handle)) |
| @@ -2870,6 +2905,26 @@ nvkm_device_ctor(const struct nvkm_device_func *func, | |||
| 2870 | strap = ioread32_native(map + 0x101000); | 2905 | strap = ioread32_native(map + 0x101000); |
| 2871 | iounmap(map); | 2906 | iounmap(map); |
| 2872 | 2907 | ||
| 2908 | /* chipset can be overridden for devel/testing purposes */ | ||
| 2909 | chipset = nvkm_longopt(device->cfgopt, "NvChipset", 0); | ||
| 2910 | if (chipset) { | ||
| 2911 | u32 override_boot0; | ||
| 2912 | |||
| 2913 | if (chipset >= 0x10) { | ||
| 2914 | override_boot0 = ((chipset & 0x1ff) << 20); | ||
| 2915 | override_boot0 |= 0x000000a1; | ||
| 2916 | } else { | ||
| 2917 | if (chipset != 0x04) | ||
| 2918 | override_boot0 = 0x20104000; | ||
| 2919 | else | ||
| 2920 | override_boot0 = 0x20004000; | ||
| 2921 | } | ||
| 2922 | |||
| 2923 | nvdev_warn(device, "CHIPSET OVERRIDE: %08x -> %08x\n", | ||
| 2924 | boot0, override_boot0); | ||
| 2925 | boot0 = override_boot0; | ||
| 2926 | } | ||
| 2927 | |||
| 2873 | /* determine chipset and derive architecture from it */ | 2928 | /* determine chipset and derive architecture from it */ |
| 2874 | if ((boot0 & 0x1f000000) > 0) { | 2929 | if ((boot0 & 0x1f000000) > 0) { |
| 2875 | device->chipset = (boot0 & 0x1ff00000) >> 20; | 2930 | device->chipset = (boot0 & 0x1ff00000) >> 20; |
| @@ -2996,6 +3051,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func, | |||
| 2996 | case 0x162: device->chip = &nv162_chipset; break; | 3051 | case 0x162: device->chip = &nv162_chipset; break; |
| 2997 | case 0x164: device->chip = &nv164_chipset; break; | 3052 | case 0x164: device->chip = &nv164_chipset; break; |
| 2998 | case 0x166: device->chip = &nv166_chipset; break; | 3053 | case 0x166: device->chip = &nv166_chipset; break; |
| 3054 | case 0x167: device->chip = &nv167_chipset; break; | ||
| 2999 | default: | 3055 | default: |
| 3000 | nvdev_error(device, "unknown chipset (%08x)\n", boot0); | 3056 | nvdev_error(device, "unknown chipset (%08x)\n", boot0); |
| 3001 | goto done; | 3057 | goto done; |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c index 5f301e632599..818d21bd28d3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c | |||
| @@ -365,8 +365,15 @@ nvkm_dp_train(struct nvkm_dp *dp, u32 dataKBps) | |||
| 365 | * and it's better to have a failed modeset than that. | 365 | * and it's better to have a failed modeset than that. |
| 366 | */ | 366 | */ |
| 367 | for (cfg = nvkm_dp_rates; cfg->rate; cfg++) { | 367 | for (cfg = nvkm_dp_rates; cfg->rate; cfg++) { |
| 368 | if (cfg->nr <= outp_nr && cfg->nr <= outp_bw) | 368 | if (cfg->nr <= outp_nr && cfg->nr <= outp_bw) { |
| 369 | failsafe = cfg; | 369 | /* Try to respect sink limits too when selecting |
| 370 | * lowest link configuration. | ||
| 371 | */ | ||
| 372 | if (!failsafe || | ||
| 373 | (cfg->nr <= sink_nr && cfg->bw <= sink_bw)) | ||
| 374 | failsafe = cfg; | ||
| 375 | } | ||
| 376 | |||
| 370 | if (failsafe && cfg[1].rate < dataKBps) | 377 | if (failsafe && cfg[1].rate < dataKBps) |
| 371 | break; | 378 | break; |
| 372 | } | 379 | } |
diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c b/drivers/gpu/drm/panfrost/panfrost_device.c index 970f669c6d29..3b2bced1b015 100644 --- a/drivers/gpu/drm/panfrost/panfrost_device.c +++ b/drivers/gpu/drm/panfrost/panfrost_device.c | |||
| @@ -165,6 +165,10 @@ err_out0: | |||
| 165 | 165 | ||
| 166 | void panfrost_device_fini(struct panfrost_device *pfdev) | 166 | void panfrost_device_fini(struct panfrost_device *pfdev) |
| 167 | { | 167 | { |
| 168 | panfrost_job_fini(pfdev); | ||
| 169 | panfrost_mmu_fini(pfdev); | ||
| 170 | panfrost_gpu_fini(pfdev); | ||
| 171 | panfrost_reset_fini(pfdev); | ||
| 168 | panfrost_regulator_fini(pfdev); | 172 | panfrost_regulator_fini(pfdev); |
| 169 | panfrost_clk_fini(pfdev); | 173 | panfrost_clk_fini(pfdev); |
| 170 | } | 174 | } |
diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c index 94b0819ad50b..d11e2281dde6 100644 --- a/drivers/gpu/drm/panfrost/panfrost_drv.c +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c | |||
| @@ -219,7 +219,8 @@ static int panfrost_ioctl_submit(struct drm_device *dev, void *data, | |||
| 219 | fail_job: | 219 | fail_job: |
| 220 | panfrost_job_put(job); | 220 | panfrost_job_put(job); |
| 221 | fail_out_sync: | 221 | fail_out_sync: |
| 222 | drm_syncobj_put(sync_out); | 222 | if (sync_out) |
| 223 | drm_syncobj_put(sync_out); | ||
| 223 | 224 | ||
| 224 | return ret; | 225 | return ret; |
| 225 | } | 226 | } |
diff --git a/drivers/gpu/drm/pl111/pl111_display.c b/drivers/gpu/drm/pl111/pl111_display.c index 0c5d391f0a8f..4501597f30ab 100644 --- a/drivers/gpu/drm/pl111/pl111_display.c +++ b/drivers/gpu/drm/pl111/pl111_display.c | |||
| @@ -531,14 +531,15 @@ pl111_init_clock_divider(struct drm_device *drm) | |||
| 531 | dev_err(drm->dev, "CLCD: unable to get clcdclk.\n"); | 531 | dev_err(drm->dev, "CLCD: unable to get clcdclk.\n"); |
| 532 | return PTR_ERR(parent); | 532 | return PTR_ERR(parent); |
| 533 | } | 533 | } |
| 534 | |||
| 535 | spin_lock_init(&priv->tim2_lock); | ||
| 536 | |||
| 534 | /* If the clock divider is broken, use the parent directly */ | 537 | /* If the clock divider is broken, use the parent directly */ |
| 535 | if (priv->variant->broken_clockdivider) { | 538 | if (priv->variant->broken_clockdivider) { |
| 536 | priv->clk = parent; | 539 | priv->clk = parent; |
| 537 | return 0; | 540 | return 0; |
| 538 | } | 541 | } |
| 539 | parent_name = __clk_get_name(parent); | 542 | parent_name = __clk_get_name(parent); |
| 540 | |||
| 541 | spin_lock_init(&priv->tim2_lock); | ||
| 542 | div->init = &init; | 543 | div->init = &init; |
| 543 | 544 | ||
| 544 | ret = devm_clk_hw_register(drm->dev, div); | 545 | ret = devm_clk_hw_register(drm->dev, div); |
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index aa898c699101..433df7036f96 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
| @@ -922,12 +922,12 @@ static void avivo_get_fb_ref_div(unsigned nom, unsigned den, unsigned post_div, | |||
| 922 | ref_div_max = max(min(100 / post_div, ref_div_max), 1u); | 922 | ref_div_max = max(min(100 / post_div, ref_div_max), 1u); |
| 923 | 923 | ||
| 924 | /* get matching reference and feedback divider */ | 924 | /* get matching reference and feedback divider */ |
| 925 | *ref_div = min(max(DIV_ROUND_CLOSEST(den, post_div), 1u), ref_div_max); | 925 | *ref_div = min(max(den/post_div, 1u), ref_div_max); |
| 926 | *fb_div = DIV_ROUND_CLOSEST(nom * *ref_div * post_div, den); | 926 | *fb_div = DIV_ROUND_CLOSEST(nom * *ref_div * post_div, den); |
| 927 | 927 | ||
| 928 | /* limit fb divider to its maximum */ | 928 | /* limit fb divider to its maximum */ |
| 929 | if (*fb_div > fb_div_max) { | 929 | if (*fb_div > fb_div_max) { |
| 930 | *ref_div = DIV_ROUND_CLOSEST(*ref_div * fb_div_max, *fb_div); | 930 | *ref_div = (*ref_div * fb_div_max)/(*fb_div); |
| 931 | *fb_div = fb_div_max; | 931 | *fb_div = fb_div_max; |
| 932 | } | 932 | } |
| 933 | } | 933 | } |
