Re: [PATCH] drm/amdkfd: Fix a compiling warning
On 2020-01-10 7:40 p.m., Yong Zhao wrote: The warning was introduced in commit b4267f2e687ff5e0402ab915c9a4d47f9a4eb73e Author: Yong Zhao Date: Fri Dec 13 11:31:48 2019 -0500 drm/amdkfd: Improve function get_sdma_rlc_reg_offset() Change-Id: I87da4f1ad8a190327a4a71f0ff78812cb942d6e0 Signed-off-by: Yong Zhao Instead of quoting the whole change description, the usual way to point to a prior patch that you're fixing is with a tag Fixes: <12 digits of sha1> ("commit title") With that fixed, this patch is Reviewed-by: Felix Kuehling --- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c index 2b26925623eb..f9011a07cb90 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c @@ -71,7 +71,7 @@ static uint32_t get_sdma_rlc_reg_offset(struct amdgpu_device *adev, unsigned int engine_id, unsigned int queue_id) { - uint32_t sdma_engine_reg_base; + uint32_t sdma_engine_reg_base = 0; uint32_t sdma_rlc_reg_offset; switch (engine_id) { ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdkfd: Fix a compiling warning
The warning was introduced in commit b4267f2e687ff5e0402ab915c9a4d47f9a4eb73e Author: Yong Zhao Date: Fri Dec 13 11:31:48 2019 -0500 drm/amdkfd: Improve function get_sdma_rlc_reg_offset() Change-Id: I87da4f1ad8a190327a4a71f0ff78812cb942d6e0 Signed-off-by: Yong Zhao --- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c index 2b26925623eb..f9011a07cb90 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c @@ -71,7 +71,7 @@ static uint32_t get_sdma_rlc_reg_offset(struct amdgpu_device *adev, unsigned int engine_id, unsigned int queue_id) { - uint32_t sdma_engine_reg_base; + uint32_t sdma_engine_reg_base = 0; uint32_t sdma_rlc_reg_offset; switch (engine_id) { -- 2.17.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu/df3.6: remove unused variable
Unused so drop it. Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/df_v3_6.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/df_v3_6.c b/drivers/gpu/drm/amd/amdgpu/df_v3_6.c index 3761c8cc1156..f51326598a8c 100644 --- a/drivers/gpu/drm/amd/amdgpu/df_v3_6.c +++ b/drivers/gpu/drm/amd/amdgpu/df_v3_6.c @@ -264,7 +264,7 @@ static DEVICE_ATTR(df_cntr_avail, S_IRUGO, df_v3_6_get_df_cntr_avail, NULL); static void df_v3_6_query_hashes(struct amdgpu_device *adev) { - u32 chan_cfg, tmp; + u32 tmp; adev->df.hash_status.hash_64k = false; adev->df.hash_status.hash_2m = false; -- 2.24.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 1/2] drm/amd/display: Reorder detect_edp_sink_caps before link settings read.
Applied. Thanks! Alex On Thu, Jan 9, 2020 at 1:41 PM Harry Wentland wrote: > > On 2020-01-09 10:20 a.m., Mario Kleiner wrote: > > read_current_link_settings_on_detect() on eDP 1.4+ may use the > > edp_supported_link_rates table which is set up by > > detect_edp_sink_caps(), so that function needs to be called first. > > > > Signed-off-by: Mario Kleiner > > Cc: Martin Leung > > Reviewed-by: Harry Wentland > > This also fixes our assumption that retrieve_link_cap is the first DPCD > reads we perform during detection. > > Harry > > > --- > > drivers/gpu/drm/amd/display/dc/core/dc_link.c | 2 +- > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > 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 cef8c1ba9797..5ea4a1675259 100644 > > --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c > > +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c > > @@ -817,8 +817,8 @@ static bool dc_link_detect_helper(struct dc_link *link, > > } > > > > case SIGNAL_TYPE_EDP: { > > - read_current_link_settings_on_detect(link); > > detect_edp_sink_caps(link); > > + read_current_link_settings_on_detect(link); > > sink_caps.transaction_type = > > DDC_TRANSACTION_TYPE_I2C_OVER_AUX; > > sink_caps.signal = SIGNAL_TYPE_EDP; > > break; > > > ___ > amd-gfx mailing list > amd-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/amd-gfx ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH] drm/amd/display: remove unnecessary conversion to bool
Applied. thanks! On Fri, Jan 10, 2020 at 4:41 PM Harry Wentland wrote: > > On 2020-01-10 2:16 a.m., Chen Zhou wrote: > > The conversion to bool is not needed, remove it. > >> Signed-off-by: Chen Zhou > > Reviewed-by: Harry Wentland > > Harry > > > --- > > drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 2 +- > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > 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 504055f..a004e8e 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 > > @@ -2792,7 +2792,7 @@ static bool retrieve_link_cap(struct dc_link *link) > > dpcd_data[DP_TRAINING_AUX_RD_INTERVAL]; > > > > link->dpcd_caps.ext_receiver_cap_field_present = > > - > > aux_rd_interval.bits.EXT_RECEIVER_CAP_FIELD_PRESENT == 1 ? true:false; > > + > > aux_rd_interval.bits.EXT_RECEIVER_CAP_FIELD_PRESENT == 1; > > > > if (aux_rd_interval.bits.EXT_RECEIVER_CAP_FIELD_PRESENT == 1) > > { > > uint8_t ext_cap_data[16]; > > > ___ > amd-gfx mailing list > amd-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/amd-gfx ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 2/2] drm/amdgpu/debugfs: properly handle runtime pm
If driver debugfs files are accessed, power up the GPU when necessary. Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | 133 ++-- drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 8 ++ 2 files changed, 134 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c index 63343bb43049..f24ed9a1a3e5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c @@ -26,6 +26,7 @@ #include #include #include +#include #include @@ -144,10 +145,17 @@ static int amdgpu_debugfs_process_reg_op(bool read, struct file *f, *pos &= (1UL << 22) - 1; + r = pm_runtime_get_sync(adev->ddev->dev); + if (r < 0) + return r; + if (use_bank) { if ((sh_bank != 0x && sh_bank >= adev->gfx.config.max_sh_per_se) || - (se_bank != 0x && se_bank >= adev->gfx.config.max_shader_engines)) + (se_bank != 0x && se_bank >= adev->gfx.config.max_shader_engines)) { + pm_runtime_mark_last_busy(adev->ddev->dev); + pm_runtime_put_autosuspend(adev->ddev->dev); return -EINVAL; + } mutex_lock(&adev->grbm_idx_mutex); amdgpu_gfx_select_se_sh(adev, se_bank, sh_bank, instance_bank); @@ -193,6 +201,9 @@ static int amdgpu_debugfs_process_reg_op(bool read, struct file *f, if (pm_pg_lock) mutex_unlock(&adev->pm.mutex); + pm_runtime_mark_last_busy(adev->ddev->dev); + pm_runtime_put_autosuspend(adev->ddev->dev); + return result; } @@ -237,13 +248,20 @@ static ssize_t amdgpu_debugfs_regs_pcie_read(struct file *f, char __user *buf, if (size & 0x3 || *pos & 0x3) return -EINVAL; + r = pm_runtime_get_sync(adev->ddev->dev); + if (r < 0) + return r; + while (size) { uint32_t value; value = RREG32_PCIE(*pos >> 2); r = put_user(value, (uint32_t *)buf); - if (r) + if (r) { + pm_runtime_mark_last_busy(adev->ddev->dev); + pm_runtime_put_autosuspend(adev->ddev->dev); return r; + } result += 4; buf += 4; @@ -251,6 +269,9 @@ static ssize_t amdgpu_debugfs_regs_pcie_read(struct file *f, char __user *buf, size -= 4; } + pm_runtime_mark_last_busy(adev->ddev->dev); + pm_runtime_put_autosuspend(adev->ddev->dev); + return result; } @@ -276,12 +297,19 @@ static ssize_t amdgpu_debugfs_regs_pcie_write(struct file *f, const char __user if (size & 0x3 || *pos & 0x3) return -EINVAL; + r = pm_runtime_get_sync(adev->ddev->dev); + if (r < 0) + return r; + while (size) { uint32_t value; r = get_user(value, (uint32_t *)buf); - if (r) + if (r) { + pm_runtime_mark_last_busy(adev->ddev->dev); + pm_runtime_put_autosuspend(adev->ddev->dev); return r; + } WREG32_PCIE(*pos >> 2, value); @@ -291,6 +319,9 @@ static ssize_t amdgpu_debugfs_regs_pcie_write(struct file *f, const char __user size -= 4; } + pm_runtime_mark_last_busy(adev->ddev->dev); + pm_runtime_put_autosuspend(adev->ddev->dev); + return result; } @@ -316,13 +347,20 @@ static ssize_t amdgpu_debugfs_regs_didt_read(struct file *f, char __user *buf, if (size & 0x3 || *pos & 0x3) return -EINVAL; + r = pm_runtime_get_sync(adev->ddev->dev); + if (r < 0) + return r; + while (size) { uint32_t value; value = RREG32_DIDT(*pos >> 2); r = put_user(value, (uint32_t *)buf); - if (r) + if (r) { + pm_runtime_mark_last_busy(adev->ddev->dev); + pm_runtime_put_autosuspend(adev->ddev->dev); return r; + } result += 4; buf += 4; @@ -330,6 +368,9 @@ static ssize_t amdgpu_debugfs_regs_didt_read(struct file *f, char __user *buf, size -= 4; } + pm_runtime_mark_last_busy(adev->ddev->dev); + pm_runtime_put_autosuspend(adev->ddev->dev); + return result; } @@ -355,12 +396,19 @@ static ssize_t amdgpu_debugfs_regs_didt_write(struct file *f, const char __user if (size & 0x3 || *pos & 0x3) return -EINVAL; + r = pm_runtime_get_sync(adev->ddev->dev); + if (r < 0) +
[PATCH 1/2] drm/amdgpu/pm: properly handle runtime pm
If power management sysfs or debugfs files are accessed, power up the GPU when necessary. Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 822 ++--- 1 file changed, 614 insertions(+), 208 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index 285d460624c8..806e731c1ff4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -37,6 +37,7 @@ #include #include #include +#include #include "hwmgr.h" #define WIDTH_4K 3840 @@ -158,10 +159,15 @@ static ssize_t amdgpu_get_dpm_state(struct device *dev, struct drm_device *ddev = dev_get_drvdata(dev); struct amdgpu_device *adev = ddev->dev_private; enum amd_pm_state_type pm; + int ret; if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) return 0; + ret = pm_runtime_get_sync(ddev->dev); + if (ret < 0) + return ret; + if (is_support_sw_smu(adev)) { if (adev->smu.ppt_funcs->get_current_power_state) pm = smu_get_current_power_state(&adev->smu); @@ -173,6 +179,9 @@ static ssize_t amdgpu_get_dpm_state(struct device *dev, pm = adev->pm.dpm.user_state; } + pm_runtime_mark_last_busy(ddev->dev); + pm_runtime_put_autosuspend(ddev->dev); + return snprintf(buf, PAGE_SIZE, "%s\n", (pm == POWER_STATE_TYPE_BATTERY) ? "battery" : (pm == POWER_STATE_TYPE_BALANCED) ? "balanced" : "performance"); @@ -186,6 +195,7 @@ static ssize_t amdgpu_set_dpm_state(struct device *dev, struct drm_device *ddev = dev_get_drvdata(dev); struct amdgpu_device *adev = ddev->dev_private; enum amd_pm_state_type state; + int ret; if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) return -EINVAL; @@ -201,6 +211,10 @@ static ssize_t amdgpu_set_dpm_state(struct device *dev, goto fail; } + ret = pm_runtime_get_sync(ddev->dev); + if (ret < 0) + return ret; + if (is_support_sw_smu(adev)) { mutex_lock(&adev->pm.mutex); adev->pm.dpm.user_state = state; @@ -212,11 +226,12 @@ static ssize_t amdgpu_set_dpm_state(struct device *dev, adev->pm.dpm.user_state = state; mutex_unlock(&adev->pm.mutex); - /* Can't set dpm state when the card is off */ - if (!(adev->flags & AMD_IS_PX) || - (ddev->switch_power_state == DRM_SWITCH_POWER_ON)) - amdgpu_pm_compute_clocks(adev); + amdgpu_pm_compute_clocks(adev); } + pm_runtime_mark_last_busy(ddev->dev); + pm_runtime_put_autosuspend(ddev->dev); + + fail: return count; } @@ -288,13 +303,14 @@ static ssize_t amdgpu_get_dpm_forced_performance_level(struct device *dev, struct drm_device *ddev = dev_get_drvdata(dev); struct amdgpu_device *adev = ddev->dev_private; enum amd_dpm_forced_level level = 0xff; + int ret; if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) return 0; - if ((adev->flags & AMD_IS_PX) && - (ddev->switch_power_state != DRM_SWITCH_POWER_ON)) - return snprintf(buf, PAGE_SIZE, "off\n"); + ret = pm_runtime_get_sync(ddev->dev); + if (ret < 0) + return ret; if (is_support_sw_smu(adev)) level = smu_get_performance_level(&adev->smu); @@ -303,6 +319,9 @@ static ssize_t amdgpu_get_dpm_forced_performance_level(struct device *dev, else level = adev->pm.dpm.forced_level; + pm_runtime_mark_last_busy(ddev->dev); + pm_runtime_put_autosuspend(ddev->dev); + return snprintf(buf, PAGE_SIZE, "%s\n", (level == AMD_DPM_FORCED_LEVEL_AUTO) ? "auto" : (level == AMD_DPM_FORCED_LEVEL_LOW) ? "low" : @@ -329,11 +348,6 @@ static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev, if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) return -EINVAL; - /* Can't force performance level when the card is off */ - if ((adev->flags & AMD_IS_PX) && -(ddev->switch_power_state != DRM_SWITCH_POWER_ON)) - return -EINVAL; - if (strncmp("low", buf, strlen("low")) == 0) { level = AMD_DPM_FORCED_LEVEL_LOW; } else if (strncmp("high", buf, strlen("high")) == 0) { @@ -353,17 +367,23 @@ static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev, } else if (strncmp("profile_peak", buf, strlen("profile_peak")) == 0) { level = AMD_DPM_FORCED_LEVEL_PROFILE_PEAK; } else { - count = -EINVAL; - goto
Re: [PATCH 5/5] drm/amdkfd: use map_queues for hiq on gfx v8 as well
On 2020-01-10 1:37 a.m., Huang Rui wrote: Align with gfx v9, use map_queues packet to load hiq MQD. Signed-off-by: Huang Rui Please make sure you test this on a GFXv8 GPU. Reviewed-by: Felix Kuehling --- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c | 69 ++- drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c | 10 +++- 2 files changed, 63 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c index bfbdded..6adac95 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c @@ -207,21 +207,6 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, acquire_queue(kgd, pipe_id, queue_id); - /* HIQ is set during driver init period with vmid set to 0*/ - if (m->cp_hqd_vmid == 0) { - uint32_t value, mec, pipe; - - mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1; - pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec); - - pr_debug("kfd: set HIQ, mec:%d, pipe:%d, queue:%d.\n", - mec, pipe, queue_id); - value = RREG32(mmRLC_CP_SCHEDULERS); - value = REG_SET_FIELD(value, RLC_CP_SCHEDULERS, scheduler1, - ((mec << 5) | (pipe << 3) | queue_id | 0x80)); - WREG32(mmRLC_CP_SCHEDULERS, value); - } - /* HQD registers extend from CP_MQD_BASE_ADDR to CP_HQD_EOP_WPTR_MEM. */ mqd_hqd = &m->cp_mqd_base_addr_lo; @@ -267,6 +252,59 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, return 0; } +static int kgd_hiq_mqd_load(struct kgd_dev *kgd, void *mqd, + uint32_t pipe_id, uint32_t queue_id, + uint32_t doorbell_off) +{ + struct amdgpu_device *adev = get_amdgpu_device(kgd); + struct amdgpu_ring *kiq_ring = &adev->gfx.kiq.ring; + struct vi_mqd *m; + uint32_t mec, pipe; + int r; + + m = get_mqd(mqd); + + acquire_queue(kgd, pipe_id, queue_id); + + mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1; + pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec); + + pr_debug("kfd: set HIQ, mec:%d, pipe:%d, queue:%d.\n", +mec, pipe, queue_id); + + spin_lock(&adev->gfx.kiq.ring_lock); + r = amdgpu_ring_alloc(kiq_ring, 7); + if (r) { + pr_err("Failed to alloc KIQ (%d).\n", r); + goto out_unlock; + } + + amdgpu_ring_write(kiq_ring, PACKET3(PACKET3_MAP_QUEUES, 5)); + amdgpu_ring_write(kiq_ring, + PACKET3_MAP_QUEUES_QUEUE_SEL(0) | /* Queue_Sel */ + PACKET3_MAP_QUEUES_VMID(m->cp_hqd_vmid) | /* VMID */ + PACKET3_MAP_QUEUES_QUEUE(queue_id) | + PACKET3_MAP_QUEUES_PIPE(pipe) | + PACKET3_MAP_QUEUES_ME((mec - 1)) | + PACKET3_MAP_QUEUES_QUEUE_TYPE(0) | /*queue_type: normal compute queue */ + PACKET3_MAP_QUEUES_ALLOC_FORMAT(0) | /* alloc format: all_on_one_pipe */ + PACKET3_MAP_QUEUES_ENGINE_SEL(1) | /* engine_sel: hiq */ + PACKET3_MAP_QUEUES_NUM_QUEUES(1)); /* num_queues: must be 1 */ + amdgpu_ring_write(kiq_ring, + PACKET3_MAP_QUEUES_DOORBELL_OFFSET(doorbell_off)); + amdgpu_ring_write(kiq_ring, m->cp_mqd_base_addr_lo); + amdgpu_ring_write(kiq_ring, m->cp_mqd_base_addr_hi); + amdgpu_ring_write(kiq_ring, m->cp_hqd_pq_wptr_poll_addr_lo); + amdgpu_ring_write(kiq_ring, m->cp_hqd_pq_wptr_poll_addr_hi); + amdgpu_ring_commit(kiq_ring); + +out_unlock: + spin_unlock(&adev->gfx.kiq.ring_lock); + release_queue(kgd); + + return r; +} + static int kgd_hqd_dump(struct kgd_dev *kgd, uint32_t pipe_id, uint32_t queue_id, uint32_t (**dump)[2], uint32_t *n_regs) @@ -701,6 +739,7 @@ const struct kfd2kgd_calls gfx_v8_kfd2kgd = { .set_pasid_vmid_mapping = kgd_set_pasid_vmid_mapping, .init_interrupts = kgd_init_interrupts, .hqd_load = kgd_hqd_load, + .hiq_mqd_load = kgd_hiq_mqd_load, .hqd_sdma_load = kgd_hqd_sdma_load, .hqd_dump = kgd_hqd_dump, .hqd_sdma_dump = kgd_hqd_sdma_dump, diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c index a5e8ff1..15cbfd4 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c @@ -166,6 +166,14 @@ static int load_mqd(struct mqd_manager *mm, void *mqd, wptr_shift, wptr_mask, mms); } +static int hiq_load_mqd_kiq(struct mqd_manager *mm, void *mqd, + uin
Re: [PATCH 4/5] drm/amdkfd: use map_queues for hiq on gfx v10 as well
On 2020-01-10 1:37 a.m., Huang Rui wrote: To align with gfx v9, we use the map_queues packet to load hiq MQD. Signed-off-by: Huang Rui Please make sure you test this on a GFXv10 GPU. Reviewed-by: Felix Kuehling --- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c | 82 -- drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c | 10 ++- 2 files changed, 70 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c index 61cd707..2a60f73 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c @@ -107,13 +107,13 @@ static void acquire_queue(struct kgd_dev *kgd, uint32_t pipe_id, lock_srbm(kgd, mec, pipe, queue_id, 0); } -static uint32_t get_queue_mask(struct amdgpu_device *adev, +static uint64_t get_queue_mask(struct amdgpu_device *adev, uint32_t pipe_id, uint32_t queue_id) { - unsigned int bit = (pipe_id * adev->gfx.mec.num_queue_per_pipe + - queue_id) & 31; + unsigned int bit = pipe_id * adev->gfx.mec.num_queue_per_pipe + + queue_id; - return ((uint32_t)1) << bit; + return 1ull << bit; } static void release_queue(struct kgd_dev *kgd) @@ -268,21 +268,6 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, pr_debug("Load hqd of pipe %d queue %d\n", pipe_id, queue_id); acquire_queue(kgd, pipe_id, queue_id); - /* HIQ is set during driver init period with vmid set to 0*/ - if (m->cp_hqd_vmid == 0) { - uint32_t value, mec, pipe; - - mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1; - pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec); - - pr_debug("kfd: set HIQ, mec:%d, pipe:%d, queue:%d.\n", - mec, pipe, queue_id); - value = RREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_CP_SCHEDULERS)); - value = REG_SET_FIELD(value, RLC_CP_SCHEDULERS, scheduler1, - ((mec << 5) | (pipe << 3) | queue_id | 0x80)); - WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_CP_SCHEDULERS), value); - } - /* HQD registers extend from CP_MQD_BASE_ADDR to CP_HQD_EOP_WPTR_MEM. */ mqd_hqd = &m->cp_mqd_base_addr_lo; hqd_base = SOC15_REG_OFFSET(GC, 0, mmCP_MQD_BASE_ADDR); @@ -332,9 +317,10 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, lower_32_bits((uint64_t)wptr)); WREG32(SOC15_REG_OFFSET(GC, 0, mmCP_HQD_PQ_WPTR_POLL_ADDR_HI), upper_32_bits((uint64_t)wptr)); - pr_debug("%s setting CP_PQ_WPTR_POLL_CNTL1 to %x\n", __func__, get_queue_mask(adev, pipe_id, queue_id)); + pr_debug("%s setting CP_PQ_WPTR_POLL_CNTL1 to %x\n", __func__, +(uint32_t)get_queue_mask(adev, pipe_id, queue_id)); WREG32(SOC15_REG_OFFSET(GC, 0, mmCP_PQ_WPTR_POLL_CNTL1), - get_queue_mask(adev, pipe_id, queue_id)); + (uint32_t)get_queue_mask(adev, pipe_id, queue_id)); } /* Start the EOP fetcher */ @@ -350,6 +336,59 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, return 0; } +static int kgd_hiq_mqd_load(struct kgd_dev *kgd, void *mqd, + uint32_t pipe_id, uint32_t queue_id, + uint32_t doorbell_off) +{ + struct amdgpu_device *adev = get_amdgpu_device(kgd); + struct amdgpu_ring *kiq_ring = &adev->gfx.kiq.ring; + struct v10_compute_mqd *m; + uint32_t mec, pipe; + int r; + + m = get_mqd(mqd); + + acquire_queue(kgd, pipe_id, queue_id); + + mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1; + pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec); + + pr_debug("kfd: set HIQ, mec:%d, pipe:%d, queue:%d.\n", +mec, pipe, queue_id); + + spin_lock(&adev->gfx.kiq.ring_lock); + r = amdgpu_ring_alloc(kiq_ring, 7); + if (r) { + pr_err("Failed to alloc KIQ (%d).\n", r); + goto out_unlock; + } + + amdgpu_ring_write(kiq_ring, PACKET3(PACKET3_MAP_QUEUES, 5)); + amdgpu_ring_write(kiq_ring, + PACKET3_MAP_QUEUES_QUEUE_SEL(0) | /* Queue_Sel */ + PACKET3_MAP_QUEUES_VMID(m->cp_hqd_vmid) | /* VMID */ + PACKET3_MAP_QUEUES_QUEUE(queue_id) | + PACKET3_MAP_QUEUES_PIPE(pipe) | + PACKET3_MAP_QUEUES_ME((mec - 1)) | + PACKET3_MAP_QUEUES_QUEUE_TYPE(0) | /*queue_type: normal compute queue */ + PACKET3_MAP_QUEUES_ALLOC_FORMAT(0) | /* alloc format: all_on_one_pipe */ + PACKET3_MAP
Re: [PATCH 3/5] drm/amdkfd: use map_queues for hiq on arcturus as well
What happens on Arcturus without this patch? Does it oops with a null pointer dereference? If yes, then you should squash this patch into patch 2 to avoid a broken intermediate state. Regards, Felix On 2020-01-10 1:37 a.m., Huang Rui wrote: Align with gfx v9, use the map_queues packet to load hiq MQD. Signed-off-by: Huang Rui --- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c | 6 +++--- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.h | 3 +++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c index 3c11940..8baad42 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c @@ -281,6 +281,7 @@ const struct kfd2kgd_calls arcturus_kfd2kgd = { .set_pasid_vmid_mapping = kgd_gfx_v9_set_pasid_vmid_mapping, .init_interrupts = kgd_gfx_v9_init_interrupts, .hqd_load = kgd_gfx_v9_hqd_load, + .hiq_mqd_load = kgd_gfx_v9_hiq_mqd_load, .hqd_sdma_load = kgd_hqd_sdma_load, .hqd_dump = kgd_gfx_v9_hqd_dump, .hqd_sdma_dump = kgd_hqd_sdma_dump, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c index ab8c23a..d2f9396 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c @@ -324,9 +324,9 @@ int kgd_gfx_v9_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, return 0; } -static int kgd_gfx_v9_hiq_mqd_load(struct kgd_dev *kgd, void *mqd, - uint32_t pipe_id, uint32_t queue_id, - uint32_t doorbell_off) +int kgd_gfx_v9_hiq_mqd_load(struct kgd_dev *kgd, void *mqd, + uint32_t pipe_id, uint32_t queue_id, + uint32_t doorbell_off) { struct amdgpu_device *adev = get_amdgpu_device(kgd); struct amdgpu_ring *kiq_ring = &adev->gfx.kiq.ring; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.h index 02b1426..32dd1a9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.h @@ -33,6 +33,9 @@ int kgd_gfx_v9_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, uint32_t queue_id, uint32_t __user *wptr, uint32_t wptr_shift, uint32_t wptr_mask, struct mm_struct *mm); +int kgd_gfx_v9_hiq_mqd_load(struct kgd_dev *kgd, void *mqd, + uint32_t pipe_id, uint32_t queue_id, + uint32_t doorbell_off); int kgd_gfx_v9_hqd_dump(struct kgd_dev *kgd, uint32_t pipe_id, uint32_t queue_id, uint32_t (**dump)[2], uint32_t *n_regs); ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
RE: [PATCH 1/8] drm/amdgpu: Avoid reclaim fs while eviction lock
[AMD Official Use Only - Internal Distribution Only] The most recen ones start at: [PATCH 1/8] drm/amdgpu: Avoid reclaim fs while eviction lock Through: [PATCH 8/8] drm/amdgpu: replace kcq enable function on gfx_v9 Regards, Alex Sierra -Original Message- From: Christian König Sent: Friday, January 10, 2020 5:29 AM To: Sierra Guiza, Alejandro (Alex) ; amd-gfx@lists.freedesktop.org Subject: Re: [PATCH 1/8] drm/amdgpu: Avoid reclaim fs while eviction lock [CAUTION: External Email] Looks like you send that patch set out twice. Which one is the most recent one? Regards, Christian. Am 10.01.20 um 01:43 schrieb Alex Sierra: > [Why] > Avoid reclaim filesystem while eviction lock is held called from MMU > notifier. > > [How] > Setting PF_MEMALLOC_NOFS flags while eviction mutex is locked. > Using memalloc_nofs_save / memalloc_nofs_restore API. > > Change-Id: I5531c9337836e7d4a430df3f16dcc82888e8018c > Signed-off-by: Alex Sierra > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 40 +- > drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h | 6 +++- > 2 files changed, 38 insertions(+), 8 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c > index b999b67ff57a..d6aba4f9df74 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c > @@ -82,6 +82,32 @@ struct amdgpu_prt_cb { > struct dma_fence_cb cb; > }; > > +/** > + * vm eviction_lock can be taken in MMU notifiers. Make sure no > +reclaim-FS > + * happens while holding this lock anywhere to prevent deadlocks when > + * an MMU notifier runs in reclaim-FS context. > + */ > +static inline void amdgpu_vm_eviction_lock(struct amdgpu_vm *vm) { > + mutex_lock(&vm->eviction_lock); > + vm->saved_flags = memalloc_nofs_save(); } > + > +static inline int amdgpu_vm_eviction_trylock(struct amdgpu_vm *vm) { > + if (mutex_trylock(&vm->eviction_lock)) { > + vm->saved_flags = memalloc_nofs_save(); > + return 1; > + } > + return 0; > +} > + > +static inline void amdgpu_vm_eviction_unlock(struct amdgpu_vm *vm) { > + memalloc_nofs_restore(vm->saved_flags); > + mutex_unlock(&vm->eviction_lock); } > + > /** >* amdgpu_vm_level_shift - return the addr shift for each level >* > @@ -678,9 +704,9 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, > struct amdgpu_vm *vm, > } > } > > - mutex_lock(&vm->eviction_lock); > + amdgpu_vm_eviction_lock(vm); > vm->evicting = false; > - mutex_unlock(&vm->eviction_lock); > + amdgpu_vm_eviction_unlock(vm); > > return 0; > } > @@ -1559,7 +1585,7 @@ static int amdgpu_vm_bo_update_mapping(struct > amdgpu_device *adev, > if (!(flags & AMDGPU_PTE_VALID)) > owner = AMDGPU_FENCE_OWNER_KFD; > > - mutex_lock(&vm->eviction_lock); > + amdgpu_vm_eviction_lock(vm); > if (vm->evicting) { > r = -EBUSY; > goto error_unlock; > @@ -1576,7 +1602,7 @@ static int amdgpu_vm_bo_update_mapping(struct > amdgpu_device *adev, > r = vm->update_funcs->commit(¶ms, fence); > > error_unlock: > - mutex_unlock(&vm->eviction_lock); > + amdgpu_vm_eviction_unlock(vm); > return r; > } > > @@ -2537,18 +2563,18 @@ bool amdgpu_vm_evictable(struct amdgpu_bo *bo) > return false; > > /* Try to block ongoing updates */ > - if (!mutex_trylock(&bo_base->vm->eviction_lock)) > + if (!amdgpu_vm_eviction_trylock(bo_base->vm)) > return false; > > /* Don't evict VM page tables while they are updated */ > if (!dma_fence_is_signaled(bo_base->vm->last_direct) || > !dma_fence_is_signaled(bo_base->vm->last_delayed)) { > - mutex_unlock(&bo_base->vm->eviction_lock); > + amdgpu_vm_eviction_unlock(bo_base->vm); > return false; > } > > bo_base->vm->evicting = true; > - mutex_unlock(&bo_base->vm->eviction_lock); > + amdgpu_vm_eviction_unlock(bo_base->vm); > return true; > } > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h > b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h > index 100547f094ff..c21a36bebc0c 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h > @@ -30,6 +30,7 @@ > #include > #include > #include > +#include > > #include "amdgpu_sync.h" > #include "amdgpu_ring.h" > @@ -242,9 +243,12 @@ struct amdgpu_vm { > /* tree of virtual addresses mapped */ > struct rb_root_cached va; > > - /* Lock to prevent eviction while we are updating page tables */ > + /* Lock to prevent eviction while we are updating page tables > + * use vm_eviction_lock/unlock(vm) > + */ > struct mutexeviction_lock; > boolevicting; > + unsigned intsaved_flags; > > /* BOs who needs a validation */ > str
Re: [PATCH] drm/amd/display: Fix compilation warnings on i386
On 1/10/20 11:41 AM, mikita.lip...@amd.com wrote: > From: Mikita Lipski > > [why] > Compilation error "undefined reference to `__udivdi3'" was > thrown on i386 architecture. > > [how] > Use div_u64 for unsigned long division instead of a divide operator. > > Reported-by: Randy Dunlap > Signed-off-by: Mikita Lipski > --- > drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c > b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c > index 5a476028ee37..52fb207393ef 100644 > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c > @@ -533,7 +533,7 @@ static int kbps_to_peak_pbn(int kbps) > u64 peak_kbps = kbps; > > peak_kbps *= 1006; > - peak_kbps /= 1000; > + peak_kbps = div_u64(peak_kbps, 1000); > return (int) DIV_ROUND_UP(peak_kbps * 64, (54 * 8 * 1000)); > } > > @@ -565,7 +565,7 @@ static int bpp_x16_from_pbn(struct > dsc_mst_fairness_params param, int pbn) > struct dc_dsc_config dsc_config; > u64 kbps; > > - kbps = (u64)pbn * 994 * 8 * 54 / 64; > + kbps = div_u64((u64)pbn * 994 * 8 * 54, 64); > dc_dsc_compute_config( > param.sink->ctx->dc->res_pool->dscs[0], > ¶m.sink->sink_dsc_caps.dsc_dec_caps, > Still getting this in a different function: ld: drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.o: in function `compute_mst_dsc_configs_for_link': amdgpu_dm_mst_types.c:(.text+0x7b8): undefined reference to `__udivdi3' ld: amdgpu_dm_mst_types.c:(.text+0x956): undefined reference to `__udivdi3' ld: amdgpu_dm_mst_types.c:(.text+0xa24): undefined reference to `__udivdi3' ld: amdgpu_dm_mst_types.c:(.text+0xb33): undefined reference to `__udivdi3' ld: amdgpu_dm_mst_types.c:(.text+0x1028): undefined reference to `__udivdi3' ld: drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.o:amdgpu_dm_mst_types.c:(.text+0x1142): more undefined references to `__udivdi3' follow -- ~Randy Reported-by: Randy Dunlap ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH AUTOSEL 5.4 20/26] drm/amdgpu: enable gfxoff for raven1 refresh
From: changzhu [ Upstream commit e0c63812352298efbce2a71483c1dab627d0c288 ] When smu version is larger than 0x41e2b, it will load raven_kicker_rlc.bin.To enable gfxoff for raven_kicker_rlc.bin,it needs to avoid adev->pm.pp_feature &= ~PP_GFXOFF_MASK when it loads raven_kicker_rlc.bin. Signed-off-by: changzhu Reviewed-by: Huang Rui Acked-by: Alex Deucher Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 15 --- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c index c9ba2ec6d038..ab4a0d8545dc 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c @@ -1038,17 +1038,10 @@ static void gfx_v9_0_check_if_need_gfxoff(struct amdgpu_device *adev) case CHIP_VEGA20: break; case CHIP_RAVEN: - /* Disable GFXOFF on original raven. There are combinations -* of sbios and platforms that are not stable. -*/ - if (!(adev->rev_id >= 0x8 || adev->pdev->device == 0x15d8)) - adev->pm.pp_feature &= ~PP_GFXOFF_MASK; - else if (!(adev->rev_id >= 0x8 || adev->pdev->device == 0x15d8) -&&((adev->gfx.rlc_fw_version != 106 && -adev->gfx.rlc_fw_version < 531) || - (adev->gfx.rlc_fw_version == 53815) || - (adev->gfx.rlc_feature_version < 1) || - !adev->gfx.rlc.is_rlc_v2_1)) + if (!(adev->rev_id >= 0x8 || + adev->pdev->device == 0x15d8) && + (adev->pm.fw_version < 0x41e2b || /* not raven1 fresh */ +!adev->gfx.rlc.is_rlc_v2_1)) /* without rlc save restore ucodes */ adev->pm.pp_feature &= ~PP_GFXOFF_MASK; if (adev->pm.pp_feature & PP_GFXOFF_MASK) -- 2.20.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[pull] drm DP MST DSC support
Hi Dave, Daniel, Same pull as yesterday, but with a fix for 32 bit. The following changes since commit 0f899fd466b693a129b16994c1b2b4db2fcde4a4: drm/amdkfd: Improve kfd_process lookup in kfd_ioctl (2020-01-09 16:08:19 -0500) are available in the Git repository at: git://people.freedesktop.org/~agd5f/linux tags/amd-drm-next-5.6-2020-01-10-dp-mst-dsc for you to fetch changes up to 485b747ea6ecf491bf07c69a4ea36c0ccf3c8435: drm/amd/display: Fix compilation warnings on i386 (2020-01-10 16:34:20 -0500) amd-drm-next-5.6-2020-01-10-dp-mst-dsc: drm: - Add MST helper for PBN calculation of DSC modes - Parse FEC caps on MST ports - Add MST DPCD R/W functions - Add MST helpers for virtual DPCD aux - Add MST HUB quirk - Add MST DSC enablement helpers amdgpu: - Enable MST DSC - Add fair share algo for DSC bandwidth calcs - Fix for 32 bit builds Alex Deucher (2): drm/amdgpu/display: protect new DSC code with CONFIG_DRM_AMD_DC_DCN drm/dp_mst: fix documentation of drm_dp_mst_add_affected_dsc_crtcs David (Dingchen) Zhang (1): drm: add dp helper to initialize remote aux channel. David Francis (9): drm/dp_mst: Add PBN calculation for DSC modes drm/dp_mst: Parse FEC capability on MST ports drm/dp_mst: Add MST support to DP DPCD R/W functions drm/dp_mst: Fill branch->num_ports drm/dp_mst: Add helpers for MST DSC and virtual DPCD aux drm/amd/display: Initialize DSC PPS variables to 0 drm/amd/display: Validate DSC caps on MST endpoints drm/amd/display: Write DSC enable to MST DPCD drm/amd/display: MST DSC compute fair share Mikita Lipski (11): drm/dp_mst: Add new quirk for Synaptics MST hubs drm/dp_mst: Manually overwrite PBN divider for calculating timeslots drm/dp_mst: Add DSC enablement helpers to DRM drm/dp_mst: Add branch bandwidth validation to MST atomic check drm/dp_mst: Rename drm_dp_mst_atomic_check_topology_state drm/amd/display: Add PBN per slot calculation for DSC drm/amd/display: Check return value of drm helper drm/amd/display: Recalculate VCPI slots for new DSC connectors drm/dp_mst: Add helper to trigger modeset on affected DSC MST CRTCs drm/amd/display: Trigger modesets on MST DSC connectors drm/amd/display: Fix compilation warnings on i386 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 121 +- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 1 + .../drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 19 +- .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.c| 420 - .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.h| 7 + drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c | 3 + drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c | 3 + .../gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 7 +- .../gpu/drm/amd/display/dc/dcn20/dcn20_resource.h | 1 + drivers/gpu/drm/drm_dp_aux_dev.c | 12 +- drivers/gpu/drm/drm_dp_helper.c| 45 ++- drivers/gpu/drm/drm_dp_mst_topology.c | 392 ++- drivers/gpu/drm/i915/display/intel_dp_mst.c| 5 +- drivers/gpu/drm/nouveau/dispnv50/disp.c| 4 +- drivers/gpu/drm/radeon/radeon_dp_mst.c | 2 +- drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c | 12 +- include/drm/drm_dp_helper.h| 8 + include/drm/drm_dp_mst_helper.h| 20 +- 18 files changed, 1031 insertions(+), 51 deletions(-) ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH] drm/amd/display: remove unnecessary conversion to bool
On 2020-01-10 2:16 a.m., Chen Zhou wrote: > The conversion to bool is not needed, remove it. >> Signed-off-by: Chen Zhou Reviewed-by: Harry Wentland Harry > --- > drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > 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 504055f..a004e8e 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 > @@ -2792,7 +2792,7 @@ static bool retrieve_link_cap(struct dc_link *link) > dpcd_data[DP_TRAINING_AUX_RD_INTERVAL]; > > link->dpcd_caps.ext_receiver_cap_field_present = > - > aux_rd_interval.bits.EXT_RECEIVER_CAP_FIELD_PRESENT == 1 ? true:false; > + > aux_rd_interval.bits.EXT_RECEIVER_CAP_FIELD_PRESENT == 1; > > if (aux_rd_interval.bits.EXT_RECEIVER_CAP_FIELD_PRESENT == 1) { > uint8_t ext_cap_data[16]; > ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 39/43] drm/amd/display: Use udelay to avoid context switch
On 2020-01-10 4:16 p.m., Harry Wentland wrote: > On 2020-01-10 1:47 p.m., Liu, Zhan wrote: >> >> >>> -Original Message- >>> From: amd-gfx On Behalf Of >>> Christian König >>> Sent: 2020/January/10, Friday 10:02 AM >>> To: Siqueira, Rodrigo ; amd- >>> g...@lists.freedesktop.org >>> Cc: Li, Sun peng (Leo) ; Cheng, Tony >>> ; Tsai, Martin ; Lakha, >>> Bhawanpreet ; Wentland, Harry >>> >>> Subject: Re: [PATCH 39/43] drm/amd/display: Use udelay to avoid context >>> switch >>> >>> Am 10.01.20 um 15:46 schrieb Rodrigo Siqueira: From: Martin Tsai [why] The rapid msleep operation causes the white line garbage when DAL check flip pending status in SetVidPnSourceVisibility. To execute this msleep will induce context switch, and longer delay could cause worse garbage situation. [how] To replace msleep with udelay. Signed-off-by: Martin Tsai Reviewed-by: Tony Cheng Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c index 89920924a154..0dc652e76848 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c @@ -1642,9 +1642,9 @@ void dcn20_program_front_end_for_ctx( struct hubp *hubp = pipe->plane_res.hubp; int j = 0; - for (j = 0; j < TIMEOUT_FOR_PIPE_ENABLE_MS + for (j = 0; j < TIMEOUT_FOR_PIPE_ENABLE_MS*1000 && hubp->funcs- hubp_is_flip_pending(hubp); j++) - msleep(1); + udelay(1); >>> >>> Why not using mdelay() here? >> >> As far as I know, mdelay() is only defined on Linux side. >> >> This piece of code is shared by both Linux and Windows, so we have to use a >> function that's available on both platforms. >> > > It was used here before so we definitely have it defined for Windows as > well. > Whoops, I misread that. mdelay is indeed not defined on our other platforms but we could go ahead and define it if needed. Harry > From the commit description it sounds like msleep wasn't tight enough > and longer delays lead to issues here, at least on Windows. > > Martin, Tony, do you have more details about this? > > Thanks, > Harry > >> Zhan >> >>> >>> Christian. >>> } } >>> >>> ___ >>> amd-gfx mailing list >>> amd-gfx@lists.freedesktop.org ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 39/43] drm/amd/display: Use udelay to avoid context switch
On 2020-01-10 1:47 p.m., Liu, Zhan wrote: > > >> -Original Message- >> From: amd-gfx On Behalf Of >> Christian König >> Sent: 2020/January/10, Friday 10:02 AM >> To: Siqueira, Rodrigo ; amd- >> g...@lists.freedesktop.org >> Cc: Li, Sun peng (Leo) ; Cheng, Tony >> ; Tsai, Martin ; Lakha, >> Bhawanpreet ; Wentland, Harry >> >> Subject: Re: [PATCH 39/43] drm/amd/display: Use udelay to avoid context >> switch >> >> Am 10.01.20 um 15:46 schrieb Rodrigo Siqueira: >>> From: Martin Tsai >>> >>> [why] >>> The rapid msleep operation causes the white line garbage when DAL >>> check flip pending status in SetVidPnSourceVisibility. >>> To execute this msleep will induce context switch, and longer delay >>> could cause worse garbage situation. >>> >>> [how] >>> To replace msleep with udelay. >>> >>> Signed-off-by: Martin Tsai >>> Reviewed-by: Tony Cheng >>> Acked-by: Harry Wentland >>> Acked-by: Rodrigo Siqueira >>> --- >>> drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 4 ++-- >>> 1 file changed, 2 insertions(+), 2 deletions(-) >>> >>> diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c >>> b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c >>> index 89920924a154..0dc652e76848 100644 >>> --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c >>> +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c >>> @@ -1642,9 +1642,9 @@ void dcn20_program_front_end_for_ctx( >>> struct hubp *hubp = pipe->plane_res.hubp; >>> int j = 0; >>> >>> - for (j = 0; j < TIMEOUT_FOR_PIPE_ENABLE_MS >>> + for (j = 0; j < TIMEOUT_FOR_PIPE_ENABLE_MS*1000 >>> && hubp->funcs- >>> hubp_is_flip_pending(hubp); j++) >>> - msleep(1); >>> + udelay(1); >> >> Why not using mdelay() here? > > As far as I know, mdelay() is only defined on Linux side. > > This piece of code is shared by both Linux and Windows, so we have to use a > function that's available on both platforms. > It was used here before so we definitely have it defined for Windows as well. From the commit description it sounds like msleep wasn't tight enough and longer delays lead to issues here, at least on Windows. Martin, Tony, do you have more details about this? Thanks, Harry > Zhan > >> >> Christian. >> >>> } >>> } >>> >> >> ___ >> amd-gfx mailing list >> amd-gfx@lists.freedesktop.org ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH] drm/amd/display: Fix compilation warnings on i386
On Fri, Jan 10, 2020 at 2:41 PM wrote: > > From: Mikita Lipski > > [why] > Compilation error "undefined reference to `__udivdi3'" was > thrown on i386 architecture. > > [how] > Use div_u64 for unsigned long division instead of a divide operator. > > Reported-by: Randy Dunlap > Signed-off-by: Mikita Lipski Reviewed-by: Alex Deucher > --- > drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c > b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c > index 5a476028ee37..52fb207393ef 100644 > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c > @@ -533,7 +533,7 @@ static int kbps_to_peak_pbn(int kbps) > u64 peak_kbps = kbps; > > peak_kbps *= 1006; > - peak_kbps /= 1000; > + peak_kbps = div_u64(peak_kbps, 1000); > return (int) DIV_ROUND_UP(peak_kbps * 64, (54 * 8 * 1000)); > } > > @@ -565,7 +565,7 @@ static int bpp_x16_from_pbn(struct > dsc_mst_fairness_params param, int pbn) > struct dc_dsc_config dsc_config; > u64 kbps; > > - kbps = (u64)pbn * 994 * 8 * 54 / 64; > + kbps = div_u64((u64)pbn * 994 * 8 * 54, 64); > dc_dsc_compute_config( > param.sink->ctx->dc->res_pool->dscs[0], > ¶m.sink->sink_dsc_caps.dsc_dec_caps, > -- > 2.17.1 > > ___ > amd-gfx mailing list > amd-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/amd-gfx ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu/display: fix logic inversion in program_timing_sync()
It looks like we should be reducing the group size when we don't have a plane rather than when we do. Bug: https://gitlab.freedesktop.org/drm/amd/issues/781 Fixes: 5fc0cbfad45648 ("drm/amd/display: determine if a pipe is synced by plane state") Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 3d89904003f0..01b27726d9c5 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -1003,9 +1003,9 @@ static void program_timing_sync( status->timing_sync_info.master = false; } - /* remove any other pipes with plane as they have already been synced */ + /* remove any other pipes without plane as they have already been synced */ for (j = j + 1; j < group_size; j++) { - if (pipe_set[j]->plane_state) { + if (!pipe_set[j]->plane_state) { group_size--; pipe_set[j] = pipe_set[group_size]; j--; -- 2.24.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amd/display: Fix compilation warnings on i386
From: Mikita Lipski [why] Compilation error "undefined reference to `__udivdi3'" was thrown on i386 architecture. [how] Use div_u64 for unsigned long division instead of a divide operator. Reported-by: Randy Dunlap Signed-off-by: Mikita Lipski --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index 5a476028ee37..52fb207393ef 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -533,7 +533,7 @@ static int kbps_to_peak_pbn(int kbps) u64 peak_kbps = kbps; peak_kbps *= 1006; - peak_kbps /= 1000; + peak_kbps = div_u64(peak_kbps, 1000); return (int) DIV_ROUND_UP(peak_kbps * 64, (54 * 8 * 1000)); } @@ -565,7 +565,7 @@ static int bpp_x16_from_pbn(struct dsc_mst_fairness_params param, int pbn) struct dc_dsc_config dsc_config; u64 kbps; - kbps = (u64)pbn * 994 * 8 * 54 / 64; + kbps = div_u64((u64)pbn * 994 * 8 * 54, 64); dc_dsc_compute_config( param.sink->ctx->dc->res_pool->dscs[0], ¶m.sink->sink_dsc_caps.dsc_dec_caps, -- 2.17.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdkfd: Add a message when SW scheduler is used
SW scheduler is previously called non HW scheduler, or non HWS. This message is useful when triaging issues from dmesg. Change-Id: I625518c88c043df5f60409d1ca520e7fc032251f Signed-off-by: Yong Zhao --- drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index d7eb6ac37f62..2870553a2ce0 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -934,6 +934,7 @@ static void uninitialize(struct device_queue_manager *dqm) static int start_nocpsch(struct device_queue_manager *dqm) { + pr_info("SW scheduler is used"); init_interrupts(dqm); if (dqm->dev->device_info->asic_family == CHIP_HAWAII) -- 2.17.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
RE: [PATCH 39/43] drm/amd/display: Use udelay to avoid context switch
> -Original Message- > From: amd-gfx On Behalf Of > Christian König > Sent: 2020/January/10, Friday 10:02 AM > To: Siqueira, Rodrigo ; amd- > g...@lists.freedesktop.org > Cc: Li, Sun peng (Leo) ; Cheng, Tony > ; Tsai, Martin ; Lakha, > Bhawanpreet ; Wentland, Harry > > Subject: Re: [PATCH 39/43] drm/amd/display: Use udelay to avoid context > switch > > Am 10.01.20 um 15:46 schrieb Rodrigo Siqueira: > > From: Martin Tsai > > > > [why] > > The rapid msleep operation causes the white line garbage when DAL > > check flip pending status in SetVidPnSourceVisibility. > > To execute this msleep will induce context switch, and longer delay > > could cause worse garbage situation. > > > > [how] > > To replace msleep with udelay. > > > > Signed-off-by: Martin Tsai > > Reviewed-by: Tony Cheng > > Acked-by: Harry Wentland > > Acked-by: Rodrigo Siqueira > > --- > > drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 4 ++-- > > 1 file changed, 2 insertions(+), 2 deletions(-) > > > > diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c > > b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c > > index 89920924a154..0dc652e76848 100644 > > --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c > > +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c > > @@ -1642,9 +1642,9 @@ void dcn20_program_front_end_for_ctx( > > struct hubp *hubp = pipe->plane_res.hubp; > > int j = 0; > > > > - for (j = 0; j < TIMEOUT_FOR_PIPE_ENABLE_MS > > + for (j = 0; j < TIMEOUT_FOR_PIPE_ENABLE_MS*1000 > > && hubp->funcs- > >hubp_is_flip_pending(hubp); j++) > > - msleep(1); > > + udelay(1); > > Why not using mdelay() here? As far as I know, mdelay() is only defined on Linux side. This piece of code is shared by both Linux and Windows, so we have to use a function that's available on both platforms. Zhan > > Christian. > > > } > > } > > > > ___ > amd-gfx mailing list > amd-gfx@lists.freedesktop.org ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu: check rlc_g firmware pointer is valid before using it
In SRIOV, rlc_g firmware is loaded by host, guest driver won't load it which will cause the rlc_fw pointer is null Change-Id: Id16f65171dd427d623af4c5bc75f674019e63dec Signed-off-by: shaoyunl --- drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c index 379e46c..07e22f2 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c @@ -808,10 +808,11 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev) info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_G]; info->ucode_id = AMDGPU_UCODE_ID_RLC_G; info->fw = adev->gfx.rlc_fw; - header = (const struct common_firmware_header *)info->fw->data; - adev->firmware.fw_size += - ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE); - + if (info->fw) { + header = (const struct common_firmware_header *)info->fw->data; + adev->firmware.fw_size += + ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE); + } if (adev->gfx.rlc.is_rlc_v2_1 && adev->gfx.rlc.save_restore_list_cntl_size_bytes && adev->gfx.rlc.save_restore_list_gpm_size_bytes && -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: linux-next: Tree for Jan 10 (amdgpu)
On 1/10/20 12:07 AM, Stephen Rothwell wrote: > Hi all, > > Changes since 20200109: > on i386: ld: drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.o: in function `compute_mst_dsc_configs_for_link': amdgpu_dm_mst_types.c:(.text+0x784): undefined reference to `__udivdi3' ld: amdgpu_dm_mst_types.c:(.text+0x7a2): undefined reference to `__udivdi3' ld: amdgpu_dm_mst_types.c:(.text+0x84a): undefined reference to `__udivdi3' ld: amdgpu_dm_mst_types.c:(.text+0x868): undefined reference to `__udivdi3' ld: amdgpu_dm_mst_types.c:(.text+0x8d0): undefined reference to `__udivdi3' ld: drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.o:amdgpu_dm_mst_types.c:(.text+0x8ee): more undefined references to `__udivdi3' follow -- ~Randy Reported-by: Randy Dunlap ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
RE: [Bug 206155] New: amdgpu several warnings while booting Fiji GPU, GPU not activated
+ amd-gfx@lists.freedesktop.org Hi there, Thank you for your bug report (though from your email address seems like you are a robot :p) Since it's an amdgpu related bug, please also add amd-gfx@lists.freedesktop.org for better visibility. Thanks, Zhan > -Original Message- > From: dri-devel On Behalf Of > bugzilla-dae...@bugzilla.kernel.org > Sent: 2020/January/10, Friday 9:13 AM > To: dri-de...@lists.freedesktop.org > Subject: [Bug 206155] New: amdgpu several warnings while booting Fiji GPU, > GPU not activated > > https://bugzilla.kernel.org/show_bug.cgi?id=206155 > > Bug ID: 206155 >Summary: amdgpu several warnings while booting Fiji GPU, GPU > not activated >Product: Drivers >Version: 2.5 > Kernel Version: 5.4.7 > Hardware: x86-64 > OS: Linux > Tree: Mainline > Status: NEW > Severity: blocking > Priority: P1 > Component: Video(DRI - non Intel) > Assignee: drivers_video-...@kernel-bugs.osdl.org > Reporter: janpieter.sol...@dommel.be > Regression: No > > Created attachment 286739 > --> https://bugzilla.kernel.org/attachment.cgi?id=286739&action=edit > > powerplay-enabled dmesg > > This dmesg is with powerplay disabled (using ppfeaturemask=0), attached pp- > enabled dmesg > > [6.728122] amdgpu: [powerplay] > failed to send message 154 ret is 0 > [6.728130] [drm] UVD initialized successfully. > [9.324771] amdgpu: [powerplay] > last message was failed ret is 0 > [ 11.818433] amdgpu: [powerplay] > failed to send message 15a ret is 0 > [ 12.122300] amdgpu :0a:00.0: [drm:amdgpu_ring_test_helper > [amdgpu]] > *ERROR* ring vce0 test failed (-110) > [ 12.122382] [drm:amdgpu_device_init.cold [amdgpu]] *ERROR* hw_init of > IP > block failed -110 > [ 12.122383] amdgpu :0a:00.0: amdgpu_device_ip_init failed > [ 12.122385] amdgpu :0a:00.0: Fatal error during GPU init > -- > > [ 14.531652] amdgpu: [powerplay] > last message was failed ret is 0 > [ 14.532747] amdgpu: [powerplay] dpm has been disabled > [ 14.534668] [ cut here ] > [ 14.534753] WARNING: CPU: 1 PID: 942 at > amdgpu_bo_unpin.cold+0x23/0x42 > [amdgpu] > [ 14.534754] Modules linked in: btrfs xor raid6_pq kvm_amd(-) amdgpu(+) > wmi_bmof gpu_sched ttm kvm uas irqbypass backlight i2c_piix4 k10temp > aacraid wmi efivarfs > [ 14.534762] CPU: 1 PID: 942 Comm: systemd-udevd Not tainted 5.4.7 #8 > [ 14.534763] Hardware name: Gigabyte Technology Co., Ltd. X570 UD/X570 > UD, > BIOS F10 11/15/2019 > [ 14.534847] RIP: 0010:amdgpu_bo_unpin.cold+0x23/0x42 [amdgpu] > [ 14.534849] Code: 84 00 00 00 00 00 90 48 8b bb f0 b0 ff ff 4c 89 e2 48 c7 > c6 b7 ea 66 c0 89 44 24 04 e8 02 30 21 d5 8b 44 24 04 e9 0f 94 e5 ff <0f> 0b > 48 8b bb f0 b0 ff ff 4c 89 e2 48 c7 c6 9f ea 66 c0 e8 57 30 > [ 14.534850] RSP: 0018:9bba8132f9d0 EFLAGS: 00010246 > [ 14.534851] RAX: 88de87d37450 RBX: 88de84984f10 RCX: > 88de85444f80 > [ 14.534852] RDX: RSI: RDI: > 88de87d37400 > [ 14.534852] RBP: 88de84987298 R08: 0001 R09: > 88de95c03500 > [ 14.534853] R10: 88de87d37000 R11: 88de87d371c0 R12: > 88de87d37400 > [ 14.534853] R13: 88de84987290 R14: 88de87d37400 R15: > > [ 14.534855] FS: 7f3e897bc800() GS:88de96c4() > knlGS: > [ 14.534856] CS: 0010 DS: ES: CR0: 80050033 > [ 14.534856] CR2: 7f3e8945a440 CR3: 000207f2c000 CR4: > 003406e0 > [ 14.534857] Call Trace: > [ 14.534929] amdgpu_bo_free_kernel+0x7d/0x150 [amdgpu] > [ 14.535007] amdgpu_gfx_rlc_fini+0x42/0x60 [amdgpu] > [ 14.535084] gfx_v8_0_sw_fini+0x9a/0x190 [amdgpu] > [ 14.535167] amdgpu_device_fini+0x238/0x42f [amdgpu] > [ 14.535234] amdgpu_driver_unload_kms+0x50/0xb0 [amdgpu] > [ 14.535317] amdgpu_driver_load_kms.cold+0x39/0x5b [amdgpu] > [ 14.535320] drm_dev_register+0x139/0x180 > [ 14.535322] ? do_pci_enable_device+0xad/0xd0 > [ 14.535389] amdgpu_pci_probe+0xb4/0x120 [amdgpu] > [ 14.535392] ? __pm_runtime_resume+0x54/0x70 > [ 14.535394] local_pci_probe+0x46/0x90 > [ 14.535396] pci_device_probe+0xe9/0x190 > [ 14.535399] really_probe+0xf3/0x2c0 > [ 14.535400] driver_probe_device+0x59/0xd0 > [ 14.535402] device_driver_attach+0x68/0x70 > [ 14.535403] __driver_attach+0x51/0xc0 > [ 14.535404] ? device_driver_attach+0x70/0x70 > [ 14.535406] bus_for_each_dev+0x5e/0x90 > [ 14.535408] bus_add_driver+0x198/0x1e0 > [ 14.535409] driver_register+0x67/0xb0 > [ 14.535411] ? 0xc0755000 > [ 14.535412] do_one_initcall+0x3e/0x1df > [ 14.535415] ? __vunmap+0x1e3/0x230 > [ 14.535417] ? kmem_cac
Re: [PATCH 03/23] drm/i915: Don't use struct drm_driver.get_scanout_position()
On Fri, Jan 10, 2020 at 03:56:06PM +0200, Jani Nikula wrote: > On Fri, 10 Jan 2020, Thomas Zimmermann wrote: > > Hi > > > > Am 10.01.20 um 12:59 schrieb Jani Nikula: > >> On Fri, 10 Jan 2020, Thomas Zimmermann wrote: > >>> The callback struct drm_driver.get_scanout_position() is deprecated in > >>> favor of struct drm_crtc_helper_funcs.get_scanout_position(). > >>> > >>> i915 doesn't use CRTC helpers. The patch duplicates the caller > >>> drm_calc_vbltimestamp_from_scanoutpos() for i915, such that the callback > >>> function is not needed. > >>> > >>> Signed-off-by: Thomas Zimmermann > >>> --- > >>> drivers/gpu/drm/i915/i915_drv.c | 3 +- > >>> drivers/gpu/drm/i915/i915_irq.c | 117 ++-- > >>> drivers/gpu/drm/i915/i915_irq.h | 9 +-- > >>> 3 files changed, 119 insertions(+), 10 deletions(-) > >> > >> Not really enthusiastic about the diffstat in a "cleanup" series. > > > > Well, the cleanup is about the content of drm_driver :) > > > >> > >> I wonder if you could add a generic helper version of > >> drm_calc_vbltimestamp_from_scanoutpos where you pass the > >> get_scanout_position function as a parameter. Both > >> drm_calc_vbltimestamp_from_scanoutpos and the new > >> i915_calc_vbltimestamp_from_scanoutpos would then be fairly thin > >> wrappers passing in the relevant get_scanout_position function. > > > > Of course. Will be in v2 of the series. > > Please give Ville (Cc'd) a moment before sending v2 in case he wants to > chime in on this. Passing the function pointer was one option I considered for this a while back. Can't remeber what other solutions I condsidered. But I guess I didn't like any of them enough to make an actual patch. -- Ville Syrjälä Intel ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH] drm/amdgpu: fix modprobe failure of the secondary GPU when GDDR6 training enabled(V4)
On Fri, Jan 10, 2020 at 12:30 AM Tianci Yin wrote: > > From: "Tianci.Yin" > > [why] > In dual GPUs scenario, stolen_size is assigned to zero on the secondary GPU, > since there is no pre-OS console using that memory. Then the bottom region of > VRAM was allocated as GTT, unfortunately a small region of bottom VRAM was > encroached by UMC firmware during GDDR6 BIST training, this cause page fault. > > [how] > Forcing stolen_size to 3MB, then the bottom region of VRAM was > allocated as stolen memory, GTT corruption avoid. > > Change-Id: I310a72ba0402994defbe50839842a8edb025a868 > Signed-off-by: Tianci.Yin > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h | 5 + > drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c | 27 - > 2 files changed, 31 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h > b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h > index c91dd602d5f1..e4b2f9bcaeb7 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h > @@ -60,6 +60,11 @@ > */ > #define AMDGPU_GMC_FAULT_TIMEOUT 5000ULL > > +/* > + * Default stolen memory size, 1024 * 768 * 4 > + */ > +#define AMDGPU_STOLEN_VGA_DEFAULT_SIZE 0x30ULL It would be better to call this AMDGPU_STOLEN_BIST_TRAINING_DEFAULT_SIZE. Also, I sounds like we are probably going to have to assume that all of vram could be touched and adjust our sequnce appropriately. I think we are just getting lucky with this size because most imporant kernel structures are in the lower area of vram. Alex > + > struct firmware; > > /* > diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c > b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c > index 5ad89bb6f3ba..14961f1ebfab 100644 > --- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c > +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c > @@ -566,7 +566,12 @@ static int gmc_v10_0_late_init(void *handle) > struct amdgpu_device *adev = (struct amdgpu_device *)handle; > int r; > > - amdgpu_bo_late_init(adev); > + /* > +* Can't free the stolen VGA memory when it might be used for memory > +* training again. > +*/ > + if (!adev->fw_vram_usage.mem_train_support) > + amdgpu_bo_late_init(adev); > > r = amdgpu_gmc_allocate_vm_inv_eng(adev); > if (r) > @@ -750,6 +755,19 @@ static int gmc_v10_0_sw_init(void *handle) > > adev->gmc.stolen_size = gmc_v10_0_get_vbios_fb_size(adev); > > + /* > +* In dual GPUs scenario, stolen_size is assigned to zero on the > +* secondary GPU, since there is no pre-OS console using that memory. > +* Then the bottom region of VRAM was allocated as GTT, unfortunately > a > +* small region of bottom VRAM was encroached by UMC firmware during > +* GDDR6 BIST training, this cause page fault. > +* The page fault can be fixed by forcing stolen_size to 3MB, then the > +* bottom region of VRAM was allocated as stolen memory, GTT > corruption > +* avoid. > +*/ > + adev->gmc.stolen_size = max(adev->gmc.stolen_size, > + AMDGPU_STOLEN_VGA_DEFAULT_SIZE); > + > /* Memory manager */ > r = amdgpu_bo_init(adev); > if (r) > @@ -789,6 +807,13 @@ static void gmc_v10_0_gart_fini(struct amdgpu_device > *adev) > static int gmc_v10_0_sw_fini(void *handle) > { > struct amdgpu_device *adev = (struct amdgpu_device *)handle; > + void *stolen_vga_buf; > + > + /* > +* Free the stolen memory if it wasn't already freed in late_init > +* because of memory training. > +*/ > + amdgpu_bo_free_kernel(&adev->stolen_vga_memory, NULL, > &stolen_vga_buf); > > amdgpu_vm_manager_fini(adev); > gmc_v10_0_gart_fini(adev); > -- > 2.17.1 > > ___ > amd-gfx mailing list > amd-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/amd-gfx ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 39/43] drm/amd/display: Use udelay to avoid context switch
Am 10.01.20 um 15:46 schrieb Rodrigo Siqueira: From: Martin Tsai [why] The rapid msleep operation causes the white line garbage when DAL check flip pending status in SetVidPnSourceVisibility. To execute this msleep will induce context switch, and longer delay could cause worse garbage situation. [how] To replace msleep with udelay. Signed-off-by: Martin Tsai Reviewed-by: Tony Cheng Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c index 89920924a154..0dc652e76848 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c @@ -1642,9 +1642,9 @@ void dcn20_program_front_end_for_ctx( struct hubp *hubp = pipe->plane_res.hubp; int j = 0; - for (j = 0; j < TIMEOUT_FOR_PIPE_ENABLE_MS + for (j = 0; j < TIMEOUT_FOR_PIPE_ENABLE_MS*1000 && hubp->funcs->hubp_is_flip_pending(hubp); j++) - msleep(1); + udelay(1); Why not using mdelay() here? Christian. } } ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 38/43] drm/amd/display: Only program surface flip for video plane via dmcub
From: Yongqiang Sun Only need to do surface flip for video plane via dmcub. Signed-off-by: Yongqiang Sun Reviewed-by: Tony Cheng Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- .../gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c | 130 +- drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h | 20 +++ .../gpu/drm/amd/display/dmub/inc/dmub_cmd.h | 19 +-- 3 files changed, 94 insertions(+), 75 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c index 12396c371569..da63fc53cc4a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c @@ -690,86 +690,98 @@ void hubp21_validate_dml_output(struct hubp *hubp, dml_dlg_attr->refcyc_per_meta_chunk_flip_l, dlg_attr.refcyc_per_meta_chunk_flip_l); } -static void program_surface_flip_and_addr(struct hubp *hubp, struct dmub_rb_cmd_flip *surface_flip) +static void program_surface_flip_and_addr(struct hubp *hubp, struct surface_flip_registers *flip_regs) { struct dcn21_hubp *hubp21 = TO_DCN21_HUBP(hubp); REG_UPDATE_3(DCSURF_FLIP_CONTROL, - SURFACE_FLIP_TYPE, surface_flip->flip.flip_params.immediate, - SURFACE_FLIP_MODE_FOR_STEREOSYNC, surface_flip->flip.flip_params.grph_stereo, - SURFACE_FLIP_IN_STEREOSYNC, surface_flip->flip.flip_params.grph_stereo); + SURFACE_FLIP_TYPE, flip_regs->immediate, + SURFACE_FLIP_MODE_FOR_STEREOSYNC, flip_regs->grph_stereo, + SURFACE_FLIP_IN_STEREOSYNC, flip_regs->grph_stereo); REG_UPDATE(VMID_SETTINGS_0, - VMID, surface_flip->flip.flip_params.vmid); + VMID, flip_regs->vmid); REG_UPDATE_8(DCSURF_SURFACE_CONTROL, - PRIMARY_SURFACE_TMZ, surface_flip->flip.flip_params.tmz_surface, - PRIMARY_SURFACE_TMZ_C, surface_flip->flip.flip_params.tmz_surface, - PRIMARY_META_SURFACE_TMZ, surface_flip->flip.flip_params.tmz_surface, - PRIMARY_META_SURFACE_TMZ_C, surface_flip->flip.flip_params.tmz_surface, - SECONDARY_SURFACE_TMZ, surface_flip->flip.flip_params.tmz_surface, - SECONDARY_SURFACE_TMZ_C, surface_flip->flip.flip_params.tmz_surface, - SECONDARY_META_SURFACE_TMZ, surface_flip->flip.flip_params.tmz_surface, - SECONDARY_META_SURFACE_TMZ_C, surface_flip->flip.flip_params.tmz_surface); + PRIMARY_SURFACE_TMZ, flip_regs->tmz_surface, + PRIMARY_SURFACE_TMZ_C, flip_regs->tmz_surface, + PRIMARY_META_SURFACE_TMZ, flip_regs->tmz_surface, + PRIMARY_META_SURFACE_TMZ_C, flip_regs->tmz_surface, + SECONDARY_SURFACE_TMZ, flip_regs->tmz_surface, + SECONDARY_SURFACE_TMZ_C, flip_regs->tmz_surface, + SECONDARY_META_SURFACE_TMZ, flip_regs->tmz_surface, + SECONDARY_META_SURFACE_TMZ_C, flip_regs->tmz_surface); REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C, 0, PRIMARY_META_SURFACE_ADDRESS_HIGH_C, - surface_flip->flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C); + flip_regs->DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C); REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_C, 0, PRIMARY_META_SURFACE_ADDRESS_C, - surface_flip->flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS_C); + flip_regs->DCSURF_PRIMARY_META_SURFACE_ADDRESS_C); REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, 0, PRIMARY_META_SURFACE_ADDRESS_HIGH, - surface_flip->flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH); + flip_regs->DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH); REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS, 0, PRIMARY_META_SURFACE_ADDRESS, - surface_flip->flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS); + flip_regs->DCSURF_PRIMARY_META_SURFACE_ADDRESS); REG_SET(DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH, 0, SECONDARY_META_SURFACE_ADDRESS_HIGH, - surface_flip->flip.DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH); + flip_regs->DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH); REG_SET(DCSURF_SECONDARY_META_SURFACE_ADDRESS, 0, SECONDARY_META_SURFACE_ADDRESS, - surface_flip->flip.DCSURF_SECONDARY_META_SURFACE_ADDRESS); +
[PATCH 42/43] drm/amd/display: 3.2.68
From: Aric Cyr Signed-off-by: Aric Cyr Reviewed-by: Aric Cyr Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- drivers/gpu/drm/amd/display/dc/dc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 7639fa074c6e..3fa85a54360f 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -39,7 +39,7 @@ #include "inc/hw/dmcu.h" #include "dml/display_mode_lib.h" -#define DC_VER "3.2.67" +#define DC_VER "3.2.68" #define MAX_SURFACES 3 #define MAX_PLANES 6 -- 2.24.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 35/43] drm/amd/display: wait for test pattern after when all pipes are programmed
From: Wenjing Liu [why] Currently we wait for test pattern after each pipe is programmed. For ODM combined scenario it will cause test pattern is shown on only half screen for 1 frame. This is not desirable. [how] No wait between odm pipe programming, only wait after all pipes are programmed. Signed-off-by: Wenjing Liu Reviewed-by: Tony Cheng Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 6 -- 1 file changed, 6 deletions(-) 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 ea5a09ca3334..9ab6b7402288 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 @@ -3658,12 +3658,6 @@ static void set_crtc_test_pattern(struct dc_link *link, NULL, width, height); - /* wait for dpg to blank pixel data with test pattern */ - for (count = 0; count < 1000; count++) - if (odm_opp->funcs->dpg_is_blanked(odm_opp)) - break; - else - udelay(100); } opp->funcs->opp_set_disp_pattern_generator(opp, controller_test_pattern, -- 2.24.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 43/43] drm/amd/display: skip opp blank or unblank if test pattern enabled
From: Wenjing Liu [why] DPG is used to generate both blank and test automation test pattern. When test automation is running the requested test pattern can be overriden by the blank or unblank call because it is using the same hardware. [how] When test pattern is requested, skip blank or unblank. Signed-off-by: Wenjing Liu Reviewed-by: Nikola Cornij Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c index 0dc652e76848..6baccdd65d3d 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c @@ -945,6 +945,9 @@ void dcn20_blank_pixel_data( int width = stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right; int height = stream->timing.v_addressable + stream->timing.v_border_bottom + stream->timing.v_border_top; + if (stream->link->test_pattern_enabled) + return; + /* get opp dpg blank color */ color_space_to_black_color(dc, color_space, &black_color); -- 2.24.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 39/43] drm/amd/display: Use udelay to avoid context switch
From: Martin Tsai [why] The rapid msleep operation causes the white line garbage when DAL check flip pending status in SetVidPnSourceVisibility. To execute this msleep will induce context switch, and longer delay could cause worse garbage situation. [how] To replace msleep with udelay. Signed-off-by: Martin Tsai Reviewed-by: Tony Cheng Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c index 89920924a154..0dc652e76848 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c @@ -1642,9 +1642,9 @@ void dcn20_program_front_end_for_ctx( struct hubp *hubp = pipe->plane_res.hubp; int j = 0; - for (j = 0; j < TIMEOUT_FOR_PIPE_ENABLE_MS + for (j = 0; j < TIMEOUT_FOR_PIPE_ENABLE_MS*1000 && hubp->funcs->hubp_is_flip_pending(hubp); j++) - msleep(1); + udelay(1); } } -- 2.24.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 31/43] drm/amd/display: implement fw-driver interface for abm 2.4
From: Josip Pavic [Why] IRAM definition needed for versions of DMCU containing ABM 2.4 [How] Pass ABM 2.3 IRAM definition, which is compatible with ABM 2.4, to DMCU when ABM 2.4 FW is detected Signed-off-by: Josip Pavic Reviewed-by: Aric Cyr Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- drivers/gpu/drm/amd/display/modules/power/power_helpers.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c index 4e2f615c3566..e75a4bb94488 100644 --- a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c +++ b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c @@ -662,7 +662,11 @@ bool dmcu_load_iram(struct dmcu *dmcu, memset(&ram_table, 0, sizeof(ram_table)); - if (dmcu->dmcu_version.abm_version == 0x23) { + if (dmcu->dmcu_version.abm_version == 0x24) { + fill_iram_v_2_3((struct iram_table_v_2_2 *)ram_table, params); + result = dmcu->funcs->load_iram( + dmcu, 0, (char *)(&ram_table), IRAM_RESERVE_AREA_START_V2_2); + } else if (dmcu->dmcu_version.abm_version == 0x23) { fill_iram_v_2_3((struct iram_table_v_2_2 *)ram_table, params); result = dmcu->funcs->load_iram( @@ -687,3 +691,4 @@ bool dmcu_load_iram(struct dmcu *dmcu, return result; } + -- 2.24.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 41/43] drm/amd/display: reallocate MST payload when link loss
From: Paul Hsieh [Why] Try to allocate MST payload but receive HPD short pulse with link loss casue driver allocate payload twice. It cause monitor can't light up successfully. [How] When driver receive HPD short pulse with link loss, we need to deallocate payload then allocate payload. Then we will not allocate payload twice with same sink. Signed-off-by: Paul Hsieh Reviewed-by: Tony Cheng Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 33 +++ .../gpu/drm/amd/display/dc/core/dc_link_dp.c | 7 ++-- drivers/gpu/drm/amd/display/dc/dc_link.h | 1 + 3 files changed, 36 insertions(+), 5 deletions(-) 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 a397b6a28633..1f2331684967 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -2873,6 +2873,39 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx) return DC_OK; } + +enum dc_status dc_link_reallocate_mst_payload(struct dc_link *link) +{ + int i; + struct pipe_ctx *pipe_ctx; + + // Clear all of MST payload then reallocate + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i]; + if (pipe_ctx && pipe_ctx->stream && pipe_ctx->stream->link == link && + pipe_ctx->stream->dpms_off == false && + pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) { + deallocate_mst_payload(pipe_ctx); + } + } + + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i]; + if (pipe_ctx && pipe_ctx->stream && pipe_ctx->stream->link == link && + pipe_ctx->stream->dpms_off == false && + pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) { + /* enable/disable PHY will clear connection between BE and FE +* need to restore it. +*/ + link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc, + pipe_ctx->stream_res.stream_enc->id, true); + dc_link_allocate_mst_payload(pipe_ctx); + } + } + + return DC_OK; +} + #if defined(CONFIG_DRM_AMD_DC_HDCP) static void update_psp_stream_config(struct pipe_ctx *pipe_ctx, bool dpms_off) { 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 8206bb3f74ec..daeee64eb899 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 @@ -2902,11 +2902,8 @@ bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd pipe_ctx, pipe_ctx->stream->signal); - if (pipe_ctx && pipe_ctx->stream && pipe_ctx->stream->link == link && - pipe_ctx->stream->dpms_off == false && - pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) { - dc_link_allocate_mst_payload(pipe_ctx); - } + if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) + dc_link_reallocate_mst_payload(link); status = false; if (out_link_loss) diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h index f9aae35aec92..d25603128394 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_link.h +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h @@ -205,6 +205,7 @@ enum dc_detect_reason { bool dc_link_detect(struct dc_link *dc_link, enum dc_detect_reason reason); bool dc_link_get_hpd_state(struct dc_link *dc_link); enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx); +enum dc_status dc_link_reallocate_mst_payload(struct dc_link *link); /* Notify DC about DP RX Interrupt (aka Short Pulse Interrupt). * Return: -- 2.24.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 37/43] drm/amd/display: Enable double buffer for OTG_BLANK
From: Alvin Lee [Why] Currently if seamless boot is enabled, we will skip double buffer enable for OTG_BLANK. However, we need the double buffer enable in order to block global sync signals when OTG becomes blanked (for PSR). Blocking global sync signals prevent pipe from requesting data. [How] Move tg_init before seamless boot check. Signed-off-by: Alvin Lee Reviewed-by: Jun Lei Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) 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 5347a85f10d7..f2127afb37b2 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 @@ -1188,8 +1188,14 @@ void dcn10_init_pipes(struct dc *dc, struct dc_state *context) if (can_apply_seamless_boot && pipe_ctx->stream != NULL && pipe_ctx->stream_res.tg->funcs->is_tg_enabled( - pipe_ctx->stream_res.tg)) + pipe_ctx->stream_res.tg)) { + // Enable double buffering for OTG_BLANK no matter if + // seamless boot is enabled or not to suppress global sync + // signals when OTG blanked. This is to prevent pipe from + // requesting data while in PSR. + tg->funcs->tg_init(tg); continue; + } /* Disable on the current state so the new one isn't cleared. */ pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i]; -- 2.24.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 33/43] drm/amd/display: 3.2.67
From: Aric Cyr Signed-off-by: Aric Cyr Reviewed-by: Aric Cyr Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- drivers/gpu/drm/amd/display/dc/dc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 8c7ff9e322f1..e1c11af2bcaf 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -39,7 +39,7 @@ #include "inc/hw/dmcu.h" #include "dml/display_mode_lib.h" -#define DC_VER "3.2.66" +#define DC_VER "3.2.67" #define MAX_SURFACES 3 #define MAX_PLANES 6 -- 2.24.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 34/43] drm/amd/display: make PSR static screen entry within 30 ms
From: Anthony Koo [Why] With different refresh rate panels, the PSR entry/exit time is different since it is dependent on 2 frame entry time today [How] Make static screen num frame entry time to be calculated such that entry time is within 30 ms instead of fixed num frames. Signed-off-by: Anthony Koo Reviewed-by: Tony Cheng Acked-by: Aric Cyr Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 32 + drivers/gpu/drm/amd/display/dc/core/dc.c | 6 ++-- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 2 +- drivers/gpu/drm/amd/display/dc/dc.h | 13 --- drivers/gpu/drm/amd/display/dc/dc_stream.h| 4 +-- drivers/gpu/drm/amd/display/dc/dc_types.h | 2 +- .../display/dc/dce110/dce110_hw_sequencer.c | 35 +++ .../dc/dce110/dce110_timing_generator.c | 11 -- .../dc/dce110/dce110_timing_generator.h | 3 +- .../dc/dce120/dce120_timing_generator.c | 11 -- .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 23 ++-- .../amd/display/dc/dcn10/dcn10_hw_sequencer.h | 2 +- .../gpu/drm/amd/display/dc/dcn10/dcn10_optc.c | 15 +--- .../gpu/drm/amd/display/dc/dcn10/dcn10_optc.h | 3 +- .../drm/amd/display/dc/dcn20/dcn20_hwseq.c| 6 +++- .../amd/display/dc/inc/hw/timing_generator.h | 3 +- .../gpu/drm/amd/display/dc/inc/hw_sequencer.h | 4 +-- .../amd/display/dc/inc/hw_sequencer_private.h | 2 +- 18 files changed, 116 insertions(+), 61 deletions(-) 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 bd51471a9c62..32885fed64af 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -8474,17 +8474,37 @@ static bool amdgpu_dm_link_setup_psr(struct dc_stream_state *stream) bool amdgpu_dm_psr_enable(struct dc_stream_state *stream) { struct dc_link *link = stream->link; - struct dc_static_screen_events triggers = {0}; + unsigned int vsync_rate_hz = 0; + struct dc_static_screen_params params = {0}; + /* Calculate number of static frames before generating interrupt to +* enter PSR. +*/ + unsigned int frame_time_microsec = 100 / vsync_rate_hz; + // Init fail safe of 2 frames static + unsigned int num_frames_static = 2; DRM_DEBUG_DRIVER("Enabling psr...\n"); - triggers.cursor_update = true; - triggers.overlay_update = true; - triggers.surface_update = true; + vsync_rate_hz = div64_u64(div64_u64(( + stream->timing.pix_clk_100hz * 100), + stream->timing.v_total), + stream->timing.h_total); + + /* Round up +* Calculate number of frames such that at least 30 ms of time has +* passed. +*/ + if (vsync_rate_hz != 0) + num_frames_static = (3 / frame_time_microsec) + 1; + + params.triggers.cursor_update = true; + params.triggers.overlay_update = true; + params.triggers.surface_update = true; + params.num_frames = num_frames_static; - dc_stream_set_static_screen_events(link->ctx->dc, + dc_stream_set_static_screen_params(link->ctx->dc, &stream, 1, - &triggers); + ¶ms); return dc_link_set_psr_allow_active(link, true, false); } diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index c918a0cd8c60..6c797fac189d 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -510,10 +510,10 @@ bool dc_stream_program_csc_matrix(struct dc *dc, struct dc_stream_state *stream) return ret; } -void dc_stream_set_static_screen_events(struct dc *dc, +void dc_stream_set_static_screen_params(struct dc *dc, struct dc_stream_state **streams, int num_streams, - const struct dc_static_screen_events *events) + const struct dc_static_screen_params *params) { int i = 0; int j = 0; @@ -532,7 +532,7 @@ void dc_stream_set_static_screen_events(struct dc *dc, } } - dc->hwss.set_static_screen_control(pipes_affected, num_pipes_affected, events); + dc->hwss.set_static_screen_control(pipes_affected, num_pipes_affected, params); } static void dc_destruct(struct dc *dc) 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 0faf582084d0..7fcae8d63811 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -2542,7 +2542,7 @@ bool dc_link_setup_psr(struct dc_link *link, transmitter_to_phy_id(link->link_enc->transmitter); psr_c
[PATCH 32/43] drm/amd/display: remove psr state condition when psr exit case
From: Lewis Huang [Why] DMCU need to wait a vblank to handle psr enter command. When psr exit coming before vblank, the psr exit command will be skip because current psr state is disable. [How] remove psr state condition when psr exit case Signed-off-by: Lewis Huang Reviewed-by: Tony Cheng Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c index e619e67e6b51..30d953acd016 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c @@ -537,9 +537,6 @@ static void dcn10_dmcu_set_psr_enable(struct dmcu *dmcu, bool enable, bool wait) if (dmcu->dmcu_state != DMCU_RUNNING) return; - dcn10_get_dmcu_psr_state(dmcu, &psr_state); - if (psr_state == 0 && !enable) - return; /* waitDMCUReadyForCmd */ REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, dmcu_wait_reg_ready_interval, -- 2.24.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 30/43] drm/amd/display: Add default switch case for DCC
From: Chris Park Signed-off-by: Chris Park Reviewed-by: Aric Cyr Reviewed-by: Jordan Lazare Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c | 3 +++ drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c index a02c10e23e0d..f36a0d8cedfe 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c @@ -930,6 +930,9 @@ static bool hubbub1_get_dcc_compression_cap(struct hubbub *hubbub, output->grph.rgb.max_compressed_blk_size = 64; output->grph.rgb.independent_64b_blks = true; break; + default: + ASSERT(false); + break; } output->capable = true; diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c index 836af0f2bbda..9235f7d29454 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c @@ -293,6 +293,9 @@ bool hubbub2_get_dcc_compression_cap(struct hubbub *hubbub, output->grph.rgb.max_compressed_blk_size = 64; output->grph.rgb.independent_64b_blks = true; break; + default: + ASSERT(false); + break; } output->capable = true; output->const_color_support = true; -- 2.24.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 40/43] drm/amd/display: fixup DML dependencies
From: Jun Lei [why] Need to fix DML portability issues to enable SW unit testing around DML [how] Move calcs into dc include folder since multiple components reference it Remove relative paths to external dependencies Signed-off-by: Jun Lei Reviewed-by: Anthony Koo Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c | 2 +- drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h | 2 +- drivers/gpu/drm/amd/display/dc/{calcs => inc}/dcn_calc_math.h | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename drivers/gpu/drm/amd/display/dc/{calcs => inc}/dcn_calc_math.h (100%) diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c index b953b02a1512..723af0b2dda0 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c @@ -24,7 +24,7 @@ */ #include "dml_common_defs.h" -#include "../calcs/dcn_calc_math.h" +#include "dcn_calc_math.h" #include "dml_inline_defs.h" diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h b/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h index eca140da13d8..ded71ea82413 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h +++ b/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h @@ -27,7 +27,7 @@ #define __DML_INLINE_DEFS_H__ #include "dml_common_defs.h" -#include "../calcs/dcn_calc_math.h" +#include "dcn_calc_math.h" #include "dml_logger.h" static inline double dml_min(double a, double b) diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.h b/drivers/gpu/drm/amd/display/dc/inc/dcn_calc_math.h similarity index 100% rename from drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.h rename to drivers/gpu/drm/amd/display/dc/inc/dcn_calc_math.h -- 2.24.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 36/43] drm/amd/display: Add monitor patch for AUO dpcd issue
From: Lewis Huang [Why] dpcd cap mismatch in 2200 vs base [How] Add monitor patch which using based caps to overwrite 2200 Signed-off-by: Lewis Huang Reviewed-by: Tony Cheng Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 7 +++ .../gpu/drm/amd/display/dc/core/dc_link_dp.c | 62 +++ drivers/gpu/drm/amd/display/dc/dc_link.h | 3 + .../gpu/drm/amd/display/dc/inc/dc_link_dp.h | 2 + 4 files changed, 74 insertions(+) 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 7fcae8d63811..a397b6a28633 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -3371,3 +3371,10 @@ const struct dc_link_settings *dc_link_get_link_cap( return &link->preferred_link_setting; return &link->verified_link_cap; } + +void dc_link_overwrite_extended_receiver_cap( + struct dc_link *link) +{ + dp_overwrite_extended_receiver_cap(link); +} + 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 9ab6b7402288..8206bb3f74ec 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 @@ -3447,6 +3447,68 @@ static bool retrieve_link_cap(struct dc_link *link) return true; } +bool dp_overwrite_extended_receiver_cap(struct dc_link *link) +{ + uint8_t dpcd_data[16]; + uint32_t read_dpcd_retry_cnt = 3; + enum dc_status status = DC_ERROR_UNEXPECTED; + union dp_downstream_port_present ds_port = { 0 }; + union down_stream_port_count down_strm_port_count; + union edp_configuration_cap edp_config_cap; + + int i; + + for (i = 0; i < read_dpcd_retry_cnt; i++) { + status = core_link_read_dpcd( + link, + DP_DPCD_REV, + dpcd_data, + sizeof(dpcd_data)); + if (status == DC_OK) + break; + } + + link->dpcd_caps.dpcd_rev.raw = + dpcd_data[DP_DPCD_REV - DP_DPCD_REV]; + + if (dpcd_data[DP_MAX_LANE_COUNT - DP_DPCD_REV] == 0) + return false; + + ds_port.byte = dpcd_data[DP_DOWNSTREAMPORT_PRESENT - + DP_DPCD_REV]; + + get_active_converter_info(ds_port.byte, link); + + down_strm_port_count.raw = dpcd_data[DP_DOWN_STREAM_PORT_COUNT - + DP_DPCD_REV]; + + link->dpcd_caps.allow_invalid_MSA_timing_param = + down_strm_port_count.bits.IGNORE_MSA_TIMING_PARAM; + + link->dpcd_caps.max_ln_count.raw = dpcd_data[ + DP_MAX_LANE_COUNT - DP_DPCD_REV]; + + link->dpcd_caps.max_down_spread.raw = dpcd_data[ + DP_MAX_DOWNSPREAD - DP_DPCD_REV]; + + link->reported_link_cap.lane_count = + link->dpcd_caps.max_ln_count.bits.MAX_LANE_COUNT; + link->reported_link_cap.link_rate = dpcd_data[ + DP_MAX_LINK_RATE - DP_DPCD_REV]; + link->reported_link_cap.link_spread = + link->dpcd_caps.max_down_spread.bits.MAX_DOWN_SPREAD ? + LINK_SPREAD_05_DOWNSPREAD_30KHZ : LINK_SPREAD_DISABLED; + + edp_config_cap.raw = dpcd_data[ + DP_EDP_CONFIGURATION_CAP - DP_DPCD_REV]; + link->dpcd_caps.panel_mode_edp = + edp_config_cap.bits.ALT_SCRAMBLER_RESET; + link->dpcd_caps.dpcd_display_control_capable = + edp_config_cap.bits.DPCD_DISPLAY_CONTROL_CAPABLE; + + return true; +} + bool detect_dp_sink_caps(struct dc_link *link) { return retrieve_link_cap(link); diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h index f420aeac7fbd..f9aae35aec92 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_link.h +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h @@ -301,6 +301,9 @@ uint32_t dc_link_bandwidth_kbps( const struct dc_link_settings *dc_link_get_link_cap( const struct dc_link *link); +void dc_link_overwrite_extended_receiver_cap( + struct dc_link *link); + bool dc_submit_i2c( struct dc *dc, uint32_t link_index, diff --git a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h index 6198bccd6199..8b1f0ce6c2a7 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h +++ b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h @@ -76,6 +76,8 @@ void dp_enable_mst_on_sink(struct dc_link *link, bool enable); enum dp_panel_mode dp_get_panel_mode(struct dc_link *link); void dp_set_panel_mode(struct dc_link *link, enum dp_panel_mode panel_mode); +bool dp_overwrite_extended_receiver_cap(struct dc_link *link); + void dp_set_fec_ready(struct dc_link *link, bool ready); void d
[PATCH 10/43] drm/amd/display: Soft reset DMUIF during DMUB reset
From: Nicholas Kazlauskas [Why] We need to ensure that the DMUIF in MMHUBBUB is also in reset so we aren't generating requests while the DMCUB is in reset. [How] Set DMUIF_SOFT_RESET=1 on reset and DMUIF_SOFT_RESET=0 on reset release. Signed-off-by: Nicholas Kazlauskas Reviewed-by: Tony Cheng Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c | 2 ++ drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h | 6 -- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c index f45e14ada685..cd51c6138894 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c @@ -66,10 +66,12 @@ void dmub_dcn20_reset(struct dmub_srv *dmub) { REG_UPDATE(DMCUB_CNTL, DMCUB_SOFT_RESET, 1); REG_UPDATE(DMCUB_CNTL, DMCUB_ENABLE, 0); + REG_UPDATE(MMHUBBUB_SOFT_RESET, DMUIF_SOFT_RESET, 1); } void dmub_dcn20_reset_release(struct dmub_srv *dmub) { + REG_UPDATE(MMHUBBUB_SOFT_RESET, DMUIF_SOFT_RESET, 0); REG_WRITE(DMCUB_SCRATCH15, dmub->psp_version & 0x001100FF); REG_UPDATE_2(DMCUB_CNTL, DMCUB_ENABLE, 1, DMCUB_TRACEPORT_EN, 1); REG_UPDATE(DMCUB_CNTL, DMCUB_SOFT_RESET, 0); diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h index 68af9b190288..53bfd4da69ad 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h @@ -91,7 +91,8 @@ struct dmub_srv; DMUB_SR(DMCUB_SCRATCH13) \ DMUB_SR(DMCUB_SCRATCH14) \ DMUB_SR(DMCUB_SCRATCH15) \ - DMUB_SR(CC_DC_PIPE_DIS) + DMUB_SR(CC_DC_PIPE_DIS) \ + DMUB_SR(MMHUBBUB_SOFT_RESET) #define DMUB_COMMON_FIELDS() \ DMUB_SF(DMCUB_CNTL, DMCUB_ENABLE) \ @@ -119,7 +120,8 @@ struct dmub_srv; DMUB_SF(DMCUB_REGION3_CW7_TOP_ADDRESS, DMCUB_REGION3_CW7_ENABLE) \ DMUB_SF(DMCUB_REGION4_TOP_ADDRESS, DMCUB_REGION4_TOP_ADDRESS) \ DMUB_SF(DMCUB_REGION4_TOP_ADDRESS, DMCUB_REGION4_ENABLE) \ - DMUB_SF(CC_DC_PIPE_DIS, DC_DMCUB_ENABLE) + DMUB_SF(CC_DC_PIPE_DIS, DC_DMCUB_ENABLE) \ + DMUB_SF(MMHUBBUB_SOFT_RESET, DMUIF_SOFT_RESET) struct dmub_srv_common_reg_offset { #define DMUB_SR(reg) uint32_t reg; -- 2.24.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 09/43] drm/amd/display: Read inst_fb data back during DMUB loading
From: Nicholas Kazlauskas [Why] The inst firmware isn't necessarily fully flushed to framebuffer memory and the DMCUB can hang due to invalid inst being parsed. [How] Like the fix to flush ringbuffer commands before updating the inbox write pointer we need to read back inst memory before writing the CW0 registers. Add a helper to read 64-byte chunks to avoid a large temporary buffer. Read the remaining leftover bytes if the inst_fb isn't fully aligned. Signed-off-by: Nicholas Kazlauskas Reviewed-by: Tony Cheng Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- .../gpu/drm/amd/display/dmub/src/dmub_srv.c | 27 +++ 1 file changed, 27 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c index 23ca1fe97757..dee676335d73 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c @@ -67,6 +67,26 @@ static inline uint32_t dmub_align(uint32_t val, uint32_t factor) return (val + factor - 1) / factor * factor; } +static void dmub_flush_buffer_mem(const struct dmub_fb *fb) +{ + const uint8_t *base = (const uint8_t *)fb->cpu_addr; + uint8_t buf[64]; + uint32_t pos, end; + + /** +* Read 64-byte chunks since we don't want to store a +* large temporary buffer for this purpose. +*/ + end = fb->size / sizeof(buf) * sizeof(buf); + + for (pos = 0; pos < end; pos += sizeof(buf)) + dmub_memcpy(buf, base + pos, sizeof(buf)); + + /* Read anything leftover into the buffer. */ + if (end < fb->size) + dmub_memcpy(buf, base + pos, fb->size - end); +} + static const struct dmub_fw_meta_info * dmub_get_fw_meta_info(const uint8_t *fw_bss_data, uint32_t fw_bss_data_size) { @@ -329,6 +349,13 @@ enum dmub_status dmub_srv_hw_init(struct dmub_srv *dmub, cw1.region.base = DMUB_CW1_BASE; cw1.region.top = cw1.region.base + stack_fb->size - 1; + /** +* Read back all the instruction memory so we don't hang the +* DMCUB when backdoor loading if the write from x86 hasn't been +* flushed yet. This only occurs in backdoor loading. +*/ + dmub_flush_buffer_mem(inst_fb); + if (params->load_inst_const && dmub->hw_funcs.backdoor_load) dmub->hw_funcs.backdoor_load(dmub, &cw0, &cw1); } -- 2.24.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 18/43] drm/amd/display: 3.2.66
From: Aric Cyr Signed-off-by: Aric Cyr Reviewed-by: Aric Cyr Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- drivers/gpu/drm/amd/display/dc/dc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index d1d57432bc7e..dfc66954a24b 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -39,7 +39,7 @@ #include "inc/hw/dmcu.h" #include "dml/display_mode_lib.h" -#define DC_VER "3.2.65" +#define DC_VER "3.2.66" #define MAX_SURFACES 3 #define MAX_PLANES 6 -- 2.24.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 13/43] drm/amd/display: Don't always set pstate true if dummy latency = 0
From: Alvin Lee [Why] If dummy pstate latency is 0 we should report the actual pstate support, and not that pstate is always supported. [How] Don't always program pstate support true Signed-off-by: Alvin Lee Reviewed-by: Jun Lei Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c index a05746142ec8..eac4c3cecadf 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c @@ -2918,7 +2918,7 @@ bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context, if (context->bw_ctx.dml.soc.dummy_pstate_latency_us == 0 || (voltage_supported && full_pstate_supported)) { - context->bw_ctx.bw.dcn.clk.p_state_change_support = true; + context->bw_ctx.bw.dcn.clk.p_state_change_support = full_pstate_supported; goto restore_dml_state; } -- 2.24.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 20/43] drm/amd/display: Driverside changes to support PSR in DMCUB
From: Wyatt Wood [Why] Moving PSR from DMCU to DMCUB. [How] Add driverside PSR changes required to send inbox messages to fw. These changes are non-functional until the psr structure allocation is uncommented. Signed-off-by: Wyatt Wood Reviewed-by: Nicholas Kazlauskas Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 22 +- drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c | 220 ++ drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h | 47 .../drm/amd/display/dc/dcn21/dcn21_resource.c | 5 + .../gpu/drm/amd/display/dc/inc/core_types.h | 1 + .../gpu/drm/amd/display/dmub/inc/dmub_cmd.h | 34 ++- 6 files changed, 313 insertions(+), 16 deletions(-) create mode 100644 drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c create mode 100644 drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h 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 cef8c1ba9797..0faf582084d0 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -45,6 +45,7 @@ #include "dpcd_defs.h" #include "dmcu.h" #include "hw/clk_mgr.h" +#include "../dce/dmub_psr.h" #define DC_LOGGER_INIT(logger) @@ -2404,10 +2405,11 @@ bool dc_link_set_psr_allow_active(struct dc_link *link, bool allow_active, bool { struct dc *dc = link->ctx->dc; struct dmcu *dmcu = dc->res_pool->dmcu; + struct dmub_psr *psr = dc->res_pool->psr; - - - if ((dmcu != NULL && dmcu->funcs->is_dmcu_initialized(dmcu)) && link->psr_feature_enabled) + if ((psr != NULL) && link->psr_feature_enabled) + psr->funcs->set_psr_enable(psr, allow_active); + else if ((dmcu != NULL && dmcu->funcs->is_dmcu_initialized(dmcu)) && link->psr_feature_enabled) dmcu->funcs->set_psr_enable(dmcu, allow_active, wait); link->psr_allow_active = allow_active; @@ -2419,8 +2421,11 @@ bool dc_link_get_psr_state(const struct dc_link *link, uint32_t *psr_state) { struct dc *dc = link->ctx->dc; struct dmcu *dmcu = dc->res_pool->dmcu; + struct dmub_psr *psr = dc->res_pool->psr; - if (dmcu != NULL && link->psr_feature_enabled) + if (psr != NULL && link->psr_feature_enabled) + psr->funcs->get_psr_state(psr_state); + else if (dmcu != NULL && link->psr_feature_enabled) dmcu->funcs->get_psr_state(dmcu, psr_state); return true; @@ -2467,6 +2472,7 @@ bool dc_link_setup_psr(struct dc_link *link, { struct dc *dc; struct dmcu *dmcu; + struct dmub_psr *psr; int i; /* updateSinkPsrDpcdConfig*/ union dpcd_psr_configuration psr_configuration; @@ -2478,8 +2484,9 @@ bool dc_link_setup_psr(struct dc_link *link, dc = link->ctx->dc; dmcu = dc->res_pool->dmcu; + psr = dc->res_pool->psr; - if (!dmcu) + if (!dmcu && !psr) return false; @@ -2588,7 +2595,10 @@ bool dc_link_setup_psr(struct dc_link *link, */ psr_context->frame_delay = 0; - link->psr_feature_enabled = dmcu->funcs->setup_psr(dmcu, link, psr_context); + if (psr) + link->psr_feature_enabled = psr->funcs->setup_psr(psr, link, psr_context); + else + link->psr_feature_enabled = dmcu->funcs->setup_psr(dmcu, link, psr_context); /* psr_enabled == 0 indicates setup_psr did not succeed, but this * should not happen since firmware should be running at this point diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c new file mode 100644 index ..225955ec6d39 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c @@ -0,0 +1,220 @@ +/* + * Copyright 2019 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. +
[PATCH 23/43] drm/amd/display: DMCUB FW Changes to support PSR
From: Wyatt Wood [Why] Moving PSR from DMCU to DMCUB. [How] Cleanup psr spec files and add PSR hw programming files. No functionality is included in this change. Signed-off-by: Wyatt Wood Reviewed-by: Tony Cheng Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- .../gpu/drm/amd/display/dmub/inc/dmub_cmd.h | 19 +-- .../drm/amd/display/dmub/inc/dmub_cmd_dal.h | 6 ++ 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h index 919323257edb..3b79079ec9b8 100644 --- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h +++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h @@ -262,23 +262,13 @@ struct dmub_rb_cmd_psr_enable { struct dmub_cmd_header header; }; -struct dmub_cmd_psr_notify_vblank_data { - uint32_t vblank_int; // Which vblank interrupt was triggered +struct dmub_cmd_psr_setup_data { + enum psr_version version; // PSR version 1 or 2 }; -struct dmub_rb_cmd_notify_vblank { +struct dmub_rb_cmd_psr_setup { struct dmub_cmd_header header; - struct dmub_cmd_psr_notify_vblank_data psr_notify_vblank_data; -}; - -struct dmub_cmd_psr_notify_static_state_data { - uint32_t ss_int;// Which static screen interrupt was triggered - uint32_t ss_enter; // Enter (1) or exit (0) static screen -}; - -struct dmub_rb_cmd_psr_notify_static_state { - struct dmub_cmd_header header; - struct dmub_cmd_psr_notify_static_state_data psr_notify_static_state_data; + struct dmub_cmd_psr_setup_data psr_setup_data; }; union dmub_rb_cmd { @@ -296,6 +286,7 @@ union dmub_rb_cmd { struct dmub_rb_cmd_psr_copy_settings psr_copy_settings; struct dmub_rb_cmd_psr_set_level psr_set_level; struct dmub_rb_cmd_flip surface_flip; + struct dmub_rb_cmd_psr_setup psr_setup; }; #pragma pack(pop) diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd_dal.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd_dal.h index 14f13e8a6f3b..20b47649f991 100644 --- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd_dal.h +++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd_dal.h @@ -36,6 +36,12 @@ enum dmub_cmd_psr_type { DMUB_CMD__PSR_DISABLE = 1, DMUB_CMD__PSR_COPY_SETTINGS = 2, DMUB_CMD__PSR_SET_LEVEL = 3, + DMUB_CMD__PSR_SETUP = 4, +}; + +enum psr_version { + PSR_VERSION_1 = 0x0, + PSR_VERSION_2 = 0x10, }; #endif /* _DMUB_CMD_DAL_H_ */ -- 2.24.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 11/43] drm/amd/display: Add double buffering to dcn20 OCSC
From: Noah Abradjian [Why] When rapidly adjusting colour properties (e.g. brightness), screen tearing was observed. This was due to overwritten values in OCSC registers. In dcn10, this issue had been fixed by implementing double buffering by alternating OCSC modes. [How] Alternate which OCSC registers are used by switching modes each time. This double buffers the CSC writes. Signed-off-by: Noah Abradjian Reviewed-by: Tony Cheng Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- .../gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c | 45 --- .../gpu/drm/amd/display/dc/dcn20/dcn20_mpc.h | 16 +++ .../drm/amd/display/dc/dcn20/dcn20_resource.c | 1 + .../drm/amd/display/dc/dcn21/dcn21_resource.c | 3 +- 4 files changed, 59 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c index f90031ed58a6..c38f7fdb43a8 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c @@ -33,6 +33,9 @@ #define REG(reg)\ mpc20->mpc_regs->reg +#define IND_REG(index) \ + (index) + #define CTX \ mpc20->base.ctx @@ -132,19 +135,32 @@ void mpc2_set_output_csc( const uint16_t *regval, enum mpc_output_csc_mode ocsc_mode) { + uint32_t cur_mode; struct dcn20_mpc *mpc20 = TO_DCN20_MPC(mpc); struct color_matrices_reg ocsc_regs; - REG_SET(CSC_MODE[opp_id], 0, MPC_OCSC_MODE, ocsc_mode); - - if (ocsc_mode == MPC_OUTPUT_CSC_DISABLE) + if (ocsc_mode == MPC_OUTPUT_CSC_DISABLE) { + REG_SET(CSC_MODE[opp_id], 0, MPC_OCSC_MODE, ocsc_mode); return; + } if (regval == NULL) { BREAK_TO_DEBUGGER(); return; } + /* determine which CSC coefficients (A or B) we are using +* currently. select the alternate set to double buffer +* the CSC update so CSC is updated on frame boundary +*/ + cur_mode = IX_REG_READ(MPC_OCSC_TEST_DEBUG_INDEX, MPC_OCSC_TEST_DEBUG_DATA, + MPC_OCSC_TEST_DEBUG_DATA_OCSC_MODE_IDX); + + if (cur_mode != MPC_OUTPUT_CSC_COEF_A) + ocsc_mode = MPC_OUTPUT_CSC_COEF_A; + else + ocsc_mode = MPC_OUTPUT_CSC_COEF_B; + ocsc_regs.shifts.csc_c11 = mpc20->mpc_shift->MPC_OCSC_C11_A; ocsc_regs.masks.csc_c11 = mpc20->mpc_mask->MPC_OCSC_C11_A; ocsc_regs.shifts.csc_c12 = mpc20->mpc_shift->MPC_OCSC_C12_A; @@ -157,10 +173,13 @@ void mpc2_set_output_csc( ocsc_regs.csc_c11_c12 = REG(CSC_C11_C12_B[opp_id]); ocsc_regs.csc_c33_c34 = REG(CSC_C33_C34_B[opp_id]); } + cm_helper_program_color_matrices( mpc20->base.ctx, regval, &ocsc_regs); + + REG_SET(CSC_MODE[opp_id], 0, MPC_OCSC_MODE, ocsc_mode); } void mpc2_set_ocsc_default( @@ -169,14 +188,16 @@ void mpc2_set_ocsc_default( enum dc_color_space color_space, enum mpc_output_csc_mode ocsc_mode) { + uint32_t cur_mode; struct dcn20_mpc *mpc20 = TO_DCN20_MPC(mpc); uint32_t arr_size; struct color_matrices_reg ocsc_regs; const uint16_t *regval = NULL; - REG_SET(CSC_MODE[opp_id], 0, MPC_OCSC_MODE, ocsc_mode); - if (ocsc_mode == MPC_OUTPUT_CSC_DISABLE) + if (ocsc_mode == MPC_OUTPUT_CSC_DISABLE) { + REG_SET(CSC_MODE[opp_id], 0, MPC_OCSC_MODE, ocsc_mode); return; + } regval = find_color_matrix(color_space, &arr_size); @@ -185,6 +206,18 @@ void mpc2_set_ocsc_default( return; } + /* determine which CSC coefficients (A or B) we are using +* currently. select the alternate set to double buffer +* the CSC update so CSC is updated on frame boundary +*/ + cur_mode = IX_REG_READ(MPC_OCSC_TEST_DEBUG_INDEX, MPC_OCSC_TEST_DEBUG_DATA, + MPC_OCSC_TEST_DEBUG_DATA_OCSC_MODE_IDX); + + if (cur_mode != MPC_OUTPUT_CSC_COEF_A) + ocsc_mode = MPC_OUTPUT_CSC_COEF_A; + else + ocsc_mode = MPC_OUTPUT_CSC_COEF_B; + ocsc_regs.shifts.csc_c11 = mpc20->mpc_shift->MPC_OCSC_C11_A; ocsc_regs.masks.csc_c11 = mpc20->mpc_mask->MPC_OCSC_C11_A; ocsc_regs.shifts.csc_c12 = mpc20->mpc_shift->MPC_OCSC_C12_A; @@ -203,6 +236,8 @@ void mpc2_set_ocsc_default( mpc20->base.ctx, regval, &ocsc_regs); + + REG_SET(CSC_MODE[opp_id], 0, MPC_OCSC_MODE, ocsc_mode); } static void mpc2_ogam_get_reg_field( diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.h index 9f53192da2dc..8c77e78e2df5 100644 --- a
[PATCH 25/43] drm/amd/display: Refactor surface flip programming
From: Yongqiang Sun Rework surface programming for RN to separate preparing parameters and register programming. Signed-off-by: Yongqiang Sun Reviewed-by: Tony Cheng Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- .../gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c | 324 +++--- .../gpu/drm/amd/display/dmub/inc/dmub_cmd.h | 16 +- 2 files changed, 127 insertions(+), 213 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c index 1f4e2cd08d4c..12396c371569 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c @@ -690,28 +690,114 @@ void hubp21_validate_dml_output(struct hubp *hubp, dml_dlg_attr->refcyc_per_meta_chunk_flip_l, dlg_attr.refcyc_per_meta_chunk_flip_l); } -static void program_video_progressive_dmcub( - struct dc_dmub_srv *dmcub, +static void program_surface_flip_and_addr(struct hubp *hubp, struct dmub_rb_cmd_flip *surface_flip) +{ + struct dcn21_hubp *hubp21 = TO_DCN21_HUBP(hubp); + + REG_UPDATE_3(DCSURF_FLIP_CONTROL, + SURFACE_FLIP_TYPE, surface_flip->flip.flip_params.immediate, + SURFACE_FLIP_MODE_FOR_STEREOSYNC, surface_flip->flip.flip_params.grph_stereo, + SURFACE_FLIP_IN_STEREOSYNC, surface_flip->flip.flip_params.grph_stereo); + + REG_UPDATE(VMID_SETTINGS_0, + VMID, surface_flip->flip.flip_params.vmid); + + REG_UPDATE_8(DCSURF_SURFACE_CONTROL, + PRIMARY_SURFACE_TMZ, surface_flip->flip.flip_params.tmz_surface, + PRIMARY_SURFACE_TMZ_C, surface_flip->flip.flip_params.tmz_surface, + PRIMARY_META_SURFACE_TMZ, surface_flip->flip.flip_params.tmz_surface, + PRIMARY_META_SURFACE_TMZ_C, surface_flip->flip.flip_params.tmz_surface, + SECONDARY_SURFACE_TMZ, surface_flip->flip.flip_params.tmz_surface, + SECONDARY_SURFACE_TMZ_C, surface_flip->flip.flip_params.tmz_surface, + SECONDARY_META_SURFACE_TMZ, surface_flip->flip.flip_params.tmz_surface, + SECONDARY_META_SURFACE_TMZ_C, surface_flip->flip.flip_params.tmz_surface); + + REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C, 0, + PRIMARY_META_SURFACE_ADDRESS_HIGH_C, + surface_flip->flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C); + + REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_C, 0, + PRIMARY_META_SURFACE_ADDRESS_C, + surface_flip->flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS_C); + + REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, 0, + PRIMARY_META_SURFACE_ADDRESS_HIGH, + surface_flip->flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH); + + REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS, 0, + PRIMARY_META_SURFACE_ADDRESS, + surface_flip->flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS); + + REG_SET(DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH, 0, + SECONDARY_META_SURFACE_ADDRESS_HIGH, + surface_flip->flip.DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH); + + REG_SET(DCSURF_SECONDARY_META_SURFACE_ADDRESS, 0, + SECONDARY_META_SURFACE_ADDRESS, + surface_flip->flip.DCSURF_SECONDARY_META_SURFACE_ADDRESS); + + + REG_SET(DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH, 0, + SECONDARY_SURFACE_ADDRESS_HIGH, + surface_flip->flip.DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH); + + REG_SET(DCSURF_SECONDARY_SURFACE_ADDRESS, 0, + SECONDARY_SURFACE_ADDRESS, + surface_flip->flip.DCSURF_SECONDARY_SURFACE_ADDRESS); + + + REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C, 0, + PRIMARY_SURFACE_ADDRESS_HIGH_C, + surface_flip->flip.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C); + + REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_C, 0, + PRIMARY_SURFACE_ADDRESS_C, + surface_flip->flip.DCSURF_PRIMARY_SURFACE_ADDRESS_C); + + REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 0, + PRIMARY_SURFACE_ADDRESS_HIGH, + surface_flip->flip.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH); + + REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS, 0, + PRIMARY_SURFACE_ADDRESS, + surface_flip->flip.DCSURF_PRIMARY_SURFACE_ADDRESS); +} + +void program_surface_flip_and_addr_dmcub(struct hubp *hubp, struct dmub_rb_cmd_flip *surface_flip) +{ + struct dc_dmub_srv *dmcub = hubp->ctx->dmub_srv; + struct dcn21_hubp *hubp21
[PATCH 19/43] drm/amd/display: Fix double buffering in dcn2 ICSC
From: Noah Abradjian [Why] When rapidly adjusting video brightness, screen tearing was observed. This was due to overwritten values in ICSC registers. In dcn10, this issue had been fixed by implementing double buffering via alternating ICSC modes. However, the second register set used in dcn1 doesn't exist in dcn2. [How] Create new program_input_csc for dcn20. Use ICSC_B registers instead of COMA registers as second set. Signed-off-by: Noah Abradjian Reviewed-by: Tony Cheng Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- .../drm/amd/display/dc/dcn10/dcn10_dpp_cm.c | 20 - .../gpu/drm/amd/display/dc/dcn20/dcn20_dpp.c | 24 +++--- .../gpu/drm/amd/display/dc/dcn20/dcn20_dpp.h | 31 ++- .../drm/amd/display/dc/dcn20/dcn20_dpp_cm.c | 83 ++- .../gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c | 10 ++- .../gpu/drm/amd/display/dc/dcn20/dcn20_mpc.h | 6 +- .../drm/amd/display/dc/dcn20/dcn20_resource.c | 1 + .../drm/amd/display/dc/dcn21/dcn21_resource.c | 7 +- drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h | 20 + 9 files changed, 160 insertions(+), 42 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c index 935c892622a0..4d3f7d5e1473 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c @@ -88,26 +88,6 @@ enum dscl_mode_sel { DSCL_MODE_DSCL_BYPASS = 6 }; -static const struct dpp_input_csc_matrix dpp_input_csc_matrix[] = { - {COLOR_SPACE_SRGB, - {0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} }, - {COLOR_SPACE_SRGB_LIMITED, - {0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} }, - {COLOR_SPACE_YCBCR601, - {0x2cdd, 0x2000, 0, 0xe991, 0xe926, 0x2000, 0xf4fd, 0x10ef, - 0, 0x2000, 0x38b4, 0xe3a6} }, - {COLOR_SPACE_YCBCR601_LIMITED, - {0x3353, 0x2568, 0, 0xe400, 0xe5dc, 0x2568, 0xf367, 0x1108, - 0, 0x2568, 0x40de, 0xdd3a} }, - {COLOR_SPACE_YCBCR709, - {0x3265, 0x2000, 0, 0xe6ce, 0xf105, 0x2000, 0xfa01, 0xa7d, 0, - 0x2000, 0x3b61, 0xe24f} }, - - {COLOR_SPACE_YCBCR709_LIMITED, - {0x39a6, 0x2568, 0, 0xe0d6, 0xeedd, 0x2568, 0xf925, 0x9a8, 0, - 0x2568, 0x43ee, 0xdbb2} } -}; - static void program_gamut_remap( struct dcn10_dpp *dpp, const uint16_t *regval, diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp.c index 4d7e45892f08..bbdab5000a7c 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp.c @@ -104,7 +104,7 @@ static void dpp2_cnv_setup ( uint32_t pixel_format = 0; uint32_t alpha_en = 1; enum dc_color_space color_space = COLOR_SPACE_SRGB; - enum dcn10_input_csc_select select = INPUT_CSC_SELECT_BYPASS; + enum dcn20_input_csc_select select = DCN2_ICSC_SELECT_BYPASS; bool force_disable_cursor = false; struct out_csc_color_matrix tbl_entry; uint32_t is_2bit = 0; @@ -145,25 +145,25 @@ static void dpp2_cnv_setup ( force_disable_cursor = false; pixel_format = 65; color_space = COLOR_SPACE_YCBCR709; - select = INPUT_CSC_SELECT_ICSC; + select = DCN2_ICSC_SELECT_ICSC_A; break; case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb: force_disable_cursor = true; pixel_format = 64; color_space = COLOR_SPACE_YCBCR709; - select = INPUT_CSC_SELECT_ICSC; + select = DCN2_ICSC_SELECT_ICSC_A; break; case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr: force_disable_cursor = true; pixel_format = 67; color_space = COLOR_SPACE_YCBCR709; - select = INPUT_CSC_SELECT_ICSC; + select = DCN2_ICSC_SELECT_ICSC_A; break; case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb: force_disable_cursor = true; pixel_format = 66; color_space = COLOR_SPACE_YCBCR709; - select = INPUT_CSC_SELECT_ICSC; + select = DCN2_ICSC_SELECT_ICSC_A; break; case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: pixel_format = 22; @@ -177,7 +177,7 @@ static void dpp2_cnv_setup ( case SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb: pixel_format = 12; color_space = COLOR_SPACE_YCBCR709; - select = INPUT_CSC_SELECT_ICSC; + select = DCN2_ICSC_SELECT_ICSC_A; break; case SURFACE_PIXEL_FORMAT_GRPH_RGB
[PATCH 15/43] drm/amd/display: wait for update when setting dpg test pattern
From: Wenjing Liu Test pattern should be applied to hardware when exiting set test pattern function. Signed-off-by: Wenjing Liu Reviewed-by: Nikola Cornij Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 13 + 1 file changed, 13 insertions(+) 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 0d0507cc9bf9..46f16a77e3a4 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 @@ -3612,6 +3612,7 @@ static void set_crtc_test_pattern(struct dc_link *link, struct pipe_ctx *odm_pipe; enum controller_dp_color_space controller_color_space; int opp_cnt = 1; + uint8_t count = 0; switch (test_pattern_color_space) { case DP_TEST_PATTERN_COLOR_SPACE_RGB: @@ -3647,6 +3648,12 @@ static void set_crtc_test_pattern(struct dc_link *link, NULL, width, height); + /* wait for dpg to blank pixel data with test pattern */ + for (count = 0; count < 1000; count++) + if (odm_opp->funcs->dpg_is_blanked(odm_opp)) + break; + else + udelay(100); } opp->funcs->opp_set_disp_pattern_generator(opp, controller_test_pattern, @@ -3655,6 +3662,12 @@ static void set_crtc_test_pattern(struct dc_link *link, NULL, width, height); + /* wait for dpg to blank pixel data with test pattern */ + for (count = 0; count < 1000; count++) + if (opp->funcs->dpg_is_blanked(opp)) + break; + else + udelay(100); } } break; -- 2.24.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 28/43] drm/amd/display: rename _lvp to l_vp
From: Charlene Liu Signed-off-by: Charlene Liu Reviewed-by: Charlene Liu Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- .../gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c| 4 ++-- .../gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c | 4 ++-- .../gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c| 4 ++-- drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c index 16559f7fb952..e7a8ac7a1f22 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c @@ -937,7 +937,7 @@ static unsigned int CalculateVMAndRowBytes( *MetaRowByte = 0; } - if (SurfaceTiling == dm_sw_linear || SurfaceTiling == dm_sw_gfx7_2d_thin_gl || SurfaceTiling == dm_sw_gfx7_2d_thin_lvp) { + if (SurfaceTiling == dm_sw_linear || SurfaceTiling == dm_sw_gfx7_2d_thin_gl || SurfaceTiling == dm_sw_gfx7_2d_thin_l_vp) { MacroTileSizeBytes = 256; MacroTileHeight = BlockHeight256Bytes; } else if (SurfaceTiling == dm_sw_4kb_s || SurfaceTiling == dm_sw_4kb_s_x @@ -3348,7 +3348,7 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l == dm_420_10)) || (((mode_lib->vba.SurfaceTiling[k] == dm_sw_gfx7_2d_thin_gl || mode_lib->vba.SurfaceTiling[k] - == dm_sw_gfx7_2d_thin_lvp) + == dm_sw_gfx7_2d_thin_l_vp) && !((mode_lib->vba.SourcePixelFormat[k] == dm_444_64 || mode_lib->vba.SourcePixelFormat[k] diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c index d6fedae03dc8..22f3b5a4b3b9 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c @@ -997,7 +997,7 @@ static unsigned int CalculateVMAndRowBytes( *MetaRowByte = 0; } - if (SurfaceTiling == dm_sw_linear || SurfaceTiling == dm_sw_gfx7_2d_thin_gl || SurfaceTiling == dm_sw_gfx7_2d_thin_lvp) { + if (SurfaceTiling == dm_sw_linear || SurfaceTiling == dm_sw_gfx7_2d_thin_gl || SurfaceTiling == dm_sw_gfx7_2d_thin_l_vp) { MacroTileSizeBytes = 256; MacroTileHeight = BlockHeight256Bytes; } else if (SurfaceTiling == dm_sw_4kb_s || SurfaceTiling == dm_sw_4kb_s_x @@ -3385,7 +3385,7 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode == dm_420_10)) || (((mode_lib->vba.SurfaceTiling[k] == dm_sw_gfx7_2d_thin_gl || mode_lib->vba.SurfaceTiling[k] - == dm_sw_gfx7_2d_thin_lvp) + == dm_sw_gfx7_2d_thin_l_vp) && !((mode_lib->vba.SourcePixelFormat[k] == dm_444_64 || mode_lib->vba.SourcePixelFormat[k] diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c index 5dcfbb0af825..af35b3bea909 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c @@ -1338,7 +1338,7 @@ static unsigned int CalculateVMAndRowBytes( *MetaRowByte = 0; } - if (SurfaceTiling == dm_sw_linear || SurfaceTiling == dm_sw_gfx7_2d_thin_gl || SurfaceTiling == dm_sw_gfx7_2d_thin_lvp) { + if (SurfaceTiling == dm_sw_linear || SurfaceTiling == dm_sw_gfx7_2d_thin_gl || SurfaceTiling == dm_sw_gfx7_2d_thin_l_vp) { MacroTileSizeBytes = 256; MacroTileHeight = BlockHeight256Bytes; } else if (SurfaceTiling == dm_sw_4kb_s || SurfaceTiling == dm_sw_4kb_s_x @@ -3453,7 +3453,7 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l == dm_420_10))
[PATCH 26/43] drm/amd/display: Fix DMUB PSR command IDs
From: Wyatt Wood [Why] The DMUB PSR command IDs do not have the correct values. [How] Fix the command IDs and cleanup the formatting. Signed-off-by: Wyatt Wood Reviewed-by: Aric Cyr Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- .../gpu/drm/amd/display/dmub/inc/dmub_cmd_dal.h | 15 --- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd_dal.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd_dal.h index 20b47649f991..7b69eb37f762 100644 --- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd_dal.h +++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd_dal.h @@ -32,16 +32,17 @@ */ enum dmub_cmd_psr_type { - DMUB_CMD__PSR_ENABLE = 0, - DMUB_CMD__PSR_DISABLE = 1, - DMUB_CMD__PSR_COPY_SETTINGS = 2, - DMUB_CMD__PSR_SET_LEVEL = 3, - DMUB_CMD__PSR_SETUP = 4, + DMUB_CMD__PSR_SETUP = 0, + DMUB_CMD__PSR_COPY_SETTINGS = 1, + DMUB_CMD__PSR_ENABLE= 2, + DMUB_CMD__PSR_DISABLE = 3, + DMUB_CMD__PSR_SET_LEVEL = 4, }; enum psr_version { - PSR_VERSION_1 = 0x0, - PSR_VERSION_2 = 0x10, + PSR_VERSION_1 = 0x10, // PSR Version 1 + PSR_VERSION_2 = 0x20, // PSR Version 2, includes selective update + PSR_VERSION_2_Y_COORD = 0x21, // PSR Version 2, includes Y-coordinate support for SU }; #endif /* _DMUB_CMD_DAL_H_ */ -- 2.24.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 04/43] drm/amd/display: fix chroma vp wa corner case
From: Eric Yang [Why] Previous implementation we may have residual chroma address offset if transition from wa enable -> wa disable. [How] Clear address offset cache when viewport updates. Also update the vp size check condition to account for rotation angle Signed-off-by: Eric Yang Reviewed-by: Tony Cheng Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- .../gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c| 16 +--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c index 216ae170bc50..4d2564f79395 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c @@ -251,10 +251,20 @@ static void hubp21_apply_PLAT_54186_wa( ROTATION_ANGLE, &rotation_angle, H_MIRROR_EN, &h_mirror_en); - /* apply wa only for NV12 surface with scatter gather enabled with view port > 512 */ + /* reset persistent cached data */ + hubp21->PLAT_54186_wa_chroma_addr_offset = 0; + /* apply wa only for NV12 surface with scatter gather enabled with viewport > 512 along +* the vertical direction*/ if (address->type != PLN_ADDR_TYPE_VIDEO_PROGRESSIVE || - address->video_progressive.luma_addr.high_part == 0xf4 - || viewport_c_height <= 512) + address->video_progressive.luma_addr.high_part == 0xf4) + return; + + if ((rotation_angle == 0 || rotation_angle == 180) + && viewport_c_height <= 512) + return; + + if ((rotation_angle == 90 || rotation_angle == 270) + && viewport_c_width <= 512) return; switch (rotation_angle) { -- 2.24.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 27/43] drm/amd/display: Add w/a to reset PHY before link training in verify_link_cap
From: George Shen [Why] PHY will sometimes be in bad state on hotplugging display from USB-C dongle. [How] Add additional calls to disable and then enable PHY before link training starts during verify_link_cap. Signed-off-by: George Shen Reviewed-by: Tony Cheng Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 10 ++ drivers/gpu/drm/amd/display/dc/dc.h | 1 + drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c | 3 ++- 3 files changed, 13 insertions(+), 1 deletion(-) 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 46f16a77e3a4..ea5a09ca3334 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 @@ -1892,6 +1892,16 @@ bool dp_verify_link_cap( /* disable PHY done possible by BIOS, will be done by driver itself */ dp_disable_link_phy(link, link->connector_signal); + /* Temporary Renoir-specific workaround for SWDEV-215184; +* PHY will sometimes be in bad state on hotplugging display from certain USB-C dongle, +* so add extra cycle of enabling and disabling the PHY before first link training. +*/ + if (link->link_enc->features.flags.bits.DP_IS_USB_C && + link->dc->debug.usbc_combo_phy_reset_wa) { + dp_enable_link_phy(link, link->connector_signal, dp_cs_id, cur); + dp_disable_link_phy(link, link->connector_signal); + } + dp_cs_id = get_clock_source_id(link); /* link training starts with the maximum common settings diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index ecd2257de80b..8c7ff9e322f1 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -421,6 +421,7 @@ struct dc_debug_options { bool disable_dram_clock_change_vactive_support; bool validate_dml_output; bool enable_dmcub_surface_flip; + bool usbc_combo_phy_reset_wa; }; struct dc_debug_data { diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c index f1ec3448c0c0..0c02120311b6 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c @@ -835,7 +835,8 @@ static const struct dc_debug_options debug_defaults_drv = { .scl_reset_length10 = true, .sanity_checks = true, .disable_48mhz_pwrdwn = false, - .nv12_iflip_vm_wa = true + .nv12_iflip_vm_wa = true, + .usbc_combo_phy_reset_wa = true }; static const struct dc_debug_options debug_defaults_diags = { -- 2.24.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 24/43] drm/amd/display: Indirect reg read macro with shift and mask
From: Noah Abradjian [Why] Recent double buffering changes for dcn2 use IX_REG_READ. However, this macro returns the full register value, with the need to manually shift and mask it to retrieve field data. [How] Create new IX_REG_GET macro that handles shift and mask. Use this for double buffering reads instead of IX_REG_READ. Signed-off-by: Noah Abradjian Reviewed-by: Tony Cheng Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- drivers/gpu/drm/amd/display/dc/dc_helper.c| 30 +++ .../gpu/drm/amd/display/dc/dcn20/dcn20_dpp.h | 16 +++--- .../drm/amd/display/dc/dcn20/dcn20_dpp_cm.c | 18 --- .../gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c | 16 -- .../gpu/drm/amd/display/dc/dcn20/dcn20_mpc.h | 10 +-- .../drm/amd/display/dc/dcn20/dcn20_resource.c | 10 --- .../drm/amd/display/dc/dcn21/dcn21_resource.c | 10 --- .../gpu/drm/amd/display/dc/inc/reg_helper.h | 13 8 files changed, 86 insertions(+), 37 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc_helper.c b/drivers/gpu/drm/amd/display/dc/dc_helper.c index 02a63e9cb62f..737048d8a96c 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_helper.c +++ b/drivers/gpu/drm/amd/display/dc/dc_helper.c @@ -552,6 +552,36 @@ uint32_t generic_read_indirect_reg(const struct dc_context *ctx, return value; } +uint32_t generic_indirect_reg_get(const struct dc_context *ctx, + uint32_t addr_index, uint32_t addr_data, + uint32_t index, int n, + uint8_t shift1, uint32_t mask1, uint32_t *field_value1, + ...) +{ + uint32_t shift, mask, *field_value; + uint32_t value = 0; + int i = 1; + + va_list ap; + + va_start(ap, field_value1); + + value = generic_read_indirect_reg(ctx, addr_index, addr_data, index); + *field_value1 = get_reg_field_value_ex(value, mask1, shift1); + + while (i < n) { + shift = va_arg(ap, uint32_t); + mask = va_arg(ap, uint32_t); + field_value = va_arg(ap, uint32_t *); + + *field_value = get_reg_field_value_ex(value, mask, shift); + i++; + } + + va_end(ap); + + return value; +} uint32_t generic_indirect_reg_update_ex(const struct dc_context *ctx, uint32_t addr_index, uint32_t addr_data, diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp.h index 141dea963db9..27610251c57f 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp.h +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp.h @@ -589,14 +589,22 @@ * Gamut Remap Mode: [10..9] */ #define CM_TEST_DEBUG_DATA_STATUS_IDX 9 -#define CM_TEST_DEBUG_DATA_ICSC_MODE_SH 3 -#define CM_TEST_DEBUG_DATA_ICSC_MODE_MASK 0x3 -#define CM_TEST_DEBUG_DATA_GAMUT_REMAP_MODE_SH 9 -#define CM_TEST_DEBUG_DATA_GAMUT_REMAP_MODE_MASK 0x3 + +#define TF_DEBUG_REG_LIST_SH_DCN20 \ + TF_DEBUG_REG_LIST_SH_DCN10, \ + .CM_TEST_DEBUG_DATA_ICSC_MODE = 3, \ + .CM_TEST_DEBUG_DATA_GAMUT_REMAP_MODE = 9 + +#define TF_DEBUG_REG_LIST_MASK_DCN20 \ + TF_DEBUG_REG_LIST_MASK_DCN10, \ + .CM_TEST_DEBUG_DATA_ICSC_MODE = 0x18, \ + .CM_TEST_DEBUG_DATA_GAMUT_REMAP_MODE = 0x600 #define TF_REG_FIELD_LIST_DCN2_0(type) \ TF_REG_FIELD_LIST(type) \ type CM_BLNDGAM_LUT_DATA; \ + type CM_TEST_DEBUG_DATA_ICSC_MODE; \ + type CM_TEST_DEBUG_DATA_GAMUT_REMAP_MODE; \ type FORMAT_CNV16; \ type CNVC_BYPASS_MSB_ALIGN; \ type CLAMP_POSITIVE; \ diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp_cm.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp_cm.c index 4047d406a74c..8dc3d1f73984 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp_cm.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp_cm.c @@ -176,12 +176,9 @@ static void program_gamut_remap( * currently. select the alternate set to double buffer * the update so gamut_remap is updated on frame boundary */ - cur_select = IX_REG_READ(CM_TEST_DEBUG_INDEX, CM_TEST_DEBUG_DATA, - CM_TEST_DEBUG_DATA_STATUS_IDX); - - /* IX_REG_READ reads whole reg, so isolate part we want [10..9] */ - cur_select = (cur_select >> CM_TEST_DEBUG_DATA_GAMUT_REMAP_MODE_SH) - & CM_TEST_DEBUG_DATA_GAMUT_REMAP_MODE_MASK; + IX_REG_GET(CM_TEST_DEBUG_INDEX, CM_TEST_DEBUG_DATA, + CM_TEST_DEBUG_DATA_STATUS_IDX, + CM_TEST_DEBUG_DATA_GAMUT_REMAP_MODE, &cur_select); /* value stored in dbg reg will be 1 greater than mode we want */ if (cur_select != DCN2_GAMUT_REMAP_COEF_A) @@ -275,12 +272,9 @@ void dpp2_program_input_csc( * currently. select the alternate set to double buffer * the CSC update so CSC is updated on frame boundary
[PATCH 01/43] drm/amd/include: Add OCSC registers
Add registers for handling Post Gamma Color Blending (OCSC), which is useful for conversion from RGB->YUV for HDMI. Reviewed-by: Leo Li Acked-by: Harry Wentland Signed-off-by: Rodrigo Siqueira --- .../gpu/drm/amd/include/asic_reg/dcn/dcn_2_0_0_offset.h | 4 .../gpu/drm/amd/include/asic_reg/dcn/dcn_2_0_0_sh_mask.h | 9 - .../gpu/drm/amd/include/asic_reg/dcn/dcn_2_1_0_offset.h | 5 - .../gpu/drm/amd/include/asic_reg/dcn/dcn_2_1_0_sh_mask.h | 8 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_2_0_0_offset.h b/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_2_0_0_offset.h index cff8f91555d3..e9b2bd84cfed 100644 --- a/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_2_0_0_offset.h +++ b/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_2_0_0_offset.h @@ -8134,6 +8134,10 @@ #define mmMPC_OUT5_CSC_C33_C34_B 0x1604 #define mmMPC_OUT5_CSC_C33_C34_B_BASE_IDX 2 +#define mmMPC_OCSC_TEST_DEBUG_INDEX 0x163b +#define mmMPC_OCSC_TEST_DEBUG_INDEX_BASE_IDX 2 +#define mmMPC_OCSC_TEST_DEBUG_DATA_BASE_IDX 2 +#define mmMPC_OCSC_TEST_DEBUG_DATA 0x163c // addressBlock: dce_dc_mpc_mpc_dcperfmon_dc_perfmon_dispdec // base address: 0x5964 diff --git a/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_2_0_0_sh_mask.h b/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_2_0_0_sh_mask.h index 10c83fecd147..dc8ce7aaa0cf 100644 --- a/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_2_0_0_sh_mask.h +++ b/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_2_0_0_sh_mask.h @@ -28263,7 +28263,14 @@ #define MPC_OUT5_CSC_C33_C34_B__MPC_OCSC_C34_B__SHIFT 0x10 #define MPC_OUT5_CSC_C33_C34_B__MPC_OCSC_C33_B_MASK 0xL #define MPC_OUT5_CSC_C33_C34_B__MPC_OCSC_C34_B_MASK 0xL - +//MPC_OCSC_TEST_DEBUG_INDEX +#define MPC_OCSC_TEST_DEBUG_INDEX__MPC_OCSC_TEST_DEBUG_INDEX__SHIFT 0x0 +#define MPC_OCSC_TEST_DEBUG_INDEX__MPC_OCSC_TEST_DEBUG_WRITE_EN__SHIFT 0x8 +#define MPC_OCSC_TEST_DEBUG_INDEX__MPC_OCSC_TEST_DEBUG_INDEX_MASK 0x00FFL +#define MPC_OCSC_TEST_DEBUG_INDEX__MPC_OCSC_TEST_DEBUG_WRITE_EN_MASK 0x0100L +//MPC_OCSC_TEST_DEBUG_DATA +#define MPC_OCSC_TEST_DEBUG_DATA__MPC_OCSC_TEST_DEBUG_DATA__SHIFT 0x0 +#define MPC_OCSC_TEST_DEBUG_DATA__MPC_OCSC_TEST_DEBUG_DATA_MASK 0xL // addressBlock: dce_dc_mpc_mpc_dcperfmon_dc_perfmon_dispdec //DC_PERFMON17_PERFCOUNTER_CNTL diff --git a/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_2_1_0_offset.h b/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_2_1_0_offset.h index eddf83ec1c39..7cd0ee61c030 100644 --- a/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_2_1_0_offset.h +++ b/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_2_1_0_offset.h @@ -7103,7 +7103,10 @@ #define mmMPC_OUT3_CSC_C31_C32_B_BASE_IDX 2 #define mmMPC_OUT3_CSC_C33_C34_B 0x15ea #define mmMPC_OUT3_CSC_C33_C34_B_BASE_IDX 2 - +#define mmMPC_OCSC_TEST_DEBUG_INDEX 0x163b +#define mmMPC_OCSC_TEST_DEBUG_INDEX_BASE_IDX 2 +#define mmMPC_OCSC_TEST_DEBUG_DATA_BASE_IDX 2 +#define mmMPC_OCSC_TEST_DEBUG_DATA 0x163c // addressBlock: dce_dc_mpc_mpc_dcperfmon_dc_perfmon_dispdec // base address: 0x5964 diff --git a/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_2_1_0_sh_mask.h b/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_2_1_0_sh_mask.h index faa0e76e32b4..2f780aefc722 100644 --- a/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_2_1_0_sh_mask.h +++ b/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_2_1_0_sh_mask.h @@ -56634,5 +56634,13 @@ #define AZF0INPUTENDPOINT7_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_INFOFRAME__INFOFRAME_BYTE_5_MASK 0x00FFL #define AZF0INPUTENDPOINT7_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_INFOFRAME__INFOFRAME_VALID_MASK 0x8000L +//MPC_OCSC_TEST_DEBUG_INDEX +#defin
[PATCH 05/43] drm/amd/display: Fix 300Hz Freesync bug
From: Alvin Lee Needed to reprogram vblank_start in dml properly in order to get the correct dlg params to program VTG. Signed-off-by: Alvin Lee Reviewed-by: Martin Leung Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- drivers/gpu/drm/amd/display/dc/core/dc.c| 1 - drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 4 +++- drivers/gpu/drm/amd/display/modules/freesync/freesync.c | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 3d89904003f0..46f2b54c3526 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -287,7 +287,6 @@ bool dc_stream_adjust_vmin_vmax(struct dc *dc, struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i]; if (pipe->stream == stream && pipe->stream_res.tg) { - pipe->stream->adjust = *adjust; dc->hwss.set_drr(&pipe, 1, adjust->v_total_min, diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c index 2dafa20d769d..b715ecc1b5e6 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c @@ -1883,12 +1883,14 @@ int dcn20_populate_dml_pipes_from_context( for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) { struct dc_crtc_timing *timing = &res_ctx->pipe_ctx[i].stream->timing; unsigned int v_total; + unsigned int front_porch; int output_bpc; if (!res_ctx->pipe_ctx[i].stream) continue; v_total = timing->v_total; + front_porch = timing->v_front_porch; /* todo: pipes[pipe_cnt].pipe.src.dynamic_metadata_enable = 0; pipes[pipe_cnt].pipe.src.dcc = 0; @@ -1915,7 +1917,7 @@ int dcn20_populate_dml_pipes_from_context( - timing->h_addressable - timing->h_border_left - timing->h_border_right; - pipes[pipe_cnt].pipe.dest.vblank_start = v_total - timing->v_front_porch; + pipes[pipe_cnt].pipe.dest.vblank_start = v_total - front_porch; pipes[pipe_cnt].pipe.dest.vblank_end = pipes[pipe_cnt].pipe.dest.vblank_start - timing->v_addressable - timing->v_border_top diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c index 832bc9b3b7d8..6e5ecefe7d9d 100644 --- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c +++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c @@ -812,11 +812,12 @@ void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync, 2 * in_out_vrr->min_refresh_in_uhz) in_out_vrr->btr.btr_enabled = false; - in_out_vrr->fixed.fixed_active = false; in_out_vrr->btr.btr_active = false; in_out_vrr->btr.inserted_duration_in_us = 0; in_out_vrr->btr.frames_to_insert = 0; in_out_vrr->btr.frame_counter = 0; + in_out_vrr->fixed.fixed_active = false; + in_out_vrr->fixed.target_refresh_in_uhz = 0; in_out_vrr->btr.mid_point_in_us = (in_out_vrr->min_duration_in_us + -- 2.24.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 16/43] drm/amd/display: stop doing unnecessary detection when going to D3
From: Joseph Gravenor [Why] Don't want to start HW discovery unless we have lost power, as doing rediscovery otherwise is both unnecessary and time consuming. Before this change it takes 40 seconds to go in to suspend, after it takes 27 seconds [How] Accelerated mode gets cleared if we lose power. Only do detection if this register is cleared Signed-off-by: Joseph Gravenor Reviewed-by: Eric Yang Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- drivers/gpu/drm/amd/display/dc/core/dc.c | 6 ++ drivers/gpu/drm/amd/display/dc/dc.h | 1 + 2 files changed, 7 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 46f2b54c3526..c918a0cd8c60 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -1318,6 +1318,12 @@ bool dc_commit_state(struct dc *dc, struct dc_state *context) return (result == DC_OK); } +bool dc_is_hw_initialized(struct dc *dc) +{ + struct dc_bios *dcb = dc->ctx->dc_bios; + return dcb->funcs->is_accelerated_mode(dcb); +} + bool dc_post_update_surfaces_to_stream(struct dc *dc) { int i; diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 29762b0531fc..d1d57432bc7e 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -1069,6 +1069,7 @@ unsigned int dc_get_current_backlight_pwm(struct dc *dc); unsigned int dc_get_target_backlight_pwm(struct dc *dc); bool dc_is_dmcu_initialized(struct dc *dc); +bool dc_is_hw_initialized(struct dc *dc); enum dc_status dc_set_clock(struct dc *dc, enum dc_clock_type clock_type, uint32_t clk_khz, uint32_t stepping); void dc_get_clock(struct dc *dc, enum dc_clock_type clock_type, struct dc_clock_config *clock_cfg); -- 2.24.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 02/43] drm/amd/display: Clear state after exiting fixed active VRR state
From: Amanda Liu [why] Upon exiting a fixed active VRR state, the state isn't cleared. This leads to the variable VRR range to be calculated incorrectly. [how] Set fixed active state to false when updating vrr params Signed-off-by: Amanda Liu Reviewed-by: Anthony Koo Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- drivers/gpu/drm/amd/display/modules/freesync/freesync.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c index fa57885503d4..832bc9b3b7d8 100644 --- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c +++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c @@ -812,6 +812,7 @@ void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync, 2 * in_out_vrr->min_refresh_in_uhz) in_out_vrr->btr.btr_enabled = false; + in_out_vrr->fixed.fixed_active = false; in_out_vrr->btr.btr_active = false; in_out_vrr->btr.inserted_duration_in_us = 0; in_out_vrr->btr.frames_to_insert = 0; @@ -832,6 +833,7 @@ void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync, in_out_vrr->adjust.v_total_max = stream->timing.v_total; } else if (in_out_vrr->state == VRR_STATE_ACTIVE_VARIABLE && refresh_range >= MIN_REFRESH_RANGE_IN_US) { + in_out_vrr->adjust.v_total_min = calc_v_total_from_refresh(stream, in_out_vrr->max_refresh_in_uhz); -- 2.24.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 14/43] drm/amd/display: Update HDMI hang w/a to apply to all TMDS signals
From: Michael Strauss [WHY] 48mhz turn off feature does not work on HDMI and DVI, but the feauture was only blocked on HDMI, this change will apply the same wa on DVI [HOW] Apply workaround for all TMDS signal types (HDMI, DVI single/dual link) Signed-off-by: Michael Strauss Reviewed-by: Eric Yang Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- .../gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c | 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c index ffed7207c099..7ae4c06232dd 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c @@ -59,14 +59,16 @@ int rn_get_active_display_cnt_wa( struct dc_state *context) { int i, display_count; - bool hdmi_present = false; + bool tmds_present = false; display_count = 0; for (i = 0; i < context->stream_count; i++) { const struct dc_stream_state *stream = context->streams[i]; - if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) - hdmi_present = true; + if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A || + stream->signal == SIGNAL_TYPE_DVI_SINGLE_LINK || + stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK) + tmds_present = true; } for (i = 0; i < dc->link_count; i++) { @@ -85,7 +87,7 @@ int rn_get_active_display_cnt_wa( } /* WA for hang on HDMI after display off back back on*/ - if (display_count == 0 && hdmi_present) + if (display_count == 0 && tmds_present) display_count = 1; return display_count; -- 2.24.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 12/43] drm/amd/display: store lttpr mode with dpcd
From: abdoulaye berthe Make sure that lttpr_caps has the mode set to repeater. Signed-off-by: abdoulaye berthe Reviewed-by: Wenjing Liu Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 13 +++-- 1 file changed, 11 insertions(+), 2 deletions(-) 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 38b0f4347383..0d0507cc9bf9 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 @@ -1217,24 +1217,33 @@ static void configure_lttpr_mode(struct dc_link *link) uint8_t repeater_cnt; uint32_t aux_interval_address; uint8_t repeater_id; + enum dc_status result = DC_ERROR_UNEXPECTED; uint8_t repeater_mode = DP_PHY_REPEATER_MODE_TRANSPARENT; DC_LOG_HW_LINK_TRAINING("%s\n Set LTTPR to Transparent Mode\n", __func__); - core_link_write_dpcd(link, + result = core_link_write_dpcd(link, DP_PHY_REPEATER_MODE, (uint8_t *)&repeater_mode, sizeof(repeater_mode)); + if (result == DC_OK) { + link->dpcd_caps.lttpr_caps.mode = repeater_mode; + } + if (!link->is_lttpr_mode_transparent) { DC_LOG_HW_LINK_TRAINING("%s\n Set LTTPR to Non Transparent Mode\n", __func__); repeater_mode = DP_PHY_REPEATER_MODE_NON_TRANSPARENT; - core_link_write_dpcd(link, + result = core_link_write_dpcd(link, DP_PHY_REPEATER_MODE, (uint8_t *)&repeater_mode, sizeof(repeater_mode)); + if (result == DC_OK) { + link->dpcd_caps.lttpr_caps.mode = repeater_mode; + } + repeater_cnt = convert_to_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt); for (repeater_id = repeater_cnt; repeater_id > 0; repeater_id--) { aux_interval_address = DP_TRAINING_AUX_RD_INTERVAL_PHY_REPEATER1 + -- 2.24.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 07/43] drm/amd/display: Adding forgotten hubbub func
From: Martin Leung [why] While doing seamless boot I made some changes to dcn2 hubbub functions, missed a link [how] link hubbub1 func to hubbub2 usage. It has already been successfully linked in dcn1 and 3. Signed-off-by: Martin Leung Reviewed-by: Alvin Lee Acked-by: Anthony Koo Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c index 8b8438566101..836af0f2bbda 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c @@ -601,7 +601,8 @@ static const struct hubbub_funcs hubbub2_funcs = { .wm_read_state = hubbub2_wm_read_state, .get_dchub_ref_freq = hubbub2_get_dchub_ref_freq, .program_watermarks = hubbub2_program_watermarks, - .allow_self_refresh_control = hubbub1_allow_self_refresh_control + .is_allow_self_refresh_enabled = hubbub1_is_allow_self_refresh_enabled, + .allow_self_refresh_control = hubbub1_allow_self_refresh_control, }; void hubbub2_construct(struct dcn20_hubbub *hubbub, -- 2.24.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 08/43] drm/amd/display: Flush framebuffer data before passing to DMCUB
From: Nicholas Kazlauskas [Why] There's a data race that can occur between when we update the inbox write pointer vs when the memory for the command actually gets flushed from the map to the framebuffer. DMCUB can read stale or partially invalid data when this race occurs. [How] Before updating the write pointer we can read back all pending commands to ensure that we stall for the writes to be flushed to framebuffer. We don't need to worry about choosing HDP vs VM flush with this mechanism. Drop the dmub_srv_cmd_submit() while we're updating this to work correctly since nothing was actually using this API and the caller should be explicit about the API flow here - by doing this on execute we can give some extra time for the flush to finish while preparing other commands. We should try to avoid writing single commands because of this overhead. Signed-off-by: Nicholas Kazlauskas Reviewed-by: Tony Cheng Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- .../gpu/drm/amd/display/dmub/inc/dmub_rb.h| 17 +++ .../gpu/drm/amd/display/dmub/inc/dmub_srv.h | 19 .../gpu/drm/amd/display/dmub/src/dmub_srv.c | 30 +-- 3 files changed, 24 insertions(+), 42 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_rb.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_rb.h index ac22744eaa94..ade688fd32f0 100644 --- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_rb.h +++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_rb.h @@ -113,6 +113,23 @@ static inline bool dmub_rb_pop_front(struct dmub_rb *rb) return true; } +static inline void dmub_rb_flush_pending(const struct dmub_rb *rb) +{ + uint8_t buf[DMUB_RB_CMD_SIZE]; + uint32_t rptr = rb->rptr; + uint32_t wptr = rb->wrpt; + + while (rptr != wptr) { + const uint8_t *data = (const uint8_t *)rb->base_address + rptr; + + dmub_memcpy(buf, data, DMUB_RB_CMD_SIZE); + + rptr += DMUB_RB_CMD_SIZE; + if (rptr >= rb->capacity) + rptr %= rb->capacity; + } +} + static inline void dmub_rb_init(struct dmub_rb *rb, struct dmub_rb_init_params *init_params) { diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_srv.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_srv.h index f34a50dd36ea..8e23a7017588 100644 --- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_srv.h +++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_srv.h @@ -444,25 +444,6 @@ enum dmub_status dmub_srv_cmd_queue(struct dmub_srv *dmub, */ enum dmub_status dmub_srv_cmd_execute(struct dmub_srv *dmub); -/** - * dmub_srv_cmd_submit() - submits a command to the DMUB immediately - * @dmub: the dmub service - * @cmd: the command to submit - * @timeout_us: the maximum number of microseconds to wait - * - * Submits a command to the DMUB with an optional timeout. - * If timeout_us is given then the service will attempt to - * resubmit for the given number of microseconds. - * - * Return: - * DMUB_STATUS_OK - success - * DMUB_STATUS_TIMEOUT - wait for submit timed out - * DMUB_STATUS_INVALID - unspecified error - */ -enum dmub_status dmub_srv_cmd_submit(struct dmub_srv *dmub, -const struct dmub_cmd_header *cmd, -uint32_t timeout_us); - /** * dmub_srv_wait_for_auto_load() - Waits for firmware auto load to complete * @dmub: the dmub service diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c index 9a959f871f11..23ca1fe97757 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c @@ -405,33 +405,17 @@ enum dmub_status dmub_srv_cmd_execute(struct dmub_srv *dmub) if (!dmub->hw_init) return DMUB_STATUS_INVALID; + /** +* Read back all the queued commands to ensure that they've +* been flushed to framebuffer memory. Otherwise DMCUB might +* read back stale, fully invalid or partially invalid data. +*/ + dmub_rb_flush_pending(&dmub->inbox1_rb); + dmub->hw_funcs.set_inbox1_wptr(dmub, dmub->inbox1_rb.wrpt); return DMUB_STATUS_OK; } -enum dmub_status dmub_srv_cmd_submit(struct dmub_srv *dmub, -const struct dmub_cmd_header *cmd, -uint32_t timeout_us) -{ - uint32_t i = 0; - - if (!dmub->hw_init) - return DMUB_STATUS_INVALID; - - for (i = 0; i <= timeout_us; ++i) { - dmub->inbox1_rb.rptr = dmub->hw_funcs.get_inbox1_rptr(dmub); - if (dmub_rb_push_front(&dmub->inbox1_rb, cmd)) { - dmub->hw_funcs.set_inbox1_wptr(dmub, - dmub->inbox1_rb.wrpt); - return DMUB_STATUS_OK; - } - - udelay(1); - } - - retu
[PATCH 22/43] drm/amd/display: programing surface flip by dmcub.
From: Yongqiang Sun Programming surface flip addresses via dmcub uC for optimizing the data flush. Signed-off-by: Yongqiang Sun Reviewed-by: Tony Cheng Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- drivers/gpu/drm/amd/display/dc/dc.h | 1 + .../gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c | 116 ++ .../gpu/drm/amd/display/dmub/inc/dmub_cmd.h | 36 +- .../gpu/drm/amd/display/dmub/inc/dmub_rb.h| 18 ++- 4 files changed, 165 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index dfc66954a24b..ecd2257de80b 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -420,6 +420,7 @@ struct dc_debug_options { bool nv12_iflip_vm_wa; bool disable_dram_clock_change_vactive_support; bool validate_dml_output; + bool enable_dmcub_surface_flip; }; struct dc_debug_data { diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c index 4d2564f79395..1f4e2cd08d4c 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c @@ -29,6 +29,8 @@ #include "dm_services.h" #include "reg_helper.h" +#include "dc_dmub_srv.h" + #define DC_LOGGER_INIT(logger) #define REG(reg)\ @@ -688,6 +690,113 @@ void hubp21_validate_dml_output(struct hubp *hubp, dml_dlg_attr->refcyc_per_meta_chunk_flip_l, dlg_attr.refcyc_per_meta_chunk_flip_l); } +static void program_video_progressive_dmcub( + struct dc_dmub_srv *dmcub, + struct hubp *hubp, + const struct dc_plane_address *address, + bool flip_immediate) +{ + struct dcn21_hubp *hubp21 = TO_DCN21_HUBP(hubp); + struct dmub_rb_cmd_flip surface_flip = { 0 }; + + surface_flip.header.type = DMUB_CMD__SURFACE_FLIP; + + surface_flip.flip.addr_type = address->type; + surface_flip.flip.immediate = flip_immediate; + surface_flip.flip.vmid = address->vmid; + + surface_flip.flip.hubp_inst = hubp->inst; + surface_flip.flip.tmz_surface = address->tmz_surface; + + switch (address->type) { + case PLN_ADDR_TYPE_GRAPHICS: + if (address->grph.addr.quad_part == 0) + return; + + if (address->grph.meta_addr.quad_part != 0) { + surface_flip.flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS = + address->grph.meta_addr.low_part; + surface_flip.flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH = + address->grph.meta_addr.high_part; + } + + surface_flip.flip.DCSURF_PRIMARY_SURFACE_ADDRESS = + address->grph.addr.low_part; + surface_flip.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH = + address->grph.addr.high_part; + break; + case PLN_ADDR_TYPE_VIDEO_PROGRESSIVE: + if (address->video_progressive.luma_addr.quad_part == 0 + || address->video_progressive.chroma_addr.quad_part == 0) + return; + + if (address->video_progressive.luma_meta_addr.quad_part != 0) { + surface_flip.flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS = + address->video_progressive.luma_meta_addr.low_part; + surface_flip.flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH = + address->video_progressive.luma_meta_addr.high_part; + + surface_flip.flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS_C = + address->video_progressive.chroma_meta_addr.low_part; + surface_flip.flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C = + address->video_progressive.chroma_meta_addr.high_part; + } + + surface_flip.flip.DCSURF_PRIMARY_SURFACE_ADDRESS = + address->video_progressive.luma_addr.low_part; + surface_flip.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH = + address->video_progressive.luma_addr.high_part; + + surface_flip.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_C = + address->video_progressive.chroma_addr.low_part; + surface_flip.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C = + address->video_progressive.chroma_addr.high_part; + + break; + case PLN_ADDR_TYPE_GRPH_STEREO: + if (address->grph_stereo.left_addr.quad_part == 0) + return; + if (address->grph_stereo.right_addr.quad_part == 0) +
[PATCH 17/43] drm/amd/display: expand dml structs
From: Dmytro Laktyushkin Add more fields to support upcoming dml versions Signed-off-by: Dmytro Laktyushkin Reviewed-by: Jun Lei Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- .../drm/amd/display/dc/dcn20/dcn20_resource.c | 35 +++- .../dc/dml/dcn20/display_mode_vba_20.c| 165 + .../dc/dml/dcn20/display_mode_vba_20v2.c | 167 +- .../dc/dml/dcn21/display_mode_vba_21.c| 157 .../amd/display/dc/dml/display_mode_enums.h | 16 ++ .../amd/display/dc/dml/display_mode_structs.h | 7 +- .../drm/amd/display/dc/dml/display_mode_vba.c | 22 ++- .../drm/amd/display/dc/dml/display_mode_vba.h | 128 ++ 8 files changed, 402 insertions(+), 295 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c index eac4c3cecadf..9233144ae74e 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c @@ -1858,6 +1858,22 @@ void dcn20_populate_dml_writeback_from_context( } +static int get_num_odm_heads(struct pipe_ctx *pipe) +{ + int odm_head_count = 0; + struct pipe_ctx *next_pipe = pipe->next_odm_pipe; + while (next_pipe) { + odm_head_count++; + next_pipe = next_pipe->next_odm_pipe; + } + pipe = pipe->prev_odm_pipe; + while (pipe) { + odm_head_count++; + pipe = pipe->prev_odm_pipe; + } + return odm_head_count ? odm_head_count + 1 : 0; +} + int dcn20_populate_dml_pipes_from_context( struct dc *dc, struct dc_state *context, display_e2e_pipe_params_st *pipes) { @@ -1897,6 +1913,8 @@ int dcn20_populate_dml_pipes_from_context( pipes[pipe_cnt].pipe.src.dcc = 0; pipes[pipe_cnt].pipe.src.vm = 0;*/ + pipes[pipe_cnt].clks_cfg.refclk_mhz = dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000.0; + pipes[pipe_cnt].dout.dsc_enable = res_ctx->pipe_ctx[i].stream->timing.flags.DSC; /* todo: rotation?*/ pipes[pipe_cnt].dout.dsc_slices = res_ctx->pipe_ctx[i].stream->timing.dsc_cfg.num_slices_h; @@ -1935,8 +1953,13 @@ int dcn20_populate_dml_pipes_from_context( pipes[pipe_cnt].dout.dp_lanes = 4; pipes[pipe_cnt].pipe.dest.vtotal_min = res_ctx->pipe_ctx[i].stream->adjust.v_total_min; pipes[pipe_cnt].pipe.dest.vtotal_max = res_ctx->pipe_ctx[i].stream->adjust.v_total_max; - pipes[pipe_cnt].pipe.dest.odm_combine = res_ctx->pipe_ctx[i].prev_odm_pipe - || res_ctx->pipe_ctx[i].next_odm_pipe; + switch (get_num_odm_heads(&res_ctx->pipe_ctx[i])) { + case 2: + pipes[pipe_cnt].pipe.dest.odm_combine = dm_odm_combine_mode_2to1; + break; + default: + pipes[pipe_cnt].pipe.dest.odm_combine = dm_odm_combine_mode_disabled; + } pipes[pipe_cnt].pipe.src.hsplit_grp = res_ctx->pipe_ctx[i].pipe_idx; if (res_ctx->pipe_ctx[i].top_pipe && res_ctx->pipe_ctx[i].top_pipe->plane_state == res_ctx->pipe_ctx[i].plane_state) @@ -2046,6 +2069,9 @@ int dcn20_populate_dml_pipes_from_context( if (pipes[pipe_cnt].pipe.src.viewport_height > 1080) pipes[pipe_cnt].pipe.src.viewport_height = 1080; pipes[pipe_cnt].pipe.src.surface_height_y = pipes[pipe_cnt].pipe.src.viewport_height; + pipes[pipe_cnt].pipe.src.surface_width_y = pipes[pipe_cnt].pipe.src.viewport_width; + pipes[pipe_cnt].pipe.src.surface_height_c = pipes[pipe_cnt].pipe.src.viewport_height; + pipes[pipe_cnt].pipe.src.surface_width_c = pipes[pipe_cnt].pipe.src.viewport_width; pipes[pipe_cnt].pipe.src.data_pitch = ((pipes[pipe_cnt].pipe.src.viewport_width + 63) / 64) * 64; /* linear sw only */ pipes[pipe_cnt].pipe.src.source_format = dm_444_32; pipes[pipe_cnt].pipe.dest.recout_width = pipes[pipe_cnt].pipe.src.viewport_width; /*vp_width/hratio*/ @@ -2079,7 +2105,10 @@ int dcn20_populate_dml_pipes_from_context( pipes[pipe_cnt].pipe.src.viewport_width_c = scl->viewport_c.width; pipes[pipe_cnt].pipe.src.viewport_height = scl->viewport.height; pipes[pipe_cnt].pipe.src.viewport_height_c = scl->viewport_c.height; + pipes[pipe_cnt].pipe.src.surface_width_y = pln->plane_size.surface_size.width; pipes[pipe_cnt].pipe.src.surface_height_y = pln->plane_size.surface_size.height; + pipes[pipe_cnt].pipe.src.surfac
[PATCH 21/43] drm/amd/display: Double buffer dcn2 Gamut Remap
From: Noah Abradjian [Why] When rapidly adjusting color temperature, screen tearing was observed. This was due to overwritten values in gamut remap registers. This issue was solved for OCSC and ICSC by alternating between "A" and "B" registers to double buffer the writes. [How] Create new set_gamut_remap and program_gamut_remap for dcn20. Alternate which registers are written to by switching modes each time. Also fixes ICSC mode reg read to use proper data offset. Signed-off-by: Noah Abradjian Reviewed-by: Tony Cheng Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- .../gpu/drm/amd/display/dc/dcn20/dcn20_dpp.c | 2 +- .../gpu/drm/amd/display/dc/dcn20/dcn20_dpp.h | 29 ++- .../drm/amd/display/dc/dcn20/dcn20_dpp_cm.c | 84 ++- 3 files changed, 109 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp.c index bbdab5000a7c..13e057d7ee93 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp.c @@ -458,7 +458,7 @@ static struct dpp_funcs dcn20_dpp_funcs = { .dpp_reset = dpp_reset, .dpp_set_scaler = dpp1_dscl_set_scaler_manual_scale, .dpp_get_optimal_number_of_taps = dpp1_get_optimal_number_of_taps, - .dpp_set_gamut_remap = dpp1_cm_set_gamut_remap, + .dpp_set_gamut_remap = dpp2_cm_set_gamut_remap, .dpp_set_csc_adjustment = NULL, .dpp_set_csc_default = NULL, .dpp_program_regamma_pwl = oppn20_dummy_program_regamma_pwl, diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp.h index d9ce60b6aa6e..141dea963db9 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp.h +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp.h @@ -151,6 +151,12 @@ SRI(CM_SHAPER_LUT_INDEX, CM, id) #define TF_REG_LIST_DCN20_COMMON_APPEND(id) \ + SRI(CM_GAMUT_REMAP_B_C11_C12, CM, id),\ + SRI(CM_GAMUT_REMAP_B_C13_C14, CM, id),\ + SRI(CM_GAMUT_REMAP_B_C21_C22, CM, id),\ + SRI(CM_GAMUT_REMAP_B_C23_C24, CM, id),\ + SRI(CM_GAMUT_REMAP_B_C31_C32, CM, id),\ + SRI(CM_GAMUT_REMAP_B_C33_C34, CM, id),\ SRI(CM_ICSC_B_C11_C12, CM, id), \ SRI(CM_ICSC_B_C33_C34, CM, id) @@ -579,11 +585,14 @@ /* DPP CM debug status register: * * Status index including current ICSC, Gamut Remap Mode is 9 - * ICSC Mode: [5..4] + * ICSC Mode: [4..3] + * Gamut Remap Mode: [10..9] */ #define CM_TEST_DEBUG_DATA_STATUS_IDX 9 -#define CM_TEST_DEBUG_DATA_ICSC_MODE_SH 4 +#define CM_TEST_DEBUG_DATA_ICSC_MODE_SH 3 #define CM_TEST_DEBUG_DATA_ICSC_MODE_MASK 0x3 +#define CM_TEST_DEBUG_DATA_GAMUT_REMAP_MODE_SH 9 +#define CM_TEST_DEBUG_DATA_GAMUT_REMAP_MODE_MASK 0x3 #define TF_REG_FIELD_LIST_DCN2_0(type) \ TF_REG_FIELD_LIST(type) \ @@ -646,6 +655,12 @@ struct dcn2_dpp_mask { uint32_t DSCL_MEM_PWR_CTRL #define DPP_DCN2_REG_VARIABLE_LIST_CM_APPEND \ + uint32_t CM_GAMUT_REMAP_B_C11_C12; \ + uint32_t CM_GAMUT_REMAP_B_C13_C14; \ + uint32_t CM_GAMUT_REMAP_B_C21_C22; \ + uint32_t CM_GAMUT_REMAP_B_C23_C24; \ + uint32_t CM_GAMUT_REMAP_B_C31_C32; \ + uint32_t CM_GAMUT_REMAP_B_C33_C34; \ uint32_t CM_ICSC_B_C11_C12; \ uint32_t CM_ICSC_B_C33_C34 @@ -679,6 +694,12 @@ enum dcn20_input_csc_select { DCN2_ICSC_SELECT_ICSC_B = 2 }; +enum dcn20_gamut_remap_select { + DCN2_GAMUT_REMAP_BYPASS = 0, + DCN2_GAMUT_REMAP_COEF_A = 1, + DCN2_GAMUT_REMAP_COEF_B = 2 +}; + void dpp20_read_state(struct dpp *dpp_base, struct dcn_dpp_state *s); @@ -690,6 +711,10 @@ void dpp2_set_degamma( struct dpp *dpp_base, enum ipp_degamma_mode mode); +void dpp2_cm_set_gamut_remap( + struct dpp *dpp_base, + const struct dpp_grph_csc_adjustment *adjust); + void dpp2_program_input_csc( struct dpp *dpp_base, enum dc_color_space color_space, diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp_cm.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp_cm.c index 423f3daa177f..4047d406a74c 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp_cm.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp_cm.c @@ -158,6 +158,85 @@ void dpp2_set_degamma( } } +static void program_gamut_remap( + struct dcn20_dpp *dpp, + const uint16_t *regval, + enum dcn20_gamut_remap_select select) +{ + uint32_t cur_select = 0; + struct color_matrices_reg gam_regs; + + if (regval == NULL || select == DCN2_GAMUT_REMAP_BYPASS) { + REG_SET(CM_GAMUT_REMAP_CONTROL, 0, + CM_GAMUT_REMAP_MODE, 0); + return; + } + + /* determine which gamut_remap coefficients (A or B) we are using +
[PATCH 00/43] DC Patches - January 10, 2020
This DC patchset brings improvements in multiple areas. In summary, we highlight: * Add OCSC improvements. * Bug fix on chroma, Freesync dml, and DMUB. * DMCUB improvements. * Some code refactor. Alvin Lee (3): drm/amd/display: Fix 300Hz Freesync bug drm/amd/display: Don't always set pstate true if dummy latency = 0 drm/amd/display: Enable double buffer for OTG_BLANK Amanda Liu (1): drm/amd/display: Clear state after exiting fixed active VRR state Anthony Koo (1): drm/amd/display: make PSR static screen entry within 30 ms Aric Cyr (4): drm/amd/display: 3.2.65 drm/amd/display: 3.2.66 drm/amd/display: 3.2.67 drm/amd/display: 3.2.68 Charlene Liu (1): drm/amd/display: rename _lvp to l_vp Chris Park (1): drm/amd/display: Add default switch case for DCC Dmytro Laktyushkin (1): drm/amd/display: expand dml structs Eric Yang (1): drm/amd/display: fix chroma vp wa corner case George Shen (1): drm/amd/display: Add w/a to reset PHY before link training in verify_link_cap Joseph Gravenor (1): drm/amd/display: stop doing unnecessary detection when going to D3 Josip Pavic (1): drm/amd/display: implement fw-driver interface for abm 2.4 Jun Lei (1): drm/amd/display: fixup DML dependencies Lewis Huang (2): drm/amd/display: remove psr state condition when psr exit case drm/amd/display: Add monitor patch for AUO dpcd issue Martin Leung (1): drm/amd/display: Adding forgotten hubbub func Martin Tsai (1): drm/amd/display: Use udelay to avoid context switch Michael Strauss (1): drm/amd/display: Update HDMI hang w/a to apply to all TMDS signals Nicholas Kazlauskas (3): drm/amd/display: Flush framebuffer data before passing to DMCUB drm/amd/display: Read inst_fb data back during DMUB loading drm/amd/display: Soft reset DMUIF during DMUB reset Nikola Cornij (1): drm/amd/display: Disable secondary link for certain monitors Noah Abradjian (4): drm/amd/display: Add double buffering to dcn20 OCSC drm/amd/display: Fix double buffering in dcn2 ICSC drm/amd/display: Double buffer dcn2 Gamut Remap drm/amd/display: Indirect reg read macro with shift and mask Paul Hsieh (1): drm/amd/display: reallocate MST payload when link loss Rodrigo Siqueira (1): drm/amd/include: Add OCSC registers Sung Lee (1): drm/amd/display: Use SMU ClockTable Values for DML Calculations Wenjing Liu (3): drm/amd/display: wait for update when setting dpg test pattern drm/amd/display: wait for test pattern after when all pipes are programmed drm/amd/display: skip opp blank or unblank if test pattern enabled Wyatt Wood (3): drm/amd/display: Driverside changes to support PSR in DMCUB drm/amd/display: DMCUB FW Changes to support PSR drm/amd/display: Fix DMUB PSR command IDs Yongqiang Sun (3): drm/amd/display: programing surface flip by dmcub. drm/amd/display: Refactor surface flip programming drm/amd/display: Only program surface flip for video plane via dmcub abdoulaye berthe (1): drm/amd/display: store lttpr mode with dpcd .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 32 +- .../amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c | 10 +- drivers/gpu/drm/amd/display/dc/core/dc.c | 13 +- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 64 +++- .../gpu/drm/amd/display/dc/core/dc_link_dp.c | 99 +- .../gpu/drm/amd/display/dc/core/dc_resource.c | 10 +- drivers/gpu/drm/amd/display/dc/dc.h | 20 +- drivers/gpu/drm/amd/display/dc/dc_helper.c| 30 ++ drivers/gpu/drm/amd/display/dc/dc_link.h | 4 + drivers/gpu/drm/amd/display/dc/dc_stream.h| 4 +- drivers/gpu/drm/amd/display/dc/dc_types.h | 3 +- drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c | 3 - drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c | 220 + drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h | 47 +++ .../display/dc/dce110/dce110_hw_sequencer.c | 35 +- .../dc/dce110/dce110_timing_generator.c | 11 +- .../dc/dce110/dce110_timing_generator.h | 3 +- .../dc/dce120/dce120_timing_generator.c | 11 +- .../drm/amd/display/dc/dcn10/dcn10_dpp_cm.c | 20 -- .../drm/amd/display/dc/dcn10/dcn10_hubbub.c | 3 + .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 31 +- .../amd/display/dc/dcn10/dcn10_hw_sequencer.h | 2 +- .../gpu/drm/amd/display/dc/dcn10/dcn10_optc.c | 15 +- .../gpu/drm/amd/display/dc/dcn10/dcn10_optc.h | 3 +- .../gpu/drm/amd/display/dc/dcn20/dcn20_dpp.c | 26 +- .../gpu/drm/amd/display/dc/dcn20/dcn20_dpp.h | 64 +++- .../drm/amd/display/dc/dcn20/dcn20_dpp_cm.c | 155 - .../drm/amd/display/dc/dcn20/dcn20_hubbub.c | 6 +- .../drm/amd/display/dc/dcn20/dcn20_hwseq.c| 13 +- .../gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c | 47 ++- .../gpu/drm/amd/display/dc/dcn20/dcn20_mpc.h | 22 ++ .../drm/amd/display/dc/dcn20/dcn20_resource.c | 53 +++- .../gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c | 300 ++ .../drm/amd/display/dc/dcn21/dcn21_resource.c | 28 +- .../dc/dml/dcn20/d
[PATCH 06/43] drm/amd/display: Disable secondary link for certain monitors
From: Nikola Cornij [why] If the specific monitor supports DSC, the secondary link should be disabled, and the other way around, too: if either that monitor or our ASIC doesn't support DSC, the secodary link should be enabled. [how] Add a monitor patch and disable secondary link if that monitor is detected and if ASIC supports DSC, or otherwise enable secondary link. Signed-off-by: Nikola Cornij Reviewed-by: Joshua Aberback Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 10 +++--- drivers/gpu/drm/amd/display/dc/dc.h | 2 ++ drivers/gpu/drm/amd/display/dc/dc_types.h | 1 + 3 files changed, 10 insertions(+), 3 deletions(-) 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 64a0e08fd019..a0eb9e533a61 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -2066,6 +2066,13 @@ void dc_resource_state_construct( dst_ctx->clk_mgr = dc->clk_mgr; } + +bool dc_resource_is_dsc_encoding_supported(const struct dc *dc) +{ + return dc->res_pool->res_cap->num_dsc > 0; +} + + /** * dc_validate_global_state() - Determine if HW can support a given state * Checks HW resource availability and bandwidth requirement. @@ -2897,6 +2904,3 @@ void get_audio_check(struct audio_info *aud_modes, } } - - - diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index c4e6c696f06f..29762b0531fc 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -910,6 +910,8 @@ void dc_resource_state_copy_construct_current( void dc_resource_state_destruct(struct dc_state *context); +bool dc_resource_is_dsc_encoding_supported(const struct dc *dc); + /* * TODO update to make it about validation sets * Set up streams and links associated to drive sinks diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h index b1a372c8df83..4b5b97520733 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_types.h @@ -229,6 +229,7 @@ struct dc_panel_patch { unsigned int extra_t12_ms; unsigned int extra_delay_backlight_off; unsigned int extra_t7_ms; + unsigned int manage_secondary_link; }; struct dc_edid_caps { -- 2.24.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 03/43] drm/amd/display: 3.2.65
From: Aric Cyr Signed-off-by: Aric Cyr Reviewed-by: Aric Cyr Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- drivers/gpu/drm/amd/display/dc/dc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 039004344dc6..c4e6c696f06f 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -39,7 +39,7 @@ #include "inc/hw/dmcu.h" #include "dml/display_mode_lib.h" -#define DC_VER "3.2.64" +#define DC_VER "3.2.65" #define MAX_SURFACES 3 #define MAX_PLANES 6 -- 2.24.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 29/43] drm/amd/display: Use SMU ClockTable Values for DML Calculations
From: Sung Lee [Why] DML Initialization was previously done on dcn21_resource initialization. This meant that DML soc struct was populated with hardcoded values. [How] Move DML initialization to after updating bounding box, to use clock table values from SMU. Signed-off-by: Sung Lee Reviewed-by: Tony Cheng Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira --- drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c index 0c02120311b6..1d741bca2211 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c @@ -1349,6 +1349,10 @@ static void update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param } dcn2_1_soc.clock_limits[i] = dcn2_1_soc.clock_limits[i - 1]; dcn2_1_soc.num_states = i; + + // diags does not retrieve proper values from SMU, do not update DML instance for diags + if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) && !IS_DIAG_DC(dc->ctx->dce_environment)) + dml_init_instance(&dc->dml, &dcn2_1_soc, &dcn2_1_ip, DML_PROJECT_DCN21); } /* Temporary Place holder until we can get them from fuse */ -- 2.24.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 1/3] drm/amdgpu: Create generic DF struct in adev
On Thu, Jan 9, 2020 at 9:34 PM Joseph Greathouse wrote: > > The only data fabric information the adev struct currently > contains is a function pointer table. In the near future, > we will be adding some cached DF information into adev. As > such, this patch creates a new amdgpu_df struct for adev > to old. Right now, it only containst the old function pointer > table, but new stuff will be added soon. > > Change-Id: I0359344297a740782efd35e902f9638bc9e67da8 > Signed-off-by: Joseph Greathouse Series is: Reviewed-by: Alex Deucher > --- > drivers/gpu/drm/amd/amdgpu/amdgpu.h | 29 ++- > drivers/gpu/drm/amd/amdgpu/amdgpu_df.h | 62 > drivers/gpu/drm/amd/amdgpu/amdgpu_pmu.c | 12 ++--- > drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c | 6 +-- > drivers/gpu/drm/amd/amdgpu/df_v1_7.c | 6 +-- > drivers/gpu/drm/amd/amdgpu/df_v3_6.c | 6 +-- > drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c| 6 +-- > drivers/gpu/drm/amd/amdgpu/soc15.c | 12 ++--- > 8 files changed, 90 insertions(+), 49 deletions(-) > create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_df.h > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > index 863bf45ba198..63eab0c135db 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > @@ -91,6 +91,7 @@ > #include "amdgpu_umc.h" > #include "amdgpu_mmhub.h" > #include "amdgpu_tmz.h" > +#include "amdgpu_df.h" > > #define MAX_GPU_INSTANCE 16 > > @@ -670,29 +671,6 @@ struct amdgpu_mmio_remap { > resource_size_t bus_addr; > }; > > -struct amdgpu_df_funcs { > - void (*sw_init)(struct amdgpu_device *adev); > - void (*sw_fini)(struct amdgpu_device *adev); > - void (*enable_broadcast_mode)(struct amdgpu_device *adev, > - bool enable); > - u32 (*get_fb_channel_number)(struct amdgpu_device *adev); > - u32 (*get_hbm_channel_number)(struct amdgpu_device *adev); > - void (*update_medium_grain_clock_gating)(struct amdgpu_device *adev, > -bool enable); > - void (*get_clockgating_state)(struct amdgpu_device *adev, > - u32 *flags); > - void (*enable_ecc_force_par_wr_rmw)(struct amdgpu_device *adev, > - bool enable); > - int (*pmc_start)(struct amdgpu_device *adev, uint64_t config, > -int is_enable); > - int (*pmc_stop)(struct amdgpu_device *adev, uint64_t config, > -int is_disable); > - void (*pmc_get_count)(struct amdgpu_device *adev, uint64_t config, > -uint64_t *count); > - uint64_t (*get_fica)(struct amdgpu_device *adev, uint32_t ficaa_val); > - void (*set_fica)(struct amdgpu_device *adev, uint32_t ficaa_val, > -uint32_t ficadl_val, uint32_t ficadh_val); > -}; > /* Define the HW IP blocks will be used in driver , add more if necessary */ > enum amd_hw_ip_block_type { > GC_HWIP = 1, > @@ -939,6 +917,9 @@ struct amdgpu_device { > /* tmz */ > struct amdgpu_tmz tmz; > > + /* df */ > + struct amdgpu_dfdf; > + > struct amdgpu_ip_block ip_blocks[AMDGPU_MAX_IP_NUM]; > int num_ip_blocks; > struct mutexmn_lock; > @@ -952,8 +933,6 @@ struct amdgpu_device { > /* soc15 register offset based on ip, instance and segment */ > uint32_t*reg_offset[MAX_HWIP][HWIP_MAX_INSTANCE]; > > - const struct amdgpu_df_funcs*df_funcs; > - > /* delayed work_func for deferring clockgating during resume */ > struct delayed_work delayed_init_work; > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_df.h > b/drivers/gpu/drm/amd/amdgpu/amdgpu_df.h > new file mode 100644 > index ..61a26c15c8dd > --- /dev/null > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_df.h > @@ -0,0 +1,62 @@ > +/* > + * Copyright 2020 Advanced Micro Devices, Inc. > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the "Software"), > + * to deal in the Software without restriction, including without limitation > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > + * and/or sell copies of the Software, and to permit persons to whom the > + * Software is furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice shall be included in > + * all copies or substantial portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS F
[PATCH] drm/amd/display: remove unnecessary conversion to bool
The conversion to bool is not needed, remove it. Signed-off-by: Chen Zhou --- drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 504055f..a004e8e 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 @@ -2792,7 +2792,7 @@ static bool retrieve_link_cap(struct dc_link *link) dpcd_data[DP_TRAINING_AUX_RD_INTERVAL]; link->dpcd_caps.ext_receiver_cap_field_present = - aux_rd_interval.bits.EXT_RECEIVER_CAP_FIELD_PRESENT == 1 ? true:false; + aux_rd_interval.bits.EXT_RECEIVER_CAP_FIELD_PRESENT == 1; if (aux_rd_interval.bits.EXT_RECEIVER_CAP_FIELD_PRESENT == 1) { uint8_t ext_cap_data[16]; -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 03/23] drm/i915: Don't use struct drm_driver.get_scanout_position()
On Fri, 10 Jan 2020, Thomas Zimmermann wrote: > Hi > > Am 10.01.20 um 12:59 schrieb Jani Nikula: >> On Fri, 10 Jan 2020, Thomas Zimmermann wrote: >>> The callback struct drm_driver.get_scanout_position() is deprecated in >>> favor of struct drm_crtc_helper_funcs.get_scanout_position(). >>> >>> i915 doesn't use CRTC helpers. The patch duplicates the caller >>> drm_calc_vbltimestamp_from_scanoutpos() for i915, such that the callback >>> function is not needed. >>> >>> Signed-off-by: Thomas Zimmermann >>> --- >>> drivers/gpu/drm/i915/i915_drv.c | 3 +- >>> drivers/gpu/drm/i915/i915_irq.c | 117 ++-- >>> drivers/gpu/drm/i915/i915_irq.h | 9 +-- >>> 3 files changed, 119 insertions(+), 10 deletions(-) >> >> Not really enthusiastic about the diffstat in a "cleanup" series. > > Well, the cleanup is about the content of drm_driver :) > >> >> I wonder if you could add a generic helper version of >> drm_calc_vbltimestamp_from_scanoutpos where you pass the >> get_scanout_position function as a parameter. Both >> drm_calc_vbltimestamp_from_scanoutpos and the new >> i915_calc_vbltimestamp_from_scanoutpos would then be fairly thin >> wrappers passing in the relevant get_scanout_position function. > > Of course. Will be in v2 of the series. Please give Ville (Cc'd) a moment before sending v2 in case he wants to chime in on this. Thanks, Jani. > > Best regards > Thomas > >> >> This would reduce the almost identical duplication of the function in >> i915. >> >> BR, >> Jani. >> >>> >>> diff --git a/drivers/gpu/drm/i915/i915_drv.c >>> b/drivers/gpu/drm/i915/i915_drv.c >>> index f7385abdd74b..4a0a7fb85c53 100644 >>> --- a/drivers/gpu/drm/i915/i915_drv.c >>> +++ b/drivers/gpu/drm/i915/i915_drv.c >>> @@ -2769,8 +2769,7 @@ static struct drm_driver driver = { >>> .gem_prime_export = i915_gem_prime_export, >>> .gem_prime_import = i915_gem_prime_import, >>> >>> - .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, >>> - .get_scanout_position = i915_get_crtc_scanoutpos, >>> + .get_vblank_timestamp = i915_calc_vbltimestamp_from_scanoutpos, >>> >>> .dumb_create = i915_gem_dumb_create, >>> .dumb_map_offset = i915_gem_dumb_mmap_offset, >>> diff --git a/drivers/gpu/drm/i915/i915_irq.c >>> b/drivers/gpu/drm/i915/i915_irq.c >>> index afc6aad9bf8c..99d0c3b0feae 100644 >>> --- a/drivers/gpu/drm/i915/i915_irq.c >>> +++ b/drivers/gpu/drm/i915/i915_irq.c >>> @@ -52,6 +52,11 @@ >>> #include "i915_trace.h" >>> #include "intel_pm.h" >>> >>> +/* Retry timestamp calculation up to 3 times to satisfy >>> + * drm_timestamp_precision before giving up. >>> + */ >>> +#define I915_TIMESTAMP_MAXRETRIES 3 >>> + >>> /** >>> * DOC: interrupt handling >>> * >>> @@ -762,10 +767,11 @@ static int __intel_get_crtc_scanline(struct >>> intel_crtc *crtc) >>> return (position + crtc->scanline_offset) % vtotal; >>> } >>> >>> -bool i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int index, >>> - bool in_vblank_irq, int *vpos, int *hpos, >>> - ktime_t *stime, ktime_t *etime, >>> - const struct drm_display_mode *mode) >>> +static bool i915_get_crtc_scanoutpos(struct drm_device *dev, >>> +unsigned int index, bool in_vblank_irq, >>> +int *vpos, int *hpos, >>> +ktime_t *stime, ktime_t *etime, >>> +const struct drm_display_mode *mode) >>> { >>> struct drm_i915_private *dev_priv = to_i915(dev); >>> struct intel_crtc *crtc = to_intel_crtc(drm_crtc_from_index(dev, >>> index)); >>> @@ -879,6 +885,109 @@ bool i915_get_crtc_scanoutpos(struct drm_device *dev, >>> unsigned int index, >>> return true; >>> } >>> >>> +bool i915_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, >>> + unsigned int pipe, >>> + int *max_error, >>> + ktime_t *vblank_time, >>> + bool in_vblank_irq) >>> +{ >>> + struct timespec64 ts_etime, ts_vblank_time; >>> + ktime_t stime, etime; >>> + bool vbl_status; >>> + struct drm_crtc *crtc; >>> + const struct drm_display_mode *mode; >>> + struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; >>> + int vpos, hpos, i; >>> + int delta_ns, duration_ns; >>> + >>> + crtc = drm_crtc_from_index(dev, pipe); >>> + >>> + if (pipe >= dev->num_crtcs || !crtc) { >>> + DRM_ERROR("Invalid crtc %u\n", pipe); >>> + return false; >>> + } >>> + >>> + if (drm_drv_uses_atomic_modeset(dev)) >>> + mode = &vblank->hwmode; >>> + else >>> + mode = &crtc->hwmode; >>> + >>> + /* If mode timing undefined, just return as no-op: >>> +* Happens during initial modesetting of a crtc. >>> +*/ >>> + if (mode->crtc_clock == 0) { >>> + DRM_DE
Re: [PATCH 18/23] drm/sti: Convert to CRTC VBLANK callbacks
Le ven. 10 janv. 2020 à 10:21, Thomas Zimmermann a écrit : > > VBLANK callbacks in struct drm_driver are deprecated in favor of > their equivalents in struct drm_crtc_funcs. Convert sti over. > Hi Thomas, Since you remove the last calls to sti_crtc functions from sti_drv.c I think that the include could also be removed. Anyway that looks for me: Acked-by: Benjamin Gaignard Thanks, Benjamin > Signed-off-by: Thomas Zimmermann > --- > drivers/gpu/drm/sti/sti_crtc.c | 11 --- > drivers/gpu/drm/sti/sti_crtc.h | 2 -- > drivers/gpu/drm/sti/sti_drv.c | 3 --- > 3 files changed, 8 insertions(+), 8 deletions(-) > > diff --git a/drivers/gpu/drm/sti/sti_crtc.c b/drivers/gpu/drm/sti/sti_crtc.c > index dc64fbfc4e61..49e6cb8f5836 100644 > --- a/drivers/gpu/drm/sti/sti_crtc.c > +++ b/drivers/gpu/drm/sti/sti_crtc.c > @@ -279,12 +279,13 @@ int sti_crtc_vblank_cb(struct notifier_block *nb, > return 0; > } > > -int sti_crtc_enable_vblank(struct drm_device *dev, unsigned int pipe) > +static int sti_crtc_enable_vblank(struct drm_crtc *crtc) > { > + struct drm_device *dev = crtc->dev; > + unsigned int pipe = crtc->index; > struct sti_private *dev_priv = dev->dev_private; > struct sti_compositor *compo = dev_priv->compo; > struct notifier_block *vtg_vblank_nb = &compo->vtg_vblank_nb[pipe]; > - struct drm_crtc *crtc = &compo->mixer[pipe]->drm_crtc; > struct sti_vtg *vtg = compo->vtg[pipe]; > > DRM_DEBUG_DRIVER("\n"); > @@ -297,8 +298,10 @@ int sti_crtc_enable_vblank(struct drm_device *dev, > unsigned int pipe) > return 0; > } > > -void sti_crtc_disable_vblank(struct drm_device *drm_dev, unsigned int pipe) > +static void sti_crtc_disable_vblank(struct drm_crtc *crtc) > { > + struct drm_device *drm_dev = crtc->dev; > + unsigned int pipe = crtc->index; > struct sti_private *priv = drm_dev->dev_private; > struct sti_compositor *compo = priv->compo; > struct notifier_block *vtg_vblank_nb = &compo->vtg_vblank_nb[pipe]; > @@ -330,6 +333,8 @@ static const struct drm_crtc_funcs sti_crtc_funcs = { > .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, > .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, > .late_register = sti_crtc_late_register, > + .enable_vblank = sti_crtc_enable_vblank, > + .disable_vblank = sti_crtc_disable_vblank, > }; > > bool sti_crtc_is_main(struct drm_crtc *crtc) > diff --git a/drivers/gpu/drm/sti/sti_crtc.h b/drivers/gpu/drm/sti/sti_crtc.h > index df489ab14e2b..1132b4586712 100644 > --- a/drivers/gpu/drm/sti/sti_crtc.h > +++ b/drivers/gpu/drm/sti/sti_crtc.h > @@ -15,8 +15,6 @@ struct sti_mixer; > > int sti_crtc_init(struct drm_device *drm_dev, struct sti_mixer *mixer, > struct drm_plane *primary, struct drm_plane *cursor); > -int sti_crtc_enable_vblank(struct drm_device *dev, unsigned int pipe); > -void sti_crtc_disable_vblank(struct drm_device *dev, unsigned int pipe); > int sti_crtc_vblank_cb(struct notifier_block *nb, >unsigned long event, void *data); > bool sti_crtc_is_main(struct drm_crtc *drm_crtc); > diff --git a/drivers/gpu/drm/sti/sti_drv.c b/drivers/gpu/drm/sti/sti_drv.c > index a39fc36f815b..8e30001bf545 100644 > --- a/drivers/gpu/drm/sti/sti_drv.c > +++ b/drivers/gpu/drm/sti/sti_drv.c > @@ -146,9 +146,6 @@ static struct drm_driver sti_driver = { > .dumb_create = drm_gem_cma_dumb_create, > .fops = &sti_driver_fops, > > - .enable_vblank = sti_crtc_enable_vblank, > - .disable_vblank = sti_crtc_disable_vblank, > - > .prime_handle_to_fd = drm_gem_prime_handle_to_fd, > .prime_fd_to_handle = drm_gem_prime_fd_to_handle, > .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table, > -- > 2.24.1 > ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 03/23] drm/i915: Don't use struct drm_driver.get_scanout_position()
Hi Am 10.01.20 um 12:59 schrieb Jani Nikula: > On Fri, 10 Jan 2020, Thomas Zimmermann wrote: >> The callback struct drm_driver.get_scanout_position() is deprecated in >> favor of struct drm_crtc_helper_funcs.get_scanout_position(). >> >> i915 doesn't use CRTC helpers. The patch duplicates the caller >> drm_calc_vbltimestamp_from_scanoutpos() for i915, such that the callback >> function is not needed. >> >> Signed-off-by: Thomas Zimmermann >> --- >> drivers/gpu/drm/i915/i915_drv.c | 3 +- >> drivers/gpu/drm/i915/i915_irq.c | 117 ++-- >> drivers/gpu/drm/i915/i915_irq.h | 9 +-- >> 3 files changed, 119 insertions(+), 10 deletions(-) > > Not really enthusiastic about the diffstat in a "cleanup" series. Well, the cleanup is about the content of drm_driver :) > > I wonder if you could add a generic helper version of > drm_calc_vbltimestamp_from_scanoutpos where you pass the > get_scanout_position function as a parameter. Both > drm_calc_vbltimestamp_from_scanoutpos and the new > i915_calc_vbltimestamp_from_scanoutpos would then be fairly thin > wrappers passing in the relevant get_scanout_position function. Of course. Will be in v2 of the series. Best regards Thomas > > This would reduce the almost identical duplication of the function in > i915. > > BR, > Jani. > >> >> diff --git a/drivers/gpu/drm/i915/i915_drv.c >> b/drivers/gpu/drm/i915/i915_drv.c >> index f7385abdd74b..4a0a7fb85c53 100644 >> --- a/drivers/gpu/drm/i915/i915_drv.c >> +++ b/drivers/gpu/drm/i915/i915_drv.c >> @@ -2769,8 +2769,7 @@ static struct drm_driver driver = { >> .gem_prime_export = i915_gem_prime_export, >> .gem_prime_import = i915_gem_prime_import, >> >> -.get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, >> -.get_scanout_position = i915_get_crtc_scanoutpos, >> +.get_vblank_timestamp = i915_calc_vbltimestamp_from_scanoutpos, >> >> .dumb_create = i915_gem_dumb_create, >> .dumb_map_offset = i915_gem_dumb_mmap_offset, >> diff --git a/drivers/gpu/drm/i915/i915_irq.c >> b/drivers/gpu/drm/i915/i915_irq.c >> index afc6aad9bf8c..99d0c3b0feae 100644 >> --- a/drivers/gpu/drm/i915/i915_irq.c >> +++ b/drivers/gpu/drm/i915/i915_irq.c >> @@ -52,6 +52,11 @@ >> #include "i915_trace.h" >> #include "intel_pm.h" >> >> +/* Retry timestamp calculation up to 3 times to satisfy >> + * drm_timestamp_precision before giving up. >> + */ >> +#define I915_TIMESTAMP_MAXRETRIES 3 >> + >> /** >> * DOC: interrupt handling >> * >> @@ -762,10 +767,11 @@ static int __intel_get_crtc_scanline(struct intel_crtc >> *crtc) >> return (position + crtc->scanline_offset) % vtotal; >> } >> >> -bool i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int index, >> - bool in_vblank_irq, int *vpos, int *hpos, >> - ktime_t *stime, ktime_t *etime, >> - const struct drm_display_mode *mode) >> +static bool i915_get_crtc_scanoutpos(struct drm_device *dev, >> + unsigned int index, bool in_vblank_irq, >> + int *vpos, int *hpos, >> + ktime_t *stime, ktime_t *etime, >> + const struct drm_display_mode *mode) >> { >> struct drm_i915_private *dev_priv = to_i915(dev); >> struct intel_crtc *crtc = to_intel_crtc(drm_crtc_from_index(dev, >> index)); >> @@ -879,6 +885,109 @@ bool i915_get_crtc_scanoutpos(struct drm_device *dev, >> unsigned int index, >> return true; >> } >> >> +bool i915_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, >> +unsigned int pipe, >> +int *max_error, >> +ktime_t *vblank_time, >> +bool in_vblank_irq) >> +{ >> +struct timespec64 ts_etime, ts_vblank_time; >> +ktime_t stime, etime; >> +bool vbl_status; >> +struct drm_crtc *crtc; >> +const struct drm_display_mode *mode; >> +struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; >> +int vpos, hpos, i; >> +int delta_ns, duration_ns; >> + >> +crtc = drm_crtc_from_index(dev, pipe); >> + >> +if (pipe >= dev->num_crtcs || !crtc) { >> +DRM_ERROR("Invalid crtc %u\n", pipe); >> +return false; >> +} >> + >> +if (drm_drv_uses_atomic_modeset(dev)) >> +mode = &vblank->hwmode; >> +else >> +mode = &crtc->hwmode; >> + >> +/* If mode timing undefined, just return as no-op: >> + * Happens during initial modesetting of a crtc. >> + */ >> +if (mode->crtc_clock == 0) { >> +DRM_DEBUG("crtc %u: Noop due to uninitialized mode.\n", pipe); >> +WARN_ON_ONCE(drm_drv_uses_atomic_modeset(dev)); >> + >> +return false; >> +} >> + >> +/* Get current scanout position with system timestamp. >> + * Re
Re: [PATCH 03/23] drm/i915: Don't use struct drm_driver.get_scanout_position()
On Fri, 10 Jan 2020, Thomas Zimmermann wrote: > The callback struct drm_driver.get_scanout_position() is deprecated in > favor of struct drm_crtc_helper_funcs.get_scanout_position(). > > i915 doesn't use CRTC helpers. The patch duplicates the caller > drm_calc_vbltimestamp_from_scanoutpos() for i915, such that the callback > function is not needed. > > Signed-off-by: Thomas Zimmermann > --- > drivers/gpu/drm/i915/i915_drv.c | 3 +- > drivers/gpu/drm/i915/i915_irq.c | 117 ++-- > drivers/gpu/drm/i915/i915_irq.h | 9 +-- > 3 files changed, 119 insertions(+), 10 deletions(-) Not really enthusiastic about the diffstat in a "cleanup" series. I wonder if you could add a generic helper version of drm_calc_vbltimestamp_from_scanoutpos where you pass the get_scanout_position function as a parameter. Both drm_calc_vbltimestamp_from_scanoutpos and the new i915_calc_vbltimestamp_from_scanoutpos would then be fairly thin wrappers passing in the relevant get_scanout_position function. This would reduce the almost identical duplication of the function in i915. BR, Jani. > > diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c > index f7385abdd74b..4a0a7fb85c53 100644 > --- a/drivers/gpu/drm/i915/i915_drv.c > +++ b/drivers/gpu/drm/i915/i915_drv.c > @@ -2769,8 +2769,7 @@ static struct drm_driver driver = { > .gem_prime_export = i915_gem_prime_export, > .gem_prime_import = i915_gem_prime_import, > > - .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, > - .get_scanout_position = i915_get_crtc_scanoutpos, > + .get_vblank_timestamp = i915_calc_vbltimestamp_from_scanoutpos, > > .dumb_create = i915_gem_dumb_create, > .dumb_map_offset = i915_gem_dumb_mmap_offset, > diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c > index afc6aad9bf8c..99d0c3b0feae 100644 > --- a/drivers/gpu/drm/i915/i915_irq.c > +++ b/drivers/gpu/drm/i915/i915_irq.c > @@ -52,6 +52,11 @@ > #include "i915_trace.h" > #include "intel_pm.h" > > +/* Retry timestamp calculation up to 3 times to satisfy > + * drm_timestamp_precision before giving up. > + */ > +#define I915_TIMESTAMP_MAXRETRIES 3 > + > /** > * DOC: interrupt handling > * > @@ -762,10 +767,11 @@ static int __intel_get_crtc_scanline(struct intel_crtc > *crtc) > return (position + crtc->scanline_offset) % vtotal; > } > > -bool i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int index, > - bool in_vblank_irq, int *vpos, int *hpos, > - ktime_t *stime, ktime_t *etime, > - const struct drm_display_mode *mode) > +static bool i915_get_crtc_scanoutpos(struct drm_device *dev, > + unsigned int index, bool in_vblank_irq, > + int *vpos, int *hpos, > + ktime_t *stime, ktime_t *etime, > + const struct drm_display_mode *mode) > { > struct drm_i915_private *dev_priv = to_i915(dev); > struct intel_crtc *crtc = to_intel_crtc(drm_crtc_from_index(dev, > index)); > @@ -879,6 +885,109 @@ bool i915_get_crtc_scanoutpos(struct drm_device *dev, > unsigned int index, > return true; > } > > +bool i915_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, > + unsigned int pipe, > + int *max_error, > + ktime_t *vblank_time, > + bool in_vblank_irq) > +{ > + struct timespec64 ts_etime, ts_vblank_time; > + ktime_t stime, etime; > + bool vbl_status; > + struct drm_crtc *crtc; > + const struct drm_display_mode *mode; > + struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; > + int vpos, hpos, i; > + int delta_ns, duration_ns; > + > + crtc = drm_crtc_from_index(dev, pipe); > + > + if (pipe >= dev->num_crtcs || !crtc) { > + DRM_ERROR("Invalid crtc %u\n", pipe); > + return false; > + } > + > + if (drm_drv_uses_atomic_modeset(dev)) > + mode = &vblank->hwmode; > + else > + mode = &crtc->hwmode; > + > + /* If mode timing undefined, just return as no-op: > + * Happens during initial modesetting of a crtc. > + */ > + if (mode->crtc_clock == 0) { > + DRM_DEBUG("crtc %u: Noop due to uninitialized mode.\n", pipe); > + WARN_ON_ONCE(drm_drv_uses_atomic_modeset(dev)); > + > + return false; > + } > + > + /* Get current scanout position with system timestamp. > + * Repeat query up to DRM_TIMESTAMP_MAXRETRIES times > + * if single query takes longer than max_error nanoseconds. > + * > + * This guarantees a tight bound on maximum error if > + * code gets preempted or delayed for some reason. > + */ > +
Re: [PATCH] drm/amdgpu: fix modprobe failure of the secondary GPU when GDDR6 training enabled(V4)
Am 10.01.20 um 06:30 schrieb Tianci Yin: From: "Tianci.Yin" [why] In dual GPUs scenario, stolen_size is assigned to zero on the secondary GPU, since there is no pre-OS console using that memory. Then the bottom region of VRAM was allocated as GTT, unfortunately a small region of bottom VRAM was encroached by UMC firmware during GDDR6 BIST training, this cause page fault. [how] Forcing stolen_size to 3MB, then the bottom region of VRAM was allocated as stolen memory, GTT corruption avoid. Change-Id: I310a72ba0402994defbe50839842a8edb025a868 Signed-off-by: Tianci.Yin Reviewed-by: Christian König --- drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h | 5 + drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c | 27 - 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h index c91dd602d5f1..e4b2f9bcaeb7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h @@ -60,6 +60,11 @@ */ #define AMDGPU_GMC_FAULT_TIMEOUT 5000ULL +/* + * Default stolen memory size, 1024 * 768 * 4 + */ +#define AMDGPU_STOLEN_VGA_DEFAULT_SIZE 0x30ULL + struct firmware; /* diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c index 5ad89bb6f3ba..14961f1ebfab 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c @@ -566,7 +566,12 @@ static int gmc_v10_0_late_init(void *handle) struct amdgpu_device *adev = (struct amdgpu_device *)handle; int r; - amdgpu_bo_late_init(adev); + /* +* Can't free the stolen VGA memory when it might be used for memory +* training again. +*/ + if (!adev->fw_vram_usage.mem_train_support) + amdgpu_bo_late_init(adev); r = amdgpu_gmc_allocate_vm_inv_eng(adev); if (r) @@ -750,6 +755,19 @@ static int gmc_v10_0_sw_init(void *handle) adev->gmc.stolen_size = gmc_v10_0_get_vbios_fb_size(adev); + /* +* In dual GPUs scenario, stolen_size is assigned to zero on the +* secondary GPU, since there is no pre-OS console using that memory. +* Then the bottom region of VRAM was allocated as GTT, unfortunately a +* small region of bottom VRAM was encroached by UMC firmware during +* GDDR6 BIST training, this cause page fault. +* The page fault can be fixed by forcing stolen_size to 3MB, then the +* bottom region of VRAM was allocated as stolen memory, GTT corruption +* avoid. +*/ + adev->gmc.stolen_size = max(adev->gmc.stolen_size, + AMDGPU_STOLEN_VGA_DEFAULT_SIZE); + /* Memory manager */ r = amdgpu_bo_init(adev); if (r) @@ -789,6 +807,13 @@ static void gmc_v10_0_gart_fini(struct amdgpu_device *adev) static int gmc_v10_0_sw_fini(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; + void *stolen_vga_buf; + + /* +* Free the stolen memory if it wasn't already freed in late_init +* because of memory training. +*/ + amdgpu_bo_free_kernel(&adev->stolen_vga_memory, NULL, &stolen_vga_buf); amdgpu_vm_manager_fini(adev); gmc_v10_0_gart_fini(adev); ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 1/8] drm/amdgpu: Avoid reclaim fs while eviction lock
Looks like you send that patch set out twice. Which one is the most recent one? Regards, Christian. Am 10.01.20 um 01:43 schrieb Alex Sierra: [Why] Avoid reclaim filesystem while eviction lock is held called from MMU notifier. [How] Setting PF_MEMALLOC_NOFS flags while eviction mutex is locked. Using memalloc_nofs_save / memalloc_nofs_restore API. Change-Id: I5531c9337836e7d4a430df3f16dcc82888e8018c Signed-off-by: Alex Sierra --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 40 +- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h | 6 +++- 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index b999b67ff57a..d6aba4f9df74 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -82,6 +82,32 @@ struct amdgpu_prt_cb { struct dma_fence_cb cb; }; +/** + * vm eviction_lock can be taken in MMU notifiers. Make sure no reclaim-FS + * happens while holding this lock anywhere to prevent deadlocks when + * an MMU notifier runs in reclaim-FS context. + */ +static inline void amdgpu_vm_eviction_lock(struct amdgpu_vm *vm) +{ + mutex_lock(&vm->eviction_lock); + vm->saved_flags = memalloc_nofs_save(); +} + +static inline int amdgpu_vm_eviction_trylock(struct amdgpu_vm *vm) +{ + if (mutex_trylock(&vm->eviction_lock)) { + vm->saved_flags = memalloc_nofs_save(); + return 1; + } + return 0; +} + +static inline void amdgpu_vm_eviction_unlock(struct amdgpu_vm *vm) +{ + memalloc_nofs_restore(vm->saved_flags); + mutex_unlock(&vm->eviction_lock); +} + /** * amdgpu_vm_level_shift - return the addr shift for each level * @@ -678,9 +704,9 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm, } } - mutex_lock(&vm->eviction_lock); + amdgpu_vm_eviction_lock(vm); vm->evicting = false; - mutex_unlock(&vm->eviction_lock); + amdgpu_vm_eviction_unlock(vm); return 0; } @@ -1559,7 +1585,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, if (!(flags & AMDGPU_PTE_VALID)) owner = AMDGPU_FENCE_OWNER_KFD; - mutex_lock(&vm->eviction_lock); + amdgpu_vm_eviction_lock(vm); if (vm->evicting) { r = -EBUSY; goto error_unlock; @@ -1576,7 +1602,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, r = vm->update_funcs->commit(¶ms, fence); error_unlock: - mutex_unlock(&vm->eviction_lock); + amdgpu_vm_eviction_unlock(vm); return r; } @@ -2537,18 +2563,18 @@ bool amdgpu_vm_evictable(struct amdgpu_bo *bo) return false; /* Try to block ongoing updates */ - if (!mutex_trylock(&bo_base->vm->eviction_lock)) + if (!amdgpu_vm_eviction_trylock(bo_base->vm)) return false; /* Don't evict VM page tables while they are updated */ if (!dma_fence_is_signaled(bo_base->vm->last_direct) || !dma_fence_is_signaled(bo_base->vm->last_delayed)) { - mutex_unlock(&bo_base->vm->eviction_lock); + amdgpu_vm_eviction_unlock(bo_base->vm); return false; } bo_base->vm->evicting = true; - mutex_unlock(&bo_base->vm->eviction_lock); + amdgpu_vm_eviction_unlock(bo_base->vm); return true; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h index 100547f094ff..c21a36bebc0c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h @@ -30,6 +30,7 @@ #include #include #include +#include #include "amdgpu_sync.h" #include "amdgpu_ring.h" @@ -242,9 +243,12 @@ struct amdgpu_vm { /* tree of virtual addresses mapped */ struct rb_root_cached va; - /* Lock to prevent eviction while we are updating page tables */ + /* Lock to prevent eviction while we are updating page tables +* use vm_eviction_lock/unlock(vm) +*/ struct mutexeviction_lock; boolevicting; + unsigned intsaved_flags; /* BOs who needs a validation */ struct list_headevicted; ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 7/7] drm/amdgpu: tlbs invalidate replaced by kiq_pm4_funcs
The end result looks good, but you should consider re-ordering this patch set. That would clean things up and make review much easier. Adding code first and then removing it later on in the same patch set is not a good practice. Regards, Christian. Am 10.01.20 um 01:04 schrieb Alex Sierra: TLBs invalidation was removed from gmc_v9 and gmc_v10 files. This implementation has been moved to kiq_pm4_funcs calls. Change-Id: I66463e2e5fdf7611ef4a802eb517ae0d269987c3 Signed-off-by: Alex Sierra --- drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c | 32 ++ drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 32 ++ 2 files changed, 4 insertions(+), 60 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c index 8cf34c7bd416..09408b8b390f 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c @@ -250,35 +250,6 @@ static bool gmc_v10_0_get_atc_vmid_pasid_mapping_info( return !!(value & ATC_VMID0_PASID_MAPPING__VALID_MASK); } -static int gmc_v10_0_invalidate_tlbs_with_kiq(struct amdgpu_device *adev, - uint16_t pasid, uint32_t flush_type, - bool all_hub) -{ - signed long r; - uint32_t seq; - struct amdgpu_ring *ring = &adev->gfx.kiq.ring; - - spin_lock(&adev->gfx.kiq.ring_lock); - amdgpu_ring_alloc(ring, 12); /* fence + invalidate_tlbs package*/ - amdgpu_ring_write(ring, PACKET3(PACKET3_INVALIDATE_TLBS, 0)); - amdgpu_ring_write(ring, - PACKET3_INVALIDATE_TLBS_DST_SEL(1) | - PACKET3_INVALIDATE_TLBS_ALL_HUB(all_hub) | - PACKET3_INVALIDATE_TLBS_PASID(pasid) | - PACKET3_INVALIDATE_TLBS_FLUSH_TYPE(flush_type)); - amdgpu_fence_emit_polling(ring, &seq); - amdgpu_ring_commit(ring); - spin_unlock(&adev->gfx.kiq.ring_lock); - - r = amdgpu_fence_wait_polling(ring, seq, adev->usec_timeout); - if (r < 1) { - DRM_ERROR("wait for kiq fence error: %ld.\n", r); - return -ETIME; - } - - return 0; -} - /* * GART * VMID 0 is the physical GPU addresses as used by the kernel. @@ -441,9 +412,10 @@ static int gmc_v10_0_flush_gpu_tlb_pasid(struct amdgpu_device *adev, uint16_t queried_pasid; bool ret; struct amdgpu_ring *ring = &adev->gfx.kiq.ring; + struct amdgpu_kiq *kiq = &adev->gfx.kiq; if (amdgpu_emu_mode == 0 && ring->sched.ready) - return gmc_v10_0_invalidate_tlbs_with_kiq(adev, + return kiq->pmf->kiq_invalidate_tlbs(ring, pasid, flush_type, all_hub); for (vmid = 1; vmid < 16; vmid++) { diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index 7cc6f305bfa8..670b2b62789b 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c @@ -455,35 +455,6 @@ static bool gmc_v9_0_get_atc_vmid_pasid_mapping_info(struct amdgpu_device *adev, return !!(value & ATC_VMID0_PASID_MAPPING__VALID_MASK); } -static int gmc_v9_0_invalidate_tlbs_with_kiq(struct amdgpu_device *adev, - uint16_t pasid, uint32_t flush_type, - bool all_hub) -{ - signed long r; - uint32_t seq; - struct amdgpu_ring *ring = &adev->gfx.kiq.ring; - - spin_lock(&adev->gfx.kiq.ring_lock); - amdgpu_ring_alloc(ring, 12); /* fence + invalidate_tlbs package*/ - amdgpu_ring_write(ring, PACKET3(PACKET3_INVALIDATE_TLBS, 0)); - amdgpu_ring_write(ring, - PACKET3_INVALIDATE_TLBS_DST_SEL(1) | - PACKET3_INVALIDATE_TLBS_ALL_HUB(all_hub) | - PACKET3_INVALIDATE_TLBS_PASID(pasid) | - PACKET3_INVALIDATE_TLBS_FLUSH_TYPE(flush_type)); - amdgpu_fence_emit_polling(ring, &seq); - amdgpu_ring_commit(ring); - spin_unlock(&adev->gfx.kiq.ring_lock); - - r = amdgpu_fence_wait_polling(ring, seq, adev->usec_timeout); - if (r < 1) { - DRM_ERROR("wait for kiq fence error: %ld.\n", r); - return -ETIME; - } - - return 0; -} - /* * GART * VMID 0 is the physical GPU addresses as used by the kernel. @@ -598,12 +569,13 @@ static int gmc_v9_0_flush_gpu_tlb_pasid(struct amdgpu_device *adev, uint16_t queried_pasid; bool ret; struct amdgpu_ring *ring = &adev->gfx.kiq.ring; + struct amdgpu_kiq *kiq = &adev->gfx.kiq; if (adev->in_gpu_reset) return -EIO; if (ring->sched.ready) - return gmc_v9_0_invalidate_tlbs_with_kiq(adev, + return kiq->pmf->kiq_invalidate_tlbs(ring, pasid, flush_type, all_hub);
Re: [PATCH 01/23] drm: Add get_scanout_position() to struct drm_crtc_helper_funcs
On Fri, 10 Jan 2020, Thomas Zimmermann wrote: > The new callback get_scanout_position() reads the current location of > the scanout process. The operation is currentyl located in struct > drm_driver, but really belongs to the CRTC. Drivers will be converted > in separate patches. > > Signed-off-by: Thomas Zimmermann > --- > drivers/gpu/drm/drm_vblank.c | 24 > include/drm/drm_drv.h| 7 +--- > include/drm/drm_modeset_helper_vtables.h | 47 > 3 files changed, 65 insertions(+), 13 deletions(-) > > diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c > index 1659b13b178c..c12f0b333e14 100644 > --- a/drivers/gpu/drm/drm_vblank.c > +++ b/drivers/gpu/drm/drm_vblank.c > @@ -30,6 +30,7 @@ > #include > #include > #include > +#include > #include > #include > > @@ -590,7 +591,7 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants); > * Implements calculation of exact vblank timestamps from given > drm_display_mode > * timings and current video scanout position of a CRTC. This can be directly > * used as the &drm_driver.get_vblank_timestamp implementation of a kms > driver > - * if &drm_driver.get_scanout_position is implemented. > + * if &drm_crtc_helper_funcs.get_scanout_position is implemented. > * > * The current implementation only handles standard video modes. For double > scan > * and interlaced modes the driver is supposed to adjust the hardware mode > @@ -632,8 +633,9 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct > drm_device *dev, > } > > /* Scanout position query not supported? Should not happen. */ > - if (!dev->driver->get_scanout_position) { > - DRM_ERROR("Called from driver w/o get_scanout_position()!?\n"); > + if (!dev->driver->get_scanout_position || > + !crtc->helper_private->get_scanout_position) { ITYM s/||/&&/ BR, Jani. > + DRM_ERROR("Called from CRTC w/o get_scanout_position()!?\n"); > return false; > } > > @@ -664,11 +666,17 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct > drm_device *dev, >* Get vertical and horizontal scanout position vpos, hpos, >* and bounding timestamps stime, etime, pre/post query. >*/ > - vbl_status = dev->driver->get_scanout_position(dev, pipe, > -in_vblank_irq, > -&vpos, &hpos, > -&stime, &etime, > -mode); > + if (crtc->helper_private->get_scanout_position) { > + vbl_status = > + crtc->helper_private->get_scanout_position( > + crtc, in_vblank_irq, &vpos, &hpos, > + &stime, &etime, mode); > + } else { > + vbl_status = > + dev->driver->get_scanout_position( > + dev, pipe, in_vblank_irq, &vpos, > + &hpos, &stime, &etime, mode); > + } > > /* Return as no-op if scanout query unsupported or failed. */ > if (!vbl_status) { > diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h > index cf13470810a5..d0049e5786fc 100644 > --- a/include/drm/drm_drv.h > +++ b/include/drm/drm_drv.h > @@ -362,11 +362,8 @@ struct drm_driver { >* True on success, false if a reliable scanout position counter could >* not be read out. >* > - * FIXME: > - * > - * Since this is a helper to implement @get_vblank_timestamp, we should > - * move it to &struct drm_crtc_helper_funcs, like all the other > - * helper-internal hooks. > + * This is deprecated and should not be used by new drivers. > + * Use &drm_crtc_helper_funcs.get_scanout_position instead. >*/ > bool (*get_scanout_position) (struct drm_device *dev, unsigned int pipe, > bool in_vblank_irq, int *vpos, int *hpos, > diff --git a/include/drm/drm_modeset_helper_vtables.h > b/include/drm/drm_modeset_helper_vtables.h > index 5a87f1bd7a3f..e398512bfd5f 100644 > --- a/include/drm/drm_modeset_helper_vtables.h > +++ b/include/drm/drm_modeset_helper_vtables.h > @@ -450,6 +450,53 @@ struct drm_crtc_helper_funcs { >*/ > void (*atomic_disable)(struct drm_crtc *crtc, > struct drm_crtc_state *old_crtc_state); > + > + /** > + * @get_scanout_position: > + * > + * Called by vblank timestamping code. > + * > + * Returns the current display scanout position from a CRTC and an > + * optional accurate ktime_get() timestamp of when the position was > + * measured. Note that
[PATCH 17/23] drm/radeon: Convert to CRTC VBLANK callbacks
VBLANK callbacks in struct drm_driver are deprecated in favor of their equivalents in struct drm_crtc_funcs. Convert radeon over. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/radeon/radeon_display.c | 12 -- drivers/gpu/drm/radeon/radeon_drv.c | 7 -- drivers/gpu/drm/radeon/radeon_kms.c | 29 ++--- 3 files changed, 26 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 7187158b9963..9116975b6eb9 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -45,6 +45,10 @@ #include "atom.h" #include "radeon.h" +u32 radeon_get_vblank_counter_kms(struct drm_crtc *crtc); +int radeon_enable_vblank_kms(struct drm_crtc *crtc); +void radeon_disable_vblank_kms(struct drm_crtc *crtc); + static void avivo_crtc_load_lut(struct drm_crtc *crtc) { struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); @@ -458,7 +462,7 @@ static void radeon_flip_work_func(struct work_struct *__work) (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_IN_VBLANK) && (!ASIC_IS_AVIVO(rdev) || ((int) (work->target_vblank - - dev->driver->get_vblank_counter(dev, work->crtc_id)) > 0))) + crtc->funcs->get_vblank_counter(crtc)) > 0))) usleep_range(1000, 2000); /* We borrow the event spin lock for protecting flip_status */ @@ -574,7 +578,7 @@ static int radeon_crtc_page_flip_target(struct drm_crtc *crtc, } work->base = base; work->target_vblank = target - (uint32_t)drm_crtc_vblank_count(crtc) + - dev->driver->get_vblank_counter(dev, work->crtc_id); + crtc->funcs->get_vblank_counter(crtc); /* We borrow the event spin lock for protecting flip_work */ spin_lock_irqsave(&crtc->dev->event_lock, flags); @@ -666,6 +670,10 @@ static const struct drm_crtc_funcs radeon_crtc_funcs = { .set_config = radeon_crtc_set_config, .destroy = radeon_crtc_destroy, .page_flip_target = radeon_crtc_page_flip_target, + .get_vblank_counter = radeon_get_vblank_counter_kms, + .enable_vblank = radeon_enable_vblank_kms, + .disable_vblank = radeon_disable_vblank_kms, + .get_vblank_timestamp = drm_crtc_calc_vbltimestamp_from_scanoutpos, }; static void radeon_crtc_init(struct drm_device *dev, int index) diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 1f597f166bff..49ce2e7d5f9e 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -119,9 +119,6 @@ void radeon_driver_postclose_kms(struct drm_device *dev, int radeon_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon, bool freeze); int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon); -u32 radeon_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); -int radeon_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); -void radeon_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); void radeon_driver_irq_preinstall_kms(struct drm_device *dev); int radeon_driver_irq_postinstall_kms(struct drm_device *dev); void radeon_driver_irq_uninstall_kms(struct drm_device *dev); @@ -571,10 +568,6 @@ static struct drm_driver kms_driver = { .postclose = radeon_driver_postclose_kms, .lastclose = radeon_driver_lastclose_kms, .unload = radeon_driver_unload_kms, - .get_vblank_counter = radeon_get_vblank_counter_kms, - .enable_vblank = radeon_enable_vblank_kms, - .disable_vblank = radeon_disable_vblank_kms, - .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, .irq_preinstall = radeon_driver_irq_preinstall_kms, .irq_postinstall = radeon_driver_irq_postinstall_kms, .irq_uninstall = radeon_driver_irq_uninstall_kms, diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index d24f23a81656..cab891f86dc0 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -739,14 +739,15 @@ void radeon_driver_postclose_kms(struct drm_device *dev, /** * radeon_get_vblank_counter_kms - get frame count * - * @dev: drm dev pointer - * @pipe: crtc to get the frame count from + * @crtc: crtc to get the frame count from * * Gets the frame count on the requested crtc (all asics). * Returns frame count on success, -EINVAL on failure. */ -u32 radeon_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe) +u32 radeon_get_vblank_counter_kms(struct drm_crtc *crtc) { + struct drm_device *dev = crtc->dev; + unsigned int pipe = crtc->index; int vpos, hpos, stat; u32 count; struct radeon_device *rdev = dev->dev_private; @@ -808,25 +809,26 @@ u32 radeon_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe)
[PATCH 19/23] drm/stm: Convert to CRTC VBLANK callbacks
VBLANK callbacks in struct drm_driver are deprecated in favor of their equivalents in struct drm_crtc_funcs. Convert stm over. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/stm/drv.c | 1 - drivers/gpu/drm/stm/ltdc.c | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c index 486985604109..ea9fcbdc68b3 100644 --- a/drivers/gpu/drm/stm/drv.c +++ b/drivers/gpu/drm/stm/drv.c @@ -72,7 +72,6 @@ static struct drm_driver drv_driver = { .gem_prime_vmap = drm_gem_cma_prime_vmap, .gem_prime_vunmap = drm_gem_cma_prime_vunmap, .gem_prime_mmap = drm_gem_cma_prime_mmap, - .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, }; static int drv_load(struct drm_device *ddev) diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c index 8b6d1a2252e3..4fe9b033de1b 100644 --- a/drivers/gpu/drm/stm/ltdc.c +++ b/drivers/gpu/drm/stm/ltdc.c @@ -722,6 +722,7 @@ static const struct drm_crtc_funcs ltdc_crtc_funcs = { .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, .enable_vblank = ltdc_crtc_enable_vblank, .disable_vblank = ltdc_crtc_disable_vblank, + .get_vblank_timestamp = drm_crtc_calc_vbltimestamp_from_scanoutpos, .gamma_set = drm_atomic_helper_legacy_gamma_set, }; -- 2.24.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 21/23] drm/vkms: Convert to CRTC VBLANK callbacks
VBLANK callbacks in struct drm_driver are deprecated in favor of their equivalents in struct drm_crtc_funcs. Convert vkms over. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/vkms/vkms_crtc.c | 9 ++--- drivers/gpu/drm/vkms/vkms_drv.c | 1 - drivers/gpu/drm/vkms/vkms_drv.h | 4 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c index 74f703b8d22a..ac85e17428f8 100644 --- a/drivers/gpu/drm/vkms/vkms_crtc.c +++ b/drivers/gpu/drm/vkms/vkms_crtc.c @@ -76,10 +76,12 @@ static void vkms_disable_vblank(struct drm_crtc *crtc) hrtimer_cancel(&out->vblank_hrtimer); } -bool vkms_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, - int *max_error, ktime_t *vblank_time, - bool in_vblank_irq) +static bool vkms_get_vblank_timestamp(struct drm_crtc *crtc, + int *max_error, ktime_t *vblank_time, + bool in_vblank_irq) { + struct drm_device *dev = crtc->dev; + unsigned int pipe = crtc->index; struct vkms_device *vkmsdev = drm_device_to_vkms_device(dev); struct vkms_output *output = &vkmsdev->output; struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; @@ -154,6 +156,7 @@ static const struct drm_crtc_funcs vkms_crtc_funcs = { .atomic_destroy_state = vkms_atomic_crtc_destroy_state, .enable_vblank = vkms_enable_vblank, .disable_vblank = vkms_disable_vblank, + .get_vblank_timestamp = vkms_get_vblank_timestamp, .get_crc_sources= vkms_get_crc_sources, .set_crc_source = vkms_set_crc_source, .verify_crc_source = vkms_verify_crc_source, diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c index 25bd7519295f..860de052e820 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.c +++ b/drivers/gpu/drm/vkms/vkms_drv.c @@ -103,7 +103,6 @@ static struct drm_driver vkms_driver = { .dumb_create= vkms_dumb_create, .gem_vm_ops = &vkms_gem_vm_ops, .gem_free_object_unlocked = vkms_gem_free_object, - .get_vblank_timestamp = vkms_get_vblank_timestamp, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, .gem_prime_import_sg_table = vkms_prime_import_sg_table, diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h index 7d52e24564db..eda04ffba7b1 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.h +++ b/drivers/gpu/drm/vkms/vkms_drv.h @@ -111,10 +111,6 @@ struct vkms_gem_object { int vkms_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, struct drm_plane *primary, struct drm_plane *cursor); -bool vkms_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, - int *max_error, ktime_t *vblank_time, - bool in_vblank_irq); - int vkms_output_init(struct vkms_device *vkmsdev, int index); struct drm_plane *vkms_plane_init(struct vkms_device *vkmsdev, -- 2.24.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 18/23] drm/sti: Convert to CRTC VBLANK callbacks
VBLANK callbacks in struct drm_driver are deprecated in favor of their equivalents in struct drm_crtc_funcs. Convert sti over. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/sti/sti_crtc.c | 11 --- drivers/gpu/drm/sti/sti_crtc.h | 2 -- drivers/gpu/drm/sti/sti_drv.c | 3 --- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/sti/sti_crtc.c b/drivers/gpu/drm/sti/sti_crtc.c index dc64fbfc4e61..49e6cb8f5836 100644 --- a/drivers/gpu/drm/sti/sti_crtc.c +++ b/drivers/gpu/drm/sti/sti_crtc.c @@ -279,12 +279,13 @@ int sti_crtc_vblank_cb(struct notifier_block *nb, return 0; } -int sti_crtc_enable_vblank(struct drm_device *dev, unsigned int pipe) +static int sti_crtc_enable_vblank(struct drm_crtc *crtc) { + struct drm_device *dev = crtc->dev; + unsigned int pipe = crtc->index; struct sti_private *dev_priv = dev->dev_private; struct sti_compositor *compo = dev_priv->compo; struct notifier_block *vtg_vblank_nb = &compo->vtg_vblank_nb[pipe]; - struct drm_crtc *crtc = &compo->mixer[pipe]->drm_crtc; struct sti_vtg *vtg = compo->vtg[pipe]; DRM_DEBUG_DRIVER("\n"); @@ -297,8 +298,10 @@ int sti_crtc_enable_vblank(struct drm_device *dev, unsigned int pipe) return 0; } -void sti_crtc_disable_vblank(struct drm_device *drm_dev, unsigned int pipe) +static void sti_crtc_disable_vblank(struct drm_crtc *crtc) { + struct drm_device *drm_dev = crtc->dev; + unsigned int pipe = crtc->index; struct sti_private *priv = drm_dev->dev_private; struct sti_compositor *compo = priv->compo; struct notifier_block *vtg_vblank_nb = &compo->vtg_vblank_nb[pipe]; @@ -330,6 +333,8 @@ static const struct drm_crtc_funcs sti_crtc_funcs = { .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, .late_register = sti_crtc_late_register, + .enable_vblank = sti_crtc_enable_vblank, + .disable_vblank = sti_crtc_disable_vblank, }; bool sti_crtc_is_main(struct drm_crtc *crtc) diff --git a/drivers/gpu/drm/sti/sti_crtc.h b/drivers/gpu/drm/sti/sti_crtc.h index df489ab14e2b..1132b4586712 100644 --- a/drivers/gpu/drm/sti/sti_crtc.h +++ b/drivers/gpu/drm/sti/sti_crtc.h @@ -15,8 +15,6 @@ struct sti_mixer; int sti_crtc_init(struct drm_device *drm_dev, struct sti_mixer *mixer, struct drm_plane *primary, struct drm_plane *cursor); -int sti_crtc_enable_vblank(struct drm_device *dev, unsigned int pipe); -void sti_crtc_disable_vblank(struct drm_device *dev, unsigned int pipe); int sti_crtc_vblank_cb(struct notifier_block *nb, unsigned long event, void *data); bool sti_crtc_is_main(struct drm_crtc *drm_crtc); diff --git a/drivers/gpu/drm/sti/sti_drv.c b/drivers/gpu/drm/sti/sti_drv.c index a39fc36f815b..8e30001bf545 100644 --- a/drivers/gpu/drm/sti/sti_drv.c +++ b/drivers/gpu/drm/sti/sti_drv.c @@ -146,9 +146,6 @@ static struct drm_driver sti_driver = { .dumb_create = drm_gem_cma_dumb_create, .fops = &sti_driver_fops, - .enable_vblank = sti_crtc_enable_vblank, - .disable_vblank = sti_crtc_disable_vblank, - .prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table, -- 2.24.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 23/23] drm: Cleanup VBLANK callbacks in struct drm_driver
All non-legacy users of VBLANK functions in struct drm_driver have been converted to use the respective interfaces in struct drm_crtc_funcs. The remaining users of VBLANK callbacks in struct drm_driver are legacy drivers with userspace modesetting. There are no users left of get_vblank_timestamp(), so the callback is being removed. The other VBLANK callbacks are being moved to the legacy section at the end of struct drm_driver. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/drm_vblank.c | 39 +- include/drm/drm_drv.h| 101 ++- 2 files changed, 17 insertions(+), 123 deletions(-) diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c index 7cf436a4b908..ceff68474d4d 100644 --- a/drivers/gpu/drm/drm_vblank.c +++ b/drivers/gpu/drm/drm_vblank.c @@ -138,10 +138,9 @@ static u32 __get_vblank_counter(struct drm_device *dev, unsigned int pipe) if (crtc->funcs->get_vblank_counter) return crtc->funcs->get_vblank_counter(crtc); - } - - if (dev->driver->get_vblank_counter) + } else if (dev->driver->get_vblank_counter) { return dev->driver->get_vblank_counter(dev, pipe); + } return drm_vblank_no_hw_counter(dev, pipe); } @@ -334,8 +333,7 @@ u64 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc) unsigned long flags; WARN_ONCE(drm_debug_enabled(DRM_UT_VBL) && - !crtc->funcs->get_vblank_timestamp && - !dev->driver->get_vblank_timestamp, + !crtc->funcs->get_vblank_timestamp, "This function requires support for accurate vblank timestamps."); spin_lock_irqsave(&dev->vblank_time_lock, flags); @@ -357,13 +355,11 @@ static void __disable_vblank(struct drm_device *dev, unsigned int pipe) if (WARN_ON(!crtc)) return; - if (crtc->funcs->disable_vblank) { + if (crtc->funcs->disable_vblank) crtc->funcs->disable_vblank(crtc); - return; - } + } else { + dev->driver->disable_vblank(dev, pipe); } - - dev->driver->disable_vblank(dev, pipe); } /* @@ -791,9 +787,6 @@ drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe, ret = crtc->funcs->get_vblank_timestamp(crtc, &max_error, tvblank, in_vblank_irq); - } else if (dev->driver->get_vblank_timestamp && (max_error > 0)) { - ret = dev->driver->get_vblank_timestamp(dev, pipe, &max_error, - tvblank, in_vblank_irq); } /* GPU high precision timestamp query unsupported or failed. @@ -1016,9 +1009,11 @@ static int __enable_vblank(struct drm_device *dev, unsigned int pipe) if (crtc->funcs->enable_vblank) return crtc->funcs->enable_vblank(crtc); + } else if (dev->driver->enable_vblank) { + return dev->driver->enable_vblank(dev, pipe); } - return dev->driver->enable_vblank(dev, pipe); + return -EINVAL; } static int drm_vblank_enable(struct drm_device *dev, unsigned int pipe) @@ -1109,13 +1104,10 @@ static bool __vblank_disable_immediate(struct drm_device *dev, unsigned int pipe return false; crtc = drm_crtc_from_index(dev, pipe); - if (crtc && crtc->funcs->get_vblank_timestamp) - return true; - - if (dev->driver->get_vblank_timestamp) - return true; + if (!crtc || !crtc->funcs->get_vblank_timestamp) + return false; - return false; + return true; } static void drm_vblank_put(struct drm_device *dev, unsigned int pipe) @@ -1798,7 +1790,6 @@ static void drm_handle_vblank_events(struct drm_device *dev, unsigned int pipe) struct drm_pending_vblank_event *e, *t; ktime_t now; u64 seq; - bool high_prec; assert_spin_locked(&dev->event_lock); @@ -1818,10 +1809,8 @@ static void drm_handle_vblank_events(struct drm_device *dev, unsigned int pipe) send_vblank_event(dev, e, seq, now); } - high_prec = crtc->funcs->get_vblank_timestamp || - dev->driver->get_vblank_timestamp; - - trace_drm_vblank_event(pipe, seq, now, high_prec); + trace_drm_vblank_event(pipe, seq, now, + crtc->funcs->get_vblank_timestamp != NULL); } /** diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index b704e252f3b2..e290b3aca6eb 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -268,104 +268,6 @@ struct drm_driver { */ void (*release) (struct drm_device *); - /** -* @get_vblank_counter: -* -* Driver callback for fetching a raw hardware vbl
[PATCH 10/23] drm: Evaluate struct drm_device.vblank_disable_immediate on each use
VBLANK interrupts can be disabled immediately or with a delay, where the latter is the default. The former option can be selected by setting get_vblank_timestamp, and enabling vblank_disable_immediate in struct drm_device. The setup is only evaluated once when DRM initializes VBLANKs. Evaluating the settings on each use of vblank_disable_immediate will allow for easy integration of CRTC VBLANK functions. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/drm_vblank.c | 31 ++- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c index b84065911d69..cbe8f3009df5 100644 --- a/drivers/gpu/drm/drm_vblank.c +++ b/drivers/gpu/drm/drm_vblank.c @@ -481,19 +481,6 @@ int drm_vblank_init(struct drm_device *dev, unsigned int num_crtcs) DRM_INFO("Supports vblank timestamp caching Rev 2 (21.10.2013).\n"); - /* Driver specific high-precision vblank timestamping supported? */ - if (dev->driver->get_vblank_timestamp) - DRM_INFO("Driver supports precise vblank timestamp query.\n"); - else - DRM_INFO("No driver support for vblank timestamp query.\n"); - - /* Must have precise timestamping for reliable vblank instant disable */ - if (dev->vblank_disable_immediate && !dev->driver->get_vblank_timestamp) { - dev->vblank_disable_immediate = false; - DRM_INFO("Setting vblank_disable_immediate to false because " -"get_vblank_timestamp == NULL\n"); - } - return 0; err: @@ -1061,6 +1048,15 @@ int drm_crtc_vblank_get(struct drm_crtc *crtc) } EXPORT_SYMBOL(drm_crtc_vblank_get); +static bool __vblank_disable_immediate(struct drm_device *dev, unsigned int pipe) +{ + if (!dev->vblank_disable_immediate) + return false; + if (!dev->driver->get_vblank_timestamp) + return false; + return true; +} + static void drm_vblank_put(struct drm_device *dev, unsigned int pipe) { struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; @@ -1077,7 +1073,7 @@ static void drm_vblank_put(struct drm_device *dev, unsigned int pipe) return; else if (drm_vblank_offdelay < 0) vblank_disable_fn(&vblank->disable_timer); - else if (!dev->vblank_disable_immediate) + else if (__vblank_disable_immediate(dev, pipe)) mod_timer(&vblank->disable_timer, jiffies + ((drm_vblank_offdelay * HZ)/1000)); } @@ -1654,7 +1650,7 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data, /* If the counter is currently enabled and accurate, short-circuit * queries to return the cached timestamp of the last vblank. */ - if (dev->vblank_disable_immediate && + if (__vblank_disable_immediate(dev, pipe) && drm_wait_vblank_is_query(vblwait) && READ_ONCE(vblank->enabled)) { drm_wait_vblank_reply(dev, pipe, &vblwait->reply); @@ -1811,7 +1807,7 @@ bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe) * been signaled. The disable has to be last (after * drm_handle_vblank_events) so that the timestamp is always accurate. */ - disable_irq = (dev->vblank_disable_immediate && + disable_irq = (__vblank_disable_immediate(dev, pipe) && drm_vblank_offdelay > 0 && !atomic_read(&vblank->refcount)); @@ -1884,7 +1880,8 @@ int drm_crtc_get_sequence_ioctl(struct drm_device *dev, void *data, pipe = drm_crtc_index(crtc); vblank = &dev->vblank[pipe]; - vblank_enabled = dev->vblank_disable_immediate && READ_ONCE(vblank->enabled); + vblank_enabled = __vblank_disable_immediate(dev, pipe) && +READ_ONCE(vblank->enabled); if (!vblank_enabled) { ret = drm_crtc_vblank_get(crtc); -- 2.24.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 15/23] drm/msm: Convert to CRTC VBLANK callbacks
VBLANK callbacks in struct drm_driver are deprecated in favor of their equivalents in struct drm_crtc_funcs. Convert msm over. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 2 ++ drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c | 2 ++ drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c | 15 ++ drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c | 34 --- drivers/gpu/drm/msm/msm_drv.c | 10 --- drivers/gpu/drm/msm/msm_drv.h | 3 ++ 6 files changed, 28 insertions(+), 38 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index f197dce54576..b177d5052c5e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -1281,6 +1281,8 @@ static const struct drm_crtc_funcs dpu_crtc_funcs = { .atomic_destroy_state = dpu_crtc_destroy_state, .late_register = dpu_crtc_late_register, .early_unregister = dpu_crtc_early_unregister, + .enable_vblank = msm_crtc_enable_vblank, + .disable_vblank = msm_crtc_disable_vblank, }; static const struct drm_crtc_helper_funcs dpu_crtc_helper_funcs = { diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c index f34dca5d4532..c9239b07fe4f 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c @@ -481,6 +481,8 @@ static const struct drm_crtc_funcs mdp4_crtc_funcs = { .reset = drm_atomic_helper_crtc_reset, .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, + .enable_vblank = msm_crtc_enable_vblank, + .disable_vblank = msm_crtc_disable_vblank, }; static const struct drm_crtc_helper_funcs mdp4_crtc_helper_funcs = { diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c index 4decf19847a8..70c326d330f6 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c @@ -471,6 +471,17 @@ static bool mdp5_crtc_get_scanout_position(struct drm_crtc *crtc, return true; } +static u32 mdp5_crtc_get_vblank_counter(struct drm_crtc *crtc) +{ + struct drm_encoder *encoder; + + encoder = get_encoder_from_crtc(crtc); + if (!encoder) + return 0; + + return mdp5_encoder_get_framecount(encoder); +} + static void mdp5_crtc_atomic_disable(struct drm_crtc *crtc, struct drm_crtc_state *old_state) { @@ -1120,6 +1131,10 @@ static const struct drm_crtc_funcs mdp5_crtc_funcs = { .cursor_set = mdp5_crtc_cursor_set, .cursor_move = mdp5_crtc_cursor_move, .atomic_print_state = mdp5_crtc_atomic_print_state, + .get_vblank_counter = mdp5_crtc_get_vblank_counter, + .enable_vblank = msm_crtc_enable_vblank, + .disable_vblank = msm_crtc_disable_vblank, + .get_vblank_timestamp = drm_crtc_calc_vbltimestamp_from_scanoutpos, }; static const struct drm_crtc_helper_funcs mdp5_crtc_helper_funcs = { diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c index 8b72ac44ce55..6650f478b226 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c @@ -583,38 +583,6 @@ static int get_clk(struct platform_device *pdev, struct clk **clkp, return 0; } -static struct drm_encoder *get_encoder_from_crtc(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct drm_encoder *encoder; - - drm_for_each_encoder(encoder, dev) - if (encoder->crtc == crtc) - return encoder; - - return NULL; -} - -static u32 mdp5_get_vblank_counter(struct drm_device *dev, unsigned int pipe) -{ - struct msm_drm_private *priv = dev->dev_private; - struct drm_crtc *crtc; - struct drm_encoder *encoder; - - if (pipe >= priv->num_crtcs) - return 0; - - crtc = priv->crtcs[pipe]; - if (!crtc) - return 0; - - encoder = get_encoder_from_crtc(crtc); - if (!encoder) - return 0; - - return mdp5_encoder_get_framecount(encoder); -} - struct msm_kms *mdp5_kms_init(struct drm_device *dev) { struct msm_drm_private *priv = dev->dev_private; @@ -702,8 +670,6 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) dev->mode_config.max_width = 0x; dev->mode_config.max_height = 0x; - dev->driver->get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos; - dev->driver->get_vblank_counter = mdp5_get_vblank_counter; dev->max_vblank_count = 0; /* max_vblank_count is set on each CRTC */ dev->vblank_disable_immediate = true; diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index c84f0a8b3f2c..c5e04413
[PATCH 01/23] drm: Add get_scanout_position() to struct drm_crtc_helper_funcs
The new callback get_scanout_position() reads the current location of the scanout process. The operation is currentyl located in struct drm_driver, but really belongs to the CRTC. Drivers will be converted in separate patches. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/drm_vblank.c | 24 include/drm/drm_drv.h| 7 +--- include/drm/drm_modeset_helper_vtables.h | 47 3 files changed, 65 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c index 1659b13b178c..c12f0b333e14 100644 --- a/drivers/gpu/drm/drm_vblank.c +++ b/drivers/gpu/drm/drm_vblank.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -590,7 +591,7 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants); * Implements calculation of exact vblank timestamps from given drm_display_mode * timings and current video scanout position of a CRTC. This can be directly * used as the &drm_driver.get_vblank_timestamp implementation of a kms driver - * if &drm_driver.get_scanout_position is implemented. + * if &drm_crtc_helper_funcs.get_scanout_position is implemented. * * The current implementation only handles standard video modes. For double scan * and interlaced modes the driver is supposed to adjust the hardware mode @@ -632,8 +633,9 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, } /* Scanout position query not supported? Should not happen. */ - if (!dev->driver->get_scanout_position) { - DRM_ERROR("Called from driver w/o get_scanout_position()!?\n"); + if (!dev->driver->get_scanout_position || + !crtc->helper_private->get_scanout_position) { + DRM_ERROR("Called from CRTC w/o get_scanout_position()!?\n"); return false; } @@ -664,11 +666,17 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, * Get vertical and horizontal scanout position vpos, hpos, * and bounding timestamps stime, etime, pre/post query. */ - vbl_status = dev->driver->get_scanout_position(dev, pipe, - in_vblank_irq, - &vpos, &hpos, - &stime, &etime, - mode); + if (crtc->helper_private->get_scanout_position) { + vbl_status = + crtc->helper_private->get_scanout_position( + crtc, in_vblank_irq, &vpos, &hpos, + &stime, &etime, mode); + } else { + vbl_status = + dev->driver->get_scanout_position( + dev, pipe, in_vblank_irq, &vpos, + &hpos, &stime, &etime, mode); + } /* Return as no-op if scanout query unsupported or failed. */ if (!vbl_status) { diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index cf13470810a5..d0049e5786fc 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -362,11 +362,8 @@ struct drm_driver { * True on success, false if a reliable scanout position counter could * not be read out. * -* FIXME: -* -* Since this is a helper to implement @get_vblank_timestamp, we should -* move it to &struct drm_crtc_helper_funcs, like all the other -* helper-internal hooks. +* This is deprecated and should not be used by new drivers. +* Use &drm_crtc_helper_funcs.get_scanout_position instead. */ bool (*get_scanout_position) (struct drm_device *dev, unsigned int pipe, bool in_vblank_irq, int *vpos, int *hpos, diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h index 5a87f1bd7a3f..e398512bfd5f 100644 --- a/include/drm/drm_modeset_helper_vtables.h +++ b/include/drm/drm_modeset_helper_vtables.h @@ -450,6 +450,53 @@ struct drm_crtc_helper_funcs { */ void (*atomic_disable)(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state); + + /** +* @get_scanout_position: +* +* Called by vblank timestamping code. +* +* Returns the current display scanout position from a CRTC and an +* optional accurate ktime_get() timestamp of when the position was +* measured. Note that this is a helper callback which is only used +* if a driver uses drm_calc_vbltimestamp_from_scanoutpos() for the +* @drm_driver.get_vblank_timestamp callback. +
[PATCH 22/23] drm/vmwgfx: Convert to CRTC VBLANK callbacks
VBLANK callbacks in struct drm_driver are deprecated in favor of their equivalents in struct drm_crtc_funcs. Convert vmwgfx over. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 5 + drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 6 +++--- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 8 drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 3 +++ drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 5 - drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 3 +++ 6 files changed, 18 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index e962048f65d2..f5ab04468522 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -1329,7 +1329,7 @@ static int vmw_pm_freeze(struct device *kdev) vmw_fence_fifo_down(dev_priv->fman); __vmw_svga_disable(dev_priv); - + vmw_release_device_late(dev_priv); return 0; } @@ -1393,9 +1393,6 @@ static struct drm_driver driver = { DRIVER_MODESET | DRIVER_RENDER | DRIVER_ATOMIC, .load = vmw_driver_load, .unload = vmw_driver_unload, - .get_vblank_counter = vmw_get_vblank_counter, - .enable_vblank = vmw_enable_vblank, - .disable_vblank = vmw_disable_vblank, .ioctls = vmw_ioctls, .num_ioctls = ARRAY_SIZE(vmw_ioctls), .master_set = vmw_master_set, diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index a31e726d6d71..845b3b8c29ca 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -1100,9 +1100,9 @@ int vmw_kms_write_svga(struct vmw_private *vmw_priv, bool vmw_kms_validate_mode_vram(struct vmw_private *dev_priv, uint32_t pitch, uint32_t height); -u32 vmw_get_vblank_counter(struct drm_device *dev, unsigned int pipe); -int vmw_enable_vblank(struct drm_device *dev, unsigned int pipe); -void vmw_disable_vblank(struct drm_device *dev, unsigned int pipe); +u32 vmw_get_vblank_counter(struct drm_crtc *crtc); +int vmw_enable_vblank(struct drm_crtc *crtc); +void vmw_disable_vblank(struct drm_crtc *crtc); int vmw_kms_present(struct vmw_private *dev_priv, struct drm_file *file_priv, struct vmw_framebuffer *vfb, diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index f47d5710cc95..9f0fee62904a 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -1991,7 +1991,7 @@ bool vmw_kms_validate_mode_vram(struct vmw_private *dev_priv, /** * Function called by DRM code called with vbl_lock held. */ -u32 vmw_get_vblank_counter(struct drm_device *dev, unsigned int pipe) +u32 vmw_get_vblank_counter(struct drm_crtc *crtc) { return 0; } @@ -1999,7 +1999,7 @@ u32 vmw_get_vblank_counter(struct drm_device *dev, unsigned int pipe) /** * Function called by DRM code called with vbl_lock held. */ -int vmw_enable_vblank(struct drm_device *dev, unsigned int pipe) +int vmw_enable_vblank(struct drm_crtc *crtc) { return -EINVAL; } @@ -2007,7 +2007,7 @@ int vmw_enable_vblank(struct drm_device *dev, unsigned int pipe) /** * Function called by DRM code called with vbl_lock held. */ -void vmw_disable_vblank(struct drm_device *dev, unsigned int pipe) +void vmw_disable_vblank(struct drm_crtc *crtc) { } @@ -2088,7 +2088,7 @@ static int vmw_du_update_layout(struct vmw_private *dev_priv, drm_modeset_drop_locks(&ctx); drm_modeset_acquire_fini(&ctx); mutex_unlock(&dev->mode_config.mutex); - + return 0; } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index 5702219ec38f..16dafff5cab1 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c @@ -236,6 +236,9 @@ static const struct drm_crtc_funcs vmw_legacy_crtc_funcs = { .atomic_duplicate_state = vmw_du_crtc_duplicate_state, .atomic_destroy_state = vmw_du_crtc_destroy_state, .set_config = drm_atomic_helper_set_config, + .get_vblank_counter = vmw_get_vblank_counter, + .enable_vblank = vmw_enable_vblank, + .disable_vblank = vmw_disable_vblank, }; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c index e5a283263211..207a4053e769 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c @@ -319,6 +319,9 @@ static const struct drm_crtc_funcs vmw_screen_object_crtc_funcs = { .atomic_destroy_state = vmw_du_crtc_destroy_state, .set_config = drm_atomic_helper_set_config, .page_flip = drm_atomic_helper_page_flip, + .get_vblank_counter = vmw_get_vblank_counter, + .enable_vblank = vmw_enable_vblank, + .disable_vblank = vmw_disable_vblank, }; /* @@ -1388,6 +1391,6 @@ int vmw_kms_sou_readback(struct vmw_private *dev_priv,
[PATCH 16/23] drm/nouveau: Convert to CRTC VBLANK callbacks
VBLANK callbacks in struct drm_driver are deprecated in favor of their equivalents in struct drm_crtc_funcs. Convert nouvean over. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/nouveau/dispnv04/crtc.c | 3 +++ drivers/gpu/drm/nouveau/dispnv50/head.c | 4 drivers/gpu/drm/nouveau/nouveau_display.c | 14 ++ drivers/gpu/drm/nouveau/nouveau_display.h | 4 ++-- drivers/gpu/drm/nouveau/nouveau_drm.c | 4 5 files changed, 11 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/nouveau/dispnv04/crtc.c b/drivers/gpu/drm/nouveau/dispnv04/crtc.c index 17e9d1c078a0..4a4122a1c057 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/crtc.c +++ b/drivers/gpu/drm/nouveau/dispnv04/crtc.c @@ -1248,6 +1248,9 @@ static const struct drm_crtc_funcs nv04_crtc_funcs = { .set_config = drm_crtc_helper_set_config, .page_flip = nv04_crtc_page_flip, .destroy = nv_crtc_destroy, + .enable_vblank = nouveau_display_vblank_enable, + .disable_vblank = nouveau_display_vblank_disable, + .get_vblank_timestamp = drm_crtc_calc_vbltimestamp_from_scanoutpos, }; static const struct drm_crtc_helper_funcs nv04_crtc_helper_funcs = { diff --git a/drivers/gpu/drm/nouveau/dispnv50/head.c b/drivers/gpu/drm/nouveau/dispnv50/head.c index 1354d19d9a18..a6b7416ca270 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head.c +++ b/drivers/gpu/drm/nouveau/dispnv50/head.c @@ -29,6 +29,7 @@ #include #include +#include #include "nouveau_connector.h" void nv50_head_flush_clr(struct nv50_head *head, @@ -472,6 +473,9 @@ nv50_head_func = { .page_flip = drm_atomic_helper_page_flip, .atomic_duplicate_state = nv50_head_atomic_duplicate_state, .atomic_destroy_state = nv50_head_atomic_destroy_state, + .enable_vblank = nouveau_display_vblank_enable, + .disable_vblank = nouveau_display_vblank_disable, + .get_vblank_timestamp = drm_crtc_calc_vbltimestamp_from_scanoutpos, }; int diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 86f99dc8fcef..700817dc4fa0 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -54,15 +54,10 @@ nouveau_display_vblank_handler(struct nvif_notify *notify) } int -nouveau_display_vblank_enable(struct drm_device *dev, unsigned int pipe) +nouveau_display_vblank_enable(struct drm_crtc *crtc) { - struct drm_crtc *crtc; struct nouveau_crtc *nv_crtc; - crtc = drm_crtc_from_index(dev, pipe); - if (!crtc) - return -EINVAL; - nv_crtc = nouveau_crtc(crtc); nvif_notify_get(&nv_crtc->vblank); @@ -70,15 +65,10 @@ nouveau_display_vblank_enable(struct drm_device *dev, unsigned int pipe) } void -nouveau_display_vblank_disable(struct drm_device *dev, unsigned int pipe) +nouveau_display_vblank_disable(struct drm_crtc *crtc) { - struct drm_crtc *crtc; struct nouveau_crtc *nv_crtc; - crtc = drm_crtc_from_index(dev, pipe); - if (!crtc) - return; - nv_crtc = nouveau_crtc(crtc); nvif_notify_put(&nv_crtc->vblank); } diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h index 71e2af693f7f..71c7048948f3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.h +++ b/drivers/gpu/drm/nouveau/nouveau_display.h @@ -61,8 +61,8 @@ int nouveau_display_init(struct drm_device *dev, bool resume, bool runtime); void nouveau_display_fini(struct drm_device *dev, bool suspend, bool runtime); int nouveau_display_suspend(struct drm_device *dev, bool runtime); void nouveau_display_resume(struct drm_device *dev, bool runtime); -int nouveau_display_vblank_enable(struct drm_device *, unsigned int); -void nouveau_display_vblank_disable(struct drm_device *, unsigned int); +int nouveau_display_vblank_enable(struct drm_crtc *); +void nouveau_display_vblank_disable(struct drm_crtc *); bool nouveau_display_scanoutpos(struct drm_crtc *, bool, int *, int *, ktime_t *, ktime_t *, const struct drm_display_mode *); diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 9fb38a018240..0003343014ce 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -1121,10 +1121,6 @@ driver_stub = { .debugfs_init = nouveau_drm_debugfs_init, #endif - .enable_vblank = nouveau_display_vblank_enable, - .disable_vblank = nouveau_display_vblank_disable, - .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, - .ioctls = nouveau_ioctls, .num_ioctls = ARRAY_SIZE(nouveau_ioctls), .fops = &nouveau_driver_fops, -- 2.24.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 03/23] drm/i915: Don't use struct drm_driver.get_scanout_position()
The callback struct drm_driver.get_scanout_position() is deprecated in favor of struct drm_crtc_helper_funcs.get_scanout_position(). i915 doesn't use CRTC helpers. The patch duplicates the caller drm_calc_vbltimestamp_from_scanoutpos() for i915, such that the callback function is not needed. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/i915/i915_drv.c | 3 +- drivers/gpu/drm/i915/i915_irq.c | 117 ++-- drivers/gpu/drm/i915/i915_irq.h | 9 +-- 3 files changed, 119 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index f7385abdd74b..4a0a7fb85c53 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -2769,8 +2769,7 @@ static struct drm_driver driver = { .gem_prime_export = i915_gem_prime_export, .gem_prime_import = i915_gem_prime_import, - .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, - .get_scanout_position = i915_get_crtc_scanoutpos, + .get_vblank_timestamp = i915_calc_vbltimestamp_from_scanoutpos, .dumb_create = i915_gem_dumb_create, .dumb_map_offset = i915_gem_dumb_mmap_offset, diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index afc6aad9bf8c..99d0c3b0feae 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -52,6 +52,11 @@ #include "i915_trace.h" #include "intel_pm.h" +/* Retry timestamp calculation up to 3 times to satisfy + * drm_timestamp_precision before giving up. + */ +#define I915_TIMESTAMP_MAXRETRIES 3 + /** * DOC: interrupt handling * @@ -762,10 +767,11 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc) return (position + crtc->scanline_offset) % vtotal; } -bool i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int index, - bool in_vblank_irq, int *vpos, int *hpos, - ktime_t *stime, ktime_t *etime, - const struct drm_display_mode *mode) +static bool i915_get_crtc_scanoutpos(struct drm_device *dev, +unsigned int index, bool in_vblank_irq, +int *vpos, int *hpos, +ktime_t *stime, ktime_t *etime, +const struct drm_display_mode *mode) { struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *crtc = to_intel_crtc(drm_crtc_from_index(dev, index)); @@ -879,6 +885,109 @@ bool i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int index, return true; } +bool i915_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, + unsigned int pipe, + int *max_error, + ktime_t *vblank_time, + bool in_vblank_irq) +{ + struct timespec64 ts_etime, ts_vblank_time; + ktime_t stime, etime; + bool vbl_status; + struct drm_crtc *crtc; + const struct drm_display_mode *mode; + struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; + int vpos, hpos, i; + int delta_ns, duration_ns; + + crtc = drm_crtc_from_index(dev, pipe); + + if (pipe >= dev->num_crtcs || !crtc) { + DRM_ERROR("Invalid crtc %u\n", pipe); + return false; + } + + if (drm_drv_uses_atomic_modeset(dev)) + mode = &vblank->hwmode; + else + mode = &crtc->hwmode; + + /* If mode timing undefined, just return as no-op: +* Happens during initial modesetting of a crtc. +*/ + if (mode->crtc_clock == 0) { + DRM_DEBUG("crtc %u: Noop due to uninitialized mode.\n", pipe); + WARN_ON_ONCE(drm_drv_uses_atomic_modeset(dev)); + + return false; + } + + /* Get current scanout position with system timestamp. +* Repeat query up to DRM_TIMESTAMP_MAXRETRIES times +* if single query takes longer than max_error nanoseconds. +* +* This guarantees a tight bound on maximum error if +* code gets preempted or delayed for some reason. +*/ + for (i = 0; i < I915_TIMESTAMP_MAXRETRIES; i++) { + /* +* Get vertical and horizontal scanout position vpos, hpos, +* and bounding timestamps stime, etime, pre/post query. +*/ + vbl_status = i915_get_crtc_scanoutpos(dev, pipe, in_vblank_irq, + &vpos, &hpos, &stime, + &etime, mode); + /* Return as no-op if scanout query unsupported or failed. */ + if (!vbl_status) { + DRM_DEBUG("crtc %u : scanoutpos query failed.\n", +
[PATCH 13/23] drm/gma500: Convert to CRTC VBLANK callbacks
VBLANK callbacks in struct drm_driver are deprecated in favor of their equivalents in struct drm_crtc_funcs. Convert gma500 over. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/gma500/cdv_intel_display.c | 3 +++ drivers/gpu/drm/gma500/psb_drv.c | 4 drivers/gpu/drm/gma500/psb_drv.h | 6 +++--- drivers/gpu/drm/gma500/psb_intel_display.c | 3 +++ drivers/gpu/drm/gma500/psb_irq.c | 12 +--- drivers/gpu/drm/gma500/psb_irq.h | 7 --- 6 files changed, 22 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/gma500/cdv_intel_display.c b/drivers/gpu/drm/gma500/cdv_intel_display.c index 1ed854f498b7..686385a66167 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_display.c +++ b/drivers/gpu/drm/gma500/cdv_intel_display.c @@ -977,6 +977,9 @@ const struct drm_crtc_funcs cdv_intel_crtc_funcs = { .set_config = gma_crtc_set_config, .destroy = gma_crtc_destroy, .page_flip = gma_crtc_page_flip, + .enable_vblank = psb_enable_vblank, + .disable_vblank = psb_disable_vblank, + .get_vblank_counter = psb_get_vblank_counter, }; const struct gma_clock_funcs cdv_clock_funcs = { diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c index 52591416f8fe..36cb292fdebe 100644 --- a/drivers/gpu/drm/gma500/psb_drv.c +++ b/drivers/gpu/drm/gma500/psb_drv.c @@ -363,7 +363,6 @@ static int psb_driver_load(struct drm_device *dev, unsigned long flags) drm_irq_install(dev, dev->pdev->irq); dev->max_vblank_count = 0xff; /* only 24 bits of frame count */ - dev->driver->get_vblank_counter = psb_get_vblank_counter; psb_modeset_init(dev); psb_fbdev_init(dev); @@ -507,9 +506,6 @@ static struct drm_driver driver = { .irq_postinstall = psb_irq_postinstall, .irq_uninstall = psb_irq_uninstall, .irq_handler = psb_irq_handler, - .enable_vblank = psb_enable_vblank, - .disable_vblank = psb_disable_vblank, - .get_vblank_counter = psb_get_vblank_counter, .gem_free_object = psb_gem_free_object, .gem_vm_ops = &psb_gem_vm_ops, diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h index 3d4ef3071d45..956926341316 100644 --- a/drivers/gpu/drm/gma500/psb_drv.h +++ b/drivers/gpu/drm/gma500/psb_drv.h @@ -681,15 +681,15 @@ extern void psb_irq_turn_off_dpst(struct drm_device *dev); extern void psb_irq_uninstall_islands(struct drm_device *dev, int hw_islands); extern int psb_vblank_wait2(struct drm_device *dev, unsigned int *sequence); extern int psb_vblank_wait(struct drm_device *dev, unsigned int *sequence); -extern int psb_enable_vblank(struct drm_device *dev, unsigned int pipe); -extern void psb_disable_vblank(struct drm_device *dev, unsigned int pipe); +extern int psb_enable_vblank(struct drm_crtc *crtc); +extern void psb_disable_vblank(struct drm_crtc *crtc); void psb_enable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask); void psb_disable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask); -extern u32 psb_get_vblank_counter(struct drm_device *dev, unsigned int pipe); +extern u32 psb_get_vblank_counter(struct drm_crtc *crtc); /* framebuffer.c */ extern int psbfb_probed(struct drm_device *dev); diff --git a/drivers/gpu/drm/gma500/psb_intel_display.c b/drivers/gpu/drm/gma500/psb_intel_display.c index fed3b563e62e..531c5485be17 100644 --- a/drivers/gpu/drm/gma500/psb_intel_display.c +++ b/drivers/gpu/drm/gma500/psb_intel_display.c @@ -433,6 +433,9 @@ const struct drm_crtc_funcs psb_intel_crtc_funcs = { .set_config = gma_crtc_set_config, .destroy = gma_crtc_destroy, .page_flip = gma_crtc_page_flip, + .enable_vblank = psb_enable_vblank, + .disable_vblank = psb_disable_vblank, + .get_vblank_counter = psb_get_vblank_counter, }; const struct gma_clock_funcs psb_clock_funcs = { diff --git a/drivers/gpu/drm/gma500/psb_irq.c b/drivers/gpu/drm/gma500/psb_irq.c index 40a37e400b02..7ec031d28dc0 100644 --- a/drivers/gpu/drm/gma500/psb_irq.c +++ b/drivers/gpu/drm/gma500/psb_irq.c @@ -507,8 +507,10 @@ int psb_irq_disable_dpst(struct drm_device *dev) /* * It is used to enable VBLANK interrupt */ -int psb_enable_vblank(struct drm_device *dev, unsigned int pipe) +int psb_enable_vblank(struct drm_crtc *crtc) { + struct drm_device *dev = crtc->dev; + unsigned int pipe = crtc->index; struct drm_psb_private *dev_priv = dev->dev_private; unsigned long irqflags; uint32_t reg_val = 0; @@ -546,8 +548,10 @@ int psb_enable_vblank(struct drm_device *dev, unsigned int pipe) /* * It is used to disable VBLANK interrupt */ -void psb_disable_vblank(struct drm_device *dev, unsigned int pipe) +void psb_disable_vblank(struct drm_crtc *crtc) { + struct drm_device *dev = crtc->dev; + unsigned int pipe = crtc->index; struct drm_psb_private *dev_priv = dev->dev_private;
[PATCH 07/23] drm/vc4: Convert to struct drm_crtc_helper_funcs.get_scanout_position()
The callback struct drm_driver.get_scanout_position() is deprecated in favor of struct drm_crtc_helper_funcs.get_scanout_position(). Convert vc4 over. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/vc4/vc4_crtc.c | 12 +++- drivers/gpu/drm/vc4/vc4_drv.c | 1 - drivers/gpu/drm/vc4/vc4_drv.h | 4 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index b00e20f5ce05..f1e7597ea17e 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -84,13 +84,14 @@ static const struct debugfs_reg32 crtc_regs[] = { VC4_REG32(PV_HACT_ACT), }; -bool vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, -bool in_vblank_irq, int *vpos, int *hpos, -ktime_t *stime, ktime_t *etime, -const struct drm_display_mode *mode) +static bool vc4_crtc_get_scanout_position(struct drm_crtc *crtc, + bool in_vblank_irq, + int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode) { + struct drm_device *dev = crtc->dev; struct vc4_dev *vc4 = to_vc4_dev(dev); - struct drm_crtc *crtc = drm_crtc_from_index(dev, crtc_id); struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); u32 val; int fifo_lines; @@ -1039,6 +1040,7 @@ static const struct drm_crtc_helper_funcs vc4_crtc_helper_funcs = { .atomic_flush = vc4_crtc_atomic_flush, .atomic_enable = vc4_crtc_atomic_enable, .atomic_disable = vc4_crtc_atomic_disable, + .get_scanout_position = vc4_crtc_get_scanout_position, }; static const struct vc4_crtc_data pv0_data = { diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index 5e6fb6c2307f..e6982a7b0c5e 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c @@ -190,7 +190,6 @@ static struct drm_driver vc4_drm_driver = { .irq_postinstall = vc4_irq_postinstall, .irq_uninstall = vc4_irq_uninstall, - .get_scanout_position = vc4_crtc_get_scanoutpos, .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, #if defined(CONFIG_DEBUG_FS) diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 6627b20c99e9..f90c0d08e740 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -743,10 +743,6 @@ void vc4_bo_remove_from_purgeable_pool(struct vc4_bo *bo); /* vc4_crtc.c */ extern struct platform_driver vc4_crtc_driver; -bool vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, -bool in_vblank_irq, int *vpos, int *hpos, -ktime_t *stime, ktime_t *etime, -const struct drm_display_mode *mode); void vc4_crtc_handle_vblank(struct vc4_crtc *crtc); void vc4_crtc_txp_armed(struct drm_crtc_state *state); void vc4_crtc_get_margins(struct drm_crtc_state *state, -- 2.24.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 09/23] drm: Remove struct drm_driver.get_scanout_position()
All users of struct drm_driver.get_scanout_position() have been covnerted to the respective CRTC helper function. Remove the callback from struct drm_driver. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/drm_vblank.c | 13 ++--- include/drm/drm_drv.h| 52 2 files changed, 2 insertions(+), 63 deletions(-) diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c index c12f0b333e14..b84065911d69 100644 --- a/drivers/gpu/drm/drm_vblank.c +++ b/drivers/gpu/drm/drm_vblank.c @@ -633,8 +633,7 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, } /* Scanout position query not supported? Should not happen. */ - if (!dev->driver->get_scanout_position || - !crtc->helper_private->get_scanout_position) { + if (!crtc->helper_private->get_scanout_position) { DRM_ERROR("Called from CRTC w/o get_scanout_position()!?\n"); return false; } @@ -666,17 +665,9 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, * Get vertical and horizontal scanout position vpos, hpos, * and bounding timestamps stime, etime, pre/post query. */ - if (crtc->helper_private->get_scanout_position) { - vbl_status = - crtc->helper_private->get_scanout_position( + vbl_status = crtc->helper_private->get_scanout_position( crtc, in_vblank_irq, &vpos, &hpos, &stime, &etime, mode); - } else { - vbl_status = - dev->driver->get_scanout_position( - dev, pipe, in_vblank_irq, &vpos, - &hpos, &stime, &etime, mode); - } /* Return as no-op if scanout query unsupported or failed. */ if (!vbl_status) { diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index d0049e5786fc..b704e252f3b2 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -318,58 +318,6 @@ struct drm_driver { */ void (*disable_vblank) (struct drm_device *dev, unsigned int pipe); - /** -* @get_scanout_position: -* -* Called by vblank timestamping code. -* -* Returns the current display scanout position from a crtc, and an -* optional accurate ktime_get() timestamp of when position was -* measured. Note that this is a helper callback which is only used if a -* driver uses drm_calc_vbltimestamp_from_scanoutpos() for the -* @get_vblank_timestamp callback. -* -* Parameters: -* -* dev: -* DRM device. -* pipe: -* Id of the crtc to query. -* in_vblank_irq: -* True when called from drm_crtc_handle_vblank(). Some drivers -* need to apply some workarounds for gpu-specific vblank irq quirks -* if flag is set. -* vpos: -* Target location for current vertical scanout position. -* hpos: -* Target location for current horizontal scanout position. -* stime: -* Target location for timestamp taken immediately before -* scanout position query. Can be NULL to skip timestamp. -* etime: -* Target location for timestamp taken immediately after -* scanout position query. Can be NULL to skip timestamp. -* mode: -* Current display timings. -* -* Returns vpos as a positive number while in active scanout area. -* Returns vpos as a negative number inside vblank, counting the number -* of scanlines to go until end of vblank, e.g., -1 means "one scanline -* until start of active scanout / end of vblank." -* -* Returns: -* -* True on success, false if a reliable scanout position counter could -* not be read out. -* -* This is deprecated and should not be used by new drivers. -* Use &drm_crtc_helper_funcs.get_scanout_position instead. -*/ - bool (*get_scanout_position) (struct drm_device *dev, unsigned int pipe, - bool in_vblank_irq, int *vpos, int *hpos, - ktime_t *stime, ktime_t *etime, - const struct drm_display_mode *mode); - /** * @get_vblank_timestamp: * -- 2.24.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 14/23] drm/i915: Convert to CRTC VBLANK callbacks
VBLANK callbacks in struct drm_driver are deprecated in favor of their equivalents in struct drm_crtc_funcs. Convert i915 over. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/i915/display/intel_display.c | 7 +++ drivers/gpu/drm/i915/i915_drv.c | 2 -- drivers/gpu/drm/i915/i915_irq.c | 13 +++-- drivers/gpu/drm/i915/i915_irq.h | 3 +-- 4 files changed, 11 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index da5266e76738..515788698298 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -16227,6 +16227,7 @@ static const struct drm_crtc_funcs bdw_crtc_funcs = { .get_vblank_counter = g4x_get_vblank_counter, .enable_vblank = bdw_enable_vblank, .disable_vblank = bdw_disable_vblank, + .get_vblank_timestamp = i915_calc_vbltimestamp_from_scanoutpos, }; static const struct drm_crtc_funcs ilk_crtc_funcs = { @@ -16235,6 +16236,7 @@ static const struct drm_crtc_funcs ilk_crtc_funcs = { .get_vblank_counter = g4x_get_vblank_counter, .enable_vblank = ilk_enable_vblank, .disable_vblank = ilk_disable_vblank, + .get_vblank_timestamp = i915_calc_vbltimestamp_from_scanoutpos, }; static const struct drm_crtc_funcs g4x_crtc_funcs = { @@ -16243,6 +16245,7 @@ static const struct drm_crtc_funcs g4x_crtc_funcs = { .get_vblank_counter = g4x_get_vblank_counter, .enable_vblank = i965_enable_vblank, .disable_vblank = i965_disable_vblank, + .get_vblank_timestamp = i915_calc_vbltimestamp_from_scanoutpos, }; static const struct drm_crtc_funcs i965_crtc_funcs = { @@ -16251,6 +16254,7 @@ static const struct drm_crtc_funcs i965_crtc_funcs = { .get_vblank_counter = i915_get_vblank_counter, .enable_vblank = i965_enable_vblank, .disable_vblank = i965_disable_vblank, + .get_vblank_timestamp = i915_calc_vbltimestamp_from_scanoutpos, }; static const struct drm_crtc_funcs i915gm_crtc_funcs = { @@ -16259,6 +16263,7 @@ static const struct drm_crtc_funcs i915gm_crtc_funcs = { .get_vblank_counter = i915_get_vblank_counter, .enable_vblank = i915gm_enable_vblank, .disable_vblank = i915gm_disable_vblank, + .get_vblank_timestamp = i915_calc_vbltimestamp_from_scanoutpos, }; static const struct drm_crtc_funcs i915_crtc_funcs = { @@ -16267,6 +16272,7 @@ static const struct drm_crtc_funcs i915_crtc_funcs = { .get_vblank_counter = i915_get_vblank_counter, .enable_vblank = i8xx_enable_vblank, .disable_vblank = i8xx_disable_vblank, + .get_vblank_timestamp = i915_calc_vbltimestamp_from_scanoutpos, }; static const struct drm_crtc_funcs i8xx_crtc_funcs = { @@ -16275,6 +16281,7 @@ static const struct drm_crtc_funcs i8xx_crtc_funcs = { /* no hw vblank counter */ .enable_vblank = i8xx_enable_vblank, .disable_vblank = i8xx_disable_vblank, + .get_vblank_timestamp = i915_calc_vbltimestamp_from_scanoutpos, }; static struct intel_crtc *intel_crtc_alloc(void) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 4a0a7fb85c53..30b9ba136a81 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -2769,8 +2769,6 @@ static struct drm_driver driver = { .gem_prime_export = i915_gem_prime_export, .gem_prime_import = i915_gem_prime_import, - .get_vblank_timestamp = i915_calc_vbltimestamp_from_scanoutpos, - .dumb_create = i915_gem_dumb_create, .dumb_map_offset = i915_gem_dumb_mmap_offset, diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 99d0c3b0feae..dbbbdff8fa89 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -885,28 +885,21 @@ static bool i915_get_crtc_scanoutpos(struct drm_device *dev, return true; } -bool i915_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, - unsigned int pipe, +bool i915_calc_vbltimestamp_from_scanoutpos(struct drm_crtc *crtc, int *max_error, ktime_t *vblank_time, bool in_vblank_irq) { + struct drm_device *dev = crtc->dev; + unsigned int pipe = crtc->index; struct timespec64 ts_etime, ts_vblank_time; ktime_t stime, etime; bool vbl_status; - struct drm_crtc *crtc; const struct drm_display_mode *mode; struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; int vpos, hpos, i; int delta_ns, duration_ns; - crtc = drm_crtc_from_index(dev, pipe); - - if (pipe >= dev->num_crtcs || !crtc) { - DRM_ERROR("Invalid crtc %u\n", pipe); - return false; -
[PATCH 08/23] drm/stm: Convert to struct drm_crtc_helper_funcs.get_scanout_position()
The callback struct drm_driver.get_scanout_position() is deprecated in favor of struct drm_crtc_helper_funcs.get_scanout_position(). Convert stm over. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/stm/drv.c | 1 - drivers/gpu/drm/stm/ltdc.c | 65 -- drivers/gpu/drm/stm/ltdc.h | 5 --- 3 files changed, 34 insertions(+), 37 deletions(-) diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c index 5a9f9aca8bc2..486985604109 100644 --- a/drivers/gpu/drm/stm/drv.c +++ b/drivers/gpu/drm/stm/drv.c @@ -72,7 +72,6 @@ static struct drm_driver drv_driver = { .gem_prime_vmap = drm_gem_cma_prime_vmap, .gem_prime_vunmap = drm_gem_cma_prime_vunmap, .gem_prime_mmap = drm_gem_cma_prime_mmap, - .get_scanout_position = ltdc_crtc_scanoutpos, .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, }; diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c index c2815e8ae1da..8b6d1a2252e3 100644 --- a/drivers/gpu/drm/stm/ltdc.c +++ b/drivers/gpu/drm/stm/ltdc.c @@ -636,38 +636,13 @@ static void ltdc_crtc_atomic_flush(struct drm_crtc *crtc, } } -static const struct drm_crtc_helper_funcs ltdc_crtc_helper_funcs = { - .mode_valid = ltdc_crtc_mode_valid, - .mode_fixup = ltdc_crtc_mode_fixup, - .mode_set_nofb = ltdc_crtc_mode_set_nofb, - .atomic_flush = ltdc_crtc_atomic_flush, - .atomic_enable = ltdc_crtc_atomic_enable, - .atomic_disable = ltdc_crtc_atomic_disable, -}; - -static int ltdc_crtc_enable_vblank(struct drm_crtc *crtc) -{ - struct ltdc_device *ldev = crtc_to_ltdc(crtc); - - DRM_DEBUG_DRIVER("\n"); - reg_set(ldev->regs, LTDC_IER, IER_LIE); - - return 0; -} - -static void ltdc_crtc_disable_vblank(struct drm_crtc *crtc) -{ - struct ltdc_device *ldev = crtc_to_ltdc(crtc); - - DRM_DEBUG_DRIVER("\n"); - reg_clear(ldev->regs, LTDC_IER, IER_LIE); -} - -bool ltdc_crtc_scanoutpos(struct drm_device *ddev, unsigned int pipe, - bool in_vblank_irq, int *vpos, int *hpos, - ktime_t *stime, ktime_t *etime, - const struct drm_display_mode *mode) +static bool ltdc_crtc_get_scanout_position(struct drm_crtc *crtc, + bool in_vblank_irq, + int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode) { + struct drm_device *ddev = crtc->dev; struct ltdc_device *ldev = ddev->dev_private; int line, vactive_start, vactive_end, vtotal; @@ -710,6 +685,34 @@ bool ltdc_crtc_scanoutpos(struct drm_device *ddev, unsigned int pipe, return true; } +static const struct drm_crtc_helper_funcs ltdc_crtc_helper_funcs = { + .mode_valid = ltdc_crtc_mode_valid, + .mode_fixup = ltdc_crtc_mode_fixup, + .mode_set_nofb = ltdc_crtc_mode_set_nofb, + .atomic_flush = ltdc_crtc_atomic_flush, + .atomic_enable = ltdc_crtc_atomic_enable, + .atomic_disable = ltdc_crtc_atomic_disable, + .get_scanout_position = ltdc_crtc_get_scanout_position, +}; + +static int ltdc_crtc_enable_vblank(struct drm_crtc *crtc) +{ + struct ltdc_device *ldev = crtc_to_ltdc(crtc); + + DRM_DEBUG_DRIVER("\n"); + reg_set(ldev->regs, LTDC_IER, IER_LIE); + + return 0; +} + +static void ltdc_crtc_disable_vblank(struct drm_crtc *crtc) +{ + struct ltdc_device *ldev = crtc_to_ltdc(crtc); + + DRM_DEBUG_DRIVER("\n"); + reg_clear(ldev->regs, LTDC_IER, IER_LIE); +} + static const struct drm_crtc_funcs ltdc_crtc_funcs = { .destroy = drm_crtc_cleanup, .set_config = drm_atomic_helper_set_config, diff --git a/drivers/gpu/drm/stm/ltdc.h b/drivers/gpu/drm/stm/ltdc.h index a1ad0ae3b006..c5467d74e707 100644 --- a/drivers/gpu/drm/stm/ltdc.h +++ b/drivers/gpu/drm/stm/ltdc.h @@ -39,11 +39,6 @@ struct ltdc_device { struct drm_atomic_state *suspend_state; }; -bool ltdc_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, - bool in_vblank_irq, int *vpos, int *hpos, - ktime_t *stime, ktime_t *etime, - const struct drm_display_mode *mode); - int ltdc_load(struct drm_device *ddev); void ltdc_unload(struct drm_device *ddev); void ltdc_suspend(struct drm_device *ddev); -- 2.24.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 06/23] drm/msm: Convert to struct drm_crtc_helper_funcs.get_scanout_position()
The callback struct drm_driver.get_scanout_position() is deprecated in favor of struct drm_crtc_helper_funcs.get_scanout_position(). Convert mem over. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c | 67 +++ drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c | 61 - 2 files changed, 67 insertions(+), 61 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c index 05cc04f729d6..4decf19847a8 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c @@ -405,6 +405,72 @@ static void mdp5_crtc_mode_set_nofb(struct drm_crtc *crtc) spin_unlock_irqrestore(&mdp5_crtc->lm_lock, flags); } +static struct drm_encoder *get_encoder_from_crtc(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_encoder *encoder; + + drm_for_each_encoder(encoder, dev) + if (encoder->crtc == crtc) + return encoder; + + return NULL; +} + +static bool mdp5_crtc_get_scanout_position(struct drm_crtc *crtc, + bool in_vblank_irq, + int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode) +{ + unsigned int pipe = crtc->index; + struct drm_encoder *encoder; + int line, vsw, vbp, vactive_start, vactive_end, vfp_end; + + + encoder = get_encoder_from_crtc(crtc); + if (!encoder) { + DRM_ERROR("no encoder found for crtc %d\n", pipe); + return false; + } + + vsw = mode->crtc_vsync_end - mode->crtc_vsync_start; + vbp = mode->crtc_vtotal - mode->crtc_vsync_end; + + /* +* the line counter is 1 at the start of the VSYNC pulse and VTOTAL at +* the end of VFP. Translate the porch values relative to the line +* counter positions. +*/ + + vactive_start = vsw + vbp + 1; + + vactive_end = vactive_start + mode->crtc_vdisplay; + + /* last scan line before VSYNC */ + vfp_end = mode->crtc_vtotal; + + if (stime) + *stime = ktime_get(); + + line = mdp5_encoder_get_linecount(encoder); + + if (line < vactive_start) + line -= vactive_start; + else if (line > vactive_end) + line = line - vfp_end - vactive_start; + else + line -= vactive_start; + + *vpos = line; + *hpos = 0; + + if (etime) + *etime = ktime_get(); + + return true; +} + static void mdp5_crtc_atomic_disable(struct drm_crtc *crtc, struct drm_crtc_state *old_state) { @@ -1063,6 +1129,7 @@ static const struct drm_crtc_helper_funcs mdp5_crtc_helper_funcs = { .atomic_flush = mdp5_crtc_atomic_flush, .atomic_enable = mdp5_crtc_atomic_enable, .atomic_disable = mdp5_crtc_atomic_disable, + .get_scanout_position = mdp5_crtc_get_scanout_position, }; static void mdp5_crtc_vblank_irq(struct mdp_irq *irq, uint32_t irqstatus) diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c index e43ecd4be10a..8b72ac44ce55 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c @@ -595,66 +595,6 @@ static struct drm_encoder *get_encoder_from_crtc(struct drm_crtc *crtc) return NULL; } -static bool mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, - bool in_vblank_irq, int *vpos, int *hpos, - ktime_t *stime, ktime_t *etime, - const struct drm_display_mode *mode) -{ - struct msm_drm_private *priv = dev->dev_private; - struct drm_crtc *crtc; - struct drm_encoder *encoder; - int line, vsw, vbp, vactive_start, vactive_end, vfp_end; - - crtc = priv->crtcs[pipe]; - if (!crtc) { - DRM_ERROR("Invalid crtc %d\n", pipe); - return false; - } - - encoder = get_encoder_from_crtc(crtc); - if (!encoder) { - DRM_ERROR("no encoder found for crtc %d\n", pipe); - return false; - } - - vsw = mode->crtc_vsync_end - mode->crtc_vsync_start; - vbp = mode->crtc_vtotal - mode->crtc_vsync_end; - - /* -* the line counter is 1 at the start of the VSYNC pulse and VTOTAL at -* the end of VFP. Translate the porch values relative to the line -* counter positions. -*/ - - vactive_start = vsw + vbp + 1; - - vactive_end = vactive_start + mode->crtc_vdisplay; - - /* last scan line before VSYNC */ - vfp_end = mode->crtc_vtotal; - - if (stime) - *stime = ktime_get(); - - line = m
[PATCH 12/23] drm/amdgpu: Convert to CRTC VBLANK callbacks
VBLANK callbacks in struct drm_driver are deprecated in favor of their equivalents in struct drm_crtc_funcs. Convert amdgpu over. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 3 +++ drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 4 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 24 +++ drivers/gpu/drm/amd/amdgpu/dce_v10_0.c| 4 drivers/gpu/drm/amd/amdgpu/dce_v11_0.c| 4 drivers/gpu/drm/amd/amdgpu/dce_v6_0.c | 4 drivers/gpu/drm/amd/amdgpu/dce_v8_0.c | 4 drivers/gpu/drm/amd/amdgpu/dce_virtual.c | 4 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 ++ 9 files changed, 49 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 81a531b652aa..c1262ab588c9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1197,6 +1197,9 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon); u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); int amdgpu_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); +u32 amdgpu_crtc_get_vblank_counter(struct drm_crtc *crtc); +int amdgpu_crtc_enable_vblank(struct drm_crtc *crtc); +void amdgpu_crtc_disable_vblank(struct drm_crtc *crtc); long amdgpu_kms_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 0749285dd1c7..9baa1ddf8693 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -1377,10 +1377,6 @@ static struct drm_driver kms_driver = { .postclose = amdgpu_driver_postclose_kms, .lastclose = amdgpu_driver_lastclose_kms, .unload = amdgpu_driver_unload_kms, - .get_vblank_counter = amdgpu_get_vblank_counter_kms, - .enable_vblank = amdgpu_enable_vblank_kms, - .disable_vblank = amdgpu_disable_vblank_kms, - .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, .irq_handler = amdgpu_irq_handler, .ioctls = amdgpu_ioctls_kms, .gem_free_object_unlocked = amdgpu_gem_object_free, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 60591dbc2097..efe4671fb032 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -1174,6 +1174,14 @@ u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe) return count; } +u32 amdgpu_crtc_get_vblank_counter(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + unsigned int pipe = crtc->index; + + return amdgpu_get_vblank_counter_kms(dev, pipe); +} + /** * amdgpu_enable_vblank_kms - enable vblank interrupt * @@ -1191,6 +1199,14 @@ int amdgpu_enable_vblank_kms(struct drm_device *dev, unsigned int pipe) return amdgpu_irq_get(adev, &adev->crtc_irq, idx); } +int amdgpu_crtc_enable_vblank(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + unsigned int pipe = crtc->index; + + return amdgpu_enable_vblank_kms(dev, pipe); +} + /** * amdgpu_disable_vblank_kms - disable vblank interrupt * @@ -1207,6 +1223,14 @@ void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe) amdgpu_irq_put(adev, &adev->crtc_irq, idx); } +void amdgpu_crtc_disable_vblank(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + unsigned int pipe = crtc->index; + + amdgpu_disable_vblank_kms(dev, pipe); +} + const struct drm_ioctl_desc amdgpu_ioctls_kms[] = { DRM_IOCTL_DEF_DRV(AMDGPU_GEM_CREATE, amdgpu_gem_create_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(AMDGPU_CTX, amdgpu_ctx_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c index bdc1e0f036d4..8e62f46f0bfd 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c @@ -2494,6 +2494,10 @@ static const struct drm_crtc_funcs dce_v10_0_crtc_funcs = { .set_config = amdgpu_display_crtc_set_config, .destroy = dce_v10_0_crtc_destroy, .page_flip_target = amdgpu_display_crtc_page_flip_target, + .get_vblank_counter = amdgpu_crtc_get_vblank_counter, + .enable_vblank = amdgpu_crtc_enable_vblank, + .disable_vblank = amdgpu_crtc_disable_vblank, + .get_vblank_timestamp = drm_crtc_calc_vbltimestamp_from_scanoutpos, }; static void dce_v10_0_crtc_dpms(struct drm_crtc *crtc, int mode) diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c index 0319da5f7bf9..9e37e4a78403 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c +++ b/drivers