diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-01-05 21:25:19 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-01-05 21:25:19 -0500 |
| commit | 0fe4e2d5cd931ad2ff99d61cfdd5c6dc0c3ec60b (patch) | |
| tree | 3fa902b06751f510915dd25b1a10aeb97fc4dea5 | |
| parent | 3954e1d0310e30e743431b58918825c4d4fe8812 (diff) | |
| parent | 9ddf32a8df9e342371aaf9233d59739a356231e6 (diff) | |
Merge tag 'drm-next-2019-01-05' of git://anongit.freedesktop.org/drm/drm
Pull drm fixes from Dave Airlie:
"Happy New Year, just decloaking from leave to get some stuff from the
last week in before rc1:
core:
- two regression fixes for damage blob and atomic
i915 gvt:
- Some missed GVT fixes from the original pull
amdgpu:
- new PCI IDs
- SR-IOV fixes
- DC fixes
- Vega20 fixes"
* tag 'drm-next-2019-01-05' of git://anongit.freedesktop.org/drm/drm: (53 commits)
drm: Put damage blob when destroy plane state
drm: fix null pointer dereference on null state pointer
drm/amdgpu: Add new VegaM pci id
drm/ttm: Use drm_debug_printer for all ttm_bo_mem_space_debug output
drm/amdgpu: add Vega20 PSP ASD firmware loading
drm/amd/display: Fix MST dp_blank REG_WAIT timeout
drm/amd/display: validate extended dongle caps
drm/amd/display: Use div_u64 for flip timestamp ns to ms
drm/amdgpu/uvd:Change uvd ring name convention
drm/amd/powerplay: add Vega20 LCLK DPM level setting support
drm/amdgpu: print process info when job timeout
drm/amdgpu/nbio7.4: add hw bug workaround for vega20
drm/amdgpu/nbio6.1: add hw bug workaround for vega10/12
drm/amd/display: Optimize passive update planes.
drm/amd/display: verify lane status before exiting verify link cap
drm/amd/display: Fix bug with not updating VSP infoframe
drm/amd/display: Add retry to read ddc_clock pin
drm/amd/display: Don't skip link training for empty dongle
drm/amd/display: Wait edp HPD to high in detect_sink
drm/amd/display: fix surface update sequence
...
51 files changed, 628 insertions, 290 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index cf4e190c0a72..1c49b8266d69 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | |||
| @@ -1428,6 +1428,9 @@ int amdgpu_cs_fence_to_handle_ioctl(struct drm_device *dev, void *data, | |||
| 1428 | if (IS_ERR(fence)) | 1428 | if (IS_ERR(fence)) |
| 1429 | return PTR_ERR(fence); | 1429 | return PTR_ERR(fence); |
| 1430 | 1430 | ||
| 1431 | if (!fence) | ||
| 1432 | fence = dma_fence_get_stub(); | ||
| 1433 | |||
| 1431 | switch (info->in.what) { | 1434 | switch (info->in.what) { |
| 1432 | case AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ: | 1435 | case AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ: |
| 1433 | r = drm_syncobj_create(&syncobj, 0, fence); | 1436 | r = drm_syncobj_create(&syncobj, 0, fence); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index b60afeade50a..8a078f4ae73d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | |||
| @@ -3476,14 +3476,16 @@ static void amdgpu_device_lock_adev(struct amdgpu_device *adev) | |||
| 3476 | mutex_lock(&adev->lock_reset); | 3476 | mutex_lock(&adev->lock_reset); |
| 3477 | atomic_inc(&adev->gpu_reset_counter); | 3477 | atomic_inc(&adev->gpu_reset_counter); |
| 3478 | adev->in_gpu_reset = 1; | 3478 | adev->in_gpu_reset = 1; |
| 3479 | /* Block kfd */ | 3479 | /* Block kfd: SRIOV would do it separately */ |
| 3480 | amdgpu_amdkfd_pre_reset(adev); | 3480 | if (!amdgpu_sriov_vf(adev)) |
| 3481 | amdgpu_amdkfd_pre_reset(adev); | ||
| 3481 | } | 3482 | } |
| 3482 | 3483 | ||
| 3483 | static void amdgpu_device_unlock_adev(struct amdgpu_device *adev) | 3484 | static void amdgpu_device_unlock_adev(struct amdgpu_device *adev) |
| 3484 | { | 3485 | { |
| 3485 | /*unlock kfd */ | 3486 | /*unlock kfd: SRIOV would do it separately */ |
| 3486 | amdgpu_amdkfd_post_reset(adev); | 3487 | if (!amdgpu_sriov_vf(adev)) |
| 3488 | amdgpu_amdkfd_post_reset(adev); | ||
| 3487 | amdgpu_vf_error_trans_all(adev); | 3489 | amdgpu_vf_error_trans_all(adev); |
| 3488 | adev->in_gpu_reset = 0; | 3490 | adev->in_gpu_reset = 0; |
| 3489 | mutex_unlock(&adev->lock_reset); | 3491 | mutex_unlock(&adev->lock_reset); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 9c77eaa45982..c806f984bcc5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | |||
| @@ -865,6 +865,7 @@ static const struct pci_device_id pciidlist[] = { | |||
| 865 | /* VEGAM */ | 865 | /* VEGAM */ |
| 866 | {0x1002, 0x694C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGAM}, | 866 | {0x1002, 0x694C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGAM}, |
| 867 | {0x1002, 0x694E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGAM}, | 867 | {0x1002, 0x694E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGAM}, |
| 868 | {0x1002, 0x694F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGAM}, | ||
| 868 | /* Vega 10 */ | 869 | /* Vega 10 */ |
| 869 | {0x1002, 0x6860, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10}, | 870 | {0x1002, 0x6860, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10}, |
| 870 | {0x1002, 0x6861, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10}, | 871 | {0x1002, 0x6861, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10}, |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c index e0af44fd6a0c..0a17fb1af204 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | |||
| @@ -32,6 +32,9 @@ static void amdgpu_job_timedout(struct drm_sched_job *s_job) | |||
| 32 | { | 32 | { |
| 33 | struct amdgpu_ring *ring = to_amdgpu_ring(s_job->sched); | 33 | struct amdgpu_ring *ring = to_amdgpu_ring(s_job->sched); |
| 34 | struct amdgpu_job *job = to_amdgpu_job(s_job); | 34 | struct amdgpu_job *job = to_amdgpu_job(s_job); |
| 35 | struct amdgpu_task_info ti; | ||
| 36 | |||
| 37 | memset(&ti, 0, sizeof(struct amdgpu_task_info)); | ||
| 35 | 38 | ||
| 36 | if (amdgpu_ring_soft_recovery(ring, job->vmid, s_job->s_fence->parent)) { | 39 | if (amdgpu_ring_soft_recovery(ring, job->vmid, s_job->s_fence->parent)) { |
| 37 | DRM_ERROR("ring %s timeout, but soft recovered\n", | 40 | DRM_ERROR("ring %s timeout, but soft recovered\n", |
| @@ -39,9 +42,12 @@ static void amdgpu_job_timedout(struct drm_sched_job *s_job) | |||
| 39 | return; | 42 | return; |
| 40 | } | 43 | } |
| 41 | 44 | ||
| 45 | amdgpu_vm_get_task_info(ring->adev, job->pasid, &ti); | ||
| 42 | DRM_ERROR("ring %s timeout, signaled seq=%u, emitted seq=%u\n", | 46 | DRM_ERROR("ring %s timeout, signaled seq=%u, emitted seq=%u\n", |
| 43 | job->base.sched->name, atomic_read(&ring->fence_drv.last_seq), | 47 | job->base.sched->name, atomic_read(&ring->fence_drv.last_seq), |
| 44 | ring->fence_drv.sync_seq); | 48 | ring->fence_drv.sync_seq); |
| 49 | DRM_ERROR("Process information: process %s pid %d thread %s pid %d\n", | ||
| 50 | ti.process_name, ti.tgid, ti.task_name, ti.pid); | ||
| 45 | 51 | ||
| 46 | if (amdgpu_device_should_recover_gpu(ring->adev)) | 52 | if (amdgpu_device_should_recover_gpu(ring->adev)) |
| 47 | amdgpu_device_gpu_recover(ring->adev, job); | 53 | amdgpu_device_gpu_recover(ring->adev, job); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index fd271f9746a2..728e15e5d68a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | |||
| @@ -912,7 +912,7 @@ int amdgpu_bo_unpin(struct amdgpu_bo *bo) | |||
| 912 | struct ttm_operation_ctx ctx = { false, false }; | 912 | struct ttm_operation_ctx ctx = { false, false }; |
| 913 | int r, i; | 913 | int r, i; |
| 914 | 914 | ||
| 915 | if (!bo->pin_count) { | 915 | if (WARN_ON_ONCE(!bo->pin_count)) { |
| 916 | dev_warn(adev->dev, "%p unpin not necessary\n", bo); | 916 | dev_warn(adev->dev, "%p unpin not necessary\n", bo); |
| 917 | return 0; | 917 | return 0; |
| 918 | } | 918 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index 6759d898b3ab..8fab0d637ee5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | |||
| @@ -155,14 +155,6 @@ psp_cmd_submit_buf(struct psp_context *psp, | |||
| 155 | return ret; | 155 | return ret; |
| 156 | } | 156 | } |
| 157 | 157 | ||
| 158 | bool psp_support_vmr_ring(struct psp_context *psp) | ||
| 159 | { | ||
| 160 | if (amdgpu_sriov_vf(psp->adev) && psp->sos_fw_version > 0x80045) | ||
| 161 | return true; | ||
| 162 | else | ||
| 163 | return false; | ||
| 164 | } | ||
| 165 | |||
| 166 | static void psp_prep_tmr_cmd_buf(struct psp_context *psp, | 158 | static void psp_prep_tmr_cmd_buf(struct psp_context *psp, |
| 167 | struct psp_gfx_cmd_resp *cmd, | 159 | struct psp_gfx_cmd_resp *cmd, |
| 168 | uint64_t tmr_mc, uint32_t size) | 160 | uint64_t tmr_mc, uint32_t size) |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h index 10decf70c9aa..3ee573b4016e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h | |||
| @@ -83,12 +83,13 @@ struct psp_funcs | |||
| 83 | enum AMDGPU_UCODE_ID ucode_type); | 83 | enum AMDGPU_UCODE_ID ucode_type); |
| 84 | bool (*smu_reload_quirk)(struct psp_context *psp); | 84 | bool (*smu_reload_quirk)(struct psp_context *psp); |
| 85 | int (*mode1_reset)(struct psp_context *psp); | 85 | int (*mode1_reset)(struct psp_context *psp); |
| 86 | uint64_t (*xgmi_get_node_id)(struct psp_context *psp); | 86 | int (*xgmi_get_node_id)(struct psp_context *psp, uint64_t *node_id); |
| 87 | uint64_t (*xgmi_get_hive_id)(struct psp_context *psp); | 87 | int (*xgmi_get_hive_id)(struct psp_context *psp, uint64_t *hive_id); |
| 88 | int (*xgmi_get_topology_info)(struct psp_context *psp, int number_devices, | 88 | int (*xgmi_get_topology_info)(struct psp_context *psp, int number_devices, |
| 89 | struct psp_xgmi_topology_info *topology); | 89 | struct psp_xgmi_topology_info *topology); |
| 90 | int (*xgmi_set_topology_info)(struct psp_context *psp, int number_devices, | 90 | int (*xgmi_set_topology_info)(struct psp_context *psp, int number_devices, |
| 91 | struct psp_xgmi_topology_info *topology); | 91 | struct psp_xgmi_topology_info *topology); |
| 92 | bool (*support_vmr_ring)(struct psp_context *psp); | ||
| 92 | }; | 93 | }; |
| 93 | 94 | ||
| 94 | struct psp_xgmi_context { | 95 | struct psp_xgmi_context { |
| @@ -192,12 +193,14 @@ struct psp_xgmi_topology_info { | |||
| 192 | ((psp)->funcs->bootloader_load_sos ? (psp)->funcs->bootloader_load_sos((psp)) : 0) | 193 | ((psp)->funcs->bootloader_load_sos ? (psp)->funcs->bootloader_load_sos((psp)) : 0) |
| 193 | #define psp_smu_reload_quirk(psp) \ | 194 | #define psp_smu_reload_quirk(psp) \ |
| 194 | ((psp)->funcs->smu_reload_quirk ? (psp)->funcs->smu_reload_quirk((psp)) : false) | 195 | ((psp)->funcs->smu_reload_quirk ? (psp)->funcs->smu_reload_quirk((psp)) : false) |
| 196 | #define psp_support_vmr_ring(psp) \ | ||
| 197 | ((psp)->funcs->support_vmr_ring ? (psp)->funcs->support_vmr_ring((psp)) : false) | ||
| 195 | #define psp_mode1_reset(psp) \ | 198 | #define psp_mode1_reset(psp) \ |
| 196 | ((psp)->funcs->mode1_reset ? (psp)->funcs->mode1_reset((psp)) : false) | 199 | ((psp)->funcs->mode1_reset ? (psp)->funcs->mode1_reset((psp)) : false) |
| 197 | #define psp_xgmi_get_node_id(psp) \ | 200 | #define psp_xgmi_get_node_id(psp, node_id) \ |
| 198 | ((psp)->funcs->xgmi_get_node_id ? (psp)->funcs->xgmi_get_node_id((psp)) : 0) | 201 | ((psp)->funcs->xgmi_get_node_id ? (psp)->funcs->xgmi_get_node_id((psp), (node_id)) : -EINVAL) |
| 199 | #define psp_xgmi_get_hive_id(psp) \ | 202 | #define psp_xgmi_get_hive_id(psp, hive_id) \ |
| 200 | ((psp)->funcs->xgmi_get_hive_id ? (psp)->funcs->xgmi_get_hive_id((psp)) : 0) | 203 | ((psp)->funcs->xgmi_get_hive_id ? (psp)->funcs->xgmi_get_hive_id((psp), (hive_id)) : -EINVAL) |
| 201 | #define psp_xgmi_get_topology_info(psp, num_device, topology) \ | 204 | #define psp_xgmi_get_topology_info(psp, num_device, topology) \ |
| 202 | ((psp)->funcs->xgmi_get_topology_info ? \ | 205 | ((psp)->funcs->xgmi_get_topology_info ? \ |
| 203 | (psp)->funcs->xgmi_get_topology_info((psp), (num_device), (topology)) : -EINVAL) | 206 | (psp)->funcs->xgmi_get_topology_info((psp), (num_device), (topology)) : -EINVAL) |
| @@ -217,8 +220,6 @@ extern const struct amdgpu_ip_block_version psp_v10_0_ip_block; | |||
| 217 | 220 | ||
| 218 | int psp_gpu_reset(struct amdgpu_device *adev); | 221 | int psp_gpu_reset(struct amdgpu_device *adev); |
| 219 | int psp_xgmi_invoke(struct psp_context *psp, uint32_t ta_cmd_id); | 222 | int psp_xgmi_invoke(struct psp_context *psp, uint32_t ta_cmd_id); |
| 220 | bool psp_support_vmr_ring(struct psp_context *psp); | ||
| 221 | |||
| 222 | extern const struct amdgpu_ip_block_version psp_v11_0_ip_block; | 223 | extern const struct amdgpu_ip_block_version psp_v11_0_ip_block; |
| 223 | 224 | ||
| 224 | #endif | 225 | #endif |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h index 0beb01fef83f..d87e828a084b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | |||
| @@ -29,7 +29,7 @@ | |||
| 29 | #include <drm/drm_print.h> | 29 | #include <drm/drm_print.h> |
| 30 | 30 | ||
| 31 | /* max number of rings */ | 31 | /* max number of rings */ |
| 32 | #define AMDGPU_MAX_RINGS 21 | 32 | #define AMDGPU_MAX_RINGS 23 |
| 33 | #define AMDGPU_MAX_GFX_RINGS 1 | 33 | #define AMDGPU_MAX_GFX_RINGS 1 |
| 34 | #define AMDGPU_MAX_COMPUTE_RINGS 8 | 34 | #define AMDGPU_MAX_COMPUTE_RINGS 8 |
| 35 | #define AMDGPU_MAX_VCE_RINGS 3 | 35 | #define AMDGPU_MAX_VCE_RINGS 3 |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c index e2e42e3fbcf3..ecf6f96df2ad 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | |||
| @@ -262,7 +262,7 @@ static int amdgpu_vcn_pause_dpg_mode(struct amdgpu_device *adev, | |||
| 262 | 262 | ||
| 263 | ring = &adev->vcn.ring_dec; | 263 | ring = &adev->vcn.ring_dec; |
| 264 | WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR, | 264 | WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR, |
| 265 | RREG32_SOC15(UVD, 0, mmUVD_SCRATCH2)); | 265 | RREG32_SOC15(UVD, 0, mmUVD_SCRATCH2) & 0x7FFFFFFF); |
| 266 | SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS, | 266 | SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS, |
| 267 | UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON, | 267 | UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON, |
| 268 | UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code); | 268 | UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code); |
| @@ -322,7 +322,7 @@ static int amdgpu_vcn_pause_dpg_mode(struct amdgpu_device *adev, | |||
| 322 | 322 | ||
| 323 | ring = &adev->vcn.ring_dec; | 323 | ring = &adev->vcn.ring_dec; |
| 324 | WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR, | 324 | WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR, |
| 325 | RREG32_SOC15(UVD, 0, mmUVD_SCRATCH2)); | 325 | RREG32_SOC15(UVD, 0, mmUVD_SCRATCH2) & 0x7FFFFFFF); |
| 326 | SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS, | 326 | SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS, |
| 327 | UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON, | 327 | UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON, |
| 328 | UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code); | 328 | UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code); |
| @@ -396,16 +396,26 @@ void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring) | |||
| 396 | 396 | ||
| 397 | if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) { | 397 | if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) { |
| 398 | struct dpg_pause_state new_state; | 398 | struct dpg_pause_state new_state; |
| 399 | unsigned int fences = 0; | ||
| 400 | unsigned int i; | ||
| 399 | 401 | ||
| 400 | if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC) | 402 | for (i = 0; i < adev->vcn.num_enc_rings; ++i) { |
| 403 | fences += amdgpu_fence_count_emitted(&adev->vcn.ring_enc[i]); | ||
| 404 | } | ||
| 405 | if (fences) | ||
| 401 | new_state.fw_based = VCN_DPG_STATE__PAUSE; | 406 | new_state.fw_based = VCN_DPG_STATE__PAUSE; |
| 402 | else | 407 | else |
| 403 | new_state.fw_based = adev->vcn.pause_state.fw_based; | 408 | new_state.fw_based = VCN_DPG_STATE__UNPAUSE; |
| 404 | 409 | ||
| 405 | if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_JPEG) | 410 | if (amdgpu_fence_count_emitted(&adev->vcn.ring_jpeg)) |
| 406 | new_state.jpeg = VCN_DPG_STATE__PAUSE; | 411 | new_state.jpeg = VCN_DPG_STATE__PAUSE; |
| 407 | else | 412 | else |
| 408 | new_state.jpeg = adev->vcn.pause_state.jpeg; | 413 | new_state.jpeg = VCN_DPG_STATE__UNPAUSE; |
| 414 | |||
| 415 | if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC) | ||
| 416 | new_state.fw_based = VCN_DPG_STATE__PAUSE; | ||
| 417 | else if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_JPEG) | ||
| 418 | new_state.jpeg = VCN_DPG_STATE__PAUSE; | ||
| 409 | 419 | ||
| 410 | amdgpu_vcn_pause_dpg_mode(adev, &new_state); | 420 | amdgpu_vcn_pause_dpg_mode(adev, &new_state); |
| 411 | } | 421 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c index 0b263a9857c6..8a8bc60cb6b4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c | |||
| @@ -97,8 +97,19 @@ int amdgpu_xgmi_add_device(struct amdgpu_device *adev) | |||
| 97 | if (!adev->gmc.xgmi.supported) | 97 | if (!adev->gmc.xgmi.supported) |
| 98 | return 0; | 98 | return 0; |
| 99 | 99 | ||
| 100 | adev->gmc.xgmi.node_id = psp_xgmi_get_node_id(&adev->psp); | 100 | ret = psp_xgmi_get_node_id(&adev->psp, &adev->gmc.xgmi.node_id); |
| 101 | adev->gmc.xgmi.hive_id = psp_xgmi_get_hive_id(&adev->psp); | 101 | if (ret) { |
| 102 | dev_err(adev->dev, | ||
| 103 | "XGMI: Failed to get node id\n"); | ||
| 104 | return ret; | ||
| 105 | } | ||
| 106 | |||
| 107 | ret = psp_xgmi_get_hive_id(&adev->psp, &adev->gmc.xgmi.hive_id); | ||
| 108 | if (ret) { | ||
| 109 | dev_err(adev->dev, | ||
| 110 | "XGMI: Failed to get hive id\n"); | ||
| 111 | return ret; | ||
| 112 | } | ||
| 102 | 113 | ||
| 103 | mutex_lock(&xgmi_mutex); | 114 | mutex_lock(&xgmi_mutex); |
| 104 | hive = amdgpu_get_xgmi_hive(adev); | 115 | hive = amdgpu_get_xgmi_hive(adev); |
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index ce150de723c9..bacdaef77b6c 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | |||
| @@ -718,37 +718,46 @@ static bool gmc_v9_0_keep_stolen_memory(struct amdgpu_device *adev) | |||
| 718 | } | 718 | } |
| 719 | } | 719 | } |
| 720 | 720 | ||
| 721 | static int gmc_v9_0_late_init(void *handle) | 721 | static int gmc_v9_0_allocate_vm_inv_eng(struct amdgpu_device *adev) |
| 722 | { | 722 | { |
| 723 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 723 | struct amdgpu_ring *ring; |
| 724 | /* | 724 | unsigned vm_inv_engs[AMDGPU_MAX_VMHUBS] = |
| 725 | * The latest engine allocation on gfx9 is: | 725 | {GFXHUB_FREE_VM_INV_ENGS_BITMAP, MMHUB_FREE_VM_INV_ENGS_BITMAP}; |
| 726 | * Engine 0, 1: idle | ||
| 727 | * Engine 2, 3: firmware | ||
| 728 | * Engine 4~13: amdgpu ring, subject to change when ring number changes | ||
| 729 | * Engine 14~15: idle | ||
| 730 | * Engine 16: kfd tlb invalidation | ||
| 731 | * Engine 17: Gart flushes | ||
| 732 | */ | ||
| 733 | unsigned vm_inv_eng[AMDGPU_MAX_VMHUBS] = { 4, 4 }; | ||
| 734 | unsigned i; | 726 | unsigned i; |
| 735 | int r; | 727 | unsigned vmhub, inv_eng; |
| 736 | 728 | ||
| 737 | if (!gmc_v9_0_keep_stolen_memory(adev)) | 729 | for (i = 0; i < adev->num_rings; ++i) { |
| 738 | amdgpu_bo_late_init(adev); | 730 | ring = adev->rings[i]; |
| 731 | vmhub = ring->funcs->vmhub; | ||
| 732 | |||
| 733 | inv_eng = ffs(vm_inv_engs[vmhub]); | ||
| 734 | if (!inv_eng) { | ||
| 735 | dev_err(adev->dev, "no VM inv eng for ring %s\n", | ||
| 736 | ring->name); | ||
| 737 | return -EINVAL; | ||
| 738 | } | ||
| 739 | 739 | ||
| 740 | for(i = 0; i < adev->num_rings; ++i) { | 740 | ring->vm_inv_eng = inv_eng - 1; |
| 741 | struct amdgpu_ring *ring = adev->rings[i]; | 741 | change_bit(inv_eng - 1, (unsigned long *)(&vm_inv_engs[vmhub])); |
| 742 | unsigned vmhub = ring->funcs->vmhub; | ||
| 743 | 742 | ||
| 744 | ring->vm_inv_eng = vm_inv_eng[vmhub]++; | ||
| 745 | dev_info(adev->dev, "ring %s uses VM inv eng %u on hub %u\n", | 743 | dev_info(adev->dev, "ring %s uses VM inv eng %u on hub %u\n", |
| 746 | ring->name, ring->vm_inv_eng, ring->funcs->vmhub); | 744 | ring->name, ring->vm_inv_eng, ring->funcs->vmhub); |
| 747 | } | 745 | } |
| 748 | 746 | ||
| 749 | /* Engine 16 is used for KFD and 17 for GART flushes */ | 747 | return 0; |
| 750 | for(i = 0; i < AMDGPU_MAX_VMHUBS; ++i) | 748 | } |
| 751 | BUG_ON(vm_inv_eng[i] > 16); | 749 | |
| 750 | static int gmc_v9_0_late_init(void *handle) | ||
| 751 | { | ||
| 752 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
| 753 | int r; | ||
| 754 | |||
| 755 | if (!gmc_v9_0_keep_stolen_memory(adev)) | ||
| 756 | amdgpu_bo_late_init(adev); | ||
| 757 | |||
| 758 | r = gmc_v9_0_allocate_vm_inv_eng(adev); | ||
| 759 | if (r) | ||
| 760 | return r; | ||
| 752 | 761 | ||
| 753 | if (adev->asic_type == CHIP_VEGA10 && !amdgpu_sriov_vf(adev)) { | 762 | if (adev->asic_type == CHIP_VEGA10 && !amdgpu_sriov_vf(adev)) { |
| 754 | r = gmc_v9_0_ecc_available(adev); | 763 | r = gmc_v9_0_ecc_available(adev); |
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.h b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.h index b030ca5ea107..5c8deac65580 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.h +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.h | |||
| @@ -24,6 +24,16 @@ | |||
| 24 | #ifndef __GMC_V9_0_H__ | 24 | #ifndef __GMC_V9_0_H__ |
| 25 | #define __GMC_V9_0_H__ | 25 | #define __GMC_V9_0_H__ |
| 26 | 26 | ||
| 27 | /* | ||
| 28 | * The latest engine allocation on gfx9 is: | ||
| 29 | * Engine 2, 3: firmware | ||
| 30 | * Engine 0, 1, 4~16: amdgpu ring, | ||
| 31 | * subject to change when ring number changes | ||
| 32 | * Engine 17: Gart flushes | ||
| 33 | */ | ||
| 34 | #define GFXHUB_FREE_VM_INV_ENGS_BITMAP 0x1FFF3 | ||
| 35 | #define MMHUB_FREE_VM_INV_ENGS_BITMAP 0x1FFF3 | ||
| 36 | |||
| 27 | extern const struct amd_ip_funcs gmc_v9_0_ip_funcs; | 37 | extern const struct amd_ip_funcs gmc_v9_0_ip_funcs; |
| 28 | extern const struct amdgpu_ip_block_version gmc_v9_0_ip_block; | 38 | extern const struct amdgpu_ip_block_version gmc_v9_0_ip_block; |
| 29 | 39 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c b/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c index 6f9c54978cc1..accdedd63c98 100644 --- a/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c +++ b/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #define smnCPM_CONTROL 0x11180460 | 32 | #define smnCPM_CONTROL 0x11180460 |
| 33 | #define smnPCIE_CNTL2 0x11180070 | 33 | #define smnPCIE_CNTL2 0x11180070 |
| 34 | #define smnPCIE_CONFIG_CNTL 0x11180044 | 34 | #define smnPCIE_CONFIG_CNTL 0x11180044 |
| 35 | #define smnPCIE_CI_CNTL 0x11180080 | ||
| 35 | 36 | ||
| 36 | static u32 nbio_v6_1_get_rev_id(struct amdgpu_device *adev) | 37 | static u32 nbio_v6_1_get_rev_id(struct amdgpu_device *adev) |
| 37 | { | 38 | { |
| @@ -270,6 +271,12 @@ static void nbio_v6_1_init_registers(struct amdgpu_device *adev) | |||
| 270 | 271 | ||
| 271 | if (def != data) | 272 | if (def != data) |
| 272 | WREG32_PCIE(smnPCIE_CONFIG_CNTL, data); | 273 | WREG32_PCIE(smnPCIE_CONFIG_CNTL, data); |
| 274 | |||
| 275 | def = data = RREG32_PCIE(smnPCIE_CI_CNTL); | ||
| 276 | data = REG_SET_FIELD(data, PCIE_CI_CNTL, CI_SLV_ORDERING_DIS, 1); | ||
| 277 | |||
| 278 | if (def != data) | ||
| 279 | WREG32_PCIE(smnPCIE_CI_CNTL, data); | ||
| 273 | } | 280 | } |
| 274 | 281 | ||
| 275 | const struct amdgpu_nbio_funcs nbio_v6_1_funcs = { | 282 | const struct amdgpu_nbio_funcs nbio_v6_1_funcs = { |
diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c index f8cee95d61cc..4cd31a276dcd 100644 --- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c +++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | 31 | ||
| 32 | #define smnCPM_CONTROL 0x11180460 | 32 | #define smnCPM_CONTROL 0x11180460 |
| 33 | #define smnPCIE_CNTL2 0x11180070 | 33 | #define smnPCIE_CNTL2 0x11180070 |
| 34 | #define smnPCIE_CI_CNTL 0x11180080 | ||
| 34 | 35 | ||
| 35 | static u32 nbio_v7_4_get_rev_id(struct amdgpu_device *adev) | 36 | static u32 nbio_v7_4_get_rev_id(struct amdgpu_device *adev) |
| 36 | { | 37 | { |
| @@ -222,7 +223,13 @@ static void nbio_v7_4_detect_hw_virt(struct amdgpu_device *adev) | |||
| 222 | 223 | ||
| 223 | static void nbio_v7_4_init_registers(struct amdgpu_device *adev) | 224 | static void nbio_v7_4_init_registers(struct amdgpu_device *adev) |
| 224 | { | 225 | { |
| 226 | uint32_t def, data; | ||
| 227 | |||
| 228 | def = data = RREG32_PCIE(smnPCIE_CI_CNTL); | ||
| 229 | data = REG_SET_FIELD(data, PCIE_CI_CNTL, CI_SLV_ORDERING_DIS, 1); | ||
| 225 | 230 | ||
| 231 | if (def != data) | ||
| 232 | WREG32_PCIE(smnPCIE_CI_CNTL, data); | ||
| 226 | } | 233 | } |
| 227 | 234 | ||
| 228 | const struct amdgpu_nbio_funcs nbio_v7_4_funcs = { | 235 | const struct amdgpu_nbio_funcs nbio_v7_4_funcs = { |
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c index 6c9a1b748ca7..0c6e7f9b143f 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #include "nbio/nbio_7_4_offset.h" | 34 | #include "nbio/nbio_7_4_offset.h" |
| 35 | 35 | ||
| 36 | MODULE_FIRMWARE("amdgpu/vega20_sos.bin"); | 36 | MODULE_FIRMWARE("amdgpu/vega20_sos.bin"); |
| 37 | MODULE_FIRMWARE("amdgpu/vega20_asd.bin"); | ||
| 37 | MODULE_FIRMWARE("amdgpu/vega20_ta.bin"); | 38 | MODULE_FIRMWARE("amdgpu/vega20_ta.bin"); |
| 38 | 39 | ||
| 39 | /* address block */ | 40 | /* address block */ |
| @@ -100,6 +101,7 @@ static int psp_v11_0_init_microcode(struct psp_context *psp) | |||
| 100 | char fw_name[30]; | 101 | char fw_name[30]; |
| 101 | int err = 0; | 102 | int err = 0; |
| 102 | const struct psp_firmware_header_v1_0 *sos_hdr; | 103 | const struct psp_firmware_header_v1_0 *sos_hdr; |
| 104 | const struct psp_firmware_header_v1_0 *asd_hdr; | ||
| 103 | const struct ta_firmware_header_v1_0 *ta_hdr; | 105 | const struct ta_firmware_header_v1_0 *ta_hdr; |
| 104 | 106 | ||
| 105 | DRM_DEBUG("\n"); | 107 | DRM_DEBUG("\n"); |
| @@ -132,14 +134,30 @@ static int psp_v11_0_init_microcode(struct psp_context *psp) | |||
| 132 | adev->psp.sos_start_addr = (uint8_t *)adev->psp.sys_start_addr + | 134 | adev->psp.sos_start_addr = (uint8_t *)adev->psp.sys_start_addr + |
| 133 | le32_to_cpu(sos_hdr->sos_offset_bytes); | 135 | le32_to_cpu(sos_hdr->sos_offset_bytes); |
| 134 | 136 | ||
| 137 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_asd.bin", chip_name); | ||
| 138 | err = request_firmware(&adev->psp.asd_fw, fw_name, adev->dev); | ||
| 139 | if (err) | ||
| 140 | goto out1; | ||
| 141 | |||
| 142 | err = amdgpu_ucode_validate(adev->psp.asd_fw); | ||
| 143 | if (err) | ||
| 144 | goto out1; | ||
| 145 | |||
| 146 | asd_hdr = (const struct psp_firmware_header_v1_0 *)adev->psp.asd_fw->data; | ||
| 147 | adev->psp.asd_fw_version = le32_to_cpu(asd_hdr->header.ucode_version); | ||
| 148 | adev->psp.asd_feature_version = le32_to_cpu(asd_hdr->ucode_feature_version); | ||
| 149 | adev->psp.asd_ucode_size = le32_to_cpu(asd_hdr->header.ucode_size_bytes); | ||
| 150 | adev->psp.asd_start_addr = (uint8_t *)asd_hdr + | ||
| 151 | le32_to_cpu(asd_hdr->header.ucode_array_offset_bytes); | ||
| 152 | |||
| 135 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ta.bin", chip_name); | 153 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ta.bin", chip_name); |
| 136 | err = request_firmware(&adev->psp.ta_fw, fw_name, adev->dev); | 154 | err = request_firmware(&adev->psp.ta_fw, fw_name, adev->dev); |
| 137 | if (err) | 155 | if (err) |
| 138 | goto out; | 156 | goto out2; |
| 139 | 157 | ||
| 140 | err = amdgpu_ucode_validate(adev->psp.ta_fw); | 158 | err = amdgpu_ucode_validate(adev->psp.ta_fw); |
| 141 | if (err) | 159 | if (err) |
| 142 | goto out; | 160 | goto out2; |
| 143 | 161 | ||
| 144 | ta_hdr = (const struct ta_firmware_header_v1_0 *)adev->psp.ta_fw->data; | 162 | ta_hdr = (const struct ta_firmware_header_v1_0 *)adev->psp.ta_fw->data; |
| 145 | adev->psp.ta_xgmi_ucode_version = le32_to_cpu(ta_hdr->ta_xgmi_ucode_version); | 163 | adev->psp.ta_xgmi_ucode_version = le32_to_cpu(ta_hdr->ta_xgmi_ucode_version); |
| @@ -148,14 +166,18 @@ static int psp_v11_0_init_microcode(struct psp_context *psp) | |||
| 148 | le32_to_cpu(ta_hdr->header.ucode_array_offset_bytes); | 166 | le32_to_cpu(ta_hdr->header.ucode_array_offset_bytes); |
| 149 | 167 | ||
| 150 | return 0; | 168 | return 0; |
| 169 | |||
| 170 | out2: | ||
| 171 | release_firmware(adev->psp.ta_fw); | ||
| 172 | adev->psp.ta_fw = NULL; | ||
| 173 | out1: | ||
| 174 | release_firmware(adev->psp.asd_fw); | ||
| 175 | adev->psp.asd_fw = NULL; | ||
| 151 | out: | 176 | out: |
| 152 | if (err) { | 177 | dev_err(adev->dev, |
| 153 | dev_err(adev->dev, | 178 | "psp v11.0: Failed to load firmware \"%s\"\n", fw_name); |
| 154 | "psp v11.0: Failed to load firmware \"%s\"\n", | 179 | release_firmware(adev->psp.sos_fw); |
| 155 | fw_name); | 180 | adev->psp.sos_fw = NULL; |
| 156 | release_firmware(adev->psp.sos_fw); | ||
| 157 | adev->psp.sos_fw = NULL; | ||
| 158 | } | ||
| 159 | 181 | ||
| 160 | return err; | 182 | return err; |
| 161 | } | 183 | } |
| @@ -291,6 +313,13 @@ static int psp_v11_0_ring_init(struct psp_context *psp, | |||
| 291 | return 0; | 313 | return 0; |
| 292 | } | 314 | } |
| 293 | 315 | ||
| 316 | static bool psp_v11_0_support_vmr_ring(struct psp_context *psp) | ||
| 317 | { | ||
| 318 | if (amdgpu_sriov_vf(psp->adev) && psp->sos_fw_version > 0x80045) | ||
| 319 | return true; | ||
| 320 | return false; | ||
| 321 | } | ||
| 322 | |||
| 294 | static int psp_v11_0_ring_create(struct psp_context *psp, | 323 | static int psp_v11_0_ring_create(struct psp_context *psp, |
| 295 | enum psp_ring_type ring_type) | 324 | enum psp_ring_type ring_type) |
| 296 | { | 325 | { |
| @@ -299,7 +328,7 @@ static int psp_v11_0_ring_create(struct psp_context *psp, | |||
| 299 | struct psp_ring *ring = &psp->km_ring; | 328 | struct psp_ring *ring = &psp->km_ring; |
| 300 | struct amdgpu_device *adev = psp->adev; | 329 | struct amdgpu_device *adev = psp->adev; |
| 301 | 330 | ||
| 302 | if (psp_support_vmr_ring(psp)) { | 331 | if (psp_v11_0_support_vmr_ring(psp)) { |
| 303 | /* Write low address of the ring to C2PMSG_102 */ | 332 | /* Write low address of the ring to C2PMSG_102 */ |
| 304 | psp_ring_reg = lower_32_bits(ring->ring_mem_mc_addr); | 333 | psp_ring_reg = lower_32_bits(ring->ring_mem_mc_addr); |
| 305 | WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_102, psp_ring_reg); | 334 | WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_102, psp_ring_reg); |
| @@ -351,7 +380,7 @@ static int psp_v11_0_ring_stop(struct psp_context *psp, | |||
| 351 | struct amdgpu_device *adev = psp->adev; | 380 | struct amdgpu_device *adev = psp->adev; |
| 352 | 381 | ||
| 353 | /* Write the ring destroy command*/ | 382 | /* Write the ring destroy command*/ |
| 354 | if (psp_support_vmr_ring(psp)) | 383 | if (psp_v11_0_support_vmr_ring(psp)) |
| 355 | WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_101, | 384 | WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_101, |
| 356 | GFX_CTRL_CMD_ID_DESTROY_GPCOM_RING); | 385 | GFX_CTRL_CMD_ID_DESTROY_GPCOM_RING); |
| 357 | else | 386 | else |
| @@ -362,7 +391,7 @@ static int psp_v11_0_ring_stop(struct psp_context *psp, | |||
| 362 | mdelay(20); | 391 | mdelay(20); |
| 363 | 392 | ||
| 364 | /* Wait for response flag (bit 31) */ | 393 | /* Wait for response flag (bit 31) */ |
| 365 | if (psp_support_vmr_ring(psp)) | 394 | if (psp_v11_0_support_vmr_ring(psp)) |
| 366 | ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_101), | 395 | ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_101), |
| 367 | 0x80000000, 0x80000000, false); | 396 | 0x80000000, 0x80000000, false); |
| 368 | else | 397 | else |
| @@ -406,7 +435,7 @@ static int psp_v11_0_cmd_submit(struct psp_context *psp, | |||
| 406 | uint32_t rb_frame_size_dw = sizeof(struct psp_gfx_rb_frame) / 4; | 435 | uint32_t rb_frame_size_dw = sizeof(struct psp_gfx_rb_frame) / 4; |
| 407 | 436 | ||
| 408 | /* KM (GPCOM) prepare write pointer */ | 437 | /* KM (GPCOM) prepare write pointer */ |
| 409 | if (psp_support_vmr_ring(psp)) | 438 | if (psp_v11_0_support_vmr_ring(psp)) |
| 410 | psp_write_ptr_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_102); | 439 | psp_write_ptr_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_102); |
| 411 | else | 440 | else |
| 412 | psp_write_ptr_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_67); | 441 | psp_write_ptr_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_67); |
| @@ -438,7 +467,7 @@ static int psp_v11_0_cmd_submit(struct psp_context *psp, | |||
| 438 | 467 | ||
| 439 | /* Update the write Pointer in DWORDs */ | 468 | /* Update the write Pointer in DWORDs */ |
| 440 | psp_write_ptr_reg = (psp_write_ptr_reg + rb_frame_size_dw) % ring_size_dw; | 469 | psp_write_ptr_reg = (psp_write_ptr_reg + rb_frame_size_dw) % ring_size_dw; |
| 441 | if (psp_support_vmr_ring(psp)) { | 470 | if (psp_v11_0_support_vmr_ring(psp)) { |
| 442 | WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_102, psp_write_ptr_reg); | 471 | WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_102, psp_write_ptr_reg); |
| 443 | WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_101, GFX_CTRL_CMD_ID_CONSUME_CMD); | 472 | WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_101, GFX_CTRL_CMD_ID_CONSUME_CMD); |
| 444 | } else | 473 | } else |
| @@ -680,7 +709,7 @@ static int psp_v11_0_xgmi_set_topology_info(struct psp_context *psp, | |||
| 680 | return psp_xgmi_invoke(psp, TA_COMMAND_XGMI__SET_TOPOLOGY_INFO); | 709 | return psp_xgmi_invoke(psp, TA_COMMAND_XGMI__SET_TOPOLOGY_INFO); |
| 681 | } | 710 | } |
| 682 | 711 | ||
| 683 | static u64 psp_v11_0_xgmi_get_hive_id(struct psp_context *psp) | 712 | static int psp_v11_0_xgmi_get_hive_id(struct psp_context *psp, uint64_t *hive_id) |
| 684 | { | 713 | { |
| 685 | struct ta_xgmi_shared_memory *xgmi_cmd; | 714 | struct ta_xgmi_shared_memory *xgmi_cmd; |
| 686 | int ret; | 715 | int ret; |
| @@ -693,12 +722,14 @@ static u64 psp_v11_0_xgmi_get_hive_id(struct psp_context *psp) | |||
| 693 | /* Invoke xgmi ta to get hive id */ | 722 | /* Invoke xgmi ta to get hive id */ |
| 694 | ret = psp_xgmi_invoke(psp, xgmi_cmd->cmd_id); | 723 | ret = psp_xgmi_invoke(psp, xgmi_cmd->cmd_id); |
| 695 | if (ret) | 724 | if (ret) |
| 696 | return 0; | 725 | return ret; |
| 697 | else | 726 | |
| 698 | return xgmi_cmd->xgmi_out_message.get_hive_id.hive_id; | 727 | *hive_id = xgmi_cmd->xgmi_out_message.get_hive_id.hive_id; |
| 728 | |||
| 729 | return 0; | ||
| 699 | } | 730 | } |
| 700 | 731 | ||
| 701 | static u64 psp_v11_0_xgmi_get_node_id(struct psp_context *psp) | 732 | static int psp_v11_0_xgmi_get_node_id(struct psp_context *psp, uint64_t *node_id) |
| 702 | { | 733 | { |
| 703 | struct ta_xgmi_shared_memory *xgmi_cmd; | 734 | struct ta_xgmi_shared_memory *xgmi_cmd; |
| 704 | int ret; | 735 | int ret; |
| @@ -711,9 +742,11 @@ static u64 psp_v11_0_xgmi_get_node_id(struct psp_context *psp) | |||
| 711 | /* Invoke xgmi ta to get the node id */ | 742 | /* Invoke xgmi ta to get the node id */ |
| 712 | ret = psp_xgmi_invoke(psp, xgmi_cmd->cmd_id); | 743 | ret = psp_xgmi_invoke(psp, xgmi_cmd->cmd_id); |
| 713 | if (ret) | 744 | if (ret) |
| 714 | return 0; | 745 | return ret; |
| 715 | else | 746 | |
| 716 | return xgmi_cmd->xgmi_out_message.get_node_id.node_id; | 747 | *node_id = xgmi_cmd->xgmi_out_message.get_node_id.node_id; |
| 748 | |||
| 749 | return 0; | ||
| 717 | } | 750 | } |
| 718 | 751 | ||
| 719 | static const struct psp_funcs psp_v11_0_funcs = { | 752 | static const struct psp_funcs psp_v11_0_funcs = { |
| @@ -732,6 +765,7 @@ static const struct psp_funcs psp_v11_0_funcs = { | |||
| 732 | .xgmi_set_topology_info = psp_v11_0_xgmi_set_topology_info, | 765 | .xgmi_set_topology_info = psp_v11_0_xgmi_set_topology_info, |
| 733 | .xgmi_get_hive_id = psp_v11_0_xgmi_get_hive_id, | 766 | .xgmi_get_hive_id = psp_v11_0_xgmi_get_hive_id, |
| 734 | .xgmi_get_node_id = psp_v11_0_xgmi_get_node_id, | 767 | .xgmi_get_node_id = psp_v11_0_xgmi_get_node_id, |
| 768 | .support_vmr_ring = psp_v11_0_support_vmr_ring, | ||
| 735 | }; | 769 | }; |
| 736 | 770 | ||
| 737 | void psp_v11_0_set_psp_funcs(struct psp_context *psp) | 771 | void psp_v11_0_set_psp_funcs(struct psp_context *psp) |
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c index 7357fd56e614..79694ff16969 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c | |||
| @@ -240,8 +240,11 @@ static int psp_v3_1_bootloader_load_sos(struct psp_context *psp) | |||
| 240 | * are already been loaded. | 240 | * are already been loaded. |
| 241 | */ | 241 | */ |
| 242 | sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81); | 242 | sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81); |
| 243 | if (sol_reg) | 243 | if (sol_reg) { |
| 244 | psp->sos_fw_version = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_58); | ||
| 245 | printk("sos fw version = 0x%x.\n", psp->sos_fw_version); | ||
| 244 | return 0; | 246 | return 0; |
| 247 | } | ||
| 245 | 248 | ||
| 246 | /* Wait for bootloader to signify that is ready having bit 31 of C2PMSG_35 set to 1 */ | 249 | /* Wait for bootloader to signify that is ready having bit 31 of C2PMSG_35 set to 1 */ |
| 247 | ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_35), | 250 | ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_35), |
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c index 4b6d3e5c821f..fd0bfe140ee0 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c | |||
| @@ -1458,8 +1458,7 @@ static bool sdma_v4_0_fw_support_paging_queue(struct amdgpu_device *adev) | |||
| 1458 | /*return fw_version >= 31;*/ | 1458 | /*return fw_version >= 31;*/ |
| 1459 | return false; | 1459 | return false; |
| 1460 | case CHIP_VEGA20: | 1460 | case CHIP_VEGA20: |
| 1461 | /*return fw_version >= 115;*/ | 1461 | return fw_version >= 123; |
| 1462 | return false; | ||
| 1463 | default: | 1462 | default: |
| 1464 | return false; | 1463 | return false; |
| 1465 | } | 1464 | } |
| @@ -1706,13 +1705,15 @@ static int sdma_v4_0_process_trap_irq(struct amdgpu_device *adev, | |||
| 1706 | amdgpu_fence_process(&adev->sdma.instance[instance].ring); | 1705 | amdgpu_fence_process(&adev->sdma.instance[instance].ring); |
| 1707 | break; | 1706 | break; |
| 1708 | case 1: | 1707 | case 1: |
| 1709 | /* XXX compute */ | 1708 | if (adev->asic_type == CHIP_VEGA20) |
| 1709 | amdgpu_fence_process(&adev->sdma.instance[instance].page); | ||
| 1710 | break; | 1710 | break; |
| 1711 | case 2: | 1711 | case 2: |
| 1712 | /* XXX compute */ | 1712 | /* XXX compute */ |
| 1713 | break; | 1713 | break; |
| 1714 | case 3: | 1714 | case 3: |
| 1715 | amdgpu_fence_process(&adev->sdma.instance[instance].page); | 1715 | if (adev->asic_type != CHIP_VEGA20) |
| 1716 | amdgpu_fence_process(&adev->sdma.instance[instance].page); | ||
| 1716 | break; | 1717 | break; |
| 1717 | } | 1718 | } |
| 1718 | return 0; | 1719 | return 0; |
diff --git a/drivers/gpu/drm/amd/amdgpu/soc15_common.h b/drivers/gpu/drm/amd/amdgpu/soc15_common.h index 958b10a57073..49c262540940 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc15_common.h +++ b/drivers/gpu/drm/amd/amdgpu/soc15_common.h | |||
| @@ -49,14 +49,19 @@ | |||
| 49 | 49 | ||
| 50 | #define SOC15_WAIT_ON_RREG(ip, inst, reg, expected_value, mask, ret) \ | 50 | #define SOC15_WAIT_ON_RREG(ip, inst, reg, expected_value, mask, ret) \ |
| 51 | do { \ | 51 | do { \ |
| 52 | uint32_t old_ = 0; \ | ||
| 52 | uint32_t tmp_ = RREG32(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg); \ | 53 | uint32_t tmp_ = RREG32(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg); \ |
| 53 | uint32_t loop = adev->usec_timeout; \ | 54 | uint32_t loop = adev->usec_timeout; \ |
| 54 | while ((tmp_ & (mask)) != (expected_value)) { \ | 55 | while ((tmp_ & (mask)) != (expected_value)) { \ |
| 55 | udelay(2); \ | 56 | if (old_ != tmp_) { \ |
| 57 | loop = adev->usec_timeout; \ | ||
| 58 | old_ = tmp_; \ | ||
| 59 | } else \ | ||
| 60 | udelay(1); \ | ||
| 56 | tmp_ = RREG32(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg); \ | 61 | tmp_ = RREG32(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg); \ |
| 57 | loop--; \ | 62 | loop--; \ |
| 58 | if (!loop) { \ | 63 | if (!loop) { \ |
| 59 | DRM_ERROR("Register(%d) [%s] failed to reach value 0x%08x != 0x%08x\n", \ | 64 | DRM_WARN("Register(%d) [%s] failed to reach value 0x%08x != 0x%08x\n", \ |
| 60 | inst, #reg, (unsigned)expected_value, (unsigned)(tmp_ & (mask))); \ | 65 | inst, #reg, (unsigned)expected_value, (unsigned)(tmp_ & (mask))); \ |
| 61 | ret = -ETIMEDOUT; \ | 66 | ret = -ETIMEDOUT; \ |
| 62 | break; \ | 67 | break; \ |
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c index 089645e78f98..aef924026a28 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c | |||
| @@ -435,7 +435,7 @@ static int uvd_v7_0_sw_init(void *handle) | |||
| 435 | continue; | 435 | continue; |
| 436 | if (!amdgpu_sriov_vf(adev)) { | 436 | if (!amdgpu_sriov_vf(adev)) { |
| 437 | ring = &adev->uvd.inst[j].ring; | 437 | ring = &adev->uvd.inst[j].ring; |
| 438 | sprintf(ring->name, "uvd<%d>", j); | 438 | sprintf(ring->name, "uvd_%d", ring->me); |
| 439 | r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.inst[j].irq, 0); | 439 | r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.inst[j].irq, 0); |
| 440 | if (r) | 440 | if (r) |
| 441 | return r; | 441 | return r; |
| @@ -443,7 +443,7 @@ static int uvd_v7_0_sw_init(void *handle) | |||
| 443 | 443 | ||
| 444 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) { | 444 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) { |
| 445 | ring = &adev->uvd.inst[j].ring_enc[i]; | 445 | ring = &adev->uvd.inst[j].ring_enc[i]; |
| 446 | sprintf(ring->name, "uvd_enc%d<%d>", i, j); | 446 | sprintf(ring->name, "uvd_enc_%d.%d", ring->me, i); |
| 447 | if (amdgpu_sriov_vf(adev)) { | 447 | if (amdgpu_sriov_vf(adev)) { |
| 448 | ring->use_doorbell = true; | 448 | ring->use_doorbell = true; |
| 449 | 449 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c index 4f8352044563..89bb2fef90eb 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | |||
| @@ -214,7 +214,8 @@ static int vcn_v1_0_hw_fini(void *handle) | |||
| 214 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 214 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 215 | struct amdgpu_ring *ring = &adev->vcn.ring_dec; | 215 | struct amdgpu_ring *ring = &adev->vcn.ring_dec; |
| 216 | 216 | ||
| 217 | if (RREG32_SOC15(VCN, 0, mmUVD_STATUS)) | 217 | if ((adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) || |
| 218 | RREG32_SOC15(VCN, 0, mmUVD_STATUS)) | ||
| 218 | vcn_v1_0_set_powergating_state(adev, AMD_PG_STATE_GATE); | 219 | vcn_v1_0_set_powergating_state(adev, AMD_PG_STATE_GATE); |
| 219 | 220 | ||
| 220 | ring->sched.ready = false; | 221 | ring->sched.ready = false; |
| @@ -1087,7 +1088,8 @@ static int vcn_v1_0_start_dpg_mode(struct amdgpu_device *adev) | |||
| 1087 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_RB_CNTL), 0, | 1088 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_RB_CNTL), 0, |
| 1088 | ~UVD_RBC_RB_CNTL__RB_NO_FETCH_MASK); | 1089 | ~UVD_RBC_RB_CNTL__RB_NO_FETCH_MASK); |
| 1089 | 1090 | ||
| 1090 | /* initialize wptr */ | 1091 | /* initialize JPEG wptr */ |
| 1092 | ring = &adev->vcn.ring_jpeg; | ||
| 1091 | ring->wptr = RREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_WPTR); | 1093 | ring->wptr = RREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_WPTR); |
| 1092 | 1094 | ||
| 1093 | /* copy patch commands to the jpeg ring */ | 1095 | /* copy patch commands to the jpeg ring */ |
| @@ -1159,21 +1161,29 @@ static int vcn_v1_0_stop_spg_mode(struct amdgpu_device *adev) | |||
| 1159 | static int vcn_v1_0_stop_dpg_mode(struct amdgpu_device *adev) | 1161 | static int vcn_v1_0_stop_dpg_mode(struct amdgpu_device *adev) |
| 1160 | { | 1162 | { |
| 1161 | int ret_code = 0; | 1163 | int ret_code = 0; |
| 1164 | uint32_t tmp; | ||
| 1162 | 1165 | ||
| 1163 | /* Wait for power status to be UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF */ | 1166 | /* Wait for power status to be UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF */ |
| 1164 | SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS, | 1167 | SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS, |
| 1165 | UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF, | 1168 | UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF, |
| 1166 | UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code); | 1169 | UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code); |
| 1167 | 1170 | ||
| 1168 | if (!ret_code) { | 1171 | /* wait for read ptr to be equal to write ptr */ |
| 1169 | int tmp = RREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR) & 0x7FFFFFFF; | 1172 | tmp = RREG32_SOC15(UVD, 0, mmUVD_RB_WPTR); |
| 1170 | /* wait for read ptr to be equal to write ptr */ | 1173 | SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_RB_RPTR, tmp, 0xFFFFFFFF, ret_code); |
| 1171 | SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_RBC_RB_RPTR, tmp, 0xFFFFFFFF, ret_code); | ||
| 1172 | 1174 | ||
| 1173 | SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS, | 1175 | tmp = RREG32_SOC15(UVD, 0, mmUVD_RB_WPTR2); |
| 1174 | UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF, | 1176 | SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_RB_RPTR2, tmp, 0xFFFFFFFF, ret_code); |
| 1175 | UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code); | 1177 | |
| 1176 | } | 1178 | tmp = RREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_WPTR); |
| 1179 | SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_JRBC_RB_RPTR, tmp, 0xFFFFFFFF, ret_code); | ||
| 1180 | |||
| 1181 | tmp = RREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR) & 0x7FFFFFFF; | ||
| 1182 | SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_RBC_RB_RPTR, tmp, 0xFFFFFFFF, ret_code); | ||
| 1183 | |||
| 1184 | SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS, | ||
| 1185 | UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF, | ||
| 1186 | UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code); | ||
| 1177 | 1187 | ||
| 1178 | /* disable dynamic power gating mode */ | 1188 | /* disable dynamic power gating mode */ |
| 1179 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_POWER_STATUS), 0, | 1189 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_POWER_STATUS), 0, |
diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c index ff2906c215fa..77e367459101 100644 --- a/drivers/gpu/drm/amd/amdgpu/vi.c +++ b/drivers/gpu/drm/amd/amdgpu/vi.c | |||
| @@ -87,9 +87,9 @@ static u32 vi_pcie_rreg(struct amdgpu_device *adev, u32 reg) | |||
| 87 | u32 r; | 87 | u32 r; |
| 88 | 88 | ||
| 89 | spin_lock_irqsave(&adev->pcie_idx_lock, flags); | 89 | spin_lock_irqsave(&adev->pcie_idx_lock, flags); |
| 90 | WREG32(mmPCIE_INDEX, reg); | 90 | WREG32_NO_KIQ(mmPCIE_INDEX, reg); |
| 91 | (void)RREG32(mmPCIE_INDEX); | 91 | (void)RREG32_NO_KIQ(mmPCIE_INDEX); |
| 92 | r = RREG32(mmPCIE_DATA); | 92 | r = RREG32_NO_KIQ(mmPCIE_DATA); |
| 93 | spin_unlock_irqrestore(&adev->pcie_idx_lock, flags); | 93 | spin_unlock_irqrestore(&adev->pcie_idx_lock, flags); |
| 94 | return r; | 94 | return r; |
| 95 | } | 95 | } |
| @@ -99,10 +99,10 @@ static void vi_pcie_wreg(struct amdgpu_device *adev, u32 reg, u32 v) | |||
| 99 | unsigned long flags; | 99 | unsigned long flags; |
| 100 | 100 | ||
| 101 | spin_lock_irqsave(&adev->pcie_idx_lock, flags); | 101 | spin_lock_irqsave(&adev->pcie_idx_lock, flags); |
| 102 | WREG32(mmPCIE_INDEX, reg); | 102 | WREG32_NO_KIQ(mmPCIE_INDEX, reg); |
| 103 | (void)RREG32(mmPCIE_INDEX); | 103 | (void)RREG32_NO_KIQ(mmPCIE_INDEX); |
| 104 | WREG32(mmPCIE_DATA, v); | 104 | WREG32_NO_KIQ(mmPCIE_DATA, v); |
| 105 | (void)RREG32(mmPCIE_DATA); | 105 | (void)RREG32_NO_KIQ(mmPCIE_DATA); |
| 106 | spin_unlock_irqrestore(&adev->pcie_idx_lock, flags); | 106 | spin_unlock_irqrestore(&adev->pcie_idx_lock, flags); |
| 107 | } | 107 | } |
| 108 | 108 | ||
| @@ -123,8 +123,8 @@ static void vi_smc_wreg(struct amdgpu_device *adev, u32 reg, u32 v) | |||
| 123 | unsigned long flags; | 123 | unsigned long flags; |
| 124 | 124 | ||
| 125 | spin_lock_irqsave(&adev->smc_idx_lock, flags); | 125 | spin_lock_irqsave(&adev->smc_idx_lock, flags); |
| 126 | WREG32(mmSMC_IND_INDEX_11, (reg)); | 126 | WREG32_NO_KIQ(mmSMC_IND_INDEX_11, (reg)); |
| 127 | WREG32(mmSMC_IND_DATA_11, (v)); | 127 | WREG32_NO_KIQ(mmSMC_IND_DATA_11, (v)); |
| 128 | spin_unlock_irqrestore(&adev->smc_idx_lock, flags); | 128 | spin_unlock_irqrestore(&adev->smc_idx_lock, flags); |
| 129 | } | 129 | } |
| 130 | 130 | ||
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index be68752c3469..083bd8114db1 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | |||
| @@ -1623,8 +1623,8 @@ static int kfd_ioctl_import_dmabuf(struct file *filep, | |||
| 1623 | return -EINVAL; | 1623 | return -EINVAL; |
| 1624 | 1624 | ||
| 1625 | dmabuf = dma_buf_get(args->dmabuf_fd); | 1625 | dmabuf = dma_buf_get(args->dmabuf_fd); |
| 1626 | if (!dmabuf) | 1626 | if (IS_ERR(dmabuf)) |
| 1627 | return -EINVAL; | 1627 | return PTR_ERR(dmabuf); |
| 1628 | 1628 | ||
| 1629 | mutex_lock(&p->mutex); | 1629 | mutex_lock(&p->mutex); |
| 1630 | 1630 | ||
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 d01315965af0..a9a28dbc3e24 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | |||
| @@ -331,12 +331,29 @@ static void dm_crtc_high_irq(void *interrupt_params) | |||
| 331 | struct common_irq_params *irq_params = interrupt_params; | 331 | struct common_irq_params *irq_params = interrupt_params; |
| 332 | struct amdgpu_device *adev = irq_params->adev; | 332 | struct amdgpu_device *adev = irq_params->adev; |
| 333 | struct amdgpu_crtc *acrtc; | 333 | struct amdgpu_crtc *acrtc; |
| 334 | struct dm_crtc_state *acrtc_state; | ||
| 334 | 335 | ||
| 335 | acrtc = get_crtc_by_otg_inst(adev, irq_params->irq_src - IRQ_TYPE_VBLANK); | 336 | acrtc = get_crtc_by_otg_inst(adev, irq_params->irq_src - IRQ_TYPE_VBLANK); |
| 336 | 337 | ||
| 337 | if (acrtc) { | 338 | if (acrtc) { |
| 338 | drm_crtc_handle_vblank(&acrtc->base); | 339 | drm_crtc_handle_vblank(&acrtc->base); |
| 339 | amdgpu_dm_crtc_handle_crc_irq(&acrtc->base); | 340 | amdgpu_dm_crtc_handle_crc_irq(&acrtc->base); |
| 341 | |||
| 342 | acrtc_state = to_dm_crtc_state(acrtc->base.state); | ||
| 343 | |||
| 344 | if (acrtc_state->stream && | ||
| 345 | acrtc_state->vrr_params.supported && | ||
| 346 | acrtc_state->freesync_config.state == VRR_STATE_ACTIVE_VARIABLE) { | ||
| 347 | mod_freesync_handle_v_update( | ||
| 348 | adev->dm.freesync_module, | ||
| 349 | acrtc_state->stream, | ||
| 350 | &acrtc_state->vrr_params); | ||
| 351 | |||
| 352 | dc_stream_adjust_vmin_vmax( | ||
| 353 | adev->dm.dc, | ||
| 354 | acrtc_state->stream, | ||
| 355 | &acrtc_state->vrr_params.adjust); | ||
| 356 | } | ||
| 340 | } | 357 | } |
| 341 | } | 358 | } |
| 342 | 359 | ||
| @@ -3009,7 +3026,7 @@ dm_crtc_duplicate_state(struct drm_crtc *crtc) | |||
| 3009 | dc_stream_retain(state->stream); | 3026 | dc_stream_retain(state->stream); |
| 3010 | } | 3027 | } |
| 3011 | 3028 | ||
| 3012 | state->adjust = cur->adjust; | 3029 | state->vrr_params = cur->vrr_params; |
| 3013 | state->vrr_infopacket = cur->vrr_infopacket; | 3030 | state->vrr_infopacket = cur->vrr_infopacket; |
| 3014 | state->abm_level = cur->abm_level; | 3031 | state->abm_level = cur->abm_level; |
| 3015 | state->vrr_supported = cur->vrr_supported; | 3032 | state->vrr_supported = cur->vrr_supported; |
| @@ -3628,10 +3645,20 @@ static int dm_plane_atomic_check(struct drm_plane *plane, | |||
| 3628 | static int dm_plane_atomic_async_check(struct drm_plane *plane, | 3645 | static int dm_plane_atomic_async_check(struct drm_plane *plane, |
| 3629 | struct drm_plane_state *new_plane_state) | 3646 | struct drm_plane_state *new_plane_state) |
| 3630 | { | 3647 | { |
| 3648 | struct drm_plane_state *old_plane_state = | ||
| 3649 | drm_atomic_get_old_plane_state(new_plane_state->state, plane); | ||
| 3650 | |||
| 3631 | /* Only support async updates on cursor planes. */ | 3651 | /* Only support async updates on cursor planes. */ |
| 3632 | if (plane->type != DRM_PLANE_TYPE_CURSOR) | 3652 | if (plane->type != DRM_PLANE_TYPE_CURSOR) |
| 3633 | return -EINVAL; | 3653 | return -EINVAL; |
| 3634 | 3654 | ||
| 3655 | /* | ||
| 3656 | * DRM calls prepare_fb and cleanup_fb on new_plane_state for | ||
| 3657 | * async commits so don't allow fb changes. | ||
| 3658 | */ | ||
| 3659 | if (old_plane_state->fb != new_plane_state->fb) | ||
| 3660 | return -EINVAL; | ||
| 3661 | |||
| 3635 | return 0; | 3662 | return 0; |
| 3636 | } | 3663 | } |
| 3637 | 3664 | ||
| @@ -4445,9 +4472,11 @@ struct dc_stream_status *dc_state_get_stream_status( | |||
| 4445 | static void update_freesync_state_on_stream( | 4472 | static void update_freesync_state_on_stream( |
| 4446 | struct amdgpu_display_manager *dm, | 4473 | struct amdgpu_display_manager *dm, |
| 4447 | struct dm_crtc_state *new_crtc_state, | 4474 | struct dm_crtc_state *new_crtc_state, |
| 4448 | struct dc_stream_state *new_stream) | 4475 | struct dc_stream_state *new_stream, |
| 4476 | struct dc_plane_state *surface, | ||
| 4477 | u32 flip_timestamp_in_us) | ||
| 4449 | { | 4478 | { |
| 4450 | struct mod_vrr_params vrr = {0}; | 4479 | struct mod_vrr_params vrr_params = new_crtc_state->vrr_params; |
| 4451 | struct dc_info_packet vrr_infopacket = {0}; | 4480 | struct dc_info_packet vrr_infopacket = {0}; |
| 4452 | struct mod_freesync_config config = new_crtc_state->freesync_config; | 4481 | struct mod_freesync_config config = new_crtc_state->freesync_config; |
| 4453 | 4482 | ||
| @@ -4474,43 +4503,52 @@ static void update_freesync_state_on_stream( | |||
| 4474 | 4503 | ||
| 4475 | mod_freesync_build_vrr_params(dm->freesync_module, | 4504 | mod_freesync_build_vrr_params(dm->freesync_module, |
| 4476 | new_stream, | 4505 | new_stream, |
| 4477 | &config, &vrr); | 4506 | &config, &vrr_params); |
| 4507 | |||
| 4508 | if (surface) { | ||
| 4509 | mod_freesync_handle_preflip( | ||
| 4510 | dm->freesync_module, | ||
| 4511 | surface, | ||
| 4512 | new_stream, | ||
| 4513 | flip_timestamp_in_us, | ||
| 4514 | &vrr_params); | ||
| 4515 | } | ||
| 4478 | 4516 | ||
| 4479 | mod_freesync_build_vrr_infopacket( | 4517 | mod_freesync_build_vrr_infopacket( |
| 4480 | dm->freesync_module, | 4518 | dm->freesync_module, |
| 4481 | new_stream, | 4519 | new_stream, |
| 4482 | &vrr, | 4520 | &vrr_params, |
| 4483 | PACKET_TYPE_VRR, | 4521 | PACKET_TYPE_VRR, |
| 4484 | TRANSFER_FUNC_UNKNOWN, | 4522 | TRANSFER_FUNC_UNKNOWN, |
| 4485 | &vrr_infopacket); | 4523 | &vrr_infopacket); |
| 4486 | 4524 | ||
| 4487 | new_crtc_state->freesync_timing_changed = | 4525 | new_crtc_state->freesync_timing_changed = |
| 4488 | (memcmp(&new_crtc_state->adjust, | 4526 | (memcmp(&new_crtc_state->vrr_params.adjust, |
| 4489 | &vrr.adjust, | 4527 | &vrr_params.adjust, |
| 4490 | sizeof(vrr.adjust)) != 0); | 4528 | sizeof(vrr_params.adjust)) != 0); |
| 4491 | 4529 | ||
| 4492 | new_crtc_state->freesync_vrr_info_changed = | 4530 | new_crtc_state->freesync_vrr_info_changed = |
| 4493 | (memcmp(&new_crtc_state->vrr_infopacket, | 4531 | (memcmp(&new_crtc_state->vrr_infopacket, |
| 4494 | &vrr_infopacket, | 4532 | &vrr_infopacket, |
| 4495 | sizeof(vrr_infopacket)) != 0); | 4533 | sizeof(vrr_infopacket)) != 0); |
| 4496 | 4534 | ||
| 4497 | new_crtc_state->adjust = vrr.adjust; | 4535 | new_crtc_state->vrr_params = vrr_params; |
| 4498 | new_crtc_state->vrr_infopacket = vrr_infopacket; | 4536 | new_crtc_state->vrr_infopacket = vrr_infopacket; |
| 4499 | 4537 | ||
| 4500 | new_stream->adjust = new_crtc_state->adjust; | 4538 | new_stream->adjust = new_crtc_state->vrr_params.adjust; |
| 4501 | new_stream->vrr_infopacket = vrr_infopacket; | 4539 | new_stream->vrr_infopacket = vrr_infopacket; |
| 4502 | 4540 | ||
| 4503 | if (new_crtc_state->freesync_vrr_info_changed) | 4541 | if (new_crtc_state->freesync_vrr_info_changed) |
| 4504 | DRM_DEBUG_KMS("VRR packet update: crtc=%u enabled=%d state=%d", | 4542 | DRM_DEBUG_KMS("VRR packet update: crtc=%u enabled=%d state=%d", |
| 4505 | new_crtc_state->base.crtc->base.id, | 4543 | new_crtc_state->base.crtc->base.id, |
| 4506 | (int)new_crtc_state->base.vrr_enabled, | 4544 | (int)new_crtc_state->base.vrr_enabled, |
| 4507 | (int)vrr.state); | 4545 | (int)vrr_params.state); |
| 4508 | 4546 | ||
| 4509 | if (new_crtc_state->freesync_timing_changed) | 4547 | if (new_crtc_state->freesync_timing_changed) |
| 4510 | DRM_DEBUG_KMS("VRR timing update: crtc=%u min=%u max=%u\n", | 4548 | DRM_DEBUG_KMS("VRR timing update: crtc=%u min=%u max=%u\n", |
| 4511 | new_crtc_state->base.crtc->base.id, | 4549 | new_crtc_state->base.crtc->base.id, |
| 4512 | vrr.adjust.v_total_min, | 4550 | vrr_params.adjust.v_total_min, |
| 4513 | vrr.adjust.v_total_max); | 4551 | vrr_params.adjust.v_total_max); |
| 4514 | } | 4552 | } |
| 4515 | 4553 | ||
| 4516 | /* | 4554 | /* |
| @@ -4524,6 +4562,7 @@ static void amdgpu_dm_do_flip(struct drm_crtc *crtc, | |||
| 4524 | struct dc_state *state) | 4562 | struct dc_state *state) |
| 4525 | { | 4563 | { |
| 4526 | unsigned long flags; | 4564 | unsigned long flags; |
| 4565 | uint64_t timestamp_ns; | ||
| 4527 | uint32_t target_vblank; | 4566 | uint32_t target_vblank; |
| 4528 | int r, vpos, hpos; | 4567 | int r, vpos, hpos; |
| 4529 | struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); | 4568 | struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); |
| @@ -4537,6 +4576,7 @@ static void amdgpu_dm_do_flip(struct drm_crtc *crtc, | |||
| 4537 | struct dc_stream_update stream_update = {0}; | 4576 | struct dc_stream_update stream_update = {0}; |
| 4538 | struct dm_crtc_state *acrtc_state = to_dm_crtc_state(crtc->state); | 4577 | struct dm_crtc_state *acrtc_state = to_dm_crtc_state(crtc->state); |
| 4539 | struct dc_stream_status *stream_status; | 4578 | struct dc_stream_status *stream_status; |
| 4579 | struct dc_plane_state *surface; | ||
| 4540 | 4580 | ||
| 4541 | 4581 | ||
| 4542 | /* Prepare wait for target vblank early - before the fence-waits */ | 4582 | /* Prepare wait for target vblank early - before the fence-waits */ |
| @@ -4586,6 +4626,9 @@ static void amdgpu_dm_do_flip(struct drm_crtc *crtc, | |||
| 4586 | addr.address.grph.addr.high_part = upper_32_bits(afb->address); | 4626 | addr.address.grph.addr.high_part = upper_32_bits(afb->address); |
| 4587 | addr.flip_immediate = async_flip; | 4627 | addr.flip_immediate = async_flip; |
| 4588 | 4628 | ||
| 4629 | timestamp_ns = ktime_get_ns(); | ||
| 4630 | addr.flip_timestamp_in_us = div_u64(timestamp_ns, 1000); | ||
| 4631 | |||
| 4589 | 4632 | ||
| 4590 | if (acrtc->base.state->event) | 4633 | if (acrtc->base.state->event) |
| 4591 | prepare_flip_isr(acrtc); | 4634 | prepare_flip_isr(acrtc); |
| @@ -4599,8 +4642,10 @@ static void amdgpu_dm_do_flip(struct drm_crtc *crtc, | |||
| 4599 | return; | 4642 | return; |
| 4600 | } | 4643 | } |
| 4601 | 4644 | ||
| 4602 | surface_updates->surface = stream_status->plane_states[0]; | 4645 | surface = stream_status->plane_states[0]; |
| 4603 | if (!surface_updates->surface) { | 4646 | surface_updates->surface = surface; |
| 4647 | |||
| 4648 | if (!surface) { | ||
| 4604 | DRM_ERROR("No surface for CRTC: id=%d\n", | 4649 | DRM_ERROR("No surface for CRTC: id=%d\n", |
| 4605 | acrtc->crtc_id); | 4650 | acrtc->crtc_id); |
| 4606 | return; | 4651 | return; |
| @@ -4611,7 +4656,9 @@ static void amdgpu_dm_do_flip(struct drm_crtc *crtc, | |||
| 4611 | update_freesync_state_on_stream( | 4656 | update_freesync_state_on_stream( |
| 4612 | &adev->dm, | 4657 | &adev->dm, |
| 4613 | acrtc_state, | 4658 | acrtc_state, |
| 4614 | acrtc_state->stream); | 4659 | acrtc_state->stream, |
| 4660 | surface, | ||
| 4661 | addr.flip_timestamp_in_us); | ||
| 4615 | 4662 | ||
| 4616 | if (acrtc_state->freesync_timing_changed) | 4663 | if (acrtc_state->freesync_timing_changed) |
| 4617 | stream_update.adjust = | 4664 | stream_update.adjust = |
| @@ -4622,7 +4669,16 @@ static void amdgpu_dm_do_flip(struct drm_crtc *crtc, | |||
| 4622 | &acrtc_state->stream->vrr_infopacket; | 4669 | &acrtc_state->stream->vrr_infopacket; |
| 4623 | } | 4670 | } |
| 4624 | 4671 | ||
| 4672 | /* Update surface timing information. */ | ||
| 4673 | surface->time.time_elapsed_in_us[surface->time.index] = | ||
| 4674 | addr.flip_timestamp_in_us - surface->time.prev_update_time_in_us; | ||
| 4675 | surface->time.prev_update_time_in_us = addr.flip_timestamp_in_us; | ||
| 4676 | surface->time.index++; | ||
| 4677 | if (surface->time.index >= DC_PLANE_UPDATE_TIMES_MAX) | ||
| 4678 | surface->time.index = 0; | ||
| 4679 | |||
| 4625 | mutex_lock(&adev->dm.dc_lock); | 4680 | mutex_lock(&adev->dm.dc_lock); |
| 4681 | |||
| 4626 | dc_commit_updates_for_stream(adev->dm.dc, | 4682 | dc_commit_updates_for_stream(adev->dm.dc, |
| 4627 | surface_updates, | 4683 | surface_updates, |
| 4628 | 1, | 4684 | 1, |
| @@ -5314,6 +5370,7 @@ static void get_freesync_config_for_crtc( | |||
| 5314 | config.max_refresh_in_uhz = | 5370 | config.max_refresh_in_uhz = |
| 5315 | aconnector->max_vfreq * 1000000; | 5371 | aconnector->max_vfreq * 1000000; |
| 5316 | config.vsif_supported = true; | 5372 | config.vsif_supported = true; |
| 5373 | config.btr = true; | ||
| 5317 | } | 5374 | } |
| 5318 | 5375 | ||
| 5319 | new_crtc_state->freesync_config = config; | 5376 | new_crtc_state->freesync_config = config; |
| @@ -5324,8 +5381,8 @@ static void reset_freesync_config_for_crtc( | |||
| 5324 | { | 5381 | { |
| 5325 | new_crtc_state->vrr_supported = false; | 5382 | new_crtc_state->vrr_supported = false; |
| 5326 | 5383 | ||
| 5327 | memset(&new_crtc_state->adjust, 0, | 5384 | memset(&new_crtc_state->vrr_params, 0, |
| 5328 | sizeof(new_crtc_state->adjust)); | 5385 | sizeof(new_crtc_state->vrr_params)); |
| 5329 | memset(&new_crtc_state->vrr_infopacket, 0, | 5386 | memset(&new_crtc_state->vrr_infopacket, 0, |
| 5330 | sizeof(new_crtc_state->vrr_infopacket)); | 5387 | sizeof(new_crtc_state->vrr_infopacket)); |
| 5331 | } | 5388 | } |
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h index 25bb91ee80ba..fbd161ddc3f4 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | |||
| @@ -268,7 +268,7 @@ struct dm_crtc_state { | |||
| 268 | 268 | ||
| 269 | bool vrr_supported; | 269 | bool vrr_supported; |
| 270 | struct mod_freesync_config freesync_config; | 270 | struct mod_freesync_config freesync_config; |
| 271 | struct dc_crtc_timing_adjust adjust; | 271 | struct mod_vrr_params vrr_params; |
| 272 | struct dc_info_packet vrr_infopacket; | 272 | struct dc_info_packet vrr_infopacket; |
| 273 | 273 | ||
| 274 | int abm_level; | 274 | int abm_level; |
diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c index 751bb614fc0e..c513ab6f3843 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c | |||
| @@ -638,6 +638,7 @@ static enum bp_result get_ss_info_v4_1( | |||
| 638 | { | 638 | { |
| 639 | enum bp_result result = BP_RESULT_OK; | 639 | enum bp_result result = BP_RESULT_OK; |
| 640 | struct atom_display_controller_info_v4_1 *disp_cntl_tbl = NULL; | 640 | struct atom_display_controller_info_v4_1 *disp_cntl_tbl = NULL; |
| 641 | struct atom_smu_info_v3_3 *smu_info = NULL; | ||
| 641 | 642 | ||
| 642 | if (!ss_info) | 643 | if (!ss_info) |
| 643 | return BP_RESULT_BADINPUT; | 644 | return BP_RESULT_BADINPUT; |
| @@ -650,6 +651,7 @@ static enum bp_result get_ss_info_v4_1( | |||
| 650 | if (!disp_cntl_tbl) | 651 | if (!disp_cntl_tbl) |
| 651 | return BP_RESULT_BADBIOSTABLE; | 652 | return BP_RESULT_BADBIOSTABLE; |
| 652 | 653 | ||
| 654 | |||
| 653 | ss_info->type.STEP_AND_DELAY_INFO = false; | 655 | ss_info->type.STEP_AND_DELAY_INFO = false; |
| 654 | ss_info->spread_percentage_divider = 1000; | 656 | ss_info->spread_percentage_divider = 1000; |
| 655 | /* BIOS no longer uses target clock. Always enable for now */ | 657 | /* BIOS no longer uses target clock. Always enable for now */ |
| @@ -688,6 +690,19 @@ static enum bp_result get_ss_info_v4_1( | |||
| 688 | */ | 690 | */ |
| 689 | result = BP_RESULT_UNSUPPORTED; | 691 | result = BP_RESULT_UNSUPPORTED; |
| 690 | break; | 692 | break; |
| 693 | case AS_SIGNAL_TYPE_XGMI: | ||
| 694 | smu_info = GET_IMAGE(struct atom_smu_info_v3_3, | ||
| 695 | DATA_TABLES(smu_info)); | ||
| 696 | if (!smu_info) | ||
| 697 | return BP_RESULT_BADBIOSTABLE; | ||
| 698 | |||
| 699 | ss_info->spread_spectrum_percentage = | ||
| 700 | smu_info->waflclk_ss_percentage; | ||
| 701 | ss_info->spread_spectrum_range = | ||
| 702 | smu_info->gpuclk_ss_rate_10hz * 10; | ||
| 703 | if (smu_info->waflclk_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE) | ||
| 704 | ss_info->type.CENTER_MODE = true; | ||
| 705 | break; | ||
| 691 | default: | 706 | default: |
| 692 | result = BP_RESULT_UNSUPPORTED; | 707 | result = BP_RESULT_UNSUPPORTED; |
| 693 | } | 708 | } |
diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c index 65b006ad372e..8196f3bb10c7 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c +++ b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c | |||
| @@ -67,6 +67,7 @@ bool dal_bios_parser_init_cmd_tbl_helper2( | |||
| 67 | return true; | 67 | return true; |
| 68 | #endif | 68 | #endif |
| 69 | case DCE_VERSION_12_0: | 69 | case DCE_VERSION_12_0: |
| 70 | case DCE_VERSION_12_1: | ||
| 70 | *h = dal_cmd_tbl_helper_dce112_get_table2(); | 71 | *h = dal_cmd_tbl_helper_dce112_get_table2(); |
| 71 | return true; | 72 | return true; |
| 72 | 73 | ||
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index d9c57984394b..5fd52094d459 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c | |||
| @@ -151,10 +151,6 @@ static bool create_links( | |||
| 151 | return false; | 151 | return false; |
| 152 | } | 152 | } |
| 153 | 153 | ||
| 154 | if (connectors_num == 0 && num_virtual_links == 0) { | ||
| 155 | dm_error("DC: Number of connectors is zero!\n"); | ||
| 156 | } | ||
| 157 | |||
| 158 | dm_output_to_console( | 154 | dm_output_to_console( |
| 159 | "DC: %s: connectors_num: physical:%d, virtual:%d\n", | 155 | "DC: %s: connectors_num: physical:%d, virtual:%d\n", |
| 160 | __func__, | 156 | __func__, |
| @@ -1471,7 +1467,8 @@ static void commit_planes_do_stream_update(struct dc *dc, | |||
| 1471 | 1467 | ||
| 1472 | if ((stream_update->hdr_static_metadata && !stream->use_dynamic_meta) || | 1468 | if ((stream_update->hdr_static_metadata && !stream->use_dynamic_meta) || |
| 1473 | stream_update->vrr_infopacket || | 1469 | stream_update->vrr_infopacket || |
| 1474 | stream_update->vsc_infopacket) { | 1470 | stream_update->vsc_infopacket || |
| 1471 | stream_update->vsp_infopacket) { | ||
| 1475 | resource_build_info_frame(pipe_ctx); | 1472 | resource_build_info_frame(pipe_ctx); |
| 1476 | dc->hwss.update_info_frame(pipe_ctx); | 1473 | dc->hwss.update_info_frame(pipe_ctx); |
| 1477 | } | 1474 | } |
| @@ -1573,9 +1570,6 @@ static void commit_planes_for_stream(struct dc *dc, | |||
| 1573 | } | 1570 | } |
| 1574 | } | 1571 | } |
| 1575 | 1572 | ||
| 1576 | if (update_type == UPDATE_TYPE_FULL) | ||
| 1577 | context_timing_trace(dc, &context->res_ctx); | ||
| 1578 | |||
| 1579 | // Update Type FAST, Surface updates | 1573 | // Update Type FAST, Surface updates |
| 1580 | if (update_type == UPDATE_TYPE_FAST) { | 1574 | if (update_type == UPDATE_TYPE_FAST) { |
| 1581 | /* Lock the top pipe while updating plane addrs, since freesync requires | 1575 | /* Lock the top pipe while updating plane addrs, since freesync requires |
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index 4dc5846de5c4..52deacf39841 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c | |||
| @@ -215,6 +215,9 @@ bool dc_link_detect_sink(struct dc_link *link, enum dc_connection_type *type) | |||
| 215 | return true; | 215 | return true; |
| 216 | } | 216 | } |
| 217 | 217 | ||
| 218 | if (link->connector_signal == SIGNAL_TYPE_EDP) | ||
| 219 | link->dc->hwss.edp_wait_for_hpd_ready(link, true); | ||
| 220 | |||
| 218 | /* todo: may need to lock gpio access */ | 221 | /* todo: may need to lock gpio access */ |
| 219 | hpd_pin = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service); | 222 | hpd_pin = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service); |
| 220 | if (hpd_pin == NULL) | 223 | if (hpd_pin == NULL) |
| @@ -339,7 +342,7 @@ bool dc_link_is_dp_sink_present(struct dc_link *link) | |||
| 339 | { | 342 | { |
| 340 | enum gpio_result gpio_result; | 343 | enum gpio_result gpio_result; |
| 341 | uint32_t clock_pin = 0; | 344 | uint32_t clock_pin = 0; |
| 342 | 345 | uint8_t retry = 0; | |
| 343 | struct ddc *ddc; | 346 | struct ddc *ddc; |
| 344 | 347 | ||
| 345 | enum connector_id connector_id = | 348 | enum connector_id connector_id = |
| @@ -368,11 +371,22 @@ bool dc_link_is_dp_sink_present(struct dc_link *link) | |||
| 368 | return present; | 371 | return present; |
| 369 | } | 372 | } |
| 370 | 373 | ||
| 371 | /* Read GPIO: DP sink is present if both clock and data pins are zero */ | 374 | /* |
| 372 | /* [anaumov] in DAL2, there was no check for GPIO failure */ | 375 | * Read GPIO: DP sink is present if both clock and data pins are zero |
| 373 | 376 | * | |
| 374 | gpio_result = dal_gpio_get_value(ddc->pin_clock, &clock_pin); | 377 | * [W/A] plug-unplug DP cable, sometimes customer board has |
| 375 | ASSERT(gpio_result == GPIO_RESULT_OK); | 378 | * one short pulse on clk_pin(1V, < 1ms). DP will be config to HDMI/DVI |
| 379 | * then monitor can't br light up. Add retry 3 times | ||
| 380 | * But in real passive dongle, it need additional 3ms to detect | ||
| 381 | */ | ||
| 382 | do { | ||
| 383 | gpio_result = dal_gpio_get_value(ddc->pin_clock, &clock_pin); | ||
| 384 | ASSERT(gpio_result == GPIO_RESULT_OK); | ||
| 385 | if (clock_pin) | ||
| 386 | udelay(1000); | ||
| 387 | else | ||
| 388 | break; | ||
| 389 | } while (retry++ < 3); | ||
| 376 | 390 | ||
| 377 | present = (gpio_result == GPIO_RESULT_OK) && !clock_pin; | 391 | present = (gpio_result == GPIO_RESULT_OK) && !clock_pin; |
| 378 | 392 | ||
| @@ -703,12 +717,26 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) | |||
| 703 | if (memcmp(&link->dpcd_caps, &prev_dpcd_caps, sizeof(struct dpcd_caps))) | 717 | if (memcmp(&link->dpcd_caps, &prev_dpcd_caps, sizeof(struct dpcd_caps))) |
| 704 | same_dpcd = false; | 718 | same_dpcd = false; |
| 705 | } | 719 | } |
| 706 | /* Active dongle downstream unplug */ | 720 | /* Active dongle plug in without display or downstream unplug*/ |
| 707 | if (link->type == dc_connection_active_dongle | 721 | if (link->type == dc_connection_active_dongle |
| 708 | && link->dpcd_caps.sink_count. | 722 | && link->dpcd_caps.sink_count. |
| 709 | bits.SINK_COUNT == 0) { | 723 | bits.SINK_COUNT == 0) { |
| 710 | if (prev_sink != NULL) | 724 | if (prev_sink != NULL) { |
| 725 | /* Downstream unplug */ | ||
| 711 | dc_sink_release(prev_sink); | 726 | dc_sink_release(prev_sink); |
| 727 | } else { | ||
| 728 | /* Empty dongle plug in */ | ||
| 729 | for (i = 0; i < LINK_TRAINING_MAX_VERIFY_RETRY; i++) { | ||
| 730 | int fail_count = 0; | ||
| 731 | |||
| 732 | dp_verify_link_cap(link, | ||
| 733 | &link->reported_link_cap, | ||
| 734 | &fail_count); | ||
| 735 | |||
| 736 | if (fail_count == 0) | ||
| 737 | break; | ||
| 738 | } | ||
| 739 | } | ||
| 712 | return true; | 740 | return true; |
| 713 | } | 741 | } |
| 714 | 742 | ||
| @@ -2622,11 +2650,11 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx, int option) | |||
| 2622 | { | 2650 | { |
| 2623 | struct dc *core_dc = pipe_ctx->stream->ctx->dc; | 2651 | struct dc *core_dc = pipe_ctx->stream->ctx->dc; |
| 2624 | 2652 | ||
| 2653 | core_dc->hwss.blank_stream(pipe_ctx); | ||
| 2654 | |||
| 2625 | if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) | 2655 | if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) |
| 2626 | deallocate_mst_payload(pipe_ctx); | 2656 | deallocate_mst_payload(pipe_ctx); |
| 2627 | 2657 | ||
| 2628 | core_dc->hwss.blank_stream(pipe_ctx); | ||
| 2629 | |||
| 2630 | core_dc->hwss.disable_stream(pipe_ctx, option); | 2658 | core_dc->hwss.disable_stream(pipe_ctx, option); |
| 2631 | 2659 | ||
| 2632 | disable_link(pipe_ctx->stream->sink->link, pipe_ctx->stream->signal); | 2660 | disable_link(pipe_ctx->stream->sink->link, pipe_ctx->stream->signal); |
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c index 849a3a3032f7..0caacb60b02f 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | |||
| @@ -1089,6 +1089,121 @@ static struct dc_link_settings get_max_link_cap(struct dc_link *link) | |||
| 1089 | return max_link_cap; | 1089 | return max_link_cap; |
| 1090 | } | 1090 | } |
| 1091 | 1091 | ||
| 1092 | static enum dc_status read_hpd_rx_irq_data( | ||
| 1093 | struct dc_link *link, | ||
| 1094 | union hpd_irq_data *irq_data) | ||
| 1095 | { | ||
| 1096 | static enum dc_status retval; | ||
| 1097 | |||
| 1098 | /* The HW reads 16 bytes from 200h on HPD, | ||
| 1099 | * but if we get an AUX_DEFER, the HW cannot retry | ||
| 1100 | * and this causes the CTS tests 4.3.2.1 - 3.2.4 to | ||
| 1101 | * fail, so we now explicitly read 6 bytes which is | ||
| 1102 | * the req from the above mentioned test cases. | ||
| 1103 | * | ||
| 1104 | * For DP 1.4 we need to read those from 2002h range. | ||
| 1105 | */ | ||
| 1106 | if (link->dpcd_caps.dpcd_rev.raw < DPCD_REV_14) | ||
| 1107 | retval = core_link_read_dpcd( | ||
| 1108 | link, | ||
| 1109 | DP_SINK_COUNT, | ||
| 1110 | irq_data->raw, | ||
| 1111 | sizeof(union hpd_irq_data)); | ||
| 1112 | else { | ||
| 1113 | /* Read 14 bytes in a single read and then copy only the required fields. | ||
| 1114 | * This is more efficient than doing it in two separate AUX reads. */ | ||
| 1115 | |||
| 1116 | uint8_t tmp[DP_SINK_STATUS_ESI - DP_SINK_COUNT_ESI + 1]; | ||
| 1117 | |||
| 1118 | retval = core_link_read_dpcd( | ||
| 1119 | link, | ||
| 1120 | DP_SINK_COUNT_ESI, | ||
| 1121 | tmp, | ||
| 1122 | sizeof(tmp)); | ||
| 1123 | |||
| 1124 | if (retval != DC_OK) | ||
| 1125 | return retval; | ||
| 1126 | |||
| 1127 | irq_data->bytes.sink_cnt.raw = tmp[DP_SINK_COUNT_ESI - DP_SINK_COUNT_ESI]; | ||
| 1128 | irq_data->bytes.device_service_irq.raw = tmp[DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0 - DP_SINK_COUNT_ESI]; | ||
| 1129 | irq_data->bytes.lane01_status.raw = tmp[DP_LANE0_1_STATUS_ESI - DP_SINK_COUNT_ESI]; | ||
| 1130 | irq_data->bytes.lane23_status.raw = tmp[DP_LANE2_3_STATUS_ESI - DP_SINK_COUNT_ESI]; | ||
| 1131 | irq_data->bytes.lane_status_updated.raw = tmp[DP_LANE_ALIGN_STATUS_UPDATED_ESI - DP_SINK_COUNT_ESI]; | ||
| 1132 | irq_data->bytes.sink_status.raw = tmp[DP_SINK_STATUS_ESI - DP_SINK_COUNT_ESI]; | ||
| 1133 | } | ||
| 1134 | |||
| 1135 | return retval; | ||
| 1136 | } | ||
| 1137 | |||
| 1138 | static bool hpd_rx_irq_check_link_loss_status( | ||
| 1139 | struct dc_link *link, | ||
| 1140 | union hpd_irq_data *hpd_irq_dpcd_data) | ||
| 1141 | { | ||
| 1142 | uint8_t irq_reg_rx_power_state = 0; | ||
| 1143 | enum dc_status dpcd_result = DC_ERROR_UNEXPECTED; | ||
| 1144 | union lane_status lane_status; | ||
| 1145 | uint32_t lane; | ||
| 1146 | bool sink_status_changed; | ||
| 1147 | bool return_code; | ||
| 1148 | |||
| 1149 | sink_status_changed = false; | ||
| 1150 | return_code = false; | ||
| 1151 | |||
| 1152 | if (link->cur_link_settings.lane_count == 0) | ||
| 1153 | return return_code; | ||
| 1154 | |||
| 1155 | /*1. Check that Link Status changed, before re-training.*/ | ||
| 1156 | |||
| 1157 | /*parse lane status*/ | ||
| 1158 | for (lane = 0; lane < link->cur_link_settings.lane_count; lane++) { | ||
| 1159 | /* check status of lanes 0,1 | ||
| 1160 | * changed DpcdAddress_Lane01Status (0x202) | ||
| 1161 | */ | ||
| 1162 | lane_status.raw = get_nibble_at_index( | ||
| 1163 | &hpd_irq_dpcd_data->bytes.lane01_status.raw, | ||
| 1164 | lane); | ||
| 1165 | |||
| 1166 | if (!lane_status.bits.CHANNEL_EQ_DONE_0 || | ||
| 1167 | !lane_status.bits.CR_DONE_0 || | ||
| 1168 | !lane_status.bits.SYMBOL_LOCKED_0) { | ||
| 1169 | /* if one of the channel equalization, clock | ||
| 1170 | * recovery or symbol lock is dropped | ||
| 1171 | * consider it as (link has been | ||
| 1172 | * dropped) dp sink status has changed | ||
| 1173 | */ | ||
| 1174 | sink_status_changed = true; | ||
| 1175 | break; | ||
| 1176 | } | ||
| 1177 | } | ||
| 1178 | |||
| 1179 | /* Check interlane align.*/ | ||
| 1180 | if (sink_status_changed || | ||
| 1181 | !hpd_irq_dpcd_data->bytes.lane_status_updated.bits.INTERLANE_ALIGN_DONE) { | ||
| 1182 | |||
| 1183 | DC_LOG_HW_HPD_IRQ("%s: Link Status changed.\n", __func__); | ||
| 1184 | |||
| 1185 | return_code = true; | ||
| 1186 | |||
| 1187 | /*2. Check that we can handle interrupt: Not in FS DOS, | ||
| 1188 | * Not in "Display Timeout" state, Link is trained. | ||
| 1189 | */ | ||
| 1190 | dpcd_result = core_link_read_dpcd(link, | ||
| 1191 | DP_SET_POWER, | ||
| 1192 | &irq_reg_rx_power_state, | ||
| 1193 | sizeof(irq_reg_rx_power_state)); | ||
| 1194 | |||
| 1195 | if (dpcd_result != DC_OK) { | ||
| 1196 | DC_LOG_HW_HPD_IRQ("%s: DPCD read failed to obtain power state.\n", | ||
| 1197 | __func__); | ||
| 1198 | } else { | ||
| 1199 | if (irq_reg_rx_power_state != DP_SET_POWER_D0) | ||
| 1200 | return_code = false; | ||
| 1201 | } | ||
| 1202 | } | ||
| 1203 | |||
| 1204 | return return_code; | ||
| 1205 | } | ||
| 1206 | |||
| 1092 | bool dp_verify_link_cap( | 1207 | bool dp_verify_link_cap( |
| 1093 | struct dc_link *link, | 1208 | struct dc_link *link, |
| 1094 | struct dc_link_settings *known_limit_link_setting, | 1209 | struct dc_link_settings *known_limit_link_setting, |
| @@ -1104,12 +1219,14 @@ bool dp_verify_link_cap( | |||
| 1104 | struct clock_source *dp_cs; | 1219 | struct clock_source *dp_cs; |
| 1105 | enum clock_source_id dp_cs_id = CLOCK_SOURCE_ID_EXTERNAL; | 1220 | enum clock_source_id dp_cs_id = CLOCK_SOURCE_ID_EXTERNAL; |
| 1106 | enum link_training_result status; | 1221 | enum link_training_result status; |
| 1222 | union hpd_irq_data irq_data; | ||
| 1107 | 1223 | ||
| 1108 | if (link->dc->debug.skip_detection_link_training) { | 1224 | if (link->dc->debug.skip_detection_link_training) { |
| 1109 | link->verified_link_cap = *known_limit_link_setting; | 1225 | link->verified_link_cap = *known_limit_link_setting; |
| 1110 | return true; | 1226 | return true; |
| 1111 | } | 1227 | } |
| 1112 | 1228 | ||
| 1229 | memset(&irq_data, 0, sizeof(irq_data)); | ||
| 1113 | success = false; | 1230 | success = false; |
| 1114 | skip_link_training = false; | 1231 | skip_link_training = false; |
| 1115 | 1232 | ||
| @@ -1168,9 +1285,15 @@ bool dp_verify_link_cap( | |||
| 1168 | (*fail_count)++; | 1285 | (*fail_count)++; |
| 1169 | } | 1286 | } |
| 1170 | 1287 | ||
| 1171 | if (success) | 1288 | if (success) { |
| 1172 | link->verified_link_cap = *cur; | 1289 | link->verified_link_cap = *cur; |
| 1173 | 1290 | udelay(1000); | |
| 1291 | if (read_hpd_rx_irq_data(link, &irq_data) == DC_OK) | ||
| 1292 | if (hpd_rx_irq_check_link_loss_status( | ||
| 1293 | link, | ||
| 1294 | &irq_data)) | ||
| 1295 | (*fail_count)++; | ||
| 1296 | } | ||
| 1174 | /* always disable the link before trying another | 1297 | /* always disable the link before trying another |
| 1175 | * setting or before returning we'll enable it later | 1298 | * setting or before returning we'll enable it later |
| 1176 | * based on the actual mode we're driving | 1299 | * based on the actual mode we're driving |
| @@ -1572,122 +1695,6 @@ void decide_link_settings(struct dc_stream_state *stream, | |||
| 1572 | } | 1695 | } |
| 1573 | 1696 | ||
| 1574 | /*************************Short Pulse IRQ***************************/ | 1697 | /*************************Short Pulse IRQ***************************/ |
| 1575 | |||
| 1576 | static bool hpd_rx_irq_check_link_loss_status( | ||
| 1577 | struct dc_link *link, | ||
| 1578 | union hpd_irq_data *hpd_irq_dpcd_data) | ||
| 1579 | { | ||
| 1580 | uint8_t irq_reg_rx_power_state = 0; | ||
| 1581 | enum dc_status dpcd_result = DC_ERROR_UNEXPECTED; | ||
| 1582 | union lane_status lane_status; | ||
| 1583 | uint32_t lane; | ||
| 1584 | bool sink_status_changed; | ||
| 1585 | bool return_code; | ||
| 1586 | |||
| 1587 | sink_status_changed = false; | ||
| 1588 | return_code = false; | ||
| 1589 | |||
| 1590 | if (link->cur_link_settings.lane_count == 0) | ||
| 1591 | return return_code; | ||
| 1592 | |||
| 1593 | /*1. Check that Link Status changed, before re-training.*/ | ||
| 1594 | |||
| 1595 | /*parse lane status*/ | ||
| 1596 | for (lane = 0; lane < link->cur_link_settings.lane_count; lane++) { | ||
| 1597 | /* check status of lanes 0,1 | ||
| 1598 | * changed DpcdAddress_Lane01Status (0x202) | ||
| 1599 | */ | ||
| 1600 | lane_status.raw = get_nibble_at_index( | ||
| 1601 | &hpd_irq_dpcd_data->bytes.lane01_status.raw, | ||
| 1602 | lane); | ||
| 1603 | |||
| 1604 | if (!lane_status.bits.CHANNEL_EQ_DONE_0 || | ||
| 1605 | !lane_status.bits.CR_DONE_0 || | ||
| 1606 | !lane_status.bits.SYMBOL_LOCKED_0) { | ||
| 1607 | /* if one of the channel equalization, clock | ||
| 1608 | * recovery or symbol lock is dropped | ||
| 1609 | * consider it as (link has been | ||
| 1610 | * dropped) dp sink status has changed | ||
| 1611 | */ | ||
| 1612 | sink_status_changed = true; | ||
| 1613 | break; | ||
| 1614 | } | ||
| 1615 | } | ||
| 1616 | |||
| 1617 | /* Check interlane align.*/ | ||
| 1618 | if (sink_status_changed || | ||
| 1619 | !hpd_irq_dpcd_data->bytes.lane_status_updated.bits.INTERLANE_ALIGN_DONE) { | ||
| 1620 | |||
| 1621 | DC_LOG_HW_HPD_IRQ("%s: Link Status changed.\n", __func__); | ||
| 1622 | |||
| 1623 | return_code = true; | ||
| 1624 | |||
| 1625 | /*2. Check that we can handle interrupt: Not in FS DOS, | ||
| 1626 | * Not in "Display Timeout" state, Link is trained. | ||
| 1627 | */ | ||
| 1628 | dpcd_result = core_link_read_dpcd(link, | ||
| 1629 | DP_SET_POWER, | ||
| 1630 | &irq_reg_rx_power_state, | ||
| 1631 | sizeof(irq_reg_rx_power_state)); | ||
| 1632 | |||
| 1633 | if (dpcd_result != DC_OK) { | ||
| 1634 | DC_LOG_HW_HPD_IRQ("%s: DPCD read failed to obtain power state.\n", | ||
| 1635 | __func__); | ||
| 1636 | } else { | ||
| 1637 | if (irq_reg_rx_power_state != DP_SET_POWER_D0) | ||
| 1638 | return_code = false; | ||
| 1639 | } | ||
| 1640 | } | ||
| 1641 | |||
| 1642 | return return_code; | ||
| 1643 | } | ||
| 1644 | |||
| 1645 | static enum dc_status read_hpd_rx_irq_data( | ||
| 1646 | struct dc_link *link, | ||
| 1647 | union hpd_irq_data *irq_data) | ||
| 1648 | { | ||
| 1649 | static enum dc_status retval; | ||
| 1650 | |||
| 1651 | /* The HW reads 16 bytes from 200h on HPD, | ||
| 1652 | * but if we get an AUX_DEFER, the HW cannot retry | ||
| 1653 | * and this causes the CTS tests 4.3.2.1 - 3.2.4 to | ||
| 1654 | * fail, so we now explicitly read 6 bytes which is | ||
| 1655 | * the req from the above mentioned test cases. | ||
| 1656 | * | ||
| 1657 | * For DP 1.4 we need to read those from 2002h range. | ||
| 1658 | */ | ||
| 1659 | if (link->dpcd_caps.dpcd_rev.raw < DPCD_REV_14) | ||
| 1660 | retval = core_link_read_dpcd( | ||
| 1661 | link, | ||
| 1662 | DP_SINK_COUNT, | ||
| 1663 | irq_data->raw, | ||
| 1664 | sizeof(union hpd_irq_data)); | ||
| 1665 | else { | ||
| 1666 | /* Read 14 bytes in a single read and then copy only the required fields. | ||
| 1667 | * This is more efficient than doing it in two separate AUX reads. */ | ||
| 1668 | |||
| 1669 | uint8_t tmp[DP_SINK_STATUS_ESI - DP_SINK_COUNT_ESI + 1]; | ||
| 1670 | |||
| 1671 | retval = core_link_read_dpcd( | ||
| 1672 | link, | ||
| 1673 | DP_SINK_COUNT_ESI, | ||
| 1674 | tmp, | ||
| 1675 | sizeof(tmp)); | ||
| 1676 | |||
| 1677 | if (retval != DC_OK) | ||
| 1678 | return retval; | ||
| 1679 | |||
| 1680 | irq_data->bytes.sink_cnt.raw = tmp[DP_SINK_COUNT_ESI - DP_SINK_COUNT_ESI]; | ||
| 1681 | irq_data->bytes.device_service_irq.raw = tmp[DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0 - DP_SINK_COUNT_ESI]; | ||
| 1682 | irq_data->bytes.lane01_status.raw = tmp[DP_LANE0_1_STATUS_ESI - DP_SINK_COUNT_ESI]; | ||
| 1683 | irq_data->bytes.lane23_status.raw = tmp[DP_LANE2_3_STATUS_ESI - DP_SINK_COUNT_ESI]; | ||
| 1684 | irq_data->bytes.lane_status_updated.raw = tmp[DP_LANE_ALIGN_STATUS_UPDATED_ESI - DP_SINK_COUNT_ESI]; | ||
| 1685 | irq_data->bytes.sink_status.raw = tmp[DP_SINK_STATUS_ESI - DP_SINK_COUNT_ESI]; | ||
| 1686 | } | ||
| 1687 | |||
| 1688 | return retval; | ||
| 1689 | } | ||
| 1690 | |||
| 1691 | static bool allow_hpd_rx_irq(const struct dc_link *link) | 1698 | static bool allow_hpd_rx_irq(const struct dc_link *link) |
| 1692 | { | 1699 | { |
| 1693 | /* | 1700 | /* |
| @@ -2240,7 +2247,8 @@ static void get_active_converter_info( | |||
| 2240 | translate_dpcd_max_bpc( | 2247 | translate_dpcd_max_bpc( |
| 2241 | hdmi_color_caps.bits.MAX_BITS_PER_COLOR_COMPONENT); | 2248 | hdmi_color_caps.bits.MAX_BITS_PER_COLOR_COMPONENT); |
| 2242 | 2249 | ||
| 2243 | link->dpcd_caps.dongle_caps.extendedCapValid = true; | 2250 | if (link->dpcd_caps.dongle_caps.dp_hdmi_max_pixel_clk != 0) |
| 2251 | link->dpcd_caps.dongle_caps.extendedCapValid = true; | ||
| 2244 | } | 2252 | } |
| 2245 | 2253 | ||
| 2246 | break; | 2254 | break; |
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c index 82cd1d6e6e59..0065ec7d5330 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c | |||
| @@ -96,6 +96,7 @@ void dp_enable_link_phy( | |||
| 96 | link_settings, | 96 | link_settings, |
| 97 | clock_source); | 97 | clock_source); |
| 98 | } | 98 | } |
| 99 | link->cur_link_settings = *link_settings; | ||
| 99 | 100 | ||
| 100 | dp_receiver_power_ctrl(link, true); | 101 | dp_receiver_power_ctrl(link, true); |
| 101 | } | 102 | } |
| @@ -307,6 +308,7 @@ void dp_retrain_link_dp_test(struct dc_link *link, | |||
| 307 | link->link_enc, | 308 | link->link_enc, |
| 308 | link_setting, | 309 | link_setting, |
| 309 | pipes[i].clock_source->id); | 310 | pipes[i].clock_source->id); |
| 311 | link->cur_link_settings = *link_setting; | ||
| 310 | 312 | ||
| 311 | dp_receiver_power_ctrl(link, true); | 313 | dp_receiver_power_ctrl(link, true); |
| 312 | 314 | ||
| @@ -316,7 +318,6 @@ void dp_retrain_link_dp_test(struct dc_link *link, | |||
| 316 | skip_video_pattern, | 318 | skip_video_pattern, |
| 317 | LINK_TRAINING_ATTEMPTS); | 319 | LINK_TRAINING_ATTEMPTS); |
| 318 | 320 | ||
| 319 | link->cur_link_settings = *link_setting; | ||
| 320 | 321 | ||
| 321 | link->dc->hwss.enable_stream(&pipes[i]); | 322 | link->dc->hwss.enable_stream(&pipes[i]); |
| 322 | 323 | ||
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index c347afd1030f..76137df74a53 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c | |||
| @@ -83,7 +83,10 @@ enum dce_version resource_parse_asic_id(struct hw_asic_id asic_id) | |||
| 83 | dc_version = DCE_VERSION_11_22; | 83 | dc_version = DCE_VERSION_11_22; |
| 84 | break; | 84 | break; |
| 85 | case FAMILY_AI: | 85 | case FAMILY_AI: |
| 86 | dc_version = DCE_VERSION_12_0; | 86 | if (ASICREV_IS_VEGA20_P(asic_id.hw_internal_rev)) |
| 87 | dc_version = DCE_VERSION_12_1; | ||
| 88 | else | ||
| 89 | dc_version = DCE_VERSION_12_0; | ||
| 87 | break; | 90 | break; |
| 88 | #if defined(CONFIG_DRM_AMD_DC_DCN1_0) | 91 | #if defined(CONFIG_DRM_AMD_DC_DCN1_0) |
| 89 | case FAMILY_RV: | 92 | case FAMILY_RV: |
| @@ -136,6 +139,7 @@ struct resource_pool *dc_create_resource_pool( | |||
| 136 | num_virtual_links, dc); | 139 | num_virtual_links, dc); |
| 137 | break; | 140 | break; |
| 138 | case DCE_VERSION_12_0: | 141 | case DCE_VERSION_12_0: |
| 142 | case DCE_VERSION_12_1: | ||
| 139 | res_pool = dce120_create_resource_pool( | 143 | res_pool = dce120_create_resource_pool( |
| 140 | num_virtual_links, dc); | 144 | num_virtual_links, dc); |
| 141 | break; | 145 | break; |
diff --git a/drivers/gpu/drm/amd/display/dc/dc_helper.c b/drivers/gpu/drm/amd/display/dc/dc_helper.c index fcfd50b5dba0..4842d2378bbf 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_helper.c +++ b/drivers/gpu/drm/amd/display/dc/dc_helper.c | |||
| @@ -234,14 +234,14 @@ uint32_t generic_reg_wait(const struct dc_context *ctx, | |||
| 234 | if (field_value == condition_value) { | 234 | if (field_value == condition_value) { |
| 235 | if (i * delay_between_poll_us > 1000 && | 235 | if (i * delay_between_poll_us > 1000 && |
| 236 | !IS_FPGA_MAXIMUS_DC(ctx->dce_environment)) | 236 | !IS_FPGA_MAXIMUS_DC(ctx->dce_environment)) |
| 237 | dm_output_to_console("REG_WAIT taking a while: %dms in %s line:%d\n", | 237 | DC_LOG_DC("REG_WAIT taking a while: %dms in %s line:%d\n", |
| 238 | delay_between_poll_us * i / 1000, | 238 | delay_between_poll_us * i / 1000, |
| 239 | func_name, line); | 239 | func_name, line); |
| 240 | return reg_val; | 240 | return reg_val; |
| 241 | } | 241 | } |
| 242 | } | 242 | } |
| 243 | 243 | ||
| 244 | dm_error("REG_WAIT timeout %dus * %d tries - %s line:%d\n", | 244 | DC_LOG_WARNING("REG_WAIT timeout %dus * %d tries - %s line:%d\n", |
| 245 | delay_between_poll_us, time_out_num_tries, | 245 | delay_between_poll_us, time_out_num_tries, |
| 246 | func_name, line); | 246 | func_name, line); |
| 247 | 247 | ||
diff --git a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h index 9ddfe4c6938b..e72fce4eca65 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h | |||
| @@ -192,7 +192,6 @@ enum surface_pixel_format { | |||
| 192 | /*swaped & float*/ | 192 | /*swaped & float*/ |
| 193 | SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F, | 193 | SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F, |
| 194 | /*grow graphics here if necessary */ | 194 | /*grow graphics here if necessary */ |
| 195 | SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888, | ||
| 196 | SURFACE_PIXEL_FORMAT_VIDEO_BEGIN, | 195 | SURFACE_PIXEL_FORMAT_VIDEO_BEGIN, |
| 197 | SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr = | 196 | SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr = |
| 198 | SURFACE_PIXEL_FORMAT_VIDEO_BEGIN, | 197 | SURFACE_PIXEL_FORMAT_VIDEO_BEGIN, |
| @@ -200,6 +199,7 @@ enum surface_pixel_format { | |||
| 200 | SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr, | 199 | SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr, |
| 201 | SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb, | 200 | SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb, |
| 202 | SURFACE_PIXEL_FORMAT_SUBSAMPLE_END, | 201 | SURFACE_PIXEL_FORMAT_SUBSAMPLE_END, |
| 202 | SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888, | ||
| 203 | SURFACE_PIXEL_FORMAT_INVALID | 203 | SURFACE_PIXEL_FORMAT_INVALID |
| 204 | 204 | ||
| 205 | /*grow 444 video here if necessary */ | 205 | /*grow 444 video here if necessary */ |
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clk_mgr.c index bd22f51813bf..afd287f08bc9 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clk_mgr.c | |||
| @@ -676,6 +676,11 @@ static void dce112_update_clocks(struct clk_mgr *clk_mgr, | |||
| 676 | { | 676 | { |
| 677 | struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(clk_mgr); | 677 | struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(clk_mgr); |
| 678 | struct dm_pp_power_level_change_request level_change_req; | 678 | struct dm_pp_power_level_change_request level_change_req; |
| 679 | int unpatched_disp_clk = context->bw.dce.dispclk_khz; | ||
| 680 | |||
| 681 | /*TODO: W/A for dal3 linux, investigate why this works */ | ||
| 682 | if (!clk_mgr_dce->dfs_bypass_active) | ||
| 683 | context->bw.dce.dispclk_khz = context->bw.dce.dispclk_khz * 115 / 100; | ||
| 679 | 684 | ||
| 680 | level_change_req.power_level = dce_get_required_clocks_state(clk_mgr, context); | 685 | level_change_req.power_level = dce_get_required_clocks_state(clk_mgr, context); |
| 681 | /* get max clock state from PPLIB */ | 686 | /* get max clock state from PPLIB */ |
| @@ -690,6 +695,8 @@ static void dce112_update_clocks(struct clk_mgr *clk_mgr, | |||
| 690 | clk_mgr->clks.dispclk_khz = context->bw.dce.dispclk_khz; | 695 | clk_mgr->clks.dispclk_khz = context->bw.dce.dispclk_khz; |
| 691 | } | 696 | } |
| 692 | dce11_pplib_apply_display_requirements(clk_mgr->ctx->dc, context); | 697 | dce11_pplib_apply_display_requirements(clk_mgr->ctx->dc, context); |
| 698 | |||
| 699 | context->bw.dce.dispclk_khz = unpatched_disp_clk; | ||
| 693 | } | 700 | } |
| 694 | 701 | ||
| 695 | static void dce12_update_clocks(struct clk_mgr *clk_mgr, | 702 | static void dce12_update_clocks(struct clk_mgr *clk_mgr, |
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index 6349ba7bec7c..4bf24758217f 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c | |||
| @@ -1267,10 +1267,19 @@ static void program_scaler(const struct dc *dc, | |||
| 1267 | pipe_ctx->plane_res.scl_data.lb_params.depth, | 1267 | pipe_ctx->plane_res.scl_data.lb_params.depth, |
| 1268 | &pipe_ctx->stream->bit_depth_params); | 1268 | &pipe_ctx->stream->bit_depth_params); |
| 1269 | 1269 | ||
| 1270 | if (pipe_ctx->stream_res.tg->funcs->set_overscan_blank_color) | 1270 | if (pipe_ctx->stream_res.tg->funcs->set_overscan_blank_color) { |
| 1271 | /* | ||
| 1272 | * The way 420 is packed, 2 channels carry Y component, 1 channel | ||
| 1273 | * alternate between Cb and Cr, so both channels need the pixel | ||
| 1274 | * value for Y | ||
| 1275 | */ | ||
| 1276 | if (pipe_ctx->stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420) | ||
| 1277 | color.color_r_cr = color.color_g_y; | ||
| 1278 | |||
| 1271 | pipe_ctx->stream_res.tg->funcs->set_overscan_blank_color( | 1279 | pipe_ctx->stream_res.tg->funcs->set_overscan_blank_color( |
| 1272 | pipe_ctx->stream_res.tg, | 1280 | pipe_ctx->stream_res.tg, |
| 1273 | &color); | 1281 | &color); |
| 1282 | } | ||
| 1274 | 1283 | ||
| 1275 | pipe_ctx->plane_res.xfm->funcs->transform_set_scaler(pipe_ctx->plane_res.xfm, | 1284 | pipe_ctx->plane_res.xfm->funcs->transform_set_scaler(pipe_ctx->plane_res.xfm, |
| 1276 | &pipe_ctx->plane_res.scl_data); | 1285 | &pipe_ctx->plane_res.scl_data); |
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 0bd33a713836..91e015e14355 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | |||
| @@ -2159,6 +2159,15 @@ static void dcn10_blank_pixel_data( | |||
| 2159 | color_space = stream->output_color_space; | 2159 | color_space = stream->output_color_space; |
| 2160 | color_space_to_black_color(dc, color_space, &black_color); | 2160 | color_space_to_black_color(dc, color_space, &black_color); |
| 2161 | 2161 | ||
| 2162 | /* | ||
| 2163 | * The way 420 is packed, 2 channels carry Y component, 1 channel | ||
| 2164 | * alternate between Cb and Cr, so both channels need the pixel | ||
| 2165 | * value for Y | ||
| 2166 | */ | ||
| 2167 | if (stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420) | ||
| 2168 | black_color.color_r_cr = black_color.color_g_y; | ||
| 2169 | |||
| 2170 | |||
| 2162 | if (stream_res->tg->funcs->set_blank_color) | 2171 | if (stream_res->tg->funcs->set_blank_color) |
| 2163 | stream_res->tg->funcs->set_blank_color( | 2172 | stream_res->tg->funcs->set_blank_color( |
| 2164 | stream_res->tg, | 2173 | stream_res->tg, |
| @@ -2348,7 +2357,8 @@ static void dcn10_apply_ctx_for_surface( | |||
| 2348 | struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; | 2357 | struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; |
| 2349 | 2358 | ||
| 2350 | /* Skip inactive pipes and ones already updated */ | 2359 | /* Skip inactive pipes and ones already updated */ |
| 2351 | if (!pipe_ctx->stream || pipe_ctx->stream == stream) | 2360 | if (!pipe_ctx->stream || pipe_ctx->stream == stream |
| 2361 | || !pipe_ctx->plane_state) | ||
| 2352 | continue; | 2362 | continue; |
| 2353 | 2363 | ||
| 2354 | pipe_ctx->stream_res.tg->funcs->lock(pipe_ctx->stream_res.tg); | 2364 | pipe_ctx->stream_res.tg->funcs->lock(pipe_ctx->stream_res.tg); |
| @@ -2362,7 +2372,8 @@ static void dcn10_apply_ctx_for_surface( | |||
| 2362 | for (i = 0; i < dc->res_pool->pipe_count; i++) { | 2372 | for (i = 0; i < dc->res_pool->pipe_count; i++) { |
| 2363 | struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; | 2373 | struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; |
| 2364 | 2374 | ||
| 2365 | if (!pipe_ctx->stream || pipe_ctx->stream == stream) | 2375 | if (!pipe_ctx->stream || pipe_ctx->stream == stream |
| 2376 | || !pipe_ctx->plane_state) | ||
| 2366 | continue; | 2377 | continue; |
| 2367 | 2378 | ||
| 2368 | dcn10_pipe_control_lock(dc, pipe_ctx, false); | 2379 | dcn10_pipe_control_lock(dc, pipe_ctx, false); |
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c b/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c index a683f4102e65..c2028c4744a6 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c | |||
| @@ -79,6 +79,7 @@ bool dal_hw_factory_init( | |||
| 79 | dal_hw_factory_dce110_init(factory); | 79 | dal_hw_factory_dce110_init(factory); |
| 80 | return true; | 80 | return true; |
| 81 | case DCE_VERSION_12_0: | 81 | case DCE_VERSION_12_0: |
| 82 | case DCE_VERSION_12_1: | ||
| 82 | dal_hw_factory_dce120_init(factory); | 83 | dal_hw_factory_dce120_init(factory); |
| 83 | return true; | 84 | return true; |
| 84 | #if defined(CONFIG_DRM_AMD_DC_DCN1_0) | 85 | #if defined(CONFIG_DRM_AMD_DC_DCN1_0) |
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c b/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c index 096f45628630..236ca28784a9 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c | |||
| @@ -76,6 +76,7 @@ bool dal_hw_translate_init( | |||
| 76 | dal_hw_translate_dce110_init(translate); | 76 | dal_hw_translate_dce110_init(translate); |
| 77 | return true; | 77 | return true; |
| 78 | case DCE_VERSION_12_0: | 78 | case DCE_VERSION_12_0: |
| 79 | case DCE_VERSION_12_1: | ||
| 79 | dal_hw_translate_dce120_init(translate); | 80 | dal_hw_translate_dce120_init(translate); |
| 80 | return true; | 81 | return true; |
| 81 | #if defined(CONFIG_DRM_AMD_DC_DCN1_0) | 82 | #if defined(CONFIG_DRM_AMD_DC_DCN1_0) |
diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/i2caux.c b/drivers/gpu/drm/amd/display/dc/i2caux/i2caux.c index e56093f26eed..1ad6e49102ff 100644 --- a/drivers/gpu/drm/amd/display/dc/i2caux/i2caux.c +++ b/drivers/gpu/drm/amd/display/dc/i2caux/i2caux.c | |||
| @@ -90,6 +90,7 @@ struct i2caux *dal_i2caux_create( | |||
| 90 | case DCE_VERSION_10_0: | 90 | case DCE_VERSION_10_0: |
| 91 | return dal_i2caux_dce100_create(ctx); | 91 | return dal_i2caux_dce100_create(ctx); |
| 92 | case DCE_VERSION_12_0: | 92 | case DCE_VERSION_12_0: |
| 93 | case DCE_VERSION_12_1: | ||
| 93 | return dal_i2caux_dce120_create(ctx); | 94 | return dal_i2caux_dce120_create(ctx); |
| 94 | #if defined(CONFIG_DRM_AMD_DC_DCN1_0) | 95 | #if defined(CONFIG_DRM_AMD_DC_DCN1_0) |
| 95 | case DCN_VERSION_1_0: | 96 | case DCN_VERSION_1_0: |
diff --git a/drivers/gpu/drm/amd/display/include/bios_parser_types.h b/drivers/gpu/drm/amd/display/include/bios_parser_types.h index f8dbfa5b89f2..7fd78a696800 100644 --- a/drivers/gpu/drm/amd/display/include/bios_parser_types.h +++ b/drivers/gpu/drm/amd/display/include/bios_parser_types.h | |||
| @@ -41,6 +41,7 @@ enum as_signal_type { | |||
| 41 | AS_SIGNAL_TYPE_LVDS, | 41 | AS_SIGNAL_TYPE_LVDS, |
| 42 | AS_SIGNAL_TYPE_DISPLAY_PORT, | 42 | AS_SIGNAL_TYPE_DISPLAY_PORT, |
| 43 | AS_SIGNAL_TYPE_GPU_PLL, | 43 | AS_SIGNAL_TYPE_GPU_PLL, |
| 44 | AS_SIGNAL_TYPE_XGMI, | ||
| 44 | AS_SIGNAL_TYPE_UNKNOWN | 45 | AS_SIGNAL_TYPE_UNKNOWN |
| 45 | }; | 46 | }; |
| 46 | 47 | ||
diff --git a/drivers/gpu/drm/amd/display/include/dal_types.h b/drivers/gpu/drm/amd/display/include/dal_types.h index 89627133e188..f5bd869d4320 100644 --- a/drivers/gpu/drm/amd/display/include/dal_types.h +++ b/drivers/gpu/drm/amd/display/include/dal_types.h | |||
| @@ -42,6 +42,7 @@ enum dce_version { | |||
| 42 | DCE_VERSION_11_2, | 42 | DCE_VERSION_11_2, |
| 43 | DCE_VERSION_11_22, | 43 | DCE_VERSION_11_22, |
| 44 | DCE_VERSION_12_0, | 44 | DCE_VERSION_12_0, |
| 45 | DCE_VERSION_12_1, | ||
| 45 | DCE_VERSION_MAX, | 46 | DCE_VERSION_MAX, |
| 46 | DCN_VERSION_1_0, | 47 | DCN_VERSION_1_0, |
| 47 | #if defined(CONFIG_DRM_AMD_DC_DCN1_01) | 48 | #if defined(CONFIG_DRM_AMD_DC_DCN1_01) |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c index 2e99ecf4ab76..26154f9b2178 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c | |||
| @@ -49,6 +49,10 @@ | |||
| 49 | #include "soc15_common.h" | 49 | #include "soc15_common.h" |
| 50 | #include "smuio/smuio_9_0_offset.h" | 50 | #include "smuio/smuio_9_0_offset.h" |
| 51 | #include "smuio/smuio_9_0_sh_mask.h" | 51 | #include "smuio/smuio_9_0_sh_mask.h" |
| 52 | #include "nbio/nbio_7_4_sh_mask.h" | ||
| 53 | |||
| 54 | #define smnPCIE_LC_SPEED_CNTL 0x11140290 | ||
| 55 | #define smnPCIE_LC_LINK_WIDTH_CNTL 0x11140288 | ||
| 52 | 56 | ||
| 53 | static void vega20_set_default_registry_data(struct pp_hwmgr *hwmgr) | 57 | static void vega20_set_default_registry_data(struct pp_hwmgr *hwmgr) |
| 54 | { | 58 | { |
| @@ -2282,6 +2286,18 @@ static int vega20_force_clock_level(struct pp_hwmgr *hwmgr, | |||
| 2282 | break; | 2286 | break; |
| 2283 | 2287 | ||
| 2284 | case PP_PCIE: | 2288 | case PP_PCIE: |
| 2289 | soft_min_level = mask ? (ffs(mask) - 1) : 0; | ||
| 2290 | soft_max_level = mask ? (fls(mask) - 1) : 0; | ||
| 2291 | if (soft_min_level >= NUM_LINK_LEVELS || | ||
| 2292 | soft_max_level >= NUM_LINK_LEVELS) | ||
| 2293 | return -EINVAL; | ||
| 2294 | |||
| 2295 | ret = smum_send_msg_to_smc_with_parameter(hwmgr, | ||
| 2296 | PPSMC_MSG_SetMinLinkDpmByIndex, soft_min_level); | ||
| 2297 | PP_ASSERT_WITH_CODE(!ret, | ||
| 2298 | "Failed to set min link dpm level!", | ||
| 2299 | return ret); | ||
| 2300 | |||
| 2285 | break; | 2301 | break; |
| 2286 | 2302 | ||
| 2287 | default: | 2303 | default: |
| @@ -2758,9 +2774,14 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr, | |||
| 2758 | data->od8_settings.od8_settings_array; | 2774 | data->od8_settings.od8_settings_array; |
| 2759 | OverDriveTable_t *od_table = | 2775 | OverDriveTable_t *od_table = |
| 2760 | &(data->smc_state_table.overdrive_table); | 2776 | &(data->smc_state_table.overdrive_table); |
| 2777 | struct phm_ppt_v3_information *pptable_information = | ||
| 2778 | (struct phm_ppt_v3_information *)hwmgr->pptable; | ||
| 2779 | PPTable_t *pptable = (PPTable_t *)pptable_information->smc_pptable; | ||
| 2780 | struct amdgpu_device *adev = hwmgr->adev; | ||
| 2761 | struct pp_clock_levels_with_latency clocks; | 2781 | struct pp_clock_levels_with_latency clocks; |
| 2762 | int i, now, size = 0; | 2782 | int i, now, size = 0; |
| 2763 | int ret = 0; | 2783 | int ret = 0; |
| 2784 | uint32_t gen_speed, lane_width; | ||
| 2764 | 2785 | ||
| 2765 | switch (type) { | 2786 | switch (type) { |
| 2766 | case PP_SCLK: | 2787 | case PP_SCLK: |
| @@ -2798,6 +2819,28 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr, | |||
| 2798 | break; | 2819 | break; |
| 2799 | 2820 | ||
| 2800 | case PP_PCIE: | 2821 | case PP_PCIE: |
| 2822 | gen_speed = (RREG32_PCIE(smnPCIE_LC_SPEED_CNTL) & | ||
| 2823 | PSWUSP0_PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK) | ||
| 2824 | >> PSWUSP0_PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT; | ||
| 2825 | lane_width = (RREG32_PCIE(smnPCIE_LC_LINK_WIDTH_CNTL) & | ||
| 2826 | PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD_MASK) | ||
| 2827 | >> PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD__SHIFT; | ||
| 2828 | for (i = 0; i < NUM_LINK_LEVELS; i++) | ||
| 2829 | size += sprintf(buf + size, "%d: %s %s %dMhz %s\n", i, | ||
| 2830 | (pptable->PcieGenSpeed[i] == 0) ? "2.5GT/s," : | ||
| 2831 | (pptable->PcieGenSpeed[i] == 1) ? "5.0GT/s," : | ||
| 2832 | (pptable->PcieGenSpeed[i] == 2) ? "8.0GT/s," : | ||
| 2833 | (pptable->PcieGenSpeed[i] == 3) ? "16.0GT/s," : "", | ||
| 2834 | (pptable->PcieLaneCount[i] == 1) ? "x1" : | ||
| 2835 | (pptable->PcieLaneCount[i] == 2) ? "x2" : | ||
| 2836 | (pptable->PcieLaneCount[i] == 3) ? "x4" : | ||
| 2837 | (pptable->PcieLaneCount[i] == 4) ? "x8" : | ||
| 2838 | (pptable->PcieLaneCount[i] == 5) ? "x12" : | ||
| 2839 | (pptable->PcieLaneCount[i] == 6) ? "x16" : "", | ||
| 2840 | pptable->LclkFreq[i], | ||
| 2841 | (gen_speed == pptable->PcieGenSpeed[i]) && | ||
| 2842 | (lane_width == pptable->PcieLaneCount[i]) ? | ||
| 2843 | "*" : ""); | ||
| 2801 | break; | 2844 | break; |
| 2802 | 2845 | ||
| 2803 | case OD_SCLK: | 2846 | case OD_SCLK: |
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c index 60bd7d708e35..4985384e51f6 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c | |||
| @@ -241,6 +241,7 @@ void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane, | |||
| 241 | 241 | ||
| 242 | state->fence = NULL; | 242 | state->fence = NULL; |
| 243 | state->commit = NULL; | 243 | state->commit = NULL; |
| 244 | state->fb_damage_clips = NULL; | ||
| 244 | } | 245 | } |
| 245 | EXPORT_SYMBOL(__drm_atomic_helper_plane_duplicate_state); | 246 | EXPORT_SYMBOL(__drm_atomic_helper_plane_duplicate_state); |
| 246 | 247 | ||
| @@ -285,6 +286,8 @@ void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state) | |||
| 285 | 286 | ||
| 286 | if (state->commit) | 287 | if (state->commit) |
| 287 | drm_crtc_commit_put(state->commit); | 288 | drm_crtc_commit_put(state->commit); |
| 289 | |||
| 290 | drm_property_blob_put(state->fb_damage_clips); | ||
| 288 | } | 291 | } |
| 289 | EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state); | 292 | EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state); |
| 290 | 293 | ||
diff --git a/drivers/gpu/drm/drm_damage_helper.c b/drivers/gpu/drm/drm_damage_helper.c index d2a1c7372f36..31032407254d 100644 --- a/drivers/gpu/drm/drm_damage_helper.c +++ b/drivers/gpu/drm/drm_damage_helper.c | |||
| @@ -178,7 +178,7 @@ int drm_atomic_helper_dirtyfb(struct drm_framebuffer *fb, | |||
| 178 | state = drm_atomic_state_alloc(fb->dev); | 178 | state = drm_atomic_state_alloc(fb->dev); |
| 179 | if (!state) { | 179 | if (!state) { |
| 180 | ret = -ENOMEM; | 180 | ret = -ENOMEM; |
| 181 | goto out; | 181 | goto out_drop_locks; |
| 182 | } | 182 | } |
| 183 | state->acquire_ctx = &ctx; | 183 | state->acquire_ctx = &ctx; |
| 184 | 184 | ||
| @@ -238,6 +238,7 @@ out: | |||
| 238 | kfree(rects); | 238 | kfree(rects); |
| 239 | drm_atomic_state_put(state); | 239 | drm_atomic_state_put(state); |
| 240 | 240 | ||
| 241 | out_drop_locks: | ||
| 241 | drm_modeset_drop_locks(&ctx); | 242 | drm_modeset_drop_locks(&ctx); |
| 242 | drm_modeset_acquire_fini(&ctx); | 243 | drm_modeset_acquire_fini(&ctx); |
| 243 | 244 | ||
diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c b/drivers/gpu/drm/i915/gvt/cmd_parser.c index 77edbfcb0f75..77ae634eb11c 100644 --- a/drivers/gpu/drm/i915/gvt/cmd_parser.c +++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c | |||
| @@ -1900,11 +1900,11 @@ static struct cmd_info cmd_info[] = { | |||
| 1900 | 1900 | ||
| 1901 | {"MI_URB_CLEAR", OP_MI_URB_CLEAR, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL}, | 1901 | {"MI_URB_CLEAR", OP_MI_URB_CLEAR, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL}, |
| 1902 | 1902 | ||
| 1903 | {"ME_SEMAPHORE_SIGNAL", OP_MI_SEMAPHORE_SIGNAL, F_LEN_VAR, R_ALL, | 1903 | {"MI_SEMAPHORE_SIGNAL", OP_MI_SEMAPHORE_SIGNAL, F_LEN_VAR, R_ALL, |
| 1904 | D_BDW_PLUS, 0, 8, NULL}, | 1904 | D_BDW_PLUS, 0, 8, NULL}, |
| 1905 | 1905 | ||
| 1906 | {"ME_SEMAPHORE_WAIT", OP_MI_SEMAPHORE_WAIT, F_LEN_VAR, R_ALL, D_BDW_PLUS, | 1906 | {"MI_SEMAPHORE_WAIT", OP_MI_SEMAPHORE_WAIT, F_LEN_VAR, R_ALL, |
| 1907 | ADDR_FIX_1(2), 8, cmd_handler_mi_semaphore_wait}, | 1907 | D_BDW_PLUS, ADDR_FIX_1(2), 8, cmd_handler_mi_semaphore_wait}, |
| 1908 | 1908 | ||
| 1909 | {"MI_STORE_DATA_IMM", OP_MI_STORE_DATA_IMM, F_LEN_VAR, R_ALL, D_BDW_PLUS, | 1909 | {"MI_STORE_DATA_IMM", OP_MI_STORE_DATA_IMM, F_LEN_VAR, R_ALL, D_BDW_PLUS, |
| 1910 | ADDR_FIX_1(1), 10, cmd_handler_mi_store_data_imm}, | 1910 | ADDR_FIX_1(1), 10, cmd_handler_mi_store_data_imm}, |
diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c index 6ef5a7fc70df..733a2a0d0c30 100644 --- a/drivers/gpu/drm/i915/gvt/gvt.c +++ b/drivers/gpu/drm/i915/gvt/gvt.c | |||
| @@ -437,7 +437,7 @@ int intel_gvt_init_device(struct drm_i915_private *dev_priv) | |||
| 437 | 437 | ||
| 438 | ret = intel_gvt_debugfs_init(gvt); | 438 | ret = intel_gvt_debugfs_init(gvt); |
| 439 | if (ret) | 439 | if (ret) |
| 440 | gvt_err("debugfs registeration failed, go on.\n"); | 440 | gvt_err("debugfs registration failed, go on.\n"); |
| 441 | 441 | ||
| 442 | gvt_dbg_core("gvt device initialization is done\n"); | 442 | gvt_dbg_core("gvt device initialization is done\n"); |
| 443 | dev_priv->gvt = gvt; | 443 | dev_priv->gvt = gvt; |
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h index 31f6cdbe5c42..b4ab1dad0143 100644 --- a/drivers/gpu/drm/i915/gvt/gvt.h +++ b/drivers/gpu/drm/i915/gvt/gvt.h | |||
| @@ -159,6 +159,10 @@ struct intel_vgpu_submission { | |||
| 159 | struct kmem_cache *workloads; | 159 | struct kmem_cache *workloads; |
| 160 | atomic_t running_workload_num; | 160 | atomic_t running_workload_num; |
| 161 | struct i915_gem_context *shadow_ctx; | 161 | struct i915_gem_context *shadow_ctx; |
| 162 | union { | ||
| 163 | u64 i915_context_pml4; | ||
| 164 | u64 i915_context_pdps[GEN8_3LVL_PDPES]; | ||
| 165 | }; | ||
| 162 | DECLARE_BITMAP(shadow_ctx_desc_updated, I915_NUM_ENGINES); | 166 | DECLARE_BITMAP(shadow_ctx_desc_updated, I915_NUM_ENGINES); |
| 163 | DECLARE_BITMAP(tlb_handle_pending, I915_NUM_ENGINES); | 167 | DECLARE_BITMAP(tlb_handle_pending, I915_NUM_ENGINES); |
| 164 | void *ring_scan_buffer[I915_NUM_ENGINES]; | 168 | void *ring_scan_buffer[I915_NUM_ENGINES]; |
diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index aa280bb07125..b5475c91e2ef 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c | |||
| @@ -475,6 +475,7 @@ static i915_reg_t force_nonpriv_white_list[] = { | |||
| 475 | _MMIO(0x7704), | 475 | _MMIO(0x7704), |
| 476 | _MMIO(0x7708), | 476 | _MMIO(0x7708), |
| 477 | _MMIO(0x770c), | 477 | _MMIO(0x770c), |
| 478 | _MMIO(0x83a8), | ||
| 478 | _MMIO(0xb110), | 479 | _MMIO(0xb110), |
| 479 | GEN8_L3SQCREG4,//_MMIO(0xb118) | 480 | GEN8_L3SQCREG4,//_MMIO(0xb118) |
| 480 | _MMIO(0xe100), | 481 | _MMIO(0xe100), |
diff --git a/drivers/gpu/drm/i915/gvt/interrupt.c b/drivers/gpu/drm/i915/gvt/interrupt.c index 5daa23ae566b..6b9d1354ff29 100644 --- a/drivers/gpu/drm/i915/gvt/interrupt.c +++ b/drivers/gpu/drm/i915/gvt/interrupt.c | |||
| @@ -126,7 +126,7 @@ static const char * const irq_name[INTEL_GVT_EVENT_MAX] = { | |||
| 126 | [FDI_RX_INTERRUPTS_TRANSCODER_C] = "FDI RX Interrupts Combined C", | 126 | [FDI_RX_INTERRUPTS_TRANSCODER_C] = "FDI RX Interrupts Combined C", |
| 127 | [AUDIO_CP_CHANGE_TRANSCODER_C] = "Audio CP Change Transcoder C", | 127 | [AUDIO_CP_CHANGE_TRANSCODER_C] = "Audio CP Change Transcoder C", |
| 128 | [AUDIO_CP_REQUEST_TRANSCODER_C] = "Audio CP Request Transcoder C", | 128 | [AUDIO_CP_REQUEST_TRANSCODER_C] = "Audio CP Request Transcoder C", |
| 129 | [ERR_AND_DBG] = "South Error and Debug Interupts Combined", | 129 | [ERR_AND_DBG] = "South Error and Debug Interrupts Combined", |
| 130 | [GMBUS] = "Gmbus", | 130 | [GMBUS] = "Gmbus", |
| 131 | [SDVO_B_HOTPLUG] = "SDVO B hotplug", | 131 | [SDVO_B_HOTPLUG] = "SDVO B hotplug", |
| 132 | [CRT_HOTPLUG] = "CRT Hotplug", | 132 | [CRT_HOTPLUG] = "CRT Hotplug", |
diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c index b8fbe3fabea3..1ad8c5e1455d 100644 --- a/drivers/gpu/drm/i915/gvt/scheduler.c +++ b/drivers/gpu/drm/i915/gvt/scheduler.c | |||
| @@ -1079,6 +1079,21 @@ err: | |||
| 1079 | return ret; | 1079 | return ret; |
| 1080 | } | 1080 | } |
| 1081 | 1081 | ||
| 1082 | static void | ||
| 1083 | i915_context_ppgtt_root_restore(struct intel_vgpu_submission *s) | ||
| 1084 | { | ||
| 1085 | struct i915_hw_ppgtt *i915_ppgtt = s->shadow_ctx->ppgtt; | ||
| 1086 | int i; | ||
| 1087 | |||
| 1088 | if (i915_vm_is_48bit(&i915_ppgtt->vm)) | ||
| 1089 | px_dma(&i915_ppgtt->pml4) = s->i915_context_pml4; | ||
| 1090 | else { | ||
| 1091 | for (i = 0; i < GEN8_3LVL_PDPES; i++) | ||
| 1092 | px_dma(i915_ppgtt->pdp.page_directory[i]) = | ||
| 1093 | s->i915_context_pdps[i]; | ||
| 1094 | } | ||
| 1095 | } | ||
| 1096 | |||
| 1082 | /** | 1097 | /** |
| 1083 | * intel_vgpu_clean_submission - free submission-related resource for vGPU | 1098 | * intel_vgpu_clean_submission - free submission-related resource for vGPU |
| 1084 | * @vgpu: a vGPU | 1099 | * @vgpu: a vGPU |
| @@ -1091,6 +1106,7 @@ void intel_vgpu_clean_submission(struct intel_vgpu *vgpu) | |||
| 1091 | struct intel_vgpu_submission *s = &vgpu->submission; | 1106 | struct intel_vgpu_submission *s = &vgpu->submission; |
| 1092 | 1107 | ||
| 1093 | intel_vgpu_select_submission_ops(vgpu, ALL_ENGINES, 0); | 1108 | intel_vgpu_select_submission_ops(vgpu, ALL_ENGINES, 0); |
| 1109 | i915_context_ppgtt_root_restore(s); | ||
| 1094 | i915_gem_context_put(s->shadow_ctx); | 1110 | i915_gem_context_put(s->shadow_ctx); |
| 1095 | kmem_cache_destroy(s->workloads); | 1111 | kmem_cache_destroy(s->workloads); |
| 1096 | } | 1112 | } |
| @@ -1116,6 +1132,21 @@ void intel_vgpu_reset_submission(struct intel_vgpu *vgpu, | |||
| 1116 | s->ops->reset(vgpu, engine_mask); | 1132 | s->ops->reset(vgpu, engine_mask); |
| 1117 | } | 1133 | } |
| 1118 | 1134 | ||
| 1135 | static void | ||
| 1136 | i915_context_ppgtt_root_save(struct intel_vgpu_submission *s) | ||
| 1137 | { | ||
| 1138 | struct i915_hw_ppgtt *i915_ppgtt = s->shadow_ctx->ppgtt; | ||
| 1139 | int i; | ||
| 1140 | |||
| 1141 | if (i915_vm_is_48bit(&i915_ppgtt->vm)) | ||
| 1142 | s->i915_context_pml4 = px_dma(&i915_ppgtt->pml4); | ||
| 1143 | else { | ||
| 1144 | for (i = 0; i < GEN8_3LVL_PDPES; i++) | ||
| 1145 | s->i915_context_pdps[i] = | ||
| 1146 | px_dma(i915_ppgtt->pdp.page_directory[i]); | ||
| 1147 | } | ||
| 1148 | } | ||
| 1149 | |||
| 1119 | /** | 1150 | /** |
| 1120 | * intel_vgpu_setup_submission - setup submission-related resource for vGPU | 1151 | * intel_vgpu_setup_submission - setup submission-related resource for vGPU |
| 1121 | * @vgpu: a vGPU | 1152 | * @vgpu: a vGPU |
| @@ -1138,6 +1169,8 @@ int intel_vgpu_setup_submission(struct intel_vgpu *vgpu) | |||
| 1138 | if (IS_ERR(s->shadow_ctx)) | 1169 | if (IS_ERR(s->shadow_ctx)) |
| 1139 | return PTR_ERR(s->shadow_ctx); | 1170 | return PTR_ERR(s->shadow_ctx); |
| 1140 | 1171 | ||
| 1172 | i915_context_ppgtt_root_save(s); | ||
| 1173 | |||
| 1141 | bitmap_zero(s->shadow_ctx_desc_updated, I915_NUM_ENGINES); | 1174 | bitmap_zero(s->shadow_ctx_desc_updated, I915_NUM_ENGINES); |
| 1142 | 1175 | ||
| 1143 | s->workloads = kmem_cache_create_usercopy("gvt-g_vgpu_workload", | 1176 | s->workloads = kmem_cache_create_usercopy("gvt-g_vgpu_workload", |
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index d87935bf8e30..0ec08394e17a 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c | |||
| @@ -77,38 +77,39 @@ static inline int ttm_mem_type_from_place(const struct ttm_place *place, | |||
| 77 | return 0; | 77 | return 0; |
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | static void ttm_mem_type_debug(struct ttm_bo_device *bdev, int mem_type) | 80 | static void ttm_mem_type_debug(struct ttm_bo_device *bdev, struct drm_printer *p, |
| 81 | int mem_type) | ||
| 81 | { | 82 | { |
| 82 | struct ttm_mem_type_manager *man = &bdev->man[mem_type]; | 83 | struct ttm_mem_type_manager *man = &bdev->man[mem_type]; |
| 83 | struct drm_printer p = drm_debug_printer(TTM_PFX); | ||
| 84 | 84 | ||
| 85 | pr_err(" has_type: %d\n", man->has_type); | 85 | drm_printf(p, " has_type: %d\n", man->has_type); |
| 86 | pr_err(" use_type: %d\n", man->use_type); | 86 | drm_printf(p, " use_type: %d\n", man->use_type); |
| 87 | pr_err(" flags: 0x%08X\n", man->flags); | 87 | drm_printf(p, " flags: 0x%08X\n", man->flags); |
| 88 | pr_err(" gpu_offset: 0x%08llX\n", man->gpu_offset); | 88 | drm_printf(p, " gpu_offset: 0x%08llX\n", man->gpu_offset); |
| 89 | pr_err(" size: %llu\n", man->size); | 89 | drm_printf(p, " size: %llu\n", man->size); |
| 90 | pr_err(" available_caching: 0x%08X\n", man->available_caching); | 90 | drm_printf(p, " available_caching: 0x%08X\n", man->available_caching); |
| 91 | pr_err(" default_caching: 0x%08X\n", man->default_caching); | 91 | drm_printf(p, " default_caching: 0x%08X\n", man->default_caching); |
| 92 | if (mem_type != TTM_PL_SYSTEM) | 92 | if (mem_type != TTM_PL_SYSTEM) |
| 93 | (*man->func->debug)(man, &p); | 93 | (*man->func->debug)(man, p); |
| 94 | } | 94 | } |
| 95 | 95 | ||
| 96 | static void ttm_bo_mem_space_debug(struct ttm_buffer_object *bo, | 96 | static void ttm_bo_mem_space_debug(struct ttm_buffer_object *bo, |
| 97 | struct ttm_placement *placement) | 97 | struct ttm_placement *placement) |
| 98 | { | 98 | { |
| 99 | struct drm_printer p = drm_debug_printer(TTM_PFX); | ||
| 99 | int i, ret, mem_type; | 100 | int i, ret, mem_type; |
| 100 | 101 | ||
| 101 | pr_err("No space for %p (%lu pages, %luK, %luM)\n", | 102 | drm_printf(&p, "No space for %p (%lu pages, %luK, %luM)\n", |
| 102 | bo, bo->mem.num_pages, bo->mem.size >> 10, | 103 | bo, bo->mem.num_pages, bo->mem.size >> 10, |
| 103 | bo->mem.size >> 20); | 104 | bo->mem.size >> 20); |
| 104 | for (i = 0; i < placement->num_placement; i++) { | 105 | for (i = 0; i < placement->num_placement; i++) { |
| 105 | ret = ttm_mem_type_from_place(&placement->placement[i], | 106 | ret = ttm_mem_type_from_place(&placement->placement[i], |
| 106 | &mem_type); | 107 | &mem_type); |
| 107 | if (ret) | 108 | if (ret) |
| 108 | return; | 109 | return; |
| 109 | pr_err(" placement[%d]=0x%08X (%d)\n", | 110 | drm_printf(&p, " placement[%d]=0x%08X (%d)\n", |
| 110 | i, placement->placement[i].flags, mem_type); | 111 | i, placement->placement[i].flags, mem_type); |
| 111 | ttm_mem_type_debug(bo->bdev, mem_type); | 112 | ttm_mem_type_debug(bo->bdev, &p, mem_type); |
| 112 | } | 113 | } |
| 113 | } | 114 | } |
| 114 | 115 | ||
